0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/kernel.h>
0021 #include <linux/errno.h>
0022 #include <linux/slab.h>
0023 #include <linux/tty.h>
0024 #include <linux/tty_driver.h>
0025 #include <linux/tty_flip.h>
0026 #include <linux/module.h>
0027 #include <linux/spinlock.h>
0028 #include <linux/uaccess.h>
0029 #include <asm/unaligned.h>
0030 #include <linux/usb.h>
0031 #include <linux/usb/serial.h>
0032 #include <linux/serial.h>
0033 #include "mct_u232.h"
0034
0035 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
0036 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
0037
0038
0039
0040
0041 static int mct_u232_port_probe(struct usb_serial_port *port);
0042 static void mct_u232_port_remove(struct usb_serial_port *remove);
0043 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
0044 static void mct_u232_close(struct usb_serial_port *port);
0045 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
0046 static void mct_u232_read_int_callback(struct urb *urb);
0047 static void mct_u232_set_termios(struct tty_struct *tty,
0048 struct usb_serial_port *port, struct ktermios *old);
0049 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
0050 static int mct_u232_tiocmget(struct tty_struct *tty);
0051 static int mct_u232_tiocmset(struct tty_struct *tty,
0052 unsigned int set, unsigned int clear);
0053 static void mct_u232_throttle(struct tty_struct *tty);
0054 static void mct_u232_unthrottle(struct tty_struct *tty);
0055
0056
0057
0058
0059
0060 static const struct usb_device_id id_table[] = {
0061 { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
0062 { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
0063 { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
0064 { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
0065 { }
0066 };
0067 MODULE_DEVICE_TABLE(usb, id_table);
0068
0069 static struct usb_serial_driver mct_u232_device = {
0070 .driver = {
0071 .owner = THIS_MODULE,
0072 .name = "mct_u232",
0073 },
0074 .description = "MCT U232",
0075 .id_table = id_table,
0076 .num_ports = 1,
0077 .open = mct_u232_open,
0078 .close = mct_u232_close,
0079 .dtr_rts = mct_u232_dtr_rts,
0080 .throttle = mct_u232_throttle,
0081 .unthrottle = mct_u232_unthrottle,
0082 .read_int_callback = mct_u232_read_int_callback,
0083 .set_termios = mct_u232_set_termios,
0084 .break_ctl = mct_u232_break_ctl,
0085 .tiocmget = mct_u232_tiocmget,
0086 .tiocmset = mct_u232_tiocmset,
0087 .tiocmiwait = usb_serial_generic_tiocmiwait,
0088 .port_probe = mct_u232_port_probe,
0089 .port_remove = mct_u232_port_remove,
0090 .get_icount = usb_serial_generic_get_icount,
0091 };
0092
0093 static struct usb_serial_driver * const serial_drivers[] = {
0094 &mct_u232_device, NULL
0095 };
0096
0097 struct mct_u232_private {
0098 struct urb *read_urb;
0099 spinlock_t lock;
0100 unsigned int control_state;
0101 unsigned char last_lcr;
0102 unsigned char last_lsr;
0103 unsigned char last_msr;
0104 unsigned int rx_flags;
0105 };
0106
0107 #define THROTTLED 0x01
0108
0109
0110
0111
0112
0113 #define WDR_TIMEOUT 5000
0114
0115
0116
0117
0118
0119 static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
0120 speed_t value, speed_t *result)
0121 {
0122 *result = value;
0123
0124 if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
0125 || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
0126 switch (value) {
0127 case 300:
0128 return 0x01;
0129 case 600:
0130 return 0x02;
0131 case 1200:
0132 return 0x03;
0133 case 2400:
0134 return 0x04;
0135 case 4800:
0136 return 0x06;
0137 case 9600:
0138 return 0x08;
0139 case 19200:
0140 return 0x09;
0141 case 38400:
0142 return 0x0a;
0143 case 57600:
0144 return 0x0b;
0145 case 115200:
0146 return 0x0c;
0147 default:
0148 *result = 9600;
0149 return 0x08;
0150 }
0151 } else {
0152
0153
0154
0155 switch (value) {
0156 case 300: break;
0157 case 600: break;
0158 case 1200: break;
0159 case 2400: break;
0160 case 4800: break;
0161 case 9600: break;
0162 case 19200: break;
0163 case 38400: break;
0164 case 57600: break;
0165 case 115200: break;
0166 default:
0167 value = 9600;
0168 *result = 9600;
0169 }
0170 return 115200/value;
0171 }
0172 }
0173
0174 static int mct_u232_set_baud_rate(struct tty_struct *tty,
0175 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
0176 {
0177 unsigned int divisor;
0178 int rc;
0179 unsigned char *buf;
0180 unsigned char cts_enable_byte = 0;
0181 speed_t speed;
0182
0183 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
0184 if (buf == NULL)
0185 return -ENOMEM;
0186
0187 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
0188 put_unaligned_le32(divisor, buf);
0189 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0190 MCT_U232_SET_BAUD_RATE_REQUEST,
0191 MCT_U232_SET_REQUEST_TYPE,
0192 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
0193 WDR_TIMEOUT);
0194 if (rc < 0)
0195 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
0196 value, rc);
0197 else
0198 tty_encode_baud_rate(tty, speed, speed);
0199 dev_dbg(&port->dev, "set_baud_rate: value: 0x%x, divisor: 0x%x\n", value, divisor);
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 buf[0] = 0;
0219 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0220 MCT_U232_SET_UNKNOWN1_REQUEST,
0221 MCT_U232_SET_REQUEST_TYPE,
0222 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
0223 WDR_TIMEOUT);
0224 if (rc < 0)
0225 dev_err(&port->dev, "Sending USB device request code %d "
0226 "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
0227 rc);
0228
0229 if (port && C_CRTSCTS(tty))
0230 cts_enable_byte = 1;
0231
0232 dev_dbg(&port->dev, "set_baud_rate: send second control message, data = %02X\n",
0233 cts_enable_byte);
0234 buf[0] = cts_enable_byte;
0235 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
0236 MCT_U232_SET_CTS_REQUEST,
0237 MCT_U232_SET_REQUEST_TYPE,
0238 0, 0, buf, MCT_U232_SET_CTS_SIZE,
0239 WDR_TIMEOUT);
0240 if (rc < 0)
0241 dev_err(&port->dev, "Sending USB device request code %d "
0242 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
0243
0244 kfree(buf);
0245 return rc;
0246 }
0247
0248 static int mct_u232_set_line_ctrl(struct usb_serial_port *port,
0249 unsigned char lcr)
0250 {
0251 int rc;
0252 unsigned char *buf;
0253
0254 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
0255 if (buf == NULL)
0256 return -ENOMEM;
0257
0258 buf[0] = lcr;
0259 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
0260 MCT_U232_SET_LINE_CTRL_REQUEST,
0261 MCT_U232_SET_REQUEST_TYPE,
0262 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
0263 WDR_TIMEOUT);
0264 if (rc < 0)
0265 dev_err(&port->dev, "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
0266 dev_dbg(&port->dev, "set_line_ctrl: 0x%x\n", lcr);
0267 kfree(buf);
0268 return rc;
0269 }
0270
0271 static int mct_u232_set_modem_ctrl(struct usb_serial_port *port,
0272 unsigned int control_state)
0273 {
0274 int rc;
0275 unsigned char mcr;
0276 unsigned char *buf;
0277
0278 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
0279 if (buf == NULL)
0280 return -ENOMEM;
0281
0282 mcr = MCT_U232_MCR_NONE;
0283 if (control_state & TIOCM_DTR)
0284 mcr |= MCT_U232_MCR_DTR;
0285 if (control_state & TIOCM_RTS)
0286 mcr |= MCT_U232_MCR_RTS;
0287
0288 buf[0] = mcr;
0289 rc = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
0290 MCT_U232_SET_MODEM_CTRL_REQUEST,
0291 MCT_U232_SET_REQUEST_TYPE,
0292 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
0293 WDR_TIMEOUT);
0294 kfree(buf);
0295
0296 dev_dbg(&port->dev, "set_modem_ctrl: state=0x%x ==> mcr=0x%x\n", control_state, mcr);
0297
0298 if (rc < 0) {
0299 dev_err(&port->dev, "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
0300 return rc;
0301 }
0302 return 0;
0303 }
0304
0305 static int mct_u232_get_modem_stat(struct usb_serial_port *port,
0306 unsigned char *msr)
0307 {
0308 int rc;
0309 unsigned char *buf;
0310
0311 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
0312 if (buf == NULL) {
0313 *msr = 0;
0314 return -ENOMEM;
0315 }
0316 rc = usb_control_msg(port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
0317 MCT_U232_GET_MODEM_STAT_REQUEST,
0318 MCT_U232_GET_REQUEST_TYPE,
0319 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
0320 WDR_TIMEOUT);
0321 if (rc < MCT_U232_GET_MODEM_STAT_SIZE) {
0322 dev_err(&port->dev, "Get MODEM STATus failed (error = %d)\n", rc);
0323
0324 if (rc >= 0)
0325 rc = -EIO;
0326
0327 *msr = 0;
0328 } else {
0329 *msr = buf[0];
0330 }
0331 dev_dbg(&port->dev, "get_modem_stat: 0x%x\n", *msr);
0332 kfree(buf);
0333 return rc;
0334 }
0335
0336 static void mct_u232_msr_to_icount(struct async_icount *icount,
0337 unsigned char msr)
0338 {
0339
0340 if (msr & MCT_U232_MSR_DDSR)
0341 icount->dsr++;
0342 if (msr & MCT_U232_MSR_DCTS)
0343 icount->cts++;
0344 if (msr & MCT_U232_MSR_DRI)
0345 icount->rng++;
0346 if (msr & MCT_U232_MSR_DCD)
0347 icount->dcd++;
0348 }
0349
0350 static void mct_u232_msr_to_state(struct usb_serial_port *port,
0351 unsigned int *control_state, unsigned char msr)
0352 {
0353
0354 if (msr & MCT_U232_MSR_DSR)
0355 *control_state |= TIOCM_DSR;
0356 else
0357 *control_state &= ~TIOCM_DSR;
0358 if (msr & MCT_U232_MSR_CTS)
0359 *control_state |= TIOCM_CTS;
0360 else
0361 *control_state &= ~TIOCM_CTS;
0362 if (msr & MCT_U232_MSR_RI)
0363 *control_state |= TIOCM_RI;
0364 else
0365 *control_state &= ~TIOCM_RI;
0366 if (msr & MCT_U232_MSR_CD)
0367 *control_state |= TIOCM_CD;
0368 else
0369 *control_state &= ~TIOCM_CD;
0370 dev_dbg(&port->dev, "msr_to_state: msr=0x%x ==> state=0x%x\n", msr, *control_state);
0371 }
0372
0373
0374
0375
0376
0377 static int mct_u232_port_probe(struct usb_serial_port *port)
0378 {
0379 struct usb_serial *serial = port->serial;
0380 struct mct_u232_private *priv;
0381
0382
0383 if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
0384 dev_err(&port->dev, "expected endpoint missing\n");
0385 return -ENODEV;
0386 }
0387
0388 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0389 if (!priv)
0390 return -ENOMEM;
0391
0392
0393 priv->read_urb = serial->port[1]->interrupt_in_urb;
0394 priv->read_urb->context = port;
0395
0396 spin_lock_init(&priv->lock);
0397
0398 usb_set_serial_port_data(port, priv);
0399
0400 return 0;
0401 }
0402
0403 static void mct_u232_port_remove(struct usb_serial_port *port)
0404 {
0405 struct mct_u232_private *priv;
0406
0407 priv = usb_get_serial_port_data(port);
0408 kfree(priv);
0409 }
0410
0411 static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
0412 {
0413 struct usb_serial *serial = port->serial;
0414 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0415 int retval = 0;
0416 unsigned int control_state;
0417 unsigned long flags;
0418 unsigned char last_lcr;
0419 unsigned char last_msr;
0420
0421
0422
0423
0424
0425
0426 if (le16_to_cpu(serial->dev->descriptor.idProduct)
0427 == MCT_U232_SITECOM_PID)
0428 port->bulk_out_size = 16;
0429
0430
0431
0432
0433
0434
0435 spin_lock_irqsave(&priv->lock, flags);
0436 if (tty && C_BAUD(tty))
0437 priv->control_state = TIOCM_DTR | TIOCM_RTS;
0438 else
0439 priv->control_state = 0;
0440
0441 priv->last_lcr = (MCT_U232_DATA_BITS_8 |
0442 MCT_U232_PARITY_NONE |
0443 MCT_U232_STOP_BITS_1);
0444 control_state = priv->control_state;
0445 last_lcr = priv->last_lcr;
0446 spin_unlock_irqrestore(&priv->lock, flags);
0447 mct_u232_set_modem_ctrl(port, control_state);
0448 mct_u232_set_line_ctrl(port, last_lcr);
0449
0450
0451 mct_u232_get_modem_stat(port, &last_msr);
0452 spin_lock_irqsave(&priv->lock, flags);
0453 priv->last_msr = last_msr;
0454 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
0455 spin_unlock_irqrestore(&priv->lock, flags);
0456
0457 retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
0458 if (retval) {
0459 dev_err(&port->dev,
0460 "usb_submit_urb(read) failed pipe 0x%x err %d\n",
0461 port->read_urb->pipe, retval);
0462 goto error;
0463 }
0464
0465 retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
0466 if (retval) {
0467 usb_kill_urb(priv->read_urb);
0468 dev_err(&port->dev,
0469 "usb_submit_urb(read int) failed pipe 0x%x err %d",
0470 port->interrupt_in_urb->pipe, retval);
0471 goto error;
0472 }
0473 return 0;
0474
0475 error:
0476 return retval;
0477 }
0478
0479 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
0480 {
0481 unsigned int control_state;
0482 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0483
0484 spin_lock_irq(&priv->lock);
0485 if (on)
0486 priv->control_state |= TIOCM_DTR | TIOCM_RTS;
0487 else
0488 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
0489 control_state = priv->control_state;
0490 spin_unlock_irq(&priv->lock);
0491
0492 mct_u232_set_modem_ctrl(port, control_state);
0493 }
0494
0495 static void mct_u232_close(struct usb_serial_port *port)
0496 {
0497 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0498
0499 usb_kill_urb(priv->read_urb);
0500 usb_kill_urb(port->interrupt_in_urb);
0501
0502 usb_serial_generic_close(port);
0503 }
0504
0505
0506 static void mct_u232_read_int_callback(struct urb *urb)
0507 {
0508 struct usb_serial_port *port = urb->context;
0509 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0510 unsigned char *data = urb->transfer_buffer;
0511 int retval;
0512 int status = urb->status;
0513 unsigned long flags;
0514
0515 switch (status) {
0516 case 0:
0517
0518 break;
0519 case -ECONNRESET:
0520 case -ENOENT:
0521 case -ESHUTDOWN:
0522
0523 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
0524 __func__, status);
0525 return;
0526 default:
0527 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
0528 __func__, status);
0529 goto exit;
0530 }
0531
0532 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
0533
0534
0535
0536
0537 if (urb->transfer_buffer_length > 2) {
0538 if (urb->actual_length) {
0539 tty_insert_flip_string(&port->port, data,
0540 urb->actual_length);
0541 tty_flip_buffer_push(&port->port);
0542 }
0543 goto exit;
0544 }
0545
0546
0547
0548
0549
0550 spin_lock_irqsave(&priv->lock, flags);
0551 priv->last_msr = data[MCT_U232_MSR_INDEX];
0552
0553
0554 mct_u232_msr_to_state(port, &priv->control_state, priv->last_msr);
0555
0556 mct_u232_msr_to_icount(&port->icount, priv->last_msr);
0557
0558 #if 0
0559
0560
0561 priv->last_lsr = data[MCT_U232_LSR_INDEX];
0562
0563
0564
0565
0566
0567 if (priv->last_lsr & MCT_U232_LSR_ERR) {
0568 tty = tty_port_tty_get(&port->port);
0569
0570 if (priv->last_lsr & MCT_U232_LSR_OE) {
0571 }
0572
0573 if (priv->last_lsr & MCT_U232_LSR_PE) {
0574 }
0575
0576 if (priv->last_lsr & MCT_U232_LSR_FE) {
0577 }
0578
0579 if (priv->last_lsr & MCT_U232_LSR_BI) {
0580 }
0581 tty_kref_put(tty);
0582 }
0583 #endif
0584 wake_up_interruptible(&port->port.delta_msr_wait);
0585 spin_unlock_irqrestore(&priv->lock, flags);
0586 exit:
0587 retval = usb_submit_urb(urb, GFP_ATOMIC);
0588 if (retval)
0589 dev_err(&port->dev,
0590 "%s - usb_submit_urb failed with result %d\n",
0591 __func__, retval);
0592 }
0593
0594 static void mct_u232_set_termios(struct tty_struct *tty,
0595 struct usb_serial_port *port,
0596 struct ktermios *old_termios)
0597 {
0598 struct usb_serial *serial = port->serial;
0599 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0600 struct ktermios *termios = &tty->termios;
0601 unsigned int cflag = termios->c_cflag;
0602 unsigned int old_cflag = old_termios->c_cflag;
0603 unsigned long flags;
0604 unsigned int control_state;
0605 unsigned char last_lcr;
0606
0607
0608 spin_lock_irqsave(&priv->lock, flags);
0609 control_state = priv->control_state;
0610 spin_unlock_irqrestore(&priv->lock, flags);
0611 last_lcr = 0;
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621 if ((old_cflag & CBAUD) == B0) {
0622 dev_dbg(&port->dev, "%s: baud was B0\n", __func__);
0623 control_state |= TIOCM_DTR | TIOCM_RTS;
0624 mct_u232_set_modem_ctrl(port, control_state);
0625 }
0626
0627 mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
0628
0629 if ((cflag & CBAUD) == B0) {
0630 dev_dbg(&port->dev, "%s: baud is B0\n", __func__);
0631
0632 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
0633 mct_u232_set_modem_ctrl(port, control_state);
0634 }
0635
0636
0637
0638
0639
0640
0641 if (cflag & PARENB)
0642 last_lcr |= (cflag & PARODD) ?
0643 MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
0644 else
0645 last_lcr |= MCT_U232_PARITY_NONE;
0646
0647
0648 switch (cflag & CSIZE) {
0649 case CS5:
0650 last_lcr |= MCT_U232_DATA_BITS_5; break;
0651 case CS6:
0652 last_lcr |= MCT_U232_DATA_BITS_6; break;
0653 case CS7:
0654 last_lcr |= MCT_U232_DATA_BITS_7; break;
0655 case CS8:
0656 last_lcr |= MCT_U232_DATA_BITS_8; break;
0657 default:
0658 dev_err(&port->dev,
0659 "CSIZE was not CS5-CS8, using default of 8\n");
0660 last_lcr |= MCT_U232_DATA_BITS_8;
0661 break;
0662 }
0663
0664 termios->c_cflag &= ~CMSPAR;
0665
0666
0667 last_lcr |= (cflag & CSTOPB) ?
0668 MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
0669
0670 mct_u232_set_line_ctrl(port, last_lcr);
0671
0672
0673 spin_lock_irqsave(&priv->lock, flags);
0674 priv->control_state = control_state;
0675 priv->last_lcr = last_lcr;
0676 spin_unlock_irqrestore(&priv->lock, flags);
0677 }
0678
0679 static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
0680 {
0681 struct usb_serial_port *port = tty->driver_data;
0682 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0683 unsigned char lcr;
0684 unsigned long flags;
0685
0686 spin_lock_irqsave(&priv->lock, flags);
0687 lcr = priv->last_lcr;
0688
0689 if (break_state)
0690 lcr |= MCT_U232_SET_BREAK;
0691 spin_unlock_irqrestore(&priv->lock, flags);
0692
0693 mct_u232_set_line_ctrl(port, lcr);
0694 }
0695
0696
0697 static int mct_u232_tiocmget(struct tty_struct *tty)
0698 {
0699 struct usb_serial_port *port = tty->driver_data;
0700 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0701 unsigned int control_state;
0702 unsigned long flags;
0703
0704 spin_lock_irqsave(&priv->lock, flags);
0705 control_state = priv->control_state;
0706 spin_unlock_irqrestore(&priv->lock, flags);
0707
0708 return control_state;
0709 }
0710
0711 static int mct_u232_tiocmset(struct tty_struct *tty,
0712 unsigned int set, unsigned int clear)
0713 {
0714 struct usb_serial_port *port = tty->driver_data;
0715 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0716 unsigned int control_state;
0717 unsigned long flags;
0718
0719 spin_lock_irqsave(&priv->lock, flags);
0720 control_state = priv->control_state;
0721
0722 if (set & TIOCM_RTS)
0723 control_state |= TIOCM_RTS;
0724 if (set & TIOCM_DTR)
0725 control_state |= TIOCM_DTR;
0726 if (clear & TIOCM_RTS)
0727 control_state &= ~TIOCM_RTS;
0728 if (clear & TIOCM_DTR)
0729 control_state &= ~TIOCM_DTR;
0730
0731 priv->control_state = control_state;
0732 spin_unlock_irqrestore(&priv->lock, flags);
0733 return mct_u232_set_modem_ctrl(port, control_state);
0734 }
0735
0736 static void mct_u232_throttle(struct tty_struct *tty)
0737 {
0738 struct usb_serial_port *port = tty->driver_data;
0739 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0740 unsigned int control_state;
0741
0742 spin_lock_irq(&priv->lock);
0743 priv->rx_flags |= THROTTLED;
0744 if (C_CRTSCTS(tty)) {
0745 priv->control_state &= ~TIOCM_RTS;
0746 control_state = priv->control_state;
0747 spin_unlock_irq(&priv->lock);
0748 mct_u232_set_modem_ctrl(port, control_state);
0749 } else {
0750 spin_unlock_irq(&priv->lock);
0751 }
0752 }
0753
0754 static void mct_u232_unthrottle(struct tty_struct *tty)
0755 {
0756 struct usb_serial_port *port = tty->driver_data;
0757 struct mct_u232_private *priv = usb_get_serial_port_data(port);
0758 unsigned int control_state;
0759
0760 spin_lock_irq(&priv->lock);
0761 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
0762 priv->rx_flags &= ~THROTTLED;
0763 priv->control_state |= TIOCM_RTS;
0764 control_state = priv->control_state;
0765 spin_unlock_irq(&priv->lock);
0766 mct_u232_set_modem_ctrl(port, control_state);
0767 } else {
0768 spin_unlock_irq(&priv->lock);
0769 }
0770 }
0771
0772 module_usb_serial_driver(serial_drivers, id_table);
0773
0774 MODULE_AUTHOR(DRIVER_AUTHOR);
0775 MODULE_DESCRIPTION(DRIVER_DESC);
0776 MODULE_LICENSE("GPL");