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 / keyspan_pda.c
index 36d8e6a..b0441c3 100644 (file)
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
-#ifdef CONFIG_USB_SERIAL_DEBUG
-       static int debug = 1;
-#else
-       static int debug;
-#endif
-
+static int debug;
 
 struct ezusb_hex_record {
        __u16 address;
@@ -155,11 +150,11 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
-       .owner =        THIS_MODULE,
        .name =         "keyspan_pda",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
 static struct usb_device_id id_table_std [] = {
@@ -191,13 +186,7 @@ static void keyspan_pda_wakeup_write( struct usb_serial_port *port )
        wake_up_interruptible( &port->write_wait );
 
        /* wake up line discipline */
-       if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-       && tty->ldisc.write_wakeup )
-               (tty->ldisc.write_wakeup)(tty);
-
-       /* wake up other tty processes */
-       wake_up_interruptible( &tty->write_wait );
-       /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */
+       tty_wakeup(tty);
 }
 
 static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
@@ -216,7 +205,7 @@ static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
                                 0, /* index */
                                 NULL,
                                 0,
-                                2*HZ);
+                                2000);
        if (result < 0)
                dbg("%s - error %d from usb_control_msg", 
                    __FUNCTION__, result);
@@ -226,8 +215,7 @@ static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
 static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-       struct usb_serial *serial;
-               struct tty_struct *tty;
+               struct tty_struct *tty = port->tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
        int status;
@@ -249,22 +237,11 @@ static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       
-       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
-               return;
-       }
-
-       serial = port->serial;
-       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
-               return;
-       }
-       
        /* see if the message is data or a status interrupt */
        switch (data[0]) {
        case 0:
                /* rest of message is rx data */
                if (urb->actual_length) {
-                       tty = serial->port[0]->tty;
                        for (i = 1; i < urb->actual_length ; ++i) {
                                tty_insert_flip_char(tty, data[i], 0);
                        }
@@ -278,7 +255,6 @@ static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs)
                case 1: /* modemline change */
                        break;
                case 2: /* tx unthrottle interrupt */
-                       tty = serial->port[0]->tty;
                        priv->tx_throttled = 0;
                        /* queue up a wakeup at scheduler time */
                        schedule_work(&priv->wakeup_work);
@@ -309,7 +285,7 @@ static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
           upon the device too. */
 
        dbg("keyspan_pda_rx_throttle port %d", port->number);
-       usb_unlink_urb(port->interrupt_in_urb);
+       usb_kill_urb(port->interrupt_in_urb);
 }
 
 
@@ -354,7 +330,7 @@ static int keyspan_pda_setbaud (struct usb_serial *serial, int baud)
                             0, /* index */
                             NULL, /* &data */
                             0, /* size */
-                            2*HZ); /* timeout */
+                            2000); /* timeout */
        return(rc);
 }
 
@@ -372,7 +348,7 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
        result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                4, /* set break */
                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                               value, 0, NULL, 0, 2*HZ);
+                               value, 0, NULL, 0, 2000);
        if (result < 0)
                dbg("%s - error %d from usb_control_msg", 
                    __FUNCTION__, result);
@@ -440,7 +416,7 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,
        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                             3, /* get pins */
                             USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
-                            0, 0, &data, 1, 2*HZ);
+                            0, 0, &data, 1, 2000);
        if (rc > 0)
                *value = data;
        return rc;
@@ -454,7 +430,7 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial,
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                             3, /* set pins */
                             USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT,
-                            value, 0, NULL, 0, 2*HZ);
+                            value, 0, NULL, 0, 2000);
        return rc;
 }
 
@@ -517,7 +493,7 @@ static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
        return -ENOIOCTLCMD;
 }
 
-static int keyspan_pda_write(struct usb_serial_port *port, int from_user, 
+static int keyspan_pda_write(struct usb_serial_port *port, 
                             const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
@@ -544,9 +520,13 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user,
           the TX urb is in-flight (wait until it completes)
           the device is full (wait until it says there is room)
        */
-       if (port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) {
-               return( 0 );
+       spin_lock(&port->lock);
+       if (port->write_urb_busy || priv->tx_throttled) {
+               spin_unlock(&port->lock);
+               return 0;
        }
+       port->write_urb_busy = 1;
+       spin_unlock(&port->lock);
 
        /* At this point the URB is in our control, nobody else can submit it
           again (the only sudden transition was the one from EINPROGRESS to
@@ -569,7 +549,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user,
                                     0, /* index */
                                     &room,
                                     1,
-                                    2*HZ);
+                                    2000);
                if (rc < 0) {
                        dbg(" roomquery failed");
                        goto exit;
@@ -591,19 +571,10 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user,
 
        if (count) {
                /* now transfer data */
-               if (from_user) {
-                       if( copy_from_user(port->write_urb->transfer_buffer,
-                       buf, count) ) {
-                               rc = -EFAULT;
-                               goto exit;
-                       }
-               }
-               else {
-                       memcpy (port->write_urb->transfer_buffer, buf, count);
-               }  
+               memcpy (port->write_urb->transfer_buffer, buf, count);
                /* send the data out the bulk port */
                port->write_urb->transfer_buffer_length = count;
-               
+
                priv->tx_room -= count;
 
                port->write_urb->dev = port->serial->dev;
@@ -626,6 +597,8 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user,
 
        rc = count;
 exit:
+       if (rc < 0)
+               port->write_urb_busy = 0;
        return rc;
 }
 
@@ -633,20 +606,11 @@ exit:
 static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-       struct usb_serial *serial;
        struct keyspan_pda_private *priv;
 
+       port->write_urb_busy = 0;
        priv = usb_get_serial_port_data(port);
 
-       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
-               return;
-       }
-
-       serial = port->serial;
-       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
-               return;
-       }
-       
        /* queue up a wakeup at scheduler time */
        schedule_work(&priv->wakeup_work);
 }
@@ -669,12 +633,12 @@ static int keyspan_pda_write_room (struct usb_serial_port *port)
 static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
 {
        struct keyspan_pda_private *priv;
-       
+
        priv = usb_get_serial_port_data(port);
-       
+
        /* when throttled, return at least WAKEUP_CHARS to tell select() (via
           n_tty.c:normal_poll() ) that we're not writeable. */
-       if( port->write_urb->status == -EINPROGRESS || priv->tx_throttled )
+       if (port->write_urb_busy || priv->tx_throttled)
                return 256;
        return 0;
 }
@@ -696,7 +660,7 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
                             0, /* index */
                             &room,
                             1,
-                            2*HZ);
+                            2000);
        if (rc < 0) {
                dbg("%s - roomquery failed", __FUNCTION__);
                goto error;
@@ -740,8 +704,8 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
                        keyspan_pda_set_modem_info(serial, 0);
 
                /* shutdown our bulk reads and writes */
-               usb_unlink_urb (port->write_urb);
-               usb_unlink_urb (port->interrupt_in_urb);
+               usb_kill_urb(port->write_urb);
+               usb_kill_urb(port->interrupt_in_urb);
        }
 }
 
@@ -756,12 +720,12 @@ static int keyspan_pda_fake_startup (struct usb_serial *serial)
        response = ezusb_set_reset(serial, 1);
 
 #ifdef KEYSPAN
-       if (serial->dev->descriptor.idVendor == KEYSPAN_VENDOR_ID)
+       if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
                record = &keyspan_pda_firmware[0];
 #endif
 #ifdef XIRCOM
-       if ((serial->dev->descriptor.idVendor == XIRCOM_VENDOR_ID) ||
-           (serial->dev->descriptor.idVendor == ENTREGRA_VENDOR_ID))
+       if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
+           (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
                record = &xircom_pgs_firmware[0];
 #endif
        if (record == NULL) {
@@ -804,7 +768,7 @@ static int keyspan_pda_startup (struct usb_serial *serial)
        usb_set_serial_port_data(serial->port[0], priv);
        init_waitqueue_head(&serial->port[0]->write_wait);
        INIT_WORK(&priv->wakeup_work, (void *)keyspan_pda_wakeup_write,
-                       (void *)(&serial->port[0]));
+                       (void *)(serial->port[0]));
        INIT_WORK(&priv->unthrottle_work,
                        (void *)keyspan_pda_request_unthrottle,
                        (void *)(serial));
@@ -819,10 +783,12 @@ static void keyspan_pda_shutdown (struct usb_serial *serial)
 }
 
 #ifdef KEYSPAN
-static struct usb_serial_device_type keyspan_pda_fake_device = {
-       .owner =                THIS_MODULE,
-       .name =                 "Keyspan PDA - (prerenumeration)",
-       .short_name =           "keyspan_pda_pre",
+static struct usb_serial_driver keyspan_pda_fake_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "keyspan_pda_pre",
+       },
+       .description =          "Keyspan PDA - (prerenumeration)",
        .id_table =             id_table_fake,
        .num_interrupt_in =     NUM_DONT_CARE,
        .num_bulk_in =          NUM_DONT_CARE,
@@ -833,10 +799,12 @@ static struct usb_serial_device_type keyspan_pda_fake_device = {
 #endif
 
 #ifdef XIRCOM
-static struct usb_serial_device_type xircom_pgs_fake_device = {
-       .owner =                THIS_MODULE,
-       .name =                 "Xircom / Entregra PGS - (prerenumeration)",
-       .short_name =           "xircom_no_firm",
+static struct usb_serial_driver xircom_pgs_fake_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "xircom_no_firm",
+       },
+       .description =          "Xircom / Entregra PGS - (prerenumeration)",
        .id_table =             id_table_fake_xircom,
        .num_interrupt_in =     NUM_DONT_CARE,
        .num_bulk_in =          NUM_DONT_CARE,
@@ -846,10 +814,12 @@ static struct usb_serial_device_type xircom_pgs_fake_device = {
 };
 #endif
 
-static struct usb_serial_device_type keyspan_pda_device = {
-       .owner =                THIS_MODULE,
-       .name =                 "Keyspan PDA",
-       .short_name =           "keyspan_pda",
+static struct usb_serial_driver keyspan_pda_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "keyspan_pda",
+       },
+       .description =          "Keyspan PDA",
        .id_table =             id_table_std,
        .num_interrupt_in =     1,
        .num_bulk_in =          0,
@@ -932,6 +902,6 @@ MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");