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