linux/drivers/usb/serial/belkin_sa.c
<<
>>
Prefs
   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 *  Copyright (C) 2010          Johan Hovold (jhovold@gmail.com)
   7 *
   8 *  This program is largely derived from work by the linux-usb group
   9 *  and associated source files.  Please see the usb/serial files for
  10 *  individual credits and copyrights.
  11 *
  12 *      This program is free software; you can redistribute it and/or modify
  13 *      it under the terms of the GNU General Public License as published by
  14 *      the Free Software Foundation; either version 2 of the License, or
  15 *      (at your option) any later version.
  16 *
  17 * See Documentation/usb/usb-serial.txt for more information on using this
  18 * driver
  19 *
  20 * TODO:
  21 * -- Add true modem control line query capability.  Currently we track the
  22 *    states reported by the interrupt and the states we request.
  23 * -- Add support for flush commands
  24 */
  25
  26#include <linux/kernel.h>
  27#include <linux/errno.h>
  28#include <linux/slab.h>
  29#include <linux/tty.h>
  30#include <linux/tty_driver.h>
  31#include <linux/tty_flip.h>
  32#include <linux/module.h>
  33#include <linux/spinlock.h>
  34#include <linux/uaccess.h>
  35#include <linux/usb.h>
  36#include <linux/usb/serial.h>
  37#include "belkin_sa.h"
  38
  39#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
  40#define DRIVER_DESC "USB Belkin Serial converter driver"
  41
  42/* function prototypes for a Belkin USB Serial Adapter F5U103 */
  43static int belkin_sa_port_probe(struct usb_serial_port *port);
  44static int belkin_sa_port_remove(struct usb_serial_port *port);
  45static int  belkin_sa_open(struct tty_struct *tty,
  46                        struct usb_serial_port *port);
  47static void belkin_sa_close(struct usb_serial_port *port);
  48static void belkin_sa_read_int_callback(struct urb *urb);
  49static void belkin_sa_process_read_urb(struct urb *urb);
  50static void belkin_sa_set_termios(struct tty_struct *tty,
  51                        struct usb_serial_port *port, struct ktermios * old);
  52static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
  53static int  belkin_sa_tiocmget(struct tty_struct *tty);
  54static int  belkin_sa_tiocmset(struct tty_struct *tty,
  55                                        unsigned int set, unsigned int clear);
  56
  57
  58static const struct usb_device_id id_table[] = {
  59        { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
  60        { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
  61        { USB_DEVICE(PERACOM_VID, PERACOM_PID) },
  62        { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
  63        { USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
  64        { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
  65        { }     /* Terminating entry */
  66};
  67MODULE_DEVICE_TABLE(usb, id_table);
  68
  69/* All of the device info needed for the serial converters */
  70static struct usb_serial_driver belkin_device = {
  71        .driver = {
  72                .owner =        THIS_MODULE,
  73                .name =         "belkin",
  74        },
  75        .description =          "Belkin / Peracom / GoHubs USB Serial Adapter",
  76        .id_table =             id_table,
  77        .num_ports =            1,
  78        .open =                 belkin_sa_open,
  79        .close =                belkin_sa_close,
  80        .read_int_callback =    belkin_sa_read_int_callback,
  81        .process_read_urb =     belkin_sa_process_read_urb,
  82        .set_termios =          belkin_sa_set_termios,
  83        .break_ctl =            belkin_sa_break_ctl,
  84        .tiocmget =             belkin_sa_tiocmget,
  85        .tiocmset =             belkin_sa_tiocmset,
  86        .port_probe =           belkin_sa_port_probe,
  87        .port_remove =          belkin_sa_port_remove,
  88};
  89
  90static struct usb_serial_driver * const serial_drivers[] = {
  91        &belkin_device, NULL
  92};
  93
  94struct belkin_sa_private {
  95        spinlock_t              lock;
  96        unsigned long           control_state;
  97        unsigned char           last_lsr;
  98        unsigned char           last_msr;
  99        int                     bad_flow_control;
 100};
 101
 102
 103/*
 104 * ***************************************************************************
 105 * Belkin USB Serial Adapter F5U103 specific driver functions
 106 * ***************************************************************************
 107 */
 108
 109#define WDR_TIMEOUT 5000 /* default urb timeout */
 110
 111/* assumes that struct usb_serial *serial is available */
 112#define BSA_USB_CMD(c, v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
 113                                            (c), BELKIN_SA_SET_REQUEST_TYPE, \
 114                                            (v), 0, NULL, 0, WDR_TIMEOUT)
 115
 116static int belkin_sa_port_probe(struct usb_serial_port *port)
 117{
 118        struct usb_device *dev = port->serial->dev;
 119        struct belkin_sa_private *priv;
 120
 121        priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
 122        if (!priv)
 123                return -ENOMEM;
 124
 125        spin_lock_init(&priv->lock);
 126        priv->control_state = 0;
 127        priv->last_lsr = 0;
 128        priv->last_msr = 0;
 129        /* see comments at top of file */
 130        priv->bad_flow_control =
 131                (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
 132        dev_info(&dev->dev, "bcdDevice: %04x, bfc: %d\n",
 133                                        le16_to_cpu(dev->descriptor.bcdDevice),
 134                                        priv->bad_flow_control);
 135
 136        usb_set_serial_port_data(port, priv);
 137
 138        return 0;
 139}
 140
 141static int belkin_sa_port_remove(struct usb_serial_port *port)
 142{
 143        struct belkin_sa_private *priv;
 144
 145        priv = usb_get_serial_port_data(port);
 146        kfree(priv);
 147
 148        return 0;
 149}
 150
 151static int belkin_sa_open(struct tty_struct *tty,
 152                                        struct usb_serial_port *port)
 153{
 154        int retval;
 155
 156        retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 157        if (retval) {
 158                dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
 159                return retval;
 160        }
 161
 162        retval = usb_serial_generic_open(tty, port);
 163        if (retval)
 164                usb_kill_urb(port->interrupt_in_urb);
 165
 166        return retval;
 167}
 168
 169static void belkin_sa_close(struct usb_serial_port *port)
 170{
 171        usb_serial_generic_close(port);
 172        usb_kill_urb(port->interrupt_in_urb);
 173}
 174
 175static void belkin_sa_read_int_callback(struct urb *urb)
 176{
 177        struct usb_serial_port *port = urb->context;
 178        struct belkin_sa_private *priv;
 179        unsigned char *data = urb->transfer_buffer;
 180        int retval;
 181        int status = urb->status;
 182        unsigned long flags;
 183
 184        switch (status) {
 185        case 0:
 186                /* success */
 187                break;
 188        case -ECONNRESET:
 189        case -ENOENT:
 190        case -ESHUTDOWN:
 191                /* this urb is terminated, clean up */
 192                dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
 193                        __func__, status);
 194                return;
 195        default:
 196                dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
 197                        __func__, status);
 198                goto exit;
 199        }
 200
 201        usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
 202
 203        /* Handle known interrupt data */
 204        /* ignore data[0] and data[1] */
 205
 206        priv = usb_get_serial_port_data(port);
 207        spin_lock_irqsave(&priv->lock, flags);
 208        priv->last_msr = data[BELKIN_SA_MSR_INDEX];
 209
 210        /* Record Control Line states */
 211        if (priv->last_msr & BELKIN_SA_MSR_DSR)
 212                priv->control_state |= TIOCM_DSR;
 213        else
 214                priv->control_state &= ~TIOCM_DSR;
 215
 216        if (priv->last_msr & BELKIN_SA_MSR_CTS)
 217                priv->control_state |= TIOCM_CTS;
 218        else
 219                priv->control_state &= ~TIOCM_CTS;
 220
 221        if (priv->last_msr & BELKIN_SA_MSR_RI)
 222                priv->control_state |= TIOCM_RI;
 223        else
 224                priv->control_state &= ~TIOCM_RI;
 225
 226        if (priv->last_msr & BELKIN_SA_MSR_CD)
 227                priv->control_state |= TIOCM_CD;
 228        else
 229                priv->control_state &= ~TIOCM_CD;
 230
 231        priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
 232        spin_unlock_irqrestore(&priv->lock, flags);
 233exit:
 234        retval = usb_submit_urb(urb, GFP_ATOMIC);
 235        if (retval)
 236                dev_err(&port->dev, "%s - usb_submit_urb failed with "
 237                        "result %d\n", __func__, retval);
 238}
 239
 240static void belkin_sa_process_read_urb(struct urb *urb)
 241{
 242        struct usb_serial_port *port = urb->context;
 243        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
 244        unsigned char *data = urb->transfer_buffer;
 245        unsigned long flags;
 246        unsigned char status;
 247        char tty_flag;
 248
 249        /* Update line status */
 250        tty_flag = TTY_NORMAL;
 251
 252        spin_lock_irqsave(&priv->lock, flags);
 253        status = priv->last_lsr;
 254        priv->last_lsr &= ~BELKIN_SA_LSR_ERR;
 255        spin_unlock_irqrestore(&priv->lock, flags);
 256
 257        if (!urb->actual_length)
 258                return;
 259
 260        if (status & BELKIN_SA_LSR_ERR) {
 261                /* Break takes precedence over parity, which takes precedence
 262                 * over framing errors. */
 263                if (status & BELKIN_SA_LSR_BI)
 264                        tty_flag = TTY_BREAK;
 265                else if (status & BELKIN_SA_LSR_PE)
 266                        tty_flag = TTY_PARITY;
 267                else if (status & BELKIN_SA_LSR_FE)
 268                        tty_flag = TTY_FRAME;
 269                dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
 270
 271                /* Overrun is special, not associated with a char. */
 272                if (status & BELKIN_SA_LSR_OE)
 273                        tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
 274        }
 275
 276        tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag,
 277                                                        urb->actual_length);
 278        tty_flip_buffer_push(&port->port);
 279}
 280
 281static void belkin_sa_set_termios(struct tty_struct *tty,
 282                struct usb_serial_port *port, struct ktermios *old_termios)
 283{
 284        struct usb_serial *serial = port->serial;
 285        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
 286        unsigned int iflag;
 287        unsigned int cflag;
 288        unsigned int old_iflag = 0;
 289        unsigned int old_cflag = 0;
 290        __u16 urb_value = 0; /* Will hold the new flags */
 291        unsigned long flags;
 292        unsigned long control_state;
 293        int bad_flow_control;
 294        speed_t baud;
 295        struct ktermios *termios = &tty->termios;
 296
 297        iflag = termios->c_iflag;
 298        cflag = termios->c_cflag;
 299
 300        termios->c_cflag &= ~CMSPAR;
 301
 302        /* get a local copy of the current port settings */
 303        spin_lock_irqsave(&priv->lock, flags);
 304        control_state = priv->control_state;
 305        bad_flow_control = priv->bad_flow_control;
 306        spin_unlock_irqrestore(&priv->lock, flags);
 307
 308        old_iflag = old_termios->c_iflag;
 309        old_cflag = old_termios->c_cflag;
 310
 311        /* Set the baud rate */
 312        if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
 313                /* reassert DTR and (maybe) RTS on transition from B0 */
 314                if ((old_cflag & CBAUD) == B0) {
 315                        control_state |= (TIOCM_DTR|TIOCM_RTS);
 316                        if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
 317                                dev_err(&port->dev, "Set DTR error\n");
 318                        /* don't set RTS if using hardware flow control */
 319                        if (!(old_cflag & CRTSCTS))
 320                                if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
 321                                                                , 1) < 0)
 322                                        dev_err(&port->dev, "Set RTS error\n");
 323                }
 324        }
 325
 326        baud = tty_get_baud_rate(tty);
 327        if (baud) {
 328                urb_value = BELKIN_SA_BAUD(baud);
 329                /* Clip to maximum speed */
 330                if (urb_value == 0)
 331                        urb_value = 1;
 332                /* Turn it back into a resulting real baud rate */
 333                baud = BELKIN_SA_BAUD(urb_value);
 334
 335                /* Report the actual baud rate back to the caller */
 336                tty_encode_baud_rate(tty, baud, baud);
 337                if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
 338                        dev_err(&port->dev, "Set baudrate error\n");
 339        } else {
 340                /* Disable flow control */
 341                if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
 342                                                BELKIN_SA_FLOW_NONE) < 0)
 343                        dev_err(&port->dev, "Disable flowcontrol error\n");
 344                /* Drop RTS and DTR */
 345                control_state &= ~(TIOCM_DTR | TIOCM_RTS);
 346                if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
 347                        dev_err(&port->dev, "DTR LOW error\n");
 348                if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
 349                        dev_err(&port->dev, "RTS LOW error\n");
 350        }
 351
 352        /* set the parity */
 353        if ((cflag ^ old_cflag) & (PARENB | PARODD)) {
 354                if (cflag & PARENB)
 355                        urb_value = (cflag & PARODD) ?  BELKIN_SA_PARITY_ODD
 356                                                : BELKIN_SA_PARITY_EVEN;
 357                else
 358                        urb_value = BELKIN_SA_PARITY_NONE;
 359                if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
 360                        dev_err(&port->dev, "Set parity error\n");
 361        }
 362
 363        /* set the number of data bits */
 364        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
 365                switch (cflag & CSIZE) {
 366                case CS5:
 367                        urb_value = BELKIN_SA_DATA_BITS(5);
 368                        break;
 369                case CS6:
 370                        urb_value = BELKIN_SA_DATA_BITS(6);
 371                        break;
 372                case CS7:
 373                        urb_value = BELKIN_SA_DATA_BITS(7);
 374                        break;
 375                case CS8:
 376                        urb_value = BELKIN_SA_DATA_BITS(8);
 377                        break;
 378                default:
 379                        dev_dbg(&port->dev,
 380                                "CSIZE was not CS5-CS8, using default of 8\n");
 381                        urb_value = BELKIN_SA_DATA_BITS(8);
 382                        break;
 383                }
 384                if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
 385                        dev_err(&port->dev, "Set data bits error\n");
 386        }
 387
 388        /* set the number of stop bits */
 389        if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
 390                urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2)
 391                                                : BELKIN_SA_STOP_BITS(1);
 392                if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST,
 393                                                        urb_value) < 0)
 394                        dev_err(&port->dev, "Set stop bits error\n");
 395        }
 396
 397        /* Set flow control */
 398        if (((iflag ^ old_iflag) & (IXOFF | IXON)) ||
 399                ((cflag ^ old_cflag) & CRTSCTS)) {
 400                urb_value = 0;
 401                if ((iflag & IXOFF) || (iflag & IXON))
 402                        urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
 403                else
 404                        urb_value &= ~(BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
 405
 406                if (cflag & CRTSCTS)
 407                        urb_value |=  (BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS);
 408                else
 409                        urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS);
 410
 411                if (bad_flow_control)
 412                        urb_value &= ~(BELKIN_SA_FLOW_IRTS);
 413
 414                if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0)
 415                        dev_err(&port->dev, "Set flow control error\n");
 416        }
 417
 418        /* save off the modified port settings */
 419        spin_lock_irqsave(&priv->lock, flags);
 420        priv->control_state = control_state;
 421        spin_unlock_irqrestore(&priv->lock, flags);
 422}
 423
 424static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
 425{
 426        struct usb_serial_port *port = tty->driver_data;
 427        struct usb_serial *serial = port->serial;
 428
 429        if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
 430                dev_err(&port->dev, "Set break_ctl %d\n", break_state);
 431}
 432
 433static int belkin_sa_tiocmget(struct tty_struct *tty)
 434{
 435        struct usb_serial_port *port = tty->driver_data;
 436        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
 437        unsigned long control_state;
 438        unsigned long flags;
 439
 440        spin_lock_irqsave(&priv->lock, flags);
 441        control_state = priv->control_state;
 442        spin_unlock_irqrestore(&priv->lock, flags);
 443
 444        return control_state;
 445}
 446
 447static int belkin_sa_tiocmset(struct tty_struct *tty,
 448                               unsigned int set, unsigned int clear)
 449{
 450        struct usb_serial_port *port = tty->driver_data;
 451        struct usb_serial *serial = port->serial;
 452        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
 453        unsigned long control_state;
 454        unsigned long flags;
 455        int retval;
 456        int rts = 0;
 457        int dtr = 0;
 458
 459        spin_lock_irqsave(&priv->lock, flags);
 460        control_state = priv->control_state;
 461
 462        if (set & TIOCM_RTS) {
 463                control_state |= TIOCM_RTS;
 464                rts = 1;
 465        }
 466        if (set & TIOCM_DTR) {
 467                control_state |= TIOCM_DTR;
 468                dtr = 1;
 469        }
 470        if (clear & TIOCM_RTS) {
 471                control_state &= ~TIOCM_RTS;
 472                rts = 0;
 473        }
 474        if (clear & TIOCM_DTR) {
 475                control_state &= ~TIOCM_DTR;
 476                dtr = 0;
 477        }
 478
 479        priv->control_state = control_state;
 480        spin_unlock_irqrestore(&priv->lock, flags);
 481
 482        retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts);
 483        if (retval < 0) {
 484                dev_err(&port->dev, "Set RTS error %d\n", retval);
 485                goto exit;
 486        }
 487
 488        retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr);
 489        if (retval < 0) {
 490                dev_err(&port->dev, "Set DTR error %d\n", retval);
 491                goto exit;
 492        }
 493exit:
 494        return retval;
 495}
 496
 497module_usb_serial_driver(serial_drivers, id_table);
 498
 499MODULE_AUTHOR(DRIVER_AUTHOR);
 500MODULE_DESCRIPTION(DRIVER_DESC);
 501MODULE_LICENSE("GPL");
 502