diff options
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r-- | drivers/usb/storage/usb.c | 173 |
1 files changed, 129 insertions, 44 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 50ebddd6f..07f0598e5 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -1,8 +1,8 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: usb.c,v 1.23 2000/08/08 20:46:45 mdharm Exp $ + * $Id: usb.c,v 1.33 2000/08/25 00:13:51 mdharm Exp $ * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * * Developed with the assistance of: @@ -43,7 +43,6 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include "usb.h" #include "scsiglue.h" #include "transport.h" @@ -58,12 +57,16 @@ #ifdef CONFIG_USB_STORAGE_DPCM #include "dpcm.h" #endif +#ifdef CONFIG_USB_STORAGE_FREECOM +#include "freecom.h" +#endif #include <linux/module.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/malloc.h> +#include <linux/config.h> /* Some informational data */ MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); @@ -213,8 +216,20 @@ static int usb_stor_control_thread(void * __us) /* reject if target != 0 or if LUN is higher than * the maximum known LUN */ - if (us->srb->target || (us->srb->lun > us->max_lun)) { - US_DEBUGP("Bad device number (%d/%d)\n", + if (us->srb->target && + !(us->flags & US_FL_SCM_MULT_TARG)) { + US_DEBUGP("Bad target number (%d/%d)\n", + us->srb->target, us->srb->lun); + us->srb->result = DID_BAD_TARGET << 16; + + set_current_state(TASK_INTERRUPTIBLE); + us->srb->scsi_done(us->srb); + us->srb = NULL; + break; + } + + if (us->srb->lun > us->max_lun) { + US_DEBUGP("Bad LUN (%d/%d)\n", us->srb->target, us->srb->lun); us->srb->result = DID_BAD_TARGET << 16; @@ -314,6 +329,19 @@ static int usb_stor_control_thread(void * __us) * are free to use as many characters as you like. */ +int euscsi_init(struct us_data *us) +{ + unsigned char bar = 0x1; + int result; + + US_DEBUGP("Attempting to init eUSCSI bridge...\n"); + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0), + 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, + 0x01, 0x0, &bar, 0x1, 5*HZ); + US_DEBUGP("-- result is %d\n", result); + US_DEBUGP("-- bar afterwards is %d\n", bar); +} + static struct us_unusual_dev us_unusual_dev_list[] = { { 0x03f0, 0x0107, 0x0200, 0x0200, @@ -339,15 +367,61 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { 0x04e6, 0x0002, 0x0100, 0x0100, "Shuttle", "eUSCSI Bridge", - US_SC_SCSI, US_PR_BULK, NULL, - 0 }, + US_SC_SCSI, US_PR_BULK, euscsi_init, + US_FL_SCM_MULT_TARG }, + +#ifdef CONFIG_USB_STORAGE_SDDR09 + { 0x04e6, 0x0003, 0x0000, 0x9999, + "Sandisk", + "ImageMate SDDR09", + US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, + US_FL_SINGLE_LUN | US_FL_START_STOP }, +#endif + +#ifdef CONFIG_USB_STORAGE_DPCM + { 0x0436, 0x0005, 0x0100, 0x0100, + "Microtech", + "CameraMate (DPCM_USB)", + US_SC_SCSI, US_PR_DPCM_USB, NULL, + US_FL_START_STOP }, +#endif - { 0x04e6, 0x0006, 0x0100, 0x0100, + { 0x04e6, 0x0006, 0x0100, 0x0200, "Shuttle", "eUSB MMC Adapter", US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN}, + { 0x04e6, 0x0009, 0x0200, 0x0200, + "Shuttle", + "ATA/ATAPI Bridge", + US_SC_8020, US_PR_CB, NULL, + US_FL_SINGLE_LUN}, + + { 0x04e6, 0x000A, 0x0200, 0x0200, + "Shuttle", + "Compact Flash Reader", + US_SC_8020, US_PR_CB, NULL, + US_FL_SINGLE_LUN}, + + { 0x04e6, 0x000B, 0x0100, 0x0100, + "Shuttle", + "eUSCSI Bridge", + US_SC_SCSI, US_PR_BULK, euscsi_init, + US_FL_SCM_MULT_TARG }, + + { 0x04e6, 0x000C, 0x0100, 0x0100, + "Shuttle", + "eUSCSI Bridge", + US_SC_SCSI, US_PR_BULK, euscsi_init, + US_FL_SCM_MULT_TARG }, + + { 0x04e6, 0x0101, 0x0200, 0x0200, + "Shuttle", + "CD-RW Device", + US_SC_8020, US_PR_CB, NULL, + US_FL_SINGLE_LUN}, + { 0x054c, 0x0010, 0x0210, 0x0210, "Sony", "DSC-S30/S70", @@ -372,6 +446,24 @@ static struct us_unusual_dev us_unusual_dev_list[] = { US_SC_UFI, US_PR_CBI, NULL, US_FL_SINGLE_LUN}, + { 0x059f, 0xa601, 0x0200, 0x0200, + "LaCie", + "USB Hard Disk", + US_SC_RBC, US_PR_CB, NULL, + 0 }, + + { 0x05ab, 0x0031, 0x0100, 0x0100, + "In-System", + "USB/IDE Bridge", + US_SC_8070, US_PR_BULK, NULL, + 0 }, + + { 0x0693, 0x0005, 0x0100, 0x0100, + "Hagiwara", + "Flashgate", + US_SC_SCSI, US_PR_BULK, NULL, + 0 }, + { 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara", "FlashGate SmartMedia", @@ -401,14 +493,21 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { 0x07af, 0x0004, 0x0100, 0x0100, "Microtech", "USB-SCSI-DB25", - US_SC_SCSI, US_PR_BULK, NULL, - 0 }, + US_SC_SCSI, US_PR_BULK, euscsi_init, + US_FL_SCM_MULT_TARG }, + +#ifdef CONFIG_USB_STORAGE_FREECOM + { 0x07ab, 0xfc01, 0x0921, 0x0921, + "Freecom", + "USB-IDE", + US_SC_8070, US_PR_FREECOM, NULL, US_FL_SINGLE_LUN }, +#endif - { 0x059f, 0xa601, 0x0200, 0x0200, - "LaCie", - "USB Hard Disk", - US_SC_RBC, US_PR_CB, NULL, - 0 }, + { 0x07af, 0x0005, 0x0100, 0x0100, + "Microtech", + "USB-SCSI-HD50", + US_SC_SCSI, US_PR_BULK, euscsi_init, + US_FL_SCM_MULT_TARG }, #ifdef CONFIG_USB_STORAGE_DPCM { 0x07af, 0x0006, 0x0100, 0x0100, @@ -417,25 +516,6 @@ static struct us_unusual_dev us_unusual_dev_list[] = { US_SC_SCSI, US_PR_DPCM_USB, NULL, US_FL_START_STOP }, #endif - - { 0x07af, 0x0005, 0x0100, 0x0100, - "Microtech", - "USB-SCSI-HD50", - US_SC_SCSI, US_PR_BULK, NULL, - 0 }, - - { 0x05ab, 0x0031, 0x0100, 0x0100, - "In-System", - "USB/IDE Bridge", - US_SC_8070, US_PR_BULK, NULL, - 0 }, - - { 0x0693, 0x0005, 0x0100, 0x0100, - "Hagiwara", - "Flashgate", - US_SC_SCSI, US_PR_BULK, NULL, - 0 }, - { 0 } }; @@ -615,15 +695,10 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) /* set the interface -- STALL is an acceptable response here */ #ifdef CONFIG_USB_STORAGE_SDDR09 - if (protocol != US_PR_EUSB_SDDR09) - result = usb_set_interface(dev, - altsetting->bInterfaceNumber, 0); - else + if (protocol == US_PR_EUSB_SDDR09) result = usb_set_configuration(dev, 1); -#else - result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0); -#endif - US_DEBUGP("Result from usb_set_interface is %d\n", result); + + US_DEBUGP("Result from usb_set_configuration is %d\n", result); if (result == -EPIPE) { US_DEBUGP("-- clearing stall on control interface\n"); usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); @@ -632,6 +707,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("-- Unknown error. Rejecting device\n"); return NULL; } +#endif /* Do some basic sanity checks, and bail if we find a problem */ if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) { @@ -702,7 +778,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) /* Re-Initialize the device if it needs it */ if (unusual_dev && unusual_dev->initFunction) - (*unusual_dev->initFunction)(ss); + (unusual_dev->initFunction)(ss); } else { /* New device -- allocate memory and initialize */ @@ -828,6 +904,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->max_lun = 1; break; #endif + +#ifdef CONFIG_USB_STORAGE_FREECOM + case US_PR_FREECOM: + ss->transport_name = "Freecom"; + ss->transport = freecom_transport; + ss->transport_reset = usb_stor_freecom_reset; + ss->max_lun = 0; + break; +#endif default: ss->transport_name = "Unknown"; @@ -909,7 +994,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) /* Just before we start our control thread, initialize * the device if it needs initialization */ if (unusual_dev && unusual_dev->initFunction) - (*unusual_dev->initFunction)(ss); + (unusual_dev->initFunction)(ss); /* start up our control thread */ ss->pid = kernel_thread(usb_stor_control_thread, ss, |