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