Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / usb / serial / pl2303.c
index 7eab5d4..c96714b 100644 (file)
@@ -8,31 +8,10 @@
  *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
+ *     the Free Software Foundation; either version 2 of the License.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
- * 2002_Mar_26 gkh
- *     allowed driver to work properly if there is no tty assigned to a port
- *     (this happens for serial console devices.)
- *
- * 2001_Oct_06 gkh
- *     Added RTS and DTR line control.  Thanks to joe@bndlg.de for parts of it.
- *
- * 2001_Sep_19 gkh
- *     Added break support.
- *
- * 2001_Aug_30 gkh
- *     fixed oops in write_bulk_callback.
- *
- * 2001_Aug_28 gkh
- *     reworked buffer logic to be like other usb-serial drivers.  Hopefully
- *     removing some reported problems.
- *
- * 2001_Jun_06 gkh
- *     finished porting to 2.4 format.
- * 
  */
 
 #include <linux/config.h>
@@ -55,7 +34,6 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.12"
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 static int debug;
@@ -65,8 +43,6 @@ static int debug;
 #define PL2303_BUF_SIZE                1024
 #define PL2303_TMP_BUF_SIZE    1024
 
-static DECLARE_MUTEX(pl2303_tmp_buf_sem);
-
 struct pl2303_buf {
        unsigned int    buf_size;
        char            *buf_buf;
@@ -85,6 +61,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },
        { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
+       { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
        { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
        { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
        { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
@@ -93,19 +70,27 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
        { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
        { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
+       { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
+       { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
+       { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
+       { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
+       { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
+       { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver pl2303_driver = {
-       .owner =        THIS_MODULE,
        .name =         "pl2303",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 #define SET_LINE_REQUEST_TYPE          0x21
@@ -174,9 +159,11 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
 
 
 /* All of the device info needed for the PL2303 SIO serial converter */
-static struct usb_serial_device_type pl2303_device = {
-       .owner =                THIS_MODULE,
-       .name =                 "PL-2303",
+static struct usb_serial_driver pl2303_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "pl2303",
+       },
        .id_table =             id_table,
        .num_interrupt_in =     NUM_DONT_CARE,
        .num_bulk_in =          1,
@@ -234,10 +221,9 @@ static int pl2303_startup (struct usb_serial *serial)
        dbg("device type: %d", type);
 
        for (i = 0; i < serial->num_ports; ++i) {
-               priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL);
+               priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
                if (!priv)
                        goto cleanup;
-               memset (priv, 0x00, sizeof (struct pl2303_private));
                spin_lock_init(&priv->lock);
                priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE);
                if (priv->buf == NULL) {
@@ -399,12 +385,11 @@ static void pl2303_set_termios (struct usb_serial_port *port, struct termios *ol
                }
        }
 
-       buf = kmalloc (7, GFP_KERNEL);
+       buf = kzalloc (7, GFP_KERNEL);
        if (!buf) {
                dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__);
                return;
        }
-       memset (buf, 0x00, 0x07);
        
        i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
                             GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
@@ -538,8 +523,10 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s -  port %d", __FUNCTION__, port->number);
 
-       usb_clear_halt(serial->dev, port->write_urb->pipe);
-       usb_clear_halt(serial->dev, port->read_urb->pipe);
+       if (priv->type != HX) {
+               usb_clear_halt(serial->dev, port->write_urb->pipe);
+               usb_clear_halt(serial->dev, port->read_urb->pipe);
+       }
 
        buf = kmalloc(10, GFP_KERNEL);
        if (buf==NULL)
@@ -650,8 +637,7 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
                timeout = max((HZ*2560)/bps,HZ/10);
        else
                timeout = 2*HZ;
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule_timeout(timeout);
+       schedule_timeout_interruptible(timeout);
 
        /* shutdown our urbs */
        dbg("%s - shutting down urbs", __FUNCTION__);
@@ -826,10 +812,12 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        u8 status_idx = UART_STATE;
-       u8 length = UART_STATE;
+       u8 length = UART_STATE + 1;
 
        if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
-           (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65)) {
+           (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 ||
+            le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_SX1 ||
+            le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X75)) {
                length = 1;
                status_idx = 0;
        }
@@ -841,6 +829,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        spin_lock_irqsave(&priv->lock, flags);
        priv->line_status = data[status_idx];
        spin_unlock_irqrestore(&priv->lock, flags);
+       wake_up_interruptible (&priv->delta_msr_wait);
 
 exit:
        return;
@@ -938,16 +927,12 @@ static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
+               tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
                if (status & UART_OVERRUN_ERROR)
                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-
-               for (i = 0; i < urb->actual_length; ++i) {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
+               for (i = 0; i < urb->actual_length; ++i)
                        tty_insert_flip_char (tty, data[i], tty_flag);
-               }
                tty_flip_buffer_push (tty);
        }
 
@@ -1193,7 +1178,7 @@ static int __init pl2303_init (void)
        retval = usb_register(&pl2303_driver);
        if (retval)
                goto failed_usb_register;
-       info(DRIVER_DESC " " DRIVER_VERSION);
+       info(DRIVER_DESC);
        return 0;
 failed_usb_register:
        usb_serial_deregister(&pl2303_device);
@@ -1213,7 +1198,6 @@ module_init(pl2303_init);
 module_exit(pl2303_exit);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);