Greg KH wrote:
> 
> On Thu, Sep 20, 2001 at 06:09:52PM -0400, kevin wrote:
> >
> >       Now I have to send a series of about a dozen vendor specific commands

> 
> Posting exact code might help out in determining what is goind wrong.
> 
> thanks,
> 
> greg k-h

Thanks all for the quick response. Before I list the code, I would like
to take note of Olivr Neukum's note that I need to use a driver that
supports a video input device. I did start with the ibmcam driver which
does interface with v4l, but I was having the same problem with
initializing the camera for video mode. I decided to simplify as much as
possible until I find out what I am doing wrong, then go back to the
ibmcam or some other driver. The initialization routines are used in the
Windows driver for both still picture and video camera mode, so I have
to get them working first.

I am using Mandrake 8.0, with their kernel 2.4.3-20mdk; no other patches
or changes. The latest driver I tried is based on Greg K-H's
usb-skeletion.c code, version 0.3, 5-29-01. I changed skel_ to pencam_
and Skeleton to STV0680, put in the correct Vendor and Product codes
(0x0553/0x0202) and added the pencam_set_camera function to do the
initialization. There is a call to that function from the pencam_init
function, at the very end just before the ret statement (see below). The
usb_set_config/interface statments are used in the Windows driver and
the linux command line program to download images; I'm not sure they are
necessary here but I added them to make sure I was communicating with
the camera. I have removed the else info("Set ... OK"); but left the
code in here and manually typed in the messages in the log below. There
is also a big comment section with the codes obtained from the Windows
usb sniff program. Examinig buf contents after the 3rd call should give
me the vendor/product codes back (test/debug check), but I never get
that far. The crash occurs with the first usb_control_msg statement
(there are about 12 total; I commented out all but one until I find the
problem).

 Note: PENCAM_TIMEOUT is set to 1000 by a define

/************************************************************/
static void pencam_set_camera(struct usb_pencam *dev)
{
  unsigned char buf[40];
  int i;
  unsigned int pipe;
  unsigned char request_type = 0xc1;


  memset(buf,0,sizeof(buf));
    
/*
 This is the initialization sequence for the camera, captured by the usb 
 sniff program.  Timeout is set to 1000
 
  requesttype     request       value       index     size   
     0x80          0x06         0x0200        0       0x09    not used
here
     0x80          0x06         0x0200        0       0x0022  not used
here

set configuration, interface, alternate_setting (1,0,0)
     0xc1          0x8a         0             0       0x0002  
     0xc1          0x8b         0             0       0x0024  
     0xc1          0x85         0             0       0x0010 
# buf[8,9,10,11} = 05 53 02 02 (vendor/product id)

set configuration, interface, alternate_setting (1,0,1)
     0xc1          0x85         0             0       0x0010
     0xc1          0x88         0x7856        0       0x0002  ??? not
used.
     0xc1          0x8d         0x0000        0       0x0008  8d = # of
pics
     0xc1          0x8a         0x0000        0       0x0002 
     0xc1          0x8b         0x0000        0       0x0010
     0xc1          0x8b         0x1000        0       0x0010
     0xc1          0x8b         0x2000        0       0x0010
     0xc1          0x86         0x0000        0       0x0010 
     0xc1          0x8f         0x0000        0       0x0010
     0xc1          0x83         0x0000        0       0x0010  03 =
SET_FEATURE
 Device should now set set for transfer of pictures.
 transfer type=bulk size=32 ep=0x82 dir=in timeout=1000
*/

/* Now the linux code */

    if (usb_set_configuration(dev->udev, 1) < 0)
      info("FAILED to set config");  
    else
        info("Set configuration OK");

    if (usb_set_interface(dev->udev, 0,0) < 0)
      info("FAILED to set interface");  
    else
        info("Set interface OK");

    if ((i = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev,0), 
            0x8a, 0xc1, 0, 0, buf, 0x02, PENCAM_TIMEOUT)) < 0)
            return i;

/* commented out everything below until I figure out what is wrong */

//    usb_control_msg(dev, pipe, 0x8b, request_type, 0, 0, buf, 0x24,
PENCAM_TIMEOUT);
//    i = usb_control_msg(dev, pipe, 0x85, request_type, 0, 0, buf,
0x10, PENCAM_TIMEOUT);
/*    if (i<0)
      info("Bad communication to camera.\n");
    else if ((i>=0) && (buf[8] == 0x05) && (buf[9] == 0x53))
      info("Found correct Vendor ID.\n");
    else
      info("Could not get correct Vendor ID.\n");    
*/
    info("buf[8]=%i, buf[9]=%i\n", buf[8], buf[9]);

                        |
  CUT OUT SIMILAR LINES v

}

/* Now the original skel_init, with an added call to pencam_set_camera
at the end */

static void * pencam_probe(struct usb_device *udev, unsigned int ifnum,
const struct usb_device_id *id)
{
        struct usb_pencam *dev = NULL;
        struct usb_interface *interface;
        struct usb_interface_descriptor *iface_desc;
        struct usb_endpoint_descriptor *endpoint;
        int minor;
        int buffer_size;
        int i;
        char name[10];

        
        /* See if the device offered us matches what we can accept */
        if ((udev->descriptor.idVendor != USB_PENCAM_VENDOR_ID) ||
            (udev->descriptor.idProduct != USB_PENCAM_PRODUCT_ID)) {
                return NULL;
        }

        /* select a "subminor" number (part of a minor number) */
        down (&minor_table_mutex);
        for (minor = 0; minor < MAX_DEVICES; i++) {
                if (minor_table[minor] == NULL)
                        break;
        }
        if (minor >= MAX_DEVICES) {
                info ("Too many devices plugged in, can not handle this
device.");
                goto exit;
        }

        /* allocate memory for our device state and intialize it */
        dev = kmalloc (sizeof(struct usb_pencam), GFP_KERNEL);
        if (dev == NULL) {
                err ("Out of memory");
                goto exit;
        }
        minor_table[minor] = dev;

        interface = &udev->actconfig->interface[ifnum];

        init_MUTEX (&dev->sem);
        dev->udev = udev;
        dev->interface = interface;
        dev->minor = minor;

        /* set up the endpoint information */
        /* check out the endpoints */
        iface_desc = &interface->altsetting[0];
        for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i];

                if ((endpoint->bEndpointAddress & 0x80) &&
                    ((endpoint->bmAttributes & 3) == 0x02)) {
                        /* we found a bulk in endpoint */
                        buffer_size = endpoint->wMaxPacketSize;
                        dev->bulk_in_size = buffer_size;
                        dev->bulk_in_endpointAddr =
endpoint->bEndpointAddress;
                        dev->bulk_in_buffer = kmalloc (buffer_size,
GFP_KERNEL);
                        if (!dev->bulk_in_buffer) {
                                err("Couldn't allocate bulk_in_buffer");
                                goto error;
                        }
                }
                
                if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
                    ((endpoint->bmAttributes & 3) == 0x02)) {
                        /* we found a bulk out endpoint */
                        dev->write_urb = usb_alloc_urb(0);
                        if (!dev->write_urb) {
                                err("No free urbs available");
                                goto error;
                        }
                        buffer_size = endpoint->wMaxPacketSize;
                        dev->bulk_out_size = buffer_size;
                        dev->bulk_out_endpointAddr =
endpoint->bEndpointAddress;
                        dev->bulk_out_buffer = kmalloc (buffer_size,
GFP_KERNEL);
                        if (!dev->bulk_out_buffer) {
                                err("Couldn't allocate
bulk_out_buffer");
                                goto error;
                        }
                        FILL_BULK_URB(dev->write_urb, udev, 
                                      usb_sndbulkpipe(udev, 
                                                     
endpoint->bEndpointAddress),
                                      dev->bulk_out_buffer, buffer_size,
                                      pencam_write_bulk_callback, dev);
                }
        }

        /* initialize the devfs node for this device and register it */
        sprintf(name, "pencam%d", dev->minor);
        
        dev->devfs = devfs_register (usb_devfs_handle, name,
                                     DEVFS_FL_DEFAULT, USB_MAJOR,
                                     USB_PENCAM_MINOR_BASE + dev->minor,
                                     S_IFCHR | S_IRUSR | S_IWUSR | 
                                     S_IRGRP | S_IWGRP | S_IROTH, 
                                     &pencam_fops, NULL);

        /* let the user know what node this device is now attached to */
        info ("USB STV0680 device now attached to pencam%d",
dev->minor);
        goto exit;
        
error:
        minor_table [dev->minor] = NULL;
        if (dev->bulk_in_buffer != NULL)
                kfree (dev->bulk_in_buffer);
        if (dev->bulk_out_buffer != NULL)
                kfree (dev->bulk_out_buffer);
        if (dev->write_urb != NULL)
                usb_free_urb (dev->write_urb);
        kfree (dev);
        dev = NULL;

exit:
        up (&minor_table_mutex);

/* put in test of communication with camera */
        pencam_set_camera(dev);

        return dev;
}


/**********/

These are the only changes I made to the usb-skeleton code. Now the
output; the interface appears to be accepted, I get my first two test
messages back (from the usb_set_config/interface), then the crash.

...  plug in camera, pendrv.o not loaded

hub.c: USB new device connect on bus1/1/3, assigned device number 3
usb.c: USB device 3 (vend/prod 0x553/0x202) is not claimed by any active
driver.

now insmod pendrv (I am using the minor number of 200 from the
usb-skeleton.c code, after "mknod pencam0 c 180 200" in /dev/usb).

usb.c: registered new driver pendrv
penmod.c: USB STV0680 device now attached to pencam0

(Set config OK)
(Set interface OK)

invalid operand: 0000
CPU:    0
EIP:    0010:[<c88f165d>]
EFLAGS: 00010202
eax: 00000300   ebx: c4c79dec   ecx: c29c2c00   edx: 04000300
esi: c541af60   edi: c29c2c00   ebp: 00000000   esp: c4c79dc4
ds: 0018   es: 0018   ss: 0018
Process insmod (pid: 1551, stackpage=c4c79000)
Stack: 0000008a 000000c1 00000000 00000000 c4c79dec 00000002 000003e8
00000000 
       00000000 00000086 00000000 00000000 00000000 00000000 00000000
00000000 
       00000000 00000000 00000000 00000000 c0113e93 c88f2130 c88f2130
00000000 
Call Trace: [<c0113e93>] [<c88f2130>] [<c88f2130>] [<c88f197e>]
[<c0129463>] [<c88f22a4>] [<c88f2360>] 
       [<c8851ae9>] [<c88f22a4>] [<c88f2494>] [<c88f237c>] [<c885c340>]
[<c885186c>] [<c8851845>] [<c8851845>] 
       [<c885c348>] [<c88f1a50>] [<c8851116>] [<c88f2360>] [<c88510f3>]
[<c88f1000>] [<c88f1a5d>] [<c88f2360>] 
       [<c012972e>] [<c0129754>] [<c0114aa8>] [<c8851000>] [<c8851000>]
[<c88f2480>] [<c88fe000>] [<c88f1060>] 
       [<c0106f23>] 

Code: 0f 44 c2 0d 80 00 00 80 50 8b 0e 51 e8 2a 0b f6 ff 83 c4 30 
 
That's all I know. Thanks again,

        Kevin


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to