vserver 1.9.5.x5
[linux-2.6.git] / drivers / usb / serial / mct_u232.c
index 212906c..a61fecf 100644 (file)
 /*
  * 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 +97,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);
@@ -152,7 +134,7 @@ static struct usb_driver mct_u232_driver = {
 
 static struct usb_serial_device_type mct_u232_device = {
        .owner =             THIS_MODULE,
-       .name =              "Magic Control Technology USB-RS232",
+       .name =              "MCT U232",
        .short_name =        "mct_u232",
        .id_table =          id_table_combined,
        .num_interrupt_in =  2,
@@ -161,10 +143,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,
@@ -195,9 +173,10 @@ struct mct_u232_private {
  * 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 */
@@ -237,7 +216,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 +346,11 @@ 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);
        if (!priv)
                return -ENOMEM;
-       /* set initial values for control structures */
+       memset(priv, 0, sizeof(struct mct_u232_private));
        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,115 +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);
-               tty_wakeup(tty);
-       } 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;
@@ -599,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 */
@@ -620,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);
 
        /*
@@ -901,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");
-