[CDC-ACM] Linux USB "Reduced" CDC-ACM driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear all,

I am actually working on the OMAP3 EVM from TI, and their eZ430u usb tool.
( http://focus.ti.com/docs/toolsw/folders/print/ez430-rf2480.html )

This kit contains a TUSB3410 which is a USB to UART bridge, and an EEPROM which
contains a firmware for using the tool as a CDC-ACM USB peripheral. This
firmware has been mostly written for beeing used under Windows XP, and for
compatibility reasons it only exports 1 interface ( kind of merged DATA and COMM
interface ).

The actual Linux CDC-ACM driver is waiting for 2 interfaces ( 1 for DATA and 1
for COMM ), so, the eZ430u tool does'nt work with Linux.

I made a small patch to "correct" this ( attached below ).

I wanted to have some feedbacks about this patch. As I suppose the eZ430u is NOT
the only device in the world that exports only 1 interface for CDC-ACM, I think
it would be nice if the Linux CDC-ACM Driver could support it.

More-over, with this patch, even if now the tool "is working", I loose some
bytes from time to time (only for the Reception, Transmition is ok), which is
actually a real problem. This seem to be a driver issue, since I don't loose any
data when using the tool on Windows.

Could you please tell me if you're interested in patching the Linux CDC-ACM
driver for backward compatibility ? Could you please have a glance at my patch
and give me some feedbacks ?


Thanks.

*** linux-orig/drivers/usb/class/
cdc-acm.c    2009-01-22 06:00:07.000000000 -0500
--- linux-new/drivers/usb/class/cdc-acm.c    2009-04-17 05:00:22.000000000 -0400
***************
*** 445,450 ****
--- 445,452 ----
          list_del(&buf->list);
 
          rcv->buffer = buf;
+             if (acm->dev->quirks == TI_EZ430U)
+                     rcv->urb->interval = 0xFF;
 
          usb_fill_bulk_urb(rcv->urb, acm->dev,
                    acm->rx_endpoint,
***************
*** 916,922 ****
      num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
 
      /* handle quirks deadly to normal probing*/
-     if (quirks == NO_UNION_NORMAL) {
          data_interface = usb_ifnum_to_if(usb_dev, 1);
          control_interface = usb_ifnum_to_if(usb_dev, 0);
          goto skip_normal_probe;
--- 918,924 ----
      num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
 
      /* handle quirks deadly to normal probing*/
+     if (quirks == NO_UNION_NORMAL || quirks == TI_EZ430U) {
          data_interface = usb_ifnum_to_if(usb_dev, 1);
          control_interface = usb_ifnum_to_if(usb_dev, 0);
          goto skip_normal_probe;
***************
*** 1012,1018 ****
 
      /*workaround for switched interfaces */
      if (data_interface->cur_altsetting->desc.bInterfaceClass !=
CDC_DATA_INTERFACE_TYPE) {
-         if (control_interface->cur_altsetting->desc.bInterfaceClass ==
CDC_DATA_INTERFACE_TYPE) {
              struct usb_interface *t;
              dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
 
--- 1014,1020 ----
 
      /*workaround for switched interfaces */
      if (data_interface->cur_altsetting->desc.bInterfaceClass !=
CDC_DATA_INTERFACE_TYPE) {
+         if ( (control_interface->cur_altsetting->desc.bInterfaceClass ==
CDC_DATA_INTERFACE_TYPE) || (quirks == TI_EZ430U) ) {
              struct usb_interface *t;
              dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
 
***************
*** 1038,1044 ****
          return -EINVAL;
 
      epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
-     epread = &data_interface->cur_altsetting->endpoint[0].desc;
      epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
 
 
--- 1040,1046 ----
          return -EINVAL;
 
      epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
+     epread = (quirks == TI_EZ430U) ?
&data_interface->cur_altsetting->endpoint[1].desc :
&data_interface->cur_altsetting->endpoint[0].desc;
      epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
 
 
***************
*** 1370,1375 ****
--- 1372,1380 ----
      { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
      .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
      },
+         { USB_DEVICE(0x0451, 0xF432), /* TI TUSB3410 */
+             .driver_info = TI_EZ430U,
+         },
 
      /* control interfaces with various AT-command sets */
      { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
*** linux-orig/drivers/usb/class/cdc-acm.h    2009-01-22 06:00:07.000000000 -0500
--- linux-new/drivers/usb/class/cdc-acm.h    2009-04-17 04:34:52.000000000 -0400
***************
*** 134,136 ****
--- 134,138 ----
  /* constants describing various quirks and errors */
  #define NO_UNION_NORMAL            1
  #define SINGLE_RX_URB            2
+ #define TI_EZ430U                       3
+ 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux