blob: 39ab6687ce23c6ddd5d8cc77e98839cd5aaae044 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * USB Keyspan PDA / Xircom / Entregra Converter driver
3 *
4 * Copyright (C) 1999 - 2001 Greg Kroah-Hartman <greg@kroah.com>
5 * Copyright (C) 1999, 2000 Brian Warner <warner@lothar.com>
6 * Copyright (C) 2000 Al Borchers <borchers@steinerpoint.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
Alan Cox9e70f312008-07-22 11:13:42 +010013 * See Documentation/usb/usb-serial.txt for more information on using this
14 * driver
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 */
16
17
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/slab.h>
22#include <linux/tty.h>
23#include <linux/tty_driver.h>
24#include <linux/tty_flip.h>
25#include <linux/module.h>
26#include <linux/spinlock.h>
27#include <linux/workqueue.h>
David Woodhouse3edbf982008-05-30 15:15:13 +030028#include <linux/firmware.h>
29#include <linux/ihex.h>
Alan Cox9e70f312008-07-22 11:13:42 +010030#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/usb.h>
Greg Kroah-Hartmana9698882006-07-11 21:22:58 -070032#include <linux/usb/serial.h>
Rene Buergelcc183e22012-09-18 09:00:41 +020033#include <linux/usb/ezusb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/* make a simple define to handle if we are compiling keyspan_pda or xircom support */
36#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
37 #define KEYSPAN
38#else
39 #undef KEYSPAN
40#endif
41#if defined(CONFIG_USB_SERIAL_XIRCOM) || defined(CONFIG_USB_SERIAL_XIRCOM_MODULE)
42 #define XIRCOM
43#else
44 #undef XIRCOM
45#endif
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/*
48 * Version Information
49 */
50#define DRIVER_VERSION "v1.1"
51#define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
52#define DRIVER_DESC "USB Keyspan PDA Converter driver"
53
54struct keyspan_pda_private {
55 int tx_room;
56 int tx_throttled;
57 struct work_struct wakeup_work;
58 struct work_struct unthrottle_work;
David Howellsc4028952006-11-22 14:57:56 +000059 struct usb_serial *serial;
60 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061};
62
63
64#define KEYSPAN_VENDOR_ID 0x06cd
65#define KEYSPAN_PDA_FAKE_ID 0x0103
66#define KEYSPAN_PDA_ID 0x0104 /* no clue */
67
68/* For Xircom PGSDB9 and older Entregra version of the same device */
69#define XIRCOM_VENDOR_ID 0x085a
70#define XIRCOM_FAKE_ID 0x8027
71#define ENTREGRA_VENDOR_ID 0x1645
72#define ENTREGRA_FAKE_ID 0x8093
73
Németh Márton7d40d7e2010-01-10 15:34:24 +010074static const struct usb_device_id id_table_combined[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070075#ifdef KEYSPAN
76 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
77#endif
78#ifdef XIRCOM
79 { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
80 { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
81#endif
82 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
83 { } /* Terminating entry */
84};
85
Alan Cox9e70f312008-07-22 11:13:42 +010086MODULE_DEVICE_TABLE(usb, id_table_combined);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
Németh Márton7d40d7e2010-01-10 15:34:24 +010088static const struct usb_device_id id_table_std[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
90 { } /* Terminating entry */
91};
92
93#ifdef KEYSPAN
Németh Márton7d40d7e2010-01-10 15:34:24 +010094static const struct usb_device_id id_table_fake[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
96 { } /* Terminating entry */
97};
98#endif
99
100#ifdef XIRCOM
Németh Márton7d40d7e2010-01-10 15:34:24 +0100101static const struct usb_device_id id_table_fake_xircom[] = {
Alan Cox9e70f312008-07-22 11:13:42 +0100102 { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
103 { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
104 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105};
106#endif
107
David Howellsc4028952006-11-22 14:57:56 +0000108static void keyspan_pda_wakeup_write(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
David Howellsc4028952006-11-22 14:57:56 +0000110 struct keyspan_pda_private *priv =
111 container_of(work, struct keyspan_pda_private, wakeup_work);
112 struct usb_serial_port *port = priv->port;
Alan Cox4a90f092008-10-13 10:39:46 +0100113 struct tty_struct *tty = tty_port_tty_get(&port->port);
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100114 if (tty)
115 tty_wakeup(tty);
Alan Cox4a90f092008-10-13 10:39:46 +0100116 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117}
118
David Howellsc4028952006-11-22 14:57:56 +0000119static void keyspan_pda_request_unthrottle(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120{
David Howellsc4028952006-11-22 14:57:56 +0000121 struct keyspan_pda_private *priv =
122 container_of(work, struct keyspan_pda_private, unthrottle_work);
123 struct usb_serial *serial = priv->serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 int result;
125
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 /* ask the device to tell us when the tx buffer becomes
127 sufficiently empty */
Alan Cox9e70f312008-07-22 11:13:42 +0100128 result = usb_control_msg(serial->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 usb_sndctrlpipe(serial->dev, 0),
130 7, /* request_unthrottle */
131 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
132 | USB_DIR_OUT,
133 16, /* value: threshold */
134 0, /* index */
135 NULL,
136 0,
137 2000);
138 if (result < 0)
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700139 dev_dbg(&serial->dev->dev, "%s - error %d from usb_control_msg\n",
140 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141}
142
143
Alan Cox9e70f312008-07-22 11:13:42 +0100144static void keyspan_pda_rx_interrupt(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145{
Ming Leicdc97792008-02-24 18:41:47 +0800146 struct usb_serial_port *port = urb->context;
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100147 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 unsigned char *data = urb->transfer_buffer;
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700149 int retval;
150 int status = urb->status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 struct keyspan_pda_private *priv;
152 priv = usb_get_serial_port_data(port);
153
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700154 switch (status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 case 0:
156 /* success */
157 break;
158 case -ECONNRESET:
159 case -ENOENT:
160 case -ESHUTDOWN:
161 /* this urb is terminated, clean up */
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700162 dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n", __func__, status);
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100163 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 default:
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700165 dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 goto exit;
167 }
168
Alan Cox9e70f312008-07-22 11:13:42 +0100169 /* see if the message is data or a status interrupt */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 switch (data[0]) {
171 case 0:
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100172 tty = tty_port_tty_get(&port->port);
173 /* rest of message is rx data */
174 if (tty && urb->actual_length) {
Alan Cox8dd03a52008-07-22 11:13:51 +0100175 tty_insert_flip_string(tty, data + 1,
176 urb->actual_length - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 tty_flip_buffer_push(tty);
178 }
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100179 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 break;
181 case 1:
182 /* status interrupt */
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700183 dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 switch (data[1]) {
185 case 1: /* modemline change */
186 break;
187 case 2: /* tx unthrottle interrupt */
188 priv->tx_throttled = 0;
189 /* queue up a wakeup at scheduler time */
190 schedule_work(&priv->wakeup_work);
191 break;
192 default:
193 break;
194 }
195 break;
196 default:
197 break;
198 }
199
200exit:
Alan Cox9e70f312008-07-22 11:13:42 +0100201 retval = usb_submit_urb(urb, GFP_ATOMIC);
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700202 if (retval)
Alan Cox4a90f092008-10-13 10:39:46 +0100203 dev_err(&port->dev,
204 "%s - usb_submit_urb failed with result %d",
205 __func__, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206}
207
208
Alan Cox95da3102008-07-22 11:09:07 +0100209static void keyspan_pda_rx_throttle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210{
211 /* stop receiving characters. We just turn off the URB request, and
212 let chars pile up in the device. If we're doing hardware
213 flowcontrol, the device will signal the other end when its buffer
214 fills up. If we're doing XON/XOFF, this would be a good time to
215 send an XOFF, although it might make sense to foist that off
216 upon the device too. */
Alan Cox95da3102008-07-22 11:09:07 +0100217 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman5542cf72012-05-03 16:44:23 -0700218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 usb_kill_urb(port->interrupt_in_urb);
220}
221
222
Alan Cox95da3102008-07-22 11:09:07 +0100223static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
Alan Cox95da3102008-07-22 11:09:07 +0100225 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 /* just restart the receive interrupt URB */
Greg Kroah-Hartman5542cf72012-05-03 16:44:23 -0700227
Oliver Neukum63832512009-10-07 10:50:23 +0200228 if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700229 dev_dbg(&port->dev, "usb_submit_urb(read urb) failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230}
231
232
Alan Cox9e70f312008-07-22 11:13:42 +0100233static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234{
235 int rc;
236 int bindex;
237
Alan Cox9e70f312008-07-22 11:13:42 +0100238 switch (baud) {
239 case 110:
240 bindex = 0;
241 break;
242 case 300:
243 bindex = 1;
244 break;
245 case 1200:
246 bindex = 2;
247 break;
248 case 2400:
249 bindex = 3;
250 break;
251 case 4800:
252 bindex = 4;
253 break;
254 case 9600:
255 bindex = 5;
256 break;
257 case 19200:
258 bindex = 6;
259 break;
260 case 38400:
261 bindex = 7;
262 break;
263 case 57600:
264 bindex = 8;
265 break;
266 case 115200:
267 bindex = 9;
268 break;
269 default:
270 bindex = 5; /* Default to 9600 */
271 baud = 9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 }
273
274 /* rather than figure out how to sleep while waiting for this
275 to complete, I just use the "legacy" API. */
276 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
277 0, /* set baud */
Alan Cox9e70f312008-07-22 11:13:42 +0100278 USB_TYPE_VENDOR
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 | USB_RECIP_INTERFACE
280 | USB_DIR_OUT, /* type */
281 bindex, /* value */
282 0, /* index */
283 NULL, /* &data */
284 0, /* size */
285 2000); /* timeout */
Alan Coxe7806e32007-12-13 16:15:28 -0800286 if (rc < 0)
287 return 0;
288 return baud;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289}
290
291
Alan Cox95da3102008-07-22 11:09:07 +0100292static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293{
Alan Cox95da3102008-07-22 11:09:07 +0100294 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 struct usb_serial *serial = port->serial;
296 int value;
297 int result;
298
299 if (break_state == -1)
300 value = 1; /* start break */
301 else
302 value = 0; /* clear break */
303 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
Alan Cox9e70f312008-07-22 11:13:42 +0100304 4, /* set break */
305 USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
306 value, 0, NULL, 0, 2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 if (result < 0)
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700308 dev_dbg(&port->dev, "%s - error %d from usb_control_msg\n",
309 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 /* there is something funky about this.. the TCSBRK that 'cu' performs
311 ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
312 seconds apart, but it feels like the break sent isn't as long as it
313 is on /dev/ttyS0 */
314}
315
316
Alan Cox95da3102008-07-22 11:09:07 +0100317static void keyspan_pda_set_termios(struct tty_struct *tty,
318 struct usb_serial_port *port, struct ktermios *old_termios)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319{
320 struct usb_serial *serial = port->serial;
Alan Coxe7806e32007-12-13 16:15:28 -0800321 speed_t speed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
323 /* cflag specifies lots of stuff: number of stop bits, parity, number
324 of data bits, baud. What can the device actually handle?:
325 CSTOPB (1 stop bit or 2)
326 PARENB (parity)
327 CSIZE (5bit .. 8bit)
328 There is minimal hw support for parity (a PSW bit seems to hold the
329 parity of whatever is in the accumulator). The UART either deals
330 with 10 bits (start, 8 data, stop) or 11 bits (start, 8 data,
331 1 special, stop). So, with firmware changes, we could do:
332 8N1: 10 bit
333 8N2: 11 bit, extra bit always (mark?)
334 8[EOMS]1: 11 bit, extra bit is parity
335 7[EOMS]1: 10 bit, b0/b7 is parity
336 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?)
337
338 HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS
339 bit.
340
341 For now, just do baud. */
342
Alan Cox95da3102008-07-22 11:09:07 +0100343 speed = tty_get_baud_rate(tty);
Alan Coxe7806e32007-12-13 16:15:28 -0800344 speed = keyspan_pda_setbaud(serial, speed);
345
346 if (speed == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700347 dev_dbg(&port->dev, "can't handle requested baud rate\n");
Alan Coxe7806e32007-12-13 16:15:28 -0800348 /* It hasn't changed so.. */
349 speed = tty_termios_baud_rate(old_termios);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 }
Alan Coxe7806e32007-12-13 16:15:28 -0800351 /* Only speed can change so copy the old h/w parameters
352 then encode the new speed */
Alan Cox95da3102008-07-22 11:09:07 +0100353 tty_termios_copy_hw(tty->termios, old_termios);
354 tty_encode_baud_rate(tty, speed, speed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355}
356
357
358/* modem control pins: DTR and RTS are outputs and can be controlled.
359 DCD, RI, DSR, CTS are inputs and can be read. All outputs can also be
360 read. The byte passed is: DTR(b7) DCD RI DSR CTS RTS(b2) unused unused */
361
362static int keyspan_pda_get_modem_info(struct usb_serial *serial,
363 unsigned char *value)
364{
365 int rc;
Johan Hovoldca65d252009-12-28 23:01:51 +0100366 u8 *data;
367
368 data = kmalloc(1, GFP_KERNEL);
369 if (!data)
370 return -ENOMEM;
371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
373 3, /* get pins */
374 USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
Johan Hovoldca65d252009-12-28 23:01:51 +0100375 0, 0, data, 1, 2000);
Benny Halevy3b36a8f2008-06-27 12:22:32 +0300376 if (rc >= 0)
Johan Hovoldca65d252009-12-28 23:01:51 +0100377 *value = *data;
378
379 kfree(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 return rc;
381}
382
383
384static int keyspan_pda_set_modem_info(struct usb_serial *serial,
385 unsigned char value)
386{
387 int rc;
388 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
389 3, /* set pins */
390 USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT,
391 value, 0, NULL, 0, 2000);
392 return rc;
393}
394
Alan Cox60b33c12011-02-14 16:26:14 +0000395static int keyspan_pda_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396{
Alan Cox95da3102008-07-22 11:09:07 +0100397 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 struct usb_serial *serial = port->serial;
399 int rc;
400 unsigned char status;
401 int value;
402
403 rc = keyspan_pda_get_modem_info(serial, &status);
404 if (rc < 0)
405 return rc;
406 value =
407 ((status & (1<<7)) ? TIOCM_DTR : 0) |
408 ((status & (1<<6)) ? TIOCM_CAR : 0) |
409 ((status & (1<<5)) ? TIOCM_RNG : 0) |
410 ((status & (1<<4)) ? TIOCM_DSR : 0) |
411 ((status & (1<<3)) ? TIOCM_CTS : 0) |
412 ((status & (1<<2)) ? TIOCM_RTS : 0);
413 return value;
414}
415
Alan Cox20b9d172011-02-14 16:26:50 +0000416static int keyspan_pda_tiocmset(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 unsigned int set, unsigned int clear)
418{
Alan Cox95da3102008-07-22 11:09:07 +0100419 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 struct usb_serial *serial = port->serial;
421 int rc;
422 unsigned char status;
423
424 rc = keyspan_pda_get_modem_info(serial, &status);
425 if (rc < 0)
426 return rc;
427
428 if (set & TIOCM_RTS)
429 status |= (1<<2);
430 if (set & TIOCM_DTR)
431 status |= (1<<7);
432
433 if (clear & TIOCM_RTS)
434 status &= ~(1<<2);
435 if (clear & TIOCM_DTR)
436 status &= ~(1<<7);
437 rc = keyspan_pda_set_modem_info(serial, status);
438 return rc;
439}
440
Alan Cox95da3102008-07-22 11:09:07 +0100441static int keyspan_pda_write(struct tty_struct *tty,
442 struct usb_serial_port *port, const unsigned char *buf, int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
444 struct usb_serial *serial = port->serial;
445 int request_unthrottle = 0;
446 int rc = 0;
447 struct keyspan_pda_private *priv;
448
449 priv = usb_get_serial_port_data(port);
450 /* guess how much room is left in the device's ring buffer, and if we
451 want to send more than that, check first, updating our notion of
452 what is left. If our write will result in no room left, ask the
453 device to give us an interrupt when the room available rises above
454 a threshold, and hold off all writers (eventually, those using
455 select() or poll() too) until we receive that unthrottle interrupt.
456 Block if we can't write anything at all, otherwise write as much as
457 we can. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 if (count == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700459 dev_dbg(&port->dev, "write request of 0 bytes\n");
Alan Cox9e70f312008-07-22 11:13:42 +0100460 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 }
462
463 /* we might block because of:
464 the TX urb is in-flight (wait until it completes)
465 the device is full (wait until it says there is room)
466 */
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200467 spin_lock_bh(&port->lock);
Johan Hovoldda280e32011-11-06 19:06:24 +0100468 if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) {
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200469 spin_unlock_bh(&port->lock);
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700470 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 }
Johan Hovoldda280e32011-11-06 19:06:24 +0100472 clear_bit(0, &port->write_urbs_free);
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200473 spin_unlock_bh(&port->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 /* At this point the URB is in our control, nobody else can submit it
476 again (the only sudden transition was the one from EINPROGRESS to
477 finished). Also, the tx process is not throttled. So we are
478 ready to write. */
479
480 count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
481
482 /* Check if we might overrun the Tx buffer. If so, ask the
483 device how much room it really has. This is done only on
484 scheduler time, since usb_control_msg() sleeps. */
485 if (count > priv->tx_room && !in_interrupt()) {
Johan Hovoldca65d252009-12-28 23:01:51 +0100486 u8 *room;
487
488 room = kmalloc(1, GFP_KERNEL);
489 if (!room) {
490 rc = -ENOMEM;
491 goto exit;
492 }
493
Alan Cox9e70f312008-07-22 11:13:42 +0100494 rc = usb_control_msg(serial->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 usb_rcvctrlpipe(serial->dev, 0),
496 6, /* write_room */
497 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
498 | USB_DIR_IN,
499 0, /* value: 0 means "remaining room" */
500 0, /* index */
Johan Hovoldca65d252009-12-28 23:01:51 +0100501 room,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 1,
503 2000);
Johan Hovoldca65d252009-12-28 23:01:51 +0100504 if (rc > 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700505 dev_dbg(&port->dev, "roomquery says %d\n", *room);
Johan Hovoldca65d252009-12-28 23:01:51 +0100506 priv->tx_room = *room;
507 }
508 kfree(room);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 if (rc < 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700510 dev_dbg(&port->dev, "roomquery failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 goto exit;
512 }
513 if (rc == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700514 dev_dbg(&port->dev, "roomquery returned 0 bytes\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 rc = -EIO; /* device didn't return any data */
516 goto exit;
517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 }
519 if (count > priv->tx_room) {
520 /* we're about to completely fill the Tx buffer, so
521 we'll be throttled afterwards. */
522 count = priv->tx_room;
523 request_unthrottle = 1;
524 }
525
526 if (count) {
527 /* now transfer data */
Alan Cox9e70f312008-07-22 11:13:42 +0100528 memcpy(port->write_urb->transfer_buffer, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 /* send the data out the bulk port */
530 port->write_urb->transfer_buffer_length = count;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 priv->tx_room -= count;
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 rc = usb_submit_urb(port->write_urb, GFP_ATOMIC);
535 if (rc) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700536 dev_dbg(&port->dev, "usb_submit_urb(write bulk) failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 goto exit;
538 }
Alan Cox9e70f312008-07-22 11:13:42 +0100539 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 /* There wasn't any room left, so we are throttled until
541 the buffer empties a bit */
542 request_unthrottle = 1;
543 }
544
545 if (request_unthrottle) {
546 priv->tx_throttled = 1; /* block writers */
547 schedule_work(&priv->unthrottle_work);
548 }
549
550 rc = count;
551exit:
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700552 if (rc < 0)
Johan Hovoldda280e32011-11-06 19:06:24 +0100553 set_bit(0, &port->write_urbs_free);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 return rc;
555}
556
557
Alan Cox9e70f312008-07-22 11:13:42 +0100558static void keyspan_pda_write_bulk_callback(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559{
Ming Leicdc97792008-02-24 18:41:47 +0800560 struct usb_serial_port *port = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 struct keyspan_pda_private *priv;
562
Johan Hovoldda280e32011-11-06 19:06:24 +0100563 set_bit(0, &port->write_urbs_free);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 priv = usb_get_serial_port_data(port);
565
566 /* queue up a wakeup at scheduler time */
567 schedule_work(&priv->wakeup_work);
568}
569
570
Alan Cox95da3102008-07-22 11:09:07 +0100571static int keyspan_pda_write_room(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572{
Alan Cox95da3102008-07-22 11:09:07 +0100573 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 struct keyspan_pda_private *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 priv = usb_get_serial_port_data(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 /* used by n_tty.c for processing of tabs and such. Giving it our
577 conservative guess is probably good enough, but needs testing by
578 running a console through the device. */
Alan Cox9e70f312008-07-22 11:13:42 +0100579 return priv->tx_room;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580}
581
582
Alan Cox95da3102008-07-22 11:09:07 +0100583static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584{
Alan Cox95da3102008-07-22 11:09:07 +0100585 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 struct keyspan_pda_private *priv;
Alan Coxa5b6f602008-04-08 17:16:06 +0100587 unsigned long flags;
588 int ret = 0;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 priv = usb_get_serial_port_data(port);
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 /* when throttled, return at least WAKEUP_CHARS to tell select() (via
593 n_tty.c:normal_poll() ) that we're not writeable. */
Alan Coxa5b6f602008-04-08 17:16:06 +0100594
595 spin_lock_irqsave(&port->lock, flags);
Johan Hovoldda280e32011-11-06 19:06:24 +0100596 if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled)
Alan Coxa5b6f602008-04-08 17:16:06 +0100597 ret = 256;
598 spin_unlock_irqrestore(&port->lock, flags);
599 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600}
601
602
Alan Cox335f8512009-06-11 12:26:29 +0100603static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
604{
605 struct usb_serial *serial = port->serial;
606
607 if (serial->dev) {
608 if (on)
609 keyspan_pda_set_modem_info(serial, (1<<7) | (1<< 2));
610 else
611 keyspan_pda_set_modem_info(serial, 0);
612 }
613}
614
Alan Cox335f8512009-06-11 12:26:29 +0100615
Alan Cox95da3102008-07-22 11:09:07 +0100616static int keyspan_pda_open(struct tty_struct *tty,
Alan Coxa509a7e2009-09-19 13:13:26 -0700617 struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618{
619 struct usb_serial *serial = port->serial;
Johan Hovoldca65d252009-12-28 23:01:51 +0100620 u8 *room;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 int rc = 0;
622 struct keyspan_pda_private *priv;
623
624 /* find out how much room is in the Tx ring */
Johan Hovoldca65d252009-12-28 23:01:51 +0100625 room = kmalloc(1, GFP_KERNEL);
626 if (!room)
627 return -ENOMEM;
628
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
630 6, /* write_room */
631 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
632 | USB_DIR_IN,
633 0, /* value */
634 0, /* index */
Johan Hovoldca65d252009-12-28 23:01:51 +0100635 room,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 1,
637 2000);
638 if (rc < 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700639 dev_dbg(&port->dev, "%s - roomquery failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 goto error;
641 }
642 if (rc == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700643 dev_dbg(&port->dev, "%s - roomquery returned 0 bytes\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 rc = -EIO;
645 goto error;
646 }
647 priv = usb_get_serial_port_data(port);
Johan Hovoldca65d252009-12-28 23:01:51 +0100648 priv->tx_room = *room;
649 priv->tx_throttled = *room ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 /*Start reading from the device*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
653 if (rc) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700654 dev_dbg(&port->dev, "%s - usb_submit_urb(read int) failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 goto error;
656 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657error:
Johan Hovoldca65d252009-12-28 23:01:51 +0100658 kfree(room);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 return rc;
660}
Alan Cox335f8512009-06-11 12:26:29 +0100661static void keyspan_pda_close(struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662{
663 struct usb_serial *serial = port->serial;
664
665 if (serial->dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 /* shutdown our bulk reads and writes */
667 usb_kill_urb(port->write_urb);
668 usb_kill_urb(port->interrupt_in_urb);
669 }
670}
671
672
673/* download the firmware to a "fake" device (pre-renumeration) */
Alan Cox9e70f312008-07-22 11:13:42 +0100674static int keyspan_pda_fake_startup(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675{
676 int response;
David Woodhouse3edbf982008-05-30 15:15:13 +0300677 const char *fw_name;
678 const struct ihex_binrec *record;
679 const struct firmware *fw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 /* download the firmware here ... */
Rene Buergelcc183e22012-09-18 09:00:41 +0200682 response = ezusb_fx1_set_reset(serial->dev, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683
David Woodhouse3edbf982008-05-30 15:15:13 +0300684 if (0) { ; }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685#ifdef KEYSPAN
David Woodhouse3edbf982008-05-30 15:15:13 +0300686 else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
687 fw_name = "keyspan_pda/keyspan_pda.fw";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688#endif
689#ifdef XIRCOM
David Woodhouse3edbf982008-05-30 15:15:13 +0300690 else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
691 (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
692 fw_name = "keyspan_pda/xircom_pgs.fw";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693#endif
David Woodhouse3edbf982008-05-30 15:15:13 +0300694 else {
Greg Kroah-Hartman194343d2008-08-20 16:56:34 -0700695 dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n",
696 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 return -ENODEV;
698 }
David Woodhouse3edbf982008-05-30 15:15:13 +0300699 if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
Greg Kroah-Hartman194343d2008-08-20 16:56:34 -0700700 dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
701 fw_name);
David Woodhouse3edbf982008-05-30 15:15:13 +0300702 return -ENOENT;
703 }
704 record = (const struct ihex_binrec *)fw->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705
David Woodhouse3edbf982008-05-30 15:15:13 +0300706 while (record) {
Rene Buergel99495c72012-09-13 22:14:38 +0200707 response = ezusb_writememory(serial->dev, be32_to_cpu(record->addr),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 (unsigned char *)record->data,
David Woodhouse3edbf982008-05-30 15:15:13 +0300709 be16_to_cpu(record->len), 0xa0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 if (response < 0) {
Greg Kroah-Hartman194343d2008-08-20 16:56:34 -0700711 dev_err(&serial->dev->dev, "ezusb_writememory failed "
712 "for Keyspan PDA firmware (%d %04X %p %d)\n",
713 response, be32_to_cpu(record->addr),
714 record->data, be16_to_cpu(record->len));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 break;
716 }
David Woodhouse3edbf982008-05-30 15:15:13 +0300717 record = ihex_next_binrec(record);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 }
David Woodhouse3edbf982008-05-30 15:15:13 +0300719 release_firmware(fw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 /* bring device out of reset. Renumeration will occur in a moment
721 and the new device will bind to the real driver */
Rene Buergelcc183e22012-09-18 09:00:41 +0200722 response = ezusb_fx1_set_reset(serial->dev, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723
724 /* we want this device to fail to have a driver assigned to it. */
Alan Cox9e70f312008-07-22 11:13:42 +0100725 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726}
727
Ben Hutchingse6c4ef92010-01-13 23:34:18 +0000728#ifdef KEYSPAN
729MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
730#endif
731#ifdef XIRCOM
732MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
733#endif
734
Alan Cox9e70f312008-07-22 11:13:42 +0100735static int keyspan_pda_startup(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736{
737
738 struct keyspan_pda_private *priv;
739
740 /* allocate the private data structures for all ports. Well, for all
741 one ports. */
742
743 priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
744 if (!priv)
Alan Cox9e70f312008-07-22 11:13:42 +0100745 return 1; /* error */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 usb_set_serial_port_data(serial->port[0], priv);
747 init_waitqueue_head(&serial->port[0]->write_wait);
David Howellsc4028952006-11-22 14:57:56 +0000748 INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
749 INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
750 priv->serial = serial;
751 priv->port = serial->port[0];
Alan Cox9e70f312008-07-22 11:13:42 +0100752 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753}
754
Alan Sternf9c99bb2009-06-02 11:53:55 -0400755static void keyspan_pda_release(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 kfree(usb_get_serial_port_data(serial->port[0]));
758}
759
760#ifdef KEYSPAN
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700761static struct usb_serial_driver keyspan_pda_fake_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700762 .driver = {
763 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700764 .name = "keyspan_pda_pre",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700765 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700766 .description = "Keyspan PDA - (prerenumeration)",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 .id_table = id_table_fake,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .num_ports = 1,
769 .attach = keyspan_pda_fake_startup,
770};
771#endif
772
773#ifdef XIRCOM
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700774static struct usb_serial_driver xircom_pgs_fake_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700775 .driver = {
776 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700777 .name = "xircom_no_firm",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700778 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700779 .description = "Xircom / Entregra PGS - (prerenumeration)",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 .id_table = id_table_fake_xircom,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 .num_ports = 1,
782 .attach = keyspan_pda_fake_startup,
783};
784#endif
785
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700786static struct usb_serial_driver keyspan_pda_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700787 .driver = {
788 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700789 .name = "keyspan_pda",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700790 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700791 .description = "Keyspan PDA",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 .id_table = id_table_std,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 .num_ports = 1,
Alan Cox335f8512009-06-11 12:26:29 +0100794 .dtr_rts = keyspan_pda_dtr_rts,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 .open = keyspan_pda_open,
796 .close = keyspan_pda_close,
797 .write = keyspan_pda_write,
798 .write_room = keyspan_pda_write_room,
799 .write_bulk_callback = keyspan_pda_write_bulk_callback,
800 .read_int_callback = keyspan_pda_rx_interrupt,
801 .chars_in_buffer = keyspan_pda_chars_in_buffer,
802 .throttle = keyspan_pda_rx_throttle,
803 .unthrottle = keyspan_pda_rx_unthrottle,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 .set_termios = keyspan_pda_set_termios,
805 .break_ctl = keyspan_pda_break_ctl,
806 .tiocmget = keyspan_pda_tiocmget,
807 .tiocmset = keyspan_pda_tiocmset,
808 .attach = keyspan_pda_startup,
Alan Sternf9c99bb2009-06-02 11:53:55 -0400809 .release = keyspan_pda_release,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810};
811
Greg Kroah-Hartman8c49fc92012-02-24 12:49:34 -0800812static struct usb_serial_driver * const serial_drivers[] = {
813 &keyspan_pda_device,
814#ifdef KEYSPAN
815 &keyspan_pda_fake_device,
816#endif
817#ifdef XIRCOM
818 &xircom_pgs_fake_device,
819#endif
820 NULL
821};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -0700823module_usb_serial_driver(serial_drivers, id_table_combined);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
Alan Cox9e70f312008-07-22 11:13:42 +0100825MODULE_AUTHOR(DRIVER_AUTHOR);
826MODULE_DESCRIPTION(DRIVER_DESC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827MODULE_LICENSE("GPL");