USB: ti_usb: fix printk format warning
[safe/jmp/linux-2.6] / drivers / usb / serial / ti_usb_3410_5052.c
index a9523b8..e1bfda3 100644 (file)
  * For questions or problems with this driver, contact Texas Instruments
  * technical support, or Al Borchers <alborchers@steinerpoint.com>, or
  * Peter Berger <pberger@brimson.com>.
- *
- * This driver needs this hotplug script in /etc/hotplug/usb/ti_usb_3410_5052
- * or in /etc/hotplug.d/usb/ti_usb_3410_5052.hotplug to set the device
- * configuration.
- *
- * #!/bin/bash
- *
- * BOOT_CONFIG=1
- * ACTIVE_CONFIG=2
- *
- * if [[ "$ACTION" != "add" ]]
- * then
- *     exit
- * fi
- *
- * CONFIG_PATH=/sys${DEVPATH%/?*}/bConfigurationValue
- *
- * if [[ 0`cat $CONFIG_PATH` -ne $BOOT_CONFIG ]]
- * then
- *     exit
- * fi
- *
- * PRODUCT=${PRODUCT%/?*}              # delete version
- * VENDOR_ID=`printf "%d" 0x${PRODUCT%/?*}`
- * PRODUCT_ID=`printf "%d" 0x${PRODUCT#*?/}`
- *
- * PARAM_PATH=/sys/module/ti_usb_3410_5052/parameters
- *
- * function scan() {
- *     s=$1
- *     shift
- *     for i
- *     do
- *             if [[ $s -eq $i ]]
- *             then
- *                     return 0
- *             fi
- *     done
- *     return 1
- * }
- *
- * IFS=$IFS,
- *
- * if (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_3410` &&
- * scan $PRODUCT_ID 13328 `cat $PARAM_PATH/product_3410`) ||
- * (scan $VENDOR_ID 1105 `cat $PARAM_PATH/vendor_5052` &&
- * scan $PRODUCT_ID 20562 20818 20570 20575 `cat $PARAM_PATH/product_5052`)
- * then
- *     echo $ACTIVE_CONFIG > $CONFIG_PATH
- * fi
  */
 
 #include <linux/kernel.h>
 
 #define TI_TRANSFER_TIMEOUT    2
 
-#define TI_DEFAULT_LOW_LATENCY 0
 #define TI_DEFAULT_CLOSING_WAIT        4000            /* in .01 secs */
 
 /* supported setserial flags */
-#define TI_SET_SERIAL_FLAGS    (ASYNC_LOW_LATENCY)
+#define TI_SET_SERIAL_FLAGS    0
 
 /* read urb states */
 #define TI_READ_URB_RUNNING    0
@@ -148,11 +97,9 @@ struct ti_device {
 /* Function Declarations */
 
 static int ti_startup(struct usb_serial *serial);
-static void ti_shutdown(struct usb_serial *serial);
-static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
-               struct file *file);
-static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
-               struct file *file);
+static void ti_release(struct usb_serial *serial);
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
+static void ti_close(struct usb_serial_port *port);
 static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
                const unsigned char *data, int count);
 static int ti_write_room(struct tty_struct *tty);
@@ -195,7 +142,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
 static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
        __u8 mask, __u8 byte);
 
-static int ti_download_firmware(struct ti_device *tdev, int type);
+static int ti_download_firmware(struct ti_device *tdev);
 
 /* circular buffer */
 static struct circ_buf *ti_buf_alloc(void);
@@ -211,7 +158,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count);
 
 /* module parameters */
 static int debug;
-static int low_latency = TI_DEFAULT_LOW_LATENCY;
 static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
 static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
 static unsigned int vendor_3410_count;
@@ -226,25 +172,47 @@ static unsigned int product_5052_count;
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+       { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
        { }
 };
 
@@ -266,7 +234,7 @@ static struct usb_serial_driver ti_1port_device = {
        .id_table               = ti_id_table_3410,
        .num_ports              = 1,
        .attach                 = ti_startup,
-       .shutdown               = ti_shutdown,
+       .release                = ti_release,
        .open                   = ti_open,
        .close                  = ti_close,
        .write                  = ti_write,
@@ -294,7 +262,7 @@ static struct usb_serial_driver ti_2port_device = {
        .id_table               = ti_id_table_5052,
        .num_ports              = 2,
        .attach                 = ti_startup,
-       .shutdown               = ti_shutdown,
+       .release                = ti_release,
        .open                   = ti_open,
        .close                  = ti_close,
        .write                  = ti_write,
@@ -322,14 +290,15 @@ MODULE_LICENSE("GPL");
 
 MODULE_FIRMWARE("ti_3410.fw");
 MODULE_FIRMWARE("ti_5052.fw");
+MODULE_FIRMWARE("mts_cdma.fw");
+MODULE_FIRMWARE("mts_gsm.fw");
+MODULE_FIRMWARE("mts_edge.fw");
+MODULE_FIRMWARE("mts_mt9234mu.fw");
+MODULE_FIRMWARE("mts_mt9234zba.fw");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
 
-module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency,
-               "TTY low_latency flag, 0=off, 1=on, default is off");
-
 module_param(closing_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(closing_wait,
     "Maximum wait for data to drain in close, in .01 secs, default is 4000");
@@ -354,21 +323,28 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
 
 static int __init ti_init(void)
 {
-       int i, j;
+       int i, j, c;
        int ret;
 
        /* insert extra vendor and product ids */
+       c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1;
        j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
-       for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) {
+       for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++, c++) {
                ti_id_table_3410[j].idVendor = vendor_3410[i];
                ti_id_table_3410[j].idProduct = product_3410[i];
                ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+               ti_id_table_combined[c].idVendor = vendor_3410[i];
+               ti_id_table_combined[c].idProduct = product_3410[i];
+               ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
        }
        j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
-       for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) {
+       for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++, c++) {
                ti_id_table_5052[j].idVendor = vendor_5052[i];
                ti_id_table_5052[j].idProduct = product_5052[i];
                ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+               ti_id_table_combined[c].idVendor = vendor_5052[i];
+               ti_id_table_combined[c].idProduct = product_5052[i];
+               ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
        }
 
        ret = usb_serial_register(&ti_1port_device);
@@ -382,7 +358,8 @@ static int __init ti_init(void)
        if (ret)
                goto failed_usb;
 
-       info(TI_DRIVER_DESC " " TI_DRIVER_VERSION);
+       printk(KERN_INFO KBUILD_MODNAME ": " TI_DRIVER_VERSION ":"
+              TI_DRIVER_DESC "\n");
 
        return 0;
 
@@ -439,11 +416,7 @@ static int ti_startup(struct usb_serial *serial)
 
        /* if we have only 1 configuration, download firmware */
        if (dev->descriptor.bNumConfigurations == 1) {
-               if (tdev->td_is_3410)
-                       status = ti_download_firmware(tdev, 3410);
-               else
-                       status = ti_download_firmware(tdev, 5052);
-               if (status)
+               if ((status = ti_download_firmware(tdev)) != 0)
                        goto free_tdev;
 
                /* 3410 must be reset, 5052 resets itself */
@@ -456,9 +429,10 @@ static int ti_startup(struct usb_serial *serial)
                goto free_tdev;
        }
 
-       /* the second configuration must be set (in sysfs by hotplug script) */
+       /* the second configuration must be set */
        if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) {
-               status = -ENODEV;
+               status = usb_driver_set_configuration(dev, TI_ACTIVE_CONFIG);
+               status = status ? status : -ENODEV;
                goto free_tdev;
        }
 
@@ -473,7 +447,6 @@ static int ti_startup(struct usb_serial *serial)
                spin_lock_init(&tport->tp_lock);
                tport->tp_uart_base_addr = (i == 0 ?
                                TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
-               tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
                tport->tp_closing_wait = closing_wait;
                init_waitqueue_head(&tport->tp_msr_wait);
                init_waitqueue_head(&tport->tp_write_wait);
@@ -506,7 +479,7 @@ free_tdev:
 }
 
 
-static void ti_shutdown(struct usb_serial *serial)
+static void ti_release(struct usb_serial *serial)
 {
        int i;
        struct ti_device *tdev = usb_get_serial_data(serial);
@@ -519,17 +492,14 @@ static void ti_shutdown(struct usb_serial *serial)
                if (tport) {
                        ti_buf_free(tport->tp_write_buf);
                        kfree(tport);
-                       usb_set_serial_port_data(serial->port[i], NULL);
                }
        }
 
        kfree(tdev);
-       usb_set_serial_data(serial, NULL);
 }
 
 
-static int ti_open(struct tty_struct *tty,
-                       struct usb_serial_port *port, struct file *file)
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        struct ti_port *tport = usb_get_serial_port_data(port);
        struct ti_device *tdev;
@@ -553,10 +523,6 @@ static int ti_open(struct tty_struct *tty,
        if (mutex_lock_interruptible(&tdev->td_open_close_lock))
                return -ERESTARTSYS;
 
-       if (tty)
-               tty->low_latency =
-                               (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
        port_number = port->number - port->serial->minor;
 
        memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount));
@@ -683,8 +649,7 @@ release_lock:
 }
 
 
-static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
-                                                       struct file *file)
+static void ti_close(struct usb_serial_port *port)
 {
        struct ti_device *tdev;
        struct ti_port *tport;
@@ -768,7 +733,7 @@ static int ti_write_room(struct tty_struct *tty)
        dbg("%s - port %d", __func__, port->number);
 
        if (tport == NULL)
-               return -ENODEV;
+               return 0;
 
        spin_lock_irqsave(&tport->tp_lock, flags);
        room = ti_buf_space_avail(tport->tp_write_buf);
@@ -789,7 +754,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
        dbg("%s - port %d", __func__, port->number);
 
        if (tport == NULL)
-               return -ENODEV;
+               return 0;
 
        spin_lock_irqsave(&tport->tp_lock, flags);
        chars = ti_buf_data_avail(tport->tp_write_buf);
@@ -1240,20 +1205,22 @@ static void ti_bulk_in_callback(struct urb *urb)
        }
 
        tty = tty_port_tty_get(&port->port);
-       if (tty && urb->actual_length) {
-               usb_serial_debug_data(debug, dev, __func__,
-                       urb->actual_length, urb->transfer_buffer);
-
-               if (!tport->tp_is_open)
-                       dbg("%s - port closed, dropping data", __func__);
-               else
-                       ti_recv(&urb->dev->dev, tty,
+       if (tty) {
+               if (urb->actual_length) {
+                       usb_serial_debug_data(debug, dev, __func__,
+                               urb->actual_length, urb->transfer_buffer);
+
+                       if (!tport->tp_is_open)
+                               dbg("%s - port closed, dropping data",
+                                       __func__);
+                       else
+                               ti_recv(&urb->dev->dev, tty,
                                                urb->transfer_buffer,
                                                urb->actual_length);
-
-               spin_lock(&tport->tp_lock);
-               tport->tp_icount.rx += urb->actual_length;
-               spin_unlock(&tport->tp_lock);
+                       spin_lock(&tport->tp_lock);
+                       tport->tp_icount.rx += urb->actual_length;
+                       spin_unlock(&tport->tp_lock);
+               }
                tty_kref_put(tty);
        }
 
@@ -1312,14 +1279,13 @@ static void ti_recv(struct device *dev, struct tty_struct *tty,
        int cnt;
 
        do {
-               cnt = tty_buffer_request_room(tty, length);
+               cnt = tty_insert_flip_string(tty, data, length);
                if (cnt < length) {
                        dev_err(dev, "%s - dropping data, %d bytes lost\n",
                                                __func__, length - cnt);
                        if (cnt == 0)
                                break;
                }
-               tty_insert_flip_string(tty, data, cnt);
                tty_flip_buffer_push(tty);
                data += cnt;
                length -= cnt;
@@ -1477,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
                return -EFAULT;
 
        tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
-       tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
        tport->tp_closing_wait = new_serial.closing_wait;
 
        return 0;
@@ -1697,7 +1662,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
        u8 cs = 0;
        int done;
        struct ti_firmware_header *header;
-       int status;
+       int status = 0;
        int len;
 
        for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
@@ -1719,9 +1684,9 @@ static int ti_do_download(struct usb_device *dev, int pipe,
        return status;
 }
 
-static int ti_download_firmware(struct ti_device *tdev, int type)
+static int ti_download_firmware(struct ti_device *tdev)
 {
-       int status = -ENOMEM;
+       int status;
        int buffer_size;
        __u8 *buffer;
        struct usb_device *dev = tdev->td_serial->dev;
@@ -1729,14 +1694,48 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
                tdev->td_serial->port[0]->bulk_out_endpointAddress);
        const struct firmware *fw_p;
        char buf[32];
-       sprintf(buf, "ti_usb-%d.bin", type);
 
-       if (request_firmware(&fw_p, buf, &dev->dev)) {
+       dbg("%s\n", __func__);
+       /* try ID specific firmware first, then try generic firmware */
+       sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
+           dev->descriptor.idProduct);
+       if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
+               buf[0] = '\0';
+               if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
+                       switch (dev->descriptor.idProduct) {
+                       case MTS_CDMA_PRODUCT_ID:
+                               strcpy(buf, "mts_cdma.fw");
+                               break;
+                       case MTS_GSM_PRODUCT_ID:
+                               strcpy(buf, "mts_gsm.fw");
+                               break;
+                       case MTS_EDGE_PRODUCT_ID:
+                               strcpy(buf, "mts_edge.fw");
+                               break;
+                       case MTS_MT9234MU_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234mu.fw");
+                               break;
+                       case MTS_MT9234ZBA_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;
+                       case MTS_MT9234ZBAOLD_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;                  }
+               }
+               if (buf[0] == '\0') {
+                       if (tdev->td_is_3410)
+                               strcpy(buf, "ti_3410.fw");
+                       else
+                               strcpy(buf, "ti_5052.fw");
+               }
+               status = request_firmware(&fw_p, buf, &dev->dev);
+       }
+       if (status) {
                dev_err(&dev->dev, "%s - firmware not found\n", __func__);
                return -ENOENT;
        }
        if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
-               dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+               dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
                return -ENOENT;
        }
 
@@ -1747,6 +1746,9 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
                memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
                status = ti_do_download(dev, pipe, buffer, fw_p->size);
                kfree(buffer);
+       } else {
+               dbg("%s ENOMEM\n", __func__);
+               status = -ENOMEM;
        }
        release_firmware(fw_p);
        if (status) {