aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/console.c13
-rw-r--r--drivers/usb/serial/cp210x.c5
-rw-r--r--drivers/usb/serial/cypress_m8.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c74
-rw-r--r--drivers/usb/serial/ftdi_sio.h39
-rw-r--r--drivers/usb/serial/generic.c20
-rw-r--r--drivers/usb/serial/mos7720.c2
-rw-r--r--drivers/usb/serial/mos7840.c10
-rw-r--r--drivers/usb/serial/option.c178
-rw-r--r--drivers/usb/serial/pl2303.c60
-rw-r--r--drivers/usb/serial/pl2303.h8
-rw-r--r--drivers/usb/serial/sierra.c51
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c7
-rw-r--r--drivers/usb/serial/usb-serial.c40
14 files changed, 360 insertions, 151 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 247b61bfb7f..0e4f2e41ace 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
kfree(tty);
}
}
- /* So we know not to kill the hardware on a hangup on this
- port. We have also bumped the use count by one so it won't go
- idle */
+ /* Now that any required fake tty operations are completed restore
+ * the tty port count */
+ --port->port.count;
+ /* The console is special in terms of closing the device so
+ * indicate this port is now acting as a system console. */
port->console = 1;
retval = 0;
@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
- if (!port->port.count) {
+ if (!port->console) {
dbg("%s - port not opened", __func__);
return;
}
@@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
{
if (usbcons_info.port) {
unregister_console(&usbcons);
- if (usbcons_info.port->port.count)
- usbcons_info.port->port.count--;
+ usbcons_info.port->console = 0;
usbcons_info.port = NULL;
}
}
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 2b9eeda62bf..985cbcf48bd 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
{ USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
+ { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
+ { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
{ USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
{ USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
{ USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
@@ -78,6 +80,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
{ USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
@@ -94,7 +97,9 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
+ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
+ { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 9734085fd2f..59adfe12311 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb)
/* precursor to disconnect so just go away */
return;
case -EPIPE:
- usb_clear_halt(port->serial->dev, 0x81);
- break;
+ /* Can't call usb_clear_halt while in_interrupt */
+ /* FALLS THROUGH */
default:
/* something ugly is going on... */
dev_err(&urb->dev->dev,
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 3dc3768ca71..8fec5d4455c 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -33,6 +33,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
@@ -107,6 +108,7 @@ struct ftdi_sio_quirk {
static int ftdi_jtag_probe(struct usb_serial *serial);
static int ftdi_mtxorb_hack_setup(struct usb_serial *serial);
+static int ftdi_NDI_device_setup(struct usb_serial *serial);
static void ftdi_USB_UIRT_setup(struct ftdi_private *priv);
static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
@@ -118,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
.probe = ftdi_mtxorb_hack_setup,
};
+static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
+ .probe = ftdi_NDI_device_setup,
+};
+
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.port_probe = ftdi_USB_UIRT_setup,
};
@@ -191,6 +197,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -579,6 +586,9 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
@@ -644,6 +654,16 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
@@ -660,6 +680,8 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
@@ -667,7 +689,6 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
{ USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
{ USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
{ USB_DEVICE(ATMEL_VID, STK541_PID) },
{ USB_DEVICE(DE_VID, STB_PID) },
{ USB_DEVICE(DE_VID, WHT_PID) },
@@ -677,6 +698,10 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
+ { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -1023,6 +1048,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
case FT2232C: /* FT2232C chip */
case FT232RL:
if (baud <= 3000000) {
+ __u16 product_id = le16_to_cpu(
+ port->serial->dev->descriptor.idProduct);
+ if (((FTDI_NDI_HUC_PID == product_id) ||
+ (FTDI_NDI_SPECTRA_SCU_PID == product_id) ||
+ (FTDI_NDI_FUTURE_2_PID == product_id) ||
+ (FTDI_NDI_FUTURE_3_PID == product_id) ||
+ (FTDI_NDI_AURORA_SCU_PID == product_id)) &&
+ (baud == 19200)) {
+ baud = 1200000;
+ }
div_value = ftdi_232bm_baud_to_divisor(baud);
} else {
dbg("%s - Baud rate too high!", __func__);
@@ -1554,6 +1589,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
} /* ftdi_HE_TIRA1_setup */
/*
+ * Module parameter to control latency timer for NDI FTDI-based USB devices.
+ * If this value is not set in modprobe.conf.local its value will be set to 1ms.
+ */
+static int ndi_latency_timer = 1;
+
+/* Setup for the NDI FTDI-based USB devices, which requires hardwired
+ * baudrate (19200 gets mapped to 1200000).
+ *
+ * Called from usbserial:serial_probe.
+ */
+static int ftdi_NDI_device_setup(struct usb_serial *serial)
+{
+ struct usb_device *udev = serial->dev;
+ int latency = ndi_latency_timer;
+ int rv = 0;
+ char buf[1];
+
+ if (latency == 0)
+ latency = 1;
+ if (latency > 99)
+ latency = 99;
+
+ dbg("%s setting NDI device latency to %d", __func__, latency);
+ dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
+
+ rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
+ FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
+ latency, 0, buf, 0, WDR_TIMEOUT);
+ return 0;
+}
+
+/*
* First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
* Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
* userspace using openocd.
@@ -2121,7 +2189,7 @@ static void ftdi_process_read(struct work_struct *work)
/* Note that the error flag is duplicated for
every character received since we don't know
which character it applied to */
- if (!usb_serial_handle_sysrq_char(port,
+ if (!usb_serial_handle_sysrq_char(tty, port,
data[packet_offset + i]))
tty_insert_flip_char(tty,
data[packet_offset + i],
@@ -2622,3 +2690,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified product ID");
+module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override");
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index f1d440a728a..8c92b88166a 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -506,6 +506,7 @@
*
* Armin Laeuger originally sent the PID for the UM 100 module.
*/
+#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */
#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
@@ -614,6 +615,9 @@
#define FTDI_CCSICDU20_0_PID 0xF9D0
#define FTDI_CCSICDU40_1_PID 0xF9D1
#define FTDI_CCSMACHX_2_PID 0xF9D2
+#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3
+#define FTDI_CCSICDU64_4_PID 0xF9D4
+#define FTDI_CCSPRIME8_5_PID 0xF9D5
/* Inside Accesso contactless reader (http://www.insidefr.com) */
#define INSIDE_ACCESSO 0xFAD0
@@ -736,6 +740,15 @@
#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
/*
+ * NDI (www.ndigital.com) product ids
+ */
+#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */
+#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */
+#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */
+#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */
+#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */
+
+/*
* Posiflex inc retail equipment (http://www.posiflex.com.tw)
*/
#define POSIFLEX_VID 0x0d3a /* Vendor ID */
@@ -848,9 +861,6 @@
#define TML_VID 0x1B91 /* Vendor ID */
#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
-/* NDI Polaris System */
-#define FTDI_NDI_HUC_PID 0xDA70
-
/* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
@@ -934,6 +944,29 @@
#define MARVELL_VID 0x9e88
#define MARVELL_SHEEVAPLUG_PID 0x9e8f
+#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
+
+/*
+ * GN Otometrics (http://www.otometrics.com)
+ * Submitted by Ville Sundberg.
+ */
+#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */
+#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */
+
+/*
+ * Bayer Ascensia Contour blood glucose meter USB-converter cable.
+ * http://winglucofacts.com/cables/
+ */
+#define BAYER_VID 0x1A79
+#define BAYER_CONTOUR_CABLE_PID 0x6001
+
+/*
+ * Marvell OpenRD Base, Client
+ * http://www.open-rd.org
+ * OpenRD Base, Client use VID 0x0403
+ */
+#define MARVELL_OPENRD_PID 0x9e90
+
/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 932d6241b78..ce57f6a32bd 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -424,10 +424,17 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
if (!tty)
goto done;
- /* Push data to tty */
- for (i = 0; i < urb->actual_length; i++, ch++) {
- if (!usb_serial_handle_sysrq_char(port, *ch))
- tty_insert_flip_char(tty, *ch, TTY_NORMAL);
+ /* The per character mucking around with sysrq path it too slow for
+ stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases
+ where the USB serial is not a console anyway */
+ if (!port->console || !port->sysrq)
+ tty_insert_flip_string(tty, ch, urb->actual_length);
+ else {
+ /* Push data to tty */
+ for (i = 0; i < urb->actual_length; i++, ch++) {
+ if (!usb_serial_handle_sysrq_char(tty, port, *ch))
+ tty_insert_flip_char(tty, *ch, TTY_NORMAL);
+ }
}
tty_flip_buffer_push(tty);
tty_kref_put(tty);
@@ -527,11 +534,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
}
}
-int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
+int usb_serial_handle_sysrq_char(struct tty_struct *tty,
+ struct usb_serial_port *port, unsigned int ch)
{
if (port->sysrq && port->console) {
if (ch && time_before(jiffies, port->sysrq)) {
- handle_sysrq(ch, tty_port_tty_get(&port->port));
+ handle_sysrq(ch, tty);
port->sysrq = 0;
return 1;
}
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index bfc5ce000ef..ccd4dd340d2 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -521,7 +521,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty)
mos7720_port = usb_get_serial_port_data(port);
if (mos7720_port == NULL) {
dbg("%s:leaving ...........", __func__);
- return -ENODEV;
+ return 0;
}
for (i = 0; i < NUM_URBS; ++i) {
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index c40f95c1951..270009afdf7 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -26,6 +26,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
@@ -123,10 +124,13 @@
#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
-/* This driver also supports the ATEN UC2324 device since it is mos7840 based
- * - if I knew the device id it would also support the ATEN UC2322 */
+/* This driver also supports
+ * ATEN UC2324 device using Moschip MCS7840
+ * ATEN UC2322 device using Moschip MCS7820
+ */
#define USB_VENDOR_ID_ATENINTL 0x0557
#define ATENINTL_DEVICE_ID_UC2324 0x2011
+#define ATENINTL_DEVICE_ID_UC2322 0x7820
/* Interrupt Routine Defines */
@@ -176,6 +180,7 @@ static struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
{} /* terminating entry */
};
@@ -185,6 +190,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
+ {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
{} /* terminating entry */
};
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 575816e6ba3..c784ddbe7b6 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -66,8 +66,10 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file);
static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static int option_send_setup(struct usb_serial_port *port);
+#ifdef CONFIG_PM
static int option_suspend(struct usb_serial *serial, pm_message_t message);
static int option_resume(struct usb_serial *serial);
+#endif
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
@@ -205,7 +207,9 @@ static int option_resume(struct usb_serial *serial);
#define NOVATELWIRELESS_PRODUCT_MC727 0x4100
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
#define NOVATELWIRELESS_PRODUCT_U727 0x5010
+#define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100
#define NOVATELWIRELESS_PRODUCT_MC760 0x6000
+#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002
/* FUTURE NOVATEL PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
@@ -258,11 +262,6 @@ static int option_resume(struct usb_serial *serial);
#define AXESSTEL_VENDOR_ID 0x1726
#define AXESSTEL_PRODUCT_MV110H 0x1000
-#define ONDA_VENDOR_ID 0x19d2
-#define ONDA_PRODUCT_MSA501HS 0x0001
-#define ONDA_PRODUCT_ET502HS 0x0002
-#define ONDA_PRODUCT_MT503HS 0x2000
-
#define BANDRICH_VENDOR_ID 0x1A8D
#define BANDRICH_PRODUCT_C100_1 0x1002
#define BANDRICH_PRODUCT_C100_2 0x1003
@@ -300,6 +299,7 @@ static int option_resume(struct usb_serial *serial);
#define ZTE_PRODUCT_MF628 0x0015
#define ZTE_PRODUCT_MF626 0x0031
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
+#define ZTE_PRODUCT_AC8710 0xfff1
#define BENQ_VENDOR_ID 0x04a5
#define BENQ_PRODUCT_H10 0x4068
@@ -307,11 +307,25 @@ static int option_resume(struct usb_serial *serial);
#define DLINK_VENDOR_ID 0x1186
#define DLINK_PRODUCT_DWM_652 0x3e04
+#define QISDA_VENDOR_ID 0x1da5
+#define QISDA_PRODUCT_H21_4512 0x4512
+#define QISDA_PRODUCT_H21_4523 0x4523
+#define QISDA_PRODUCT_H20_4515 0x4515
+#define QISDA_PRODUCT_H20_4519 0x4519
+
/* TOSHIBA PRODUCTS */
#define TOSHIBA_VENDOR_ID 0x0930
#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302
+#define ALINK_VENDOR_ID 0x1e0e
+#define ALINK_PRODUCT_3GU 0x9200
+
+/* ALCATEL PRODUCTS */
+#define ALCATEL_VENDOR_ID 0x1bbb
+#define ALCATEL_PRODUCT_X060S 0x0000
+
+
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -428,8 +442,10 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
@@ -463,42 +479,6 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
- { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
- { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0003) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0004) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0005) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0006) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0007) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0008) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0009) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000a) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000b) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000c) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000d) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000e) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x000f) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0010) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0011) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0012) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0013) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0014) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0015) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0016) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0017) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0018) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0019) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0020) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0021) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0022) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0023) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0024) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0025) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0026) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0027) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0028) },
- { USB_DEVICE(ONDA_VENDOR_ID, 0x0029) },
- { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MT503HS) },
{ USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
@@ -523,14 +503,85 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
- { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) },
- { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
- { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
- { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000b, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000c, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000d, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000e, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
- { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
+ { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -539,8 +590,10 @@ static struct usb_driver option_driver = {
.name = "option",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+#ifdef CONFIG_PM
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
+#endif
.id_table = option_ids,
.no_dynamic_id = 1,
};
@@ -572,8 +625,10 @@ static struct usb_serial_driver option_1port_device = {
.disconnect = option_disconnect,
.release = option_release,
.read_int_callback = option_instat_callback,
+#ifdef CONFIG_PM
.suspend = option_suspend,
.resume = option_resume,
+#endif
};
static int debug;
@@ -732,7 +787,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
memcpy(this_urb->transfer_buffer, buf, todo);
this_urb->transfer_buffer_length = todo;
- this_urb->dev = port->serial->dev;
err = usb_submit_urb(this_urb, GFP_ATOMIC);
if (err) {
dbg("usb_submit_urb %p (write bulk) failed "
@@ -816,7 +870,6 @@ static void option_instat_callback(struct urb *urb)
int status = urb->status;
struct usb_serial_port *port = urb->context;
struct option_port_private *portdata = usb_get_serial_port_data(port);
- struct usb_serial *serial = port->serial;
dbg("%s", __func__);
dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
@@ -860,7 +913,6 @@ static void option_instat_callback(struct urb *urb)
/* Resubmit urb so we continue receiving IRQ data */
if (status != -ESHUTDOWN && status != -ENOENT) {
- urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
dbg("%s: resubmit intr urb failed. (%d)",
@@ -913,7 +965,6 @@ static int option_open(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp)
{
struct option_port_private *portdata;
- struct usb_serial *serial = port->serial;
int i, err;
struct urb *urb;
@@ -921,23 +972,11 @@ static int option_open(struct tty_struct *tty,
dbg("%s", __func__);
- /* Reset low level data toggle and start reading from endpoints */
+ /* Start reading from the IN endpoint */
for (i = 0; i < N_IN_URB; i++) {
urb = portdata->in_urbs[i];
if (!urb)
continue;
- if (urb->dev != serial->dev) {
- dbg("%s: dev %p != %p", __func__,
- urb->dev, serial->dev);
- continue;
- }
-
- /*
- * make sure endpoint data toggle is synchronized with the
- * device
- */
- usb_clear_halt(urb->dev, urb->pipe);
-
err = usb_submit_urb(urb, GFP_KERNEL);
if (err) {
dbg("%s: submit urb %d failed (%d) %d",
@@ -946,16 +985,6 @@ static int option_open(struct tty_struct *tty,
}
}
- /* Reset low level data toggle on out endpoints */
- for (i = 0; i < N_OUT_URB; i++) {
- urb = portdata->out_urbs[i];
- if (!urb)
- continue;
- urb->dev = serial->dev;
- /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
- usb_pipeout(urb->pipe), 0); */
- }
-
option_send_setup(port);
return 0;
@@ -1195,6 +1224,7 @@ static void option_release(struct usb_serial *serial)
}
}
+#ifdef CONFIG_PM
static int option_suspend(struct usb_serial *serial, pm_message_t message)
{
dbg("%s entered", __func__);
@@ -1218,7 +1248,6 @@ static int option_resume(struct usb_serial *serial)
dbg("%s: No interrupt URB for port %d\n", __func__, i);
continue;
}
- port->interrupt_in_urb->dev = serial->dev;
err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
dbg("Submitted interrupt URB for port %d (result %d)", i, err);
if (err < 0) {
@@ -1254,6 +1283,7 @@ static int option_resume(struct usb_serial *serial)
}
return 0;
}
+#endif
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ec6c132a25b..3e86815b270 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -94,6 +94,8 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -971,18 +973,46 @@ exit:
__func__, retval);
}
+static void pl2303_push_data(struct tty_struct *tty,
+ struct usb_serial_port *port, struct urb *urb,
+ u8 line_status)
+{
+ unsigned char *data = urb->transfer_buffer;
+ /* get tty_flag from status */
+ char tty_flag = TTY_NORMAL;
+ /* break takes precedence over parity, */
+ /* which takes precedence over framing errors */
+ if (line_status & UART_BREAK_ERROR)
+ tty_flag = TTY_BREAK;
+ else if (line_status & UART_PARITY_ERROR)
+ tty_flag = TTY_PARITY;
+ else if (line_status & UART_FRAME_ERROR)
+ tty_flag = TTY_FRAME;
+ dbg("%s - tty_flag = %d", __func__, tty_flag);
+
+ tty_buffer_request_room(tty, urb->actual_length + 1);
+ /* overrun is special, not associated with a char */
+ if (line_status & UART_OVERRUN_ERROR)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ if (port->console && port->sysrq) {
+ int i;
+ for (i = 0; i < urb->actual_length; ++i)
+ if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
+ tty_insert_flip_char(tty, data[i], tty_flag);
+ } else
+ tty_insert_flip_string(tty, data, urb->actual_length);
+ tty_flip_buffer_push(tty);
+}
+
static void pl2303_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
struct pl2303_private *priv = usb_get_serial_port_data(port);
struct tty_struct *tty;
- unsigned char *data = urb->transfer_buffer;
unsigned long flags;
- int i;
int result;
int status = urb->status;
u8 line_status;
- char tty_flag;
dbg("%s - port %d", __func__, port->number);
@@ -1010,10 +1040,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
}
usb_serial_debug_data(debug, &port->dev, __func__,
- urb->actual_length, data);
-
- /* get tty_flag from status */
- tty_flag = TTY_NORMAL;
+ urb->actual_length, urb->transfer_buffer);
spin_lock_irqsave(&priv->lock, flags);
line_status = priv->line_status;
@@ -1021,26 +1048,9 @@ static void pl2303_read_bulk_callback(struct urb *urb)
spin_unlock_irqrestore(&priv->lock, flags);
wake_up_interruptible(&priv->delta_msr_wait);
- /* break takes precedence over parity, */
- /* which takes precedence over framing errors */
- if (line_status & UART_BREAK_ERROR)
- tty_flag = TTY_BREAK;
- else if (line_status & UART_PARITY_ERROR)
- tty_flag = TTY_PARITY;
- else if (line_status & UART_FRAME_ERROR)
- tty_flag = TTY_FRAME;
- dbg("%s - tty_flag = %d", __func__, tty_flag);
-
tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
- tty_buffer_request_room(tty, urb->actual_length + 1);
- /* overrun is special, not associated with a char */
- if (line_status & UART_OVERRUN_ERROR)
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- for (i = 0; i < urb->actual_length; ++i)
- if (!usb_serial_handle_sysrq_char(port, data[i]))
- tty_insert_flip_char(tty, data[i], tty_flag);
- tty_flip_buffer_push(tty);
+ pl2303_push_data(tty, port, urb, line_status);
}
tty_kref_put(tty);
/* Schedule the next read _if_ we are still open */
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 1d7a22e3a9f..ee9505e1dd9 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -122,3 +122,11 @@
/* Hewlett-Packard LD220-HP POS Pole Display */
#define HP_VENDOR_ID 0x03f0
#define HP_LD220_PRODUCT_ID 0x3524
+
+/* Cressi Edy (diving computer) PC interface */
+#define CRESSI_VENDOR_ID 0x04b8
+#define CRESSI_EDY_PRODUCT_ID 0x0521
+
+/* Sony, USB data cable for CMD-Jxx mobile phones */
+#define SONY_VENDOR_ID 0x054c
+#define SONY_QN3USB_PRODUCT_ID 0x0437
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 032f7aeb40a..f48d05e0acc 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
};
static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
+ { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+ { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
+
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
- { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
- { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
+ { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */
+ { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
+ { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
+ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
- /* Sierra Wireless C597 */
+ /* Sierra Wireless C597 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
- /* Sierra Wireless Device */
+ /* Sierra Wireless T598 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
- { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
- { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
- { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
+ { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
+ { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
+ { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
+ { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
- { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
+ { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */
+ { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */
+ { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */
{ USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
- { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
+ { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */
{ USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
- { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
+ { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */
{ USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
+ { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */
{ USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
{ USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+ { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */
+ { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */
+ { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */
+ { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */
{ USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
{ USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
/* Sierra Wireless MC8790, MC8791, MC8792 Composite */
@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
/* Sierra Wireless C885 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
- /* Sierra Wireless Device */
+ /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
- /* Sierra Wireless Device */
+ /* Sierra Wireless C22/C33 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
- /* Sierra Wireless Device */
+ /* Sierra Wireless HSPA Non-Composite Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
-
- { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
- { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
-
+ { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
},
@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial)
return 0;
}
-static void sierra_disconnect(struct usb_serial *serial)
+static void sierra_release(struct usb_serial *serial)
{
int i;
struct usb_serial_port *port;
@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial)
if (!portdata)
continue;
kfree(portdata);
- usb_set_serial_port_data(port, NULL);
}
}
@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = {
.tiocmget = sierra_tiocmget,
.tiocmset = sierra_tiocmset,
.attach = sierra_startup,
- .disconnect = sierra_disconnect,
+ .release = sierra_release,
.read_int_callback = sierra_instat_callback,
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 991d8232e37..3bc609fe224 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
- { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
};
static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
@@ -728,7 +727,7 @@ static int ti_write_room(struct tty_struct *tty)
dbg("%s - port %d", __func__, port->number);
if (tport == NULL)
- return -ENODEV;
+ return 0;
spin_lock_irqsave(&tport->tp_lock, flags);
room = ti_buf_space_avail(tport->tp_write_buf);
@@ -749,7 +748,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty)
dbg("%s - port %d", __func__, port->number);
if (tport == NULL)
- return -ENODEV;
+ return 0;
spin_lock_irqsave(&tport->tp_lock, flags);
chars = ti_buf_data_avail(tport->tp_write_buf);
@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
u8 cs = 0;
int done;
struct ti_firmware_header *header;
- int status;
+ int status = 0;
int len;
for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index a84216464ca..99188c92068 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
@@ -31,6 +32,7 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/uaccess.h>
+#include <linux/serial.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "pl2303.h"
@@ -183,6 +185,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
struct usb_serial_port *port;
unsigned int portNumber;
int retval = 0;
+ int first = 0;
dbg("%s", __func__);
@@ -220,8 +223,9 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
tty->driver_data = port;
tty_port_tty_set(&port->port, tty);
- if (port->port.count == 1) {
-
+ /* If the console is attached, the device is already open */
+ if (port->port.count == 1 && !port->console) {
+ first = 1;
/* lock this module before we call it
* this may fail, which means we must bail out,
* safe because we are called with BKL held */
@@ -244,13 +248,21 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
if (retval)
goto bailout_interface_put;
mutex_unlock(&serial->disc_mutex);
+ set_bit(ASYNCB_INITIALIZED, &port->port.flags);
}
mutex_unlock(&port->mutex);
/* Now do the correct tty layer semantics */
retval = tty_port_block_til_ready(&port->port, tty, filp);
- if (retval == 0)
+ if (retval == 0) {
+ if (!first)
+ usb_serial_put(serial);
return 0;
-
+ }
+ mutex_lock(&port->mutex);
+ if (first == 0)
+ goto bailout_mutex_unlock;
+ /* Undo the initial port actions */
+ mutex_lock(&serial->disc_mutex);
bailout_interface_put:
usb_autopm_put_interface(serial->interface);
bailout_module_put:
@@ -338,6 +350,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
dbg("%s - port %d", __func__, port->number);
+ /* FIXME:
+ This leaves a very narrow race. Really we should do the
+ serial_do_free() on tty->shutdown(), but tty->shutdown can
+ be called from IRQ context and serial_do_free can sleep.
+
+ The right fix is probably to make the tty free (which is rare)
+ and thus tty->shutdown() occur via a work queue and simplify all
+ the drivers that use it.
+ */
+ if (tty_hung_up_p(filp)) {
+ /* serial_hangup already called serial_down at this point.
+ Another user may have already reopened the port but
+ serial_do_free is refcounted */
+ serial_do_free(port);
+ return;
+ }
if (tty_port_close_start(&port->port, tty, filp) == 0)
return;
@@ -353,7 +381,8 @@ static void serial_hangup(struct tty_struct *tty)
struct usb_serial_port *port = tty->driver_data;
serial_do_down(port);
tty_port_hangup(&port->port);
- serial_do_free(port);
+ /* We must not free port yet - the USB serial layer depends on it's
+ continued existence */
}
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -392,7 +421,6 @@ static int serial_chars_in_buffer(struct tty_struct *tty)
struct usb_serial_port *port = tty->driver_data;
dbg("%s = port %d", __func__, port->number);
- WARN_ON(!port->port.count);
/* if the device was unplugged then any remaining characters
fell out of the connector ;) */
if (port->serial->disconnected)