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