Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / usb / serial / mct_u232.c
index b4961f0..f4d4305 100644 (file)
@@ -64,7 +64,6 @@
  *   (via linux-usb-devel).
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
 #include "mct_u232.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.2"
+#define DRIVER_VERSION "z2.0"          /* Linux in-kernel version */
 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
 
-/*
- * Some not properly written applications do not handle the return code of
- * write() correctly. This can result in character losses. A work-a-round
- * can be compiled in with the following definition. This work-a-round
- * should _NOT_ be part of an 'official' kernel release, of course!
- */
-#undef FIX_WRITE_RETURN_CODE_PROBLEM
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int write_blocking; /* disabled by default */
-#endif
-
 static int debug;
 
 /*
@@ -108,13 +96,6 @@ static int  mct_u232_open            (struct usb_serial_port *port,
                                          struct file *filp);
 static void mct_u232_close              (struct usb_serial_port *port,
                                          struct file *filp);
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-static int  mct_u232_write              (struct usb_serial_port *port,
-                                         int from_user,
-                                         const unsigned char *buf,
-                                         int count);
-static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-#endif
 static void mct_u232_read_int_callback   (struct urb *urb, struct pt_regs *regs);
 static void mct_u232_set_termios         (struct usb_serial_port *port,
                                          struct termios * old);
@@ -143,17 +124,19 @@ static struct usb_device_id id_table_combined [] = {
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
-       .owner =        THIS_MODULE,
        .name =         "mct_u232",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
+       .no_dynamic_id =        1,
 };
 
-static struct usb_serial_device_type mct_u232_device = {
-       .owner =             THIS_MODULE,
-       .name =              "Magic Control Technology USB-RS232",
-       .short_name =        "mct_u232",
+static struct usb_serial_driver mct_u232_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "mct_u232",
+       },
+       .description =       "MCT U232",
        .id_table =          id_table_combined,
        .num_interrupt_in =  2,
        .num_bulk_in =       0,
@@ -161,10 +144,6 @@ static struct usb_serial_device_type mct_u232_device = {
        .num_ports =         1,
        .open =              mct_u232_open,
        .close =             mct_u232_close,
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-       .write =             mct_u232_write,
-       .write_bulk_callback = mct_u232_write_bulk_callback,
-#endif
        .read_int_callback = mct_u232_read_int_callback,
        .ioctl =             mct_u232_ioctl,
        .set_termios =       mct_u232_set_termios,
@@ -188,16 +167,17 @@ struct mct_u232_private {
  * Handle vendor specific USB requests
  */
 
-#define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
+#define WDR_TIMEOUT 5000 /* default urb timeout */
 
 /*
  * Later day 2.6.0-test kernels have new baud rates like B230400 which
  * we do not know how to support. We ignore them for the moment.
  * XXX Rate-limit the error message, it's user triggerable.
  */
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
-       if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
-         || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
+{
+       if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
+         || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
                switch (value) {
                case    B300: return 0x01;
                case    B600: return 0x02; /* this one not tested */
@@ -216,16 +196,16 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
                }
        } else {
                switch (value) {
-               case    B300: value =     300;
-               case    B600: value =     600;
-               case   B1200: value =    1200;
-               case   B2400: value =    2400;
-               case   B4800: value =    4800;
-               case   B9600: value =    9600;
-               case  B19200: value =   19200;
-               case  B38400: value =   38400;
-               case  B57600: value =   57600;
-               case B115200: value =  115200;
+               case    B300: value =     300; break;
+               case    B600: value =     600; break;
+               case   B1200: value =    1200; break;
+               case   B2400: value =    2400; break;
+               case   B4800: value =    4800; break;
+               case   B9600: value =    9600; break;
+               case  B19200: value =   19200; break;
+               case  B38400: value =   38400; break;
+               case  B57600: value =   57600; break;
+               case B115200: value =  115200; break;
                default:
                        err("MCT USB-RS232: unsupported baudrate request 0x%x,"
                            " using default of B9600", value);
@@ -237,7 +217,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
 
 static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
 {
-       unsigned int divisor;
+       __le32 divisor;
         int rc;
         unsigned char zero_byte = 0;
 
@@ -367,15 +347,10 @@ static int mct_u232_startup (struct usb_serial *serial)
        struct mct_u232_private *priv;
        struct usb_serial_port *port, *rport;
 
-       /* allocate the private data structure */
-       priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
+       priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
-       /* set initial values for control structures */
        spin_lock_init(&priv->lock);
-       priv->control_state = 0;
-       priv->last_lsr = 0;
-       priv->last_msr = 0;
        usb_set_serial_port_data(serial->port[0], priv);
 
        init_waitqueue_head(&serial->port[0]->write_wait);
@@ -405,8 +380,10 @@ static void mct_u232_shutdown (struct usb_serial *serial)
        for (i=0; i < serial->num_ports; ++i) {
                /* My special items, the standard routines free my urbs */
                priv = usb_get_serial_port_data(serial->port[i]);
-               if (priv)
+               if (priv) {
+                       usb_set_serial_port_data(serial->port[i], NULL);
                        kfree(priv);
+               }
        }
 } /* mct_u232_shutdown */
 
@@ -427,7 +404,7 @@ static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
         * it seems to be able to accept only 16 bytes (and that's what
         * SniffUSB says too...)
         */
-       if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID)
+       if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
                port->bulk_out_size = 16;
 
        /* Do a defined restart: the normal serial device seems to 
@@ -460,14 +437,16 @@ static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
        port->read_urb->dev = port->serial->dev;
        retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (retval) {
-               err("usb_submit_urb(read bulk) failed");
+               err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
+                   port->read_urb->pipe, retval);
                goto exit;
        }
 
        port->interrupt_in_urb->dev = port->serial->dev;
        retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
        if (retval)
-               err(" usb_submit_urb(read int) failed");
+               err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
+                   port->interrupt_in_urb->pipe, retval);
 
 exit:
        return 0;
@@ -480,119 +459,13 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 
        if (port->serial->dev) {
                /* shutdown our urbs */
-               usb_unlink_urb (port->write_urb);
-               usb_unlink_urb (port->read_urb);
-               usb_unlink_urb (port->interrupt_in_urb);
+               usb_kill_urb(port->write_urb);
+               usb_kill_urb(port->read_urb);
+               usb_kill_urb(port->interrupt_in_urb);
        }
 } /* mct_u232_close */
 
 
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-/* The generic routines work fine otherwise */
-
-static int mct_u232_write (struct usb_serial_port *port, int from_user,
-                          const unsigned char *buf, int count)
-{
-       struct usb_serial *serial = port->serial;
-       int result, bytes_sent, size;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if (count == 0) {
-               dbg("%s - write request of 0 bytes", __FUNCTION__);
-               return (0);
-       }
-
-       /* only do something if we have a bulk out endpoint */
-       if (!serial->num_bulk_out)
-               return(0);
-       
-       /* another write is still pending? */
-       if (port->write_urb->status == -EINPROGRESS) {
-               dbg("%s - already writing", __FUNCTION__);
-               return (0);
-       }
-               
-       bytes_sent = 0;
-       while (count > 0) {
-               size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-               
-               usb_serial_debug_data(debug, &port->dev, __FUNCTION__, size, buf);
-               
-               if (from_user) {
-                       if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) {
-                               return -EFAULT;
-                       }
-               }
-               else {
-                       memcpy (port->write_urb->transfer_buffer, buf, size);
-               }
-               
-               /* set up our urb */
-               usb_fill_bulk_urb(port->write_urb, serial->dev,
-                             usb_sndbulkpipe(serial->dev,
-                                             port->bulk_out_endpointAddress),
-                             port->write_urb->transfer_buffer, size,
-                             ((serial->type->write_bulk_callback) ?
-                              serial->type->write_bulk_callback :
-                              mct_u232_write_bulk_callback),
-                             port);
-               
-               /* send the data out the bulk port */
-               result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-               if (result) {
-                       err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
-                       return result;
-               }
-
-               bytes_sent += size;
-               if (write_blocking)
-                       interruptible_sleep_on(&port->write_wait);
-               else
-                       break;
-
-               buf += size;
-               count -= size;
-       }
-       
-       return bytes_sent;
-} /* mct_u232_write */
-
-static void mct_u232_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 = port->serial;
-               struct tty_struct *tty = port->tty;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       if (!serial) {
-               dbg("%s - bad serial pointer, exiting", __FUNCTION__);
-               return;
-       }
-
-       if (urb->status) {
-               dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
-                   urb->status);
-               return;
-       }
-
-       if (write_blocking) {
-               wake_up_interruptible(&port->write_wait);
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                   tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup)(tty);
-               wake_up_interruptible(&tty->write_wait);
-               
-       } else {
-               /* from generic_write_bulk_callback */
-               schedule_work(&port->work);
-       }
-
-       return;
-} /* mct_u232_write_bulk_callback */
-#endif
-
 static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -603,8 +476,6 @@ static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
        int status;
        unsigned long flags;
 
-        dbg("%s - port %d", __FUNCTION__, port->number);
-
        switch (urb->status) {
        case 0:
                /* success */
@@ -624,7 +495,8 @@ static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
                dbg("%s - bad serial pointer, exiting", __FUNCTION__);
                return;
        }
-       
+
+        dbg("%s - port %d", __FUNCTION__, port->number);
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
 
        /*
@@ -774,7 +646,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
        else
                new_state &= ~(TIOCM_DTR | TIOCM_RTS);
        if (new_state != control_state) {
-               mct_u232_set_modem_ctrl(serial, control_state);
+               mct_u232_set_modem_ctrl(serial, new_state);
                control_state = new_state;
        }
 
@@ -905,12 +777,5 @@ MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_LICENSE("GPL");
 
-#ifdef FIX_WRITE_RETURN_CODE_PROBLEM
-module_param(write_blocking, int, 0);
-MODULE_PARM_DESC(write_blocking, 
-                "The write function will block to write out all data");
-#endif
-
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-