linux/drivers/usb/serial/mct_u232.c
<<
>>
Prefs
   1/*
   2 * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver
   3 *
   4 *   Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch)
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 * This program is largely derived from the Belkin USB Serial Adapter Driver
  12 * (see belkin_sa.[ch]). All of the information about the device was acquired
  13 * by using SniffUSB on Windows98. For technical details see mct_u232.h.
  14 *
  15 * William G. Greathouse and Greg Kroah-Hartman provided great help on how to
  16 * do the reverse engineering and how to write a USB serial device driver.
  17 *
  18 * TO BE DONE, TO BE CHECKED:
  19 *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly
  20 *   implemented what I have seen with SniffUSB or found in belkin_sa.c.
  21 *   For further TODOs check also belkin_sa.c.
  22 *
  23 * TEST STATUS:
  24 *   Basic tests have been performed with minicom/zmodem transfers and
  25 *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
  26 *
  27 * 04-Nov-2003 Bill Marr <marr at flex dot com>
  28 *   - Mimic Windows driver by sending 2 USB 'device request' messages
  29 *     following normal 'baud rate change' message.  This allows data to be
  30 *     transmitted to RS-232 devices which don't assert the 'CTS' signal.
  31 *
  32 * 10-Nov-2001 Wolfgang Grandegger
  33 *   - Fixed an endianess problem with the baudrate selection for PowerPC.
  34 *
  35 * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
  36 *   - Added support for the Belkin F5U109 DB9 adaptor
  37 *
  38 * 30-May-2001 Greg Kroah-Hartman
  39 *   - switched from using spinlock to a semaphore, which fixes lots of
  40 *     problems.
  41 *
  42 * 04-May-2001 Stelian Pop
  43 *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
  44 *     instead of the device reported 32 (using 32 bytes causes many data
  45 *     loss, Windows driver uses 16 too).
  46 *
  47 * 02-May-2001 Stelian Pop
  48 *   - Fixed the baud calculation for Sitecom U232-P25 model
  49 *
  50 * 08-Apr-2001 gb
  51 *   - Identify version on module load.
  52 *
  53 * 06-Jan-2001 Cornel Ciocirlan
  54 *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
  55 *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
  56 *
  57 * 29-Nov-2000 Greg Kroah-Hartman
  58 *   - Added device id table to fit with 2.4.0-test11 structure.
  59 *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed
  60 *     (lots of things will change if/when the usb-serial core changes to
  61 *     handle these issues.
  62 *
  63 * 27-Nov-2000 Wolfgang Grandegge
  64 *   A version for kernel 2.4.0-test10 released to the Linux community
  65 *   (via linux-usb-devel).
  66 */
  67
  68#include <linux/kernel.h>
  69#include <linux/errno.h>
  70#include <linux/init.h>
  71#include <linux/slab.h>
  72#include <linux/tty.h>
  73#include <linux/tty_driver.h>
  74#include <linux/tty_flip.h>
  75#include <linux/module.h>
  76#include <linux/spinlock.h>
  77#include <linux/uaccess.h>
  78#include <asm/unaligned.h>
  79#include <linux/usb.h>
  80#include <linux/usb/serial.h>
  81#include "mct_u232.h"
  82
  83/*
  84 * Version Information
  85 */
  86#define DRIVER_VERSION "z2.1"           /* Linux in-kernel version */
  87#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
  88#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
  89
  90static int debug;
  91
  92/*
  93 * Function prototypes
  94 */
  95static int  mct_u232_startup(struct usb_serial *serial);
  96static void mct_u232_release(struct usb_serial *serial);
  97static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
  98static void mct_u232_close(struct usb_serial_port *port);
  99static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
 100static void mct_u232_read_int_callback(struct urb *urb);
 101static void mct_u232_set_termios(struct tty_struct *tty,
 102                        struct usb_serial_port *port, struct ktermios *old);
 103static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
 104static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
 105static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
 106                        unsigned int set, unsigned int clear);
 107static void mct_u232_throttle(struct tty_struct *tty);
 108static void mct_u232_unthrottle(struct tty_struct *tty);
 109
 110
 111/*
 112 * All of the device info needed for the MCT USB-RS232 converter.
 113 */
 114static const struct usb_device_id id_table_combined[] = {
 115        { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 116        { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 117        { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
 118        { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
 119        { }             /* Terminating entry */
 120};
 121
 122MODULE_DEVICE_TABLE(usb, id_table_combined);
 123
 124static struct usb_driver mct_u232_driver = {
 125        .name =         "mct_u232",
 126        .probe =        usb_serial_probe,
 127        .disconnect =   usb_serial_disconnect,
 128        .id_table =     id_table_combined,
 129        .no_dynamic_id =        1,
 130};
 131
 132static struct usb_serial_driver mct_u232_device = {
 133        .driver = {
 134                .owner =        THIS_MODULE,
 135                .name =         "mct_u232",
 136        },
 137        .description =       "MCT U232",
 138        .usb_driver =        &mct_u232_driver,
 139        .id_table =          id_table_combined,
 140        .num_ports =         1,
 141        .open =              mct_u232_open,
 142        .close =             mct_u232_close,
 143        .dtr_rts =           mct_u232_dtr_rts,
 144        .throttle =          mct_u232_throttle,
 145        .unthrottle =        mct_u232_unthrottle,
 146        .read_int_callback = mct_u232_read_int_callback,
 147        .set_termios =       mct_u232_set_termios,
 148        .break_ctl =         mct_u232_break_ctl,
 149        .tiocmget =          mct_u232_tiocmget,
 150        .tiocmset =          mct_u232_tiocmset,
 151        .attach =            mct_u232_startup,
 152        .release =           mct_u232_release,
 153};
 154
 155
 156struct mct_u232_private {
 157        spinlock_t lock;
 158        unsigned int         control_state; /* Modem Line Setting (TIOCM) */
 159        unsigned char        last_lcr;      /* Line Control Register */
 160        unsigned char        last_lsr;      /* Line Status Register */
 161        unsigned char        last_msr;      /* Modem Status Register */
 162        unsigned int         rx_flags;      /* Throttling flags */
 163};
 164
 165#define THROTTLED               0x01
 166
 167/*
 168 * Handle vendor specific USB requests
 169 */
 170
 171#define WDR_TIMEOUT 5000 /* default urb timeout */
 172
 173/*
 174 * Later day 2.6.0-test kernels have new baud rates like B230400 which
 175 * we do not know how to support. We ignore them for the moment.
 176 */
 177static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
 178                                        speed_t value, speed_t *result)
 179{
 180        *result = value;
 181
 182        if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
 183                || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
 184                switch (value) {
 185                case 300:
 186                        return 0x01;
 187                case 600:
 188                        return 0x02; /* this one not tested */
 189                case 1200:
 190                        return 0x03;
 191                case 2400:
 192                        return 0x04;
 193                case 4800:
 194                        return 0x06;
 195                case 9600:
 196                        return 0x08;
 197                case 19200:
 198                        return 0x09;
 199                case 38400:
 200                        return 0x0a;
 201                case 57600:
 202                        return 0x0b;
 203                case 115200:
 204                        return 0x0c;
 205                default:
 206                        *result = 9600;
 207                        return 0x08;
 208                }
 209        } else {
 210                /* FIXME: Can we use any divider - should we do
 211                   divider = 115200/value;
 212                   real baud = 115200/divider */
 213                switch (value) {
 214                case 300: break;
 215                case 600: break;
 216                case 1200: break;
 217                case 2400: break;
 218                case 4800: break;
 219                case 9600: break;
 220                case 19200: break;
 221                case 38400: break;
 222                case 57600: break;
 223                case 115200: break;
 224                default:
 225                        value = 9600;
 226                        *result = 9600;
 227                }
 228                return 115200/value;
 229        }
 230}
 231
 232static int mct_u232_set_baud_rate(struct tty_struct *tty,
 233        struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
 234{
 235        unsigned int divisor;
 236        int rc;
 237        unsigned char *buf;
 238        unsigned char cts_enable_byte = 0;
 239        speed_t speed;
 240
 241        buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
 242        if (buf == NULL)
 243                return -ENOMEM;
 244
 245        divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
 246        put_unaligned_le32(cpu_to_le32(divisor), buf);
 247        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 248                                MCT_U232_SET_BAUD_RATE_REQUEST,
 249                                MCT_U232_SET_REQUEST_TYPE,
 250                                0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
 251                                WDR_TIMEOUT);
 252        if (rc < 0)     /*FIXME: What value speed results */
 253                dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
 254                        value, rc);
 255        else
 256                tty_encode_baud_rate(tty, speed, speed);
 257        dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
 258
 259        /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
 260           always sends two extra USB 'device request' messages after the
 261           'baud rate change' message.  The actual functionality of the
 262           request codes in these messages is not fully understood but these
 263           particular codes are never seen in any operation besides a baud
 264           rate change.  Both of these messages send a single byte of data.
 265           In the first message, the value of this byte is always zero.
 266
 267           The second message has been determined experimentally to control
 268           whether data will be transmitted to a device which is not asserting
 269           the 'CTS' signal.  If the second message's data byte is zero, data
 270           will be transmitted even if 'CTS' is not asserted (i.e. no hardware
 271           flow control).  if the second message's data byte is nonzero (a
 272           value of 1 is used by this driver), data will not be transmitted to
 273           a device which is not asserting 'CTS'.
 274        */
 275
 276        buf[0] = 0;
 277        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 278                                MCT_U232_SET_UNKNOWN1_REQUEST,
 279                                MCT_U232_SET_REQUEST_TYPE,
 280                                0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
 281                                WDR_TIMEOUT);
 282        if (rc < 0)
 283                dev_err(&port->dev, "Sending USB device request code %d "
 284                        "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
 285                        rc);
 286
 287        if (port && C_CRTSCTS(tty))
 288           cts_enable_byte = 1;
 289
 290        dbg("set_baud_rate: send second control message, data = %02X",
 291                                                        cts_enable_byte);
 292        buf[0] = cts_enable_byte;
 293        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 294                        MCT_U232_SET_CTS_REQUEST,
 295                        MCT_U232_SET_REQUEST_TYPE,
 296                        0, 0, buf, MCT_U232_SET_CTS_SIZE,
 297                        WDR_TIMEOUT);
 298        if (rc < 0)
 299                dev_err(&port->dev, "Sending USB device request code %d "
 300                        "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
 301
 302        kfree(buf);
 303        return rc;
 304} /* mct_u232_set_baud_rate */
 305
 306static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
 307{
 308        int rc;
 309        unsigned char *buf;
 310
 311        buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
 312        if (buf == NULL)
 313                return -ENOMEM;
 314
 315        buf[0] = lcr;
 316        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 317                        MCT_U232_SET_LINE_CTRL_REQUEST,
 318                        MCT_U232_SET_REQUEST_TYPE,
 319                        0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
 320                        WDR_TIMEOUT);
 321        if (rc < 0)
 322                dev_err(&serial->dev->dev,
 323                        "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
 324        dbg("set_line_ctrl: 0x%x", lcr);
 325        kfree(buf);
 326        return rc;
 327} /* mct_u232_set_line_ctrl */
 328
 329static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
 330                                   unsigned int control_state)
 331{
 332        int rc;
 333        unsigned char mcr;
 334        unsigned char *buf;
 335
 336        buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
 337        if (buf == NULL)
 338                return -ENOMEM;
 339
 340        mcr = MCT_U232_MCR_NONE;
 341        if (control_state & TIOCM_DTR)
 342                mcr |= MCT_U232_MCR_DTR;
 343        if (control_state & TIOCM_RTS)
 344                mcr |= MCT_U232_MCR_RTS;
 345
 346        buf[0] = mcr;
 347        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 348                        MCT_U232_SET_MODEM_CTRL_REQUEST,
 349                        MCT_U232_SET_REQUEST_TYPE,
 350                        0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
 351                        WDR_TIMEOUT);
 352        if (rc < 0)
 353                dev_err(&serial->dev->dev,
 354                        "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
 355        dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
 356
 357        kfree(buf);
 358        return rc;
 359} /* mct_u232_set_modem_ctrl */
 360
 361static int mct_u232_get_modem_stat(struct usb_serial *serial,
 362                                                unsigned char *msr)
 363{
 364        int rc;
 365        unsigned char *buf;
 366
 367        buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
 368        if (buf == NULL) {
 369                *msr = 0;
 370                return -ENOMEM;
 371        }
 372        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 373                        MCT_U232_GET_MODEM_STAT_REQUEST,
 374                        MCT_U232_GET_REQUEST_TYPE,
 375                        0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
 376                        WDR_TIMEOUT);
 377        if (rc < 0) {
 378                dev_err(&serial->dev->dev,
 379                        "Get MODEM STATus failed (error = %d)\n", rc);
 380                *msr = 0;
 381        } else {
 382                *msr = buf[0];
 383        }
 384        dbg("get_modem_stat: 0x%x", *msr);
 385        kfree(buf);
 386        return rc;
 387} /* mct_u232_get_modem_stat */
 388
 389static void mct_u232_msr_to_state(unsigned int *control_state,
 390                                                unsigned char msr)
 391{
 392        /* Translate Control Line states */
 393        if (msr & MCT_U232_MSR_DSR)
 394                *control_state |=  TIOCM_DSR;
 395        else
 396                *control_state &= ~TIOCM_DSR;
 397        if (msr & MCT_U232_MSR_CTS)
 398                *control_state |=  TIOCM_CTS;
 399        else
 400                *control_state &= ~TIOCM_CTS;
 401        if (msr & MCT_U232_MSR_RI)
 402                *control_state |=  TIOCM_RI;
 403        else
 404                *control_state &= ~TIOCM_RI;
 405        if (msr & MCT_U232_MSR_CD)
 406                *control_state |=  TIOCM_CD;
 407        else
 408                *control_state &= ~TIOCM_CD;
 409        dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
 410} /* mct_u232_msr_to_state */
 411
 412/*
 413 * Driver's tty interface functions
 414 */
 415
 416static int mct_u232_startup(struct usb_serial *serial)
 417{
 418        struct mct_u232_private *priv;
 419        struct usb_serial_port *port, *rport;
 420
 421        priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
 422        if (!priv)
 423                return -ENOMEM;
 424        spin_lock_init(&priv->lock);
 425        usb_set_serial_port_data(serial->port[0], priv);
 426
 427        init_waitqueue_head(&serial->port[0]->write_wait);
 428
 429        /* Puh, that's dirty */
 430        port = serial->port[0];
 431        rport = serial->port[1];
 432        /* No unlinking, it wasn't submitted yet. */
 433        usb_free_urb(port->read_urb);
 434        port->read_urb = rport->interrupt_in_urb;
 435        rport->interrupt_in_urb = NULL;
 436        port->read_urb->context = port;
 437
 438        return 0;
 439} /* mct_u232_startup */
 440
 441
 442static void mct_u232_release(struct usb_serial *serial)
 443{
 444        struct mct_u232_private *priv;
 445        int i;
 446
 447        dbg("%s", __func__);
 448
 449        for (i = 0; i < serial->num_ports; ++i) {
 450                /* My special items, the standard routines free my urbs */
 451                priv = usb_get_serial_port_data(serial->port[i]);
 452                kfree(priv);
 453        }
 454} /* mct_u232_release */
 455
 456static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
 457{
 458        struct usb_serial *serial = port->serial;
 459        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 460        int retval = 0;
 461        unsigned int control_state;
 462        unsigned long flags;
 463        unsigned char last_lcr;
 464        unsigned char last_msr;
 465
 466        dbg("%s port %d", __func__, port->number);
 467
 468        /* Compensate for a hardware bug: although the Sitecom U232-P25
 469         * device reports a maximum output packet size of 32 bytes,
 470         * it seems to be able to accept only 16 bytes (and that's what
 471         * SniffUSB says too...)
 472         */
 473        if (le16_to_cpu(serial->dev->descriptor.idProduct)
 474                                                == MCT_U232_SITECOM_PID)
 475                port->bulk_out_size = 16;
 476
 477        /* Do a defined restart: the normal serial device seems to
 478         * always turn on DTR and RTS here, so do the same. I'm not
 479         * sure if this is really necessary. But it should not harm
 480         * either.
 481         */
 482        spin_lock_irqsave(&priv->lock, flags);
 483        if (tty && (tty->termios->c_cflag & CBAUD))
 484                priv->control_state = TIOCM_DTR | TIOCM_RTS;
 485        else
 486                priv->control_state = 0;
 487
 488        priv->last_lcr = (MCT_U232_DATA_BITS_8 |
 489                          MCT_U232_PARITY_NONE |
 490                          MCT_U232_STOP_BITS_1);
 491        control_state = priv->control_state;
 492        last_lcr = priv->last_lcr;
 493        spin_unlock_irqrestore(&priv->lock, flags);
 494        mct_u232_set_modem_ctrl(serial, control_state);
 495        mct_u232_set_line_ctrl(serial, last_lcr);
 496
 497        /* Read modem status and update control state */
 498        mct_u232_get_modem_stat(serial, &last_msr);
 499        spin_lock_irqsave(&priv->lock, flags);
 500        priv->last_msr = last_msr;
 501        mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
 502        spin_unlock_irqrestore(&priv->lock, flags);
 503
 504        port->read_urb->dev = port->serial->dev;
 505        retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
 506        if (retval) {
 507                dev_err(&port->dev,
 508                        "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
 509                        port->read_urb->pipe, retval);
 510                goto error;
 511        }
 512
 513        port->interrupt_in_urb->dev = port->serial->dev;
 514        retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 515        if (retval) {
 516                usb_kill_urb(port->read_urb);
 517                dev_err(&port->dev,
 518                        "usb_submit_urb(read int) failed pipe 0x%x err %d",
 519                        port->interrupt_in_urb->pipe, retval);
 520                goto error;
 521        }
 522        return 0;
 523
 524error:
 525        return retval;
 526} /* mct_u232_open */
 527
 528static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
 529{
 530        unsigned int control_state;
 531        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 532
 533        mutex_lock(&port->serial->disc_mutex);
 534        if (!port->serial->disconnected) {
 535                /* drop DTR and RTS */
 536                spin_lock_irq(&priv->lock);
 537                if (on)
 538                        priv->control_state |= TIOCM_DTR | TIOCM_RTS;
 539                else
 540                        priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
 541                control_state = priv->control_state;
 542                spin_unlock_irq(&priv->lock);
 543                mct_u232_set_modem_ctrl(port->serial, control_state);
 544        }
 545        mutex_unlock(&port->serial->disc_mutex);
 546}
 547
 548static void mct_u232_close(struct usb_serial_port *port)
 549{
 550        dbg("%s port %d", __func__, port->number);
 551
 552        if (port->serial->dev) {
 553                /* shutdown our urbs */
 554                usb_kill_urb(port->write_urb);
 555                usb_kill_urb(port->read_urb);
 556                usb_kill_urb(port->interrupt_in_urb);
 557        }
 558} /* mct_u232_close */
 559
 560
 561static void mct_u232_read_int_callback(struct urb *urb)
 562{
 563        struct usb_serial_port *port = urb->context;
 564        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 565        struct usb_serial *serial = port->serial;
 566        struct tty_struct *tty;
 567        unsigned char *data = urb->transfer_buffer;
 568        int retval;
 569        int status = urb->status;
 570        unsigned long flags;
 571
 572        switch (status) {
 573        case 0:
 574                /* success */
 575                break;
 576        case -ECONNRESET:
 577        case -ENOENT:
 578        case -ESHUTDOWN:
 579                /* this urb is terminated, clean up */
 580                dbg("%s - urb shutting down with status: %d",
 581                    __func__, status);
 582                return;
 583        default:
 584                dbg("%s - nonzero urb status received: %d",
 585                    __func__, status);
 586                goto exit;
 587        }
 588
 589        if (!serial) {
 590                dbg("%s - bad serial pointer, exiting", __func__);
 591                return;
 592        }
 593
 594        dbg("%s - port %d", __func__, port->number);
 595        usb_serial_debug_data(debug, &port->dev, __func__,
 596                                        urb->actual_length, data);
 597
 598        /*
 599         * Work-a-round: handle the 'usual' bulk-in pipe here
 600         */
 601        if (urb->transfer_buffer_length > 2) {
 602                if (urb->actual_length) {
 603                        tty = tty_port_tty_get(&port->port);
 604                        if (tty) {
 605                                tty_insert_flip_string(tty, data,
 606                                                urb->actual_length);
 607                                tty_flip_buffer_push(tty);
 608                        }
 609                        tty_kref_put(tty);
 610                }
 611                goto exit;
 612        }
 613
 614        /*
 615         * The interrupt-in pipe signals exceptional conditions (modem line
 616         * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
 617         */
 618        spin_lock_irqsave(&priv->lock, flags);
 619        priv->last_msr = data[MCT_U232_MSR_INDEX];
 620
 621        /* Record Control Line states */
 622        mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
 623
 624#if 0
 625        /* Not yet handled. See belkin_sa.c for further information */
 626        /* Now to report any errors */
 627        priv->last_lsr = data[MCT_U232_LSR_INDEX];
 628        /*
 629         * fill in the flip buffer here, but I do not know the relation
 630         * to the current/next receive buffer or characters.  I need
 631         * to look in to this before committing any code.
 632         */
 633        if (priv->last_lsr & MCT_U232_LSR_ERR) {
 634                tty = tty_port_tty_get(&port->port);
 635                /* Overrun Error */
 636                if (priv->last_lsr & MCT_U232_LSR_OE) {
 637                }
 638                /* Parity Error */
 639                if (priv->last_lsr & MCT_U232_LSR_PE) {
 640                }
 641                /* Framing Error */
 642                if (priv->last_lsr & MCT_U232_LSR_FE) {
 643                }
 644                /* Break Indicator */
 645                if (priv->last_lsr & MCT_U232_LSR_BI) {
 646                }
 647                tty_kref_put(tty);
 648        }
 649#endif
 650        spin_unlock_irqrestore(&priv->lock, flags);
 651exit:
 652        retval = usb_submit_urb(urb, GFP_ATOMIC);
 653        if (retval)
 654                dev_err(&port->dev,
 655                        "%s - usb_submit_urb failed with result %d\n",
 656                        __func__, retval);
 657} /* mct_u232_read_int_callback */
 658
 659static void mct_u232_set_termios(struct tty_struct *tty,
 660                                 struct usb_serial_port *port,
 661                                 struct ktermios *old_termios)
 662{
 663        struct usb_serial *serial = port->serial;
 664        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 665        struct ktermios *termios = tty->termios;
 666        unsigned int cflag = termios->c_cflag;
 667        unsigned int old_cflag = old_termios->c_cflag;
 668        unsigned long flags;
 669        unsigned int control_state;
 670        unsigned char last_lcr;
 671
 672        /* get a local copy of the current port settings */
 673        spin_lock_irqsave(&priv->lock, flags);
 674        control_state = priv->control_state;
 675        spin_unlock_irqrestore(&priv->lock, flags);
 676        last_lcr = 0;
 677
 678        /*
 679         * Update baud rate.
 680         * Do not attempt to cache old rates and skip settings,
 681         * disconnects screw such tricks up completely.
 682         * Premature optimization is the root of all evil.
 683         */
 684
 685        /* reassert DTR and RTS on transition from B0 */
 686        if ((old_cflag & CBAUD) == B0) {
 687                dbg("%s: baud was B0", __func__);
 688                control_state |= TIOCM_DTR | TIOCM_RTS;
 689                mct_u232_set_modem_ctrl(serial, control_state);
 690        }
 691
 692        mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
 693
 694        if ((cflag & CBAUD) == B0) {
 695                dbg("%s: baud is B0", __func__);
 696                /* Drop RTS and DTR */
 697                control_state &= ~(TIOCM_DTR | TIOCM_RTS);
 698                mct_u232_set_modem_ctrl(serial, control_state);
 699        }
 700
 701        /*
 702         * Update line control register (LCR)
 703         */
 704
 705        /* set the parity */
 706        if (cflag & PARENB)
 707                last_lcr |= (cflag & PARODD) ?
 708                        MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
 709        else
 710                last_lcr |= MCT_U232_PARITY_NONE;
 711
 712        /* set the number of data bits */
 713        switch (cflag & CSIZE) {
 714        case CS5:
 715                last_lcr |= MCT_U232_DATA_BITS_5; break;
 716        case CS6:
 717                last_lcr |= MCT_U232_DATA_BITS_6; break;
 718        case CS7:
 719                last_lcr |= MCT_U232_DATA_BITS_7; break;
 720        case CS8:
 721                last_lcr |= MCT_U232_DATA_BITS_8; break;
 722        default:
 723                dev_err(&port->dev,
 724                        "CSIZE was not CS5-CS8, using default of 8\n");
 725                last_lcr |= MCT_U232_DATA_BITS_8;
 726                break;
 727        }
 728
 729        termios->c_cflag &= ~CMSPAR;
 730
 731        /* set the number of stop bits */
 732        last_lcr |= (cflag & CSTOPB) ?
 733                MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
 734
 735        mct_u232_set_line_ctrl(serial, last_lcr);
 736
 737        /* save off the modified port settings */
 738        spin_lock_irqsave(&priv->lock, flags);
 739        priv->control_state = control_state;
 740        priv->last_lcr = last_lcr;
 741        spin_unlock_irqrestore(&priv->lock, flags);
 742} /* mct_u232_set_termios */
 743
 744static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
 745{
 746        struct usb_serial_port *port = tty->driver_data;
 747        struct usb_serial *serial = port->serial;
 748        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 749        unsigned char lcr;
 750        unsigned long flags;
 751
 752        dbg("%sstate=%d", __func__, break_state);
 753
 754        spin_lock_irqsave(&priv->lock, flags);
 755        lcr = priv->last_lcr;
 756
 757        if (break_state)
 758                lcr |= MCT_U232_SET_BREAK;
 759        spin_unlock_irqrestore(&priv->lock, flags);
 760
 761        mct_u232_set_line_ctrl(serial, lcr);
 762} /* mct_u232_break_ctl */
 763
 764
 765static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
 766{
 767        struct usb_serial_port *port = tty->driver_data;
 768        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 769        unsigned int control_state;
 770        unsigned long flags;
 771
 772        dbg("%s", __func__);
 773
 774        spin_lock_irqsave(&priv->lock, flags);
 775        control_state = priv->control_state;
 776        spin_unlock_irqrestore(&priv->lock, flags);
 777
 778        return control_state;
 779}
 780
 781static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
 782                              unsigned int set, unsigned int clear)
 783{
 784        struct usb_serial_port *port = tty->driver_data;
 785        struct usb_serial *serial = port->serial;
 786        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 787        unsigned int control_state;
 788        unsigned long flags;
 789
 790        dbg("%s", __func__);
 791
 792        spin_lock_irqsave(&priv->lock, flags);
 793        control_state = priv->control_state;
 794
 795        if (set & TIOCM_RTS)
 796                control_state |= TIOCM_RTS;
 797        if (set & TIOCM_DTR)
 798                control_state |= TIOCM_DTR;
 799        if (clear & TIOCM_RTS)
 800                control_state &= ~TIOCM_RTS;
 801        if (clear & TIOCM_DTR)
 802                control_state &= ~TIOCM_DTR;
 803
 804        priv->control_state = control_state;
 805        spin_unlock_irqrestore(&priv->lock, flags);
 806        return mct_u232_set_modem_ctrl(serial, control_state);
 807}
 808
 809static void mct_u232_throttle(struct tty_struct *tty)
 810{
 811        struct usb_serial_port *port = tty->driver_data;
 812        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 813        unsigned int control_state;
 814
 815        dbg("%s - port %d", __func__, port->number);
 816
 817        spin_lock_irq(&priv->lock);
 818        priv->rx_flags |= THROTTLED;
 819        if (C_CRTSCTS(tty)) {
 820                priv->control_state &= ~TIOCM_RTS;
 821                control_state = priv->control_state;
 822                spin_unlock_irq(&priv->lock);
 823                (void) mct_u232_set_modem_ctrl(port->serial, control_state);
 824        } else {
 825                spin_unlock_irq(&priv->lock);
 826        }
 827}
 828
 829
 830static void mct_u232_unthrottle(struct tty_struct *tty)
 831{
 832        struct usb_serial_port *port = tty->driver_data;
 833        struct mct_u232_private *priv = usb_get_serial_port_data(port);
 834        unsigned int control_state;
 835
 836        dbg("%s - port %d", __func__, port->number);
 837
 838        spin_lock_irq(&priv->lock);
 839        if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
 840                priv->rx_flags &= ~THROTTLED;
 841                priv->control_state |= TIOCM_RTS;
 842                control_state = priv->control_state;
 843                spin_unlock_irq(&priv->lock);
 844                (void) mct_u232_set_modem_ctrl(port->serial, control_state);
 845        } else {
 846                spin_unlock_irq(&priv->lock);
 847        }
 848}
 849
 850static int __init mct_u232_init(void)
 851{
 852        int retval;
 853        retval = usb_serial_register(&mct_u232_device);
 854        if (retval)
 855                goto failed_usb_serial_register;
 856        retval = usb_register(&mct_u232_driver);
 857        if (retval)
 858                goto failed_usb_register;
 859        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 860               DRIVER_DESC "\n");
 861        return 0;
 862failed_usb_register:
 863        usb_serial_deregister(&mct_u232_device);
 864failed_usb_serial_register:
 865        return retval;
 866}
 867
 868
 869static void __exit mct_u232_exit(void)
 870{
 871        usb_deregister(&mct_u232_driver);
 872        usb_serial_deregister(&mct_u232_device);
 873}
 874
 875module_init(mct_u232_init);
 876module_exit(mct_u232_exit);
 877
 878MODULE_AUTHOR(DRIVER_AUTHOR);
 879MODULE_DESCRIPTION(DRIVER_DESC);
 880MODULE_LICENSE("GPL");
 881
 882module_param(debug, bool, S_IRUGO | S_IWUSR);
 883MODULE_PARM_DESC(debug, "Debug enabled or not");
 884