aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/qcserial.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 9215f6c582c3..04bb759536bb 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -78,6 +78,8 @@ static const struct usb_device_id id_table[] = {
78 {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ 78 {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
79 {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ 79 {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */
80 {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ 80 {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */
81 {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */
82 {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */
81 { } /* Terminating entry */ 83 { } /* Terminating entry */
82}; 84};
83MODULE_DEVICE_TABLE(usb, id_table); 85MODULE_DEVICE_TABLE(usb, id_table);
@@ -95,6 +97,7 @@ static struct usb_driver qcdriver = {
95static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) 97static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
96{ 98{
97 struct usb_wwan_intf_private *data; 99 struct usb_wwan_intf_private *data;
100 struct usb_host_interface *intf = serial->interface->cur_altsetting;
98 int retval = -ENODEV; 101 int retval = -ENODEV;
99 __u8 nintf; 102 __u8 nintf;
100 __u8 ifnum; 103 __u8 ifnum;
@@ -103,7 +106,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
103 106
104 nintf = serial->dev->actconfig->desc.bNumInterfaces; 107 nintf = serial->dev->actconfig->desc.bNumInterfaces;
105 dbg("Num Interfaces = %d", nintf); 108 dbg("Num Interfaces = %d", nintf);
106 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 109 ifnum = intf->desc.bInterfaceNumber;
107 dbg("This Interface = %d", ifnum); 110 dbg("This Interface = %d", ifnum);
108 111
109 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), 112 data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private),
@@ -116,27 +119,32 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
116 switch (nintf) { 119 switch (nintf) {
117 case 1: 120 case 1:
118 /* QDL mode */ 121 /* QDL mode */
119 if (serial->interface->num_altsetting == 2) { 122 /* Gobi 2000 has a single altsetting, older ones have two */
120 struct usb_host_interface *intf; 123 if (serial->interface->num_altsetting == 2)
121
122 intf = &serial->interface->altsetting[1]; 124 intf = &serial->interface->altsetting[1];
123 if (intf->desc.bNumEndpoints == 2) { 125 else if (serial->interface->num_altsetting > 2)
124 if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && 126 break;
125 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { 127
126 dbg("QDL port found"); 128 if (intf->desc.bNumEndpoints == 2 &&
127 retval = usb_set_interface(serial->dev, ifnum, 1); 129 usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
128 if (retval < 0) { 130 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
129 dev_err(&serial->dev->dev, 131 dbg("QDL port found");
130 "Could not set interface, error %d\n", 132
131 retval); 133 if (serial->interface->num_altsetting == 1)
132 retval = -ENODEV; 134 return 0;
133 } 135
134 return retval; 136 retval = usb_set_interface(serial->dev, ifnum, 1);
135 } 137 if (retval < 0) {
138 dev_err(&serial->dev->dev,
139 "Could not set interface, error %d\n",
140 retval);
141 retval = -ENODEV;
136 } 142 }
143 return retval;
137 } 144 }
138 break; 145 break;
139 146
147 case 3:
140 case 4: 148 case 4:
141 /* Composite mode */ 149 /* Composite mode */
142 if (ifnum == 2) { 150 if (ifnum == 2) {