]> err.no Git - linux-2.6/blobdiff - drivers/usb/serial/mct_u232.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
[linux-2.6] / drivers / usb / serial / mct_u232.c
index 0dc99f75bb09d13ab67072e4703c81a80894eb21..5fc2cef30e39f76603421616b3e4a06c9cebd586 100644 (file)
@@ -143,9 +143,6 @@ static struct usb_serial_driver mct_u232_device = {
        .description =       "MCT U232",
        .usb_driver =        &mct_u232_driver,
        .id_table =          id_table_combined,
-       .num_interrupt_in =  2,
-       .num_bulk_in =       0,
-       .num_bulk_out =      1,
        .num_ports =         1,
        .open =              mct_u232_open,
        .close =             mct_u232_close,
@@ -182,10 +179,11 @@ struct mct_u232_private {
 /*
  * 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, speed_t value)
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result)
 {
+       *result = 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) {
@@ -200,11 +198,13 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value
                case  57600: return 0x0b;
                case 115200: return 0x0c;
                default:
-                       err("MCT USB-RS232: unsupported baudrate request 0x%x,"
-                           " using default of B9600", value);
+                       *result = 9600;
                        return 0x08;
                }
        } else {
+               /* FIXME: Can we use any divider - should we do
+                  divider = 115200/value;
+                  real baud = 115200/divider */
                switch (value) {
                case 300: break;
                case 600: break;
@@ -217,9 +217,8 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value
                case 57600: break;
                case 115200: break;
                default:
-                       err("MCT USB-RS232: unsupported baudrate request 0x%x,"
-                           " using default of B9600", value);
                        value = 9600;
+                       *result = 9600;
                }
                return 115200/value;
        }
@@ -232,16 +231,19 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_p
         int rc;
         unsigned char zero_byte = 0;
         unsigned char cts_enable_byte = 0;
+        speed_t speed;
 
-       divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
+       divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, &speed));
 
         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                              MCT_U232_SET_BAUD_RATE_REQUEST,
                             MCT_U232_SET_REQUEST_TYPE,
                              0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
                             WDR_TIMEOUT);
-       if (rc < 0)
+       if (rc < 0)     /*FIXME: What value speed results */
                err("Set BAUD RATE %d failed (error = %d)", value, rc);
+       else
+               tty_encode_baud_rate(port->tty, speed, speed);
        dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
 
        /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
@@ -397,7 +399,7 @@ static void mct_u232_shutdown (struct usb_serial *serial)
        struct mct_u232_private *priv;
        int i;
        
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        for (i=0; i < serial->num_ports; ++i) {
                /* My special items, the standard routines free my urbs */
@@ -419,7 +421,7 @@ static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
        unsigned char last_lcr;
        unsigned char last_msr;
 
-       dbg("%s port %d", __FUNCTION__, port->number);
+       dbg("%s port %d", __func__, port->number);
 
        /* Compensate for a hardware bug: although the Sitecom U232-P25
         * device reports a maximum output packet size of 32 bytes,
@@ -482,21 +484,22 @@ error:
 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 {
        unsigned int c_cflag;
-       unsigned long flags;
        unsigned int control_state;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
-       dbg("%s port %d", __FUNCTION__, port->number);
+       dbg("%s port %d", __func__, port->number);
 
        if (port->tty) {
                c_cflag = port->tty->termios->c_cflag;
-               if (c_cflag & HUPCL) {
-                  /* drop DTR and RTS */
-                  spin_lock_irqsave(&priv->lock, flags);
-                  priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-                  control_state = priv->control_state;
-                  spin_unlock_irqrestore(&priv->lock, flags);
-                  mct_u232_set_modem_ctrl(port->serial, control_state);
+               mutex_lock(&port->serial->disc_mutex);
+               if (c_cflag & HUPCL && !port->serial->disconnected) {
+                       /* drop DTR and RTS */
+                       spin_lock_irq(&priv->lock);
+                       priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+                       control_state = priv->control_state;
+                       spin_unlock_irq(&priv->lock);
+                       mct_u232_set_modem_ctrl(port->serial, control_state);
                }
+               mutex_unlock(&port->serial->disc_mutex);
        }
 
 
@@ -511,7 +514,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 
 static void mct_u232_read_int_callback (struct urb *urb)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial_port *port = urb->context;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
        struct tty_struct *tty;
@@ -529,21 +532,21 @@ static void mct_u232_read_int_callback (struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, status);
+                   __func__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, status);
+                   __func__, status);
                goto exit;
        }
 
        if (!serial) {
-               dbg("%s - bad serial pointer, exiting", __FUNCTION__);
+               dbg("%s - bad serial pointer, exiting", __func__);
                return;
        }
 
-        dbg("%s - port %d", __FUNCTION__, port->number);
-       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+        dbg("%s - port %d", __func__, port->number);
+       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
 
        /*
         * Work-a-round: handle the 'usual' bulk-in pipe here
@@ -600,7 +603,7 @@ exit:
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, retval);
+                    __func__, retval);
 } /* mct_u232_read_int_callback */
 
 static void mct_u232_set_termios (struct usb_serial_port *port,
@@ -608,7 +611,8 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
 {
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
-       unsigned int cflag = port->tty->termios->c_cflag;
+       struct ktermios *termios = port->tty->termios;
+       unsigned int cflag = termios->c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned long flags;
        unsigned int control_state;
@@ -629,7 +633,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
 
         /* reassert DTR and RTS on transition from B0 */
        if ((old_cflag & CBAUD) == B0) {
-               dbg("%s: baud was B0", __FUNCTION__);
+               dbg("%s: baud was B0", __func__);
                control_state |= TIOCM_DTR | TIOCM_RTS;
                mct_u232_set_modem_ctrl(serial, control_state);
        }
@@ -637,7 +641,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
        mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty));
 
        if ((cflag & CBAUD) == B0 ) {
-               dbg("%s: baud is B0", __FUNCTION__);
+               dbg("%s: baud is B0", __func__);
                /* Drop RTS and DTR */
                control_state &= ~(TIOCM_DTR | TIOCM_RTS);
                        mct_u232_set_modem_ctrl(serial, control_state);
@@ -670,6 +674,8 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
                break;
        }
 
+       termios->c_cflag &= ~CMSPAR;
+
        /* set the number of stop bits */
        last_lcr |= (cflag & CSTOPB) ?
                MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
@@ -690,7 +696,7 @@ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
        unsigned char lcr;
        unsigned long flags;
 
-       dbg("%sstate=%d", __FUNCTION__, break_state);
+       dbg("%sstate=%d", __func__, break_state);
 
        spin_lock_irqsave(&priv->lock, flags);
        lcr = priv->last_lcr;
@@ -709,7 +715,7 @@ static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
        unsigned int control_state;
        unsigned long flags;
        
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
        control_state = priv->control_state;
@@ -726,7 +732,7 @@ static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
        unsigned int control_state;
        unsigned long flags;
        
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
        control_state = priv->control_state;
@@ -748,7 +754,7 @@ static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
 static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
                           unsigned int cmd, unsigned long arg)
 {
-       dbg("%scmd=0x%x", __FUNCTION__, cmd);
+       dbg("%scmd=0x%x", __func__, cmd);
 
        /* Based on code from acm.c and others */
        switch (cmd) {
@@ -763,7 +769,7 @@ static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
                return 0;
 
        default:
-               dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd);
+               dbg("%s: arg not supported - 0x%04x", __func__,cmd);
                return(-ENOIOCTLCMD);
                break;
        }
@@ -778,7 +784,7 @@ static void mct_u232_throttle (struct usb_serial_port *port)
        struct tty_struct *tty;
 
        tty = port->tty;
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->rx_flags |= THROTTLED;
@@ -800,7 +806,7 @@ static void mct_u232_unthrottle (struct usb_serial_port *port)
        unsigned int control_state;
        struct tty_struct *tty;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        tty = port->tty;
        spin_lock_irqsave(&priv->lock, flags);