diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 21:26:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 21:26:12 -0700 |
commit | 7a9b149212f3716c598afe973b6261fd58453b7a (patch) | |
tree | 477716d84c71da124448b72278e98da28aadbd3d /drivers/usb/serial/qcserial.c | |
parent | 3d62e3fdce8ef265a3706c52ae1ca6ab84e30f0e (diff) | |
parent | e26bcf37234c67624f62d9fc95f922b8dbda1363 (diff) | |
download | kernel_samsung_smdk4412-7a9b149212f3716c598afe973b6261fd58453b7a.zip kernel_samsung_smdk4412-7a9b149212f3716c598afe973b6261fd58453b7a.tar.gz kernel_samsung_smdk4412-7a9b149212f3716c598afe973b6261fd58453b7a.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (229 commits)
USB: remove unused usb_buffer_alloc and usb_buffer_free macros
usb: musb: update gfp/slab.h includes
USB: ftdi_sio: fix legacy SIO-device header
USB: kl5usb105: reimplement using generic framework
USB: kl5usb105: minor clean ups
USB: kl5usb105: fix memory leak
USB: io_ti: use kfifo to implement write buffering
USB: io_ti: remove unsused private counter
USB: ti_usb: use kfifo to implement write buffering
USB: ir-usb: fix incorrect write-buffer length
USB: aircable: fix incorrect write-buffer length
USB: safe_serial: straighten out read processing
USB: safe_serial: reimplement read using generic framework
USB: safe_serial: reimplement write using generic framework
usb-storage: always print quirks
USB: usb-storage: trivial debug improvements
USB: oti6858: use port write fifo
USB: oti6858: use kfifo to implement write buffering
USB: cypress_m8: use kfifo to implement write buffering
USB: cypress_m8: remove unused drain define
...
Fix up conflicts (due to usb_buffer_alloc/free renaming) in
drivers/input/tablet/acecad.c
drivers/input/tablet/kbtab.c
drivers/input/tablet/wacom_sys.c
drivers/media/video/gspca/gspca.c
sound/usb/usbaudio.c
Diffstat (limited to 'drivers/usb/serial/qcserial.c')
-rw-r--r-- | drivers/usb/serial/qcserial.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 53a2d5a..04bb759 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -15,6 +15,8 @@ #include <linux/tty_flip.h> #include <linux/usb.h> #include <linux/usb/serial.h> +#include <linux/slab.h> +#include "usb-wwan.h" #define DRIVER_AUTHOR "Qualcomm Inc" #define DRIVER_DESC "Qualcomm USB Serial driver" @@ -76,6 +78,8 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ + {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */ + {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); @@ -92,6 +96,8 @@ static struct usb_driver qcdriver = { static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { + struct usb_wwan_intf_private *data; + struct usb_host_interface *intf = serial->interface->cur_altsetting; int retval = -ENODEV; __u8 nintf; __u8 ifnum; @@ -100,33 +106,45 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) nintf = serial->dev->actconfig->desc.bNumInterfaces; dbg("Num Interfaces = %d", nintf); - ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; + ifnum = intf->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); + data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + spin_lock_init(&data->susp_lock); + switch (nintf) { case 1: /* QDL mode */ - if (serial->interface->num_altsetting == 2) { - struct usb_host_interface *intf; - + /* Gobi 2000 has a single altsetting, older ones have two */ + if (serial->interface->num_altsetting == 2) intf = &serial->interface->altsetting[1]; - if (intf->desc.bNumEndpoints == 2) { - if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && - usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { - dbg("QDL port found"); - retval = usb_set_interface(serial->dev, ifnum, 1); - if (retval < 0) { - dev_err(&serial->dev->dev, - "Could not set interface, error %d\n", - retval); - retval = -ENODEV; - } - return retval; - } + else if (serial->interface->num_altsetting > 2) + break; + + if (intf->desc.bNumEndpoints == 2 && + usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && + usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { + dbg("QDL port found"); + + if (serial->interface->num_altsetting == 1) + return 0; + + retval = usb_set_interface(serial->dev, ifnum, 1); + if (retval < 0) { + dev_err(&serial->dev->dev, + "Could not set interface, error %d\n", + retval); + retval = -ENODEV; } + return retval; } break; + case 3: case 4: /* Composite mode */ if (ifnum == 2) { @@ -161,6 +179,18 @@ static struct usb_serial_driver qcdevice = { .usb_driver = &qcdriver, .num_ports = 1, .probe = qcprobe, + .open = usb_wwan_open, + .close = usb_wwan_close, + .write = usb_wwan_write, + .write_room = usb_wwan_write_room, + .chars_in_buffer = usb_wwan_chars_in_buffer, + .attach = usb_wwan_startup, + .disconnect = usb_wwan_disconnect, + .release = usb_wwan_release, +#ifdef CONFIG_PM + .suspend = usb_wwan_suspend, + .resume = usb_wwan_resume, +#endif }; static int __init qcinit(void) |