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