I am fiddeling around with an IR USB device to get it working with Linux.
Right now, I am trying to get data from the device using Interrupt Transfer.
However, the device does not trigger any interrupts at all which puzzles me.
I can successfully query the device with control messages to get any kind of descriptor (device, string).
However, after setting the device configuration and submitting an int URB, the provided completion routine does not get triggered at all.
Any hints on what I am missing?
Thanks, Oliver
The device looks like this (taken from GET_DESCRIPTOR_FROM_DEVICE request)
0000: 09 02 20 00 01 01 04 a0 32
bLength : 0x09 (9)
bDescriptorType : 0x02 (2)
wTotalLength : 0x0020 (32)
bNumInterfaces : 0x01 (1)
bConfigurationValue: 0x01 (1)
iConfiguration : 0x04 (4)
bmAttributes : 0xa0 (160)
MaxPower : 0x32 (50)
000A: 09 04 00 00 02 00 00 00 00
bLength : 0x09 (9)
bDescriptorType : 0x04 (4)
bInterfaceNumber : 0x00
bAlternateSetting : 0x00
bNumEndpoints : 0x02
bInterfaceClass : 0x00
bInterfaceSubClass : 0x00
bInterfaceProtocol : 0x00
iInterface : 0x00
0012: 07 05 81 03 08 00 32
bLength : 0x07 (7)
bDescriptorType : 0x05 (5)
bEndpointAddress : 0x81
bmAttributes : 0x03
wMaxPacketSize : 0x0008
bIntervall : 0x32
0019: 07 05 02 03 08 00 32
bLength : 0x07 (7)
bDescriptorType : 0x05 (5)
bEndpointAddress : 0x02
bmAttributes : 0x03
wMaxPacketSize : 0x0008
bIntervall : 0x32and the "driver" currently looks like this:
#include <linux/kernel.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h>
struct usb_sasem {
signed char data[8];
char name[128];
struct usb_device *usbdev;
struct urb irq;
int open;
};static void usb_sasem_irq(struct urb *urb)
{
struct usb_sasem *sasem = urb->context;
signed char *data = sasem->data; info("Sasem Interrupt start");
usb_submit_urb(urb);
}static void *usb_sasem_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
{
struct usb_interface *iface;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_sasem *sasem;
int pipe, maxp;
char *buf; // get current interface
iface = &dev->actconfig->interface[ifnum];
// get interface descriptor
interface = &iface->altsetting[iface->act_altsetting]; // interface has two Endpoints
if (interface->bNumEndpoints != 2) return NULL; endpoint = interface->endpoint + 0;
// Endpoint is not DIRECTION_IN
if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
// Endpoint is not of type INTERRUPT
if ((endpoint->bmAttributes & 3) != 3) return NULL; // create pipe
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
// and get maxpacket size
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
// allocate memory in Kernel for Sasem structure
if (!(sasem = kmalloc(sizeof(struct usb_sasem), GFP_KERNEL))) return NULL;
memset(sasem, 0, sizeof(struct usb_sasem));sasem->usbdev = dev;
// allocate buffer for String operations
if (!(buf = kmalloc(63, GFP_KERNEL))) {
kfree(sasem);
return NULL;
}// get iManufacturer from USB Device
if (dev->descriptor.iManufacturer && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) {
strcat(sasem->name, buf);
info("Manufacturer: %s", buf);
}
// get iProduct from USB Device
if (dev->descriptor.iProduct && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) {
sprintf(sasem->name, "%s %s", sasem->name, buf);
info("Product: %s", buf);
}
if (dev->descriptor.iSerialNumber && usb_string(dev, dev->descriptor.iSerialNumber, buf, 63) > 0) {
info("Serial: %s", buf);
}
info("VendorID: %04X", dev->descriptor.idVendor);
info("ProductID: %04X", dev->descriptor.idProduct);kfree(buf);
if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
info("set_configuration failed");
kfree(sasem);
return NULL;
}
// create Interrupt URB
FILL_INT_URB(&sasem->irq, dev, pipe, sasem->data, maxp > 8 ? 8 : maxp,
usb_sasem_irq, sasem, endpoint->bInterval); if (usb_submit_urb(&sasem->irq)) {
kfree (sasem);
return NULL;
}
info("Probe done");
return sasem;
}static void usb_sasem_disconnect(struct usb_device *dev, void *ptr)
{
struct usb_sasem *sasem = ptr;
usb_unlink_urb(&sasem->irq);
kfree(sasem);
}static struct usb_device_id usb_sasem_id_table [] = {
{ USB_DEVICE(0x11ba, 0x0101) },
{ } /* Terminating entry */
};MODULE_DEVICE_TABLE (usb, usb_sasem_id_table);
static struct usb_driver usb_sasem_driver = {
name: "usbsasem",
probe: usb_sasem_probe,
disconnect: usb_sasem_disconnect,
id_table: usb_sasem_id_table,
};static int __init usb_sasem_init(void)
{
usb_register(&usb_sasem_driver);
return 0;
}static void __exit usb_sasem_exit(void)
{
usb_deregister(&usb_sasem_driver);
}module_init(usb_sasem_init); module_exit(usb_sasem_exit);
------------------------------------------------------- This SF.Net email is sponsored by: IBM Linux Tutorials Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-users
