diff options
-rw-r--r-- | drivers/usb/serial/sierra.c | 83 |
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), |