CTC++ Coverage Report - Execution Profile    #750/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/usb/serial/belkin_sa.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/313)

Start/ End/    
True False - Line Source

  1 /*
  2  * Belkin USB Serial Adapter Driver
  3  *
  4  *  Copyright (C) 2000      William Greathouse (wgreathouse@smva.com)
  5  *  Copyright (C) 2000-2001    Greg Kroah-Hartman (greg@kroah.com)
  6  *
  7  *  This program is largely derived from work by the linux-usb group
  8  *  and associated source files.  Please see the usb/serial files for
  9  *  individual credits and copyrights.
  10  *  
  11  *    This program is free software; you can redistribute it and/or modify
  12  *    it under the terms of the GNU General Public License as published by
  13  *    the Free Software Foundation; either version 2 of the License, or
  14  *    (at your option) any later version.
  15  *
  16  * See Documentation/usb/usb-serial.txt for more information on using this driver
  17  *
  18  * TODO:
  19  * -- Add true modem contol line query capability.  Currently we track the
  20  *    states reported by the interrupt and the states we request.
  21  * -- Add error reporting back to application for UART error conditions.
  22  *    Just point me at how to implement this and I'll do it. I've put the
  23  *    framework in, but haven't analyzed the "tty_flip" interface yet.
  24  * -- Add support for flush commands
  25  * -- Add everything that is missing :)
  26  *
  27  * 27-Nov-2001 gkh
  28  *    compressed all the differnent device entries into 1.
  29  *
  30  * 30-May-2001 gkh
  31  *   switched from using spinlock to a semaphore, which fixes lots of problems.
  32  *
  33  * 08-Apr-2001 gb
  34  *   - Identify version on module load.
  35  *
  36  * 12-Mar-2001 gkh
  37  *   - Added support for the GoHubs GO-COM232 device which is the same as the
  38  *     Peracom device.
  39  *
  40  * 06-Nov-2000 gkh
  41  *   - Added support for the old Belkin and Peracom devices.
  42  *   - Made the port able to be opened multiple times.
  43  *   - Added some defaults incase the line settings are things these devices
  44  *     can't support. 
  45  *
  46  * 18-Oct-2000 William Greathouse
  47  *    Released into the wild (linux-usb-devel)
  48  *
  49  * 17-Oct-2000 William Greathouse
  50  *    Add code to recognize firmware version and set hardware flow control
  51  *    appropriately.  Belkin states that firmware prior to 3.05 does not
  52  *    operate correctly in hardware handshake mode.  I have verified this
  53  *    on firmware 2.05 -- for both RTS and DTR input flow control, the control
  54  *    line is not reset.  The test performed by the Belkin Win* driver is
  55  *    to enable hardware flow control for firmware 2.06 or greater and
  56  *    for 1.00 or prior.  I am only enabling for 2.06 or greater.
  57  *
  58  * 12-Oct-2000 William Greathouse
  59  *    First cut at supporting Belkin USB Serial Adapter F5U103
  60  *    I did not have a copy of the original work to support this
  61  *    adapter, so pardon any stupid mistakes.  All of the information
  62  *    I am using to write this driver was acquired by using a modified
  63  *    UsbSnoop on Windows2000 and from examining the other USB drivers.
  64  */
  65 
  66 #include <linux/config.h>
  67 #include <linux/kernel.h>
  68 #include <linux/errno.h>
  69 #include <linux/init.h>
  70 #include <linux/slab.h>
  71 #include <linux/tty.h>
  72 #include <linux/tty_driver.h>
  73 #include <linux/tty_flip.h>
  74 #include <linux/module.h>
  75 #include <linux/spinlock.h>
  76 #include <asm/uaccess.h>
  77 #include <linux/usb.h>
  78 #include "usb-serial.h"
  79 #include "belkin_sa.h"
  80 
  81 static int debug;
  82 
  83 /*
  84  * Version Information
  85  */
  86 #define DRIVER_VERSION "v1.2"
  87 #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
  88 #define DRIVER_DESC "USB Belkin Serial converter driver"
  89 
  90 /* function prototypes for a Belkin USB Serial Adapter F5U103 */
  91 static int  belkin_sa_startup      (struct usb_serial *serial);
  92 static void belkin_sa_shutdown      (struct usb_serial *serial);
  93 static int  belkin_sa_open      (struct usb_serial_port *port, struct file *filp);
  94 static void belkin_sa_close      (struct usb_serial_port *port, struct file *filp);
  95 static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs);
  96 static void belkin_sa_set_termios   (struct usb_serial_port *port, struct termios * old);
  97 static int  belkin_sa_ioctl      (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
  98 static void belkin_sa_break_ctl      (struct usb_serial_port *port, int break_state );
  99 static int  belkin_sa_tiocmget      (struct usb_serial_port *port, struct file *file);
  100 static int  belkin_sa_tiocmset      (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
  101 
  102 
  103 static struct usb_device_id id_table_combined [] = {
  104    { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
  105    { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
  106    { USB_DEVICE(PERACOM_VID, PERACOM_PID) },
  107    { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
  108    { USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
  109    { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
  110    { }                     /* Terminating entry */
  111 };
  112 
  113 MODULE_DEVICE_TABLE (usb, id_table_combined);
  114 
  115 static struct usb_driver belkin_driver = {
  116    .name =      "belkin",
  117    .probe =   usb_serial_probe,
  118    .disconnect =   usb_serial_disconnect,
  119    .id_table =   id_table_combined,
  120    .no_dynamic_id =    1,
  121 };
  122 
  123 /* All of the device info needed for the serial converters */
  124 static struct usb_serial_driver belkin_device = {
  125    .driver = {
  126       .owner =   THIS_MODULE,
  127       .name =      "belkin",
  128    },
  129    .description =      "Belkin / Peracom / GoHubs USB Serial Adapter",
  130    .id_table =      id_table_combined,
  131    .num_interrupt_in =   1,
  132    .num_bulk_in =      1,
  133    .num_bulk_out =      1,
  134    .num_ports =      1,
  135    .open =         belkin_sa_open,
  136    .close =      belkin_sa_close,
  137    .read_int_callback =   belkin_sa_read_int_callback,   /* How we get the status info */
  138    .ioctl =      belkin_sa_ioctl,
  139    .set_termios =      belkin_sa_set_termios,
  140    .break_ctl =      belkin_sa_break_ctl,
  141    .tiocmget =      belkin_sa_tiocmget,
  142    .tiocmset =      belkin_sa_tiocmset,
  143    .attach =      belkin_sa_startup,
  144    .shutdown =      belkin_sa_shutdown,
  145 };
  146 
  147 
  148 struct belkin_sa_private {
  149    spinlock_t      lock;
  150    unsigned long      control_state;
  151    unsigned char      last_lsr;
  152    unsigned char      last_msr;
  153    int         bad_flow_control;
  154 };
  155 
  156 
  157 /*
  158  * ***************************************************************************
  159  * Belkin USB Serial Adapter F5U103 specific driver functions
  160  * ***************************************************************************
  161  */
  162 
  163 #define WDR_TIMEOUT 5000 /* default urb timeout */
  164 
  165 /* assumes that struct usb_serial *serial is available */
  166 #define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
  167                    (c), BELKIN_SA_SET_REQUEST_TYPE, \
  168                    (v), 0, NULL, 0, WDR_TIMEOUT)
  169 
  170 /* do some startup allocations not currently performed by usb_serial_probe() */
 
- 171 static int belkin_sa_startup (struct usb_serial *serial)
  172 {
  173    struct usb_device *dev = serial->dev;
  174    struct belkin_sa_private *priv;
  175 
  176    /* allocate the private data structure */
  177    priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
- 178    if (!priv)
 - 179       return (-1); /* error */
  180    /* set initial values for control structures */
    181    spin_lock_init(&priv->lock);
- 181 do-while (0)
  182    priv->control_state = 0;
  183    priv->last_lsr = 0;
  184    priv->last_msr = 0;
  185    /* see comments at top of file */
    186    priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
- 186 ternary-?: ( ( ( __u16 ) ( __le16 ) ( dev -> d..
  187    info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
  188 
  189    init_waitqueue_head(&serial->port[0]->write_wait);
  190    usb_set_serial_port_data(serial->port[0], priv);
  191    
 - 192    return (0);
  193 }
  194 
  195 
 
- 196 static void belkin_sa_shutdown (struct usb_serial *serial)
  197 {
  198    struct belkin_sa_private *priv;
  199    int i;
  200    
    201    dbg ("%s", __FUNCTION__);
- 201   if (debug)
- 201 do-while (0)
  202 
  203    /* stop reads and writes on all ports */
- 204    for (i=0; i < serial->num_ports; ++i) {
  205       /* My special items, the standard routines free my urbs */
  206       priv = usb_get_serial_port_data(serial->port[i]);
  207       kfree(priv);
  208    }
  209 }
  210 
  211 
 
- 212 static int  belkin_sa_open (struct usb_serial_port *port, struct file *filp)
  213 {
  214    int retval = 0;
  215 
    216    dbg("%s port %d", __FUNCTION__, port->number);
- 216   if (debug)
- 216 do-while (0)
  217 
  218    /*Start reading from the device*/
  219    /* TODO: Look at possibility of submitting multiple URBs to device to
  220     *       enhance buffering.  Win trace shows 16 initial read URBs.
  221     */
  222    port->read_urb->dev = port->serial->dev;
  223    retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
- 224    if (retval) {
  225       err("usb_submit_urb(read bulk) failed");
 - 226       goto exit;
  227    }
  228 
  229    port->interrupt_in_urb->dev = port->serial->dev;
  230    retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
- 231    if (retval) {
  232       usb_kill_urb(port->read_urb);
  233       err(" usb_submit_urb(read int) failed");
  234    }
  235 
  236 exit:
 - 237    return retval;
  238 } /* belkin_sa_open */
  239 
  240 
 
- 241 static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
  242 {
    243    dbg("%s port %d", __FUNCTION__, port->number);
- 243   if (debug)
- 243 do-while (0)
  244 
  245    /* shutdown our bulk reads and writes */
  246    usb_kill_urb(port->write_urb);
  247    usb_kill_urb(port->read_urb);
  248    usb_kill_urb(port->interrupt_in_urb);
  249 } /* belkin_sa_close */
  250 
  251 
 
- 252 static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs)
  253 {
  254    struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
  255    struct belkin_sa_private *priv;
  256    unsigned char *data = urb->transfer_buffer;
  257    int retval;
  258    unsigned long flags;
  259 
    260    switch (urb->status) {
 - 261    case 0:
  262       /* success */
 - 263       break;
 - 264    case -ECONNRESET:
 - 265    case -ENOENT:
 - 266    case -ESHUTDOWN:
  267       /* this urb is terminated, clean up */
    268       dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- 268     if (debug)
- 268   do-while (0)
 - 269       return;
 - 270    default:
    271       dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- 271     if (debug)
- 271   do-while (0)
 - 272       goto exit;
  273    }
  274 
  275    usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
  276 
  277    /* Handle known interrupt data */
  278    /* ignore data[0] and data[1] */
  279 
  280    priv = usb_get_serial_port_data(port);
    281    spin_lock_irqsave(&priv->lock, flags);
    281   do
    281     do
- 281     do-while (0)
- 281   do-while (0)
    281   do
    281     do
- 281     do-while (0)
- 281   do-while (0)
- 281 do-while (0)
  282    priv->last_msr = data[BELKIN_SA_MSR_INDEX];
  283    
  284    /* Record Control Line states */
- 285    if (priv->last_msr & BELKIN_SA_MSR_DSR)
  286       priv->control_state |= TIOCM_DSR;
    287    else
  288       priv->control_state &= ~TIOCM_DSR;
  289 
- 290    if (priv->last_msr & BELKIN_SA_MSR_CTS)
  291       priv->control_state |= TIOCM_CTS;
    292    else
  293       priv->control_state &= ~TIOCM_CTS;
  294 
- 295    if (priv->last_msr & BELKIN_SA_MSR_RI)
  296       priv->control_state |= TIOCM_RI;
    297    else
  298       priv->control_state &= ~TIOCM_RI;
  299 
- 300    if (priv->last_msr & BELKIN_SA_MSR_CD)
  301       priv->control_state |= TIOCM_CD;
    302    else
  303       priv->control_state &= ~TIOCM_CD;
  304 
  305    /* Now to report any errors */
  306    priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
  307 #if 0
  308    /*
  309     * fill in the flip buffer here, but I do not know the relation
  310     * to the current/next receive buffer or characters.  I need
  311     * to look in to this before committing any code.
  312     */
  313    if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
  314       tty = port->tty;
  315       /* Overrun Error */
  316       if (priv->last_lsr & BELKIN_SA_LSR_OE) {
  317       }
  318       /* Parity Error */
  319       if (priv->last_lsr & BELKIN_SA_LSR_PE) {
  320       }
  321       /* Framing Error */
  322       if (priv->last_lsr & BELKIN_SA_LSR_FE) {
  323       }
  324       /* Break Indicator */
  325       if (priv->last_lsr & BELKIN_SA_LSR_BI) {
  326       }
  327    }
  328 #endif
    329    spin_unlock_irqrestore(&priv->lock, flags);
    329   do
    329     do
- 329     do-while (0)
- 329   do-while (0)
- 329 do-while (0)
  330 exit:
  331    retval = usb_submit_urb (urb, GFP_ATOMIC);
- 332    if (retval)
  333       err ("%s - usb_submit_urb failed with result %d",
  334            __FUNCTION__, retval);
  335 }
  336 
 
- 337 static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios)
  338 {
  339    struct usb_serial *serial = port->serial;
  340    struct belkin_sa_private *priv = usb_get_serial_port_data(port);
  341    unsigned int iflag;
  342    unsigned int cflag;
  343    unsigned int old_iflag = 0;
  344    unsigned int old_cflag = 0;
  345    __u16 urb_value = 0; /* Will hold the new flags */
  346    unsigned long flags;
  347    unsigned long control_state;
  348    int bad_flow_control;
  349    
- 350    if ((!port->tty) || (!port->tty->termios)) {
 - 350   (T) || (_)
 - 350   (F) || (T)
 - 350   (F) || (F)
    351       dbg ("%s - no tty or termios structure", __FUNCTION__);
- 351     if (debug)
- 351   do-while (0)
 - 352       return;
  353    }
  354 
  355    iflag = port->tty->termios->c_iflag;
  356    cflag = port->tty->termios->c_cflag;
  357 
  358    /* get a local copy of the current port settings */
    359    spin_lock_irqsave(&priv->lock, flags);
    359   do
    359     do
- 359     do-while (0)
- 359   do-while (0)
    359   do
    359     do
- 359     do-while (0)
- 359   do-while (0)
- 359 do-while (0)
  360    control_state = priv->control_state;
  361    bad_flow_control = priv->bad_flow_control;
    362    spin_unlock_irqrestore(&priv->lock, flags);
    362   do
    362     do
- 362     do-while (0)
- 362   do-while (0)
- 362 do-while (0)
  363    
  364    /* check that they really want us to change something */
- 365    if (old_termios) {
  366       if ((cflag == old_termios->c_cflag) &&
- 367           (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
 - 367     (T) && (T)
 - 367     (T) && (F)
 - 367     (F) && (_)
    368          dbg("%s - nothing to change...", __FUNCTION__);
- 368       if (debug)
- 368     do-while (0)
 - 369          return;
  370       }
  371       old_iflag = old_termios->c_iflag;
  372       old_cflag = old_termios->c_cflag;
  373    }
  374 
  375    /* Set the baud rate */
- 376    if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
  377       /* reassert DTR and (maybe) RTS on transition from B0 */
- 378       if( (old_cflag&CBAUD) == B0 ) {
  379          control_state |= (TIOCM_DTR|TIOCM_RTS);
- 380          if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
  381             err("Set DTR error");
  382          /* don't set RTS if using hardware flow control */
- 383          if (!(old_cflag&CRTSCTS) )
- 384             if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
  385                err("Set RTS error");
  386       }
  387 
    388       switch(cflag & CBAUD) {
 - 389          case B0: /* handled below */ break;
 - 389     break
 - 390          case B300: urb_value = BELKIN_SA_BAUD(300); break;
 - 390     break
 - 391          case B600: urb_value = BELKIN_SA_BAUD(600); break;
 - 391     break
 - 392          case B1200: urb_value = BELKIN_SA_BAUD(1200); break;
 - 392     break
 - 393          case B2400: urb_value = BELKIN_SA_BAUD(2400); break;
 - 393     break
 - 394          case B4800: urb_value = BELKIN_SA_BAUD(4800); break;
 - 394     break
 - 395          case B9600: urb_value = BELKIN_SA_BAUD(9600); break;
 - 395     break
 - 396          case B19200: urb_value = BELKIN_SA_BAUD(19200); break;
 - 396     break
 - 397          case B38400: urb_value = BELKIN_SA_BAUD(38400); break;
 - 397     break
 - 398          case B57600: urb_value = BELKIN_SA_BAUD(57600); break;
 - 398     break
 - 399          case B115200: urb_value = BELKIN_SA_BAUD(115200); break;
 - 399     break
 - 400          case B230400: urb_value = BELKIN_SA_BAUD(230400); break;
 - 400     break
 - 401          default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600");
 - 402             urb_value = BELKIN_SA_BAUD(9600); break;
  403       }
- 404       if ((cflag & CBAUD) != B0 ) {
- 405          if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
  406             err("Set baudrate error");
    407       } else {
  408          /* Disable flow control */
- 409          if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
  410             err("Disable flowcontrol error");
  411 
  412          /* Drop RTS and DTR */
  413          control_state &= ~(TIOCM_DTR | TIOCM_RTS);
- 414          if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
  415             err("DTR LOW error");
- 416          if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
  417             err("RTS LOW error");
  418       }
  419    }
  420 
  421    /* set the parity */
- 422    if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) {
- 423       if (cflag & PARENB)
    424          urb_value = (cflag & PARODD) ?  BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN;
- 424     ternary-?: ( cflag & 0001000 )
    425       else
  426          urb_value = BELKIN_SA_PARITY_NONE;
- 427       if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
  428          err("Set parity error");
  429    }
  430 
  431    /* set the number of data bits */
- 432    if( (cflag&CSIZE) != (old_cflag&CSIZE) ) {
    433       switch (cflag & CSIZE) {
 - 434          case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break;
 - 434     break
 - 435          case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
 - 435     break
 - 436          case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
 - 436     break
 - 437          case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
 - 437     break
 - 438          default: err("CSIZE was not CS5-CS8, using default of 8");