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