USB: option: remove duplicate device id table
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / usb / serial / option.c
CommitLineData
58cfe911 1/*
14f76cc7 2 USB Driver for GSM modems
58cfe911
MU
3
4 Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de>
5
6 This driver is free software; you can redistribute it and/or modify
7 it under the terms of Version 2 of the GNU General Public License as
8 published by the Free Software Foundation.
9
10 Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
11
b3fdab59 12 History: see the git log.
ba460e48
MU
13
14 Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
15
14f76cc7
MU
16 This driver exists because the "normal" serial driver doesn't work too well
17 with GSM modems. Issues:
18 - data loss -- one single Receive URB is not nearly enough
7c1c2f73 19 - nonstandard flow (Option devices) control
14f76cc7
MU
20 - controlling the baud rate doesn't make sense
21
22 This driver is named "option" because the most common device it's
23 used for is a PC-Card (with an internal OHCI-USB interface, behind
24 which the GSM interface sits), made by Option Inc.
25
26 Some of the "one port" devices actually exhibit multiple USB instances
27 on the USB bus. This is not a bug, these ports are used for different
28 device features.
58cfe911 29*/
ba460e48 30
e37de9e0 31#define DRIVER_VERSION "v0.7.1"
58cfe911 32#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
14f76cc7 33#define DRIVER_DESC "USB Driver for GSM modems"
58cfe911 34
58cfe911
MU
35#include <linux/kernel.h>
36#include <linux/jiffies.h>
37#include <linux/errno.h>
38#include <linux/tty.h>
39#include <linux/tty_flip.h>
40#include <linux/module.h>
41#include <linux/usb.h>
a969888c 42#include <linux/usb/serial.h>
58cfe911
MU
43
44/* Function prototypes */
7bb75aee
AM
45static int option_open(struct usb_serial_port *port, struct file *filp);
46static void option_close(struct usb_serial_port *port, struct file *filp);
47static int option_startup(struct usb_serial *serial);
48static void option_shutdown(struct usb_serial *serial);
49static void option_rx_throttle(struct usb_serial_port *port);
50static void option_rx_unthrottle(struct usb_serial_port *port);
51static int option_write_room(struct usb_serial_port *port);
58cfe911 52
7d12e780 53static void option_instat_callback(struct urb *urb);
58cfe911 54
7bb75aee
AM
55static int option_write(struct usb_serial_port *port,
56 const unsigned char *buf, int count);
58cfe911 57
7bb75aee
AM
58static int option_chars_in_buffer(struct usb_serial_port *port);
59static int option_ioctl(struct usb_serial_port *port, struct file *file,
60 unsigned int cmd, unsigned long arg);
61static void option_set_termios(struct usb_serial_port *port,
606d099c 62 struct ktermios *old);
7bb75aee
AM
63static void option_break_ctl(struct usb_serial_port *port, int break_state);
64static int option_tiocmget(struct usb_serial_port *port, struct file *file);
65static int option_tiocmset(struct usb_serial_port *port, struct file *file,
66 unsigned int set, unsigned int clear);
67static int option_send_setup(struct usb_serial_port *port);
58cfe911
MU
68
69/* Vendor and product IDs */
14f76cc7
MU
70#define OPTION_VENDOR_ID 0x0AF0
71#define HUAWEI_VENDOR_ID 0x12D1
14f76cc7 72#define NOVATELWIRELESS_VENDOR_ID 0x1410
31fcbb73 73#define ANYDATA_VENDOR_ID 0x16d5
14f76cc7
MU
74
75#define OPTION_PRODUCT_OLD 0x5000
76#define OPTION_PRODUCT_FUSION 0x6000
77#define OPTION_PRODUCT_FUSION2 0x6300
78#define OPTION_PRODUCT_COBRA 0x6500
e37de9e0 79#define OPTION_PRODUCT_COBRA2 0x6600
53e8f84d 80#define OPTION_PRODUCT_GTMAX36 0x6701
14f76cc7 81#define HUAWEI_PRODUCT_E600 0x1001
ab195890 82#define HUAWEI_PRODUCT_E220 0x1003
14f76cc7 83#define NOVATELWIRELESS_PRODUCT_U740 0x1400
31fcbb73 84#define ANYDATA_PRODUCT_ID 0x6501
58cfe911 85
58cfe911
MU
86static struct usb_device_id option_ids[] = {
87 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
ba460e48
MU
88 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
89 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
14f76cc7 90 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
e37de9e0 91 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
53e8f84d 92 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
b6137383 93 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
ab195890 94 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
14f76cc7 95 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
31fcbb73 96 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
14f76cc7
MU
97 { } /* Terminating entry */
98};
58cfe911
MU
99MODULE_DEVICE_TABLE(usb, option_ids);
100
101static struct usb_driver option_driver = {
58cfe911
MU
102 .name = "option",
103 .probe = usb_serial_probe,
104 .disconnect = usb_serial_disconnect,
105 .id_table = option_ids,
ba9dc657 106 .no_dynamic_id = 1,
58cfe911
MU
107};
108
c30fe7f7 109/* The card has three separate interfaces, which the serial driver
58cfe911
MU
110 * recognizes separately, thus num_port=1.
111 */
14f76cc7
MU
112
113static struct usb_serial_driver option_1port_device = {
114 .driver = {
115 .owner = THIS_MODULE,
02b2ac5b 116 .name = "option1",
14f76cc7
MU
117 },
118 .description = "GSM modem (1-port)",
d9b1b787 119 .usb_driver = &option_driver,
b656b2cb 120 .id_table = option_ids,
ba460e48
MU
121 .num_interrupt_in = NUM_DONT_CARE,
122 .num_bulk_in = NUM_DONT_CARE,
123 .num_bulk_out = NUM_DONT_CARE,
14f76cc7 124 .num_ports = 1,
ba460e48
MU
125 .open = option_open,
126 .close = option_close,
127 .write = option_write,
128 .write_room = option_write_room,
129 .chars_in_buffer = option_chars_in_buffer,
130 .throttle = option_rx_throttle,
131 .unthrottle = option_rx_unthrottle,
132 .ioctl = option_ioctl,
133 .set_termios = option_set_termios,
134 .break_ctl = option_break_ctl,
135 .tiocmget = option_tiocmget,
136 .tiocmset = option_tiocmset,
137 .attach = option_startup,
138 .shutdown = option_shutdown,
139 .read_int_callback = option_instat_callback,
58cfe911
MU
140};
141
ba460e48 142#ifdef CONFIG_USB_DEBUG
58cfe911 143static int debug;
ba460e48
MU
144#else
145#define debug 0
146#endif
147
58cfe911
MU
148/* per port private data */
149
ba460e48
MU
150#define N_IN_URB 4
151#define N_OUT_URB 1
b27c73dc 152#define IN_BUFLEN 4096
ba460e48 153#define OUT_BUFLEN 128
58cfe911
MU
154
155struct option_port_private {
156 /* Input endpoints and buffer for this port */
ba460e48
MU
157 struct urb *in_urbs[N_IN_URB];
158 char in_buffer[N_IN_URB][IN_BUFLEN];
58cfe911 159 /* Output endpoints and buffer for this port */
ba460e48
MU
160 struct urb *out_urbs[N_OUT_URB];
161 char out_buffer[N_OUT_URB][OUT_BUFLEN];
58cfe911
MU
162
163 /* Settings for the port */
ba460e48
MU
164 int rts_state; /* Handshaking pins (outputs) */
165 int dtr_state;
166 int cts_state; /* Handshaking pins (inputs) */
167 int dsr_state;
168 int dcd_state;
169 int ri_state;
170
171 unsigned long tx_start_time[N_OUT_URB];
58cfe911
MU
172};
173
58cfe911 174/* Functions used by new usb-serial code. */
7bb75aee 175static int __init option_init(void)
58cfe911
MU
176{
177 int retval;
14f76cc7
MU
178 retval = usb_serial_register(&option_1port_device);
179 if (retval)
180 goto failed_1port_device_register;
58cfe911
MU
181 retval = usb_register(&option_driver);
182 if (retval)
183 goto failed_driver_register;
184
185 info(DRIVER_DESC ": " DRIVER_VERSION);
186
187 return 0;
188
189failed_driver_register:
14f76cc7
MU
190 usb_serial_deregister (&option_1port_device);
191failed_1port_device_register:
58cfe911
MU
192 return retval;
193}
194
7bb75aee 195static void __exit option_exit(void)
58cfe911
MU
196{
197 usb_deregister (&option_driver);
14f76cc7 198 usb_serial_deregister (&option_1port_device);
58cfe911
MU
199}
200
201module_init(option_init);
202module_exit(option_exit);
203
7bb75aee 204static void option_rx_throttle(struct usb_serial_port *port)
58cfe911
MU
205{
206 dbg("%s", __FUNCTION__);
207}
208
7bb75aee 209static void option_rx_unthrottle(struct usb_serial_port *port)
58cfe911
MU
210{
211 dbg("%s", __FUNCTION__);
212}
213
7bb75aee 214static void option_break_ctl(struct usb_serial_port *port, int break_state)
58cfe911
MU
215{
216 /* Unfortunately, I don't know how to send a break */
ba460e48 217 dbg("%s", __FUNCTION__);
58cfe911
MU
218}
219
7bb75aee 220static void option_set_termios(struct usb_serial_port *port,
606d099c 221 struct ktermios *old_termios)
58cfe911
MU
222{
223 dbg("%s", __FUNCTION__);
224
225 option_send_setup(port);
226}
227
7bb75aee 228static int option_tiocmget(struct usb_serial_port *port, struct file *file)
58cfe911 229{
ba460e48
MU
230 unsigned int value;
231 struct option_port_private *portdata;
58cfe911
MU
232
233 portdata = usb_get_serial_port_data(port);
234
235 value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
236 ((portdata->dtr_state) ? TIOCM_DTR : 0) |
237 ((portdata->cts_state) ? TIOCM_CTS : 0) |
238 ((portdata->dsr_state) ? TIOCM_DSR : 0) |
239 ((portdata->dcd_state) ? TIOCM_CAR : 0) |
240 ((portdata->ri_state) ? TIOCM_RNG : 0);
241
242 return value;
243}
244
7bb75aee
AM
245static int option_tiocmset(struct usb_serial_port *port, struct file *file,
246 unsigned int set, unsigned int clear)
58cfe911 247{
ba460e48 248 struct option_port_private *portdata;
58cfe911
MU
249
250 portdata = usb_get_serial_port_data(port);
251
252 if (set & TIOCM_RTS)
253 portdata->rts_state = 1;
254 if (set & TIOCM_DTR)
255 portdata->dtr_state = 1;
256
257 if (clear & TIOCM_RTS)
258 portdata->rts_state = 0;
259 if (clear & TIOCM_DTR)
260 portdata->dtr_state = 0;
261 return option_send_setup(port);
262}
263
7bb75aee
AM
264static int option_ioctl(struct usb_serial_port *port, struct file *file,
265 unsigned int cmd, unsigned long arg)
58cfe911
MU
266{
267 return -ENOIOCTLCMD;
268}
269
270/* Write */
7bb75aee
AM
271static int option_write(struct usb_serial_port *port,
272 const unsigned char *buf, int count)
58cfe911 273{
ba460e48
MU
274 struct option_port_private *portdata;
275 int i;
276 int left, todo;
277 struct urb *this_urb = NULL; /* spurious */
278 int err;
58cfe911
MU
279
280 portdata = usb_get_serial_port_data(port);
281
282 dbg("%s: write (%d chars)", __FUNCTION__, count);
283
58cfe911
MU
284 i = 0;
285 left = count;
ba460e48 286 for (i=0; left > 0 && i < N_OUT_URB; i++) {
58cfe911
MU
287 todo = left;
288 if (todo > OUT_BUFLEN)
289 todo = OUT_BUFLEN;
290
ba460e48
MU
291 this_urb = portdata->out_urbs[i];
292 if (this_urb->status == -EINPROGRESS) {
7bb75aee
AM
293 if (time_before(jiffies,
294 portdata->tx_start_time[i] + 10 * HZ))
58cfe911 295 continue;
58cfe911 296 usb_unlink_urb(this_urb);
ba460e48 297 continue;
58cfe911 298 }
ba460e48 299 if (this_urb->status != 0)
7bb75aee
AM
300 dbg("usb_write %p failed (err=%d)",
301 this_urb, this_urb->status);
58cfe911 302
7bb75aee
AM
303 dbg("%s: endpoint %d buf %d", __FUNCTION__,
304 usb_pipeendpoint(this_urb->pipe), i);
58cfe911 305
ba460e48 306 /* send the data */
58cfe911 307 memcpy (this_urb->transfer_buffer, buf, todo);
58cfe911
MU
308 this_urb->transfer_buffer_length = todo;
309
58cfe911
MU
310 this_urb->dev = port->serial->dev;
311 err = usb_submit_urb(this_urb, GFP_ATOMIC);
312 if (err) {
7bb75aee
AM
313 dbg("usb_submit_urb %p (write bulk) failed "
314 "(%d, has %d)", this_urb,
315 err, this_urb->status);
58cfe911
MU
316 continue;
317 }
318 portdata->tx_start_time[i] = jiffies;
319 buf += todo;
320 left -= todo;
321 }
322
323 count -= left;
58cfe911
MU
324 dbg("%s: wrote (did %d)", __FUNCTION__, count);
325 return count;
326}
327
7d12e780 328static void option_indat_callback(struct urb *urb)
58cfe911 329{
33f0f88f 330 int err;
58cfe911
MU
331 int endpoint;
332 struct usb_serial_port *port;
333 struct tty_struct *tty;
334 unsigned char *data = urb->transfer_buffer;
335
336 dbg("%s: %p", __FUNCTION__, urb);
337
338 endpoint = usb_pipeendpoint(urb->pipe);
339 port = (struct usb_serial_port *) urb->context;
340
341 if (urb->status) {
342 dbg("%s: nonzero status: %d on endpoint %02x.",
343 __FUNCTION__, urb->status, endpoint);
344 } else {
345 tty = port->tty;
346 if (urb->actual_length) {
33f0f88f
AC
347 tty_buffer_request_room(tty, urb->actual_length);
348 tty_insert_flip_string(tty, data, urb->actual_length);
58cfe911
MU
349 tty_flip_buffer_push(tty);
350 } else {
351 dbg("%s: empty read urb received", __FUNCTION__);
352 }
353
354 /* Resubmit urb so we continue receiving */
355 if (port->open_count && urb->status != -ESHUTDOWN) {
356 err = usb_submit_urb(urb, GFP_ATOMIC);
357 if (err)
7bb75aee
AM
358 printk(KERN_ERR "%s: resubmit read urb failed. "
359 "(%d)", __FUNCTION__, err);
58cfe911
MU
360 }
361 }
362 return;
363}
364
7d12e780 365static void option_outdat_callback(struct urb *urb)
58cfe911
MU
366{
367 struct usb_serial_port *port;
368
369 dbg("%s", __FUNCTION__);
370
371 port = (struct usb_serial_port *) urb->context;
372
cf2c7481 373 usb_serial_port_softint(port);
58cfe911
MU
374}
375
7d12e780 376static void option_instat_callback(struct urb *urb)
58cfe911
MU
377{
378 int err;
379 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
380 struct option_port_private *portdata = usb_get_serial_port_data(port);
381 struct usb_serial *serial = port->serial;
382
383 dbg("%s", __FUNCTION__);
384 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
385
386 if (urb->status == 0) {
387 struct usb_ctrlrequest *req_pkt =
388 (struct usb_ctrlrequest *)urb->transfer_buffer;
389
390 if (!req_pkt) {
391 dbg("%s: NULL req_pkt\n", __FUNCTION__);
392 return;
393 }
7bb75aee
AM
394 if ((req_pkt->bRequestType == 0xA1) &&
395 (req_pkt->bRequest == 0x20)) {
58cfe911
MU
396 int old_dcd_state;
397 unsigned char signals = *((unsigned char *)
7bb75aee
AM
398 urb->transfer_buffer +
399 sizeof(struct usb_ctrlrequest));
58cfe911
MU
400
401 dbg("%s: signal x%x", __FUNCTION__, signals);
402
403 old_dcd_state = portdata->dcd_state;
404 portdata->cts_state = 1;
405 portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
406 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
407 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
408
7bb75aee
AM
409 if (port->tty && !C_CLOCAL(port->tty) &&
410 old_dcd_state && !portdata->dcd_state)
58cfe911 411 tty_hangup(port->tty);
7bb75aee
AM
412 } else {
413 dbg("%s: type %x req %x", __FUNCTION__,
414 req_pkt->bRequestType,req_pkt->bRequest);
415 }
58cfe911
MU
416 } else
417 dbg("%s: error %d", __FUNCTION__, urb->status);
418
419 /* Resubmit urb so we continue receiving IRQ data */
420 if (urb->status != -ESHUTDOWN) {
421 urb->dev = serial->dev;
422 err = usb_submit_urb(urb, GFP_ATOMIC);
423 if (err)
7bb75aee
AM
424 dbg("%s: resubmit intr urb failed. (%d)",
425 __FUNCTION__, err);
58cfe911
MU
426 }
427}
428
7bb75aee 429static int option_write_room(struct usb_serial_port *port)
58cfe911
MU
430{
431 struct option_port_private *portdata;
432 int i;
433 int data_len = 0;
434 struct urb *this_urb;
435
436 portdata = usb_get_serial_port_data(port);
437
ba460e48 438 for (i=0; i < N_OUT_URB; i++) {
58cfe911
MU
439 this_urb = portdata->out_urbs[i];
440 if (this_urb && this_urb->status != -EINPROGRESS)
441 data_len += OUT_BUFLEN;
ba460e48 442 }
58cfe911
MU
443
444 dbg("%s: %d", __FUNCTION__, data_len);
445 return data_len;
446}
447
7bb75aee 448static int option_chars_in_buffer(struct usb_serial_port *port)
58cfe911
MU
449{
450 struct option_port_private *portdata;
451 int i;
452 int data_len = 0;
453 struct urb *this_urb;
454
455 portdata = usb_get_serial_port_data(port);
456
ba460e48 457 for (i=0; i < N_OUT_URB; i++) {
58cfe911
MU
458 this_urb = portdata->out_urbs[i];
459 if (this_urb && this_urb->status == -EINPROGRESS)
460 data_len += this_urb->transfer_buffer_length;
ba460e48 461 }
58cfe911
MU
462 dbg("%s: %d", __FUNCTION__, data_len);
463 return data_len;
464}
465
7bb75aee 466static int option_open(struct usb_serial_port *port, struct file *filp)
58cfe911 467{
ba460e48
MU
468 struct option_port_private *portdata;
469 struct usb_serial *serial = port->serial;
470 int i, err;
471 struct urb *urb;
58cfe911
MU
472
473 portdata = usb_get_serial_port_data(port);
474
475 dbg("%s", __FUNCTION__);
476
477 /* Set some sane defaults */
478 portdata->rts_state = 1;
479 portdata->dtr_state = 1;
480
481 /* Reset low level data toggle and start reading from endpoints */
482 for (i = 0; i < N_IN_URB; i++) {
483 urb = portdata->in_urbs[i];
484 if (! urb)
485 continue;
486 if (urb->dev != serial->dev) {
7bb75aee
AM
487 dbg("%s: dev %p != %p", __FUNCTION__,
488 urb->dev, serial->dev);
58cfe911
MU
489 continue;
490 }
491
7bb75aee
AM
492 /*
493 * make sure endpoint data toggle is synchronized with the
494 * device
495 */
58cfe911
MU
496 usb_clear_halt(urb->dev, urb->pipe);
497
498 err = usb_submit_urb(urb, GFP_KERNEL);
499 if (err) {
7bb75aee
AM
500 dbg("%s: submit urb %d failed (%d) %d",
501 __FUNCTION__, i, err,
58cfe911
MU
502 urb->transfer_buffer_length);
503 }
504 }
505
506 /* Reset low level data toggle on out endpoints */
507 for (i = 0; i < N_OUT_URB; i++) {
508 urb = portdata->out_urbs[i];
509 if (! urb)
510 continue;
511 urb->dev = serial->dev;
7bb75aee
AM
512 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
513 usb_pipeout(urb->pipe), 0); */
58cfe911
MU
514 }
515
516 port->tty->low_latency = 1;
517
518 option_send_setup(port);
519
520 return (0);
521}
522
7bb75aee 523static inline void stop_urb(struct urb *urb)
58cfe911 524{
242cf670 525 if (urb && urb->status == -EINPROGRESS)
58cfe911 526 usb_kill_urb(urb);
58cfe911
MU
527}
528
7bb75aee 529static void option_close(struct usb_serial_port *port, struct file *filp)
58cfe911 530{
ba460e48
MU
531 int i;
532 struct usb_serial *serial = port->serial;
533 struct option_port_private *portdata;
58cfe911
MU
534
535 dbg("%s", __FUNCTION__);
536 portdata = usb_get_serial_port_data(port);
537
538 portdata->rts_state = 0;
539 portdata->dtr_state = 0;
540
541 if (serial->dev) {
542 option_send_setup(port);
543
544 /* Stop reading/writing urbs */
545 for (i = 0; i < N_IN_URB; i++)
546 stop_urb(portdata->in_urbs[i]);
547 for (i = 0; i < N_OUT_URB; i++)
548 stop_urb(portdata->out_urbs[i]);
549 }
550 port->tty = NULL;
551}
552
58cfe911 553/* Helper functions used by option_setup_urbs */
7bb75aee
AM
554static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
555 int dir, void *ctx, char *buf, int len,
7d12e780 556 void (*callback)(struct urb *))
58cfe911
MU
557{
558 struct urb *urb;
559
560 if (endpoint == -1)
561 return NULL; /* endpoint not needed */
562
563 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
564 if (urb == NULL) {
565 dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
566 return NULL;
567 }
568
569 /* Fill URB using supplied data. */
570 usb_fill_bulk_urb(urb, serial->dev,
571 usb_sndbulkpipe(serial->dev, endpoint) | dir,
572 buf, len, callback, ctx);
573
574 return urb;
575}
576
577/* Setup urbs */
7bb75aee 578static void option_setup_urbs(struct usb_serial *serial)
58cfe911 579{
14f76cc7 580 int i,j;
ba460e48
MU
581 struct usb_serial_port *port;
582 struct option_port_private *portdata;
58cfe911
MU
583
584 dbg("%s", __FUNCTION__);
585
14f76cc7
MU
586 for (i = 0; i < serial->num_ports; i++) {
587 port = serial->port[i];
588 portdata = usb_get_serial_port_data(port);
58cfe911
MU
589
590 /* Do indat endpoints first */
14f76cc7
MU
591 for (j = 0; j < N_IN_URB; ++j) {
592 portdata->in_urbs[j] = option_setup_urb (serial,
593 port->bulk_in_endpointAddress, USB_DIR_IN, port,
594 portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
595 }
58cfe911 596
14f76cc7
MU
597 /* outdat endpoints */
598 for (j = 0; j < N_OUT_URB; ++j) {
599 portdata->out_urbs[j] = option_setup_urb (serial,
600 port->bulk_out_endpointAddress, USB_DIR_OUT, port,
601 portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
602 }
58cfe911
MU
603 }
604}
605
7bb75aee 606static int option_send_setup(struct usb_serial_port *port)
58cfe911
MU
607{
608 struct usb_serial *serial = port->serial;
609 struct option_port_private *portdata;
610
611 dbg("%s", __FUNCTION__);
612
8c152713
MAA
613 if (port->number != 0)
614 return 0;
615
58cfe911
MU
616 portdata = usb_get_serial_port_data(port);
617
618 if (port->tty) {
619 int val = 0;
620 if (portdata->dtr_state)
621 val |= 0x01;
622 if (portdata->rts_state)
623 val |= 0x02;
624
7bb75aee
AM
625 return usb_control_msg(serial->dev,
626 usb_rcvctrlpipe(serial->dev, 0),
627 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
58cfe911
MU
628 }
629
630 return 0;
631}
632
7bb75aee 633static int option_startup(struct usb_serial *serial)
58cfe911 634{
ba460e48
MU
635 int i, err;
636 struct usb_serial_port *port;
637 struct option_port_private *portdata;
58cfe911
MU
638
639 dbg("%s", __FUNCTION__);
640
641 /* Now setup per port private data */
642 for (i = 0; i < serial->num_ports; i++) {
643 port = serial->port[i];
80b6ca48 644 portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
58cfe911 645 if (!portdata) {
7bb75aee
AM
646 dbg("%s: kmalloc for option_port_private (%d) failed!.",
647 __FUNCTION__, i);
58cfe911
MU
648 return (1);
649 }
58cfe911
MU
650
651 usb_set_serial_port_data(port, portdata);
652
653 if (! port->interrupt_in_urb)
654 continue;
655 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
656 if (err)
7bb75aee
AM
657 dbg("%s: submit irq_in urb failed %d",
658 __FUNCTION__, err);
58cfe911
MU
659 }
660
661 option_setup_urbs(serial);
662
663 return (0);
664}
665
7bb75aee 666static void option_shutdown(struct usb_serial *serial)
58cfe911 667{
ba460e48
MU
668 int i, j;
669 struct usb_serial_port *port;
670 struct option_port_private *portdata;
58cfe911
MU
671
672 dbg("%s", __FUNCTION__);
673
674 /* Stop reading/writing urbs */
675 for (i = 0; i < serial->num_ports; ++i) {
676 port = serial->port[i];
677 portdata = usb_get_serial_port_data(port);
678 for (j = 0; j < N_IN_URB; j++)
679 stop_urb(portdata->in_urbs[j]);
680 for (j = 0; j < N_OUT_URB; j++)
681 stop_urb(portdata->out_urbs[j]);
682 }
683
684 /* Now free them */
685 for (i = 0; i < serial->num_ports; ++i) {
686 port = serial->port[i];
687 portdata = usb_get_serial_port_data(port);
688
689 for (j = 0; j < N_IN_URB; j++) {
690 if (portdata->in_urbs[j]) {
691 usb_free_urb(portdata->in_urbs[j]);
692 portdata->in_urbs[j] = NULL;
693 }
694 }
695 for (j = 0; j < N_OUT_URB; j++) {
696 if (portdata->out_urbs[j]) {
697 usb_free_urb(portdata->out_urbs[j]);
698 portdata->out_urbs[j] = NULL;
699 }
700 }
701 }
702
703 /* Now free per port private data */
704 for (i = 0; i < serial->num_ports; i++) {
705 port = serial->port[i];
706 kfree(usb_get_serial_port_data(port));
707 }
708}
709
710MODULE_AUTHOR(DRIVER_AUTHOR);
711MODULE_DESCRIPTION(DRIVER_DESC);
712MODULE_VERSION(DRIVER_VERSION);
713MODULE_LICENSE("GPL");
714
ba460e48 715#ifdef CONFIG_USB_DEBUG
58cfe911
MU
716module_param(debug, bool, S_IRUGO | S_IWUSR);
717MODULE_PARM_DESC(debug, "Debug messages");
ba460e48 718#endif
58cfe911 719