diff options
Diffstat (limited to 'drivers/usb/serial')
52 files changed, 3168 insertions, 6353 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index a0ecb42cb33a..bd8aab0ef1cf 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -425,6 +425,16 @@ config USB_SERIAL_MOS7720 | |||
425 | To compile this driver as a module, choose M here: the | 425 | To compile this driver as a module, choose M here: the |
426 | module will be called mos7720. | 426 | module will be called mos7720. |
427 | 427 | ||
428 | config USB_SERIAL_MOS7715_PARPORT | ||
429 | bool "Support for parallel port on the Moschip 7715" | ||
430 | depends on USB_SERIAL_MOS7720 | ||
431 | depends on PARPORT=y || PARPORT=USB_SERIAL_MOS7720 | ||
432 | select PARPORT_NOT_PC | ||
433 | ---help--- | ||
434 | Say Y if you have a Moschip 7715 device and would like to use | ||
435 | the parallel port it provides. The port will register with | ||
436 | the parport subsystem as a low-level driver. | ||
437 | |||
428 | config USB_SERIAL_MOS7840 | 438 | config USB_SERIAL_MOS7840 |
429 | tristate "USB Moschip 7840/7820 USB Serial Driver" | 439 | tristate "USB Moschip 7840/7820 USB Serial Driver" |
430 | ---help--- | 440 | ---help--- |
@@ -485,6 +495,7 @@ config USB_SERIAL_QCAUX | |||
485 | 495 | ||
486 | config USB_SERIAL_QUALCOMM | 496 | config USB_SERIAL_QUALCOMM |
487 | tristate "USB Qualcomm Serial modem" | 497 | tristate "USB Qualcomm Serial modem" |
498 | select USB_SERIAL_WWAN | ||
488 | help | 499 | help |
489 | Say Y here if you have a Qualcomm USB modem device. These are | 500 | Say Y here if you have a Qualcomm USB modem device. These are |
490 | usually wireless cellular modems. | 501 | usually wireless cellular modems. |
@@ -576,8 +587,12 @@ config USB_SERIAL_XIRCOM | |||
576 | To compile this driver as a module, choose M here: the | 587 | To compile this driver as a module, choose M here: the |
577 | module will be called keyspan_pda. | 588 | module will be called keyspan_pda. |
578 | 589 | ||
590 | config USB_SERIAL_WWAN | ||
591 | tristate | ||
592 | |||
579 | config USB_SERIAL_OPTION | 593 | config USB_SERIAL_OPTION |
580 | tristate "USB driver for GSM and CDMA modems" | 594 | tristate "USB driver for GSM and CDMA modems" |
595 | select USB_SERIAL_WWAN | ||
581 | help | 596 | help |
582 | Say Y here if you have a GSM or CDMA modem that's connected to USB. | 597 | Say Y here if you have a GSM or CDMA modem that's connected to USB. |
583 | 598 | ||
@@ -619,6 +634,14 @@ config USB_SERIAL_VIVOPAY_SERIAL | |||
619 | To compile this driver as a module, choose M here: the | 634 | To compile this driver as a module, choose M here: the |
620 | module will be called vivopay-serial. | 635 | module will be called vivopay-serial. |
621 | 636 | ||
637 | config USB_SERIAL_ZIO | ||
638 | tristate "ZIO Motherboard USB serial interface driver" | ||
639 | help | ||
640 | Say Y here if you want to use ZIO Motherboard. | ||
641 | |||
642 | To compile this driver as a module, choose M here: the | ||
643 | module will be called zio. | ||
644 | |||
622 | config USB_SERIAL_DEBUG | 645 | config USB_SERIAL_DEBUG |
623 | tristate "USB Debugging Device" | 646 | tristate "USB Debugging Device" |
624 | help | 647 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 83c9e431a568..e54c728c016e 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -52,9 +52,11 @@ obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | |||
52 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o | 52 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o |
53 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o | 53 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o |
54 | obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o | 54 | obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o |
55 | obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o | ||
55 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 56 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
56 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | 57 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o |
57 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 58 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
58 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o | 59 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o |
59 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o | 60 | obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o |
61 | obj-$(CONFIG_USB_SERIAL_ZIO) += zio.o | ||
60 | 62 | ||
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 4fd7af98b1ae..0db6ace16f7b 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -1,7 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * AIRcable USB Bluetooth Dongle Driver. | 2 | * AIRcable USB Bluetooth Dongle Driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> | ||
4 | * Copyright (C) 2006 Manuel Francisco Naranjo (naranjo.manuel@gmail.com) | 5 | * Copyright (C) 2006 Manuel Francisco Naranjo (naranjo.manuel@gmail.com) |
6 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | 7 | * This program is free software; you can redistribute it and/or modify it under |
6 | * the terms of the GNU General Public License version 2 as published by the | 8 | * the terms of the GNU General Public License version 2 as published by the |
7 | * Free Software Foundation. | 9 | * Free Software Foundation. |
@@ -42,10 +44,10 @@ | |||
42 | * | 44 | * |
43 | */ | 45 | */ |
44 | 46 | ||
47 | #include <asm/unaligned.h> | ||
45 | #include <linux/tty.h> | 48 | #include <linux/tty.h> |
46 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
47 | #include <linux/tty_flip.h> | 50 | #include <linux/tty_flip.h> |
48 | #include <linux/circ_buf.h> | ||
49 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
50 | #include <linux/usb/serial.h> | 52 | #include <linux/usb/serial.h> |
51 | 53 | ||
@@ -55,16 +57,12 @@ static int debug; | |||
55 | #define AIRCABLE_VID 0x16CA | 57 | #define AIRCABLE_VID 0x16CA |
56 | #define AIRCABLE_USB_PID 0x1502 | 58 | #define AIRCABLE_USB_PID 0x1502 |
57 | 59 | ||
58 | /* write buffer size defines */ | ||
59 | #define AIRCABLE_BUF_SIZE 2048 | ||
60 | |||
61 | /* Protocol Stuff */ | 60 | /* Protocol Stuff */ |
62 | #define HCI_HEADER_LENGTH 0x4 | 61 | #define HCI_HEADER_LENGTH 0x4 |
63 | #define TX_HEADER_0 0x20 | 62 | #define TX_HEADER_0 0x20 |
64 | #define TX_HEADER_1 0x29 | 63 | #define TX_HEADER_1 0x29 |
65 | #define RX_HEADER_0 0x00 | 64 | #define RX_HEADER_0 0x00 |
66 | #define RX_HEADER_1 0x20 | 65 | #define RX_HEADER_1 0x20 |
67 | #define MAX_HCI_FRAMESIZE 60 | ||
68 | #define HCI_COMPLETE_FRAME 64 | 66 | #define HCI_COMPLETE_FRAME 64 |
69 | 67 | ||
70 | /* rx_flags */ | 68 | /* rx_flags */ |
@@ -74,8 +72,8 @@ static int debug; | |||
74 | /* | 72 | /* |
75 | * Version Information | 73 | * Version Information |
76 | */ | 74 | */ |
77 | #define DRIVER_VERSION "v1.0b2" | 75 | #define DRIVER_VERSION "v2.0" |
78 | #define DRIVER_AUTHOR "Naranjo, Manuel Francisco <naranjo.manuel@gmail.com>" | 76 | #define DRIVER_AUTHOR "Naranjo, Manuel Francisco <naranjo.manuel@gmail.com>, Johan Hovold <jhovold@gmail.com>" |
79 | #define DRIVER_DESC "AIRcable USB Driver" | 77 | #define DRIVER_DESC "AIRcable USB Driver" |
80 | 78 | ||
81 | /* ID table that will be registered with USB core */ | 79 | /* ID table that will be registered with USB core */ |
@@ -85,226 +83,21 @@ static const struct usb_device_id id_table[] = { | |||
85 | }; | 83 | }; |
86 | MODULE_DEVICE_TABLE(usb, id_table); | 84 | MODULE_DEVICE_TABLE(usb, id_table); |
87 | 85 | ||
88 | 86 | static int aircable_prepare_write_buffer(struct usb_serial_port *port, | |
89 | /* Internal Structure */ | 87 | void *dest, size_t size) |
90 | struct aircable_private { | ||
91 | spinlock_t rx_lock; /* spinlock for the receive lines */ | ||
92 | struct circ_buf *tx_buf; /* write buffer */ | ||
93 | struct circ_buf *rx_buf; /* read buffer */ | ||
94 | int rx_flags; /* for throttilng */ | ||
95 | struct work_struct rx_work; /* work cue for the receiving line */ | ||
96 | struct usb_serial_port *port; /* USB port with which associated */ | ||
97 | }; | ||
98 | |||
99 | /* Private methods */ | ||
100 | |||
101 | /* Circular Buffer Methods, code from ti_usb_3410_5052 used */ | ||
102 | /* | ||
103 | * serial_buf_clear | ||
104 | * | ||
105 | * Clear out all data in the circular buffer. | ||
106 | */ | ||
107 | static void serial_buf_clear(struct circ_buf *cb) | ||
108 | { | ||
109 | cb->head = cb->tail = 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * serial_buf_alloc | ||
114 | * | ||
115 | * Allocate a circular buffer and all associated memory. | ||
116 | */ | ||
117 | static struct circ_buf *serial_buf_alloc(void) | ||
118 | { | ||
119 | struct circ_buf *cb; | ||
120 | cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL); | ||
121 | if (cb == NULL) | ||
122 | return NULL; | ||
123 | cb->buf = kmalloc(AIRCABLE_BUF_SIZE, GFP_KERNEL); | ||
124 | if (cb->buf == NULL) { | ||
125 | kfree(cb); | ||
126 | return NULL; | ||
127 | } | ||
128 | serial_buf_clear(cb); | ||
129 | return cb; | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * serial_buf_free | ||
134 | * | ||
135 | * Free the buffer and all associated memory. | ||
136 | */ | ||
137 | static void serial_buf_free(struct circ_buf *cb) | ||
138 | { | ||
139 | kfree(cb->buf); | ||
140 | kfree(cb); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * serial_buf_data_avail | ||
145 | * | ||
146 | * Return the number of bytes of data available in the circular | ||
147 | * buffer. | ||
148 | */ | ||
149 | static int serial_buf_data_avail(struct circ_buf *cb) | ||
150 | { | ||
151 | return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE); | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * serial_buf_put | ||
156 | * | ||
157 | * Copy data data from a user buffer and put it into the circular buffer. | ||
158 | * Restrict to the amount of space available. | ||
159 | * | ||
160 | * Return the number of bytes copied. | ||
161 | */ | ||
162 | static int serial_buf_put(struct circ_buf *cb, const char *buf, int count) | ||
163 | { | ||
164 | int c, ret = 0; | ||
165 | while (1) { | ||
166 | c = CIRC_SPACE_TO_END(cb->head, cb->tail, AIRCABLE_BUF_SIZE); | ||
167 | if (count < c) | ||
168 | c = count; | ||
169 | if (c <= 0) | ||
170 | break; | ||
171 | memcpy(cb->buf + cb->head, buf, c); | ||
172 | cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1); | ||
173 | buf += c; | ||
174 | count -= c; | ||
175 | ret = c; | ||
176 | } | ||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * serial_buf_get | ||
182 | * | ||
183 | * Get data from the circular buffer and copy to the given buffer. | ||
184 | * Restrict to the amount of data available. | ||
185 | * | ||
186 | * Return the number of bytes copied. | ||
187 | */ | ||
188 | static int serial_buf_get(struct circ_buf *cb, char *buf, int count) | ||
189 | { | ||
190 | int c, ret = 0; | ||
191 | while (1) { | ||
192 | c = CIRC_CNT_TO_END(cb->head, cb->tail, AIRCABLE_BUF_SIZE); | ||
193 | if (count < c) | ||
194 | c = count; | ||
195 | if (c <= 0) | ||
196 | break; | ||
197 | memcpy(buf, cb->buf + cb->tail, c); | ||
198 | cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1); | ||
199 | buf += c; | ||
200 | count -= c; | ||
201 | ret = c; | ||
202 | } | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | /* End of circula buffer methods */ | ||
207 | |||
208 | static void aircable_send(struct usb_serial_port *port) | ||
209 | { | 88 | { |
210 | int count, result; | 89 | int count; |
211 | struct aircable_private *priv = usb_get_serial_port_data(port); | 90 | unsigned char *buf = dest; |
212 | unsigned char *buf; | ||
213 | __le16 *dbuf; | ||
214 | dbg("%s - port %d", __func__, port->number); | ||
215 | if (port->write_urb_busy) | ||
216 | return; | ||
217 | |||
218 | count = min(serial_buf_data_avail(priv->tx_buf), MAX_HCI_FRAMESIZE); | ||
219 | if (count == 0) | ||
220 | return; | ||
221 | |||
222 | buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC); | ||
223 | if (!buf) { | ||
224 | dev_err(&port->dev, "%s- kzalloc(%d) failed.\n", | ||
225 | __func__, count + HCI_HEADER_LENGTH); | ||
226 | return; | ||
227 | } | ||
228 | 91 | ||
92 | count = kfifo_out_locked(&port->write_fifo, buf + HCI_HEADER_LENGTH, | ||
93 | size - HCI_HEADER_LENGTH, &port->lock); | ||
229 | buf[0] = TX_HEADER_0; | 94 | buf[0] = TX_HEADER_0; |
230 | buf[1] = TX_HEADER_1; | 95 | buf[1] = TX_HEADER_1; |
231 | dbuf = (__le16 *)&buf[2]; | 96 | put_unaligned_le16(count, &buf[2]); |
232 | *dbuf = cpu_to_le16((u16)count); | ||
233 | serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH, | ||
234 | MAX_HCI_FRAMESIZE); | ||
235 | |||
236 | memcpy(port->write_urb->transfer_buffer, buf, | ||
237 | count + HCI_HEADER_LENGTH); | ||
238 | |||
239 | kfree(buf); | ||
240 | port->write_urb_busy = 1; | ||
241 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
242 | count + HCI_HEADER_LENGTH, | ||
243 | port->write_urb->transfer_buffer); | ||
244 | port->write_urb->transfer_buffer_length = count + HCI_HEADER_LENGTH; | ||
245 | port->write_urb->dev = port->serial->dev; | ||
246 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
247 | |||
248 | if (result) { | ||
249 | dev_err(&port->dev, | ||
250 | "%s - failed submitting write urb, error %d\n", | ||
251 | __func__, result); | ||
252 | port->write_urb_busy = 0; | ||
253 | } | ||
254 | 97 | ||
255 | schedule_work(&port->work); | 98 | return count + HCI_HEADER_LENGTH; |
256 | } | 99 | } |
257 | 100 | ||
258 | static void aircable_read(struct work_struct *work) | ||
259 | { | ||
260 | struct aircable_private *priv = | ||
261 | container_of(work, struct aircable_private, rx_work); | ||
262 | struct usb_serial_port *port = priv->port; | ||
263 | struct tty_struct *tty; | ||
264 | unsigned char *data; | ||
265 | int count; | ||
266 | if (priv->rx_flags & THROTTLED) { | ||
267 | if (priv->rx_flags & ACTUALLY_THROTTLED) | ||
268 | schedule_work(&priv->rx_work); | ||
269 | return; | ||
270 | } | ||
271 | |||
272 | /* By now I will flush data to the tty in packages of no more than | ||
273 | * 64 bytes, to ensure I do not get throttled. | ||
274 | * Ask USB mailing list for better aproach. | ||
275 | */ | ||
276 | tty = tty_port_tty_get(&port->port); | ||
277 | |||
278 | if (!tty) { | ||
279 | schedule_work(&priv->rx_work); | ||
280 | dev_err(&port->dev, "%s - No tty available\n", __func__); | ||
281 | return ; | ||
282 | } | ||
283 | |||
284 | count = min(64, serial_buf_data_avail(priv->rx_buf)); | ||
285 | |||
286 | if (count <= 0) | ||
287 | goto out; /* We have finished sending everything. */ | ||
288 | |||
289 | tty_prepare_flip_string(tty, &data, count); | ||
290 | if (!data) { | ||
291 | dev_err(&port->dev, "%s- kzalloc(%d) failed.", | ||
292 | __func__, count); | ||
293 | goto out; | ||
294 | } | ||
295 | |||
296 | serial_buf_get(priv->rx_buf, data, count); | ||
297 | |||
298 | tty_flip_buffer_push(tty); | ||
299 | |||
300 | if (serial_buf_data_avail(priv->rx_buf)) | ||
301 | schedule_work(&priv->rx_work); | ||
302 | out: | ||
303 | tty_kref_put(tty); | ||
304 | return; | ||
305 | } | ||
306 | /* End of private methods */ | ||
307 | |||
308 | static int aircable_probe(struct usb_serial *serial, | 101 | static int aircable_probe(struct usb_serial *serial, |
309 | const struct usb_device_id *id) | 102 | const struct usb_device_id *id) |
310 | { | 103 | { |
@@ -330,247 +123,50 @@ static int aircable_probe(struct usb_serial *serial, | |||
330 | return 0; | 123 | return 0; |
331 | } | 124 | } |
332 | 125 | ||
333 | static int aircable_attach(struct usb_serial *serial) | 126 | static int aircable_process_packet(struct tty_struct *tty, |
334 | { | 127 | struct usb_serial_port *port, int has_headers, |
335 | struct usb_serial_port *port = serial->port[0]; | 128 | char *packet, int len) |
336 | struct aircable_private *priv; | ||
337 | |||
338 | priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); | ||
339 | if (!priv) { | ||
340 | dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, | ||
341 | sizeof(struct aircable_private)); | ||
342 | return -ENOMEM; | ||
343 | } | ||
344 | |||
345 | /* Allocation of Circular Buffers */ | ||
346 | priv->tx_buf = serial_buf_alloc(); | ||
347 | if (priv->tx_buf == NULL) { | ||
348 | kfree(priv); | ||
349 | return -ENOMEM; | ||
350 | } | ||
351 | |||
352 | priv->rx_buf = serial_buf_alloc(); | ||
353 | if (priv->rx_buf == NULL) { | ||
354 | kfree(priv->tx_buf); | ||
355 | kfree(priv); | ||
356 | return -ENOMEM; | ||
357 | } | ||
358 | |||
359 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | ||
360 | priv->port = port; | ||
361 | INIT_WORK(&priv->rx_work, aircable_read); | ||
362 | |||
363 | usb_set_serial_port_data(serial->port[0], priv); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static void aircable_release(struct usb_serial *serial) | ||
369 | { | 129 | { |
370 | 130 | if (has_headers) { | |
371 | struct usb_serial_port *port = serial->port[0]; | 131 | len -= HCI_HEADER_LENGTH; |
372 | struct aircable_private *priv = usb_get_serial_port_data(port); | 132 | packet += HCI_HEADER_LENGTH; |
373 | |||
374 | dbg("%s", __func__); | ||
375 | |||
376 | if (priv) { | ||
377 | serial_buf_free(priv->tx_buf); | ||
378 | serial_buf_free(priv->rx_buf); | ||
379 | kfree(priv); | ||
380 | } | 133 | } |
381 | } | 134 | if (len <= 0) { |
382 | 135 | dbg("%s - malformed packet", __func__); | |
383 | static int aircable_write_room(struct tty_struct *tty) | 136 | return 0; |
384 | { | ||
385 | struct usb_serial_port *port = tty->driver_data; | ||
386 | struct aircable_private *priv = usb_get_serial_port_data(port); | ||
387 | return serial_buf_data_avail(priv->tx_buf); | ||
388 | } | ||
389 | |||
390 | static int aircable_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
391 | const unsigned char *source, int count) | ||
392 | { | ||
393 | struct aircable_private *priv = usb_get_serial_port_data(port); | ||
394 | int temp; | ||
395 | |||
396 | dbg("%s - port %d, %d bytes", __func__, port->number, count); | ||
397 | |||
398 | usb_serial_debug_data(debug, &port->dev, __func__, count, source); | ||
399 | |||
400 | if (!count) { | ||
401 | dbg("%s - write request of 0 bytes", __func__); | ||
402 | return count; | ||
403 | } | 137 | } |
404 | 138 | ||
405 | temp = serial_buf_put(priv->tx_buf, source, count); | 139 | tty_insert_flip_string(tty, packet, len); |
406 | |||
407 | aircable_send(port); | ||
408 | |||
409 | if (count > AIRCABLE_BUF_SIZE) | ||
410 | count = AIRCABLE_BUF_SIZE; | ||
411 | |||
412 | return count; | ||
413 | 140 | ||
141 | return len; | ||
414 | } | 142 | } |
415 | 143 | ||
416 | static void aircable_write_bulk_callback(struct urb *urb) | 144 | static void aircable_process_read_urb(struct urb *urb) |
417 | { | 145 | { |
418 | struct usb_serial_port *port = urb->context; | 146 | struct usb_serial_port *port = urb->context; |
419 | int status = urb->status; | 147 | char *data = (char *)urb->transfer_buffer; |
420 | int result; | ||
421 | |||
422 | dbg("%s - urb status: %d", __func__ , status); | ||
423 | |||
424 | /* This has been taken from cypress_m8.c cypress_write_int_callback */ | ||
425 | switch (status) { | ||
426 | case 0: | ||
427 | /* success */ | ||
428 | break; | ||
429 | case -ECONNRESET: | ||
430 | case -ENOENT: | ||
431 | case -ESHUTDOWN: | ||
432 | /* this urb is terminated, clean up */ | ||
433 | dbg("%s - urb shutting down with status: %d", | ||
434 | __func__, status); | ||
435 | port->write_urb_busy = 0; | ||
436 | return; | ||
437 | default: | ||
438 | /* error in the urb, so we have to resubmit it */ | ||
439 | dbg("%s - Overflow in write", __func__); | ||
440 | dbg("%s - nonzero write bulk status received: %d", | ||
441 | __func__, status); | ||
442 | port->write_urb->transfer_buffer_length = 1; | ||
443 | port->write_urb->dev = port->serial->dev; | ||
444 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
445 | if (result) | ||
446 | dev_err(&urb->dev->dev, | ||
447 | "%s - failed resubmitting write urb, error %d\n", | ||
448 | __func__, result); | ||
449 | else | ||
450 | return; | ||
451 | } | ||
452 | |||
453 | port->write_urb_busy = 0; | ||
454 | |||
455 | aircable_send(port); | ||
456 | } | ||
457 | |||
458 | static void aircable_read_bulk_callback(struct urb *urb) | ||
459 | { | ||
460 | struct usb_serial_port *port = urb->context; | ||
461 | struct aircable_private *priv = usb_get_serial_port_data(port); | ||
462 | struct tty_struct *tty; | 148 | struct tty_struct *tty; |
463 | unsigned long no_packages, remaining, package_length, i; | 149 | int has_headers; |
464 | int result, shift = 0; | 150 | int count; |
465 | unsigned char *temp; | 151 | int len; |
466 | int status = urb->status; | 152 | int i; |
467 | |||
468 | dbg("%s - port %d", __func__, port->number); | ||
469 | |||
470 | if (status) { | ||
471 | dbg("%s - urb status = %d", __func__, status); | ||
472 | if (status == -EPROTO) { | ||
473 | dbg("%s - caught -EPROTO, resubmitting the urb", | ||
474 | __func__); | ||
475 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
476 | usb_rcvbulkpipe(port->serial->dev, | ||
477 | port->bulk_in_endpointAddress), | ||
478 | port->read_urb->transfer_buffer, | ||
479 | port->read_urb->transfer_buffer_length, | ||
480 | aircable_read_bulk_callback, port); | ||
481 | |||
482 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
483 | if (result) | ||
484 | dev_err(&urb->dev->dev, | ||
485 | "%s - failed resubmitting read urb, error %d\n", | ||
486 | __func__, result); | ||
487 | return; | ||
488 | } | ||
489 | dbg("%s - unable to handle the error, exiting.", __func__); | ||
490 | return; | ||
491 | } | ||
492 | |||
493 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
494 | urb->actual_length, urb->transfer_buffer); | ||
495 | 153 | ||
496 | tty = tty_port_tty_get(&port->port); | 154 | tty = tty_port_tty_get(&port->port); |
497 | if (tty && urb->actual_length) { | 155 | if (!tty) |
498 | if (urb->actual_length <= 2) { | 156 | return; |
499 | /* This is an incomplete package */ | ||
500 | serial_buf_put(priv->rx_buf, urb->transfer_buffer, | ||
501 | urb->actual_length); | ||
502 | } else { | ||
503 | temp = urb->transfer_buffer; | ||
504 | if (temp[0] == RX_HEADER_0) | ||
505 | shift = HCI_HEADER_LENGTH; | ||
506 | |||
507 | remaining = urb->actual_length; | ||
508 | no_packages = urb->actual_length / (HCI_COMPLETE_FRAME); | ||
509 | |||
510 | if (urb->actual_length % HCI_COMPLETE_FRAME != 0) | ||
511 | no_packages++; | ||
512 | 157 | ||
513 | for (i = 0; i < no_packages; i++) { | 158 | has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); |
514 | if (remaining > (HCI_COMPLETE_FRAME)) | ||
515 | package_length = HCI_COMPLETE_FRAME; | ||
516 | else | ||
517 | package_length = remaining; | ||
518 | remaining -= package_length; | ||
519 | 159 | ||
520 | serial_buf_put(priv->rx_buf, | 160 | count = 0; |
521 | urb->transfer_buffer + shift + | 161 | for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { |
522 | (HCI_COMPLETE_FRAME) * (i), | 162 | len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); |
523 | package_length - shift); | 163 | count += aircable_process_packet(tty, port, has_headers, |
524 | } | 164 | &data[i], len); |
525 | } | ||
526 | aircable_read(&priv->rx_work); | ||
527 | } | 165 | } |
528 | tty_kref_put(tty); | ||
529 | |||
530 | /* Schedule the next read */ | ||
531 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
532 | usb_rcvbulkpipe(port->serial->dev, | ||
533 | port->bulk_in_endpointAddress), | ||
534 | port->read_urb->transfer_buffer, | ||
535 | port->read_urb->transfer_buffer_length, | ||
536 | aircable_read_bulk_callback, port); | ||
537 | |||
538 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
539 | if (result && result != -EPERM) | ||
540 | dev_err(&urb->dev->dev, | ||
541 | "%s - failed resubmitting read urb, error %d\n", | ||
542 | __func__, result); | ||
543 | } | ||
544 | |||
545 | /* Based on ftdi_sio.c throttle */ | ||
546 | static void aircable_throttle(struct tty_struct *tty) | ||
547 | { | ||
548 | struct usb_serial_port *port = tty->driver_data; | ||
549 | struct aircable_private *priv = usb_get_serial_port_data(port); | ||
550 | 166 | ||
551 | dbg("%s - port %d", __func__, port->number); | 167 | if (count) |
552 | 168 | tty_flip_buffer_push(tty); | |
553 | spin_lock_irq(&priv->rx_lock); | 169 | tty_kref_put(tty); |
554 | priv->rx_flags |= THROTTLED; | ||
555 | spin_unlock_irq(&priv->rx_lock); | ||
556 | } | ||
557 | |||
558 | /* Based on ftdi_sio.c unthrottle */ | ||
559 | static void aircable_unthrottle(struct tty_struct *tty) | ||
560 | { | ||
561 | struct usb_serial_port *port = tty->driver_data; | ||
562 | struct aircable_private *priv = usb_get_serial_port_data(port); | ||
563 | int actually_throttled; | ||
564 | |||
565 | dbg("%s - port %d", __func__, port->number); | ||
566 | |||
567 | spin_lock_irq(&priv->rx_lock); | ||
568 | actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; | ||
569 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | ||
570 | spin_unlock_irq(&priv->rx_lock); | ||
571 | |||
572 | if (actually_throttled) | ||
573 | schedule_work(&priv->rx_work); | ||
574 | } | 170 | } |
575 | 171 | ||
576 | static struct usb_driver aircable_driver = { | 172 | static struct usb_driver aircable_driver = { |
@@ -589,15 +185,12 @@ static struct usb_serial_driver aircable_device = { | |||
589 | .usb_driver = &aircable_driver, | 185 | .usb_driver = &aircable_driver, |
590 | .id_table = id_table, | 186 | .id_table = id_table, |
591 | .num_ports = 1, | 187 | .num_ports = 1, |
592 | .attach = aircable_attach, | 188 | .bulk_out_size = HCI_COMPLETE_FRAME, |
593 | .probe = aircable_probe, | 189 | .probe = aircable_probe, |
594 | .release = aircable_release, | 190 | .process_read_urb = aircable_process_read_urb, |
595 | .write = aircable_write, | 191 | .prepare_write_buffer = aircable_prepare_write_buffer, |
596 | .write_room = aircable_write_room, | 192 | .throttle = usb_serial_generic_throttle, |
597 | .write_bulk_callback = aircable_write_bulk_callback, | 193 | .unthrottle = usb_serial_generic_unthrottle, |
598 | .read_bulk_callback = aircable_read_bulk_callback, | ||
599 | .throttle = aircable_throttle, | ||
600 | .unthrottle = aircable_unthrottle, | ||
601 | }; | 194 | }; |
602 | 195 | ||
603 | static int __init aircable_init(void) | 196 | static int __init aircable_init(void) |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 9b66bf19f751..4e41a2a39422 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -42,7 +42,7 @@ static int debug; | |||
42 | * Version information | 42 | * Version information |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define DRIVER_VERSION "v0.5" | 45 | #define DRIVER_VERSION "v0.6" |
46 | #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" | 46 | #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" |
47 | #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" | 47 | #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" |
48 | #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" | 48 | #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" |
@@ -355,14 +355,11 @@ static void ark3116_close(struct usb_serial_port *port) | |||
355 | /* deactivate interrupts */ | 355 | /* deactivate interrupts */ |
356 | ark3116_write_reg(serial, UART_IER, 0); | 356 | ark3116_write_reg(serial, UART_IER, 0); |
357 | 357 | ||
358 | /* shutdown any bulk reads that might be going on */ | 358 | usb_serial_generic_close(port); |
359 | if (serial->num_bulk_out) | ||
360 | usb_kill_urb(port->write_urb); | ||
361 | if (serial->num_bulk_in) | ||
362 | usb_kill_urb(port->read_urb); | ||
363 | if (serial->num_interrupt_in) | 359 | if (serial->num_interrupt_in) |
364 | usb_kill_urb(port->interrupt_in_urb); | 360 | usb_kill_urb(port->interrupt_in_urb); |
365 | } | 361 | } |
362 | |||
366 | } | 363 | } |
367 | 364 | ||
368 | static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) | 365 | static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -675,87 +672,45 @@ static void ark3116_read_int_callback(struct urb *urb) | |||
675 | * error for the next block of data as well... | 672 | * error for the next block of data as well... |
676 | * For now, let's pretend this can't happen. | 673 | * For now, let's pretend this can't happen. |
677 | */ | 674 | */ |
678 | 675 | static void ark3116_process_read_urb(struct urb *urb) | |
679 | static void send_to_tty(struct tty_struct *tty, | ||
680 | const unsigned char *chars, | ||
681 | size_t size, char flag) | ||
682 | { | 676 | { |
683 | if (size == 0) | 677 | struct usb_serial_port *port = urb->context; |
684 | return; | ||
685 | if (flag == TTY_NORMAL) { | ||
686 | tty_insert_flip_string(tty, chars, size); | ||
687 | } else { | ||
688 | int i; | ||
689 | for (i = 0; i < size; ++i) | ||
690 | tty_insert_flip_char(tty, chars[i], flag); | ||
691 | } | ||
692 | } | ||
693 | |||
694 | static void ark3116_read_bulk_callback(struct urb *urb) | ||
695 | { | ||
696 | struct usb_serial_port *port = urb->context; | ||
697 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 678 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
698 | const __u8 *data = urb->transfer_buffer; | ||
699 | int status = urb->status; | ||
700 | struct tty_struct *tty; | 679 | struct tty_struct *tty; |
680 | unsigned char *data = urb->transfer_buffer; | ||
681 | char tty_flag = TTY_NORMAL; | ||
701 | unsigned long flags; | 682 | unsigned long flags; |
702 | int result; | ||
703 | char flag; | ||
704 | __u32 lsr; | 683 | __u32 lsr; |
705 | 684 | ||
706 | switch (status) { | 685 | /* update line status */ |
707 | case -ECONNRESET: | 686 | spin_lock_irqsave(&priv->status_lock, flags); |
708 | case -ENOENT: | 687 | lsr = priv->lsr; |
709 | case -ESHUTDOWN: | 688 | priv->lsr &= ~UART_LSR_BRK_ERROR_BITS; |
710 | /* this urb is terminated, clean up */ | 689 | spin_unlock_irqrestore(&priv->status_lock, flags); |
711 | dbg("%s - urb shutting down with status: %d", | 690 | |
712 | __func__, status); | 691 | if (!urb->actual_length) |
713 | return; | 692 | return; |
714 | default: | ||
715 | dbg("%s - nonzero urb status received: %d", | ||
716 | __func__, status); | ||
717 | break; | ||
718 | case 0: /* success */ | ||
719 | 693 | ||
720 | spin_lock_irqsave(&priv->status_lock, flags); | 694 | tty = tty_port_tty_get(&port->port); |
721 | lsr = priv->lsr; | 695 | if (!tty) |
722 | /* clear error bits */ | 696 | return; |
723 | priv->lsr &= ~UART_LSR_BRK_ERROR_BITS; | 697 | |
724 | spin_unlock_irqrestore(&priv->status_lock, flags); | 698 | if (lsr & UART_LSR_BRK_ERROR_BITS) { |
725 | 699 | if (lsr & UART_LSR_BI) | |
726 | if (unlikely(lsr & UART_LSR_BI)) | 700 | tty_flag = TTY_BREAK; |
727 | flag = TTY_BREAK; | 701 | else if (lsr & UART_LSR_PE) |
728 | else if (unlikely(lsr & UART_LSR_PE)) | 702 | tty_flag = TTY_PARITY; |
729 | flag = TTY_PARITY; | 703 | else if (lsr & UART_LSR_FE) |
730 | else if (unlikely(lsr & UART_LSR_FE)) | 704 | tty_flag = TTY_FRAME; |
731 | flag = TTY_FRAME; | ||
732 | else | ||
733 | flag = TTY_NORMAL; | ||
734 | |||
735 | tty = tty_port_tty_get(&port->port); | ||
736 | if (tty) { | ||
737 | /* overrun is special, not associated with a char */ | ||
738 | if (unlikely(lsr & UART_LSR_OE)) | ||
739 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
740 | send_to_tty(tty, data, urb->actual_length, flag); | ||
741 | tty_flip_buffer_push(tty); | ||
742 | tty_kref_put(tty); | ||
743 | } | ||
744 | 705 | ||
745 | /* Throttle the device if requested by tty */ | 706 | /* overrun is special, not associated with a char */ |
746 | spin_lock_irqsave(&port->lock, flags); | 707 | if (lsr & UART_LSR_OE) |
747 | port->throttled = port->throttle_req; | 708 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
748 | if (port->throttled) { | ||
749 | spin_unlock_irqrestore(&port->lock, flags); | ||
750 | return; | ||
751 | } else | ||
752 | spin_unlock_irqrestore(&port->lock, flags); | ||
753 | } | 709 | } |
754 | /* Continue reading from device */ | 710 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, |
755 | result = usb_submit_urb(urb, GFP_ATOMIC); | 711 | urb->actual_length); |
756 | if (result) | 712 | tty_flip_buffer_push(tty); |
757 | dev_err(&urb->dev->dev, "%s - failed resubmitting" | 713 | tty_kref_put(tty); |
758 | " read urb, error %d\n", __func__, result); | ||
759 | } | 714 | } |
760 | 715 | ||
761 | static struct usb_driver ark3116_driver = { | 716 | static struct usb_driver ark3116_driver = { |
@@ -785,7 +740,7 @@ static struct usb_serial_driver ark3116_device = { | |||
785 | .close = ark3116_close, | 740 | .close = ark3116_close, |
786 | .break_ctl = ark3116_break_ctl, | 741 | .break_ctl = ark3116_break_ctl, |
787 | .read_int_callback = ark3116_read_int_callback, | 742 | .read_int_callback = ark3116_read_int_callback, |
788 | .read_bulk_callback = ark3116_read_bulk_callback, | 743 | .process_read_urb = ark3116_process_read_urb, |
789 | }; | 744 | }; |
790 | 745 | ||
791 | static int __init ark3116_init(void) | 746 | static int __init ark3116_init(void) |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 1295e44e3f1c..36df35295db2 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) | 4 | * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) |
5 | * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) |
6 | * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) | ||
6 | * | 7 | * |
7 | * This program is largely derived from work by the linux-usb group | 8 | * This program is largely derived from work by the linux-usb group |
8 | * and associated source files. Please see the usb/serial files for | 9 | * and associated source files. Please see the usb/serial files for |
@@ -84,7 +85,7 @@ static int debug; | |||
84 | /* | 85 | /* |
85 | * Version Information | 86 | * Version Information |
86 | */ | 87 | */ |
87 | #define DRIVER_VERSION "v1.2" | 88 | #define DRIVER_VERSION "v1.3" |
88 | #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" | 89 | #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" |
89 | #define DRIVER_DESC "USB Belkin Serial converter driver" | 90 | #define DRIVER_DESC "USB Belkin Serial converter driver" |
90 | 91 | ||
@@ -95,6 +96,7 @@ static int belkin_sa_open(struct tty_struct *tty, | |||
95 | struct usb_serial_port *port); | 96 | struct usb_serial_port *port); |
96 | static void belkin_sa_close(struct usb_serial_port *port); | 97 | static void belkin_sa_close(struct usb_serial_port *port); |
97 | static void belkin_sa_read_int_callback(struct urb *urb); | 98 | static void belkin_sa_read_int_callback(struct urb *urb); |
99 | static void belkin_sa_process_read_urb(struct urb *urb); | ||
98 | static void belkin_sa_set_termios(struct tty_struct *tty, | 100 | static void belkin_sa_set_termios(struct tty_struct *tty, |
99 | struct usb_serial_port *port, struct ktermios * old); | 101 | struct usb_serial_port *port, struct ktermios * old); |
100 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); | 102 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); |
@@ -112,7 +114,6 @@ static const struct usb_device_id id_table_combined[] = { | |||
112 | { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, | 114 | { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, |
113 | { } /* Terminating entry */ | 115 | { } /* Terminating entry */ |
114 | }; | 116 | }; |
115 | |||
116 | MODULE_DEVICE_TABLE(usb, id_table_combined); | 117 | MODULE_DEVICE_TABLE(usb, id_table_combined); |
117 | 118 | ||
118 | static struct usb_driver belkin_driver = { | 119 | static struct usb_driver belkin_driver = { |
@@ -120,7 +121,7 @@ static struct usb_driver belkin_driver = { | |||
120 | .probe = usb_serial_probe, | 121 | .probe = usb_serial_probe, |
121 | .disconnect = usb_serial_disconnect, | 122 | .disconnect = usb_serial_disconnect, |
122 | .id_table = id_table_combined, | 123 | .id_table = id_table_combined, |
123 | .no_dynamic_id = 1, | 124 | .no_dynamic_id = 1, |
124 | }; | 125 | }; |
125 | 126 | ||
126 | /* All of the device info needed for the serial converters */ | 127 | /* All of the device info needed for the serial converters */ |
@@ -136,7 +137,7 @@ static struct usb_serial_driver belkin_device = { | |||
136 | .open = belkin_sa_open, | 137 | .open = belkin_sa_open, |
137 | .close = belkin_sa_close, | 138 | .close = belkin_sa_close, |
138 | .read_int_callback = belkin_sa_read_int_callback, | 139 | .read_int_callback = belkin_sa_read_int_callback, |
139 | /* How we get the status info */ | 140 | .process_read_urb = belkin_sa_process_read_urb, |
140 | .set_termios = belkin_sa_set_termios, | 141 | .set_termios = belkin_sa_set_termios, |
141 | .break_ctl = belkin_sa_break_ctl, | 142 | .break_ctl = belkin_sa_break_ctl, |
142 | .tiocmget = belkin_sa_tiocmget, | 143 | .tiocmget = belkin_sa_tiocmget, |
@@ -145,7 +146,6 @@ static struct usb_serial_driver belkin_device = { | |||
145 | .release = belkin_sa_release, | 146 | .release = belkin_sa_release, |
146 | }; | 147 | }; |
147 | 148 | ||
148 | |||
149 | struct belkin_sa_private { | 149 | struct belkin_sa_private { |
150 | spinlock_t lock; | 150 | spinlock_t lock; |
151 | unsigned long control_state; | 151 | unsigned long control_state; |
@@ -196,62 +196,43 @@ static int belkin_sa_startup(struct usb_serial *serial) | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | |||
200 | static void belkin_sa_release(struct usb_serial *serial) | 199 | static void belkin_sa_release(struct usb_serial *serial) |
201 | { | 200 | { |
202 | struct belkin_sa_private *priv; | ||
203 | int i; | 201 | int i; |
204 | 202 | ||
205 | dbg("%s", __func__); | 203 | dbg("%s", __func__); |
206 | 204 | ||
207 | for (i = 0; i < serial->num_ports; ++i) { | 205 | for (i = 0; i < serial->num_ports; ++i) |
208 | /* My special items, the standard routines free my urbs */ | 206 | kfree(usb_get_serial_port_data(serial->port[i])); |
209 | priv = usb_get_serial_port_data(serial->port[i]); | ||
210 | kfree(priv); | ||
211 | } | ||
212 | } | 207 | } |
213 | 208 | ||
214 | 209 | static int belkin_sa_open(struct tty_struct *tty, | |
215 | static int belkin_sa_open(struct tty_struct *tty, | ||
216 | struct usb_serial_port *port) | 210 | struct usb_serial_port *port) |
217 | { | 211 | { |
218 | int retval = 0; | 212 | int retval; |
219 | 213 | ||
220 | dbg("%s port %d", __func__, port->number); | 214 | dbg("%s port %d", __func__, port->number); |
221 | 215 | ||
222 | /*Start reading from the device*/ | ||
223 | /* TODO: Look at possibility of submitting multiple URBs to device to | ||
224 | * enhance buffering. Win trace shows 16 initial read URBs. | ||
225 | */ | ||
226 | port->read_urb->dev = port->serial->dev; | ||
227 | retval = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
228 | if (retval) { | ||
229 | dev_err(&port->dev, "usb_submit_urb(read bulk) failed\n"); | ||
230 | goto exit; | ||
231 | } | ||
232 | |||
233 | port->interrupt_in_urb->dev = port->serial->dev; | ||
234 | retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 216 | retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
235 | if (retval) { | 217 | if (retval) { |
236 | usb_kill_urb(port->read_urb); | ||
237 | dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); | 218 | dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); |
219 | return retval; | ||
238 | } | 220 | } |
239 | 221 | ||
240 | exit: | 222 | retval = usb_serial_generic_open(tty, port); |
241 | return retval; | 223 | if (retval) |
242 | } /* belkin_sa_open */ | 224 | usb_kill_urb(port->interrupt_in_urb); |
243 | 225 | ||
226 | return retval; | ||
227 | } | ||
244 | 228 | ||
245 | static void belkin_sa_close(struct usb_serial_port *port) | 229 | static void belkin_sa_close(struct usb_serial_port *port) |
246 | { | 230 | { |
247 | dbg("%s port %d", __func__, port->number); | 231 | dbg("%s port %d", __func__, port->number); |
248 | 232 | ||
249 | /* shutdown our bulk reads and writes */ | 233 | usb_serial_generic_close(port); |
250 | usb_kill_urb(port->write_urb); | ||
251 | usb_kill_urb(port->read_urb); | ||
252 | usb_kill_urb(port->interrupt_in_urb); | 234 | usb_kill_urb(port->interrupt_in_urb); |
253 | } /* belkin_sa_close */ | 235 | } |
254 | |||
255 | 236 | ||
256 | static void belkin_sa_read_int_callback(struct urb *urb) | 237 | static void belkin_sa_read_int_callback(struct urb *urb) |
257 | { | 238 | { |
@@ -310,31 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb) | |||
310 | else | 291 | else |
311 | priv->control_state &= ~TIOCM_CD; | 292 | priv->control_state &= ~TIOCM_CD; |
312 | 293 | ||
313 | /* Now to report any errors */ | ||
314 | priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; | 294 | priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; |
315 | #if 0 | ||
316 | /* | ||
317 | * fill in the flip buffer here, but I do not know the relation | ||
318 | * to the current/next receive buffer or characters. I need | ||
319 | * to look in to this before committing any code. | ||
320 | */ | ||
321 | if (priv->last_lsr & BELKIN_SA_LSR_ERR) { | ||
322 | tty = tty_port_tty_get(&port->port); | ||
323 | /* Overrun Error */ | ||
324 | if (priv->last_lsr & BELKIN_SA_LSR_OE) { | ||
325 | } | ||
326 | /* Parity Error */ | ||
327 | if (priv->last_lsr & BELKIN_SA_LSR_PE) { | ||
328 | } | ||
329 | /* Framing Error */ | ||
330 | if (priv->last_lsr & BELKIN_SA_LSR_FE) { | ||
331 | } | ||
332 | /* Break Indicator */ | ||
333 | if (priv->last_lsr & BELKIN_SA_LSR_BI) { | ||
334 | } | ||
335 | tty_kref_put(tty); | ||
336 | } | ||
337 | #endif | ||
338 | spin_unlock_irqrestore(&priv->lock, flags); | 295 | spin_unlock_irqrestore(&priv->lock, flags); |
339 | exit: | 296 | exit: |
340 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 297 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -343,6 +300,53 @@ exit: | |||
343 | "result %d\n", __func__, retval); | 300 | "result %d\n", __func__, retval); |
344 | } | 301 | } |
345 | 302 | ||
303 | static void belkin_sa_process_read_urb(struct urb *urb) | ||
304 | { | ||
305 | struct usb_serial_port *port = urb->context; | ||
306 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | ||
307 | struct tty_struct *tty; | ||
308 | unsigned char *data = urb->transfer_buffer; | ||
309 | unsigned long flags; | ||
310 | unsigned char status; | ||
311 | char tty_flag; | ||
312 | |||
313 | /* Update line status */ | ||
314 | tty_flag = TTY_NORMAL; | ||
315 | |||
316 | spin_lock_irqsave(&priv->lock, flags); | ||
317 | status = priv->last_lsr; | ||
318 | priv->last_lsr &= ~BELKIN_SA_LSR_ERR; | ||
319 | spin_unlock_irqrestore(&priv->lock, flags); | ||
320 | |||
321 | if (!urb->actual_length) | ||
322 | return; | ||
323 | |||
324 | tty = tty_port_tty_get(&port->port); | ||
325 | if (!tty) | ||
326 | return; | ||
327 | |||
328 | if (status & BELKIN_SA_LSR_ERR) { | ||
329 | /* Break takes precedence over parity, which takes precedence | ||
330 | * over framing errors. */ | ||
331 | if (status & BELKIN_SA_LSR_BI) | ||
332 | tty_flag = TTY_BREAK; | ||
333 | else if (status & BELKIN_SA_LSR_PE) | ||
334 | tty_flag = TTY_PARITY; | ||
335 | else if (status & BELKIN_SA_LSR_FE) | ||
336 | tty_flag = TTY_FRAME; | ||
337 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); | ||
338 | |||
339 | /* Overrun is special, not associated with a char. */ | ||
340 | if (status & BELKIN_SA_LSR_OE) | ||
341 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
342 | } | ||
343 | |||
344 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | ||
345 | urb->actual_length); | ||
346 | tty_flip_buffer_push(tty); | ||
347 | tty_kref_put(tty); | ||
348 | } | ||
349 | |||
346 | static void belkin_sa_set_termios(struct tty_struct *tty, | 350 | static void belkin_sa_set_termios(struct tty_struct *tty, |
347 | struct usb_serial_port *port, struct ktermios *old_termios) | 351 | struct usb_serial_port *port, struct ktermios *old_termios) |
348 | { | 352 | { |
@@ -482,8 +486,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, | |||
482 | spin_lock_irqsave(&priv->lock, flags); | 486 | spin_lock_irqsave(&priv->lock, flags); |
483 | priv->control_state = control_state; | 487 | priv->control_state = control_state; |
484 | spin_unlock_irqrestore(&priv->lock, flags); | 488 | spin_unlock_irqrestore(&priv->lock, flags); |
485 | } /* belkin_sa_set_termios */ | 489 | } |
486 | |||
487 | 490 | ||
488 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) | 491 | static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) |
489 | { | 492 | { |
@@ -494,7 +497,6 @@ static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) | |||
494 | dev_err(&port->dev, "Set break_ctl %d\n", break_state); | 497 | dev_err(&port->dev, "Set break_ctl %d\n", break_state); |
495 | } | 498 | } |
496 | 499 | ||
497 | |||
498 | static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) | 500 | static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) |
499 | { | 501 | { |
500 | struct usb_serial_port *port = tty->driver_data; | 502 | struct usb_serial_port *port = tty->driver_data; |
@@ -511,7 +513,6 @@ static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) | |||
511 | return control_state; | 513 | return control_state; |
512 | } | 514 | } |
513 | 515 | ||
514 | |||
515 | static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, | 516 | static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, |
516 | unsigned int set, unsigned int clear) | 517 | unsigned int set, unsigned int clear) |
517 | { | 518 | { |
@@ -583,7 +584,6 @@ failed_usb_serial_register: | |||
583 | return retval; | 584 | return retval; |
584 | } | 585 | } |
585 | 586 | ||
586 | |||
587 | static void __exit belkin_sa_exit (void) | 587 | static void __exit belkin_sa_exit (void) |
588 | { | 588 | { |
589 | usb_deregister(&belkin_driver); | 589 | usb_deregister(&belkin_driver); |
diff --git a/drivers/usb/serial/belkin_sa.h b/drivers/usb/serial/belkin_sa.h index c66a6730d38c..c74b58ab56f9 100644 --- a/drivers/usb/serial/belkin_sa.h +++ b/drivers/usb/serial/belkin_sa.h | |||
@@ -8,10 +8,10 @@ | |||
8 | * and associated source files. Please see the usb/serial files for | 8 | * and associated source files. Please see the usb/serial files for |
9 | * individual credits and copyrights. | 9 | * individual credits and copyrights. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * See Documentation/usb/usb-serial.txt for more information on using this | 16 | * See Documentation/usb/usb-serial.txt for more information on using this |
17 | * driver | 17 | * driver |
@@ -66,7 +66,7 @@ | |||
66 | #ifdef WHEN_I_LEARN_THIS | 66 | #ifdef WHEN_I_LEARN_THIS |
67 | #define BELKIN_SA_SET_MAGIC_REQUEST 17 /* I don't know, possibly flush */ | 67 | #define BELKIN_SA_SET_MAGIC_REQUEST 17 /* I don't know, possibly flush */ |
68 | /* (always in Wininit sequence before flow control) */ | 68 | /* (always in Wininit sequence before flow control) */ |
69 | #define BELKIN_SA_RESET xx /* Reset the port */ | 69 | #define BELKIN_SA_RESET xx /* Reset the port */ |
70 | #define BELKIN_SA_GET_MODEM_STATUS xx /* Force return of modem status register */ | 70 | #define BELKIN_SA_GET_MODEM_STATUS xx /* Force return of modem status register */ |
71 | #endif | 71 | #endif |
72 | 72 | ||
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 7e8e39818414..63f7cc45bcac 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -305,10 +305,7 @@ static void ch341_close(struct usb_serial_port *port) | |||
305 | { | 305 | { |
306 | dbg("%s - port %d", __func__, port->number); | 306 | dbg("%s - port %d", __func__, port->number); |
307 | 307 | ||
308 | /* shutdown our urbs */ | 308 | usb_serial_generic_close(port); |
309 | dbg("%s - shutting down urbs", __func__); | ||
310 | usb_kill_urb(port->write_urb); | ||
311 | usb_kill_urb(port->read_urb); | ||
312 | usb_kill_urb(port->interrupt_in_urb); | 309 | usb_kill_urb(port->interrupt_in_urb); |
313 | } | 310 | } |
314 | 311 | ||
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index f347da2ef00a..1ee6b2ab0f89 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -66,7 +66,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
66 | struct usb_serial_port *port; | 66 | struct usb_serial_port *port; |
67 | int retval; | 67 | int retval; |
68 | struct tty_struct *tty = NULL; | 68 | struct tty_struct *tty = NULL; |
69 | struct ktermios *termios = NULL, dummy; | 69 | struct ktermios dummy; |
70 | 70 | ||
71 | dbg("%s", __func__); | 71 | dbg("%s", __func__); |
72 | 72 | ||
@@ -141,15 +141,14 @@ static int usb_console_setup(struct console *co, char *options) | |||
141 | goto reset_open_count; | 141 | goto reset_open_count; |
142 | } | 142 | } |
143 | kref_init(&tty->kref); | 143 | kref_init(&tty->kref); |
144 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); | 144 | tty_port_tty_set(&port->port, tty); |
145 | if (!termios) { | 145 | tty->driver = usb_serial_tty_driver; |
146 | tty->index = co->index; | ||
147 | if (tty_init_termios(tty)) { | ||
146 | retval = -ENOMEM; | 148 | retval = -ENOMEM; |
147 | err("no more memory"); | 149 | err("no more memory"); |
148 | goto free_tty; | 150 | goto free_tty; |
149 | } | 151 | } |
150 | memset(&dummy, 0, sizeof(struct ktermios)); | ||
151 | tty->termios = termios; | ||
152 | tty_port_tty_set(&port->port, tty); | ||
153 | } | 152 | } |
154 | 153 | ||
155 | /* only call the device specific open if this | 154 | /* only call the device specific open if this |
@@ -161,16 +160,16 @@ static int usb_console_setup(struct console *co, char *options) | |||
161 | 160 | ||
162 | if (retval) { | 161 | if (retval) { |
163 | err("could not open USB console port"); | 162 | err("could not open USB console port"); |
164 | goto free_termios; | 163 | goto fail; |
165 | } | 164 | } |
166 | 165 | ||
167 | if (serial->type->set_termios) { | 166 | if (serial->type->set_termios) { |
168 | termios->c_cflag = cflag; | 167 | tty->termios->c_cflag = cflag; |
169 | tty_termios_encode_baud_rate(termios, baud, baud); | 168 | tty_termios_encode_baud_rate(tty->termios, baud, baud); |
169 | memset(&dummy, 0, sizeof(struct ktermios)); | ||
170 | serial->type->set_termios(tty, port, &dummy); | 170 | serial->type->set_termios(tty, port, &dummy); |
171 | 171 | ||
172 | tty_port_tty_set(&port->port, NULL); | 172 | tty_port_tty_set(&port->port, NULL); |
173 | kfree(termios); | ||
174 | kfree(tty); | 173 | kfree(tty); |
175 | } | 174 | } |
176 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); | 175 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); |
@@ -180,14 +179,12 @@ static int usb_console_setup(struct console *co, char *options) | |||
180 | --port->port.count; | 179 | --port->port.count; |
181 | /* The console is special in terms of closing the device so | 180 | /* The console is special in terms of closing the device so |
182 | * indicate this port is now acting as a system console. */ | 181 | * indicate this port is now acting as a system console. */ |
183 | port->console = 1; | ||
184 | port->port.console = 1; | 182 | port->port.console = 1; |
185 | 183 | ||
186 | mutex_unlock(&serial->disc_mutex); | 184 | mutex_unlock(&serial->disc_mutex); |
187 | return retval; | 185 | return retval; |
188 | 186 | ||
189 | free_termios: | 187 | fail: |
190 | kfree(termios); | ||
191 | tty_port_tty_set(&port->port, NULL); | 188 | tty_port_tty_set(&port->port, NULL); |
192 | free_tty: | 189 | free_tty: |
193 | kfree(tty); | 190 | kfree(tty); |
@@ -217,7 +214,7 @@ static void usb_console_write(struct console *co, | |||
217 | 214 | ||
218 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); | 215 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); |
219 | 216 | ||
220 | if (!port->console) { | 217 | if (!port->port.console) { |
221 | dbg("%s - port not opened", __func__); | 218 | dbg("%s - port not opened", __func__); |
222 | return; | 219 | return; |
223 | } | 220 | } |
@@ -313,7 +310,7 @@ void usb_serial_console_exit(void) | |||
313 | { | 310 | { |
314 | if (usbcons_info.port) { | 311 | if (usbcons_info.port) { |
315 | unregister_console(&usbcons); | 312 | unregister_console(&usbcons); |
316 | usbcons_info.port->console = 0; | 313 | usbcons_info.port->port.console = 0; |
317 | usbcons_info.port = NULL; | 314 | usbcons_info.port = NULL; |
318 | } | 315 | } |
319 | } | 316 | } |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index ec9b0449ccf6..8b8c7976b4c0 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -34,7 +34,6 @@ | |||
34 | * Function Prototypes | 34 | * Function Prototypes |
35 | */ | 35 | */ |
36 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); | 36 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); |
37 | static void cp210x_cleanup(struct usb_serial_port *); | ||
38 | static void cp210x_close(struct usb_serial_port *); | 37 | static void cp210x_close(struct usb_serial_port *); |
39 | static void cp210x_get_termios(struct tty_struct *, | 38 | static void cp210x_get_termios(struct tty_struct *, |
40 | struct usb_serial_port *port); | 39 | struct usb_serial_port *port); |
@@ -49,7 +48,6 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, | |||
49 | unsigned int, unsigned int); | 48 | unsigned int, unsigned int); |
50 | static void cp210x_break_ctl(struct tty_struct *, int); | 49 | static void cp210x_break_ctl(struct tty_struct *, int); |
51 | static int cp210x_startup(struct usb_serial *); | 50 | static int cp210x_startup(struct usb_serial *); |
52 | static void cp210x_disconnect(struct usb_serial *); | ||
53 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on); | 51 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on); |
54 | static int cp210x_carrier_raised(struct usb_serial_port *p); | 52 | static int cp210x_carrier_raised(struct usb_serial_port *p); |
55 | 53 | ||
@@ -61,6 +59,8 @@ static const struct usb_device_id id_table[] = { | |||
61 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ | 59 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ |
62 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 60 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
63 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ | 61 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ |
62 | { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ | ||
63 | { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ | ||
64 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 64 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
65 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ | 65 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ |
66 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ | 66 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ |
@@ -72,9 +72,12 @@ static const struct usb_device_id id_table[] = { | |||
72 | { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ | 72 | { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ |
73 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 73 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
74 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 74 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
75 | { USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */ | ||
76 | { USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in converter */ | ||
75 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 77 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
76 | { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */ | 78 | { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */ |
77 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ | 79 | { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ |
80 | { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ | ||
78 | { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ | 81 | { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ |
79 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ | 82 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ |
80 | { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ | 83 | { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ |
@@ -82,12 +85,15 @@ static const struct usb_device_id id_table[] = { | |||
82 | { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ | 85 | { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ |
83 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ | 86 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ |
84 | { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ | 87 | { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ |
88 | { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ | ||
85 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 89 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
86 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 90 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
87 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 91 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
92 | { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ | ||
88 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ | 93 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ |
89 | { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ | 94 | { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ |
90 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ | 95 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ |
96 | { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ | ||
91 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | 97 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ |
92 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | 98 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ |
93 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ | 99 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ |
@@ -105,6 +111,7 @@ static const struct usb_device_id id_table[] = { | |||
105 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 111 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
106 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 112 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
107 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 113 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
114 | { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ | ||
108 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | 115 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ |
109 | { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ | 116 | { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ |
110 | { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ | 117 | { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ |
@@ -115,6 +122,8 @@ static const struct usb_device_id id_table[] = { | |||
115 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ | 122 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ |
116 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | 123 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ |
117 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 124 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
125 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||
126 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
118 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | 127 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
119 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | 128 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ |
120 | { } /* Terminating Entry */ | 129 | { } /* Terminating Entry */ |
@@ -138,6 +147,8 @@ static struct usb_serial_driver cp210x_device = { | |||
138 | .usb_driver = &cp210x_driver, | 147 | .usb_driver = &cp210x_driver, |
139 | .id_table = id_table, | 148 | .id_table = id_table, |
140 | .num_ports = 1, | 149 | .num_ports = 1, |
150 | .bulk_in_size = 256, | ||
151 | .bulk_out_size = 256, | ||
141 | .open = cp210x_open, | 152 | .open = cp210x_open, |
142 | .close = cp210x_close, | 153 | .close = cp210x_close, |
143 | .break_ctl = cp210x_break_ctl, | 154 | .break_ctl = cp210x_break_ctl, |
@@ -145,7 +156,6 @@ static struct usb_serial_driver cp210x_device = { | |||
145 | .tiocmget = cp210x_tiocmget, | 156 | .tiocmget = cp210x_tiocmget, |
146 | .tiocmset = cp210x_tiocmset, | 157 | .tiocmset = cp210x_tiocmset, |
147 | .attach = cp210x_startup, | 158 | .attach = cp210x_startup, |
148 | .disconnect = cp210x_disconnect, | ||
149 | .dtr_rts = cp210x_dtr_rts, | 159 | .dtr_rts = cp210x_dtr_rts, |
150 | .carrier_raised = cp210x_carrier_raised | 160 | .carrier_raised = cp210x_carrier_raised |
151 | }; | 161 | }; |
@@ -370,7 +380,6 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { | |||
370 | 380 | ||
371 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) | 381 | static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) |
372 | { | 382 | { |
373 | struct usb_serial *serial = port->serial; | ||
374 | int result; | 383 | int result; |
375 | 384 | ||
376 | dbg("%s - port %d", __func__, port->number); | 385 | dbg("%s - port %d", __func__, port->number); |
@@ -381,49 +390,20 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
381 | return -EPROTO; | 390 | return -EPROTO; |
382 | } | 391 | } |
383 | 392 | ||
384 | /* Start reading from the device */ | 393 | result = usb_serial_generic_open(tty, port); |
385 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 394 | if (result) |
386 | usb_rcvbulkpipe(serial->dev, | ||
387 | port->bulk_in_endpointAddress), | ||
388 | port->read_urb->transfer_buffer, | ||
389 | port->read_urb->transfer_buffer_length, | ||
390 | serial->type->read_bulk_callback, | ||
391 | port); | ||
392 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
393 | if (result) { | ||
394 | dev_err(&port->dev, "%s - failed resubmitting read urb, " | ||
395 | "error %d\n", __func__, result); | ||
396 | return result; | 395 | return result; |
397 | } | ||
398 | 396 | ||
399 | /* Configure the termios structure */ | 397 | /* Configure the termios structure */ |
400 | cp210x_get_termios(tty, port); | 398 | cp210x_get_termios(tty, port); |
401 | return 0; | 399 | return 0; |
402 | } | 400 | } |
403 | 401 | ||
404 | static void cp210x_cleanup(struct usb_serial_port *port) | ||
405 | { | ||
406 | struct usb_serial *serial = port->serial; | ||
407 | |||
408 | dbg("%s - port %d", __func__, port->number); | ||
409 | |||
410 | if (serial->dev) { | ||
411 | /* shutdown any bulk reads that might be going on */ | ||
412 | if (serial->num_bulk_out) | ||
413 | usb_kill_urb(port->write_urb); | ||
414 | if (serial->num_bulk_in) | ||
415 | usb_kill_urb(port->read_urb); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | static void cp210x_close(struct usb_serial_port *port) | 402 | static void cp210x_close(struct usb_serial_port *port) |
420 | { | 403 | { |
421 | dbg("%s - port %d", __func__, port->number); | 404 | dbg("%s - port %d", __func__, port->number); |
422 | 405 | ||
423 | /* shutdown our urbs */ | 406 | usb_serial_generic_close(port); |
424 | dbg("%s - shutting down urbs", __func__); | ||
425 | usb_kill_urb(port->write_urb); | ||
426 | usb_kill_urb(port->read_urb); | ||
427 | 407 | ||
428 | mutex_lock(&port->serial->disc_mutex); | 408 | mutex_lock(&port->serial->disc_mutex); |
429 | if (!port->serial->disconnected) | 409 | if (!port->serial->disconnected) |
@@ -807,17 +787,6 @@ static int cp210x_startup(struct usb_serial *serial) | |||
807 | return 0; | 787 | return 0; |
808 | } | 788 | } |
809 | 789 | ||
810 | static void cp210x_disconnect(struct usb_serial *serial) | ||
811 | { | ||
812 | int i; | ||
813 | |||
814 | dbg("%s", __func__); | ||
815 | |||
816 | /* Stop reads and writes on all ports */ | ||
817 | for (i = 0; i < serial->num_ports; ++i) | ||
818 | cp210x_cleanup(serial->port[i]); | ||
819 | } | ||
820 | |||
821 | static int __init cp210x_init(void) | 790 | static int __init cp210x_init(void) |
822 | { | 791 | { |
823 | int retval; | 792 | int retval; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e23c77925e7a..f5d06746cc3b 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/usb.h> | 64 | #include <linux/usb.h> |
65 | #include <linux/usb/serial.h> | 65 | #include <linux/usb/serial.h> |
66 | #include <linux/serial.h> | 66 | #include <linux/serial.h> |
67 | #include <linux/kfifo.h> | ||
67 | #include <linux/delay.h> | 68 | #include <linux/delay.h> |
68 | #include <linux/uaccess.h> | 69 | #include <linux/uaccess.h> |
69 | #include <asm/unaligned.h> | 70 | #include <asm/unaligned.h> |
@@ -79,13 +80,12 @@ static int unstable_bauds; | |||
79 | /* | 80 | /* |
80 | * Version Information | 81 | * Version Information |
81 | */ | 82 | */ |
82 | #define DRIVER_VERSION "v1.09" | 83 | #define DRIVER_VERSION "v1.10" |
83 | #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" | 84 | #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" |
84 | #define DRIVER_DESC "Cypress USB to Serial Driver" | 85 | #define DRIVER_DESC "Cypress USB to Serial Driver" |
85 | 86 | ||
86 | /* write buffer size defines */ | 87 | /* write buffer size defines */ |
87 | #define CYPRESS_BUF_SIZE 1024 | 88 | #define CYPRESS_BUF_SIZE 1024 |
88 | #define CYPRESS_CLOSING_WAIT (30*HZ) | ||
89 | 89 | ||
90 | static const struct usb_device_id id_table_earthmate[] = { | 90 | static const struct usb_device_id id_table_earthmate[] = { |
91 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 91 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
@@ -135,7 +135,7 @@ struct cypress_private { | |||
135 | int bytes_out; /* used for statistics */ | 135 | int bytes_out; /* used for statistics */ |
136 | int cmd_count; /* used for statistics */ | 136 | int cmd_count; /* used for statistics */ |
137 | int cmd_ctrl; /* always set this to 1 before issuing a command */ | 137 | int cmd_ctrl; /* always set this to 1 before issuing a command */ |
138 | struct cypress_buf *buf; /* write buffer */ | 138 | struct kfifo write_fifo; /* write fifo */ |
139 | int write_urb_in_use; /* write urb in use indicator */ | 139 | int write_urb_in_use; /* write urb in use indicator */ |
140 | int write_urb_interval; /* interval to use for write urb */ | 140 | int write_urb_interval; /* interval to use for write urb */ |
141 | int read_urb_interval; /* interval to use for read urb */ | 141 | int read_urb_interval; /* interval to use for read urb */ |
@@ -157,14 +157,6 @@ struct cypress_private { | |||
157 | struct ktermios tmp_termios; /* stores the old termios settings */ | 157 | struct ktermios tmp_termios; /* stores the old termios settings */ |
158 | }; | 158 | }; |
159 | 159 | ||
160 | /* write buffer structure */ | ||
161 | struct cypress_buf { | ||
162 | unsigned int buf_size; | ||
163 | char *buf_buf; | ||
164 | char *buf_get; | ||
165 | char *buf_put; | ||
166 | }; | ||
167 | |||
168 | /* function prototypes for the Cypress USB to serial device */ | 160 | /* function prototypes for the Cypress USB to serial device */ |
169 | static int cypress_earthmate_startup(struct usb_serial *serial); | 161 | static int cypress_earthmate_startup(struct usb_serial *serial); |
170 | static int cypress_hidcom_startup(struct usb_serial *serial); | 162 | static int cypress_hidcom_startup(struct usb_serial *serial); |
@@ -190,17 +182,6 @@ static void cypress_unthrottle(struct tty_struct *tty); | |||
190 | static void cypress_set_dead(struct usb_serial_port *port); | 182 | static void cypress_set_dead(struct usb_serial_port *port); |
191 | static void cypress_read_int_callback(struct urb *urb); | 183 | static void cypress_read_int_callback(struct urb *urb); |
192 | static void cypress_write_int_callback(struct urb *urb); | 184 | static void cypress_write_int_callback(struct urb *urb); |
193 | /* write buffer functions */ | ||
194 | static struct cypress_buf *cypress_buf_alloc(unsigned int size); | ||
195 | static void cypress_buf_free(struct cypress_buf *cb); | ||
196 | static void cypress_buf_clear(struct cypress_buf *cb); | ||
197 | static unsigned int cypress_buf_data_avail(struct cypress_buf *cb); | ||
198 | static unsigned int cypress_buf_space_avail(struct cypress_buf *cb); | ||
199 | static unsigned int cypress_buf_put(struct cypress_buf *cb, | ||
200 | const char *buf, unsigned int count); | ||
201 | static unsigned int cypress_buf_get(struct cypress_buf *cb, | ||
202 | char *buf, unsigned int count); | ||
203 | |||
204 | 185 | ||
205 | static struct usb_serial_driver cypress_earthmate_device = { | 186 | static struct usb_serial_driver cypress_earthmate_device = { |
206 | .driver = { | 187 | .driver = { |
@@ -503,8 +484,7 @@ static int generic_startup(struct usb_serial *serial) | |||
503 | 484 | ||
504 | priv->comm_is_ok = !0; | 485 | priv->comm_is_ok = !0; |
505 | spin_lock_init(&priv->lock); | 486 | spin_lock_init(&priv->lock); |
506 | priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); | 487 | if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { |
507 | if (priv->buf == NULL) { | ||
508 | kfree(priv); | 488 | kfree(priv); |
509 | return -ENOMEM; | 489 | return -ENOMEM; |
510 | } | 490 | } |
@@ -627,7 +607,7 @@ static void cypress_release(struct usb_serial *serial) | |||
627 | priv = usb_get_serial_port_data(serial->port[0]); | 607 | priv = usb_get_serial_port_data(serial->port[0]); |
628 | 608 | ||
629 | if (priv) { | 609 | if (priv) { |
630 | cypress_buf_free(priv->buf); | 610 | kfifo_free(&priv->write_fifo); |
631 | kfree(priv); | 611 | kfree(priv); |
632 | } | 612 | } |
633 | } | 613 | } |
@@ -704,6 +684,7 @@ static void cypress_dtr_rts(struct usb_serial_port *port, int on) | |||
704 | static void cypress_close(struct usb_serial_port *port) | 684 | static void cypress_close(struct usb_serial_port *port) |
705 | { | 685 | { |
706 | struct cypress_private *priv = usb_get_serial_port_data(port); | 686 | struct cypress_private *priv = usb_get_serial_port_data(port); |
687 | unsigned long flags; | ||
707 | 688 | ||
708 | dbg("%s - port %d", __func__, port->number); | 689 | dbg("%s - port %d", __func__, port->number); |
709 | 690 | ||
@@ -713,12 +694,14 @@ static void cypress_close(struct usb_serial_port *port) | |||
713 | mutex_unlock(&port->serial->disc_mutex); | 694 | mutex_unlock(&port->serial->disc_mutex); |
714 | return; | 695 | return; |
715 | } | 696 | } |
716 | cypress_buf_clear(priv->buf); | 697 | spin_lock_irqsave(&priv->lock, flags); |
698 | kfifo_reset_out(&priv->write_fifo); | ||
699 | spin_unlock_irqrestore(&priv->lock, flags); | ||
700 | |||
717 | dbg("%s - stopping urbs", __func__); | 701 | dbg("%s - stopping urbs", __func__); |
718 | usb_kill_urb(port->interrupt_in_urb); | 702 | usb_kill_urb(port->interrupt_in_urb); |
719 | usb_kill_urb(port->interrupt_out_urb); | 703 | usb_kill_urb(port->interrupt_out_urb); |
720 | 704 | ||
721 | |||
722 | if (stats) | 705 | if (stats) |
723 | dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", | 706 | dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", |
724 | priv->bytes_in, priv->bytes_out, priv->cmd_count); | 707 | priv->bytes_in, priv->bytes_out, priv->cmd_count); |
@@ -730,7 +713,6 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
730 | const unsigned char *buf, int count) | 713 | const unsigned char *buf, int count) |
731 | { | 714 | { |
732 | struct cypress_private *priv = usb_get_serial_port_data(port); | 715 | struct cypress_private *priv = usb_get_serial_port_data(port); |
733 | unsigned long flags; | ||
734 | 716 | ||
735 | dbg("%s - port %d, %d bytes", __func__, port->number, count); | 717 | dbg("%s - port %d, %d bytes", __func__, port->number, count); |
736 | 718 | ||
@@ -745,9 +727,7 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
745 | if (!count) | 727 | if (!count) |
746 | return count; | 728 | return count; |
747 | 729 | ||
748 | spin_lock_irqsave(&priv->lock, flags); | 730 | count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); |
749 | count = cypress_buf_put(priv->buf, buf, count); | ||
750 | spin_unlock_irqrestore(&priv->lock, flags); | ||
751 | 731 | ||
752 | finish: | 732 | finish: |
753 | cypress_send(port); | 733 | cypress_send(port); |
@@ -807,9 +787,10 @@ static void cypress_send(struct usb_serial_port *port) | |||
807 | } else | 787 | } else |
808 | spin_unlock_irqrestore(&priv->lock, flags); | 788 | spin_unlock_irqrestore(&priv->lock, flags); |
809 | 789 | ||
810 | count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset], | 790 | count = kfifo_out_locked(&priv->write_fifo, |
811 | port->interrupt_out_size-offset); | 791 | &port->interrupt_out_buffer[offset], |
812 | 792 | port->interrupt_out_size - offset, | |
793 | &priv->lock); | ||
813 | if (count == 0) | 794 | if (count == 0) |
814 | return; | 795 | return; |
815 | 796 | ||
@@ -875,7 +856,7 @@ static int cypress_write_room(struct tty_struct *tty) | |||
875 | dbg("%s - port %d", __func__, port->number); | 856 | dbg("%s - port %d", __func__, port->number); |
876 | 857 | ||
877 | spin_lock_irqsave(&priv->lock, flags); | 858 | spin_lock_irqsave(&priv->lock, flags); |
878 | room = cypress_buf_space_avail(priv->buf); | 859 | room = kfifo_avail(&priv->write_fifo); |
879 | spin_unlock_irqrestore(&priv->lock, flags); | 860 | spin_unlock_irqrestore(&priv->lock, flags); |
880 | 861 | ||
881 | dbg("%s - returns %d", __func__, room); | 862 | dbg("%s - returns %d", __func__, room); |
@@ -1143,7 +1124,7 @@ static int cypress_chars_in_buffer(struct tty_struct *tty) | |||
1143 | dbg("%s - port %d", __func__, port->number); | 1124 | dbg("%s - port %d", __func__, port->number); |
1144 | 1125 | ||
1145 | spin_lock_irqsave(&priv->lock, flags); | 1126 | spin_lock_irqsave(&priv->lock, flags); |
1146 | chars = cypress_buf_data_avail(priv->buf); | 1127 | chars = kfifo_len(&priv->write_fifo); |
1147 | spin_unlock_irqrestore(&priv->lock, flags); | 1128 | spin_unlock_irqrestore(&priv->lock, flags); |
1148 | 1129 | ||
1149 | dbg("%s - returns %d", __func__, chars); | 1130 | dbg("%s - returns %d", __func__, chars); |
@@ -1309,7 +1290,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1309 | /* process read if there is data other than line status */ | 1290 | /* process read if there is data other than line status */ |
1310 | if (tty && bytes > i) { | 1291 | if (tty && bytes > i) { |
1311 | tty_insert_flip_string_fixed_flag(tty, data + i, | 1292 | tty_insert_flip_string_fixed_flag(tty, data + i, |
1312 | bytes - i, tty_flag); | 1293 | tty_flag, bytes - i); |
1313 | tty_flip_buffer_push(tty); | 1294 | tty_flip_buffer_push(tty); |
1314 | } | 1295 | } |
1315 | 1296 | ||
@@ -1397,193 +1378,6 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1397 | 1378 | ||
1398 | 1379 | ||
1399 | /***************************************************************************** | 1380 | /***************************************************************************** |
1400 | * Write buffer functions - buffering code from pl2303 used | ||
1401 | *****************************************************************************/ | ||
1402 | |||
1403 | /* | ||
1404 | * cypress_buf_alloc | ||
1405 | * | ||
1406 | * Allocate a circular buffer and all associated memory. | ||
1407 | */ | ||
1408 | |||
1409 | static struct cypress_buf *cypress_buf_alloc(unsigned int size) | ||
1410 | { | ||
1411 | |||
1412 | struct cypress_buf *cb; | ||
1413 | |||
1414 | |||
1415 | if (size == 0) | ||
1416 | return NULL; | ||
1417 | |||
1418 | cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL); | ||
1419 | if (cb == NULL) | ||
1420 | return NULL; | ||
1421 | |||
1422 | cb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
1423 | if (cb->buf_buf == NULL) { | ||
1424 | kfree(cb); | ||
1425 | return NULL; | ||
1426 | } | ||
1427 | |||
1428 | cb->buf_size = size; | ||
1429 | cb->buf_get = cb->buf_put = cb->buf_buf; | ||
1430 | |||
1431 | return cb; | ||
1432 | |||
1433 | } | ||
1434 | |||
1435 | |||
1436 | /* | ||
1437 | * cypress_buf_free | ||
1438 | * | ||
1439 | * Free the buffer and all associated memory. | ||
1440 | */ | ||
1441 | |||
1442 | static void cypress_buf_free(struct cypress_buf *cb) | ||
1443 | { | ||
1444 | if (cb) { | ||
1445 | kfree(cb->buf_buf); | ||
1446 | kfree(cb); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | |||
1451 | /* | ||
1452 | * cypress_buf_clear | ||
1453 | * | ||
1454 | * Clear out all data in the circular buffer. | ||
1455 | */ | ||
1456 | |||
1457 | static void cypress_buf_clear(struct cypress_buf *cb) | ||
1458 | { | ||
1459 | if (cb != NULL) | ||
1460 | cb->buf_get = cb->buf_put; | ||
1461 | /* equivalent to a get of all data available */ | ||
1462 | } | ||
1463 | |||
1464 | |||
1465 | /* | ||
1466 | * cypress_buf_data_avail | ||
1467 | * | ||
1468 | * Return the number of bytes of data available in the circular | ||
1469 | * buffer. | ||
1470 | */ | ||
1471 | |||
1472 | static unsigned int cypress_buf_data_avail(struct cypress_buf *cb) | ||
1473 | { | ||
1474 | if (cb != NULL) | ||
1475 | return (cb->buf_size + cb->buf_put - cb->buf_get) | ||
1476 | % cb->buf_size; | ||
1477 | else | ||
1478 | return 0; | ||
1479 | } | ||
1480 | |||
1481 | |||
1482 | /* | ||
1483 | * cypress_buf_space_avail | ||
1484 | * | ||
1485 | * Return the number of bytes of space available in the circular | ||
1486 | * buffer. | ||
1487 | */ | ||
1488 | |||
1489 | static unsigned int cypress_buf_space_avail(struct cypress_buf *cb) | ||
1490 | { | ||
1491 | if (cb != NULL) | ||
1492 | return (cb->buf_size + cb->buf_get - cb->buf_put - 1) | ||
1493 | % cb->buf_size; | ||
1494 | else | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | |||
1499 | /* | ||
1500 | * cypress_buf_put | ||
1501 | * | ||
1502 | * Copy data data from a user buffer and put it into the circular buffer. | ||
1503 | * Restrict to the amount of space available. | ||
1504 | * | ||
1505 | * Return the number of bytes copied. | ||
1506 | */ | ||
1507 | |||
1508 | static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, | ||
1509 | unsigned int count) | ||
1510 | { | ||
1511 | |||
1512 | unsigned int len; | ||
1513 | |||
1514 | |||
1515 | if (cb == NULL) | ||
1516 | return 0; | ||
1517 | |||
1518 | len = cypress_buf_space_avail(cb); | ||
1519 | if (count > len) | ||
1520 | count = len; | ||
1521 | |||
1522 | if (count == 0) | ||
1523 | return 0; | ||
1524 | |||
1525 | len = cb->buf_buf + cb->buf_size - cb->buf_put; | ||
1526 | if (count > len) { | ||
1527 | memcpy(cb->buf_put, buf, len); | ||
1528 | memcpy(cb->buf_buf, buf+len, count - len); | ||
1529 | cb->buf_put = cb->buf_buf + count - len; | ||
1530 | } else { | ||
1531 | memcpy(cb->buf_put, buf, count); | ||
1532 | if (count < len) | ||
1533 | cb->buf_put += count; | ||
1534 | else /* count == len */ | ||
1535 | cb->buf_put = cb->buf_buf; | ||
1536 | } | ||
1537 | |||
1538 | return count; | ||
1539 | |||
1540 | } | ||
1541 | |||
1542 | |||
1543 | /* | ||
1544 | * cypress_buf_get | ||
1545 | * | ||
1546 | * Get data from the circular buffer and copy to the given buffer. | ||
1547 | * Restrict to the amount of data available. | ||
1548 | * | ||
1549 | * Return the number of bytes copied. | ||
1550 | */ | ||
1551 | |||
1552 | static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, | ||
1553 | unsigned int count) | ||
1554 | { | ||
1555 | |||
1556 | unsigned int len; | ||
1557 | |||
1558 | |||
1559 | if (cb == NULL) | ||
1560 | return 0; | ||
1561 | |||
1562 | len = cypress_buf_data_avail(cb); | ||
1563 | if (count > len) | ||
1564 | count = len; | ||
1565 | |||
1566 | if (count == 0) | ||
1567 | return 0; | ||
1568 | |||
1569 | len = cb->buf_buf + cb->buf_size - cb->buf_get; | ||
1570 | if (count > len) { | ||
1571 | memcpy(buf, cb->buf_get, len); | ||
1572 | memcpy(buf+len, cb->buf_buf, count - len); | ||
1573 | cb->buf_get = cb->buf_buf + count - len; | ||
1574 | } else { | ||
1575 | memcpy(buf, cb->buf_get, count); | ||
1576 | if (count < len) | ||
1577 | cb->buf_get += count; | ||
1578 | else /* count == len */ | ||
1579 | cb->buf_get = cb->buf_buf; | ||
1580 | } | ||
1581 | |||
1582 | return count; | ||
1583 | |||
1584 | } | ||
1585 | |||
1586 | /***************************************************************************** | ||
1587 | * Module functions | 1381 | * Module functions |
1588 | *****************************************************************************/ | 1382 | *****************************************************************************/ |
1589 | 1383 | ||
diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index 1fd360e04065..67cf60826884 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h | |||
@@ -1,27 +1,32 @@ | |||
1 | #ifndef CYPRESS_M8_H | 1 | #ifndef CYPRESS_M8_H |
2 | #define CYPRESS_M8_H | 2 | #define CYPRESS_M8_H |
3 | 3 | ||
4 | /* definitions and function prototypes used for the cypress USB to Serial controller */ | 4 | /* |
5 | * definitions and function prototypes used for the cypress USB to Serial | ||
6 | * controller | ||
7 | */ | ||
5 | 8 | ||
6 | /* For sending our feature buffer - controlling serial communication states */ | 9 | /* |
7 | /* Linux HID has no support for serial devices so we do this through the driver */ | 10 | * For sending our feature buffer - controlling serial communication states. |
8 | #define HID_REQ_GET_REPORT 0x01 | 11 | * Linux HID has no support for serial devices so we do this through the driver |
9 | #define HID_REQ_SET_REPORT 0x09 | 12 | */ |
13 | #define HID_REQ_GET_REPORT 0x01 | ||
14 | #define HID_REQ_SET_REPORT 0x09 | ||
10 | 15 | ||
11 | /* List other cypress USB to Serial devices here, and add them to the id_table */ | 16 | /* List other cypress USB to Serial devices here, and add them to the id_table */ |
12 | 17 | ||
13 | /* DeLorme Earthmate USB - a GPS device */ | 18 | /* DeLorme Earthmate USB - a GPS device */ |
14 | #define VENDOR_ID_DELORME 0x1163 | 19 | #define VENDOR_ID_DELORME 0x1163 |
15 | #define PRODUCT_ID_EARTHMATEUSB 0x0100 | 20 | #define PRODUCT_ID_EARTHMATEUSB 0x0100 |
16 | #define PRODUCT_ID_EARTHMATEUSB_LT20 0x0200 | 21 | #define PRODUCT_ID_EARTHMATEUSB_LT20 0x0200 |
17 | 22 | ||
18 | /* Cypress HID->COM RS232 Adapter */ | 23 | /* Cypress HID->COM RS232 Adapter */ |
19 | #define VENDOR_ID_CYPRESS 0x04b4 | 24 | #define VENDOR_ID_CYPRESS 0x04b4 |
20 | #define PRODUCT_ID_CYPHIDCOM 0x5500 | 25 | #define PRODUCT_ID_CYPHIDCOM 0x5500 |
21 | 26 | ||
22 | /* Powercom UPS, chip CY7C63723 */ | 27 | /* Powercom UPS, chip CY7C63723 */ |
23 | #define VENDOR_ID_POWERCOM 0x0d9f | 28 | #define VENDOR_ID_POWERCOM 0x0d9f |
24 | #define PRODUCT_ID_UPS 0x0002 | 29 | #define PRODUCT_ID_UPS 0x0002 |
25 | 30 | ||
26 | /* Nokia CA-42 USB to serial cable */ | 31 | /* Nokia CA-42 USB to serial cable */ |
27 | #define VENDOR_ID_DAZZLE 0x07d0 | 32 | #define VENDOR_ID_DAZZLE 0x07d0 |
@@ -29,17 +34,17 @@ | |||
29 | /* End of device listing */ | 34 | /* End of device listing */ |
30 | 35 | ||
31 | /* Used for setting / requesting serial line settings */ | 36 | /* Used for setting / requesting serial line settings */ |
32 | #define CYPRESS_SET_CONFIG 0x01 | 37 | #define CYPRESS_SET_CONFIG 0x01 |
33 | #define CYPRESS_GET_CONFIG 0x02 | 38 | #define CYPRESS_GET_CONFIG 0x02 |
34 | 39 | ||
35 | /* Used for throttle control */ | 40 | /* Used for throttle control */ |
36 | #define THROTTLED 0x1 | 41 | #define THROTTLED 0x1 |
37 | #define ACTUALLY_THROTTLED 0x2 | 42 | #define ACTUALLY_THROTTLED 0x2 |
38 | 43 | ||
39 | /* chiptypes - used in case firmware differs from the generic form ... offering | 44 | /* |
40 | * different baud speeds/etc. | 45 | * chiptypes - used in case firmware differs from the generic form ... offering |
46 | * different baud speeds/etc. | ||
41 | */ | 47 | */ |
42 | |||
43 | #define CT_EARTHMATE 0x01 | 48 | #define CT_EARTHMATE 0x01 |
44 | #define CT_CYPHIDCOM 0x02 | 49 | #define CT_CYPHIDCOM 0x02 |
45 | #define CT_CA42V2 0x03 | 50 | #define CT_CA42V2 0x03 |
@@ -50,15 +55,15 @@ | |||
50 | /* these are sent / read at byte 0 of the input/output hid reports */ | 55 | /* these are sent / read at byte 0 of the input/output hid reports */ |
51 | /* You can find these values defined in the CY4601 USB to Serial design notes */ | 56 | /* You can find these values defined in the CY4601 USB to Serial design notes */ |
52 | 57 | ||
53 | #define CONTROL_DTR 0x20 /* data terminal ready - flow control - host to device */ | 58 | #define CONTROL_DTR 0x20 /* data terminal ready - flow control - host to device */ |
54 | #define UART_DSR 0x20 /* data set ready - flow control - device to host */ | 59 | #define UART_DSR 0x20 /* data set ready - flow control - device to host */ |
55 | #define CONTROL_RTS 0x10 /* request to send - flow control - host to device */ | 60 | #define CONTROL_RTS 0x10 /* request to send - flow control - host to device */ |
56 | #define UART_CTS 0x10 /* clear to send - flow control - device to host */ | 61 | #define UART_CTS 0x10 /* clear to send - flow control - device to host */ |
57 | #define UART_RI 0x10 /* ring indicator - modem - device to host */ | 62 | #define UART_RI 0x10 /* ring indicator - modem - device to host */ |
58 | #define UART_CD 0x40 /* carrier detect - modem - device to host */ | 63 | #define UART_CD 0x40 /* carrier detect - modem - device to host */ |
59 | #define CYP_ERROR 0x08 /* received from input report - device to host */ | 64 | #define CYP_ERROR 0x08 /* received from input report - device to host */ |
60 | /* Note - the below has nothing to do with the "feature report" reset */ | 65 | /* Note - the below has nothing to do with the "feature report" reset */ |
61 | #define CONTROL_RESET 0x08 /* sent with output report - host to device */ | 66 | #define CONTROL_RESET 0x08 /* sent with output report - host to device */ |
62 | 67 | ||
63 | /* End of RS-232 protocol definitions */ | 68 | /* End of RS-232 protocol definitions */ |
64 | 69 | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 68b0aa5e516c..3edda3ed822a 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -1703,8 +1703,8 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1703 | /* data length is len-1 (one byte of len is port_status) */ | 1703 | /* data length is len-1 (one byte of len is port_status) */ |
1704 | --len; | 1704 | --len; |
1705 | if (len > 0) { | 1705 | if (len > 0) { |
1706 | tty_insert_flip_string_fixed_flag(tty, data, len, | 1706 | tty_insert_flip_string_fixed_flag(tty, data, flag, |
1707 | flag); | 1707 | len); |
1708 | tty_flip_buffer_push(tty); | 1708 | tty_flip_buffer_push(tty); |
1709 | } | 1709 | } |
1710 | } | 1710 | } |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 5f740a1eacab..504b5585ea45 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -13,44 +13,6 @@ | |||
13 | * | 13 | * |
14 | * See Documentation/usb/usb-serial.txt for more information on using this | 14 | * See Documentation/usb/usb-serial.txt for more information on using this |
15 | * driver | 15 | * driver |
16 | * | ||
17 | * (07/16/2001) gb | ||
18 | * remove unused code in empeg_close() (thanks to Oliver Neukum for | ||
19 | * pointing this out) and rewrote empeg_set_termios(). | ||
20 | * | ||
21 | * (05/30/2001) gkh | ||
22 | * switched from using spinlock to a semaphore, which fixes lots of | ||
23 | * problems. | ||
24 | * | ||
25 | * (04/08/2001) gb | ||
26 | * Identify version on module load. | ||
27 | * | ||
28 | * (01/22/2001) gb | ||
29 | * Added write_room() and chars_in_buffer() support. | ||
30 | * | ||
31 | * (12/21/2000) gb | ||
32 | * Moved termio stuff inside the port->active check. | ||
33 | * Moved MOD_DEC_USE_COUNT to end of empeg_close(). | ||
34 | * | ||
35 | * (12/03/2000) gb | ||
36 | * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open(). | ||
37 | * This notifies the tty driver that the termios have changed. | ||
38 | * | ||
39 | * (11/13/2000) gb | ||
40 | * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to | ||
41 | * empeg_open() (It only needs to be set once - Doh!) | ||
42 | * | ||
43 | * (11/11/2000) gb | ||
44 | * Updated to work with id_table structure. | ||
45 | * | ||
46 | * (11/04/2000) gb | ||
47 | * Forked this from visor.c, and hacked it up to work with an | ||
48 | * Empeg ltd. empeg-car player. Constructive criticism welcomed. | ||
49 | * I would like to say, 'Thank You' to Greg Kroah-Hartman for the | ||
50 | * use of his code, and for his guidance, advice and patience. :) | ||
51 | * A 'Thank You' is in order for John Ripley of Empeg ltd for his | ||
52 | * advice, and patience too. | ||
53 | * | ||
54 | */ | 16 | */ |
55 | 17 | ||
56 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
@@ -71,7 +33,7 @@ static int debug; | |||
71 | /* | 33 | /* |
72 | * Version Information | 34 | * Version Information |
73 | */ | 35 | */ |
74 | #define DRIVER_VERSION "v1.2" | 36 | #define DRIVER_VERSION "v1.3" |
75 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>" | 37 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>" |
76 | #define DRIVER_DESC "USB Empeg Mark I/II Driver" | 38 | #define DRIVER_DESC "USB Empeg Mark I/II Driver" |
77 | 39 | ||
@@ -79,19 +41,8 @@ static int debug; | |||
79 | #define EMPEG_PRODUCT_ID 0x0001 | 41 | #define EMPEG_PRODUCT_ID 0x0001 |
80 | 42 | ||
81 | /* function prototypes for an empeg-car player */ | 43 | /* function prototypes for an empeg-car player */ |
82 | static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port); | ||
83 | static void empeg_close(struct usb_serial_port *port); | ||
84 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
85 | const unsigned char *buf, | ||
86 | int count); | ||
87 | static int empeg_write_room(struct tty_struct *tty); | ||
88 | static int empeg_chars_in_buffer(struct tty_struct *tty); | ||
89 | static void empeg_throttle(struct tty_struct *tty); | ||
90 | static void empeg_unthrottle(struct tty_struct *tty); | ||
91 | static int empeg_startup(struct usb_serial *serial); | 44 | static int empeg_startup(struct usb_serial *serial); |
92 | static void empeg_init_termios(struct tty_struct *tty); | 45 | static void empeg_init_termios(struct tty_struct *tty); |
93 | static void empeg_write_bulk_callback(struct urb *urb); | ||
94 | static void empeg_read_bulk_callback(struct urb *urb); | ||
95 | 46 | ||
96 | static const struct usb_device_id id_table[] = { | 47 | static const struct usb_device_id id_table[] = { |
97 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, | 48 | { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, |
@@ -105,7 +56,7 @@ static struct usb_driver empeg_driver = { | |||
105 | .probe = usb_serial_probe, | 56 | .probe = usb_serial_probe, |
106 | .disconnect = usb_serial_disconnect, | 57 | .disconnect = usb_serial_disconnect, |
107 | .id_table = id_table, | 58 | .id_table = id_table, |
108 | .no_dynamic_id = 1, | 59 | .no_dynamic_id = 1, |
109 | }; | 60 | }; |
110 | 61 | ||
111 | static struct usb_serial_driver empeg_device = { | 62 | static struct usb_serial_driver empeg_device = { |
@@ -114,291 +65,16 @@ static struct usb_serial_driver empeg_device = { | |||
114 | .name = "empeg", | 65 | .name = "empeg", |
115 | }, | 66 | }, |
116 | .id_table = id_table, | 67 | .id_table = id_table, |
117 | .usb_driver = &empeg_driver, | 68 | .usb_driver = &empeg_driver, |
118 | .num_ports = 1, | 69 | .num_ports = 1, |
119 | .open = empeg_open, | 70 | .bulk_out_size = 256, |
120 | .close = empeg_close, | 71 | .throttle = usb_serial_generic_throttle, |
121 | .throttle = empeg_throttle, | 72 | .unthrottle = usb_serial_generic_unthrottle, |
122 | .unthrottle = empeg_unthrottle, | ||
123 | .attach = empeg_startup, | 73 | .attach = empeg_startup, |
124 | .init_termios = empeg_init_termios, | 74 | .init_termios = empeg_init_termios, |
125 | .write = empeg_write, | ||
126 | .write_room = empeg_write_room, | ||
127 | .chars_in_buffer = empeg_chars_in_buffer, | ||
128 | .write_bulk_callback = empeg_write_bulk_callback, | ||
129 | .read_bulk_callback = empeg_read_bulk_callback, | ||
130 | }; | 75 | }; |
131 | 76 | ||
132 | #define NUM_URBS 16 | 77 | static int empeg_startup(struct usb_serial *serial) |
133 | #define URB_TRANSFER_BUFFER_SIZE 4096 | ||
134 | |||
135 | static struct urb *write_urb_pool[NUM_URBS]; | ||
136 | static spinlock_t write_urb_pool_lock; | ||
137 | static int bytes_in; | ||
138 | static int bytes_out; | ||
139 | |||
140 | /****************************************************************************** | ||
141 | * Empeg specific driver functions | ||
142 | ******************************************************************************/ | ||
143 | static int empeg_open(struct tty_struct *tty,struct usb_serial_port *port) | ||
144 | { | ||
145 | struct usb_serial *serial = port->serial; | ||
146 | int result = 0; | ||
147 | |||
148 | dbg("%s - port %d", __func__, port->number); | ||
149 | |||
150 | bytes_in = 0; | ||
151 | bytes_out = 0; | ||
152 | |||
153 | /* Start reading from the device */ | ||
154 | usb_fill_bulk_urb( | ||
155 | port->read_urb, | ||
156 | serial->dev, | ||
157 | usb_rcvbulkpipe(serial->dev, | ||
158 | port->bulk_in_endpointAddress), | ||
159 | port->read_urb->transfer_buffer, | ||
160 | port->read_urb->transfer_buffer_length, | ||
161 | empeg_read_bulk_callback, | ||
162 | port); | ||
163 | |||
164 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
165 | |||
166 | if (result) | ||
167 | dev_err(&port->dev, | ||
168 | "%s - failed submitting read urb, error %d\n", | ||
169 | __func__, result); | ||
170 | |||
171 | return result; | ||
172 | } | ||
173 | |||
174 | |||
175 | static void empeg_close(struct usb_serial_port *port) | ||
176 | { | ||
177 | dbg("%s - port %d", __func__, port->number); | ||
178 | |||
179 | /* shutdown our bulk read */ | ||
180 | usb_kill_urb(port->read_urb); | ||
181 | /* Uncomment the following line if you want to see some statistics in your syslog */ | ||
182 | /* dev_info (&port->dev, "Bytes In = %d Bytes Out = %d\n", bytes_in, bytes_out); */ | ||
183 | } | ||
184 | |||
185 | |||
186 | static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
187 | const unsigned char *buf, int count) | ||
188 | { | ||
189 | struct usb_serial *serial = port->serial; | ||
190 | struct urb *urb; | ||
191 | const unsigned char *current_position = buf; | ||
192 | unsigned long flags; | ||
193 | int status; | ||
194 | int i; | ||
195 | int bytes_sent = 0; | ||
196 | int transfer_size; | ||
197 | |||
198 | dbg("%s - port %d", __func__, port->number); | ||
199 | |||
200 | while (count > 0) { | ||
201 | /* try to find a free urb in our list of them */ | ||
202 | urb = NULL; | ||
203 | |||
204 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
205 | |||
206 | for (i = 0; i < NUM_URBS; ++i) { | ||
207 | if (write_urb_pool[i]->status != -EINPROGRESS) { | ||
208 | urb = write_urb_pool[i]; | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
214 | |||
215 | if (urb == NULL) { | ||
216 | dbg("%s - no more free urbs", __func__); | ||
217 | goto exit; | ||
218 | } | ||
219 | |||
220 | if (urb->transfer_buffer == NULL) { | ||
221 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); | ||
222 | if (urb->transfer_buffer == NULL) { | ||
223 | dev_err(&port->dev, | ||
224 | "%s no more kernel memory...\n", | ||
225 | __func__); | ||
226 | goto exit; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); | ||
231 | |||
232 | memcpy(urb->transfer_buffer, current_position, transfer_size); | ||
233 | |||
234 | usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer); | ||
235 | |||
236 | /* build up our urb */ | ||
237 | usb_fill_bulk_urb( | ||
238 | urb, | ||
239 | serial->dev, | ||
240 | usb_sndbulkpipe(serial->dev, | ||
241 | port->bulk_out_endpointAddress), | ||
242 | urb->transfer_buffer, | ||
243 | transfer_size, | ||
244 | empeg_write_bulk_callback, | ||
245 | port); | ||
246 | |||
247 | /* send it down the pipe */ | ||
248 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
249 | if (status) { | ||
250 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); | ||
251 | bytes_sent = status; | ||
252 | break; | ||
253 | } | ||
254 | |||
255 | current_position += transfer_size; | ||
256 | bytes_sent += transfer_size; | ||
257 | count -= transfer_size; | ||
258 | bytes_out += transfer_size; | ||
259 | |||
260 | } | ||
261 | exit: | ||
262 | return bytes_sent; | ||
263 | } | ||
264 | |||
265 | |||
266 | static int empeg_write_room(struct tty_struct *tty) | ||
267 | { | ||
268 | struct usb_serial_port *port = tty->driver_data; | ||
269 | unsigned long flags; | ||
270 | int i; | ||
271 | int room = 0; | ||
272 | |||
273 | dbg("%s - port %d", __func__, port->number); | ||
274 | |||
275 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
276 | /* tally up the number of bytes available */ | ||
277 | for (i = 0; i < NUM_URBS; ++i) { | ||
278 | if (write_urb_pool[i]->status != -EINPROGRESS) | ||
279 | room += URB_TRANSFER_BUFFER_SIZE; | ||
280 | } | ||
281 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
282 | dbg("%s - returns %d", __func__, room); | ||
283 | return room; | ||
284 | |||
285 | } | ||
286 | |||
287 | |||
288 | static int empeg_chars_in_buffer(struct tty_struct *tty) | ||
289 | { | ||
290 | struct usb_serial_port *port = tty->driver_data; | ||
291 | unsigned long flags; | ||
292 | int i; | ||
293 | int chars = 0; | ||
294 | |||
295 | dbg("%s - port %d", __func__, port->number); | ||
296 | |||
297 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
298 | |||
299 | /* tally up the number of bytes waiting */ | ||
300 | for (i = 0; i < NUM_URBS; ++i) { | ||
301 | if (write_urb_pool[i]->status == -EINPROGRESS) | ||
302 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
303 | } | ||
304 | |||
305 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
306 | dbg("%s - returns %d", __func__, chars); | ||
307 | return chars; | ||
308 | } | ||
309 | |||
310 | |||
311 | static void empeg_write_bulk_callback(struct urb *urb) | ||
312 | { | ||
313 | struct usb_serial_port *port = urb->context; | ||
314 | int status = urb->status; | ||
315 | |||
316 | dbg("%s - port %d", __func__, port->number); | ||
317 | |||
318 | if (status) { | ||
319 | dbg("%s - nonzero write bulk status received: %d", | ||
320 | __func__, status); | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | usb_serial_port_softint(port); | ||
325 | } | ||
326 | |||
327 | |||
328 | static void empeg_read_bulk_callback(struct urb *urb) | ||
329 | { | ||
330 | struct usb_serial_port *port = urb->context; | ||
331 | struct tty_struct *tty; | ||
332 | unsigned char *data = urb->transfer_buffer; | ||
333 | int result; | ||
334 | int status = urb->status; | ||
335 | |||
336 | dbg("%s - port %d", __func__, port->number); | ||
337 | |||
338 | if (status) { | ||
339 | dbg("%s - nonzero read bulk status received: %d", | ||
340 | __func__, status); | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
345 | urb->actual_length, data); | ||
346 | tty = tty_port_tty_get(&port->port); | ||
347 | |||
348 | if (urb->actual_length) { | ||
349 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
350 | tty_flip_buffer_push(tty); | ||
351 | bytes_in += urb->actual_length; | ||
352 | } | ||
353 | tty_kref_put(tty); | ||
354 | |||
355 | /* Continue trying to always read */ | ||
356 | usb_fill_bulk_urb( | ||
357 | port->read_urb, | ||
358 | port->serial->dev, | ||
359 | usb_rcvbulkpipe(port->serial->dev, | ||
360 | port->bulk_in_endpointAddress), | ||
361 | port->read_urb->transfer_buffer, | ||
362 | port->read_urb->transfer_buffer_length, | ||
363 | empeg_read_bulk_callback, | ||
364 | port); | ||
365 | |||
366 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
367 | |||
368 | if (result) | ||
369 | dev_err(&urb->dev->dev, | ||
370 | "%s - failed resubmitting read urb, error %d\n", | ||
371 | __func__, result); | ||
372 | |||
373 | return; | ||
374 | |||
375 | } | ||
376 | |||
377 | |||
378 | static void empeg_throttle(struct tty_struct *tty) | ||
379 | { | ||
380 | struct usb_serial_port *port = tty->driver_data; | ||
381 | dbg("%s - port %d", __func__, port->number); | ||
382 | usb_kill_urb(port->read_urb); | ||
383 | } | ||
384 | |||
385 | |||
386 | static void empeg_unthrottle(struct tty_struct *tty) | ||
387 | { | ||
388 | struct usb_serial_port *port = tty->driver_data; | ||
389 | int result; | ||
390 | dbg("%s - port %d", __func__, port->number); | ||
391 | |||
392 | port->read_urb->dev = port->serial->dev; | ||
393 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
394 | if (result) | ||
395 | dev_err(&port->dev, | ||
396 | "%s - failed submitting read urb, error %d\n", | ||
397 | __func__, result); | ||
398 | } | ||
399 | |||
400 | |||
401 | static int empeg_startup(struct usb_serial *serial) | ||
402 | { | 78 | { |
403 | int r; | 79 | int r; |
404 | 80 | ||
@@ -414,10 +90,8 @@ static int empeg_startup(struct usb_serial *serial) | |||
414 | 90 | ||
415 | /* continue on with initialization */ | 91 | /* continue on with initialization */ |
416 | return r; | 92 | return r; |
417 | |||
418 | } | 93 | } |
419 | 94 | ||
420 | |||
421 | static void empeg_init_termios(struct tty_struct *tty) | 95 | static void empeg_init_termios(struct tty_struct *tty) |
422 | { | 96 | { |
423 | struct ktermios *termios = tty->termios; | 97 | struct ktermios *termios = tty->termios; |
@@ -462,77 +136,28 @@ static void empeg_init_termios(struct tty_struct *tty) | |||
462 | tty_encode_baud_rate(tty, 115200, 115200); | 136 | tty_encode_baud_rate(tty, 115200, 115200); |
463 | } | 137 | } |
464 | 138 | ||
465 | |||
466 | static int __init empeg_init(void) | 139 | static int __init empeg_init(void) |
467 | { | 140 | { |
468 | struct urb *urb; | 141 | int retval; |
469 | int i, retval; | ||
470 | |||
471 | /* create our write urb pool and transfer buffers */ | ||
472 | spin_lock_init(&write_urb_pool_lock); | ||
473 | for (i = 0; i < NUM_URBS; ++i) { | ||
474 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
475 | write_urb_pool[i] = urb; | ||
476 | if (urb == NULL) { | ||
477 | printk(KERN_ERR "empeg: No more urbs???\n"); | ||
478 | continue; | ||
479 | } | ||
480 | |||
481 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, | ||
482 | GFP_KERNEL); | ||
483 | if (!urb->transfer_buffer) { | ||
484 | printk(KERN_ERR "empeg: %s - out of memory for urb " | ||
485 | "buffers.", __func__); | ||
486 | continue; | ||
487 | } | ||
488 | } | ||
489 | 142 | ||
490 | retval = usb_serial_register(&empeg_device); | 143 | retval = usb_serial_register(&empeg_device); |
491 | if (retval) | 144 | if (retval) |
492 | goto failed_usb_serial_register; | 145 | return retval; |
493 | retval = usb_register(&empeg_driver); | 146 | retval = usb_register(&empeg_driver); |
494 | if (retval) | 147 | if (retval) { |
495 | goto failed_usb_register; | 148 | usb_serial_deregister(&empeg_device); |
496 | 149 | return retval; | |
150 | } | ||
497 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 151 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" |
498 | DRIVER_DESC "\n"); | 152 | DRIVER_DESC "\n"); |
499 | 153 | ||
500 | return 0; | 154 | return 0; |
501 | failed_usb_register: | ||
502 | usb_serial_deregister(&empeg_device); | ||
503 | failed_usb_serial_register: | ||
504 | for (i = 0; i < NUM_URBS; ++i) { | ||
505 | if (write_urb_pool[i]) { | ||
506 | kfree(write_urb_pool[i]->transfer_buffer); | ||
507 | usb_free_urb(write_urb_pool[i]); | ||
508 | } | ||
509 | } | ||
510 | return retval; | ||
511 | } | 155 | } |
512 | 156 | ||
513 | |||
514 | static void __exit empeg_exit(void) | 157 | static void __exit empeg_exit(void) |
515 | { | 158 | { |
516 | int i; | ||
517 | unsigned long flags; | ||
518 | |||
519 | usb_deregister(&empeg_driver); | 159 | usb_deregister(&empeg_driver); |
520 | usb_serial_deregister(&empeg_device); | 160 | usb_serial_deregister(&empeg_device); |
521 | |||
522 | spin_lock_irqsave(&write_urb_pool_lock, flags); | ||
523 | |||
524 | for (i = 0; i < NUM_URBS; ++i) { | ||
525 | if (write_urb_pool[i]) { | ||
526 | /* FIXME - uncomment the following usb_kill_urb call | ||
527 | * when the host controllers get fixed to set urb->dev | ||
528 | * = NULL after the urb is finished. Otherwise this | ||
529 | * call oopses. */ | ||
530 | /* usb_kill_urb(write_urb_pool[i]); */ | ||
531 | kfree(write_urb_pool[i]->transfer_buffer); | ||
532 | usb_free_urb(write_urb_pool[i]); | ||
533 | } | ||
534 | } | ||
535 | spin_unlock_irqrestore(&write_urb_pool_lock, flags); | ||
536 | } | 161 | } |
537 | 162 | ||
538 | 163 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1d7c4fac02e8..050211afc07e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * USB FTDI SIO driver | 2 | * USB FTDI SIO driver |
3 | * | 3 | * |
4 | * Copyright (C) 2009 - 2010 | ||
5 | * Johan Hovold (jhovold@gmail.com) | ||
4 | * Copyright (C) 1999 - 2001 | 6 | * Copyright (C) 1999 - 2001 |
5 | * Greg Kroah-Hartman (greg@kroah.com) | 7 | * Greg Kroah-Hartman (greg@kroah.com) |
6 | * Bill Ryder (bryder@sgi.com) | 8 | * Bill Ryder (bryder@sgi.com) |
@@ -49,8 +51,8 @@ | |||
49 | /* | 51 | /* |
50 | * Version Information | 52 | * Version Information |
51 | */ | 53 | */ |
52 | #define DRIVER_VERSION "v1.5.0" | 54 | #define DRIVER_VERSION "v1.6.0" |
53 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr" | 55 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr, Johan Hovold <jhovold@gmail.com>" |
54 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 56 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
55 | 57 | ||
56 | static int debug; | 58 | static int debug; |
@@ -59,7 +61,7 @@ static __u16 product; | |||
59 | 61 | ||
60 | struct ftdi_private { | 62 | struct ftdi_private { |
61 | struct kref kref; | 63 | struct kref kref; |
62 | ftdi_chip_type_t chip_type; | 64 | enum ftdi_chip_type chip_type; |
63 | /* type of device, either SIO or FT8U232AM */ | 65 | /* type of device, either SIO or FT8U232AM */ |
64 | int baud_base; /* baud base clock for divisor setting */ | 66 | int baud_base; /* baud base clock for divisor setting */ |
65 | int custom_divisor; /* custom_divisor kludge, this is for | 67 | int custom_divisor; /* custom_divisor kludge, this is for |
@@ -69,10 +71,6 @@ struct ftdi_private { | |||
69 | /* the last data state set - needed for doing | 71 | /* the last data state set - needed for doing |
70 | * a break | 72 | * a break |
71 | */ | 73 | */ |
72 | int write_offset; /* This is the offset in the usb data block to | ||
73 | * write the serial data - it varies between | ||
74 | * devices | ||
75 | */ | ||
76 | int flags; /* some ASYNC_xxxx flags are supported */ | 74 | int flags; /* some ASYNC_xxxx flags are supported */ |
77 | unsigned long last_dtr_rts; /* saved modem control outputs */ | 75 | unsigned long last_dtr_rts; /* saved modem control outputs */ |
78 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 76 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
@@ -87,9 +85,6 @@ struct ftdi_private { | |||
87 | be enabled */ | 85 | be enabled */ |
88 | 86 | ||
89 | unsigned int latency; /* latency setting in use */ | 87 | unsigned int latency; /* latency setting in use */ |
90 | spinlock_t tx_lock; /* spinlock for transmit state */ | ||
91 | unsigned long tx_outstanding_bytes; | ||
92 | unsigned long tx_outstanding_urbs; | ||
93 | unsigned short max_packet_size; | 88 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ | 89 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ |
95 | }; | 90 | }; |
@@ -768,9 +763,6 @@ static const char *ftdi_chip_name[] = { | |||
768 | }; | 763 | }; |
769 | 764 | ||
770 | 765 | ||
771 | /* Constants for read urb and write urb */ | ||
772 | #define BUFSZ 512 | ||
773 | |||
774 | /* Used for TIOCMIWAIT */ | 766 | /* Used for TIOCMIWAIT */ |
775 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) | 767 | #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) |
776 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) | 768 | #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) |
@@ -787,13 +779,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port); | |||
787 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port); | 779 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port); |
788 | static void ftdi_close(struct usb_serial_port *port); | 780 | static void ftdi_close(struct usb_serial_port *port); |
789 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on); | 781 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on); |
790 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | 782 | static void ftdi_process_read_urb(struct urb *urb); |
791 | const unsigned char *buf, int count); | 783 | static int ftdi_prepare_write_buffer(struct usb_serial_port *port, |
792 | static int ftdi_write_room(struct tty_struct *tty); | 784 | void *dest, size_t size); |
793 | static int ftdi_chars_in_buffer(struct tty_struct *tty); | ||
794 | static void ftdi_write_bulk_callback(struct urb *urb); | ||
795 | static void ftdi_read_bulk_callback(struct urb *urb); | ||
796 | static void ftdi_process_read(struct usb_serial_port *port); | ||
797 | static void ftdi_set_termios(struct tty_struct *tty, | 785 | static void ftdi_set_termios(struct tty_struct *tty, |
798 | struct usb_serial_port *port, struct ktermios *old); | 786 | struct usb_serial_port *port, struct ktermios *old); |
799 | static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); | 787 | static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); |
@@ -802,8 +790,6 @@ static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | |||
802 | static int ftdi_ioctl(struct tty_struct *tty, struct file *file, | 790 | static int ftdi_ioctl(struct tty_struct *tty, struct file *file, |
803 | unsigned int cmd, unsigned long arg); | 791 | unsigned int cmd, unsigned long arg); |
804 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state); | 792 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state); |
805 | static void ftdi_throttle(struct tty_struct *tty); | ||
806 | static void ftdi_unthrottle(struct tty_struct *tty); | ||
807 | 793 | ||
808 | static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); | 794 | static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); |
809 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); | 795 | static unsigned short int ftdi_232am_baud_to_divisor(int baud); |
@@ -821,19 +807,18 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
821 | .usb_driver = &ftdi_driver, | 807 | .usb_driver = &ftdi_driver, |
822 | .id_table = id_table_combined, | 808 | .id_table = id_table_combined, |
823 | .num_ports = 1, | 809 | .num_ports = 1, |
810 | .bulk_in_size = 512, | ||
811 | .bulk_out_size = 256, | ||
824 | .probe = ftdi_sio_probe, | 812 | .probe = ftdi_sio_probe, |
825 | .port_probe = ftdi_sio_port_probe, | 813 | .port_probe = ftdi_sio_port_probe, |
826 | .port_remove = ftdi_sio_port_remove, | 814 | .port_remove = ftdi_sio_port_remove, |
827 | .open = ftdi_open, | 815 | .open = ftdi_open, |
828 | .close = ftdi_close, | 816 | .close = ftdi_close, |
829 | .dtr_rts = ftdi_dtr_rts, | 817 | .dtr_rts = ftdi_dtr_rts, |
830 | .throttle = ftdi_throttle, | 818 | .throttle = usb_serial_generic_throttle, |
831 | .unthrottle = ftdi_unthrottle, | 819 | .unthrottle = usb_serial_generic_unthrottle, |
832 | .write = ftdi_write, | 820 | .process_read_urb = ftdi_process_read_urb, |
833 | .write_room = ftdi_write_room, | 821 | .prepare_write_buffer = ftdi_prepare_write_buffer, |
834 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
835 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
836 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
837 | .tiocmget = ftdi_tiocmget, | 822 | .tiocmget = ftdi_tiocmget, |
838 | .tiocmset = ftdi_tiocmset, | 823 | .tiocmset = ftdi_tiocmset, |
839 | .ioctl = ftdi_ioctl, | 824 | .ioctl = ftdi_ioctl, |
@@ -849,9 +834,6 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
849 | #define HIGH 1 | 834 | #define HIGH 1 |
850 | #define LOW 0 | 835 | #define LOW 0 |
851 | 836 | ||
852 | /* number of outstanding urbs to prevent userspace DoS from happening */ | ||
853 | #define URB_UPPER_LIMIT 42 | ||
854 | |||
855 | /* | 837 | /* |
856 | * *************************************************************************** | 838 | * *************************************************************************** |
857 | * Utility functions | 839 | * Utility functions |
@@ -987,7 +969,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
987 | 969 | ||
988 | static __u32 get_ftdi_divisor(struct tty_struct *tty, | 970 | static __u32 get_ftdi_divisor(struct tty_struct *tty, |
989 | struct usb_serial_port *port) | 971 | struct usb_serial_port *port) |
990 | { /* get_ftdi_divisor */ | 972 | { |
991 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 973 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
992 | __u32 div_value = 0; | 974 | __u32 div_value = 0; |
993 | int div_okay = 1; | 975 | int div_okay = 1; |
@@ -1211,12 +1193,11 @@ static int get_serial_info(struct usb_serial_port *port, | |||
1211 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 1193 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
1212 | return -EFAULT; | 1194 | return -EFAULT; |
1213 | return 0; | 1195 | return 0; |
1214 | } /* get_serial_info */ | 1196 | } |
1215 | |||
1216 | 1197 | ||
1217 | static int set_serial_info(struct tty_struct *tty, | 1198 | static int set_serial_info(struct tty_struct *tty, |
1218 | struct usb_serial_port *port, struct serial_struct __user *newinfo) | 1199 | struct usb_serial_port *port, struct serial_struct __user *newinfo) |
1219 | { /* set_serial_info */ | 1200 | { |
1220 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1201 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1221 | struct serial_struct new_serial; | 1202 | struct serial_struct new_serial; |
1222 | struct ftdi_private old_priv; | 1203 | struct ftdi_private old_priv; |
@@ -1279,8 +1260,7 @@ check_and_exit: | |||
1279 | else | 1260 | else |
1280 | mutex_unlock(&priv->cfg_lock); | 1261 | mutex_unlock(&priv->cfg_lock); |
1281 | return 0; | 1262 | return 0; |
1282 | 1263 | } | |
1283 | } /* set_serial_info */ | ||
1284 | 1264 | ||
1285 | 1265 | ||
1286 | /* Determine type of FTDI chip based on USB config and descriptor. */ | 1266 | /* Determine type of FTDI chip based on USB config and descriptor. */ |
@@ -1294,7 +1274,6 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1294 | 1274 | ||
1295 | /* Assume it is not the original SIO device for now. */ | 1275 | /* Assume it is not the original SIO device for now. */ |
1296 | priv->baud_base = 48000000 / 2; | 1276 | priv->baud_base = 48000000 / 2; |
1297 | priv->write_offset = 0; | ||
1298 | 1277 | ||
1299 | version = le16_to_cpu(udev->descriptor.bcdDevice); | 1278 | version = le16_to_cpu(udev->descriptor.bcdDevice); |
1300 | interfaces = udev->actconfig->desc.bNumInterfaces; | 1279 | interfaces = udev->actconfig->desc.bNumInterfaces; |
@@ -1336,7 +1315,6 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1336 | /* Old device. Assume it's the original SIO. */ | 1315 | /* Old device. Assume it's the original SIO. */ |
1337 | priv->chip_type = SIO; | 1316 | priv->chip_type = SIO; |
1338 | priv->baud_base = 12000000 / 16; | 1317 | priv->baud_base = 12000000 / 16; |
1339 | priv->write_offset = 1; | ||
1340 | } else if (version < 0x400) { | 1318 | } else if (version < 0x400) { |
1341 | /* Assume it's an FT8U232AM (or FT8U245AM) */ | 1319 | /* Assume it's an FT8U232AM (or FT8U245AM) */ |
1342 | /* (It might be a BM because of the iSerialNumber bug, | 1320 | /* (It might be a BM because of the iSerialNumber bug, |
@@ -1543,7 +1521,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1543 | } | 1521 | } |
1544 | 1522 | ||
1545 | kref_init(&priv->kref); | 1523 | kref_init(&priv->kref); |
1546 | spin_lock_init(&priv->tx_lock); | ||
1547 | mutex_init(&priv->cfg_lock); | 1524 | mutex_init(&priv->cfg_lock); |
1548 | init_waitqueue_head(&priv->delta_msr_wait); | 1525 | init_waitqueue_head(&priv->delta_msr_wait); |
1549 | 1526 | ||
@@ -1552,28 +1529,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1552 | if (quirk && quirk->port_probe) | 1529 | if (quirk && quirk->port_probe) |
1553 | quirk->port_probe(priv); | 1530 | quirk->port_probe(priv); |
1554 | 1531 | ||
1555 | /* Increase the size of read buffers */ | ||
1556 | kfree(port->bulk_in_buffer); | ||
1557 | port->bulk_in_buffer = kmalloc(BUFSZ, GFP_KERNEL); | ||
1558 | if (!port->bulk_in_buffer) { | ||
1559 | kfree(priv); | ||
1560 | return -ENOMEM; | ||
1561 | } | ||
1562 | if (port->read_urb) { | ||
1563 | port->read_urb->transfer_buffer = port->bulk_in_buffer; | ||
1564 | port->read_urb->transfer_buffer_length = BUFSZ; | ||
1565 | } | ||
1566 | |||
1567 | priv->port = port; | 1532 | priv->port = port; |
1568 | |||
1569 | /* Free port's existing write urb and transfer buffer. */ | ||
1570 | if (port->write_urb) { | ||
1571 | usb_free_urb(port->write_urb); | ||
1572 | port->write_urb = NULL; | ||
1573 | } | ||
1574 | kfree(port->bulk_out_buffer); | ||
1575 | port->bulk_out_buffer = NULL; | ||
1576 | |||
1577 | usb_set_serial_port_data(port, priv); | 1533 | usb_set_serial_port_data(port, priv); |
1578 | 1534 | ||
1579 | ftdi_determine_type(port); | 1535 | ftdi_determine_type(port); |
@@ -1594,7 +1550,7 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) | |||
1594 | priv->flags |= ASYNC_SPD_CUST; | 1550 | priv->flags |= ASYNC_SPD_CUST; |
1595 | priv->custom_divisor = 77; | 1551 | priv->custom_divisor = 77; |
1596 | priv->force_baud = 38400; | 1552 | priv->force_baud = 38400; |
1597 | } /* ftdi_USB_UIRT_setup */ | 1553 | } |
1598 | 1554 | ||
1599 | /* Setup for the HE-TIRA1 device, which requires hardwired | 1555 | /* Setup for the HE-TIRA1 device, which requires hardwired |
1600 | * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ | 1556 | * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ |
@@ -1607,7 +1563,7 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |||
1607 | priv->custom_divisor = 240; | 1563 | priv->custom_divisor = 240; |
1608 | priv->force_baud = 38400; | 1564 | priv->force_baud = 38400; |
1609 | priv->force_rtscts = 1; | 1565 | priv->force_rtscts = 1; |
1610 | } /* ftdi_HE_TIRA1_setup */ | 1566 | } |
1611 | 1567 | ||
1612 | /* | 1568 | /* |
1613 | * Module parameter to control latency timer for NDI FTDI-based USB devices. | 1569 | * Module parameter to control latency timer for NDI FTDI-based USB devices. |
@@ -1700,31 +1656,10 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) | |||
1700 | return 0; | 1656 | return 0; |
1701 | } | 1657 | } |
1702 | 1658 | ||
1703 | static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | ||
1704 | { | ||
1705 | struct urb *urb = port->read_urb; | ||
1706 | struct usb_serial *serial = port->serial; | ||
1707 | int result; | ||
1708 | |||
1709 | usb_fill_bulk_urb(urb, serial->dev, | ||
1710 | usb_rcvbulkpipe(serial->dev, | ||
1711 | port->bulk_in_endpointAddress), | ||
1712 | urb->transfer_buffer, | ||
1713 | urb->transfer_buffer_length, | ||
1714 | ftdi_read_bulk_callback, port); | ||
1715 | result = usb_submit_urb(urb, mem_flags); | ||
1716 | if (result && result != -EPERM) | ||
1717 | dev_err(&port->dev, | ||
1718 | "%s - failed submitting read urb, error %d\n", | ||
1719 | __func__, result); | ||
1720 | return result; | ||
1721 | } | ||
1722 | |||
1723 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | 1659 | static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) |
1724 | { /* ftdi_open */ | 1660 | { |
1725 | struct usb_device *dev = port->serial->dev; | 1661 | struct usb_device *dev = port->serial->dev; |
1726 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1662 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1727 | unsigned long flags; | ||
1728 | int result; | 1663 | int result; |
1729 | 1664 | ||
1730 | dbg("%s", __func__); | 1665 | dbg("%s", __func__); |
@@ -1746,20 +1681,13 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1746 | if (tty) | 1681 | if (tty) |
1747 | ftdi_set_termios(tty, port, tty->termios); | 1682 | ftdi_set_termios(tty, port, tty->termios); |
1748 | 1683 | ||
1749 | /* Not throttled */ | ||
1750 | spin_lock_irqsave(&port->lock, flags); | ||
1751 | port->throttled = 0; | ||
1752 | port->throttle_req = 0; | ||
1753 | spin_unlock_irqrestore(&port->lock, flags); | ||
1754 | |||
1755 | /* Start reading from the device */ | 1684 | /* Start reading from the device */ |
1756 | result = ftdi_submit_read_urb(port, GFP_KERNEL); | 1685 | result = usb_serial_generic_open(tty, port); |
1757 | if (!result) | 1686 | if (!result) |
1758 | kref_get(&priv->kref); | 1687 | kref_get(&priv->kref); |
1759 | 1688 | ||
1760 | return result; | 1689 | return result; |
1761 | } /* ftdi_open */ | 1690 | } |
1762 | |||
1763 | 1691 | ||
1764 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | 1692 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) |
1765 | { | 1693 | { |
@@ -1789,22 +1717,16 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1789 | * usbserial:__serial_close only calls ftdi_close if the point is open | 1717 | * usbserial:__serial_close only calls ftdi_close if the point is open |
1790 | * | 1718 | * |
1791 | * This only gets called when it is the last close | 1719 | * This only gets called when it is the last close |
1792 | * | ||
1793 | * | ||
1794 | */ | 1720 | */ |
1795 | |||
1796 | static void ftdi_close(struct usb_serial_port *port) | 1721 | static void ftdi_close(struct usb_serial_port *port) |
1797 | { /* ftdi_close */ | 1722 | { |
1798 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1723 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1799 | 1724 | ||
1800 | dbg("%s", __func__); | 1725 | dbg("%s", __func__); |
1801 | 1726 | ||
1802 | /* shutdown our bulk read */ | 1727 | usb_serial_generic_close(port); |
1803 | usb_kill_urb(port->read_urb); | ||
1804 | kref_put(&priv->kref, ftdi_sio_priv_release); | 1728 | kref_put(&priv->kref, ftdi_sio_priv_release); |
1805 | } /* ftdi_close */ | 1729 | } |
1806 | |||
1807 | |||
1808 | 1730 | ||
1809 | /* The SIO requires the first byte to have: | 1731 | /* The SIO requires the first byte to have: |
1810 | * B0 1 | 1732 | * B0 1 |
@@ -1813,211 +1735,39 @@ static void ftdi_close(struct usb_serial_port *port) | |||
1813 | * | 1735 | * |
1814 | * The new devices do not require this byte | 1736 | * The new devices do not require this byte |
1815 | */ | 1737 | */ |
1816 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | 1738 | static int ftdi_prepare_write_buffer(struct usb_serial_port *port, |
1817 | const unsigned char *buf, int count) | 1739 | void *dest, size_t size) |
1818 | { /* ftdi_write */ | 1740 | { |
1819 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1741 | struct ftdi_private *priv; |
1820 | struct urb *urb; | 1742 | int count; |
1821 | unsigned char *buffer; | ||
1822 | int data_offset ; /* will be 1 for the SIO and 0 otherwise */ | ||
1823 | int status; | ||
1824 | int transfer_size; | ||
1825 | unsigned long flags; | 1743 | unsigned long flags; |
1826 | 1744 | ||
1827 | dbg("%s port %d, %d bytes", __func__, port->number, count); | 1745 | priv = usb_get_serial_port_data(port); |
1828 | |||
1829 | if (count == 0) { | ||
1830 | dbg("write request of 0 bytes"); | ||
1831 | return 0; | ||
1832 | } | ||
1833 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1834 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { | ||
1835 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1836 | dbg("%s - write limit hit", __func__); | ||
1837 | return 0; | ||
1838 | } | ||
1839 | priv->tx_outstanding_urbs++; | ||
1840 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1841 | |||
1842 | data_offset = priv->write_offset; | ||
1843 | dbg("data_offset set to %d", data_offset); | ||
1844 | |||
1845 | /* Determine total transfer size */ | ||
1846 | transfer_size = count; | ||
1847 | if (data_offset > 0) { | ||
1848 | /* Original sio needs control bytes too... */ | ||
1849 | transfer_size += (data_offset * | ||
1850 | ((count + (priv->max_packet_size - 1 - data_offset)) / | ||
1851 | (priv->max_packet_size - data_offset))); | ||
1852 | } | ||
1853 | |||
1854 | buffer = kmalloc(transfer_size, GFP_ATOMIC); | ||
1855 | if (!buffer) { | ||
1856 | dev_err(&port->dev, | ||
1857 | "%s ran out of kernel memory for urb ...\n", __func__); | ||
1858 | count = -ENOMEM; | ||
1859 | goto error_no_buffer; | ||
1860 | } | ||
1861 | |||
1862 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
1863 | if (!urb) { | ||
1864 | dev_err(&port->dev, "%s - no more free urbs\n", __func__); | ||
1865 | count = -ENOMEM; | ||
1866 | goto error_no_urb; | ||
1867 | } | ||
1868 | 1746 | ||
1869 | /* Copy data */ | 1747 | if (priv->chip_type == SIO) { |
1870 | if (data_offset > 0) { | 1748 | unsigned char *buffer = dest; |
1871 | /* Original sio requires control byte at start of | 1749 | int i, len, c; |
1872 | each packet. */ | 1750 | |
1873 | int user_pktsz = priv->max_packet_size - data_offset; | 1751 | count = 0; |
1874 | int todo = count; | 1752 | spin_lock_irqsave(&port->lock, flags); |
1875 | unsigned char *first_byte = buffer; | 1753 | for (i = 0; i < size - 1; i += priv->max_packet_size) { |
1876 | const unsigned char *current_position = buf; | 1754 | len = min_t(int, size - i, priv->max_packet_size) - 1; |
1877 | 1755 | c = kfifo_out(&port->write_fifo, &buffer[i + 1], len); | |
1878 | while (todo > 0) { | 1756 | if (!c) |
1879 | if (user_pktsz > todo) | 1757 | break; |
1880 | user_pktsz = todo; | 1758 | buffer[i] = (c << 2) + 1; |
1881 | /* Write the control byte at the front of the packet*/ | 1759 | count += c + 1; |
1882 | *first_byte = 1 | ((user_pktsz) << 2); | ||
1883 | /* Copy data for packet */ | ||
1884 | memcpy(first_byte + data_offset, | ||
1885 | current_position, user_pktsz); | ||
1886 | first_byte += user_pktsz + data_offset; | ||
1887 | current_position += user_pktsz; | ||
1888 | todo -= user_pktsz; | ||
1889 | } | 1760 | } |
1761 | spin_unlock_irqrestore(&port->lock, flags); | ||
1890 | } else { | 1762 | } else { |
1891 | /* No control byte required. */ | 1763 | count = kfifo_out_locked(&port->write_fifo, dest, size, |
1892 | /* Copy in the data to send */ | 1764 | &port->lock); |
1893 | memcpy(buffer, buf, count); | ||
1894 | } | ||
1895 | |||
1896 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
1897 | transfer_size, buffer); | ||
1898 | |||
1899 | /* fill the buffer and send it */ | ||
1900 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
1901 | usb_sndbulkpipe(port->serial->dev, | ||
1902 | port->bulk_out_endpointAddress), | ||
1903 | buffer, transfer_size, | ||
1904 | ftdi_write_bulk_callback, port); | ||
1905 | |||
1906 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
1907 | if (status) { | ||
1908 | dev_err(&port->dev, | ||
1909 | "%s - failed submitting write urb, error %d\n", | ||
1910 | __func__, status); | ||
1911 | count = status; | ||
1912 | goto error; | ||
1913 | } else { | ||
1914 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1915 | priv->tx_outstanding_bytes += count; | ||
1916 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1917 | } | 1765 | } |
1918 | 1766 | ||
1919 | /* we are done with this urb, so let the host driver | ||
1920 | * really free it when it is finished with it */ | ||
1921 | usb_free_urb(urb); | ||
1922 | |||
1923 | dbg("%s write returning: %d", __func__, count); | ||
1924 | return count; | ||
1925 | error: | ||
1926 | usb_free_urb(urb); | ||
1927 | error_no_urb: | ||
1928 | kfree(buffer); | ||
1929 | error_no_buffer: | ||
1930 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1931 | priv->tx_outstanding_urbs--; | ||
1932 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1933 | return count; | 1767 | return count; |
1934 | } /* ftdi_write */ | ||
1935 | |||
1936 | |||
1937 | /* This function may get called when the device is closed */ | ||
1938 | |||
1939 | static void ftdi_write_bulk_callback(struct urb *urb) | ||
1940 | { | ||
1941 | unsigned long flags; | ||
1942 | struct usb_serial_port *port = urb->context; | ||
1943 | struct ftdi_private *priv; | ||
1944 | int data_offset; /* will be 1 for the SIO and 0 otherwise */ | ||
1945 | unsigned long countback; | ||
1946 | int status = urb->status; | ||
1947 | |||
1948 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
1949 | kfree(urb->transfer_buffer); | ||
1950 | |||
1951 | dbg("%s - port %d", __func__, port->number); | ||
1952 | |||
1953 | priv = usb_get_serial_port_data(port); | ||
1954 | if (!priv) { | ||
1955 | dbg("%s - bad port private data pointer - exiting", __func__); | ||
1956 | return; | ||
1957 | } | ||
1958 | /* account for transferred data */ | ||
1959 | countback = urb->transfer_buffer_length; | ||
1960 | data_offset = priv->write_offset; | ||
1961 | if (data_offset > 0) { | ||
1962 | /* Subtract the control bytes */ | ||
1963 | countback -= (data_offset * DIV_ROUND_UP(countback, priv->max_packet_size)); | ||
1964 | } | ||
1965 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1966 | --priv->tx_outstanding_urbs; | ||
1967 | priv->tx_outstanding_bytes -= countback; | ||
1968 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1969 | |||
1970 | if (status) { | ||
1971 | dbg("nonzero write bulk status received: %d", status); | ||
1972 | } | ||
1973 | |||
1974 | usb_serial_port_softint(port); | ||
1975 | } /* ftdi_write_bulk_callback */ | ||
1976 | |||
1977 | |||
1978 | static int ftdi_write_room(struct tty_struct *tty) | ||
1979 | { | ||
1980 | struct usb_serial_port *port = tty->driver_data; | ||
1981 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
1982 | int room; | ||
1983 | unsigned long flags; | ||
1984 | |||
1985 | dbg("%s - port %d", __func__, port->number); | ||
1986 | |||
1987 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1988 | if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) { | ||
1989 | /* | ||
1990 | * We really can take anything the user throws at us | ||
1991 | * but let's pick a nice big number to tell the tty | ||
1992 | * layer that we have lots of free space | ||
1993 | */ | ||
1994 | room = 2048; | ||
1995 | } else { | ||
1996 | room = 0; | ||
1997 | } | ||
1998 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1999 | return room; | ||
2000 | } | 1768 | } |
2001 | 1769 | ||
2002 | static int ftdi_chars_in_buffer(struct tty_struct *tty) | 1770 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) |
2003 | { | ||
2004 | struct usb_serial_port *port = tty->driver_data; | ||
2005 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
2006 | int buffered; | ||
2007 | unsigned long flags; | ||
2008 | |||
2009 | dbg("%s - port %d", __func__, port->number); | ||
2010 | |||
2011 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
2012 | buffered = (int)priv->tx_outstanding_bytes; | ||
2013 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
2014 | if (buffered < 0) { | ||
2015 | dev_err(&port->dev, "%s outstanding tx bytes is negative!\n", | ||
2016 | __func__); | ||
2017 | buffered = 0; | ||
2018 | } | ||
2019 | return buffered; | ||
2020 | } | ||
2021 | 1771 | ||
2022 | static int ftdi_process_packet(struct tty_struct *tty, | 1772 | static int ftdi_process_packet(struct tty_struct *tty, |
2023 | struct usb_serial_port *port, struct ftdi_private *priv, | 1773 | struct usb_serial_port *port, struct ftdi_private *priv, |
@@ -2045,28 +1795,21 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2045 | priv->prev_status = status; | 1795 | priv->prev_status = status; |
2046 | } | 1796 | } |
2047 | 1797 | ||
2048 | /* | ||
2049 | * Although the device uses a bitmask and hence can have multiple | ||
2050 | * errors on a packet - the order here sets the priority the error is | ||
2051 | * returned to the tty layer. | ||
2052 | */ | ||
2053 | flag = TTY_NORMAL; | 1798 | flag = TTY_NORMAL; |
2054 | if (packet[1] & FTDI_RS_OE) { | 1799 | if (packet[1] & FTDI_RS_ERR_MASK) { |
2055 | flag = TTY_OVERRUN; | 1800 | /* Break takes precedence over parity, which takes precedence |
2056 | dbg("OVERRRUN error"); | 1801 | * over framing errors */ |
2057 | } | 1802 | if (packet[1] & FTDI_RS_BI) { |
2058 | if (packet[1] & FTDI_RS_BI) { | 1803 | flag = TTY_BREAK; |
2059 | flag = TTY_BREAK; | 1804 | usb_serial_handle_break(port); |
2060 | dbg("BREAK received"); | 1805 | } else if (packet[1] & FTDI_RS_PE) { |
2061 | usb_serial_handle_break(port); | 1806 | flag = TTY_PARITY; |
2062 | } | 1807 | } else if (packet[1] & FTDI_RS_FE) { |
2063 | if (packet[1] & FTDI_RS_PE) { | 1808 | flag = TTY_FRAME; |
2064 | flag = TTY_PARITY; | 1809 | } |
2065 | dbg("PARITY error"); | 1810 | /* Overrun is special, not associated with a char */ |
2066 | } | 1811 | if (packet[1] & FTDI_RS_OE) |
2067 | if (packet[1] & FTDI_RS_FE) { | 1812 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
2068 | flag = TTY_FRAME; | ||
2069 | dbg("FRAMING error"); | ||
2070 | } | 1813 | } |
2071 | 1814 | ||
2072 | len -= 2; | 1815 | len -= 2; |
@@ -2074,20 +1817,21 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2074 | return 0; /* status only */ | 1817 | return 0; /* status only */ |
2075 | ch = packet + 2; | 1818 | ch = packet + 2; |
2076 | 1819 | ||
2077 | if (!(port->console && port->sysrq) && flag == TTY_NORMAL) | 1820 | if (port->port.console && port->sysrq) { |
2078 | tty_insert_flip_string(tty, ch, len); | ||
2079 | else { | ||
2080 | for (i = 0; i < len; i++, ch++) { | 1821 | for (i = 0; i < len; i++, ch++) { |
2081 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 1822 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) |
2082 | tty_insert_flip_char(tty, *ch, flag); | 1823 | tty_insert_flip_char(tty, *ch, flag); |
2083 | } | 1824 | } |
1825 | } else { | ||
1826 | tty_insert_flip_string_fixed_flag(tty, ch, flag, len); | ||
2084 | } | 1827 | } |
1828 | |||
2085 | return len; | 1829 | return len; |
2086 | } | 1830 | } |
2087 | 1831 | ||
2088 | static void ftdi_process_read(struct usb_serial_port *port) | 1832 | static void ftdi_process_read_urb(struct urb *urb) |
2089 | { | 1833 | { |
2090 | struct urb *urb = port->read_urb; | 1834 | struct usb_serial_port *port = urb->context; |
2091 | struct tty_struct *tty; | 1835 | struct tty_struct *tty; |
2092 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1836 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2093 | char *data = (char *)urb->transfer_buffer; | 1837 | char *data = (char *)urb->transfer_buffer; |
@@ -2109,32 +1853,6 @@ static void ftdi_process_read(struct usb_serial_port *port) | |||
2109 | tty_kref_put(tty); | 1853 | tty_kref_put(tty); |
2110 | } | 1854 | } |
2111 | 1855 | ||
2112 | static void ftdi_read_bulk_callback(struct urb *urb) | ||
2113 | { | ||
2114 | struct usb_serial_port *port = urb->context; | ||
2115 | unsigned long flags; | ||
2116 | |||
2117 | dbg("%s - port %d", __func__, port->number); | ||
2118 | |||
2119 | if (urb->status) { | ||
2120 | dbg("%s - nonzero read bulk status received: %d", | ||
2121 | __func__, urb->status); | ||
2122 | return; | ||
2123 | } | ||
2124 | |||
2125 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
2126 | urb->actual_length, urb->transfer_buffer); | ||
2127 | ftdi_process_read(port); | ||
2128 | |||
2129 | spin_lock_irqsave(&port->lock, flags); | ||
2130 | port->throttled = port->throttle_req; | ||
2131 | if (!port->throttled) { | ||
2132 | spin_unlock_irqrestore(&port->lock, flags); | ||
2133 | ftdi_submit_read_urb(port, GFP_ATOMIC); | ||
2134 | } else | ||
2135 | spin_unlock_irqrestore(&port->lock, flags); | ||
2136 | } | ||
2137 | |||
2138 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | 1856 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) |
2139 | { | 1857 | { |
2140 | struct usb_serial_port *port = tty->driver_data; | 1858 | struct usb_serial_port *port = tty->driver_data; |
@@ -2165,15 +1883,13 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2165 | 1883 | ||
2166 | } | 1884 | } |
2167 | 1885 | ||
2168 | |||
2169 | /* old_termios contains the original termios settings and tty->termios contains | 1886 | /* old_termios contains the original termios settings and tty->termios contains |
2170 | * the new setting to be used | 1887 | * the new setting to be used |
2171 | * WARNING: set_termios calls this with old_termios in kernel space | 1888 | * WARNING: set_termios calls this with old_termios in kernel space |
2172 | */ | 1889 | */ |
2173 | |||
2174 | static void ftdi_set_termios(struct tty_struct *tty, | 1890 | static void ftdi_set_termios(struct tty_struct *tty, |
2175 | struct usb_serial_port *port, struct ktermios *old_termios) | 1891 | struct usb_serial_port *port, struct ktermios *old_termios) |
2176 | { /* ftdi_termios */ | 1892 | { |
2177 | struct usb_device *dev = port->serial->dev; | 1893 | struct usb_device *dev = port->serial->dev; |
2178 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1894 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2179 | struct ktermios *termios = tty->termios; | 1895 | struct ktermios *termios = tty->termios; |
@@ -2401,7 +2117,6 @@ static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | |||
2401 | return update_mctrl(port, set, clear); | 2117 | return update_mctrl(port, set, clear); |
2402 | } | 2118 | } |
2403 | 2119 | ||
2404 | |||
2405 | static int ftdi_ioctl(struct tty_struct *tty, struct file *file, | 2120 | static int ftdi_ioctl(struct tty_struct *tty, struct file *file, |
2406 | unsigned int cmd, unsigned long arg) | 2121 | unsigned int cmd, unsigned long arg) |
2407 | { | 2122 | { |
@@ -2470,35 +2185,6 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file, | |||
2470 | return -ENOIOCTLCMD; | 2185 | return -ENOIOCTLCMD; |
2471 | } | 2186 | } |
2472 | 2187 | ||
2473 | static void ftdi_throttle(struct tty_struct *tty) | ||
2474 | { | ||
2475 | struct usb_serial_port *port = tty->driver_data; | ||
2476 | unsigned long flags; | ||
2477 | |||
2478 | dbg("%s - port %d", __func__, port->number); | ||
2479 | |||
2480 | spin_lock_irqsave(&port->lock, flags); | ||
2481 | port->throttle_req = 1; | ||
2482 | spin_unlock_irqrestore(&port->lock, flags); | ||
2483 | } | ||
2484 | |||
2485 | void ftdi_unthrottle(struct tty_struct *tty) | ||
2486 | { | ||
2487 | struct usb_serial_port *port = tty->driver_data; | ||
2488 | int was_throttled; | ||
2489 | unsigned long flags; | ||
2490 | |||
2491 | dbg("%s - port %d", __func__, port->number); | ||
2492 | |||
2493 | spin_lock_irqsave(&port->lock, flags); | ||
2494 | was_throttled = port->throttled; | ||
2495 | port->throttled = port->throttle_req = 0; | ||
2496 | spin_unlock_irqrestore(&port->lock, flags); | ||
2497 | |||
2498 | if (was_throttled) | ||
2499 | ftdi_submit_read_urb(port, GFP_KERNEL); | ||
2500 | } | ||
2501 | |||
2502 | static int __init ftdi_init(void) | 2188 | static int __init ftdi_init(void) |
2503 | { | 2189 | { |
2504 | int retval; | 2190 | int retval; |
@@ -2529,15 +2215,12 @@ failed_sio_register: | |||
2529 | return retval; | 2215 | return retval; |
2530 | } | 2216 | } |
2531 | 2217 | ||
2532 | |||
2533 | static void __exit ftdi_exit(void) | 2218 | static void __exit ftdi_exit(void) |
2534 | { | 2219 | { |
2535 | |||
2536 | dbg("%s", __func__); | 2220 | dbg("%s", __func__); |
2537 | 2221 | ||
2538 | usb_deregister(&ftdi_driver); | 2222 | usb_deregister(&ftdi_driver); |
2539 | usb_serial_deregister(&ftdi_sio_device); | 2223 | usb_serial_deregister(&ftdi_sio_device); |
2540 | |||
2541 | } | 2224 | } |
2542 | 2225 | ||
2543 | 2226 | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index ff9bf80327a3..213fe3d61282 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -23,14 +23,16 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* Commands */ | 25 | /* Commands */ |
26 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 26 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
27 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 27 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
28 | #define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */ | 28 | #define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */ |
29 | #define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */ | 29 | #define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */ |
30 | #define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the port */ | 30 | #define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of |
31 | #define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem status register */ | 31 | the port */ |
32 | #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ | 32 | #define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem |
33 | #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ | 33 | status register */ |
34 | #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ | ||
35 | #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ | ||
34 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ | 36 | #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ |
35 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ | 37 | #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ |
36 | 38 | ||
@@ -52,7 +54,7 @@ | |||
52 | */ | 54 | */ |
53 | 55 | ||
54 | /* Port Identifier Table */ | 56 | /* Port Identifier Table */ |
55 | #define PIT_DEFAULT 0 /* SIOA */ | 57 | #define PIT_DEFAULT 0 /* SIOA */ |
56 | #define PIT_SIOA 1 /* SIOA */ | 58 | #define PIT_SIOA 1 /* SIOA */ |
57 | /* The device this driver is tested with one has only one port */ | 59 | /* The device this driver is tested with one has only one port */ |
58 | #define PIT_SIOB 2 /* SIOB */ | 60 | #define PIT_SIOB 2 /* SIOB */ |
@@ -103,20 +105,21 @@ | |||
103 | * wLength: 0 | 105 | * wLength: 0 |
104 | * Data: None | 106 | * Data: None |
105 | * The BaudDivisor values are calculated as follows: | 107 | * The BaudDivisor values are calculated as follows: |
106 | * - BaseClock is either 12000000 or 48000000 depending on the device. FIXME: I wish | 108 | * - BaseClock is either 12000000 or 48000000 depending on the device. |
107 | * I knew how to detect old chips to select proper base clock! | 109 | * FIXME: I wish I knew how to detect old chips to select proper base clock! |
108 | * - BaudDivisor is a fixed point number encoded in a funny way. | 110 | * - BaudDivisor is a fixed point number encoded in a funny way. |
109 | * (--WRONG WAY OF THINKING--) | 111 | * (--WRONG WAY OF THINKING--) |
110 | * BaudDivisor is a fixed point number encoded with following bit weighs: | 112 | * BaudDivisor is a fixed point number encoded with following bit weighs: |
111 | * (-2)(-1)(13..0). It is a radical with a denominator of 4, so values | 113 | * (-2)(-1)(13..0). It is a radical with a denominator of 4, so values |
112 | * end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...). | 114 | * end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...). |
113 | * (--THE REALITY--) | 115 | * (--THE REALITY--) |
114 | * The both-bits-set has quite different meaning from 0.75 - the chip designers | 116 | * The both-bits-set has quite different meaning from 0.75 - the chip |
115 | * have decided it to mean 0.125 instead of 0.75. | 117 | * designers have decided it to mean 0.125 instead of 0.75. |
116 | * This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates | 118 | * This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates |
117 | * and Flow Control Consideration for USB to RS232". | 119 | * and Flow Control Consideration for USB to RS232". |
118 | * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should | 120 | * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should |
119 | * automagically re-encode the resulting value to take fractions into consideration. | 121 | * automagically re-encode the resulting value to take fractions into |
122 | * consideration. | ||
120 | * As all values are integers, some bit twiddling is in order: | 123 | * As all values are integers, some bit twiddling is in order: |
121 | * BaudDivisor = (BaseClock / 16 / BaudRate) | | 124 | * BaudDivisor = (BaseClock / 16 / BaudRate) | |
122 | * (((BaseClock / 2 / BaudRate) & 4) ? 0x4000 // 0.5 | 125 | * (((BaseClock / 2 / BaudRate) & 4) ? 0x4000 // 0.5 |
@@ -146,7 +149,7 @@ | |||
146 | * not supported by the FT8U232AM). | 149 | * not supported by the FT8U232AM). |
147 | */ | 150 | */ |
148 | 151 | ||
149 | typedef enum { | 152 | enum ftdi_chip_type { |
150 | SIO = 1, | 153 | SIO = 1, |
151 | FT8U232AM = 2, | 154 | FT8U232AM = 2, |
152 | FT232BM = 3, | 155 | FT232BM = 3, |
@@ -154,37 +157,36 @@ typedef enum { | |||
154 | FT232RL = 5, | 157 | FT232RL = 5, |
155 | FT2232H = 6, | 158 | FT2232H = 6, |
156 | FT4232H = 7 | 159 | FT4232H = 7 |
157 | } ftdi_chip_type_t; | 160 | }; |
158 | 161 | ||
159 | typedef enum { | 162 | enum ftdi_sio_baudrate { |
160 | ftdi_sio_b300 = 0, | 163 | ftdi_sio_b300 = 0, |
161 | ftdi_sio_b600 = 1, | 164 | ftdi_sio_b600 = 1, |
162 | ftdi_sio_b1200 = 2, | 165 | ftdi_sio_b1200 = 2, |
163 | ftdi_sio_b2400 = 3, | 166 | ftdi_sio_b2400 = 3, |
164 | ftdi_sio_b4800 = 4, | 167 | ftdi_sio_b4800 = 4, |
165 | ftdi_sio_b9600 = 5, | 168 | ftdi_sio_b9600 = 5, |
166 | ftdi_sio_b19200 = 6, | 169 | ftdi_sio_b19200 = 6, |
167 | ftdi_sio_b38400 = 7, | 170 | ftdi_sio_b38400 = 7, |
168 | ftdi_sio_b57600 = 8, | 171 | ftdi_sio_b57600 = 8, |
169 | ftdi_sio_b115200 = 9 | 172 | ftdi_sio_b115200 = 9 |
170 | } FTDI_SIO_baudrate_t; | 173 | }; |
171 | 174 | ||
172 | /* | 175 | /* |
173 | * The ftdi_8U232AM_xxMHz_byyy constants have been removed. The encoded divisor values | 176 | * The ftdi_8U232AM_xxMHz_byyy constants have been removed. The encoded divisor |
174 | * are calculated internally. | 177 | * values are calculated internally. |
175 | */ | 178 | */ |
176 | 179 | #define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA | |
177 | #define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA | 180 | #define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40 |
178 | #define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40 | 181 | #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8) |
179 | #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8) | 182 | #define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8) |
180 | #define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8) | 183 | #define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8) |
181 | #define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8) | 184 | #define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8) |
182 | #define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8) | 185 | #define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8) |
183 | #define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8) | 186 | #define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11) |
184 | #define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11) | 187 | #define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11) |
185 | #define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11) | 188 | #define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11) |
186 | #define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11) | 189 | #define FTDI_SIO_SET_BREAK (0x1 << 14) |
187 | #define FTDI_SIO_SET_BREAK (0x1 << 14) | ||
188 | /* FTDI_SIO_SET_DATA */ | 190 | /* FTDI_SIO_SET_DATA */ |
189 | 191 | ||
190 | /* | 192 | /* |
@@ -287,8 +289,8 @@ typedef enum { | |||
287 | * | 289 | * |
288 | * A value of zero in the hIndex field disables handshaking | 290 | * A value of zero in the hIndex field disables handshaking |
289 | * | 291 | * |
290 | * If Xon/Xoff handshaking is specified, the hValue field should contain the XOFF character | 292 | * If Xon/Xoff handshaking is specified, the hValue field should contain the |
291 | * and the lValue field contains the XON character. | 293 | * XOFF character and the lValue field contains the XON character. |
292 | */ | 294 | */ |
293 | 295 | ||
294 | /* | 296 | /* |
@@ -373,7 +375,10 @@ typedef enum { | |||
373 | 375 | ||
374 | /* FTDI_SIO_SET_ERROR_CHAR */ | 376 | /* FTDI_SIO_SET_ERROR_CHAR */ |
375 | 377 | ||
376 | /* Set the parity error replacement character for the specified communications port */ | 378 | /* |
379 | * Set the parity error replacement character for the specified communications | ||
380 | * port | ||
381 | */ | ||
377 | 382 | ||
378 | /* | 383 | /* |
379 | * BmRequestType: 0100 0000b | 384 | * BmRequestType: 0100 0000b |
@@ -496,9 +501,10 @@ typedef enum { | |||
496 | * | 501 | * |
497 | * IN Endpoint | 502 | * IN Endpoint |
498 | * | 503 | * |
499 | * The device reserves the first two bytes of data on this endpoint to contain the current | 504 | * The device reserves the first two bytes of data on this endpoint to contain |
500 | * values of the modem and line status registers. In the absence of data, the device | 505 | * the current values of the modem and line status registers. In the absence of |
501 | * generates a message consisting of these two status bytes every 40 ms | 506 | * data, the device generates a message consisting of these two status bytes |
507 | * every 40 ms | ||
502 | * | 508 | * |
503 | * Byte 0: Modem Status | 509 | * Byte 0: Modem Status |
504 | * | 510 | * |
@@ -530,21 +536,21 @@ typedef enum { | |||
530 | #define FTDI_RS0_RI (1 << 6) | 536 | #define FTDI_RS0_RI (1 << 6) |
531 | #define FTDI_RS0_RLSD (1 << 7) | 537 | #define FTDI_RS0_RLSD (1 << 7) |
532 | 538 | ||
533 | #define FTDI_RS_DR 1 | 539 | #define FTDI_RS_DR 1 |
534 | #define FTDI_RS_OE (1<<1) | 540 | #define FTDI_RS_OE (1<<1) |
535 | #define FTDI_RS_PE (1<<2) | 541 | #define FTDI_RS_PE (1<<2) |
536 | #define FTDI_RS_FE (1<<3) | 542 | #define FTDI_RS_FE (1<<3) |
537 | #define FTDI_RS_BI (1<<4) | 543 | #define FTDI_RS_BI (1<<4) |
538 | #define FTDI_RS_THRE (1<<5) | 544 | #define FTDI_RS_THRE (1<<5) |
539 | #define FTDI_RS_TEMT (1<<6) | 545 | #define FTDI_RS_TEMT (1<<6) |
540 | #define FTDI_RS_FIFO (1<<7) | 546 | #define FTDI_RS_FIFO (1<<7) |
541 | 547 | ||
542 | /* | 548 | /* |
543 | * OUT Endpoint | 549 | * OUT Endpoint |
544 | * | 550 | * |
545 | * This device reserves the first bytes of data on this endpoint contain the length | 551 | * This device reserves the first bytes of data on this endpoint contain the |
546 | * and port identifier of the message. For the FTDI USB Serial converter the port | 552 | * length and port identifier of the message. For the FTDI USB Serial converter |
547 | * identifier is always 1. | 553 | * the port identifier is always 1. |
548 | * | 554 | * |
549 | * Byte 0: Line Status | 555 | * Byte 0: Line Status |
550 | * | 556 | * |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 75482cbc3998..94d86c3febcb 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -275,8 +275,8 @@ | |||
275 | /* | 275 | /* |
276 | * Hameg HO820 and HO870 interface (using VID 0x0403) | 276 | * Hameg HO820 and HO870 interface (using VID 0x0403) |
277 | */ | 277 | */ |
278 | #define HAMEG_HO820_PID 0xed74 | 278 | #define HAMEG_HO820_PID 0xed74 |
279 | #define HAMEG_HO870_PID 0xed71 | 279 | #define HAMEG_HO870_PID 0xed71 |
280 | 280 | ||
281 | /* | 281 | /* |
282 | * MaxStream devices www.maxstream.net | 282 | * MaxStream devices www.maxstream.net |
@@ -289,14 +289,14 @@ | |||
289 | * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. | 289 | * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. |
290 | * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. | 290 | * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. |
291 | */ | 291 | */ |
292 | #define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ | 292 | #define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ |
293 | #define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ | 293 | #define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ |
294 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ | 294 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ |
295 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ | 295 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ |
296 | #define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ | 296 | #define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ |
297 | #define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ | 297 | #define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ |
298 | #define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ | 298 | #define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ |
299 | #define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ | 299 | #define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ |
300 | 300 | ||
301 | /* Domintell products http://www.domintell.com */ | 301 | /* Domintell products http://www.domintell.com */ |
302 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ | 302 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ |
@@ -483,9 +483,9 @@ | |||
483 | * Blackfin gnICE JTAG | 483 | * Blackfin gnICE JTAG |
484 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice | 484 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice |
485 | */ | 485 | */ |
486 | #define ADI_VID 0x0456 | 486 | #define ADI_VID 0x0456 |
487 | #define ADI_GNICE_PID 0xF000 | 487 | #define ADI_GNICE_PID 0xF000 |
488 | #define ADI_GNICEPLUS_PID 0xF001 | 488 | #define ADI_GNICEPLUS_PID 0xF001 |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * RATOC REX-USB60F | 491 | * RATOC REX-USB60F |
@@ -611,13 +611,13 @@ | |||
611 | #define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ | 611 | #define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ |
612 | #define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ | 612 | #define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ |
613 | #define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ | 613 | #define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ |
614 | #define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ | 614 | #define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ |
615 | #define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ | 615 | #define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ |
616 | #define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ | 616 | #define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ |
617 | #define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ | 617 | #define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ |
618 | #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ | 618 | #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ |
619 | #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ | 619 | #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ |
620 | #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ | 620 | #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ |
621 | 621 | ||
622 | /* | 622 | /* |
623 | * JETI SPECTROMETER SPECBOS 1201 | 623 | * JETI SPECTROMETER SPECBOS 1201 |
@@ -1013,7 +1013,7 @@ | |||
1013 | */ | 1013 | */ |
1014 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | 1014 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ |
1015 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | 1015 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ |
1016 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | 1016 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ |
1017 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | 1017 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ |
1018 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | 1018 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ |
1019 | 1019 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index f804acb138ec..a817ced82835 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB Serial Converter Generic functions | 2 | * USB Serial Converter Generic functions |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) | ||
4 | * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
@@ -12,6 +13,7 @@ | |||
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/sysrq.h> | ||
15 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
16 | #include <linux/tty_flip.h> | 18 | #include <linux/tty_flip.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -117,7 +119,6 @@ void usb_serial_generic_deregister(void) | |||
117 | 119 | ||
118 | int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) | 120 | int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) |
119 | { | 121 | { |
120 | struct usb_serial *serial = port->serial; | ||
121 | int result = 0; | 122 | int result = 0; |
122 | unsigned long flags; | 123 | unsigned long flags; |
123 | 124 | ||
@@ -130,23 +131,8 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port | |||
130 | spin_unlock_irqrestore(&port->lock, flags); | 131 | spin_unlock_irqrestore(&port->lock, flags); |
131 | 132 | ||
132 | /* if we have a bulk endpoint, start reading from it */ | 133 | /* if we have a bulk endpoint, start reading from it */ |
133 | if (port->bulk_in_size) { | 134 | if (port->bulk_in_size) |
134 | /* Start reading from the device */ | 135 | result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL); |
135 | usb_fill_bulk_urb(port->read_urb, serial->dev, | ||
136 | usb_rcvbulkpipe(serial->dev, | ||
137 | port->bulk_in_endpointAddress), | ||
138 | port->read_urb->transfer_buffer, | ||
139 | port->read_urb->transfer_buffer_length, | ||
140 | ((serial->type->read_bulk_callback) ? | ||
141 | serial->type->read_bulk_callback : | ||
142 | usb_serial_generic_read_bulk_callback), | ||
143 | port); | ||
144 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
145 | if (result) | ||
146 | dev_err(&port->dev, | ||
147 | "%s - failed resubmitting read urb, error %d\n", | ||
148 | __func__, result); | ||
149 | } | ||
150 | 136 | ||
151 | return result; | 137 | return result; |
152 | } | 138 | } |
@@ -155,13 +141,22 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_open); | |||
155 | static void generic_cleanup(struct usb_serial_port *port) | 141 | static void generic_cleanup(struct usb_serial_port *port) |
156 | { | 142 | { |
157 | struct usb_serial *serial = port->serial; | 143 | struct usb_serial *serial = port->serial; |
144 | unsigned long flags; | ||
145 | int i; | ||
158 | 146 | ||
159 | dbg("%s - port %d", __func__, port->number); | 147 | dbg("%s - port %d", __func__, port->number); |
160 | 148 | ||
161 | if (serial->dev) { | 149 | if (serial->dev) { |
162 | /* shutdown any bulk transfers that might be going on */ | 150 | /* shutdown any bulk transfers that might be going on */ |
163 | if (port->bulk_out_size) | 151 | if (port->bulk_out_size) { |
164 | usb_kill_urb(port->write_urb); | 152 | usb_kill_urb(port->write_urb); |
153 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | ||
154 | usb_kill_urb(port->write_urbs[i]); | ||
155 | |||
156 | spin_lock_irqsave(&port->lock, flags); | ||
157 | kfifo_reset_out(&port->write_fifo); | ||
158 | spin_unlock_irqrestore(&port->lock, flags); | ||
159 | } | ||
165 | if (port->bulk_in_size) | 160 | if (port->bulk_in_size) |
166 | usb_kill_urb(port->read_urb); | 161 | usb_kill_urb(port->read_urb); |
167 | } | 162 | } |
@@ -172,146 +167,68 @@ void usb_serial_generic_close(struct usb_serial_port *port) | |||
172 | dbg("%s - port %d", __func__, port->number); | 167 | dbg("%s - port %d", __func__, port->number); |
173 | generic_cleanup(port); | 168 | generic_cleanup(port); |
174 | } | 169 | } |
170 | EXPORT_SYMBOL_GPL(usb_serial_generic_close); | ||
175 | 171 | ||
176 | static int usb_serial_multi_urb_write(struct tty_struct *tty, | 172 | int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, |
177 | struct usb_serial_port *port, const unsigned char *buf, int count) | 173 | void *dest, size_t size) |
178 | { | 174 | { |
179 | unsigned long flags; | 175 | return kfifo_out_locked(&port->write_fifo, dest, size, &port->lock); |
180 | struct urb *urb; | ||
181 | unsigned char *buffer; | ||
182 | int status; | ||
183 | int towrite; | ||
184 | int bwrite = 0; | ||
185 | |||
186 | dbg("%s - port %d", __func__, port->number); | ||
187 | |||
188 | if (count == 0) | ||
189 | dbg("%s - write request of 0 bytes", __func__); | ||
190 | |||
191 | while (count > 0) { | ||
192 | towrite = (count > port->bulk_out_size) ? | ||
193 | port->bulk_out_size : count; | ||
194 | spin_lock_irqsave(&port->lock, flags); | ||
195 | if (port->urbs_in_flight > | ||
196 | port->serial->type->max_in_flight_urbs) { | ||
197 | spin_unlock_irqrestore(&port->lock, flags); | ||
198 | dbg("%s - write limit hit", __func__); | ||
199 | return bwrite; | ||
200 | } | ||
201 | port->tx_bytes_flight += towrite; | ||
202 | port->urbs_in_flight++; | ||
203 | spin_unlock_irqrestore(&port->lock, flags); | ||
204 | |||
205 | buffer = kmalloc(towrite, GFP_ATOMIC); | ||
206 | if (!buffer) { | ||
207 | dev_err(&port->dev, | ||
208 | "%s ran out of kernel memory for urb ...\n", __func__); | ||
209 | goto error_no_buffer; | ||
210 | } | ||
211 | |||
212 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
213 | if (!urb) { | ||
214 | dev_err(&port->dev, "%s - no more free urbs\n", | ||
215 | __func__); | ||
216 | goto error_no_urb; | ||
217 | } | ||
218 | |||
219 | /* Copy data */ | ||
220 | memcpy(buffer, buf + bwrite, towrite); | ||
221 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
222 | towrite, buffer); | ||
223 | /* fill the buffer and send it */ | ||
224 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
225 | usb_sndbulkpipe(port->serial->dev, | ||
226 | port->bulk_out_endpointAddress), | ||
227 | buffer, towrite, | ||
228 | usb_serial_generic_write_bulk_callback, port); | ||
229 | |||
230 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
231 | if (status) { | ||
232 | dev_err(&port->dev, | ||
233 | "%s - failed submitting write urb, error %d\n", | ||
234 | __func__, status); | ||
235 | goto error; | ||
236 | } | ||
237 | |||
238 | /* This urb is the responsibility of the host driver now */ | ||
239 | usb_free_urb(urb); | ||
240 | dbg("%s write: %d", __func__, towrite); | ||
241 | count -= towrite; | ||
242 | bwrite += towrite; | ||
243 | } | ||
244 | return bwrite; | ||
245 | |||
246 | error: | ||
247 | usb_free_urb(urb); | ||
248 | error_no_urb: | ||
249 | kfree(buffer); | ||
250 | error_no_buffer: | ||
251 | spin_lock_irqsave(&port->lock, flags); | ||
252 | port->urbs_in_flight--; | ||
253 | port->tx_bytes_flight -= towrite; | ||
254 | spin_unlock_irqrestore(&port->lock, flags); | ||
255 | return bwrite; | ||
256 | } | 176 | } |
257 | 177 | ||
258 | /** | 178 | /** |
259 | * usb_serial_generic_write_start - kick off an URB write | 179 | * usb_serial_generic_write_start - kick off an URB write |
260 | * @port: Pointer to the &struct usb_serial_port data | 180 | * @port: Pointer to the &struct usb_serial_port data |
261 | * | 181 | * |
262 | * Returns the number of bytes queued on success. This will be zero if there | 182 | * Returns zero on success, or a negative errno value |
263 | * was nothing to send. Otherwise, it returns a negative errno value | ||
264 | */ | 183 | */ |
265 | static int usb_serial_generic_write_start(struct usb_serial_port *port) | 184 | static int usb_serial_generic_write_start(struct usb_serial_port *port) |
266 | { | 185 | { |
267 | struct usb_serial *serial = port->serial; | 186 | struct urb *urb; |
268 | unsigned char *data; | 187 | int count, result; |
269 | int result; | ||
270 | int count; | ||
271 | unsigned long flags; | 188 | unsigned long flags; |
272 | bool start_io; | 189 | int i; |
273 | 190 | ||
274 | /* Atomically determine whether we can and need to start a USB | 191 | if (test_and_set_bit_lock(USB_SERIAL_WRITE_BUSY, &port->flags)) |
275 | * operation. */ | 192 | return 0; |
193 | retry: | ||
276 | spin_lock_irqsave(&port->lock, flags); | 194 | spin_lock_irqsave(&port->lock, flags); |
277 | if (port->write_urb_busy) | 195 | if (!port->write_urbs_free || !kfifo_len(&port->write_fifo)) { |
278 | start_io = false; | 196 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); |
279 | else { | 197 | spin_unlock_irqrestore(&port->lock, flags); |
280 | start_io = (kfifo_len(&port->write_fifo) != 0); | 198 | return 0; |
281 | port->write_urb_busy = start_io; | ||
282 | } | 199 | } |
200 | i = (int)find_first_bit(&port->write_urbs_free, | ||
201 | ARRAY_SIZE(port->write_urbs)); | ||
283 | spin_unlock_irqrestore(&port->lock, flags); | 202 | spin_unlock_irqrestore(&port->lock, flags); |
284 | 203 | ||
285 | if (!start_io) | 204 | urb = port->write_urbs[i]; |
286 | return 0; | 205 | count = port->serial->type->prepare_write_buffer(port, |
287 | 206 | urb->transfer_buffer, | |
288 | data = port->write_urb->transfer_buffer; | 207 | port->bulk_out_size); |
289 | count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock); | 208 | urb->transfer_buffer_length = count; |
290 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | 209 | usb_serial_debug_data(debug, &port->dev, __func__, count, |
291 | 210 | urb->transfer_buffer); | |
292 | /* set up our urb */ | 211 | result = usb_submit_urb(urb, GFP_ATOMIC); |
293 | usb_fill_bulk_urb(port->write_urb, serial->dev, | ||
294 | usb_sndbulkpipe(serial->dev, | ||
295 | port->bulk_out_endpointAddress), | ||
296 | port->write_urb->transfer_buffer, count, | ||
297 | ((serial->type->write_bulk_callback) ? | ||
298 | serial->type->write_bulk_callback : | ||
299 | usb_serial_generic_write_bulk_callback), | ||
300 | port); | ||
301 | |||
302 | /* send the data out the bulk port */ | ||
303 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
304 | if (result) { | 212 | if (result) { |
305 | dev_err(&port->dev, | 213 | dev_err(&port->dev, "%s - error submitting urb: %d\n", |
306 | "%s - failed submitting write urb, error %d\n", | ||
307 | __func__, result); | 214 | __func__, result); |
308 | /* don't have to grab the lock here, as we will | 215 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); |
309 | retry if != 0 */ | 216 | return result; |
310 | port->write_urb_busy = 0; | 217 | } |
311 | } else | 218 | clear_bit(i, &port->write_urbs_free); |
312 | result = count; | ||
313 | 219 | ||
314 | return result; | 220 | spin_lock_irqsave(&port->lock, flags); |
221 | port->tx_bytes += count; | ||
222 | spin_unlock_irqrestore(&port->lock, flags); | ||
223 | |||
224 | /* Try sending off another urb, unless in irq context (in which case | ||
225 | * there will be no free urb). */ | ||
226 | if (!in_irq()) | ||
227 | goto retry; | ||
228 | |||
229 | clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); | ||
230 | |||
231 | return 0; | ||
315 | } | 232 | } |
316 | 233 | ||
317 | /** | 234 | /** |
@@ -328,7 +245,6 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) | |||
328 | int usb_serial_generic_write(struct tty_struct *tty, | 245 | int usb_serial_generic_write(struct tty_struct *tty, |
329 | struct usb_serial_port *port, const unsigned char *buf, int count) | 246 | struct usb_serial_port *port, const unsigned char *buf, int count) |
330 | { | 247 | { |
331 | struct usb_serial *serial = port->serial; | ||
332 | int result; | 248 | int result; |
333 | 249 | ||
334 | dbg("%s - port %d", __func__, port->number); | 250 | dbg("%s - port %d", __func__, port->number); |
@@ -337,31 +253,23 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
337 | if (!port->bulk_out_size) | 253 | if (!port->bulk_out_size) |
338 | return -ENODEV; | 254 | return -ENODEV; |
339 | 255 | ||
340 | if (count == 0) { | 256 | if (!count) |
341 | dbg("%s - write request of 0 bytes", __func__); | ||
342 | return 0; | 257 | return 0; |
343 | } | ||
344 | |||
345 | if (serial->type->max_in_flight_urbs) | ||
346 | return usb_serial_multi_urb_write(tty, port, | ||
347 | buf, count); | ||
348 | 258 | ||
349 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); | 259 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); |
350 | result = usb_serial_generic_write_start(port); | 260 | result = usb_serial_generic_write_start(port); |
261 | if (result) | ||
262 | return result; | ||
351 | 263 | ||
352 | if (result >= 0) | 264 | return count; |
353 | result = count; | ||
354 | |||
355 | return result; | ||
356 | } | 265 | } |
357 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); | 266 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); |
358 | 267 | ||
359 | int usb_serial_generic_write_room(struct tty_struct *tty) | 268 | int usb_serial_generic_write_room(struct tty_struct *tty) |
360 | { | 269 | { |
361 | struct usb_serial_port *port = tty->driver_data; | 270 | struct usb_serial_port *port = tty->driver_data; |
362 | struct usb_serial *serial = port->serial; | ||
363 | unsigned long flags; | 271 | unsigned long flags; |
364 | int room = 0; | 272 | int room; |
365 | 273 | ||
366 | dbg("%s - port %d", __func__, port->number); | 274 | dbg("%s - port %d", __func__, port->number); |
367 | 275 | ||
@@ -369,14 +277,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
369 | return 0; | 277 | return 0; |
370 | 278 | ||
371 | spin_lock_irqsave(&port->lock, flags); | 279 | spin_lock_irqsave(&port->lock, flags); |
372 | if (serial->type->max_in_flight_urbs) { | 280 | room = kfifo_avail(&port->write_fifo); |
373 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) | ||
374 | room = port->bulk_out_size * | ||
375 | (serial->type->max_in_flight_urbs - | ||
376 | port->urbs_in_flight); | ||
377 | } else { | ||
378 | room = kfifo_avail(&port->write_fifo); | ||
379 | } | ||
380 | spin_unlock_irqrestore(&port->lock, flags); | 281 | spin_unlock_irqrestore(&port->lock, flags); |
381 | 282 | ||
382 | dbg("%s - returns %d", __func__, room); | 283 | dbg("%s - returns %d", __func__, room); |
@@ -386,7 +287,6 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
386 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | 287 | int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) |
387 | { | 288 | { |
388 | struct usb_serial_port *port = tty->driver_data; | 289 | struct usb_serial_port *port = tty->driver_data; |
389 | struct usb_serial *serial = port->serial; | ||
390 | unsigned long flags; | 290 | unsigned long flags; |
391 | int chars; | 291 | int chars; |
392 | 292 | ||
@@ -396,61 +296,47 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
396 | return 0; | 296 | return 0; |
397 | 297 | ||
398 | spin_lock_irqsave(&port->lock, flags); | 298 | spin_lock_irqsave(&port->lock, flags); |
399 | if (serial->type->max_in_flight_urbs) | 299 | chars = kfifo_len(&port->write_fifo) + port->tx_bytes; |
400 | chars = port->tx_bytes_flight; | ||
401 | else | ||
402 | chars = kfifo_len(&port->write_fifo); | ||
403 | spin_unlock_irqrestore(&port->lock, flags); | 300 | spin_unlock_irqrestore(&port->lock, flags); |
404 | 301 | ||
405 | dbg("%s - returns %d", __func__, chars); | 302 | dbg("%s - returns %d", __func__, chars); |
406 | return chars; | 303 | return chars; |
407 | } | 304 | } |
408 | 305 | ||
409 | 306 | int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, | |
410 | void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, | 307 | gfp_t mem_flags) |
411 | gfp_t mem_flags) | ||
412 | { | 308 | { |
413 | struct urb *urb = port->read_urb; | ||
414 | struct usb_serial *serial = port->serial; | ||
415 | int result; | 309 | int result; |
416 | 310 | ||
417 | /* Continue reading from device */ | 311 | result = usb_submit_urb(port->read_urb, mem_flags); |
418 | usb_fill_bulk_urb(urb, serial->dev, | ||
419 | usb_rcvbulkpipe(serial->dev, | ||
420 | port->bulk_in_endpointAddress), | ||
421 | urb->transfer_buffer, | ||
422 | urb->transfer_buffer_length, | ||
423 | ((serial->type->read_bulk_callback) ? | ||
424 | serial->type->read_bulk_callback : | ||
425 | usb_serial_generic_read_bulk_callback), port); | ||
426 | |||
427 | result = usb_submit_urb(urb, mem_flags); | ||
428 | if (result && result != -EPERM) { | 312 | if (result && result != -EPERM) { |
429 | dev_err(&port->dev, | 313 | dev_err(&port->dev, "%s - error submitting urb: %d\n", |
430 | "%s - failed resubmitting read urb, error %d\n", | ||
431 | __func__, result); | 314 | __func__, result); |
432 | } | 315 | } |
316 | return result; | ||
433 | } | 317 | } |
434 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); | 318 | EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urb); |
435 | 319 | ||
436 | /* Push data to tty layer and resubmit the bulk read URB */ | 320 | void usb_serial_generic_process_read_urb(struct urb *urb) |
437 | static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | ||
438 | { | 321 | { |
439 | struct urb *urb = port->read_urb; | 322 | struct usb_serial_port *port = urb->context; |
440 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 323 | struct tty_struct *tty; |
441 | char *ch = (char *)urb->transfer_buffer; | 324 | char *ch = (char *)urb->transfer_buffer; |
442 | int i; | 325 | int i; |
443 | 326 | ||
327 | if (!urb->actual_length) | ||
328 | return; | ||
329 | |||
330 | tty = tty_port_tty_get(&port->port); | ||
444 | if (!tty) | 331 | if (!tty) |
445 | goto done; | 332 | return; |
446 | 333 | ||
447 | /* The per character mucking around with sysrq path it too slow for | 334 | /* The per character mucking around with sysrq path it too slow for |
448 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases | 335 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
449 | where the USB serial is not a console anyway */ | 336 | where the USB serial is not a console anyway */ |
450 | if (!port->console || !port->sysrq) | 337 | if (!port->port.console || !port->sysrq) |
451 | tty_insert_flip_string(tty, ch, urb->actual_length); | 338 | tty_insert_flip_string(tty, ch, urb->actual_length); |
452 | else { | 339 | else { |
453 | /* Push data to tty */ | ||
454 | for (i = 0; i < urb->actual_length; i++, ch++) { | 340 | for (i = 0; i < urb->actual_length; i++, ch++) { |
455 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 341 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) |
456 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 342 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); |
@@ -458,9 +344,8 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | |||
458 | } | 344 | } |
459 | tty_flip_buffer_push(tty); | 345 | tty_flip_buffer_push(tty); |
460 | tty_kref_put(tty); | 346 | tty_kref_put(tty); |
461 | done: | ||
462 | usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC); | ||
463 | } | 347 | } |
348 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); | ||
464 | 349 | ||
465 | void usb_serial_generic_read_bulk_callback(struct urb *urb) | 350 | void usb_serial_generic_read_bulk_callback(struct urb *urb) |
466 | { | 351 | { |
@@ -479,13 +364,14 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) | |||
479 | 364 | ||
480 | usb_serial_debug_data(debug, &port->dev, __func__, | 365 | usb_serial_debug_data(debug, &port->dev, __func__, |
481 | urb->actual_length, data); | 366 | urb->actual_length, data); |
367 | port->serial->type->process_read_urb(urb); | ||
482 | 368 | ||
483 | /* Throttle the device if requested by tty */ | 369 | /* Throttle the device if requested by tty */ |
484 | spin_lock_irqsave(&port->lock, flags); | 370 | spin_lock_irqsave(&port->lock, flags); |
485 | port->throttled = port->throttle_req; | 371 | port->throttled = port->throttle_req; |
486 | if (!port->throttled) { | 372 | if (!port->throttled) { |
487 | spin_unlock_irqrestore(&port->lock, flags); | 373 | spin_unlock_irqrestore(&port->lock, flags); |
488 | flush_and_resubmit_read_urb(port); | 374 | usb_serial_generic_submit_read_urb(port, GFP_ATOMIC); |
489 | } else | 375 | } else |
490 | spin_unlock_irqrestore(&port->lock, flags); | 376 | spin_unlock_irqrestore(&port->lock, flags); |
491 | } | 377 | } |
@@ -496,30 +382,29 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
496 | unsigned long flags; | 382 | unsigned long flags; |
497 | struct usb_serial_port *port = urb->context; | 383 | struct usb_serial_port *port = urb->context; |
498 | int status = urb->status; | 384 | int status = urb->status; |
385 | int i; | ||
499 | 386 | ||
500 | dbg("%s - port %d", __func__, port->number); | 387 | dbg("%s - port %d", __func__, port->number); |
501 | 388 | ||
502 | if (port->serial->type->max_in_flight_urbs) { | 389 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) |
503 | kfree(urb->transfer_buffer); | 390 | if (port->write_urbs[i] == urb) |
391 | break; | ||
392 | |||
393 | spin_lock_irqsave(&port->lock, flags); | ||
394 | port->tx_bytes -= urb->transfer_buffer_length; | ||
395 | set_bit(i, &port->write_urbs_free); | ||
396 | spin_unlock_irqrestore(&port->lock, flags); | ||
397 | |||
398 | if (status) { | ||
399 | dbg("%s - non-zero urb status: %d", __func__, status); | ||
504 | 400 | ||
505 | spin_lock_irqsave(&port->lock, flags); | 401 | spin_lock_irqsave(&port->lock, flags); |
506 | --port->urbs_in_flight; | 402 | kfifo_reset_out(&port->write_fifo); |
507 | port->tx_bytes_flight -= urb->transfer_buffer_length; | ||
508 | if (port->urbs_in_flight < 0) | ||
509 | port->urbs_in_flight = 0; | ||
510 | spin_unlock_irqrestore(&port->lock, flags); | 403 | spin_unlock_irqrestore(&port->lock, flags); |
511 | } else { | 404 | } else { |
512 | port->write_urb_busy = 0; | 405 | usb_serial_generic_write_start(port); |
513 | |||
514 | if (status) | ||
515 | kfifo_reset_out(&port->write_fifo); | ||
516 | else | ||
517 | usb_serial_generic_write_start(port); | ||
518 | } | 406 | } |
519 | 407 | ||
520 | if (status) | ||
521 | dbg("%s - non-zero urb status: %d", __func__, status); | ||
522 | |||
523 | usb_serial_port_softint(port); | 408 | usb_serial_port_softint(port); |
524 | } | 409 | } |
525 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 410 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
@@ -537,31 +422,31 @@ void usb_serial_generic_throttle(struct tty_struct *tty) | |||
537 | port->throttle_req = 1; | 422 | port->throttle_req = 1; |
538 | spin_unlock_irqrestore(&port->lock, flags); | 423 | spin_unlock_irqrestore(&port->lock, flags); |
539 | } | 424 | } |
425 | EXPORT_SYMBOL_GPL(usb_serial_generic_throttle); | ||
540 | 426 | ||
541 | void usb_serial_generic_unthrottle(struct tty_struct *tty) | 427 | void usb_serial_generic_unthrottle(struct tty_struct *tty) |
542 | { | 428 | { |
543 | struct usb_serial_port *port = tty->driver_data; | 429 | struct usb_serial_port *port = tty->driver_data; |
544 | int was_throttled; | 430 | int was_throttled; |
545 | unsigned long flags; | ||
546 | 431 | ||
547 | dbg("%s - port %d", __func__, port->number); | 432 | dbg("%s - port %d", __func__, port->number); |
548 | 433 | ||
549 | /* Clear the throttle flags */ | 434 | /* Clear the throttle flags */ |
550 | spin_lock_irqsave(&port->lock, flags); | 435 | spin_lock_irq(&port->lock); |
551 | was_throttled = port->throttled; | 436 | was_throttled = port->throttled; |
552 | port->throttled = port->throttle_req = 0; | 437 | port->throttled = port->throttle_req = 0; |
553 | spin_unlock_irqrestore(&port->lock, flags); | 438 | spin_unlock_irq(&port->lock); |
554 | 439 | ||
555 | if (was_throttled) { | 440 | if (was_throttled) |
556 | /* Resume reading from device */ | 441 | usb_serial_generic_submit_read_urb(port, GFP_KERNEL); |
557 | flush_and_resubmit_read_urb(port); | ||
558 | } | ||
559 | } | 442 | } |
443 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); | ||
560 | 444 | ||
445 | #ifdef CONFIG_MAGIC_SYSRQ | ||
561 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 446 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, |
562 | struct usb_serial_port *port, unsigned int ch) | 447 | struct usb_serial_port *port, unsigned int ch) |
563 | { | 448 | { |
564 | if (port->sysrq && port->console) { | 449 | if (port->sysrq && port->port.console) { |
565 | if (ch && time_before(jiffies, port->sysrq)) { | 450 | if (ch && time_before(jiffies, port->sysrq)) { |
566 | handle_sysrq(ch, tty); | 451 | handle_sysrq(ch, tty); |
567 | port->sysrq = 0; | 452 | port->sysrq = 0; |
@@ -571,6 +456,13 @@ int usb_serial_handle_sysrq_char(struct tty_struct *tty, | |||
571 | } | 456 | } |
572 | return 0; | 457 | return 0; |
573 | } | 458 | } |
459 | #else | ||
460 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | ||
461 | struct usb_serial_port *port, unsigned int ch) | ||
462 | { | ||
463 | return 0; | ||
464 | } | ||
465 | #endif | ||
574 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); | 466 | EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); |
575 | 467 | ||
576 | int usb_serial_handle_break(struct usb_serial_port *port) | 468 | int usb_serial_handle_break(struct usb_serial_port *port) |
@@ -600,7 +492,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
600 | c++; | 492 | c++; |
601 | } | 493 | } |
602 | 494 | ||
603 | if (port->write_urb) { | 495 | if (port->bulk_out_size) { |
604 | r = usb_serial_generic_write_start(port); | 496 | r = usb_serial_generic_write_start(port); |
605 | if (r < 0) | 497 | if (r < 0) |
606 | c++; | 498 | c++; |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 3ef8df0ef888..76e6fb3aab7a 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -3020,7 +3020,7 @@ static int edge_startup(struct usb_serial *serial) | |||
3020 | 3020 | ||
3021 | /* set up our port private structures */ | 3021 | /* set up our port private structures */ |
3022 | for (i = 0; i < serial->num_ports; ++i) { | 3022 | for (i = 0; i < serial->num_ports; ++i) { |
3023 | edge_port = kmalloc(sizeof(struct edgeport_port), GFP_KERNEL); | 3023 | edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); |
3024 | if (edge_port == NULL) { | 3024 | if (edge_port == NULL) { |
3025 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | 3025 | dev_err(&serial->dev->dev, "%s - Out of memory\n", |
3026 | __func__); | 3026 | __func__); |
@@ -3033,7 +3033,6 @@ static int edge_startup(struct usb_serial *serial) | |||
3033 | kfree(edge_serial); | 3033 | kfree(edge_serial); |
3034 | return -ENOMEM; | 3034 | return -ENOMEM; |
3035 | } | 3035 | } |
3036 | memset(edge_port, 0, sizeof(struct edgeport_port)); | ||
3037 | spin_lock_init(&edge_port->ep_lock); | 3036 | spin_lock_init(&edge_port->ep_lock); |
3038 | edge_port->port = serial->port[i]; | 3037 | edge_port->port = serial->port[i]; |
3039 | usb_set_serial_port_data(serial->port[i], edge_port); | 3038 | usb_set_serial_port_data(serial->port[i], edge_port); |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index cb201c1f67f9..dced7ec65470 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
@@ -34,15 +34,15 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | 36 | ||
37 | /* The following table is used to map the USBx port number to | 37 | /* The following table is used to map the USBx port number to |
38 | * the device serial number (or physical USB path), */ | 38 | * the device serial number (or physical USB path), */ |
39 | #define MAX_EDGEPORTS 64 | 39 | #define MAX_EDGEPORTS 64 |
40 | 40 | ||
41 | struct comMapper { | 41 | struct comMapper { |
42 | char SerialNumber[MAX_SERIALNUMBER_LEN+1]; /* Serial number/usb path */ | 42 | char SerialNumber[MAX_SERIALNUMBER_LEN+1]; /* Serial number/usb path */ |
43 | int numPorts; /* Number of ports */ | 43 | int numPorts; /* Number of ports */ |
44 | int Original[MAX_RS232_PORTS]; /* Port numbers set by IOCTL */ | 44 | int Original[MAX_RS232_PORTS]; /* Port numbers set by IOCTL */ |
45 | int Port[MAX_RS232_PORTS]; /* Actual used port numbers */ | 45 | int Port[MAX_RS232_PORTS]; /* Actual used port numbers */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | 48 | ||
@@ -51,7 +51,7 @@ struct comMapper { | |||
51 | /* /proc/edgeport Interface | 51 | /* /proc/edgeport Interface |
52 | * This interface uses read/write/lseek interface to talk to the edgeport driver | 52 | * This interface uses read/write/lseek interface to talk to the edgeport driver |
53 | * the following read functions are supported: */ | 53 | * the following read functions are supported: */ |
54 | #define PROC_GET_MAPPING_TO_PATH 1 | 54 | #define PROC_GET_MAPPING_TO_PATH 1 |
55 | #define PROC_GET_COM_ENTRY 2 | 55 | #define PROC_GET_COM_ENTRY 2 |
56 | #define PROC_GET_EDGE_MANUF_DESCRIPTOR 3 | 56 | #define PROC_GET_EDGE_MANUF_DESCRIPTOR 3 |
57 | #define PROC_GET_BOOT_DESCRIPTOR 4 | 57 | #define PROC_GET_BOOT_DESCRIPTOR 4 |
@@ -64,7 +64,7 @@ struct comMapper { | |||
64 | 64 | ||
65 | 65 | ||
66 | /* the following write functions are supported: */ | 66 | /* the following write functions are supported: */ |
67 | #define PROC_SET_COM_MAPPING 1 | 67 | #define PROC_SET_COM_MAPPING 1 |
68 | #define PROC_SET_COM_ENTRY 2 | 68 | #define PROC_SET_COM_ENTRY 2 |
69 | 69 | ||
70 | 70 | ||
@@ -97,8 +97,8 @@ struct edgeport_product_info { | |||
97 | __u8 BoardRev; /* PCB revision level (chg only if s/w visible) */ | 97 | __u8 BoardRev; /* PCB revision level (chg only if s/w visible) */ |
98 | 98 | ||
99 | __u8 BootMajorVersion; /* Boot Firmware version: xx. */ | 99 | __u8 BootMajorVersion; /* Boot Firmware version: xx. */ |
100 | __u8 BootMinorVersion; /* yy. */ | 100 | __u8 BootMinorVersion; /* yy. */ |
101 | __le16 BootBuildNumber; /* zzzz (LE format) */ | 101 | __le16 BootBuildNumber; /* zzzz (LE format) */ |
102 | 102 | ||
103 | __u8 FirmwareMajorVersion; /* Operational Firmware version:xx. */ | 103 | __u8 FirmwareMajorVersion; /* Operational Firmware version:xx. */ |
104 | __u8 FirmwareMinorVersion; /* yy. */ | 104 | __u8 FirmwareMinorVersion; /* yy. */ |
diff --git a/drivers/usb/serial/io_ionsp.h b/drivers/usb/serial/io_ionsp.h index 092e03d2dfc4..5cc591bae54d 100644 --- a/drivers/usb/serial/io_ionsp.h +++ b/drivers/usb/serial/io_ionsp.h | |||
@@ -89,10 +89,10 @@ All 16-bit fields are sent in little-endian (Intel) format. | |||
89 | // | 89 | // |
90 | 90 | ||
91 | struct int_status_pkt { | 91 | struct int_status_pkt { |
92 | __u16 RxBytesAvail; // Additional bytes available to | 92 | __u16 RxBytesAvail; // Additional bytes available to |
93 | // be read from Bulk IN pipe | 93 | // be read from Bulk IN pipe |
94 | __u16 TxCredits[ MAX_RS232_PORTS ]; // Additional space available in | 94 | __u16 TxCredits[MAX_RS232_PORTS]; // Additional space available in |
95 | // given port's TxBuffer | 95 | // given port's TxBuffer |
96 | }; | 96 | }; |
97 | 97 | ||
98 | 98 | ||
@@ -115,24 +115,24 @@ struct int_status_pkt { | |||
115 | #define IOSP_CMD_STAT_BIT 0x80 // If set, this is command/status header | 115 | #define IOSP_CMD_STAT_BIT 0x80 // If set, this is command/status header |
116 | 116 | ||
117 | #define IS_CMD_STAT_HDR(Byte1) ((Byte1) & IOSP_CMD_STAT_BIT) | 117 | #define IS_CMD_STAT_HDR(Byte1) ((Byte1) & IOSP_CMD_STAT_BIT) |
118 | #define IS_DATA_HDR(Byte1) (! IS_CMD_STAT_HDR(Byte1)) | 118 | #define IS_DATA_HDR(Byte1) (!IS_CMD_STAT_HDR(Byte1)) |
119 | 119 | ||
120 | #define IOSP_GET_HDR_PORT(Byte1) ((__u8) ((Byte1) & IOSP_PORT_MASK)) | 120 | #define IOSP_GET_HDR_PORT(Byte1) ((__u8) ((Byte1) & IOSP_PORT_MASK)) |
121 | #define IOSP_GET_HDR_DATA_LEN(Byte1, Byte2) ((__u16) ( ((__u16)((Byte1) & 0x78)) << 5) | (Byte2)) | 121 | #define IOSP_GET_HDR_DATA_LEN(Byte1, Byte2) ((__u16) (((__u16)((Byte1) & 0x78)) << 5) | (Byte2)) |
122 | #define IOSP_GET_STATUS_CODE(Byte1) ((__u8) (((Byte1) & 0x78) >> 3)) | 122 | #define IOSP_GET_STATUS_CODE(Byte1) ((__u8) (((Byte1) & 0x78) >> 3)) |
123 | 123 | ||
124 | 124 | ||
125 | // | 125 | // |
126 | // These macros build the 1st and 2nd bytes for a data header | 126 | // These macros build the 1st and 2nd bytes for a data header |
127 | // | 127 | // |
128 | #define IOSP_BUILD_DATA_HDR1(Port, Len) ((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78 )))) | 128 | #define IOSP_BUILD_DATA_HDR1(Port, Len) ((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78)))) |
129 | #define IOSP_BUILD_DATA_HDR2(Port, Len) ((__u8) (Len)) | 129 | #define IOSP_BUILD_DATA_HDR2(Port, Len) ((__u8) (Len)) |
130 | 130 | ||
131 | 131 | ||
132 | // | 132 | // |
133 | // These macros build the 1st and 2nd bytes for a command header | 133 | // These macros build the 1st and 2nd bytes for a command header |
134 | // | 134 | // |
135 | #define IOSP_BUILD_CMD_HDR1(Port, Cmd) ((__u8) ( IOSP_CMD_STAT_BIT | (Port) | ((__u8) ((Cmd) << 3)) )) | 135 | #define IOSP_BUILD_CMD_HDR1(Port, Cmd) ((__u8) (IOSP_CMD_STAT_BIT | (Port) | ((__u8) ((Cmd) << 3)))) |
136 | 136 | ||
137 | 137 | ||
138 | //-------------------------------------------------------------- | 138 | //-------------------------------------------------------------- |
@@ -194,24 +194,25 @@ struct int_status_pkt { | |||
194 | // Define macros to simplify building of IOSP cmds | 194 | // Define macros to simplify building of IOSP cmds |
195 | // | 195 | // |
196 | 196 | ||
197 | #define MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val) \ | 197 | #define MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val) \ |
198 | do { \ | 198 | do { \ |
199 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_WRITE_UART_REG(Reg) ); \ | 199 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), \ |
200 | (*(ppBuf))[1] = (Val); \ | 200 | IOSP_WRITE_UART_REG(Reg)); \ |
201 | \ | 201 | (*(ppBuf))[1] = (Val); \ |
202 | *ppBuf += 2; \ | 202 | \ |
203 | *pLen += 2; \ | 203 | *ppBuf += 2; \ |
204 | } while (0) | 204 | *pLen += 2; \ |
205 | } while (0) | ||
205 | 206 | ||
206 | #define MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param) \ | 207 | #define MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param) \ |
207 | do { \ | 208 | do { \ |
208 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1( (Port), IOSP_EXT_CMD ); \ | 209 | (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), IOSP_EXT_CMD); \ |
209 | (*(ppBuf))[1] = (ExtCmd); \ | 210 | (*(ppBuf))[1] = (ExtCmd); \ |
210 | (*(ppBuf))[2] = (Param); \ | 211 | (*(ppBuf))[2] = (Param); \ |
211 | \ | 212 | \ |
212 | *ppBuf += 3; \ | 213 | *ppBuf += 3; \ |
213 | *pLen += 3; \ | 214 | *pLen += 3; \ |
214 | } while (0) | 215 | } while (0) |
215 | 216 | ||
216 | 217 | ||
217 | 218 | ||
@@ -310,16 +311,16 @@ struct int_status_pkt { | |||
310 | // | 311 | // |
311 | // IOSP_CMD_RX_CHECK_REQ | 312 | // IOSP_CMD_RX_CHECK_REQ |
312 | // | 313 | // |
313 | // This command is used to assist in the implementation of the | 314 | // This command is used to assist in the implementation of the |
314 | // IOCTL_SERIAL_PURGE Windows IOCTL. | 315 | // IOCTL_SERIAL_PURGE Windows IOCTL. |
315 | // This IOSP command tries to place a marker at the end of the RX | 316 | // This IOSP command tries to place a marker at the end of the RX |
316 | // queue in the Edgeport. If the Edgeport RX queue is full then | 317 | // queue in the Edgeport. If the Edgeport RX queue is full then |
317 | // the Check will be discarded. | 318 | // the Check will be discarded. |
318 | // It is up to the device driver to timeout waiting for the | 319 | // It is up to the device driver to timeout waiting for the |
319 | // RX_CHECK_RSP. If a RX_CHECK_RSP is received, the driver is | 320 | // RX_CHECK_RSP. If a RX_CHECK_RSP is received, the driver is |
320 | // sure that all data has been received from the edgeport and | 321 | // sure that all data has been received from the edgeport and |
321 | // may now purge any internal RX buffers. | 322 | // may now purge any internal RX buffers. |
322 | // Note tat the sequence numbers may be used to detect lost | 323 | // Note tat the sequence numbers may be used to detect lost |
323 | // CHECK_REQs. | 324 | // CHECK_REQs. |
324 | 325 | ||
325 | // Example for Port 0 | 326 | // Example for Port 0 |
@@ -341,7 +342,7 @@ struct int_status_pkt { | |||
341 | // | 342 | // |
342 | // 1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]... | 343 | // 1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]... |
343 | // | 344 | // |
344 | // ssss: 00-07 2-byte status. ssss identifies which UART register | 345 | // ssss: 00-07 2-byte status. ssss identifies which UART register |
345 | // has changed value, and the new value is in P1. | 346 | // has changed value, and the new value is in P1. |
346 | // Note that the ssss values do not correspond to the | 347 | // Note that the ssss values do not correspond to the |
347 | // 16554 register numbers given in 16554.H. Instead, | 348 | // 16554 register numbers given in 16554.H. Instead, |
@@ -383,14 +384,14 @@ struct int_status_pkt { | |||
383 | // returns this in order to report | 384 | // returns this in order to report |
384 | // changes in modem status lines | 385 | // changes in modem status lines |
385 | // (CTS, DSR, RI, CD) | 386 | // (CTS, DSR, RI, CD) |
386 | // | 387 | // |
387 | 388 | ||
388 | // 0x02 // Available for future expansion | 389 | // 0x02 // Available for future expansion |
389 | // 0x03 // | 390 | // 0x03 // |
390 | // 0x04 // | 391 | // 0x04 // |
391 | // 0x05 // | 392 | // 0x05 // |
392 | // 0x06 // | 393 | // 0x06 // |
393 | // 0x07 // | 394 | // 0x07 // |
394 | 395 | ||
395 | 396 | ||
396 | /**************************************************** | 397 | /**************************************************** |
@@ -400,7 +401,7 @@ struct int_status_pkt { | |||
400 | #define IOSP_STATUS_LSR_DATA 0x08 // P1 is new value of LSR register (same as STATUS_LSR) | 401 | #define IOSP_STATUS_LSR_DATA 0x08 // P1 is new value of LSR register (same as STATUS_LSR) |
401 | 402 | ||
402 | // P2 is errored character read from | 403 | // P2 is errored character read from |
403 | // RxFIFO after LSR reported an error. | 404 | // RxFIFO after LSR reported an error. |
404 | 405 | ||
405 | #define IOSP_EXT_STATUS 0x09 // P1 is status/response code, param in P2. | 406 | #define IOSP_EXT_STATUS 0x09 // P1 is status/response code, param in P2. |
406 | 407 | ||
@@ -408,7 +409,7 @@ struct int_status_pkt { | |||
408 | // Response Codes (P1 values) for 3-byte status messages | 409 | // Response Codes (P1 values) for 3-byte status messages |
409 | 410 | ||
410 | #define IOSP_EXT_STATUS_CHASE_RSP 0 // Reply to CHASE_PORT cmd. P2 is outcome: | 411 | #define IOSP_EXT_STATUS_CHASE_RSP 0 // Reply to CHASE_PORT cmd. P2 is outcome: |
411 | #define IOSP_EXT_STATUS_CHASE_PASS 0 // P2 = 0: All Tx data drained successfully | 412 | #define IOSP_EXT_STATUS_CHASE_PASS 0 // P2 = 0: All Tx data drained successfully |
412 | #define IOSP_EXT_STATUS_CHASE_FAIL 1 // P2 = 1: Timed out (stuck due to flow | 413 | #define IOSP_EXT_STATUS_CHASE_FAIL 1 // P2 = 1: Timed out (stuck due to flow |
413 | 414 | ||
414 | // control from remote device). | 415 | // control from remote device). |
@@ -446,9 +447,9 @@ struct int_status_pkt { | |||
446 | // Macros to parse status messages | 447 | // Macros to parse status messages |
447 | // | 448 | // |
448 | 449 | ||
449 | #define IOSP_GET_STATUS_LEN(code) ( (code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4) ) | 450 | #define IOSP_GET_STATUS_LEN(code) ((code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4)) |
450 | 451 | ||
451 | #define IOSP_STATUS_IS_2BYTE(code) ( (code) < 0x08 ) | 452 | #define IOSP_STATUS_IS_2BYTE(code) ((code) < 0x08) |
452 | #define IOSP_STATUS_IS_3BYTE(code) ( ((code) >= 0x08) && ((code) <= 0x0B) ) | 453 | #define IOSP_STATUS_IS_3BYTE(code) (((code) >= 0x08) && ((code) <= 0x0B)) |
453 | #define IOSP_STATUS_IS_4BYTE(code) ( ((code) >= 0x0C) && ((code) <= 0x0D) ) | 454 | #define IOSP_STATUS_IS_4BYTE(code) (((code) >= 0x0C) && ((code) <= 0x0D)) |
454 | 455 | ||
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index aa876f71f228..0fca2659206f 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/serial.h> | 38 | #include <linux/serial.h> |
39 | #include <linux/kfifo.h> | ||
39 | #include <linux/ioctl.h> | 40 | #include <linux/ioctl.h> |
40 | #include <linux/firmware.h> | 41 | #include <linux/firmware.h> |
41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
@@ -56,10 +57,6 @@ | |||
56 | #define EPROM_PAGE_SIZE 64 | 57 | #define EPROM_PAGE_SIZE 64 |
57 | 58 | ||
58 | 59 | ||
59 | struct edgeport_uart_buf_desc { | ||
60 | __u32 count; /* Number of bytes currently in buffer */ | ||
61 | }; | ||
62 | |||
63 | /* different hardware types */ | 60 | /* different hardware types */ |
64 | #define HARDWARE_TYPE_930 0 | 61 | #define HARDWARE_TYPE_930 0 |
65 | #define HARDWARE_TYPE_TIUMP 1 | 62 | #define HARDWARE_TYPE_TIUMP 1 |
@@ -87,14 +84,6 @@ struct product_info { | |||
87 | __u8 hardware_type; /* Type of hardware */ | 84 | __u8 hardware_type; /* Type of hardware */ |
88 | } __attribute__((packed)); | 85 | } __attribute__((packed)); |
89 | 86 | ||
90 | /* circular buffer */ | ||
91 | struct edge_buf { | ||
92 | unsigned int buf_size; | ||
93 | char *buf_buf; | ||
94 | char *buf_get; | ||
95 | char *buf_put; | ||
96 | }; | ||
97 | |||
98 | struct edgeport_port { | 87 | struct edgeport_port { |
99 | __u16 uart_base; | 88 | __u16 uart_base; |
100 | __u16 dma_address; | 89 | __u16 dma_address; |
@@ -108,7 +97,6 @@ struct edgeport_port { | |||
108 | int baud_rate; | 97 | int baud_rate; |
109 | int close_pending; | 98 | int close_pending; |
110 | int lsr_event; | 99 | int lsr_event; |
111 | struct edgeport_uart_buf_desc tx; | ||
112 | struct async_icount icount; | 100 | struct async_icount icount; |
113 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while | 101 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while |
114 | waiting for msr change to | 102 | waiting for msr change to |
@@ -119,7 +107,7 @@ struct edgeport_port { | |||
119 | spinlock_t ep_lock; | 107 | spinlock_t ep_lock; |
120 | int ep_read_urb_state; | 108 | int ep_read_urb_state; |
121 | int ep_write_urb_in_use; | 109 | int ep_write_urb_in_use; |
122 | struct edge_buf *ep_out_buf; | 110 | struct kfifo write_fifo; |
123 | }; | 111 | }; |
124 | 112 | ||
125 | struct edgeport_serial { | 113 | struct edgeport_serial { |
@@ -249,17 +237,6 @@ static void edge_send(struct tty_struct *tty); | |||
249 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); | 237 | static int edge_create_sysfs_attrs(struct usb_serial_port *port); |
250 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); | 238 | static int edge_remove_sysfs_attrs(struct usb_serial_port *port); |
251 | 239 | ||
252 | /* circular buffer */ | ||
253 | static struct edge_buf *edge_buf_alloc(unsigned int size); | ||
254 | static void edge_buf_free(struct edge_buf *eb); | ||
255 | static void edge_buf_clear(struct edge_buf *eb); | ||
256 | static unsigned int edge_buf_data_avail(struct edge_buf *eb); | ||
257 | static unsigned int edge_buf_space_avail(struct edge_buf *eb); | ||
258 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
259 | unsigned int count); | ||
260 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
261 | unsigned int count); | ||
262 | |||
263 | 240 | ||
264 | static int ti_vread_sync(struct usb_device *dev, __u8 request, | 241 | static int ti_vread_sync(struct usb_device *dev, __u8 request, |
265 | __u16 value, __u16 index, u8 *data, int size) | 242 | __u16 value, __u16 index, u8 *data, int size) |
@@ -590,7 +567,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
590 | add_wait_queue(&tty->write_wait, &wait); | 567 | add_wait_queue(&tty->write_wait, &wait); |
591 | for (;;) { | 568 | for (;;) { |
592 | set_current_state(TASK_INTERRUPTIBLE); | 569 | set_current_state(TASK_INTERRUPTIBLE); |
593 | if (edge_buf_data_avail(port->ep_out_buf) == 0 | 570 | if (kfifo_len(&port->write_fifo) == 0 |
594 | || timeout == 0 || signal_pending(current) | 571 | || timeout == 0 || signal_pending(current) |
595 | || !usb_get_intfdata(port->port->serial->interface)) | 572 | || !usb_get_intfdata(port->port->serial->interface)) |
596 | /* disconnect */ | 573 | /* disconnect */ |
@@ -602,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | |||
602 | set_current_state(TASK_RUNNING); | 579 | set_current_state(TASK_RUNNING); |
603 | remove_wait_queue(&tty->write_wait, &wait); | 580 | remove_wait_queue(&tty->write_wait, &wait); |
604 | if (flush) | 581 | if (flush) |
605 | edge_buf_clear(port->ep_out_buf); | 582 | kfifo_reset_out(&port->write_fifo); |
606 | spin_unlock_irqrestore(&port->ep_lock, flags); | 583 | spin_unlock_irqrestore(&port->ep_lock, flags); |
607 | tty_kref_put(tty); | 584 | tty_kref_put(tty); |
608 | 585 | ||
@@ -2089,7 +2066,6 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
2089 | const unsigned char *data, int count) | 2066 | const unsigned char *data, int count) |
2090 | { | 2067 | { |
2091 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2068 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
2092 | unsigned long flags; | ||
2093 | 2069 | ||
2094 | dbg("%s - port %d", __func__, port->number); | 2070 | dbg("%s - port %d", __func__, port->number); |
2095 | 2071 | ||
@@ -2103,10 +2079,8 @@ static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
2103 | if (edge_port->close_pending == 1) | 2079 | if (edge_port->close_pending == 1) |
2104 | return -ENODEV; | 2080 | return -ENODEV; |
2105 | 2081 | ||
2106 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2082 | count = kfifo_in_locked(&edge_port->write_fifo, data, count, |
2107 | count = edge_buf_put(edge_port->ep_out_buf, data, count); | 2083 | &edge_port->ep_lock); |
2108 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | ||
2109 | |||
2110 | edge_send(tty); | 2084 | edge_send(tty); |
2111 | 2085 | ||
2112 | return count; | 2086 | return count; |
@@ -2129,7 +2103,7 @@ static void edge_send(struct tty_struct *tty) | |||
2129 | return; | 2103 | return; |
2130 | } | 2104 | } |
2131 | 2105 | ||
2132 | count = edge_buf_get(edge_port->ep_out_buf, | 2106 | count = kfifo_out(&edge_port->write_fifo, |
2133 | port->write_urb->transfer_buffer, | 2107 | port->write_urb->transfer_buffer, |
2134 | port->bulk_out_size); | 2108 | port->bulk_out_size); |
2135 | 2109 | ||
@@ -2185,7 +2159,7 @@ static int edge_write_room(struct tty_struct *tty) | |||
2185 | return 0; | 2159 | return 0; |
2186 | 2160 | ||
2187 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2161 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
2188 | room = edge_buf_space_avail(edge_port->ep_out_buf); | 2162 | room = kfifo_avail(&edge_port->write_fifo); |
2189 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2163 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
2190 | 2164 | ||
2191 | dbg("%s - returns %d", __func__, room); | 2165 | dbg("%s - returns %d", __func__, room); |
@@ -2207,7 +2181,7 @@ static int edge_chars_in_buffer(struct tty_struct *tty) | |||
2207 | return 0; | 2181 | return 0; |
2208 | 2182 | ||
2209 | spin_lock_irqsave(&edge_port->ep_lock, flags); | 2183 | spin_lock_irqsave(&edge_port->ep_lock, flags); |
2210 | chars = edge_buf_data_avail(edge_port->ep_out_buf); | 2184 | chars = kfifo_len(&edge_port->write_fifo); |
2211 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); | 2185 | spin_unlock_irqrestore(&edge_port->ep_lock, flags); |
2212 | 2186 | ||
2213 | dbg("%s - returns %d", __func__, chars); | 2187 | dbg("%s - returns %d", __func__, chars); |
@@ -2664,8 +2638,8 @@ static int edge_startup(struct usb_serial *serial) | |||
2664 | goto cleanup; | 2638 | goto cleanup; |
2665 | } | 2639 | } |
2666 | spin_lock_init(&edge_port->ep_lock); | 2640 | spin_lock_init(&edge_port->ep_lock); |
2667 | edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); | 2641 | if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, |
2668 | if (edge_port->ep_out_buf == NULL) { | 2642 | GFP_KERNEL)) { |
2669 | dev_err(&serial->dev->dev, "%s - Out of memory\n", | 2643 | dev_err(&serial->dev->dev, "%s - Out of memory\n", |
2670 | __func__); | 2644 | __func__); |
2671 | kfree(edge_port); | 2645 | kfree(edge_port); |
@@ -2682,7 +2656,7 @@ static int edge_startup(struct usb_serial *serial) | |||
2682 | cleanup: | 2656 | cleanup: |
2683 | for (--i; i >= 0; --i) { | 2657 | for (--i; i >= 0; --i) { |
2684 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2658 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2685 | edge_buf_free(edge_port->ep_out_buf); | 2659 | kfifo_free(&edge_port->write_fifo); |
2686 | kfree(edge_port); | 2660 | kfree(edge_port); |
2687 | usb_set_serial_port_data(serial->port[i], NULL); | 2661 | usb_set_serial_port_data(serial->port[i], NULL); |
2688 | } | 2662 | } |
@@ -2713,7 +2687,7 @@ static void edge_release(struct usb_serial *serial) | |||
2713 | 2687 | ||
2714 | for (i = 0; i < serial->num_ports; ++i) { | 2688 | for (i = 0; i < serial->num_ports; ++i) { |
2715 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2689 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2716 | edge_buf_free(edge_port->ep_out_buf); | 2690 | kfifo_free(&edge_port->write_fifo); |
2717 | kfree(edge_port); | 2691 | kfree(edge_port); |
2718 | } | 2692 | } |
2719 | kfree(usb_get_serial_data(serial)); | 2693 | kfree(usb_get_serial_data(serial)); |
@@ -2763,182 +2737,6 @@ static int edge_remove_sysfs_attrs(struct usb_serial_port *port) | |||
2763 | } | 2737 | } |
2764 | 2738 | ||
2765 | 2739 | ||
2766 | /* Circular Buffer */ | ||
2767 | |||
2768 | /* | ||
2769 | * edge_buf_alloc | ||
2770 | * | ||
2771 | * Allocate a circular buffer and all associated memory. | ||
2772 | */ | ||
2773 | |||
2774 | static struct edge_buf *edge_buf_alloc(unsigned int size) | ||
2775 | { | ||
2776 | struct edge_buf *eb; | ||
2777 | |||
2778 | |||
2779 | if (size == 0) | ||
2780 | return NULL; | ||
2781 | |||
2782 | eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL); | ||
2783 | if (eb == NULL) | ||
2784 | return NULL; | ||
2785 | |||
2786 | eb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
2787 | if (eb->buf_buf == NULL) { | ||
2788 | kfree(eb); | ||
2789 | return NULL; | ||
2790 | } | ||
2791 | |||
2792 | eb->buf_size = size; | ||
2793 | eb->buf_get = eb->buf_put = eb->buf_buf; | ||
2794 | |||
2795 | return eb; | ||
2796 | } | ||
2797 | |||
2798 | |||
2799 | /* | ||
2800 | * edge_buf_free | ||
2801 | * | ||
2802 | * Free the buffer and all associated memory. | ||
2803 | */ | ||
2804 | |||
2805 | static void edge_buf_free(struct edge_buf *eb) | ||
2806 | { | ||
2807 | if (eb) { | ||
2808 | kfree(eb->buf_buf); | ||
2809 | kfree(eb); | ||
2810 | } | ||
2811 | } | ||
2812 | |||
2813 | |||
2814 | /* | ||
2815 | * edge_buf_clear | ||
2816 | * | ||
2817 | * Clear out all data in the circular buffer. | ||
2818 | */ | ||
2819 | |||
2820 | static void edge_buf_clear(struct edge_buf *eb) | ||
2821 | { | ||
2822 | if (eb != NULL) | ||
2823 | eb->buf_get = eb->buf_put; | ||
2824 | /* equivalent to a get of all data available */ | ||
2825 | } | ||
2826 | |||
2827 | |||
2828 | /* | ||
2829 | * edge_buf_data_avail | ||
2830 | * | ||
2831 | * Return the number of bytes of data available in the circular | ||
2832 | * buffer. | ||
2833 | */ | ||
2834 | |||
2835 | static unsigned int edge_buf_data_avail(struct edge_buf *eb) | ||
2836 | { | ||
2837 | if (eb == NULL) | ||
2838 | return 0; | ||
2839 | return ((eb->buf_size + eb->buf_put - eb->buf_get) % eb->buf_size); | ||
2840 | } | ||
2841 | |||
2842 | |||
2843 | /* | ||
2844 | * edge_buf_space_avail | ||
2845 | * | ||
2846 | * Return the number of bytes of space available in the circular | ||
2847 | * buffer. | ||
2848 | */ | ||
2849 | |||
2850 | static unsigned int edge_buf_space_avail(struct edge_buf *eb) | ||
2851 | { | ||
2852 | if (eb == NULL) | ||
2853 | return 0; | ||
2854 | return ((eb->buf_size + eb->buf_get - eb->buf_put - 1) % eb->buf_size); | ||
2855 | } | ||
2856 | |||
2857 | |||
2858 | /* | ||
2859 | * edge_buf_put | ||
2860 | * | ||
2861 | * Copy data data from a user buffer and put it into the circular buffer. | ||
2862 | * Restrict to the amount of space available. | ||
2863 | * | ||
2864 | * Return the number of bytes copied. | ||
2865 | */ | ||
2866 | |||
2867 | static unsigned int edge_buf_put(struct edge_buf *eb, const char *buf, | ||
2868 | unsigned int count) | ||
2869 | { | ||
2870 | unsigned int len; | ||
2871 | |||
2872 | |||
2873 | if (eb == NULL) | ||
2874 | return 0; | ||
2875 | |||
2876 | len = edge_buf_space_avail(eb); | ||
2877 | if (count > len) | ||
2878 | count = len; | ||
2879 | |||
2880 | if (count == 0) | ||
2881 | return 0; | ||
2882 | |||
2883 | len = eb->buf_buf + eb->buf_size - eb->buf_put; | ||
2884 | if (count > len) { | ||
2885 | memcpy(eb->buf_put, buf, len); | ||
2886 | memcpy(eb->buf_buf, buf+len, count - len); | ||
2887 | eb->buf_put = eb->buf_buf + count - len; | ||
2888 | } else { | ||
2889 | memcpy(eb->buf_put, buf, count); | ||
2890 | if (count < len) | ||
2891 | eb->buf_put += count; | ||
2892 | else /* count == len */ | ||
2893 | eb->buf_put = eb->buf_buf; | ||
2894 | } | ||
2895 | |||
2896 | return count; | ||
2897 | } | ||
2898 | |||
2899 | |||
2900 | /* | ||
2901 | * edge_buf_get | ||
2902 | * | ||
2903 | * Get data from the circular buffer and copy to the given buffer. | ||
2904 | * Restrict to the amount of data available. | ||
2905 | * | ||
2906 | * Return the number of bytes copied. | ||
2907 | */ | ||
2908 | |||
2909 | static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | ||
2910 | unsigned int count) | ||
2911 | { | ||
2912 | unsigned int len; | ||
2913 | |||
2914 | |||
2915 | if (eb == NULL) | ||
2916 | return 0; | ||
2917 | |||
2918 | len = edge_buf_data_avail(eb); | ||
2919 | if (count > len) | ||
2920 | count = len; | ||
2921 | |||
2922 | if (count == 0) | ||
2923 | return 0; | ||
2924 | |||
2925 | len = eb->buf_buf + eb->buf_size - eb->buf_get; | ||
2926 | if (count > len) { | ||
2927 | memcpy(buf, eb->buf_get, len); | ||
2928 | memcpy(buf+len, eb->buf_buf, count - len); | ||
2929 | eb->buf_get = eb->buf_buf + count - len; | ||
2930 | } else { | ||
2931 | memcpy(buf, eb->buf_get, count); | ||
2932 | if (count < len) | ||
2933 | eb->buf_get += count; | ||
2934 | else /* count == len */ | ||
2935 | eb->buf_get = eb->buf_buf; | ||
2936 | } | ||
2937 | |||
2938 | return count; | ||
2939 | } | ||
2940 | |||
2941 | |||
2942 | static struct usb_serial_driver edgeport_1port_device = { | 2740 | static struct usb_serial_driver edgeport_1port_device = { |
2943 | .driver = { | 2741 | .driver = { |
2944 | .owner = THIS_MODULE, | 2742 | .owner = THIS_MODULE, |
diff --git a/drivers/usb/serial/io_ti.h b/drivers/usb/serial/io_ti.h index cab84f2256b9..1bd67b24f916 100644 --- a/drivers/usb/serial/io_ti.h +++ b/drivers/usb/serial/io_ti.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Copyright (C) 1997-2002 Inside Out Networks, Inc. | 3 | * Copyright (C) 1997-2002 Inside Out Networks, Inc. |
4 | * | 4 | * |
@@ -22,10 +22,10 @@ | |||
22 | #define DTK_ADDR_SPACE_I2C_TYPE_II 0x82 /* Addr is placed in I2C area */ | 22 | #define DTK_ADDR_SPACE_I2C_TYPE_II 0x82 /* Addr is placed in I2C area */ |
23 | #define DTK_ADDR_SPACE_I2C_TYPE_III 0x83 /* Addr is placed in I2C area */ | 23 | #define DTK_ADDR_SPACE_I2C_TYPE_III 0x83 /* Addr is placed in I2C area */ |
24 | 24 | ||
25 | // UART Defines | 25 | /* UART Defines */ |
26 | #define UMPMEM_BASE_UART1 0xFFA0 /* UMP UART1 base address */ | 26 | #define UMPMEM_BASE_UART1 0xFFA0 /* UMP UART1 base address */ |
27 | #define UMPMEM_BASE_UART2 0xFFB0 /* UMP UART2 base address */ | 27 | #define UMPMEM_BASE_UART2 0xFFB0 /* UMP UART2 base address */ |
28 | #define UMPMEM_OFFS_UART_LSR 0x05 /* UMP UART LSR register offset */ | 28 | #define UMPMEM_OFFS_UART_LSR 0x05 /* UMP UART LSR register offset */ |
29 | 29 | ||
30 | /* Bits per character */ | 30 | /* Bits per character */ |
31 | #define UMP_UART_CHAR5BITS 0x00 | 31 | #define UMP_UART_CHAR5BITS 0x00 |
@@ -54,7 +54,7 @@ | |||
54 | #define UMP_UART_LSR_RX_MASK 0x10 | 54 | #define UMP_UART_LSR_RX_MASK 0x10 |
55 | #define UMP_UART_LSR_TX_MASK 0x20 | 55 | #define UMP_UART_LSR_TX_MASK 0x20 |
56 | 56 | ||
57 | #define UMP_UART_LSR_DATA_MASK ( LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK ) | 57 | #define UMP_UART_LSR_DATA_MASK (LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK) |
58 | 58 | ||
59 | /* Port Settings Constants) */ | 59 | /* Port Settings Constants) */ |
60 | #define UMP_MASK_UART_FLAGS_RTS_FLOW 0x0001 | 60 | #define UMP_MASK_UART_FLAGS_RTS_FLOW 0x0001 |
@@ -79,50 +79,57 @@ | |||
79 | #define UMP_PORT_DIR_OUT 0x01 | 79 | #define UMP_PORT_DIR_OUT 0x01 |
80 | #define UMP_PORT_DIR_IN 0x02 | 80 | #define UMP_PORT_DIR_IN 0x02 |
81 | 81 | ||
82 | // Address of Port 0 | 82 | /* Address of Port 0 */ |
83 | #define UMPM_UART1_PORT 0x03 | 83 | #define UMPM_UART1_PORT 0x03 |
84 | 84 | ||
85 | // Commands | 85 | /* Commands */ |
86 | #define UMPC_SET_CONFIG 0x05 | 86 | #define UMPC_SET_CONFIG 0x05 |
87 | #define UMPC_OPEN_PORT 0x06 | 87 | #define UMPC_OPEN_PORT 0x06 |
88 | #define UMPC_CLOSE_PORT 0x07 | 88 | #define UMPC_CLOSE_PORT 0x07 |
89 | #define UMPC_START_PORT 0x08 | 89 | #define UMPC_START_PORT 0x08 |
90 | #define UMPC_STOP_PORT 0x09 | 90 | #define UMPC_STOP_PORT 0x09 |
91 | #define UMPC_TEST_PORT 0x0A | 91 | #define UMPC_TEST_PORT 0x0A |
92 | #define UMPC_PURGE_PORT 0x0B | 92 | #define UMPC_PURGE_PORT 0x0B |
93 | 93 | ||
94 | #define UMPC_COMPLETE_READ 0x80 // Force the Firmware to complete the current Read | 94 | /* Force the Firmware to complete the current Read */ |
95 | #define UMPC_HARDWARE_RESET 0x81 // Force UMP back into BOOT Mode | 95 | #define UMPC_COMPLETE_READ 0x80 |
96 | #define UMPC_COPY_DNLD_TO_I2C 0x82 // Copy current download image to type 0xf2 record in 16k I2C | 96 | /* Force UMP back into BOOT Mode */ |
97 | // firmware will change 0xff record to type 2 record when complete | 97 | #define UMPC_HARDWARE_RESET 0x81 |
98 | /* | ||
99 | * Copy current download image to type 0xf2 record in 16k I2C | ||
100 | * firmware will change 0xff record to type 2 record when complete | ||
101 | */ | ||
102 | #define UMPC_COPY_DNLD_TO_I2C 0x82 | ||
98 | 103 | ||
99 | // Special function register commands | 104 | /* |
100 | // wIndex is register address | 105 | * Special function register commands |
101 | // wValue is MSB/LSB mask/data | 106 | * wIndex is register address |
102 | #define UMPC_WRITE_SFR 0x83 // Write SFR Register | 107 | * wValue is MSB/LSB mask/data |
108 | */ | ||
109 | #define UMPC_WRITE_SFR 0x83 /* Write SFR Register */ | ||
103 | 110 | ||
104 | // wIndex is register address | 111 | /* wIndex is register address */ |
105 | #define UMPC_READ_SFR 0x84 // Read SRF Register | 112 | #define UMPC_READ_SFR 0x84 /* Read SRF Register */ |
106 | 113 | ||
107 | // Set or Clear DTR (wValue bit 0 Set/Clear) wIndex ModuleID (port) | 114 | /* Set or Clear DTR (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ |
108 | #define UMPC_SET_CLR_DTR 0x85 | 115 | #define UMPC_SET_CLR_DTR 0x85 |
109 | 116 | ||
110 | // Set or Clear RTS (wValue bit 0 Set/Clear) wIndex ModuleID (port) | 117 | /* Set or Clear RTS (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ |
111 | #define UMPC_SET_CLR_RTS 0x86 | 118 | #define UMPC_SET_CLR_RTS 0x86 |
112 | 119 | ||
113 | // Set or Clear LOOPBACK (wValue bit 0 Set/Clear) wIndex ModuleID (port) | 120 | /* Set or Clear LOOPBACK (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ |
114 | #define UMPC_SET_CLR_LOOPBACK 0x87 | 121 | #define UMPC_SET_CLR_LOOPBACK 0x87 |
115 | 122 | ||
116 | // Set or Clear BREAK (wValue bit 0 Set/Clear) wIndex ModuleID (port) | 123 | /* Set or Clear BREAK (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ |
117 | #define UMPC_SET_CLR_BREAK 0x88 | 124 | #define UMPC_SET_CLR_BREAK 0x88 |
118 | 125 | ||
119 | // Read MSR wIndex ModuleID (port) | 126 | /* Read MSR wIndex ModuleID (port) */ |
120 | #define UMPC_READ_MSR 0x89 | 127 | #define UMPC_READ_MSR 0x89 |
121 | 128 | ||
122 | /* Toolkit commands */ | 129 | /* Toolkit commands */ |
123 | /* Read-write group */ | 130 | /* Read-write group */ |
124 | #define UMPC_MEMORY_READ 0x92 | 131 | #define UMPC_MEMORY_READ 0x92 |
125 | #define UMPC_MEMORY_WRITE 0x93 | 132 | #define UMPC_MEMORY_WRITE 0x93 |
126 | 133 | ||
127 | /* | 134 | /* |
128 | * UMP DMA Definitions | 135 | * UMP DMA Definitions |
@@ -130,8 +137,7 @@ | |||
130 | #define UMPD_OEDB1_ADDRESS 0xFF08 | 137 | #define UMPD_OEDB1_ADDRESS 0xFF08 |
131 | #define UMPD_OEDB2_ADDRESS 0xFF10 | 138 | #define UMPD_OEDB2_ADDRESS 0xFF10 |
132 | 139 | ||
133 | struct out_endpoint_desc_block | 140 | struct out_endpoint_desc_block { |
134 | { | ||
135 | __u8 Configuration; | 141 | __u8 Configuration; |
136 | __u8 XBufAddr; | 142 | __u8 XBufAddr; |
137 | __u8 XByteCount; | 143 | __u8 XByteCount; |
@@ -147,8 +153,8 @@ struct out_endpoint_desc_block | |||
147 | * TYPE DEFINITIONS | 153 | * TYPE DEFINITIONS |
148 | * Structures for Firmware commands | 154 | * Structures for Firmware commands |
149 | */ | 155 | */ |
150 | struct ump_uart_config /* UART settings */ | 156 | /* UART settings */ |
151 | { | 157 | struct ump_uart_config { |
152 | __u16 wBaudRate; /* Baud rate */ | 158 | __u16 wBaudRate; /* Baud rate */ |
153 | __u16 wFlags; /* Bitmap mask of flags */ | 159 | __u16 wFlags; /* Bitmap mask of flags */ |
154 | __u8 bDataBits; /* 5..8 - data bits per character */ | 160 | __u8 bDataBits; /* 5..8 - data bits per character */ |
@@ -165,8 +171,8 @@ struct ump_uart_config /* UART settings */ | |||
165 | * TYPE DEFINITIONS | 171 | * TYPE DEFINITIONS |
166 | * Structures for USB interrupts | 172 | * Structures for USB interrupts |
167 | */ | 173 | */ |
168 | struct ump_interrupt /* Interrupt packet structure */ | 174 | /* Interrupt packet structure */ |
169 | { | 175 | struct ump_interrupt { |
170 | __u8 bICode; /* Interrupt code (interrupt num) */ | 176 | __u8 bICode; /* Interrupt code (interrupt num) */ |
171 | __u8 bIInfo; /* Interrupt information */ | 177 | __u8 bIInfo; /* Interrupt information */ |
172 | } __attribute__((packed)); | 178 | } __attribute__((packed)); |
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index 8e1a491e52a9..51f83fbb73bb 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | // | 27 | // |
28 | // Definitions of USB product IDs | 28 | // Definitions of USB product IDs |
29 | // | 29 | // |
30 | 30 | ||
31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID | 31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID |
32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID | 32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID |
@@ -54,7 +54,7 @@ | |||
54 | // Product IDs - assigned to match middle digit of serial number (No longer true) | 54 | // Product IDs - assigned to match middle digit of serial number (No longer true) |
55 | 55 | ||
56 | #define ION_DEVICE_ID_80251_NETCHIP 0x020 // This bit is set in the PID if this edgeport hardware$ | 56 | #define ION_DEVICE_ID_80251_NETCHIP 0x020 // This bit is set in the PID if this edgeport hardware$ |
57 | // is based on the 80251+Netchip. | 57 | // is based on the 80251+Netchip. |
58 | 58 | ||
59 | #define ION_DEVICE_ID_GENERATION_1 0x00 // Value for 930 based edgeports | 59 | #define ION_DEVICE_ID_GENERATION_1 0x00 // Value for 930 based edgeports |
60 | #define ION_DEVICE_ID_GENERATION_2 0x01 // Value for 80251+Netchip. | 60 | #define ION_DEVICE_ID_GENERATION_2 0x01 // Value for 80251+Netchip. |
@@ -134,7 +134,7 @@ | |||
134 | #define ION_DEVICE_ID_TI_EDGEPORT_416 0x0212 // Edgeport/416 | 134 | #define ION_DEVICE_ID_TI_EDGEPORT_416 0x0212 // Edgeport/416 |
135 | #define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 // Edgeport/1 RS232 | 135 | #define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 // Edgeport/1 RS232 |
136 | #define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 // Edgeport/42 4 hub 2 RS232 | 136 | #define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 // Edgeport/42 4 hub 2 RS232 |
137 | #define ION_DEVICE_ID_TI_EDGEPORT_22I 0x021A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 | 137 | #define ION_DEVICE_ID_TI_EDGEPORT_22I 0x021A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 |
138 | #define ION_DEVICE_ID_TI_EDGEPORT_2C 0x021B // Edgeport/2c RS232 | 138 | #define ION_DEVICE_ID_TI_EDGEPORT_2C 0x021B // Edgeport/2c RS232 |
139 | #define ION_DEVICE_ID_TI_EDGEPORT_221C 0x021C // Edgeport/221c is a TI based Edgeport/2 with lucent chip and | 139 | #define ION_DEVICE_ID_TI_EDGEPORT_221C 0x021C // Edgeport/221c is a TI based Edgeport/2 with lucent chip and |
140 | // 2 external hub ports - Large I2C | 140 | // 2 external hub ports - Large I2C |
@@ -142,7 +142,7 @@ | |||
142 | // 2 external hub ports - Large I2C | 142 | // 2 external hub ports - Large I2C |
143 | #define ION_DEVICE_ID_TI_EDGEPORT_21C 0x021E // Edgeport/21c is a TI based Edgeport/2 with lucent chip | 143 | #define ION_DEVICE_ID_TI_EDGEPORT_21C 0x021E // Edgeport/21c is a TI based Edgeport/2 with lucent chip |
144 | 144 | ||
145 | // Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) | 145 | // Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) |
146 | #define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1 0x0240 // Edgeport/1 RS232 | 146 | #define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1 0x0240 // Edgeport/1 RS232 |
147 | #define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I 0x0241 // Edgeport/1i- RS422 model | 147 | #define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I 0x0241 // Edgeport/1i- RS422 model |
148 | 148 | ||
@@ -176,7 +176,7 @@ | |||
176 | // Default to /P function | 176 | // Default to /P function |
177 | 177 | ||
178 | #define ION_DEVICE_ID_PLUS_PWR_HP4CD 0x30C // 5052 Plus Power HubPort/4CD+ (for Dell) | 178 | #define ION_DEVICE_ID_PLUS_PWR_HP4CD 0x30C // 5052 Plus Power HubPort/4CD+ (for Dell) |
179 | #define ION_DEVICE_ID_PLUS_PWR_HP4C 0x30D // 5052 Plus Power HubPort/4C+ | 179 | #define ION_DEVICE_ID_PLUS_PWR_HP4C 0x30D // 5052 Plus Power HubPort/4C+ |
180 | #define ION_DEVICE_ID_PLUS_PWR_PCI 0x30E // 3410 Plus Power PCI Host Controller 4 port | 180 | #define ION_DEVICE_ID_PLUS_PWR_PCI 0x30E // 3410 Plus Power PCI Host Controller 4 port |
181 | 181 | ||
182 | 182 | ||
@@ -217,17 +217,17 @@ | |||
217 | #define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device | 217 | #define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device |
218 | 218 | ||
219 | 219 | ||
220 | #define GENERATION_ID_FROM_USB_PRODUCT_ID( ProductId ) \ | 220 | #define GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId) \ |
221 | ( (__u16) ((ProductId >> 8) & (ION_GENERATION_MASK)) ) | 221 | ((__u16) ((ProductId >> 8) & (ION_GENERATION_MASK))) |
222 | 222 | ||
223 | #define MAKE_USB_PRODUCT_ID( OemId, DeviceId ) \ | 223 | #define MAKE_USB_PRODUCT_ID(OemId, DeviceId) \ |
224 | ( (__u16) (((OemId) << 10) || (DeviceId)) ) | 224 | ((__u16) (((OemId) << 10) || (DeviceId))) |
225 | 225 | ||
226 | #define DEVICE_ID_FROM_USB_PRODUCT_ID( ProductId ) \ | 226 | #define DEVICE_ID_FROM_USB_PRODUCT_ID(ProductId) \ |
227 | ( (__u16) ((ProductId) & (EDGEPORT_DEVICE_ID_MASK)) ) | 227 | ((__u16) ((ProductId) & (EDGEPORT_DEVICE_ID_MASK))) |
228 | 228 | ||
229 | #define OEM_ID_FROM_USB_PRODUCT_ID( ProductId ) \ | 229 | #define OEM_ID_FROM_USB_PRODUCT_ID(ProductId) \ |
230 | ( (__u16) (((ProductId) >> 10) & 0x3F) ) | 230 | ((__u16) (((ProductId) >> 10) & 0x3F)) |
231 | 231 | ||
232 | // | 232 | // |
233 | // Definitions of parameters for download code. Note that these are | 233 | // Definitions of parameters for download code. Note that these are |
@@ -237,7 +237,7 @@ | |||
237 | 237 | ||
238 | // TxCredits value below which driver won't bother sending (to prevent too many small writes). | 238 | // TxCredits value below which driver won't bother sending (to prevent too many small writes). |
239 | // Send only if above 25% | 239 | // Send only if above 25% |
240 | #define EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(InitialCredit, MaxPacketSize) (max( ((InitialCredit) / 4), (MaxPacketSize) )) | 240 | #define EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(InitialCredit, MaxPacketSize) (max(((InitialCredit) / 4), (MaxPacketSize))) |
241 | 241 | ||
242 | #define EDGE_FW_BULK_MAX_PACKET_SIZE 64 // Max Packet Size for Bulk In Endpoint (EP1) | 242 | #define EDGE_FW_BULK_MAX_PACKET_SIZE 64 // Max Packet Size for Bulk In Endpoint (EP1) |
243 | #define EDGE_FW_BULK_READ_BUFFER_SIZE 1024 // Size to use for Bulk reads | 243 | #define EDGE_FW_BULK_READ_BUFFER_SIZE 1024 // Size to use for Bulk reads |
@@ -263,7 +263,7 @@ | |||
263 | // wValue = 16-bit address | 263 | // wValue = 16-bit address |
264 | // wIndex = unused (though we could put segment 00: or FF: here) | 264 | // wIndex = unused (though we could put segment 00: or FF: here) |
265 | // wLength = # bytes to read/write (max 64) | 265 | // wLength = # bytes to read/write (max 64) |
266 | // | 266 | // |
267 | 267 | ||
268 | #define USB_REQUEST_ION_RESET_DEVICE 0 // Warm reboot Edgeport, retaining USB address | 268 | #define USB_REQUEST_ION_RESET_DEVICE 0 // Warm reboot Edgeport, retaining USB address |
269 | #define USB_REQUEST_ION_GET_EPIC_DESC 1 // Get Edgeport Compatibility Descriptor | 269 | #define USB_REQUEST_ION_GET_EPIC_DESC 1 // Get Edgeport Compatibility Descriptor |
@@ -278,7 +278,7 @@ | |||
278 | #define USB_REQUEST_ION_ENABLE_SUSPEND 9 // Enable/Disable suspend feature | 278 | #define USB_REQUEST_ION_ENABLE_SUSPEND 9 // Enable/Disable suspend feature |
279 | // (wValue != 0: Enable; wValue = 0: Disable) | 279 | // (wValue != 0: Enable; wValue = 0: Disable) |
280 | 280 | ||
281 | #define USB_REQUEST_ION_SEND_IOSP 10 // Send an IOSP command to the edgeport over the control pipe | 281 | #define USB_REQUEST_ION_SEND_IOSP 10 // Send an IOSP command to the edgeport over the control pipe |
282 | #define USB_REQUEST_ION_RECV_IOSP 11 // Receive an IOSP command from the edgeport over the control pipe | 282 | #define USB_REQUEST_ION_RECV_IOSP 11 // Receive an IOSP command from the edgeport over the control pipe |
283 | 283 | ||
284 | 284 | ||
@@ -301,8 +301,7 @@ | |||
301 | // this is a "real" Edgeport. | 301 | // this is a "real" Edgeport. |
302 | // | 302 | // |
303 | 303 | ||
304 | struct edge_compatibility_bits | 304 | struct edge_compatibility_bits { |
305 | { | ||
306 | // This __u32 defines which Vendor-specific commands/functionality | 305 | // This __u32 defines which Vendor-specific commands/functionality |
307 | // the device supports on the default EP0 pipe. | 306 | // the device supports on the default EP0 pipe. |
308 | 307 | ||
@@ -334,24 +333,22 @@ struct edge_compatibility_bits | |||
334 | __u32 TrueEdgeport : 1; // 0001 Set if device is a 'real' Edgeport | 333 | __u32 TrueEdgeport : 1; // 0001 Set if device is a 'real' Edgeport |
335 | // (Used only by driver, NEVER set by an EPiC device) | 334 | // (Used only by driver, NEVER set by an EPiC device) |
336 | __u32 GenUnused : 31; // Available for future expansion, must be 0 | 335 | __u32 GenUnused : 31; // Available for future expansion, must be 0 |
337 | |||
338 | }; | 336 | }; |
339 | 337 | ||
340 | #define EDGE_COMPATIBILITY_MASK0 0x0001 | 338 | #define EDGE_COMPATIBILITY_MASK0 0x0001 |
341 | #define EDGE_COMPATIBILITY_MASK1 0x3FFF | 339 | #define EDGE_COMPATIBILITY_MASK1 0x3FFF |
342 | #define EDGE_COMPATIBILITY_MASK2 0x0001 | 340 | #define EDGE_COMPATIBILITY_MASK2 0x0001 |
343 | 341 | ||
344 | struct edge_compatibility_descriptor | 342 | struct edge_compatibility_descriptor { |
345 | { | ||
346 | __u8 Length; // Descriptor Length (per USB spec) | 343 | __u8 Length; // Descriptor Length (per USB spec) |
347 | __u8 DescType; // Descriptor Type (per USB spec, =DEVICE type) | 344 | __u8 DescType; // Descriptor Type (per USB spec, =DEVICE type) |
348 | __u8 EpicVer; // Version of EPiC spec supported | 345 | __u8 EpicVer; // Version of EPiC spec supported |
349 | // (Currently must be 1) | 346 | // (Currently must be 1) |
350 | __u8 NumPorts; // Number of serial ports supported | 347 | __u8 NumPorts; // Number of serial ports supported |
351 | __u8 iDownloadFile; // Index of string containing download code filename | 348 | __u8 iDownloadFile; // Index of string containing download code filename |
352 | // 0=no download, FF=download compiled into driver. | 349 | // 0=no download, FF=download compiled into driver. |
353 | __u8 Unused[ 3 ]; // Available for future expansion, must be 0 | 350 | __u8 Unused[3]; // Available for future expansion, must be 0 |
354 | // (Currently must be 0). | 351 | // (Currently must be 0). |
355 | __u8 MajorVersion; // Firmware version: xx. | 352 | __u8 MajorVersion; // Firmware version: xx. |
356 | __u8 MinorVersion; // yy. | 353 | __u8 MinorVersion; // yy. |
357 | __le16 BuildNumber; // zzzz (LE format) | 354 | __le16 BuildNumber; // zzzz (LE format) |
@@ -359,9 +356,7 @@ struct edge_compatibility_descriptor | |||
359 | // The following structure contains __u32s, with each bit | 356 | // The following structure contains __u32s, with each bit |
360 | // specifying whether the EPiC device supports the given | 357 | // specifying whether the EPiC device supports the given |
361 | // command or functionality. | 358 | // command or functionality. |
362 | |||
363 | struct edge_compatibility_bits Supports; | 359 | struct edge_compatibility_bits Supports; |
364 | |||
365 | }; | 360 | }; |
366 | 361 | ||
367 | // Values for iDownloadFile | 362 | // Values for iDownloadFile |
@@ -391,8 +386,8 @@ struct edge_compatibility_descriptor | |||
391 | 386 | ||
392 | // Define the max block size that may be read or written | 387 | // Define the max block size that may be read or written |
393 | // in a read/write RAM/ROM command. | 388 | // in a read/write RAM/ROM command. |
394 | #define MAX_SIZE_REQ_ION_READ_MEM ( (__u16) 64 ) | 389 | #define MAX_SIZE_REQ_ION_READ_MEM ((__u16)64) |
395 | #define MAX_SIZE_REQ_ION_WRITE_MEM ( (__u16) 64 ) | 390 | #define MAX_SIZE_REQ_ION_WRITE_MEM ((__u16)64) |
396 | 391 | ||
397 | 392 | ||
398 | // | 393 | // |
@@ -545,7 +540,7 @@ struct edge_boot_descriptor { | |||
545 | __u8 MajorVersion; // C6 Firmware version: xx. | 540 | __u8 MajorVersion; // C6 Firmware version: xx. |
546 | __u8 MinorVersion; // C7 yy. | 541 | __u8 MinorVersion; // C7 yy. |
547 | __le16 BuildNumber; // C8 zzzz (LE format) | 542 | __le16 BuildNumber; // C8 zzzz (LE format) |
548 | 543 | ||
549 | __u16 EnumRootDescTable; // CA Root of ROM-based descriptor table | 544 | __u16 EnumRootDescTable; // CA Root of ROM-based descriptor table |
550 | __u8 NumDescTypes; // CC Number of supported descriptor types | 545 | __u8 NumDescTypes; // CC Number of supported descriptor types |
551 | 546 | ||
@@ -597,41 +592,36 @@ struct edge_boot_descriptor { | |||
597 | #define I2C_DESC_TYPE_ION 0 // Not defined by TI | 592 | #define I2C_DESC_TYPE_ION 0 // Not defined by TI |
598 | 593 | ||
599 | 594 | ||
600 | struct ti_i2c_desc | 595 | struct ti_i2c_desc { |
601 | { | ||
602 | __u8 Type; // Type of descriptor | 596 | __u8 Type; // Type of descriptor |
603 | __u16 Size; // Size of data only not including header | 597 | __u16 Size; // Size of data only not including header |
604 | __u8 CheckSum; // Checksum (8 bit sum of data only) | 598 | __u8 CheckSum; // Checksum (8 bit sum of data only) |
605 | __u8 Data[0]; // Data starts here | 599 | __u8 Data[0]; // Data starts here |
606 | }__attribute__((packed)); | 600 | } __attribute__((packed)); |
607 | 601 | ||
608 | // for 5152 devices only (type 2 record) | 602 | // for 5152 devices only (type 2 record) |
609 | // for 3410 the version is stored in the WATCHPORT_FIRMWARE_VERSION descriptor | 603 | // for 3410 the version is stored in the WATCHPORT_FIRMWARE_VERSION descriptor |
610 | struct ti_i2c_firmware_rec | 604 | struct ti_i2c_firmware_rec { |
611 | { | ||
612 | __u8 Ver_Major; // Firmware Major version number | 605 | __u8 Ver_Major; // Firmware Major version number |
613 | __u8 Ver_Minor; // Firmware Minor version number | 606 | __u8 Ver_Minor; // Firmware Minor version number |
614 | __u8 Data[0]; // Download starts here | 607 | __u8 Data[0]; // Download starts here |
615 | }__attribute__((packed)); | 608 | } __attribute__((packed)); |
616 | 609 | ||
617 | 610 | ||
618 | struct watchport_firmware_version | 611 | struct watchport_firmware_version { |
619 | { | ||
620 | // Added 2 bytes for version number | 612 | // Added 2 bytes for version number |
621 | __u8 Version_Major; // Download Version (for Watchport) | 613 | __u8 Version_Major; // Download Version (for Watchport) |
622 | __u8 Version_Minor; | 614 | __u8 Version_Minor; |
623 | }__attribute__((packed)); | 615 | } __attribute__((packed)); |
624 | 616 | ||
625 | 617 | ||
626 | // Structure of header of download image in fw_down.h | 618 | // Structure of header of download image in fw_down.h |
627 | struct ti_i2c_image_header | 619 | struct ti_i2c_image_header { |
628 | { | ||
629 | __le16 Length; | 620 | __le16 Length; |
630 | __u8 CheckSum; | 621 | __u8 CheckSum; |
631 | }__attribute__((packed)); | 622 | } __attribute__((packed)); |
632 | 623 | ||
633 | struct ti_basic_descriptor | 624 | struct ti_basic_descriptor { |
634 | { | ||
635 | __u8 Power; // Self powered | 625 | __u8 Power; // Self powered |
636 | // bit 7: 1 - power switching supported | 626 | // bit 7: 1 - power switching supported |
637 | // 0 - power switching not supported | 627 | // 0 - power switching not supported |
@@ -663,9 +653,9 @@ struct ti_basic_descriptor | |||
663 | #define TI_I2C_SIZE_MASK 0x1f // 5 bits | 653 | #define TI_I2C_SIZE_MASK 0x1f // 5 bits |
664 | #define TI_GET_I2C_SIZE(x) ((((x) & TI_I2C_SIZE_MASK)+1)*256) | 654 | #define TI_GET_I2C_SIZE(x) ((((x) & TI_I2C_SIZE_MASK)+1)*256) |
665 | 655 | ||
666 | #define TI_MAX_I2C_SIZE ( 16 * 1024 ) | 656 | #define TI_MAX_I2C_SIZE (16 * 1024) |
667 | 657 | ||
668 | #define TI_MANUF_VERSION_0 0 | 658 | #define TI_MANUF_VERSION_0 0 |
669 | 659 | ||
670 | // IonConig2 flags | 660 | // IonConig2 flags |
671 | #define TI_CONFIG2_RS232 0x01 | 661 | #define TI_CONFIG2_RS232 0x01 |
@@ -676,8 +666,7 @@ struct ti_basic_descriptor | |||
676 | #define TI_CONFIG2_WATCHPORT 0x10 | 666 | #define TI_CONFIG2_WATCHPORT 0x10 |
677 | 667 | ||
678 | 668 | ||
679 | struct edge_ti_manuf_descriptor | 669 | struct edge_ti_manuf_descriptor { |
680 | { | ||
681 | __u8 IonConfig; // Config byte for ION manufacturing use | 670 | __u8 IonConfig; // Config byte for ION manufacturing use |
682 | __u8 IonConfig2; // Expansion | 671 | __u8 IonConfig2; // Expansion |
683 | __u8 Version; // Version | 672 | __u8 Version; // Version |
@@ -688,7 +677,7 @@ struct edge_ti_manuf_descriptor | |||
688 | __u8 HubConfig2; // Used to configure the Hub | 677 | __u8 HubConfig2; // Used to configure the Hub |
689 | __u8 TotalPorts; // Total Number of Com Ports for the entire device (All UMPs) | 678 | __u8 TotalPorts; // Total Number of Com Ports for the entire device (All UMPs) |
690 | __u8 Reserved; // Reserved | 679 | __u8 Reserved; // Reserved |
691 | }__attribute__((packed)); | 680 | } __attribute__((packed)); |
692 | 681 | ||
693 | 682 | ||
694 | #endif // if !defined(_USBVEND_H) | 683 | #endif // if !defined(_USBVEND_H) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 3fea9298eb15..28913fa95fb7 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/uaccess.h> | 56 | #include <linux/uaccess.h> |
57 | #include <linux/usb.h> | 57 | #include <linux/usb.h> |
58 | #include <linux/usb/serial.h> | 58 | #include <linux/usb/serial.h> |
59 | #include "ipaq.h" | ||
60 | 59 | ||
61 | #define KP_RETRIES 100 | 60 | #define KP_RETRIES 100 |
62 | 61 | ||
@@ -64,7 +63,7 @@ | |||
64 | * Version Information | 63 | * Version Information |
65 | */ | 64 | */ |
66 | 65 | ||
67 | #define DRIVER_VERSION "v0.5" | 66 | #define DRIVER_VERSION "v1.0" |
68 | #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>" | 67 | #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>" |
69 | #define DRIVER_DESC "USB PocketPC PDA driver" | 68 | #define DRIVER_DESC "USB PocketPC PDA driver" |
70 | 69 | ||
@@ -76,20 +75,8 @@ static int initial_wait; | |||
76 | /* Function prototypes for an ipaq */ | 75 | /* Function prototypes for an ipaq */ |
77 | static int ipaq_open(struct tty_struct *tty, | 76 | static int ipaq_open(struct tty_struct *tty, |
78 | struct usb_serial_port *port); | 77 | struct usb_serial_port *port); |
79 | static void ipaq_close(struct usb_serial_port *port); | ||
80 | static int ipaq_calc_num_ports(struct usb_serial *serial); | 78 | static int ipaq_calc_num_ports(struct usb_serial *serial); |
81 | static int ipaq_startup(struct usb_serial *serial); | 79 | static int ipaq_startup(struct usb_serial *serial); |
82 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
83 | const unsigned char *buf, int count); | ||
84 | static int ipaq_write_bulk(struct usb_serial_port *port, | ||
85 | const unsigned char *buf, int count); | ||
86 | static void ipaq_write_gather(struct usb_serial_port *port); | ||
87 | static void ipaq_read_bulk_callback(struct urb *urb); | ||
88 | static void ipaq_write_bulk_callback(struct urb *urb); | ||
89 | static int ipaq_write_room(struct tty_struct *tty); | ||
90 | static int ipaq_chars_in_buffer(struct tty_struct *tty); | ||
91 | static void ipaq_destroy_lists(struct usb_serial_port *port); | ||
92 | |||
93 | 80 | ||
94 | static struct usb_device_id ipaq_id_table [] = { | 81 | static struct usb_device_id ipaq_id_table [] = { |
95 | /* The first entry is a placeholder for the insmod-specified device */ | 82 | /* The first entry is a placeholder for the insmod-specified device */ |
@@ -558,7 +545,7 @@ static struct usb_driver ipaq_driver = { | |||
558 | .probe = usb_serial_probe, | 545 | .probe = usb_serial_probe, |
559 | .disconnect = usb_serial_disconnect, | 546 | .disconnect = usb_serial_disconnect, |
560 | .id_table = ipaq_id_table, | 547 | .id_table = ipaq_id_table, |
561 | .no_dynamic_id = 1, | 548 | .no_dynamic_id = 1, |
562 | }; | 549 | }; |
563 | 550 | ||
564 | 551 | ||
@@ -569,91 +556,24 @@ static struct usb_serial_driver ipaq_device = { | |||
569 | .name = "ipaq", | 556 | .name = "ipaq", |
570 | }, | 557 | }, |
571 | .description = "PocketPC PDA", | 558 | .description = "PocketPC PDA", |
572 | .usb_driver = &ipaq_driver, | 559 | .usb_driver = &ipaq_driver, |
573 | .id_table = ipaq_id_table, | 560 | .id_table = ipaq_id_table, |
561 | .bulk_in_size = 256, | ||
562 | .bulk_out_size = 256, | ||
574 | .open = ipaq_open, | 563 | .open = ipaq_open, |
575 | .close = ipaq_close, | ||
576 | .attach = ipaq_startup, | 564 | .attach = ipaq_startup, |
577 | .calc_num_ports = ipaq_calc_num_ports, | 565 | .calc_num_ports = ipaq_calc_num_ports, |
578 | .write = ipaq_write, | ||
579 | .write_room = ipaq_write_room, | ||
580 | .chars_in_buffer = ipaq_chars_in_buffer, | ||
581 | .read_bulk_callback = ipaq_read_bulk_callback, | ||
582 | .write_bulk_callback = ipaq_write_bulk_callback, | ||
583 | }; | 566 | }; |
584 | 567 | ||
585 | static spinlock_t write_list_lock; | ||
586 | static int bytes_in; | ||
587 | static int bytes_out; | ||
588 | |||
589 | static int ipaq_open(struct tty_struct *tty, | 568 | static int ipaq_open(struct tty_struct *tty, |
590 | struct usb_serial_port *port) | 569 | struct usb_serial_port *port) |
591 | { | 570 | { |
592 | struct usb_serial *serial = port->serial; | 571 | struct usb_serial *serial = port->serial; |
593 | struct ipaq_private *priv; | 572 | int result = 0; |
594 | struct ipaq_packet *pkt; | ||
595 | int i, result = 0; | ||
596 | int retries = connect_retries; | 573 | int retries = connect_retries; |
597 | 574 | ||
598 | dbg("%s - port %d", __func__, port->number); | 575 | dbg("%s - port %d", __func__, port->number); |
599 | 576 | ||
600 | bytes_in = 0; | ||
601 | bytes_out = 0; | ||
602 | priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); | ||
603 | if (priv == NULL) { | ||
604 | dev_err(&port->dev, "%s - Out of memory\n", __func__); | ||
605 | return -ENOMEM; | ||
606 | } | ||
607 | usb_set_serial_port_data(port, priv); | ||
608 | priv->active = 0; | ||
609 | priv->queue_len = 0; | ||
610 | priv->free_len = 0; | ||
611 | INIT_LIST_HEAD(&priv->queue); | ||
612 | INIT_LIST_HEAD(&priv->freelist); | ||
613 | |||
614 | for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) { | ||
615 | pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL); | ||
616 | if (pkt == NULL) | ||
617 | goto enomem; | ||
618 | |||
619 | pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL); | ||
620 | if (pkt->data == NULL) { | ||
621 | kfree(pkt); | ||
622 | goto enomem; | ||
623 | } | ||
624 | pkt->len = 0; | ||
625 | pkt->written = 0; | ||
626 | INIT_LIST_HEAD(&pkt->list); | ||
627 | list_add(&pkt->list, &priv->freelist); | ||
628 | priv->free_len += PACKET_SIZE; | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * Lose the small buffers usbserial provides. Make larger ones. | ||
633 | */ | ||
634 | |||
635 | kfree(port->bulk_in_buffer); | ||
636 | kfree(port->bulk_out_buffer); | ||
637 | /* make sure the generic serial code knows */ | ||
638 | port->bulk_out_buffer = NULL; | ||
639 | |||
640 | port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | ||
641 | if (port->bulk_in_buffer == NULL) | ||
642 | goto enomem; | ||
643 | |||
644 | port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | ||
645 | if (port->bulk_out_buffer == NULL) { | ||
646 | /* the buffer is useless, free it */ | ||
647 | kfree(port->bulk_in_buffer); | ||
648 | port->bulk_in_buffer = NULL; | ||
649 | goto enomem; | ||
650 | } | ||
651 | port->read_urb->transfer_buffer = port->bulk_in_buffer; | ||
652 | port->write_urb->transfer_buffer = port->bulk_out_buffer; | ||
653 | port->read_urb->transfer_buffer_length = URBDATA_SIZE; | ||
654 | port->bulk_out_size = port->write_urb->transfer_buffer_length | ||
655 | = URBDATA_SIZE; | ||
656 | |||
657 | msleep(1000*initial_wait); | 577 | msleep(1000*initial_wait); |
658 | 578 | ||
659 | /* | 579 | /* |
@@ -663,7 +583,6 @@ static int ipaq_open(struct tty_struct *tty, | |||
663 | * through. Since this has a reasonably high failure rate, we retry | 583 | * through. Since this has a reasonably high failure rate, we retry |
664 | * several times. | 584 | * several times. |
665 | */ | 585 | */ |
666 | |||
667 | while (retries--) { | 586 | while (retries--) { |
668 | result = usb_control_msg(serial->dev, | 587 | result = usb_control_msg(serial->dev, |
669 | usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, | 588 | usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, |
@@ -673,269 +592,15 @@ static int ipaq_open(struct tty_struct *tty, | |||
673 | 592 | ||
674 | msleep(1000); | 593 | msleep(1000); |
675 | } | 594 | } |
676 | |||
677 | if (!retries && result) { | 595 | if (!retries && result) { |
678 | dev_err(&port->dev, "%s - failed doing control urb, error %d\n", __func__, result); | 596 | dev_err(&port->dev, "%s - failed doing control urb, error %d\n", |
679 | goto error; | 597 | __func__, result); |
680 | } | 598 | return result; |
681 | |||
682 | /* Start reading from the device */ | ||
683 | usb_fill_bulk_urb(port->read_urb, serial->dev, | ||
684 | usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), | ||
685 | port->read_urb->transfer_buffer, | ||
686 | port->read_urb->transfer_buffer_length, | ||
687 | ipaq_read_bulk_callback, port); | ||
688 | |||
689 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
690 | if (result) { | ||
691 | dev_err(&port->dev, | ||
692 | "%s - failed submitting read urb, error %d\n", | ||
693 | __func__, result); | ||
694 | goto error; | ||
695 | } | ||
696 | |||
697 | return 0; | ||
698 | |||
699 | enomem: | ||
700 | result = -ENOMEM; | ||
701 | dev_err(&port->dev, "%s - Out of memory\n", __func__); | ||
702 | error: | ||
703 | ipaq_destroy_lists(port); | ||
704 | kfree(priv); | ||
705 | return result; | ||
706 | } | ||
707 | |||
708 | |||
709 | static void ipaq_close(struct usb_serial_port *port) | ||
710 | { | ||
711 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
712 | |||
713 | dbg("%s - port %d", __func__, port->number); | ||
714 | |||
715 | /* | ||
716 | * shut down bulk read and write | ||
717 | */ | ||
718 | usb_kill_urb(port->write_urb); | ||
719 | usb_kill_urb(port->read_urb); | ||
720 | ipaq_destroy_lists(port); | ||
721 | kfree(priv); | ||
722 | usb_set_serial_port_data(port, NULL); | ||
723 | |||
724 | /* Uncomment the following line if you want to see some statistics | ||
725 | * in your syslog */ | ||
726 | /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */ | ||
727 | } | ||
728 | |||
729 | static void ipaq_read_bulk_callback(struct urb *urb) | ||
730 | { | ||
731 | struct usb_serial_port *port = urb->context; | ||
732 | struct tty_struct *tty; | ||
733 | unsigned char *data = urb->transfer_buffer; | ||
734 | int result; | ||
735 | int status = urb->status; | ||
736 | |||
737 | dbg("%s - port %d", __func__, port->number); | ||
738 | |||
739 | if (status) { | ||
740 | dbg("%s - nonzero read bulk status received: %d", | ||
741 | __func__, status); | ||
742 | return; | ||
743 | } | ||
744 | |||
745 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
746 | urb->actual_length, data); | ||
747 | |||
748 | tty = tty_port_tty_get(&port->port); | ||
749 | if (tty && urb->actual_length) { | ||
750 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
751 | tty_flip_buffer_push(tty); | ||
752 | bytes_in += urb->actual_length; | ||
753 | } | ||
754 | tty_kref_put(tty); | ||
755 | |||
756 | /* Continue trying to always read */ | ||
757 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
758 | usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), | ||
759 | port->read_urb->transfer_buffer, | ||
760 | port->read_urb->transfer_buffer_length, | ||
761 | ipaq_read_bulk_callback, port); | ||
762 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
763 | if (result) | ||
764 | dev_err(&port->dev, | ||
765 | "%s - failed resubmitting read urb, error %d\n", | ||
766 | __func__, result); | ||
767 | return; | ||
768 | } | ||
769 | |||
770 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
771 | const unsigned char *buf, int count) | ||
772 | { | ||
773 | const unsigned char *current_position = buf; | ||
774 | int bytes_sent = 0; | ||
775 | int transfer_size; | ||
776 | |||
777 | dbg("%s - port %d", __func__, port->number); | ||
778 | |||
779 | while (count > 0) { | ||
780 | transfer_size = min(count, PACKET_SIZE); | ||
781 | if (ipaq_write_bulk(port, current_position, transfer_size)) | ||
782 | break; | ||
783 | current_position += transfer_size; | ||
784 | bytes_sent += transfer_size; | ||
785 | count -= transfer_size; | ||
786 | bytes_out += transfer_size; | ||
787 | } | 599 | } |
788 | 600 | ||
789 | return bytes_sent; | 601 | return usb_serial_generic_open(tty, port); |
790 | } | 602 | } |
791 | 603 | ||
792 | static int ipaq_write_bulk(struct usb_serial_port *port, | ||
793 | const unsigned char *buf, int count) | ||
794 | { | ||
795 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
796 | struct ipaq_packet *pkt = NULL; | ||
797 | int result = 0; | ||
798 | unsigned long flags; | ||
799 | |||
800 | if (priv->free_len <= 0) { | ||
801 | dbg("%s - we're stuffed", __func__); | ||
802 | return -EAGAIN; | ||
803 | } | ||
804 | |||
805 | spin_lock_irqsave(&write_list_lock, flags); | ||
806 | if (!list_empty(&priv->freelist)) { | ||
807 | pkt = list_entry(priv->freelist.next, struct ipaq_packet, list); | ||
808 | list_del(&pkt->list); | ||
809 | priv->free_len -= PACKET_SIZE; | ||
810 | } | ||
811 | spin_unlock_irqrestore(&write_list_lock, flags); | ||
812 | if (pkt == NULL) { | ||
813 | dbg("%s - we're stuffed", __func__); | ||
814 | return -EAGAIN; | ||
815 | } | ||
816 | |||
817 | memcpy(pkt->data, buf, count); | ||
818 | usb_serial_debug_data(debug, &port->dev, __func__, count, pkt->data); | ||
819 | |||
820 | pkt->len = count; | ||
821 | pkt->written = 0; | ||
822 | spin_lock_irqsave(&write_list_lock, flags); | ||
823 | list_add_tail(&pkt->list, &priv->queue); | ||
824 | priv->queue_len += count; | ||
825 | if (priv->active == 0) { | ||
826 | priv->active = 1; | ||
827 | ipaq_write_gather(port); | ||
828 | spin_unlock_irqrestore(&write_list_lock, flags); | ||
829 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
830 | if (result) | ||
831 | dev_err(&port->dev, | ||
832 | "%s - failed submitting write urb, error %d\n", | ||
833 | __func__, result); | ||
834 | } else { | ||
835 | spin_unlock_irqrestore(&write_list_lock, flags); | ||
836 | } | ||
837 | return result; | ||
838 | } | ||
839 | |||
840 | static void ipaq_write_gather(struct usb_serial_port *port) | ||
841 | { | ||
842 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
843 | struct usb_serial *serial = port->serial; | ||
844 | int count, room; | ||
845 | struct ipaq_packet *pkt, *tmp; | ||
846 | struct urb *urb = port->write_urb; | ||
847 | |||
848 | room = URBDATA_SIZE; | ||
849 | list_for_each_entry_safe(pkt, tmp, &priv->queue, list) { | ||
850 | count = min(room, (int)(pkt->len - pkt->written)); | ||
851 | memcpy(urb->transfer_buffer + (URBDATA_SIZE - room), | ||
852 | pkt->data + pkt->written, count); | ||
853 | room -= count; | ||
854 | pkt->written += count; | ||
855 | priv->queue_len -= count; | ||
856 | if (pkt->written == pkt->len) { | ||
857 | list_move(&pkt->list, &priv->freelist); | ||
858 | priv->free_len += PACKET_SIZE; | ||
859 | } | ||
860 | if (room == 0) | ||
861 | break; | ||
862 | } | ||
863 | |||
864 | count = URBDATA_SIZE - room; | ||
865 | usb_fill_bulk_urb(port->write_urb, serial->dev, | ||
866 | usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), | ||
867 | port->write_urb->transfer_buffer, count, | ||
868 | ipaq_write_bulk_callback, port); | ||
869 | return; | ||
870 | } | ||
871 | |||
872 | static void ipaq_write_bulk_callback(struct urb *urb) | ||
873 | { | ||
874 | struct usb_serial_port *port = urb->context; | ||
875 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
876 | unsigned long flags; | ||
877 | int result; | ||
878 | int status = urb->status; | ||
879 | |||
880 | dbg("%s - port %d", __func__, port->number); | ||
881 | |||
882 | if (status) { | ||
883 | dbg("%s - nonzero write bulk status received: %d", | ||
884 | __func__, status); | ||
885 | return; | ||
886 | } | ||
887 | |||
888 | spin_lock_irqsave(&write_list_lock, flags); | ||
889 | if (!list_empty(&priv->queue)) { | ||
890 | ipaq_write_gather(port); | ||
891 | spin_unlock_irqrestore(&write_list_lock, flags); | ||
892 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
893 | if (result) | ||
894 | dev_err(&port->dev, | ||
895 | "%s - failed submitting write urb, error %d\n", | ||
896 | __func__, result); | ||
897 | } else { | ||
898 | priv->active = 0; | ||
899 | spin_unlock_irqrestore(&write_list_lock, flags); | ||
900 | } | ||
901 | |||
902 | usb_serial_port_softint(port); | ||
903 | } | ||
904 | |||
905 | static int ipaq_write_room(struct tty_struct *tty) | ||
906 | { | ||
907 | struct usb_serial_port *port = tty->driver_data; | ||
908 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
909 | |||
910 | dbg("%s - freelen %d", __func__, priv->free_len); | ||
911 | return priv->free_len; | ||
912 | } | ||
913 | |||
914 | static int ipaq_chars_in_buffer(struct tty_struct *tty) | ||
915 | { | ||
916 | struct usb_serial_port *port = tty->driver_data; | ||
917 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
918 | |||
919 | dbg("%s - queuelen %d", __func__, priv->queue_len); | ||
920 | return priv->queue_len; | ||
921 | } | ||
922 | |||
923 | static void ipaq_destroy_lists(struct usb_serial_port *port) | ||
924 | { | ||
925 | struct ipaq_private *priv = usb_get_serial_port_data(port); | ||
926 | struct ipaq_packet *pkt, *tmp; | ||
927 | |||
928 | list_for_each_entry_safe(pkt, tmp, &priv->queue, list) { | ||
929 | kfree(pkt->data); | ||
930 | kfree(pkt); | ||
931 | } | ||
932 | list_for_each_entry_safe(pkt, tmp, &priv->freelist, list) { | ||
933 | kfree(pkt->data); | ||
934 | kfree(pkt); | ||
935 | } | ||
936 | } | ||
937 | |||
938 | |||
939 | static int ipaq_calc_num_ports(struct usb_serial *serial) | 604 | static int ipaq_calc_num_ports(struct usb_serial *serial) |
940 | { | 605 | { |
941 | /* | 606 | /* |
@@ -994,7 +659,6 @@ static int ipaq_startup(struct usb_serial *serial) | |||
994 | static int __init ipaq_init(void) | 659 | static int __init ipaq_init(void) |
995 | { | 660 | { |
996 | int retval; | 661 | int retval; |
997 | spin_lock_init(&write_list_lock); | ||
998 | retval = usb_serial_register(&ipaq_device); | 662 | retval = usb_serial_register(&ipaq_device); |
999 | if (retval) | 663 | if (retval) |
1000 | goto failed_usb_serial_register; | 664 | goto failed_usb_serial_register; |
@@ -1015,7 +679,6 @@ failed_usb_serial_register: | |||
1015 | return retval; | 679 | return retval; |
1016 | } | 680 | } |
1017 | 681 | ||
1018 | |||
1019 | static void __exit ipaq_exit(void) | 682 | static void __exit ipaq_exit(void) |
1020 | { | 683 | { |
1021 | usb_deregister(&ipaq_driver); | 684 | usb_deregister(&ipaq_driver); |
diff --git a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h deleted file mode 100644 index 2b9035918b85..000000000000 --- a/drivers/usb/serial/ipaq.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * USB Compaq iPAQ driver | ||
3 | * | ||
4 | * Copyright (C) 2001 - 2002 | ||
5 | * Ganesh Varadarajan <ganesh@veritas.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __LINUX_USB_SERIAL_IPAQ_H | ||
15 | #define __LINUX_USB_SERIAL_IPAQ_H | ||
16 | |||
17 | /* | ||
18 | * Since we can't queue our bulk write urbs (don't know why - it just | ||
19 | * doesn't work), we can send down only one write urb at a time. The simplistic | ||
20 | * approach taken by the generic usbserial driver will work, but it's not good | ||
21 | * for performance. Therefore, we buffer upto URBDATA_QUEUE_MAX bytes of write | ||
22 | * requests coming from the line discipline. This is done by chaining them | ||
23 | * in lists of struct ipaq_packet, each packet holding a maximum of | ||
24 | * PACKET_SIZE bytes. | ||
25 | * | ||
26 | * ipaq_write() can be called from bottom half context; hence we can't | ||
27 | * allocate memory for packets there. So we initialize a pool of packets at | ||
28 | * the first open and maintain a freelist. | ||
29 | * | ||
30 | * The value of PACKET_SIZE was empirically determined by | ||
31 | * checking the maximum write sizes sent down by the ppp ldisc. | ||
32 | * URBDATA_QUEUE_MAX is set to 64K, which is the maximum TCP window size. | ||
33 | */ | ||
34 | |||
35 | struct ipaq_packet { | ||
36 | char *data; | ||
37 | size_t len; | ||
38 | size_t written; | ||
39 | struct list_head list; | ||
40 | }; | ||
41 | |||
42 | struct ipaq_private { | ||
43 | int active; | ||
44 | int queue_len; | ||
45 | int free_len; | ||
46 | struct list_head queue; | ||
47 | struct list_head freelist; | ||
48 | }; | ||
49 | |||
50 | #define URBDATA_SIZE 4096 | ||
51 | #define URBDATA_QUEUE_MAX (64 * 1024) | ||
52 | #define PACKET_SIZE 256 | ||
53 | |||
54 | #endif | ||
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index e1d07840cee6..ca77e88836bd 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -34,7 +34,6 @@ | |||
34 | * DCD, DTR, RTS, CTS which are currently faked. | 34 | * DCD, DTR, RTS, CTS which are currently faked. |
35 | * It's good enough for PPP at this point. It's based off all kinds of | 35 | * It's good enough for PPP at this point. It's based off all kinds of |
36 | * code found in usb/serial and usb/class | 36 | * code found in usb/serial and usb/class |
37 | * | ||
38 | */ | 37 | */ |
39 | 38 | ||
40 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
@@ -52,7 +51,7 @@ | |||
52 | /* | 51 | /* |
53 | * Version Information | 52 | * Version Information |
54 | */ | 53 | */ |
55 | #define DRIVER_VERSION "v0.3" | 54 | #define DRIVER_VERSION "v0.4" |
56 | #define DRIVER_AUTHOR "Roelf Diedericks" | 55 | #define DRIVER_AUTHOR "Roelf Diedericks" |
57 | #define DRIVER_DESC "IPWireless tty driver" | 56 | #define DRIVER_DESC "IPWireless tty driver" |
58 | 57 | ||
@@ -65,8 +64,6 @@ | |||
65 | /* Message sizes */ | 64 | /* Message sizes */ |
66 | #define EVENT_BUFFER_SIZE 0xFF | 65 | #define EVENT_BUFFER_SIZE 0xFF |
67 | #define CHAR2INT16(c1, c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff)) | 66 | #define CHAR2INT16(c1, c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff)) |
68 | #define NUM_BULK_URBS 24 | ||
69 | #define NUM_CONTROL_URBS 16 | ||
70 | 67 | ||
71 | /* vendor/product pairs that are known work with this driver*/ | 68 | /* vendor/product pairs that are known work with this driver*/ |
72 | #define IPW_VID 0x0bc3 | 69 | #define IPW_VID 0x0bc3 |
@@ -151,47 +148,6 @@ static struct usb_driver usb_ipw_driver = { | |||
151 | 148 | ||
152 | static int debug; | 149 | static int debug; |
153 | 150 | ||
154 | static void ipw_read_bulk_callback(struct urb *urb) | ||
155 | { | ||
156 | struct usb_serial_port *port = urb->context; | ||
157 | unsigned char *data = urb->transfer_buffer; | ||
158 | struct tty_struct *tty; | ||
159 | int result; | ||
160 | int status = urb->status; | ||
161 | |||
162 | dbg("%s - port %d", __func__, port->number); | ||
163 | |||
164 | if (status) { | ||
165 | dbg("%s - nonzero read bulk status received: %d", | ||
166 | __func__, status); | ||
167 | return; | ||
168 | } | ||
169 | |||
170 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
171 | urb->actual_length, data); | ||
172 | |||
173 | tty = tty_port_tty_get(&port->port); | ||
174 | if (tty && urb->actual_length) { | ||
175 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
176 | tty_flip_buffer_push(tty); | ||
177 | } | ||
178 | tty_kref_put(tty); | ||
179 | |||
180 | /* Continue trying to always read */ | ||
181 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
182 | usb_rcvbulkpipe(port->serial->dev, | ||
183 | port->bulk_in_endpointAddress), | ||
184 | port->read_urb->transfer_buffer, | ||
185 | port->read_urb->transfer_buffer_length, | ||
186 | ipw_read_bulk_callback, port); | ||
187 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
188 | if (result) | ||
189 | dev_err(&port->dev, | ||
190 | "%s - failed resubmitting read urb, error %d\n", | ||
191 | __func__, result); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) | 151 | static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) |
196 | { | 152 | { |
197 | struct usb_device *dev = port->serial->dev; | 153 | struct usb_device *dev = port->serial->dev; |
@@ -229,15 +185,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
229 | 185 | ||
230 | /*--2: Start reading from the device */ | 186 | /*--2: Start reading from the device */ |
231 | dbg("%s: setting up bulk read callback", __func__); | 187 | dbg("%s: setting up bulk read callback", __func__); |
232 | usb_fill_bulk_urb(port->read_urb, dev, | 188 | usb_serial_generic_open(tty, port); |
233 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), | ||
234 | port->bulk_in_buffer, | ||
235 | port->bulk_in_size, | ||
236 | ipw_read_bulk_callback, port); | ||
237 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
238 | if (result < 0) | ||
239 | dbg("%s - usb_submit_urb(read bulk) failed with status %d", | ||
240 | __func__, result); | ||
241 | 189 | ||
242 | /*--3: Tell the modem to open the floodgates on the rx bulk channel */ | 190 | /*--3: Tell the modem to open the floodgates on the rx bulk channel */ |
243 | dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__); | 191 | dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__); |
@@ -267,35 +215,6 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
267 | dev_err(&port->dev, | 215 | dev_err(&port->dev, |
268 | "initial flowcontrol failed (error = %d)\n", result); | 216 | "initial flowcontrol failed (error = %d)\n", result); |
269 | 217 | ||
270 | |||
271 | /*--5: raise the dtr */ | ||
272 | dbg("%s:raising dtr", __func__); | ||
273 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
274 | IPW_SIO_SET_PIN, | ||
275 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
276 | IPW_PIN_SETDTR, | ||
277 | 0, | ||
278 | NULL, | ||
279 | 0, | ||
280 | 200000); | ||
281 | if (result < 0) | ||
282 | dev_err(&port->dev, | ||
283 | "setting dtr failed (error = %d)\n", result); | ||
284 | |||
285 | /*--6: raise the rts */ | ||
286 | dbg("%s:raising rts", __func__); | ||
287 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
288 | IPW_SIO_SET_PIN, | ||
289 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
290 | IPW_PIN_SETRTS, | ||
291 | 0, | ||
292 | NULL, | ||
293 | 0, | ||
294 | 200000); | ||
295 | if (result < 0) | ||
296 | dev_err(&port->dev, | ||
297 | "setting dtr failed (error = %d)\n", result); | ||
298 | |||
299 | kfree(buf_flow_init); | 218 | kfree(buf_flow_init); |
300 | return 0; | 219 | return 0; |
301 | } | 220 | } |
@@ -305,8 +224,8 @@ static void ipw_dtr_rts(struct usb_serial_port *port, int on) | |||
305 | struct usb_device *dev = port->serial->dev; | 224 | struct usb_device *dev = port->serial->dev; |
306 | int result; | 225 | int result; |
307 | 226 | ||
308 | /*--1: drop the dtr */ | 227 | dbg("%s: on = %d", __func__, on); |
309 | dbg("%s:dropping dtr", __func__); | 228 | |
310 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 229 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
311 | IPW_SIO_SET_PIN, | 230 | IPW_SIO_SET_PIN, |
312 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, | 231 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, |
@@ -316,22 +235,20 @@ static void ipw_dtr_rts(struct usb_serial_port *port, int on) | |||
316 | 0, | 235 | 0, |
317 | 200000); | 236 | 200000); |
318 | if (result < 0) | 237 | if (result < 0) |
319 | dev_err(&port->dev, "dropping dtr failed (error = %d)\n", | 238 | dev_err(&port->dev, "setting dtr failed (error = %d)\n", |
320 | result); | 239 | result); |
321 | 240 | ||
322 | /*--2: drop the rts */ | ||
323 | dbg("%s:dropping rts", __func__); | ||
324 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 241 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
325 | IPW_SIO_SET_PIN, USB_TYPE_VENDOR | | 242 | IPW_SIO_SET_PIN, USB_TYPE_VENDOR | |
326 | USB_RECIP_INTERFACE | USB_DIR_OUT, | 243 | USB_RECIP_INTERFACE | USB_DIR_OUT, |
327 | on ? IPW_PIN_SETRTS : IPW_PIN_CLRRTS, | 244 | on ? IPW_PIN_SETRTS : IPW_PIN_CLRRTS, |
328 | 0, | 245 | 0, |
329 | NULL, | 246 | NULL, |
330 | 0, | 247 | 0, |
331 | 200000); | 248 | 200000); |
332 | if (result < 0) | 249 | if (result < 0) |
333 | dev_err(&port->dev, | 250 | dev_err(&port->dev, "setting rts failed (error = %d)\n", |
334 | "dropping rts failed (error = %d)\n", result); | 251 | result); |
335 | } | 252 | } |
336 | 253 | ||
337 | static void ipw_close(struct usb_serial_port *port) | 254 | static void ipw_close(struct usb_serial_port *port) |
@@ -368,83 +285,7 @@ static void ipw_close(struct usb_serial_port *port) | |||
368 | dev_err(&port->dev, | 285 | dev_err(&port->dev, |
369 | "Disabling bulk RxRead failed (error = %d)\n", result); | 286 | "Disabling bulk RxRead failed (error = %d)\n", result); |
370 | 287 | ||
371 | /* shutdown any in-flight urbs that we know about */ | 288 | usb_serial_generic_close(port); |
372 | usb_kill_urb(port->read_urb); | ||
373 | usb_kill_urb(port->write_urb); | ||
374 | } | ||
375 | |||
376 | static void ipw_write_bulk_callback(struct urb *urb) | ||
377 | { | ||
378 | struct usb_serial_port *port = urb->context; | ||
379 | int status = urb->status; | ||
380 | |||
381 | dbg("%s", __func__); | ||
382 | |||
383 | port->write_urb_busy = 0; | ||
384 | |||
385 | if (status) | ||
386 | dbg("%s - nonzero write bulk status received: %d", | ||
387 | __func__, status); | ||
388 | |||
389 | usb_serial_port_softint(port); | ||
390 | } | ||
391 | |||
392 | static int ipw_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
393 | const unsigned char *buf, int count) | ||
394 | { | ||
395 | struct usb_device *dev = port->serial->dev; | ||
396 | int ret; | ||
397 | |||
398 | dbg("%s: TOP: count=%d, in_interrupt=%ld", __func__, | ||
399 | count, in_interrupt()); | ||
400 | |||
401 | if (count == 0) { | ||
402 | dbg("%s - write request of 0 bytes", __func__); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | spin_lock_bh(&port->lock); | ||
407 | if (port->write_urb_busy) { | ||
408 | spin_unlock_bh(&port->lock); | ||
409 | dbg("%s - already writing", __func__); | ||
410 | return 0; | ||
411 | } | ||
412 | port->write_urb_busy = 1; | ||
413 | spin_unlock_bh(&port->lock); | ||
414 | |||
415 | count = min(count, port->bulk_out_size); | ||
416 | memcpy(port->bulk_out_buffer, buf, count); | ||
417 | |||
418 | dbg("%s count now:%d", __func__, count); | ||
419 | |||
420 | usb_fill_bulk_urb(port->write_urb, dev, | ||
421 | usb_sndbulkpipe(dev, port->bulk_out_endpointAddress), | ||
422 | port->write_urb->transfer_buffer, | ||
423 | count, | ||
424 | ipw_write_bulk_callback, | ||
425 | port); | ||
426 | |||
427 | ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
428 | if (ret != 0) { | ||
429 | port->write_urb_busy = 0; | ||
430 | dbg("%s - usb_submit_urb(write bulk) failed with error = %d", | ||
431 | __func__, ret); | ||
432 | return ret; | ||
433 | } | ||
434 | |||
435 | dbg("%s returning %d", __func__, count); | ||
436 | return count; | ||
437 | } | ||
438 | |||
439 | static int ipw_probe(struct usb_serial_port *port) | ||
440 | { | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int ipw_disconnect(struct usb_serial_port *port) | ||
445 | { | ||
446 | usb_set_serial_port_data(port, NULL); | ||
447 | return 0; | ||
448 | } | 289 | } |
449 | 290 | ||
450 | static struct usb_serial_driver ipw_device = { | 291 | static struct usb_serial_driver ipw_device = { |
@@ -453,17 +294,12 @@ static struct usb_serial_driver ipw_device = { | |||
453 | .name = "ipw", | 294 | .name = "ipw", |
454 | }, | 295 | }, |
455 | .description = "IPWireless converter", | 296 | .description = "IPWireless converter", |
456 | .usb_driver = &usb_ipw_driver, | 297 | .usb_driver = &usb_ipw_driver, |
457 | .id_table = usb_ipw_ids, | 298 | .id_table = usb_ipw_ids, |
458 | .num_ports = 1, | 299 | .num_ports = 1, |
459 | .open = ipw_open, | 300 | .open = ipw_open, |
460 | .close = ipw_close, | 301 | .close = ipw_close, |
461 | .dtr_rts = ipw_dtr_rts, | 302 | .dtr_rts = ipw_dtr_rts, |
462 | .port_probe = ipw_probe, | ||
463 | .port_remove = ipw_disconnect, | ||
464 | .write = ipw_write, | ||
465 | .write_bulk_callback = ipw_write_bulk_callback, | ||
466 | .read_bulk_callback = ipw_read_bulk_callback, | ||
467 | }; | 303 | }; |
468 | 304 | ||
469 | 305 | ||
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 4a0f51974232..ccbce4066d04 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) | 4 | * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) |
5 | * Copyright (C) 2002 Gary Brubaker (xavyer@ix.netcom.com) | 5 | * Copyright (C) 2002 Gary Brubaker (xavyer@ix.netcom.com) |
6 | * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -72,8 +73,8 @@ | |||
72 | /* | 73 | /* |
73 | * Version Information | 74 | * Version Information |
74 | */ | 75 | */ |
75 | #define DRIVER_VERSION "v0.4" | 76 | #define DRIVER_VERSION "v0.5" |
76 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" | 77 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Johan Hovold <jhovold@gmail.com>" |
77 | #define DRIVER_DESC "USB IR Dongle driver" | 78 | #define DRIVER_DESC "USB IR Dongle driver" |
78 | 79 | ||
79 | static int debug; | 80 | static int debug; |
@@ -87,11 +88,9 @@ static int xbof = -1; | |||
87 | 88 | ||
88 | static int ir_startup (struct usb_serial *serial); | 89 | static int ir_startup (struct usb_serial *serial); |
89 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port); | 90 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port); |
90 | static void ir_close(struct usb_serial_port *port); | 91 | static int ir_prepare_write_buffer(struct usb_serial_port *port, |
91 | static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, | 92 | void *dest, size_t size); |
92 | const unsigned char *buf, int count); | 93 | static void ir_process_read_urb(struct urb *urb); |
93 | static void ir_write_bulk_callback (struct urb *urb); | ||
94 | static void ir_read_bulk_callback (struct urb *urb); | ||
95 | static void ir_set_termios(struct tty_struct *tty, | 94 | static void ir_set_termios(struct tty_struct *tty, |
96 | struct usb_serial_port *port, struct ktermios *old_termios); | 95 | struct usb_serial_port *port, struct ktermios *old_termios); |
97 | 96 | ||
@@ -130,10 +129,8 @@ static struct usb_serial_driver ir_device = { | |||
130 | .set_termios = ir_set_termios, | 129 | .set_termios = ir_set_termios, |
131 | .attach = ir_startup, | 130 | .attach = ir_startup, |
132 | .open = ir_open, | 131 | .open = ir_open, |
133 | .close = ir_close, | 132 | .prepare_write_buffer = ir_prepare_write_buffer, |
134 | .write = ir_write, | 133 | .process_read_urb = ir_process_read_urb, |
135 | .write_bulk_callback = ir_write_bulk_callback, | ||
136 | .read_bulk_callback = ir_read_bulk_callback, | ||
137 | }; | 134 | }; |
138 | 135 | ||
139 | static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc) | 136 | static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc) |
@@ -198,7 +195,6 @@ error: | |||
198 | return NULL; | 195 | return NULL; |
199 | } | 196 | } |
200 | 197 | ||
201 | |||
202 | static u8 ir_xbof_change(u8 xbof) | 198 | static u8 ir_xbof_change(u8 xbof) |
203 | { | 199 | { |
204 | u8 result; | 200 | u8 result; |
@@ -237,7 +233,6 @@ static u8 ir_xbof_change(u8 xbof) | |||
237 | return(result); | 233 | return(result); |
238 | } | 234 | } |
239 | 235 | ||
240 | |||
241 | static int ir_startup(struct usb_serial *serial) | 236 | static int ir_startup(struct usb_serial *serial) |
242 | { | 237 | { |
243 | struct usb_irda_cs_descriptor *irda_desc; | 238 | struct usb_irda_cs_descriptor *irda_desc; |
@@ -297,83 +292,22 @@ static int ir_startup(struct usb_serial *serial) | |||
297 | 292 | ||
298 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) | 293 | static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) |
299 | { | 294 | { |
300 | char *buffer; | 295 | int i; |
301 | int result = 0; | ||
302 | 296 | ||
303 | dbg("%s - port %d", __func__, port->number); | 297 | dbg("%s - port %d", __func__, port->number); |
304 | 298 | ||
305 | if (buffer_size) { | 299 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) |
306 | /* override the default buffer sizes */ | 300 | port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET; |
307 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
308 | if (!buffer) { | ||
309 | dev_err(&port->dev, "%s - out of memory.\n", __func__); | ||
310 | return -ENOMEM; | ||
311 | } | ||
312 | kfree(port->read_urb->transfer_buffer); | ||
313 | port->read_urb->transfer_buffer = buffer; | ||
314 | port->read_urb->transfer_buffer_length = buffer_size; | ||
315 | |||
316 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
317 | if (!buffer) { | ||
318 | dev_err(&port->dev, "%s - out of memory.\n", __func__); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | kfree(port->write_urb->transfer_buffer); | ||
322 | port->write_urb->transfer_buffer = buffer; | ||
323 | port->write_urb->transfer_buffer_length = buffer_size; | ||
324 | port->bulk_out_size = buffer_size; | ||
325 | } | ||
326 | 301 | ||
327 | /* Start reading from the device */ | 302 | /* Start reading from the device */ |
328 | usb_fill_bulk_urb( | 303 | return usb_serial_generic_open(tty, port); |
329 | port->read_urb, | ||
330 | port->serial->dev, | ||
331 | usb_rcvbulkpipe(port->serial->dev, | ||
332 | port->bulk_in_endpointAddress), | ||
333 | port->read_urb->transfer_buffer, | ||
334 | port->read_urb->transfer_buffer_length, | ||
335 | ir_read_bulk_callback, | ||
336 | port); | ||
337 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
338 | if (result) | ||
339 | dev_err(&port->dev, | ||
340 | "%s - failed submitting read urb, error %d\n", | ||
341 | __func__, result); | ||
342 | |||
343 | return result; | ||
344 | } | 304 | } |
345 | 305 | ||
346 | static void ir_close(struct usb_serial_port *port) | 306 | static int ir_prepare_write_buffer(struct usb_serial_port *port, |
307 | void *dest, size_t size) | ||
347 | { | 308 | { |
348 | dbg("%s - port %d", __func__, port->number); | 309 | unsigned char *buf = dest; |
349 | 310 | int count; | |
350 | /* shutdown our bulk read */ | ||
351 | usb_kill_urb(port->read_urb); | ||
352 | } | ||
353 | |||
354 | static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
355 | const unsigned char *buf, int count) | ||
356 | { | ||
357 | unsigned char *transfer_buffer; | ||
358 | int result; | ||
359 | int transfer_size; | ||
360 | |||
361 | dbg("%s - port = %d, count = %d", __func__, port->number, count); | ||
362 | |||
363 | if (count == 0) | ||
364 | return 0; | ||
365 | |||
366 | spin_lock_bh(&port->lock); | ||
367 | if (port->write_urb_busy) { | ||
368 | spin_unlock_bh(&port->lock); | ||
369 | dbg("%s - already writing", __func__); | ||
370 | return 0; | ||
371 | } | ||
372 | port->write_urb_busy = 1; | ||
373 | spin_unlock_bh(&port->lock); | ||
374 | |||
375 | transfer_buffer = port->write_urb->transfer_buffer; | ||
376 | transfer_size = min(count, port->bulk_out_size - 1); | ||
377 | 311 | ||
378 | /* | 312 | /* |
379 | * The first byte of the packet we send to the device contains an | 313 | * The first byte of the packet we send to the device contains an |
@@ -382,119 +316,57 @@ static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
382 | * | 316 | * |
383 | * See section 5.4.2.2 of the USB IrDA spec. | 317 | * See section 5.4.2.2 of the USB IrDA spec. |
384 | */ | 318 | */ |
385 | *transfer_buffer = ir_xbof | ir_baud; | 319 | *buf = ir_xbof | ir_baud; |
386 | ++transfer_buffer; | ||
387 | |||
388 | memcpy(transfer_buffer, buf, transfer_size); | ||
389 | 320 | ||
390 | usb_fill_bulk_urb( | 321 | count = kfifo_out_locked(&port->write_fifo, buf + 1, size - 1, |
391 | port->write_urb, | 322 | &port->lock); |
392 | port->serial->dev, | 323 | return count + 1; |
393 | usb_sndbulkpipe(port->serial->dev, | ||
394 | port->bulk_out_endpointAddress), | ||
395 | port->write_urb->transfer_buffer, | ||
396 | transfer_size + 1, | ||
397 | ir_write_bulk_callback, | ||
398 | port); | ||
399 | |||
400 | port->write_urb->transfer_flags = URB_ZERO_PACKET; | ||
401 | |||
402 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
403 | if (result) { | ||
404 | port->write_urb_busy = 0; | ||
405 | dev_err(&port->dev, | ||
406 | "%s - failed submitting write urb, error %d\n", | ||
407 | __func__, result); | ||
408 | } else | ||
409 | result = transfer_size; | ||
410 | |||
411 | return result; | ||
412 | } | 324 | } |
413 | 325 | ||
414 | static void ir_write_bulk_callback(struct urb *urb) | 326 | static void ir_process_read_urb(struct urb *urb) |
415 | { | 327 | { |
416 | struct usb_serial_port *port = urb->context; | 328 | struct usb_serial_port *port = urb->context; |
417 | int status = urb->status; | 329 | unsigned char *data = urb->transfer_buffer; |
418 | 330 | struct tty_struct *tty; | |
419 | dbg("%s - port %d", __func__, port->number); | ||
420 | 331 | ||
421 | port->write_urb_busy = 0; | 332 | if (!urb->actual_length) |
422 | if (status) { | ||
423 | dbg("%s - nonzero write bulk status received: %d", | ||
424 | __func__, status); | ||
425 | return; | 333 | return; |
426 | } | 334 | /* |
335 | * The first byte of the packet we get from the device | ||
336 | * contains a busy indicator and baud rate change. | ||
337 | * See section 5.4.1.2 of the USB IrDA spec. | ||
338 | */ | ||
339 | if (*data & 0x0f) | ||
340 | ir_baud = *data & 0x0f; | ||
427 | 341 | ||
428 | usb_serial_debug_data( | 342 | if (urb->actual_length == 1) |
429 | debug, | 343 | return; |
430 | &port->dev, | ||
431 | __func__, | ||
432 | urb->actual_length, | ||
433 | urb->transfer_buffer); | ||
434 | 344 | ||
435 | usb_serial_port_softint(port); | 345 | tty = tty_port_tty_get(&port->port); |
346 | if (!tty) | ||
347 | return; | ||
348 | tty_insert_flip_string(tty, data + 1, urb->actual_length - 1); | ||
349 | tty_flip_buffer_push(tty); | ||
350 | tty_kref_put(tty); | ||
436 | } | 351 | } |
437 | 352 | ||
438 | static void ir_read_bulk_callback(struct urb *urb) | 353 | static void ir_set_termios_callback(struct urb *urb) |
439 | { | 354 | { |
440 | struct usb_serial_port *port = urb->context; | 355 | struct usb_serial_port *port = urb->context; |
441 | struct tty_struct *tty; | ||
442 | unsigned char *data = urb->transfer_buffer; | ||
443 | int result; | ||
444 | int status = urb->status; | 356 | int status = urb->status; |
445 | 357 | ||
446 | dbg("%s - port %d", __func__, port->number); | 358 | dbg("%s - port %d", __func__, port->number); |
447 | 359 | ||
448 | switch (status) { | 360 | kfree(urb->transfer_buffer); |
449 | case 0: /* Successful */ | 361 | |
450 | /* | 362 | if (status) |
451 | * The first byte of the packet we get from the device | 363 | dbg("%s - non-zero urb status: %d", __func__, status); |
452 | * contains a busy indicator and baud rate change. | ||
453 | * See section 5.4.1.2 of the USB IrDA spec. | ||
454 | */ | ||
455 | if ((*data & 0x0f) > 0) | ||
456 | ir_baud = *data & 0x0f; | ||
457 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
458 | urb->actual_length, data); | ||
459 | tty = tty_port_tty_get(&port->port); | ||
460 | tty_insert_flip_string(tty, data+1, urb->actual_length - 1); | ||
461 | tty_flip_buffer_push(tty); | ||
462 | tty_kref_put(tty); | ||
463 | |||
464 | /* | ||
465 | * No break here. | ||
466 | * We want to resubmit the urb so we can read | ||
467 | * again. | ||
468 | */ | ||
469 | |||
470 | case -EPROTO: /* taking inspiration from pl2303.c */ | ||
471 | /* Continue trying to always read */ | ||
472 | usb_fill_bulk_urb( | ||
473 | port->read_urb, | ||
474 | port->serial->dev, | ||
475 | usb_rcvbulkpipe(port->serial->dev, | ||
476 | port->bulk_in_endpointAddress), | ||
477 | port->read_urb->transfer_buffer, | ||
478 | port->read_urb->transfer_buffer_length, | ||
479 | ir_read_bulk_callback, | ||
480 | port); | ||
481 | |||
482 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
483 | if (result) | ||
484 | dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", | ||
485 | __func__, result); | ||
486 | break ; | ||
487 | default: | ||
488 | dbg("%s - nonzero read bulk status received: %d", | ||
489 | __func__, status); | ||
490 | break ; | ||
491 | } | ||
492 | return; | ||
493 | } | 364 | } |
494 | 365 | ||
495 | static void ir_set_termios(struct tty_struct *tty, | 366 | static void ir_set_termios(struct tty_struct *tty, |
496 | struct usb_serial_port *port, struct ktermios *old_termios) | 367 | struct usb_serial_port *port, struct ktermios *old_termios) |
497 | { | 368 | { |
369 | struct urb *urb; | ||
498 | unsigned char *transfer_buffer; | 370 | unsigned char *transfer_buffer; |
499 | int result; | 371 | int result; |
500 | speed_t baud; | 372 | speed_t baud; |
@@ -548,41 +420,63 @@ static void ir_set_termios(struct tty_struct *tty, | |||
548 | else | 420 | else |
549 | ir_xbof = ir_xbof_change(xbof) ; | 421 | ir_xbof = ir_xbof_change(xbof) ; |
550 | 422 | ||
551 | /* FIXME need to check to see if our write urb is busy right | 423 | /* Only speed changes are supported */ |
552 | * now, or use a urb pool. | 424 | tty_termios_copy_hw(tty->termios, old_termios); |
553 | * | 425 | tty_encode_baud_rate(tty, baud, baud); |
426 | |||
427 | /* | ||
554 | * send the baud change out on an "empty" data packet | 428 | * send the baud change out on an "empty" data packet |
555 | */ | 429 | */ |
556 | transfer_buffer = port->write_urb->transfer_buffer; | 430 | urb = usb_alloc_urb(0, GFP_KERNEL); |
431 | if (!urb) { | ||
432 | dev_err(&port->dev, "%s - no more urbs\n", __func__); | ||
433 | return; | ||
434 | } | ||
435 | transfer_buffer = kmalloc(1, GFP_KERNEL); | ||
436 | if (!transfer_buffer) { | ||
437 | dev_err(&port->dev, "%s - out of memory\n", __func__); | ||
438 | goto err_buf; | ||
439 | } | ||
440 | |||
557 | *transfer_buffer = ir_xbof | ir_baud; | 441 | *transfer_buffer = ir_xbof | ir_baud; |
558 | 442 | ||
559 | usb_fill_bulk_urb( | 443 | usb_fill_bulk_urb( |
560 | port->write_urb, | 444 | urb, |
561 | port->serial->dev, | 445 | port->serial->dev, |
562 | usb_sndbulkpipe(port->serial->dev, | 446 | usb_sndbulkpipe(port->serial->dev, |
563 | port->bulk_out_endpointAddress), | 447 | port->bulk_out_endpointAddress), |
564 | port->write_urb->transfer_buffer, | 448 | transfer_buffer, |
565 | 1, | 449 | 1, |
566 | ir_write_bulk_callback, | 450 | ir_set_termios_callback, |
567 | port); | 451 | port); |
568 | 452 | ||
569 | port->write_urb->transfer_flags = URB_ZERO_PACKET; | 453 | urb->transfer_flags = URB_ZERO_PACKET; |
570 | 454 | ||
571 | result = usb_submit_urb(port->write_urb, GFP_KERNEL); | 455 | result = usb_submit_urb(urb, GFP_KERNEL); |
572 | if (result) | 456 | if (result) { |
573 | dev_err(&port->dev, | 457 | dev_err(&port->dev, "%s - failed to submit urb: %d\n", |
574 | "%s - failed submitting write urb, error %d\n", | 458 | __func__, result); |
575 | __func__, result); | 459 | goto err_subm; |
460 | } | ||
576 | 461 | ||
577 | /* Only speed changes are supported */ | 462 | usb_free_urb(urb); |
578 | tty_termios_copy_hw(tty->termios, old_termios); | 463 | |
579 | tty_encode_baud_rate(tty, baud, baud); | 464 | return; |
465 | err_subm: | ||
466 | kfree(transfer_buffer); | ||
467 | err_buf: | ||
468 | usb_free_urb(urb); | ||
580 | } | 469 | } |
581 | 470 | ||
582 | static int __init ir_init(void) | 471 | static int __init ir_init(void) |
583 | { | 472 | { |
584 | int retval; | 473 | int retval; |
585 | 474 | ||
475 | if (buffer_size) { | ||
476 | ir_device.bulk_in_size = buffer_size; | ||
477 | ir_device.bulk_out_size = buffer_size; | ||
478 | } | ||
479 | |||
586 | retval = usb_serial_register(&ir_device); | 480 | retval = usb_serial_register(&ir_device); |
587 | if (retval) | 481 | if (retval) |
588 | goto failed_usb_serial_register; | 482 | goto failed_usb_serial_register; |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 43f13cf2f016..74551cb2e8ee 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -1044,34 +1044,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1044 | if (buf == NULL) | 1044 | if (buf == NULL) |
1045 | return -ENOMEM; | 1045 | return -ENOMEM; |
1046 | 1046 | ||
1047 | /* fixup the endpoint buffer size */ | ||
1048 | kfree(port->bulk_out_buffer); | ||
1049 | port->bulk_out_buffer = kmalloc(512, GFP_KERNEL); | ||
1050 | port->bulk_out_size = 512; | ||
1051 | kfree(port->bulk_in_buffer); | ||
1052 | port->bulk_in_buffer = kmalloc(512, GFP_KERNEL); | ||
1053 | port->bulk_in_size = 512; | ||
1054 | |||
1055 | if (!port->bulk_out_buffer || !port->bulk_in_buffer) { | ||
1056 | kfree(port->bulk_out_buffer); | ||
1057 | kfree(port->bulk_in_buffer); | ||
1058 | kfree(buf); | ||
1059 | return -ENOMEM; | ||
1060 | } | ||
1061 | |||
1062 | usb_fill_bulk_urb(port->write_urb, port->serial->dev, | ||
1063 | usb_sndbulkpipe(port->serial->dev, | ||
1064 | port->bulk_out_endpointAddress), | ||
1065 | port->bulk_out_buffer, 512, | ||
1066 | NULL, NULL); | ||
1067 | |||
1068 | |||
1069 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
1070 | usb_rcvbulkpipe(port->serial->dev, | ||
1071 | port->bulk_in_endpointAddress), | ||
1072 | port->bulk_in_buffer, 512, | ||
1073 | NULL, NULL); | ||
1074 | |||
1075 | priv->poll = 0; | 1047 | priv->poll = 0; |
1076 | 1048 | ||
1077 | /* initialize writebuf */ | 1049 | /* initialize writebuf */ |
@@ -1277,6 +1249,8 @@ static struct usb_serial_driver iuu_device = { | |||
1277 | }, | 1249 | }, |
1278 | .id_table = id_table, | 1250 | .id_table = id_table, |
1279 | .num_ports = 1, | 1251 | .num_ports = 1, |
1252 | .bulk_in_size = 512, | ||
1253 | .bulk_out_size = 512, | ||
1280 | .port_probe = iuu_create_sysfs_attrs, | 1254 | .port_probe = iuu_create_sysfs_attrs, |
1281 | .port_remove = iuu_remove_sysfs_attrs, | 1255 | .port_remove = iuu_remove_sysfs_attrs, |
1282 | .open = iuu_open, | 1256 | .open = iuu_open, |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 8eef91ba4b1c..cdbe8bf7f674 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * KLSI KL5KUSB105 chip RS232 converter driver | 2 | * KLSI KL5KUSB105 chip RS232 converter driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> | ||
4 | * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de> | 5 | * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de> |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -34,17 +35,6 @@ | |||
34 | * implement handshaking or decide that we do not support it | 35 | * implement handshaking or decide that we do not support it |
35 | */ | 36 | */ |
36 | 37 | ||
37 | /* History: | ||
38 | * 0.3a - implemented pools of write URBs | ||
39 | * 0.3 - alpha version for public testing | ||
40 | * 0.2 - TIOCMGET works, so autopilot(1) can be used! | ||
41 | * 0.1 - can be used to do pilot-xfer -p /dev/ttyUSB0 -l | ||
42 | * | ||
43 | * The driver skeleton is mainly based on mct_u232.c and various other | ||
44 | * pieces of code shamelessly copied from the drivers/usb/serial/ directory. | ||
45 | */ | ||
46 | |||
47 | |||
48 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
49 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
50 | #include <linux/init.h> | 40 | #include <linux/init.h> |
@@ -64,8 +54,8 @@ static int debug; | |||
64 | /* | 54 | /* |
65 | * Version Information | 55 | * Version Information |
66 | */ | 56 | */ |
67 | #define DRIVER_VERSION "v0.3a" | 57 | #define DRIVER_VERSION "v0.4" |
68 | #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>" | 58 | #define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>" |
69 | #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" | 59 | #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" |
70 | 60 | ||
71 | 61 | ||
@@ -73,23 +63,17 @@ static int debug; | |||
73 | * Function prototypes | 63 | * Function prototypes |
74 | */ | 64 | */ |
75 | static int klsi_105_startup(struct usb_serial *serial); | 65 | static int klsi_105_startup(struct usb_serial *serial); |
76 | static void klsi_105_disconnect(struct usb_serial *serial); | ||
77 | static void klsi_105_release(struct usb_serial *serial); | 66 | static void klsi_105_release(struct usb_serial *serial); |
78 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); | 67 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); |
79 | static void klsi_105_close(struct usb_serial_port *port); | 68 | static void klsi_105_close(struct usb_serial_port *port); |
80 | static int klsi_105_write(struct tty_struct *tty, | ||
81 | struct usb_serial_port *port, const unsigned char *buf, int count); | ||
82 | static void klsi_105_write_bulk_callback(struct urb *urb); | ||
83 | static int klsi_105_chars_in_buffer(struct tty_struct *tty); | ||
84 | static int klsi_105_write_room(struct tty_struct *tty); | ||
85 | static void klsi_105_read_bulk_callback(struct urb *urb); | ||
86 | static void klsi_105_set_termios(struct tty_struct *tty, | 69 | static void klsi_105_set_termios(struct tty_struct *tty, |
87 | struct usb_serial_port *port, struct ktermios *old); | 70 | struct usb_serial_port *port, struct ktermios *old); |
88 | static void klsi_105_throttle(struct tty_struct *tty); | ||
89 | static void klsi_105_unthrottle(struct tty_struct *tty); | ||
90 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file); | 71 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file); |
91 | static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, | 72 | static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, |
92 | unsigned int set, unsigned int clear); | 73 | unsigned int set, unsigned int clear); |
74 | static void klsi_105_process_read_urb(struct urb *urb); | ||
75 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, | ||
76 | void *dest, size_t size); | ||
93 | 77 | ||
94 | /* | 78 | /* |
95 | * All of the device info needed for the KLSI converters. | 79 | * All of the device info needed for the KLSI converters. |
@@ -107,7 +91,7 @@ static struct usb_driver kl5kusb105d_driver = { | |||
107 | .probe = usb_serial_probe, | 91 | .probe = usb_serial_probe, |
108 | .disconnect = usb_serial_disconnect, | 92 | .disconnect = usb_serial_disconnect, |
109 | .id_table = id_table, | 93 | .id_table = id_table, |
110 | .no_dynamic_id = 1, | 94 | .no_dynamic_id = 1, |
111 | }; | 95 | }; |
112 | 96 | ||
113 | static struct usb_serial_driver kl5kusb105d_device = { | 97 | static struct usb_serial_driver kl5kusb105d_device = { |
@@ -115,26 +99,23 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
115 | .owner = THIS_MODULE, | 99 | .owner = THIS_MODULE, |
116 | .name = "kl5kusb105d", | 100 | .name = "kl5kusb105d", |
117 | }, | 101 | }, |
118 | .description = "KL5KUSB105D / PalmConnect", | 102 | .description = "KL5KUSB105D / PalmConnect", |
119 | .usb_driver = &kl5kusb105d_driver, | 103 | .usb_driver = &kl5kusb105d_driver, |
120 | .id_table = id_table, | 104 | .id_table = id_table, |
121 | .num_ports = 1, | 105 | .num_ports = 1, |
122 | .open = klsi_105_open, | 106 | .bulk_out_size = 64, |
123 | .close = klsi_105_close, | 107 | .open = klsi_105_open, |
124 | .write = klsi_105_write, | 108 | .close = klsi_105_close, |
125 | .write_bulk_callback = klsi_105_write_bulk_callback, | 109 | .set_termios = klsi_105_set_termios, |
126 | .chars_in_buffer = klsi_105_chars_in_buffer, | 110 | /*.break_ctl = klsi_105_break_ctl,*/ |
127 | .write_room = klsi_105_write_room, | 111 | .tiocmget = klsi_105_tiocmget, |
128 | .read_bulk_callback = klsi_105_read_bulk_callback, | 112 | .tiocmset = klsi_105_tiocmset, |
129 | .set_termios = klsi_105_set_termios, | 113 | .attach = klsi_105_startup, |
130 | /*.break_ctl = klsi_105_break_ctl,*/ | 114 | .release = klsi_105_release, |
131 | .tiocmget = klsi_105_tiocmget, | 115 | .throttle = usb_serial_generic_throttle, |
132 | .tiocmset = klsi_105_tiocmset, | 116 | .unthrottle = usb_serial_generic_unthrottle, |
133 | .attach = klsi_105_startup, | 117 | .process_read_urb = klsi_105_process_read_urb, |
134 | .disconnect = klsi_105_disconnect, | 118 | .prepare_write_buffer = klsi_105_prepare_write_buffer, |
135 | .release = klsi_105_release, | ||
136 | .throttle = klsi_105_throttle, | ||
137 | .unthrottle = klsi_105_unthrottle, | ||
138 | }; | 119 | }; |
139 | 120 | ||
140 | struct klsi_105_port_settings { | 121 | struct klsi_105_port_settings { |
@@ -145,18 +126,11 @@ struct klsi_105_port_settings { | |||
145 | __u8 unknown2; | 126 | __u8 unknown2; |
146 | } __attribute__ ((packed)); | 127 | } __attribute__ ((packed)); |
147 | 128 | ||
148 | /* we implement a pool of NUM_URBS urbs per usb_serial */ | ||
149 | #define NUM_URBS 1 | ||
150 | #define URB_TRANSFER_BUFFER_SIZE 64 | ||
151 | struct klsi_105_private { | 129 | struct klsi_105_private { |
152 | struct klsi_105_port_settings cfg; | 130 | struct klsi_105_port_settings cfg; |
153 | struct ktermios termios; | 131 | struct ktermios termios; |
154 | unsigned long line_state; /* modem line settings */ | 132 | unsigned long line_state; /* modem line settings */ |
155 | /* write pool */ | ||
156 | struct urb *write_urb_pool[NUM_URBS]; | ||
157 | spinlock_t lock; | 133 | spinlock_t lock; |
158 | unsigned long bytes_in; | ||
159 | unsigned long bytes_out; | ||
160 | }; | 134 | }; |
161 | 135 | ||
162 | 136 | ||
@@ -189,7 +163,7 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port, | |||
189 | settings->pktlen, settings->baudrate, settings->databits, | 163 | settings->pktlen, settings->baudrate, settings->databits, |
190 | settings->unknown1, settings->unknown2); | 164 | settings->unknown1, settings->unknown2); |
191 | return rc; | 165 | return rc; |
192 | } /* klsi_105_chg_port_settings */ | 166 | } |
193 | 167 | ||
194 | /* translate a 16-bit status value from the device to linux's TIO bits */ | 168 | /* translate a 16-bit status value from the device to linux's TIO bits */ |
195 | static unsigned long klsi_105_status2linestate(const __u16 status) | 169 | static unsigned long klsi_105_status2linestate(const __u16 status) |
@@ -202,6 +176,7 @@ static unsigned long klsi_105_status2linestate(const __u16 status) | |||
202 | 176 | ||
203 | return res; | 177 | return res; |
204 | } | 178 | } |
179 | |||
205 | /* | 180 | /* |
206 | * Read line control via vendor command and return result through | 181 | * Read line control via vendor command and return result through |
207 | * *line_state_p | 182 | * *line_state_p |
@@ -258,7 +233,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
258 | static int klsi_105_startup(struct usb_serial *serial) | 233 | static int klsi_105_startup(struct usb_serial *serial) |
259 | { | 234 | { |
260 | struct klsi_105_private *priv; | 235 | struct klsi_105_private *priv; |
261 | int i, j; | 236 | int i; |
262 | 237 | ||
263 | /* check if we support the product id (see keyspan.c) | 238 | /* check if we support the product id (see keyspan.c) |
264 | * FIXME | 239 | * FIXME |
@@ -282,29 +257,9 @@ static int klsi_105_startup(struct usb_serial *serial) | |||
282 | 257 | ||
283 | priv->line_state = 0; | 258 | priv->line_state = 0; |
284 | 259 | ||
285 | priv->bytes_in = 0; | ||
286 | priv->bytes_out = 0; | ||
287 | usb_set_serial_port_data(serial->port[i], priv); | 260 | usb_set_serial_port_data(serial->port[i], priv); |
288 | 261 | ||
289 | spin_lock_init(&priv->lock); | 262 | spin_lock_init(&priv->lock); |
290 | for (j = 0; j < NUM_URBS; j++) { | ||
291 | struct urb *urb = usb_alloc_urb(0, GFP_KERNEL); | ||
292 | |||
293 | priv->write_urb_pool[j] = urb; | ||
294 | if (urb == NULL) { | ||
295 | dev_err(&serial->dev->dev, "No more urbs???\n"); | ||
296 | goto err_cleanup; | ||
297 | } | ||
298 | |||
299 | urb->transfer_buffer = | ||
300 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); | ||
301 | if (!urb->transfer_buffer) { | ||
302 | dev_err(&serial->dev->dev, | ||
303 | "%s - out of memory for urb buffers.\n", | ||
304 | __func__); | ||
305 | goto err_cleanup; | ||
306 | } | ||
307 | } | ||
308 | 263 | ||
309 | /* priv->termios is left uninitalized until port opening */ | 264 | /* priv->termios is left uninitalized until port opening */ |
310 | init_waitqueue_head(&serial->port[i]->write_wait); | 265 | init_waitqueue_head(&serial->port[i]->write_wait); |
@@ -315,44 +270,11 @@ static int klsi_105_startup(struct usb_serial *serial) | |||
315 | err_cleanup: | 270 | err_cleanup: |
316 | for (; i >= 0; i--) { | 271 | for (; i >= 0; i--) { |
317 | priv = usb_get_serial_port_data(serial->port[i]); | 272 | priv = usb_get_serial_port_data(serial->port[i]); |
318 | for (j = 0; j < NUM_URBS; j++) { | 273 | kfree(priv); |
319 | if (priv->write_urb_pool[j]) { | ||
320 | kfree(priv->write_urb_pool[j]->transfer_buffer); | ||
321 | usb_free_urb(priv->write_urb_pool[j]); | ||
322 | } | ||
323 | } | ||
324 | usb_set_serial_port_data(serial->port[i], NULL); | 274 | usb_set_serial_port_data(serial->port[i], NULL); |
325 | } | 275 | } |
326 | return -ENOMEM; | 276 | return -ENOMEM; |
327 | } /* klsi_105_startup */ | 277 | } |
328 | |||
329 | |||
330 | static void klsi_105_disconnect(struct usb_serial *serial) | ||
331 | { | ||
332 | int i; | ||
333 | |||
334 | dbg("%s", __func__); | ||
335 | |||
336 | /* stop reads and writes on all ports */ | ||
337 | for (i = 0; i < serial->num_ports; ++i) { | ||
338 | struct klsi_105_private *priv = | ||
339 | usb_get_serial_port_data(serial->port[i]); | ||
340 | |||
341 | if (priv) { | ||
342 | /* kill our write urb pool */ | ||
343 | int j; | ||
344 | struct urb **write_urbs = priv->write_urb_pool; | ||
345 | |||
346 | for (j = 0; j < NUM_URBS; j++) { | ||
347 | if (write_urbs[j]) { | ||
348 | usb_kill_urb(write_urbs[j]); | ||
349 | usb_free_urb(write_urbs[j]); | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | } /* klsi_105_disconnect */ | ||
355 | |||
356 | 278 | ||
357 | static void klsi_105_release(struct usb_serial *serial) | 279 | static void klsi_105_release(struct usb_serial *serial) |
358 | { | 280 | { |
@@ -360,13 +282,9 @@ static void klsi_105_release(struct usb_serial *serial) | |||
360 | 282 | ||
361 | dbg("%s", __func__); | 283 | dbg("%s", __func__); |
362 | 284 | ||
363 | for (i = 0; i < serial->num_ports; ++i) { | 285 | for (i = 0; i < serial->num_ports; ++i) |
364 | struct klsi_105_private *priv = | 286 | kfree(usb_get_serial_port_data(serial->port[i])); |
365 | usb_get_serial_port_data(serial->port[i]); | 287 | } |
366 | |||
367 | kfree(priv); | ||
368 | } | ||
369 | } /* klsi_105_release */ | ||
370 | 288 | ||
371 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | 289 | static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) |
372 | { | 290 | { |
@@ -416,18 +334,8 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
416 | spin_unlock_irqrestore(&priv->lock, flags); | 334 | spin_unlock_irqrestore(&priv->lock, flags); |
417 | 335 | ||
418 | /* READ_ON and urb submission */ | 336 | /* READ_ON and urb submission */ |
419 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 337 | rc = usb_serial_generic_open(tty, port); |
420 | usb_rcvbulkpipe(port->serial->dev, | ||
421 | port->bulk_in_endpointAddress), | ||
422 | port->read_urb->transfer_buffer, | ||
423 | port->read_urb->transfer_buffer_length, | ||
424 | klsi_105_read_bulk_callback, | ||
425 | port); | ||
426 | |||
427 | rc = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
428 | if (rc) { | 338 | if (rc) { |
429 | dev_err(&port->dev, "%s - failed submitting read urb, " | ||
430 | "error %d\n", __func__, rc); | ||
431 | retval = rc; | 339 | retval = rc; |
432 | goto exit; | 340 | goto exit; |
433 | } | 341 | } |
@@ -460,12 +368,10 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
460 | exit: | 368 | exit: |
461 | kfree(cfg); | 369 | kfree(cfg); |
462 | return retval; | 370 | return retval; |
463 | } /* klsi_105_open */ | 371 | } |
464 | |||
465 | 372 | ||
466 | static void klsi_105_close(struct usb_serial_port *port) | 373 | static void klsi_105_close(struct usb_serial_port *port) |
467 | { | 374 | { |
468 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
469 | int rc; | 375 | int rc; |
470 | 376 | ||
471 | dbg("%s port %d", __func__, port->number); | 377 | dbg("%s port %d", __func__, port->number); |
@@ -488,239 +394,62 @@ static void klsi_105_close(struct usb_serial_port *port) | |||
488 | mutex_unlock(&port->serial->disc_mutex); | 394 | mutex_unlock(&port->serial->disc_mutex); |
489 | 395 | ||
490 | /* shutdown our bulk reads and writes */ | 396 | /* shutdown our bulk reads and writes */ |
491 | usb_kill_urb(port->write_urb); | 397 | usb_serial_generic_close(port); |
492 | usb_kill_urb(port->read_urb); | 398 | |
493 | /* unlink our write pool */ | ||
494 | /* FIXME */ | ||
495 | /* wgg - do I need this? I think so. */ | 399 | /* wgg - do I need this? I think so. */ |
496 | usb_kill_urb(port->interrupt_in_urb); | 400 | usb_kill_urb(port->interrupt_in_urb); |
497 | dev_info(&port->serial->dev->dev, | 401 | } |
498 | "port stats: %ld bytes in, %ld bytes out\n", | ||
499 | priv->bytes_in, priv->bytes_out); | ||
500 | } /* klsi_105_close */ | ||
501 | |||
502 | 402 | ||
503 | /* We need to write a complete 64-byte data block and encode the | 403 | /* We need to write a complete 64-byte data block and encode the |
504 | * number actually sent in the first double-byte, LSB-order. That | 404 | * number actually sent in the first double-byte, LSB-order. That |
505 | * leaves at most 62 bytes of payload. | 405 | * leaves at most 62 bytes of payload. |
506 | */ | 406 | */ |
507 | #define KLSI_105_DATA_OFFSET 2 /* in the bulk urb data block */ | 407 | #define KLSI_HDR_LEN 2 |
508 | 408 | static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, | |
509 | 409 | void *dest, size_t size) | |
510 | static int klsi_105_write(struct tty_struct *tty, | ||
511 | struct usb_serial_port *port, const unsigned char *buf, int count) | ||
512 | { | 410 | { |
513 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | 411 | unsigned char *buf = dest; |
514 | int result, size; | 412 | int count; |
515 | int bytes_sent = 0; | ||
516 | |||
517 | dbg("%s - port %d", __func__, port->number); | ||
518 | |||
519 | while (count > 0) { | ||
520 | /* try to find a free urb (write 0 bytes if none) */ | ||
521 | struct urb *urb = NULL; | ||
522 | unsigned long flags; | ||
523 | int i; | ||
524 | /* since the pool is per-port we might not need | ||
525 | the spin lock !? */ | ||
526 | spin_lock_irqsave(&priv->lock, flags); | ||
527 | for (i = 0; i < NUM_URBS; i++) { | ||
528 | if (priv->write_urb_pool[i]->status != -EINPROGRESS) { | ||
529 | urb = priv->write_urb_pool[i]; | ||
530 | dbg("%s - using pool URB %d", __func__, i); | ||
531 | break; | ||
532 | } | ||
533 | } | ||
534 | spin_unlock_irqrestore(&priv->lock, flags); | ||
535 | |||
536 | if (urb == NULL) { | ||
537 | dbg("%s - no more free urbs", __func__); | ||
538 | goto exit; | ||
539 | } | ||
540 | |||
541 | if (urb->transfer_buffer == NULL) { | ||
542 | urb->transfer_buffer = | ||
543 | kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC); | ||
544 | if (urb->transfer_buffer == NULL) { | ||
545 | dev_err(&port->dev, | ||
546 | "%s - no more kernel memory...\n", | ||
547 | __func__); | ||
548 | goto exit; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | size = min(count, port->bulk_out_size - KLSI_105_DATA_OFFSET); | ||
553 | size = min(size, URB_TRANSFER_BUFFER_SIZE - | ||
554 | KLSI_105_DATA_OFFSET); | ||
555 | |||
556 | memcpy(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size); | ||
557 | |||
558 | /* write payload size into transfer buffer */ | ||
559 | ((__u8 *)urb->transfer_buffer)[0] = (__u8) (size & 0xFF); | ||
560 | ((__u8 *)urb->transfer_buffer)[1] = (__u8) ((size & 0xFF00)>>8); | ||
561 | |||
562 | /* set up our urb */ | ||
563 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
564 | usb_sndbulkpipe(port->serial->dev, | ||
565 | port->bulk_out_endpointAddress), | ||
566 | urb->transfer_buffer, | ||
567 | URB_TRANSFER_BUFFER_SIZE, | ||
568 | klsi_105_write_bulk_callback, | ||
569 | port); | ||
570 | |||
571 | /* send the data out the bulk port */ | ||
572 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
573 | if (result) { | ||
574 | dev_err(&port->dev, | ||
575 | "%s - failed submitting write urb, error %d\n", | ||
576 | __func__, result); | ||
577 | goto exit; | ||
578 | } | ||
579 | buf += size; | ||
580 | bytes_sent += size; | ||
581 | count -= size; | ||
582 | } | ||
583 | exit: | ||
584 | /* lockless, but it's for debug info only... */ | ||
585 | priv->bytes_out += bytes_sent; | ||
586 | |||
587 | return bytes_sent; /* that's how much we wrote */ | ||
588 | } /* klsi_105_write */ | ||
589 | |||
590 | static void klsi_105_write_bulk_callback(struct urb *urb) | ||
591 | { | ||
592 | struct usb_serial_port *port = urb->context; | ||
593 | int status = urb->status; | ||
594 | |||
595 | dbg("%s - port %d", __func__, port->number); | ||
596 | |||
597 | if (status) { | ||
598 | dbg("%s - nonzero write bulk status received: %d", __func__, | ||
599 | status); | ||
600 | return; | ||
601 | } | ||
602 | 413 | ||
603 | usb_serial_port_softint(port); | 414 | count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size, |
604 | } /* klsi_105_write_bulk_completion_callback */ | 415 | &port->lock); |
416 | put_unaligned_le16(count, buf); | ||
605 | 417 | ||
606 | 418 | return count + KLSI_HDR_LEN; | |
607 | /* return number of characters currently in the writing process */ | ||
608 | static int klsi_105_chars_in_buffer(struct tty_struct *tty) | ||
609 | { | ||
610 | struct usb_serial_port *port = tty->driver_data; | ||
611 | int chars = 0; | ||
612 | int i; | ||
613 | unsigned long flags; | ||
614 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
615 | |||
616 | spin_lock_irqsave(&priv->lock, flags); | ||
617 | |||
618 | for (i = 0; i < NUM_URBS; ++i) { | ||
619 | if (priv->write_urb_pool[i]->status == -EINPROGRESS) | ||
620 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
621 | } | ||
622 | |||
623 | spin_unlock_irqrestore(&priv->lock, flags); | ||
624 | |||
625 | dbg("%s - returns %d", __func__, chars); | ||
626 | return chars; | ||
627 | } | 419 | } |
628 | 420 | ||
629 | static int klsi_105_write_room(struct tty_struct *tty) | 421 | /* The data received is preceded by a length double-byte in LSB-first order. |
630 | { | 422 | */ |
631 | struct usb_serial_port *port = tty->driver_data; | 423 | static void klsi_105_process_read_urb(struct urb *urb) |
632 | unsigned long flags; | ||
633 | int i; | ||
634 | int room = 0; | ||
635 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
636 | |||
637 | spin_lock_irqsave(&priv->lock, flags); | ||
638 | for (i = 0; i < NUM_URBS; ++i) { | ||
639 | if (priv->write_urb_pool[i]->status != -EINPROGRESS) | ||
640 | room += URB_TRANSFER_BUFFER_SIZE; | ||
641 | } | ||
642 | |||
643 | spin_unlock_irqrestore(&priv->lock, flags); | ||
644 | |||
645 | dbg("%s - returns %d", __func__, room); | ||
646 | return room; | ||
647 | } | ||
648 | |||
649 | |||
650 | |||
651 | static void klsi_105_read_bulk_callback(struct urb *urb) | ||
652 | { | 424 | { |
653 | struct usb_serial_port *port = urb->context; | 425 | struct usb_serial_port *port = urb->context; |
654 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
655 | struct tty_struct *tty; | ||
656 | unsigned char *data = urb->transfer_buffer; | 426 | unsigned char *data = urb->transfer_buffer; |
657 | int rc; | 427 | struct tty_struct *tty; |
658 | int status = urb->status; | 428 | unsigned len; |
659 | 429 | ||
660 | dbg("%s - port %d", __func__, port->number); | 430 | /* empty urbs seem to happen, we ignore them */ |
431 | if (!urb->actual_length) | ||
432 | return; | ||
661 | 433 | ||
662 | /* The urb might have been killed. */ | 434 | if (urb->actual_length <= KLSI_HDR_LEN) { |
663 | if (status) { | 435 | dbg("%s - malformed packet", __func__); |
664 | dbg("%s - nonzero read bulk status received: %d", __func__, | ||
665 | status); | ||
666 | return; | 436 | return; |
667 | } | 437 | } |
668 | 438 | ||
669 | /* The data received is again preceded by a length double-byte in LSB- | 439 | tty = tty_port_tty_get(&port->port); |
670 | * first order (see klsi_105_write() ) | 440 | if (!tty) |
671 | */ | 441 | return; |
672 | if (urb->actual_length == 0) { | ||
673 | /* empty urbs seem to happen, we ignore them */ | ||
674 | /* dbg("%s - emtpy URB", __func__); */ | ||
675 | ; | ||
676 | } else if (urb->actual_length <= 2) { | ||
677 | dbg("%s - size %d URB not understood", __func__, | ||
678 | urb->actual_length); | ||
679 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
680 | urb->actual_length, data); | ||
681 | } else { | ||
682 | int bytes_sent = ((__u8 *) data)[0] + | ||
683 | ((unsigned int) ((__u8 *) data)[1] << 8); | ||
684 | tty = tty_port_tty_get(&port->port); | ||
685 | /* we should immediately resubmit the URB, before attempting | ||
686 | * to pass the data on to the tty layer. But that needs locking | ||
687 | * against re-entry an then mixed-up data because of | ||
688 | * intermixed tty_flip_buffer_push()s | ||
689 | * FIXME | ||
690 | */ | ||
691 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
692 | urb->actual_length, data); | ||
693 | |||
694 | if (bytes_sent + 2 > urb->actual_length) { | ||
695 | dbg("%s - trying to read more data than available" | ||
696 | " (%d vs. %d)", __func__, | ||
697 | bytes_sent+2, urb->actual_length); | ||
698 | /* cap at implied limit */ | ||
699 | bytes_sent = urb->actual_length - 2; | ||
700 | } | ||
701 | |||
702 | tty_insert_flip_string(tty, data + 2, bytes_sent); | ||
703 | tty_flip_buffer_push(tty); | ||
704 | tty_kref_put(tty); | ||
705 | 442 | ||
706 | /* again lockless, but debug info only */ | 443 | len = get_unaligned_le16(data); |
707 | priv->bytes_in += bytes_sent; | 444 | if (len > urb->actual_length - KLSI_HDR_LEN) { |
445 | dbg("%s - packet length mismatch", __func__); | ||
446 | len = urb->actual_length - KLSI_HDR_LEN; | ||
708 | } | 447 | } |
709 | /* Continue trying to always read */ | ||
710 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
711 | usb_rcvbulkpipe(port->serial->dev, | ||
712 | port->bulk_in_endpointAddress), | ||
713 | port->read_urb->transfer_buffer, | ||
714 | port->read_urb->transfer_buffer_length, | ||
715 | klsi_105_read_bulk_callback, | ||
716 | port); | ||
717 | rc = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
718 | if (rc) | ||
719 | dev_err(&port->dev, | ||
720 | "%s - failed resubmitting read urb, error %d\n", | ||
721 | __func__, rc); | ||
722 | } /* klsi_105_read_bulk_callback */ | ||
723 | 448 | ||
449 | tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len); | ||
450 | tty_flip_buffer_push(tty); | ||
451 | tty_kref_put(tty); | ||
452 | } | ||
724 | 453 | ||
725 | static void klsi_105_set_termios(struct tty_struct *tty, | 454 | static void klsi_105_set_termios(struct tty_struct *tty, |
726 | struct usb_serial_port *port, | 455 | struct usb_serial_port *port, |
@@ -887,8 +616,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
887 | klsi_105_chg_port_settings(port, cfg); | 616 | klsi_105_chg_port_settings(port, cfg); |
888 | err: | 617 | err: |
889 | kfree(cfg); | 618 | kfree(cfg); |
890 | } /* klsi_105_set_termios */ | 619 | } |
891 | |||
892 | 620 | ||
893 | #if 0 | 621 | #if 0 |
894 | static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) | 622 | static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) |
@@ -906,7 +634,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) | |||
906 | lcr |= MCT_U232_SET_BREAK; | 634 | lcr |= MCT_U232_SET_BREAK; |
907 | 635 | ||
908 | mct_u232_set_line_ctrl(serial, lcr); | 636 | mct_u232_set_line_ctrl(serial, lcr); |
909 | } /* mct_u232_break_ctl */ | 637 | } |
910 | #endif | 638 | #endif |
911 | 639 | ||
912 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file) | 640 | static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file) |
@@ -962,29 +690,6 @@ static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, | |||
962 | return retval; | 690 | return retval; |
963 | } | 691 | } |
964 | 692 | ||
965 | static void klsi_105_throttle(struct tty_struct *tty) | ||
966 | { | ||
967 | struct usb_serial_port *port = tty->driver_data; | ||
968 | dbg("%s - port %d", __func__, port->number); | ||
969 | usb_kill_urb(port->read_urb); | ||
970 | } | ||
971 | |||
972 | static void klsi_105_unthrottle(struct tty_struct *tty) | ||
973 | { | ||
974 | struct usb_serial_port *port = tty->driver_data; | ||
975 | int result; | ||
976 | |||
977 | dbg("%s - port %d", __func__, port->number); | ||
978 | |||
979 | port->read_urb->dev = port->serial->dev; | ||
980 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
981 | if (result) | ||
982 | dev_err(&port->dev, | ||
983 | "%s - failed submitting read urb, error %d\n", | ||
984 | __func__, result); | ||
985 | } | ||
986 | |||
987 | |||
988 | 693 | ||
989 | static int __init klsi_105_init(void) | 694 | static int __init klsi_105_init(void) |
990 | { | 695 | { |
@@ -1005,7 +710,6 @@ failed_usb_serial_register: | |||
1005 | return retval; | 710 | return retval; |
1006 | } | 711 | } |
1007 | 712 | ||
1008 | |||
1009 | static void __exit klsi_105_exit(void) | 713 | static void __exit klsi_105_exit(void) |
1010 | { | 714 | { |
1011 | usb_deregister(&kl5kusb105d_driver); | 715 | usb_deregister(&kl5kusb105d_driver); |
@@ -1023,5 +727,3 @@ MODULE_LICENSE("GPL"); | |||
1023 | 727 | ||
1024 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 728 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
1025 | MODULE_PARM_DESC(debug, "enable extensive debugging messages"); | 729 | MODULE_PARM_DESC(debug, "enable extensive debugging messages"); |
1026 | |||
1027 | /* vim: set sts=8 ts=8 sw=8: */ | ||
diff --git a/drivers/usb/serial/kl5kusb105.h b/drivers/usb/serial/kl5kusb105.h index 1231d9e78398..22a90badc86b 100644 --- a/drivers/usb/serial/kl5kusb105.h +++ b/drivers/usb/serial/kl5kusb105.h | |||
@@ -17,16 +17,16 @@ | |||
17 | /* baud rates */ | 17 | /* baud rates */ |
18 | 18 | ||
19 | enum { | 19 | enum { |
20 | kl5kusb105a_sio_b115200 = 0, | 20 | kl5kusb105a_sio_b115200 = 0, |
21 | kl5kusb105a_sio_b57600 = 1, | 21 | kl5kusb105a_sio_b57600 = 1, |
22 | kl5kusb105a_sio_b38400 = 2, | 22 | kl5kusb105a_sio_b38400 = 2, |
23 | kl5kusb105a_sio_b19200 = 4, | 23 | kl5kusb105a_sio_b19200 = 4, |
24 | kl5kusb105a_sio_b14400 = 5, | 24 | kl5kusb105a_sio_b14400 = 5, |
25 | kl5kusb105a_sio_b9600 = 6, | 25 | kl5kusb105a_sio_b9600 = 6, |
26 | kl5kusb105a_sio_b4800 = 8, /* unchecked */ | 26 | kl5kusb105a_sio_b4800 = 8, /* unchecked */ |
27 | kl5kusb105a_sio_b2400 = 9, /* unchecked */ | 27 | kl5kusb105a_sio_b2400 = 9, /* unchecked */ |
28 | kl5kusb105a_sio_b1200 = 0xa, /* unchecked */ | 28 | kl5kusb105a_sio_b1200 = 0xa, /* unchecked */ |
29 | kl5kusb105a_sio_b600 = 0xb /* unchecked */ | 29 | kl5kusb105a_sio_b600 = 0xb /* unchecked */ |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* data bits */ | 32 | /* data bits */ |
@@ -53,17 +53,16 @@ enum { | |||
53 | #define KL5KUSB105A_CTS ((1<<5) | (1<<4)) | 53 | #define KL5KUSB105A_CTS ((1<<5) | (1<<4)) |
54 | 54 | ||
55 | #define KL5KUSB105A_WANTS_TO_SEND 0x30 | 55 | #define KL5KUSB105A_WANTS_TO_SEND 0x30 |
56 | //#define KL5KUSB105A_DTR /* Data Terminal Ready */ | 56 | #if 0 |
57 | //#define KL5KUSB105A_CTS /* Clear To Send */ | 57 | #define KL5KUSB105A_DTR /* Data Terminal Ready */ |
58 | //#define KL5KUSB105A_CD /* Carrier Detect */ | 58 | #define KL5KUSB105A_CTS /* Clear To Send */ |
59 | //#define KL5KUSB105A_DSR /* Data Set Ready */ | 59 | #define KL5KUSB105A_CD /* Carrier Detect */ |
60 | //#define KL5KUSB105A_RxD /* Receive pin */ | 60 | #define KL5KUSB105A_DSR /* Data Set Ready */ |
61 | 61 | #define KL5KUSB105A_RxD /* Receive pin */ | |
62 | //#define KL5KUSB105A_LE | 62 | |
63 | //#define KL5KUSB105A_RTS | 63 | #define KL5KUSB105A_LE |
64 | //#define KL5KUSB105A_ST | 64 | #define KL5KUSB105A_RTS |
65 | //#define KL5KUSB105A_SR | 65 | #define KL5KUSB105A_ST |
66 | //#define KL5KUSB105A_RI /* Ring Indicator */ | 66 | #define KL5KUSB105A_SR |
67 | 67 | #define KL5KUSB105A_RI /* Ring Indicator */ | |
68 | /* vim: set ts=8 sts=8: */ | 68 | #endif |
69 | |||
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index c113a2a0e10c..bd5bd8589e04 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -345,7 +345,8 @@ static void kobil_close(struct usb_serial_port *port) | |||
345 | 345 | ||
346 | /* FIXME: Add rts/dtr methods */ | 346 | /* FIXME: Add rts/dtr methods */ |
347 | if (port->write_urb) { | 347 | if (port->write_urb) { |
348 | usb_kill_urb(port->write_urb); | 348 | usb_poison_urb(port->write_urb); |
349 | kfree(port->write_urb->transfer_buffer); | ||
349 | usb_free_urb(port->write_urb); | 350 | usb_free_urb(port->write_urb); |
350 | port->write_urb = NULL; | 351 | port->write_urb = NULL; |
351 | } | 352 | } |
diff --git a/drivers/usb/serial/kobil_sct.h b/drivers/usb/serial/kobil_sct.h index a51fbb5ae45c..be207f7156fe 100644 --- a/drivers/usb/serial/kobil_sct.h +++ b/drivers/usb/serial/kobil_sct.h | |||
@@ -23,38 +23,55 @@ | |||
23 | #define SUSBCR_SSL_SETDTR 0x0004 | 23 | #define SUSBCR_SSL_SETDTR 0x0004 |
24 | #define SUSBCR_SSL_CLRDTR 0x0010 | 24 | #define SUSBCR_SSL_CLRDTR 0x0010 |
25 | 25 | ||
26 | #define SUSBCR_SSL_PURGE_TXABORT 0x0100 // Kill the pending/current writes to the comm port. | 26 | /* Kill the pending/current writes to the comm port. */ |
27 | #define SUSBCR_SSL_PURGE_RXABORT 0x0200 // Kill the pending/current reads to the comm port. | 27 | #define SUSBCR_SSL_PURGE_TXABORT 0x0100 |
28 | #define SUSBCR_SSL_PURGE_TXCLEAR 0x0400 // Kill the transmit queue if there. | 28 | /* Kill the pending/current reads to the comm port. */ |
29 | #define SUSBCR_SSL_PURGE_RXCLEAR 0x0800 // Kill the typeahead buffer if there. | 29 | #define SUSBCR_SSL_PURGE_RXABORT 0x0200 |
30 | /* Kill the transmit queue if there. */ | ||
31 | #define SUSBCR_SSL_PURGE_TXCLEAR 0x0400 | ||
32 | /* Kill the typeahead buffer if there. */ | ||
33 | #define SUSBCR_SSL_PURGE_RXCLEAR 0x0800 | ||
30 | 34 | ||
31 | #define SUSBCRequest_GetStatusLineState 4 | 35 | #define SUSBCRequest_GetStatusLineState 4 |
32 | #define SUSBCR_GSL_RXCHAR 0x0001 // Any Character received | 36 | /* Any Character received */ |
33 | #define SUSBCR_GSL_TXEMPTY 0x0004 // Transmitt Queue Empty | 37 | #define SUSBCR_GSL_RXCHAR 0x0001 |
34 | #define SUSBCR_GSL_CTS 0x0008 // CTS changed state | 38 | /* Transmitt Queue Empty */ |
35 | #define SUSBCR_GSL_DSR 0x0010 // DSR changed state | 39 | #define SUSBCR_GSL_TXEMPTY 0x0004 |
36 | #define SUSBCR_GSL_RLSD 0x0020 // RLSD changed state | 40 | /* CTS changed state */ |
37 | #define SUSBCR_GSL_BREAK 0x0040 // BREAK received | 41 | #define SUSBCR_GSL_CTS 0x0008 |
38 | #define SUSBCR_GSL_ERR 0x0080 // Line status error occurred | 42 | /* DSR changed state */ |
39 | #define SUSBCR_GSL_RING 0x0100 // Ring signal detected | 43 | #define SUSBCR_GSL_DSR 0x0010 |
44 | /* RLSD changed state */ | ||
45 | #define SUSBCR_GSL_RLSD 0x0020 | ||
46 | /* BREAK received */ | ||
47 | #define SUSBCR_GSL_BREAK 0x0040 | ||
48 | /* Line status error occurred */ | ||
49 | #define SUSBCR_GSL_ERR 0x0080 | ||
50 | /* Ring signal detected */ | ||
51 | #define SUSBCR_GSL_RING 0x0100 | ||
40 | 52 | ||
41 | #define SUSBCRequest_Misc 8 | 53 | #define SUSBCRequest_Misc 8 |
42 | #define SUSBCR_MSC_ResetReader 0x0001 // use a predefined reset sequence | 54 | /* use a predefined reset sequence */ |
43 | #define SUSBCR_MSC_ResetAllQueues 0x0002 // use a predefined sequence to reset the internal queues | 55 | #define SUSBCR_MSC_ResetReader 0x0001 |
56 | /* use a predefined sequence to reset the internal queues */ | ||
57 | #define SUSBCR_MSC_ResetAllQueues 0x0002 | ||
44 | 58 | ||
45 | #define SUSBCRequest_GetMisc 0x10 | 59 | #define SUSBCRequest_GetMisc 0x10 |
46 | #define SUSBCR_MSC_GetFWVersion 0x0001 /* get the firmware version from device, | 60 | |
47 | coded like this 0xHHLLBBPP | 61 | /* |
48 | with HH = Firmware Version High Byte | 62 | * get the firmware version from device, coded like this 0xHHLLBBPP with |
49 | LL = Firmware Version Low Byte | 63 | * HH = Firmware Version High Byte |
50 | BB = Build Number | 64 | * LL = Firmware Version Low Byte |
51 | PP = Further Attributes | 65 | * BB = Build Number |
52 | */ | 66 | * PP = Further Attributes |
53 | 67 | */ | |
54 | #define SUSBCR_MSC_GetHWVersion 0x0002 /* get the hardware version from device | 68 | #define SUSBCR_MSC_GetFWVersion 0x0001 |
55 | coded like this 0xHHLLPPRR | 69 | |
56 | with HH = Software Version High Byte | 70 | /* |
57 | LL = Software Version Low Byte | 71 | * get the hardware version from device coded like this 0xHHLLPPRR with |
58 | PP = Further Attributes | 72 | * HH = Software Version High Byte |
59 | RR = Reserved for the hardware ID | 73 | * LL = Software Version Low Byte |
60 | */ | 74 | * PP = Further Attributes |
75 | * RR = Reserved for the hardware ID | ||
76 | */ | ||
77 | #define SUSBCR_MSC_GetHWVersion 0x0002 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2849f8c32015..7aa01b95b1d4 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -549,12 +549,9 @@ static void mct_u232_close(struct usb_serial_port *port) | |||
549 | { | 549 | { |
550 | dbg("%s port %d", __func__, port->number); | 550 | dbg("%s port %d", __func__, port->number); |
551 | 551 | ||
552 | if (port->serial->dev) { | 552 | usb_serial_generic_close(port); |
553 | /* shutdown our urbs */ | 553 | if (port->serial->dev) |
554 | usb_kill_urb(port->write_urb); | ||
555 | usb_kill_urb(port->read_urb); | ||
556 | usb_kill_urb(port->interrupt_in_urb); | 554 | usb_kill_urb(port->interrupt_in_urb); |
557 | } | ||
558 | } /* mct_u232_close */ | 555 | } /* mct_u232_close */ |
559 | 556 | ||
560 | 557 | ||
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index 7417d5ce1e23..3a3f5e6b8f96 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h | |||
@@ -42,36 +42,44 @@ | |||
42 | #define MCT_U232_SET_REQUEST_TYPE 0x40 | 42 | #define MCT_U232_SET_REQUEST_TYPE 0x40 |
43 | #define MCT_U232_GET_REQUEST_TYPE 0xc0 | 43 | #define MCT_U232_GET_REQUEST_TYPE 0xc0 |
44 | 44 | ||
45 | #define MCT_U232_GET_MODEM_STAT_REQUEST 2 /* Get Modem Status Register (MSR) */ | 45 | /* Get Modem Status Register (MSR) */ |
46 | #define MCT_U232_GET_MODEM_STAT_SIZE 1 | 46 | #define MCT_U232_GET_MODEM_STAT_REQUEST 2 |
47 | #define MCT_U232_GET_MODEM_STAT_SIZE 1 | ||
47 | 48 | ||
48 | #define MCT_U232_GET_LINE_CTRL_REQUEST 6 /* Get Line Control Register (LCR) */ | 49 | /* Get Line Control Register (LCR) */ |
49 | #define MCT_U232_GET_LINE_CTRL_SIZE 1 /* ... not used by this driver */ | 50 | /* ... not used by this driver */ |
51 | #define MCT_U232_GET_LINE_CTRL_REQUEST 6 | ||
52 | #define MCT_U232_GET_LINE_CTRL_SIZE 1 | ||
50 | 53 | ||
51 | #define MCT_U232_SET_BAUD_RATE_REQUEST 5 /* Set Baud Rate Divisor */ | 54 | /* Set Baud Rate Divisor */ |
52 | #define MCT_U232_SET_BAUD_RATE_SIZE 4 | 55 | #define MCT_U232_SET_BAUD_RATE_REQUEST 5 |
56 | #define MCT_U232_SET_BAUD_RATE_SIZE 4 | ||
53 | 57 | ||
54 | #define MCT_U232_SET_LINE_CTRL_REQUEST 7 /* Set Line Control Register (LCR) */ | 58 | /* Set Line Control Register (LCR) */ |
55 | #define MCT_U232_SET_LINE_CTRL_SIZE 1 | 59 | #define MCT_U232_SET_LINE_CTRL_REQUEST 7 |
60 | #define MCT_U232_SET_LINE_CTRL_SIZE 1 | ||
56 | 61 | ||
57 | #define MCT_U232_SET_MODEM_CTRL_REQUEST 10 /* Set Modem Control Register (MCR) */ | 62 | /* Set Modem Control Register (MCR) */ |
58 | #define MCT_U232_SET_MODEM_CTRL_SIZE 1 | 63 | #define MCT_U232_SET_MODEM_CTRL_REQUEST 10 |
64 | #define MCT_U232_SET_MODEM_CTRL_SIZE 1 | ||
59 | 65 | ||
60 | /* This USB device request code is not well understood. It is transmitted by | 66 | /* |
61 | the MCT-supplied Windows driver whenever the baud rate changes. | 67 | * This USB device request code is not well understood. It is transmitted by |
62 | */ | 68 | * the MCT-supplied Windows driver whenever the baud rate changes. |
63 | #define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */ | 69 | */ |
64 | #define MCT_U232_SET_UNKNOWN1_SIZE 1 | 70 | #define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */ |
71 | #define MCT_U232_SET_UNKNOWN1_SIZE 1 | ||
65 | 72 | ||
66 | /* This USB device request code appears to control whether CTS is required | 73 | /* |
67 | during transmission. | 74 | * This USB device request code appears to control whether CTS is required |
68 | 75 | * during transmission. | |
69 | Sending a zero byte allows data transmission to a device which is not | 76 | * |
70 | asserting CTS. Sending a '1' byte will cause transmission to be deferred | 77 | * Sending a zero byte allows data transmission to a device which is not |
71 | until the device asserts CTS. | 78 | * asserting CTS. Sending a '1' byte will cause transmission to be deferred |
72 | */ | 79 | * until the device asserts CTS. |
73 | #define MCT_U232_SET_CTS_REQUEST 12 | 80 | */ |
74 | #define MCT_U232_SET_CTS_SIZE 1 | 81 | #define MCT_U232_SET_CTS_REQUEST 12 |
82 | #define MCT_U232_SET_CTS_SIZE 1 | ||
75 | 83 | ||
76 | #define MCT_U232_MAX_SIZE 4 /* of MCT_XXX_SIZE */ | 84 | #define MCT_U232_MAX_SIZE 4 /* of MCT_XXX_SIZE */ |
77 | 85 | ||
@@ -81,7 +89,8 @@ | |||
81 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. | 89 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. |
82 | * This is pointless to document in the header, see the code for the bits. | 90 | * This is pointless to document in the header, see the code for the bits. |
83 | */ | 91 | */ |
84 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result); | 92 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, |
93 | speed_t value, speed_t *result); | ||
85 | 94 | ||
86 | /* | 95 | /* |
87 | * Line Control Register (LCR) | 96 | * Line Control Register (LCR) |
@@ -125,16 +134,16 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
125 | /* | 134 | /* |
126 | * Line Status Register (LSR) | 135 | * Line Status Register (LSR) |
127 | */ | 136 | */ |
128 | #define MCT_U232_LSR_INDEX 1 /* data[index] */ | 137 | #define MCT_U232_LSR_INDEX 1 /* data[index] */ |
129 | #define MCT_U232_LSR_ERR 0x80 /* OE | PE | FE | BI */ | 138 | #define MCT_U232_LSR_ERR 0x80 /* OE | PE | FE | BI */ |
130 | #define MCT_U232_LSR_TEMT 0x40 /* transmit register empty */ | 139 | #define MCT_U232_LSR_TEMT 0x40 /* transmit register empty */ |
131 | #define MCT_U232_LSR_THRE 0x20 /* transmit holding register empty */ | 140 | #define MCT_U232_LSR_THRE 0x20 /* transmit holding register empty */ |
132 | #define MCT_U232_LSR_BI 0x10 /* break indicator */ | 141 | #define MCT_U232_LSR_BI 0x10 /* break indicator */ |
133 | #define MCT_U232_LSR_FE 0x08 /* framing error */ | 142 | #define MCT_U232_LSR_FE 0x08 /* framing error */ |
134 | #define MCT_U232_LSR_OE 0x02 /* overrun error */ | 143 | #define MCT_U232_LSR_OE 0x02 /* overrun error */ |
135 | #define MCT_U232_LSR_PE 0x04 /* parity error */ | 144 | #define MCT_U232_LSR_PE 0x04 /* parity error */ |
136 | #define MCT_U232_LSR_OE 0x02 /* overrun error */ | 145 | #define MCT_U232_LSR_OE 0x02 /* overrun error */ |
137 | #define MCT_U232_LSR_DR 0x01 /* receive data ready */ | 146 | #define MCT_U232_LSR_DR 0x01 /* receive data ready */ |
138 | 147 | ||
139 | 148 | ||
140 | /* ----------------------------------------------------------------------------- | 149 | /* ----------------------------------------------------------------------------- |
@@ -143,10 +152,10 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
143 | * | 152 | * |
144 | * The technical details of the device have been acquired be using "SniffUSB" | 153 | * The technical details of the device have been acquired be using "SniffUSB" |
145 | * and the vendor-supplied device driver (version 2.3A) under Windows98. To | 154 | * and the vendor-supplied device driver (version 2.3A) under Windows98. To |
146 | * identify the USB vendor-specific requests and to assign them to terminal | 155 | * identify the USB vendor-specific requests and to assign them to terminal |
147 | * settings (flow control, baud rate, etc.) the program "SerialSettings" from | 156 | * settings (flow control, baud rate, etc.) the program "SerialSettings" from |
148 | * William G. Greathouse has been proven to be very useful. I also used the | 157 | * William G. Greathouse has been proven to be very useful. I also used the |
149 | * Win98 "HyperTerminal" and "usb-robot" on Linux for testing. The results and | 158 | * Win98 "HyperTerminal" and "usb-robot" on Linux for testing. The results and |
150 | * observations are summarized below: | 159 | * observations are summarized below: |
151 | * | 160 | * |
152 | * The USB requests seem to be directly mapped to the registers of a 8250, | 161 | * The USB requests seem to be directly mapped to the registers of a 8250, |
@@ -186,33 +195,33 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
186 | * Data: LCR (see below) | 195 | * Data: LCR (see below) |
187 | * | 196 | * |
188 | * Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data | 197 | * Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data |
189 | * transmit/receive register (THR/RBR) and the Interrupt Enable Register | 198 | * transmit/receive register (THR/RBR) and the Interrupt Enable Register |
190 | * (IER) is disabled. Any access to these ports is now redirected to the | 199 | * (IER) is disabled. Any access to these ports is now redirected to the |
191 | * Divisor Latch Registers. Setting this bit, loading the Divisor | 200 | * Divisor Latch Registers. Setting this bit, loading the Divisor |
192 | * Registers, and clearing DLAB should be done with interrupts disabled. | 201 | * Registers, and clearing DLAB should be done with interrupts disabled. |
193 | * Bit 6: Set Break. When set to "1", the transmitter begins to transmit | 202 | * Bit 6: Set Break. When set to "1", the transmitter begins to transmit |
194 | * continuous Spacing until this bit is set to "0". This overrides any | 203 | * continuous Spacing until this bit is set to "0". This overrides any |
195 | * bits of characters that are being transmitted. | 204 | * bits of characters that are being transmitted. |
196 | * Bit 5: Stick Parity. When parity is enabled, setting this bit causes parity | 205 | * Bit 5: Stick Parity. When parity is enabled, setting this bit causes parity |
197 | * to always be "1" or "0", based on the value of Bit 4. | 206 | * to always be "1" or "0", based on the value of Bit 4. |
198 | * Bit 4: Even Parity Select (EPS). When parity is enabled and Bit 5 is "0", | 207 | * Bit 4: Even Parity Select (EPS). When parity is enabled and Bit 5 is "0", |
199 | * setting this bit causes even parity to be transmitted and expected. | 208 | * setting this bit causes even parity to be transmitted and expected. |
200 | * Otherwise, odd parity is used. | 209 | * Otherwise, odd parity is used. |
201 | * Bit 3: Parity Enable (PEN). When set to "1", a parity bit is inserted | 210 | * Bit 3: Parity Enable (PEN). When set to "1", a parity bit is inserted |
202 | * between the last bit of the data and the Stop Bit. The UART will also | 211 | * between the last bit of the data and the Stop Bit. The UART will also |
203 | * expect parity to be present in the received data. | 212 | * expect parity to be present in the received data. |
204 | * Bit 2: Number of Stop Bits (STB). If set to "1" and using 5-bit data words, | 213 | * Bit 2: Number of Stop Bits (STB). If set to "1" and using 5-bit data words, |
205 | * 1.5 Stop Bits are transmitted and expected in each data word. For | 214 | * 1.5 Stop Bits are transmitted and expected in each data word. For |
206 | * 6, 7 and 8-bit data words, 2 Stop Bits are transmitted and expected. | 215 | * 6, 7 and 8-bit data words, 2 Stop Bits are transmitted and expected. |
207 | * When this bit is set to "0", one Stop Bit is used on each data word. | 216 | * When this bit is set to "0", one Stop Bit is used on each data word. |
208 | * Bit 1: Word Length Select Bit #1 (WLSB1) | 217 | * Bit 1: Word Length Select Bit #1 (WLSB1) |
209 | * Bit 0: Word Length Select Bit #0 (WLSB0) | 218 | * Bit 0: Word Length Select Bit #0 (WLSB0) |
210 | * Together these bits specify the number of bits in each data word. | 219 | * Together these bits specify the number of bits in each data word. |
211 | * 1 0 Word Length | 220 | * 1 0 Word Length |
212 | * 0 0 5 Data Bits | 221 | * 0 0 5 Data Bits |
213 | * 0 1 6 Data Bits | 222 | * 0 1 6 Data Bits |
214 | * 1 0 7 Data Bits | 223 | * 1 0 7 Data Bits |
215 | * 1 1 8 Data Bits | 224 | * 1 1 8 Data Bits |
216 | * | 225 | * |
217 | * SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs | 226 | * SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs |
218 | * in the Win98 driver: the break does not work (bit 6 is not asserted) and the | 227 | * in the Win98 driver: the break does not work (bit 6 is not asserted) and the |
@@ -234,20 +243,20 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
234 | * Bit 6: Reserved, always 0. | 243 | * Bit 6: Reserved, always 0. |
235 | * Bit 5: Reserved, always 0. | 244 | * Bit 5: Reserved, always 0. |
236 | * Bit 4: Loop-Back Enable. When set to "1", the UART transmitter and receiver | 245 | * Bit 4: Loop-Back Enable. When set to "1", the UART transmitter and receiver |
237 | * are internally connected together to allow diagnostic operations. In | 246 | * are internally connected together to allow diagnostic operations. In |
238 | * addition, the UART modem control outputs are connected to the UART | 247 | * addition, the UART modem control outputs are connected to the UART |
239 | * modem control inputs. CTS is connected to RTS, DTR is connected to | 248 | * modem control inputs. CTS is connected to RTS, DTR is connected to |
240 | * DSR, OUT1 is connected to RI, and OUT 2 is connected to DCD. | 249 | * DSR, OUT1 is connected to RI, and OUT 2 is connected to DCD. |
241 | * Bit 3: OUT 2. An auxiliary output that the host processor may set high or | 250 | * Bit 3: OUT 2. An auxiliary output that the host processor may set high or |
242 | * low. In the IBM PC serial adapter (and most clones), OUT 2 is used | 251 | * low. In the IBM PC serial adapter (and most clones), OUT 2 is used |
243 | * to tri-state (disable) the interrupt signal from the | 252 | * to tri-state (disable) the interrupt signal from the |
244 | * 8250/16450/16550 UART. | 253 | * 8250/16450/16550 UART. |
245 | * Bit 2: OUT 1. An auxiliary output that the host processor may set high or | 254 | * Bit 2: OUT 1. An auxiliary output that the host processor may set high or |
246 | * low. This output is not used on the IBM PC serial adapter. | 255 | * low. This output is not used on the IBM PC serial adapter. |
247 | * Bit 1: Request to Send (RTS). When set to "1", the output of the UART -RTS | 256 | * Bit 1: Request to Send (RTS). When set to "1", the output of the UART -RTS |
248 | * line is Low (Active). | 257 | * line is Low (Active). |
249 | * Bit 0: Data Terminal Ready (DTR). When set to "1", the output of the UART | 258 | * Bit 0: Data Terminal Ready (DTR). When set to "1", the output of the UART |
250 | * -DTR line is Low (Active). | 259 | * -DTR line is Low (Active). |
251 | * | 260 | * |
252 | * SniffUSB observations: Bit 2 and 4 seem not to be used but bit 3 has been | 261 | * SniffUSB observations: Bit 2 and 4 seem not to be used but bit 3 has been |
253 | * seen _always_ set. | 262 | * seen _always_ set. |
@@ -264,22 +273,22 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
264 | * Data: MSR (see below) | 273 | * Data: MSR (see below) |
265 | * | 274 | * |
266 | * Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the | 275 | * Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the |
267 | * UART. | 276 | * UART. |
268 | * Bit 6: Ring Indicator (RI). Reflects the state of the RI line on the UART. | 277 | * Bit 6: Ring Indicator (RI). Reflects the state of the RI line on the UART. |
269 | * Bit 5: Data Set Ready (DSR). Reflects the state of the DSR line on the UART. | 278 | * Bit 5: Data Set Ready (DSR). Reflects the state of the DSR line on the UART. |
270 | * Bit 4: Clear To Send (CTS). Reflects the state of the CTS line on the UART. | 279 | * Bit 4: Clear To Send (CTS). Reflects the state of the CTS line on the UART. |
271 | * Bit 3: Delta Data Carrier Detect (DDCD). Set to "1" if the -DCD line has | 280 | * Bit 3: Delta Data Carrier Detect (DDCD). Set to "1" if the -DCD line has |
272 | * changed state one more more times since the last time the MSR was | 281 | * changed state one more more times since the last time the MSR was |
273 | * read by the host. | 282 | * read by the host. |
274 | * Bit 2: Trailing Edge Ring Indicator (TERI). Set to "1" if the -RI line has | 283 | * Bit 2: Trailing Edge Ring Indicator (TERI). Set to "1" if the -RI line has |
275 | * had a low to high transition since the last time the MSR was read by | 284 | * had a low to high transition since the last time the MSR was read by |
276 | * the host. | 285 | * the host. |
277 | * Bit 1: Delta Data Set Ready (DDSR). Set to "1" if the -DSR line has changed | 286 | * Bit 1: Delta Data Set Ready (DDSR). Set to "1" if the -DSR line has changed |
278 | * state one more more times since the last time the MSR was read by the | 287 | * state one more more times since the last time the MSR was read by the |
279 | * host. | 288 | * host. |
280 | * Bit 0: Delta Clear To Send (DCTS). Set to "1" if the -CTS line has changed | 289 | * Bit 0: Delta Clear To Send (DCTS). Set to "1" if the -CTS line has changed |
281 | * state one more times since the last time the MSR was read by the | 290 | * state one more times since the last time the MSR was read by the |
282 | * host. | 291 | * host. |
283 | * | 292 | * |
284 | * SniffUSB observations: the MSR is also returned as first byte on the | 293 | * SniffUSB observations: the MSR is also returned as first byte on the |
285 | * interrupt-in endpoint 0x83 to signal changes of modem status lines. The USB | 294 | * interrupt-in endpoint 0x83 to signal changes of modem status lines. The USB |
@@ -290,31 +299,34 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
290 | * -------------------------- | 299 | * -------------------------- |
291 | * | 300 | * |
292 | * Bit 7 Error in Receiver FIFO. On the 8250/16450 UART, this bit is zero. | 301 | * Bit 7 Error in Receiver FIFO. On the 8250/16450 UART, this bit is zero. |
293 | * This bit is set to "1" when any of the bytes in the FIFO have one or | 302 | * This bit is set to "1" when any of the bytes in the FIFO have one |
294 | * more of the following error conditions: PE, FE, or BI. | 303 | * or more of the following error conditions: PE, FE, or BI. |
295 | * Bit 6 Transmitter Empty (TEMT). When set to "1", there are no words | 304 | * Bit 6 Transmitter Empty (TEMT). When set to "1", there are no words |
296 | * remaining in the transmit FIFO or the transmit shift register. The | 305 | * remaining in the transmit FIFO or the transmit shift register. The |
297 | * transmitter is completely idle. | 306 | * transmitter is completely idle. |
298 | * Bit 5 Transmitter Holding Register Empty (THRE). When set to "1", the FIFO | 307 | * Bit 5 Transmitter Holding Register Empty (THRE). When set to "1", the |
299 | * (or holding register) now has room for at least one additional word | 308 | * FIFO (or holding register) now has room for at least one additional |
300 | * to transmit. The transmitter may still be transmitting when this bit | 309 | * word to transmit. The transmitter may still be transmitting when |
301 | * is set to "1". | 310 | * this bit is set to "1". |
302 | * Bit 4 Break Interrupt (BI). The receiver has detected a Break signal. | 311 | * Bit 4 Break Interrupt (BI). The receiver has detected a Break signal. |
303 | * Bit 3 Framing Error (FE). A Start Bit was detected but the Stop Bit did not | 312 | * Bit 3 Framing Error (FE). A Start Bit was detected but the Stop Bit did |
304 | * appear at the expected time. The received word is probably garbled. | 313 | * not appear at the expected time. The received word is probably |
305 | * Bit 2 Parity Error (PE). The parity bit was incorrect for the word received. | 314 | * garbled. |
306 | * Bit 1 Overrun Error (OE). A new word was received and there was no room in | 315 | * Bit 2 Parity Error (PE). The parity bit was incorrect for the word |
307 | * the receive buffer. The newly-arrived word in the shift register is | 316 | * received. |
308 | * discarded. On 8250/16450 UARTs, the word in the holding register is | 317 | * Bit 1 Overrun Error (OE). A new word was received and there was no room |
309 | * discarded and the newly- arrived word is put in the holding register. | 318 | * in the receive buffer. The newly-arrived word in the shift register |
319 | * is discarded. On 8250/16450 UARTs, the word in the holding register | ||
320 | * is discarded and the newly- arrived word is put in the holding | ||
321 | * register. | ||
310 | * Bit 0 Data Ready (DR). One or more words are in the receive FIFO that the | 322 | * Bit 0 Data Ready (DR). One or more words are in the receive FIFO that the |
311 | * host may read. A word must be completely received and moved from the | 323 | * host may read. A word must be completely received and moved from |
312 | * shift register into the FIFO (or holding register for 8250/16450 | 324 | * the shift register into the FIFO (or holding register for |
313 | * designs) before this bit is set. | 325 | * 8250/16450 designs) before this bit is set. |
314 | * | 326 | * |
315 | * SniffUSB observations: the LSR is returned as second byte on the interrupt-in | 327 | * SniffUSB observations: the LSR is returned as second byte on the |
316 | * endpoint 0x83 to signal error conditions. Such errors have been seen with | 328 | * interrupt-in endpoint 0x83 to signal error conditions. Such errors have |
317 | * minicom/zmodem transfers (CRC errors). | 329 | * been seen with minicom/zmodem transfers (CRC errors). |
318 | * | 330 | * |
319 | * | 331 | * |
320 | * Unknown #1 | 332 | * Unknown #1 |
@@ -364,16 +376,16 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
364 | * -------------- | 376 | * -------------- |
365 | * | 377 | * |
366 | * SniffUSB observations: the bulk-out endpoint 0x1 and interrupt-in endpoint | 378 | * SniffUSB observations: the bulk-out endpoint 0x1 and interrupt-in endpoint |
367 | * 0x81 is used to transmit and receive characters. The second interrupt-in | 379 | * 0x81 is used to transmit and receive characters. The second interrupt-in |
368 | * endpoint 0x83 signals exceptional conditions like modem line changes and | 380 | * endpoint 0x83 signals exceptional conditions like modem line changes and |
369 | * errors. The first byte returned is the MSR and the second byte the LSR. | 381 | * errors. The first byte returned is the MSR and the second byte the LSR. |
370 | * | 382 | * |
371 | * | 383 | * |
372 | * Other observations | 384 | * Other observations |
373 | * ------------------ | 385 | * ------------------ |
374 | * | 386 | * |
375 | * Queued bulk transfers like used in visor.c did not work. | 387 | * Queued bulk transfers like used in visor.c did not work. |
376 | * | 388 | * |
377 | * | 389 | * |
378 | * Properties of the USB device used (as found in /var/log/messages) | 390 | * Properties of the USB device used (as found in /var/log/messages) |
379 | * ----------------------------------------------------------------- | 391 | * ----------------------------------------------------------------- |
@@ -411,26 +423,26 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
411 | * bInterface Class:SubClass:Protocol = 00:00:00 | 423 | * bInterface Class:SubClass:Protocol = 00:00:00 |
412 | * iInterface = 00 | 424 | * iInterface = 00 |
413 | * Endpoint: | 425 | * Endpoint: |
414 | * bLength = 7 | 426 | * bLength = 7 |
415 | * bDescriptorType = 05 | 427 | * bDescriptorType = 05 |
416 | * bEndpointAddress = 81 (in) | 428 | * bEndpointAddress = 81 (in) |
417 | * bmAttributes = 03 (Interrupt) | 429 | * bmAttributes = 03 (Interrupt) |
418 | * wMaxPacketSize = 0040 | 430 | * wMaxPacketSize = 0040 |
419 | * bInterval = 02 | 431 | * bInterval = 02 |
420 | * Endpoint: | 432 | * Endpoint: |
421 | * bLength = 7 | 433 | * bLength = 7 |
422 | * bDescriptorType = 05 | 434 | * bDescriptorType = 05 |
423 | * bEndpointAddress = 01 (out) | 435 | * bEndpointAddress = 01 (out) |
424 | * bmAttributes = 02 (Bulk) | 436 | * bmAttributes = 02 (Bulk) |
425 | * wMaxPacketSize = 0040 | 437 | * wMaxPacketSize = 0040 |
426 | * bInterval = 00 | 438 | * bInterval = 00 |
427 | * Endpoint: | 439 | * Endpoint: |
428 | * bLength = 7 | 440 | * bLength = 7 |
429 | * bDescriptorType = 05 | 441 | * bDescriptorType = 05 |
430 | * bEndpointAddress = 83 (in) | 442 | * bEndpointAddress = 83 (in) |
431 | * bmAttributes = 03 (Interrupt) | 443 | * bmAttributes = 03 (Interrupt) |
432 | * wMaxPacketSize = 0002 | 444 | * wMaxPacketSize = 0002 |
433 | * bInterval = 02 | 445 | * bInterval = 02 |
434 | * | 446 | * |
435 | * | 447 | * |
436 | * Hardware details (added by Martin Hamilton, 2001/12/06) | 448 | * Hardware details (added by Martin Hamilton, 2001/12/06) |
@@ -440,7 +452,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
440 | * adaptor, which turns out to simply be a re-badged U232-P9. We | 452 | * adaptor, which turns out to simply be a re-badged U232-P9. We |
441 | * know this because there is a sticky label on the circuit board | 453 | * know this because there is a sticky label on the circuit board |
442 | * which says "U232-P9" ;-) | 454 | * which says "U232-P9" ;-) |
443 | * | 455 | * |
444 | * The circuit board inside the adaptor contains a Philips PDIUSBD12 | 456 | * The circuit board inside the adaptor contains a Philips PDIUSBD12 |
445 | * USB endpoint chip and a Philips P87C52UBAA microcontroller with | 457 | * USB endpoint chip and a Philips P87C52UBAA microcontroller with |
446 | * embedded UART. Exhaustive documentation for these is available at: | 458 | * embedded UART. Exhaustive documentation for these is available at: |
@@ -449,7 +461,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value | |||
449 | * http://www.semiconductors.philips.com/pip/pdiusbd12 | 461 | * http://www.semiconductors.philips.com/pip/pdiusbd12 |
450 | * | 462 | * |
451 | * Thanks to Julian Highfield for the pointer to the Philips database. | 463 | * Thanks to Julian Highfield for the pointer to the Philips database. |
452 | * | 464 | * |
453 | */ | 465 | */ |
454 | 466 | ||
455 | #endif /* __LINUX_USB_SERIAL_MCT_U232_H */ | 467 | #endif /* __LINUX_USB_SERIAL_MCT_U232_H */ |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 0d47f2c4d59f..30922a7e3347 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -34,21 +34,18 @@ | |||
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/usb/serial.h> | 35 | #include <linux/usb/serial.h> |
36 | #include <linux/uaccess.h> | 36 | #include <linux/uaccess.h> |
37 | 37 | #include <linux/parport.h> | |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Version Information | 40 | * Version Information |
41 | */ | 41 | */ |
42 | #define DRIVER_VERSION "1.0.0.4F" | 42 | #define DRIVER_VERSION "2.1" |
43 | #define DRIVER_AUTHOR "Aspire Communications pvt Ltd." | 43 | #define DRIVER_AUTHOR "Aspire Communications pvt Ltd." |
44 | #define DRIVER_DESC "Moschip USB Serial Driver" | 44 | #define DRIVER_DESC "Moschip USB Serial Driver" |
45 | 45 | ||
46 | /* default urb timeout */ | 46 | /* default urb timeout */ |
47 | #define MOS_WDR_TIMEOUT (HZ * 5) | 47 | #define MOS_WDR_TIMEOUT (HZ * 5) |
48 | 48 | ||
49 | #define MOS_PORT1 0x0200 | ||
50 | #define MOS_PORT2 0x0300 | ||
51 | #define MOS_VENREG 0x0000 | ||
52 | #define MOS_MAX_PORT 0x02 | 49 | #define MOS_MAX_PORT 0x02 |
53 | #define MOS_WRITE 0x0E | 50 | #define MOS_WRITE 0x0E |
54 | #define MOS_READ 0x0D | 51 | #define MOS_READ 0x0D |
@@ -63,7 +60,7 @@ | |||
63 | #define NUM_URBS 16 /* URB Count */ | 60 | #define NUM_URBS 16 /* URB Count */ |
64 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ | 61 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ |
65 | 62 | ||
66 | /* This structure holds all of the local port information */ | 63 | /* This structure holds all of the local serial port information */ |
67 | struct moschip_port { | 64 | struct moschip_port { |
68 | __u8 shadowLCR; /* last LCR value received */ | 65 | __u8 shadowLCR; /* last LCR value received */ |
69 | __u8 shadowMCR; /* last MCR value received */ | 66 | __u8 shadowMCR; /* last MCR value received */ |
@@ -74,11 +71,6 @@ struct moschip_port { | |||
74 | struct urb *write_urb_pool[NUM_URBS]; | 71 | struct urb *write_urb_pool[NUM_URBS]; |
75 | }; | 72 | }; |
76 | 73 | ||
77 | /* This structure holds all of the individual serial device information */ | ||
78 | struct moschip_serial { | ||
79 | int interrupt_started; | ||
80 | }; | ||
81 | |||
82 | static int debug; | 74 | static int debug; |
83 | 75 | ||
84 | static struct usb_serial_driver moschip7720_2port_driver; | 76 | static struct usb_serial_driver moschip7720_2port_driver; |
@@ -94,6 +86,658 @@ static const struct usb_device_id moschip_port_id_table[] = { | |||
94 | }; | 86 | }; |
95 | MODULE_DEVICE_TABLE(usb, moschip_port_id_table); | 87 | MODULE_DEVICE_TABLE(usb, moschip_port_id_table); |
96 | 88 | ||
89 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | ||
90 | |||
91 | /* initial values for parport regs */ | ||
92 | #define DCR_INIT_VAL 0x0c /* SLCTIN, nINIT */ | ||
93 | #define ECR_INIT_VAL 0x00 /* SPP mode */ | ||
94 | |||
95 | struct urbtracker { | ||
96 | struct mos7715_parport *mos_parport; | ||
97 | struct list_head urblist_entry; | ||
98 | struct kref ref_count; | ||
99 | struct urb *urb; | ||
100 | }; | ||
101 | |||
102 | enum mos7715_pp_modes { | ||
103 | SPP = 0<<5, | ||
104 | PS2 = 1<<5, /* moschip calls this 'NIBBLE' mode */ | ||
105 | PPF = 2<<5, /* moschip calls this 'CB-FIFO mode */ | ||
106 | }; | ||
107 | |||
108 | struct mos7715_parport { | ||
109 | struct parport *pp; /* back to containing struct */ | ||
110 | struct kref ref_count; /* to instance of this struct */ | ||
111 | struct list_head deferred_urbs; /* list deferred async urbs */ | ||
112 | struct list_head active_urbs; /* list async urbs in flight */ | ||
113 | spinlock_t listlock; /* protects list access */ | ||
114 | bool msg_pending; /* usb sync call pending */ | ||
115 | struct completion syncmsg_compl; /* usb sync call completed */ | ||
116 | struct tasklet_struct urb_tasklet; /* for sending deferred urbs */ | ||
117 | struct usb_serial *serial; /* back to containing struct */ | ||
118 | __u8 shadowECR; /* parallel port regs... */ | ||
119 | __u8 shadowDCR; | ||
120 | atomic_t shadowDSR; /* updated in int-in callback */ | ||
121 | }; | ||
122 | |||
123 | /* lock guards against dereferencing NULL ptr in parport ops callbacks */ | ||
124 | static DEFINE_SPINLOCK(release_lock); | ||
125 | |||
126 | #endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */ | ||
127 | |||
128 | static const unsigned int dummy; /* for clarity in register access fns */ | ||
129 | |||
130 | enum mos_regs { | ||
131 | THR, /* serial port regs */ | ||
132 | RHR, | ||
133 | IER, | ||
134 | FCR, | ||
135 | ISR, | ||
136 | LCR, | ||
137 | MCR, | ||
138 | LSR, | ||
139 | MSR, | ||
140 | SPR, | ||
141 | DLL, | ||
142 | DLM, | ||
143 | DPR, /* parallel port regs */ | ||
144 | DSR, | ||
145 | DCR, | ||
146 | ECR, | ||
147 | SP1_REG, /* device control regs */ | ||
148 | SP2_REG, /* serial port 2 (7720 only) */ | ||
149 | PP_REG, | ||
150 | SP_CONTROL_REG, | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | * Return the correct value for the Windex field of the setup packet | ||
155 | * for a control endpoint message. See the 7715 datasheet. | ||
156 | */ | ||
157 | static inline __u16 get_reg_index(enum mos_regs reg) | ||
158 | { | ||
159 | static const __u16 mos7715_index_lookup_table[] = { | ||
160 | 0x00, /* THR */ | ||
161 | 0x00, /* RHR */ | ||
162 | 0x01, /* IER */ | ||
163 | 0x02, /* FCR */ | ||
164 | 0x02, /* ISR */ | ||
165 | 0x03, /* LCR */ | ||
166 | 0x04, /* MCR */ | ||
167 | 0x05, /* LSR */ | ||
168 | 0x06, /* MSR */ | ||
169 | 0x07, /* SPR */ | ||
170 | 0x00, /* DLL */ | ||
171 | 0x01, /* DLM */ | ||
172 | 0x00, /* DPR */ | ||
173 | 0x01, /* DSR */ | ||
174 | 0x02, /* DCR */ | ||
175 | 0x0a, /* ECR */ | ||
176 | 0x01, /* SP1_REG */ | ||
177 | 0x02, /* SP2_REG (7720 only) */ | ||
178 | 0x04, /* PP_REG (7715 only) */ | ||
179 | 0x08, /* SP_CONTROL_REG */ | ||
180 | }; | ||
181 | return mos7715_index_lookup_table[reg]; | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Return the correct value for the upper byte of the Wvalue field of | ||
186 | * the setup packet for a control endpoint message. | ||
187 | */ | ||
188 | static inline __u16 get_reg_value(enum mos_regs reg, | ||
189 | unsigned int serial_portnum) | ||
190 | { | ||
191 | if (reg >= SP1_REG) /* control reg */ | ||
192 | return 0x0000; | ||
193 | |||
194 | else if (reg >= DPR) /* parallel port reg (7715 only) */ | ||
195 | return 0x0100; | ||
196 | |||
197 | else /* serial port reg */ | ||
198 | return (serial_portnum + 2) << 8; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Write data byte to the specified device register. The data is embedded in | ||
203 | * the value field of the setup packet. serial_portnum is ignored for registers | ||
204 | * not specific to a particular serial port. | ||
205 | */ | ||
206 | static int write_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, | ||
207 | enum mos_regs reg, __u8 data) | ||
208 | { | ||
209 | struct usb_device *usbdev = serial->dev; | ||
210 | unsigned int pipe = usb_sndctrlpipe(usbdev, 0); | ||
211 | __u8 request = (__u8)0x0e; | ||
212 | __u8 requesttype = (__u8)0x40; | ||
213 | __u16 index = get_reg_index(reg); | ||
214 | __u16 value = get_reg_value(reg, serial_portnum) + data; | ||
215 | int status = usb_control_msg(usbdev, pipe, request, requesttype, value, | ||
216 | index, NULL, 0, MOS_WDR_TIMEOUT); | ||
217 | if (status < 0) | ||
218 | dev_err(&usbdev->dev, | ||
219 | "mos7720: usb_control_msg() failed: %d", status); | ||
220 | return status; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Read data byte from the specified device register. The data returned by the | ||
225 | * device is embedded in the value field of the setup packet. serial_portnum is | ||
226 | * ignored for registers that are not specific to a particular serial port. | ||
227 | */ | ||
228 | static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, | ||
229 | enum mos_regs reg, __u8 *data) | ||
230 | { | ||
231 | struct usb_device *usbdev = serial->dev; | ||
232 | unsigned int pipe = usb_rcvctrlpipe(usbdev, 0); | ||
233 | __u8 request = (__u8)0x0d; | ||
234 | __u8 requesttype = (__u8)0xc0; | ||
235 | __u16 index = get_reg_index(reg); | ||
236 | __u16 value = get_reg_value(reg, serial_portnum); | ||
237 | int status = usb_control_msg(usbdev, pipe, request, requesttype, value, | ||
238 | index, data, 1, MOS_WDR_TIMEOUT); | ||
239 | if (status < 0) | ||
240 | dev_err(&usbdev->dev, | ||
241 | "mos7720: usb_control_msg() failed: %d", status); | ||
242 | return status; | ||
243 | } | ||
244 | |||
245 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | ||
246 | |||
247 | static inline int mos7715_change_mode(struct mos7715_parport *mos_parport, | ||
248 | enum mos7715_pp_modes mode) | ||
249 | { | ||
250 | mos_parport->shadowECR = mode; | ||
251 | write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static void destroy_mos_parport(struct kref *kref) | ||
256 | { | ||
257 | struct mos7715_parport *mos_parport = | ||
258 | container_of(kref, struct mos7715_parport, ref_count); | ||
259 | |||
260 | dbg("%s called", __func__); | ||
261 | kfree(mos_parport); | ||
262 | } | ||
263 | |||
264 | static void destroy_urbtracker(struct kref *kref) | ||
265 | { | ||
266 | struct urbtracker *urbtrack = | ||
267 | container_of(kref, struct urbtracker, ref_count); | ||
268 | struct mos7715_parport *mos_parport = urbtrack->mos_parport; | ||
269 | dbg("%s called", __func__); | ||
270 | usb_free_urb(urbtrack->urb); | ||
271 | kfree(urbtrack); | ||
272 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * This runs as a tasklet when sending an urb in a non-blocking parallel | ||
277 | * port callback had to be deferred because the disconnect mutex could not be | ||
278 | * obtained at the time. | ||
279 | */ | ||
280 | static void send_deferred_urbs(unsigned long _mos_parport) | ||
281 | { | ||
282 | int ret_val; | ||
283 | unsigned long flags; | ||
284 | struct mos7715_parport *mos_parport = (void *)_mos_parport; | ||
285 | struct urbtracker *urbtrack; | ||
286 | struct list_head *cursor, *next; | ||
287 | |||
288 | dbg("%s called", __func__); | ||
289 | |||
290 | /* if release function ran, game over */ | ||
291 | if (unlikely(mos_parport->serial == NULL)) | ||
292 | return; | ||
293 | |||
294 | /* try again to get the mutex */ | ||
295 | if (!mutex_trylock(&mos_parport->serial->disc_mutex)) { | ||
296 | dbg("%s: rescheduling tasklet", __func__); | ||
297 | tasklet_schedule(&mos_parport->urb_tasklet); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | /* if device disconnected, game over */ | ||
302 | if (unlikely(mos_parport->serial->disconnected)) { | ||
303 | mutex_unlock(&mos_parport->serial->disc_mutex); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | spin_lock_irqsave(&mos_parport->listlock, flags); | ||
308 | if (list_empty(&mos_parport->deferred_urbs)) { | ||
309 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
310 | mutex_unlock(&mos_parport->serial->disc_mutex); | ||
311 | dbg("%s: deferred_urbs list empty", __func__); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | /* move contents of deferred_urbs list to active_urbs list and submit */ | ||
316 | list_for_each_safe(cursor, next, &mos_parport->deferred_urbs) | ||
317 | list_move_tail(cursor, &mos_parport->active_urbs); | ||
318 | list_for_each_entry(urbtrack, &mos_parport->active_urbs, | ||
319 | urblist_entry) { | ||
320 | ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC); | ||
321 | dbg("%s: urb submitted", __func__); | ||
322 | if (ret_val) { | ||
323 | dev_err(&mos_parport->serial->dev->dev, | ||
324 | "usb_submit_urb() failed: %d", ret_val); | ||
325 | list_del(&urbtrack->urblist_entry); | ||
326 | kref_put(&urbtrack->ref_count, destroy_urbtracker); | ||
327 | } | ||
328 | } | ||
329 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
330 | mutex_unlock(&mos_parport->serial->disc_mutex); | ||
331 | } | ||
332 | |||
333 | /* callback for parallel port control urbs submitted asynchronously */ | ||
334 | static void async_complete(struct urb *urb) | ||
335 | { | ||
336 | struct urbtracker *urbtrack = urb->context; | ||
337 | int status = urb->status; | ||
338 | dbg("%s called", __func__); | ||
339 | if (unlikely(status)) | ||
340 | dbg("%s - nonzero urb status received: %d", __func__, status); | ||
341 | |||
342 | /* remove the urbtracker from the active_urbs list */ | ||
343 | spin_lock(&urbtrack->mos_parport->listlock); | ||
344 | list_del(&urbtrack->urblist_entry); | ||
345 | spin_unlock(&urbtrack->mos_parport->listlock); | ||
346 | kref_put(&urbtrack->ref_count, destroy_urbtracker); | ||
347 | } | ||
348 | |||
349 | static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | ||
350 | enum mos_regs reg, __u8 data) | ||
351 | { | ||
352 | struct urbtracker *urbtrack; | ||
353 | int ret_val; | ||
354 | unsigned long flags; | ||
355 | struct usb_ctrlrequest setup; | ||
356 | struct usb_serial *serial = mos_parport->serial; | ||
357 | struct usb_device *usbdev = serial->dev; | ||
358 | dbg("%s called", __func__); | ||
359 | |||
360 | /* create and initialize the control urb and containing urbtracker */ | ||
361 | urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC); | ||
362 | if (urbtrack == NULL) { | ||
363 | dev_err(&usbdev->dev, "out of memory"); | ||
364 | return -ENOMEM; | ||
365 | } | ||
366 | kref_get(&mos_parport->ref_count); | ||
367 | urbtrack->mos_parport = mos_parport; | ||
368 | urbtrack->urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
369 | if (urbtrack->urb == NULL) { | ||
370 | dev_err(&usbdev->dev, "out of urbs"); | ||
371 | kfree(urbtrack); | ||
372 | return -ENOMEM; | ||
373 | } | ||
374 | setup.bRequestType = (__u8)0x40; | ||
375 | setup.bRequest = (__u8)0x0e; | ||
376 | setup.wValue = get_reg_value(reg, dummy); | ||
377 | setup.wIndex = get_reg_index(reg); | ||
378 | setup.wLength = 0; | ||
379 | usb_fill_control_urb(urbtrack->urb, usbdev, | ||
380 | usb_sndctrlpipe(usbdev, 0), | ||
381 | (unsigned char *)&setup, | ||
382 | NULL, 0, async_complete, urbtrack); | ||
383 | kref_init(&urbtrack->ref_count); | ||
384 | INIT_LIST_HEAD(&urbtrack->urblist_entry); | ||
385 | |||
386 | /* | ||
387 | * get the disconnect mutex, or add tracker to the deferred_urbs list | ||
388 | * and schedule a tasklet to try again later | ||
389 | */ | ||
390 | if (!mutex_trylock(&serial->disc_mutex)) { | ||
391 | spin_lock_irqsave(&mos_parport->listlock, flags); | ||
392 | list_add_tail(&urbtrack->urblist_entry, | ||
393 | &mos_parport->deferred_urbs); | ||
394 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
395 | tasklet_schedule(&mos_parport->urb_tasklet); | ||
396 | dbg("tasklet scheduled"); | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | /* bail if device disconnected */ | ||
401 | if (serial->disconnected) { | ||
402 | kref_put(&urbtrack->ref_count, destroy_urbtracker); | ||
403 | mutex_unlock(&serial->disc_mutex); | ||
404 | return -ENODEV; | ||
405 | } | ||
406 | |||
407 | /* add the tracker to the active_urbs list and submit */ | ||
408 | spin_lock_irqsave(&mos_parport->listlock, flags); | ||
409 | list_add_tail(&urbtrack->urblist_entry, &mos_parport->active_urbs); | ||
410 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
411 | ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC); | ||
412 | mutex_unlock(&serial->disc_mutex); | ||
413 | if (ret_val) { | ||
414 | dev_err(&usbdev->dev, | ||
415 | "%s: submit_urb() failed: %d", __func__, ret_val); | ||
416 | spin_lock_irqsave(&mos_parport->listlock, flags); | ||
417 | list_del(&urbtrack->urblist_entry); | ||
418 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
419 | kref_put(&urbtrack->ref_count, destroy_urbtracker); | ||
420 | return ret_val; | ||
421 | } | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * This is the the common top part of all parallel port callback operations that | ||
427 | * send synchronous messages to the device. This implements convoluted locking | ||
428 | * that avoids two scenarios: (1) a port operation is called after usbserial | ||
429 | * has called our release function, at which point struct mos7715_parport has | ||
430 | * been destroyed, and (2) the device has been disconnected, but usbserial has | ||
431 | * not called the release function yet because someone has a serial port open. | ||
432 | * The shared release_lock prevents the first, and the mutex and disconnected | ||
433 | * flag maintained by usbserial covers the second. We also use the msg_pending | ||
434 | * flag to ensure that all synchronous usb messgage calls have completed before | ||
435 | * our release function can return. | ||
436 | */ | ||
437 | static int parport_prologue(struct parport *pp) | ||
438 | { | ||
439 | struct mos7715_parport *mos_parport; | ||
440 | |||
441 | spin_lock(&release_lock); | ||
442 | mos_parport = pp->private_data; | ||
443 | if (unlikely(mos_parport == NULL)) { | ||
444 | /* release fn called, port struct destroyed */ | ||
445 | spin_unlock(&release_lock); | ||
446 | return -1; | ||
447 | } | ||
448 | mos_parport->msg_pending = true; /* synch usb call pending */ | ||
449 | INIT_COMPLETION(mos_parport->syncmsg_compl); | ||
450 | spin_unlock(&release_lock); | ||
451 | |||
452 | mutex_lock(&mos_parport->serial->disc_mutex); | ||
453 | if (mos_parport->serial->disconnected) { | ||
454 | /* device disconnected */ | ||
455 | mutex_unlock(&mos_parport->serial->disc_mutex); | ||
456 | mos_parport->msg_pending = false; | ||
457 | complete(&mos_parport->syncmsg_compl); | ||
458 | return -1; | ||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * This is the the common bottom part of all parallel port functions that send | ||
466 | * synchronous messages to the device. | ||
467 | */ | ||
468 | static inline void parport_epilogue(struct parport *pp) | ||
469 | { | ||
470 | struct mos7715_parport *mos_parport = pp->private_data; | ||
471 | mutex_unlock(&mos_parport->serial->disc_mutex); | ||
472 | mos_parport->msg_pending = false; | ||
473 | complete(&mos_parport->syncmsg_compl); | ||
474 | } | ||
475 | |||
476 | static void parport_mos7715_write_data(struct parport *pp, unsigned char d) | ||
477 | { | ||
478 | struct mos7715_parport *mos_parport = pp->private_data; | ||
479 | dbg("%s called: %2.2x", __func__, d); | ||
480 | if (parport_prologue(pp) < 0) | ||
481 | return; | ||
482 | mos7715_change_mode(mos_parport, SPP); | ||
483 | write_mos_reg(mos_parport->serial, dummy, DPR, (__u8)d); | ||
484 | parport_epilogue(pp); | ||
485 | } | ||
486 | |||
487 | static unsigned char parport_mos7715_read_data(struct parport *pp) | ||
488 | { | ||
489 | struct mos7715_parport *mos_parport = pp->private_data; | ||
490 | unsigned char d; | ||
491 | dbg("%s called", __func__); | ||
492 | if (parport_prologue(pp) < 0) | ||
493 | return 0; | ||
494 | read_mos_reg(mos_parport->serial, dummy, DPR, &d); | ||
495 | parport_epilogue(pp); | ||
496 | return d; | ||
497 | } | ||
498 | |||
499 | static void parport_mos7715_write_control(struct parport *pp, unsigned char d) | ||
500 | { | ||
501 | struct mos7715_parport *mos_parport = pp->private_data; | ||
502 | __u8 data; | ||
503 | dbg("%s called: %2.2x", __func__, d); | ||
504 | if (parport_prologue(pp) < 0) | ||
505 | return; | ||
506 | data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0); | ||
507 | write_mos_reg(mos_parport->serial, dummy, DCR, data); | ||
508 | mos_parport->shadowDCR = data; | ||
509 | parport_epilogue(pp); | ||
510 | } | ||
511 | |||
512 | static unsigned char parport_mos7715_read_control(struct parport *pp) | ||
513 | { | ||
514 | struct mos7715_parport *mos_parport = pp->private_data; | ||
515 | __u8 dcr; | ||
516 | dbg("%s called", __func__); | ||
517 | spin_lock(&release_lock); | ||
518 | mos_parport = pp->private_data; | ||
519 | if (unlikely(mos_parport == NULL)) { | ||
520 | spin_unlock(&release_lock); | ||
521 | return 0; | ||
522 | } | ||
523 | dcr = mos_parport->shadowDCR & 0x0f; | ||
524 | spin_unlock(&release_lock); | ||
525 | return dcr; | ||
526 | } | ||
527 | |||
528 | static unsigned char parport_mos7715_frob_control(struct parport *pp, | ||
529 | unsigned char mask, | ||
530 | unsigned char val) | ||
531 | { | ||
532 | struct mos7715_parport *mos_parport = pp->private_data; | ||
533 | __u8 dcr; | ||
534 | dbg("%s called", __func__); | ||
535 | mask &= 0x0f; | ||
536 | val &= 0x0f; | ||
537 | if (parport_prologue(pp) < 0) | ||
538 | return 0; | ||
539 | mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val; | ||
540 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | ||
541 | dcr = mos_parport->shadowDCR & 0x0f; | ||
542 | parport_epilogue(pp); | ||
543 | return dcr; | ||
544 | } | ||
545 | |||
546 | static unsigned char parport_mos7715_read_status(struct parport *pp) | ||
547 | { | ||
548 | unsigned char status; | ||
549 | struct mos7715_parport *mos_parport = pp->private_data; | ||
550 | dbg("%s called", __func__); | ||
551 | spin_lock(&release_lock); | ||
552 | mos_parport = pp->private_data; | ||
553 | if (unlikely(mos_parport == NULL)) { /* release called */ | ||
554 | spin_unlock(&release_lock); | ||
555 | return 0; | ||
556 | } | ||
557 | status = atomic_read(&mos_parport->shadowDSR) & 0xf8; | ||
558 | spin_unlock(&release_lock); | ||
559 | return status; | ||
560 | } | ||
561 | |||
562 | static void parport_mos7715_enable_irq(struct parport *pp) | ||
563 | { | ||
564 | dbg("%s called", __func__); | ||
565 | } | ||
566 | static void parport_mos7715_disable_irq(struct parport *pp) | ||
567 | { | ||
568 | dbg("%s called", __func__); | ||
569 | } | ||
570 | |||
571 | static void parport_mos7715_data_forward(struct parport *pp) | ||
572 | { | ||
573 | struct mos7715_parport *mos_parport = pp->private_data; | ||
574 | dbg("%s called", __func__); | ||
575 | if (parport_prologue(pp) < 0) | ||
576 | return; | ||
577 | mos7715_change_mode(mos_parport, PS2); | ||
578 | mos_parport->shadowDCR &= ~0x20; | ||
579 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | ||
580 | parport_epilogue(pp); | ||
581 | } | ||
582 | |||
583 | static void parport_mos7715_data_reverse(struct parport *pp) | ||
584 | { | ||
585 | struct mos7715_parport *mos_parport = pp->private_data; | ||
586 | dbg("%s called", __func__); | ||
587 | if (parport_prologue(pp) < 0) | ||
588 | return; | ||
589 | mos7715_change_mode(mos_parport, PS2); | ||
590 | mos_parport->shadowDCR |= 0x20; | ||
591 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | ||
592 | parport_epilogue(pp); | ||
593 | } | ||
594 | |||
595 | static void parport_mos7715_init_state(struct pardevice *dev, | ||
596 | struct parport_state *s) | ||
597 | { | ||
598 | dbg("%s called", __func__); | ||
599 | s->u.pc.ctr = DCR_INIT_VAL; | ||
600 | s->u.pc.ecr = ECR_INIT_VAL; | ||
601 | } | ||
602 | |||
603 | /* N.B. Parport core code requires that this function not block */ | ||
604 | static void parport_mos7715_save_state(struct parport *pp, | ||
605 | struct parport_state *s) | ||
606 | { | ||
607 | struct mos7715_parport *mos_parport; | ||
608 | dbg("%s called", __func__); | ||
609 | spin_lock(&release_lock); | ||
610 | mos_parport = pp->private_data; | ||
611 | if (unlikely(mos_parport == NULL)) { /* release called */ | ||
612 | spin_unlock(&release_lock); | ||
613 | return; | ||
614 | } | ||
615 | s->u.pc.ctr = mos_parport->shadowDCR; | ||
616 | s->u.pc.ecr = mos_parport->shadowECR; | ||
617 | spin_unlock(&release_lock); | ||
618 | } | ||
619 | |||
620 | /* N.B. Parport core code requires that this function not block */ | ||
621 | static void parport_mos7715_restore_state(struct parport *pp, | ||
622 | struct parport_state *s) | ||
623 | { | ||
624 | struct mos7715_parport *mos_parport; | ||
625 | dbg("%s called", __func__); | ||
626 | spin_lock(&release_lock); | ||
627 | mos_parport = pp->private_data; | ||
628 | if (unlikely(mos_parport == NULL)) { /* release called */ | ||
629 | spin_unlock(&release_lock); | ||
630 | return; | ||
631 | } | ||
632 | write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR); | ||
633 | write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR); | ||
634 | spin_unlock(&release_lock); | ||
635 | } | ||
636 | |||
637 | static size_t parport_mos7715_write_compat(struct parport *pp, | ||
638 | const void *buffer, | ||
639 | size_t len, int flags) | ||
640 | { | ||
641 | int retval; | ||
642 | struct mos7715_parport *mos_parport = pp->private_data; | ||
643 | int actual_len; | ||
644 | dbg("%s called: %u chars", __func__, (unsigned int)len); | ||
645 | if (parport_prologue(pp) < 0) | ||
646 | return 0; | ||
647 | mos7715_change_mode(mos_parport, PPF); | ||
648 | retval = usb_bulk_msg(mos_parport->serial->dev, | ||
649 | usb_sndbulkpipe(mos_parport->serial->dev, 2), | ||
650 | (void *)buffer, len, &actual_len, | ||
651 | MOS_WDR_TIMEOUT); | ||
652 | parport_epilogue(pp); | ||
653 | if (retval) { | ||
654 | dev_err(&mos_parport->serial->dev->dev, | ||
655 | "mos7720: usb_bulk_msg() failed: %d", retval); | ||
656 | return 0; | ||
657 | } | ||
658 | return actual_len; | ||
659 | } | ||
660 | |||
661 | static struct parport_operations parport_mos7715_ops = { | ||
662 | .owner = THIS_MODULE, | ||
663 | .write_data = parport_mos7715_write_data, | ||
664 | .read_data = parport_mos7715_read_data, | ||
665 | |||
666 | .write_control = parport_mos7715_write_control, | ||
667 | .read_control = parport_mos7715_read_control, | ||
668 | .frob_control = parport_mos7715_frob_control, | ||
669 | |||
670 | .read_status = parport_mos7715_read_status, | ||
671 | |||
672 | .enable_irq = parport_mos7715_enable_irq, | ||
673 | .disable_irq = parport_mos7715_disable_irq, | ||
674 | |||
675 | .data_forward = parport_mos7715_data_forward, | ||
676 | .data_reverse = parport_mos7715_data_reverse, | ||
677 | |||
678 | .init_state = parport_mos7715_init_state, | ||
679 | .save_state = parport_mos7715_save_state, | ||
680 | .restore_state = parport_mos7715_restore_state, | ||
681 | |||
682 | .compat_write_data = parport_mos7715_write_compat, | ||
683 | |||
684 | .nibble_read_data = parport_ieee1284_read_nibble, | ||
685 | .byte_read_data = parport_ieee1284_read_byte, | ||
686 | }; | ||
687 | |||
688 | /* | ||
689 | * Allocate and initialize parallel port control struct, initialize | ||
690 | * the parallel port hardware device, and register with the parport subsystem. | ||
691 | */ | ||
692 | static int mos7715_parport_init(struct usb_serial *serial) | ||
693 | { | ||
694 | struct mos7715_parport *mos_parport; | ||
695 | |||
696 | /* allocate and initialize parallel port control struct */ | ||
697 | mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL); | ||
698 | if (mos_parport == NULL) { | ||
699 | dbg("mos7715_parport_init: kzalloc failed"); | ||
700 | return -ENOMEM; | ||
701 | } | ||
702 | mos_parport->msg_pending = false; | ||
703 | kref_init(&mos_parport->ref_count); | ||
704 | spin_lock_init(&mos_parport->listlock); | ||
705 | INIT_LIST_HEAD(&mos_parport->active_urbs); | ||
706 | INIT_LIST_HEAD(&mos_parport->deferred_urbs); | ||
707 | usb_set_serial_data(serial, mos_parport); /* hijack private pointer */ | ||
708 | mos_parport->serial = serial; | ||
709 | tasklet_init(&mos_parport->urb_tasklet, send_deferred_urbs, | ||
710 | (unsigned long) mos_parport); | ||
711 | init_completion(&mos_parport->syncmsg_compl); | ||
712 | |||
713 | /* cycle parallel port reset bit */ | ||
714 | write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x80); | ||
715 | write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x00); | ||
716 | |||
717 | /* initialize device registers */ | ||
718 | mos_parport->shadowDCR = DCR_INIT_VAL; | ||
719 | write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); | ||
720 | mos_parport->shadowECR = ECR_INIT_VAL; | ||
721 | write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); | ||
722 | |||
723 | /* register with parport core */ | ||
724 | mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE, | ||
725 | PARPORT_DMA_NONE, | ||
726 | &parport_mos7715_ops); | ||
727 | if (mos_parport->pp == NULL) { | ||
728 | dev_err(&serial->interface->dev, | ||
729 | "Could not register parport\n"); | ||
730 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | ||
731 | return -EIO; | ||
732 | } | ||
733 | mos_parport->pp->private_data = mos_parport; | ||
734 | mos_parport->pp->modes = PARPORT_MODE_COMPAT | PARPORT_MODE_PCSPP; | ||
735 | mos_parport->pp->dev = &serial->interface->dev; | ||
736 | parport_announce_port(mos_parport->pp); | ||
737 | |||
738 | return 0; | ||
739 | } | ||
740 | #endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */ | ||
97 | 741 | ||
98 | /* | 742 | /* |
99 | * mos7720_interrupt_callback | 743 | * mos7720_interrupt_callback |
@@ -109,8 +753,6 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
109 | __u8 sp1; | 753 | __u8 sp1; |
110 | __u8 sp2; | 754 | __u8 sp2; |
111 | 755 | ||
112 | dbg(" : Entering"); | ||
113 | |||
114 | switch (status) { | 756 | switch (status) { |
115 | case 0: | 757 | case 0: |
116 | /* success */ | 758 | /* success */ |
@@ -161,7 +803,7 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
161 | dbg("Serial Port 1: Receiver time out"); | 803 | dbg("Serial Port 1: Receiver time out"); |
162 | break; | 804 | break; |
163 | case SERIAL_IIR_MS: | 805 | case SERIAL_IIR_MS: |
164 | dbg("Serial Port 1: Modem status change"); | 806 | /* dbg("Serial Port 1: Modem status change"); */ |
165 | break; | 807 | break; |
166 | } | 808 | } |
167 | 809 | ||
@@ -174,7 +816,7 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
174 | dbg("Serial Port 2: Receiver time out"); | 816 | dbg("Serial Port 2: Receiver time out"); |
175 | break; | 817 | break; |
176 | case SERIAL_IIR_MS: | 818 | case SERIAL_IIR_MS: |
177 | dbg("Serial Port 2: Modem status change"); | 819 | /* dbg("Serial Port 2: Modem status change"); */ |
178 | break; | 820 | break; |
179 | } | 821 | } |
180 | } | 822 | } |
@@ -208,6 +850,7 @@ static void mos7715_interrupt_callback(struct urb *urb) | |||
208 | case -ECONNRESET: | 850 | case -ECONNRESET: |
209 | case -ENOENT: | 851 | case -ENOENT: |
210 | case -ESHUTDOWN: | 852 | case -ESHUTDOWN: |
853 | case -ENODEV: | ||
211 | /* this urb is terminated, clean up */ | 854 | /* this urb is terminated, clean up */ |
212 | dbg("%s - urb shutting down with status: %d", __func__, | 855 | dbg("%s - urb shutting down with status: %d", __func__, |
213 | status); | 856 | status); |
@@ -243,11 +886,21 @@ static void mos7715_interrupt_callback(struct urb *urb) | |||
243 | dbg("Serial Port: Receiver time out"); | 886 | dbg("Serial Port: Receiver time out"); |
244 | break; | 887 | break; |
245 | case SERIAL_IIR_MS: | 888 | case SERIAL_IIR_MS: |
246 | dbg("Serial Port: Modem status change"); | 889 | /* dbg("Serial Port: Modem status change"); */ |
247 | break; | 890 | break; |
248 | } | 891 | } |
249 | } | 892 | } |
250 | 893 | ||
894 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | ||
895 | { /* update local copy of DSR reg */ | ||
896 | struct usb_serial_port *port = urb->context; | ||
897 | struct mos7715_parport *mos_parport = port->serial->private; | ||
898 | if (unlikely(mos_parport == NULL)) | ||
899 | return; | ||
900 | atomic_set(&mos_parport->shadowDSR, data[2]); | ||
901 | } | ||
902 | #endif | ||
903 | |||
251 | exit: | 904 | exit: |
252 | result = usb_submit_urb(urb, GFP_ATOMIC); | 905 | result = usb_submit_urb(urb, GFP_ATOMIC); |
253 | if (result) | 906 | if (result) |
@@ -267,7 +920,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
267 | int retval; | 920 | int retval; |
268 | unsigned char *data ; | 921 | unsigned char *data ; |
269 | struct usb_serial_port *port; | 922 | struct usb_serial_port *port; |
270 | struct moschip_port *mos7720_port; | ||
271 | struct tty_struct *tty; | 923 | struct tty_struct *tty; |
272 | int status = urb->status; | 924 | int status = urb->status; |
273 | 925 | ||
@@ -276,13 +928,7 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
276 | return; | 928 | return; |
277 | } | 929 | } |
278 | 930 | ||
279 | mos7720_port = urb->context; | 931 | port = urb->context; |
280 | if (!mos7720_port) { | ||
281 | dbg("NULL mos7720_port pointer"); | ||
282 | return ; | ||
283 | } | ||
284 | |||
285 | port = mos7720_port->port; | ||
286 | 932 | ||
287 | dbg("Entering...%s", __func__); | 933 | dbg("Entering...%s", __func__); |
288 | 934 | ||
@@ -332,8 +978,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) | |||
332 | return ; | 978 | return ; |
333 | } | 979 | } |
334 | 980 | ||
335 | dbg("Entering ........."); | ||
336 | |||
337 | tty = tty_port_tty_get(&mos7720_port->port->port); | 981 | tty = tty_port_tty_get(&mos7720_port->port->port); |
338 | 982 | ||
339 | if (tty && mos7720_port->open) | 983 | if (tty && mos7720_port->open) |
@@ -342,56 +986,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) | |||
342 | } | 986 | } |
343 | 987 | ||
344 | /* | 988 | /* |
345 | * send_mos_cmd | ||
346 | * this function will be used for sending command to device | ||
347 | */ | ||
348 | static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, | ||
349 | __u16 index, u8 *data) | ||
350 | { | ||
351 | int status; | ||
352 | u8 *buf; | ||
353 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | ||
354 | |||
355 | if (value < MOS_MAX_PORT) { | ||
356 | if (product == MOSCHIP_DEVICE_ID_7715) | ||
357 | value = 0x0200; /* identifies the 7715's serial port */ | ||
358 | else | ||
359 | value = value*0x100+0x200; | ||
360 | } else { | ||
361 | value = 0x0000; | ||
362 | if ((product == MOSCHIP_DEVICE_ID_7715) && | ||
363 | (index != 0x08)) { | ||
364 | dbg("serial->product== MOSCHIP_DEVICE_ID_7715"); | ||
365 | /* index = 0x01 ; */ | ||
366 | } | ||
367 | } | ||
368 | |||
369 | if (request == MOS_WRITE) { | ||
370 | value = value + *data; | ||
371 | status = usb_control_msg(serial->dev, | ||
372 | usb_sndctrlpipe(serial->dev, 0), MOS_WRITE, | ||
373 | 0x40, value, index, NULL, 0, MOS_WDR_TIMEOUT); | ||
374 | } else { | ||
375 | buf = kmalloc(1, GFP_KERNEL); | ||
376 | if (!buf) { | ||
377 | status = -ENOMEM; | ||
378 | goto out; | ||
379 | } | ||
380 | status = usb_control_msg(serial->dev, | ||
381 | usb_rcvctrlpipe(serial->dev, 0), MOS_READ, | ||
382 | 0xc0, value, index, buf, 1, MOS_WDR_TIMEOUT); | ||
383 | *data = *buf; | ||
384 | kfree(buf); | ||
385 | } | ||
386 | out: | ||
387 | if (status < 0) | ||
388 | dbg("Command Write failed Value %x index %x", value, index); | ||
389 | |||
390 | return status; | ||
391 | } | ||
392 | |||
393 | |||
394 | /* | ||
395 | * mos77xx_probe | 989 | * mos77xx_probe |
396 | * this function installs the appropriate read interrupt endpoint callback | 990 | * this function installs the appropriate read interrupt endpoint callback |
397 | * depending on whether the device is a 7720 or 7715, thus avoiding costly | 991 | * depending on whether the device is a 7720 or 7715, thus avoiding costly |
@@ -424,11 +1018,10 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
424 | struct usb_serial *serial; | 1018 | struct usb_serial *serial; |
425 | struct usb_serial_port *port0; | 1019 | struct usb_serial_port *port0; |
426 | struct urb *urb; | 1020 | struct urb *urb; |
427 | struct moschip_serial *mos7720_serial; | ||
428 | struct moschip_port *mos7720_port; | 1021 | struct moschip_port *mos7720_port; |
429 | int response; | 1022 | int response; |
430 | int port_number; | 1023 | int port_number; |
431 | char data; | 1024 | __u8 data; |
432 | int allocated_urbs = 0; | 1025 | int allocated_urbs = 0; |
433 | int j; | 1026 | int j; |
434 | 1027 | ||
@@ -440,11 +1033,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
440 | 1033 | ||
441 | port0 = serial->port[0]; | 1034 | port0 = serial->port[0]; |
442 | 1035 | ||
443 | mos7720_serial = usb_get_serial_data(serial); | ||
444 | |||
445 | if (mos7720_serial == NULL || port0 == NULL) | ||
446 | return -ENODEV; | ||
447 | |||
448 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 1036 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
449 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 1037 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
450 | 1038 | ||
@@ -489,103 +1077,36 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
489 | * 0x08 : SP1/2 Control Reg | 1077 | * 0x08 : SP1/2 Control Reg |
490 | */ | 1078 | */ |
491 | port_number = port->number - port->serial->minor; | 1079 | port_number = port->number - port->serial->minor; |
492 | send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); | 1080 | read_mos_reg(serial, port_number, LSR, &data); |
1081 | |||
493 | dbg("SS::%p LSR:%x", mos7720_port, data); | 1082 | dbg("SS::%p LSR:%x", mos7720_port, data); |
494 | 1083 | ||
495 | dbg("Check:Sending Command .........."); | 1084 | dbg("Check:Sending Command .........."); |
496 | 1085 | ||
497 | data = 0x02; | 1086 | write_mos_reg(serial, dummy, SP1_REG, 0x02); |
498 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data); | 1087 | write_mos_reg(serial, dummy, SP2_REG, 0x02); |
499 | data = 0x02; | ||
500 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data); | ||
501 | 1088 | ||
502 | data = 0x00; | 1089 | write_mos_reg(serial, port_number, IER, 0x00); |
503 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | 1090 | write_mos_reg(serial, port_number, FCR, 0x00); |
504 | data = 0x00; | ||
505 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | ||
506 | 1091 | ||
507 | data = 0xCF; | 1092 | write_mos_reg(serial, port_number, FCR, 0xcf); |
508 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | 1093 | mos7720_port->shadowLCR = 0x03; |
509 | data = 0x03; | 1094 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); |
510 | mos7720_port->shadowLCR = data; | 1095 | mos7720_port->shadowMCR = 0x0b; |
511 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | 1096 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); |
512 | data = 0x0b; | ||
513 | mos7720_port->shadowMCR = data; | ||
514 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
515 | data = 0x0b; | ||
516 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
517 | |||
518 | data = 0x00; | ||
519 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
520 | data = 0x00; | ||
521 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
522 | |||
523 | /* data = 0x00; | ||
524 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data); | ||
525 | data = 0x03; | ||
526 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); | ||
527 | data = 0x00; | ||
528 | send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, | ||
529 | port_number + 1, &data); | ||
530 | */ | ||
531 | data = 0x00; | ||
532 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
533 | 1097 | ||
1098 | write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00); | ||
1099 | read_mos_reg(serial, dummy, SP_CONTROL_REG, &data); | ||
534 | data = data | (port->number - port->serial->minor + 1); | 1100 | data = data | (port->number - port->serial->minor + 1); |
535 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | 1101 | write_mos_reg(serial, dummy, SP_CONTROL_REG, data); |
1102 | mos7720_port->shadowLCR = 0x83; | ||
1103 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | ||
1104 | write_mos_reg(serial, port_number, THR, 0x0c); | ||
1105 | write_mos_reg(serial, port_number, IER, 0x00); | ||
1106 | mos7720_port->shadowLCR = 0x03; | ||
1107 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); | ||
1108 | write_mos_reg(serial, port_number, IER, 0x0c); | ||
536 | 1109 | ||
537 | data = 0x83; | ||
538 | mos7720_port->shadowLCR = data; | ||
539 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
540 | data = 0x0c; | ||
541 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); | ||
542 | data = 0x00; | ||
543 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
544 | data = 0x03; | ||
545 | mos7720_port->shadowLCR = data; | ||
546 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
547 | data = 0x0c; | ||
548 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
549 | data = 0x0c; | ||
550 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
551 | |||
552 | /* see if we've set up our endpoint info yet * | ||
553 | * (can't set it up in mos7720_startup as the * | ||
554 | * structures were not set up at that time.) */ | ||
555 | if (!mos7720_serial->interrupt_started) { | ||
556 | dbg("Interrupt buffer NULL !!!"); | ||
557 | |||
558 | /* not set up yet, so do it now */ | ||
559 | mos7720_serial->interrupt_started = 1; | ||
560 | |||
561 | dbg("To Submit URB !!!"); | ||
562 | |||
563 | /* set up our interrupt urb */ | ||
564 | usb_fill_int_urb(port0->interrupt_in_urb, serial->dev, | ||
565 | usb_rcvintpipe(serial->dev, | ||
566 | port->interrupt_in_endpointAddress), | ||
567 | port0->interrupt_in_buffer, | ||
568 | port0->interrupt_in_urb->transfer_buffer_length, | ||
569 | mos7720_interrupt_callback, mos7720_port, | ||
570 | port0->interrupt_in_urb->interval); | ||
571 | |||
572 | /* start interrupt read for this mos7720 this interrupt * | ||
573 | * will continue as long as the mos7720 is connected */ | ||
574 | dbg("Submit URB over !!!"); | ||
575 | response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); | ||
576 | if (response) | ||
577 | dev_err(&port->dev, | ||
578 | "%s - Error %d submitting control urb\n", | ||
579 | __func__, response); | ||
580 | } | ||
581 | |||
582 | /* set up our bulk in urb */ | ||
583 | usb_fill_bulk_urb(port->read_urb, serial->dev, | ||
584 | usb_rcvbulkpipe(serial->dev, | ||
585 | port->bulk_in_endpointAddress), | ||
586 | port->bulk_in_buffer, | ||
587 | port->read_urb->transfer_buffer_length, | ||
588 | mos7720_bulk_in_callback, mos7720_port); | ||
589 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); | 1110 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); |
590 | if (response) | 1111 | if (response) |
591 | dev_err(&port->dev, "%s - Error %d submitting read urb\n", | 1112 | dev_err(&port->dev, "%s - Error %d submitting read urb\n", |
@@ -640,7 +1161,6 @@ static void mos7720_close(struct usb_serial_port *port) | |||
640 | { | 1161 | { |
641 | struct usb_serial *serial; | 1162 | struct usb_serial *serial; |
642 | struct moschip_port *mos7720_port; | 1163 | struct moschip_port *mos7720_port; |
643 | char data; | ||
644 | int j; | 1164 | int j; |
645 | 1165 | ||
646 | dbg("mos7720_close:entering..."); | 1166 | dbg("mos7720_close:entering..."); |
@@ -673,13 +1193,10 @@ static void mos7720_close(struct usb_serial_port *port) | |||
673 | /* these commands must not be issued if the device has | 1193 | /* these commands must not be issued if the device has |
674 | * been disconnected */ | 1194 | * been disconnected */ |
675 | if (!serial->disconnected) { | 1195 | if (!serial->disconnected) { |
676 | data = 0x00; | 1196 | write_mos_reg(serial, port->number - port->serial->minor, |
677 | send_mos_cmd(serial, MOS_WRITE, | 1197 | MCR, 0x00); |
678 | port->number - port->serial->minor, 0x04, &data); | 1198 | write_mos_reg(serial, port->number - port->serial->minor, |
679 | 1199 | IER, 0x00); | |
680 | data = 0x00; | ||
681 | send_mos_cmd(serial, MOS_WRITE, | ||
682 | port->number - port->serial->minor, 0x01, &data); | ||
683 | } | 1200 | } |
684 | mutex_unlock(&serial->disc_mutex); | 1201 | mutex_unlock(&serial->disc_mutex); |
685 | mos7720_port->open = 0; | 1202 | mos7720_port->open = 0; |
@@ -708,8 +1225,8 @@ static void mos7720_break(struct tty_struct *tty, int break_state) | |||
708 | data = mos7720_port->shadowLCR & ~UART_LCR_SBC; | 1225 | data = mos7720_port->shadowLCR & ~UART_LCR_SBC; |
709 | 1226 | ||
710 | mos7720_port->shadowLCR = data; | 1227 | mos7720_port->shadowLCR = data; |
711 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | 1228 | write_mos_reg(serial, port->number - port->serial->minor, |
712 | 0x03, &data); | 1229 | LCR, mos7720_port->shadowLCR); |
713 | 1230 | ||
714 | return; | 1231 | return; |
715 | } | 1232 | } |
@@ -854,9 +1371,8 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
854 | /* if we are implementing RTS/CTS, toggle that line */ | 1371 | /* if we are implementing RTS/CTS, toggle that line */ |
855 | if (tty->termios->c_cflag & CRTSCTS) { | 1372 | if (tty->termios->c_cflag & CRTSCTS) { |
856 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | 1373 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; |
857 | status = send_mos_cmd(port->serial, MOS_WRITE, | 1374 | write_mos_reg(port->serial, port->number - port->serial->minor, |
858 | port->number - port->serial->minor, | 1375 | MCR, mos7720_port->shadowMCR); |
859 | UART_MCR, &mos7720_port->shadowMCR); | ||
860 | if (status != 0) | 1376 | if (status != 0) |
861 | return; | 1377 | return; |
862 | } | 1378 | } |
@@ -889,22 +1405,21 @@ static void mos7720_unthrottle(struct tty_struct *tty) | |||
889 | /* if we are implementing RTS/CTS, toggle that line */ | 1405 | /* if we are implementing RTS/CTS, toggle that line */ |
890 | if (tty->termios->c_cflag & CRTSCTS) { | 1406 | if (tty->termios->c_cflag & CRTSCTS) { |
891 | mos7720_port->shadowMCR |= UART_MCR_RTS; | 1407 | mos7720_port->shadowMCR |= UART_MCR_RTS; |
892 | status = send_mos_cmd(port->serial, MOS_WRITE, | 1408 | write_mos_reg(port->serial, port->number - port->serial->minor, |
893 | port->number - port->serial->minor, | 1409 | MCR, mos7720_port->shadowMCR); |
894 | UART_MCR, &mos7720_port->shadowMCR); | ||
895 | if (status != 0) | 1410 | if (status != 0) |
896 | return; | 1411 | return; |
897 | } | 1412 | } |
898 | } | 1413 | } |
899 | 1414 | ||
1415 | /* FIXME: this function does not work */ | ||
900 | static int set_higher_rates(struct moschip_port *mos7720_port, | 1416 | static int set_higher_rates(struct moschip_port *mos7720_port, |
901 | unsigned int baud) | 1417 | unsigned int baud) |
902 | { | 1418 | { |
903 | unsigned char data; | ||
904 | struct usb_serial_port *port; | 1419 | struct usb_serial_port *port; |
905 | struct usb_serial *serial; | 1420 | struct usb_serial *serial; |
906 | int port_number; | 1421 | int port_number; |
907 | 1422 | enum mos_regs sp_reg; | |
908 | if (mos7720_port == NULL) | 1423 | if (mos7720_port == NULL) |
909 | return -EINVAL; | 1424 | return -EINVAL; |
910 | 1425 | ||
@@ -917,58 +1432,35 @@ static int set_higher_rates(struct moschip_port *mos7720_port, | |||
917 | dbg("Sending Setting Commands .........."); | 1432 | dbg("Sending Setting Commands .........."); |
918 | port_number = port->number - port->serial->minor; | 1433 | port_number = port->number - port->serial->minor; |
919 | 1434 | ||
920 | data = 0x000; | 1435 | write_mos_reg(serial, port_number, IER, 0x00); |
921 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | 1436 | write_mos_reg(serial, port_number, FCR, 0x00); |
922 | data = 0x000; | 1437 | write_mos_reg(serial, port_number, FCR, 0xcf); |
923 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | 1438 | mos7720_port->shadowMCR = 0x0b; |
924 | data = 0x0CF; | 1439 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); |
925 | send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data); | 1440 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x00); |
926 | data = 0x00b; | ||
927 | mos7720_port->shadowMCR = data; | ||
928 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
929 | data = 0x00b; | ||
930 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
931 | |||
932 | data = 0x000; | ||
933 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
934 | data = 0x000; | ||
935 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
936 | |||
937 | 1441 | ||
938 | /*********************************************** | 1442 | /*********************************************** |
939 | * Set for higher rates * | 1443 | * Set for higher rates * |
940 | ***********************************************/ | 1444 | ***********************************************/ |
941 | 1445 | /* writing baud rate verbatum into uart clock field clearly not right */ | |
942 | data = baud * 0x10; | 1446 | if (port_number == 0) |
943 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); | 1447 | sp_reg = SP1_REG; |
944 | 1448 | else | |
945 | data = 0x003; | 1449 | sp_reg = SP2_REG; |
946 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | 1450 | write_mos_reg(serial, dummy, sp_reg, baud * 0x10); |
947 | data = 0x003; | 1451 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x03); |
948 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | 1452 | mos7720_port->shadowMCR = 0x2b; |
949 | 1453 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | |
950 | data = 0x02b; | ||
951 | mos7720_port->shadowMCR = data; | ||
952 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
953 | data = 0x02b; | ||
954 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
955 | 1454 | ||
956 | /*********************************************** | 1455 | /*********************************************** |
957 | * Set DLL/DLM | 1456 | * Set DLL/DLM |
958 | ***********************************************/ | 1457 | ***********************************************/ |
959 | 1458 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; | |
960 | data = mos7720_port->shadowLCR | UART_LCR_DLAB; | 1459 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); |
961 | mos7720_port->shadowLCR = data; | 1460 | write_mos_reg(serial, port_number, DLL, 0x01); |
962 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | 1461 | write_mos_reg(serial, port_number, DLM, 0x00); |
963 | 1462 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | |
964 | data = 0x001; /* DLL */ | 1463 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); |
965 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); | ||
966 | data = 0x000; /* DLM */ | ||
967 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
968 | |||
969 | data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | ||
970 | mos7720_port->shadowLCR = data; | ||
971 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
972 | 1464 | ||
973 | return 0; | 1465 | return 0; |
974 | } | 1466 | } |
@@ -1056,7 +1548,6 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, | |||
1056 | struct usb_serial *serial; | 1548 | struct usb_serial *serial; |
1057 | int divisor; | 1549 | int divisor; |
1058 | int status; | 1550 | int status; |
1059 | unsigned char data; | ||
1060 | unsigned char number; | 1551 | unsigned char number; |
1061 | 1552 | ||
1062 | if (mos7720_port == NULL) | 1553 | if (mos7720_port == NULL) |
@@ -1078,21 +1569,16 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, | |||
1078 | } | 1569 | } |
1079 | 1570 | ||
1080 | /* Enable access to divisor latch */ | 1571 | /* Enable access to divisor latch */ |
1081 | data = mos7720_port->shadowLCR | UART_LCR_DLAB; | 1572 | mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; |
1082 | mos7720_port->shadowLCR = data; | 1573 | write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); |
1083 | send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data); | ||
1084 | 1574 | ||
1085 | /* Write the divisor */ | 1575 | /* Write the divisor */ |
1086 | data = ((unsigned char)(divisor & 0xff)); | 1576 | write_mos_reg(serial, number, DLL, (__u8)(divisor & 0xff)); |
1087 | send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data); | 1577 | write_mos_reg(serial, number, DLM, (__u8)((divisor & 0xff00) >> 8)); |
1088 | |||
1089 | data = ((unsigned char)((divisor & 0xff00) >> 8)); | ||
1090 | send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data); | ||
1091 | 1578 | ||
1092 | /* Disable access to divisor latch */ | 1579 | /* Disable access to divisor latch */ |
1093 | data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | 1580 | mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; |
1094 | mos7720_port->shadowLCR = data; | 1581 | write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); |
1095 | send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data); | ||
1096 | 1582 | ||
1097 | return status; | 1583 | return status; |
1098 | } | 1584 | } |
@@ -1117,7 +1603,6 @@ static void change_port_settings(struct tty_struct *tty, | |||
1117 | __u8 lStop; | 1603 | __u8 lStop; |
1118 | int status; | 1604 | int status; |
1119 | int port_number; | 1605 | int port_number; |
1120 | char data; | ||
1121 | 1606 | ||
1122 | if (mos7720_port == NULL) | 1607 | if (mos7720_port == NULL) |
1123 | return ; | 1608 | return ; |
@@ -1196,30 +1681,19 @@ static void change_port_settings(struct tty_struct *tty, | |||
1196 | 1681 | ||
1197 | /* Update the LCR with the correct value */ | 1682 | /* Update the LCR with the correct value */ |
1198 | mos7720_port->shadowLCR &= | 1683 | mos7720_port->shadowLCR &= |
1199 | ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | 1684 | ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); |
1200 | mos7720_port->shadowLCR |= (lData | lParity | lStop); | 1685 | mos7720_port->shadowLCR |= (lData | lParity | lStop); |
1201 | 1686 | ||
1202 | 1687 | ||
1203 | /* Disable Interrupts */ | 1688 | /* Disable Interrupts */ |
1204 | data = 0x00; | 1689 | write_mos_reg(serial, port_number, IER, 0x00); |
1205 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | 1690 | write_mos_reg(serial, port_number, FCR, 0x00); |
1206 | UART_IER, &data); | 1691 | write_mos_reg(serial, port_number, FCR, 0xcf); |
1207 | |||
1208 | data = 0x00; | ||
1209 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); | ||
1210 | |||
1211 | data = 0xcf; | ||
1212 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); | ||
1213 | 1692 | ||
1214 | /* Send the updated LCR value to the mos7720 */ | 1693 | /* Send the updated LCR value to the mos7720 */ |
1215 | data = mos7720_port->shadowLCR; | 1694 | write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); |
1216 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data); | 1695 | mos7720_port->shadowMCR = 0x0b; |
1217 | 1696 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); | |
1218 | data = 0x00b; | ||
1219 | mos7720_port->shadowMCR = data; | ||
1220 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
1221 | data = 0x00b; | ||
1222 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
1223 | 1697 | ||
1224 | /* set up the MCR register and send it to the mos7720 */ | 1698 | /* set up the MCR register and send it to the mos7720 */ |
1225 | mos7720_port->shadowMCR = UART_MCR_OUT2; | 1699 | mos7720_port->shadowMCR = UART_MCR_OUT2; |
@@ -1230,21 +1704,15 @@ static void change_port_settings(struct tty_struct *tty, | |||
1230 | mos7720_port->shadowMCR |= (UART_MCR_XONANY); | 1704 | mos7720_port->shadowMCR |= (UART_MCR_XONANY); |
1231 | /* To set hardware flow control to the specified * | 1705 | /* To set hardware flow control to the specified * |
1232 | * serial port, in SP1/2_CONTROL_REG */ | 1706 | * serial port, in SP1/2_CONTROL_REG */ |
1233 | if (port->number) { | 1707 | if (port->number) |
1234 | data = 0x001; | 1708 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); |
1235 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, | 1709 | else |
1236 | 0x08, &data); | 1710 | write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); |
1237 | } else { | 1711 | |
1238 | data = 0x002; | 1712 | } else |
1239 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, | ||
1240 | 0x08, &data); | ||
1241 | } | ||
1242 | } else { | ||
1243 | mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); | 1713 | mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); |
1244 | } | ||
1245 | 1714 | ||
1246 | data = mos7720_port->shadowMCR; | 1715 | write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); |
1247 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data); | ||
1248 | 1716 | ||
1249 | /* Determine divisor based on baud rate */ | 1717 | /* Determine divisor based on baud rate */ |
1250 | baud = tty_get_baud_rate(tty); | 1718 | baud = tty_get_baud_rate(tty); |
@@ -1257,8 +1725,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
1257 | if (baud >= 230400) { | 1725 | if (baud >= 230400) { |
1258 | set_higher_rates(mos7720_port, baud); | 1726 | set_higher_rates(mos7720_port, baud); |
1259 | /* Enable Interrupts */ | 1727 | /* Enable Interrupts */ |
1260 | data = 0x0c; | 1728 | write_mos_reg(serial, port_number, IER, 0x0c); |
1261 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); | ||
1262 | return; | 1729 | return; |
1263 | } | 1730 | } |
1264 | 1731 | ||
@@ -1269,8 +1736,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
1269 | if (cflag & CBAUD) | 1736 | if (cflag & CBAUD) |
1270 | tty_encode_baud_rate(tty, baud, baud); | 1737 | tty_encode_baud_rate(tty, baud, baud); |
1271 | /* Enable Interrupts */ | 1738 | /* Enable Interrupts */ |
1272 | data = 0x0c; | 1739 | write_mos_reg(serial, port_number, IER, 0x0c); |
1273 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); | ||
1274 | 1740 | ||
1275 | if (port->read_urb->status != -EINPROGRESS) { | 1741 | if (port->read_urb->status != -EINPROGRESS) { |
1276 | port->read_urb->dev = serial->dev; | 1742 | port->read_urb->dev = serial->dev; |
@@ -1308,7 +1774,7 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
1308 | return; | 1774 | return; |
1309 | } | 1775 | } |
1310 | 1776 | ||
1311 | dbg("setting termios - ASPIRE"); | 1777 | dbg("%s\n", "setting termios - ASPIRE"); |
1312 | 1778 | ||
1313 | cflag = tty->termios->c_cflag; | 1779 | cflag = tty->termios->c_cflag; |
1314 | 1780 | ||
@@ -1326,7 +1792,7 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
1326 | change_port_settings(tty, mos7720_port, old_termios); | 1792 | change_port_settings(tty, mos7720_port, old_termios); |
1327 | 1793 | ||
1328 | if (!port->read_urb) { | 1794 | if (!port->read_urb) { |
1329 | dbg("URB KILLED !!!!!"); | 1795 | dbg("%s", "URB KILLED !!!!!"); |
1330 | return; | 1796 | return; |
1331 | } | 1797 | } |
1332 | 1798 | ||
@@ -1361,8 +1827,7 @@ static int get_lsr_info(struct tty_struct *tty, | |||
1361 | 1827 | ||
1362 | count = mos7720_chars_in_buffer(tty); | 1828 | count = mos7720_chars_in_buffer(tty); |
1363 | if (count == 0) { | 1829 | if (count == 0) { |
1364 | send_mos_cmd(port->serial, MOS_READ, port_number, | 1830 | read_mos_reg(port->serial, port_number, LSR, &data); |
1365 | UART_LSR, &data); | ||
1366 | if ((data & (UART_LSR_TEMT | UART_LSR_THRE)) | 1831 | if ((data & (UART_LSR_TEMT | UART_LSR_THRE)) |
1367 | == (UART_LSR_TEMT | UART_LSR_THRE)) { | 1832 | == (UART_LSR_TEMT | UART_LSR_THRE)) { |
1368 | dbg("%s -- Empty", __func__); | 1833 | dbg("%s -- Empty", __func__); |
@@ -1400,13 +1865,11 @@ static int mos7720_tiocmget(struct tty_struct *tty, struct file *file) | |||
1400 | } | 1865 | } |
1401 | 1866 | ||
1402 | static int mos7720_tiocmset(struct tty_struct *tty, struct file *file, | 1867 | static int mos7720_tiocmset(struct tty_struct *tty, struct file *file, |
1403 | unsigned int set, unsigned int clear) | 1868 | unsigned int set, unsigned int clear) |
1404 | { | 1869 | { |
1405 | struct usb_serial_port *port = tty->driver_data; | 1870 | struct usb_serial_port *port = tty->driver_data; |
1406 | struct moschip_port *mos7720_port = usb_get_serial_port_data(port); | 1871 | struct moschip_port *mos7720_port = usb_get_serial_port_data(port); |
1407 | unsigned int mcr ; | 1872 | unsigned int mcr ; |
1408 | unsigned char lmcr; | ||
1409 | |||
1410 | dbg("%s - port %d", __func__, port->number); | 1873 | dbg("%s - port %d", __func__, port->number); |
1411 | dbg("he was at tiocmget"); | 1874 | dbg("he was at tiocmget"); |
1412 | 1875 | ||
@@ -1427,10 +1890,8 @@ static int mos7720_tiocmset(struct tty_struct *tty, struct file *file, | |||
1427 | mcr &= ~UART_MCR_LOOP; | 1890 | mcr &= ~UART_MCR_LOOP; |
1428 | 1891 | ||
1429 | mos7720_port->shadowMCR = mcr; | 1892 | mos7720_port->shadowMCR = mcr; |
1430 | lmcr = mos7720_port->shadowMCR; | 1893 | write_mos_reg(port->serial, port->number - port->serial->minor, |
1431 | 1894 | MCR, mos7720_port->shadowMCR); | |
1432 | send_mos_cmd(port->serial, MOS_WRITE, | ||
1433 | port->number - port->serial->minor, UART_MCR, &lmcr); | ||
1434 | 1895 | ||
1435 | return 0; | 1896 | return 0; |
1436 | } | 1897 | } |
@@ -1440,7 +1901,6 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, | |||
1440 | { | 1901 | { |
1441 | unsigned int mcr ; | 1902 | unsigned int mcr ; |
1442 | unsigned int arg; | 1903 | unsigned int arg; |
1443 | unsigned char data; | ||
1444 | 1904 | ||
1445 | struct usb_serial_port *port; | 1905 | struct usb_serial_port *port; |
1446 | 1906 | ||
@@ -1475,10 +1935,8 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, | |||
1475 | } | 1935 | } |
1476 | 1936 | ||
1477 | mos7720_port->shadowMCR = mcr; | 1937 | mos7720_port->shadowMCR = mcr; |
1478 | 1938 | write_mos_reg(port->serial, port->number - port->serial->minor, | |
1479 | data = mos7720_port->shadowMCR; | 1939 | MCR, mos7720_port->shadowMCR); |
1480 | send_mos_cmd(port->serial, MOS_WRITE, | ||
1481 | port->number - port->serial->minor, UART_MCR, &data); | ||
1482 | 1940 | ||
1483 | return 0; | 1941 | return 0; |
1484 | } | 1942 | } |
@@ -1590,12 +2048,12 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file, | |||
1590 | 2048 | ||
1591 | static int mos7720_startup(struct usb_serial *serial) | 2049 | static int mos7720_startup(struct usb_serial *serial) |
1592 | { | 2050 | { |
1593 | struct moschip_serial *mos7720_serial; | ||
1594 | struct moschip_port *mos7720_port; | 2051 | struct moschip_port *mos7720_port; |
1595 | struct usb_device *dev; | 2052 | struct usb_device *dev; |
1596 | int i; | 2053 | int i; |
1597 | char data; | 2054 | char data; |
1598 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | 2055 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); |
2056 | int ret_val; | ||
1599 | 2057 | ||
1600 | dbg("%s: Entering ..........", __func__); | 2058 | dbg("%s: Entering ..........", __func__); |
1601 | 2059 | ||
@@ -1606,15 +2064,6 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1606 | 2064 | ||
1607 | dev = serial->dev; | 2065 | dev = serial->dev; |
1608 | 2066 | ||
1609 | /* create our private serial structure */ | ||
1610 | mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); | ||
1611 | if (mos7720_serial == NULL) { | ||
1612 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | ||
1613 | return -ENOMEM; | ||
1614 | } | ||
1615 | |||
1616 | usb_set_serial_data(serial, mos7720_serial); | ||
1617 | |||
1618 | /* | 2067 | /* |
1619 | * The 7715 uses the first bulk in/out endpoint pair for the parallel | 2068 | * The 7715 uses the first bulk in/out endpoint pair for the parallel |
1620 | * port, and the second for the serial port. Because the usbserial core | 2069 | * port, and the second for the serial port. Because the usbserial core |
@@ -1638,16 +2087,12 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1638 | serial->port[1]->interrupt_in_buffer = NULL; | 2087 | serial->port[1]->interrupt_in_buffer = NULL; |
1639 | } | 2088 | } |
1640 | 2089 | ||
1641 | /* we set up the pointers to the endpoints in the mos7720_open * | ||
1642 | * function, as the structures aren't created yet. */ | ||
1643 | 2090 | ||
1644 | /* set up port private structures */ | 2091 | /* set up serial port private structures */ |
1645 | for (i = 0; i < serial->num_ports; ++i) { | 2092 | for (i = 0; i < serial->num_ports; ++i) { |
1646 | mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | 2093 | mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
1647 | if (mos7720_port == NULL) { | 2094 | if (mos7720_port == NULL) { |
1648 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | 2095 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); |
1649 | usb_set_serial_data(serial, NULL); | ||
1650 | kfree(mos7720_serial); | ||
1651 | return -ENOMEM; | 2096 | return -ENOMEM; |
1652 | } | 2097 | } |
1653 | 2098 | ||
@@ -1669,12 +2114,22 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1669 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2114 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
1670 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); | 2115 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); |
1671 | 2116 | ||
1672 | /* LSR For Port 1 */ | 2117 | /* start the interrupt urb */ |
1673 | send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data); | 2118 | ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); |
1674 | dbg("LSR:%x", data); | 2119 | if (ret_val) |
2120 | dev_err(&dev->dev, | ||
2121 | "%s - Error %d submitting control urb\n", | ||
2122 | __func__, ret_val); | ||
1675 | 2123 | ||
1676 | /* LSR For Port 2 */ | 2124 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT |
1677 | send_mos_cmd(serial, MOS_READ, 0x01, UART_LSR, &data); | 2125 | if (product == MOSCHIP_DEVICE_ID_7715) { |
2126 | ret_val = mos7715_parport_init(serial); | ||
2127 | if (ret_val < 0) | ||
2128 | return ret_val; | ||
2129 | } | ||
2130 | #endif | ||
2131 | /* LSR For Port 1 */ | ||
2132 | read_mos_reg(serial, 0, LSR, &data); | ||
1678 | dbg("LSR:%x", data); | 2133 | dbg("LSR:%x", data); |
1679 | 2134 | ||
1680 | return 0; | 2135 | return 0; |
@@ -1684,12 +2139,47 @@ static void mos7720_release(struct usb_serial *serial) | |||
1684 | { | 2139 | { |
1685 | int i; | 2140 | int i; |
1686 | 2141 | ||
2142 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | ||
2143 | /* close the parallel port */ | ||
2144 | |||
2145 | if (le16_to_cpu(serial->dev->descriptor.idProduct) | ||
2146 | == MOSCHIP_DEVICE_ID_7715) { | ||
2147 | struct urbtracker *urbtrack; | ||
2148 | unsigned long flags; | ||
2149 | struct mos7715_parport *mos_parport = | ||
2150 | usb_get_serial_data(serial); | ||
2151 | |||
2152 | /* prevent NULL ptr dereference in port callbacks */ | ||
2153 | spin_lock(&release_lock); | ||
2154 | mos_parport->pp->private_data = NULL; | ||
2155 | spin_unlock(&release_lock); | ||
2156 | |||
2157 | /* wait for synchronous usb calls to return */ | ||
2158 | if (mos_parport->msg_pending) | ||
2159 | wait_for_completion_timeout(&mos_parport->syncmsg_compl, | ||
2160 | MOS_WDR_TIMEOUT); | ||
2161 | |||
2162 | parport_remove_port(mos_parport->pp); | ||
2163 | usb_set_serial_data(serial, NULL); | ||
2164 | mos_parport->serial = NULL; | ||
2165 | |||
2166 | /* if tasklet currently scheduled, wait for it to complete */ | ||
2167 | tasklet_kill(&mos_parport->urb_tasklet); | ||
2168 | |||
2169 | /* unlink any urbs sent by the tasklet */ | ||
2170 | spin_lock_irqsave(&mos_parport->listlock, flags); | ||
2171 | list_for_each_entry(urbtrack, | ||
2172 | &mos_parport->active_urbs, | ||
2173 | urblist_entry) | ||
2174 | usb_unlink_urb(urbtrack->urb); | ||
2175 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | ||
2176 | |||
2177 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | ||
2178 | } | ||
2179 | #endif | ||
1687 | /* free private structure allocated for serial port */ | 2180 | /* free private structure allocated for serial port */ |
1688 | for (i = 0; i < serial->num_ports; ++i) | 2181 | for (i = 0; i < serial->num_ports; ++i) |
1689 | kfree(usb_get_serial_port_data(serial->port[i])); | 2182 | kfree(usb_get_serial_port_data(serial->port[i])); |
1690 | |||
1691 | /* free private structure allocated for serial device */ | ||
1692 | kfree(usb_get_serial_data(serial)); | ||
1693 | } | 2183 | } |
1694 | 2184 | ||
1695 | static struct usb_driver usb_driver = { | 2185 | static struct usb_driver usb_driver = { |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2fda1c0182b7..f8424d1bfc1b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
31 | #include <linux/tty_driver.h> | 30 | #include <linux/tty_driver.h> |
32 | #include <linux/tty_flip.h> | 31 | #include <linux/tty_flip.h> |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 84d0edad8e4f..e280ad8e12f7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -42,35 +42,14 @@ | |||
42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
43 | #include <linux/usb.h> | 43 | #include <linux/usb.h> |
44 | #include <linux/usb/serial.h> | 44 | #include <linux/usb/serial.h> |
45 | #include "usb-wwan.h" | ||
45 | 46 | ||
46 | /* Function prototypes */ | 47 | /* Function prototypes */ |
47 | static int option_probe(struct usb_serial *serial, | 48 | static int option_probe(struct usb_serial *serial, |
48 | const struct usb_device_id *id); | 49 | const struct usb_device_id *id); |
49 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port); | 50 | static int option_send_setup(struct usb_serial_port *port); |
50 | static void option_close(struct usb_serial_port *port); | ||
51 | static void option_dtr_rts(struct usb_serial_port *port, int on); | ||
52 | |||
53 | static int option_startup(struct usb_serial *serial); | ||
54 | static void option_disconnect(struct usb_serial *serial); | ||
55 | static void option_release(struct usb_serial *serial); | ||
56 | static int option_write_room(struct tty_struct *tty); | ||
57 | |||
58 | static void option_instat_callback(struct urb *urb); | 51 | static void option_instat_callback(struct urb *urb); |
59 | 52 | ||
60 | static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
61 | const unsigned char *buf, int count); | ||
62 | static int option_chars_in_buffer(struct tty_struct *tty); | ||
63 | static void option_set_termios(struct tty_struct *tty, | ||
64 | struct usb_serial_port *port, struct ktermios *old); | ||
65 | static int option_tiocmget(struct tty_struct *tty, struct file *file); | ||
66 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | ||
67 | unsigned int set, unsigned int clear); | ||
68 | static int option_send_setup(struct usb_serial_port *port); | ||
69 | #ifdef CONFIG_PM | ||
70 | static int option_suspend(struct usb_serial *serial, pm_message_t message); | ||
71 | static int option_resume(struct usb_serial *serial); | ||
72 | #endif | ||
73 | |||
74 | /* Vendor and product IDs */ | 53 | /* Vendor and product IDs */ |
75 | #define OPTION_VENDOR_ID 0x0AF0 | 54 | #define OPTION_VENDOR_ID 0x0AF0 |
76 | #define OPTION_PRODUCT_COLT 0x5000 | 55 | #define OPTION_PRODUCT_COLT 0x5000 |
@@ -380,6 +359,10 @@ static int option_resume(struct usb_serial *serial); | |||
380 | 359 | ||
381 | #define CINTERION_VENDOR_ID 0x0681 | 360 | #define CINTERION_VENDOR_ID 0x0681 |
382 | 361 | ||
362 | /* Olivetti products */ | ||
363 | #define OLIVETTI_VENDOR_ID 0x0b3c | ||
364 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 | ||
365 | |||
383 | /* some devices interfaces need special handling due to a number of reasons */ | 366 | /* some devices interfaces need special handling due to a number of reasons */ |
384 | enum option_blacklist_reason { | 367 | enum option_blacklist_reason { |
385 | OPTION_BLACKLIST_NONE = 0, | 368 | OPTION_BLACKLIST_NONE = 0, |
@@ -675,6 +658,180 @@ static const struct usb_device_id option_ids[] = { | |||
675 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, | 658 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, |
676 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, | 659 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, |
677 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, | 660 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, |
661 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, | ||
662 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) }, | ||
663 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | ||
664 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | ||
665 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | ||
666 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | ||
667 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1060, 0xff, 0xff, 0xff) }, | ||
668 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1061, 0xff, 0xff, 0xff) }, | ||
669 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1062, 0xff, 0xff, 0xff) }, | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1063, 0xff, 0xff, 0xff) }, | ||
671 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1064, 0xff, 0xff, 0xff) }, | ||
672 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1065, 0xff, 0xff, 0xff) }, | ||
673 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1066, 0xff, 0xff, 0xff) }, | ||
674 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1067, 0xff, 0xff, 0xff) }, | ||
675 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1068, 0xff, 0xff, 0xff) }, | ||
676 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1069, 0xff, 0xff, 0xff) }, | ||
677 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1070, 0xff, 0xff, 0xff) }, | ||
678 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1071, 0xff, 0xff, 0xff) }, | ||
679 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1072, 0xff, 0xff, 0xff) }, | ||
680 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1073, 0xff, 0xff, 0xff) }, | ||
681 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1074, 0xff, 0xff, 0xff) }, | ||
682 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1075, 0xff, 0xff, 0xff) }, | ||
683 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1076, 0xff, 0xff, 0xff) }, | ||
684 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1077, 0xff, 0xff, 0xff) }, | ||
685 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1078, 0xff, 0xff, 0xff) }, | ||
686 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1079, 0xff, 0xff, 0xff) }, | ||
687 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1080, 0xff, 0xff, 0xff) }, | ||
688 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1081, 0xff, 0xff, 0xff) }, | ||
689 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1082, 0xff, 0xff, 0xff) }, | ||
690 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1083, 0xff, 0xff, 0xff) }, | ||
691 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1084, 0xff, 0xff, 0xff) }, | ||
692 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1085, 0xff, 0xff, 0xff) }, | ||
693 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1086, 0xff, 0xff, 0xff) }, | ||
694 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1087, 0xff, 0xff, 0xff) }, | ||
695 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1088, 0xff, 0xff, 0xff) }, | ||
696 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1089, 0xff, 0xff, 0xff) }, | ||
697 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1090, 0xff, 0xff, 0xff) }, | ||
698 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1091, 0xff, 0xff, 0xff) }, | ||
699 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1092, 0xff, 0xff, 0xff) }, | ||
700 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1093, 0xff, 0xff, 0xff) }, | ||
701 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1094, 0xff, 0xff, 0xff) }, | ||
702 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1095, 0xff, 0xff, 0xff) }, | ||
703 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1096, 0xff, 0xff, 0xff) }, | ||
704 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1097, 0xff, 0xff, 0xff) }, | ||
705 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1098, 0xff, 0xff, 0xff) }, | ||
706 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1099, 0xff, 0xff, 0xff) }, | ||
707 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1100, 0xff, 0xff, 0xff) }, | ||
708 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1101, 0xff, 0xff, 0xff) }, | ||
709 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1102, 0xff, 0xff, 0xff) }, | ||
710 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1103, 0xff, 0xff, 0xff) }, | ||
711 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1104, 0xff, 0xff, 0xff) }, | ||
712 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1105, 0xff, 0xff, 0xff) }, | ||
713 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1106, 0xff, 0xff, 0xff) }, | ||
714 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1107, 0xff, 0xff, 0xff) }, | ||
715 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1108, 0xff, 0xff, 0xff) }, | ||
716 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1109, 0xff, 0xff, 0xff) }, | ||
717 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1110, 0xff, 0xff, 0xff) }, | ||
718 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1111, 0xff, 0xff, 0xff) }, | ||
719 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1112, 0xff, 0xff, 0xff) }, | ||
720 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1113, 0xff, 0xff, 0xff) }, | ||
721 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1114, 0xff, 0xff, 0xff) }, | ||
722 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1115, 0xff, 0xff, 0xff) }, | ||
723 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1116, 0xff, 0xff, 0xff) }, | ||
724 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1117, 0xff, 0xff, 0xff) }, | ||
725 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1118, 0xff, 0xff, 0xff) }, | ||
726 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1119, 0xff, 0xff, 0xff) }, | ||
727 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1120, 0xff, 0xff, 0xff) }, | ||
728 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1121, 0xff, 0xff, 0xff) }, | ||
729 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1122, 0xff, 0xff, 0xff) }, | ||
730 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1123, 0xff, 0xff, 0xff) }, | ||
731 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1124, 0xff, 0xff, 0xff) }, | ||
732 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1125, 0xff, 0xff, 0xff) }, | ||
733 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1126, 0xff, 0xff, 0xff) }, | ||
734 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1127, 0xff, 0xff, 0xff) }, | ||
735 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1128, 0xff, 0xff, 0xff) }, | ||
736 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1129, 0xff, 0xff, 0xff) }, | ||
737 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1130, 0xff, 0xff, 0xff) }, | ||
738 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1131, 0xff, 0xff, 0xff) }, | ||
739 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1132, 0xff, 0xff, 0xff) }, | ||
740 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1133, 0xff, 0xff, 0xff) }, | ||
741 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1134, 0xff, 0xff, 0xff) }, | ||
742 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1135, 0xff, 0xff, 0xff) }, | ||
743 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1136, 0xff, 0xff, 0xff) }, | ||
744 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1137, 0xff, 0xff, 0xff) }, | ||
745 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1138, 0xff, 0xff, 0xff) }, | ||
746 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1139, 0xff, 0xff, 0xff) }, | ||
747 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1140, 0xff, 0xff, 0xff) }, | ||
748 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1141, 0xff, 0xff, 0xff) }, | ||
749 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1142, 0xff, 0xff, 0xff) }, | ||
750 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1143, 0xff, 0xff, 0xff) }, | ||
751 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1144, 0xff, 0xff, 0xff) }, | ||
752 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1145, 0xff, 0xff, 0xff) }, | ||
753 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1146, 0xff, 0xff, 0xff) }, | ||
754 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1147, 0xff, 0xff, 0xff) }, | ||
755 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1148, 0xff, 0xff, 0xff) }, | ||
756 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1149, 0xff, 0xff, 0xff) }, | ||
757 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1150, 0xff, 0xff, 0xff) }, | ||
758 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1151, 0xff, 0xff, 0xff) }, | ||
759 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1152, 0xff, 0xff, 0xff) }, | ||
760 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1153, 0xff, 0xff, 0xff) }, | ||
761 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1154, 0xff, 0xff, 0xff) }, | ||
762 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1155, 0xff, 0xff, 0xff) }, | ||
763 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1156, 0xff, 0xff, 0xff) }, | ||
764 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1157, 0xff, 0xff, 0xff) }, | ||
765 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1158, 0xff, 0xff, 0xff) }, | ||
766 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1159, 0xff, 0xff, 0xff) }, | ||
767 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1160, 0xff, 0xff, 0xff) }, | ||
768 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1161, 0xff, 0xff, 0xff) }, | ||
769 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1162, 0xff, 0xff, 0xff) }, | ||
770 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1163, 0xff, 0xff, 0xff) }, | ||
771 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1164, 0xff, 0xff, 0xff) }, | ||
772 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1165, 0xff, 0xff, 0xff) }, | ||
773 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1166, 0xff, 0xff, 0xff) }, | ||
774 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1167, 0xff, 0xff, 0xff) }, | ||
775 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1168, 0xff, 0xff, 0xff) }, | ||
776 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, | ||
777 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, | ||
778 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, | ||
779 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, | ||
780 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, | ||
781 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, | ||
782 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, | ||
783 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, | ||
784 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, | ||
785 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, | ||
786 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, | ||
787 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, | ||
788 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, | ||
789 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, | ||
790 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, | ||
791 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, | ||
792 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, | ||
793 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, | ||
794 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1260, 0xff, 0xff, 0xff) }, | ||
795 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1261, 0xff, 0xff, 0xff) }, | ||
796 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1262, 0xff, 0xff, 0xff) }, | ||
797 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1263, 0xff, 0xff, 0xff) }, | ||
798 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1264, 0xff, 0xff, 0xff) }, | ||
799 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1265, 0xff, 0xff, 0xff) }, | ||
800 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1266, 0xff, 0xff, 0xff) }, | ||
801 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, | ||
802 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, | ||
803 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, | ||
804 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) }, | ||
805 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, | ||
806 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, | ||
807 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, | ||
808 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) }, | ||
809 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) }, | ||
810 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) }, | ||
811 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) }, | ||
812 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) }, | ||
813 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1279, 0xff, 0xff, 0xff) }, | ||
814 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1280, 0xff, 0xff, 0xff) }, | ||
815 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1281, 0xff, 0xff, 0xff) }, | ||
816 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1282, 0xff, 0xff, 0xff) }, | ||
817 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1283, 0xff, 0xff, 0xff) }, | ||
818 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1284, 0xff, 0xff, 0xff) }, | ||
819 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1285, 0xff, 0xff, 0xff) }, | ||
820 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1286, 0xff, 0xff, 0xff) }, | ||
821 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1287, 0xff, 0xff, 0xff) }, | ||
822 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1288, 0xff, 0xff, 0xff) }, | ||
823 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1289, 0xff, 0xff, 0xff) }, | ||
824 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1290, 0xff, 0xff, 0xff) }, | ||
825 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1291, 0xff, 0xff, 0xff) }, | ||
826 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1292, 0xff, 0xff, 0xff) }, | ||
827 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1293, 0xff, 0xff, 0xff) }, | ||
828 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1294, 0xff, 0xff, 0xff) }, | ||
829 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1295, 0xff, 0xff, 0xff) }, | ||
830 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1296, 0xff, 0xff, 0xff) }, | ||
831 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1297, 0xff, 0xff, 0xff) }, | ||
832 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, | ||
833 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, | ||
834 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, | ||
678 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ | 835 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ |
679 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, | 836 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, |
680 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, | 837 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, |
@@ -726,6 +883,8 @@ static const struct usb_device_id option_ids[] = { | |||
726 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | 883 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, |
727 | 884 | ||
728 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, | 885 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, |
886 | |||
887 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, | ||
729 | { } /* Terminating entry */ | 888 | { } /* Terminating entry */ |
730 | }; | 889 | }; |
731 | MODULE_DEVICE_TABLE(usb, option_ids); | 890 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -757,22 +916,22 @@ static struct usb_serial_driver option_1port_device = { | |||
757 | .id_table = option_ids, | 916 | .id_table = option_ids, |
758 | .num_ports = 1, | 917 | .num_ports = 1, |
759 | .probe = option_probe, | 918 | .probe = option_probe, |
760 | .open = option_open, | 919 | .open = usb_wwan_open, |
761 | .close = option_close, | 920 | .close = usb_wwan_close, |
762 | .dtr_rts = option_dtr_rts, | 921 | .dtr_rts = usb_wwan_dtr_rts, |
763 | .write = option_write, | 922 | .write = usb_wwan_write, |
764 | .write_room = option_write_room, | 923 | .write_room = usb_wwan_write_room, |
765 | .chars_in_buffer = option_chars_in_buffer, | 924 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
766 | .set_termios = option_set_termios, | 925 | .set_termios = usb_wwan_set_termios, |
767 | .tiocmget = option_tiocmget, | 926 | .tiocmget = usb_wwan_tiocmget, |
768 | .tiocmset = option_tiocmset, | 927 | .tiocmset = usb_wwan_tiocmset, |
769 | .attach = option_startup, | 928 | .attach = usb_wwan_startup, |
770 | .disconnect = option_disconnect, | 929 | .disconnect = usb_wwan_disconnect, |
771 | .release = option_release, | 930 | .release = usb_wwan_release, |
772 | .read_int_callback = option_instat_callback, | 931 | .read_int_callback = option_instat_callback, |
773 | #ifdef CONFIG_PM | 932 | #ifdef CONFIG_PM |
774 | .suspend = option_suspend, | 933 | .suspend = usb_wwan_suspend, |
775 | .resume = option_resume, | 934 | .resume = usb_wwan_resume, |
776 | #endif | 935 | #endif |
777 | }; | 936 | }; |
778 | 937 | ||
@@ -785,13 +944,6 @@ static int debug; | |||
785 | #define IN_BUFLEN 4096 | 944 | #define IN_BUFLEN 4096 |
786 | #define OUT_BUFLEN 4096 | 945 | #define OUT_BUFLEN 4096 |
787 | 946 | ||
788 | struct option_intf_private { | ||
789 | spinlock_t susp_lock; | ||
790 | unsigned int suspended:1; | ||
791 | int in_flight; | ||
792 | struct option_blacklist_info *blacklist_info; | ||
793 | }; | ||
794 | |||
795 | struct option_port_private { | 947 | struct option_port_private { |
796 | /* Input endpoints and buffer for this port */ | 948 | /* Input endpoints and buffer for this port */ |
797 | struct urb *in_urbs[N_IN_URB]; | 949 | struct urb *in_urbs[N_IN_URB]; |
@@ -848,8 +1000,7 @@ module_exit(option_exit); | |||
848 | static int option_probe(struct usb_serial *serial, | 1000 | static int option_probe(struct usb_serial *serial, |
849 | const struct usb_device_id *id) | 1001 | const struct usb_device_id *id) |
850 | { | 1002 | { |
851 | struct option_intf_private *data; | 1003 | struct usb_wwan_intf_private *data; |
852 | |||
853 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | 1004 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ |
854 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | 1005 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && |
855 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | 1006 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && |
@@ -862,11 +1013,13 @@ static int option_probe(struct usb_serial *serial, | |||
862 | serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) | 1013 | serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) |
863 | return -ENODEV; | 1014 | return -ENODEV; |
864 | 1015 | ||
865 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); | 1016 | data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); |
1017 | |||
866 | if (!data) | 1018 | if (!data) |
867 | return -ENOMEM; | 1019 | return -ENOMEM; |
1020 | data->send_setup = option_send_setup; | ||
868 | spin_lock_init(&data->susp_lock); | 1021 | spin_lock_init(&data->susp_lock); |
869 | data->blacklist_info = (struct option_blacklist_info*) id->driver_info; | 1022 | data->private = (void *)id->driver_info; |
870 | return 0; | 1023 | return 0; |
871 | } | 1024 | } |
872 | 1025 | ||
@@ -887,194 +1040,6 @@ static enum option_blacklist_reason is_blacklisted(const u8 ifnum, | |||
887 | return OPTION_BLACKLIST_NONE; | 1040 | return OPTION_BLACKLIST_NONE; |
888 | } | 1041 | } |
889 | 1042 | ||
890 | static void option_set_termios(struct tty_struct *tty, | ||
891 | struct usb_serial_port *port, struct ktermios *old_termios) | ||
892 | { | ||
893 | dbg("%s", __func__); | ||
894 | /* Doesn't support option setting */ | ||
895 | tty_termios_copy_hw(tty->termios, old_termios); | ||
896 | option_send_setup(port); | ||
897 | } | ||
898 | |||
899 | static int option_tiocmget(struct tty_struct *tty, struct file *file) | ||
900 | { | ||
901 | struct usb_serial_port *port = tty->driver_data; | ||
902 | unsigned int value; | ||
903 | struct option_port_private *portdata; | ||
904 | |||
905 | portdata = usb_get_serial_port_data(port); | ||
906 | |||
907 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | ||
908 | ((portdata->dtr_state) ? TIOCM_DTR : 0) | | ||
909 | ((portdata->cts_state) ? TIOCM_CTS : 0) | | ||
910 | ((portdata->dsr_state) ? TIOCM_DSR : 0) | | ||
911 | ((portdata->dcd_state) ? TIOCM_CAR : 0) | | ||
912 | ((portdata->ri_state) ? TIOCM_RNG : 0); | ||
913 | |||
914 | return value; | ||
915 | } | ||
916 | |||
917 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | ||
918 | unsigned int set, unsigned int clear) | ||
919 | { | ||
920 | struct usb_serial_port *port = tty->driver_data; | ||
921 | struct option_port_private *portdata; | ||
922 | |||
923 | portdata = usb_get_serial_port_data(port); | ||
924 | |||
925 | /* FIXME: what locks portdata fields ? */ | ||
926 | if (set & TIOCM_RTS) | ||
927 | portdata->rts_state = 1; | ||
928 | if (set & TIOCM_DTR) | ||
929 | portdata->dtr_state = 1; | ||
930 | |||
931 | if (clear & TIOCM_RTS) | ||
932 | portdata->rts_state = 0; | ||
933 | if (clear & TIOCM_DTR) | ||
934 | portdata->dtr_state = 0; | ||
935 | return option_send_setup(port); | ||
936 | } | ||
937 | |||
938 | /* Write */ | ||
939 | static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
940 | const unsigned char *buf, int count) | ||
941 | { | ||
942 | struct option_port_private *portdata; | ||
943 | struct option_intf_private *intfdata; | ||
944 | int i; | ||
945 | int left, todo; | ||
946 | struct urb *this_urb = NULL; /* spurious */ | ||
947 | int err; | ||
948 | unsigned long flags; | ||
949 | |||
950 | portdata = usb_get_serial_port_data(port); | ||
951 | intfdata = port->serial->private; | ||
952 | |||
953 | dbg("%s: write (%d chars)", __func__, count); | ||
954 | |||
955 | i = 0; | ||
956 | left = count; | ||
957 | for (i = 0; left > 0 && i < N_OUT_URB; i++) { | ||
958 | todo = left; | ||
959 | if (todo > OUT_BUFLEN) | ||
960 | todo = OUT_BUFLEN; | ||
961 | |||
962 | this_urb = portdata->out_urbs[i]; | ||
963 | if (test_and_set_bit(i, &portdata->out_busy)) { | ||
964 | if (time_before(jiffies, | ||
965 | portdata->tx_start_time[i] + 10 * HZ)) | ||
966 | continue; | ||
967 | usb_unlink_urb(this_urb); | ||
968 | continue; | ||
969 | } | ||
970 | dbg("%s: endpoint %d buf %d", __func__, | ||
971 | usb_pipeendpoint(this_urb->pipe), i); | ||
972 | |||
973 | err = usb_autopm_get_interface_async(port->serial->interface); | ||
974 | if (err < 0) | ||
975 | break; | ||
976 | |||
977 | /* send the data */ | ||
978 | memcpy(this_urb->transfer_buffer, buf, todo); | ||
979 | this_urb->transfer_buffer_length = todo; | ||
980 | |||
981 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
982 | if (intfdata->suspended) { | ||
983 | usb_anchor_urb(this_urb, &portdata->delayed); | ||
984 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
985 | } else { | ||
986 | intfdata->in_flight++; | ||
987 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
988 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
989 | if (err) { | ||
990 | dbg("usb_submit_urb %p (write bulk) failed " | ||
991 | "(%d)", this_urb, err); | ||
992 | clear_bit(i, &portdata->out_busy); | ||
993 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
994 | intfdata->in_flight--; | ||
995 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
996 | continue; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | portdata->tx_start_time[i] = jiffies; | ||
1001 | buf += todo; | ||
1002 | left -= todo; | ||
1003 | } | ||
1004 | |||
1005 | count -= left; | ||
1006 | dbg("%s: wrote (did %d)", __func__, count); | ||
1007 | return count; | ||
1008 | } | ||
1009 | |||
1010 | static void option_indat_callback(struct urb *urb) | ||
1011 | { | ||
1012 | int err; | ||
1013 | int endpoint; | ||
1014 | struct usb_serial_port *port; | ||
1015 | struct tty_struct *tty; | ||
1016 | unsigned char *data = urb->transfer_buffer; | ||
1017 | int status = urb->status; | ||
1018 | |||
1019 | dbg("%s: %p", __func__, urb); | ||
1020 | |||
1021 | endpoint = usb_pipeendpoint(urb->pipe); | ||
1022 | port = urb->context; | ||
1023 | |||
1024 | if (status) { | ||
1025 | dbg("%s: nonzero status: %d on endpoint %02x.", | ||
1026 | __func__, status, endpoint); | ||
1027 | } else { | ||
1028 | tty = tty_port_tty_get(&port->port); | ||
1029 | if (urb->actual_length) { | ||
1030 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1031 | tty_flip_buffer_push(tty); | ||
1032 | } else | ||
1033 | dbg("%s: empty read urb received", __func__); | ||
1034 | tty_kref_put(tty); | ||
1035 | |||
1036 | /* Resubmit urb so we continue receiving */ | ||
1037 | if (status != -ESHUTDOWN) { | ||
1038 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
1039 | if (err && err != -EPERM) | ||
1040 | printk(KERN_ERR "%s: resubmit read urb failed. " | ||
1041 | "(%d)", __func__, err); | ||
1042 | else | ||
1043 | usb_mark_last_busy(port->serial->dev); | ||
1044 | } | ||
1045 | |||
1046 | } | ||
1047 | return; | ||
1048 | } | ||
1049 | |||
1050 | static void option_outdat_callback(struct urb *urb) | ||
1051 | { | ||
1052 | struct usb_serial_port *port; | ||
1053 | struct option_port_private *portdata; | ||
1054 | struct option_intf_private *intfdata; | ||
1055 | int i; | ||
1056 | |||
1057 | dbg("%s", __func__); | ||
1058 | |||
1059 | port = urb->context; | ||
1060 | intfdata = port->serial->private; | ||
1061 | |||
1062 | usb_serial_port_softint(port); | ||
1063 | usb_autopm_put_interface_async(port->serial->interface); | ||
1064 | portdata = usb_get_serial_port_data(port); | ||
1065 | spin_lock(&intfdata->susp_lock); | ||
1066 | intfdata->in_flight--; | ||
1067 | spin_unlock(&intfdata->susp_lock); | ||
1068 | |||
1069 | for (i = 0; i < N_OUT_URB; ++i) { | ||
1070 | if (portdata->out_urbs[i] == urb) { | ||
1071 | smp_mb__before_clear_bit(); | ||
1072 | clear_bit(i, &portdata->out_busy); | ||
1073 | break; | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | static void option_instat_callback(struct urb *urb) | 1043 | static void option_instat_callback(struct urb *urb) |
1079 | { | 1044 | { |
1080 | int err; | 1045 | int err; |
@@ -1131,183 +1096,6 @@ static void option_instat_callback(struct urb *urb) | |||
1131 | } | 1096 | } |
1132 | } | 1097 | } |
1133 | 1098 | ||
1134 | static int option_write_room(struct tty_struct *tty) | ||
1135 | { | ||
1136 | struct usb_serial_port *port = tty->driver_data; | ||
1137 | struct option_port_private *portdata; | ||
1138 | int i; | ||
1139 | int data_len = 0; | ||
1140 | struct urb *this_urb; | ||
1141 | |||
1142 | portdata = usb_get_serial_port_data(port); | ||
1143 | |||
1144 | for (i = 0; i < N_OUT_URB; i++) { | ||
1145 | this_urb = portdata->out_urbs[i]; | ||
1146 | if (this_urb && !test_bit(i, &portdata->out_busy)) | ||
1147 | data_len += OUT_BUFLEN; | ||
1148 | } | ||
1149 | |||
1150 | dbg("%s: %d", __func__, data_len); | ||
1151 | return data_len; | ||
1152 | } | ||
1153 | |||
1154 | static int option_chars_in_buffer(struct tty_struct *tty) | ||
1155 | { | ||
1156 | struct usb_serial_port *port = tty->driver_data; | ||
1157 | struct option_port_private *portdata; | ||
1158 | int i; | ||
1159 | int data_len = 0; | ||
1160 | struct urb *this_urb; | ||
1161 | |||
1162 | portdata = usb_get_serial_port_data(port); | ||
1163 | |||
1164 | for (i = 0; i < N_OUT_URB; i++) { | ||
1165 | this_urb = portdata->out_urbs[i]; | ||
1166 | /* FIXME: This locking is insufficient as this_urb may | ||
1167 | go unused during the test */ | ||
1168 | if (this_urb && test_bit(i, &portdata->out_busy)) | ||
1169 | data_len += this_urb->transfer_buffer_length; | ||
1170 | } | ||
1171 | dbg("%s: %d", __func__, data_len); | ||
1172 | return data_len; | ||
1173 | } | ||
1174 | |||
1175 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
1176 | { | ||
1177 | struct option_port_private *portdata; | ||
1178 | struct option_intf_private *intfdata; | ||
1179 | struct usb_serial *serial = port->serial; | ||
1180 | int i, err; | ||
1181 | struct urb *urb; | ||
1182 | |||
1183 | portdata = usb_get_serial_port_data(port); | ||
1184 | intfdata = serial->private; | ||
1185 | |||
1186 | dbg("%s", __func__); | ||
1187 | |||
1188 | /* Start reading from the IN endpoint */ | ||
1189 | for (i = 0; i < N_IN_URB; i++) { | ||
1190 | urb = portdata->in_urbs[i]; | ||
1191 | if (!urb) | ||
1192 | continue; | ||
1193 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
1194 | if (err) { | ||
1195 | dbg("%s: submit urb %d failed (%d) %d", | ||
1196 | __func__, i, err, | ||
1197 | urb->transfer_buffer_length); | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | option_send_setup(port); | ||
1202 | |||
1203 | serial->interface->needs_remote_wakeup = 1; | ||
1204 | spin_lock_irq(&intfdata->susp_lock); | ||
1205 | portdata->opened = 1; | ||
1206 | spin_unlock_irq(&intfdata->susp_lock); | ||
1207 | usb_autopm_put_interface(serial->interface); | ||
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | static void option_dtr_rts(struct usb_serial_port *port, int on) | ||
1213 | { | ||
1214 | struct usb_serial *serial = port->serial; | ||
1215 | struct option_port_private *portdata; | ||
1216 | |||
1217 | dbg("%s", __func__); | ||
1218 | portdata = usb_get_serial_port_data(port); | ||
1219 | mutex_lock(&serial->disc_mutex); | ||
1220 | portdata->rts_state = on; | ||
1221 | portdata->dtr_state = on; | ||
1222 | if (serial->dev) | ||
1223 | option_send_setup(port); | ||
1224 | mutex_unlock(&serial->disc_mutex); | ||
1225 | } | ||
1226 | |||
1227 | |||
1228 | static void option_close(struct usb_serial_port *port) | ||
1229 | { | ||
1230 | int i; | ||
1231 | struct usb_serial *serial = port->serial; | ||
1232 | struct option_port_private *portdata; | ||
1233 | struct option_intf_private *intfdata = port->serial->private; | ||
1234 | |||
1235 | dbg("%s", __func__); | ||
1236 | portdata = usb_get_serial_port_data(port); | ||
1237 | |||
1238 | if (serial->dev) { | ||
1239 | /* Stop reading/writing urbs */ | ||
1240 | spin_lock_irq(&intfdata->susp_lock); | ||
1241 | portdata->opened = 0; | ||
1242 | spin_unlock_irq(&intfdata->susp_lock); | ||
1243 | |||
1244 | for (i = 0; i < N_IN_URB; i++) | ||
1245 | usb_kill_urb(portdata->in_urbs[i]); | ||
1246 | for (i = 0; i < N_OUT_URB; i++) | ||
1247 | usb_kill_urb(portdata->out_urbs[i]); | ||
1248 | usb_autopm_get_interface(serial->interface); | ||
1249 | serial->interface->needs_remote_wakeup = 0; | ||
1250 | } | ||
1251 | } | ||
1252 | |||
1253 | /* Helper functions used by option_setup_urbs */ | ||
1254 | static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint, | ||
1255 | int dir, void *ctx, char *buf, int len, | ||
1256 | void (*callback)(struct urb *)) | ||
1257 | { | ||
1258 | struct urb *urb; | ||
1259 | |||
1260 | if (endpoint == -1) | ||
1261 | return NULL; /* endpoint not needed */ | ||
1262 | |||
1263 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | ||
1264 | if (urb == NULL) { | ||
1265 | dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); | ||
1266 | return NULL; | ||
1267 | } | ||
1268 | |||
1269 | /* Fill URB using supplied data. */ | ||
1270 | usb_fill_bulk_urb(urb, serial->dev, | ||
1271 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
1272 | buf, len, callback, ctx); | ||
1273 | |||
1274 | return urb; | ||
1275 | } | ||
1276 | |||
1277 | /* Setup urbs */ | ||
1278 | static void option_setup_urbs(struct usb_serial *serial) | ||
1279 | { | ||
1280 | int i, j; | ||
1281 | struct usb_serial_port *port; | ||
1282 | struct option_port_private *portdata; | ||
1283 | |||
1284 | dbg("%s", __func__); | ||
1285 | |||
1286 | for (i = 0; i < serial->num_ports; i++) { | ||
1287 | port = serial->port[i]; | ||
1288 | portdata = usb_get_serial_port_data(port); | ||
1289 | |||
1290 | /* Do indat endpoints first */ | ||
1291 | for (j = 0; j < N_IN_URB; ++j) { | ||
1292 | portdata->in_urbs[j] = option_setup_urb(serial, | ||
1293 | port->bulk_in_endpointAddress, | ||
1294 | USB_DIR_IN, port, | ||
1295 | portdata->in_buffer[j], | ||
1296 | IN_BUFLEN, option_indat_callback); | ||
1297 | } | ||
1298 | |||
1299 | /* outdat endpoints */ | ||
1300 | for (j = 0; j < N_OUT_URB; ++j) { | ||
1301 | portdata->out_urbs[j] = option_setup_urb(serial, | ||
1302 | port->bulk_out_endpointAddress, | ||
1303 | USB_DIR_OUT, port, | ||
1304 | portdata->out_buffer[j], | ||
1305 | OUT_BUFLEN, option_outdat_callback); | ||
1306 | } | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1310 | |||
1311 | /** send RTS/DTR state to the port. | 1099 | /** send RTS/DTR state to the port. |
1312 | * | 1100 | * |
1313 | * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN | 1101 | * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN |
@@ -1316,15 +1104,16 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
1316 | static int option_send_setup(struct usb_serial_port *port) | 1104 | static int option_send_setup(struct usb_serial_port *port) |
1317 | { | 1105 | { |
1318 | struct usb_serial *serial = port->serial; | 1106 | struct usb_serial *serial = port->serial; |
1319 | struct option_intf_private *intfdata = | 1107 | struct usb_wwan_intf_private *intfdata = |
1320 | (struct option_intf_private *) serial->private; | 1108 | (struct usb_wwan_intf_private *) serial->private; |
1321 | struct option_port_private *portdata; | 1109 | struct option_port_private *portdata; |
1322 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 1110 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
1323 | int val = 0; | 1111 | int val = 0; |
1324 | dbg("%s", __func__); | 1112 | dbg("%s", __func__); |
1325 | 1113 | ||
1326 | if (is_blacklisted(ifNum, intfdata->blacklist_info) == | 1114 | if (is_blacklisted(ifNum, |
1327 | OPTION_BLACKLIST_SENDSETUP) { | 1115 | (struct option_blacklist_info *) intfdata->private) |
1116 | == OPTION_BLACKLIST_SENDSETUP) { | ||
1328 | dbg("No send_setup on blacklisted interface #%d\n", ifNum); | 1117 | dbg("No send_setup on blacklisted interface #%d\n", ifNum); |
1329 | return -EIO; | 1118 | return -EIO; |
1330 | } | 1119 | } |
@@ -1341,224 +1130,6 @@ static int option_send_setup(struct usb_serial_port *port) | |||
1341 | 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); | 1130 | 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); |
1342 | } | 1131 | } |
1343 | 1132 | ||
1344 | static int option_startup(struct usb_serial *serial) | ||
1345 | { | ||
1346 | int i, j, err; | ||
1347 | struct usb_serial_port *port; | ||
1348 | struct option_port_private *portdata; | ||
1349 | u8 *buffer; | ||
1350 | |||
1351 | dbg("%s", __func__); | ||
1352 | |||
1353 | /* Now setup per port private data */ | ||
1354 | for (i = 0; i < serial->num_ports; i++) { | ||
1355 | port = serial->port[i]; | ||
1356 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
1357 | if (!portdata) { | ||
1358 | dbg("%s: kmalloc for option_port_private (%d) failed!.", | ||
1359 | __func__, i); | ||
1360 | return 1; | ||
1361 | } | ||
1362 | init_usb_anchor(&portdata->delayed); | ||
1363 | |||
1364 | for (j = 0; j < N_IN_URB; j++) { | ||
1365 | buffer = (u8 *)__get_free_page(GFP_KERNEL); | ||
1366 | if (!buffer) | ||
1367 | goto bail_out_error; | ||
1368 | portdata->in_buffer[j] = buffer; | ||
1369 | } | ||
1370 | |||
1371 | for (j = 0; j < N_OUT_URB; j++) { | ||
1372 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); | ||
1373 | if (!buffer) | ||
1374 | goto bail_out_error2; | ||
1375 | portdata->out_buffer[j] = buffer; | ||
1376 | } | ||
1377 | |||
1378 | usb_set_serial_port_data(port, portdata); | ||
1379 | |||
1380 | if (!port->interrupt_in_urb) | ||
1381 | continue; | ||
1382 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
1383 | if (err) | ||
1384 | dbg("%s: submit irq_in urb failed %d", | ||
1385 | __func__, err); | ||
1386 | } | ||
1387 | option_setup_urbs(serial); | ||
1388 | return 0; | ||
1389 | |||
1390 | bail_out_error2: | ||
1391 | for (j = 0; j < N_OUT_URB; j++) | ||
1392 | kfree(portdata->out_buffer[j]); | ||
1393 | bail_out_error: | ||
1394 | for (j = 0; j < N_IN_URB; j++) | ||
1395 | if (portdata->in_buffer[j]) | ||
1396 | free_page((unsigned long)portdata->in_buffer[j]); | ||
1397 | kfree(portdata); | ||
1398 | return 1; | ||
1399 | } | ||
1400 | |||
1401 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
1402 | { | ||
1403 | int i, j; | ||
1404 | struct usb_serial_port *port; | ||
1405 | struct option_port_private *portdata; | ||
1406 | |||
1407 | /* Stop reading/writing urbs */ | ||
1408 | for (i = 0; i < serial->num_ports; ++i) { | ||
1409 | port = serial->port[i]; | ||
1410 | portdata = usb_get_serial_port_data(port); | ||
1411 | for (j = 0; j < N_IN_URB; j++) | ||
1412 | usb_kill_urb(portdata->in_urbs[j]); | ||
1413 | for (j = 0; j < N_OUT_URB; j++) | ||
1414 | usb_kill_urb(portdata->out_urbs[j]); | ||
1415 | } | ||
1416 | } | ||
1417 | |||
1418 | static void option_disconnect(struct usb_serial *serial) | ||
1419 | { | ||
1420 | dbg("%s", __func__); | ||
1421 | |||
1422 | stop_read_write_urbs(serial); | ||
1423 | } | ||
1424 | |||
1425 | static void option_release(struct usb_serial *serial) | ||
1426 | { | ||
1427 | int i, j; | ||
1428 | struct usb_serial_port *port; | ||
1429 | struct option_port_private *portdata; | ||
1430 | |||
1431 | dbg("%s", __func__); | ||
1432 | |||
1433 | /* Now free them */ | ||
1434 | for (i = 0; i < serial->num_ports; ++i) { | ||
1435 | port = serial->port[i]; | ||
1436 | portdata = usb_get_serial_port_data(port); | ||
1437 | |||
1438 | for (j = 0; j < N_IN_URB; j++) { | ||
1439 | if (portdata->in_urbs[j]) { | ||
1440 | usb_free_urb(portdata->in_urbs[j]); | ||
1441 | free_page((unsigned long) | ||
1442 | portdata->in_buffer[j]); | ||
1443 | portdata->in_urbs[j] = NULL; | ||
1444 | } | ||
1445 | } | ||
1446 | for (j = 0; j < N_OUT_URB; j++) { | ||
1447 | if (portdata->out_urbs[j]) { | ||
1448 | usb_free_urb(portdata->out_urbs[j]); | ||
1449 | kfree(portdata->out_buffer[j]); | ||
1450 | portdata->out_urbs[j] = NULL; | ||
1451 | } | ||
1452 | } | ||
1453 | } | ||
1454 | |||
1455 | /* Now free per port private data */ | ||
1456 | for (i = 0; i < serial->num_ports; i++) { | ||
1457 | port = serial->port[i]; | ||
1458 | kfree(usb_get_serial_port_data(port)); | ||
1459 | } | ||
1460 | } | ||
1461 | |||
1462 | #ifdef CONFIG_PM | ||
1463 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | ||
1464 | { | ||
1465 | struct option_intf_private *intfdata = serial->private; | ||
1466 | int b; | ||
1467 | |||
1468 | dbg("%s entered", __func__); | ||
1469 | |||
1470 | if (message.event & PM_EVENT_AUTO) { | ||
1471 | spin_lock_irq(&intfdata->susp_lock); | ||
1472 | b = intfdata->in_flight; | ||
1473 | spin_unlock_irq(&intfdata->susp_lock); | ||
1474 | |||
1475 | if (b) | ||
1476 | return -EBUSY; | ||
1477 | } | ||
1478 | |||
1479 | spin_lock_irq(&intfdata->susp_lock); | ||
1480 | intfdata->suspended = 1; | ||
1481 | spin_unlock_irq(&intfdata->susp_lock); | ||
1482 | stop_read_write_urbs(serial); | ||
1483 | |||
1484 | return 0; | ||
1485 | } | ||
1486 | |||
1487 | static void play_delayed(struct usb_serial_port *port) | ||
1488 | { | ||
1489 | struct option_intf_private *data; | ||
1490 | struct option_port_private *portdata; | ||
1491 | struct urb *urb; | ||
1492 | int err; | ||
1493 | |||
1494 | portdata = usb_get_serial_port_data(port); | ||
1495 | data = port->serial->private; | ||
1496 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | ||
1497 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
1498 | if (!err) | ||
1499 | data->in_flight++; | ||
1500 | } | ||
1501 | } | ||
1502 | |||
1503 | static int option_resume(struct usb_serial *serial) | ||
1504 | { | ||
1505 | int i, j; | ||
1506 | struct usb_serial_port *port; | ||
1507 | struct option_intf_private *intfdata = serial->private; | ||
1508 | struct option_port_private *portdata; | ||
1509 | struct urb *urb; | ||
1510 | int err = 0; | ||
1511 | |||
1512 | dbg("%s entered", __func__); | ||
1513 | /* get the interrupt URBs resubmitted unconditionally */ | ||
1514 | for (i = 0; i < serial->num_ports; i++) { | ||
1515 | port = serial->port[i]; | ||
1516 | if (!port->interrupt_in_urb) { | ||
1517 | dbg("%s: No interrupt URB for port %d", __func__, i); | ||
1518 | continue; | ||
1519 | } | ||
1520 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | ||
1521 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | ||
1522 | if (err < 0) { | ||
1523 | err("%s: Error %d for interrupt URB of port%d", | ||
1524 | __func__, err, i); | ||
1525 | goto err_out; | ||
1526 | } | ||
1527 | } | ||
1528 | |||
1529 | for (i = 0; i < serial->num_ports; i++) { | ||
1530 | /* walk all ports */ | ||
1531 | port = serial->port[i]; | ||
1532 | portdata = usb_get_serial_port_data(port); | ||
1533 | |||
1534 | /* skip closed ports */ | ||
1535 | spin_lock_irq(&intfdata->susp_lock); | ||
1536 | if (!portdata->opened) { | ||
1537 | spin_unlock_irq(&intfdata->susp_lock); | ||
1538 | continue; | ||
1539 | } | ||
1540 | |||
1541 | for (j = 0; j < N_IN_URB; j++) { | ||
1542 | urb = portdata->in_urbs[j]; | ||
1543 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
1544 | if (err < 0) { | ||
1545 | err("%s: Error %d for bulk URB %d", | ||
1546 | __func__, err, i); | ||
1547 | spin_unlock_irq(&intfdata->susp_lock); | ||
1548 | goto err_out; | ||
1549 | } | ||
1550 | } | ||
1551 | play_delayed(port); | ||
1552 | spin_unlock_irq(&intfdata->susp_lock); | ||
1553 | } | ||
1554 | spin_lock_irq(&intfdata->susp_lock); | ||
1555 | intfdata->suspended = 0; | ||
1556 | spin_unlock_irq(&intfdata->susp_lock); | ||
1557 | err_out: | ||
1558 | return err; | ||
1559 | } | ||
1560 | #endif | ||
1561 | |||
1562 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1133 | MODULE_AUTHOR(DRIVER_AUTHOR); |
1563 | MODULE_DESCRIPTION(DRIVER_DESC); | 1134 | MODULE_DESCRIPTION(DRIVER_DESC); |
1564 | MODULE_VERSION(DRIVER_VERSION); | 1135 | MODULE_VERSION(DRIVER_VERSION); |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index deeacdea05db..e199b0f4f99c 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -51,12 +51,13 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/usb/serial.h> | 52 | #include <linux/usb/serial.h> |
53 | #include <linux/uaccess.h> | 53 | #include <linux/uaccess.h> |
54 | #include <linux/kfifo.h> | ||
54 | #include "oti6858.h" | 55 | #include "oti6858.h" |
55 | 56 | ||
56 | #define OTI6858_DESCRIPTION \ | 57 | #define OTI6858_DESCRIPTION \ |
57 | "Ours Technology Inc. OTi-6858 USB to serial adapter driver" | 58 | "Ours Technology Inc. OTi-6858 USB to serial adapter driver" |
58 | #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" | 59 | #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" |
59 | #define OTI6858_VERSION "0.1" | 60 | #define OTI6858_VERSION "0.2" |
60 | 61 | ||
61 | static const struct usb_device_id id_table[] = { | 62 | static const struct usb_device_id id_table[] = { |
62 | { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, | 63 | { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, |
@@ -75,18 +76,6 @@ static struct usb_driver oti6858_driver = { | |||
75 | 76 | ||
76 | static int debug; | 77 | static int debug; |
77 | 78 | ||
78 | |||
79 | /* buffering code, copied from pl2303 driver */ | ||
80 | #define PL2303_BUF_SIZE 1024 | ||
81 | #define PL2303_TMP_BUF_SIZE 1024 | ||
82 | |||
83 | struct oti6858_buf { | ||
84 | unsigned int buf_size; | ||
85 | char *buf_buf; | ||
86 | char *buf_get; | ||
87 | char *buf_put; | ||
88 | }; | ||
89 | |||
90 | /* requests */ | 79 | /* requests */ |
91 | #define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) | 80 | #define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) |
92 | #define OTI6858_REQ_T_GET_STATUS 0x01 | 81 | #define OTI6858_REQ_T_GET_STATUS 0x01 |
@@ -161,18 +150,6 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, | |||
161 | static int oti6858_startup(struct usb_serial *serial); | 150 | static int oti6858_startup(struct usb_serial *serial); |
162 | static void oti6858_release(struct usb_serial *serial); | 151 | static void oti6858_release(struct usb_serial *serial); |
163 | 152 | ||
164 | /* functions operating on buffers */ | ||
165 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); | ||
166 | static void oti6858_buf_free(struct oti6858_buf *pb); | ||
167 | static void oti6858_buf_clear(struct oti6858_buf *pb); | ||
168 | static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb); | ||
169 | static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb); | ||
170 | static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf, | ||
171 | unsigned int count); | ||
172 | static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf, | ||
173 | unsigned int count); | ||
174 | |||
175 | |||
176 | /* device info */ | 153 | /* device info */ |
177 | static struct usb_serial_driver oti6858_device = { | 154 | static struct usb_serial_driver oti6858_device = { |
178 | .driver = { | 155 | .driver = { |
@@ -201,7 +178,6 @@ static struct usb_serial_driver oti6858_device = { | |||
201 | struct oti6858_private { | 178 | struct oti6858_private { |
202 | spinlock_t lock; | 179 | spinlock_t lock; |
203 | 180 | ||
204 | struct oti6858_buf *buf; | ||
205 | struct oti6858_control_pkt status; | 181 | struct oti6858_control_pkt status; |
206 | 182 | ||
207 | struct { | 183 | struct { |
@@ -295,7 +271,7 @@ static void setup_line(struct work_struct *work) | |||
295 | } | 271 | } |
296 | } | 272 | } |
297 | 273 | ||
298 | void send_data(struct work_struct *work) | 274 | static void send_data(struct work_struct *work) |
299 | { | 275 | { |
300 | struct oti6858_private *priv = container_of(work, | 276 | struct oti6858_private *priv = container_of(work, |
301 | struct oti6858_private, delayed_write_work.work); | 277 | struct oti6858_private, delayed_write_work.work); |
@@ -314,9 +290,12 @@ void send_data(struct work_struct *work) | |||
314 | return; | 290 | return; |
315 | } | 291 | } |
316 | priv->flags.write_urb_in_use = 1; | 292 | priv->flags.write_urb_in_use = 1; |
317 | |||
318 | count = oti6858_buf_data_avail(priv->buf); | ||
319 | spin_unlock_irqrestore(&priv->lock, flags); | 293 | spin_unlock_irqrestore(&priv->lock, flags); |
294 | |||
295 | spin_lock_irqsave(&port->lock, flags); | ||
296 | count = kfifo_len(&port->write_fifo); | ||
297 | spin_unlock_irqrestore(&port->lock, flags); | ||
298 | |||
320 | if (count > port->bulk_out_size) | 299 | if (count > port->bulk_out_size) |
321 | count = port->bulk_out_size; | 300 | count = port->bulk_out_size; |
322 | 301 | ||
@@ -350,10 +329,9 @@ void send_data(struct work_struct *work) | |||
350 | return; | 329 | return; |
351 | } | 330 | } |
352 | 331 | ||
353 | spin_lock_irqsave(&priv->lock, flags); | 332 | count = kfifo_out_locked(&port->write_fifo, |
354 | oti6858_buf_get(priv->buf, port->write_urb->transfer_buffer, count); | 333 | port->write_urb->transfer_buffer, |
355 | spin_unlock_irqrestore(&priv->lock, flags); | 334 | count, &port->lock); |
356 | |||
357 | port->write_urb->transfer_buffer_length = count; | 335 | port->write_urb->transfer_buffer_length = count; |
358 | port->write_urb->dev = port->serial->dev; | 336 | port->write_urb->dev = port->serial->dev; |
359 | result = usb_submit_urb(port->write_urb, GFP_NOIO); | 337 | result = usb_submit_urb(port->write_urb, GFP_NOIO); |
@@ -376,11 +354,6 @@ static int oti6858_startup(struct usb_serial *serial) | |||
376 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); | 354 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); |
377 | if (!priv) | 355 | if (!priv) |
378 | break; | 356 | break; |
379 | priv->buf = oti6858_buf_alloc(PL2303_BUF_SIZE); | ||
380 | if (priv->buf == NULL) { | ||
381 | kfree(priv); | ||
382 | break; | ||
383 | } | ||
384 | 357 | ||
385 | spin_lock_init(&priv->lock); | 358 | spin_lock_init(&priv->lock); |
386 | init_waitqueue_head(&priv->intr_wait); | 359 | init_waitqueue_head(&priv->intr_wait); |
@@ -397,7 +370,6 @@ static int oti6858_startup(struct usb_serial *serial) | |||
397 | 370 | ||
398 | for (--i; i >= 0; --i) { | 371 | for (--i; i >= 0; --i) { |
399 | priv = usb_get_serial_port_data(serial->port[i]); | 372 | priv = usb_get_serial_port_data(serial->port[i]); |
400 | oti6858_buf_free(priv->buf); | ||
401 | kfree(priv); | 373 | kfree(priv); |
402 | usb_set_serial_port_data(serial->port[i], NULL); | 374 | usb_set_serial_port_data(serial->port[i], NULL); |
403 | } | 375 | } |
@@ -407,17 +379,12 @@ static int oti6858_startup(struct usb_serial *serial) | |||
407 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, | 379 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
408 | const unsigned char *buf, int count) | 380 | const unsigned char *buf, int count) |
409 | { | 381 | { |
410 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
411 | unsigned long flags; | ||
412 | |||
413 | dbg("%s(port = %d, count = %d)", __func__, port->number, count); | 382 | dbg("%s(port = %d, count = %d)", __func__, port->number, count); |
414 | 383 | ||
415 | if (!count) | 384 | if (!count) |
416 | return count; | 385 | return count; |
417 | 386 | ||
418 | spin_lock_irqsave(&priv->lock, flags); | 387 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); |
419 | count = oti6858_buf_put(priv->buf, buf, count); | ||
420 | spin_unlock_irqrestore(&priv->lock, flags); | ||
421 | 388 | ||
422 | return count; | 389 | return count; |
423 | } | 390 | } |
@@ -425,15 +392,14 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
425 | static int oti6858_write_room(struct tty_struct *tty) | 392 | static int oti6858_write_room(struct tty_struct *tty) |
426 | { | 393 | { |
427 | struct usb_serial_port *port = tty->driver_data; | 394 | struct usb_serial_port *port = tty->driver_data; |
428 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
429 | int room = 0; | 395 | int room = 0; |
430 | unsigned long flags; | 396 | unsigned long flags; |
431 | 397 | ||
432 | dbg("%s(port = %d)", __func__, port->number); | 398 | dbg("%s(port = %d)", __func__, port->number); |
433 | 399 | ||
434 | spin_lock_irqsave(&priv->lock, flags); | 400 | spin_lock_irqsave(&port->lock, flags); |
435 | room = oti6858_buf_space_avail(priv->buf); | 401 | room = kfifo_avail(&port->write_fifo); |
436 | spin_unlock_irqrestore(&priv->lock, flags); | 402 | spin_unlock_irqrestore(&port->lock, flags); |
437 | 403 | ||
438 | return room; | 404 | return room; |
439 | } | 405 | } |
@@ -441,15 +407,14 @@ static int oti6858_write_room(struct tty_struct *tty) | |||
441 | static int oti6858_chars_in_buffer(struct tty_struct *tty) | 407 | static int oti6858_chars_in_buffer(struct tty_struct *tty) |
442 | { | 408 | { |
443 | struct usb_serial_port *port = tty->driver_data; | 409 | struct usb_serial_port *port = tty->driver_data; |
444 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
445 | int chars = 0; | 410 | int chars = 0; |
446 | unsigned long flags; | 411 | unsigned long flags; |
447 | 412 | ||
448 | dbg("%s(port = %d)", __func__, port->number); | 413 | dbg("%s(port = %d)", __func__, port->number); |
449 | 414 | ||
450 | spin_lock_irqsave(&priv->lock, flags); | 415 | spin_lock_irqsave(&port->lock, flags); |
451 | chars = oti6858_buf_data_avail(priv->buf); | 416 | chars = kfifo_len(&port->write_fifo); |
452 | spin_unlock_irqrestore(&priv->lock, flags); | 417 | spin_unlock_irqrestore(&port->lock, flags); |
453 | 418 | ||
454 | return chars; | 419 | return chars; |
455 | } | 420 | } |
@@ -640,10 +605,10 @@ static void oti6858_close(struct usb_serial_port *port) | |||
640 | 605 | ||
641 | dbg("%s(port = %d)", __func__, port->number); | 606 | dbg("%s(port = %d)", __func__, port->number); |
642 | 607 | ||
643 | spin_lock_irqsave(&priv->lock, flags); | 608 | spin_lock_irqsave(&port->lock, flags); |
644 | /* clear out any remaining data in the buffer */ | 609 | /* clear out any remaining data in the buffer */ |
645 | oti6858_buf_clear(priv->buf); | 610 | kfifo_reset_out(&port->write_fifo); |
646 | spin_unlock_irqrestore(&priv->lock, flags); | 611 | spin_unlock_irqrestore(&port->lock, flags); |
647 | 612 | ||
648 | dbg("%s(): after buf_clear()", __func__); | 613 | dbg("%s(): after buf_clear()", __func__); |
649 | 614 | ||
@@ -785,18 +750,12 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | |||
785 | 750 | ||
786 | static void oti6858_release(struct usb_serial *serial) | 751 | static void oti6858_release(struct usb_serial *serial) |
787 | { | 752 | { |
788 | struct oti6858_private *priv; | ||
789 | int i; | 753 | int i; |
790 | 754 | ||
791 | dbg("%s()", __func__); | 755 | dbg("%s()", __func__); |
792 | 756 | ||
793 | for (i = 0; i < serial->num_ports; ++i) { | 757 | for (i = 0; i < serial->num_ports; ++i) |
794 | priv = usb_get_serial_port_data(serial->port[i]); | 758 | kfree(usb_get_serial_port_data(serial->port[i])); |
795 | if (priv) { | ||
796 | oti6858_buf_free(priv->buf); | ||
797 | kfree(priv); | ||
798 | } | ||
799 | } | ||
800 | } | 759 | } |
801 | 760 | ||
802 | static void oti6858_read_int_callback(struct urb *urb) | 761 | static void oti6858_read_int_callback(struct urb *urb) |
@@ -889,10 +848,14 @@ static void oti6858_read_int_callback(struct urb *urb) | |||
889 | } | 848 | } |
890 | } else if (!transient) { | 849 | } else if (!transient) { |
891 | unsigned long flags; | 850 | unsigned long flags; |
851 | int count; | ||
852 | |||
853 | spin_lock_irqsave(&port->lock, flags); | ||
854 | count = kfifo_len(&port->write_fifo); | ||
855 | spin_unlock_irqrestore(&port->lock, flags); | ||
892 | 856 | ||
893 | spin_lock_irqsave(&priv->lock, flags); | 857 | spin_lock_irqsave(&priv->lock, flags); |
894 | if (priv->flags.write_urb_in_use == 0 | 858 | if (priv->flags.write_urb_in_use == 0 && count != 0) { |
895 | && oti6858_buf_data_avail(priv->buf) != 0) { | ||
896 | schedule_delayed_work(&priv->delayed_write_work, 0); | 859 | schedule_delayed_work(&priv->delayed_write_work, 0); |
897 | resubmit = 0; | 860 | resubmit = 0; |
898 | } | 861 | } |
@@ -1014,165 +977,6 @@ static void oti6858_write_bulk_callback(struct urb *urb) | |||
1014 | } | 977 | } |
1015 | } | 978 | } |
1016 | 979 | ||
1017 | |||
1018 | /* | ||
1019 | * oti6858_buf_alloc | ||
1020 | * | ||
1021 | * Allocate a circular buffer and all associated memory. | ||
1022 | */ | ||
1023 | static struct oti6858_buf *oti6858_buf_alloc(unsigned int size) | ||
1024 | { | ||
1025 | struct oti6858_buf *pb; | ||
1026 | |||
1027 | if (size == 0) | ||
1028 | return NULL; | ||
1029 | |||
1030 | pb = kmalloc(sizeof(struct oti6858_buf), GFP_KERNEL); | ||
1031 | if (pb == NULL) | ||
1032 | return NULL; | ||
1033 | |||
1034 | pb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
1035 | if (pb->buf_buf == NULL) { | ||
1036 | kfree(pb); | ||
1037 | return NULL; | ||
1038 | } | ||
1039 | |||
1040 | pb->buf_size = size; | ||
1041 | pb->buf_get = pb->buf_put = pb->buf_buf; | ||
1042 | |||
1043 | return pb; | ||
1044 | } | ||
1045 | |||
1046 | /* | ||
1047 | * oti6858_buf_free | ||
1048 | * | ||
1049 | * Free the buffer and all associated memory. | ||
1050 | */ | ||
1051 | static void oti6858_buf_free(struct oti6858_buf *pb) | ||
1052 | { | ||
1053 | if (pb) { | ||
1054 | kfree(pb->buf_buf); | ||
1055 | kfree(pb); | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | /* | ||
1060 | * oti6858_buf_clear | ||
1061 | * | ||
1062 | * Clear out all data in the circular buffer. | ||
1063 | */ | ||
1064 | static void oti6858_buf_clear(struct oti6858_buf *pb) | ||
1065 | { | ||
1066 | if (pb != NULL) { | ||
1067 | /* equivalent to a get of all data available */ | ||
1068 | pb->buf_get = pb->buf_put; | ||
1069 | } | ||
1070 | } | ||
1071 | |||
1072 | /* | ||
1073 | * oti6858_buf_data_avail | ||
1074 | * | ||
1075 | * Return the number of bytes of data available in the circular | ||
1076 | * buffer. | ||
1077 | */ | ||
1078 | static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb) | ||
1079 | { | ||
1080 | if (pb == NULL) | ||
1081 | return 0; | ||
1082 | return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; | ||
1083 | } | ||
1084 | |||
1085 | /* | ||
1086 | * oti6858_buf_space_avail | ||
1087 | * | ||
1088 | * Return the number of bytes of space available in the circular | ||
1089 | * buffer. | ||
1090 | */ | ||
1091 | static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb) | ||
1092 | { | ||
1093 | if (pb == NULL) | ||
1094 | return 0; | ||
1095 | return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; | ||
1096 | } | ||
1097 | |||
1098 | /* | ||
1099 | * oti6858_buf_put | ||
1100 | * | ||
1101 | * Copy data data from a user buffer and put it into the circular buffer. | ||
1102 | * Restrict to the amount of space available. | ||
1103 | * | ||
1104 | * Return the number of bytes copied. | ||
1105 | */ | ||
1106 | static unsigned int oti6858_buf_put(struct oti6858_buf *pb, const char *buf, | ||
1107 | unsigned int count) | ||
1108 | { | ||
1109 | unsigned int len; | ||
1110 | |||
1111 | if (pb == NULL) | ||
1112 | return 0; | ||
1113 | |||
1114 | len = oti6858_buf_space_avail(pb); | ||
1115 | if (count > len) | ||
1116 | count = len; | ||
1117 | |||
1118 | if (count == 0) | ||
1119 | return 0; | ||
1120 | |||
1121 | len = pb->buf_buf + pb->buf_size - pb->buf_put; | ||
1122 | if (count > len) { | ||
1123 | memcpy(pb->buf_put, buf, len); | ||
1124 | memcpy(pb->buf_buf, buf+len, count - len); | ||
1125 | pb->buf_put = pb->buf_buf + count - len; | ||
1126 | } else { | ||
1127 | memcpy(pb->buf_put, buf, count); | ||
1128 | if (count < len) | ||
1129 | pb->buf_put += count; | ||
1130 | else /* count == len */ | ||
1131 | pb->buf_put = pb->buf_buf; | ||
1132 | } | ||
1133 | |||
1134 | return count; | ||
1135 | } | ||
1136 | |||
1137 | /* | ||
1138 | * oti6858_buf_get | ||
1139 | * | ||
1140 | * Get data from the circular buffer and copy to the given buffer. | ||
1141 | * Restrict to the amount of data available. | ||
1142 | * | ||
1143 | * Return the number of bytes copied. | ||
1144 | */ | ||
1145 | static unsigned int oti6858_buf_get(struct oti6858_buf *pb, char *buf, | ||
1146 | unsigned int count) | ||
1147 | { | ||
1148 | unsigned int len; | ||
1149 | |||
1150 | if (pb == NULL) | ||
1151 | return 0; | ||
1152 | |||
1153 | len = oti6858_buf_data_avail(pb); | ||
1154 | if (count > len) | ||
1155 | count = len; | ||
1156 | |||
1157 | if (count == 0) | ||
1158 | return 0; | ||
1159 | |||
1160 | len = pb->buf_buf + pb->buf_size - pb->buf_get; | ||
1161 | if (count > len) { | ||
1162 | memcpy(buf, pb->buf_get, len); | ||
1163 | memcpy(buf+len, pb->buf_buf, count - len); | ||
1164 | pb->buf_get = pb->buf_buf + count - len; | ||
1165 | } else { | ||
1166 | memcpy(buf, pb->buf_get, count); | ||
1167 | if (count < len) | ||
1168 | pb->buf_get += count; | ||
1169 | else /* count == len */ | ||
1170 | pb->buf_get = pb->buf_buf; | ||
1171 | } | ||
1172 | |||
1173 | return count; | ||
1174 | } | ||
1175 | |||
1176 | /* module description and (de)initialization */ | 980 | /* module description and (de)initialization */ |
1177 | 981 | ||
1178 | static int __init oti6858_init(void) | 982 | static int __init oti6858_init(void) |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c28b1607eacc..6b6001822279 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -40,16 +40,6 @@ static int debug; | |||
40 | 40 | ||
41 | #define PL2303_CLOSING_WAIT (30*HZ) | 41 | #define PL2303_CLOSING_WAIT (30*HZ) |
42 | 42 | ||
43 | #define PL2303_BUF_SIZE 1024 | ||
44 | #define PL2303_TMP_BUF_SIZE 1024 | ||
45 | |||
46 | struct pl2303_buf { | ||
47 | unsigned int buf_size; | ||
48 | char *buf_buf; | ||
49 | char *buf_get; | ||
50 | char *buf_put; | ||
51 | }; | ||
52 | |||
53 | static const struct usb_device_id id_table[] = { | 43 | static const struct usb_device_id id_table[] = { |
54 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, | 44 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) }, |
55 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, | 45 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) }, |
@@ -157,173 +147,12 @@ enum pl2303_type { | |||
157 | 147 | ||
158 | struct pl2303_private { | 148 | struct pl2303_private { |
159 | spinlock_t lock; | 149 | spinlock_t lock; |
160 | struct pl2303_buf *buf; | ||
161 | int write_urb_in_use; | ||
162 | wait_queue_head_t delta_msr_wait; | 150 | wait_queue_head_t delta_msr_wait; |
163 | u8 line_control; | 151 | u8 line_control; |
164 | u8 line_status; | 152 | u8 line_status; |
165 | enum pl2303_type type; | 153 | enum pl2303_type type; |
166 | }; | 154 | }; |
167 | 155 | ||
168 | /* | ||
169 | * pl2303_buf_alloc | ||
170 | * | ||
171 | * Allocate a circular buffer and all associated memory. | ||
172 | */ | ||
173 | static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | ||
174 | { | ||
175 | struct pl2303_buf *pb; | ||
176 | |||
177 | if (size == 0) | ||
178 | return NULL; | ||
179 | |||
180 | pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); | ||
181 | if (pb == NULL) | ||
182 | return NULL; | ||
183 | |||
184 | pb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
185 | if (pb->buf_buf == NULL) { | ||
186 | kfree(pb); | ||
187 | return NULL; | ||
188 | } | ||
189 | |||
190 | pb->buf_size = size; | ||
191 | pb->buf_get = pb->buf_put = pb->buf_buf; | ||
192 | |||
193 | return pb; | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * pl2303_buf_free | ||
198 | * | ||
199 | * Free the buffer and all associated memory. | ||
200 | */ | ||
201 | static void pl2303_buf_free(struct pl2303_buf *pb) | ||
202 | { | ||
203 | if (pb) { | ||
204 | kfree(pb->buf_buf); | ||
205 | kfree(pb); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * pl2303_buf_clear | ||
211 | * | ||
212 | * Clear out all data in the circular buffer. | ||
213 | */ | ||
214 | static void pl2303_buf_clear(struct pl2303_buf *pb) | ||
215 | { | ||
216 | if (pb != NULL) | ||
217 | pb->buf_get = pb->buf_put; | ||
218 | /* equivalent to a get of all data available */ | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * pl2303_buf_data_avail | ||
223 | * | ||
224 | * Return the number of bytes of data available in the circular | ||
225 | * buffer. | ||
226 | */ | ||
227 | static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb) | ||
228 | { | ||
229 | if (pb == NULL) | ||
230 | return 0; | ||
231 | |||
232 | return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * pl2303_buf_space_avail | ||
237 | * | ||
238 | * Return the number of bytes of space available in the circular | ||
239 | * buffer. | ||
240 | */ | ||
241 | static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb) | ||
242 | { | ||
243 | if (pb == NULL) | ||
244 | return 0; | ||
245 | |||
246 | return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * pl2303_buf_put | ||
251 | * | ||
252 | * Copy data data from a user buffer and put it into the circular buffer. | ||
253 | * Restrict to the amount of space available. | ||
254 | * | ||
255 | * Return the number of bytes copied. | ||
256 | */ | ||
257 | static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf, | ||
258 | unsigned int count) | ||
259 | { | ||
260 | unsigned int len; | ||
261 | |||
262 | if (pb == NULL) | ||
263 | return 0; | ||
264 | |||
265 | len = pl2303_buf_space_avail(pb); | ||
266 | if (count > len) | ||
267 | count = len; | ||
268 | |||
269 | if (count == 0) | ||
270 | return 0; | ||
271 | |||
272 | len = pb->buf_buf + pb->buf_size - pb->buf_put; | ||
273 | if (count > len) { | ||
274 | memcpy(pb->buf_put, buf, len); | ||
275 | memcpy(pb->buf_buf, buf+len, count - len); | ||
276 | pb->buf_put = pb->buf_buf + count - len; | ||
277 | } else { | ||
278 | memcpy(pb->buf_put, buf, count); | ||
279 | if (count < len) | ||
280 | pb->buf_put += count; | ||
281 | else /* count == len */ | ||
282 | pb->buf_put = pb->buf_buf; | ||
283 | } | ||
284 | |||
285 | return count; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * pl2303_buf_get | ||
290 | * | ||
291 | * Get data from the circular buffer and copy to the given buffer. | ||
292 | * Restrict to the amount of data available. | ||
293 | * | ||
294 | * Return the number of bytes copied. | ||
295 | */ | ||
296 | static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | ||
297 | unsigned int count) | ||
298 | { | ||
299 | unsigned int len; | ||
300 | |||
301 | if (pb == NULL) | ||
302 | return 0; | ||
303 | |||
304 | len = pl2303_buf_data_avail(pb); | ||
305 | if (count > len) | ||
306 | count = len; | ||
307 | |||
308 | if (count == 0) | ||
309 | return 0; | ||
310 | |||
311 | len = pb->buf_buf + pb->buf_size - pb->buf_get; | ||
312 | if (count > len) { | ||
313 | memcpy(buf, pb->buf_get, len); | ||
314 | memcpy(buf+len, pb->buf_buf, count - len); | ||
315 | pb->buf_get = pb->buf_buf + count - len; | ||
316 | } else { | ||
317 | memcpy(buf, pb->buf_get, count); | ||
318 | if (count < len) | ||
319 | pb->buf_get += count; | ||
320 | else /* count == len */ | ||
321 | pb->buf_get = pb->buf_buf; | ||
322 | } | ||
323 | |||
324 | return count; | ||
325 | } | ||
326 | |||
327 | static int pl2303_vendor_read(__u16 value, __u16 index, | 156 | static int pl2303_vendor_read(__u16 value, __u16 index, |
328 | struct usb_serial *serial, unsigned char *buf) | 157 | struct usb_serial *serial, unsigned char *buf) |
329 | { | 158 | { |
@@ -372,11 +201,6 @@ static int pl2303_startup(struct usb_serial *serial) | |||
372 | if (!priv) | 201 | if (!priv) |
373 | goto cleanup; | 202 | goto cleanup; |
374 | spin_lock_init(&priv->lock); | 203 | spin_lock_init(&priv->lock); |
375 | priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE); | ||
376 | if (priv->buf == NULL) { | ||
377 | kfree(priv); | ||
378 | goto cleanup; | ||
379 | } | ||
380 | init_waitqueue_head(&priv->delta_msr_wait); | 204 | init_waitqueue_head(&priv->delta_msr_wait); |
381 | priv->type = type; | 205 | priv->type = type; |
382 | usb_set_serial_port_data(serial->port[i], priv); | 206 | usb_set_serial_port_data(serial->port[i], priv); |
@@ -404,7 +228,6 @@ cleanup: | |||
404 | kfree(buf); | 228 | kfree(buf); |
405 | for (--i; i >= 0; --i) { | 229 | for (--i; i >= 0; --i) { |
406 | priv = usb_get_serial_port_data(serial->port[i]); | 230 | priv = usb_get_serial_port_data(serial->port[i]); |
407 | pl2303_buf_free(priv->buf); | ||
408 | kfree(priv); | 231 | kfree(priv); |
409 | usb_set_serial_port_data(serial->port[i], NULL); | 232 | usb_set_serial_port_data(serial->port[i], NULL); |
410 | } | 233 | } |
@@ -422,102 +245,6 @@ static int set_control_lines(struct usb_device *dev, u8 value) | |||
422 | return retval; | 245 | return retval; |
423 | } | 246 | } |
424 | 247 | ||
425 | static void pl2303_send(struct usb_serial_port *port) | ||
426 | { | ||
427 | int count, result; | ||
428 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
429 | unsigned long flags; | ||
430 | |||
431 | dbg("%s - port %d", __func__, port->number); | ||
432 | |||
433 | spin_lock_irqsave(&priv->lock, flags); | ||
434 | |||
435 | if (priv->write_urb_in_use) { | ||
436 | spin_unlock_irqrestore(&priv->lock, flags); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | count = pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer, | ||
441 | port->bulk_out_size); | ||
442 | |||
443 | if (count == 0) { | ||
444 | spin_unlock_irqrestore(&priv->lock, flags); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | priv->write_urb_in_use = 1; | ||
449 | |||
450 | spin_unlock_irqrestore(&priv->lock, flags); | ||
451 | |||
452 | usb_serial_debug_data(debug, &port->dev, __func__, count, | ||
453 | port->write_urb->transfer_buffer); | ||
454 | |||
455 | port->write_urb->transfer_buffer_length = count; | ||
456 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
457 | if (result) { | ||
458 | dev_err(&port->dev, "%s - failed submitting write urb," | ||
459 | " error %d\n", __func__, result); | ||
460 | priv->write_urb_in_use = 0; | ||
461 | /* TODO: reschedule pl2303_send */ | ||
462 | } | ||
463 | |||
464 | usb_serial_port_softint(port); | ||
465 | } | ||
466 | |||
467 | static int pl2303_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
468 | const unsigned char *buf, int count) | ||
469 | { | ||
470 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
471 | unsigned long flags; | ||
472 | |||
473 | dbg("%s - port %d, %d bytes", __func__, port->number, count); | ||
474 | |||
475 | if (!count) | ||
476 | return count; | ||
477 | |||
478 | spin_lock_irqsave(&priv->lock, flags); | ||
479 | count = pl2303_buf_put(priv->buf, buf, count); | ||
480 | spin_unlock_irqrestore(&priv->lock, flags); | ||
481 | |||
482 | pl2303_send(port); | ||
483 | |||
484 | return count; | ||
485 | } | ||
486 | |||
487 | static int pl2303_write_room(struct tty_struct *tty) | ||
488 | { | ||
489 | struct usb_serial_port *port = tty->driver_data; | ||
490 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
491 | int room = 0; | ||
492 | unsigned long flags; | ||
493 | |||
494 | dbg("%s - port %d", __func__, port->number); | ||
495 | |||
496 | spin_lock_irqsave(&priv->lock, flags); | ||
497 | room = pl2303_buf_space_avail(priv->buf); | ||
498 | spin_unlock_irqrestore(&priv->lock, flags); | ||
499 | |||
500 | dbg("%s - returns %d", __func__, room); | ||
501 | return room; | ||
502 | } | ||
503 | |||
504 | static int pl2303_chars_in_buffer(struct tty_struct *tty) | ||
505 | { | ||
506 | struct usb_serial_port *port = tty->driver_data; | ||
507 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
508 | int chars = 0; | ||
509 | unsigned long flags; | ||
510 | |||
511 | dbg("%s - port %d", __func__, port->number); | ||
512 | |||
513 | spin_lock_irqsave(&priv->lock, flags); | ||
514 | chars = pl2303_buf_data_avail(priv->buf); | ||
515 | spin_unlock_irqrestore(&priv->lock, flags); | ||
516 | |||
517 | dbg("%s - returns %d", __func__, chars); | ||
518 | return chars; | ||
519 | } | ||
520 | |||
521 | static void pl2303_set_termios(struct tty_struct *tty, | 248 | static void pl2303_set_termios(struct tty_struct *tty, |
522 | struct usb_serial_port *port, struct ktermios *old_termios) | 249 | struct usb_serial_port *port, struct ktermios *old_termios) |
523 | { | 250 | { |
@@ -729,22 +456,10 @@ static void pl2303_dtr_rts(struct usb_serial_port *port, int on) | |||
729 | 456 | ||
730 | static void pl2303_close(struct usb_serial_port *port) | 457 | static void pl2303_close(struct usb_serial_port *port) |
731 | { | 458 | { |
732 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
733 | unsigned long flags; | ||
734 | |||
735 | dbg("%s - port %d", __func__, port->number); | 459 | dbg("%s - port %d", __func__, port->number); |
736 | 460 | ||
737 | spin_lock_irqsave(&priv->lock, flags); | 461 | usb_serial_generic_close(port); |
738 | /* clear out any remaining data in the buffer */ | ||
739 | pl2303_buf_clear(priv->buf); | ||
740 | spin_unlock_irqrestore(&priv->lock, flags); | ||
741 | |||
742 | /* shutdown our urbs */ | ||
743 | dbg("%s - shutting down urbs", __func__); | ||
744 | usb_kill_urb(port->write_urb); | ||
745 | usb_kill_urb(port->read_urb); | ||
746 | usb_kill_urb(port->interrupt_in_urb); | 462 | usb_kill_urb(port->interrupt_in_urb); |
747 | |||
748 | } | 463 | } |
749 | 464 | ||
750 | static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | 465 | static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -770,10 +485,8 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
770 | pl2303_set_termios(tty, port, &tmp_termios); | 485 | pl2303_set_termios(tty, port, &tmp_termios); |
771 | 486 | ||
772 | dbg("%s - submitting read urb", __func__); | 487 | dbg("%s - submitting read urb", __func__); |
773 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | 488 | result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL); |
774 | if (result) { | 489 | if (result) { |
775 | dev_err(&port->dev, "%s - failed submitting read urb," | ||
776 | " error %d\n", __func__, result); | ||
777 | pl2303_close(port); | 490 | pl2303_close(port); |
778 | return -EPROTO; | 491 | return -EPROTO; |
779 | } | 492 | } |
@@ -953,10 +666,7 @@ static void pl2303_release(struct usb_serial *serial) | |||
953 | 666 | ||
954 | for (i = 0; i < serial->num_ports; ++i) { | 667 | for (i = 0; i < serial->num_ports; ++i) { |
955 | priv = usb_get_serial_port_data(serial->port[i]); | 668 | priv = usb_get_serial_port_data(serial->port[i]); |
956 | if (priv) { | 669 | kfree(priv); |
957 | pl2303_buf_free(priv->buf); | ||
958 | kfree(priv); | ||
959 | } | ||
960 | } | 670 | } |
961 | } | 671 | } |
962 | 672 | ||
@@ -1037,13 +747,31 @@ exit: | |||
1037 | __func__, retval); | 747 | __func__, retval); |
1038 | } | 748 | } |
1039 | 749 | ||
1040 | static void pl2303_push_data(struct tty_struct *tty, | 750 | static void pl2303_process_read_urb(struct urb *urb) |
1041 | struct usb_serial_port *port, struct urb *urb, | ||
1042 | u8 line_status) | ||
1043 | { | 751 | { |
752 | struct usb_serial_port *port = urb->context; | ||
753 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
754 | struct tty_struct *tty; | ||
1044 | unsigned char *data = urb->transfer_buffer; | 755 | unsigned char *data = urb->transfer_buffer; |
1045 | /* get tty_flag from status */ | ||
1046 | char tty_flag = TTY_NORMAL; | 756 | char tty_flag = TTY_NORMAL; |
757 | unsigned long flags; | ||
758 | u8 line_status; | ||
759 | int i; | ||
760 | |||
761 | /* update line status */ | ||
762 | spin_lock_irqsave(&priv->lock, flags); | ||
763 | line_status = priv->line_status; | ||
764 | priv->line_status &= ~UART_STATE_TRANSIENT_MASK; | ||
765 | spin_unlock_irqrestore(&priv->lock, flags); | ||
766 | wake_up_interruptible(&priv->delta_msr_wait); | ||
767 | |||
768 | if (!urb->actual_length) | ||
769 | return; | ||
770 | |||
771 | tty = tty_port_tty_get(&port->port); | ||
772 | if (!tty) | ||
773 | return; | ||
774 | |||
1047 | /* break takes precedence over parity, */ | 775 | /* break takes precedence over parity, */ |
1048 | /* which takes precedence over framing errors */ | 776 | /* which takes precedence over framing errors */ |
1049 | if (line_status & UART_BREAK_ERROR) | 777 | if (line_status & UART_BREAK_ERROR) |
@@ -1058,107 +786,17 @@ static void pl2303_push_data(struct tty_struct *tty, | |||
1058 | if (line_status & UART_OVERRUN_ERROR) | 786 | if (line_status & UART_OVERRUN_ERROR) |
1059 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 787 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1060 | 788 | ||
1061 | if (tty_flag == TTY_NORMAL && !(port->console && port->sysrq)) | 789 | if (port->port.console && port->sysrq) { |
1062 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1063 | else { | ||
1064 | int i; | ||
1065 | for (i = 0; i < urb->actual_length; ++i) | 790 | for (i = 0; i < urb->actual_length; ++i) |
1066 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | 791 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) |
1067 | tty_insert_flip_char(tty, data[i], tty_flag); | 792 | tty_insert_flip_char(tty, data[i], tty_flag); |
793 | } else { | ||
794 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | ||
795 | urb->actual_length); | ||
1068 | } | 796 | } |
1069 | tty_flip_buffer_push(tty); | ||
1070 | } | ||
1071 | |||
1072 | static void pl2303_read_bulk_callback(struct urb *urb) | ||
1073 | { | ||
1074 | struct usb_serial_port *port = urb->context; | ||
1075 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
1076 | struct tty_struct *tty; | ||
1077 | unsigned long flags; | ||
1078 | int result; | ||
1079 | int status = urb->status; | ||
1080 | u8 line_status; | ||
1081 | |||
1082 | dbg("%s - port %d", __func__, port->number); | ||
1083 | |||
1084 | if (status) { | ||
1085 | dbg("%s - urb status = %d", __func__, status); | ||
1086 | if (status == -EPROTO) { | ||
1087 | /* PL2303 mysteriously fails with -EPROTO reschedule | ||
1088 | * the read */ | ||
1089 | dbg("%s - caught -EPROTO, resubmitting the urb", | ||
1090 | __func__); | ||
1091 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
1092 | if (result) | ||
1093 | dev_err(&urb->dev->dev, "%s - failed" | ||
1094 | " resubmitting read urb, error %d\n", | ||
1095 | __func__, result); | ||
1096 | return; | ||
1097 | } | ||
1098 | dbg("%s - unable to handle the error, exiting.", __func__); | ||
1099 | return; | ||
1100 | } | ||
1101 | |||
1102 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
1103 | urb->actual_length, urb->transfer_buffer); | ||
1104 | |||
1105 | spin_lock_irqsave(&priv->lock, flags); | ||
1106 | line_status = priv->line_status; | ||
1107 | priv->line_status &= ~UART_STATE_TRANSIENT_MASK; | ||
1108 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1109 | wake_up_interruptible(&priv->delta_msr_wait); | ||
1110 | 797 | ||
1111 | tty = tty_port_tty_get(&port->port); | 798 | tty_flip_buffer_push(tty); |
1112 | if (tty && urb->actual_length) { | ||
1113 | pl2303_push_data(tty, port, urb, line_status); | ||
1114 | } | ||
1115 | tty_kref_put(tty); | 799 | tty_kref_put(tty); |
1116 | /* Schedule the next read _if_ we are still open */ | ||
1117 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
1118 | if (result && result != -EPERM) | ||
1119 | dev_err(&urb->dev->dev, "%s - failed resubmitting" | ||
1120 | " read urb, error %d\n", __func__, result); | ||
1121 | } | ||
1122 | |||
1123 | static void pl2303_write_bulk_callback(struct urb *urb) | ||
1124 | { | ||
1125 | struct usb_serial_port *port = urb->context; | ||
1126 | struct pl2303_private *priv = usb_get_serial_port_data(port); | ||
1127 | int result; | ||
1128 | int status = urb->status; | ||
1129 | |||
1130 | dbg("%s - port %d", __func__, port->number); | ||
1131 | |||
1132 | switch (status) { | ||
1133 | case 0: | ||
1134 | /* success */ | ||
1135 | break; | ||
1136 | case -ECONNRESET: | ||
1137 | case -ENOENT: | ||
1138 | case -ESHUTDOWN: | ||
1139 | /* this urb is terminated, clean up */ | ||
1140 | dbg("%s - urb shutting down with status: %d", __func__, | ||
1141 | status); | ||
1142 | priv->write_urb_in_use = 0; | ||
1143 | return; | ||
1144 | default: | ||
1145 | /* error in the urb, so we have to resubmit it */ | ||
1146 | dbg("%s - Overflow in write", __func__); | ||
1147 | dbg("%s - nonzero write bulk status received: %d", __func__, | ||
1148 | status); | ||
1149 | port->write_urb->transfer_buffer_length = 1; | ||
1150 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
1151 | if (result) | ||
1152 | dev_err(&urb->dev->dev, "%s - failed resubmitting write" | ||
1153 | " urb, error %d\n", __func__, result); | ||
1154 | else | ||
1155 | return; | ||
1156 | } | ||
1157 | |||
1158 | priv->write_urb_in_use = 0; | ||
1159 | |||
1160 | /* send any buffered data */ | ||
1161 | pl2303_send(port); | ||
1162 | } | 800 | } |
1163 | 801 | ||
1164 | /* All of the device info needed for the PL2303 SIO serial converter */ | 802 | /* All of the device info needed for the PL2303 SIO serial converter */ |
@@ -1170,21 +808,19 @@ static struct usb_serial_driver pl2303_device = { | |||
1170 | .id_table = id_table, | 808 | .id_table = id_table, |
1171 | .usb_driver = &pl2303_driver, | 809 | .usb_driver = &pl2303_driver, |
1172 | .num_ports = 1, | 810 | .num_ports = 1, |
811 | .bulk_in_size = 256, | ||
812 | .bulk_out_size = 256, | ||
1173 | .open = pl2303_open, | 813 | .open = pl2303_open, |
1174 | .close = pl2303_close, | 814 | .close = pl2303_close, |
1175 | .dtr_rts = pl2303_dtr_rts, | 815 | .dtr_rts = pl2303_dtr_rts, |
1176 | .carrier_raised = pl2303_carrier_raised, | 816 | .carrier_raised = pl2303_carrier_raised, |
1177 | .write = pl2303_write, | ||
1178 | .ioctl = pl2303_ioctl, | 817 | .ioctl = pl2303_ioctl, |
1179 | .break_ctl = pl2303_break_ctl, | 818 | .break_ctl = pl2303_break_ctl, |
1180 | .set_termios = pl2303_set_termios, | 819 | .set_termios = pl2303_set_termios, |
1181 | .tiocmget = pl2303_tiocmget, | 820 | .tiocmget = pl2303_tiocmget, |
1182 | .tiocmset = pl2303_tiocmset, | 821 | .tiocmset = pl2303_tiocmset, |
1183 | .read_bulk_callback = pl2303_read_bulk_callback, | 822 | .process_read_urb = pl2303_process_read_urb, |
1184 | .read_int_callback = pl2303_read_int_callback, | 823 | .read_int_callback = pl2303_read_int_callback, |
1185 | .write_bulk_callback = pl2303_write_bulk_callback, | ||
1186 | .write_room = pl2303_write_room, | ||
1187 | .chars_in_buffer = pl2303_chars_in_buffer, | ||
1188 | .attach = pl2303_startup, | 824 | .attach = pl2303_startup, |
1189 | .release = pl2303_release, | 825 | .release = pl2303_release, |
1190 | }; | 826 | }; |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 23c09b38b9ec..a871645389dd 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define BENQ_VENDOR_ID 0x04a5 | 11 | #define BENQ_VENDOR_ID 0x04a5 |
@@ -137,5 +137,5 @@ | |||
137 | #define SANWA_PRODUCT_ID 0x0001 | 137 | #define SANWA_PRODUCT_ID 0x0001 |
138 | 138 | ||
139 | /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ | 139 | /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ |
140 | #define ADLINK_VENDOR_ID 0x0b63 | 140 | #define ADLINK_VENDOR_ID 0x0b63 |
141 | #define ADLINK_ND6530_PRODUCT_ID 0x6530 | 141 | #define ADLINK_ND6530_PRODUCT_ID 0x6530 |
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c index 7e3bea23600b..214a3e504292 100644 --- a/drivers/usb/serial/qcaux.c +++ b/drivers/usb/serial/qcaux.c | |||
@@ -50,6 +50,10 @@ | |||
50 | #define SANYO_VENDOR_ID 0x0474 | 50 | #define SANYO_VENDOR_ID 0x0474 |
51 | #define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */ | 51 | #define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */ |
52 | 52 | ||
53 | /* Samsung devices */ | ||
54 | #define SAMSUNG_VENDOR_ID 0x04e8 | ||
55 | #define SAMSUNG_PRODUCT_U520 0x6640 /* SCH-U520 */ | ||
56 | |||
53 | static struct usb_device_id id_table[] = { | 57 | static struct usb_device_id id_table[] = { |
54 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) }, | 58 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) }, |
55 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) }, | 59 | { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) }, |
@@ -61,6 +65,7 @@ static struct usb_device_id id_table[] = { | |||
61 | { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) }, | 65 | { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) }, |
62 | { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, | 66 | { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, |
63 | { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, | 67 | { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, |
68 | { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, | ||
64 | { }, | 69 | { }, |
65 | }; | 70 | }; |
66 | MODULE_DEVICE_TABLE(usb, id_table); | 71 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 53a2d5a935a2..04bb759536bb 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/tty_flip.h> | 15 | #include <linux/tty_flip.h> |
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 17 | #include <linux/usb/serial.h> |
18 | #include <linux/slab.h> | ||
19 | #include "usb-wwan.h" | ||
18 | 20 | ||
19 | #define DRIVER_AUTHOR "Qualcomm Inc" | 21 | #define DRIVER_AUTHOR "Qualcomm Inc" |
20 | #define DRIVER_DESC "Qualcomm USB Serial driver" | 22 | #define DRIVER_DESC "Qualcomm USB Serial driver" |
@@ -76,6 +78,8 @@ static const struct usb_device_id id_table[] = { | |||
76 | {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 78 | {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
77 | {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ | 79 | {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ |
78 | {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 80 | {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
81 | {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */ | ||
82 | {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | ||
79 | { } /* Terminating entry */ | 83 | { } /* Terminating entry */ |
80 | }; | 84 | }; |
81 | MODULE_DEVICE_TABLE(usb, id_table); | 85 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -92,6 +96,8 @@ static struct usb_driver qcdriver = { | |||
92 | 96 | ||
93 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | 97 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) |
94 | { | 98 | { |
99 | struct usb_wwan_intf_private *data; | ||
100 | struct usb_host_interface *intf = serial->interface->cur_altsetting; | ||
95 | int retval = -ENODEV; | 101 | int retval = -ENODEV; |
96 | __u8 nintf; | 102 | __u8 nintf; |
97 | __u8 ifnum; | 103 | __u8 ifnum; |
@@ -100,33 +106,45 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
100 | 106 | ||
101 | nintf = serial->dev->actconfig->desc.bNumInterfaces; | 107 | nintf = serial->dev->actconfig->desc.bNumInterfaces; |
102 | dbg("Num Interfaces = %d", nintf); | 108 | dbg("Num Interfaces = %d", nintf); |
103 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 109 | ifnum = intf->desc.bInterfaceNumber; |
104 | dbg("This Interface = %d", ifnum); | 110 | dbg("This Interface = %d", ifnum); |
105 | 111 | ||
112 | data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), | ||
113 | GFP_KERNEL); | ||
114 | if (!data) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | spin_lock_init(&data->susp_lock); | ||
118 | |||
106 | switch (nintf) { | 119 | switch (nintf) { |
107 | case 1: | 120 | case 1: |
108 | /* QDL mode */ | 121 | /* QDL mode */ |
109 | if (serial->interface->num_altsetting == 2) { | 122 | /* Gobi 2000 has a single altsetting, older ones have two */ |
110 | struct usb_host_interface *intf; | 123 | if (serial->interface->num_altsetting == 2) |
111 | |||
112 | intf = &serial->interface->altsetting[1]; | 124 | intf = &serial->interface->altsetting[1]; |
113 | if (intf->desc.bNumEndpoints == 2) { | 125 | else if (serial->interface->num_altsetting > 2) |
114 | if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && | 126 | break; |
115 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | 127 | |
116 | dbg("QDL port found"); | 128 | if (intf->desc.bNumEndpoints == 2 && |
117 | retval = usb_set_interface(serial->dev, ifnum, 1); | 129 | usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && |
118 | if (retval < 0) { | 130 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { |
119 | dev_err(&serial->dev->dev, | 131 | dbg("QDL port found"); |
120 | "Could not set interface, error %d\n", | 132 | |
121 | retval); | 133 | if (serial->interface->num_altsetting == 1) |
122 | retval = -ENODEV; | 134 | return 0; |
123 | } | 135 | |
124 | return retval; | 136 | retval = usb_set_interface(serial->dev, ifnum, 1); |
125 | } | 137 | if (retval < 0) { |
138 | dev_err(&serial->dev->dev, | ||
139 | "Could not set interface, error %d\n", | ||
140 | retval); | ||
141 | retval = -ENODEV; | ||
126 | } | 142 | } |
143 | return retval; | ||
127 | } | 144 | } |
128 | break; | 145 | break; |
129 | 146 | ||
147 | case 3: | ||
130 | case 4: | 148 | case 4: |
131 | /* Composite mode */ | 149 | /* Composite mode */ |
132 | if (ifnum == 2) { | 150 | if (ifnum == 2) { |
@@ -161,6 +179,18 @@ static struct usb_serial_driver qcdevice = { | |||
161 | .usb_driver = &qcdriver, | 179 | .usb_driver = &qcdriver, |
162 | .num_ports = 1, | 180 | .num_ports = 1, |
163 | .probe = qcprobe, | 181 | .probe = qcprobe, |
182 | .open = usb_wwan_open, | ||
183 | .close = usb_wwan_close, | ||
184 | .write = usb_wwan_write, | ||
185 | .write_room = usb_wwan_write_room, | ||
186 | .chars_in_buffer = usb_wwan_chars_in_buffer, | ||
187 | .attach = usb_wwan_startup, | ||
188 | .disconnect = usb_wwan_disconnect, | ||
189 | .release = usb_wwan_release, | ||
190 | #ifdef CONFIG_PM | ||
191 | .suspend = usb_wwan_suspend, | ||
192 | .resume = usb_wwan_resume, | ||
193 | #endif | ||
164 | }; | 194 | }; |
165 | 195 | ||
166 | static int __init qcinit(void) | 196 | static int __init qcinit(void) |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 43a0cadd5782..a36e2313eed0 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Safe Encapsulated USB Serial Driver | 2 | * Safe Encapsulated USB Serial Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> | ||
4 | * Copyright (C) 2001 Lineo | 5 | * Copyright (C) 2001 Lineo |
5 | * Copyright (C) 2001 Hewlett-Packard | 6 | * Copyright (C) 2001 Hewlett-Packard |
6 | * | 7 | * |
@@ -84,8 +85,8 @@ static int debug; | |||
84 | static int safe = 1; | 85 | static int safe = 1; |
85 | static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; | 86 | static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; |
86 | 87 | ||
87 | #define DRIVER_VERSION "v0.0b" | 88 | #define DRIVER_VERSION "v0.1" |
88 | #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" | 89 | #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com, Johan Hovold <jhovold@gmail.com>" |
89 | #define DRIVER_DESC "USB Safe Encapsulated Serial" | 90 | #define DRIVER_DESC "USB Safe Encapsulated Serial" |
90 | 91 | ||
91 | MODULE_AUTHOR(DRIVER_AUTHOR); | 92 | MODULE_AUTHOR(DRIVER_AUTHOR); |
@@ -212,191 +213,80 @@ static __u16 __inline__ fcs_compute10(unsigned char *sp, int len, __u16 fcs) | |||
212 | return fcs; | 213 | return fcs; |
213 | } | 214 | } |
214 | 215 | ||
215 | static void safe_read_bulk_callback(struct urb *urb) | 216 | static void safe_process_read_urb(struct urb *urb) |
216 | { | 217 | { |
217 | struct usb_serial_port *port = urb->context; | 218 | struct usb_serial_port *port = urb->context; |
218 | unsigned char *data = urb->transfer_buffer; | 219 | unsigned char *data = urb->transfer_buffer; |
219 | unsigned char length = urb->actual_length; | 220 | unsigned char length = urb->actual_length; |
221 | int actual_length; | ||
220 | struct tty_struct *tty; | 222 | struct tty_struct *tty; |
221 | int result; | 223 | __u16 fcs; |
222 | int status = urb->status; | ||
223 | 224 | ||
224 | dbg("%s", __func__); | 225 | if (!length) |
225 | |||
226 | if (status) { | ||
227 | dbg("%s - nonzero read bulk status received: %d", | ||
228 | __func__, status); | ||
229 | return; | 226 | return; |
230 | } | ||
231 | 227 | ||
232 | dbg("safe_read_bulk_callback length: %d", | ||
233 | port->read_urb->actual_length); | ||
234 | #ifdef ECHO_RCV | ||
235 | { | ||
236 | int i; | ||
237 | unsigned char *cp = port->read_urb->transfer_buffer; | ||
238 | for (i = 0; i < port->read_urb->actual_length; i++) { | ||
239 | if ((i % 32) == 0) | ||
240 | printk("\nru[%02x] ", i); | ||
241 | printk("%02x ", *cp++); | ||
242 | } | ||
243 | printk("\n"); | ||
244 | } | ||
245 | #endif | ||
246 | tty = tty_port_tty_get(&port->port); | 228 | tty = tty_port_tty_get(&port->port); |
247 | if (safe) { | 229 | if (!tty) |
248 | __u16 fcs; | 230 | return; |
249 | fcs = fcs_compute10(data, length, CRC10_INITFCS); | ||
250 | if (!fcs) { | ||
251 | int actual_length = data[length - 2] >> 2; | ||
252 | if (actual_length <= (length - 2)) { | ||
253 | dev_info(&urb->dev->dev, "%s - actual: %d\n", | ||
254 | __func__, actual_length); | ||
255 | tty_insert_flip_string(tty, | ||
256 | data, actual_length); | ||
257 | tty_flip_buffer_push(tty); | ||
258 | } else { | ||
259 | dev_err(&port->dev, | ||
260 | "%s - inconsistent lengths %d:%d\n", | ||
261 | __func__, actual_length, length); | ||
262 | } | ||
263 | } else { | ||
264 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); | ||
265 | } | ||
266 | } else { | ||
267 | tty_insert_flip_string(tty, data, length); | ||
268 | tty_flip_buffer_push(tty); | ||
269 | } | ||
270 | tty_kref_put(tty); | ||
271 | |||
272 | /* Continue trying to always read */ | ||
273 | usb_fill_bulk_urb(urb, port->serial->dev, | ||
274 | usb_rcvbulkpipe(port->serial->dev, | ||
275 | port->bulk_in_endpointAddress), | ||
276 | urb->transfer_buffer, urb->transfer_buffer_length, | ||
277 | safe_read_bulk_callback, port); | ||
278 | |||
279 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
280 | if (result) | ||
281 | dev_err(&port->dev, | ||
282 | "%s - failed resubmitting read urb, error %d\n", | ||
283 | __func__, result); | ||
284 | /* FIXME: Need a mechanism to retry later if this happens */ | ||
285 | } | ||
286 | |||
287 | static int safe_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
288 | const unsigned char *buf, int count) | ||
289 | { | ||
290 | unsigned char *data; | ||
291 | int result; | ||
292 | int i; | ||
293 | int packet_length; | ||
294 | |||
295 | dbg("safe_write port: %p %d urb: %p count: %d", | ||
296 | port, port->number, port->write_urb, count); | ||
297 | |||
298 | if (!port->write_urb) { | ||
299 | dbg("%s - write urb NULL", __func__); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | dbg("safe_write write_urb: %d transfer_buffer_length", | ||
304 | port->write_urb->transfer_buffer_length); | ||
305 | |||
306 | if (!port->write_urb->transfer_buffer_length) { | ||
307 | dbg("%s - write urb transfer_buffer_length zero", __func__); | ||
308 | return 0; | ||
309 | } | ||
310 | if (count == 0) { | ||
311 | dbg("%s - write request of 0 bytes", __func__); | ||
312 | return 0; | ||
313 | } | ||
314 | spin_lock_bh(&port->lock); | ||
315 | if (port->write_urb_busy) { | ||
316 | spin_unlock_bh(&port->lock); | ||
317 | dbg("%s - already writing", __func__); | ||
318 | return 0; | ||
319 | } | ||
320 | port->write_urb_busy = 1; | ||
321 | spin_unlock_bh(&port->lock); | ||
322 | |||
323 | packet_length = port->bulk_out_size; /* get max packetsize */ | ||
324 | |||
325 | i = packet_length - (safe ? 2 : 0); /* get bytes to send */ | ||
326 | count = (count > i) ? i : count; | ||
327 | |||
328 | |||
329 | /* get the data into the transfer buffer */ | ||
330 | data = port->write_urb->transfer_buffer; | ||
331 | memset(data, '0', packet_length); | ||
332 | |||
333 | memcpy(data, buf, count); | ||
334 | |||
335 | if (safe) { | ||
336 | __u16 fcs; | ||
337 | |||
338 | /* pad if necessary */ | ||
339 | if (!padded) | ||
340 | packet_length = count + 2; | ||
341 | /* set count */ | ||
342 | data[packet_length - 2] = count << 2; | ||
343 | data[packet_length - 1] = 0; | ||
344 | 231 | ||
345 | /* compute fcs and insert into trailer */ | 232 | if (!safe) |
346 | fcs = fcs_compute10(data, packet_length, CRC10_INITFCS); | 233 | goto out; |
347 | data[packet_length - 2] |= fcs >> 8; | ||
348 | data[packet_length - 1] |= fcs & 0xff; | ||
349 | 234 | ||
350 | /* set length to send */ | 235 | fcs = fcs_compute10(data, length, CRC10_INITFCS); |
351 | port->write_urb->transfer_buffer_length = packet_length; | 236 | if (fcs) { |
352 | } else { | 237 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); |
353 | port->write_urb->transfer_buffer_length = count; | 238 | goto err; |
354 | } | 239 | } |
355 | 240 | ||
356 | usb_serial_debug_data(debug, &port->dev, __func__, count, | 241 | actual_length = data[length - 2] >> 2; |
357 | port->write_urb->transfer_buffer); | 242 | if (actual_length > (length - 2)) { |
358 | #ifdef ECHO_TX | 243 | dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", |
359 | { | 244 | __func__, actual_length, length); |
360 | int i; | 245 | goto err; |
361 | unsigned char *cp = port->write_urb->transfer_buffer; | ||
362 | for (i = 0; i < port->write_urb->transfer_buffer_length; i++) { | ||
363 | if ((i % 32) == 0) | ||
364 | printk("\nsu[%02x] ", i); | ||
365 | printk("%02x ", *cp++); | ||
366 | } | ||
367 | printk("\n"); | ||
368 | } | ||
369 | #endif | ||
370 | port->write_urb->dev = port->serial->dev; | ||
371 | result = usb_submit_urb(port->write_urb, GFP_KERNEL); | ||
372 | if (result) { | ||
373 | port->write_urb_busy = 0; | ||
374 | dev_err(&port->dev, | ||
375 | "%s - failed submitting write urb, error %d\n", | ||
376 | __func__, result); | ||
377 | return 0; | ||
378 | } | 246 | } |
379 | dbg("%s urb: %p submitted", __func__, port->write_urb); | 247 | dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); |
380 | 248 | length = actual_length; | |
381 | return count; | 249 | out: |
250 | tty_insert_flip_string(tty, data, length); | ||
251 | tty_flip_buffer_push(tty); | ||
252 | err: | ||
253 | tty_kref_put(tty); | ||
382 | } | 254 | } |
383 | 255 | ||
384 | static int safe_write_room(struct tty_struct *tty) | 256 | static int safe_prepare_write_buffer(struct usb_serial_port *port, |
257 | void *dest, size_t size) | ||
385 | { | 258 | { |
386 | struct usb_serial_port *port = tty->driver_data; | 259 | unsigned char *buf = dest; |
387 | int room = 0; /* Default: no room */ | 260 | int count; |
388 | unsigned long flags; | 261 | int trailer_len; |
262 | int pkt_len; | ||
263 | __u16 fcs; | ||
264 | |||
265 | trailer_len = safe ? 2 : 0; | ||
266 | |||
267 | count = kfifo_out_locked(&port->write_fifo, buf, size - trailer_len, | ||
268 | &port->lock); | ||
269 | if (!safe) | ||
270 | return count; | ||
271 | |||
272 | /* pad if necessary */ | ||
273 | if (padded) { | ||
274 | pkt_len = size; | ||
275 | memset(buf + count, '0', pkt_len - count - trailer_len); | ||
276 | } else { | ||
277 | pkt_len = count + trailer_len; | ||
278 | } | ||
389 | 279 | ||
390 | dbg("%s", __func__); | 280 | /* set count */ |
281 | buf[pkt_len - 2] = count << 2; | ||
282 | buf[pkt_len - 1] = 0; | ||
391 | 283 | ||
392 | spin_lock_irqsave(&port->lock, flags); | 284 | /* compute fcs and insert into trailer */ |
393 | if (port->write_urb_busy) | 285 | fcs = fcs_compute10(buf, pkt_len, CRC10_INITFCS); |
394 | room = port->bulk_out_size - (safe ? 2 : 0); | 286 | buf[pkt_len - 2] |= fcs >> 8; |
395 | spin_unlock_irqrestore(&port->lock, flags); | 287 | buf[pkt_len - 1] |= fcs & 0xff; |
396 | 288 | ||
397 | if (room) | 289 | return pkt_len; |
398 | dbg("safe_write_room returns %d", room); | ||
399 | return room; | ||
400 | } | 290 | } |
401 | 291 | ||
402 | static int safe_startup(struct usb_serial *serial) | 292 | static int safe_startup(struct usb_serial *serial) |
@@ -421,9 +311,8 @@ static struct usb_serial_driver safe_device = { | |||
421 | .id_table = id_table, | 311 | .id_table = id_table, |
422 | .usb_driver = &safe_driver, | 312 | .usb_driver = &safe_driver, |
423 | .num_ports = 1, | 313 | .num_ports = 1, |
424 | .write = safe_write, | 314 | .process_read_urb = safe_process_read_urb, |
425 | .write_room = safe_write_room, | 315 | .prepare_write_buffer = safe_prepare_write_buffer, |
426 | .read_bulk_callback = safe_read_bulk_callback, | ||
427 | .attach = safe_startup, | 316 | .attach = safe_startup, |
428 | }; | 317 | }; |
429 | 318 | ||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 5d39191e7244..329d311a35d9 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * spcp8x5 USB to serial adaptor driver | 2 | * spcp8x5 USB to serial adaptor driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) | ||
4 | * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn) | 5 | * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn) |
5 | * Copyright (C) 2006 S1 Corp. | 6 | * Copyright (C) 2006 S1 Corp. |
6 | * | 7 | * |
@@ -29,7 +30,7 @@ | |||
29 | 30 | ||
30 | 31 | ||
31 | /* Version Information */ | 32 | /* Version Information */ |
32 | #define DRIVER_VERSION "v0.04" | 33 | #define DRIVER_VERSION "v0.10" |
33 | #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver" | 34 | #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver" |
34 | 35 | ||
35 | static int debug; | 36 | static int debug; |
@@ -64,11 +65,6 @@ struct spcp8x5_usb_ctrl_arg { | |||
64 | u16 length; | 65 | u16 length; |
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* wait 30s before close */ | ||
68 | #define SPCP8x5_CLOSING_WAIT (30*HZ) | ||
69 | |||
70 | #define SPCP8x5_BUF_SIZE 1024 | ||
71 | |||
72 | 68 | ||
73 | /* spcp8x5 spec register define */ | 69 | /* spcp8x5 spec register define */ |
74 | #define MCR_CONTROL_LINE_RTS 0x02 | 70 | #define MCR_CONTROL_LINE_RTS 0x02 |
@@ -155,133 +151,6 @@ enum spcp8x5_type { | |||
155 | SPCP835_TYPE, | 151 | SPCP835_TYPE, |
156 | }; | 152 | }; |
157 | 153 | ||
158 | /* 1st in 1st out buffer 4 driver */ | ||
159 | struct ringbuf { | ||
160 | unsigned int buf_size; | ||
161 | char *buf_buf; | ||
162 | char *buf_get; | ||
163 | char *buf_put; | ||
164 | }; | ||
165 | |||
166 | /* alloc the ring buf and alloc the buffer itself */ | ||
167 | static inline struct ringbuf *alloc_ringbuf(unsigned int size) | ||
168 | { | ||
169 | struct ringbuf *pb; | ||
170 | |||
171 | if (size == 0) | ||
172 | return NULL; | ||
173 | |||
174 | pb = kmalloc(sizeof(*pb), GFP_KERNEL); | ||
175 | if (pb == NULL) | ||
176 | return NULL; | ||
177 | |||
178 | pb->buf_buf = kmalloc(size, GFP_KERNEL); | ||
179 | if (pb->buf_buf == NULL) { | ||
180 | kfree(pb); | ||
181 | return NULL; | ||
182 | } | ||
183 | |||
184 | pb->buf_size = size; | ||
185 | pb->buf_get = pb->buf_put = pb->buf_buf; | ||
186 | |||
187 | return pb; | ||
188 | } | ||
189 | |||
190 | /* free the ring buf and the buffer itself */ | ||
191 | static inline void free_ringbuf(struct ringbuf *pb) | ||
192 | { | ||
193 | if (pb != NULL) { | ||
194 | kfree(pb->buf_buf); | ||
195 | kfree(pb); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* clear pipo , juest repoint the pointer here */ | ||
200 | static inline void clear_ringbuf(struct ringbuf *pb) | ||
201 | { | ||
202 | if (pb != NULL) | ||
203 | pb->buf_get = pb->buf_put; | ||
204 | } | ||
205 | |||
206 | /* get the number of data in the pipo */ | ||
207 | static inline unsigned int ringbuf_avail_data(struct ringbuf *pb) | ||
208 | { | ||
209 | if (pb == NULL) | ||
210 | return 0; | ||
211 | return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; | ||
212 | } | ||
213 | |||
214 | /* get the number of space in the pipo */ | ||
215 | static inline unsigned int ringbuf_avail_space(struct ringbuf *pb) | ||
216 | { | ||
217 | if (pb == NULL) | ||
218 | return 0; | ||
219 | return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; | ||
220 | } | ||
221 | |||
222 | /* put count data into pipo */ | ||
223 | static unsigned int put_ringbuf(struct ringbuf *pb, const char *buf, | ||
224 | unsigned int count) | ||
225 | { | ||
226 | unsigned int len; | ||
227 | |||
228 | if (pb == NULL) | ||
229 | return 0; | ||
230 | |||
231 | len = ringbuf_avail_space(pb); | ||
232 | if (count > len) | ||
233 | count = len; | ||
234 | |||
235 | if (count == 0) | ||
236 | return 0; | ||
237 | |||
238 | len = pb->buf_buf + pb->buf_size - pb->buf_put; | ||
239 | if (count > len) { | ||
240 | memcpy(pb->buf_put, buf, len); | ||
241 | memcpy(pb->buf_buf, buf+len, count - len); | ||
242 | pb->buf_put = pb->buf_buf + count - len; | ||
243 | } else { | ||
244 | memcpy(pb->buf_put, buf, count); | ||
245 | if (count < len) | ||
246 | pb->buf_put += count; | ||
247 | else /* count == len */ | ||
248 | pb->buf_put = pb->buf_buf; | ||
249 | } | ||
250 | return count; | ||
251 | } | ||
252 | |||
253 | /* get count data from pipo */ | ||
254 | static unsigned int get_ringbuf(struct ringbuf *pb, char *buf, | ||
255 | unsigned int count) | ||
256 | { | ||
257 | unsigned int len; | ||
258 | |||
259 | if (pb == NULL || buf == NULL) | ||
260 | return 0; | ||
261 | |||
262 | len = ringbuf_avail_data(pb); | ||
263 | if (count > len) | ||
264 | count = len; | ||
265 | |||
266 | if (count == 0) | ||
267 | return 0; | ||
268 | |||
269 | len = pb->buf_buf + pb->buf_size - pb->buf_get; | ||
270 | if (count > len) { | ||
271 | memcpy(buf, pb->buf_get, len); | ||
272 | memcpy(buf+len, pb->buf_buf, count - len); | ||
273 | pb->buf_get = pb->buf_buf + count - len; | ||
274 | } else { | ||
275 | memcpy(buf, pb->buf_get, count); | ||
276 | if (count < len) | ||
277 | pb->buf_get += count; | ||
278 | else /* count == len */ | ||
279 | pb->buf_get = pb->buf_buf; | ||
280 | } | ||
281 | |||
282 | return count; | ||
283 | } | ||
284 | |||
285 | static struct usb_driver spcp8x5_driver = { | 154 | static struct usb_driver spcp8x5_driver = { |
286 | .name = "spcp8x5", | 155 | .name = "spcp8x5", |
287 | .probe = usb_serial_probe, | 156 | .probe = usb_serial_probe, |
@@ -293,8 +162,6 @@ static struct usb_driver spcp8x5_driver = { | |||
293 | 162 | ||
294 | struct spcp8x5_private { | 163 | struct spcp8x5_private { |
295 | spinlock_t lock; | 164 | spinlock_t lock; |
296 | struct ringbuf *buf; | ||
297 | int write_urb_in_use; | ||
298 | enum spcp8x5_type type; | 165 | enum spcp8x5_type type; |
299 | wait_queue_head_t delta_msr_wait; | 166 | wait_queue_head_t delta_msr_wait; |
300 | u8 line_control; | 167 | u8 line_control; |
@@ -330,24 +197,15 @@ static int spcp8x5_startup(struct usb_serial *serial) | |||
330 | goto cleanup; | 197 | goto cleanup; |
331 | 198 | ||
332 | spin_lock_init(&priv->lock); | 199 | spin_lock_init(&priv->lock); |
333 | priv->buf = alloc_ringbuf(SPCP8x5_BUF_SIZE); | ||
334 | if (priv->buf == NULL) | ||
335 | goto cleanup2; | ||
336 | |||
337 | init_waitqueue_head(&priv->delta_msr_wait); | 200 | init_waitqueue_head(&priv->delta_msr_wait); |
338 | priv->type = type; | 201 | priv->type = type; |
339 | usb_set_serial_port_data(serial->port[i] , priv); | 202 | usb_set_serial_port_data(serial->port[i] , priv); |
340 | |||
341 | } | 203 | } |
342 | 204 | ||
343 | return 0; | 205 | return 0; |
344 | |||
345 | cleanup2: | ||
346 | kfree(priv); | ||
347 | cleanup: | 206 | cleanup: |
348 | for (--i; i >= 0; --i) { | 207 | for (--i; i >= 0; --i) { |
349 | priv = usb_get_serial_port_data(serial->port[i]); | 208 | priv = usb_get_serial_port_data(serial->port[i]); |
350 | free_ringbuf(priv->buf); | ||
351 | kfree(priv); | 209 | kfree(priv); |
352 | usb_set_serial_port_data(serial->port[i] , NULL); | 210 | usb_set_serial_port_data(serial->port[i] , NULL); |
353 | } | 211 | } |
@@ -358,15 +216,9 @@ cleanup: | |||
358 | static void spcp8x5_release(struct usb_serial *serial) | 216 | static void spcp8x5_release(struct usb_serial *serial) |
359 | { | 217 | { |
360 | int i; | 218 | int i; |
361 | struct spcp8x5_private *priv; | ||
362 | 219 | ||
363 | for (i = 0; i < serial->num_ports; i++) { | 220 | for (i = 0; i < serial->num_ports; i++) |
364 | priv = usb_get_serial_port_data(serial->port[i]); | 221 | kfree(usb_get_serial_port_data(serial->port[i])); |
365 | if (priv) { | ||
366 | free_ringbuf(priv->buf); | ||
367 | kfree(priv); | ||
368 | } | ||
369 | } | ||
370 | } | 222 | } |
371 | 223 | ||
372 | /* set the modem control line of the device. | 224 | /* set the modem control line of the device. |
@@ -470,33 +322,6 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | |||
470 | spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); | 322 | spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); |
471 | } | 323 | } |
472 | 324 | ||
473 | /* close the serial port. We should wait for data sending to device 1st and | ||
474 | * then kill all urb. */ | ||
475 | static void spcp8x5_close(struct usb_serial_port *port) | ||
476 | { | ||
477 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
478 | unsigned long flags; | ||
479 | int result; | ||
480 | |||
481 | dbg("%s - port %d", __func__, port->number); | ||
482 | |||
483 | spin_lock_irqsave(&priv->lock, flags); | ||
484 | /* clear out any remaining data in the buffer */ | ||
485 | clear_ringbuf(priv->buf); | ||
486 | spin_unlock_irqrestore(&priv->lock, flags); | ||
487 | |||
488 | /* kill urb */ | ||
489 | if (port->write_urb != NULL) { | ||
490 | result = usb_unlink_urb(port->write_urb); | ||
491 | if (result) | ||
492 | dev_dbg(&port->dev, | ||
493 | "usb_unlink_urb(write_urb) = %d\n", result); | ||
494 | } | ||
495 | result = usb_unlink_urb(port->read_urb); | ||
496 | if (result) | ||
497 | dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result); | ||
498 | } | ||
499 | |||
500 | static void spcp8x5_init_termios(struct tty_struct *tty) | 325 | static void spcp8x5_init_termios(struct tty_struct *tty) |
501 | { | 326 | { |
502 | /* for the 1st time call this function */ | 327 | /* for the 1st time call this function */ |
@@ -620,7 +445,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
620 | } | 445 | } |
621 | 446 | ||
622 | /* open the serial port. do some usb system call. set termios and get the line | 447 | /* open the serial port. do some usb system call. set termios and get the line |
623 | * status of the device. then submit the read urb */ | 448 | * status of the device. */ |
624 | static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) | 449 | static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) |
625 | { | 450 | { |
626 | struct ktermios tmp_termios; | 451 | struct ktermios tmp_termios; |
@@ -655,52 +480,21 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
655 | priv->line_status = status & 0xf0 ; | 480 | priv->line_status = status & 0xf0 ; |
656 | spin_unlock_irqrestore(&priv->lock, flags); | 481 | spin_unlock_irqrestore(&priv->lock, flags); |
657 | 482 | ||
658 | dbg("%s - submitting read urb", __func__); | ||
659 | port->read_urb->dev = serial->dev; | ||
660 | ret = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
661 | if (ret) { | ||
662 | spcp8x5_close(port); | ||
663 | return -EPROTO; | ||
664 | } | ||
665 | port->port.drain_delay = 256; | 483 | port->port.drain_delay = 256; |
666 | return 0; | 484 | |
485 | return usb_serial_generic_open(tty, port); | ||
667 | } | 486 | } |
668 | 487 | ||
669 | /* bulk read call back function. check the status of the urb. if transfer | 488 | static void spcp8x5_process_read_urb(struct urb *urb) |
670 | * failed return. then update the status and the tty send data to tty subsys. | ||
671 | * submit urb again. | ||
672 | */ | ||
673 | static void spcp8x5_read_bulk_callback(struct urb *urb) | ||
674 | { | 489 | { |
675 | struct usb_serial_port *port = urb->context; | 490 | struct usb_serial_port *port = urb->context; |
676 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 491 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
677 | struct tty_struct *tty; | 492 | struct tty_struct *tty; |
678 | unsigned char *data = urb->transfer_buffer; | 493 | unsigned char *data = urb->transfer_buffer; |
679 | unsigned long flags; | 494 | unsigned long flags; |
680 | int result = urb->status; | ||
681 | u8 status; | 495 | u8 status; |
682 | char tty_flag; | 496 | char tty_flag; |
683 | 497 | ||
684 | dev_dbg(&port->dev, "start, result = %d, urb->actual_length = %d\n,", | ||
685 | result, urb->actual_length); | ||
686 | |||
687 | /* check the urb status */ | ||
688 | if (result) { | ||
689 | if (result == -EPROTO) { | ||
690 | /* spcp8x5 mysteriously fails with -EPROTO */ | ||
691 | /* reschedule the read */ | ||
692 | urb->dev = port->serial->dev; | ||
693 | result = usb_submit_urb(urb , GFP_ATOMIC); | ||
694 | if (result) | ||
695 | dev_dbg(&port->dev, | ||
696 | "failed submitting read urb %d\n", | ||
697 | result); | ||
698 | return; | ||
699 | } | ||
700 | dev_dbg(&port->dev, "unable to handle the error, exiting.\n"); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | /* get tty_flag from status */ | 498 | /* get tty_flag from status */ |
705 | tty_flag = TTY_NORMAL; | 499 | tty_flag = TTY_NORMAL; |
706 | 500 | ||
@@ -711,141 +505,33 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
711 | /* wake up the wait for termios */ | 505 | /* wake up the wait for termios */ |
712 | wake_up_interruptible(&priv->delta_msr_wait); | 506 | wake_up_interruptible(&priv->delta_msr_wait); |
713 | 507 | ||
714 | /* break takes precedence over parity, which takes precedence over | 508 | if (!urb->actual_length) |
715 | * framing errors */ | ||
716 | if (status & UART_BREAK_ERROR) | ||
717 | tty_flag = TTY_BREAK; | ||
718 | else if (status & UART_PARITY_ERROR) | ||
719 | tty_flag = TTY_PARITY; | ||
720 | else if (status & UART_FRAME_ERROR) | ||
721 | tty_flag = TTY_FRAME; | ||
722 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); | ||
723 | |||
724 | tty = tty_port_tty_get(&port->port); | ||
725 | if (tty && urb->actual_length) { | ||
726 | /* overrun is special, not associated with a char */ | ||
727 | if (status & UART_OVERRUN_ERROR) | ||
728 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
729 | tty_insert_flip_string_fixed_flag(tty, data, | ||
730 | urb->actual_length, tty_flag); | ||
731 | tty_flip_buffer_push(tty); | ||
732 | } | ||
733 | tty_kref_put(tty); | ||
734 | |||
735 | /* Schedule the next read */ | ||
736 | urb->dev = port->serial->dev; | ||
737 | result = usb_submit_urb(urb , GFP_ATOMIC); | ||
738 | if (result) | ||
739 | dev_dbg(&port->dev, "failed submitting read urb %d\n", result); | ||
740 | } | ||
741 | |||
742 | /* get data from ring buffer and then write to usb bus */ | ||
743 | static void spcp8x5_send(struct usb_serial_port *port) | ||
744 | { | ||
745 | int count, result; | ||
746 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
747 | unsigned long flags; | ||
748 | |||
749 | spin_lock_irqsave(&priv->lock, flags); | ||
750 | |||
751 | if (priv->write_urb_in_use) { | ||
752 | dev_dbg(&port->dev, "write urb still used\n"); | ||
753 | spin_unlock_irqrestore(&priv->lock, flags); | ||
754 | return; | 509 | return; |
755 | } | ||
756 | |||
757 | /* send the 1st urb for writting */ | ||
758 | memset(port->write_urb->transfer_buffer , 0x00 , port->bulk_out_size); | ||
759 | count = get_ringbuf(priv->buf, port->write_urb->transfer_buffer, | ||
760 | port->bulk_out_size); | ||
761 | 510 | ||
762 | if (count == 0) { | 511 | tty = tty_port_tty_get(&port->port); |
763 | spin_unlock_irqrestore(&priv->lock, flags); | 512 | if (!tty) |
764 | return; | 513 | return; |
765 | } | ||
766 | |||
767 | /* update the urb status */ | ||
768 | priv->write_urb_in_use = 1; | ||
769 | |||
770 | spin_unlock_irqrestore(&priv->lock, flags); | ||
771 | |||
772 | port->write_urb->transfer_buffer_length = count; | ||
773 | port->write_urb->dev = port->serial->dev; | ||
774 | |||
775 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
776 | if (result) { | ||
777 | dev_dbg(&port->dev, "failed submitting write urb, error %d\n", | ||
778 | result); | ||
779 | priv->write_urb_in_use = 0; | ||
780 | /* TODO: reschedule spcp8x5_send */ | ||
781 | } | ||
782 | |||
783 | |||
784 | schedule_work(&port->work); | ||
785 | } | ||
786 | 514 | ||
787 | /* this is the call back function for write urb. NOTE we should not sleep in | 515 | if (status & UART_STATE_TRANSIENT_MASK) { |
788 | * this routine. check the urb return code and then submit the write urb again | 516 | /* break takes precedence over parity, which takes precedence |
789 | * to hold the write loop */ | 517 | * over framing errors */ |
790 | static void spcp8x5_write_bulk_callback(struct urb *urb) | 518 | if (status & UART_BREAK_ERROR) |
791 | { | 519 | tty_flag = TTY_BREAK; |
792 | struct usb_serial_port *port = urb->context; | 520 | else if (status & UART_PARITY_ERROR) |
793 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 521 | tty_flag = TTY_PARITY; |
794 | int result; | 522 | else if (status & UART_FRAME_ERROR) |
795 | int status = urb->status; | 523 | tty_flag = TTY_FRAME; |
524 | dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); | ||
796 | 525 | ||
797 | switch (status) { | 526 | /* overrun is special, not associated with a char */ |
798 | case 0: | 527 | if (status & UART_OVERRUN_ERROR) |
799 | /* success */ | 528 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
800 | break; | ||
801 | case -ECONNRESET: | ||
802 | case -ENOENT: | ||
803 | case -ESHUTDOWN: | ||
804 | /* this urb is terminated, clean up */ | ||
805 | dev_dbg(&port->dev, "urb shutting down with status: %d\n", | ||
806 | status); | ||
807 | priv->write_urb_in_use = 0; | ||
808 | return; | ||
809 | default: | ||
810 | /* error in the urb, so we have to resubmit it */ | ||
811 | dbg("%s - Overflow in write", __func__); | ||
812 | dbg("%s - nonzero write bulk status received: %d", | ||
813 | __func__, status); | ||
814 | port->write_urb->transfer_buffer_length = 1; | ||
815 | port->write_urb->dev = port->serial->dev; | ||
816 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
817 | if (result) | ||
818 | dev_dbg(&port->dev, | ||
819 | "failed resubmitting write urb %d\n", result); | ||
820 | else | ||
821 | return; | ||
822 | } | 529 | } |
823 | 530 | ||
824 | priv->write_urb_in_use = 0; | 531 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, |
825 | 532 | urb->actual_length); | |
826 | /* send any buffered data */ | 533 | tty_flip_buffer_push(tty); |
827 | spcp8x5_send(port); | 534 | tty_kref_put(tty); |
828 | } | ||
829 | |||
830 | /* write data to ring buffer. and then start the write transfer */ | ||
831 | static int spcp8x5_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
832 | const unsigned char *buf, int count) | ||
833 | { | ||
834 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
835 | unsigned long flags; | ||
836 | |||
837 | dev_dbg(&port->dev, "%d bytes\n", count); | ||
838 | |||
839 | if (!count) | ||
840 | return count; | ||
841 | |||
842 | spin_lock_irqsave(&priv->lock, flags); | ||
843 | count = put_ringbuf(priv->buf, buf, count); | ||
844 | spin_unlock_irqrestore(&priv->lock, flags); | ||
845 | |||
846 | spcp8x5_send(port); | ||
847 | |||
848 | return count; | ||
849 | } | 535 | } |
850 | 536 | ||
851 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, | 537 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, |
@@ -953,36 +639,6 @@ static int spcp8x5_tiocmget(struct tty_struct *tty, struct file *file) | |||
953 | return result; | 639 | return result; |
954 | } | 640 | } |
955 | 641 | ||
956 | /* get the avail space room in ring buffer */ | ||
957 | static int spcp8x5_write_room(struct tty_struct *tty) | ||
958 | { | ||
959 | struct usb_serial_port *port = tty->driver_data; | ||
960 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
961 | int room = 0; | ||
962 | unsigned long flags; | ||
963 | |||
964 | spin_lock_irqsave(&priv->lock, flags); | ||
965 | room = ringbuf_avail_space(priv->buf); | ||
966 | spin_unlock_irqrestore(&priv->lock, flags); | ||
967 | |||
968 | return room; | ||
969 | } | ||
970 | |||
971 | /* get the number of avail data in write ring buffer */ | ||
972 | static int spcp8x5_chars_in_buffer(struct tty_struct *tty) | ||
973 | { | ||
974 | struct usb_serial_port *port = tty->driver_data; | ||
975 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | ||
976 | int chars = 0; | ||
977 | unsigned long flags; | ||
978 | |||
979 | spin_lock_irqsave(&priv->lock, flags); | ||
980 | chars = ringbuf_avail_data(priv->buf); | ||
981 | spin_unlock_irqrestore(&priv->lock, flags); | ||
982 | |||
983 | return chars; | ||
984 | } | ||
985 | |||
986 | /* All of the device info needed for the spcp8x5 SIO serial converter */ | 642 | /* All of the device info needed for the spcp8x5 SIO serial converter */ |
987 | static struct usb_serial_driver spcp8x5_device = { | 643 | static struct usb_serial_driver spcp8x5_device = { |
988 | .driver = { | 644 | .driver = { |
@@ -992,21 +648,16 @@ static struct usb_serial_driver spcp8x5_device = { | |||
992 | .id_table = id_table, | 648 | .id_table = id_table, |
993 | .num_ports = 1, | 649 | .num_ports = 1, |
994 | .open = spcp8x5_open, | 650 | .open = spcp8x5_open, |
995 | .close = spcp8x5_close, | ||
996 | .dtr_rts = spcp8x5_dtr_rts, | 651 | .dtr_rts = spcp8x5_dtr_rts, |
997 | .carrier_raised = spcp8x5_carrier_raised, | 652 | .carrier_raised = spcp8x5_carrier_raised, |
998 | .write = spcp8x5_write, | ||
999 | .set_termios = spcp8x5_set_termios, | 653 | .set_termios = spcp8x5_set_termios, |
1000 | .init_termios = spcp8x5_init_termios, | 654 | .init_termios = spcp8x5_init_termios, |
1001 | .ioctl = spcp8x5_ioctl, | 655 | .ioctl = spcp8x5_ioctl, |
1002 | .tiocmget = spcp8x5_tiocmget, | 656 | .tiocmget = spcp8x5_tiocmget, |
1003 | .tiocmset = spcp8x5_tiocmset, | 657 | .tiocmset = spcp8x5_tiocmset, |
1004 | .write_room = spcp8x5_write_room, | ||
1005 | .read_bulk_callback = spcp8x5_read_bulk_callback, | ||
1006 | .write_bulk_callback = spcp8x5_write_bulk_callback, | ||
1007 | .chars_in_buffer = spcp8x5_chars_in_buffer, | ||
1008 | .attach = spcp8x5_startup, | 658 | .attach = spcp8x5_startup, |
1009 | .release = spcp8x5_release, | 659 | .release = spcp8x5_release, |
660 | .process_read_urb = spcp8x5_process_read_urb, | ||
1010 | }; | 661 | }; |
1011 | 662 | ||
1012 | static int __init spcp8x5_init(void) | 663 | static int __init spcp8x5_init(void) |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index e1bfda33f5b9..90979a1f5311 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/ioctl.h> | 31 | #include <linux/ioctl.h> |
32 | #include <linux/serial.h> | 32 | #include <linux/serial.h> |
33 | #include <linux/circ_buf.h> | 33 | #include <linux/kfifo.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | /* Defines */ | 41 | /* Defines */ |
42 | 42 | ||
43 | #define TI_DRIVER_VERSION "v0.9" | 43 | #define TI_DRIVER_VERSION "v0.10" |
44 | #define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>" | 44 | #define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>" |
45 | #define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver" | 45 | #define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver" |
46 | 46 | ||
@@ -82,7 +82,7 @@ struct ti_port { | |||
82 | spinlock_t tp_lock; | 82 | spinlock_t tp_lock; |
83 | int tp_read_urb_state; | 83 | int tp_read_urb_state; |
84 | int tp_write_urb_in_use; | 84 | int tp_write_urb_in_use; |
85 | struct circ_buf *tp_write_buf; | 85 | struct kfifo write_fifo; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct ti_device { | 88 | struct ti_device { |
@@ -144,15 +144,6 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr, | |||
144 | 144 | ||
145 | static int ti_download_firmware(struct ti_device *tdev); | 145 | static int ti_download_firmware(struct ti_device *tdev); |
146 | 146 | ||
147 | /* circular buffer */ | ||
148 | static struct circ_buf *ti_buf_alloc(void); | ||
149 | static void ti_buf_free(struct circ_buf *cb); | ||
150 | static void ti_buf_clear(struct circ_buf *cb); | ||
151 | static int ti_buf_data_avail(struct circ_buf *cb); | ||
152 | static int ti_buf_space_avail(struct circ_buf *cb); | ||
153 | static int ti_buf_put(struct circ_buf *cb, const char *buf, int count); | ||
154 | static int ti_buf_get(struct circ_buf *cb, char *buf, int count); | ||
155 | |||
156 | 147 | ||
157 | /* Data */ | 148 | /* Data */ |
158 | 149 | ||
@@ -450,8 +441,8 @@ static int ti_startup(struct usb_serial *serial) | |||
450 | tport->tp_closing_wait = closing_wait; | 441 | tport->tp_closing_wait = closing_wait; |
451 | init_waitqueue_head(&tport->tp_msr_wait); | 442 | init_waitqueue_head(&tport->tp_msr_wait); |
452 | init_waitqueue_head(&tport->tp_write_wait); | 443 | init_waitqueue_head(&tport->tp_write_wait); |
453 | tport->tp_write_buf = ti_buf_alloc(); | 444 | if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, |
454 | if (tport->tp_write_buf == NULL) { | 445 | GFP_KERNEL)) { |
455 | dev_err(&dev->dev, "%s - out of memory\n", __func__); | 446 | dev_err(&dev->dev, "%s - out of memory\n", __func__); |
456 | kfree(tport); | 447 | kfree(tport); |
457 | status = -ENOMEM; | 448 | status = -ENOMEM; |
@@ -468,7 +459,7 @@ static int ti_startup(struct usb_serial *serial) | |||
468 | free_tports: | 459 | free_tports: |
469 | for (--i; i >= 0; --i) { | 460 | for (--i; i >= 0; --i) { |
470 | tport = usb_get_serial_port_data(serial->port[i]); | 461 | tport = usb_get_serial_port_data(serial->port[i]); |
471 | ti_buf_free(tport->tp_write_buf); | 462 | kfifo_free(&tport->write_fifo); |
472 | kfree(tport); | 463 | kfree(tport); |
473 | usb_set_serial_port_data(serial->port[i], NULL); | 464 | usb_set_serial_port_data(serial->port[i], NULL); |
474 | } | 465 | } |
@@ -490,7 +481,7 @@ static void ti_release(struct usb_serial *serial) | |||
490 | for (i = 0; i < serial->num_ports; ++i) { | 481 | for (i = 0; i < serial->num_ports; ++i) { |
491 | tport = usb_get_serial_port_data(serial->port[i]); | 482 | tport = usb_get_serial_port_data(serial->port[i]); |
492 | if (tport) { | 483 | if (tport) { |
493 | ti_buf_free(tport->tp_write_buf); | 484 | kfifo_free(&tport->write_fifo); |
494 | kfree(tport); | 485 | kfree(tport); |
495 | } | 486 | } |
496 | } | 487 | } |
@@ -701,7 +692,6 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
701 | const unsigned char *data, int count) | 692 | const unsigned char *data, int count) |
702 | { | 693 | { |
703 | struct ti_port *tport = usb_get_serial_port_data(port); | 694 | struct ti_port *tport = usb_get_serial_port_data(port); |
704 | unsigned long flags; | ||
705 | 695 | ||
706 | dbg("%s - port %d", __func__, port->number); | 696 | dbg("%s - port %d", __func__, port->number); |
707 | 697 | ||
@@ -713,10 +703,8 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
713 | if (tport == NULL || !tport->tp_is_open) | 703 | if (tport == NULL || !tport->tp_is_open) |
714 | return -ENODEV; | 704 | return -ENODEV; |
715 | 705 | ||
716 | spin_lock_irqsave(&tport->tp_lock, flags); | 706 | count = kfifo_in_locked(&tport->write_fifo, data, count, |
717 | count = ti_buf_put(tport->tp_write_buf, data, count); | 707 | &tport->tp_lock); |
718 | spin_unlock_irqrestore(&tport->tp_lock, flags); | ||
719 | |||
720 | ti_send(tport); | 708 | ti_send(tport); |
721 | 709 | ||
722 | return count; | 710 | return count; |
@@ -736,7 +724,7 @@ static int ti_write_room(struct tty_struct *tty) | |||
736 | return 0; | 724 | return 0; |
737 | 725 | ||
738 | spin_lock_irqsave(&tport->tp_lock, flags); | 726 | spin_lock_irqsave(&tport->tp_lock, flags); |
739 | room = ti_buf_space_avail(tport->tp_write_buf); | 727 | room = kfifo_avail(&tport->write_fifo); |
740 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 728 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
741 | 729 | ||
742 | dbg("%s - returns %d", __func__, room); | 730 | dbg("%s - returns %d", __func__, room); |
@@ -757,7 +745,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty) | |||
757 | return 0; | 745 | return 0; |
758 | 746 | ||
759 | spin_lock_irqsave(&tport->tp_lock, flags); | 747 | spin_lock_irqsave(&tport->tp_lock, flags); |
760 | chars = ti_buf_data_avail(tport->tp_write_buf); | 748 | chars = kfifo_len(&tport->write_fifo); |
761 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 749 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
762 | 750 | ||
763 | dbg("%s - returns %d", __func__, chars); | 751 | dbg("%s - returns %d", __func__, chars); |
@@ -1309,7 +1297,7 @@ static void ti_send(struct ti_port *tport) | |||
1309 | if (tport->tp_write_urb_in_use) | 1297 | if (tport->tp_write_urb_in_use) |
1310 | goto unlock; | 1298 | goto unlock; |
1311 | 1299 | ||
1312 | count = ti_buf_get(tport->tp_write_buf, | 1300 | count = kfifo_out(&tport->write_fifo, |
1313 | port->write_urb->transfer_buffer, | 1301 | port->write_urb->transfer_buffer, |
1314 | port->bulk_out_size); | 1302 | port->bulk_out_size); |
1315 | 1303 | ||
@@ -1504,7 +1492,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1504 | add_wait_queue(&tport->tp_write_wait, &wait); | 1492 | add_wait_queue(&tport->tp_write_wait, &wait); |
1505 | for (;;) { | 1493 | for (;;) { |
1506 | set_current_state(TASK_INTERRUPTIBLE); | 1494 | set_current_state(TASK_INTERRUPTIBLE); |
1507 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 | 1495 | if (kfifo_len(&tport->write_fifo) == 0 |
1508 | || timeout == 0 || signal_pending(current) | 1496 | || timeout == 0 || signal_pending(current) |
1509 | || tdev->td_urb_error | 1497 | || tdev->td_urb_error |
1510 | || port->serial->disconnected) /* disconnect */ | 1498 | || port->serial->disconnected) /* disconnect */ |
@@ -1518,7 +1506,7 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1518 | 1506 | ||
1519 | /* flush any remaining data in the buffer */ | 1507 | /* flush any remaining data in the buffer */ |
1520 | if (flush) | 1508 | if (flush) |
1521 | ti_buf_clear(tport->tp_write_buf); | 1509 | kfifo_reset_out(&tport->write_fifo); |
1522 | 1510 | ||
1523 | spin_unlock_irq(&tport->tp_lock); | 1511 | spin_unlock_irq(&tport->tp_lock); |
1524 | 1512 | ||
@@ -1761,142 +1749,3 @@ static int ti_download_firmware(struct ti_device *tdev) | |||
1761 | 1749 | ||
1762 | return 0; | 1750 | return 0; |
1763 | } | 1751 | } |
1764 | |||
1765 | |||
1766 | /* Circular Buffer Functions */ | ||
1767 | |||
1768 | /* | ||
1769 | * ti_buf_alloc | ||
1770 | * | ||
1771 | * Allocate a circular buffer and all associated memory. | ||
1772 | */ | ||
1773 | |||
1774 | static struct circ_buf *ti_buf_alloc(void) | ||
1775 | { | ||
1776 | struct circ_buf *cb; | ||
1777 | |||
1778 | cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL); | ||
1779 | if (cb == NULL) | ||
1780 | return NULL; | ||
1781 | |||
1782 | cb->buf = kmalloc(TI_WRITE_BUF_SIZE, GFP_KERNEL); | ||
1783 | if (cb->buf == NULL) { | ||
1784 | kfree(cb); | ||
1785 | return NULL; | ||
1786 | } | ||
1787 | |||
1788 | ti_buf_clear(cb); | ||
1789 | |||
1790 | return cb; | ||
1791 | } | ||
1792 | |||
1793 | |||
1794 | /* | ||
1795 | * ti_buf_free | ||
1796 | * | ||
1797 | * Free the buffer and all associated memory. | ||
1798 | */ | ||
1799 | |||
1800 | static void ti_buf_free(struct circ_buf *cb) | ||
1801 | { | ||
1802 | kfree(cb->buf); | ||
1803 | kfree(cb); | ||
1804 | } | ||
1805 | |||
1806 | |||
1807 | /* | ||
1808 | * ti_buf_clear | ||
1809 | * | ||
1810 | * Clear out all data in the circular buffer. | ||
1811 | */ | ||
1812 | |||
1813 | static void ti_buf_clear(struct circ_buf *cb) | ||
1814 | { | ||
1815 | cb->head = cb->tail = 0; | ||
1816 | } | ||
1817 | |||
1818 | |||
1819 | /* | ||
1820 | * ti_buf_data_avail | ||
1821 | * | ||
1822 | * Return the number of bytes of data available in the circular | ||
1823 | * buffer. | ||
1824 | */ | ||
1825 | |||
1826 | static int ti_buf_data_avail(struct circ_buf *cb) | ||
1827 | { | ||
1828 | return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
1829 | } | ||
1830 | |||
1831 | |||
1832 | /* | ||
1833 | * ti_buf_space_avail | ||
1834 | * | ||
1835 | * Return the number of bytes of space available in the circular | ||
1836 | * buffer. | ||
1837 | */ | ||
1838 | |||
1839 | static int ti_buf_space_avail(struct circ_buf *cb) | ||
1840 | { | ||
1841 | return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
1842 | } | ||
1843 | |||
1844 | |||
1845 | /* | ||
1846 | * ti_buf_put | ||
1847 | * | ||
1848 | * Copy data data from a user buffer and put it into the circular buffer. | ||
1849 | * Restrict to the amount of space available. | ||
1850 | * | ||
1851 | * Return the number of bytes copied. | ||
1852 | */ | ||
1853 | |||
1854 | static int ti_buf_put(struct circ_buf *cb, const char *buf, int count) | ||
1855 | { | ||
1856 | int c, ret = 0; | ||
1857 | |||
1858 | while (1) { | ||
1859 | c = CIRC_SPACE_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
1860 | if (count < c) | ||
1861 | c = count; | ||
1862 | if (c <= 0) | ||
1863 | break; | ||
1864 | memcpy(cb->buf + cb->head, buf, c); | ||
1865 | cb->head = (cb->head + c) & (TI_WRITE_BUF_SIZE-1); | ||
1866 | buf += c; | ||
1867 | count -= c; | ||
1868 | ret += c; | ||
1869 | } | ||
1870 | |||
1871 | return ret; | ||
1872 | } | ||
1873 | |||
1874 | |||
1875 | /* | ||
1876 | * ti_buf_get | ||
1877 | * | ||
1878 | * Get data from the circular buffer and copy to the given buffer. | ||
1879 | * Restrict to the amount of data available. | ||
1880 | * | ||
1881 | * Return the number of bytes copied. | ||
1882 | */ | ||
1883 | |||
1884 | static int ti_buf_get(struct circ_buf *cb, char *buf, int count) | ||
1885 | { | ||
1886 | int c, ret = 0; | ||
1887 | |||
1888 | while (1) { | ||
1889 | c = CIRC_CNT_TO_END(cb->head, cb->tail, TI_WRITE_BUF_SIZE); | ||
1890 | if (count < c) | ||
1891 | c = count; | ||
1892 | if (c <= 0) | ||
1893 | break; | ||
1894 | memcpy(buf, cb->buf + cb->tail, c); | ||
1895 | cb->tail = (cb->tail + c) & (TI_WRITE_BUF_SIZE-1); | ||
1896 | buf += c; | ||
1897 | count -= c; | ||
1898 | ret += c; | ||
1899 | } | ||
1900 | |||
1901 | return ret; | ||
1902 | } | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 3873660d8217..941c2d409f85 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -289,7 +289,7 @@ static void serial_down(struct tty_port *tport) | |||
289 | * The console is magical. Do not hang up the console hardware | 289 | * The console is magical. Do not hang up the console hardware |
290 | * or there will be tears. | 290 | * or there will be tears. |
291 | */ | 291 | */ |
292 | if (port->console) | 292 | if (port->port.console) |
293 | return; | 293 | return; |
294 | if (drv->close) | 294 | if (drv->close) |
295 | drv->close(port); | 295 | drv->close(port); |
@@ -328,7 +328,7 @@ static void serial_cleanup(struct tty_struct *tty) | |||
328 | /* The console is magical. Do not hang up the console hardware | 328 | /* The console is magical. Do not hang up the console hardware |
329 | * or there will be tears. | 329 | * or there will be tears. |
330 | */ | 330 | */ |
331 | if (port->console) | 331 | if (port->port.console) |
332 | return; | 332 | return; |
333 | 333 | ||
334 | dbg("%s - port %d", __func__, port->number); | 334 | dbg("%s - port %d", __func__, port->number); |
@@ -548,8 +548,12 @@ static void usb_serial_port_work(struct work_struct *work) | |||
548 | 548 | ||
549 | static void kill_traffic(struct usb_serial_port *port) | 549 | static void kill_traffic(struct usb_serial_port *port) |
550 | { | 550 | { |
551 | int i; | ||
552 | |||
551 | usb_kill_urb(port->read_urb); | 553 | usb_kill_urb(port->read_urb); |
552 | usb_kill_urb(port->write_urb); | 554 | usb_kill_urb(port->write_urb); |
555 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | ||
556 | usb_kill_urb(port->write_urbs[i]); | ||
553 | /* | 557 | /* |
554 | * This is tricky. | 558 | * This is tricky. |
555 | * Some drivers submit the read_urb in the | 559 | * Some drivers submit the read_urb in the |
@@ -568,6 +572,7 @@ static void kill_traffic(struct usb_serial_port *port) | |||
568 | static void port_release(struct device *dev) | 572 | static void port_release(struct device *dev) |
569 | { | 573 | { |
570 | struct usb_serial_port *port = to_usb_serial_port(dev); | 574 | struct usb_serial_port *port = to_usb_serial_port(dev); |
575 | int i; | ||
571 | 576 | ||
572 | dbg ("%s - %s", __func__, dev_name(dev)); | 577 | dbg ("%s - %s", __func__, dev_name(dev)); |
573 | 578 | ||
@@ -582,6 +587,10 @@ static void port_release(struct device *dev) | |||
582 | usb_free_urb(port->write_urb); | 587 | usb_free_urb(port->write_urb); |
583 | usb_free_urb(port->interrupt_in_urb); | 588 | usb_free_urb(port->interrupt_in_urb); |
584 | usb_free_urb(port->interrupt_out_urb); | 589 | usb_free_urb(port->interrupt_out_urb); |
590 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { | ||
591 | usb_free_urb(port->write_urbs[i]); | ||
592 | kfree(port->bulk_out_buffers[i]); | ||
593 | } | ||
585 | kfifo_free(&port->write_fifo); | 594 | kfifo_free(&port->write_fifo); |
586 | kfree(port->bulk_in_buffer); | 595 | kfree(port->bulk_in_buffer); |
587 | kfree(port->bulk_out_buffer); | 596 | kfree(port->bulk_out_buffer); |
@@ -901,7 +910,9 @@ int usb_serial_probe(struct usb_interface *interface, | |||
901 | dev_err(&interface->dev, "No free urbs available\n"); | 910 | dev_err(&interface->dev, "No free urbs available\n"); |
902 | goto probe_error; | 911 | goto probe_error; |
903 | } | 912 | } |
904 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 913 | buffer_size = serial->type->bulk_in_size; |
914 | if (!buffer_size) | ||
915 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
905 | port->bulk_in_size = buffer_size; | 916 | port->bulk_in_size = buffer_size; |
906 | port->bulk_in_endpointAddress = endpoint->bEndpointAddress; | 917 | port->bulk_in_endpointAddress = endpoint->bEndpointAddress; |
907 | port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | 918 | port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); |
@@ -918,6 +929,8 @@ int usb_serial_probe(struct usb_interface *interface, | |||
918 | } | 929 | } |
919 | 930 | ||
920 | for (i = 0; i < num_bulk_out; ++i) { | 931 | for (i = 0; i < num_bulk_out; ++i) { |
932 | int j; | ||
933 | |||
921 | endpoint = bulk_out_endpoint[i]; | 934 | endpoint = bulk_out_endpoint[i]; |
922 | port = serial->port[i]; | 935 | port = serial->port[i]; |
923 | port->write_urb = usb_alloc_urb(0, GFP_KERNEL); | 936 | port->write_urb = usb_alloc_urb(0, GFP_KERNEL); |
@@ -927,7 +940,9 @@ int usb_serial_probe(struct usb_interface *interface, | |||
927 | } | 940 | } |
928 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) | 941 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) |
929 | goto probe_error; | 942 | goto probe_error; |
930 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 943 | buffer_size = serial->type->bulk_out_size; |
944 | if (!buffer_size) | ||
945 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
931 | port->bulk_out_size = buffer_size; | 946 | port->bulk_out_size = buffer_size; |
932 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; | 947 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; |
933 | port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | 948 | port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); |
@@ -941,6 +956,28 @@ int usb_serial_probe(struct usb_interface *interface, | |||
941 | endpoint->bEndpointAddress), | 956 | endpoint->bEndpointAddress), |
942 | port->bulk_out_buffer, buffer_size, | 957 | port->bulk_out_buffer, buffer_size, |
943 | serial->type->write_bulk_callback, port); | 958 | serial->type->write_bulk_callback, port); |
959 | for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) { | ||
960 | set_bit(j, &port->write_urbs_free); | ||
961 | port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); | ||
962 | if (!port->write_urbs[j]) { | ||
963 | dev_err(&interface->dev, | ||
964 | "No free urbs available\n"); | ||
965 | goto probe_error; | ||
966 | } | ||
967 | port->bulk_out_buffers[j] = kmalloc(buffer_size, | ||
968 | GFP_KERNEL); | ||
969 | if (!port->bulk_out_buffers[j]) { | ||
970 | dev_err(&interface->dev, | ||
971 | "Couldn't allocate bulk_out_buffer\n"); | ||
972 | goto probe_error; | ||
973 | } | ||
974 | usb_fill_bulk_urb(port->write_urbs[j], dev, | ||
975 | usb_sndbulkpipe(dev, | ||
976 | endpoint->bEndpointAddress), | ||
977 | port->bulk_out_buffers[j], buffer_size, | ||
978 | serial->type->write_bulk_callback, | ||
979 | port); | ||
980 | } | ||
944 | } | 981 | } |
945 | 982 | ||
946 | if (serial->type->read_int_callback) { | 983 | if (serial->type->read_int_callback) { |
@@ -1294,6 +1331,8 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1294 | set_to_generic_if_null(device, write_bulk_callback); | 1331 | set_to_generic_if_null(device, write_bulk_callback); |
1295 | set_to_generic_if_null(device, disconnect); | 1332 | set_to_generic_if_null(device, disconnect); |
1296 | set_to_generic_if_null(device, release); | 1333 | set_to_generic_if_null(device, release); |
1334 | set_to_generic_if_null(device, process_read_urb); | ||
1335 | set_to_generic_if_null(device, prepare_write_buffer); | ||
1297 | } | 1336 | } |
1298 | 1337 | ||
1299 | int usb_serial_register(struct usb_serial_driver *driver) | 1338 | int usb_serial_register(struct usb_serial_driver *driver) |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h new file mode 100644 index 000000000000..2be298a1305b --- /dev/null +++ b/drivers/usb/serial/usb-wwan.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Definitions for USB serial mobile broadband cards | ||
3 | */ | ||
4 | |||
5 | #ifndef __LINUX_USB_USB_WWAN | ||
6 | #define __LINUX_USB_USB_WWAN | ||
7 | |||
8 | extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | ||
9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | ||
10 | extern void usb_wwan_close(struct usb_serial_port *port); | ||
11 | extern int usb_wwan_startup(struct usb_serial *serial); | ||
12 | extern void usb_wwan_disconnect(struct usb_serial *serial); | ||
13 | extern void usb_wwan_release(struct usb_serial *serial); | ||
14 | extern int usb_wwan_write_room(struct tty_struct *tty); | ||
15 | extern void usb_wwan_set_termios(struct tty_struct *tty, | ||
16 | struct usb_serial_port *port, | ||
17 | struct ktermios *old); | ||
18 | extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); | ||
19 | extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | ||
20 | unsigned int set, unsigned int clear); | ||
21 | extern int usb_wwan_send_setup(struct usb_serial_port *port); | ||
22 | extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
23 | const unsigned char *buf, int count); | ||
24 | extern int usb_wwan_chars_in_buffer(struct tty_struct *tty); | ||
25 | #ifdef CONFIG_PM | ||
26 | extern int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message); | ||
27 | extern int usb_wwan_resume(struct usb_serial *serial); | ||
28 | #endif | ||
29 | |||
30 | /* per port private data */ | ||
31 | |||
32 | #define N_IN_URB 4 | ||
33 | #define N_OUT_URB 4 | ||
34 | #define IN_BUFLEN 4096 | ||
35 | #define OUT_BUFLEN 4096 | ||
36 | |||
37 | struct usb_wwan_intf_private { | ||
38 | spinlock_t susp_lock; | ||
39 | unsigned int suspended:1; | ||
40 | int in_flight; | ||
41 | int (*send_setup) (struct usb_serial_port *port); | ||
42 | void *private; | ||
43 | }; | ||
44 | |||
45 | struct usb_wwan_port_private { | ||
46 | /* Input endpoints and buffer for this port */ | ||
47 | struct urb *in_urbs[N_IN_URB]; | ||
48 | u8 *in_buffer[N_IN_URB]; | ||
49 | /* Output endpoints and buffer for this port */ | ||
50 | struct urb *out_urbs[N_OUT_URB]; | ||
51 | u8 *out_buffer[N_OUT_URB]; | ||
52 | unsigned long out_busy; /* Bit vector of URBs in use */ | ||
53 | int opened; | ||
54 | struct usb_anchor delayed; | ||
55 | |||
56 | /* Settings for the port */ | ||
57 | int rts_state; /* Handshaking pins (outputs) */ | ||
58 | int dtr_state; | ||
59 | int cts_state; /* Handshaking pins (inputs) */ | ||
60 | int dsr_state; | ||
61 | int dcd_state; | ||
62 | int ri_state; | ||
63 | |||
64 | unsigned long tx_start_time[N_OUT_URB]; | ||
65 | }; | ||
66 | |||
67 | #endif /* __LINUX_USB_USB_WWAN */ | ||
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 28026b47344a..f2ed6a31be77 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 17 | #include <linux/usb/serial.h> |
18 | 18 | ||
19 | #define URB_DEBUG_MAX_IN_FLIGHT_URBS 4000 | ||
20 | #define USB_DEBUG_MAX_PACKET_SIZE 8 | 19 | #define USB_DEBUG_MAX_PACKET_SIZE 8 |
21 | #define USB_DEBUG_BRK_SIZE 8 | 20 | #define USB_DEBUG_BRK_SIZE 8 |
22 | static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { | 21 | static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { |
@@ -44,12 +43,6 @@ static struct usb_driver debug_driver = { | |||
44 | .no_dynamic_id = 1, | 43 | .no_dynamic_id = 1, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
48 | { | ||
49 | port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE; | ||
50 | return usb_serial_generic_open(tty, port); | ||
51 | } | ||
52 | |||
53 | /* This HW really does not support a serial break, so one will be | 46 | /* This HW really does not support a serial break, so one will be |
54 | * emulated when ever the break state is set to true. | 47 | * emulated when ever the break state is set to true. |
55 | */ | 48 | */ |
@@ -69,7 +62,7 @@ static void usb_debug_read_bulk_callback(struct urb *urb) | |||
69 | memcmp(urb->transfer_buffer, USB_DEBUG_BRK, | 62 | memcmp(urb->transfer_buffer, USB_DEBUG_BRK, |
70 | USB_DEBUG_BRK_SIZE) == 0) { | 63 | USB_DEBUG_BRK_SIZE) == 0) { |
71 | usb_serial_handle_break(port); | 64 | usb_serial_handle_break(port); |
72 | usb_serial_generic_resubmit_read_urb(port, GFP_ATOMIC); | 65 | usb_serial_generic_submit_read_urb(port, GFP_ATOMIC); |
73 | return; | 66 | return; |
74 | } | 67 | } |
75 | 68 | ||
@@ -83,8 +76,7 @@ static struct usb_serial_driver debug_device = { | |||
83 | }, | 76 | }, |
84 | .id_table = id_table, | 77 | .id_table = id_table, |
85 | .num_ports = 1, | 78 | .num_ports = 1, |
86 | .open = usb_debug_open, | 79 | .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, |
87 | .max_in_flight_urbs = URB_DEBUG_MAX_IN_FLIGHT_URBS, | ||
88 | .break_ctl = usb_debug_break_ctl, | 80 | .break_ctl = usb_debug_break_ctl, |
89 | .read_bulk_callback = usb_debug_read_bulk_callback, | 81 | .read_bulk_callback = usb_debug_read_bulk_callback, |
90 | }; | 82 | }; |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c new file mode 100644 index 000000000000..0c70b4a621bb --- /dev/null +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -0,0 +1,665 @@ | |||
1 | /* | ||
2 | USB Driver layer for GSM modems | ||
3 | |||
4 | Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> | ||
5 | |||
6 | This driver is free software; you can redistribute it and/or modify | ||
7 | it under the terms of Version 2 of the GNU General Public License as | ||
8 | published by the Free Software Foundation. | ||
9 | |||
10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> | ||
11 | |||
12 | History: see the git log. | ||
13 | |||
14 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> | ||
15 | |||
16 | This driver exists because the "normal" serial driver doesn't work too well | ||
17 | with GSM modems. Issues: | ||
18 | - data loss -- one single Receive URB is not nearly enough | ||
19 | - controlling the baud rate doesn't make sense | ||
20 | */ | ||
21 | |||
22 | #define DRIVER_VERSION "v0.7.2" | ||
23 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" | ||
24 | #define DRIVER_DESC "USB Driver for GSM modems" | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/bitops.h> | ||
34 | #include <linux/usb.h> | ||
35 | #include <linux/usb/serial.h> | ||
36 | #include "usb-wwan.h" | ||
37 | |||
38 | static int debug; | ||
39 | |||
40 | void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) | ||
41 | { | ||
42 | struct usb_serial *serial = port->serial; | ||
43 | struct usb_wwan_port_private *portdata; | ||
44 | |||
45 | struct usb_wwan_intf_private *intfdata; | ||
46 | |||
47 | dbg("%s", __func__); | ||
48 | |||
49 | intfdata = port->serial->private; | ||
50 | |||
51 | if (!intfdata->send_setup) | ||
52 | return; | ||
53 | |||
54 | portdata = usb_get_serial_port_data(port); | ||
55 | mutex_lock(&serial->disc_mutex); | ||
56 | portdata->rts_state = on; | ||
57 | portdata->dtr_state = on; | ||
58 | if (serial->dev) | ||
59 | intfdata->send_setup(port); | ||
60 | mutex_unlock(&serial->disc_mutex); | ||
61 | } | ||
62 | EXPORT_SYMBOL(usb_wwan_dtr_rts); | ||
63 | |||
64 | void usb_wwan_set_termios(struct tty_struct *tty, | ||
65 | struct usb_serial_port *port, | ||
66 | struct ktermios *old_termios) | ||
67 | { | ||
68 | struct usb_wwan_intf_private *intfdata = port->serial->private; | ||
69 | |||
70 | dbg("%s", __func__); | ||
71 | |||
72 | /* Doesn't support option setting */ | ||
73 | tty_termios_copy_hw(tty->termios, old_termios); | ||
74 | |||
75 | if (intfdata->send_setup) | ||
76 | intfdata->send_setup(port); | ||
77 | } | ||
78 | EXPORT_SYMBOL(usb_wwan_set_termios); | ||
79 | |||
80 | int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file) | ||
81 | { | ||
82 | struct usb_serial_port *port = tty->driver_data; | ||
83 | unsigned int value; | ||
84 | struct usb_wwan_port_private *portdata; | ||
85 | |||
86 | portdata = usb_get_serial_port_data(port); | ||
87 | |||
88 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | ||
89 | ((portdata->dtr_state) ? TIOCM_DTR : 0) | | ||
90 | ((portdata->cts_state) ? TIOCM_CTS : 0) | | ||
91 | ((portdata->dsr_state) ? TIOCM_DSR : 0) | | ||
92 | ((portdata->dcd_state) ? TIOCM_CAR : 0) | | ||
93 | ((portdata->ri_state) ? TIOCM_RNG : 0); | ||
94 | |||
95 | return value; | ||
96 | } | ||
97 | EXPORT_SYMBOL(usb_wwan_tiocmget); | ||
98 | |||
99 | int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | ||
100 | unsigned int set, unsigned int clear) | ||
101 | { | ||
102 | struct usb_serial_port *port = tty->driver_data; | ||
103 | struct usb_wwan_port_private *portdata; | ||
104 | struct usb_wwan_intf_private *intfdata; | ||
105 | |||
106 | portdata = usb_get_serial_port_data(port); | ||
107 | intfdata = port->serial->private; | ||
108 | |||
109 | if (!intfdata->send_setup) | ||
110 | return -EINVAL; | ||
111 | |||
112 | /* FIXME: what locks portdata fields ? */ | ||
113 | if (set & TIOCM_RTS) | ||
114 | portdata->rts_state = 1; | ||
115 | if (set & TIOCM_DTR) | ||
116 | portdata->dtr_state = 1; | ||
117 | |||
118 | if (clear & TIOCM_RTS) | ||
119 | portdata->rts_state = 0; | ||
120 | if (clear & TIOCM_DTR) | ||
121 | portdata->dtr_state = 0; | ||
122 | return intfdata->send_setup(port); | ||
123 | } | ||
124 | EXPORT_SYMBOL(usb_wwan_tiocmset); | ||
125 | |||
126 | /* Write */ | ||
127 | int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
128 | const unsigned char *buf, int count) | ||
129 | { | ||
130 | struct usb_wwan_port_private *portdata; | ||
131 | struct usb_wwan_intf_private *intfdata; | ||
132 | int i; | ||
133 | int left, todo; | ||
134 | struct urb *this_urb = NULL; /* spurious */ | ||
135 | int err; | ||
136 | unsigned long flags; | ||
137 | |||
138 | portdata = usb_get_serial_port_data(port); | ||
139 | intfdata = port->serial->private; | ||
140 | |||
141 | dbg("%s: write (%d chars)", __func__, count); | ||
142 | |||
143 | i = 0; | ||
144 | left = count; | ||
145 | for (i = 0; left > 0 && i < N_OUT_URB; i++) { | ||
146 | todo = left; | ||
147 | if (todo > OUT_BUFLEN) | ||
148 | todo = OUT_BUFLEN; | ||
149 | |||
150 | this_urb = portdata->out_urbs[i]; | ||
151 | if (test_and_set_bit(i, &portdata->out_busy)) { | ||
152 | if (time_before(jiffies, | ||
153 | portdata->tx_start_time[i] + 10 * HZ)) | ||
154 | continue; | ||
155 | usb_unlink_urb(this_urb); | ||
156 | continue; | ||
157 | } | ||
158 | dbg("%s: endpoint %d buf %d", __func__, | ||
159 | usb_pipeendpoint(this_urb->pipe), i); | ||
160 | |||
161 | err = usb_autopm_get_interface_async(port->serial->interface); | ||
162 | if (err < 0) | ||
163 | break; | ||
164 | |||
165 | /* send the data */ | ||
166 | memcpy(this_urb->transfer_buffer, buf, todo); | ||
167 | this_urb->transfer_buffer_length = todo; | ||
168 | |||
169 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
170 | if (intfdata->suspended) { | ||
171 | usb_anchor_urb(this_urb, &portdata->delayed); | ||
172 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
173 | } else { | ||
174 | intfdata->in_flight++; | ||
175 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
176 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
177 | if (err) { | ||
178 | dbg("usb_submit_urb %p (write bulk) failed " | ||
179 | "(%d)", this_urb, err); | ||
180 | clear_bit(i, &portdata->out_busy); | ||
181 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
182 | intfdata->in_flight--; | ||
183 | spin_unlock_irqrestore(&intfdata->susp_lock, | ||
184 | flags); | ||
185 | continue; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | portdata->tx_start_time[i] = jiffies; | ||
190 | buf += todo; | ||
191 | left -= todo; | ||
192 | } | ||
193 | |||
194 | count -= left; | ||
195 | dbg("%s: wrote (did %d)", __func__, count); | ||
196 | return count; | ||
197 | } | ||
198 | EXPORT_SYMBOL(usb_wwan_write); | ||
199 | |||
200 | static void usb_wwan_indat_callback(struct urb *urb) | ||
201 | { | ||
202 | int err; | ||
203 | int endpoint; | ||
204 | struct usb_serial_port *port; | ||
205 | struct tty_struct *tty; | ||
206 | unsigned char *data = urb->transfer_buffer; | ||
207 | int status = urb->status; | ||
208 | |||
209 | dbg("%s: %p", __func__, urb); | ||
210 | |||
211 | endpoint = usb_pipeendpoint(urb->pipe); | ||
212 | port = urb->context; | ||
213 | |||
214 | if (status) { | ||
215 | dbg("%s: nonzero status: %d on endpoint %02x.", | ||
216 | __func__, status, endpoint); | ||
217 | } else { | ||
218 | tty = tty_port_tty_get(&port->port); | ||
219 | if (urb->actual_length) { | ||
220 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
221 | tty_flip_buffer_push(tty); | ||
222 | } else | ||
223 | dbg("%s: empty read urb received", __func__); | ||
224 | tty_kref_put(tty); | ||
225 | |||
226 | /* Resubmit urb so we continue receiving */ | ||
227 | if (status != -ESHUTDOWN) { | ||
228 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
229 | if (err && err != -EPERM) | ||
230 | printk(KERN_ERR "%s: resubmit read urb failed. " | ||
231 | "(%d)", __func__, err); | ||
232 | else | ||
233 | usb_mark_last_busy(port->serial->dev); | ||
234 | } | ||
235 | |||
236 | } | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | static void usb_wwan_outdat_callback(struct urb *urb) | ||
241 | { | ||
242 | struct usb_serial_port *port; | ||
243 | struct usb_wwan_port_private *portdata; | ||
244 | struct usb_wwan_intf_private *intfdata; | ||
245 | int i; | ||
246 | |||
247 | dbg("%s", __func__); | ||
248 | |||
249 | port = urb->context; | ||
250 | intfdata = port->serial->private; | ||
251 | |||
252 | usb_serial_port_softint(port); | ||
253 | usb_autopm_put_interface_async(port->serial->interface); | ||
254 | portdata = usb_get_serial_port_data(port); | ||
255 | spin_lock(&intfdata->susp_lock); | ||
256 | intfdata->in_flight--; | ||
257 | spin_unlock(&intfdata->susp_lock); | ||
258 | |||
259 | for (i = 0; i < N_OUT_URB; ++i) { | ||
260 | if (portdata->out_urbs[i] == urb) { | ||
261 | smp_mb__before_clear_bit(); | ||
262 | clear_bit(i, &portdata->out_busy); | ||
263 | break; | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | |||
268 | int usb_wwan_write_room(struct tty_struct *tty) | ||
269 | { | ||
270 | struct usb_serial_port *port = tty->driver_data; | ||
271 | struct usb_wwan_port_private *portdata; | ||
272 | int i; | ||
273 | int data_len = 0; | ||
274 | struct urb *this_urb; | ||
275 | |||
276 | portdata = usb_get_serial_port_data(port); | ||
277 | |||
278 | for (i = 0; i < N_OUT_URB; i++) { | ||
279 | this_urb = portdata->out_urbs[i]; | ||
280 | if (this_urb && !test_bit(i, &portdata->out_busy)) | ||
281 | data_len += OUT_BUFLEN; | ||
282 | } | ||
283 | |||
284 | dbg("%s: %d", __func__, data_len); | ||
285 | return data_len; | ||
286 | } | ||
287 | EXPORT_SYMBOL(usb_wwan_write_room); | ||
288 | |||
289 | int usb_wwan_chars_in_buffer(struct tty_struct *tty) | ||
290 | { | ||
291 | struct usb_serial_port *port = tty->driver_data; | ||
292 | struct usb_wwan_port_private *portdata; | ||
293 | int i; | ||
294 | int data_len = 0; | ||
295 | struct urb *this_urb; | ||
296 | |||
297 | portdata = usb_get_serial_port_data(port); | ||
298 | |||
299 | for (i = 0; i < N_OUT_URB; i++) { | ||
300 | this_urb = portdata->out_urbs[i]; | ||
301 | /* FIXME: This locking is insufficient as this_urb may | ||
302 | go unused during the test */ | ||
303 | if (this_urb && test_bit(i, &portdata->out_busy)) | ||
304 | data_len += this_urb->transfer_buffer_length; | ||
305 | } | ||
306 | dbg("%s: %d", __func__, data_len); | ||
307 | return data_len; | ||
308 | } | ||
309 | EXPORT_SYMBOL(usb_wwan_chars_in_buffer); | ||
310 | |||
311 | int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
312 | { | ||
313 | struct usb_wwan_port_private *portdata; | ||
314 | struct usb_wwan_intf_private *intfdata; | ||
315 | struct usb_serial *serial = port->serial; | ||
316 | int i, err; | ||
317 | struct urb *urb; | ||
318 | |||
319 | portdata = usb_get_serial_port_data(port); | ||
320 | intfdata = serial->private; | ||
321 | |||
322 | dbg("%s", __func__); | ||
323 | |||
324 | /* Start reading from the IN endpoint */ | ||
325 | for (i = 0; i < N_IN_URB; i++) { | ||
326 | urb = portdata->in_urbs[i]; | ||
327 | if (!urb) | ||
328 | continue; | ||
329 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
330 | if (err) { | ||
331 | dbg("%s: submit urb %d failed (%d) %d", | ||
332 | __func__, i, err, urb->transfer_buffer_length); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | if (intfdata->send_setup) | ||
337 | intfdata->send_setup(port); | ||
338 | |||
339 | serial->interface->needs_remote_wakeup = 1; | ||
340 | spin_lock_irq(&intfdata->susp_lock); | ||
341 | portdata->opened = 1; | ||
342 | spin_unlock_irq(&intfdata->susp_lock); | ||
343 | usb_autopm_put_interface(serial->interface); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | EXPORT_SYMBOL(usb_wwan_open); | ||
348 | |||
349 | void usb_wwan_close(struct usb_serial_port *port) | ||
350 | { | ||
351 | int i; | ||
352 | struct usb_serial *serial = port->serial; | ||
353 | struct usb_wwan_port_private *portdata; | ||
354 | struct usb_wwan_intf_private *intfdata = port->serial->private; | ||
355 | |||
356 | dbg("%s", __func__); | ||
357 | portdata = usb_get_serial_port_data(port); | ||
358 | |||
359 | if (serial->dev) { | ||
360 | /* Stop reading/writing urbs */ | ||
361 | spin_lock_irq(&intfdata->susp_lock); | ||
362 | portdata->opened = 0; | ||
363 | spin_unlock_irq(&intfdata->susp_lock); | ||
364 | |||
365 | for (i = 0; i < N_IN_URB; i++) | ||
366 | usb_kill_urb(portdata->in_urbs[i]); | ||
367 | for (i = 0; i < N_OUT_URB; i++) | ||
368 | usb_kill_urb(portdata->out_urbs[i]); | ||
369 | usb_autopm_get_interface(serial->interface); | ||
370 | serial->interface->needs_remote_wakeup = 0; | ||
371 | } | ||
372 | } | ||
373 | EXPORT_SYMBOL(usb_wwan_close); | ||
374 | |||
375 | /* Helper functions used by usb_wwan_setup_urbs */ | ||
376 | static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, | ||
377 | int dir, void *ctx, char *buf, int len, | ||
378 | void (*callback) (struct urb *)) | ||
379 | { | ||
380 | struct urb *urb; | ||
381 | |||
382 | if (endpoint == -1) | ||
383 | return NULL; /* endpoint not needed */ | ||
384 | |||
385 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | ||
386 | if (urb == NULL) { | ||
387 | dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); | ||
388 | return NULL; | ||
389 | } | ||
390 | |||
391 | /* Fill URB using supplied data. */ | ||
392 | usb_fill_bulk_urb(urb, serial->dev, | ||
393 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
394 | buf, len, callback, ctx); | ||
395 | |||
396 | return urb; | ||
397 | } | ||
398 | |||
399 | /* Setup urbs */ | ||
400 | static void usb_wwan_setup_urbs(struct usb_serial *serial) | ||
401 | { | ||
402 | int i, j; | ||
403 | struct usb_serial_port *port; | ||
404 | struct usb_wwan_port_private *portdata; | ||
405 | |||
406 | dbg("%s", __func__); | ||
407 | |||
408 | for (i = 0; i < serial->num_ports; i++) { | ||
409 | port = serial->port[i]; | ||
410 | portdata = usb_get_serial_port_data(port); | ||
411 | |||
412 | /* Do indat endpoints first */ | ||
413 | for (j = 0; j < N_IN_URB; ++j) { | ||
414 | portdata->in_urbs[j] = usb_wwan_setup_urb(serial, | ||
415 | port-> | ||
416 | bulk_in_endpointAddress, | ||
417 | USB_DIR_IN, | ||
418 | port, | ||
419 | portdata-> | ||
420 | in_buffer[j], | ||
421 | IN_BUFLEN, | ||
422 | usb_wwan_indat_callback); | ||
423 | } | ||
424 | |||
425 | /* outdat endpoints */ | ||
426 | for (j = 0; j < N_OUT_URB; ++j) { | ||
427 | portdata->out_urbs[j] = usb_wwan_setup_urb(serial, | ||
428 | port-> | ||
429 | bulk_out_endpointAddress, | ||
430 | USB_DIR_OUT, | ||
431 | port, | ||
432 | portdata-> | ||
433 | out_buffer | ||
434 | [j], | ||
435 | OUT_BUFLEN, | ||
436 | usb_wwan_outdat_callback); | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | int usb_wwan_startup(struct usb_serial *serial) | ||
442 | { | ||
443 | int i, j, err; | ||
444 | struct usb_serial_port *port; | ||
445 | struct usb_wwan_port_private *portdata; | ||
446 | u8 *buffer; | ||
447 | |||
448 | dbg("%s", __func__); | ||
449 | |||
450 | /* Now setup per port private data */ | ||
451 | for (i = 0; i < serial->num_ports; i++) { | ||
452 | port = serial->port[i]; | ||
453 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
454 | if (!portdata) { | ||
455 | dbg("%s: kmalloc for usb_wwan_port_private (%d) failed!.", | ||
456 | __func__, i); | ||
457 | return 1; | ||
458 | } | ||
459 | init_usb_anchor(&portdata->delayed); | ||
460 | |||
461 | for (j = 0; j < N_IN_URB; j++) { | ||
462 | buffer = (u8 *) __get_free_page(GFP_KERNEL); | ||
463 | if (!buffer) | ||
464 | goto bail_out_error; | ||
465 | portdata->in_buffer[j] = buffer; | ||
466 | } | ||
467 | |||
468 | for (j = 0; j < N_OUT_URB; j++) { | ||
469 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); | ||
470 | if (!buffer) | ||
471 | goto bail_out_error2; | ||
472 | portdata->out_buffer[j] = buffer; | ||
473 | } | ||
474 | |||
475 | usb_set_serial_port_data(port, portdata); | ||
476 | |||
477 | if (!port->interrupt_in_urb) | ||
478 | continue; | ||
479 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
480 | if (err) | ||
481 | dbg("%s: submit irq_in urb failed %d", __func__, err); | ||
482 | } | ||
483 | usb_wwan_setup_urbs(serial); | ||
484 | return 0; | ||
485 | |||
486 | bail_out_error2: | ||
487 | for (j = 0; j < N_OUT_URB; j++) | ||
488 | kfree(portdata->out_buffer[j]); | ||
489 | bail_out_error: | ||
490 | for (j = 0; j < N_IN_URB; j++) | ||
491 | if (portdata->in_buffer[j]) | ||
492 | free_page((unsigned long)portdata->in_buffer[j]); | ||
493 | kfree(portdata); | ||
494 | return 1; | ||
495 | } | ||
496 | EXPORT_SYMBOL(usb_wwan_startup); | ||
497 | |||
498 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
499 | { | ||
500 | int i, j; | ||
501 | struct usb_serial_port *port; | ||
502 | struct usb_wwan_port_private *portdata; | ||
503 | |||
504 | /* Stop reading/writing urbs */ | ||
505 | for (i = 0; i < serial->num_ports; ++i) { | ||
506 | port = serial->port[i]; | ||
507 | portdata = usb_get_serial_port_data(port); | ||
508 | for (j = 0; j < N_IN_URB; j++) | ||
509 | usb_kill_urb(portdata->in_urbs[j]); | ||
510 | for (j = 0; j < N_OUT_URB; j++) | ||
511 | usb_kill_urb(portdata->out_urbs[j]); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | void usb_wwan_disconnect(struct usb_serial *serial) | ||
516 | { | ||
517 | dbg("%s", __func__); | ||
518 | |||
519 | stop_read_write_urbs(serial); | ||
520 | } | ||
521 | EXPORT_SYMBOL(usb_wwan_disconnect); | ||
522 | |||
523 | void usb_wwan_release(struct usb_serial *serial) | ||
524 | { | ||
525 | int i, j; | ||
526 | struct usb_serial_port *port; | ||
527 | struct usb_wwan_port_private *portdata; | ||
528 | |||
529 | dbg("%s", __func__); | ||
530 | |||
531 | /* Now free them */ | ||
532 | for (i = 0; i < serial->num_ports; ++i) { | ||
533 | port = serial->port[i]; | ||
534 | portdata = usb_get_serial_port_data(port); | ||
535 | |||
536 | for (j = 0; j < N_IN_URB; j++) { | ||
537 | usb_free_urb(portdata->in_urbs[j]); | ||
538 | free_page((unsigned long) | ||
539 | portdata->in_buffer[j]); | ||
540 | portdata->in_urbs[j] = NULL; | ||
541 | } | ||
542 | for (j = 0; j < N_OUT_URB; j++) { | ||
543 | usb_free_urb(portdata->out_urbs[j]); | ||
544 | kfree(portdata->out_buffer[j]); | ||
545 | portdata->out_urbs[j] = NULL; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | /* Now free per port private data */ | ||
550 | for (i = 0; i < serial->num_ports; i++) { | ||
551 | port = serial->port[i]; | ||
552 | kfree(usb_get_serial_port_data(port)); | ||
553 | } | ||
554 | } | ||
555 | EXPORT_SYMBOL(usb_wwan_release); | ||
556 | |||
557 | #ifdef CONFIG_PM | ||
558 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) | ||
559 | { | ||
560 | struct usb_wwan_intf_private *intfdata = serial->private; | ||
561 | int b; | ||
562 | |||
563 | dbg("%s entered", __func__); | ||
564 | |||
565 | if (message.event & PM_EVENT_AUTO) { | ||
566 | spin_lock_irq(&intfdata->susp_lock); | ||
567 | b = intfdata->in_flight; | ||
568 | spin_unlock_irq(&intfdata->susp_lock); | ||
569 | |||
570 | if (b) | ||
571 | return -EBUSY; | ||
572 | } | ||
573 | |||
574 | spin_lock_irq(&intfdata->susp_lock); | ||
575 | intfdata->suspended = 1; | ||
576 | spin_unlock_irq(&intfdata->susp_lock); | ||
577 | stop_read_write_urbs(serial); | ||
578 | |||
579 | return 0; | ||
580 | } | ||
581 | EXPORT_SYMBOL(usb_wwan_suspend); | ||
582 | |||
583 | static void play_delayed(struct usb_serial_port *port) | ||
584 | { | ||
585 | struct usb_wwan_intf_private *data; | ||
586 | struct usb_wwan_port_private *portdata; | ||
587 | struct urb *urb; | ||
588 | int err; | ||
589 | |||
590 | portdata = usb_get_serial_port_data(port); | ||
591 | data = port->serial->private; | ||
592 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | ||
593 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
594 | if (!err) | ||
595 | data->in_flight++; | ||
596 | } | ||
597 | } | ||
598 | |||
599 | int usb_wwan_resume(struct usb_serial *serial) | ||
600 | { | ||
601 | int i, j; | ||
602 | struct usb_serial_port *port; | ||
603 | struct usb_wwan_intf_private *intfdata = serial->private; | ||
604 | struct usb_wwan_port_private *portdata; | ||
605 | struct urb *urb; | ||
606 | int err = 0; | ||
607 | |||
608 | dbg("%s entered", __func__); | ||
609 | /* get the interrupt URBs resubmitted unconditionally */ | ||
610 | for (i = 0; i < serial->num_ports; i++) { | ||
611 | port = serial->port[i]; | ||
612 | if (!port->interrupt_in_urb) { | ||
613 | dbg("%s: No interrupt URB for port %d", __func__, i); | ||
614 | continue; | ||
615 | } | ||
616 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | ||
617 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | ||
618 | if (err < 0) { | ||
619 | err("%s: Error %d for interrupt URB of port%d", | ||
620 | __func__, err, i); | ||
621 | goto err_out; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | for (i = 0; i < serial->num_ports; i++) { | ||
626 | /* walk all ports */ | ||
627 | port = serial->port[i]; | ||
628 | portdata = usb_get_serial_port_data(port); | ||
629 | |||
630 | /* skip closed ports */ | ||
631 | spin_lock_irq(&intfdata->susp_lock); | ||
632 | if (!portdata->opened) { | ||
633 | spin_unlock_irq(&intfdata->susp_lock); | ||
634 | continue; | ||
635 | } | ||
636 | |||
637 | for (j = 0; j < N_IN_URB; j++) { | ||
638 | urb = portdata->in_urbs[j]; | ||
639 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
640 | if (err < 0) { | ||
641 | err("%s: Error %d for bulk URB %d", | ||
642 | __func__, err, i); | ||
643 | spin_unlock_irq(&intfdata->susp_lock); | ||
644 | goto err_out; | ||
645 | } | ||
646 | } | ||
647 | play_delayed(port); | ||
648 | spin_unlock_irq(&intfdata->susp_lock); | ||
649 | } | ||
650 | spin_lock_irq(&intfdata->susp_lock); | ||
651 | intfdata->suspended = 0; | ||
652 | spin_unlock_irq(&intfdata->susp_lock); | ||
653 | err_out: | ||
654 | return err; | ||
655 | } | ||
656 | EXPORT_SYMBOL(usb_wwan_resume); | ||
657 | #endif | ||
658 | |||
659 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
660 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
661 | MODULE_VERSION(DRIVER_VERSION); | ||
662 | MODULE_LICENSE("GPL"); | ||
663 | |||
664 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
665 | MODULE_PARM_DESC(debug, "Debug messages"); | ||
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 094942707c7d..eb76aaef4268 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -38,17 +38,9 @@ | |||
38 | /* function prototypes for a handspring visor */ | 38 | /* function prototypes for a handspring visor */ |
39 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); | 39 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); |
40 | static void visor_close(struct usb_serial_port *port); | 40 | static void visor_close(struct usb_serial_port *port); |
41 | static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
42 | const unsigned char *buf, int count); | ||
43 | static int visor_write_room(struct tty_struct *tty); | ||
44 | static void visor_throttle(struct tty_struct *tty); | ||
45 | static void visor_unthrottle(struct tty_struct *tty); | ||
46 | static int visor_probe(struct usb_serial *serial, | 41 | static int visor_probe(struct usb_serial *serial, |
47 | const struct usb_device_id *id); | 42 | const struct usb_device_id *id); |
48 | static int visor_calc_num_ports(struct usb_serial *serial); | 43 | static int visor_calc_num_ports(struct usb_serial *serial); |
49 | static void visor_release(struct usb_serial *serial); | ||
50 | static void visor_write_bulk_callback(struct urb *urb); | ||
51 | static void visor_read_bulk_callback(struct urb *urb); | ||
52 | static void visor_read_int_callback(struct urb *urb); | 44 | static void visor_read_int_callback(struct urb *urb); |
53 | static int clie_3_5_startup(struct usb_serial *serial); | 45 | static int clie_3_5_startup(struct usb_serial *serial); |
54 | static int treo_attach(struct usb_serial *serial); | 46 | static int treo_attach(struct usb_serial *serial); |
@@ -194,18 +186,14 @@ static struct usb_serial_driver handspring_device = { | |||
194 | .usb_driver = &visor_driver, | 186 | .usb_driver = &visor_driver, |
195 | .id_table = id_table, | 187 | .id_table = id_table, |
196 | .num_ports = 2, | 188 | .num_ports = 2, |
189 | .bulk_out_size = 256, | ||
197 | .open = visor_open, | 190 | .open = visor_open, |
198 | .close = visor_close, | 191 | .close = visor_close, |
199 | .throttle = visor_throttle, | 192 | .throttle = usb_serial_generic_throttle, |
200 | .unthrottle = visor_unthrottle, | 193 | .unthrottle = usb_serial_generic_unthrottle, |
201 | .attach = treo_attach, | 194 | .attach = treo_attach, |
202 | .probe = visor_probe, | 195 | .probe = visor_probe, |
203 | .calc_num_ports = visor_calc_num_ports, | 196 | .calc_num_ports = visor_calc_num_ports, |
204 | .release = visor_release, | ||
205 | .write = visor_write, | ||
206 | .write_room = visor_write_room, | ||
207 | .write_bulk_callback = visor_write_bulk_callback, | ||
208 | .read_bulk_callback = visor_read_bulk_callback, | ||
209 | .read_int_callback = visor_read_int_callback, | 197 | .read_int_callback = visor_read_int_callback, |
210 | }; | 198 | }; |
211 | 199 | ||
@@ -219,18 +207,14 @@ static struct usb_serial_driver clie_5_device = { | |||
219 | .usb_driver = &visor_driver, | 207 | .usb_driver = &visor_driver, |
220 | .id_table = clie_id_5_table, | 208 | .id_table = clie_id_5_table, |
221 | .num_ports = 2, | 209 | .num_ports = 2, |
210 | .bulk_out_size = 256, | ||
222 | .open = visor_open, | 211 | .open = visor_open, |
223 | .close = visor_close, | 212 | .close = visor_close, |
224 | .throttle = visor_throttle, | 213 | .throttle = usb_serial_generic_throttle, |
225 | .unthrottle = visor_unthrottle, | 214 | .unthrottle = usb_serial_generic_unthrottle, |
226 | .attach = clie_5_attach, | 215 | .attach = clie_5_attach, |
227 | .probe = visor_probe, | 216 | .probe = visor_probe, |
228 | .calc_num_ports = visor_calc_num_ports, | 217 | .calc_num_ports = visor_calc_num_ports, |
229 | .release = visor_release, | ||
230 | .write = visor_write, | ||
231 | .write_room = visor_write_room, | ||
232 | .write_bulk_callback = visor_write_bulk_callback, | ||
233 | .read_bulk_callback = visor_read_bulk_callback, | ||
234 | .read_int_callback = visor_read_int_callback, | 218 | .read_int_callback = visor_read_int_callback, |
235 | }; | 219 | }; |
236 | 220 | ||
@@ -244,39 +228,19 @@ static struct usb_serial_driver clie_3_5_device = { | |||
244 | .usb_driver = &visor_driver, | 228 | .usb_driver = &visor_driver, |
245 | .id_table = clie_id_3_5_table, | 229 | .id_table = clie_id_3_5_table, |
246 | .num_ports = 1, | 230 | .num_ports = 1, |
231 | .bulk_out_size = 256, | ||
247 | .open = visor_open, | 232 | .open = visor_open, |
248 | .close = visor_close, | 233 | .close = visor_close, |
249 | .throttle = visor_throttle, | 234 | .throttle = usb_serial_generic_throttle, |
250 | .unthrottle = visor_unthrottle, | 235 | .unthrottle = usb_serial_generic_unthrottle, |
251 | .attach = clie_3_5_startup, | 236 | .attach = clie_3_5_startup, |
252 | .write = visor_write, | ||
253 | .write_room = visor_write_room, | ||
254 | .write_bulk_callback = visor_write_bulk_callback, | ||
255 | .read_bulk_callback = visor_read_bulk_callback, | ||
256 | }; | 237 | }; |
257 | 238 | ||
258 | struct visor_private { | ||
259 | spinlock_t lock; | ||
260 | int bytes_in; | ||
261 | int bytes_out; | ||
262 | int outstanding_urbs; | ||
263 | unsigned char throttled; | ||
264 | unsigned char actually_throttled; | ||
265 | }; | ||
266 | |||
267 | /* number of outstanding urbs to prevent userspace DoS from happening */ | ||
268 | #define URB_UPPER_LIMIT 42 | ||
269 | |||
270 | static int stats; | ||
271 | |||
272 | /****************************************************************************** | 239 | /****************************************************************************** |
273 | * Handspring Visor specific driver functions | 240 | * Handspring Visor specific driver functions |
274 | ******************************************************************************/ | 241 | ******************************************************************************/ |
275 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) | 242 | static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) |
276 | { | 243 | { |
277 | struct usb_serial *serial = port->serial; | ||
278 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
279 | unsigned long flags; | ||
280 | int result = 0; | 244 | int result = 0; |
281 | 245 | ||
282 | dbg("%s - port %d", __func__, port->number); | 246 | dbg("%s - port %d", __func__, port->number); |
@@ -287,26 +251,10 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
287 | return -ENODEV; | 251 | return -ENODEV; |
288 | } | 252 | } |
289 | 253 | ||
290 | spin_lock_irqsave(&priv->lock, flags); | ||
291 | priv->bytes_in = 0; | ||
292 | priv->bytes_out = 0; | ||
293 | priv->throttled = 0; | ||
294 | spin_unlock_irqrestore(&priv->lock, flags); | ||
295 | |||
296 | /* Start reading from the device */ | 254 | /* Start reading from the device */ |
297 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 255 | result = usb_serial_generic_open(tty, port); |
298 | usb_rcvbulkpipe(serial->dev, | 256 | if (result) |
299 | port->bulk_in_endpointAddress), | ||
300 | port->read_urb->transfer_buffer, | ||
301 | port->read_urb->transfer_buffer_length, | ||
302 | visor_read_bulk_callback, port); | ||
303 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
304 | if (result) { | ||
305 | dev_err(&port->dev, | ||
306 | "%s - failed submitting read urb, error %d\n", | ||
307 | __func__, result); | ||
308 | goto exit; | 257 | goto exit; |
309 | } | ||
310 | 258 | ||
311 | if (port->interrupt_in_urb) { | 259 | if (port->interrupt_in_urb) { |
312 | dbg("%s - adding interrupt input for treo", __func__); | 260 | dbg("%s - adding interrupt input for treo", __func__); |
@@ -323,13 +271,12 @@ exit: | |||
323 | 271 | ||
324 | static void visor_close(struct usb_serial_port *port) | 272 | static void visor_close(struct usb_serial_port *port) |
325 | { | 273 | { |
326 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
327 | unsigned char *transfer_buffer; | 274 | unsigned char *transfer_buffer; |
328 | 275 | ||
329 | dbg("%s - port %d", __func__, port->number); | 276 | dbg("%s - port %d", __func__, port->number); |
330 | 277 | ||
331 | /* shutdown our urbs */ | 278 | /* shutdown our urbs */ |
332 | usb_kill_urb(port->read_urb); | 279 | usb_serial_generic_close(port); |
333 | usb_kill_urb(port->interrupt_in_urb); | 280 | usb_kill_urb(port->interrupt_in_urb); |
334 | 281 | ||
335 | mutex_lock(&port->serial->disc_mutex); | 282 | mutex_lock(&port->serial->disc_mutex); |
@@ -346,192 +293,6 @@ static void visor_close(struct usb_serial_port *port) | |||
346 | } | 293 | } |
347 | } | 294 | } |
348 | mutex_unlock(&port->serial->disc_mutex); | 295 | mutex_unlock(&port->serial->disc_mutex); |
349 | |||
350 | if (stats) | ||
351 | dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", | ||
352 | priv->bytes_in, priv->bytes_out); | ||
353 | } | ||
354 | |||
355 | |||
356 | static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
357 | const unsigned char *buf, int count) | ||
358 | { | ||
359 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
360 | struct usb_serial *serial = port->serial; | ||
361 | struct urb *urb; | ||
362 | unsigned char *buffer; | ||
363 | unsigned long flags; | ||
364 | int status; | ||
365 | |||
366 | dbg("%s - port %d", __func__, port->number); | ||
367 | |||
368 | spin_lock_irqsave(&priv->lock, flags); | ||
369 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { | ||
370 | spin_unlock_irqrestore(&priv->lock, flags); | ||
371 | dbg("%s - write limit hit", __func__); | ||
372 | return 0; | ||
373 | } | ||
374 | priv->outstanding_urbs++; | ||
375 | spin_unlock_irqrestore(&priv->lock, flags); | ||
376 | |||
377 | buffer = kmalloc(count, GFP_ATOMIC); | ||
378 | if (!buffer) { | ||
379 | dev_err(&port->dev, "out of memory\n"); | ||
380 | count = -ENOMEM; | ||
381 | goto error_no_buffer; | ||
382 | } | ||
383 | |||
384 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
385 | if (!urb) { | ||
386 | dev_err(&port->dev, "no more free urbs\n"); | ||
387 | count = -ENOMEM; | ||
388 | goto error_no_urb; | ||
389 | } | ||
390 | |||
391 | memcpy(buffer, buf, count); | ||
392 | |||
393 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | ||
394 | |||
395 | usb_fill_bulk_urb(urb, serial->dev, | ||
396 | usb_sndbulkpipe(serial->dev, | ||
397 | port->bulk_out_endpointAddress), | ||
398 | buffer, count, | ||
399 | visor_write_bulk_callback, port); | ||
400 | |||
401 | /* send it down the pipe */ | ||
402 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
403 | if (status) { | ||
404 | dev_err(&port->dev, | ||
405 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", | ||
406 | __func__, status); | ||
407 | count = status; | ||
408 | goto error; | ||
409 | } else { | ||
410 | spin_lock_irqsave(&priv->lock, flags); | ||
411 | priv->bytes_out += count; | ||
412 | spin_unlock_irqrestore(&priv->lock, flags); | ||
413 | } | ||
414 | |||
415 | /* we are done with this urb, so let the host driver | ||
416 | * really free it when it is finished with it */ | ||
417 | usb_free_urb(urb); | ||
418 | |||
419 | return count; | ||
420 | error: | ||
421 | usb_free_urb(urb); | ||
422 | error_no_urb: | ||
423 | kfree(buffer); | ||
424 | error_no_buffer: | ||
425 | spin_lock_irqsave(&priv->lock, flags); | ||
426 | --priv->outstanding_urbs; | ||
427 | spin_unlock_irqrestore(&priv->lock, flags); | ||
428 | return count; | ||
429 | } | ||
430 | |||
431 | |||
432 | static int visor_write_room(struct tty_struct *tty) | ||
433 | { | ||
434 | struct usb_serial_port *port = tty->driver_data; | ||
435 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
436 | unsigned long flags; | ||
437 | |||
438 | dbg("%s - port %d", __func__, port->number); | ||
439 | |||
440 | /* | ||
441 | * We really can take anything the user throws at us | ||
442 | * but let's pick a nice big number to tell the tty | ||
443 | * layer that we have lots of free space, unless we don't. | ||
444 | */ | ||
445 | |||
446 | spin_lock_irqsave(&priv->lock, flags); | ||
447 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | ||
448 | spin_unlock_irqrestore(&priv->lock, flags); | ||
449 | dbg("%s - write limit hit", __func__); | ||
450 | return 0; | ||
451 | } | ||
452 | spin_unlock_irqrestore(&priv->lock, flags); | ||
453 | |||
454 | return 2048; | ||
455 | } | ||
456 | |||
457 | |||
458 | static void visor_write_bulk_callback(struct urb *urb) | ||
459 | { | ||
460 | struct usb_serial_port *port = urb->context; | ||
461 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
462 | int status = urb->status; | ||
463 | unsigned long flags; | ||
464 | |||
465 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
466 | kfree(urb->transfer_buffer); | ||
467 | |||
468 | dbg("%s - port %d", __func__, port->number); | ||
469 | |||
470 | if (status) | ||
471 | dbg("%s - nonzero write bulk status received: %d", | ||
472 | __func__, status); | ||
473 | |||
474 | spin_lock_irqsave(&priv->lock, flags); | ||
475 | --priv->outstanding_urbs; | ||
476 | spin_unlock_irqrestore(&priv->lock, flags); | ||
477 | |||
478 | usb_serial_port_softint(port); | ||
479 | } | ||
480 | |||
481 | |||
482 | static void visor_read_bulk_callback(struct urb *urb) | ||
483 | { | ||
484 | struct usb_serial_port *port = urb->context; | ||
485 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
486 | unsigned char *data = urb->transfer_buffer; | ||
487 | int status = urb->status; | ||
488 | struct tty_struct *tty; | ||
489 | int result; | ||
490 | int available_room = 0; | ||
491 | |||
492 | dbg("%s - port %d", __func__, port->number); | ||
493 | |||
494 | if (status) { | ||
495 | dbg("%s - nonzero read bulk status received: %d", | ||
496 | __func__, status); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
501 | urb->actual_length, data); | ||
502 | |||
503 | if (urb->actual_length) { | ||
504 | tty = tty_port_tty_get(&port->port); | ||
505 | if (tty) { | ||
506 | tty_insert_flip_string(tty, data, | ||
507 | urb->actual_length); | ||
508 | tty_flip_buffer_push(tty); | ||
509 | tty_kref_put(tty); | ||
510 | } | ||
511 | spin_lock(&priv->lock); | ||
512 | if (tty) | ||
513 | priv->bytes_in += available_room; | ||
514 | |||
515 | } else { | ||
516 | spin_lock(&priv->lock); | ||
517 | } | ||
518 | |||
519 | /* Continue trying to always read if we should */ | ||
520 | if (!priv->throttled) { | ||
521 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
522 | usb_rcvbulkpipe(port->serial->dev, | ||
523 | port->bulk_in_endpointAddress), | ||
524 | port->read_urb->transfer_buffer, | ||
525 | port->read_urb->transfer_buffer_length, | ||
526 | visor_read_bulk_callback, port); | ||
527 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
528 | if (result) | ||
529 | dev_err(&port->dev, | ||
530 | "%s - failed resubmitting read urb, error %d\n", | ||
531 | __func__, result); | ||
532 | } else | ||
533 | priv->actually_throttled = 1; | ||
534 | spin_unlock(&priv->lock); | ||
535 | } | 296 | } |
536 | 297 | ||
537 | static void visor_read_int_callback(struct urb *urb) | 298 | static void visor_read_int_callback(struct urb *urb) |
@@ -575,41 +336,6 @@ exit: | |||
575 | __func__, result); | 336 | __func__, result); |
576 | } | 337 | } |
577 | 338 | ||
578 | static void visor_throttle(struct tty_struct *tty) | ||
579 | { | ||
580 | struct usb_serial_port *port = tty->driver_data; | ||
581 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
582 | |||
583 | dbg("%s - port %d", __func__, port->number); | ||
584 | spin_lock_irq(&priv->lock); | ||
585 | priv->throttled = 1; | ||
586 | spin_unlock_irq(&priv->lock); | ||
587 | } | ||
588 | |||
589 | |||
590 | static void visor_unthrottle(struct tty_struct *tty) | ||
591 | { | ||
592 | struct usb_serial_port *port = tty->driver_data; | ||
593 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
594 | int result, was_throttled; | ||
595 | |||
596 | dbg("%s - port %d", __func__, port->number); | ||
597 | spin_lock_irq(&priv->lock); | ||
598 | priv->throttled = 0; | ||
599 | was_throttled = priv->actually_throttled; | ||
600 | priv->actually_throttled = 0; | ||
601 | spin_unlock_irq(&priv->lock); | ||
602 | |||
603 | if (was_throttled) { | ||
604 | port->read_urb->dev = port->serial->dev; | ||
605 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
606 | if (result) | ||
607 | dev_err(&port->dev, | ||
608 | "%s - failed submitting read urb, error %d\n", | ||
609 | __func__, result); | ||
610 | } | ||
611 | } | ||
612 | |||
613 | static int palm_os_3_probe(struct usb_serial *serial, | 339 | static int palm_os_3_probe(struct usb_serial *serial, |
614 | const struct usb_device_id *id) | 340 | const struct usb_device_id *id) |
615 | { | 341 | { |
@@ -777,28 +503,6 @@ static int visor_calc_num_ports(struct usb_serial *serial) | |||
777 | return num_ports; | 503 | return num_ports; |
778 | } | 504 | } |
779 | 505 | ||
780 | static int generic_startup(struct usb_serial *serial) | ||
781 | { | ||
782 | struct usb_serial_port **ports = serial->port; | ||
783 | struct visor_private *priv; | ||
784 | int i; | ||
785 | |||
786 | for (i = 0; i < serial->num_ports; ++i) { | ||
787 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
788 | if (!priv) { | ||
789 | while (i-- != 0) { | ||
790 | priv = usb_get_serial_port_data(ports[i]); | ||
791 | usb_set_serial_port_data(ports[i], NULL); | ||
792 | kfree(priv); | ||
793 | } | ||
794 | return -ENOMEM; | ||
795 | } | ||
796 | spin_lock_init(&priv->lock); | ||
797 | usb_set_serial_port_data(ports[i], priv); | ||
798 | } | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | static int clie_3_5_startup(struct usb_serial *serial) | 506 | static int clie_3_5_startup(struct usb_serial *serial) |
803 | { | 507 | { |
804 | struct device *dev = &serial->dev->dev; | 508 | struct device *dev = &serial->dev->dev; |
@@ -849,7 +553,7 @@ static int clie_3_5_startup(struct usb_serial *serial) | |||
849 | goto out; | 553 | goto out; |
850 | } | 554 | } |
851 | 555 | ||
852 | result = generic_startup(serial); | 556 | result = 0; |
853 | out: | 557 | out: |
854 | kfree(data); | 558 | kfree(data); |
855 | 559 | ||
@@ -867,7 +571,7 @@ static int treo_attach(struct usb_serial *serial) | |||
867 | (le16_to_cpu(serial->dev->descriptor.idVendor) | 571 | (le16_to_cpu(serial->dev->descriptor.idVendor) |
868 | == KYOCERA_VENDOR_ID)) || | 572 | == KYOCERA_VENDOR_ID)) || |
869 | (serial->num_interrupt_in == 0)) | 573 | (serial->num_interrupt_in == 0)) |
870 | goto generic_startup; | 574 | return 0; |
871 | 575 | ||
872 | dbg("%s", __func__); | 576 | dbg("%s", __func__); |
873 | 577 | ||
@@ -897,8 +601,7 @@ static int treo_attach(struct usb_serial *serial) | |||
897 | COPY_PORT(serial->port[1], swap_port); | 601 | COPY_PORT(serial->port[1], swap_port); |
898 | kfree(swap_port); | 602 | kfree(swap_port); |
899 | 603 | ||
900 | generic_startup: | 604 | return 0; |
901 | return generic_startup(serial); | ||
902 | } | 605 | } |
903 | 606 | ||
904 | static int clie_5_attach(struct usb_serial *serial) | 607 | static int clie_5_attach(struct usb_serial *serial) |
@@ -921,20 +624,7 @@ static int clie_5_attach(struct usb_serial *serial) | |||
921 | serial->port[0]->bulk_out_endpointAddress = | 624 | serial->port[0]->bulk_out_endpointAddress = |
922 | serial->port[1]->bulk_out_endpointAddress; | 625 | serial->port[1]->bulk_out_endpointAddress; |
923 | 626 | ||
924 | return generic_startup(serial); | 627 | return 0; |
925 | } | ||
926 | |||
927 | static void visor_release(struct usb_serial *serial) | ||
928 | { | ||
929 | struct visor_private *priv; | ||
930 | int i; | ||
931 | |||
932 | dbg("%s", __func__); | ||
933 | |||
934 | for (i = 0; i < serial->num_ports; i++) { | ||
935 | priv = usb_get_serial_port_data(serial->port[i]); | ||
936 | kfree(priv); | ||
937 | } | ||
938 | } | 628 | } |
939 | 629 | ||
940 | static int __init visor_init(void) | 630 | static int __init visor_init(void) |
@@ -1018,8 +708,6 @@ MODULE_LICENSE("GPL"); | |||
1018 | 708 | ||
1019 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 709 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
1020 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 710 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
1021 | module_param(stats, bool, S_IRUGO | S_IWUSR); | ||
1022 | MODULE_PARM_DESC(stats, "Enables statistics or not"); | ||
1023 | 711 | ||
1024 | module_param(vendor, ushort, 0); | 712 | module_param(vendor, ushort, 0); |
1025 | MODULE_PARM_DESC(vendor, "User specified vendor ID"); | 713 | MODULE_PARM_DESC(vendor, "User specified vendor ID"); |
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 57229cf66477..88db4d06aefb 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h | |||
@@ -9,8 +9,9 @@ | |||
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 12 | * See Documentation/usb/usb-serial.txt for more information on using this |
13 | * | 13 | * driver. |
14 | * | ||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #ifndef __LINUX_USB_SERIAL_VISOR_H | 17 | #ifndef __LINUX_USB_SERIAL_VISOR_H |
@@ -65,7 +66,7 @@ | |||
65 | #define ACEECA_MEZ1000_ID 0x0001 | 66 | #define ACEECA_MEZ1000_ID 0x0001 |
66 | 67 | ||
67 | #define KYOCERA_VENDOR_ID 0x0C88 | 68 | #define KYOCERA_VENDOR_ID 0x0C88 |
68 | #define KYOCERA_7135_ID 0x0021 | 69 | #define KYOCERA_7135_ID 0x0021 |
69 | 70 | ||
70 | #define FOSSIL_VENDOR_ID 0x0E67 | 71 | #define FOSSIL_VENDOR_ID 0x0E67 |
71 | #define FOSSIL_ABACUS_ID 0x0002 | 72 | #define FOSSIL_ABACUS_ID 0x0002 |
@@ -145,7 +146,7 @@ struct visor_connection_info { | |||
145 | * The maximum number of connections currently supported is 2 | 146 | * The maximum number of connections currently supported is 2 |
146 | */ | 147 | */ |
147 | struct palm_ext_connection_info { | 148 | struct palm_ext_connection_info { |
148 | __u8 num_ports; | 149 | __u8 num_ports; |
149 | __u8 endpoint_numbers_different; | 150 | __u8 endpoint_numbers_different; |
150 | __le16 reserved1; | 151 | __le16 reserved1; |
151 | struct { | 152 | struct { |
diff --git a/drivers/usb/serial/zio.c b/drivers/usb/serial/zio.c new file mode 100644 index 000000000000..f57967278833 --- /dev/null +++ b/drivers/usb/serial/zio.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * ZIO Motherboard USB driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Zilogic Systems <code@zilogic.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/usb.h> | ||
16 | #include <linux/usb/serial.h> | ||
17 | #include <linux/uaccess.h> | ||
18 | |||
19 | static const struct usb_device_id id_table[] = { | ||
20 | { USB_DEVICE(0x1CBE, 0x0103) }, | ||
21 | { }, | ||
22 | }; | ||
23 | MODULE_DEVICE_TABLE(usb, id_table); | ||
24 | |||
25 | static struct usb_driver zio_driver = { | ||
26 | .name = "zio", | ||
27 | .probe = usb_serial_probe, | ||
28 | .disconnect = usb_serial_disconnect, | ||
29 | .id_table = id_table, | ||
30 | .no_dynamic_id = 1, | ||
31 | }; | ||
32 | |||
33 | static struct usb_serial_driver zio_device = { | ||
34 | .driver = { | ||
35 | .owner = THIS_MODULE, | ||
36 | .name = "zio", | ||
37 | }, | ||
38 | .id_table = id_table, | ||
39 | .usb_driver = &zio_driver, | ||
40 | .num_ports = 1, | ||
41 | }; | ||
42 | |||
43 | static int __init zio_init(void) | ||
44 | { | ||
45 | int retval; | ||
46 | |||
47 | retval = usb_serial_register(&zio_device); | ||
48 | if (retval) | ||
49 | return retval; | ||
50 | retval = usb_register(&zio_driver); | ||
51 | if (retval) | ||
52 | usb_serial_deregister(&zio_device); | ||
53 | return retval; | ||
54 | } | ||
55 | |||
56 | static void __exit zio_exit(void) | ||
57 | { | ||
58 | usb_deregister(&zio_driver); | ||
59 | usb_serial_deregister(&zio_device); | ||
60 | } | ||
61 | |||
62 | module_init(zio_init); | ||
63 | module_exit(zio_exit); | ||
64 | MODULE_LICENSE("GPL"); | ||