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