aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorKevin Lloyd <linux@sierrawireless.com>2007-07-16 16:49:27 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-19 20:46:03 -0400
commit112225b13cedd53dfd6455038b8843cf004ddec9 (patch)
treeb700aba6f57c5d7805314039a49b89801dd2e166 /drivers/usb
parenteb33caec1ed29fa2b04a2c5f02e3fed2add91db4 (diff)
USB: sierra: Add TRU-Install (c) Support
This patch adds compatibility with Sierra Wireless' new TRU-Install feature. Future devices that use this feature will not work unless this patch has been applied. Signed-off-by: Kevin Lloyd <linux@sierrawireless.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/sierra.c98
-rw-r--r--drivers/usb/storage/unusual_devs.h11
2 files changed, 89 insertions, 20 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index e7db20343d1..c137c8962b9 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -1,7 +1,7 @@
1/* 1/*
2 USB Driver for Sierra Wireless 2 USB Driver for Sierra Wireless
3 3
4 Copyright (C) 2006 Kevin Lloyd <linux@sierrawireless.com> 4 Copyright (C) 2006, 2007 Kevin Lloyd <linux@sierrawireless.com>
5 5
6 IMPORTANT DISCLAIMER: This driver is not commercially supported by 6 IMPORTANT DISCLAIMER: This driver is not commercially supported by
7 Sierra Wireless. Use at your own risk. 7 Sierra Wireless. Use at your own risk.
@@ -12,10 +12,9 @@
12 12
13 Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> 13 Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
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
16*/ 15*/
17 16
18#define DRIVER_VERSION "v.1.0.6" 17#define DRIVER_VERSION "v.1.2.4b"
19#define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" 18#define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>"
20#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" 19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
21 20
@@ -28,6 +27,71 @@
28#include <linux/usb.h> 27#include <linux/usb.h>
29#include <linux/usb/serial.h> 28#include <linux/usb/serial.h>
30 29
30#define SWIMS_USB_REQUEST_SetMode 0x0B
31#define SWIMS_USB_REQUEST_TYPE_SetMode 0x40
32#define SWIMS_USB_INDEX_SetMode 0x0000
33#define SWIMS_SET_MODE_Modem 0x0001
34
35/* per port private data */
36#define N_IN_URB 4
37#define N_OUT_URB 4
38#define IN_BUFLEN 4096
39
40static int debug;
41
42enum devicetype {
43 DEVICE_3_PORT = 0,
44 DEVICE_1_PORT = 1,
45 DEVICE_INSTALLER = 2,
46};
47
48int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
49{
50 int result;
51 dev_dbg(&udev->dev, "%s", "SET POWER STATE");
52 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
53 0x00, /* __u8 request */
54 0x40, /* __u8 request type */
55 swiState, /* __u16 value */
56 0, /* __u16 index */
57 NULL, /* void *data */
58 0, /* __u16 size */
59 USB_CTRL_SET_TIMEOUT); /* int timeout */
60 return result;
61}
62
63int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode)
64{
65 int result;
66 dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH");
67 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
68 SWIMS_USB_REQUEST_SetMode, /* __u8 request */
69 SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */
70 eSocMode, /* __u16 value */
71 SWIMS_USB_INDEX_SetMode, /* __u16 index */
72 NULL, /* void *data */
73 0, /* __u16 size */
74 USB_CTRL_SET_TIMEOUT); /* int timeout */
75 return result;
76}
77
78int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id)
79{
80 int result;
81 struct usb_device *udev;
82
83 udev = usb_get_dev(interface_to_usbdev(iface));
84
85 /* Check if in installer mode */
86 if (id->driver_info == DEVICE_INSTALLER) {
87 dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n");
88 result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
89 /*We do not want to bind to the device when in installer mode*/
90 return -EIO;
91 }
92
93 return usb_serial_probe(iface, id);
94}
31 95
32static struct usb_device_id id_table [] = { 96static struct usb_device_id id_table [] = {
33 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ 97 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
@@ -43,8 +107,10 @@ static struct usb_device_id id_table [] = {
43 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ 107 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
44 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ 108 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
45 109
46 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ 110 { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
47 { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ 111 { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
112
113 { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
48 { } 114 { }
49}; 115};
50MODULE_DEVICE_TABLE(usb, id_table); 116MODULE_DEVICE_TABLE(usb, id_table);
@@ -56,6 +122,7 @@ static struct usb_device_id id_table_1port [] = {
56}; 122};
57 123
58static struct usb_device_id id_table_3port [] = { 124static struct usb_device_id id_table_3port [] = {
125 /* CDMA Devices */
59 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ 126 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
60 { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ 127 { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
61 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ 128 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
@@ -63,6 +130,8 @@ static struct usb_device_id id_table_3port [] = {
63 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ 130 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
64 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ 131 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
65 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ 132 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
133
134 /* GSM/UMTS Devices */
66 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ 135 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
67 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ 136 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
68 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ 137 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
@@ -73,20 +142,13 @@ static struct usb_device_id id_table_3port [] = {
73 142
74static struct usb_driver sierra_driver = { 143static struct usb_driver sierra_driver = {
75 .name = "sierra", 144 .name = "sierra",
76 .probe = usb_serial_probe, 145 .probe = sierra_probe,
77 .disconnect = usb_serial_disconnect, 146 .disconnect = usb_serial_disconnect,
78 .id_table = id_table, 147 .id_table = id_table,
79 .no_dynamic_id = 1, 148 .no_dynamic_id = 1,
80}; 149};
81 150
82 151
83static int debug;
84
85/* per port private data */
86#define N_IN_URB 4
87#define N_OUT_URB 4
88#define IN_BUFLEN 4096
89
90struct sierra_port_private { 152struct sierra_port_private {
91 spinlock_t lock; /* lock the structure */ 153 spinlock_t lock; /* lock the structure */
92 int outstanding_urbs; /* number of out urbs in flight */ 154 int outstanding_urbs; /* number of out urbs in flight */
@@ -421,7 +483,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
421 int i; 483 int i;
422 struct urb *urb; 484 struct urb *urb;
423 int result; 485 int result;
424 __u16 set_mode_dzero = 0x0000;
425 486
426 portdata = usb_get_serial_port_data(port); 487 portdata = usb_get_serial_port_data(port);
427 488
@@ -457,12 +518,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
457 518
458 port->tty->low_latency = 1; 519 port->tty->low_latency = 1;
459 520
460 /* set mode to D0 */
461 result = usb_control_msg(serial->dev,
462 usb_rcvctrlpipe(serial->dev, 0),
463 0x00, 0x40, set_mode_dzero, 0, NULL,
464 0, USB_CTRL_SET_TIMEOUT);
465
466 sierra_send_setup(port); 521 sierra_send_setup(port);
467 522
468 /* start up the interrupt endpoint if we have one */ 523 /* start up the interrupt endpoint if we have one */
@@ -510,6 +565,9 @@ static int sierra_startup(struct usb_serial *serial)
510 565
511 dbg("%s", __FUNCTION__); 566 dbg("%s", __FUNCTION__);
512 567
568 /*Set Device mode to D0 */
569 sierra_set_power_state(serial->dev, 0x0000);
570
513 /* Now setup per port private data */ 571 /* Now setup per port private data */
514 for (i = 0; i < serial->num_ports; i++) { 572 for (i = 0; i < serial->num_ports; i++) {
515 port = serial->port[i]; 573 port = serial->port[i];
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index b6bf31a97b6..26fd196869b 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1384,6 +1384,17 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110,
1384 US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 1384 US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
1385 0 ), 1385 0 ),
1386 1386
1387/* Reported by Kevin Lloyd <linux@sierrawireless.com>
1388 * Entry is needed for the initializer function override,
1389 * which instructs the device to load as a modem
1390 * device.
1391 */
1392UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999,
1393 "Sierra Wireless",
1394 "USB MMC Storage",
1395 US_SC_DEVICE, US_PR_DEVICE, NULL,
1396 US_FL_IGNORE_DEVICE),
1397
1387/* Reported by Jaco Kroon <jaco@kroon.co.za> 1398/* Reported by Jaco Kroon <jaco@kroon.co.za>
1388 * The usb-storage module found on the Digitech GNX4 (and supposedly other 1399 * The usb-storage module found on the Digitech GNX4 (and supposedly other
1389 * devices) misbehaves and causes a bunch of invalid I/O errors. 1400 * devices) misbehaves and causes a bunch of invalid I/O errors.