aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/Kconfig13
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/ark3116.c10
-rw-r--r--drivers/usb/serial/baseband_usb_chr.c1124
-rw-r--r--drivers/usb/serial/baseband_usb_chr.h106
-rw-r--r--drivers/usb/serial/cp210x.c108
-rw-r--r--drivers/usb/serial/ftdi_sio.c61
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h31
-rw-r--r--drivers/usb/serial/garmin_gps.c2
-rw-r--r--drivers/usb/serial/io_ti.c10
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/option.c321
-rw-r--r--drivers/usb/serial/pl2303.c27
-rw-r--r--drivers/usb/serial/pl2303.h5
-rw-r--r--drivers/usb/serial/qcaux.c7
-rw-r--r--drivers/usb/serial/qcserial.c4
16 files changed, 1709 insertions, 123 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index b71e309116a..f6a54356c29 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -661,4 +661,17 @@ config USB_SERIAL_DEBUG
661 To compile this driver as a module, choose M here: the 661 To compile this driver as a module, choose M here: the
662 module will be called usb-debug. 662 module will be called usb-debug.
663 663
664config USB_SERIAL_BASEBAND
665 tristate "USB Baseband Driver"
666 help
667 Say Y here if you want to use USB baseband character driver.
668
669 This driver may be used as a raw character device driver for
670 USB modems. For example, downloading modem firmware upon
671 modem boot up (for flashless modems), or sending modem
672 AT commands after modem software is running on device.
673
674 To compile this driver as a module, choose M here: the
675 module will be called baseband_chr.
676
664endif # USB_SERIAL 677endif # USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 9e536eefb32..2654c327aaf 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -13,6 +13,7 @@ usbserial-$(CONFIG_USB_EZUSB) += ezusb.o
13 13
14obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o 14obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o
15obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o 15obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o
16obj-$(CONFIG_USB_SERIAL_BASEBAND) += baseband_usb_chr.o
16obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o 17obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o
17obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o 18obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o
18obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o 19obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 5cdb9d91227..18e875b92e0 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.6" 45#define DRIVER_VERSION "v0.7"
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"
@@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
380 goto err_out; 380 goto err_out;
381 } 381 }
382 382
383 /* setup termios */
384 if (tty)
385 ark3116_set_termios(tty, port, NULL);
386
387 /* remove any data still left: also clears error state */ 383 /* remove any data still left: also clears error state */
388 ark3116_read_reg(serial, UART_RX, buf); 384 ark3116_read_reg(serial, UART_RX, buf);
389 385
@@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
406 /* enable DMA */ 402 /* enable DMA */
407 ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); 403 ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
408 404
405 /* setup termios */
406 if (tty)
407 ark3116_set_termios(tty, port, NULL);
408
409err_out: 409err_out:
410 kfree(buf); 410 kfree(buf);
411 return result; 411 return result;
diff --git a/drivers/usb/serial/baseband_usb_chr.c b/drivers/usb/serial/baseband_usb_chr.c
new file mode 100644
index 00000000000..6d691a40312
--- /dev/null
+++ b/drivers/usb/serial/baseband_usb_chr.c
@@ -0,0 +1,1124 @@
1/*
2 * baseband_usb_chr.c
3 *
4 * USB character driver to communicate with baseband modems.
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/types.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/cdev.h>
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/list.h>
33#include <linux/errno.h>
34#include <linux/usb.h>
35#include <linux/workqueue.h>
36#include <asm/ioctls.h>
37#include <linux/uaccess.h>
38#include "baseband_usb_chr.h"
39
40MODULE_LICENSE("GPL");
41
42unsigned long baseband_usb_chr_vid = 0x058b;
43unsigned long baseband_usb_chr_pid = 0x0041;
44unsigned long baseband_usb_chr_intf = 0x01;
45
46module_param(baseband_usb_chr_vid, ulong, 0644);
47MODULE_PARM_DESC(baseband_usb_chr_vid, "baseband (usb chr) - USB VID");
48module_param(baseband_usb_chr_pid, ulong, 0644);
49MODULE_PARM_DESC(baseband_usb_chr_pid, "baseband (usb chr) - USB PID");
50module_param(baseband_usb_chr_intf, ulong, 0644);
51MODULE_PARM_DESC(baseband_usb_chr_intf, "baseband (usb chr) - USB interface");
52
53static struct baseband_usb *baseband_usb_chr;
54static bool usb_device_connection;
55
56static atomic_t g_rx_count = ATOMIC_INIT(0);
57
58/* baseband ipc functions */
59
60static void baseband_ipc_dump(const char *prefix, unsigned long int offset,
61 const void *buf, size_t bufsiz)
62{
63 size_t i;
64
65 for (i = 0; i < bufsiz; i += 16) {
66 pr_debug("%s"
67 "[%lx+%x] %p "
68 "%02x %02x %02x %02x "
69 "%02x %02x %02x %02x "
70 "%02x %02x %02x %02x "
71 "%02x %02x %02x %02x\n",
72 prefix,
73 offset,
74 i,
75 ((const unsigned char *) buf) + i,
76 (i + 0 < bufsiz) ? ((const unsigned char *) buf)[i+0]
77 : 0xff,
78 (i + 1 < bufsiz) ? ((const unsigned char *) buf)[i+1]
79 : 0xff,
80 (i + 2 < bufsiz) ? ((const unsigned char *) buf)[i+2]
81 : 0xff,
82 (i + 3 < bufsiz) ? ((const unsigned char *) buf)[i+3]
83 : 0xff,
84 (i + 4 < bufsiz) ? ((const unsigned char *) buf)[i+4]
85 : 0xff,
86 (i + 5 < bufsiz) ? ((const unsigned char *) buf)[i+5]
87 : 0xff,
88 (i + 6 < bufsiz) ? ((const unsigned char *) buf)[i+6]
89 : 0xff,
90 (i + 7 < bufsiz) ? ((const unsigned char *) buf)[i+7]
91 : 0xff,
92 (i + 8 < bufsiz) ? ((const unsigned char *) buf)[i+8]
93 : 0xff,
94 (i + 9 < bufsiz) ? ((const unsigned char *) buf)[i+9]
95 : 0xff,
96 (i + 10 < bufsiz) ? ((const unsigned char *) buf)[i+10]
97 : 0xff,
98 (i + 11 < bufsiz) ? ((const unsigned char *) buf)[i+11]
99 : 0xff,
100 (i + 12 < bufsiz) ? ((const unsigned char *) buf)[i+12]
101 : 0xff,
102 (i + 13 < bufsiz) ? ((const unsigned char *) buf)[i+13]
103 : 0xff,
104 (i + 14 < bufsiz) ? ((const unsigned char *) buf)[i+14]
105 : 0xff,
106 (i + 15 < bufsiz) ? ((const unsigned char *) buf)[i+15]
107 : 0xff);
108 }
109
110}
111
112static size_t peek_ipc_tx_bufsiz(struct baseband_ipc *ipc,
113 size_t bufsiz)
114{
115 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
116 size_t tx_bufsiz;
117
118 pr_debug("peek_ipc_tx_bufsiz\n");
119
120 /* check input */
121 if (!ipc) {
122 pr_err("!ipc\n");
123 return 0;
124 }
125
126 /* acquire tx buffer semaphores */
127 if (down_interruptible(&ipc->buf_sem)) {
128 pr_err("peek_ipc_tx_bufsiz - "
129 "cannot acquire buffer semaphore\n");
130 return -ERESTARTSYS;
131 }
132
133 /* calculate maximum number of tx buffers which can be sent */
134 tx_bufsiz = 0;
135 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
136 {
137 pr_debug("peek_ipc_tx_bufsiz - "
138 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
139 ipc_buf, ipc_buf->offset, ipc_buf->count);
140 if (ipc_buf->count > bufsiz - tx_bufsiz)
141 break;
142 else
143 tx_bufsiz += ipc_buf->count;
144 }
145
146 /* release tx buffer semaphores */
147 up(&ipc->buf_sem);
148
149 return tx_bufsiz;
150}
151
152static size_t get_ipc_tx_buf(struct baseband_ipc *ipc,
153 void *buf, size_t bufsiz)
154{
155 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
156 size_t tx_bufsiz;
157
158 pr_debug("get_ipc_tx_buf\n");
159
160 /* check input */
161 if (!ipc || !buf) {
162 pr_err("!ipc || !buf\n");
163 return 0;
164 }
165 if (!bufsiz)
166 return 0;
167
168 /* acquire tx buffer semaphores */
169 if (down_interruptible(&ipc->buf_sem)) {
170 pr_err("get_ipc_tx_buf - "
171 "cannot acquire buffer semaphore\n");
172 return -ERESTARTSYS;
173 }
174
175 /* get tx data from tx linked list */
176 tx_bufsiz = 0;
177 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
178 {
179 pr_debug("get_ipc_tx_buf - "
180 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
181 ipc_buf, ipc_buf->offset, ipc_buf->count);
182 pr_debug("get_ipc_tx_buf - "
183 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
184 ipc_buf->data[0],
185 ipc_buf->data[1],
186 ipc_buf->data[2],
187 ipc_buf->data[3]);
188 if (ipc_buf->count > bufsiz - tx_bufsiz) {
189 /* copy part of tx buffer */
190 memcpy(buf + tx_bufsiz,
191 ipc_buf->data + ipc_buf->offset,
192 bufsiz - tx_bufsiz);
193 ipc_buf->offset += bufsiz - tx_bufsiz;
194 ipc_buf->count -= bufsiz - tx_bufsiz;
195 tx_bufsiz = bufsiz;
196 } else {
197 /* copy all data from tx buffer */
198 memcpy(buf + tx_bufsiz,
199 ipc_buf->data + ipc_buf->offset,
200 ipc_buf->count);
201 tx_bufsiz += ipc_buf->count;
202 ipc_buf->offset = 0;
203 ipc_buf->count = 0;
204 /* add tx buffer to tx free list */
205 list_move_tail(&ipc_buf->list, &ipc->tx_free.buf);
206 wake_up(&ipc->tx_free.wait);
207 }
208 /* check if done */
209 if (tx_bufsiz == bufsiz)
210 break;
211 }
212
213 /* release tx buffer semaphores */
214 up(&ipc->buf_sem);
215
216 return tx_bufsiz;
217}
218
219static size_t put_ipc_rx_buf(struct baseband_ipc *ipc,
220 const void *buf, size_t bufsiz)
221{
222 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
223 size_t rx_bufsiz;
224
225 pr_debug("put_ipc_rx_buf\n");
226
227 /* check input */
228 if (!ipc || !buf) {
229 pr_err("!ipc || !buf\n");
230 return 0;
231 }
232 if (!bufsiz)
233 return 0;
234
235 /* acquire rx buffer semaphores */
236retry:
237 if (down_interruptible(&ipc->buf_sem)) {
238 pr_err("put_ipc_rx_buf - "
239 "cannot acquire buffer semaphore\n");
240 return -ERESTARTSYS;
241 }
242
243 /* put rx data in rx linked list */
244 rx_bufsiz = 0;
245 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list)
246 {
247 pr_debug("put_ipc_rx_buf - "
248 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
249 ipc_buf, ipc_buf->offset, ipc_buf->count);
250 if (sizeof(ipc_buf->data) > bufsiz - rx_bufsiz) {
251 /* partially fill rx free buffer */
252 memcpy(ipc_buf->data,
253 buf + rx_bufsiz,
254 bufsiz - rx_bufsiz);
255 ipc_buf->offset = 0;
256 ipc_buf->count = bufsiz - rx_bufsiz;
257 rx_bufsiz = bufsiz;
258 } else {
259 /* fill entire rx free buffer */
260 memcpy(ipc_buf->data,
261 buf + rx_bufsiz,
262 sizeof(ipc_buf->data));
263 ipc_buf->offset = 0;
264 ipc_buf->count = sizeof(ipc_buf->data);
265 rx_bufsiz += sizeof(ipc_buf->data);
266 }
267 /* add filled rx free buffer to rx linked list */
268 list_move_tail(&ipc_buf->list, &ipc->rx.buf);
269 wake_up(&ipc->rx.wait);
270 /* check if done */
271 if (rx_bufsiz == bufsiz)
272 break;
273 }
274
275 /* release rx buffer semaphores */
276 up(&ipc->buf_sem);
277
278 /* wait for rx free buffer available */
279 if (!rx_bufsiz) {
280 if (wait_event_interruptible(ipc->rx_free.wait,
281 !list_empty(&ipc->rx_free.buf))) {
282 pr_err("put_ipc_rx_buf - "
283 "interrupted wait\n");
284 return -ERESTARTSYS;
285 }
286 goto retry;
287 }
288
289 return rx_bufsiz;
290
291}
292
293static ssize_t baseband_ipc_file_read(struct baseband_ipc *ipc,
294 struct file *file, char *buf, size_t count, loff_t *pos)
295{
296 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
297 size_t read_count;
298
299 pr_debug("baseband_ipc_file_read\n");
300
301 /* check input */
302 if (!ipc) {
303 pr_err("!ipc\n");
304 return -EIO;
305 }
306
307 /* acquire rx buffer semaphores */
308retry:
309 if (down_interruptible(&ipc->buf_sem)) {
310 pr_err("baseband_ipc_file_read - "
311 "cannot acquire buffer semaphore\n");
312 return -ERESTARTSYS;
313 }
314
315 /* get read data from rx linked list */
316 read_count = 0;
317 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list)
318 {
319 pr_debug("baseband_ipc_file_read - "
320 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
321 ipc_buf, ipc_buf->offset, ipc_buf->count);
322 pr_debug("baseband_ipc_file_read - "
323 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
324 ipc_buf->data[0],
325 ipc_buf->data[1],
326 ipc_buf->data[2],
327 ipc_buf->data[3]);
328 if (ipc_buf->count > count - read_count) {
329 /* copy part of rx buffer */
330 if (copy_to_user(buf + read_count,
331 ipc_buf->data + ipc_buf->offset,
332 count - read_count)) {
333 pr_err("copy_to_user failed\n");
334 up(&ipc->buf_sem);
335 return -EFAULT;
336 }
337 ipc_buf->offset += count - read_count;
338 ipc_buf->count -= count - read_count;
339 read_count = count;
340 } else {
341 /* copy all data from rx buffer */
342 if (copy_to_user(buf + read_count,
343 ipc_buf->data + ipc_buf->offset,
344 ipc_buf->count)) {
345 pr_err("copy_to_user failed\n");
346 up(&ipc->buf_sem);
347 return -EFAULT;
348 }
349 read_count += ipc_buf->count;
350 ipc_buf->offset = 0;
351 ipc_buf->count = 0;
352 /* add rx buffer to rx free list */
353 list_move_tail(&ipc_buf->list, &ipc->rx_free.buf);
354 wake_up(&ipc->rx_free.wait);
355 }
356 /* check if done */
357 if (read_count == count)
358 break;
359 }
360
361 /* release rx buffer semaphores */
362 up(&ipc->buf_sem);
363
364 /* wait for rx buffer available */
365 if (!read_count) {
366 if (wait_event_interruptible(ipc->rx.wait,
367 !list_empty(&ipc->rx.buf))) {
368 pr_err("baseband_ipc_file_read - "
369 "interrupted wait\n");
370 return -ERESTARTSYS;
371 }
372 goto retry;
373 }
374
375 return read_count;
376}
377
378static ssize_t baseband_ipc_file_write(struct baseband_ipc *ipc,
379 struct file *file, const char *buf, size_t count, loff_t *pos)
380{
381 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
382 size_t write_count;
383
384 pr_debug("baseband_ipc_file_write\n");
385
386 /* check input */
387 if (!ipc) {
388 pr_err("!ipc\n");
389 return -EIO;
390 }
391
392 /* acquire tx buffer semaphores */
393retry:
394 if (down_interruptible(&ipc->buf_sem)) {
395 pr_err("baseband_ipc_file_write - "
396 "cannot acquire buffer semaphore\n");
397 return -ERESTARTSYS;
398 }
399
400 /* put write data in tx linked list */
401 write_count = 0;
402 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list)
403 {
404 pr_debug("baseband_ipc_file_write - "
405 "ipc_buf %p ipc_buf->offset %x ipc_buf->count %x\n",
406 ipc_buf, ipc_buf->offset, ipc_buf->count);
407 if (sizeof(ipc_buf->data) > count - write_count) {
408 /* partially fill tx free buffer */
409 if (copy_from_user(ipc_buf->data,
410 buf + write_count,
411 count - write_count)) {
412 pr_err("copy_from_user failed\n");
413 up(&ipc->buf_sem);
414 return -EFAULT;
415 }
416 ipc_buf->offset = 0;
417 ipc_buf->count = count - write_count;
418 write_count = count;
419 } else {
420 /* fill entire tx free buffer */
421 if (copy_from_user(ipc_buf->data,
422 buf + write_count,
423 sizeof(ipc_buf->data))) {
424 pr_err("copy_from_user failed\n");
425 up(&ipc->buf_sem);
426 return -EFAULT;
427 }
428 ipc_buf->offset = 0;
429 ipc_buf->count = sizeof(ipc_buf->data);
430 write_count += sizeof(ipc_buf->data);
431 }
432 /* add filled tx free buffer to tx linked list */
433 pr_debug("baseband_ipc_file_write - "
434 "ipc_buf->data [0] %x [1] %x [2] %x [3] %x\n",
435 ipc_buf->data[0],
436 ipc_buf->data[1],
437 ipc_buf->data[2],
438 ipc_buf->data[3]);
439 list_move_tail(&ipc_buf->list, &ipc->tx.buf);
440 wake_up(&ipc->tx.wait);
441 /* check if done */
442 if (write_count == count)
443 break;
444 }
445
446 /* release tx buffer semaphores */
447 up(&ipc->buf_sem);
448
449 /* wait for tx buffer available */
450 if (!write_count) {
451 if (wait_event_interruptible(ipc->tx_free.wait,
452 !list_empty(&ipc->tx_free.buf))) {
453 pr_err("baseband_ipc_file_write - "
454 "interrupted wait\n");
455 return -ERESTARTSYS;
456 }
457 goto retry;
458 }
459
460 /* queue ipc transaction work */
461 queue_work(ipc->workqueue, &ipc->work);
462
463 return write_count;
464}
465
466static void baseband_ipc_close(struct baseband_ipc *ipc)
467{
468 struct baseband_ipc_buf *ipc_buf, *ipc_buf_next;
469
470 pr_debug("baseband_ipc_close {\n");
471
472 /* check input */
473 if (!ipc)
474 return;
475
476 /* destroy work queue */
477 if (ipc->workqueue) {
478 pr_debug("destroy workqueue {\n");
479 cancel_work_sync(&ipc->work);
480 destroy_workqueue(ipc->workqueue);
481 ipc->workqueue = (struct workqueue_struct *) 0;
482 pr_debug("destroy workqueue }\n");
483 }
484 memset(&ipc->work, 0, sizeof(ipc->work));
485
486 /* destroy wait queues */
487 memset(&ipc->tx_free.wait, 0, sizeof(ipc->tx_free.wait));
488 memset(&ipc->rx_free.wait, 0, sizeof(ipc->rx_free.wait));
489 memset(&ipc->tx.wait, 0, sizeof(ipc->tx.wait));
490 memset(&ipc->rx.wait, 0, sizeof(ipc->rx.wait));
491
492 /* destroy data buffers */
493 kfree(ipc->ipc_tx);
494 ipc->ipc_tx = (unsigned char *) 0;
495 kfree(ipc->ipc_rx);
496 ipc->ipc_rx = (unsigned char *) 0;
497 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx_free.buf, list)
498 {
499 kfree(ipc_buf);
500 }
501 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx_free.buf, list)
502 {
503 kfree(ipc_buf);
504 }
505 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->tx.buf, list)
506 {
507 kfree(ipc_buf);
508 }
509 list_for_each_entry_safe(ipc_buf, ipc_buf_next, &ipc->rx.buf, list)
510 {
511 kfree(ipc_buf);
512 }
513
514 /* destroy semaphores */
515 memset(&ipc->buf_sem, 0, sizeof(ipc->buf_sem));
516
517 /* free baseband ipc structure */
518 kfree(ipc);
519
520 pr_debug("baseband_ipc_close }\n");
521}
522
523static struct baseband_ipc *baseband_ipc_open(work_func_t work_func,
524 work_func_t rx_work_func,
525 work_func_t tx_work_func)
526{
527 struct baseband_ipc *ipc;
528 struct baseband_ipc_buf *ipc_buf;
529 int i;
530
531 pr_debug("baseband_ipc_open {\n");
532
533 /* allocate baseband ipc structure */
534 ipc = kzalloc(sizeof(struct baseband_ipc), GFP_KERNEL);
535 if (!ipc)
536 return (struct baseband_ipc *) 0;
537
538 /* create semaphores */
539 sema_init(&ipc->buf_sem, 1);
540
541 /* create data buffers */
542 INIT_LIST_HEAD(&ipc->rx.buf);
543 INIT_LIST_HEAD(&ipc->tx.buf);
544 INIT_LIST_HEAD(&ipc->rx_free.buf);
545 INIT_LIST_HEAD(&ipc->tx_free.buf);
546 for (i = 0; i < BASEBAND_IPC_NUM_RX_BUF; i++) {
547 ipc_buf = (struct baseband_ipc_buf *)
548 kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
549 if (!ipc_buf) {
550 pr_err("cannot allocate baseband ipc rx buffer #%d\n",
551 i);
552 goto error_exit;
553 }
554 pr_debug("baseband_ipc_open - "
555 "rx_free: ipc_buf %p\n",
556 ipc_buf);
557 list_add_tail(&ipc_buf->list, &ipc->rx_free.buf);
558 }
559 for (i = 0; i < BASEBAND_IPC_NUM_TX_BUF; i++) {
560 ipc_buf = (struct baseband_ipc_buf *)
561 kzalloc(sizeof(struct baseband_ipc_buf), GFP_KERNEL);
562 if (!ipc_buf) {
563 pr_err("cannot allocate baseband ipc tx buffer #%d\n",
564 i);
565 goto error_exit;
566 }
567 pr_debug("baseband_ipc_open - "
568 "tx_free: ipc_buf %p\n",
569 ipc_buf);
570 list_add_tail(&ipc_buf->list, &ipc->tx_free.buf);
571 }
572 ipc->ipc_rx = (unsigned char *) 0;
573 ipc->ipc_tx = (unsigned char *) 0;
574
575 /* create wait queues */
576 init_waitqueue_head(&ipc->rx.wait);
577 init_waitqueue_head(&ipc->tx.wait);
578 init_waitqueue_head(&ipc->rx_free.wait);
579 init_waitqueue_head(&ipc->tx_free.wait);
580
581 /* create work queue */
582 ipc->workqueue = create_singlethread_workqueue
583 ("baseband_usb_chr_ipc_workqueue");
584 if (!ipc->workqueue) {
585 pr_err("cannot create workqueue\n");
586 goto error_exit;
587 }
588 if (work_func)
589 INIT_WORK(&ipc->work, work_func);
590 if (rx_work_func)
591 INIT_WORK(&ipc->rx_work, rx_work_func);
592 if (tx_work_func)
593 INIT_WORK(&ipc->tx_work, tx_work_func);
594
595 pr_debug("baseband_ipc_open }\n");
596 return ipc;
597
598error_exit:
599 baseband_ipc_close(ipc);
600 return (struct baseband_ipc *) 0;
601}
602
603/* usb rx */
604
605static void baseband_usb_chr_rx_urb_comp(struct urb *urb)
606{
607 struct baseband_usb *usb = (struct baseband_usb *) urb->context;
608
609 pr_debug("baseband_usb_chr_rx_urb_comp { urb %p\n", urb);
610
611 /* queue rx urb completion work */
612 queue_work(usb->ipc->workqueue, &usb->ipc->rx_work);
613
614 pr_debug("baseband_usb_chr_rx_urb_comp }\n");
615}
616
617static int baseband_usb_chr_rx_urb_submit(struct baseband_usb *usb)
618{
619 struct urb *urb;
620 void *buf;
621 int err;
622
623 pr_debug("baseband_usb_chr_rx_urb_submit { usb %p\n", usb);
624
625 if (!usb_device_connection) {
626 pr_err("!!no usb device conenction!!!!!\n");
627 return -1;
628 }
629
630 /* check input */
631 if (usb->usb.rx_urb) {
632 pr_err("previous urb still active\n");
633 return -1;
634 }
635
636 /* allocate rx urb */
637 urb = usb_alloc_urb(0, GFP_ATOMIC);
638 if (!urb) {
639 pr_err("usb_alloc_urb() failed\n");
640 return -ENOMEM;
641 }
642 buf = kzalloc(USB_CHR_RX_BUFSIZ, GFP_ATOMIC);
643 if (!buf) {
644 pr_err("usb buffer kzalloc() failed\n");
645 usb_free_urb(urb);
646 return -ENOMEM;
647 }
648 usb_fill_bulk_urb(urb, usb->usb.device, usb->usb.pipe.bulk.in,
649 buf, USB_CHR_RX_BUFSIZ,
650 baseband_usb_chr_rx_urb_comp,
651 usb);
652 urb->transfer_flags = 0;
653
654 /* submit rx urb */
655 usb->usb.rx_urb = urb;
656 err = usb_submit_urb(urb, GFP_ATOMIC);
657 if (err < 0) {
658 pr_err("usb_submit_urb() failed - err %d\n", err);
659 usb->usb.rx_urb = (struct urb *) 0;
660 kfree(urb->transfer_buffer);
661 usb_free_urb(urb);
662 return err;
663 }
664
665 pr_debug("baseband_usb_chr_rx_urb_submit }\n");
666 return err;
667}
668
669static void baseband_usb_chr_rx_urb_comp_work(struct work_struct *work)
670{
671 struct baseband_usb *usb = baseband_usb_chr;
672 struct urb *urb = usb->usb.rx_urb;
673 size_t len;
674
675 pr_debug("baseband_usb_chr_rx_urb_comp_work { work %p\n", work);
676
677 /* put rx urb data in rx buffer */
678 if (urb->actual_length) {
679 pr_debug("baseband_usb_chr_rx_urb_comp_work - "
680 "urb->actual_length %d\n", urb->actual_length);
681 len = put_ipc_rx_buf(usb->ipc,
682 urb->transfer_buffer, urb->actual_length);
683 baseband_ipc_dump("baseband_usb_chr_rx_urb_comp_work"
684 " - rx buf ", 0,
685 urb->transfer_buffer, len > 16 ? 16 : len);
686 if (len != urb->actual_length) {
687 pr_err("baseband_usb_chr_rx_urb_comp_work - "
688 "put_ipx_rx_buf() only put %d/%d bytes\n",
689 len, urb->actual_length);
690 }
691 /* increment count of available rx bytes */
692 atomic_add(len, &g_rx_count);
693 }
694
695 /* free rx urb */
696 kfree(urb->transfer_buffer);
697 urb->transfer_buffer = (void *) 0;
698 usb_free_urb(urb);
699 usb->usb.rx_urb = (struct urb *) 0;
700
701 /* submit next rx urb */
702 baseband_usb_chr_rx_urb_submit(usb);
703
704 pr_debug("baseband_usb_chr_rx_urb_comp_work }\n");
705}
706
707/* usb functions */
708
709static void find_usb_pipe(struct baseband_usb *usb)
710{
711 struct usb_device *usbdev = usb->usb.device;
712 struct usb_interface *intf = usb->usb.interface;
713 unsigned char numendpoint = intf->cur_altsetting->desc.bNumEndpoints;
714 struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint;
715 unsigned char n;
716
717 for (n = 0; n < numendpoint; n++) {
718 if (usb_endpoint_is_isoc_in(&endpoint[n].desc)) {
719 pr_debug("endpoint[%d] isochronous in\n", n);
720 usb->usb.pipe.isoch.in = usb_rcvisocpipe(usbdev,
721 endpoint[n].desc.bEndpointAddress);
722 } else if (usb_endpoint_is_isoc_out(&endpoint[n].desc)) {
723 pr_debug("endpoint[%d] isochronous out\n", n);
724 usb->usb.pipe.isoch.out = usb_sndisocpipe(usbdev,
725 endpoint[n].desc.bEndpointAddress);
726 } else if (usb_endpoint_is_bulk_in(&endpoint[n].desc)) {
727 pr_debug("endpoint[%d] bulk in\n", n);
728 usb->usb.pipe.bulk.in = usb_rcvbulkpipe(usbdev,
729 endpoint[n].desc.bEndpointAddress);
730 } else if (usb_endpoint_is_bulk_out(&endpoint[n].desc)) {
731 pr_debug("endpoint[%d] bulk out\n", n);
732 usb->usb.pipe.bulk.out = usb_sndbulkpipe(usbdev,
733 endpoint[n].desc.bEndpointAddress);
734 } else if (usb_endpoint_is_int_in(&endpoint[n].desc)) {
735 pr_debug("endpoint[%d] interrupt in\n", n);
736 usb->usb.pipe.interrupt.in = usb_rcvintpipe(usbdev,
737 endpoint[n].desc.bEndpointAddress);
738 } else if (usb_endpoint_is_int_out(&endpoint[n].desc)) {
739 pr_debug("endpoint[%d] interrupt out\n", n);
740 usb->usb.pipe.interrupt.out = usb_sndintpipe(usbdev,
741 endpoint[n].desc.bEndpointAddress);
742 } else {
743 pr_debug("endpoint[%d] skipped\n", n);
744 }
745 }
746}
747
748static int baseband_usb_driver_probe(struct usb_interface *intf,
749 const struct usb_device_id *id)
750{
751 int err;
752
753 pr_debug("%s(%d) { intf %p id %p\n", __func__, __LINE__, intf, id);
754
755 pr_debug("intf->cur_altsetting->desc.bInterfaceNumber %02x\n",
756 intf->cur_altsetting->desc.bInterfaceNumber);
757 pr_debug("intf->cur_altsetting->desc.bAlternateSetting %02x\n",
758 intf->cur_altsetting->desc.bAlternateSetting);
759 pr_debug("intf->cur_altsetting->desc.bNumEndpoints %02x\n",
760 intf->cur_altsetting->desc.bNumEndpoints);
761 pr_debug("intf->cur_altsetting->desc.bInterfaceClass %02x\n",
762 intf->cur_altsetting->desc.bInterfaceClass);
763 pr_debug("intf->cur_altsetting->desc.bInterfaceSubClass %02x\n",
764 intf->cur_altsetting->desc.bInterfaceSubClass);
765 pr_debug("intf->cur_altsetting->desc.bInterfaceProtocol %02x\n",
766 intf->cur_altsetting->desc.bInterfaceProtocol);
767 pr_debug("intf->cur_altsetting->desc.iInterface %02x\n",
768 intf->cur_altsetting->desc.iInterface);
769
770 /* usb interface mismatch */
771 if (baseband_usb_chr_intf !=
772 intf->cur_altsetting->desc.bInterfaceNumber) {
773 pr_debug("%s(%d) } -ENODEV\n", __func__, __LINE__);
774 return -ENODEV;
775 }
776
777 /* usb interface match */
778 baseband_usb_chr->usb.device = interface_to_usbdev(intf);
779 baseband_usb_chr->usb.interface = intf;
780 find_usb_pipe(baseband_usb_chr);
781 baseband_usb_chr->usb.rx_urb = (struct urb *) 0;
782 baseband_usb_chr->usb.tx_urb = (struct urb *) 0;
783 pr_debug("baseband_usb_chr->usb.driver->name %s\n",
784 baseband_usb_chr->usb.driver->name);
785 pr_debug("baseband_usb_chr->usb.device %p\n",
786 baseband_usb_chr->usb.device);
787 pr_debug("baseband_usb_chr->usb.interface %p\n",
788 baseband_usb_chr->usb.interface);
789 pr_debug("baseband_usb_chr->usb.pipe.isoch.in %x\n",
790 baseband_usb_chr->usb.pipe.isoch.in);
791 pr_debug("baseband_usb_chr->usb.pipe.isoch.out %x\n",
792 baseband_usb_chr->usb.pipe.isoch.out);
793 pr_debug("baseband_usb_chr->usb.pipe.bulk.in %x\n",
794 baseband_usb_chr->usb.pipe.bulk.in);
795 pr_debug("baseband_usb_chr->usb.pipe.bulk.out %x\n",
796 baseband_usb_chr->usb.pipe.bulk.out);
797 pr_debug("baseband_usb_chr->usb.pipe.interrupt.in %x\n",
798 baseband_usb_chr->usb.pipe.interrupt.in);
799 pr_debug("baseband_usb_chr->usb.pipe.interrupt.out %x\n",
800 baseband_usb_chr->usb.pipe.interrupt.out);
801 usb_device_connection = true;
802
803 /* start usb rx */
804 err = baseband_usb_chr_rx_urb_submit(baseband_usb_chr);
805 if (err < 0) {
806 pr_err("submit rx failed - err %d\n", err);
807 return -ENODEV;
808 }
809
810 pr_debug("%s(%d) }\n", __func__, __LINE__);
811 return 0;
812}
813
814static void baseband_usb_driver_disconnect(struct usb_interface *intf)
815{
816 struct usb_device *usb_dev = interface_to_usbdev(intf);
817 pr_debug("%s(%d) { intf %p\n", __func__, __LINE__, intf);
818 pr_debug("%s(%d) }\n", __func__, __LINE__);
819 if (baseband_usb_chr->usb.interface != intf) {
820 pr_info("%s(%d) -ENODEV\n", __func__, __LINE__);
821 return;
822 }
823 if (baseband_usb_chr->usb.device == usb_dev) {
824 pr_info("%s: Matching usb device: Flush workqueue\n", __func__);
825 flush_workqueue(baseband_usb_chr->ipc->workqueue);
826 usb_device_connection = false;
827 }
828
829}
830
831static char baseband_usb_driver_name[32];
832
833static struct usb_device_id baseband_usb_driver_id_table[2];
834
835static struct usb_driver baseband_usb_driver = {
836 .name = baseband_usb_driver_name,
837 .probe = baseband_usb_driver_probe,
838 .disconnect = baseband_usb_driver_disconnect,
839 .id_table = baseband_usb_driver_id_table,
840};
841
842static void baseband_usb_chr_work(struct work_struct *work)
843{
844 struct baseband_usb *usb = baseband_usb_chr;
845 struct {
846 unsigned char *buf;
847 unsigned int bufsiz_byte;
848 } rx, tx;
849 int ipc_tx_byte;
850 int err;
851
852 pr_debug("baseband_usb_chr_work {\n");
853
854 /* check input */
855 if (!usb || !usb->ipc) {
856 pr_err("baseband_usb_chr_work - "
857 "usb not open\n");
858 return;
859 }
860 if (!usb->usb.device) {
861 pr_err("baseband_usb_chr_work - "
862 "usb device not probed yet\n");
863 mdelay(10);
864 queue_work(usb->ipc->workqueue, &usb->ipc->work);
865 return;
866 }
867
868 /* allocate buffers on first transaction (will be freed on close) */
869 if (!usb->ipc->ipc_rx) {
870 usb->ipc->ipc_rx = kzalloc(USB_CHR_RX_BUFSIZ, GFP_KERNEL);
871 if (!usb->ipc->ipc_rx) {
872 pr_err("baseband_usb_chr_work - "
873 "cannot allocate usb->ipc->ipc_rx\n");
874 return;
875 }
876 }
877 if (!usb->ipc->ipc_tx) {
878 usb->ipc->ipc_tx = kzalloc(USB_CHR_TX_BUFSIZ, GFP_KERNEL);
879 if (!usb->ipc->ipc_tx) {
880 pr_err("baseband_usb_chr_work - "
881 "cannot allocate usb->ipc->ipc_tx\n");
882 return;
883 }
884 }
885
886 /* usb transaction loop */
887 rx.buf = usb->ipc->ipc_rx;
888 tx.buf = usb->ipc->ipc_tx;
889 while ((tx.bufsiz_byte = peek_ipc_tx_bufsiz(usb->ipc,
890 USB_CHR_TX_BUFSIZ)) != 0) {
891 get_ipc_tx_buf(usb->ipc, tx.buf, tx.bufsiz_byte);
892 err = usb_bulk_msg(usb->usb.device, usb->usb.pipe.bulk.out,
893 tx.buf, tx.bufsiz_byte, &ipc_tx_byte, USB_CHR_TIMEOUT);
894 if (err < 0) {
895 pr_err("baseband_usb_chr_work - "
896 "usb_bulk_msg err %d\n", err);
897 continue;
898 }
899 if (tx.bufsiz_byte != ipc_tx_byte) {
900 pr_err("tx.bufsiz_byte %d != ipc_tx_byte %d\n",
901 tx.bufsiz_byte, ipc_tx_byte);
902 continue;
903 }
904 }
905
906 pr_debug("baseband_usb_chr_work }\n");
907}
908
909/* usb character file operations */
910
911static int baseband_usb_chr_open(struct inode *inode, struct file *file)
912{
913 pr_debug("baseband_usb_chr_open\n");
914 return 0;
915}
916
917static int baseband_usb_chr_release(struct inode *inode, struct file *file)
918{
919 pr_debug("baseband_usb_chr_release\n");
920 return 0;
921}
922
923static ssize_t baseband_usb_chr_read(struct file *file, char *buf,
924 size_t count, loff_t *pos)
925{
926 ssize_t ret;
927
928 pr_debug("baseband_usb_chr_read\n");
929
930 ret = baseband_ipc_file_read(baseband_usb_chr->ipc,
931 file, buf, count, pos);
932 if (ret > 0) {
933 /* decrement count of available rx bytes */
934 int val = atomic_read(&g_rx_count);
935 pr_debug("baseband_usb_chr_read - read %d unread %d\n",
936 ret, val - ret);
937 atomic_sub(ret, &g_rx_count);
938 }
939 return ret;
940}
941
942static ssize_t baseband_usb_chr_write(struct file *file, const char *buf,
943 size_t count, loff_t *pos)
944{
945 pr_debug("baseband_usb_chr_write\n");
946 return baseband_ipc_file_write(baseband_usb_chr->ipc,
947 file, buf, count, pos);
948}
949
950static long baseband_usb_chr_ioctl(struct file *file, unsigned int cmd,
951 unsigned long arg)
952{
953 pr_debug("baseband_usb_chr_ioctl\n");
954 switch (cmd) {
955 case TCFLSH:
956 pr_debug("TCFLSH\n");
957 /* flush queued ipc transaction work */
958 flush_workqueue(baseband_usb_chr->ipc->workqueue);
959 return 0;
960 case FIONREAD:
961 pr_debug("FIONREAD\n");
962 /* return count of available rx bytes */
963 {
964 int __user *p = (int __user *) arg;
965 int val = atomic_read(&g_rx_count);
966 if (put_user(val, p))
967 break;
968 }
969 return 0;
970 default:
971 pr_err("unsupported ioctl cmd %x\n", cmd);
972 }
973 return -ENODEV;
974}
975
976static const struct file_operations baseband_usb_chr_fops = {
977 .open = baseband_usb_chr_open,
978 .release = baseband_usb_chr_release,
979 .read = baseband_usb_chr_read,
980 .write = baseband_usb_chr_write,
981 .unlocked_ioctl = baseband_usb_chr_ioctl,
982};
983
984/* usb device driver functions */
985
986static void baseband_usb_close(struct baseband_usb *usb)
987{
988 pr_debug("baseband_usb_close {\n");
989
990 /* check input */
991 if (!usb)
992 return;
993
994 /* close usb driver */
995 if (usb->usb.driver) {
996 pr_debug("close usb driver {\n");
997 usb_deregister(usb->usb.driver);
998 usb->usb.driver = (struct usb_driver *) 0;
999 pr_debug("close usb driver }\n");
1000 }
1001
1002 /* close baseband ipc */
1003 if (usb->ipc) {
1004 baseband_ipc_close(usb->ipc);
1005 usb->ipc = (struct baseband_ipc *) 0;
1006 }
1007
1008 /* free baseband usb structure */
1009 kfree(usb);
1010
1011 pr_debug("baseband_usb_close }\n");
1012}
1013
1014static struct baseband_usb *baseband_usb_open(unsigned int vid,
1015 unsigned int pid,
1016 unsigned int intf,
1017 work_func_t work_func,
1018 work_func_t rx_work_func,
1019 work_func_t tx_work_func)
1020{
1021 struct baseband_usb *usb;
1022 int err;
1023
1024 pr_debug("baseband_usb_open {\n");
1025
1026 /* allocate baseband usb structure */
1027 usb = kzalloc(sizeof(struct baseband_usb), GFP_KERNEL);
1028 if (!usb)
1029 return (struct baseband_usb *) 0;
1030 baseband_usb_chr = usb;
1031
1032 /* open baseband ipc */
1033 usb->ipc = baseband_ipc_open(work_func,
1034 rx_work_func,
1035 tx_work_func);
1036 if (!usb->ipc) {
1037 pr_err("open baseband ipc failed\n");
1038 goto error_exit;
1039 }
1040
1041 /* open usb driver */
1042 sprintf(baseband_usb_driver_name,
1043 "baseband_usb_%x_%x_%x",
1044 vid, pid, intf);
1045 baseband_usb_driver_id_table[0].match_flags
1046 = USB_DEVICE_ID_MATCH_DEVICE;
1047 baseband_usb_driver_id_table[0].idVendor = vid;
1048 baseband_usb_driver_id_table[0].idProduct = pid;
1049 usb->usb.driver = &baseband_usb_driver;
1050 err = usb_register(&baseband_usb_driver);
1051 if (err < 0) {
1052 pr_err("cannot open usb driver - err %d\n", err);
1053 goto error_exit;
1054 }
1055
1056 pr_debug("baseband_usb_open }\n");
1057 return usb;
1058
1059error_exit:
1060 baseband_usb_close(usb);
1061 baseband_usb_chr = (struct baseband_usb *) 0;
1062 return (struct baseband_usb *) 0;
1063}
1064
1065/* module init / exit functions */
1066
1067static int baseband_usb_chr_init(void)
1068{
1069 int err;
1070
1071 pr_debug("baseband_usb_chr_init {\n");
1072
1073 /* open baseband usb */
1074 baseband_usb_chr = baseband_usb_open
1075 (baseband_usb_chr_vid,
1076 baseband_usb_chr_pid,
1077 baseband_usb_chr_intf,
1078 baseband_usb_chr_work,
1079 baseband_usb_chr_rx_urb_comp_work,
1080 (work_func_t) 0);
1081 if (!baseband_usb_chr) {
1082 pr_err("cannot open baseband usb chr\n");
1083 err = -1;
1084 goto err1;
1085 }
1086
1087 /* register character device */
1088 err = register_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
1089 BASEBAND_USB_CHR_DEV_NAME,
1090 &baseband_usb_chr_fops);
1091 if (err < 0) {
1092 pr_err("cannot register character device - %d\n", err);
1093 goto err2;
1094 }
1095 pr_debug("registered baseband usb character device - major %d\n",
1096 BASEBAND_USB_CHR_DEV_MAJOR);
1097
1098 pr_debug("baseband_usb_chr_init }\n");
1099 return 0;
1100err2: baseband_usb_close(baseband_usb_chr);
1101 baseband_usb_chr = (struct baseband_usb *) 0;
1102err1: return err;
1103}
1104
1105static void baseband_usb_chr_exit(void)
1106{
1107 pr_debug("baseband_usb_chr_exit {\n");
1108
1109 /* unregister character device */
1110 unregister_chrdev(BASEBAND_USB_CHR_DEV_MAJOR,
1111 BASEBAND_USB_CHR_DEV_NAME);
1112
1113 /* close baseband usb */
1114 if (baseband_usb_chr) {
1115 baseband_usb_close(baseband_usb_chr);
1116 baseband_usb_chr = (struct baseband_usb *) 0;
1117 }
1118
1119 pr_debug("baseband_usb_chr_exit }\n");
1120}
1121
1122module_init(baseband_usb_chr_init)
1123module_exit(baseband_usb_chr_exit)
1124
diff --git a/drivers/usb/serial/baseband_usb_chr.h b/drivers/usb/serial/baseband_usb_chr.h
new file mode 100644
index 00000000000..7935e795a54
--- /dev/null
+++ b/drivers/usb/serial/baseband_usb_chr.h
@@ -0,0 +1,106 @@
1/*
2 * baseband_usb_chr.h
3 *
4 * USB character driver to communicate with baseband modems.
5 *
6 * Copyright (c) 2011, NVIDIA Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef __BASEBAND_USB_CHR_H__
24#define __BASEBAND_USB_CHR_H__
25
26#define BASEBAND_USB_CHR_DEV_NAME "baseband_usb_chr"
27#define BASEBAND_USB_CHR_DEV_MAJOR 66
28
29#ifndef USB_CHR_RX_BUFSIZ
30#define USB_CHR_RX_BUFSIZ (128*1024)
31#endif /* USB_CHR_RX_BUFSIZ */
32
33#ifndef USB_CHR_TX_BUFSIZ
34#define USB_CHR_TX_BUFSIZ (128*1024)
35#endif /* USB_CHR_TX_BUFSIZ */
36
37#ifndef USB_CHR_TIMEOUT
38#define USB_CHR_TIMEOUT 5000 /* ms */
39#endif /* USB_CHR_TIMEOUT */
40
41#ifndef BASEBAND_IPC_NUM_RX_BUF
42#define BASEBAND_IPC_NUM_RX_BUF 32
43#endif /* BASEBAND_IPC_NUM_RX_BUF */
44
45#ifndef BASEBAND_IPC_NUM_TX_BUF
46#define BASEBAND_IPC_NUM_TX_BUF 16
47#endif /* BASEBAND_IPC_NUM_TX_BUF */
48
49#ifndef BASEBAND_IPC_BUFSIZ
50#define BASEBAND_IPC_BUFSIZ 65536
51#endif /* BASEBAND_IPC_BUFSIZ */
52
53struct baseband_ipc {
54 /* rx / tx data */
55 struct semaphore buf_sem;
56 struct {
57 /* linked list of data buffers */
58 struct list_head buf;
59 /* wait queue of processes trying to access data buffers */
60 wait_queue_head_t wait;
61 } rx, tx, rx_free, tx_free;
62 unsigned char *ipc_rx;
63 unsigned char *ipc_tx;
64 /* work queue
65 * - queued per ipc transaction
66 * - initiated by either:
67 * = interrupt on gpio line (rx data available)
68 * = tx data packet being added to tx linked list
69 */
70 struct workqueue_struct *workqueue;
71 struct work_struct work;
72 struct work_struct rx_work;
73 struct work_struct tx_work;
74};
75
76struct baseband_ipc_buf {
77 struct list_head list;
78 /* data buffer */
79 unsigned char data[BASEBAND_IPC_BUFSIZ];
80 /* offset of first data byte */
81 size_t offset;
82 /* number of valid data bytes */
83 size_t count;
84};
85
86struct baseband_usb {
87 struct baseband_ipc *ipc;
88 struct {
89 struct usb_driver *driver;
90 struct usb_device *device;
91 struct usb_interface *interface;
92 struct {
93 struct {
94 unsigned int in;
95 unsigned int out;
96 } isoch, bulk, interrupt;
97 } pipe;
98 /* currently active rx urb */
99 struct urb *rx_urb;
100 /* currently active tx urb */
101 struct urb *tx_urb;
102 } usb;
103};
104
105#endif /* __BASEBAND_USB_CHR_H__ */
106
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index fd67cc53545..a5152379cb4 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -39,6 +39,8 @@ static void cp210x_get_termios(struct tty_struct *,
39 struct usb_serial_port *port); 39 struct usb_serial_port *port);
40static void cp210x_get_termios_port(struct usb_serial_port *port, 40static void cp210x_get_termios_port(struct usb_serial_port *port,
41 unsigned int *cflagp, unsigned int *baudp); 41 unsigned int *cflagp, unsigned int *baudp);
42static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
43 struct ktermios *);
42static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, 44static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
43 struct ktermios*); 45 struct ktermios*);
44static int cp210x_tiocmget(struct tty_struct *); 46static int cp210x_tiocmget(struct tty_struct *);
@@ -92,6 +94,7 @@ static const struct usb_device_id id_table[] = {
92 { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ 94 { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
93 { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ 95 { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
94 { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ 96 { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
97 { USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
95 { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ 98 { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
96 { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ 99 { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
97 { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ 100 { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
@@ -137,6 +140,7 @@ static const struct usb_device_id id_table[] = {
137 { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ 140 { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
138 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ 141 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
139 { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ 142 { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
143 { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
140 { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ 144 { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
141 { } /* Terminating Entry */ 145 { } /* Terminating Entry */
142}; 146};
@@ -200,6 +204,8 @@ static struct usb_serial_driver cp210x_device = {
200#define CP210X_EMBED_EVENTS 0x15 204#define CP210X_EMBED_EVENTS 0x15
201#define CP210X_GET_EVENTSTATE 0x16 205#define CP210X_GET_EVENTSTATE 0x16
202#define CP210X_SET_CHARS 0x19 206#define CP210X_SET_CHARS 0x19
207#define CP210X_GET_BAUDRATE 0x1D
208#define CP210X_SET_BAUDRATE 0x1E
203 209
204/* CP210X_IFC_ENABLE */ 210/* CP210X_IFC_ENABLE */
205#define UART_ENABLE 0x0001 211#define UART_ENABLE 0x0001
@@ -353,8 +359,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
353 * Quantises the baud rate as per AN205 Table 1 359 * Quantises the baud rate as per AN205 Table 1
354 */ 360 */
355static unsigned int cp210x_quantise_baudrate(unsigned int baud) { 361static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
356 if (baud <= 56) baud = 0; 362 if (baud <= 300)
357 else if (baud <= 300) baud = 300; 363 baud = 300;
358 else if (baud <= 600) baud = 600; 364 else if (baud <= 600) baud = 600;
359 else if (baud <= 1200) baud = 1200; 365 else if (baud <= 1200) baud = 1200;
360 else if (baud <= 1800) baud = 1800; 366 else if (baud <= 1800) baud = 1800;
@@ -382,17 +388,15 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
382 else if (baud <= 491520) baud = 460800; 388 else if (baud <= 491520) baud = 460800;
383 else if (baud <= 567138) baud = 500000; 389 else if (baud <= 567138) baud = 500000;
384 else if (baud <= 670254) baud = 576000; 390 else if (baud <= 670254) baud = 576000;
385 else if (baud <= 1053257) baud = 921600; 391 else if (baud < 1000000)
386 else if (baud <= 1474560) baud = 1228800; 392 baud = 921600;
387 else if (baud <= 2457600) baud = 1843200; 393 else if (baud > 2000000)
388 else baud = 3686400; 394 baud = 2000000;
389 return baud; 395 return baud;
390} 396}
391 397
392static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) 398static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
393{ 399{
394 int result;
395
396 dbg("%s - port %d", __func__, port->number); 400 dbg("%s - port %d", __func__, port->number);
397 401
398 if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) { 402 if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) {
@@ -401,13 +405,14 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
401 return -EPROTO; 405 return -EPROTO;
402 } 406 }
403 407
404 result = usb_serial_generic_open(tty, port);
405 if (result)
406 return result;
407
408 /* Configure the termios structure */ 408 /* Configure the termios structure */
409 cp210x_get_termios(tty, port); 409 cp210x_get_termios(tty, port);
410 return 0; 410
411 /* The baud rate must be initialised on cp2104 */
412 if (tty)
413 cp210x_change_speed(tty, port, NULL);
414
415 return usb_serial_generic_open(tty, port);
411} 416}
412 417
413static void cp210x_close(struct usb_serial_port *port) 418static void cp210x_close(struct usb_serial_port *port)
@@ -459,10 +464,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
459 464
460 dbg("%s - port %d", __func__, port->number); 465 dbg("%s - port %d", __func__, port->number);
461 466
462 cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); 467 cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4);
463 /* Convert to baudrate */
464 if (baud)
465 baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
466 468
467 dbg("%s - baud rate = %d", __func__, baud); 469 dbg("%s - baud rate = %d", __func__, baud);
468 *baudp = baud; 470 *baudp = baud;
@@ -576,11 +578,64 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
576 *cflagp = cflag; 578 *cflagp = cflag;
577} 579}
578 580
581/*
582 * CP2101 supports the following baud rates:
583 *
584 * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800,
585 * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600
586 *
587 * CP2102 and CP2103 support the following additional rates:
588 *
589 * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000,
590 * 576000
591 *
592 * The device will map a requested rate to a supported one, but the result
593 * of requests for rates greater than 1053257 is undefined (see AN205).
594 *
595 * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud,
596 * respectively, with an error less than 1%. The actual rates are determined
597 * by
598 *
599 * div = round(freq / (2 x prescale x request))
600 * actual = freq / (2 x prescale x div)
601 *
602 * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps
603 * or 1 otherwise.
604 * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1
605 * otherwise.
606 */
607static void cp210x_change_speed(struct tty_struct *tty,
608 struct usb_serial_port *port, struct ktermios *old_termios)
609{
610 u32 baud;
611
612 baud = tty->termios->c_ospeed;
613
614 /* This maps the requested rate to a rate valid on cp2102 or cp2103,
615 * or to an arbitrary rate in [1M,2M].
616 *
617 * NOTE: B0 is not implemented.
618 */
619 baud = cp210x_quantise_baudrate(baud);
620
621 dbg("%s - setting baud rate to %u", __func__, baud);
622 if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud,
623 sizeof(baud))) {
624 dev_warn(&port->dev, "failed to set baud rate to %u\n", baud);
625 if (old_termios)
626 baud = old_termios->c_ospeed;
627 else
628 baud = 9600;
629 }
630
631 tty_encode_baud_rate(tty, baud, baud);
632}
633
579static void cp210x_set_termios(struct tty_struct *tty, 634static void cp210x_set_termios(struct tty_struct *tty,
580 struct usb_serial_port *port, struct ktermios *old_termios) 635 struct usb_serial_port *port, struct ktermios *old_termios)
581{ 636{
582 unsigned int cflag, old_cflag; 637 unsigned int cflag, old_cflag;
583 unsigned int baud = 0, bits; 638 unsigned int bits;
584 unsigned int modem_ctl[4]; 639 unsigned int modem_ctl[4];
585 640
586 dbg("%s - port %d", __func__, port->number); 641 dbg("%s - port %d", __func__, port->number);
@@ -591,20 +646,9 @@ static void cp210x_set_termios(struct tty_struct *tty,
591 tty->termios->c_cflag &= ~CMSPAR; 646 tty->termios->c_cflag &= ~CMSPAR;
592 cflag = tty->termios->c_cflag; 647 cflag = tty->termios->c_cflag;
593 old_cflag = old_termios->c_cflag; 648 old_cflag = old_termios->c_cflag;
594 baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); 649
595 650 if (tty->termios->c_ospeed != old_termios->c_ospeed)
596 /* If the baud rate is to be updated*/ 651 cp210x_change_speed(tty, port, old_termios);
597 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
598 dbg("%s - Setting baud rate to %d baud", __func__,
599 baud);
600 if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
601 ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
602 dbg("Baud rate requested not supported by device");
603 baud = tty_termios_baud_rate(old_termios);
604 }
605 }
606 /* Report back the resulting baud rate */
607 tty_encode_baud_rate(tty, baud, baud);
608 652
609 /* If the number of data bits is to be updated */ 653 /* If the number of data bits is to be updated */
610 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 654 if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 2e06b90aa1f..1a1710a91e0 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -101,6 +101,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial);
101static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); 101static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
102static int ftdi_NDI_device_setup(struct usb_serial *serial); 102static int ftdi_NDI_device_setup(struct usb_serial *serial);
103static int ftdi_stmclite_probe(struct usb_serial *serial); 103static int ftdi_stmclite_probe(struct usb_serial *serial);
104static int ftdi_8u2232c_probe(struct usb_serial *serial);
104static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); 105static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
105static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); 106static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
106 107
@@ -128,6 +129,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
128 .probe = ftdi_stmclite_probe, 129 .probe = ftdi_stmclite_probe,
129}; 130};
130 131
132static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
133 .probe = ftdi_8u2232c_probe,
134};
135
131/* 136/*
132 * The 8U232AM has the same API as the sio except for: 137 * The 8U232AM has the same API as the sio except for:
133 * - it can support MUCH higher baudrates; up to: 138 * - it can support MUCH higher baudrates; up to:
@@ -151,6 +156,7 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
151 * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! 156 * /sys/bus/usb/ftdi_sio/new_id, then send patch/report!
152 */ 157 */
153static struct usb_device_id id_table_combined [] = { 158static struct usb_device_id id_table_combined [] = {
159 { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) },
154 { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, 160 { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) },
155 { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, 161 { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) },
156 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, 162 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
@@ -177,7 +183,8 @@ static struct usb_device_id id_table_combined [] = {
177 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, 183 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
178 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, 184 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
179 { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, 185 { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
180 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, 186 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) ,
187 .driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
181 { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, 188 { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
182 { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, 189 { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
183 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, 190 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
@@ -200,6 +207,8 @@ static struct usb_device_id id_table_combined [] = {
200 { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) }, 207 { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) },
201 { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) }, 208 { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) },
202 { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, 209 { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
210 { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) },
211 { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) },
203 { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, 212 { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
204 { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, 213 { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
205 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, 214 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
@@ -726,6 +735,7 @@ static struct usb_device_id id_table_combined [] = {
726 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, 735 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
727 { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, 736 { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
728 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, 737 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
738 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
729 { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), 739 { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
730 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 740 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
731 { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), 741 { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
@@ -738,6 +748,8 @@ static struct usb_device_id id_table_combined [] = {
738 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 748 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
739 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), 749 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
740 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 750 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
751 { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID),
752 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
741 { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), 753 { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
742 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 754 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
743 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, 755 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
@@ -784,6 +796,7 @@ static struct usb_device_id id_table_combined [] = {
784 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 796 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
785 { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), 797 { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
786 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 798 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
799 { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
787 { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, 800 { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
788 { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), 801 { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
789 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 802 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
@@ -792,6 +805,8 @@ static struct usb_device_id id_table_combined [] = {
792 { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, 805 { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
793 { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), 806 { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
794 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 807 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
808 { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
809 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
795 { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, 810 { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
796 { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, 811 { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
797 { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, 812 { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
@@ -828,6 +843,7 @@ static struct usb_device_id id_table_combined [] = {
828 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 843 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
829 { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), 844 { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
830 .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, 845 .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
846 { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
831 { }, /* Optional parameter entry */ 847 { }, /* Optional parameter entry */
832 { } /* Terminating entry */ 848 { } /* Terminating entry */
833}; 849};
@@ -1171,7 +1187,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
1171 case FT2232H: /* FT2232H chip */ 1187 case FT2232H: /* FT2232H chip */
1172 case FT4232H: /* FT4232H chip */ 1188 case FT4232H: /* FT4232H chip */
1173 case FT232H: /* FT232H chip */ 1189 case FT232H: /* FT232H chip */
1174 if ((baud <= 12000000) & (baud >= 1200)) { 1190 if ((baud <= 12000000) && (baud >= 1200)) {
1175 div_value = ftdi_2232h_baud_to_divisor(baud); 1191 div_value = ftdi_2232h_baud_to_divisor(baud);
1176 } else if (baud < 1200) { 1192 } else if (baud < 1200) {
1177 div_value = ftdi_232bm_baud_to_divisor(baud); 1193 div_value = ftdi_232bm_baud_to_divisor(baud);
@@ -1205,7 +1221,10 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
1205 urb_index_value = get_ftdi_divisor(tty, port); 1221 urb_index_value = get_ftdi_divisor(tty, port);
1206 urb_value = (__u16)urb_index_value; 1222 urb_value = (__u16)urb_index_value;
1207 urb_index = (__u16)(urb_index_value >> 16); 1223 urb_index = (__u16)(urb_index_value >> 16);
1208 if (priv->interface) { /* FT2232C */ 1224 if ((priv->chip_type == FT2232C) || (priv->chip_type == FT2232H) ||
1225 (priv->chip_type == FT4232H) || (priv->chip_type == FT232H)) {
1226 /* Probably the BM type needs the MSB of the encoded fractional
1227 * divider also moved like for the chips above. Any infos? */
1209 urb_index = (__u16)((urb_index << 8) | priv->interface); 1228 urb_index = (__u16)((urb_index << 8) | priv->interface);
1210 } 1229 }
1211 1230
@@ -1314,8 +1333,7 @@ static int set_serial_info(struct tty_struct *tty,
1314 goto check_and_exit; 1333 goto check_and_exit;
1315 } 1334 }
1316 1335
1317 if ((new_serial.baud_base != priv->baud_base) && 1336 if (new_serial.baud_base != priv->baud_base) {
1318 (new_serial.baud_base < 9600)) {
1319 mutex_unlock(&priv->cfg_lock); 1337 mutex_unlock(&priv->cfg_lock);
1320 return -EINVAL; 1338 return -EINVAL;
1321 } 1339 }
@@ -1733,6 +1751,18 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
1733 return 0; 1751 return 0;
1734} 1752}
1735 1753
1754static int ftdi_8u2232c_probe(struct usb_serial *serial)
1755{
1756 struct usb_device *udev = serial->dev;
1757
1758 dbg("%s", __func__);
1759
1760 if (strcmp(udev->manufacturer, "CALAO Systems") == 0)
1761 return ftdi_jtag_probe(serial);
1762
1763 return 0;
1764}
1765
1736/* 1766/*
1737 * First and second port on STMCLiteadaptors is reserved for JTAG interface 1767 * First and second port on STMCLiteadaptors is reserved for JTAG interface
1738 * and the forth port for pio 1768 * and the forth port for pio
@@ -1792,6 +1822,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
1792 1822
1793static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) 1823static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1794{ 1824{
1825 struct ktermios dummy;
1795 struct usb_device *dev = port->serial->dev; 1826 struct usb_device *dev = port->serial->dev;
1796 struct ftdi_private *priv = usb_get_serial_port_data(port); 1827 struct ftdi_private *priv = usb_get_serial_port_data(port);
1797 int result; 1828 int result;
@@ -1810,8 +1841,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1810 This is same behaviour as serial.c/rs_open() - Kuba */ 1841 This is same behaviour as serial.c/rs_open() - Kuba */
1811 1842
1812 /* ftdi_set_termios will send usb control messages */ 1843 /* ftdi_set_termios will send usb control messages */
1813 if (tty) 1844 if (tty) {
1814 ftdi_set_termios(tty, port, tty->termios); 1845 memset(&dummy, 0, sizeof(dummy));
1846 ftdi_set_termios(tty, port, &dummy);
1847 }
1815 1848
1816 /* Start reading from the device */ 1849 /* Start reading from the device */
1817 result = usb_serial_generic_open(tty, port); 1850 result = usb_serial_generic_open(tty, port);
@@ -2057,13 +2090,19 @@ static void ftdi_set_termios(struct tty_struct *tty,
2057 2090
2058 cflag = termios->c_cflag; 2091 cflag = termios->c_cflag;
2059 2092
2060 /* FIXME -For this cut I don't care if the line is really changing or 2093 if (old_termios->c_cflag == termios->c_cflag
2061 not - so just do the change regardless - should be able to 2094 && old_termios->c_ispeed == termios->c_ispeed
2062 compare old_termios and tty->termios */ 2095 && old_termios->c_ospeed == termios->c_ospeed)
2096 goto no_c_cflag_changes;
2097
2063 /* NOTE These routines can get interrupted by 2098 /* NOTE These routines can get interrupted by
2064 ftdi_sio_read_bulk_callback - need to examine what this means - 2099 ftdi_sio_read_bulk_callback - need to examine what this means -
2065 don't see any problems yet */ 2100 don't see any problems yet */
2066 2101
2102 if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
2103 (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
2104 goto no_data_parity_stop_changes;
2105
2067 /* Set number of data bits, parity, stop bits */ 2106 /* Set number of data bits, parity, stop bits */
2068 2107
2069 urb_value = 0; 2108 urb_value = 0;
@@ -2104,6 +2143,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
2104 } 2143 }
2105 2144
2106 /* Now do the baudrate */ 2145 /* Now do the baudrate */
2146no_data_parity_stop_changes:
2107 if ((cflag & CBAUD) == B0) { 2147 if ((cflag & CBAUD) == B0) {
2108 /* Disable flow control */ 2148 /* Disable flow control */
2109 if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 2149 if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2131,6 +2171,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
2131 2171
2132 /* Set flow control */ 2172 /* Set flow control */
2133 /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ 2173 /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
2174no_c_cflag_changes:
2134 if (cflag & CRTSCTS) { 2175 if (cflag & CRTSCTS) {
2135 dbg("%s Setting to CRTSCTS flow control", __func__); 2176 dbg("%s Setting to CRTSCTS flow control", __func__);
2136 if (usb_control_msg(dev, 2177 if (usb_control_msg(dev,
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 19156d1049f..76d4f31b38c 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -39,6 +39,13 @@
39/* www.candapter.com Ewert Energy Systems CANdapter device */ 39/* www.candapter.com Ewert Energy Systems CANdapter device */
40#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ 40#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
41 41
42/*
43 * Texas Instruments XDS100v2 JTAG / BeagleBone A3
44 * http://processors.wiki.ti.com/index.php/XDS100
45 * http://beagleboard.org/bone
46 */
47#define TI_XDS100V2_PID 0xa6d0
48
42#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ 49#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
43 50
44/* US Interface Navigator (http://www.usinterface.com/) */ 51/* US Interface Navigator (http://www.usinterface.com/) */
@@ -54,6 +61,7 @@
54/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ 61/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
55#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 62#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8
56#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 63#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
64#define LMI_LM3S_ICDI_BOARD_PID 0xbcda
57 65
58#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */ 66#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */
59 67
@@ -111,6 +119,7 @@
111 119
112/* Propox devices */ 120/* Propox devices */
113#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 121#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
122#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739
114 123
115/* Lenz LI-USB Computer Interface. */ 124/* Lenz LI-USB Computer Interface. */
116#define FTDI_LENZ_LIUSB_PID 0xD780 125#define FTDI_LENZ_LIUSB_PID 0xD780
@@ -420,9 +429,11 @@
420#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ 429#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */
421 430
422/* 431/*
423 * DSS-20 Sync Station for Sony Ericsson P800 432 * Sony Ericsson product ids
424 */ 433 */
425#define FTDI_DSS20_PID 0xFC82 434#define FTDI_DSS20_PID 0xFC82 /* DSS-20 Sync Station for Sony Ericsson P800 */
435#define FTDI_URBAN_0_PID 0xFC8A /* Sony Ericsson Urban, uart #0 */
436#define FTDI_URBAN_1_PID 0xFC8B /* Sony Ericsson Urban, uart #1 */
426 437
427/* www.irtrans.de device */ 438/* www.irtrans.de device */
428#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ 439#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
@@ -521,6 +532,12 @@
521#define ADI_GNICEPLUS_PID 0xF001 532#define ADI_GNICEPLUS_PID 0xF001
522 533
523/* 534/*
535 * Hornby Elite
536 */
537#define HORNBY_VID 0x04D8
538#define HORNBY_ELITE_PID 0x000A
539
540/*
524 * RATOC REX-USB60F 541 * RATOC REX-USB60F
525 */ 542 */
526#define RATOC_VENDOR_ID 0x0584 543#define RATOC_VENDOR_ID 0x0584
@@ -1159,4 +1176,14 @@
1159/* USB-Nano-485*/ 1176/* USB-Nano-485*/
1160#define FTDI_CTI_NANO_PID 0xF60B 1177#define FTDI_CTI_NANO_PID 0xF60B
1161 1178
1179/*
1180 * ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de
1181 */
1182/* TagTracer MIFARE*/
1183#define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0
1162 1184
1185/*
1186 * Rainforest Automation
1187 */
1188/* ZigBee controller */
1189#define FTDI_RF_R106 0x8A28
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index b0a7a9e909a..1a49ca9c8ea 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -34,7 +34,7 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <asm/atomic.h> 37#include <linux/atomic.h>
38#include <linux/usb.h> 38#include <linux/usb.h>
39#include <linux/usb/serial.h> 39#include <linux/usb/serial.h>
40 40
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 0aac00afb5c..8a90d58ee96 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2677,15 +2677,7 @@ cleanup:
2677 2677
2678static void edge_disconnect(struct usb_serial *serial) 2678static void edge_disconnect(struct usb_serial *serial)
2679{ 2679{
2680 int i;
2681 struct edgeport_port *edge_port;
2682
2683 dbg("%s", __func__); 2680 dbg("%s", __func__);
2684
2685 for (i = 0; i < serial->num_ports; ++i) {
2686 edge_port = usb_get_serial_port_data(serial->port[i]);
2687 edge_remove_sysfs_attrs(edge_port->port);
2688 }
2689} 2681}
2690 2682
2691static void edge_release(struct usb_serial *serial) 2683static void edge_release(struct usb_serial *serial)
@@ -2764,6 +2756,7 @@ static struct usb_serial_driver edgeport_1port_device = {
2764 .disconnect = edge_disconnect, 2756 .disconnect = edge_disconnect,
2765 .release = edge_release, 2757 .release = edge_release,
2766 .port_probe = edge_create_sysfs_attrs, 2758 .port_probe = edge_create_sysfs_attrs,
2759 .port_remove = edge_remove_sysfs_attrs,
2767 .ioctl = edge_ioctl, 2760 .ioctl = edge_ioctl,
2768 .set_termios = edge_set_termios, 2761 .set_termios = edge_set_termios,
2769 .tiocmget = edge_tiocmget, 2762 .tiocmget = edge_tiocmget,
@@ -2795,6 +2788,7 @@ static struct usb_serial_driver edgeport_2port_device = {
2795 .disconnect = edge_disconnect, 2788 .disconnect = edge_disconnect,
2796 .release = edge_release, 2789 .release = edge_release,
2797 .port_probe = edge_create_sysfs_attrs, 2790 .port_probe = edge_create_sysfs_attrs,
2791 .port_remove = edge_remove_sysfs_attrs,
2798 .ioctl = edge_ioctl, 2792 .ioctl = edge_ioctl,
2799 .set_termios = edge_set_termios, 2793 .set_termios = edge_set_termios,
2800 .tiocmget = edge_tiocmget, 2794 .tiocmget = edge_tiocmget,
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 60f38d5e64f..0a8c1e64b24 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -315,7 +315,7 @@ static int omninet_write_room(struct tty_struct *tty)
315 int room = 0; /* Default: no room */ 315 int room = 0; /* Default: no room */
316 316
317 /* FIXME: no consistent locking for write_urb_busy */ 317 /* FIXME: no consistent locking for write_urb_busy */
318 if (wport->write_urb_busy) 318 if (!wport->write_urb_busy)
319 room = wport->bulk_out_size - OMNINET_HEADERLEN; 319 room = wport->bulk_out_size - OMNINET_HEADERLEN;
320 320
321 dbg("%s - returns %d", __func__, room); 321 dbg("%s - returns %d", __func__, room);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 60b25d8ea0e..2a9ed6ec8cb 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -148,8 +148,15 @@ static void option_instat_callback(struct urb *urb);
148#define HUAWEI_PRODUCT_K4505 0x1464 148#define HUAWEI_PRODUCT_K4505 0x1464
149#define HUAWEI_PRODUCT_K3765 0x1465 149#define HUAWEI_PRODUCT_K3765 0x1465
150#define HUAWEI_PRODUCT_E14AC 0x14AC 150#define HUAWEI_PRODUCT_E14AC 0x14AC
151#define HUAWEI_PRODUCT_K3806 0x14AE
152#define HUAWEI_PRODUCT_K4605 0x14C6
153#define HUAWEI_PRODUCT_K3770 0x14C9
154#define HUAWEI_PRODUCT_K3771 0x14CA
155#define HUAWEI_PRODUCT_K4510 0x14CB
156#define HUAWEI_PRODUCT_K4511 0x14CC
151#define HUAWEI_PRODUCT_ETS1220 0x1803 157#define HUAWEI_PRODUCT_ETS1220 0x1803
152#define HUAWEI_PRODUCT_E353 0x1506 158#define HUAWEI_PRODUCT_E353 0x1506
159#define HUAWEI_PRODUCT_E173S 0x1C05
153 160
154#define QUANTA_VENDOR_ID 0x0408 161#define QUANTA_VENDOR_ID 0x0408
155#define QUANTA_PRODUCT_Q101 0xEA02 162#define QUANTA_PRODUCT_Q101 0xEA02
@@ -310,6 +317,9 @@ static void option_instat_callback(struct urb *urb);
310#define ZTE_PRODUCT_AC8710 0xfff1 317#define ZTE_PRODUCT_AC8710 0xfff1
311#define ZTE_PRODUCT_AC2726 0xfff5 318#define ZTE_PRODUCT_AC2726 0xfff5
312#define ZTE_PRODUCT_AC8710T 0xffff 319#define ZTE_PRODUCT_AC8710T 0xffff
320#define ZTE_PRODUCT_MC2718 0xffe8
321#define ZTE_PRODUCT_AD3812 0xffeb
322#define ZTE_PRODUCT_MC2716 0xffed
313 323
314#define BENQ_VENDOR_ID 0x04a5 324#define BENQ_VENDOR_ID 0x04a5
315#define BENQ_PRODUCT_H10 0x4068 325#define BENQ_PRODUCT_H10 0x4068
@@ -412,6 +422,68 @@ static void option_instat_callback(struct urb *urb);
412#define SAMSUNG_VENDOR_ID 0x04e8 422#define SAMSUNG_VENDOR_ID 0x04e8
413#define SAMSUNG_PRODUCT_GT_B3730 0x6889 423#define SAMSUNG_PRODUCT_GT_B3730 0x6889
414 424
425/* YUGA products www.yuga-info.com*/
426#define YUGA_VENDOR_ID 0x257A
427#define YUGA_PRODUCT_CEM600 0x1601
428#define YUGA_PRODUCT_CEM610 0x1602
429#define YUGA_PRODUCT_CEM500 0x1603
430#define YUGA_PRODUCT_CEM510 0x1604
431#define YUGA_PRODUCT_CEM800 0x1605
432#define YUGA_PRODUCT_CEM900 0x1606
433
434#define YUGA_PRODUCT_CEU818 0x1607
435#define YUGA_PRODUCT_CEU816 0x1608
436#define YUGA_PRODUCT_CEU828 0x1609
437#define YUGA_PRODUCT_CEU826 0x160A
438#define YUGA_PRODUCT_CEU518 0x160B
439#define YUGA_PRODUCT_CEU516 0x160C
440#define YUGA_PRODUCT_CEU528 0x160D
441#define YUGA_PRODUCT_CEU526 0x160F
442
443#define YUGA_PRODUCT_CWM600 0x2601
444#define YUGA_PRODUCT_CWM610 0x2602
445#define YUGA_PRODUCT_CWM500 0x2603
446#define YUGA_PRODUCT_CWM510 0x2604
447#define YUGA_PRODUCT_CWM800 0x2605
448#define YUGA_PRODUCT_CWM900 0x2606
449
450#define YUGA_PRODUCT_CWU718 0x2607
451#define YUGA_PRODUCT_CWU716 0x2608
452#define YUGA_PRODUCT_CWU728 0x2609
453#define YUGA_PRODUCT_CWU726 0x260A
454#define YUGA_PRODUCT_CWU518 0x260B
455#define YUGA_PRODUCT_CWU516 0x260C
456#define YUGA_PRODUCT_CWU528 0x260D
457#define YUGA_PRODUCT_CWU526 0x260F
458
459#define YUGA_PRODUCT_CLM600 0x2601
460#define YUGA_PRODUCT_CLM610 0x2602
461#define YUGA_PRODUCT_CLM500 0x2603
462#define YUGA_PRODUCT_CLM510 0x2604
463#define YUGA_PRODUCT_CLM800 0x2605
464#define YUGA_PRODUCT_CLM900 0x2606
465
466#define YUGA_PRODUCT_CLU718 0x2607
467#define YUGA_PRODUCT_CLU716 0x2608
468#define YUGA_PRODUCT_CLU728 0x2609
469#define YUGA_PRODUCT_CLU726 0x260A
470#define YUGA_PRODUCT_CLU518 0x260B
471#define YUGA_PRODUCT_CLU516 0x260C
472#define YUGA_PRODUCT_CLU528 0x260D
473#define YUGA_PRODUCT_CLU526 0x260F
474
475/* Viettel products */
476#define VIETTEL_VENDOR_ID 0x2262
477#define VIETTEL_PRODUCT_VT1000 0x0002
478
479/* ZD Incorporated */
480#define ZD_VENDOR_ID 0x0685
481#define ZD_PRODUCT_7000 0x7000
482
483/* LG products */
484#define LG_VENDOR_ID 0x1004
485#define LG_PRODUCT_L02C 0x618f
486
415/* some devices interfaces need special handling due to a number of reasons */ 487/* some devices interfaces need special handling due to a number of reasons */
416enum option_blacklist_reason { 488enum option_blacklist_reason {
417 OPTION_BLACKLIST_NONE = 0, 489 OPTION_BLACKLIST_NONE = 0,
@@ -419,31 +491,66 @@ enum option_blacklist_reason {
419 OPTION_BLACKLIST_RESERVED_IF = 2 491 OPTION_BLACKLIST_RESERVED_IF = 2
420}; 492};
421 493
494#define MAX_BL_NUM 8
422struct option_blacklist_info { 495struct option_blacklist_info {
423 const u32 infolen; /* number of interface numbers on blacklist */ 496 /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */
424 const u8 *ifaceinfo; /* pointer to the array holding the numbers */ 497 const unsigned long sendsetup;
425 enum option_blacklist_reason reason; 498 /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */
499 const unsigned long reserved;
426}; 500};
427 501
428static const u8 four_g_w14_no_sendsetup[] = { 0, 1 };
429static const struct option_blacklist_info four_g_w14_blacklist = { 502static const struct option_blacklist_info four_g_w14_blacklist = {
430 .infolen = ARRAY_SIZE(four_g_w14_no_sendsetup), 503 .sendsetup = BIT(0) | BIT(1),
431 .ifaceinfo = four_g_w14_no_sendsetup,
432 .reason = OPTION_BLACKLIST_SENDSETUP
433}; 504};
434 505
435static const u8 alcatel_x200_no_sendsetup[] = { 0, 1 };
436static const struct option_blacklist_info alcatel_x200_blacklist = { 506static const struct option_blacklist_info alcatel_x200_blacklist = {
437 .infolen = ARRAY_SIZE(alcatel_x200_no_sendsetup), 507 .sendsetup = BIT(0) | BIT(1),
438 .ifaceinfo = alcatel_x200_no_sendsetup, 508};
439 .reason = OPTION_BLACKLIST_SENDSETUP 509
510static const struct option_blacklist_info zte_0037_blacklist = {
511 .sendsetup = BIT(0) | BIT(1),
440}; 512};
441 513
442static const u8 zte_k3765_z_no_sendsetup[] = { 0, 1, 2 };
443static const struct option_blacklist_info zte_k3765_z_blacklist = { 514static const struct option_blacklist_info zte_k3765_z_blacklist = {
444 .infolen = ARRAY_SIZE(zte_k3765_z_no_sendsetup), 515 .sendsetup = BIT(0) | BIT(1) | BIT(2),
445 .ifaceinfo = zte_k3765_z_no_sendsetup, 516 .reserved = BIT(4),
446 .reason = OPTION_BLACKLIST_SENDSETUP 517};
518
519static const struct option_blacklist_info zte_ad3812_z_blacklist = {
520 .sendsetup = BIT(0) | BIT(1) | BIT(2),
521};
522
523static const struct option_blacklist_info zte_mc2718_z_blacklist = {
524 .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
525};
526
527static const struct option_blacklist_info zte_mc2716_z_blacklist = {
528 .sendsetup = BIT(1) | BIT(2) | BIT(3),
529};
530
531static const struct option_blacklist_info huawei_cdc12_blacklist = {
532 .reserved = BIT(1) | BIT(2),
533};
534
535static const struct option_blacklist_info net_intf1_blacklist = {
536 .reserved = BIT(1),
537};
538
539static const struct option_blacklist_info net_intf3_blacklist = {
540 .reserved = BIT(3),
541};
542
543static const struct option_blacklist_info net_intf4_blacklist = {
544 .reserved = BIT(4),
545};
546
547static const struct option_blacklist_info net_intf5_blacklist = {
548 .reserved = BIT(5),
549};
550
551static const struct option_blacklist_info zte_mf626_blacklist = {
552 .sendsetup = BIT(0) | BIT(1),
553 .reserved = BIT(4),
447}; 554};
448 555
449static const struct usb_device_id option_ids[] = { 556static const struct usb_device_id option_ids[] = {
@@ -543,11 +650,33 @@ static const struct usb_device_id option_ids[] = {
543 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, 650 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
544 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, 651 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
545 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, 652 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
546 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, 653 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },
547 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, 654 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
655 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
656 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
657 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
548 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, 658 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
549 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, 659 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
660 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
661 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
662 .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
663 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
664 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
665 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
666 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) },
667 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) },
668 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) },
669 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
670 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
550 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, 671 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
672 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
673 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
674 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) },
675 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) },
676 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) },
677 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */
678 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */
679 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */
551 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, 680 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
552 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, 681 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
553 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, 682 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
@@ -634,12 +763,14 @@ static const struct usb_device_id option_ids[] = {
634 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, 763 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
635 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ 764 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
636 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ 765 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
766 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
637 { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ 767 { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
638 { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, 768 { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
639 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, 769 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
640 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, 770 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
641 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ 771 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
642 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, 772 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
773 .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
643 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, 774 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) },
644 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, 775 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) },
645 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, 776 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) },
@@ -654,51 +785,62 @@ static const struct usb_device_id option_ids[] = {
654 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) }, 785 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) },
655 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, 786 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) },
656 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, 787 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) },
657 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, 788 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff),
789 .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
658 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, 790 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
659 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, 791 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) },
660 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, 792 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
661 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, 793 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
662 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, 794 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff),
795 .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
663 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, 796 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) },
664 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, 797 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) },
665 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, 798 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) },
666 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff) }, 799 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff),
800 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
667 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, 801 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) },
668 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, 802 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) },
669 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, 803 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
670 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, 804 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff),
805 .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
671 /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */ 806 /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */
672 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, 807 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
673 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, 808 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
674 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, 809 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
675 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 810 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff,
676 0xff, 0xff), .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, 811 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist },
677 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, 812 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) },
678 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, 813 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) },
679 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, 814 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) },
680 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, 815 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff),
816 .driver_info = (kernel_ulong_t)&zte_0037_blacklist },
681 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, 817 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) },
682 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, 818 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) },
683 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, 819 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) },
684 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, 820 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff),
821 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
685 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, 822 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) },
686 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, 823 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) },
687 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, 824 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) },
688 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, 825 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff),
826 .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
689 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, 827 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) },
690 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, 828 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
691 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, 829 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff),
830 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
692 /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */ 831 /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */
693 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, 832 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
694 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, 833 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff),
834 .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
695 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, 835 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) },
696 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, 836 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
697 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, 837 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff),
838 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
698 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, 839 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
699 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, 840 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
700 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, 841 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
701 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, 842 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff),
843 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
702 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, 844 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) },
703 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, 845 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) },
704 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, 846 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
@@ -713,11 +855,13 @@ static const struct usb_device_id option_ids[] = {
713 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, 855 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) },
714 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, 856 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
715 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, 857 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) },
716 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, 858 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
859 .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
717 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, 860 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
718 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, 861 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) },
719 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, 862 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) },
720 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, 863 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff),
864 .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
721 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, 865 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) },
722 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, 866 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) },
723 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, 867 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) },
@@ -937,6 +1081,12 @@ static const struct usb_device_id option_ids[] = {
937 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, 1081 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
938 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, 1082 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
939 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, 1083 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
1084 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
1085 .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
1086 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
1087 .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
1088 { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
1089 .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
940 { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, 1090 { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
941 { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, 1091 { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
942 { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ 1092 { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
@@ -993,6 +1143,51 @@ static const struct usb_device_id option_ids[] = {
993 { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ 1143 { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
994 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ 1144 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
995 { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ 1145 { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
1146 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
1147 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) },
1148 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) },
1149 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) },
1150 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) },
1151 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) },
1152 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) },
1153 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) },
1154 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) },
1155 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) },
1156 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) },
1157 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) },
1158 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) },
1159 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) },
1160 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) },
1161 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) },
1162 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) },
1163 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) },
1164 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) },
1165 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) },
1166 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) },
1167 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) },
1168 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) },
1169 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) },
1170 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) },
1171 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) },
1172 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) },
1173 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) },
1174 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) },
1175 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) },
1176 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) },
1177 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) },
1178 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) },
1179 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) },
1180 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) },
1181 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) },
1182 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) },
1183 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) },
1184 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) },
1185 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
1186 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
1187 { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
1188 { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
1189 { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
1190 { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */
996 { } /* Terminating entry */ 1191 { } /* Terminating entry */
997}; 1192};
998MODULE_DEVICE_TABLE(usb, option_ids); 1193MODULE_DEVICE_TABLE(usb, option_ids);
@@ -1106,10 +1301,35 @@ static void __exit option_exit(void)
1106module_init(option_init); 1301module_init(option_init);
1107module_exit(option_exit); 1302module_exit(option_exit);
1108 1303
1304static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
1305 const struct option_blacklist_info *blacklist)
1306{
1307 unsigned long num;
1308 const unsigned long *intf_list;
1309
1310 if (blacklist) {
1311 if (reason == OPTION_BLACKLIST_SENDSETUP)
1312 intf_list = &blacklist->sendsetup;
1313 else if (reason == OPTION_BLACKLIST_RESERVED_IF)
1314 intf_list = &blacklist->reserved;
1315 else {
1316 BUG_ON(reason);
1317 return false;
1318 }
1319
1320 for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) {
1321 if (num == ifnum)
1322 return true;
1323 }
1324 }
1325 return false;
1326}
1327
1109static int option_probe(struct usb_serial *serial, 1328static int option_probe(struct usb_serial *serial,
1110 const struct usb_device_id *id) 1329 const struct usb_device_id *id)
1111{ 1330{
1112 struct usb_wwan_intf_private *data; 1331 struct usb_wwan_intf_private *data;
1332
1113 /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ 1333 /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
1114 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && 1334 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
1115 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && 1335 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
@@ -1122,12 +1342,14 @@ static int option_probe(struct usb_serial *serial,
1122 serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) 1342 serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
1123 return -ENODEV; 1343 return -ENODEV;
1124 1344
1125 /* Don't bind network interfaces on Huawei K3765 & K4505 */ 1345 /* Don't bind reserved interfaces (like network ones) which often have
1126 if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && 1346 * the same class/subclass/protocol as the serial interfaces. Look at
1127 (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || 1347 * the Windows driver .INF files for reserved interface numbers.
1128 serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && 1348 */
1129 serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) 1349 if (is_blacklisted(
1130 return -ENODEV; 1350 serial->interface->cur_altsetting->desc.bInterfaceNumber,
1351 OPTION_BLACKLIST_RESERVED_IF,
1352 (const struct option_blacklist_info *) id->driver_info))
1131 1353
1132 /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ 1354 /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
1133 if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && 1355 if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID &&
@@ -1136,7 +1358,6 @@ static int option_probe(struct usb_serial *serial,
1136 return -ENODEV; 1358 return -ENODEV;
1137 1359
1138 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); 1360 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
1139
1140 if (!data) 1361 if (!data)
1141 return -ENOMEM; 1362 return -ENOMEM;
1142 data->send_setup = option_send_setup; 1363 data->send_setup = option_send_setup;
@@ -1145,23 +1366,6 @@ static int option_probe(struct usb_serial *serial,
1145 return 0; 1366 return 0;
1146} 1367}
1147 1368
1148static enum option_blacklist_reason is_blacklisted(const u8 ifnum,
1149 const struct option_blacklist_info *blacklist)
1150{
1151 const u8 *info;
1152 int i;
1153
1154 if (blacklist) {
1155 info = blacklist->ifaceinfo;
1156
1157 for (i = 0; i < blacklist->infolen; i++) {
1158 if (info[i] == ifnum)
1159 return blacklist->reason;
1160 }
1161 }
1162 return OPTION_BLACKLIST_NONE;
1163}
1164
1165static void option_instat_callback(struct urb *urb) 1369static void option_instat_callback(struct urb *urb)
1166{ 1370{
1167 int err; 1371 int err;
@@ -1233,9 +1437,8 @@ static int option_send_setup(struct usb_serial_port *port)
1233 int val = 0; 1437 int val = 0;
1234 dbg("%s", __func__); 1438 dbg("%s", __func__);
1235 1439
1236 if (is_blacklisted(ifNum, 1440 if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
1237 (struct option_blacklist_info *) intfdata->private) 1441 (struct option_blacklist_info *) intfdata->private)) {
1238 == OPTION_BLACKLIST_SENDSETUP) {
1239 dbg("No send_setup on blacklisted interface #%d\n", ifNum); 1442 dbg("No send_setup on blacklisted interface #%d\n", ifNum);
1240 return -EIO; 1443 return -EIO;
1241 } 1444 }
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 30461fcc220..d44c669cc48 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = {
91 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, 91 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
92 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, 92 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
93 { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, 93 { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
94 { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
94 { } /* Terminating entry */ 95 { } /* Terminating entry */
95}; 96};
96 97
@@ -342,10 +343,28 @@ static void pl2303_set_termios(struct tty_struct *tty,
342 baud = 6000000; 343 baud = 6000000;
343 } 344 }
344 dbg("%s - baud set = %d", __func__, baud); 345 dbg("%s - baud set = %d", __func__, baud);
345 buf[0] = baud & 0xff; 346 if (baud <= 115200) {
346 buf[1] = (baud >> 8) & 0xff; 347 buf[0] = baud & 0xff;
347 buf[2] = (baud >> 16) & 0xff; 348 buf[1] = (baud >> 8) & 0xff;
348 buf[3] = (baud >> 24) & 0xff; 349 buf[2] = (baud >> 16) & 0xff;
350 buf[3] = (baud >> 24) & 0xff;
351 } else {
352 /* apparently the formula for higher speeds is:
353 * baudrate = 12M * 32 / (2^buf[1]) / buf[0]
354 */
355 unsigned tmp = 12*1000*1000*32 / baud;
356 buf[3] = 0x80;
357 buf[2] = 0;
358 buf[1] = (tmp >= 256);
359 while (tmp >= 256) {
360 tmp >>= 2;
361 buf[1] <<= 1;
362 }
363 if (tmp > 256) {
364 tmp %= 256;
365 }
366 buf[0] = tmp;
367 }
349 } 368 }
350 369
351 /* For reference buf[4]=0 is 1 stop bits */ 370 /* For reference buf[4]=0 is 1 stop bits */
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 1b025f75daf..c38b8c00c06 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -144,3 +144,8 @@
144/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ 144/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
145#define ADLINK_VENDOR_ID 0x0b63 145#define ADLINK_VENDOR_ID 0x0b63
146#define ADLINK_ND6530_PRODUCT_ID 0x6530 146#define ADLINK_ND6530_PRODUCT_ID 0x6530
147
148/* SMART USB Serial Adapter */
149#define SMART_VENDOR_ID 0x0b8c
150#define SMART_PRODUCT_ID 0x2303
151
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
index 30b73e68a90..a34819884c1 100644
--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -36,6 +36,7 @@
36#define UTSTARCOM_PRODUCT_UM175_V1 0x3712 36#define UTSTARCOM_PRODUCT_UM175_V1 0x3712
37#define UTSTARCOM_PRODUCT_UM175_V2 0x3714 37#define UTSTARCOM_PRODUCT_UM175_V2 0x3714
38#define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 38#define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715
39#define PANTECH_PRODUCT_UML190_VZW 0x3716
39#define PANTECH_PRODUCT_UML290_VZW 0x3718 40#define PANTECH_PRODUCT_UML290_VZW 0x3718
40 41
41/* CMOTECH devices */ 42/* CMOTECH devices */
@@ -67,7 +68,11 @@ static struct usb_device_id id_table[] = {
67 { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, 68 { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
68 { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, 69 { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
69 { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, 70 { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
70 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, 71 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) },
72 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) },
73 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */
74 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */
75 { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */
71 { }, 76 { },
72}; 77};
73MODULE_DEVICE_TABLE(usb, id_table); 78MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 54a9dab1f33..b9bb24729c9 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -28,6 +28,7 @@ static const struct usb_device_id id_table[] = {
28 {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ 28 {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
29 {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ 29 {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */
30 {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ 30 {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */
31 {USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */
31 {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ 32 {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */
32 {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ 33 {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */
33 {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ 34 {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */
@@ -45,6 +46,7 @@ static const struct usb_device_id id_table[] = {
45 {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ 46 {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
46 {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ 47 {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
47 {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ 48 {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */
49 {USB_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
48 {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ 50 {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */
49 {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ 51 {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
50 {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ 52 {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
@@ -78,10 +80,12 @@ static const struct usb_device_id id_table[] = {
78 {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 80 {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
79 {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 81 {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
80 {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 82 {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
83 {USB_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */
81 {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ 84 {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */
82 {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ 85 {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */
83 {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */ 86 {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */
84 {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ 87 {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */
88 {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
85 { } /* Terminating entry */ 89 { } /* Terminating entry */
86}; 90};
87MODULE_DEVICE_TABLE(usb, id_table); 91MODULE_DEVICE_TABLE(usb, id_table);