Messages in this thread Patch in this message | | | Date | Mon, 30 Aug 1999 22:59:18 +0200 | From | Pavel Machek <> | Subject | FIX for acm.c to detect ELSA microlink USB |
| |
Hi!
This patch fixes docs a bit (log for 0.5 was there twice), makes code look for any errors from tty_register_driver, plus makes acm.c correctly detect ELSA microlink USB (acm.c used to assume more than guaranteed by specification).
Pavel PS: Armin Fuerst, please list your email address in acm.c headers.
--- clean//drivers/usb/acm.c Sun Aug 29 23:43:44 1999 +++ linux/drivers/usb/acm.c Mon Aug 30 22:51:02 1999 @@ -23,10 +23,7 @@ * uhci.c. Should have the correct interface now. * (6/6/99) * - * version 0.5 driver now generates a tty instead of a simple character - * device - * - * version 0.3: Mayor changes. Changed Bulk transfer to interrupt based + * version 0.3: Major changes. Changed Bulk transfer to interrupt based * transfer. Using FIFO Buffers now. Consistent handling of open/close * file state and detected/nondetected device. File operations behave * according to this. Driver is able to send+receive now! Heureka! @@ -61,13 +58,13 @@ #include <linux/module.h> //#include <sys/ioctl.h> #include <asm/spinlock.h> #include "usb.h" #define NR_PORTS 3 #define ACM_MAJOR 166 -#define info(message); printk(message); -//#define info(message); +#define info(message...); printk(message); +//#define info(message...); #define CTRL_STAT_DTR 1 #define CTRL_STAT_RTS 2 @@ -485,6 +489,7 @@ struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; int cfgnum,acmno; + int swapped=0; info("acm_probe\n"); @@ -500,14 +505,13 @@ dev->descriptor.bDeviceProtocol != 0) return -1; - /* Now scan all configs for a ACM configuration */ +#define IFCLASS(if) ((if->bInterfaceClass << 24) | (if->bInterfaceSubClass << 16) | (if->bInterfaceProtocol << 8) | (if->bNumEndpoints)) + + /* Now scan all configs for a ACM configuration*/ for (cfgnum=0;cfgnum<dev->descriptor.bNumConfigurations;cfgnum++) { /* The first one should be Communications interface? */ interface = &dev->config[cfgnum].interface[0].altsetting[0]; - if (interface->bInterfaceClass != 2 || - interface->bInterfaceSubClass != 2 || - interface->bInterfaceProtocol != 1 || - interface->bNumEndpoints != 1) + if (IFCLASS(interface) != 0x02020101) continue; /*Which uses an interrupt input */ @@ -519,19 +523,20 @@ /* The second one should be a Data interface? */ interface = &dev->config[cfgnum].interface[1].altsetting[0]; if (interface->bInterfaceClass != 10 || - interface->bInterfaceSubClass != 0 || - interface->bInterfaceProtocol != 0 || - interface->bNumEndpoints != 2) + interface->bNumEndpoints != 2) continue; + if ((endpoint->bEndpointAddress & 0x80) == 0x80) + swapped = 1; + /*With a bulk input */ - endpoint = &interface->endpoint[0]; + endpoint = &interface->endpoint[0^swapped]; if ((endpoint->bEndpointAddress & 0x80) != 0x80 || (endpoint->bmAttributes & 3) != 2) continue; /*And a bulk output */ - endpoint = &interface->endpoint[1]; + endpoint = &interface->endpoint[1^swapped]; if ((endpoint->bEndpointAddress & 0x80) == 0x80 || (endpoint->bmAttributes & 3) != 2) continue; @@ -542,30 +547,30 @@ acm->dev=dev; dev->private=acm; - acm->readendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[0].bEndpointAddress; + acm->readendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[0^swapped].bEndpointAddress; acm->readpipe=usb_rcvbulkpipe(dev,acm->readendp); - acm->readbuffer=kmalloc(acm->readsize=dev->config[cfgnum].interface[1].altsetting[0].endpoint[0].wMaxPacketSize,GFP_KERNEL); + acm->readbuffer=kmalloc(acm->readsize=dev->config[cfgnum].interface[1].altsetting[0].endpoint[0^swapped].wMaxPacketSize,GFP_KERNEL); acm->reading=0; if (!acm->readbuffer) { printk("ACM: Couldn't allocate readbuffer\n"); return -1; } - - acm->writeendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[1].bEndpointAddress; + + acm->writeendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[1^swapped].bEndpointAddress; acm->writepipe=usb_sndbulkpipe(dev,acm->writeendp); - acm->writebuffer=kmalloc(acm->writesize=dev->config[cfgnum].interface[1].altsetting[0].endpoint[1].wMaxPacketSize, GFP_KERNEL); + acm->writebuffer=kmalloc(acm->writesize=dev->config[cfgnum].interface[1].altsetting[0].endpoint[1^swapped].wMaxPacketSize, GFP_KERNEL); acm->writing=0; if (!acm->writebuffer) { printk("ACM: Couldn't allocate writebuffer\n"); kfree(acm->readbuffer); return -1; } - + acm->ctrlendp=dev->config[cfgnum].interface[0].altsetting[0].endpoint[0].bEndpointAddress; acm->ctrlpipe=usb_rcvctrlpipe(acm->dev,acm->ctrlendp); acm->ctrlinterval=dev->config[cfgnum].interface[0].altsetting[0].endpoint[0].bInterval; - acm->present=1; + acm->present=1; MOD_INC_USE_COUNT; return 0; } @@ -660,7 +665,10 @@ acm_tty_driver.read_proc = NULL; //rs_read_proc; acm_tty_driver.chars_in_buffer = rs_chars_in_buffer; acm_tty_driver.flush_buffer = NULL; //rs_flush_buffer; - tty_register_driver(&acm_tty_driver); + if (tty_register_driver(&acm_tty_driver)) { + printk( "acm: failed to register tty driver\n" ); + return -EPERM; + } //REGISTER USB DRIVER usb_register(&acm_driver); -- I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel. Pavel Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |