Skip to content

Commit

Permalink
USB Serial Sierra: Dynamic interface detection
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kevin Lloyd authored and Greg Kroah-Hartman committed Aug 14, 2008
1 parent 4e0fee8 commit e3173b2
Showing 1 changed file with 52 additions and 31 deletions.
83 changes: 52 additions & 31 deletions drivers/usb/serial/sierra.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,30 +137,31 @@ static int sierra_probe(struct usb_serial *serial,
struct usb_device *udev;
int *num_ports;
u8 ifnum;
u8 numendpoints;

dev_dbg(&serial->dev->dev, "%s", __func__);

num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
if (!num_ports)
return -ENOMEM;

ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
udev = serial->dev;

/* Figure out the interface number from the serial structure */
ifnum = sierra_calc_interface(serial);

/*
* If this interface supports more than 1 alternate
* select the 2nd one
*/
if (serial->interface->num_altsetting == 2) {
dev_dbg(&udev->dev,
"Selecting alt setting for interface %d\n",
ifnum);
/* Figure out the interface number from the serial structure */
ifnum = sierra_calc_interface(serial);

/* We know the alternate setting is 1 for the MC8785 */
usb_set_interface(udev, ifnum, 1);
}
/*
* If this interface supports more than 1 alternate
* select the 2nd one
*/
if (serial->interface->num_altsetting == 2) {
dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
ifnum);
/* We know the alternate setting is 1 for the MC8785 */
usb_set_interface(udev, ifnum, 1);
}

/* Check if in installer mode */
if (truinstall && id->driver_info == DEVICE_INSTALLER) {
Expand All @@ -169,12 +170,14 @@ static int sierra_probe(struct usb_serial *serial,
/* Don't bind to the device when in installer mode */
kfree(num_ports);
return -EIO;
} else if (id->driver_info == DEVICE_1_PORT)
*num_ports = 1;
else if (ifnum == 0x99)
/* Dummy interface present on some SKUs should be ignored */
} else if (ifnum == 0x99)
*num_ports = 0;
else if (numendpoints <= 3)
*num_ports = 1;
else
*num_ports = 3;
*num_ports = (numendpoints-1)/2;

/*
* save off our num_ports info so that we can use it in the
* calc_num_ports callback
Expand All @@ -197,6 +200,9 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
/* Sierra Wireless C597 */
{ 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, 0x6804) }, /* Sierra Wireless MC8755 */
Expand All @@ -209,18 +215,27 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
{ USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
{ 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, 0x6851) }, /* Sierra Wireless AirCard 881 */
{ USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
{ USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
{ USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 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, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */

{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
{ USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
{ USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
/* Sierra Wireless C885 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
/* 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},
{ }
Expand Down Expand Up @@ -270,13 +285,19 @@ static int sierra_send_setup(struct tty_struct *tty,
if (portdata->rts_state)
val |= 0x02;

/* Determine which port is targeted */
if (port->bulk_out_endpointAddress == 2)
interface = 0;
else if (port->bulk_out_endpointAddress == 4)
interface = 1;
else if (port->bulk_out_endpointAddress == 5)
interface = 2;
/* 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)
interface = 0;
else if (port->bulk_out_endpointAddress == 4)
interface = 1;
else if (port->bulk_out_endpointAddress == 5)
interface = 2;
}

return usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
Expand Down

0 comments on commit e3173b2

Please sign in to comment.