[Please CC me on replies, I'm not subscribed to the list]

General:
--------

The device in question is a Mackie SDR24/96 24 Track
Hard Disk Recorder, the manufacturer URL is:
http://www.mackie.com/record/sdr2496/index.html
Though I don't believe there are too many Linux
users around that have such a device (actually
I guess the number is 1) I wanted to have the
device fully working under Linux.

Functionality:
--------------

The device supports two LUNs, one for an internal disk
and one for a removable disk in a tray (Lian-Li RH-58).
The device has a USB 1.1 interface.

The device can be switched to USB mass storage mode,
insertion or removal of the external disk is not possible
while the device is in mass storage mode.

If no removable disk is attached the internal disk has LUN0.
If a removable disk is attached the external disk has LUN0
and the internal disk has LUN1.

Problems:
---------

The device fails to report the number of LUNs.

The device messes up the protocol for LUN1 when
only LUN0 is available.

Even if the device would report the current amount of
LUNs this would cause problems with the way usb-storage
works. The amount of LUNs would be cached and when the
device disconnects and then lateron reconnects with a
different amount of LUNs the GUID of the device would
be the same, causing either LUN1 not to be accessible
or a then not existing LUN1 would expose the erroneous
LUN1 handling of the device.

Workaround Mechanism:
---------------------

The device is always set up to have two LUNs.

If after first device connect or after a device reconnect
the first command issued for LUN1 fails, LUN1 is assumed
to be not available, otherwise it is assumed to be available.

If LUN1 is assumed to be not available all device commands
for LUN1 are faked the same way as for a device that has
actually gone, resulting in 'no medium found' from a
userspace point of view.

To archieve this US_PR_MACKIE and an appropriate unusual
device entry with a special init function are introduced,
as well as an int sized allocated buffer.

The init function resets the buffer to contain zero.
After the first command for LUN1 is executed the result
is checked (buffer value zero). If the result is GOOD,
the buffer is set a value of one and otherwise to a
value of two.

If a command has to be issued and the buffer contains
the value two, the same handling as for a device that has
gone is used instead of executing the command.

This handling seems to me to be the least invasive
to the usb-storage code.

Patch:
------

The following patch enables full usage of the device.
It is against 2.4.20. If there is any problem with the
patch that will prevent kernel inclusion please let me
know.

initializers.c |    8 +++++++-
initializers.h |    3 +++
transport.h    |    2 ++
unusual_devs.h |    9 +++++++++
usb.c          |   30 ++++++++++++++++++++++++++++++
5 files changed, 51 insertions(+), 1 deletion(-)


diff -ru linux.orig/drivers/usb/storage/initializers.c linux/drivers/usb/storage/initializers.c --- linux.orig/drivers/usb/storage/initializers.c 2000-09-09 01:39:12.000000000 +0200 +++ linux/drivers/usb/storage/initializers.c 2003-02-22 18:28:58.000000000 +0100 @@ -57,4 +57,10 @@ return 0; }

-
+/* this enables proper handling for LUN1 of a Mackie SDR24/96 */
+int mackie_init(struct us_data *us)
+{
+       int *state = us->extra;
+       *state = 0;
+       return 0;
+}
diff -ru linux.orig/drivers/usb/storage/initializers.h 
linux/drivers/usb/storage/initializers.h
--- linux.orig/drivers/usb/storage/initializers.h       2001-11-22 20:49:34.000000000 
+0100
+++ linux/drivers/usb/storage/initializers.h    2003-02-22 18:29:17.000000000 +0100
@@ -42,3 +42,6 @@
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
 int usb_stor_euscsi_init(struct us_data *us);
+
+/* this enables proper handling for LUN1 of a Mackie SDR24/96 */
+int mackie_init(struct us_data *us);
diff -ru linux.orig/drivers/usb/storage/transport.h 
linux/drivers/usb/storage/transport.h
--- linux.orig/drivers/usb/storage/transport.h  2002-11-29 00:53:15.000000000 +0100
+++ linux/drivers/usb/storage/transport.h       2003-02-21 23:38:20.000000000 +0100
@@ -75,6 +75,8 @@
 #define US_PR_JUMPSHOT  0xf3            /* Lexar Jumpshot */
 #endif

+#define US_PR_MACKIE   0xf4            /* Mackie SDR24/96 */
+
 /*
  * Bulk only data structures
  */
diff -ru linux.orig/drivers/usb/storage/unusual_devs.h 
linux/drivers/usb/storage/unusual_devs.h
--- linux.orig/drivers/usb/storage/unusual_devs.h       2002-11-29 00:53:15.000000000 
+0100
+++ linux/drivers/usb/storage/unusual_devs.h    2003-02-22 17:39:08.000000000 +0100
@@ -506,6 +506,15 @@
                US_SC_SCSI, US_PR_CB, NULL,
                US_FL_MODE_XLATE ),

+/*
+ * Mackie SDR24/96 supports 2 LUNs but doesn't report them,
+ * behaves badly when LUN1 (removable) is not available */
+UNUSUAL_DEV(  0x0a73, 0x0001, 0x0001, 0x0001,
+               "MACKIE",
+               "SDR",
+               US_SC_SCSI, US_PR_MACKIE, mackie_init,
+               US_FL_FIX_INQUIRY),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
                 "ATI",
diff -ru linux.orig/drivers/usb/storage/usb.c linux/drivers/usb/storage/usb.c
--- linux.orig/drivers/usb/storage/usb.c        2002-11-29 00:53:15.000000000 +0100
+++ linux/drivers/usb/storage/usb.c     2003-02-22 18:33:20.000000000 +0100
@@ -453,6 +453,26 @@
                                        US_DEBUGP("Faking INQUIRY command\n");
                                        fill_inquiry_response(us, data_ptr, 36);
                                        us->srb->result = GOOD << 1;
+                               /* special for Mackie LUN1 */
+                               } else if(us->protocol == US_PR_MACKIE &&
+                                           (us->srb->cmnd[1] >> 5)) {
+                                       int *state = us->extra;
+                                       if(*state == 2) {
+                                           memcpy(us->srb->sense_buffer,
+                                              usb_stor_sense_notready,
+                                              sizeof(usb_stor_sense_notready));
+                                           us->srb->result =
+                                               CHECK_CONDITION << 1;
+                                       } else {
+                                           US_DEBUG(usb_stor_show_command(us->srb));
+                                           us->proto_handler(us->srb, us);
+                                           if(*state == 0) {
+                                               if(us->srb->result != GOOD << 1)
+                                                   *state = 2;
+                                               else
+                                                   *state = 1;
+                                           }
+                                       }
                                } else {
                                        /* we've got a command, let's do it! */
                                        US_DEBUG(usb_stor_show_command(us->srb));
@@ -912,6 +932,16 @@
                         break;
 #endif

+               case US_PR_MACKIE:
+                       if((ss->extra = kmalloc(sizeof(int), GFP_NOIO))) {
+                               ss->transport_name = "Mackie Bulk";
+                               ss->transport = usb_stor_Bulk_transport;
+                               ss->transport_reset = usb_stor_Bulk_reset;
+                               ss->max_lun = 1;
+                               break;
+                       }
+                       /* fall through */
+
                default:
                        ss->transport_name = "Unknown";
                        kfree(ss->current_urb);




------------------------------------------------------- This SF.net email is sponsored by: SlickEdit Inc. Develop an edge. The most comprehensive and flexible code editor you can use. Code faster. C/C++, C#, Java, HTML, XML, many more. FREE 30-Day Trial. www.slickedit.com/sourceforge _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to