source: src/linux/sl2312/linux-2.6.23/drivers/usb/serial/sierra.c @ 12066

Last change on this file since 12066 was 12066, checked in by BrainSlayer, 4 years ago

latest sierra driver

File size: 26.5 KB
Line 
1/*
2  USB Driver for Sierra Wireless
3
4  Copyright (C) 2006, 2007, 2008  Kevin Lloyd <klloyd@sierrawireless.com>
5 
6  Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer
7                           <linux@sierrawireless.com>
8
9  IMPORTANT DISCLAIMER: This driver is not commercially supported by
10  Sierra Wireless. Use at your own risk.
11
12  This driver is free software; you can redistribute it and/or modify
13  it under the terms of Version 2 of the GNU General Public License as
14  published by the Free Software Foundation.
15
16  Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
17  Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
18
19  Back ported to kernel 2.6.23
20*/
21/* Uncomment to log function calls */
22/*#define DEBUG*/
23#define DRIVER_VERSION "v.1.7.0"
24#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
25#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
26
27#include <linux/kernel.h>
28#include <linux/jiffies.h>
29#include <linux/errno.h>
30#include <linux/tty.h>
31#include <linux/tty_flip.h>
32#include <linux/module.h>
33#include <linux/usb.h>
34#include <linux/usb/serial.h>
35
36#define SWIMS_USB_REQUEST_SetPower      0x00
37#define SWIMS_USB_REQUEST_SetNmea       0x07
38#define SWIMS_USB_REQUEST_SetMode       0x0B
39#define SWIMS_SET_MODE_Modem            0x0001
40
41#define N_IN_URB        8
42#define N_OUT_URB       64
43#define IN_BUFLEN       4096
44
45#define MAX_TRANSFER            (PAGE_SIZE - 512)
46/* MAX_TRANSFER is chosen so that the VM is not stressed by
47   allocations > PAGE_SIZE and the number of packets in a page
48   is an integer 512 is the largest possible packet on EHCI */
49
50static int debug;
51static int nmea;
52static int truinstall = 1;
53static int suspend_support;
54
55enum devicetype {
56        DEVICE_MODEM =          0,
57        DEVICE_INSTALLER =      1,
58};
59
60/* list of interface numbers - used for constructing interface blacklists */
61struct list {
62        const u32 listlen; /* number of interface numbers on list */
63        const u8  *list;   /* pointer to the array holding the numbers */
64};
65
66/* static device type specific data */
67struct sierra_device_static_info {
68        const enum devicetype   dev_type;
69        const struct list       iface_blacklist;
70};
71
72static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
73{
74        int result;
75        dev_dbg(&udev->dev, "%s\n", __func__);
76        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
77                        SWIMS_USB_REQUEST_SetPower,     /* __u8 request      */
78                        USB_TYPE_VENDOR,                /* __u8 request type */
79                        swiState,                       /* __u16 value       */
80                        0,                              /* __u16 index       */
81                        NULL,                           /* void *data        */
82                        0,                              /* __u16 size        */
83                        USB_CTRL_SET_TIMEOUT);          /* int timeout       */
84        return result;
85}
86
87static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
88{
89        int result;
90        dev_dbg(&udev->dev, "%s\n", "DEVICE MODE SWITCH");
91        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
92                        SWIMS_USB_REQUEST_SetMode,      /* __u8 request      */
93                        USB_TYPE_VENDOR,                /* __u8 request type */
94                        eSWocMode,                      /* __u16 value       */
95                        0x0000,                         /* __u16 index       */
96                        NULL,                           /* void *data        */
97                        0,                              /* __u16 size        */
98                        USB_CTRL_SET_TIMEOUT);          /* int timeout       */
99        return result;
100}
101
102static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
103{
104        int result;
105        dev_dbg(&udev->dev, "%s\n", __func__);
106        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
107                        SWIMS_USB_REQUEST_SetNmea,      /* __u8 request      */
108                        USB_TYPE_VENDOR,                /* __u8 request type */
109                        enable,                         /* __u16 value       */
110                        0x0000,                         /* __u16 index       */
111                        NULL,                           /* void *data        */
112                        0,                              /* __u16 size        */
113                        USB_CTRL_SET_TIMEOUT);          /* int timeout       */
114        return result;
115}
116
117static int sierra_calc_num_ports(struct usb_serial *serial)
118{
119        int num_ports = 0;
120        u8 ifnum, numendpoints;
121       
122        dev_dbg(&serial->dev->dev, "%s\n", __func__);
123       
124        ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
125        numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
126       
127        /* Dummy interface present on some SKUs should be ignored */
128        if (ifnum == 0x99)
129                num_ports = 0;
130        else if (numendpoints <= 3)
131                num_ports = 1;
132        else
133                num_ports = (numendpoints-1)/2;
134        return num_ports;
135}
136
137static int is_blacklisted(const u8 ifnum, const struct list *blacklist)
138{
139        const u8  *list;
140        int i;
141       
142        if (blacklist) {
143                list = blacklist->list;
144               
145                for (i=0; i < blacklist->listlen; i++) {
146                        if (list[i] == ifnum)
147                                return 1;
148                }
149        }
150        return 0;
151}
152
153static int sierra_calc_interface(struct usb_serial *serial)
154{
155        int interface;
156        struct usb_interface *p_interface;
157        struct usb_host_interface *p_host_interface;
158        dev_dbg(&serial->dev->dev, "%s\n", __func__);
159
160        /* Get the interface structure pointer from the serial struct */
161        p_interface = serial->interface;
162
163        /* Get a pointer to the host interface structure */
164        p_host_interface = p_interface->cur_altsetting;
165
166        /* read the interface descriptor for this active altsetting
167         * to find out the interface number we are on
168        */
169        interface = p_host_interface->desc.bInterfaceNumber;
170
171        return interface;
172}
173
174static int sierra_probe(struct usb_serial *serial,
175                        const struct usb_device_id *id)
176{
177        const struct sierra_device_static_info * info; 
178        int result = 0;
179        struct usb_device *udev;
180        u8 ifnum, ifclass;
181
182        udev = serial->dev;
183        dev_dbg(&udev->dev, "%s\n", __func__);
184
185        /* Check TRU-Install first */
186        info = (const struct sierra_device_static_info *)id->driver_info;
187        ifclass = serial->interface->cur_altsetting->desc.bInterfaceClass;
188        if (ifclass == USB_CLASS_MASS_STORAGE) {
189                /* If TRU-Install support is enabled, force to modem mode */
190                if (truinstall && info && info->dev_type == DEVICE_INSTALLER) {
191                        dev_dbg(&udev->dev, "%s\n", "FOUND TRU-INSTALL DEVICE");
192                        result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
193                }
194                return -ENODEV;
195        }
196       
197        ifnum = sierra_calc_interface(serial);
198        if (info && is_blacklisted(ifnum, &info->iface_blacklist)) {
199                dev_dbg(&serial->dev->dev,
200                        "Ignoring blacklisted interface #%d\n", ifnum);
201                return -ENODEV;
202        }
203       
204        /*
205         * If this interface supports more than 1 alternate
206         * select the 2nd one
207         */
208        if (serial->interface->num_altsetting == 2) {
209                dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
210                        ifnum);
211                /* We know the alternate setting is 1 for the MC8785 */
212                usb_set_interface(udev, ifnum, 1);
213        }
214        /* Be careful here, The ifnum, ifclass etc. might be incorrect, because
215         * of the usb_set_interface call. (all obtained using
216         * serial->interface->cur_altsetting that was changed by that call)
217         */
218       
219        return result;
220}
221
222static const struct sierra_device_static_info tru_inst_info = {
223        .dev_type = DEVICE_INSTALLER,
224};
225
226static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
227static const struct sierra_device_static_info direct_ip_interface_blacklist = {
228        .dev_type = DEVICE_MODEM,
229        .iface_blacklist = {
230                .listlen = ARRAY_SIZE( direct_ip_non_serial_ifaces ),
231                .list = direct_ip_non_serial_ifaces,
232        },
233};
234
235static struct usb_device_id id_table [] = {
236        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
237        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
238        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
239        { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
240        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
241        { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
242        { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
243        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
244        { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
245        { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
246         /* Sierra Wireless C597 */
247        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
248         /* Sierra Wireless Device */
249        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
250        { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
251        { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
252        { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
253
254        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
255        { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
256        { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
257        { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
258        { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
259        { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
260        { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
261        { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
262        { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
263        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
264        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
265        { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
266        { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
267        /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
268        { USB_DEVICE(0x1199, 0x683C) },
269        { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */
270        /* Sierra Wireless MC8790, MC8791, MC8792 */
271        { USB_DEVICE(0x1199, 0x683E) },
272        { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
273        { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
274        { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
275        { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
276        { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
277        { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
278        { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
279        { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
280        /* Sierra Wireless C885 */
281        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
282        /* Sierra Wireless Device */
283        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
284        /* Sierra Wireless Device */
285        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
286        /* Sierra Wireless Device */
287        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
288
289        { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
290        { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
291
292        { USB_DEVICE(0x1199, 0x0FFF),
293                .driver_info = (kernel_ulong_t)&tru_inst_info
294        },
295       
296        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
297                .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
298        },
299       
300        { }
301};
302MODULE_DEVICE_TABLE(usb, id_table);
303
304/* per port private data */
305struct sierra_port_private {
306        spinlock_t lock;        /* lock the structure */
307        int outstanding_urbs;   /* number of out urbs in flight */
308
309        /* Input endpoints and buffers for this port */
310        struct urb *in_urbs[N_IN_URB];
311
312        /* Settings for the port */
313        int rts_state;  /* Handshaking pins (outputs) */
314        int dtr_state;
315        int cts_state;  /* Handshaking pins (inputs) */
316        int dsr_state;
317        int dcd_state;
318        int ri_state;
319};
320
321static int sierra_send_setup(struct usb_serial_port *port)
322{
323        struct usb_serial *serial = port->serial;
324        struct sierra_port_private *portdata;
325        __u16 interface = 0;
326
327        dev_dbg(&port->dev, "%s\n", __func__);
328
329        portdata = usb_get_serial_port_data(port);
330
331        if (port->tty) {
332
333                int val = 0;
334                if (portdata->dtr_state)
335                        val |= 0x01;
336                if (portdata->rts_state)
337                        val |= 0x02;
338                       
339                /* If composite device then properly report interface */
340                if (serial->num_ports == 1) {
341                        interface = sierra_calc_interface(serial);
342                        /* Control message is send only to interfaces with
343                         * interrupt_in endpoints
344                         */
345                        if(port->interrupt_in_urb) {
346                                /* send control message */
347                                return usb_control_msg(serial->dev,
348                                        usb_rcvctrlpipe(serial->dev, 0),
349                                        0x22, 0x21, val, interface,
350                                        NULL, 0, USB_CTRL_SET_TIMEOUT);
351                        }
352                }
353
354                /* Otherwise the need to do non-composite mapping */
355                else {
356                        if (port->bulk_out_endpointAddress == 2)
357                                interface = 0;
358                        else if (port->bulk_out_endpointAddress == 4)
359                                interface = 1;
360                        else if (port->bulk_out_endpointAddress == 5)
361                                interface = 2;
362
363                        return usb_control_msg(serial->dev,
364                                usb_rcvctrlpipe(serial->dev, 0),
365                                0x22, 0x21, val, interface,
366                                NULL, 0, USB_CTRL_SET_TIMEOUT);
367
368                }
369        }
370
371        return 0;
372}
373
374static void sierra_set_termios(struct usb_serial_port *port,
375                        struct ktermios *old_termios)
376{
377        dev_dbg(&port->dev, "%s\n", __func__);
378        sierra_send_setup(port);
379}
380
381static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
382{
383        unsigned int value;
384        struct sierra_port_private *portdata;
385
386        dev_dbg(&port->dev, "%s\n", __func__);
387        portdata = usb_get_serial_port_data(port);
388
389        value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
390                ((portdata->dtr_state) ? TIOCM_DTR : 0) |
391                ((portdata->cts_state) ? TIOCM_CTS : 0) |
392                ((portdata->dsr_state) ? TIOCM_DSR : 0) |
393                ((portdata->dcd_state) ? TIOCM_CAR : 0) |
394                ((portdata->ri_state) ? TIOCM_RNG : 0);
395
396        return value;
397}
398
399static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
400                        unsigned int set, unsigned int clear)
401{
402        struct sierra_port_private *portdata;
403
404        portdata = usb_get_serial_port_data(port);
405
406        if (set & TIOCM_RTS)
407                portdata->rts_state = 1;
408        if (set & TIOCM_DTR)
409                portdata->dtr_state = 1;
410
411        if (clear & TIOCM_RTS)
412                portdata->rts_state = 0;
413        if (clear & TIOCM_DTR)
414                portdata->dtr_state = 0;
415        return sierra_send_setup(port);
416}
417static void sierra_release_urb(struct urb *urb)
418{
419        struct usb_serial_port *port;
420        if (urb) {
421                port =  urb->context;
422                dev_dbg(&port->dev, "%s: %p\n", __func__, urb);
423                if (urb->transfer_buffer)
424                        kfree(urb->transfer_buffer);
425                usb_free_urb(urb);
426        }
427}
428
429static void sierra_outdat_callback(struct urb *urb)
430{
431        struct usb_serial_port *port = urb->context;
432        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
433        int status = urb->status;
434        unsigned long flags;
435
436        dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
437
438        /* free up the transfer buffer, as usb_free_urb() does not do this */
439        kfree(urb->transfer_buffer);
440
441        if (status)
442                dev_dbg(&port->dev, "%s - nonzero write bulk status "
443                    "received: %d\n", __func__, status);
444
445        spin_lock_irqsave(&portdata->lock, flags);
446        --portdata->outstanding_urbs;
447        spin_unlock_irqrestore(&portdata->lock, flags);
448
449        usb_serial_port_softint(port);
450}
451
452/* Write */
453static int sierra_write(struct usb_serial_port *port,
454                        const unsigned char *buf, int count)
455{
456        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
457        struct usb_serial *serial = port->serial;
458        unsigned long flags;
459        unsigned char *buffer;
460        struct urb *urb;
461        size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER);
462        int retval = 0;
463
464        /* verify that we actually have some data to write */
465        if (count == 0)
466                return 0;
467
468        portdata = usb_get_serial_port_data(port);
469
470        dev_dbg(&port->dev, "%s: write (%d bytes)\n", __func__, writesize);
471
472        spin_lock_irqsave(&portdata->lock, flags);
473        if (portdata->outstanding_urbs > N_OUT_URB) {
474                spin_unlock_irqrestore(&portdata->lock, flags);
475                dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
476                return 0;
477        }
478        portdata->outstanding_urbs++;
479        spin_unlock_irqrestore(&portdata->lock, flags);
480
481        buffer = kmalloc(writesize, GFP_ATOMIC);
482        if (!buffer) {
483                dev_err(&port->dev, "out of memory\n");
484                retval = -ENOMEM;
485                goto error_no_buffer;
486        }
487
488        urb = usb_alloc_urb(0, GFP_ATOMIC);
489        if (!urb) {
490                dev_err(&port->dev, "no more free urbs\n");
491                retval = -ENOMEM;
492                goto error_no_urb;
493        }
494
495        memcpy(buffer, buf, writesize);
496
497        usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer);
498
499        usb_fill_bulk_urb(urb, serial->dev,
500                          usb_sndbulkpipe(serial->dev,
501                                          port->bulk_out_endpointAddress),
502                          buffer, writesize, sierra_outdat_callback, port);
503
504        /* Handle the need to send a zero length packet */
505        urb->transfer_flags |= URB_ZERO_PACKET;
506
507        /* send it down the pipe */
508        retval = usb_submit_urb(urb, GFP_ATOMIC);
509        if (retval) {
510                dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
511                        "with status = %d\n", __func__, retval);
512                goto error;
513        }
514
515        /* we are done with this urb, so let the host driver
516         * really free it when it is finished with it */
517        usb_free_urb(urb);
518       
519        return writesize;
520error:
521        usb_free_urb(urb);
522error_no_urb:
523        kfree(buffer);
524error_no_buffer:
525        spin_lock_irqsave(&portdata->lock, flags);
526        --portdata->outstanding_urbs;
527        spin_unlock_irqrestore(&portdata->lock, flags);
528        return retval;
529}
530
531static void sierra_indat_callback(struct urb *urb)
532{
533        int err;
534        int endpoint;
535        struct usb_serial_port *port;
536        struct tty_struct *tty;
537        unsigned char *data = urb->transfer_buffer;
538        int status = urb->status;
539
540        endpoint = usb_pipeendpoint(urb->pipe);
541        port =  urb->context;
542       
543        dev_dbg(&port->dev, "%s: %p\n", __func__, urb);
544
545        if (status) {
546                dev_dbg(&port->dev, "%s: nonzero status: %d on"
547                        " endpoint %02x\n", __func__, status, endpoint);
548        } else {
549                tty = port->tty;
550                if (urb->actual_length) {
551                        tty_buffer_request_room(tty, urb->actual_length);
552                        tty_insert_flip_string(tty, data, urb->actual_length);
553                        tty_flip_buffer_push(tty);
554                        usb_serial_debug_data(debug, &port->dev, __func__,
555                                urb->actual_length, data);
556                } else {
557                        dev_dbg(&port->dev, "%s: empty read urb"
558                                " received\n", __func__);
559                }
560        }
561
562        /* Resubmit urb so we continue receiving */
563        if (port->open_count && status != -ESHUTDOWN && status != -ENOENT) {
564                err = usb_submit_urb(urb, GFP_ATOMIC);
565                if (err)
566                        dev_err(&port->dev, "resubmit read urb failed."
567                                "(%d)\n", err);
568        }
569       
570        return;
571}
572
573static void sierra_instat_callback(struct urb *urb)
574{
575        int err;
576        int status = urb->status;
577        struct usb_serial_port *port =  urb->context;
578        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
579        struct usb_serial *serial = port->serial;
580
581        dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__,
582                urb, port, portdata);
583
584        if (status == 0) {
585                struct usb_ctrlrequest *req_pkt =
586                                (struct usb_ctrlrequest *)urb->transfer_buffer;
587
588                if (!req_pkt) {
589                        dev_dbg(&port->dev, "%s: NULL req_pkt\n",
590                                __func__);
591                        return;
592                }
593                if ((req_pkt->bRequestType == 0xA1) &&
594                                (req_pkt->bRequest == 0x20)) {
595                        int old_dcd_state;
596                        unsigned char signals = *((unsigned char *)
597                                        urb->transfer_buffer +
598                                        sizeof(struct usb_ctrlrequest));
599
600                        dev_dbg(&port->dev, "%s: signal x%x\n", __func__,
601                                signals);
602
603                        old_dcd_state = portdata->dcd_state;
604                        portdata->cts_state = 1;
605                        portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
606                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
607                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
608
609                        if (port->tty && !C_CLOCAL(port->tty) &&
610                                        old_dcd_state && !portdata->dcd_state)
611                                tty_hangup(port->tty);
612                } else {
613                        dev_dbg(&port->dev, "%s: type %x req %x\n",
614                                __func__, req_pkt->bRequestType,
615                                req_pkt->bRequest);
616                }
617        } else
618                dev_dbg(&port->dev, "%s: error %d\n", __func__, status);
619
620        /* Resubmit urb so we continue receiving IRQ data */
621        if (port->open_count && status != -ESHUTDOWN && status != -ENOENT) {
622                urb->dev = serial->dev;
623                err = usb_submit_urb(urb, GFP_ATOMIC);
624                if (err)
625                        dev_err(&port->dev, "%s: resubmit intr urb "
626                                "failed. (%d)\n", __func__, err);
627        }
628}
629
630static int sierra_write_room(struct usb_serial_port *port)
631{
632        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
633        unsigned long flags;
634
635        dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
636
637        /* try to give a good number back based on if we have any free urbs at
638         * this point in time */
639        spin_lock_irqsave(&portdata->lock, flags);
640        if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
641                spin_unlock_irqrestore(&portdata->lock, flags);
642                dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
643                return 0;
644        }
645        spin_unlock_irqrestore(&portdata->lock, flags);
646
647        return 2048;
648}
649
650static void sierra_stop_rx_urbs(struct usb_serial_port *port)
651{
652        int i;
653        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
654       
655        for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
656                usb_kill_urb(portdata->in_urbs[i]);
657        }
658        usb_kill_urb(port->interrupt_in_urb);
659}
660
661static int sierra_submit_rx_urbs(struct usb_serial_port *port)
662{
663        int ok_cnt;
664        int err = -EINVAL;
665        int i;
666        struct urb * urb;
667        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
668
669        ok_cnt = 0;
670        for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
671                urb = portdata->in_urbs[i];
672                if (!urb)
673                        continue;
674                err = usb_submit_urb(urb, GFP_KERNEL);
675                if (err) {
676                        dev_err(&port->dev, "%s: submit urb failed: %d\n",
677                                __func__, err );
678                } else {
679                        ok_cnt ++;
680                }
681        }
682
683        if (ok_cnt && port->interrupt_in_urb) {
684                err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
685                if (err) {
686                        dev_err(&port->dev, "%s: submit intr urb failed: %d\n",
687                                __func__, err );
688                }
689        }
690
691        if (ok_cnt > 0) /* at least one rx urb submitted */
692                return 0;
693        else
694                return err;
695}
696
697static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
698                                        int dir, void *ctx, int len,
699                                        usb_complete_t callback)
700{
701        struct urb      *urb;
702        u8              *buf;
703       
704        if (endpoint == -1)
705                return NULL;
706
707        urb = usb_alloc_urb( 0, GFP_KERNEL );
708        if (urb == NULL) {
709                dev_dbg(&serial->dev->dev, "%s: alloc for endpoint %d failed\n",
710                        __func__, endpoint);
711                return NULL;
712        }
713       
714        buf = kmalloc(len, GFP_KERNEL);
715        if (buf)
716        {
717                /* Fill URB using supplied data */
718                usb_fill_bulk_urb(urb, serial->dev,
719                        usb_sndbulkpipe(serial->dev, endpoint) | dir,
720                        buf, len, callback, ctx);
721
722                /* debug */
723                dev_dbg(&serial->dev->dev,"%s %c u:%p d:%p\n", __func__,
724                                dir == USB_DIR_IN?'i':'o', urb, buf );
725        } else {
726                dev_dbg(&serial->dev->dev,"%s %c u:%p d:%p\n", __func__,
727                                dir == USB_DIR_IN?'i':'o', urb, buf );
728
729                sierra_release_urb(urb);
730                urb = NULL;
731        }
732       
733        return urb;
734}
735
736static void sierra_close(struct usb_serial_port *port, struct file *filp)
737{
738        int i;
739        struct usb_serial *serial = port->serial;
740        struct sierra_port_private *portdata;
741
742        dev_dbg(&port->dev, "%s\n", __func__);
743        portdata = usb_get_serial_port_data(port);
744
745        portdata->rts_state = 0;
746        portdata->dtr_state = 0;
747
748        if (serial->dev) {
749                sierra_send_setup(port);
750
751                /* Stop reading urbs */
752                sierra_stop_rx_urbs(port);
753                /* .. and release them */
754                for (i = 0; i < N_IN_URB; i++) {
755                        sierra_release_urb(portdata->in_urbs[i]);
756                        portdata->in_urbs[i] = NULL;
757                }
758        }
759
760        port->tty = NULL;
761}
762
763static int sierra_open(struct usb_serial_port *port, struct file *filp)
764{
765        struct sierra_port_private *portdata;
766        struct usb_serial *serial = port->serial;
767        int i;
768        int err;
769        int endpoint;
770        struct urb *urb;
771
772        portdata = usb_get_serial_port_data(port);
773
774        dev_dbg(&port->dev, "%s\n", __func__);
775
776        /* Set some sane defaults */
777        portdata->rts_state = 1;
778        portdata->dtr_state = 1;
779       
780        if (port->tty) {
781                port->tty->low_latency = 1;
782        }
783
784        spin_lock_init(&portdata->lock);
785       
786        endpoint = port->bulk_in_endpointAddress;
787       
788        for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
789                urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
790                                        IN_BUFLEN, sierra_indat_callback);
791                portdata->in_urbs[i] = urb;
792        }
793        /* clear halt condition */
794        usb_clear_halt(serial->dev,
795                        usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
796               
797        err = sierra_submit_rx_urbs(port);
798        if (err) {
799                /* get rid of everything as in close */
800                sierra_close(port, filp);
801                return err;
802        }
803        sierra_send_setup(port);
804
805        return 0;
806}
807
808static int sierra_startup(struct usb_serial *serial)
809{
810        struct usb_serial_port *port;
811        struct sierra_port_private *portdata;
812        int i;
813
814        dev_dbg(&serial->dev->dev, "%s\n", __func__);
815
816        /* Set Device mode to D0 */
817        sierra_set_power_state(serial->dev, 0x0000);
818
819        /* Check NMEA and set */
820        if (nmea)
821                sierra_vsc_set_nmea(serial->dev, 1);
822
823        /* Now setup per port private data */
824        for (i = 0; i < serial->num_ports; i++) {
825                port = serial->port[i];
826                portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
827                if (!portdata) {
828                        dev_dbg(&port->dev, "%s: kmalloc for "
829                                "sierra_port_private (%d) failed!\n",
830                                __func__, i);
831                        return -ENOMEM;
832                }
833                /* Set the port private data pointer */
834                usb_set_serial_port_data(port, portdata);
835        }
836
837        return 0;
838}
839
840static void sierra_shutdown(struct usb_serial *serial)
841{
842        int i;
843        struct usb_serial_port *port;
844        struct sierra_port_private *portdata;
845
846        dev_dbg(&serial->dev->dev, "%s\n", __func__);
847
848        for (i = 0; i < serial->num_ports; ++i) {
849                port = serial->port[i];
850                if (!port)
851                        continue;
852                portdata = usb_get_serial_port_data(port);
853                if (!portdata)
854                        continue;
855                kfree(portdata);
856                usb_set_serial_port_data(port, NULL);
857        }
858}
859
860int sierra_suspend(struct usb_serial *serial, pm_message_t message)
861{
862        int i;
863
864        dev_dbg(&serial->dev->dev, "%s\n", __func__);
865
866        /* The dummy interface doesn't prevent suspended state */
867        if (serial->num_ports == 0)
868                return 0;
869
870        if (!suspend_support)
871                return -EOPNOTSUPP;
872
873        for (i=0; i < serial->num_ports ; i++) {
874                sierra_stop_rx_urbs(serial->port[i]);
875        }
876        return 0;
877}
878
879int sierra_resume(struct usb_serial *serial)
880{
881        int i;
882
883        dev_dbg(&serial->dev->dev, "%s\n", __func__);
884
885        for (i=0; i < serial->num_ports ; i++) {
886                sierra_submit_rx_urbs(serial->port[i]);
887        }
888
889        return 0;
890}
891
892static struct usb_driver sierra_driver = {
893        .name       = "sierra",
894        .probe      = usb_serial_probe,
895        .disconnect = usb_serial_disconnect,
896        .suspend    = usb_serial_suspend,
897        .resume     = usb_serial_resume,
898        .id_table   = id_table,
899
900        .no_dynamic_id        = 1,
901        .supports_autosuspend = 1,
902};
903
904static struct usb_serial_driver sierra_device = {
905        .driver = {
906                .owner =        THIS_MODULE,
907                .name =         "sierra",
908        },
909        .description       = "Sierra USB modem",
910        .id_table          = id_table,
911        .usb_driver        = &sierra_driver,
912        .num_interrupt_in  = NUM_DONT_CARE,
913        .num_bulk_in       = NUM_DONT_CARE,
914        .num_bulk_out      = NUM_DONT_CARE,
915        .calc_num_ports    = sierra_calc_num_ports,
916        .probe             = sierra_probe,
917        .open              = sierra_open,
918        .close             = sierra_close,
919        .write             = sierra_write,
920        .write_room        = sierra_write_room,
921        .set_termios       = sierra_set_termios,
922        .tiocmget          = sierra_tiocmget,
923        .tiocmset          = sierra_tiocmset,
924        .attach            = sierra_startup,
925        .shutdown          = sierra_shutdown,
926        .read_int_callback = sierra_instat_callback,
927        .suspend           = sierra_suspend,
928        .resume            = sierra_resume,
929};
930
931/* Functions used by new usb-serial code. */
932static int __init sierra_init(void)
933{
934        int retval;
935        retval = usb_serial_register(&sierra_device);
936        if (retval)
937                goto failed_device_register;
938
939
940        retval = usb_register(&sierra_driver);
941        if (retval)
942                goto failed_driver_register;
943
944        info(DRIVER_DESC ": " DRIVER_VERSION);
945
946        return 0;
947
948failed_driver_register:
949        usb_serial_deregister(&sierra_device);
950failed_device_register:
951        return retval;
952}
953
954static void __exit sierra_exit(void)
955{
956        usb_deregister(&sierra_driver);
957        usb_serial_deregister(&sierra_device);
958}
959
960module_init(sierra_init);
961module_exit(sierra_exit);
962
963MODULE_AUTHOR(DRIVER_AUTHOR);
964MODULE_DESCRIPTION(DRIVER_DESC);
965MODULE_VERSION(DRIVER_VERSION);
966MODULE_LICENSE("GPL");
967
968module_param(truinstall, bool, S_IRUGO | S_IWUSR);
969MODULE_PARM_DESC(truinstall, "TRU-Install support");
970
971module_param(nmea, bool, S_IRUGO | S_IWUSR);
972MODULE_PARM_DESC(nmea, "NMEA streaming");
973
974module_param(debug, bool, S_IRUGO | S_IWUSR);
975MODULE_PARM_DESC(debug, "Debug messages");
976
977module_param(suspend_support, bool, S_IRUGO | S_IWUSR);
978MODULE_PARM_DESC(suspend_support, "Selective Suspend support");
Note: See TracBrowser for help on using the repository browser.