You should use kmalloc to allocate dma-able ram for the buf buffer.
- Roman
kevin wrote:
>
> 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
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel