aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2011-04-19 07:32:41 -0400
committerJames Morris <jmorris@namei.org>2011-04-19 07:32:41 -0400
commitd4ab4e6a23f805abb8fc3cc34525eec3788aeca1 (patch)
treeeefd82c155bc27469a85667d759cd90facf4a6e3 /drivers/usb/serial
parentc0fa797ae6cd02ff87c0bfe0d509368a3b45640e (diff)
parent96fd2d57b8252e16dfacf8941f7a74a6119197f5 (diff)
Merge branch 'master'; commit 'v2.6.39-rc3' into next
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/aircable.c4
-rw-r--r--drivers/usb/serial/cp210x.c2
-rw-r--r--drivers/usb/serial/cypress_m8.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c7
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h12
-rw-r--r--drivers/usb/serial/io_edgeport.c2
-rw-r--r--drivers/usb/serial/io_edgeport.h2
-rw-r--r--drivers/usb/serial/io_ti.c2
-rw-r--r--drivers/usb/serial/mct_u232.c4
-rw-r--r--drivers/usb/serial/opticon.c4
-rw-r--r--drivers/usb/serial/option.c5
-rw-r--r--drivers/usb/serial/qcserial.c31
12 files changed, 58 insertions, 19 deletions
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 0db6ace16f7b..aba201cb872c 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -16,7 +16,7 @@
16 * When reading the process is almost equal except that the header starts with 16 * When reading the process is almost equal except that the header starts with
17 * 0x00 0x20. 17 * 0x00 0x20.
18 * 18 *
19 * The device simply need some stuff to understand data comming from the usb 19 * The device simply need some stuff to understand data coming from the usb
20 * buffer: The First and Second byte is used for a Header, the Third and Fourth 20 * buffer: The First and Second byte is used for a Header, the Third and Fourth
21 * tells the device the amount of information the package holds. 21 * tells the device the amount of information the package holds.
22 * Packages are 60 bytes long Header Stuff. 22 * Packages are 60 bytes long Header Stuff.
@@ -30,7 +30,7 @@
30 * one. 30 * one.
31 * 31 *
32 * The driver registers himself with the USB-serial core and the USB Core. I had 32 * The driver registers himself with the USB-serial core and the USB Core. I had
33 * to implement a probe function agains USB-serial, because other way, the 33 * to implement a probe function against USB-serial, because other way, the
34 * driver was attaching himself to both interfaces. I have tryed with different 34 * driver was attaching himself to both interfaces. I have tryed with different
35 * configurations of usb_serial_driver with out exit, only the probe function 35 * configurations of usb_serial_driver with out exit, only the probe function
36 * could handle this correctly. 36 * could handle this correctly.
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 4df3e0cecbae..0f11afdda134 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -101,7 +101,7 @@ static const struct usb_device_id id_table[] = {
101 { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ 101 { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
102 { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ 102 { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
103 { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ 103 { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
104 { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ 104 { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
105 { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ 105 { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */
106 { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ 106 { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
107 { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ 107 { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 987e9bf7bd02..d9906eb9d16a 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -35,7 +35,7 @@
35 * 35 *
36 * Lonnie Mendez <dignome@gmail.com> 36 * Lonnie Mendez <dignome@gmail.com>
37 * 04-10-2004 37 * 04-10-2004
38 * Driver modified to support dynamic line settings. Various improvments 38 * Driver modified to support dynamic line settings. Various improvements
39 * and features. 39 * and features.
40 * 40 *
41 * Neil Whelchel 41 * Neil Whelchel
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 65967b36365f..4de6ef0ae52a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -17,7 +17,7 @@
17 * See Documentation/usb/usb-serial.txt for more information on using this 17 * See Documentation/usb/usb-serial.txt for more information on using this
18 * driver 18 * driver
19 * 19 *
20 * See http://ftdi-usb-sio.sourceforge.net for upto date testing info 20 * See http://ftdi-usb-sio.sourceforge.net for up to date testing info
21 * and extra documentation 21 * and extra documentation
22 * 22 *
23 * Change entries from 2004 and earlier can be found in versions of this 23 * Change entries from 2004 and earlier can be found in versions of this
@@ -151,6 +151,8 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
151 * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! 151 * /sys/bus/usb/ftdi_sio/new_id, then send patch/report!
152 */ 152 */
153static struct usb_device_id id_table_combined [] = { 153static struct usb_device_id id_table_combined [] = {
154 { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) },
155 { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) },
154 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, 156 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
155 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, 157 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
156 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, 158 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
@@ -525,6 +527,7 @@ static struct usb_device_id id_table_combined [] = {
525 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, 527 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
526 { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, 528 { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
527 { USB_DEVICE(OCT_VID, OCT_US101_PID) }, 529 { USB_DEVICE(OCT_VID, OCT_US101_PID) },
530 { USB_DEVICE(OCT_VID, OCT_DK201_PID) },
528 { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID), 531 { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID),
529 .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk }, 532 .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk },
530 { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID), 533 { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID),
@@ -787,6 +790,8 @@ static struct usb_device_id id_table_combined [] = {
787 { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), 790 { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
788 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 791 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
789 { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, 792 { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
793 { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
794 { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
790 { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, 795 { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
791 { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, 796 { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) },
792 { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, 797 { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index c543e55bafba..efffc23723bd 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -300,6 +300,8 @@
300 * Hameg HO820 and HO870 interface (using VID 0x0403) 300 * Hameg HO820 and HO870 interface (using VID 0x0403)
301 */ 301 */
302#define HAMEG_HO820_PID 0xed74 302#define HAMEG_HO820_PID 0xed74
303#define HAMEG_HO730_PID 0xed73
304#define HAMEG_HO720_PID 0xed72
303#define HAMEG_HO870_PID 0xed71 305#define HAMEG_HO870_PID 0xed71
304 306
305/* 307/*
@@ -572,6 +574,7 @@
572/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ 574/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
573/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ 575/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */
574/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ 576/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */
577#define OCT_DK201_PID 0x0103 /* OCT DK201 USB docking station */
575#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ 578#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */
576 579
577/* 580/*
@@ -1141,3 +1144,12 @@
1141#define QIHARDWARE_VID 0x20B7 1144#define QIHARDWARE_VID 0x20B7
1142#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 1145#define MILKYMISTONE_JTAGSERIAL_PID 0x0713
1143 1146
1147/*
1148 * CTI GmbH RS485 Converter http://www.cti-lean.com/
1149 */
1150/* USB-485-Mini*/
1151#define FTDI_CTI_MINI_PID 0xF608
1152/* USB-Nano-485*/
1153#define FTDI_CTI_NANO_PID 0xF60B
1154
1155
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index f1aedfa7c420..abf095be5753 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -1981,7 +1981,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
1981 if (code == IOSP_STATUS_OPEN_RSP) { 1981 if (code == IOSP_STATUS_OPEN_RSP) {
1982 edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3); 1982 edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3);
1983 edge_port->maxTxCredits = edge_port->txCredits; 1983 edge_port->maxTxCredits = edge_port->txCredits;
1984 dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits); 1984 dbg("%s - Port %u Open Response Initial MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits);
1985 handle_new_msr(edge_port, byte2); 1985 handle_new_msr(edge_port, byte2);
1986 1986
1987 /* send the current line settings to the port so we are 1987 /* send the current line settings to the port so we are
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h
index dced7ec65470..ad9c1d47a619 100644
--- a/drivers/usb/serial/io_edgeport.h
+++ b/drivers/usb/serial/io_edgeport.h
@@ -68,7 +68,7 @@ struct comMapper {
68#define PROC_SET_COM_ENTRY 2 68#define PROC_SET_COM_ENTRY 2
69 69
70 70
71/* The following sturcture is passed to the write */ 71/* The following structure is passed to the write */
72struct procWrite { 72struct procWrite {
73 int Command; 73 int Command;
74 union { 74 union {
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index d8434910fa7b..0aac00afb5c8 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -433,7 +433,7 @@ static int write_i2c_mem(struct edgeport_serial *serial,
433 433
434 /* We can only send a maximum of 1 aligned byte page at a time */ 434 /* We can only send a maximum of 1 aligned byte page at a time */
435 435
436 /* calulate the number of bytes left in the first page */ 436 /* calculate the number of bytes left in the first page */
437 write_length = EPROM_PAGE_SIZE - 437 write_length = EPROM_PAGE_SIZE -
438 (start_address & (EPROM_PAGE_SIZE - 1)); 438 (start_address & (EPROM_PAGE_SIZE - 1));
439 439
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index d2c019637e45..ba0d28727ccb 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -106,7 +106,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
106static int mct_u232_tiocmget(struct tty_struct *tty); 106static int mct_u232_tiocmget(struct tty_struct *tty);
107static int mct_u232_tiocmset(struct tty_struct *tty, 107static int mct_u232_tiocmset(struct tty_struct *tty,
108 unsigned int set, unsigned int clear); 108 unsigned int set, unsigned int clear);
109static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, 109static int mct_u232_ioctl(struct tty_struct *tty,
110 unsigned int cmd, unsigned long arg); 110 unsigned int cmd, unsigned long arg);
111static int mct_u232_get_icount(struct tty_struct *tty, 111static int mct_u232_get_icount(struct tty_struct *tty,
112 struct serial_icounter_struct *icount); 112 struct serial_icounter_struct *icount);
@@ -874,7 +874,7 @@ static void mct_u232_unthrottle(struct tty_struct *tty)
874 } 874 }
875} 875}
876 876
877static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, 877static int mct_u232_ioctl(struct tty_struct *tty,
878 unsigned int cmd, unsigned long arg) 878 unsigned int cmd, unsigned long arg)
879{ 879{
880 DEFINE_WAIT(wait); 880 DEFINE_WAIT(wait);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 201f6096844b..1b5633f46984 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -116,7 +116,7 @@ static void opticon_read_bulk_callback(struct urb *urb)
116 } else { 116 } else {
117 if ((data[0] == 0x00) && (data[1] == 0x01)) { 117 if ((data[0] == 0x00) && (data[1] == 0x01)) {
118 spin_lock_irqsave(&priv->lock, flags); 118 spin_lock_irqsave(&priv->lock, flags);
119 /* CTS status infomation package */ 119 /* CTS status information package */
120 if (data[2] == 0x00) 120 if (data[2] == 0x00)
121 priv->cts = false; 121 priv->cts = false;
122 else 122 else
@@ -413,7 +413,7 @@ static int opticon_tiocmget(struct tty_struct *tty)
413 return result; 413 return result;
414} 414}
415 415
416static int opticon_tiocmset(struct tty_struct *tty, struct file *file, 416static int opticon_tiocmset(struct tty_struct *tty,
417 unsigned int set, unsigned int clear) 417 unsigned int set, unsigned int clear)
418{ 418{
419 struct usb_serial_port *port = tty->driver_data; 419 struct usb_serial_port *port = tty->driver_data;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 75c7f456eed5..d77ff0435896 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -407,6 +407,10 @@ static void option_instat_callback(struct urb *urb);
407/* ONDA MT825UP HSDPA 14.2 modem */ 407/* ONDA MT825UP HSDPA 14.2 modem */
408#define ONDA_MT825UP 0x000b 408#define ONDA_MT825UP 0x000b
409 409
410/* Samsung products */
411#define SAMSUNG_VENDOR_ID 0x04e8
412#define SAMSUNG_PRODUCT_GT_B3730 0x6889
413
410/* some devices interfaces need special handling due to a number of reasons */ 414/* some devices interfaces need special handling due to a number of reasons */
411enum option_blacklist_reason { 415enum option_blacklist_reason {
412 OPTION_BLACKLIST_NONE = 0, 416 OPTION_BLACKLIST_NONE = 0,
@@ -968,6 +972,7 @@ static const struct usb_device_id option_ids[] = {
968 { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, 972 { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
969 { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ 973 { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
970 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ 974 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
975 { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730/GT-B3710 LTE USB modem.*/
971 { } /* Terminating entry */ 976 { } /* Terminating entry */
972}; 977};
973MODULE_DEVICE_TABLE(usb, option_ids); 978MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 8858201eb1d3..54a9dab1f33b 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -111,7 +111,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
111 ifnum = intf->desc.bInterfaceNumber; 111 ifnum = intf->desc.bInterfaceNumber;
112 dbg("This Interface = %d", ifnum); 112 dbg("This Interface = %d", ifnum);
113 113
114 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), 114 data = kzalloc(sizeof(struct usb_wwan_intf_private),
115 GFP_KERNEL); 115 GFP_KERNEL);
116 if (!data) 116 if (!data)
117 return -ENOMEM; 117 return -ENOMEM;
@@ -134,8 +134,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
134 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { 134 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
135 dbg("QDL port found"); 135 dbg("QDL port found");
136 136
137 if (serial->interface->num_altsetting == 1) 137 if (serial->interface->num_altsetting == 1) {
138 return 0; 138 retval = 0; /* Success */
139 break;
140 }
139 141
140 retval = usb_set_interface(serial->dev, ifnum, 1); 142 retval = usb_set_interface(serial->dev, ifnum, 1);
141 if (retval < 0) { 143 if (retval < 0) {
@@ -145,7 +147,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
145 retval = -ENODEV; 147 retval = -ENODEV;
146 kfree(data); 148 kfree(data);
147 } 149 }
148 return retval;
149 } 150 }
150 break; 151 break;
151 152
@@ -166,6 +167,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
166 "Could not set interface, error %d\n", 167 "Could not set interface, error %d\n",
167 retval); 168 retval);
168 retval = -ENODEV; 169 retval = -ENODEV;
170 kfree(data);
169 } 171 }
170 } else if (ifnum == 2) { 172 } else if (ifnum == 2) {
171 dbg("Modem port found"); 173 dbg("Modem port found");
@@ -177,7 +179,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
177 retval = -ENODEV; 179 retval = -ENODEV;
178 kfree(data); 180 kfree(data);
179 } 181 }
180 return retval;
181 } else if (ifnum==3) { 182 } else if (ifnum==3) {
182 /* 183 /*
183 * NMEA (serial line 9600 8N1) 184 * NMEA (serial line 9600 8N1)
@@ -191,6 +192,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
191 "Could not set interface, error %d\n", 192 "Could not set interface, error %d\n",
192 retval); 193 retval);
193 retval = -ENODEV; 194 retval = -ENODEV;
195 kfree(data);
194 } 196 }
195 } 197 }
196 break; 198 break;
@@ -199,12 +201,27 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
199 dev_err(&serial->dev->dev, 201 dev_err(&serial->dev->dev,
200 "unknown number of interfaces: %d\n", nintf); 202 "unknown number of interfaces: %d\n", nintf);
201 kfree(data); 203 kfree(data);
202 return -ENODEV; 204 retval = -ENODEV;
203 } 205 }
204 206
207 /* Set serial->private if not returning -ENODEV */
208 if (retval != -ENODEV)
209 usb_set_serial_data(serial, data);
205 return retval; 210 return retval;
206} 211}
207 212
213static void qc_release(struct usb_serial *serial)
214{
215 struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
216
217 dbg("%s", __func__);
218
219 /* Call usb_wwan release & free the private data allocated in qcprobe */
220 usb_wwan_release(serial);
221 usb_set_serial_data(serial, NULL);
222 kfree(priv);
223}
224
208static struct usb_serial_driver qcdevice = { 225static struct usb_serial_driver qcdevice = {
209 .driver = { 226 .driver = {
210 .owner = THIS_MODULE, 227 .owner = THIS_MODULE,
@@ -222,7 +239,7 @@ static struct usb_serial_driver qcdevice = {
222 .chars_in_buffer = usb_wwan_chars_in_buffer, 239 .chars_in_buffer = usb_wwan_chars_in_buffer,
223 .attach = usb_wwan_startup, 240 .attach = usb_wwan_startup,
224 .disconnect = usb_wwan_disconnect, 241 .disconnect = usb_wwan_disconnect,
225 .release = usb_wwan_release, 242 .release = qc_release,
226#ifdef CONFIG_PM 243#ifdef CONFIG_PM
227 .suspend = usb_wwan_suspend, 244 .suspend = usb_wwan_suspend,
228 .resume = usb_wwan_resume, 245 .resume = usb_wwan_resume,