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 switch (value) { 211 case 300: break; 212 case 600: break; 213 case 1200: break; 214 case 2400: break; 215 case 4800: break; 216 case 9600: break; 217 case 19200: break; 218 case 38400: break; 219 case 57600: break; 220 case 115200: break; 221 default: 222 value = 9600; 223 *result = 9600; 224 } 225 return 115200/value; 226 } 227} 228 229static int mct_u232_set_baud_rate(struct tty_struct *tty, 230 struct usb_serial *serial, struct usb_serial_port *port, speed_t value) 231{ 232 unsigned int divisor; 233 int rc; 234 unsigned char *buf; 235 unsigned char cts_enable_byte = 0; 236 speed_t speed; 237 238 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); 239 if (buf == NULL) 240 return -ENOMEM; 241 242 divisor = mct_u232_calculate_baud_rate(serial, value, &speed); 243 put_unaligned_le32(cpu_to_le32(divisor), buf); 244 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 245 MCT_U232_SET_BAUD_RATE_REQUEST, 246 MCT_U232_SET_REQUEST_TYPE, 247 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE, 248 WDR_TIMEOUT); 249 if (rc < 0) 250 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", 251 value, rc); 252 else 253 tty_encode_baud_rate(tty, speed, speed); 254 dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); 255 256 /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which 257 always sends two extra USB 'device request' messages after the 258 'baud rate change' message. The actual functionality of the 259 request codes in these messages is not fully understood but these 260 particular codes are never seen in any operation besides a baud 261 rate change. Both of these messages send a single byte of data. 262 In the first message, the value of this byte is always zero. 263 264 The second message has been determined experimentally to control 265 whether data will be transmitted to a device which is not asserting 266 the 'CTS' signal. If the second message's data byte is zero, data 267 will be transmitted even if 'CTS' is not asserted (i.e. no hardware 268 flow control). if the second message's data byte is nonzero (a 269 value of 1 is used by this driver), data will not be transmitted to 270 a device which is not asserting 'CTS'. 271 */ 272 273 buf[0] = 0; 274 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 275 MCT_U232_SET_UNKNOWN1_REQUEST, 276 MCT_U232_SET_REQUEST_TYPE, 277 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE, 278 WDR_TIMEOUT); 279 if (rc < 0) 280 dev_err(&port->dev, "Sending USB device request code %d " 281 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST, 282 rc); 283 284 if (port && C_CRTSCTS(tty)) 285 cts_enable_byte = 1; 286 287 dbg("set_baud_rate: send second control message, data = %02X", 288 cts_enable_byte); 289 buf[0] = cts_enable_byte; 290 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 291 MCT_U232_SET_CTS_REQUEST, 292 MCT_U232_SET_REQUEST_TYPE, 293 0, 0, buf, MCT_U232_SET_CTS_SIZE, 294 WDR_TIMEOUT); 295 if (rc < 0) 296 dev_err(&port->dev, "Sending USB device request code %d " 297 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); 298 299 kfree(buf); 300 return rc; 301} /* mct_u232_set_baud_rate */ 302 303static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) 304{ 305 int rc; 306 unsigned char *buf; 307 308 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); 309 if (buf == NULL) 310 return -ENOMEM; 311 312 buf[0] = lcr; 313 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 314 MCT_U232_SET_LINE_CTRL_REQUEST, 315 MCT_U232_SET_REQUEST_TYPE, 316 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE, 317 WDR_TIMEOUT); 318 if (rc < 0) 319 dev_err(&serial->dev->dev, 320 "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); 321 dbg("set_line_ctrl: 0x%x", lcr); 322 kfree(buf); 323 return rc; 324} /* mct_u232_set_line_ctrl */ 325 326static int mct_u232_set_modem_ctrl(struct usb_serial *serial, 327 unsigned int control_state) 328{ 329 int rc; 330 unsigned char mcr; 331 unsigned char *buf; 332 333 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); 334 if (buf == NULL) 335 return -ENOMEM; 336 337 mcr = MCT_U232_MCR_NONE; 338 if (control_state & TIOCM_DTR) 339 mcr |= MCT_U232_MCR_DTR; 340 if (control_state & TIOCM_RTS) 341 mcr |= MCT_U232_MCR_RTS; 342 343 buf[0] = mcr; 344 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 345 MCT_U232_SET_MODEM_CTRL_REQUEST, 346 MCT_U232_SET_REQUEST_TYPE, 347 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, 348 WDR_TIMEOUT); 349 if (rc < 0) 350 dev_err(&serial->dev->dev, 351 "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); 352 dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); 353 354 kfree(buf); 355 return rc; 356} /* mct_u232_set_modem_ctrl */ 357 358static int mct_u232_get_modem_stat(struct usb_serial *serial, 359 unsigned char *msr) 360{ 361 int rc; 362 unsigned char *buf; 363 364 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); 365 if (buf == NULL) { 366 *msr = 0; 367 return -ENOMEM; 368 } 369 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 370 MCT_U232_GET_MODEM_STAT_REQUEST, 371 MCT_U232_GET_REQUEST_TYPE, 372 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE, 373 WDR_TIMEOUT); 374 if (rc < 0) { 375 dev_err(&serial->dev->dev, 376 "Get MODEM STATus failed (error = %d)\n", rc); 377 *msr = 0; 378 } else { 379 *msr = buf[0]; 380 } 381 dbg("get_modem_stat: 0x%x", *msr); 382 kfree(buf); 383 return rc; 384} /* mct_u232_get_modem_stat */ 385 386static void mct_u232_msr_to_state(unsigned int *control_state, 387 unsigned char msr) 388{ 389 /* Translate Control Line states */ 390 if (msr & MCT_U232_MSR_DSR) 391 *control_state |= TIOCM_DSR; 392 else 393 *control_state &= ~TIOCM_DSR; 394 if (msr & MCT_U232_MSR_CTS) 395 *control_state |= TIOCM_CTS; 396 else 397 *control_state &= ~TIOCM_CTS; 398 if (msr & MCT_U232_MSR_RI) 399 *control_state |= TIOCM_RI; 400 else 401 *control_state &= ~TIOCM_RI; 402 if (msr & MCT_U232_MSR_CD) 403 *control_state |= TIOCM_CD; 404 else 405 *control_state &= ~TIOCM_CD; 406 dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state); 407} /* mct_u232_msr_to_state */ 408 409/* 410 * Driver's tty interface functions 411 */ 412 413static int mct_u232_startup(struct usb_serial *serial) 414{ 415 struct mct_u232_private *priv; 416 struct usb_serial_port *port, *rport; 417 418 priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); 419 if (!priv) 420 return -ENOMEM; 421 spin_lock_init(&priv->lock); 422 usb_set_serial_port_data(serial->port[0], priv); 423 424 init_waitqueue_head(&serial->port[0]->write_wait); 425 426 /* Puh, that's dirty */ 427 port = serial->port[0]; 428 rport = serial->port[1]; 429 /* No unlinking, it wasn't submitted yet. */ 430 usb_free_urb(port->read_urb); 431 port->read_urb = rport->interrupt_in_urb; 432 rport->interrupt_in_urb = NULL; 433 port->read_urb->context = port; 434 435 return 0; 436} /* mct_u232_startup */ 437 438 439static void mct_u232_release(struct usb_serial *serial) 440{ 441 struct mct_u232_private *priv; 442 int i; 443 444 dbg("%s", __func__); 445 446 for (i = 0; i < serial->num_ports; ++i) { 447 /* My special items, the standard routines free my urbs */ 448 priv = usb_get_serial_port_data(serial->port[i]); 449 kfree(priv); 450 } 451} /* mct_u232_release */ 452 453static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) 454{ 455 struct usb_serial *serial = port->serial; 456 struct mct_u232_private *priv = usb_get_serial_port_data(port); 457 int retval = 0; 458 unsigned int control_state; 459 unsigned long flags; 460 unsigned char last_lcr; 461 unsigned char last_msr; 462 463 dbg("%s port %d", __func__, port->number); 464 465 /* Compensate for a hardware bug: although the Sitecom U232-P25 466 * device reports a maximum output packet size of 32 bytes, 467 * it seems to be able to accept only 16 bytes (and that's what 468 * SniffUSB says too...) 469 */ 470 if (le16_to_cpu(serial->dev->descriptor.idProduct) 471 == MCT_U232_SITECOM_PID) 472 port->bulk_out_size = 16; 473 474 /* Do a defined restart: the normal serial device seems to 475 * always turn on DTR and RTS here, so do the same. I'm not 476 * sure if this is really necessary. But it should not harm 477 * either. 478 */ 479 spin_lock_irqsave(&priv->lock, flags); 480 if (tty && (tty->termios->c_cflag & CBAUD)) 481 priv->control_state = TIOCM_DTR | TIOCM_RTS; 482 else 483 priv->control_state = 0; 484 485 priv->last_lcr = (MCT_U232_DATA_BITS_8 | 486 MCT_U232_PARITY_NONE | 487 MCT_U232_STOP_BITS_1); 488 control_state = priv->control_state; 489 last_lcr = priv->last_lcr; 490 spin_unlock_irqrestore(&priv->lock, flags); 491 mct_u232_set_modem_ctrl(serial, control_state); 492 mct_u232_set_line_ctrl(serial, last_lcr); 493 494 /* Read modem status and update control state */ 495 mct_u232_get_modem_stat(serial, &last_msr); 496 spin_lock_irqsave(&priv->lock, flags); 497 priv->last_msr = last_msr; 498 mct_u232_msr_to_state(&priv->control_state, priv->last_msr); 499 spin_unlock_irqrestore(&priv->lock, flags); 500 501 port->read_urb->dev = port->serial->dev; 502 retval = usb_submit_urb(port->read_urb, GFP_KERNEL); 503 if (retval) { 504 dev_err(&port->dev, 505 "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n", 506 port->read_urb->pipe, retval); 507 goto error; 508 } 509 510 port->interrupt_in_urb->dev = port->serial->dev; 511 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 512 if (retval) { 513 usb_kill_urb(port->read_urb); 514 dev_err(&port->dev, 515 "usb_submit_urb(read int) failed pipe 0x%x err %d", 516 port->interrupt_in_urb->pipe, retval); 517 goto error; 518 } 519 return 0; 520 521error: 522 return retval; 523} /* mct_u232_open */ 524 525static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) 526{ 527 unsigned int control_state; 528 struct mct_u232_private *priv = usb_get_serial_port_data(port); 529 530 mutex_lock(&port->serial->disc_mutex); 531 if (!port->serial->disconnected) { 532 /* drop DTR and RTS */ 533 spin_lock_irq(&priv->lock); 534 if (on) 535 priv->control_state |= TIOCM_DTR | TIOCM_RTS; 536 else 537 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); 538 control_state = priv->control_state; 539 spin_unlock_irq(&priv->lock); 540 mct_u232_set_modem_ctrl(port->serial, control_state); 541 } 542 mutex_unlock(&port->serial->disc_mutex); 543} 544 545static void mct_u232_close(struct usb_serial_port *port) 546{ 547 dbg("%s port %d", __func__, port->number); 548 549 if (port->serial->dev) { 550 /* shutdown our urbs */ 551 usb_kill_urb(port->write_urb); 552 usb_kill_urb(port->read_urb); 553 usb_kill_urb(port->interrupt_in_urb); 554 } 555} /* mct_u232_close */ 556 557 558static void mct_u232_read_int_callback(struct urb *urb) 559{ 560 struct usb_serial_port *port = urb->context; 561 struct mct_u232_private *priv = usb_get_serial_port_data(port); 562 struct usb_serial *serial = port->serial; 563 struct tty_struct *tty; 564 unsigned char *data = urb->transfer_buffer; 565 int retval; 566 int status = urb->status; 567 unsigned long flags; 568 569 switch (status) { 570 case 0: 571 /* success */ 572 break; 573 case -ECONNRESET: 574 case -ENOENT: 575 case -ESHUTDOWN: 576 /* this urb is terminated, clean up */ 577 dbg("%s - urb shutting down with status: %d", 578 __func__, status); 579 return; 580 default: 581 dbg("%s - nonzero urb status received: %d", 582 __func__, status); 583 goto exit; 584 } 585 586 if (!serial) { 587 dbg("%s - bad serial pointer, exiting", __func__); 588 return; 589 } 590 591 dbg("%s - port %d", __func__, port->number); 592 usb_serial_debug_data(debug, &port->dev, __func__, 593 urb->actual_length, data); 594 595 /* 596 * Work-a-round: handle the 'usual' bulk-in pipe here 597 */ 598 if (urb->transfer_buffer_length > 2) { 599 if (urb->actual_length) { 600 tty = tty_port_tty_get(&port->port); 601 if (tty) { 602 tty_insert_flip_string(tty, data, 603 urb->actual_length); 604 tty_flip_buffer_push(tty); 605 } 606 tty_kref_put(tty); 607 } 608 goto exit; 609 } 610 611 /* 612 * The interrupt-in pipe signals exceptional conditions (modem line 613 * signal changes and errors). data[0] holds MSR, data[1] holds LSR. 614 */ 615 spin_lock_irqsave(&priv->lock, flags); 616 priv->last_msr = data[MCT_U232_MSR_INDEX]; 617 618 /* Record Control Line states */ 619 mct_u232_msr_to_state(&priv->control_state, priv->last_msr); 620 621 spin_unlock_irqrestore(&priv->lock, flags); 622exit: 623 retval = usb_submit_urb(urb, GFP_ATOMIC); 624 if (retval) 625 dev_err(&port->dev, 626 "%s - usb_submit_urb failed with result %d\n", 627 __func__, retval); 628} /* mct_u232_read_int_callback */ 629 630static void mct_u232_set_termios(struct tty_struct *tty, 631 struct usb_serial_port *port, 632 struct ktermios *old_termios) 633{ 634 struct usb_serial *serial = port->serial; 635 struct mct_u232_private *priv = usb_get_serial_port_data(port); 636 struct ktermios *termios = tty->termios; 637 unsigned int cflag = termios->c_cflag; 638 unsigned int old_cflag = old_termios->c_cflag; 639 unsigned long flags; 640 unsigned int control_state; 641 unsigned char last_lcr; 642 643 /* get a local copy of the current port settings */ 644 spin_lock_irqsave(&priv->lock, flags); 645 control_state = priv->control_state; 646 spin_unlock_irqrestore(&priv->lock, flags); 647 last_lcr = 0; 648 649 /* 650 * Update baud rate. 651 * Do not attempt to cache old rates and skip settings, 652 * disconnects screw such tricks up completely. 653 * Premature optimization is the root of all evil. 654 */ 655 656 /* reassert DTR and RTS on transition from B0 */ 657 if ((old_cflag & CBAUD) == B0) { 658 dbg("%s: baud was B0", __func__); 659 control_state |= TIOCM_DTR | TIOCM_RTS; 660 mct_u232_set_modem_ctrl(serial, control_state); 661 } 662 663 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty)); 664 665 if ((cflag & CBAUD) == B0) { 666 dbg("%s: baud is B0", __func__); 667 /* Drop RTS and DTR */ 668 control_state &= ~(TIOCM_DTR | TIOCM_RTS); 669 mct_u232_set_modem_ctrl(serial, control_state); 670 } 671 672 /* 673 * Update line control register (LCR) 674 */ 675 676 /* set the parity */ 677 if (cflag & PARENB) 678 last_lcr |= (cflag & PARODD) ? 679 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN; 680 else 681 last_lcr |= MCT_U232_PARITY_NONE; 682 683 /* set the number of data bits */ 684 switch (cflag & CSIZE) { 685 case CS5: 686 last_lcr |= MCT_U232_DATA_BITS_5; break; 687 case CS6: 688 last_lcr |= MCT_U232_DATA_BITS_6; break; 689 case CS7: 690 last_lcr |= MCT_U232_DATA_BITS_7; break; 691 case CS8: 692 last_lcr |= MCT_U232_DATA_BITS_8; break; 693 default: 694 dev_err(&port->dev, 695 "CSIZE was not CS5-CS8, using default of 8\n"); 696 last_lcr |= MCT_U232_DATA_BITS_8; 697 break; 698 } 699 700 termios->c_cflag &= ~CMSPAR; 701 702 /* set the number of stop bits */ 703 last_lcr |= (cflag & CSTOPB) ? 704 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; 705 706 mct_u232_set_line_ctrl(serial, last_lcr); 707 708 /* save off the modified port settings */ 709 spin_lock_irqsave(&priv->lock, flags); 710 priv->control_state = control_state; 711 priv->last_lcr = last_lcr; 712 spin_unlock_irqrestore(&priv->lock, flags); 713} /* mct_u232_set_termios */ 714 715static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) 716{ 717 struct usb_serial_port *port = tty->driver_data; 718 struct usb_serial *serial = port->serial; 719 struct mct_u232_private *priv = usb_get_serial_port_data(port); 720 unsigned char lcr; 721 unsigned long flags; 722 723 dbg("%sstate=%d", __func__, break_state); 724 725 spin_lock_irqsave(&priv->lock, flags); 726 lcr = priv->last_lcr; 727 728 if (break_state) 729 lcr |= MCT_U232_SET_BREAK; 730 spin_unlock_irqrestore(&priv->lock, flags); 731 732 mct_u232_set_line_ctrl(serial, lcr); 733} /* mct_u232_break_ctl */ 734 735 736static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file) 737{ 738 struct usb_serial_port *port = tty->driver_data; 739 struct mct_u232_private *priv = usb_get_serial_port_data(port); 740 unsigned int control_state; 741 unsigned long flags; 742 743 dbg("%s", __func__); 744 745 spin_lock_irqsave(&priv->lock, flags); 746 control_state = priv->control_state; 747 spin_unlock_irqrestore(&priv->lock, flags); 748 749 return control_state; 750} 751 752static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, 753 unsigned int set, unsigned int clear) 754{ 755 struct usb_serial_port *port = tty->driver_data; 756 struct usb_serial *serial = port->serial; 757 struct mct_u232_private *priv = usb_get_serial_port_data(port); 758 unsigned int control_state; 759 unsigned long flags; 760 761 dbg("%s", __func__); 762 763 spin_lock_irqsave(&priv->lock, flags); 764 control_state = priv->control_state; 765 766 if (set & TIOCM_RTS) 767 control_state |= TIOCM_RTS; 768 if (set & TIOCM_DTR) 769 control_state |= TIOCM_DTR; 770 if (clear & TIOCM_RTS) 771 control_state &= ~TIOCM_RTS; 772 if (clear & TIOCM_DTR) 773 control_state &= ~TIOCM_DTR; 774 775 priv->control_state = control_state; 776 spin_unlock_irqrestore(&priv->lock, flags); 777 return mct_u232_set_modem_ctrl(serial, control_state); 778} 779 780static void mct_u232_throttle(struct tty_struct *tty) 781{ 782 struct usb_serial_port *port = tty->driver_data; 783 struct mct_u232_private *priv = usb_get_serial_port_data(port); 784 unsigned int control_state; 785 786 dbg("%s - port %d", __func__, port->number); 787 788 spin_lock_irq(&priv->lock); 789 priv->rx_flags |= THROTTLED; 790 if (C_CRTSCTS(tty)) { 791 priv->control_state &= ~TIOCM_RTS; 792 control_state = priv->control_state; 793 spin_unlock_irq(&priv->lock); 794 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 795 } else { 796 spin_unlock_irq(&priv->lock); 797 } 798} 799 800 801static void mct_u232_unthrottle(struct tty_struct *tty) 802{ 803 struct usb_serial_port *port = tty->driver_data; 804 struct mct_u232_private *priv = usb_get_serial_port_data(port); 805 unsigned int control_state; 806 807 dbg("%s - port %d", __func__, port->number); 808 809 spin_lock_irq(&priv->lock); 810 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) { 811 priv->rx_flags &= ~THROTTLED; 812 priv->control_state |= TIOCM_RTS; 813 control_state = priv->control_state; 814 spin_unlock_irq(&priv->lock); 815 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 816 } else { 817 spin_unlock_irq(&priv->lock); 818 } 819} 820 821static int __init mct_u232_init(void) 822{ 823 int retval; 824 retval = usb_serial_register(&mct_u232_device); 825 if (retval) 826 goto failed_usb_serial_register; 827 retval = usb_register(&mct_u232_driver); 828 if (retval) 829 goto failed_usb_register; 830 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 831 DRIVER_DESC "\n"); 832 return 0; 833failed_usb_register: 834 usb_serial_deregister(&mct_u232_device); 835failed_usb_serial_register: 836 return retval; 837} 838 839 840static void __exit mct_u232_exit(void) 841{ 842 usb_deregister(&mct_u232_driver); 843 usb_serial_deregister(&mct_u232_device); 844} 845 846module_init(mct_u232_init); 847module_exit(mct_u232_exit); 848 849MODULE_AUTHOR(DRIVER_AUTHOR); 850MODULE_DESCRIPTION(DRIVER_DESC); 851MODULE_LICENSE("GPL"); 852 853module_param(debug, bool, S_IRUGO | S_IWUSR); 854MODULE_PARM_DESC(debug, "Debug enabled or not"); 855