aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c170
1 files changed, 79 insertions, 91 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 2f6f1523ec56..706033753adb 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -14,7 +14,7 @@
14 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> 14 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
15*/ 15*/
16 16
17#define DRIVER_VERSION "v.1.2.9c" 17#define DRIVER_VERSION "v.1.2.13a"
18#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" 18#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" 19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
20 20
@@ -31,6 +31,7 @@
31#define SWIMS_USB_REQUEST_SetPower 0x00 31#define SWIMS_USB_REQUEST_SetPower 0x00
32#define SWIMS_USB_REQUEST_SetNmea 0x07 32#define SWIMS_USB_REQUEST_SetNmea 0x07
33#define SWIMS_USB_REQUEST_SetMode 0x0B 33#define SWIMS_USB_REQUEST_SetMode 0x0B
34#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A
34#define SWIMS_SET_MODE_Modem 0x0001 35#define SWIMS_SET_MODE_Modem 0x0001
35 36
36/* per port private data */ 37/* per port private data */
@@ -40,18 +41,11 @@
40 41
41static int debug; 42static int debug;
42static int nmea; 43static int nmea;
43static int truinstall = 1;
44
45enum devicetype {
46 DEVICE_3_PORT = 0,
47 DEVICE_1_PORT = 1,
48 DEVICE_INSTALLER = 2,
49};
50 44
51static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) 45static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
52{ 46{
53 int result; 47 int result;
54 dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); 48 dev_dbg(&udev->dev, "%s", __func__);
55 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 49 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
56 SWIMS_USB_REQUEST_SetPower, /* __u8 request */ 50 SWIMS_USB_REQUEST_SetPower, /* __u8 request */
57 USB_TYPE_VENDOR, /* __u8 request type */ 51 USB_TYPE_VENDOR, /* __u8 request type */
@@ -63,25 +57,10 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
63 return result; 57 return result;
64} 58}
65 59
66static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
67{
68 int result;
69 dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");
70 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
71 SWIMS_USB_REQUEST_SetMode, /* __u8 request */
72 USB_TYPE_VENDOR, /* __u8 request type */
73 eSWocMode, /* __u16 value */
74 0x0000, /* __u16 index */
75 NULL, /* void *data */
76 0, /* __u16 size */
77 USB_CTRL_SET_TIMEOUT); /* int timeout */
78 return result;
79}
80
81static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) 60static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
82{ 61{
83 int result; 62 int result;
84 dev_dbg(&udev->dev, "%s", "NMEA Enable sent\n"); 63 dev_dbg(&udev->dev, "%s", __func__);
85 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 64 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
86 SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ 65 SWIMS_USB_REQUEST_SetNmea, /* __u8 request */
87 USB_TYPE_VENDOR, /* __u8 request type */ 66 USB_TYPE_VENDOR, /* __u8 request type */
@@ -97,6 +76,7 @@ static int sierra_calc_num_ports(struct usb_serial *serial)
97{ 76{
98 int result; 77 int result;
99 int *num_ports = usb_get_serial_data(serial); 78 int *num_ports = usb_get_serial_data(serial);
79 dev_dbg(&serial->dev->dev, "%s", __func__);
100 80
101 result = *num_ports; 81 result = *num_ports;
102 82
@@ -110,22 +90,23 @@ static int sierra_calc_num_ports(struct usb_serial *serial)
110 90
111static int sierra_calc_interface(struct usb_serial *serial) 91static int sierra_calc_interface(struct usb_serial *serial)
112{ 92{
113 int interface; 93 int interface;
114 struct usb_interface *p_interface; 94 struct usb_interface *p_interface;
115 struct usb_host_interface *p_host_interface; 95 struct usb_host_interface *p_host_interface;
96 dev_dbg(&serial->dev->dev, "%s", __func__);
116 97
117 /* Get the interface structure pointer from the serial struct */ 98 /* Get the interface structure pointer from the serial struct */
118 p_interface = serial->interface; 99 p_interface = serial->interface;
119 100
120 /* Get a pointer to the host interface structure */ 101 /* Get a pointer to the host interface structure */
121 p_host_interface = p_interface->cur_altsetting; 102 p_host_interface = p_interface->cur_altsetting;
122 103
123 /* read the interface descriptor for this active altsetting 104 /* read the interface descriptor for this active altsetting
124 * to find out the interface number we are on 105 * to find out the interface number we are on
125 */ 106 */
126 interface = p_host_interface->desc.bInterfaceNumber; 107 interface = p_host_interface->desc.bInterfaceNumber;
127 108
128 return interface; 109 return interface;
129} 110}
130 111
131static int sierra_probe(struct usb_serial *serial, 112static int sierra_probe(struct usb_serial *serial,
@@ -135,43 +116,40 @@ static int sierra_probe(struct usb_serial *serial,
135 struct usb_device *udev; 116 struct usb_device *udev;
136 int *num_ports; 117 int *num_ports;
137 u8 ifnum; 118 u8 ifnum;
119 u8 numendpoints;
120
121 dev_dbg(&serial->dev->dev, "%s", __func__);
138 122
139 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); 123 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
140 if (!num_ports) 124 if (!num_ports)
141 return -ENOMEM; 125 return -ENOMEM;
142 126
143 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 127 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
128 numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
144 udev = serial->dev; 129 udev = serial->dev;
145 130
146 /* Figure out the interface number from the serial structure */ 131 /* Figure out the interface number from the serial structure */
147 ifnum = sierra_calc_interface(serial); 132 ifnum = sierra_calc_interface(serial);
148
149 /*
150 * If this interface supports more than 1 alternate
151 * select the 2nd one
152 */
153 if (serial->interface->num_altsetting == 2) {
154 dev_dbg(&udev->dev,
155 "Selecting alt setting for interface %d\n",
156 ifnum);
157 133
158 /* We know the alternate setting is 1 for the MC8785 */ 134 /*
159 usb_set_interface(udev, ifnum, 1); 135 * If this interface supports more than 1 alternate
160 } 136 * select the 2nd one
137 */
138 if (serial->interface->num_altsetting == 2) {
139 dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
140 ifnum);
141 /* We know the alternate setting is 1 for the MC8785 */
142 usb_set_interface(udev, ifnum, 1);
143 }
161 144
162 /* Check if in installer mode */ 145 /* Dummy interface present on some SKUs should be ignored */
163 if (truinstall && id->driver_info == DEVICE_INSTALLER) { 146 if (ifnum == 0x99)
164 dev_dbg(&udev->dev, "%s", "FOUND TRU-INSTALL DEVICE(SW)\n");
165 result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
166 /* Don't bind to the device when in installer mode */
167 kfree(num_ports);
168 return -EIO;
169 } else if (id->driver_info == DEVICE_1_PORT)
170 *num_ports = 1;
171 else if (ifnum == 0x99)
172 *num_ports = 0; 147 *num_ports = 0;
148 else if (numendpoints <= 3)
149 *num_ports = 1;
173 else 150 else
174 *num_ports = 3; 151 *num_ports = (numendpoints-1)/2;
152
175 /* 153 /*
176 * save off our num_ports info so that we can use it in the 154 * save off our num_ports info so that we can use it in the
177 * calc_num_ports callback 155 * calc_num_ports callback
@@ -187,40 +165,50 @@ static struct usb_device_id id_table [] = {
187 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ 165 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
188 { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ 166 { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
189 { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ 167 { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
168 { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
190 { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ 169 { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
191 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ 170 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
192 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ 171 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
193 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ 172 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
194 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, /* Sierra Wireless C597 */ 173 /* Sierra Wireless C597 */
174 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
175 /* Sierra Wireless Device */
176 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
177 { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
195 178
196 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ 179 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
197 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ 180 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
198 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ 181 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
199 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ 182 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
200 { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ 183 { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
201 { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ 184 { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
202 { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ 185 { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
203 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ 186 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
204 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ 187 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
205 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ 188 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
206 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ 189 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
207 { USB_DEVICE(0x1199, 0x683B), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless MC8785 Composite*/ 190 { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
191 { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
192 { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
193 { USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */
208 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ 194 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
209 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ 195 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
210 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ 196 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
211 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ 197 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
212 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ 198 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
213 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ 199 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
214 { USB_DEVICE(0x1199, 0x6859), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 200 { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
215 { USB_DEVICE(0x1199, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 201 { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
216 202 /* Sierra Wireless C885 */
217 { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */ 203 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
218 { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */ 204 /* Sierra Wireless Device */
219 205 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
220 { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ 206 /* Sierra Wireless Device */
221 { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ 207 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
208
209 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
210 { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
222 211
223 { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
224 { } 212 { }
225}; 213};
226MODULE_DEVICE_TABLE(usb, id_table); 214MODULE_DEVICE_TABLE(usb, id_table);
@@ -268,13 +256,19 @@ static int sierra_send_setup(struct tty_struct *tty,
268 if (portdata->rts_state) 256 if (portdata->rts_state)
269 val |= 0x02; 257 val |= 0x02;
270 258
271 /* Determine which port is targeted */ 259 /* If composite device then properly report interface */
272 if (port->bulk_out_endpointAddress == 2) 260 if (serial->num_ports == 1)
273 interface = 0; 261 interface = sierra_calc_interface(serial);
274 else if (port->bulk_out_endpointAddress == 4) 262
275 interface = 1; 263 /* Otherwise the need to do non-composite mapping */
276 else if (port->bulk_out_endpointAddress == 5) 264 else {
277 interface = 2; 265 if (port->bulk_out_endpointAddress == 2)
266 interface = 0;
267 else if (port->bulk_out_endpointAddress == 4)
268 interface = 1;
269 else if (port->bulk_out_endpointAddress == 5)
270 interface = 2;
271 }
278 272
279 return usb_control_msg(serial->dev, 273 return usb_control_msg(serial->dev,
280 usb_rcvctrlpipe(serial->dev, 0), 274 usb_rcvctrlpipe(serial->dev, 0),
@@ -713,7 +707,7 @@ static void sierra_shutdown(struct usb_serial *serial)
713static struct usb_serial_driver sierra_device = { 707static struct usb_serial_driver sierra_device = {
714 .driver = { 708 .driver = {
715 .owner = THIS_MODULE, 709 .owner = THIS_MODULE,
716 .name = "sierra1", 710 .name = "sierra",
717 }, 711 },
718 .description = "Sierra USB modem", 712 .description = "Sierra USB modem",
719 .id_table = id_table, 713 .id_table = id_table,
@@ -769,14 +763,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
769MODULE_VERSION(DRIVER_VERSION); 763MODULE_VERSION(DRIVER_VERSION);
770MODULE_LICENSE("GPL"); 764MODULE_LICENSE("GPL");
771 765
772module_param(truinstall, bool, 0); 766module_param(nmea, bool, S_IRUGO | S_IWUSR);
773MODULE_PARM_DESC(truinstall, "TRU-Install support");
774
775module_param(nmea, bool, 0);
776MODULE_PARM_DESC(nmea, "NMEA streaming"); 767MODULE_PARM_DESC(nmea, "NMEA streaming");
777 768
778#ifdef CONFIG_USB_DEBUG
779module_param(debug, bool, S_IRUGO | S_IWUSR); 769module_param(debug, bool, S_IRUGO | S_IWUSR);
780MODULE_PARM_DESC(debug, "Debug messages"); 770MODULE_PARM_DESC(debug, "Debug messages");
781#endif
782