X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fusb%2Fserial%2Fmct_u232.c;h=5fc2cef30e39f76603421616b3e4a06c9cebd586;hb=908cf4b925e419bc74f3297b2f0e51d6f8a81da2;hp=0dc99f75bb09d13ab67072e4703c81a80894eb21;hpb=6a84258e5f5bb8b9bd72e06a5837fa6fdacaf5c5;p=linux-2.6 diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 0dc99f75bb..5fc2cef30e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -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);