diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
| commit | be90a49ca22a95f184d9f32d35b5247b44032849 (patch) | |
| tree | d3c2edc18c003c384366f57901616ac29c80bc27 /drivers/usb/serial | |
| parent | 1f0918d03ff4b5c94540c71ce889672abdbc2f4a (diff) | |
| parent | a87371b477774b290c27bc5cb7f4ccc5379574a9 (diff) | |
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: (142 commits)
USB: Fix sysfs paths in documentation
USB: skeleton: fix coding style issues.
USB: O_NONBLOCK in read path of skeleton
USB: make usb-skeleton honor O_NONBLOCK in write path
USB: skel_read really sucks royally
USB: Add hub descriptor update hook for xHCI
USB: xhci: Support USB hubs.
USB: xhci: Set multi-TT field for LS/FS devices under hubs.
USB: xhci: Set route string for all devices.
USB: xhci: Fix command wait list handling.
USB: xhci: Change how xHCI commands are handled.
USB: xhci: Refactor input device context setup.
USB: xhci: Endpoint representation refactoring.
USB: gadget: ether needs to select CRC32
USB: fix USBTMC get_capabilities success handling
USB: fix missing error check in probing
USB: usbfs: add USBDEVFS_URB_BULK_CONTINUATION flag
USB: support for autosuspend in sierra while online
USB: ehci-dbgp,ehci: Allow dbpg to work with suspend/resume
USB: ehci-dbgp,documentation: Documentation updates for ehci-dbgp
...
Diffstat (limited to 'drivers/usb/serial')
| -rw-r--r-- | drivers/usb/serial/ark3116.c | 24 | ||||
| -rw-r--r-- | drivers/usb/serial/ch341.c | 52 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 7 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 10 | ||||
| -rw-r--r-- | drivers/usb/serial/generic.c | 206 | ||||
| -rw-r--r-- | drivers/usb/serial/iuu_phoenix.c | 115 | ||||
| -rw-r--r-- | drivers/usb/serial/moto_modem.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 138 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.c | 71 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.h | 4 | ||||
| -rw-r--r-- | drivers/usb/serial/sierra.c | 157 | ||||
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 23 |
12 files changed, 676 insertions, 133 deletions
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 5d25d3e52bf6..131e61adaaf7 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
| @@ -31,10 +31,20 @@ static int debug; | |||
| 31 | 31 | ||
| 32 | static struct usb_device_id id_table [] = { | 32 | static struct usb_device_id id_table [] = { |
| 33 | { USB_DEVICE(0x6547, 0x0232) }, | 33 | { USB_DEVICE(0x6547, 0x0232) }, |
| 34 | { USB_DEVICE(0x18ec, 0x3118) }, /* USB to IrDA adapter */ | ||
| 34 | { }, | 35 | { }, |
| 35 | }; | 36 | }; |
| 36 | MODULE_DEVICE_TABLE(usb, id_table); | 37 | MODULE_DEVICE_TABLE(usb, id_table); |
| 37 | 38 | ||
| 39 | static int is_irda(struct usb_serial *serial) | ||
| 40 | { | ||
| 41 | struct usb_device *dev = serial->dev; | ||
| 42 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x18ec && | ||
| 43 | le16_to_cpu(dev->descriptor.idProduct) == 0x3118) | ||
| 44 | return 1; | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 38 | static inline void ARK3116_SND(struct usb_serial *serial, int seq, | 48 | static inline void ARK3116_SND(struct usb_serial *serial, int seq, |
| 39 | __u8 request, __u8 requesttype, | 49 | __u8 request, __u8 requesttype, |
| 40 | __u16 value, __u16 index) | 50 | __u16 value, __u16 index) |
| @@ -84,11 +94,21 @@ static int ark3116_attach(struct usb_serial *serial) | |||
| 84 | return -ENOMEM; | 94 | return -ENOMEM; |
| 85 | } | 95 | } |
| 86 | 96 | ||
| 97 | if (is_irda(serial)) | ||
| 98 | dbg("IrDA mode"); | ||
| 99 | |||
| 87 | /* 3 */ | 100 | /* 3 */ |
| 88 | ARK3116_SND(serial, 3, 0xFE, 0x40, 0x0008, 0x0002); | 101 | ARK3116_SND(serial, 3, 0xFE, 0x40, 0x0008, 0x0002); |
| 89 | ARK3116_SND(serial, 4, 0xFE, 0x40, 0x0008, 0x0001); | 102 | ARK3116_SND(serial, 4, 0xFE, 0x40, 0x0008, 0x0001); |
| 90 | ARK3116_SND(serial, 5, 0xFE, 0x40, 0x0000, 0x0008); | 103 | ARK3116_SND(serial, 5, 0xFE, 0x40, 0x0000, 0x0008); |
| 91 | ARK3116_SND(serial, 6, 0xFE, 0x40, 0x0000, 0x000B); | 104 | ARK3116_SND(serial, 6, 0xFE, 0x40, is_irda(serial) ? 0x0001 : 0x0000, |
| 105 | 0x000B); | ||
| 106 | |||
| 107 | if (is_irda(serial)) { | ||
| 108 | ARK3116_SND(serial, 1001, 0xFE, 0x40, 0x0000, 0x000C); | ||
| 109 | ARK3116_SND(serial, 1002, 0xFE, 0x40, 0x0041, 0x000D); | ||
| 110 | ARK3116_SND(serial, 1003, 0xFE, 0x40, 0x0001, 0x000A); | ||
| 111 | } | ||
| 92 | 112 | ||
| 93 | /* <-- seq7 */ | 113 | /* <-- seq7 */ |
| 94 | ARK3116_RCV(serial, 7, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf); | 114 | ARK3116_RCV(serial, 7, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf); |
| @@ -125,6 +145,8 @@ static int ark3116_attach(struct usb_serial *serial) | |||
| 125 | ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003); | 145 | ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003); |
| 126 | ARK3116_SND(serial, 148, 0xFE, 0x40, 0x0038, 0x0000); | 146 | ARK3116_SND(serial, 148, 0xFE, 0x40, 0x0038, 0x0000); |
| 127 | ARK3116_SND(serial, 149, 0xFE, 0x40, 0x0001, 0x0001); | 147 | ARK3116_SND(serial, 149, 0xFE, 0x40, 0x0001, 0x0001); |
| 148 | if (is_irda(serial)) | ||
| 149 | ARK3116_SND(serial, 1004, 0xFE, 0x40, 0x0000, 0x0009); | ||
| 128 | ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003); | 150 | ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003); |
| 129 | ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf); | 151 | ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf); |
| 130 | ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003); | 152 | ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003); |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 8c894a7d5dcf..59eff721fcc5 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
| @@ -56,6 +56,18 @@ | |||
| 56 | #define CH341_BAUDBASE_FACTOR 1532620800 | 56 | #define CH341_BAUDBASE_FACTOR 1532620800 |
| 57 | #define CH341_BAUDBASE_DIVMAX 3 | 57 | #define CH341_BAUDBASE_DIVMAX 3 |
| 58 | 58 | ||
| 59 | /* Break support - the information used to implement this was gleaned from | ||
| 60 | * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. | ||
| 61 | */ | ||
| 62 | |||
| 63 | #define CH341_REQ_WRITE_REG 0x9A | ||
| 64 | #define CH341_REQ_READ_REG 0x95 | ||
| 65 | #define CH341_REG_BREAK1 0x05 | ||
| 66 | #define CH341_REG_BREAK2 0x18 | ||
| 67 | #define CH341_NBREAK_BITS_REG1 0x01 | ||
| 68 | #define CH341_NBREAK_BITS_REG2 0x40 | ||
| 69 | |||
| 70 | |||
| 59 | static int debug; | 71 | static int debug; |
| 60 | 72 | ||
| 61 | static struct usb_device_id id_table [] = { | 73 | static struct usb_device_id id_table [] = { |
| @@ -373,6 +385,45 @@ static void ch341_set_termios(struct tty_struct *tty, | |||
| 373 | */ | 385 | */ |
| 374 | } | 386 | } |
| 375 | 387 | ||
| 388 | static void ch341_break_ctl(struct tty_struct *tty, int break_state) | ||
| 389 | { | ||
| 390 | const uint16_t ch341_break_reg = | ||
| 391 | CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8); | ||
| 392 | struct usb_serial_port *port = tty->driver_data; | ||
| 393 | int r; | ||
| 394 | uint16_t reg_contents; | ||
| 395 | uint8_t break_reg[2]; | ||
| 396 | |||
| 397 | dbg("%s()", __func__); | ||
| 398 | |||
| 399 | r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, | ||
| 400 | ch341_break_reg, 0, break_reg, sizeof(break_reg)); | ||
| 401 | if (r < 0) { | ||
| 402 | printk(KERN_WARNING "%s: USB control read error whilst getting" | ||
| 403 | " break register contents.\n", __FILE__); | ||
| 404 | return; | ||
| 405 | } | ||
| 406 | dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", | ||
| 407 | __func__, break_reg[0], break_reg[1]); | ||
| 408 | if (break_state != 0) { | ||
| 409 | dbg("%s - Enter break state requested", __func__); | ||
| 410 | break_reg[0] &= ~CH341_NBREAK_BITS_REG1; | ||
| 411 | break_reg[1] &= ~CH341_NBREAK_BITS_REG2; | ||
| 412 | } else { | ||
| 413 | dbg("%s - Leave break state requested", __func__); | ||
| 414 | break_reg[0] |= CH341_NBREAK_BITS_REG1; | ||
| 415 | break_reg[1] |= CH341_NBREAK_BITS_REG2; | ||
| 416 | } | ||
| 417 | dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", | ||
| 418 | __func__, break_reg[0], break_reg[1]); | ||
| 419 | reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8); | ||
| 420 | r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, | ||
| 421 | ch341_break_reg, reg_contents); | ||
| 422 | if (r < 0) | ||
| 423 | printk(KERN_WARNING "%s: USB control write error whilst setting" | ||
| 424 | " break register contents.\n", __FILE__); | ||
| 425 | } | ||
| 426 | |||
| 376 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, | 427 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, |
| 377 | unsigned int set, unsigned int clear) | 428 | unsigned int set, unsigned int clear) |
| 378 | { | 429 | { |
| @@ -576,6 +627,7 @@ static struct usb_serial_driver ch341_device = { | |||
| 576 | .close = ch341_close, | 627 | .close = ch341_close, |
| 577 | .ioctl = ch341_ioctl, | 628 | .ioctl = ch341_ioctl, |
| 578 | .set_termios = ch341_set_termios, | 629 | .set_termios = ch341_set_termios, |
| 630 | .break_ctl = ch341_break_ctl, | ||
| 579 | .tiocmget = ch341_tiocmget, | 631 | .tiocmget = ch341_tiocmget, |
| 580 | .tiocmset = ch341_tiocmset, | 632 | .tiocmset = ch341_tiocmset, |
| 581 | .read_int_callback = ch341_read_int_callback, | 633 | .read_int_callback = ch341_read_int_callback, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 76a17f915eef..4f883b1773d0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -176,6 +176,9 @@ static struct usb_device_id id_table_combined [] = { | |||
| 176 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | 176 | { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, |
| 177 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | 177 | { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, |
| 178 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, | 178 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, |
| 179 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) }, | ||
| 180 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, | ||
| 181 | { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, | ||
| 179 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 182 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
| 180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 183 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
| 181 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, | 184 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, |
| @@ -694,6 +697,8 @@ static struct usb_device_id id_table_combined [] = { | |||
| 694 | { USB_DEVICE(DE_VID, WHT_PID) }, | 697 | { USB_DEVICE(DE_VID, WHT_PID) }, |
| 695 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), | 698 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), |
| 696 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 699 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 700 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), | ||
| 701 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
| 697 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 702 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
| 698 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 703 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
| 699 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 704 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| @@ -702,6 +707,8 @@ static struct usb_device_id id_table_combined [] = { | |||
| 702 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 707 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
| 703 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 708 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
| 704 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 709 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 710 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | ||
| 711 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | ||
| 705 | { }, /* Optional parameter entry */ | 712 | { }, /* Optional parameter entry */ |
| 706 | { } /* Terminating entry */ | 713 | { } /* Terminating entry */ |
| 707 | }; | 714 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8c92b88166ae..6f31e0d71898 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -81,6 +81,9 @@ | |||
| 81 | 81 | ||
| 82 | /* OpenDCC (www.opendcc.de) product id */ | 82 | /* OpenDCC (www.opendcc.de) product id */ |
| 83 | #define FTDI_OPENDCC_PID 0xBFD8 | 83 | #define FTDI_OPENDCC_PID 0xBFD8 |
| 84 | #define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 | ||
| 85 | #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA | ||
| 86 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | ||
| 84 | 87 | ||
| 85 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ | 88 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ |
| 86 | #define FTDI_SPROG_II 0xF0C8 | 89 | #define FTDI_SPROG_II 0xF0C8 |
| @@ -930,6 +933,7 @@ | |||
| 930 | */ | 933 | */ |
| 931 | #define ADI_VID 0x0456 | 934 | #define ADI_VID 0x0456 |
| 932 | #define ADI_GNICE_PID 0xF000 | 935 | #define ADI_GNICE_PID 0xF000 |
| 936 | #define ADI_GNICEPLUS_PID 0xF001 | ||
| 933 | 937 | ||
| 934 | /* | 938 | /* |
| 935 | * JETI SPECTROMETER SPECBOS 1201 | 939 | * JETI SPECTROMETER SPECBOS 1201 |
| @@ -968,6 +972,12 @@ | |||
| 968 | #define MARVELL_OPENRD_PID 0x9e90 | 972 | #define MARVELL_OPENRD_PID 0x9e90 |
| 969 | 973 | ||
| 970 | /* | 974 | /* |
| 975 | * Hameg HO820 and HO870 interface (using VID 0x0403) | ||
| 976 | */ | ||
| 977 | #define HAMEG_HO820_PID 0xed74 | ||
| 978 | #define HAMEG_HO870_PID 0xed71 | ||
| 979 | |||
| 980 | /* | ||
| 971 | * BmRequestType: 1100 0000b | 981 | * BmRequestType: 1100 0000b |
| 972 | * bRequest: FTDI_E2_READ | 982 | * bRequest: FTDI_E2_READ |
| 973 | * wValue: 0 | 983 | * wValue: 0 |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index d9398e9f30ce..deba08c7a015 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
| 20 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
| 21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | 22 | #include <linux/kfifo.h> | |
| 23 | 23 | ||
| 24 | static int debug; | 24 | static int debug; |
| 25 | 25 | ||
| @@ -166,24 +166,6 @@ static void generic_cleanup(struct usb_serial_port *port) | |||
| 166 | } | 166 | } |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | int usb_serial_generic_resume(struct usb_serial *serial) | ||
| 170 | { | ||
| 171 | struct usb_serial_port *port; | ||
| 172 | int i, c = 0, r; | ||
| 173 | |||
| 174 | for (i = 0; i < serial->num_ports; i++) { | ||
| 175 | port = serial->port[i]; | ||
| 176 | if (port->port.count && port->read_urb) { | ||
| 177 | r = usb_submit_urb(port->read_urb, GFP_NOIO); | ||
| 178 | if (r < 0) | ||
| 179 | c++; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | return c ? -EIO : 0; | ||
| 184 | } | ||
| 185 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | ||
| 186 | |||
| 187 | void usb_serial_generic_close(struct usb_serial_port *port) | 169 | void usb_serial_generic_close(struct usb_serial_port *port) |
| 188 | { | 170 | { |
| 189 | dbg("%s - port %d", __func__, port->number); | 171 | dbg("%s - port %d", __func__, port->number); |
| @@ -272,12 +254,81 @@ error_no_buffer: | |||
| 272 | return bwrite; | 254 | return bwrite; |
| 273 | } | 255 | } |
| 274 | 256 | ||
| 257 | /** | ||
| 258 | * usb_serial_generic_write_start - kick off an URB write | ||
| 259 | * @port: Pointer to the &struct usb_serial_port data | ||
| 260 | * | ||
| 261 | * Returns the number of bytes queued on success. This will be zero if there | ||
| 262 | * was nothing to send. Otherwise, it returns a negative errno value | ||
| 263 | */ | ||
| 264 | static int usb_serial_generic_write_start(struct usb_serial_port *port) | ||
| 265 | { | ||
| 266 | struct usb_serial *serial = port->serial; | ||
| 267 | unsigned char *data; | ||
| 268 | int result; | ||
| 269 | int count; | ||
| 270 | unsigned long flags; | ||
| 271 | bool start_io; | ||
| 272 | |||
| 273 | /* Atomically determine whether we can and need to start a USB | ||
| 274 | * operation. */ | ||
| 275 | spin_lock_irqsave(&port->lock, flags); | ||
| 276 | if (port->write_urb_busy) | ||
| 277 | start_io = false; | ||
| 278 | else { | ||
| 279 | start_io = (__kfifo_len(port->write_fifo) != 0); | ||
| 280 | port->write_urb_busy = start_io; | ||
| 281 | } | ||
| 282 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 283 | |||
| 284 | if (!start_io) | ||
| 285 | return 0; | ||
| 286 | |||
| 287 | data = port->write_urb->transfer_buffer; | ||
| 288 | count = kfifo_get(port->write_fifo, data, port->bulk_out_size); | ||
| 289 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | ||
| 290 | |||
| 291 | /* set up our urb */ | ||
| 292 | usb_fill_bulk_urb(port->write_urb, serial->dev, | ||
| 293 | usb_sndbulkpipe(serial->dev, | ||
| 294 | port->bulk_out_endpointAddress), | ||
| 295 | port->write_urb->transfer_buffer, count, | ||
| 296 | ((serial->type->write_bulk_callback) ? | ||
| 297 | serial->type->write_bulk_callback : | ||
| 298 | usb_serial_generic_write_bulk_callback), | ||
| 299 | port); | ||
| 300 | |||
| 301 | /* send the data out the bulk port */ | ||
| 302 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
| 303 | if (result) { | ||
| 304 | dev_err(&port->dev, | ||
| 305 | "%s - failed submitting write urb, error %d\n", | ||
| 306 | __func__, result); | ||
| 307 | /* don't have to grab the lock here, as we will | ||
| 308 | retry if != 0 */ | ||
| 309 | port->write_urb_busy = 0; | ||
| 310 | } else | ||
| 311 | result = count; | ||
| 312 | |||
| 313 | return result; | ||
| 314 | } | ||
| 315 | |||
| 316 | /** | ||
| 317 | * usb_serial_generic_write - generic write function for serial USB devices | ||
| 318 | * @tty: Pointer to &struct tty_struct for the device | ||
| 319 | * @port: Pointer to the &usb_serial_port structure for the device | ||
| 320 | * @buf: Pointer to the data to write | ||
| 321 | * @count: Number of bytes to write | ||
| 322 | * | ||
| 323 | * Returns the number of characters actually written, which may be anything | ||
| 324 | * from zero to @count. If an error occurs, it returns the negative errno | ||
| 325 | * value. | ||
| 326 | */ | ||
| 275 | int usb_serial_generic_write(struct tty_struct *tty, | 327 | int usb_serial_generic_write(struct tty_struct *tty, |
| 276 | struct usb_serial_port *port, const unsigned char *buf, int count) | 328 | struct usb_serial_port *port, const unsigned char *buf, int count) |
| 277 | { | 329 | { |
| 278 | struct usb_serial *serial = port->serial; | 330 | struct usb_serial *serial = port->serial; |
| 279 | int result; | 331 | int result; |
| 280 | unsigned char *data; | ||
| 281 | 332 | ||
| 282 | dbg("%s - port %d", __func__, port->number); | 333 | dbg("%s - port %d", __func__, port->number); |
| 283 | 334 | ||
| @@ -287,57 +338,20 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
| 287 | } | 338 | } |
| 288 | 339 | ||
| 289 | /* only do something if we have a bulk out endpoint */ | 340 | /* only do something if we have a bulk out endpoint */ |
| 290 | if (serial->num_bulk_out) { | 341 | if (!serial->num_bulk_out) |
| 291 | unsigned long flags; | 342 | return 0; |
| 292 | |||
| 293 | if (serial->type->max_in_flight_urbs) | ||
| 294 | return usb_serial_multi_urb_write(tty, port, | ||
| 295 | buf, count); | ||
| 296 | |||
| 297 | spin_lock_irqsave(&port->lock, flags); | ||
| 298 | if (port->write_urb_busy) { | ||
| 299 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 300 | dbg("%s - already writing", __func__); | ||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | port->write_urb_busy = 1; | ||
| 304 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 305 | |||
| 306 | count = (count > port->bulk_out_size) ? | ||
| 307 | port->bulk_out_size : count; | ||
| 308 | |||
| 309 | memcpy(port->write_urb->transfer_buffer, buf, count); | ||
| 310 | data = port->write_urb->transfer_buffer; | ||
| 311 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | ||
| 312 | 343 | ||
| 313 | /* set up our urb */ | 344 | if (serial->type->max_in_flight_urbs) |
| 314 | usb_fill_bulk_urb(port->write_urb, serial->dev, | 345 | return usb_serial_multi_urb_write(tty, port, |
| 315 | usb_sndbulkpipe(serial->dev, | 346 | buf, count); |
| 316 | port->bulk_out_endpointAddress), | ||
| 317 | port->write_urb->transfer_buffer, count, | ||
| 318 | ((serial->type->write_bulk_callback) ? | ||
| 319 | serial->type->write_bulk_callback : | ||
| 320 | usb_serial_generic_write_bulk_callback), | ||
| 321 | port); | ||
| 322 | 347 | ||
| 323 | /* send the data out the bulk port */ | 348 | count = kfifo_put(port->write_fifo, buf, count); |
| 324 | port->write_urb_busy = 1; | 349 | result = usb_serial_generic_write_start(port); |
| 325 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | ||
| 326 | if (result) { | ||
| 327 | dev_err(&port->dev, | ||
| 328 | "%s - failed submitting write urb, error %d\n", | ||
| 329 | __func__, result); | ||
| 330 | /* don't have to grab the lock here, as we will | ||
| 331 | retry if != 0 */ | ||
| 332 | port->write_urb_busy = 0; | ||
| 333 | } else | ||
| 334 | result = count; | ||
| 335 | 350 | ||
| 336 | return result; | 351 | if (result >= 0) |
| 337 | } | 352 | result = count; |
| 338 | 353 | ||
| 339 | /* no bulk out, so return 0 bytes written */ | 354 | return result; |
| 340 | return 0; | ||
| 341 | } | 355 | } |
| 342 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); | 356 | EXPORT_SYMBOL_GPL(usb_serial_generic_write); |
| 343 | 357 | ||
| @@ -355,9 +369,8 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
| 355 | room = port->bulk_out_size * | 369 | room = port->bulk_out_size * |
| 356 | (serial->type->max_in_flight_urbs - | 370 | (serial->type->max_in_flight_urbs - |
| 357 | port->urbs_in_flight); | 371 | port->urbs_in_flight); |
| 358 | } else if (serial->num_bulk_out && !(port->write_urb_busy)) { | 372 | } else if (serial->num_bulk_out) |
| 359 | room = port->bulk_out_size; | 373 | room = port->write_fifo->size - __kfifo_len(port->write_fifo); |
| 360 | } | ||
| 361 | spin_unlock_irqrestore(&port->lock, flags); | 374 | spin_unlock_irqrestore(&port->lock, flags); |
| 362 | 375 | ||
| 363 | dbg("%s - returns %d", __func__, room); | 376 | dbg("%s - returns %d", __func__, room); |
| @@ -377,11 +390,8 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
| 377 | spin_lock_irqsave(&port->lock, flags); | 390 | spin_lock_irqsave(&port->lock, flags); |
| 378 | chars = port->tx_bytes_flight; | 391 | chars = port->tx_bytes_flight; |
| 379 | spin_unlock_irqrestore(&port->lock, flags); | 392 | spin_unlock_irqrestore(&port->lock, flags); |
| 380 | } else if (serial->num_bulk_out) { | 393 | } else if (serial->num_bulk_out) |
| 381 | /* FIXME: Locking */ | 394 | chars = kfifo_len(port->write_fifo); |
| 382 | if (port->write_urb_busy) | ||
| 383 | chars = port->write_urb->transfer_buffer_length; | ||
| 384 | } | ||
| 385 | 395 | ||
| 386 | dbg("%s - returns %d", __func__, chars); | 396 | dbg("%s - returns %d", __func__, chars); |
| 387 | return chars; | 397 | return chars; |
| @@ -485,16 +495,23 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
| 485 | if (port->urbs_in_flight < 0) | 495 | if (port->urbs_in_flight < 0) |
| 486 | port->urbs_in_flight = 0; | 496 | port->urbs_in_flight = 0; |
| 487 | spin_unlock_irqrestore(&port->lock, flags); | 497 | spin_unlock_irqrestore(&port->lock, flags); |
| 498 | |||
| 499 | if (status) { | ||
| 500 | dbg("%s - nonzero multi-urb write bulk status " | ||
| 501 | "received: %d", __func__, status); | ||
| 502 | return; | ||
| 503 | } | ||
| 488 | } else { | 504 | } else { |
| 489 | /* Handle the case for single urb mode */ | ||
| 490 | port->write_urb_busy = 0; | 505 | port->write_urb_busy = 0; |
| 491 | } | ||
| 492 | 506 | ||
| 493 | if (status) { | 507 | if (status) { |
| 494 | dbg("%s - nonzero write bulk status received: %d", | 508 | dbg("%s - nonzero multi-urb write bulk status " |
| 495 | __func__, status); | 509 | "received: %d", __func__, status); |
| 496 | return; | 510 | kfifo_reset(port->write_fifo); |
| 511 | } else | ||
| 512 | usb_serial_generic_write_start(port); | ||
| 497 | } | 513 | } |
| 514 | |||
| 498 | usb_serial_port_softint(port); | 515 | usb_serial_port_softint(port); |
| 499 | } | 516 | } |
| 500 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 517 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
| @@ -559,6 +576,33 @@ int usb_serial_handle_break(struct usb_serial_port *port) | |||
| 559 | } | 576 | } |
| 560 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); | 577 | EXPORT_SYMBOL_GPL(usb_serial_handle_break); |
| 561 | 578 | ||
| 579 | int usb_serial_generic_resume(struct usb_serial *serial) | ||
| 580 | { | ||
| 581 | struct usb_serial_port *port; | ||
| 582 | int i, c = 0, r; | ||
| 583 | |||
| 584 | for (i = 0; i < serial->num_ports; i++) { | ||
| 585 | port = serial->port[i]; | ||
| 586 | if (!port->port.count) | ||
| 587 | continue; | ||
| 588 | |||
| 589 | if (port->read_urb) { | ||
| 590 | r = usb_submit_urb(port->read_urb, GFP_NOIO); | ||
| 591 | if (r < 0) | ||
| 592 | c++; | ||
| 593 | } | ||
| 594 | |||
| 595 | if (port->write_urb) { | ||
| 596 | r = usb_serial_generic_write_start(port); | ||
| 597 | if (r < 0) | ||
| 598 | c++; | ||
| 599 | } | ||
| 600 | } | ||
| 601 | |||
| 602 | return c ? -EIO : 0; | ||
| 603 | } | ||
| 604 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | ||
| 605 | |||
| 562 | void usb_serial_generic_disconnect(struct usb_serial *serial) | 606 | void usb_serial_generic_disconnect(struct usb_serial *serial) |
| 563 | { | 607 | { |
| 564 | int i; | 608 | int i; |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 6138c1cda35f..e6e02b178d2b 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
| @@ -40,7 +40,7 @@ static int debug; | |||
| 40 | /* | 40 | /* |
| 41 | * Version Information | 41 | * Version Information |
| 42 | */ | 42 | */ |
| 43 | #define DRIVER_VERSION "v0.10" | 43 | #define DRIVER_VERSION "v0.11" |
| 44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" | 44 | #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" |
| 45 | 45 | ||
| 46 | static struct usb_device_id id_table[] = { | 46 | static struct usb_device_id id_table[] = { |
| @@ -64,6 +64,7 @@ static int cdmode = 1; | |||
| 64 | static int iuu_cardin; | 64 | static int iuu_cardin; |
| 65 | static int iuu_cardout; | 65 | static int iuu_cardout; |
| 66 | static int xmas; | 66 | static int xmas; |
| 67 | static int vcc_default = 5; | ||
| 67 | 68 | ||
| 68 | static void read_rxcmd_callback(struct urb *urb); | 69 | static void read_rxcmd_callback(struct urb *urb); |
| 69 | 70 | ||
| @@ -79,6 +80,7 @@ struct iuu_private { | |||
| 79 | u8 *buf; /* used for initialize speed */ | 80 | u8 *buf; /* used for initialize speed */ |
| 80 | u8 *dbgbuf; /* debug buffer */ | 81 | u8 *dbgbuf; /* debug buffer */ |
| 81 | u8 len; | 82 | u8 len; |
| 83 | int vcc; /* vcc (either 3 or 5 V) */ | ||
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | 86 | ||
| @@ -114,6 +116,7 @@ static int iuu_startup(struct usb_serial *serial) | |||
| 114 | kfree(priv); | 116 | kfree(priv); |
| 115 | return -ENOMEM; | 117 | return -ENOMEM; |
| 116 | } | 118 | } |
| 119 | priv->vcc = vcc_default; | ||
| 117 | spin_lock_init(&priv->lock); | 120 | spin_lock_init(&priv->lock); |
| 118 | init_waitqueue_head(&priv->delta_msr_wait); | 121 | init_waitqueue_head(&priv->delta_msr_wait); |
| 119 | usb_set_serial_port_data(serial->port[0], priv); | 122 | usb_set_serial_port_data(serial->port[0], priv); |
| @@ -1009,11 +1012,7 @@ static void iuu_close(struct usb_serial_port *port) | |||
| 1009 | usb_kill_urb(port->write_urb); | 1012 | usb_kill_urb(port->write_urb); |
| 1010 | usb_kill_urb(port->read_urb); | 1013 | usb_kill_urb(port->read_urb); |
| 1011 | usb_kill_urb(port->interrupt_in_urb); | 1014 | usb_kill_urb(port->interrupt_in_urb); |
| 1012 | msleep(1000); | ||
| 1013 | /* wait one second to free all buffers */ | ||
| 1014 | iuu_led(port, 0, 0, 0xF000, 0xFF); | 1015 | iuu_led(port, 0, 0, 0xF000, 0xFF); |
| 1015 | msleep(1000); | ||
| 1016 | usb_reset_device(port->serial->dev); | ||
| 1017 | } | 1016 | } |
| 1018 | } | 1017 | } |
| 1019 | 1018 | ||
| @@ -1182,6 +1181,95 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1182 | return result; | 1181 | return result; |
| 1183 | } | 1182 | } |
| 1184 | 1183 | ||
| 1184 | /* how to change VCC */ | ||
| 1185 | static int iuu_vcc_set(struct usb_serial_port *port, unsigned int vcc) | ||
| 1186 | { | ||
| 1187 | int status; | ||
| 1188 | u8 *buf; | ||
| 1189 | |||
| 1190 | buf = kmalloc(5, GFP_KERNEL); | ||
| 1191 | if (!buf) | ||
| 1192 | return -ENOMEM; | ||
| 1193 | |||
| 1194 | dbg("%s - enter", __func__); | ||
| 1195 | |||
| 1196 | buf[0] = IUU_SET_VCC; | ||
| 1197 | buf[1] = vcc & 0xFF; | ||
| 1198 | buf[2] = (vcc >> 8) & 0xFF; | ||
| 1199 | buf[3] = (vcc >> 16) & 0xFF; | ||
| 1200 | buf[4] = (vcc >> 24) & 0xFF; | ||
| 1201 | |||
| 1202 | status = bulk_immediate(port, buf, 5); | ||
| 1203 | kfree(buf); | ||
| 1204 | |||
| 1205 | if (status != IUU_OPERATION_OK) | ||
| 1206 | dbg("%s - vcc error status = %2x", __func__, status); | ||
| 1207 | else | ||
| 1208 | dbg("%s - vcc OK !", __func__); | ||
| 1209 | |||
| 1210 | return status; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | /* | ||
| 1214 | * Sysfs Attributes | ||
| 1215 | */ | ||
| 1216 | |||
| 1217 | static ssize_t show_vcc_mode(struct device *dev, | ||
| 1218 | struct device_attribute *attr, char *buf) | ||
| 1219 | { | ||
| 1220 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
| 1221 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
| 1222 | |||
| 1223 | return sprintf(buf, "%d\n", priv->vcc); | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | static ssize_t store_vcc_mode(struct device *dev, | ||
| 1227 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 1228 | { | ||
| 1229 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
| 1230 | struct iuu_private *priv = usb_get_serial_port_data(port); | ||
| 1231 | unsigned long v; | ||
| 1232 | |||
| 1233 | if (strict_strtoul(buf, 10, &v)) { | ||
| 1234 | dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n", | ||
| 1235 | __func__, buf); | ||
| 1236 | goto fail_store_vcc_mode; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | dbg("%s: setting vcc_mode = %ld", __func__, v); | ||
| 1240 | |||
| 1241 | if ((v != 3) && (v != 5)) { | ||
| 1242 | dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v); | ||
| 1243 | } else { | ||
| 1244 | iuu_vcc_set(port, v); | ||
| 1245 | priv->vcc = v; | ||
| 1246 | } | ||
| 1247 | fail_store_vcc_mode: | ||
| 1248 | return count; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | static DEVICE_ATTR(vcc_mode, S_IRUSR | S_IWUSR, show_vcc_mode, | ||
| 1252 | store_vcc_mode); | ||
| 1253 | |||
| 1254 | static int iuu_create_sysfs_attrs(struct usb_serial_port *port) | ||
| 1255 | { | ||
| 1256 | dbg("%s", __func__); | ||
| 1257 | |||
| 1258 | return device_create_file(&port->dev, &dev_attr_vcc_mode); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | static int iuu_remove_sysfs_attrs(struct usb_serial_port *port) | ||
| 1262 | { | ||
| 1263 | dbg("%s", __func__); | ||
| 1264 | |||
| 1265 | device_remove_file(&port->dev, &dev_attr_vcc_mode); | ||
| 1266 | return 0; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | /* | ||
| 1270 | * End Sysfs Attributes | ||
| 1271 | */ | ||
| 1272 | |||
| 1185 | static struct usb_serial_driver iuu_device = { | 1273 | static struct usb_serial_driver iuu_device = { |
| 1186 | .driver = { | 1274 | .driver = { |
| 1187 | .owner = THIS_MODULE, | 1275 | .owner = THIS_MODULE, |
| @@ -1189,6 +1277,8 @@ static struct usb_serial_driver iuu_device = { | |||
| 1189 | }, | 1277 | }, |
| 1190 | .id_table = id_table, | 1278 | .id_table = id_table, |
| 1191 | .num_ports = 1, | 1279 | .num_ports = 1, |
| 1280 | .port_probe = iuu_create_sysfs_attrs, | ||
| 1281 | .port_remove = iuu_remove_sysfs_attrs, | ||
| 1192 | .open = iuu_open, | 1282 | .open = iuu_open, |
| 1193 | .close = iuu_close, | 1283 | .close = iuu_close, |
| 1194 | .write = iuu_uart_write, | 1284 | .write = iuu_uart_write, |
| @@ -1238,14 +1328,19 @@ module_param(debug, bool, S_IRUGO | S_IWUSR); | |||
| 1238 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 1328 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
| 1239 | 1329 | ||
| 1240 | module_param(xmas, bool, S_IRUGO | S_IWUSR); | 1330 | module_param(xmas, bool, S_IRUGO | S_IWUSR); |
| 1241 | MODULE_PARM_DESC(xmas, "xmas color enabled or not"); | 1331 | MODULE_PARM_DESC(xmas, "Xmas colors enabled or not"); |
| 1242 | 1332 | ||
| 1243 | module_param(boost, int, S_IRUGO | S_IWUSR); | 1333 | module_param(boost, int, S_IRUGO | S_IWUSR); |
| 1244 | MODULE_PARM_DESC(boost, "overclock boost percent 100 to 500"); | 1334 | MODULE_PARM_DESC(boost, "Card overclock boost (in percent 100-500)"); |
| 1245 | 1335 | ||
| 1246 | module_param(clockmode, int, S_IRUGO | S_IWUSR); | 1336 | module_param(clockmode, int, S_IRUGO | S_IWUSR); |
| 1247 | MODULE_PARM_DESC(clockmode, "1=3Mhz579,2=3Mhz680,3=6Mhz"); | 1337 | MODULE_PARM_DESC(clockmode, "Card clock mode (1=3.579 MHz, 2=3.680 MHz, " |
| 1338 | "3=6 Mhz)"); | ||
| 1248 | 1339 | ||
| 1249 | module_param(cdmode, int, S_IRUGO | S_IWUSR); | 1340 | module_param(cdmode, int, S_IRUGO | S_IWUSR); |
| 1250 | MODULE_PARM_DESC(cdmode, "Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, " | 1341 | MODULE_PARM_DESC(cdmode, "Card detect mode (0=none, 1=CD, 2=!CD, 3=DSR, " |
| 1251 | "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING"); | 1342 | "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING)"); |
| 1343 | |||
| 1344 | module_param(vcc_default, int, S_IRUGO | S_IWUSR); | ||
| 1345 | MODULE_PARM_DESC(vcc_default, "Set default VCC (either 3 for 3.3V or 5 " | ||
| 1346 | "for 5V). Default to 5."); | ||
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c index b66b71ccd12b..99bd00f5188a 100644 --- a/drivers/usb/serial/moto_modem.c +++ b/drivers/usb/serial/moto_modem.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
| 9 | * | 9 | * |
| 10 | * {sigh} | 10 | * {sigh} |
| 11 | * Mororola should be using the CDC ACM USB spec, but instead | 11 | * Motorola should be using the CDC ACM USB spec, but instead |
| 12 | * they try to just "do their own thing"... This driver should handle a | 12 | * they try to just "do their own thing"... This driver should handle a |
| 13 | * few phones in which a basic "dumb serial connection" is needed to be | 13 | * few phones in which a basic "dumb serial connection" is needed to be |
| 14 | * able to get a connection through to them. | 14 | * able to get a connection through to them. |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index fe47051dbef2..f66e39883218 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -291,6 +291,7 @@ static int option_resume(struct usb_serial *serial); | |||
| 291 | 291 | ||
| 292 | #define TELIT_VENDOR_ID 0x1bc7 | 292 | #define TELIT_VENDOR_ID 0x1bc7 |
| 293 | #define TELIT_PRODUCT_UC864E 0x1003 | 293 | #define TELIT_PRODUCT_UC864E 0x1003 |
| 294 | #define TELIT_PRODUCT_UC864G 0x1004 | ||
| 294 | 295 | ||
| 295 | /* ZTE PRODUCTS */ | 296 | /* ZTE PRODUCTS */ |
| 296 | #define ZTE_VENDOR_ID 0x19d2 | 297 | #define ZTE_VENDOR_ID 0x19d2 |
| @@ -299,6 +300,7 @@ static int option_resume(struct usb_serial *serial); | |||
| 299 | #define ZTE_PRODUCT_MF626 0x0031 | 300 | #define ZTE_PRODUCT_MF626 0x0031 |
| 300 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | 301 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe |
| 301 | #define ZTE_PRODUCT_AC8710 0xfff1 | 302 | #define ZTE_PRODUCT_AC8710 0xfff1 |
| 303 | #define ZTE_PRODUCT_AC2726 0xfff5 | ||
| 302 | 304 | ||
| 303 | #define BENQ_VENDOR_ID 0x04a5 | 305 | #define BENQ_VENDOR_ID 0x04a5 |
| 304 | #define BENQ_PRODUCT_H10 0x4068 | 306 | #define BENQ_PRODUCT_H10 0x4068 |
| @@ -502,6 +504,7 @@ static struct usb_device_id option_ids[] = { | |||
| 502 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 504 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
| 503 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 505 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
| 504 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 506 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
| 507 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, | ||
| 505 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 508 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
| 506 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, | 509 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, |
| 507 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, | 510 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, |
| @@ -571,6 +574,7 @@ static struct usb_device_id option_ids[] = { | |||
| 571 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | 574 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, |
| 572 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | 575 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
| 573 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | 576 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, |
| 577 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
| 574 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 578 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
| 575 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 579 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
| 576 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 580 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
| @@ -592,6 +596,7 @@ static struct usb_driver option_driver = { | |||
| 592 | #ifdef CONFIG_PM | 596 | #ifdef CONFIG_PM |
| 593 | .suspend = usb_serial_suspend, | 597 | .suspend = usb_serial_suspend, |
| 594 | .resume = usb_serial_resume, | 598 | .resume = usb_serial_resume, |
| 599 | .supports_autosuspend = 1, | ||
| 595 | #endif | 600 | #endif |
| 596 | .id_table = option_ids, | 601 | .id_table = option_ids, |
| 597 | .no_dynamic_id = 1, | 602 | .no_dynamic_id = 1, |
| @@ -639,6 +644,12 @@ static int debug; | |||
| 639 | #define IN_BUFLEN 4096 | 644 | #define IN_BUFLEN 4096 |
| 640 | #define OUT_BUFLEN 4096 | 645 | #define OUT_BUFLEN 4096 |
| 641 | 646 | ||
| 647 | struct option_intf_private { | ||
| 648 | spinlock_t susp_lock; | ||
| 649 | unsigned int suspended:1; | ||
| 650 | int in_flight; | ||
| 651 | }; | ||
| 652 | |||
| 642 | struct option_port_private { | 653 | struct option_port_private { |
| 643 | /* Input endpoints and buffer for this port */ | 654 | /* Input endpoints and buffer for this port */ |
| 644 | struct urb *in_urbs[N_IN_URB]; | 655 | struct urb *in_urbs[N_IN_URB]; |
| @@ -647,6 +658,8 @@ struct option_port_private { | |||
| 647 | struct urb *out_urbs[N_OUT_URB]; | 658 | struct urb *out_urbs[N_OUT_URB]; |
| 648 | u8 *out_buffer[N_OUT_URB]; | 659 | u8 *out_buffer[N_OUT_URB]; |
| 649 | unsigned long out_busy; /* Bit vector of URBs in use */ | 660 | unsigned long out_busy; /* Bit vector of URBs in use */ |
| 661 | int opened; | ||
| 662 | struct usb_anchor delayed; | ||
| 650 | 663 | ||
| 651 | /* Settings for the port */ | 664 | /* Settings for the port */ |
| 652 | int rts_state; /* Handshaking pins (outputs) */ | 665 | int rts_state; /* Handshaking pins (outputs) */ |
| @@ -693,12 +706,17 @@ module_exit(option_exit); | |||
| 693 | static int option_probe(struct usb_serial *serial, | 706 | static int option_probe(struct usb_serial *serial, |
| 694 | const struct usb_device_id *id) | 707 | const struct usb_device_id *id) |
| 695 | { | 708 | { |
| 709 | struct option_intf_private *data; | ||
| 696 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | 710 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ |
| 697 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | 711 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && |
| 698 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | 712 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && |
| 699 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) | 713 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) |
| 700 | return -ENODEV; | 714 | return -ENODEV; |
| 701 | 715 | ||
| 716 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); | ||
| 717 | if (!data) | ||
| 718 | return -ENOMEM; | ||
| 719 | spin_lock_init(&data->susp_lock); | ||
| 702 | return 0; | 720 | return 0; |
| 703 | } | 721 | } |
| 704 | 722 | ||
| @@ -755,12 +773,15 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 755 | const unsigned char *buf, int count) | 773 | const unsigned char *buf, int count) |
| 756 | { | 774 | { |
| 757 | struct option_port_private *portdata; | 775 | struct option_port_private *portdata; |
| 776 | struct option_intf_private *intfdata; | ||
| 758 | int i; | 777 | int i; |
| 759 | int left, todo; | 778 | int left, todo; |
| 760 | struct urb *this_urb = NULL; /* spurious */ | 779 | struct urb *this_urb = NULL; /* spurious */ |
| 761 | int err; | 780 | int err; |
| 781 | unsigned long flags; | ||
| 762 | 782 | ||
| 763 | portdata = usb_get_serial_port_data(port); | 783 | portdata = usb_get_serial_port_data(port); |
| 784 | intfdata = port->serial->private; | ||
| 764 | 785 | ||
| 765 | dbg("%s: write (%d chars)", __func__, count); | 786 | dbg("%s: write (%d chars)", __func__, count); |
| 766 | 787 | ||
| @@ -782,17 +803,33 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 782 | dbg("%s: endpoint %d buf %d", __func__, | 803 | dbg("%s: endpoint %d buf %d", __func__, |
| 783 | usb_pipeendpoint(this_urb->pipe), i); | 804 | usb_pipeendpoint(this_urb->pipe), i); |
| 784 | 805 | ||
| 806 | err = usb_autopm_get_interface_async(port->serial->interface); | ||
| 807 | if (err < 0) | ||
| 808 | break; | ||
| 809 | |||
| 785 | /* send the data */ | 810 | /* send the data */ |
| 786 | memcpy(this_urb->transfer_buffer, buf, todo); | 811 | memcpy(this_urb->transfer_buffer, buf, todo); |
| 787 | this_urb->transfer_buffer_length = todo; | 812 | this_urb->transfer_buffer_length = todo; |
| 788 | 813 | ||
| 789 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 814 | spin_lock_irqsave(&intfdata->susp_lock, flags); |
| 790 | if (err) { | 815 | if (intfdata->suspended) { |
| 791 | dbg("usb_submit_urb %p (write bulk) failed " | 816 | usb_anchor_urb(this_urb, &portdata->delayed); |
| 792 | "(%d)", this_urb, err); | 817 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); |
| 793 | clear_bit(i, &portdata->out_busy); | 818 | } else { |
| 794 | continue; | 819 | intfdata->in_flight++; |
| 820 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
| 821 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
| 822 | if (err) { | ||
| 823 | dbg("usb_submit_urb %p (write bulk) failed " | ||
| 824 | "(%d)", this_urb, err); | ||
| 825 | clear_bit(i, &portdata->out_busy); | ||
| 826 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
| 827 | intfdata->in_flight--; | ||
| 828 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
| 829 | continue; | ||
| 830 | } | ||
| 795 | } | 831 | } |
| 832 | |||
| 796 | portdata->tx_start_time[i] = jiffies; | 833 | portdata->tx_start_time[i] = jiffies; |
| 797 | buf += todo; | 834 | buf += todo; |
| 798 | left -= todo; | 835 | left -= todo; |
| @@ -836,7 +873,10 @@ static void option_indat_callback(struct urb *urb) | |||
| 836 | if (err) | 873 | if (err) |
| 837 | printk(KERN_ERR "%s: resubmit read urb failed. " | 874 | printk(KERN_ERR "%s: resubmit read urb failed. " |
| 838 | "(%d)", __func__, err); | 875 | "(%d)", __func__, err); |
| 876 | else | ||
| 877 | usb_mark_last_busy(port->serial->dev); | ||
| 839 | } | 878 | } |
| 879 | |||
| 840 | } | 880 | } |
| 841 | return; | 881 | return; |
| 842 | } | 882 | } |
| @@ -845,15 +885,21 @@ static void option_outdat_callback(struct urb *urb) | |||
| 845 | { | 885 | { |
| 846 | struct usb_serial_port *port; | 886 | struct usb_serial_port *port; |
| 847 | struct option_port_private *portdata; | 887 | struct option_port_private *portdata; |
| 888 | struct option_intf_private *intfdata; | ||
| 848 | int i; | 889 | int i; |
| 849 | 890 | ||
| 850 | dbg("%s", __func__); | 891 | dbg("%s", __func__); |
| 851 | 892 | ||
| 852 | port = urb->context; | 893 | port = urb->context; |
| 894 | intfdata = port->serial->private; | ||
| 853 | 895 | ||
| 854 | usb_serial_port_softint(port); | 896 | usb_serial_port_softint(port); |
| 855 | 897 | usb_autopm_put_interface_async(port->serial->interface); | |
| 856 | portdata = usb_get_serial_port_data(port); | 898 | portdata = usb_get_serial_port_data(port); |
| 899 | spin_lock(&intfdata->susp_lock); | ||
| 900 | intfdata->in_flight--; | ||
| 901 | spin_unlock(&intfdata->susp_lock); | ||
| 902 | |||
| 857 | for (i = 0; i < N_OUT_URB; ++i) { | 903 | for (i = 0; i < N_OUT_URB; ++i) { |
| 858 | if (portdata->out_urbs[i] == urb) { | 904 | if (portdata->out_urbs[i] == urb) { |
| 859 | smp_mb__before_clear_bit(); | 905 | smp_mb__before_clear_bit(); |
| @@ -963,10 +1009,13 @@ static int option_chars_in_buffer(struct tty_struct *tty) | |||
| 963 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port) | 1009 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port) |
| 964 | { | 1010 | { |
| 965 | struct option_port_private *portdata; | 1011 | struct option_port_private *portdata; |
| 1012 | struct option_intf_private *intfdata; | ||
| 1013 | struct usb_serial *serial = port->serial; | ||
| 966 | int i, err; | 1014 | int i, err; |
| 967 | struct urb *urb; | 1015 | struct urb *urb; |
| 968 | 1016 | ||
| 969 | portdata = usb_get_serial_port_data(port); | 1017 | portdata = usb_get_serial_port_data(port); |
| 1018 | intfdata = serial->private; | ||
| 970 | 1019 | ||
| 971 | dbg("%s", __func__); | 1020 | dbg("%s", __func__); |
| 972 | 1021 | ||
| @@ -985,6 +1034,12 @@ static int option_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 985 | 1034 | ||
| 986 | option_send_setup(port); | 1035 | option_send_setup(port); |
| 987 | 1036 | ||
| 1037 | serial->interface->needs_remote_wakeup = 1; | ||
| 1038 | spin_lock_irq(&intfdata->susp_lock); | ||
| 1039 | portdata->opened = 1; | ||
| 1040 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1041 | usb_autopm_put_interface(serial->interface); | ||
| 1042 | |||
| 988 | return 0; | 1043 | return 0; |
| 989 | } | 1044 | } |
| 990 | 1045 | ||
| @@ -1009,16 +1064,23 @@ static void option_close(struct usb_serial_port *port) | |||
| 1009 | int i; | 1064 | int i; |
| 1010 | struct usb_serial *serial = port->serial; | 1065 | struct usb_serial *serial = port->serial; |
| 1011 | struct option_port_private *portdata; | 1066 | struct option_port_private *portdata; |
| 1067 | struct option_intf_private *intfdata = port->serial->private; | ||
| 1012 | 1068 | ||
| 1013 | dbg("%s", __func__); | 1069 | dbg("%s", __func__); |
| 1014 | portdata = usb_get_serial_port_data(port); | 1070 | portdata = usb_get_serial_port_data(port); |
| 1015 | 1071 | ||
| 1016 | if (serial->dev) { | 1072 | if (serial->dev) { |
| 1017 | /* Stop reading/writing urbs */ | 1073 | /* Stop reading/writing urbs */ |
| 1074 | spin_lock_irq(&intfdata->susp_lock); | ||
| 1075 | portdata->opened = 0; | ||
| 1076 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1077 | |||
| 1018 | for (i = 0; i < N_IN_URB; i++) | 1078 | for (i = 0; i < N_IN_URB; i++) |
| 1019 | usb_kill_urb(portdata->in_urbs[i]); | 1079 | usb_kill_urb(portdata->in_urbs[i]); |
| 1020 | for (i = 0; i < N_OUT_URB; i++) | 1080 | for (i = 0; i < N_OUT_URB; i++) |
| 1021 | usb_kill_urb(portdata->out_urbs[i]); | 1081 | usb_kill_urb(portdata->out_urbs[i]); |
| 1082 | usb_autopm_get_interface(serial->interface); | ||
| 1083 | serial->interface->needs_remote_wakeup = 0; | ||
| 1022 | } | 1084 | } |
| 1023 | } | 1085 | } |
| 1024 | 1086 | ||
| @@ -1123,6 +1185,7 @@ static int option_startup(struct usb_serial *serial) | |||
| 1123 | __func__, i); | 1185 | __func__, i); |
| 1124 | return 1; | 1186 | return 1; |
| 1125 | } | 1187 | } |
| 1188 | init_usb_anchor(&portdata->delayed); | ||
| 1126 | 1189 | ||
| 1127 | for (j = 0; j < N_IN_URB; j++) { | 1190 | for (j = 0; j < N_IN_URB; j++) { |
| 1128 | buffer = (u8 *)__get_free_page(GFP_KERNEL); | 1191 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
| @@ -1225,18 +1288,52 @@ static void option_release(struct usb_serial *serial) | |||
| 1225 | #ifdef CONFIG_PM | 1288 | #ifdef CONFIG_PM |
| 1226 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | 1289 | static int option_suspend(struct usb_serial *serial, pm_message_t message) |
| 1227 | { | 1290 | { |
| 1291 | struct option_intf_private *intfdata = serial->private; | ||
| 1292 | int b; | ||
| 1293 | |||
| 1228 | dbg("%s entered", __func__); | 1294 | dbg("%s entered", __func__); |
| 1295 | |||
| 1296 | if (serial->dev->auto_pm) { | ||
| 1297 | spin_lock_irq(&intfdata->susp_lock); | ||
| 1298 | b = intfdata->in_flight; | ||
| 1299 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1300 | |||
| 1301 | if (b) | ||
| 1302 | return -EBUSY; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | spin_lock_irq(&intfdata->susp_lock); | ||
| 1306 | intfdata->suspended = 1; | ||
| 1307 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1229 | stop_read_write_urbs(serial); | 1308 | stop_read_write_urbs(serial); |
| 1230 | 1309 | ||
| 1231 | return 0; | 1310 | return 0; |
| 1232 | } | 1311 | } |
| 1233 | 1312 | ||
| 1313 | static void play_delayed(struct usb_serial_port *port) | ||
| 1314 | { | ||
| 1315 | struct option_intf_private *data; | ||
| 1316 | struct option_port_private *portdata; | ||
| 1317 | struct urb *urb; | ||
| 1318 | int err; | ||
| 1319 | |||
| 1320 | portdata = usb_get_serial_port_data(port); | ||
| 1321 | data = port->serial->private; | ||
| 1322 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | ||
| 1323 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 1324 | if (!err) | ||
| 1325 | data->in_flight++; | ||
| 1326 | } | ||
| 1327 | } | ||
| 1328 | |||
| 1234 | static int option_resume(struct usb_serial *serial) | 1329 | static int option_resume(struct usb_serial *serial) |
| 1235 | { | 1330 | { |
| 1236 | int err, i, j; | 1331 | int i, j; |
| 1237 | struct usb_serial_port *port; | 1332 | struct usb_serial_port *port; |
| 1238 | struct urb *urb; | 1333 | struct option_intf_private *intfdata = serial->private; |
| 1239 | struct option_port_private *portdata; | 1334 | struct option_port_private *portdata; |
| 1335 | struct urb *urb; | ||
| 1336 | int err = 0; | ||
| 1240 | 1337 | ||
| 1241 | dbg("%s entered", __func__); | 1338 | dbg("%s entered", __func__); |
| 1242 | /* get the interrupt URBs resubmitted unconditionally */ | 1339 | /* get the interrupt URBs resubmitted unconditionally */ |
| @@ -1251,7 +1348,7 @@ static int option_resume(struct usb_serial *serial) | |||
| 1251 | if (err < 0) { | 1348 | if (err < 0) { |
| 1252 | err("%s: Error %d for interrupt URB of port%d", | 1349 | err("%s: Error %d for interrupt URB of port%d", |
| 1253 | __func__, err, i); | 1350 | __func__, err, i); |
| 1254 | return err; | 1351 | goto err_out; |
| 1255 | } | 1352 | } |
| 1256 | } | 1353 | } |
| 1257 | 1354 | ||
| @@ -1259,27 +1356,32 @@ static int option_resume(struct usb_serial *serial) | |||
| 1259 | /* walk all ports */ | 1356 | /* walk all ports */ |
| 1260 | port = serial->port[i]; | 1357 | port = serial->port[i]; |
| 1261 | portdata = usb_get_serial_port_data(port); | 1358 | portdata = usb_get_serial_port_data(port); |
| 1262 | mutex_lock(&port->mutex); | ||
| 1263 | 1359 | ||
| 1264 | /* skip closed ports */ | 1360 | /* skip closed ports */ |
| 1265 | if (!port->port.count) { | 1361 | spin_lock_irq(&intfdata->susp_lock); |
| 1266 | mutex_unlock(&port->mutex); | 1362 | if (!portdata->opened) { |
| 1363 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1267 | continue; | 1364 | continue; |
| 1268 | } | 1365 | } |
| 1269 | 1366 | ||
| 1270 | for (j = 0; j < N_IN_URB; j++) { | 1367 | for (j = 0; j < N_IN_URB; j++) { |
| 1271 | urb = portdata->in_urbs[j]; | 1368 | urb = portdata->in_urbs[j]; |
| 1272 | err = usb_submit_urb(urb, GFP_NOIO); | 1369 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 1273 | if (err < 0) { | 1370 | if (err < 0) { |
| 1274 | mutex_unlock(&port->mutex); | ||
| 1275 | err("%s: Error %d for bulk URB %d", | 1371 | err("%s: Error %d for bulk URB %d", |
| 1276 | __func__, err, i); | 1372 | __func__, err, i); |
| 1277 | return err; | 1373 | spin_unlock_irq(&intfdata->susp_lock); |
| 1374 | goto err_out; | ||
| 1278 | } | 1375 | } |
| 1279 | } | 1376 | } |
| 1280 | mutex_unlock(&port->mutex); | 1377 | play_delayed(port); |
| 1378 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1281 | } | 1379 | } |
| 1282 | return 0; | 1380 | spin_lock_irq(&intfdata->susp_lock); |
| 1381 | intfdata->suspended = 0; | ||
| 1382 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 1383 | err_out: | ||
| 1384 | return err; | ||
| 1283 | } | 1385 | } |
| 1284 | #endif | 1386 | #endif |
| 1285 | 1387 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a63ea99936f7..1128e01525b1 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -96,6 +96,7 @@ static struct usb_device_id id_table [] = { | |||
| 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
| 97 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | 97 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, |
| 98 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | 98 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
| 99 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | ||
| 99 | { } /* Terminating entry */ | 100 | { } /* Terminating entry */ |
| 100 | }; | 101 | }; |
| 101 | 102 | ||
| @@ -527,6 +528,12 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 527 | int baud; | 528 | int baud; |
| 528 | int i; | 529 | int i; |
| 529 | u8 control; | 530 | u8 control; |
| 531 | const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, | ||
| 532 | 4800, 7200, 9600, 14400, 19200, 28800, 38400, | ||
| 533 | 57600, 115200, 230400, 460800, 614400, | ||
| 534 | 921600, 1228800, 2457600, 3000000, 6000000 }; | ||
| 535 | int baud_floor, baud_ceil; | ||
| 536 | int k; | ||
| 530 | 537 | ||
| 531 | dbg("%s - port %d", __func__, port->number); | 538 | dbg("%s - port %d", __func__, port->number); |
| 532 | 539 | ||
| @@ -572,9 +579,39 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 572 | dbg("%s - data bits = %d", __func__, buf[6]); | 579 | dbg("%s - data bits = %d", __func__, buf[6]); |
| 573 | } | 580 | } |
| 574 | 581 | ||
| 582 | /* For reference buf[0]:buf[3] baud rate value */ | ||
| 583 | /* NOTE: Only the values defined in baud_sup are supported ! | ||
| 584 | * => if unsupported values are set, the PL2303 seems to use | ||
| 585 | * 9600 baud (at least my PL2303X always does) | ||
| 586 | */ | ||
| 575 | baud = tty_get_baud_rate(tty); | 587 | baud = tty_get_baud_rate(tty); |
| 576 | dbg("%s - baud = %d", __func__, baud); | 588 | dbg("%s - baud requested = %d", __func__, baud); |
| 577 | if (baud) { | 589 | if (baud) { |
| 590 | /* Set baudrate to nearest supported value */ | ||
| 591 | for (k=0; k<ARRAY_SIZE(baud_sup); k++) { | ||
| 592 | if (baud_sup[k] / baud) { | ||
| 593 | baud_ceil = baud_sup[k]; | ||
| 594 | if (k==0) { | ||
| 595 | baud = baud_ceil; | ||
| 596 | } else { | ||
| 597 | baud_floor = baud_sup[k-1]; | ||
| 598 | if ((baud_ceil % baud) | ||
| 599 | > (baud % baud_floor)) | ||
| 600 | baud = baud_floor; | ||
| 601 | else | ||
| 602 | baud = baud_ceil; | ||
| 603 | } | ||
| 604 | break; | ||
| 605 | } | ||
| 606 | } | ||
| 607 | if (baud > 1228800) { | ||
| 608 | /* type_0, type_1 only support up to 1228800 baud */ | ||
| 609 | if (priv->type != HX) | ||
| 610 | baud = 1228800; | ||
| 611 | else if (baud > 6000000) | ||
| 612 | baud = 6000000; | ||
| 613 | } | ||
| 614 | dbg("%s - baud set = %d", __func__, baud); | ||
| 578 | buf[0] = baud & 0xff; | 615 | buf[0] = baud & 0xff; |
| 579 | buf[1] = (baud >> 8) & 0xff; | 616 | buf[1] = (baud >> 8) & 0xff; |
| 580 | buf[2] = (baud >> 16) & 0xff; | 617 | buf[2] = (baud >> 16) & 0xff; |
| @@ -585,8 +622,16 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 585 | /* For reference buf[4]=1 is 1.5 stop bits */ | 622 | /* For reference buf[4]=1 is 1.5 stop bits */ |
| 586 | /* For reference buf[4]=2 is 2 stop bits */ | 623 | /* For reference buf[4]=2 is 2 stop bits */ |
| 587 | if (cflag & CSTOPB) { | 624 | if (cflag & CSTOPB) { |
| 588 | buf[4] = 2; | 625 | /* NOTE: Comply with "real" UARTs / RS232: |
| 589 | dbg("%s - stop bits = 2", __func__); | 626 | * use 1.5 instead of 2 stop bits with 5 data bits |
| 627 | */ | ||
| 628 | if ((cflag & CSIZE) == CS5) { | ||
| 629 | buf[4] = 1; | ||
| 630 | dbg("%s - stop bits = 1.5", __func__); | ||
| 631 | } else { | ||
| 632 | buf[4] = 2; | ||
| 633 | dbg("%s - stop bits = 2", __func__); | ||
| 634 | } | ||
| 590 | } else { | 635 | } else { |
| 591 | buf[4] = 0; | 636 | buf[4] = 0; |
| 592 | dbg("%s - stop bits = 1", __func__); | 637 | dbg("%s - stop bits = 1", __func__); |
| @@ -599,11 +644,21 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 599 | /* For reference buf[5]=3 is mark parity */ | 644 | /* For reference buf[5]=3 is mark parity */ |
| 600 | /* For reference buf[5]=4 is space parity */ | 645 | /* For reference buf[5]=4 is space parity */ |
| 601 | if (cflag & PARODD) { | 646 | if (cflag & PARODD) { |
| 602 | buf[5] = 1; | 647 | if (cflag & CMSPAR) { |
| 603 | dbg("%s - parity = odd", __func__); | 648 | buf[5] = 3; |
| 649 | dbg("%s - parity = mark", __func__); | ||
| 650 | } else { | ||
| 651 | buf[5] = 1; | ||
| 652 | dbg("%s - parity = odd", __func__); | ||
| 653 | } | ||
| 604 | } else { | 654 | } else { |
| 605 | buf[5] = 2; | 655 | if (cflag & CMSPAR) { |
| 606 | dbg("%s - parity = even", __func__); | 656 | buf[5] = 4; |
| 657 | dbg("%s - parity = space", __func__); | ||
| 658 | } else { | ||
| 659 | buf[5] = 2; | ||
| 660 | dbg("%s - parity = even", __func__); | ||
| 661 | } | ||
| 607 | } | 662 | } |
| 608 | } else { | 663 | } else { |
| 609 | buf[5] = 0; | 664 | buf[5] = 0; |
| @@ -647,7 +702,7 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 647 | pl2303_vendor_write(0x0, 0x0, serial); | 702 | pl2303_vendor_write(0x0, 0x0, serial); |
| 648 | } | 703 | } |
| 649 | 704 | ||
| 650 | /* FIXME: Need to read back resulting baud rate */ | 705 | /* Save resulting baud rate */ |
| 651 | if (baud) | 706 | if (baud) |
| 652 | tty_encode_baud_rate(tty, baud, baud); | 707 | tty_encode_baud_rate(tty, baud, baud); |
| 653 | 708 | ||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index ee9505e1dd92..d640dc951568 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
| @@ -130,3 +130,7 @@ | |||
| 130 | /* Sony, USB data cable for CMD-Jxx mobile phones */ | 130 | /* Sony, USB data cable for CMD-Jxx mobile phones */ |
| 131 | #define SONY_VENDOR_ID 0x054c | 131 | #define SONY_VENDOR_ID 0x054c |
| 132 | #define SONY_QN3USB_PRODUCT_ID 0x0437 | 132 | #define SONY_QN3USB_PRODUCT_ID 0x0437 |
| 133 | |||
| 134 | /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ | ||
| 135 | #define SANWA_VENDOR_ID 0x11ad | ||
| 136 | #define SANWA_PRODUCT_ID 0x0001 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 55391bbe1230..68fa0e43b781 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -51,6 +51,12 @@ struct sierra_iface_info { | |||
| 51 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | 51 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | struct sierra_intf_private { | ||
| 55 | spinlock_t susp_lock; | ||
| 56 | unsigned int suspended:1; | ||
| 57 | int in_flight; | ||
| 58 | }; | ||
| 59 | |||
| 54 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | 60 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) |
| 55 | { | 61 | { |
| 56 | int result; | 62 | int result; |
| @@ -144,6 +150,7 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 144 | { | 150 | { |
| 145 | int result = 0; | 151 | int result = 0; |
| 146 | struct usb_device *udev; | 152 | struct usb_device *udev; |
| 153 | struct sierra_intf_private *data; | ||
| 147 | u8 ifnum; | 154 | u8 ifnum; |
| 148 | 155 | ||
| 149 | udev = serial->dev; | 156 | udev = serial->dev; |
| @@ -171,6 +178,11 @@ static int sierra_probe(struct usb_serial *serial, | |||
| 171 | return -ENODEV; | 178 | return -ENODEV; |
| 172 | } | 179 | } |
| 173 | 180 | ||
| 181 | data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); | ||
| 182 | if (!data) | ||
| 183 | return -ENOMEM; | ||
| 184 | spin_lock_init(&data->susp_lock); | ||
| 185 | |||
| 174 | return result; | 186 | return result; |
| 175 | } | 187 | } |
| 176 | 188 | ||
| @@ -261,13 +273,18 @@ static struct usb_driver sierra_driver = { | |||
| 261 | .name = "sierra", | 273 | .name = "sierra", |
| 262 | .probe = usb_serial_probe, | 274 | .probe = usb_serial_probe, |
| 263 | .disconnect = usb_serial_disconnect, | 275 | .disconnect = usb_serial_disconnect, |
| 276 | .suspend = usb_serial_suspend, | ||
| 277 | .resume = usb_serial_resume, | ||
| 264 | .id_table = id_table, | 278 | .id_table = id_table, |
| 265 | .no_dynamic_id = 1, | 279 | .no_dynamic_id = 1, |
| 280 | .supports_autosuspend = 1, | ||
| 266 | }; | 281 | }; |
| 267 | 282 | ||
| 268 | struct sierra_port_private { | 283 | struct sierra_port_private { |
| 269 | spinlock_t lock; /* lock the structure */ | 284 | spinlock_t lock; /* lock the structure */ |
| 270 | int outstanding_urbs; /* number of out urbs in flight */ | 285 | int outstanding_urbs; /* number of out urbs in flight */ |
| 286 | struct usb_anchor active; | ||
| 287 | struct usb_anchor delayed; | ||
| 271 | 288 | ||
| 272 | /* Input endpoints and buffers for this port */ | 289 | /* Input endpoints and buffers for this port */ |
| 273 | struct urb *in_urbs[N_IN_URB]; | 290 | struct urb *in_urbs[N_IN_URB]; |
| @@ -279,6 +296,8 @@ struct sierra_port_private { | |||
| 279 | int dsr_state; | 296 | int dsr_state; |
| 280 | int dcd_state; | 297 | int dcd_state; |
| 281 | int ri_state; | 298 | int ri_state; |
| 299 | |||
| 300 | unsigned int opened:1; | ||
| 282 | }; | 301 | }; |
| 283 | 302 | ||
| 284 | static int sierra_send_setup(struct usb_serial_port *port) | 303 | static int sierra_send_setup(struct usb_serial_port *port) |
| @@ -390,21 +409,25 @@ static void sierra_outdat_callback(struct urb *urb) | |||
| 390 | { | 409 | { |
| 391 | struct usb_serial_port *port = urb->context; | 410 | struct usb_serial_port *port = urb->context; |
| 392 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 411 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
| 412 | struct sierra_intf_private *intfdata; | ||
| 393 | int status = urb->status; | 413 | int status = urb->status; |
| 394 | unsigned long flags; | ||
| 395 | 414 | ||
| 396 | dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); | 415 | dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); |
| 416 | intfdata = port->serial->private; | ||
| 397 | 417 | ||
| 398 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 418 | /* free up the transfer buffer, as usb_free_urb() does not do this */ |
| 399 | kfree(urb->transfer_buffer); | 419 | kfree(urb->transfer_buffer); |
| 400 | 420 | usb_autopm_put_interface_async(port->serial->interface); | |
| 401 | if (status) | 421 | if (status) |
| 402 | dev_dbg(&port->dev, "%s - nonzero write bulk status " | 422 | dev_dbg(&port->dev, "%s - nonzero write bulk status " |
| 403 | "received: %d\n", __func__, status); | 423 | "received: %d\n", __func__, status); |
| 404 | 424 | ||
| 405 | spin_lock_irqsave(&portdata->lock, flags); | 425 | spin_lock(&portdata->lock); |
| 406 | --portdata->outstanding_urbs; | 426 | --portdata->outstanding_urbs; |
| 407 | spin_unlock_irqrestore(&portdata->lock, flags); | 427 | spin_unlock(&portdata->lock); |
| 428 | spin_lock(&intfdata->susp_lock); | ||
| 429 | --intfdata->in_flight; | ||
| 430 | spin_unlock(&intfdata->susp_lock); | ||
| 408 | 431 | ||
| 409 | usb_serial_port_softint(port); | 432 | usb_serial_port_softint(port); |
| 410 | } | 433 | } |
| @@ -414,6 +437,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 414 | const unsigned char *buf, int count) | 437 | const unsigned char *buf, int count) |
| 415 | { | 438 | { |
| 416 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 439 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
| 440 | struct sierra_intf_private *intfdata; | ||
| 417 | struct usb_serial *serial = port->serial; | 441 | struct usb_serial *serial = port->serial; |
| 418 | unsigned long flags; | 442 | unsigned long flags; |
| 419 | unsigned char *buffer; | 443 | unsigned char *buffer; |
| @@ -426,9 +450,9 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 426 | return 0; | 450 | return 0; |
| 427 | 451 | ||
| 428 | portdata = usb_get_serial_port_data(port); | 452 | portdata = usb_get_serial_port_data(port); |
| 453 | intfdata = serial->private; | ||
| 429 | 454 | ||
| 430 | dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); | 455 | dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); |
| 431 | |||
| 432 | spin_lock_irqsave(&portdata->lock, flags); | 456 | spin_lock_irqsave(&portdata->lock, flags); |
| 433 | dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, | 457 | dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, |
| 434 | portdata->outstanding_urbs); | 458 | portdata->outstanding_urbs); |
| @@ -442,6 +466,14 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 442 | portdata->outstanding_urbs); | 466 | portdata->outstanding_urbs); |
| 443 | spin_unlock_irqrestore(&portdata->lock, flags); | 467 | spin_unlock_irqrestore(&portdata->lock, flags); |
| 444 | 468 | ||
| 469 | retval = usb_autopm_get_interface_async(serial->interface); | ||
| 470 | if (retval < 0) { | ||
| 471 | spin_lock_irqsave(&portdata->lock, flags); | ||
| 472 | portdata->outstanding_urbs--; | ||
| 473 | spin_unlock_irqrestore(&portdata->lock, flags); | ||
| 474 | goto error_simple; | ||
| 475 | } | ||
| 476 | |||
| 445 | buffer = kmalloc(writesize, GFP_ATOMIC); | 477 | buffer = kmalloc(writesize, GFP_ATOMIC); |
| 446 | if (!buffer) { | 478 | if (!buffer) { |
| 447 | dev_err(&port->dev, "out of memory\n"); | 479 | dev_err(&port->dev, "out of memory\n"); |
| @@ -468,14 +500,29 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 468 | /* Handle the need to send a zero length packet */ | 500 | /* Handle the need to send a zero length packet */ |
| 469 | urb->transfer_flags |= URB_ZERO_PACKET; | 501 | urb->transfer_flags |= URB_ZERO_PACKET; |
| 470 | 502 | ||
| 503 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
| 504 | |||
| 505 | if (intfdata->suspended) { | ||
| 506 | usb_anchor_urb(urb, &portdata->delayed); | ||
| 507 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
| 508 | goto skip_power; | ||
| 509 | } else { | ||
| 510 | usb_anchor_urb(urb, &portdata->active); | ||
| 511 | } | ||
| 471 | /* send it down the pipe */ | 512 | /* send it down the pipe */ |
| 472 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 513 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| 473 | if (retval) { | 514 | if (retval) { |
| 515 | usb_unanchor_urb(urb); | ||
| 516 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
| 474 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " | 517 | dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " |
| 475 | "with status = %d\n", __func__, retval); | 518 | "with status = %d\n", __func__, retval); |
| 476 | goto error; | 519 | goto error; |
| 520 | } else { | ||
| 521 | intfdata->in_flight++; | ||
| 522 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
| 477 | } | 523 | } |
| 478 | 524 | ||
| 525 | skip_power: | ||
| 479 | /* we are done with this urb, so let the host driver | 526 | /* we are done with this urb, so let the host driver |
| 480 | * really free it when it is finished with it */ | 527 | * really free it when it is finished with it */ |
| 481 | usb_free_urb(urb); | 528 | usb_free_urb(urb); |
| @@ -491,6 +538,8 @@ error_no_buffer: | |||
| 491 | dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, | 538 | dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, |
| 492 | portdata->outstanding_urbs); | 539 | portdata->outstanding_urbs); |
| 493 | spin_unlock_irqrestore(&portdata->lock, flags); | 540 | spin_unlock_irqrestore(&portdata->lock, flags); |
| 541 | usb_autopm_put_interface_async(serial->interface); | ||
| 542 | error_simple: | ||
| 494 | return retval; | 543 | return retval; |
| 495 | } | 544 | } |
| 496 | 545 | ||
| @@ -530,6 +579,7 @@ static void sierra_indat_callback(struct urb *urb) | |||
| 530 | 579 | ||
| 531 | /* Resubmit urb so we continue receiving */ | 580 | /* Resubmit urb so we continue receiving */ |
| 532 | if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { | 581 | if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { |
| 582 | usb_mark_last_busy(port->serial->dev); | ||
| 533 | err = usb_submit_urb(urb, GFP_ATOMIC); | 583 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 534 | if (err) | 584 | if (err) |
| 535 | dev_err(&port->dev, "resubmit read urb failed." | 585 | dev_err(&port->dev, "resubmit read urb failed." |
| @@ -591,6 +641,7 @@ static void sierra_instat_callback(struct urb *urb) | |||
| 591 | 641 | ||
| 592 | /* Resubmit urb so we continue receiving IRQ data */ | 642 | /* Resubmit urb so we continue receiving IRQ data */ |
| 593 | if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) { | 643 | if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) { |
| 644 | usb_mark_last_busy(serial->dev); | ||
| 594 | urb->dev = serial->dev; | 645 | urb->dev = serial->dev; |
| 595 | err = usb_submit_urb(urb, GFP_ATOMIC); | 646 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 596 | if (err) | 647 | if (err) |
| @@ -711,6 +762,8 @@ static void sierra_close(struct usb_serial_port *port) | |||
| 711 | int i; | 762 | int i; |
| 712 | struct usb_serial *serial = port->serial; | 763 | struct usb_serial *serial = port->serial; |
| 713 | struct sierra_port_private *portdata; | 764 | struct sierra_port_private *portdata; |
| 765 | struct sierra_intf_private *intfdata = port->serial->private; | ||
| 766 | |||
| 714 | 767 | ||
| 715 | dev_dbg(&port->dev, "%s\n", __func__); | 768 | dev_dbg(&port->dev, "%s\n", __func__); |
| 716 | portdata = usb_get_serial_port_data(port); | 769 | portdata = usb_get_serial_port_data(port); |
| @@ -723,6 +776,10 @@ static void sierra_close(struct usb_serial_port *port) | |||
| 723 | if (!serial->disconnected) | 776 | if (!serial->disconnected) |
| 724 | sierra_send_setup(port); | 777 | sierra_send_setup(port); |
| 725 | mutex_unlock(&serial->disc_mutex); | 778 | mutex_unlock(&serial->disc_mutex); |
| 779 | spin_lock_irq(&intfdata->susp_lock); | ||
| 780 | portdata->opened = 0; | ||
| 781 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 782 | |||
| 726 | 783 | ||
| 727 | /* Stop reading urbs */ | 784 | /* Stop reading urbs */ |
| 728 | sierra_stop_rx_urbs(port); | 785 | sierra_stop_rx_urbs(port); |
| @@ -731,6 +788,8 @@ static void sierra_close(struct usb_serial_port *port) | |||
| 731 | sierra_release_urb(portdata->in_urbs[i]); | 788 | sierra_release_urb(portdata->in_urbs[i]); |
| 732 | portdata->in_urbs[i] = NULL; | 789 | portdata->in_urbs[i] = NULL; |
| 733 | } | 790 | } |
| 791 | usb_autopm_get_interface(serial->interface); | ||
| 792 | serial->interface->needs_remote_wakeup = 0; | ||
| 734 | } | 793 | } |
| 735 | } | 794 | } |
| 736 | 795 | ||
| @@ -738,6 +797,7 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 738 | { | 797 | { |
| 739 | struct sierra_port_private *portdata; | 798 | struct sierra_port_private *portdata; |
| 740 | struct usb_serial *serial = port->serial; | 799 | struct usb_serial *serial = port->serial; |
| 800 | struct sierra_intf_private *intfdata = serial->private; | ||
| 741 | int i; | 801 | int i; |
| 742 | int err; | 802 | int err; |
| 743 | int endpoint; | 803 | int endpoint; |
| @@ -771,6 +831,12 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 771 | } | 831 | } |
| 772 | sierra_send_setup(port); | 832 | sierra_send_setup(port); |
| 773 | 833 | ||
| 834 | serial->interface->needs_remote_wakeup = 1; | ||
| 835 | spin_lock_irq(&intfdata->susp_lock); | ||
| 836 | portdata->opened = 1; | ||
| 837 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 838 | usb_autopm_put_interface(serial->interface); | ||
| 839 | |||
| 774 | return 0; | 840 | return 0; |
| 775 | } | 841 | } |
| 776 | 842 | ||
| @@ -818,6 +884,8 @@ static int sierra_startup(struct usb_serial *serial) | |||
| 818 | return -ENOMEM; | 884 | return -ENOMEM; |
| 819 | } | 885 | } |
| 820 | spin_lock_init(&portdata->lock); | 886 | spin_lock_init(&portdata->lock); |
| 887 | init_usb_anchor(&portdata->active); | ||
| 888 | init_usb_anchor(&portdata->delayed); | ||
| 821 | /* Set the port private data pointer */ | 889 | /* Set the port private data pointer */ |
| 822 | usb_set_serial_port_data(port, portdata); | 890 | usb_set_serial_port_data(port, portdata); |
| 823 | } | 891 | } |
| @@ -844,6 +912,83 @@ static void sierra_release(struct usb_serial *serial) | |||
| 844 | } | 912 | } |
| 845 | } | 913 | } |
| 846 | 914 | ||
| 915 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
| 916 | { | ||
| 917 | int i, j; | ||
| 918 | struct usb_serial_port *port; | ||
| 919 | struct sierra_port_private *portdata; | ||
| 920 | |||
| 921 | /* Stop reading/writing urbs */ | ||
| 922 | for (i = 0; i < serial->num_ports; ++i) { | ||
| 923 | port = serial->port[i]; | ||
| 924 | portdata = usb_get_serial_port_data(port); | ||
| 925 | for (j = 0; j < N_IN_URB; j++) | ||
| 926 | usb_kill_urb(portdata->in_urbs[j]); | ||
| 927 | usb_kill_anchored_urbs(&portdata->active); | ||
| 928 | } | ||
| 929 | } | ||
| 930 | |||
| 931 | static int sierra_suspend(struct usb_serial *serial, pm_message_t message) | ||
| 932 | { | ||
| 933 | struct sierra_intf_private *intfdata; | ||
| 934 | int b; | ||
| 935 | |||
| 936 | if (serial->dev->auto_pm) { | ||
| 937 | intfdata = serial->private; | ||
| 938 | spin_lock_irq(&intfdata->susp_lock); | ||
| 939 | b = intfdata->in_flight; | ||
| 940 | |||
| 941 | if (b) { | ||
| 942 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 943 | return -EBUSY; | ||
| 944 | } else { | ||
| 945 | intfdata->suspended = 1; | ||
| 946 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 947 | } | ||
| 948 | } | ||
| 949 | stop_read_write_urbs(serial); | ||
| 950 | |||
| 951 | return 0; | ||
| 952 | } | ||
| 953 | |||
| 954 | static int sierra_resume(struct usb_serial *serial) | ||
| 955 | { | ||
| 956 | struct usb_serial_port *port; | ||
| 957 | struct sierra_intf_private *intfdata = serial->private; | ||
| 958 | struct sierra_port_private *portdata; | ||
| 959 | struct urb *urb; | ||
| 960 | int ec = 0; | ||
| 961 | int i, err; | ||
| 962 | |||
| 963 | spin_lock_irq(&intfdata->susp_lock); | ||
| 964 | for (i = 0; i < serial->num_ports; i++) { | ||
| 965 | port = serial->port[i]; | ||
| 966 | portdata = usb_get_serial_port_data(port); | ||
| 967 | |||
| 968 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | ||
| 969 | usb_anchor_urb(urb, &portdata->active); | ||
| 970 | intfdata->in_flight++; | ||
| 971 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 972 | if (err < 0) { | ||
| 973 | intfdata->in_flight--; | ||
| 974 | usb_unanchor_urb(urb); | ||
| 975 | usb_scuttle_anchored_urbs(&portdata->delayed); | ||
| 976 | break; | ||
| 977 | } | ||
| 978 | } | ||
| 979 | |||
| 980 | if (portdata->opened) { | ||
| 981 | err = sierra_submit_rx_urbs(port, GFP_ATOMIC); | ||
| 982 | if (err) | ||
| 983 | ec++; | ||
| 984 | } | ||
| 985 | } | ||
| 986 | intfdata->suspended = 0; | ||
| 987 | spin_unlock_irq(&intfdata->susp_lock); | ||
| 988 | |||
| 989 | return ec ? -EIO : 0; | ||
| 990 | } | ||
| 991 | |||
| 847 | static struct usb_serial_driver sierra_device = { | 992 | static struct usb_serial_driver sierra_device = { |
| 848 | .driver = { | 993 | .driver = { |
| 849 | .owner = THIS_MODULE, | 994 | .owner = THIS_MODULE, |
| @@ -864,6 +1009,8 @@ static struct usb_serial_driver sierra_device = { | |||
| 864 | .tiocmset = sierra_tiocmset, | 1009 | .tiocmset = sierra_tiocmset, |
| 865 | .attach = sierra_startup, | 1010 | .attach = sierra_startup, |
| 866 | .release = sierra_release, | 1011 | .release = sierra_release, |
| 1012 | .suspend = sierra_suspend, | ||
| 1013 | .resume = sierra_resume, | ||
| 867 | .read_int_callback = sierra_instat_callback, | 1014 | .read_int_callback = sierra_instat_callback, |
| 868 | }; | 1015 | }; |
| 869 | 1016 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 9d7ca4868d37..ff75a3589e7e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
| 36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
| 37 | #include <linux/usb/serial.h> | 37 | #include <linux/usb/serial.h> |
| 38 | #include <linux/kfifo.h> | ||
| 38 | #include "pl2303.h" | 39 | #include "pl2303.h" |
| 39 | 40 | ||
| 40 | /* | 41 | /* |
| @@ -292,8 +293,6 @@ static int serial_open(struct tty_struct *tty, struct file *filp) | |||
| 292 | static void serial_down(struct usb_serial_port *port) | 293 | static void serial_down(struct usb_serial_port *port) |
| 293 | { | 294 | { |
| 294 | struct usb_serial_driver *drv = port->serial->type; | 295 | struct usb_serial_driver *drv = port->serial->type; |
| 295 | struct usb_serial *serial; | ||
| 296 | struct module *owner; | ||
| 297 | 296 | ||
| 298 | /* | 297 | /* |
| 299 | * The console is magical. Do not hang up the console hardware | 298 | * The console is magical. Do not hang up the console hardware |
| @@ -309,12 +308,8 @@ static void serial_down(struct usb_serial_port *port) | |||
| 309 | return; | 308 | return; |
| 310 | 309 | ||
| 311 | mutex_lock(&port->mutex); | 310 | mutex_lock(&port->mutex); |
| 312 | serial = port->serial; | ||
| 313 | owner = serial->type->driver.owner; | ||
| 314 | |||
| 315 | if (drv->close) | 311 | if (drv->close) |
| 316 | drv->close(port); | 312 | drv->close(port); |
| 317 | |||
| 318 | mutex_unlock(&port->mutex); | 313 | mutex_unlock(&port->mutex); |
| 319 | } | 314 | } |
| 320 | 315 | ||
| @@ -631,6 +626,8 @@ static void port_release(struct device *dev) | |||
| 631 | usb_free_urb(port->write_urb); | 626 | usb_free_urb(port->write_urb); |
| 632 | usb_free_urb(port->interrupt_in_urb); | 627 | usb_free_urb(port->interrupt_in_urb); |
| 633 | usb_free_urb(port->interrupt_out_urb); | 628 | usb_free_urb(port->interrupt_out_urb); |
| 629 | if (!IS_ERR(port->write_fifo) && port->write_fifo) | ||
| 630 | kfifo_free(port->write_fifo); | ||
| 634 | kfree(port->bulk_in_buffer); | 631 | kfree(port->bulk_in_buffer); |
| 635 | kfree(port->bulk_out_buffer); | 632 | kfree(port->bulk_out_buffer); |
| 636 | kfree(port->interrupt_in_buffer); | 633 | kfree(port->interrupt_in_buffer); |
| @@ -970,6 +967,10 @@ int usb_serial_probe(struct usb_interface *interface, | |||
| 970 | dev_err(&interface->dev, "No free urbs available\n"); | 967 | dev_err(&interface->dev, "No free urbs available\n"); |
| 971 | goto probe_error; | 968 | goto probe_error; |
| 972 | } | 969 | } |
| 970 | port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL, | ||
| 971 | &port->lock); | ||
| 972 | if (IS_ERR(port->write_fifo)) | ||
| 973 | goto probe_error; | ||
| 973 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 974 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); |
| 974 | port->bulk_out_size = buffer_size; | 975 | port->bulk_out_size = buffer_size; |
| 975 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; | 976 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; |
| @@ -1163,15 +1164,19 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 1163 | 1164 | ||
| 1164 | serial->suspending = 1; | 1165 | serial->suspending = 1; |
| 1165 | 1166 | ||
| 1167 | if (serial->type->suspend) { | ||
| 1168 | r = serial->type->suspend(serial, message); | ||
| 1169 | if (r < 0) | ||
| 1170 | goto err_out; | ||
| 1171 | } | ||
| 1172 | |||
| 1166 | for (i = 0; i < serial->num_ports; ++i) { | 1173 | for (i = 0; i < serial->num_ports; ++i) { |
| 1167 | port = serial->port[i]; | 1174 | port = serial->port[i]; |
| 1168 | if (port) | 1175 | if (port) |
| 1169 | kill_traffic(port); | 1176 | kill_traffic(port); |
| 1170 | } | 1177 | } |
| 1171 | 1178 | ||
| 1172 | if (serial->type->suspend) | 1179 | err_out: |
| 1173 | r = serial->type->suspend(serial, message); | ||
| 1174 | |||
| 1175 | return r; | 1180 | return r; |
| 1176 | } | 1181 | } |
| 1177 | EXPORT_SYMBOL(usb_serial_suspend); | 1182 | EXPORT_SYMBOL(usb_serial_suspend); |
