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