aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/sierra.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index a3aaf08e56d5..e2a7463346fc 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -137,6 +137,8 @@ static int sierra_probe(struct usb_serial *serial,
137 struct usb_device *udev; 137 struct usb_device *udev;
138 int *num_ports; 138 int *num_ports;
139 u8 ifnum; 139 u8 ifnum;
140 u8 numendpoints;
141
140 dev_dbg(&serial->dev->dev, "%s", __func__); 142 dev_dbg(&serial->dev->dev, "%s", __func__);
141 143
142 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); 144 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
@@ -144,23 +146,22 @@ static int sierra_probe(struct usb_serial *serial,
144 return -ENOMEM; 146 return -ENOMEM;
145 147
146 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 148 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
149 numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
147 udev = serial->dev; 150 udev = serial->dev;
148 151
149 /* Figure out the interface number from the serial structure */ 152 /* Figure out the interface number from the serial structure */
150 ifnum = sierra_calc_interface(serial); 153 ifnum = sierra_calc_interface(serial);
151
152 /*
153 * If this interface supports more than 1 alternate
154 * select the 2nd one
155 */
156 if (serial->interface->num_altsetting == 2) {
157 dev_dbg(&udev->dev,
158 "Selecting alt setting for interface %d\n",
159 ifnum);
160 154
161 /* We know the alternate setting is 1 for the MC8785 */ 155 /*
162 usb_set_interface(udev, ifnum, 1); 156 * If this interface supports more than 1 alternate
163 } 157 * select the 2nd one
158 */
159 if (serial->interface->num_altsetting == 2) {
160 dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
161 ifnum);
162 /* We know the alternate setting is 1 for the MC8785 */
163 usb_set_interface(udev, ifnum, 1);
164 }
164 165
165 /* Check if in installer mode */ 166 /* Check if in installer mode */
166 if (truinstall && id->driver_info == DEVICE_INSTALLER) { 167 if (truinstall && id->driver_info == DEVICE_INSTALLER) {
@@ -169,12 +170,14 @@ static int sierra_probe(struct usb_serial *serial,
169 /* Don't bind to the device when in installer mode */ 170 /* Don't bind to the device when in installer mode */
170 kfree(num_ports); 171 kfree(num_ports);
171 return -EIO; 172 return -EIO;
172 } else if (id->driver_info == DEVICE_1_PORT) 173 /* Dummy interface present on some SKUs should be ignored */
173 *num_ports = 1; 174 } else if (ifnum == 0x99)
174 else if (ifnum == 0x99)
175 *num_ports = 0; 175 *num_ports = 0;
176 else if (numendpoints <= 3)
177 *num_ports = 1;
176 else 178 else
177 *num_ports = 3; 179 *num_ports = (numendpoints-1)/2;
180
178 /* 181 /*
179 * save off our num_ports info so that we can use it in the 182 * save off our num_ports info so that we can use it in the
180 * calc_num_ports callback 183 * calc_num_ports callback
@@ -197,6 +200,9 @@ static struct usb_device_id id_table [] = {
197 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ 200 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
198 /* Sierra Wireless C597 */ 201 /* Sierra Wireless C597 */
199 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, 202 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
203 /* Sierra Wireless Device */
204 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
205 { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
200 206
201 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ 207 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
202 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ 208 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -209,18 +215,27 @@ static struct usb_device_id id_table [] = {
209 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ 215 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
210 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ 216 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
211 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ 217 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
212 { USB_DEVICE(0x1199, 0x683B), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless MC8785 Composite */ 218 { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
219 { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
220 { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
221 { USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */
213 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ 222 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
214 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ 223 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
215 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ 224 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
216 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ 225 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
217 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ 226 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
218 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ 227 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
219 { USB_DEVICE(0x1199, 0x6859), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 228 { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
220 { USB_DEVICE(0x1199, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 229 { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
221 230 /* Sierra Wireless C885 */
222 { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ 231 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
223 { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ 232 /* Sierra Wireless Device */
233 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
234 /* Sierra Wireless Device */
235 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
236
237 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
238 { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
224 239
225 { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, 240 { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
226 { } 241 { }
@@ -270,13 +285,19 @@ static int sierra_send_setup(struct tty_struct *tty,
270 if (portdata->rts_state) 285 if (portdata->rts_state)
271 val |= 0x02; 286 val |= 0x02;
272 287
273 /* Determine which port is targeted */ 288 /* If composite device then properly report interface */
274 if (port->bulk_out_endpointAddress == 2) 289 if (serial->num_ports == 1)
275 interface = 0; 290 interface = sierra_calc_interface(serial);
276 else if (port->bulk_out_endpointAddress == 4) 291
277 interface = 1; 292 /* Otherwise the need to do non-composite mapping */
278 else if (port->bulk_out_endpointAddress == 5) 293 else {
279 interface = 2; 294 if (port->bulk_out_endpointAddress == 2)
295 interface = 0;
296 else if (port->bulk_out_endpointAddress == 4)
297 interface = 1;
298 else if (port->bulk_out_endpointAddress == 5)
299 interface = 2;
300 }
280 301
281 return usb_control_msg(serial->dev, 302 return usb_control_msg(serial->dev,
282 usb_rcvctrlpipe(serial->dev, 0), 303 usb_rcvctrlpipe(serial->dev, 0),