aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
authorKevin Lloyd <klloyd@sierrawireless.com>2008-07-10 17:14:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-13 20:32:51 -0400
commite3173b22eb7b50a23af60e12bab7a29d4b24f284 (patch)
tree52594768085675b50c727772dc73c23408ef5984 /drivers/usb/serial/sierra.c
parent4e0fee82619937acb13806ffc901d3920b947286 (diff)
USB Serial Sierra: Dynamic interface detection
This patch changes the method by which the number of ports per interface is assigned so that it is more dynamic and calculated on the fly (as opposed to hard coding it). This will allow for faster and easier addition of products. Signed-off-by: Kevin Lloyd <klloyd@sierrawireless.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-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),