blob: 2230223978ca731bef98ffb09b121ad974ff649f [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>
Alan Cox9e70f312008-07-22 11:13:42 +010028#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/usb.h>
Greg Kroah-Hartmana9698882006-07-11 21:22:58 -070030#include <linux/usb/serial.h>
Rene Buergelcc183e22012-09-18 09:00:41 +020031#include <linux/usb/ezusb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Linus Torvalds1da177e2005-04-16 15:20:36 -070033/* make a simple define to handle if we are compiling keyspan_pda or xircom support */
34#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
35 #define KEYSPAN
36#else
37 #undef KEYSPAN
38#endif
39#if defined(CONFIG_USB_SERIAL_XIRCOM) || defined(CONFIG_USB_SERIAL_XIRCOM_MODULE)
40 #define XIRCOM
41#else
42 #undef XIRCOM
43#endif
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>"
46#define DRIVER_DESC "USB Keyspan PDA Converter driver"
47
48struct keyspan_pda_private {
49 int tx_room;
50 int tx_throttled;
51 struct work_struct wakeup_work;
52 struct work_struct unthrottle_work;
David Howellsc4028952006-11-22 14:57:56 +000053 struct usb_serial *serial;
54 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055};
56
57
58#define KEYSPAN_VENDOR_ID 0x06cd
59#define KEYSPAN_PDA_FAKE_ID 0x0103
60#define KEYSPAN_PDA_ID 0x0104 /* no clue */
61
62/* For Xircom PGSDB9 and older Entregra version of the same device */
63#define XIRCOM_VENDOR_ID 0x085a
64#define XIRCOM_FAKE_ID 0x8027
65#define ENTREGRA_VENDOR_ID 0x1645
66#define ENTREGRA_FAKE_ID 0x8093
67
Németh Márton7d40d7e2010-01-10 15:34:24 +010068static const struct usb_device_id id_table_combined[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#ifdef KEYSPAN
70 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
71#endif
72#ifdef XIRCOM
73 { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
74 { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
75#endif
76 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
77 { } /* Terminating entry */
78};
79
Alan Cox9e70f312008-07-22 11:13:42 +010080MODULE_DEVICE_TABLE(usb, id_table_combined);
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Németh Márton7d40d7e2010-01-10 15:34:24 +010082static const struct usb_device_id id_table_std[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
84 { } /* Terminating entry */
85};
86
87#ifdef KEYSPAN
Németh Márton7d40d7e2010-01-10 15:34:24 +010088static const struct usb_device_id id_table_fake[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) },
90 { } /* Terminating entry */
91};
92#endif
93
94#ifdef XIRCOM
Németh Márton7d40d7e2010-01-10 15:34:24 +010095static const struct usb_device_id id_table_fake_xircom[] = {
Alan Cox9e70f312008-07-22 11:13:42 +010096 { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
97 { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
98 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -070099};
100#endif
101
David Howellsc4028952006-11-22 14:57:56 +0000102static void keyspan_pda_wakeup_write(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103{
David Howellsc4028952006-11-22 14:57:56 +0000104 struct keyspan_pda_private *priv =
105 container_of(work, struct keyspan_pda_private, wakeup_work);
106 struct usb_serial_port *port = priv->port;
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100107
108 tty_port_tty_wakeup(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109}
110
David Howellsc4028952006-11-22 14:57:56 +0000111static void keyspan_pda_request_unthrottle(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112{
David Howellsc4028952006-11-22 14:57:56 +0000113 struct keyspan_pda_private *priv =
114 container_of(work, struct keyspan_pda_private, unthrottle_work);
115 struct usb_serial *serial = priv->serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 int result;
117
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 /* ask the device to tell us when the tx buffer becomes
119 sufficiently empty */
Alan Cox9e70f312008-07-22 11:13:42 +0100120 result = usb_control_msg(serial->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 usb_sndctrlpipe(serial->dev, 0),
122 7, /* request_unthrottle */
123 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
124 | USB_DIR_OUT,
125 16, /* value: threshold */
126 0, /* index */
127 NULL,
128 0,
129 2000);
130 if (result < 0)
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700131 dev_dbg(&serial->dev->dev, "%s - error %d from usb_control_msg\n",
132 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133}
134
135
Alan Cox9e70f312008-07-22 11:13:42 +0100136static void keyspan_pda_rx_interrupt(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137{
Ming Leicdc97792008-02-24 18:41:47 +0800138 struct usb_serial_port *port = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 unsigned char *data = urb->transfer_buffer;
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700140 int retval;
141 int status = urb->status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 struct keyspan_pda_private *priv;
143 priv = usb_get_serial_port_data(port);
144
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700145 switch (status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 case 0:
147 /* success */
148 break;
149 case -ECONNRESET:
150 case -ENOENT:
151 case -ESHUTDOWN:
152 /* this urb is terminated, clean up */
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700153 dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n", __func__, status);
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100154 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 default:
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700156 dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 goto exit;
158 }
159
Alan Cox9e70f312008-07-22 11:13:42 +0100160 /* see if the message is data or a status interrupt */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 switch (data[0]) {
162 case 0:
Jiri Slabyf7d7aed2011-02-28 10:34:05 +0100163 /* rest of message is rx data */
Jiri Slaby2e124b42013-01-03 15:53:06 +0100164 if (urb->actual_length) {
Jiri Slaby05c7cd32013-01-03 15:53:04 +0100165 tty_insert_flip_string(&port->port, data + 1,
Alan Cox8dd03a52008-07-22 11:13:51 +0100166 urb->actual_length - 1);
Jiri Slaby2e124b42013-01-03 15:53:06 +0100167 tty_flip_buffer_push(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 }
169 break;
170 case 1:
171 /* status interrupt */
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700172 dev_dbg(&port->dev, "rx int, d1=%d, d2=%d\n", data[1], data[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 switch (data[1]) {
174 case 1: /* modemline change */
175 break;
176 case 2: /* tx unthrottle interrupt */
177 priv->tx_throttled = 0;
178 /* queue up a wakeup at scheduler time */
179 schedule_work(&priv->wakeup_work);
180 break;
181 default:
182 break;
183 }
184 break;
185 default:
186 break;
187 }
188
189exit:
Alan Cox9e70f312008-07-22 11:13:42 +0100190 retval = usb_submit_urb(urb, GFP_ATOMIC);
Greg Kroah-Hartman23189ae2007-06-15 15:44:13 -0700191 if (retval)
Alan Cox4a90f092008-10-13 10:39:46 +0100192 dev_err(&port->dev,
193 "%s - usb_submit_urb failed with result %d",
194 __func__, retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195}
196
197
Alan Cox95da3102008-07-22 11:09:07 +0100198static void keyspan_pda_rx_throttle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199{
200 /* stop receiving characters. We just turn off the URB request, and
201 let chars pile up in the device. If we're doing hardware
202 flowcontrol, the device will signal the other end when its buffer
203 fills up. If we're doing XON/XOFF, this would be a good time to
204 send an XOFF, although it might make sense to foist that off
205 upon the device too. */
Alan Cox95da3102008-07-22 11:09:07 +0100206 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman5542cf72012-05-03 16:44:23 -0700207
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 usb_kill_urb(port->interrupt_in_urb);
209}
210
211
Alan Cox95da3102008-07-22 11:09:07 +0100212static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213{
Alan Cox95da3102008-07-22 11:09:07 +0100214 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 /* just restart the receive interrupt URB */
Greg Kroah-Hartman5542cf72012-05-03 16:44:23 -0700216
Oliver Neukum63832512009-10-07 10:50:23 +0200217 if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700218 dev_dbg(&port->dev, "usb_submit_urb(read urb) failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219}
220
221
Alan Cox9e70f312008-07-22 11:13:42 +0100222static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223{
224 int rc;
225 int bindex;
226
Alan Cox9e70f312008-07-22 11:13:42 +0100227 switch (baud) {
228 case 110:
229 bindex = 0;
230 break;
231 case 300:
232 bindex = 1;
233 break;
234 case 1200:
235 bindex = 2;
236 break;
237 case 2400:
238 bindex = 3;
239 break;
240 case 4800:
241 bindex = 4;
242 break;
243 case 9600:
244 bindex = 5;
245 break;
246 case 19200:
247 bindex = 6;
248 break;
249 case 38400:
250 bindex = 7;
251 break;
252 case 57600:
253 bindex = 8;
254 break;
255 case 115200:
256 bindex = 9;
257 break;
258 default:
259 bindex = 5; /* Default to 9600 */
260 baud = 9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262
263 /* rather than figure out how to sleep while waiting for this
264 to complete, I just use the "legacy" API. */
265 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
266 0, /* set baud */
Alan Cox9e70f312008-07-22 11:13:42 +0100267 USB_TYPE_VENDOR
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 | USB_RECIP_INTERFACE
269 | USB_DIR_OUT, /* type */
270 bindex, /* value */
271 0, /* index */
272 NULL, /* &data */
273 0, /* size */
274 2000); /* timeout */
Alan Coxe7806e32007-12-13 16:15:28 -0800275 if (rc < 0)
276 return 0;
277 return baud;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278}
279
280
Alan Cox95da3102008-07-22 11:09:07 +0100281static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282{
Alan Cox95da3102008-07-22 11:09:07 +0100283 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 struct usb_serial *serial = port->serial;
285 int value;
286 int result;
287
288 if (break_state == -1)
289 value = 1; /* start break */
290 else
291 value = 0; /* clear break */
292 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
Alan Cox9e70f312008-07-22 11:13:42 +0100293 4, /* set break */
294 USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
295 value, 0, NULL, 0, 2000);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 if (result < 0)
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700297 dev_dbg(&port->dev, "%s - error %d from usb_control_msg\n",
298 __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 /* there is something funky about this.. the TCSBRK that 'cu' performs
300 ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
301 seconds apart, but it feels like the break sent isn't as long as it
302 is on /dev/ttyS0 */
303}
304
305
Alan Cox95da3102008-07-22 11:09:07 +0100306static void keyspan_pda_set_termios(struct tty_struct *tty,
307 struct usb_serial_port *port, struct ktermios *old_termios)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308{
309 struct usb_serial *serial = port->serial;
Alan Coxe7806e32007-12-13 16:15:28 -0800310 speed_t speed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
312 /* cflag specifies lots of stuff: number of stop bits, parity, number
313 of data bits, baud. What can the device actually handle?:
314 CSTOPB (1 stop bit or 2)
315 PARENB (parity)
316 CSIZE (5bit .. 8bit)
317 There is minimal hw support for parity (a PSW bit seems to hold the
318 parity of whatever is in the accumulator). The UART either deals
319 with 10 bits (start, 8 data, stop) or 11 bits (start, 8 data,
320 1 special, stop). So, with firmware changes, we could do:
321 8N1: 10 bit
322 8N2: 11 bit, extra bit always (mark?)
323 8[EOMS]1: 11 bit, extra bit is parity
324 7[EOMS]1: 10 bit, b0/b7 is parity
325 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?)
326
Alan Coxadc8d742012-07-14 15:31:47 +0100327 HW flow control is dictated by the tty->termios.c_cflags & CRTSCTS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 bit.
329
330 For now, just do baud. */
331
Alan Cox95da3102008-07-22 11:09:07 +0100332 speed = tty_get_baud_rate(tty);
Alan Coxe7806e32007-12-13 16:15:28 -0800333 speed = keyspan_pda_setbaud(serial, speed);
334
335 if (speed == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700336 dev_dbg(&port->dev, "can't handle requested baud rate\n");
Alan Coxe7806e32007-12-13 16:15:28 -0800337 /* It hasn't changed so.. */
338 speed = tty_termios_baud_rate(old_termios);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 }
Alan Coxe7806e32007-12-13 16:15:28 -0800340 /* Only speed can change so copy the old h/w parameters
341 then encode the new speed */
Alan Coxadc8d742012-07-14 15:31:47 +0100342 tty_termios_copy_hw(&tty->termios, old_termios);
Alan Cox95da3102008-07-22 11:09:07 +0100343 tty_encode_baud_rate(tty, speed, speed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344}
345
346
347/* modem control pins: DTR and RTS are outputs and can be controlled.
348 DCD, RI, DSR, CTS are inputs and can be read. All outputs can also be
349 read. The byte passed is: DTR(b7) DCD RI DSR CTS RTS(b2) unused unused */
350
351static int keyspan_pda_get_modem_info(struct usb_serial *serial,
352 unsigned char *value)
353{
354 int rc;
Johan Hovoldca65d252009-12-28 23:01:51 +0100355 u8 *data;
356
357 data = kmalloc(1, GFP_KERNEL);
358 if (!data)
359 return -ENOMEM;
360
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
362 3, /* get pins */
363 USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
Johan Hovoldca65d252009-12-28 23:01:51 +0100364 0, 0, data, 1, 2000);
Benny Halevy3b36a8f2008-06-27 12:22:32 +0300365 if (rc >= 0)
Johan Hovoldca65d252009-12-28 23:01:51 +0100366 *value = *data;
367
368 kfree(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 return rc;
370}
371
372
373static int keyspan_pda_set_modem_info(struct usb_serial *serial,
374 unsigned char value)
375{
376 int rc;
377 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
378 3, /* set pins */
379 USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT,
380 value, 0, NULL, 0, 2000);
381 return rc;
382}
383
Alan Cox60b33c12011-02-14 16:26:14 +0000384static int keyspan_pda_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385{
Alan Cox95da3102008-07-22 11:09:07 +0100386 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 struct usb_serial *serial = port->serial;
388 int rc;
389 unsigned char status;
390 int value;
391
392 rc = keyspan_pda_get_modem_info(serial, &status);
393 if (rc < 0)
394 return rc;
395 value =
396 ((status & (1<<7)) ? TIOCM_DTR : 0) |
397 ((status & (1<<6)) ? TIOCM_CAR : 0) |
398 ((status & (1<<5)) ? TIOCM_RNG : 0) |
399 ((status & (1<<4)) ? TIOCM_DSR : 0) |
400 ((status & (1<<3)) ? TIOCM_CTS : 0) |
401 ((status & (1<<2)) ? TIOCM_RTS : 0);
402 return value;
403}
404
Alan Cox20b9d172011-02-14 16:26:50 +0000405static int keyspan_pda_tiocmset(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 unsigned int set, unsigned int clear)
407{
Alan Cox95da3102008-07-22 11:09:07 +0100408 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 struct usb_serial *serial = port->serial;
410 int rc;
411 unsigned char status;
412
413 rc = keyspan_pda_get_modem_info(serial, &status);
414 if (rc < 0)
415 return rc;
416
417 if (set & TIOCM_RTS)
418 status |= (1<<2);
419 if (set & TIOCM_DTR)
420 status |= (1<<7);
421
422 if (clear & TIOCM_RTS)
423 status &= ~(1<<2);
424 if (clear & TIOCM_DTR)
425 status &= ~(1<<7);
426 rc = keyspan_pda_set_modem_info(serial, status);
427 return rc;
428}
429
Alan Cox95da3102008-07-22 11:09:07 +0100430static int keyspan_pda_write(struct tty_struct *tty,
431 struct usb_serial_port *port, const unsigned char *buf, int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
433 struct usb_serial *serial = port->serial;
434 int request_unthrottle = 0;
435 int rc = 0;
436 struct keyspan_pda_private *priv;
437
438 priv = usb_get_serial_port_data(port);
439 /* guess how much room is left in the device's ring buffer, and if we
440 want to send more than that, check first, updating our notion of
441 what is left. If our write will result in no room left, ask the
442 device to give us an interrupt when the room available rises above
443 a threshold, and hold off all writers (eventually, those using
444 select() or poll() too) until we receive that unthrottle interrupt.
445 Block if we can't write anything at all, otherwise write as much as
446 we can. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 if (count == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700448 dev_dbg(&port->dev, "write request of 0 bytes\n");
Alan Cox9e70f312008-07-22 11:13:42 +0100449 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 }
451
452 /* we might block because of:
453 the TX urb is in-flight (wait until it completes)
454 the device is full (wait until it says there is room)
455 */
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200456 spin_lock_bh(&port->lock);
Johan Hovoldda280e32011-11-06 19:06:24 +0100457 if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) {
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200458 spin_unlock_bh(&port->lock);
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700459 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 }
Johan Hovoldda280e32011-11-06 19:06:24 +0100461 clear_bit(0, &port->write_urbs_free);
Peter Zijlstrae81ee632006-09-25 12:51:41 +0200462 spin_unlock_bh(&port->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
464 /* At this point the URB is in our control, nobody else can submit it
465 again (the only sudden transition was the one from EINPROGRESS to
466 finished). Also, the tx process is not throttled. So we are
467 ready to write. */
468
469 count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
470
471 /* Check if we might overrun the Tx buffer. If so, ask the
472 device how much room it really has. This is done only on
473 scheduler time, since usb_control_msg() sleeps. */
474 if (count > priv->tx_room && !in_interrupt()) {
Johan Hovoldca65d252009-12-28 23:01:51 +0100475 u8 *room;
476
477 room = kmalloc(1, GFP_KERNEL);
478 if (!room) {
479 rc = -ENOMEM;
480 goto exit;
481 }
482
Alan Cox9e70f312008-07-22 11:13:42 +0100483 rc = usb_control_msg(serial->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 usb_rcvctrlpipe(serial->dev, 0),
485 6, /* write_room */
486 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
487 | USB_DIR_IN,
488 0, /* value: 0 means "remaining room" */
489 0, /* index */
Johan Hovoldca65d252009-12-28 23:01:51 +0100490 room,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 1,
492 2000);
Johan Hovoldca65d252009-12-28 23:01:51 +0100493 if (rc > 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700494 dev_dbg(&port->dev, "roomquery says %d\n", *room);
Johan Hovoldca65d252009-12-28 23:01:51 +0100495 priv->tx_room = *room;
496 }
497 kfree(room);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 if (rc < 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700499 dev_dbg(&port->dev, "roomquery failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 goto exit;
501 }
502 if (rc == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700503 dev_dbg(&port->dev, "roomquery returned 0 bytes\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 rc = -EIO; /* device didn't return any data */
505 goto exit;
506 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
508 if (count > priv->tx_room) {
509 /* we're about to completely fill the Tx buffer, so
510 we'll be throttled afterwards. */
511 count = priv->tx_room;
512 request_unthrottle = 1;
513 }
514
515 if (count) {
516 /* now transfer data */
Alan Cox9e70f312008-07-22 11:13:42 +0100517 memcpy(port->write_urb->transfer_buffer, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 /* send the data out the bulk port */
519 port->write_urb->transfer_buffer_length = count;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 priv->tx_room -= count;
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 rc = usb_submit_urb(port->write_urb, GFP_ATOMIC);
524 if (rc) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700525 dev_dbg(&port->dev, "usb_submit_urb(write bulk) failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 goto exit;
527 }
Alan Cox9e70f312008-07-22 11:13:42 +0100528 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 /* There wasn't any room left, so we are throttled until
530 the buffer empties a bit */
531 request_unthrottle = 1;
532 }
533
534 if (request_unthrottle) {
535 priv->tx_throttled = 1; /* block writers */
536 schedule_work(&priv->unthrottle_work);
537 }
538
539 rc = count;
540exit:
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700541 if (rc < 0)
Johan Hovoldda280e32011-11-06 19:06:24 +0100542 set_bit(0, &port->write_urbs_free);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 return rc;
544}
545
546
Alan Cox9e70f312008-07-22 11:13:42 +0100547static void keyspan_pda_write_bulk_callback(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548{
Ming Leicdc97792008-02-24 18:41:47 +0800549 struct usb_serial_port *port = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 struct keyspan_pda_private *priv;
551
Johan Hovoldda280e32011-11-06 19:06:24 +0100552 set_bit(0, &port->write_urbs_free);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 priv = usb_get_serial_port_data(port);
554
555 /* queue up a wakeup at scheduler time */
556 schedule_work(&priv->wakeup_work);
557}
558
559
Alan Cox95da3102008-07-22 11:09:07 +0100560static int keyspan_pda_write_room(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561{
Alan Cox95da3102008-07-22 11:09:07 +0100562 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 struct keyspan_pda_private *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 priv = usb_get_serial_port_data(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 /* used by n_tty.c for processing of tabs and such. Giving it our
566 conservative guess is probably good enough, but needs testing by
567 running a console through the device. */
Alan Cox9e70f312008-07-22 11:13:42 +0100568 return priv->tx_room;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569}
570
571
Alan Cox95da3102008-07-22 11:09:07 +0100572static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573{
Alan Cox95da3102008-07-22 11:09:07 +0100574 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 struct keyspan_pda_private *priv;
Alan Coxa5b6f602008-04-08 17:16:06 +0100576 unsigned long flags;
577 int ret = 0;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 priv = usb_get_serial_port_data(port);
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 /* when throttled, return at least WAKEUP_CHARS to tell select() (via
582 n_tty.c:normal_poll() ) that we're not writeable. */
Alan Coxa5b6f602008-04-08 17:16:06 +0100583
584 spin_lock_irqsave(&port->lock, flags);
Johan Hovoldda280e32011-11-06 19:06:24 +0100585 if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled)
Alan Coxa5b6f602008-04-08 17:16:06 +0100586 ret = 256;
587 spin_unlock_irqrestore(&port->lock, flags);
588 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589}
590
591
Alan Cox335f8512009-06-11 12:26:29 +0100592static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
593{
594 struct usb_serial *serial = port->serial;
595
596 if (serial->dev) {
597 if (on)
598 keyspan_pda_set_modem_info(serial, (1<<7) | (1<< 2));
599 else
600 keyspan_pda_set_modem_info(serial, 0);
601 }
602}
603
Alan Cox335f8512009-06-11 12:26:29 +0100604
Alan Cox95da3102008-07-22 11:09:07 +0100605static int keyspan_pda_open(struct tty_struct *tty,
Alan Coxa509a7e2009-09-19 13:13:26 -0700606 struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607{
608 struct usb_serial *serial = port->serial;
Johan Hovoldca65d252009-12-28 23:01:51 +0100609 u8 *room;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 int rc = 0;
611 struct keyspan_pda_private *priv;
612
613 /* find out how much room is in the Tx ring */
Johan Hovoldca65d252009-12-28 23:01:51 +0100614 room = kmalloc(1, GFP_KERNEL);
615 if (!room)
616 return -ENOMEM;
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
619 6, /* write_room */
620 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
621 | USB_DIR_IN,
622 0, /* value */
623 0, /* index */
Johan Hovoldca65d252009-12-28 23:01:51 +0100624 room,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 1,
626 2000);
627 if (rc < 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700628 dev_dbg(&port->dev, "%s - roomquery failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 goto error;
630 }
631 if (rc == 0) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700632 dev_dbg(&port->dev, "%s - roomquery returned 0 bytes\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 rc = -EIO;
634 goto error;
635 }
636 priv = usb_get_serial_port_data(port);
Johan Hovoldca65d252009-12-28 23:01:51 +0100637 priv->tx_room = *room;
638 priv->tx_throttled = *room ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 /*Start reading from the device*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
642 if (rc) {
Greg Kroah-Hartman826575f2012-09-14 12:06:52 -0700643 dev_dbg(&port->dev, "%s - usb_submit_urb(read int) failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 goto error;
645 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646error:
Johan Hovoldca65d252009-12-28 23:01:51 +0100647 kfree(room);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 return rc;
649}
Alan Cox335f8512009-06-11 12:26:29 +0100650static void keyspan_pda_close(struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651{
652 struct usb_serial *serial = port->serial;
653
654 if (serial->dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 /* shutdown our bulk reads and writes */
656 usb_kill_urb(port->write_urb);
657 usb_kill_urb(port->interrupt_in_urb);
658 }
659}
660
661
662/* download the firmware to a "fake" device (pre-renumeration) */
Alan Cox9e70f312008-07-22 11:13:42 +0100663static int keyspan_pda_fake_startup(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664{
665 int response;
David Woodhouse3edbf982008-05-30 15:15:13 +0300666 const char *fw_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667
668 /* download the firmware here ... */
Rene Buergelcc183e22012-09-18 09:00:41 +0200669 response = ezusb_fx1_set_reset(serial->dev, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
David Woodhouse3edbf982008-05-30 15:15:13 +0300671 if (0) { ; }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672#ifdef KEYSPAN
David Woodhouse3edbf982008-05-30 15:15:13 +0300673 else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID)
674 fw_name = "keyspan_pda/keyspan_pda.fw";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675#endif
676#ifdef XIRCOM
David Woodhouse3edbf982008-05-30 15:15:13 +0300677 else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) ||
678 (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID))
679 fw_name = "keyspan_pda/xircom_pgs.fw";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680#endif
David Woodhouse3edbf982008-05-30 15:15:13 +0300681 else {
Greg Kroah-Hartman194343d2008-08-20 16:56:34 -0700682 dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n",
683 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 return -ENODEV;
685 }
Rene Buergel8d733e22012-09-18 09:02:01 +0200686
687 if (ezusb_fx1_ihex_firmware_download(serial->dev, fw_name) < 0) {
Greg Kroah-Hartman194343d2008-08-20 16:56:34 -0700688 dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
689 fw_name);
David Woodhouse3edbf982008-05-30 15:15:13 +0300690 return -ENOENT;
691 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
Rene Buergel8d733e22012-09-18 09:02:01 +0200693 /* after downloading firmware Renumeration will occur in a
694 moment and the new device will bind to the real driver */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
696 /* we want this device to fail to have a driver assigned to it. */
Alan Cox9e70f312008-07-22 11:13:42 +0100697 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698}
699
Ben Hutchingse6c4ef92010-01-13 23:34:18 +0000700#ifdef KEYSPAN
701MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
702#endif
703#ifdef XIRCOM
704MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
705#endif
706
Johan Hovold94ab71c2012-10-17 13:35:00 +0200707static int keyspan_pda_port_probe(struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708{
709
710 struct keyspan_pda_private *priv;
711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
713 if (!priv)
Johan Hovold94ab71c2012-10-17 13:35:00 +0200714 return -ENOMEM;
715
David Howellsc4028952006-11-22 14:57:56 +0000716 INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
717 INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
Johan Hovold94ab71c2012-10-17 13:35:00 +0200718 priv->serial = port->serial;
719 priv->port = port;
720
721 usb_set_serial_port_data(port, priv);
722
Alan Cox9e70f312008-07-22 11:13:42 +0100723 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724}
725
Johan Hovold94ab71c2012-10-17 13:35:00 +0200726static int keyspan_pda_port_remove(struct usb_serial_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727{
Johan Hovold94ab71c2012-10-17 13:35:00 +0200728 struct keyspan_pda_private *priv;
729
730 priv = usb_get_serial_port_data(port);
731 kfree(priv);
732
733 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734}
735
736#ifdef KEYSPAN
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700737static struct usb_serial_driver keyspan_pda_fake_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700738 .driver = {
739 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700740 .name = "keyspan_pda_pre",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700741 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700742 .description = "Keyspan PDA - (prerenumeration)",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 .id_table = id_table_fake,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 .num_ports = 1,
745 .attach = keyspan_pda_fake_startup,
746};
747#endif
748
749#ifdef XIRCOM
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700750static struct usb_serial_driver xircom_pgs_fake_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700751 .driver = {
752 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700753 .name = "xircom_no_firm",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700754 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700755 .description = "Xircom / Entregra PGS - (prerenumeration)",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 .id_table = id_table_fake_xircom,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 .num_ports = 1,
758 .attach = keyspan_pda_fake_startup,
759};
760#endif
761
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700762static struct usb_serial_driver keyspan_pda_device = {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700763 .driver = {
764 .owner = THIS_MODULE,
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700765 .name = "keyspan_pda",
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700766 },
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700767 .description = "Keyspan PDA",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .id_table = id_table_std,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 .num_ports = 1,
Alan Cox335f8512009-06-11 12:26:29 +0100770 .dtr_rts = keyspan_pda_dtr_rts,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 .open = keyspan_pda_open,
772 .close = keyspan_pda_close,
773 .write = keyspan_pda_write,
774 .write_room = keyspan_pda_write_room,
775 .write_bulk_callback = keyspan_pda_write_bulk_callback,
776 .read_int_callback = keyspan_pda_rx_interrupt,
777 .chars_in_buffer = keyspan_pda_chars_in_buffer,
778 .throttle = keyspan_pda_rx_throttle,
779 .unthrottle = keyspan_pda_rx_unthrottle,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 .set_termios = keyspan_pda_set_termios,
781 .break_ctl = keyspan_pda_break_ctl,
782 .tiocmget = keyspan_pda_tiocmget,
783 .tiocmset = keyspan_pda_tiocmset,
Johan Hovold94ab71c2012-10-17 13:35:00 +0200784 .port_probe = keyspan_pda_port_probe,
785 .port_remove = keyspan_pda_port_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786};
787
Greg Kroah-Hartman8c49fc92012-02-24 12:49:34 -0800788static struct usb_serial_driver * const serial_drivers[] = {
789 &keyspan_pda_device,
790#ifdef KEYSPAN
791 &keyspan_pda_fake_device,
792#endif
793#ifdef XIRCOM
794 &xircom_pgs_fake_device,
795#endif
796 NULL
797};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -0700799module_usb_serial_driver(serial_drivers, id_table_combined);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
Alan Cox9e70f312008-07-22 11:13:42 +0100801MODULE_AUTHOR(DRIVER_AUTHOR);
802MODULE_DESCRIPTION(DRIVER_DESC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803MODULE_LICENSE("GPL");