2007-05-14 21:59:01

by Kevin Lloyd

[permalink] [raw]
Subject: [PATCH] usb-storage: Add support for unusual device by Sierra Wireless

From: Kevin Lloyd <[email protected]>

This patch is targeted for the 2.6.21.1 kernel source. It adds support
for Sierra Wireless devices with auto-install support to the
unusual_devices list of the usb-mass storage driver. This requires
changes to Kconfig, Makefile, usb.c, unusual_devs.h, and the addition
of sierra_ms.h & sierra_ms.c.

Signed-off-by: Kevin Lloyd <[email protected]>
---
diff -uprN linux-2.6.21.1/drivers/usb/storage/Kconfig linux-2.6.21.1.swoc/drivers/usb/storage/Kconfig
--- linux-2.6.21.1/drivers/usb/storage/Kconfig 2007-04-27 14:49:26.000000000 -0700
+++ linux-2.6.21.1.swoc/drivers/usb/storage/Kconfig 2007-05-14 13:56:41.000000000 -0700
@@ -105,6 +105,13 @@ config USB_STORAGE_SDDR55
Say Y here to include additional code to support the Sandisk SDDR-55
SmartMedia reader in the USB Mass Storage driver.

+config USB_STORAGE_SIERRA
+ bool "Sierra Wireless Modem Support"
+ depends on USB_STORAGE
+ help
+ Say Y here in order to support new Sierra Wireless devices with the
+ auto install feature.
+
config USB_STORAGE_JUMPSHOT
bool "Lexar Jumpshot Compact Flash Reader (EXPERIMENTAL)"
depends on USB_STORAGE && EXPERIMENTAL
diff -uprN linux-2.6.21.1/drivers/usb/storage/Makefile linux-2.6.21.1.swoc/drivers/usb/storage/Makefile
--- linux-2.6.21.1/drivers/usb/storage/Makefile 2007-04-27 14:49:26.000000000 -0700
+++ linux-2.6.21.1.swoc/drivers/usb/storage/Makefile 2007-05-11 15:56:44.000000000 -0700
@@ -21,6 +21,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUM
usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA) += sierra_ms.o

usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o $(usb-storage-obj-y)
diff -uprN linux-2.6.21.1/drivers/usb/storage/sierra_ms.c linux-2.6.21.1.swoc/drivers/usb/storage/sierra_ms.c
--- linux-2.6.21.1/drivers/usb/storage/sierra_ms.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.21.1.swoc/drivers/usb/storage/sierra_ms.c 2007-05-14 13:55:38.000000000 -0700
@@ -0,0 +1,82 @@
+/* Driver for Sierra Wireless devices with auto-install support
+ *
+ * First release
+ *
+ * Current development and maintenance by:
+ * (C) 2007 Kevin Lloyd <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "transport.h"
+#include "protocol.h"
+#include "scsiglue.h"
+#include "debug.h"
+#include "sierra_ms.h"
+
+
+int sierra_ms_init(struct us_data *us)
+{
+ int retval, retries;
+ signed long delay_t;
+ US_DEBUGP("sierra_ms: sierra_ms_init called\n");
+
+ delay_t = 2;
+ retries = 3;
+ while (retries)
+ {
+ schedule_timeout_uninterruptible(delay_t*HZ);
+ retval = sierra_ms_change_mode(us, SWIMS_SET_MODE_Modem);
+ if (retval == -ETIMEDOUT || retval == -ETIME) {
+ US_DEBUGP("sierra_ms: Command timed out.\n");
+ retries--;
+ }
+ else if (retval < 0) {
+ /* something prevented us from registering this driver */
+ err("sierra_ms: Error sending change mode command (%d).\n", retval);
+ retries--;
+ }
+ else
+ retries=0;
+ }
+ return retval;
+}
+
+int sierra_ms_change_mode(struct us_data *us, SWIMS_SET_MODE_VALUE
+ eSocMode)
+{
+ int result;
+ unsigned char *blankArray;
+ blankArray = kmalloc(0, GFP_KERNEL);
+
+ US_DEBUGP("sierra_ms: attempting to change modes.\n");
+
+ result = usb_stor_control_msg(us, us->send_ctrl_pipe,
+ SWIMS_USB_REQUEST_SetMode,
+ SWIMS_USB_REQUEST_TYPE_SetMode,
+ eSocMode,
+ SWIMS_USB_INDEX_SetMode,
+ blankArray,
+ 0,
+ 5*HZ);
+
+ return result;
+}
+
diff -uprN linux-2.6.21.1/drivers/usb/storage/sierra_ms.h linux-2.6.21.1.swoc/drivers/usb/storage/sierra_ms.h
--- linux-2.6.21.1/drivers/usb/storage/sierra_ms.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.21.1.swoc/drivers/usb/storage/sierra_ms.h 2007-05-14 13:55:45.000000000 -0700
@@ -0,0 +1,41 @@
+/* Header File for Sierra Wireless auto-install driver
+ *
+ * First release
+ *
+ * Current development and maintenance by:
+ * (c) 2000 In-System Design, Inc. ([email protected])
+ *
+ * See sierra_ms.c for more information.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SIERRA_MS_H
+#define _SIERRA_MS_H
+
+#define USB_sierra_ms_VENDOR_ID 0x1199
+#define USB_sierra_ms_PRODUCT_ID 0x0fff
+
+#define SWIMS_USB_REQUEST_SetMode 0x0B
+#define SWIMS_USB_REQUEST_TYPE_SetMode 0x40
+#define SWIMS_USB_INDEX_SetMode 0x0000
+#define SWIMS_SET_MODE_Modem 0x0001
+
+typedef __u16 SWIMS_SET_MODE_VALUE;
+
+extern int sierra_ms_init(struct us_data *us);
+int sierra_ms_change_mode(struct us_data *us, SWIMS_SET_MODE_VALUE eSocMode);
+
+#endif
diff -uprN linux-2.6.21.1/drivers/usb/storage/unusual_devs.h linux-2.6.21.1.swoc/drivers/usb/storage/unusual_devs.h
--- linux-2.6.21.1/drivers/usb/storage/unusual_devs.h 2007-04-27 14:49:26.000000000 -0700
+++ linux-2.6.21.1.swoc/drivers/usb/storage/unusual_devs.h 2007-05-11 15:56:44.000000000 -0700
@@ -1361,6 +1361,17 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x
US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
0 ),

+/* Reported by Kevin Lloyd <[email protected]>
+ * Entry is needed for the initializer function override,
+ * which instructs the device to load as a modem
+ * device.
+ */
+UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999,
+ "Sierra Wireless",
+ "USB MMC Storage",
+ US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init,
+ 0),
+
/* Reported by Jaco Kroon <[email protected]>
* The usb-storage module found on the Digitech GNX4 (and supposedly other
* devices) misbehaves and causes a bunch of invalid I/O errors.
diff -uprN linux-2.6.21.1/drivers/usb/storage/usb.c linux-2.6.21.1.swoc/drivers/usb/storage/usb.c
--- linux-2.6.21.1/drivers/usb/storage/usb.c 2007-04-27 14:49:26.000000000 -0700
+++ linux-2.6.21.1.swoc/drivers/usb/storage/usb.c 2007-05-11 15:56:44.000000000 -0700
@@ -101,6 +101,10 @@
#ifdef CONFIG_USB_STORAGE_KARMA
#include "karma.h"
#endif
+#ifdef CONFIG_USB_STORAGE_SIERRA
+#include "sierra_ms.h"
+#endif
+

/* Some informational data */
MODULE_AUTHOR("Matthew Dharm <[email protected]>");



2007-05-14 22:27:20

by Pete Zaitcev

[permalink] [raw]
Subject: Re: [PATCH] usb-storage: Add support for unusual device by Sierra Wireless

On Mon, 14 May 2007 14:44:49 -0700, Kevin Lloyd <[email protected]> wrote:

> + schedule_timeout_uninterruptible(delay_t*HZ);
> + retval = sierra_ms_change_mode(us, SWIMS_SET_MODE_Modem);
> + if (retval == -ETIMEDOUT || retval == -ETIME) {
> + US_DEBUGP("sierra_ms: Command timed out.\n");
> + retries--;

This is strange. The two values should not typically be mixed this way.

ETIMEOUT happens when we (host) sent the setup packet, device took it,
and then posted NAKs for all data-in that we did, so eventually (after 5s),
we unlinked the URB. This means that the device works, just doesn't
want to perform the command in time. The bus itself functions fine.

ETIME means that something has violated the bus protocol. It's like
-EBUS for MMIO on PCI. Usually it means that the firmware in the device
is completely dead. You can call this a timeout in some sense, but
in reality it's no different from EILSEQ. We just report a different
code for finer shades of debugging. It happens in less than a millisecond.

I think you just need to test for ETIMEDOUT for that message.

> + int result;
> + unsigned char *blankArray;
> + blankArray = kmalloc(0, GFP_KERNEL);

> + result = usb_stor_control_msg(us, us->send_ctrl_pipe,
> + SWIMS_USB_REQUEST_SetMode,
> + SWIMS_USB_REQUEST_TYPE_SetMode,
> + eSocMode,
> + SWIMS_USB_INDEX_SetMode,
> + blankArray,
> + 0,
> + 5*HZ);

The blankArray is completely unnecessary here. If something hits
a NULL despite the zero transfer size, it has to be fixed.

-- Pete

2007-05-14 23:00:38

by Daniel Drake

[permalink] [raw]
Subject: Re: [PATCH] usb-storage: Add support for unusual device by Sierra Wireless

Kevin Lloyd wrote:
> From: Kevin Lloyd <[email protected]>
>
> This patch is targeted for the 2.6.21.1 kernel source. It adds support
> for Sierra Wireless devices with auto-install support to the
> unusual_devices list of the usb-mass storage driver. This requires
> changes to Kconfig, Makefile, usb.c, unusual_devs.h, and the addition of
> sierra_ms.h & sierra_ms.c.

We have to do a similar thing for some zd1211rw USB-wireless devices,
which appear as a virtual CDROM drive on plugin. To convert them to a
proper wireless device, the cdrom has to be ejected, then the device
disconnects and reconnects with different ID's (and the wireless endpoints).

Originally I wrote a usb-storage subdriver to handle the auto-eject, but
this was rejected. It was decided to make usb-storage simply ignore the
devices, and have the zd1211rw driver do the eject operation. The same
may also apply in your case. See the US_FL_IGNORE_DEVICE flag, and the
DEVICE_INSTALLER handling in drivers/net/wireless/zd1211rw/zd_usb.c

Daniel

2007-05-14 23:09:21

by Kevin Lloyd

[permalink] [raw]
Subject: RE: [PATCH] usb-storage: Add support for unusual device by Sierra Wireless

Not a bad idea. When using the US_FL_IGNORE_DEVICE flag, that causes the
usb-storage driver to no load the device and allow another driver
properly load it? The reason I ask is because I previously had a
separate driver for the device, however there were priority issues
regarding which loaded first usb-storage or the separate driver.

Thanks,
- Kevin

-----Original Message-----
From: Daniel Drake [mailto:[email protected]]
Sent: Monday, May 14, 2007 3:59 PM
To: Kevin Lloyd
Cc: [email protected]; [email protected];
[email protected];
[email protected]; [email protected]
Subject: Re: [PATCH] usb-storage: Add support for unusual device by
Sierra Wireless

Kevin Lloyd wrote:
> From: Kevin Lloyd <[email protected]>
>
> This patch is targeted for the 2.6.21.1 kernel source. It adds support

> for Sierra Wireless devices with auto-install support to the
> unusual_devices list of the usb-mass storage driver. This requires
> changes to Kconfig, Makefile, usb.c, unusual_devs.h, and the addition
> of sierra_ms.h & sierra_ms.c.

We have to do a similar thing for some zd1211rw USB-wireless devices,
which appear as a virtual CDROM drive on plugin. To convert them to a
proper wireless device, the cdrom has to be ejected, then the device
disconnects and reconnects with different ID's (and the wireless
endpoints).

Originally I wrote a usb-storage subdriver to handle the auto-eject, but
this was rejected. It was decided to make usb-storage simply ignore the
devices, and have the zd1211rw driver do the eject operation. The same
may also apply in your case. See the US_FL_IGNORE_DEVICE flag, and the
DEVICE_INSTALLER handling in drivers/net/wireless/zd1211rw/zd_usb.c

Daniel


2007-05-14 23:28:19

by Daniel Drake

[permalink] [raw]
Subject: Re: [PATCH] usb-storage: Add support for unusual device by Sierra Wireless

Kevin Lloyd wrote:
> Not a bad idea. When using the US_FL_IGNORE_DEVICE flag, that causes the
> usb-storage driver to no load the device and allow another driver
> properly load it? The reason I ask is because I previously had a
> separate driver for the device, however there were priority issues
> regarding which loaded first usb-storage or the separate driver.

Yes, that's what it's designed for. If usb-storage does come first, the
US_FL_IGNORE_DEVICE flag causes it to return -ENODEV from probe, which
causes the driver core to look for other candidate drivers to claim the
device.

Daniel