Commit e3173b22 authored by Kevin Lloyd's avatar Kevin Lloyd Committed by Greg Kroah-Hartman

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: default avatarKevin Lloyd <klloyd@sierrawireless.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 4e0fee82
...@@ -137,6 +137,8 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -137,6 +137,8 @@ static int sierra_probe(struct usb_serial *serial,
struct usb_device *udev; struct usb_device *udev;
int *num_ports; int *num_ports;
u8 ifnum; u8 ifnum;
u8 numendpoints;
dev_dbg(&serial->dev->dev, "%s", __func__); dev_dbg(&serial->dev->dev, "%s", __func__);
num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
...@@ -144,6 +146,7 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -144,6 +146,7 @@ static int sierra_probe(struct usb_serial *serial,
return -ENOMEM; return -ENOMEM;
ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
udev = serial->dev; udev = serial->dev;
/* Figure out the interface number from the serial structure */ /* Figure out the interface number from the serial structure */
...@@ -154,10 +157,8 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -154,10 +157,8 @@ static int sierra_probe(struct usb_serial *serial,
* select the 2nd one * select the 2nd one
*/ */
if (serial->interface->num_altsetting == 2) { if (serial->interface->num_altsetting == 2) {
dev_dbg(&udev->dev, dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
"Selecting alt setting for interface %d\n",
ifnum); ifnum);
/* We know the alternate setting is 1 for the MC8785 */ /* We know the alternate setting is 1 for the MC8785 */
usb_set_interface(udev, ifnum, 1); usb_set_interface(udev, ifnum, 1);
} }
...@@ -169,12 +170,14 @@ static int sierra_probe(struct usb_serial *serial, ...@@ -169,12 +170,14 @@ static int sierra_probe(struct usb_serial *serial,
/* Don't bind to the device when in installer mode */ /* Don't bind to the device when in installer mode */
kfree(num_ports); kfree(num_ports);
return -EIO; return -EIO;
} else if (id->driver_info == DEVICE_1_PORT) /* Dummy interface present on some SKUs should be ignored */
*num_ports = 1; } else if (ifnum == 0x99)
else if (ifnum == 0x99)
*num_ports = 0; *num_ports = 0;
else if (numendpoints <= 3)
*num_ports = 1;
else else
*num_ports = 3; *num_ports = (numendpoints-1)/2;
/* /*
* save off our num_ports info so that we can use it in the * save off our num_ports info so that we can use it in the
* calc_num_ports callback * calc_num_ports callback
...@@ -197,6 +200,9 @@ static struct usb_device_id id_table [] = { ...@@ -197,6 +200,9 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ { 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) }, { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
/* Sierra Wireless Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
{ USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
...@@ -209,18 +215,27 @@ static struct usb_device_id id_table [] = { ...@@ -209,18 +215,27 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
{ USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
{ USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
{ USB_DEVICE(0x1199, 0x683B), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless MC8785 Composite */ { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
{ USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
{ USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
{ USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */
{ USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
{ USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
{ USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
{ USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
{ USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
{ USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
{ USB_DEVICE(0x1199, 0x6859), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
{ USB_DEVICE(0x1199, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
/* Sierra Wireless C885 */
{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ /* Sierra Wireless Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
/* Sierra Wireless 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, 0x0FFF), .driver_info = DEVICE_INSTALLER}, { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
{ } { }
...@@ -270,13 +285,19 @@ static int sierra_send_setup(struct tty_struct *tty, ...@@ -270,13 +285,19 @@ static int sierra_send_setup(struct tty_struct *tty,
if (portdata->rts_state) if (portdata->rts_state)
val |= 0x02; val |= 0x02;
/* Determine which port is targeted */ /* If composite device then properly report interface */
if (serial->num_ports == 1)
interface = sierra_calc_interface(serial);
/* Otherwise the need to do non-composite mapping */
else {
if (port->bulk_out_endpointAddress == 2) if (port->bulk_out_endpointAddress == 2)
interface = 0; interface = 0;
else if (port->bulk_out_endpointAddress == 4) else if (port->bulk_out_endpointAddress == 4)
interface = 1; interface = 1;
else if (port->bulk_out_endpointAddress == 5) else if (port->bulk_out_endpointAddress == 5)
interface = 2; interface = 2;
}
return usb_control_msg(serial->dev, return usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0), usb_rcvctrlpipe(serial->dev, 0),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment