From a60c6812feb6ba35b5b8a9ee8a5ca3d01d1fcd5f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 29 Aug 2000 05:27:07 +0000 Subject: Merge with Linux 2.4.0-test8-pre1. --- drivers/usb/storage/Makefile | 81 ++++---- drivers/usb/storage/debug.c | 4 +- drivers/usb/storage/debug.h | 4 +- drivers/usb/storage/dpcm.c | 5 +- drivers/usb/storage/dpcm.h | 4 +- drivers/usb/storage/freecom.c | 375 ++++++++++++++++++++++++++++++++++++ drivers/usb/storage/freecom.h | 35 ++++ drivers/usb/storage/protocol.c | 4 +- drivers/usb/storage/protocol.h | 4 +- drivers/usb/storage/scsiglue.c | 4 +- drivers/usb/storage/scsiglue.h | 4 +- drivers/usb/storage/sddr09.c | 176 ++++++++++++----- drivers/usb/storage/sddr09.h | 16 +- drivers/usb/storage/shuttle_usbat.c | 10 +- drivers/usb/storage/shuttle_usbat.h | 5 +- drivers/usb/storage/transport.c | 86 ++++----- drivers/usb/storage/transport.h | 10 +- drivers/usb/storage/usb.c | 173 ++++++++++++----- drivers/usb/storage/usb.h | 4 +- 19 files changed, 784 insertions(+), 220 deletions(-) create mode 100644 drivers/usb/storage/freecom.c create mode 100644 drivers/usb/storage/freecom.h (limited to 'drivers/usb/storage') diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index e7761863e..e09a8cac1 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -1,47 +1,44 @@ # # Makefile for the USB Mass Storage device drivers. # +# 15 Aug 2000, Christoph Hellwig +# Rewritten to use lists instead of if-statements. +# + +O_TARGET := storage.o +EXTRA_CFLAGS := -I../../scsi/ + +list-multi := usb-storage.o + +obj-$(CONFIG_USB_STORAGE) += usb-storage.o + +usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o +usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e) += shuttle_usbat.o +usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o +usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o +usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_SMARTMEDIA) += shuttle_sm.o +usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_COMPACTFLASH) += shuttle_cf.o +usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o + +usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ + $(usb-storage-obj-y) + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Take multi-part drivers out of obj-y and put components in. +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. +O_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MI_OBJS := $(int-m) -O_TARGET := usb-storage.o -M_OBJS := usb-storage.o -O_OBJS := scsiglue.o protocol.o transport.o usb.o -MOD_LIST_NAME := USB_STORAGE_MODULES - -CFLAGS_scsiglue.o:= -I../../scsi/ -CFLAGS_protocol.o:= -I../../scsi/ -CFLAGS_transport.o:= -I../../scsi/ -CFLAGS_debug.o:= -I../../scsi/ -CFLAGS_usb.o:= -I../../scsi/ -CFLAGS_shuttle_usbat.o:= -I../../scsi/ -CFLAGS_sddr09.o:= -I../../scsi/ -CFLAGS_dpcm.o:= -I../../scsi/ - -ifeq ($(CONFIG_USB_STORAGE_DEBUG),y) - O_OBJS += debug.o -endif - -ifeq ($(CONFIG_USB_STORAGE_HP8200e),y) - O_OBJS += shuttle_usbat.o -endif - -ifeq ($(CONFIG_USB_STORAGE_SDDR09),y) - O_OBJS += sddr09.o -endif - -ifeq ($(CONFIG_USB_STORAGE_FREECOM),y) - O_OBJS += freecom.o -endif - -ifeq ($(CONFIG_USB_STORAGE_SHUTTLE_SMARTMEDIA),y) - O_OBJS += shuttle_sm.o -endif - -ifeq ($(CONFIG_USB_STORAGE_SHUTTLE_COMPACTFLASH),y) - O_OBJS += shuttle_cf.o -endif - -ifeq ($(CONFIG_USB_STORAGE_DPCM),y) - O_OBJS += dpcm.o -endif - include $(TOPDIR)/Rules.make + +usb-storage.o: $(usb-storage-objs) + $(LD) -r -o $@ $(usb-storage-objs) diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 2a5127bb6..9f4693b95 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * Debugging Functions Source Code File * - * $Id: debug.c,v 1.2 2000/07/19 17:21:39 groovyjava Exp $ + * $Id: debug.c,v 1.3 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) * * Initial work by: diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index 04a08be2e..f03c53351 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * Debugging Functions Header File * - * $Id: debug.h,v 1.3 2000/07/19 19:34:48 groovyjava Exp $ + * $Id: debug.h,v 1.4 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) * * Initial work by: diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c index 8b7195bfc..33cb674e2 100644 --- a/drivers/usb/storage/dpcm.c +++ b/drivers/usb/storage/dpcm.c @@ -1,12 +1,12 @@ /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader * - * $Id: dpcm.c,v 1.1 2000/08/08 01:26:12 webbb Exp $ + * $Id: dpcm.c,v 1.3 2000/08/25 00:13:51 mdharm Exp $ * * DPCM driver v0.1: * * First release * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 2000 Brian Webb (webbb@earthlink.net) * * This device contains both a CompactFlash card reader, which @@ -37,7 +37,6 @@ #include "dpcm.h" #include "sddr09.h" - /* * Transport for the Microtech DPCM-USB * diff --git a/drivers/usb/storage/dpcm.h b/drivers/usb/storage/dpcm.h index d6e5f86ad..e6e5637d6 100644 --- a/drivers/usb/storage/dpcm.h +++ b/drivers/usb/storage/dpcm.h @@ -1,12 +1,12 @@ /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader * - * $Id: dpcm.h,v 1.1 2000/08/08 01:26:12 webbb Exp $ + * $Id: dpcm.h,v 1.2 2000/08/25 00:13:51 mdharm Exp $ * * DPCM driver v0.1: * * First release * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 2000 Brian Webb (webbb@earthlink.net) * * See dpcm.c for more explanation diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c new file mode 100644 index 000000000..6b0914cf6 --- /dev/null +++ b/drivers/usb/storage/freecom.c @@ -0,0 +1,375 @@ +/* Driver for Freecom USB/IDE adaptor + * + * $Id: freecom.c,v 1.7 2000/08/25 00:13:51 mdharm Exp $ + * + * Freecom v0.1: + * + * First release + * + * Current development and maintenance by: + * (C) 2000 David Brown + * + * 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. + * + * This driver was developed with information provided in FREECOM's USB + * Programmers Reference Guide. For further information contact Freecom + * (http://www.freecom.de/) + */ + +#include +#include "transport.h" +#include "protocol.h" +#include "usb.h" +#include "debug.h" +#include "freecom.h" + +static void pdump (void *, int); + +struct freecom_udata { + __u8 buffer[64]; /* Common command block. */ +}; +typedef struct freecom_udata *freecom_udata_t; + +/* All of the outgoing packets are 64 bytes long. */ +struct freecom_cb_wrap { + __u8 Type; /* Command type. */ + __u8 Timeout; /* Timeout in seconds. */ + __u8 Atapi[12]; /* An ATAPI packet. */ + __u8 Filler[50]; /* Padding Data. */ +}; + +struct freecom_xfer_wrap { + __u8 Type; /* Command type. */ + __u8 Timeout; /* Timeout in seconds. */ + __u32 Count; /* Number of bytes to transfer. */ + __u8 Pad[58]; +}; + +struct freecom_status { + __u8 Status; + __u8 Reason; + __u16 Count; + __u8 Pad[60]; +}; + +/* These are the packet types. The low bit indicates that this command + * should wait for an interrupt. */ +#define FCM_PACKET_ATAPI 0x21 + +/* Receive data from the IDE interface. The ATAPI packet has already + * waited, so the data should be immediately available. */ +#define FCM_PACKET_INPUT 0x90 + +/* All packets (except for status) are 64 bytes long. */ +#define FCM_PACKET_LENGTH 64 + +static int +freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, + int ipipe, int opipe, int count) +{ + freecom_udata_t extra = (freecom_udata_t) us->extra; + struct freecom_xfer_wrap *fxfr = + (struct freecom_xfer_wrap *) extra->buffer; + int result, partial; + int offset; + __u8 *buffer = extra->buffer; + + fxfr->Type = FCM_PACKET_INPUT | 0x00; + fxfr->Timeout = 0; /* Short timeout for debugging. */ + fxfr->Count = cpu_to_le32 (count); + memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); + + printk (KERN_DEBUG "Read data Freecom! (c=%d)\n", count); + + /* Issue the transfer command. */ + result = usb_stor_bulk_msg (us, fxfr, opipe, + FCM_PACKET_LENGTH, &partial); + if (result != 0) { + US_DEBUGP ("Freecom readdata xpot failure: r=%d, p=%d\n", + result, partial); + + /* -ENOENT -- we canceled this transfer */ + if (result == -ENOENT) { + US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + return US_BULK_TRANSFER_ABORTED; + } + + return USB_STOR_TRANSPORT_ERROR; + } + printk (KERN_DEBUG "Done issuing read request: %d %d\n", + result, partial); + + /* Now transfer all of our blocks. */ + if (srb->use_sg) { + US_DEBUGP ("Need to implement scatter-gather\n"); + return USB_STOR_TRANSPORT_ERROR; + } else { + offset = 0; + + while (offset < count) { + printk (KERN_DEBUG "Start of read\n"); + /* Use the given buffer directly, but only if there + * is space for an entire packet. */ + + if (offset + 64 <= srb->request_bufflen) { + result = usb_stor_bulk_msg ( + us, srb->request_buffer+offset, + ipipe, 64, &partial); + printk (KERN_DEBUG "Read111 = %d, %d\n", + result, partial); + pdump (srb->request_buffer+offset, + partial); + } else { + result = usb_stor_bulk_msg ( + us, buffer, + ipipe, 64, &partial); + printk (KERN_DEBUG "Read112 = %d, %d\n", + result, partial); + memcpy (srb->request_buffer+offset, + buffer, + srb->request_bufflen - offset); + pdump (srb->request_buffer+offset, + srb->request_bufflen - offset); + } + + if (result != 0) { + US_DEBUGP ("Freecom readblock r=%d, p=%d\n", + result, partial); + + /* -ENOENT -- we canceled this transfer */ + if (result == -ENOENT) { + US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + return US_BULK_TRANSFER_ABORTED; + } + + return USB_STOR_TRANSPORT_ERROR; + } + + offset += 64; + } + } + + printk (KERN_DEBUG "freecom_readdata done!\n"); + return USB_STOR_TRANSPORT_GOOD; +} + +/* + * Transport for the Freecom USB/IDE adaptor. + * + */ +int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) +{ + struct freecom_cb_wrap *fcb; + struct freecom_status *fst; + int ipipe, opipe; /* We need both pipes. */ + int result; + int partial; + int length; + freecom_udata_t extra; + + /* Allocate a buffer for us. The upper usb transport code will + * free this for us when cleaning up. */ + if (us->extra == NULL) { + us->extra = kmalloc (sizeof (struct freecom_udata), + GFP_KERNEL); + if (us->extra == NULL) { + printk (KERN_WARNING USB_STORAGE "Out of memory\n"); + return USB_STOR_TRANSPORT_ERROR; + } + } + + extra = (freecom_udata_t) us->extra; + + fcb = (struct freecom_cb_wrap *) extra->buffer; + fst = (struct freecom_status *) extra->buffer; + + printk (KERN_DEBUG "Freecom TRANSPORT STARTED\n"); + + /* Get handles for both transports. */ + opipe = usb_sndbulkpipe (us->pusb_dev, us->ep_out); + ipipe = usb_rcvbulkpipe (us->pusb_dev, us->ep_in); + +#if 0 + /* Yuck, let's see if this helps us. Artificially increase the + * length on this. */ + if (srb->cmnd[0] == 0x03 && srb->cmnd[4] == 0x12) + srb->cmnd[4] = 0x0E; +#endif + + /* The ATAPI Command always goes out first. */ + fcb->Type = FCM_PACKET_ATAPI; + fcb->Timeout = 0; + memcpy (fcb->Atapi, srb->cmnd, 12); + memset (fcb->Filler, 0, sizeof (fcb->Filler)); + + pdump (srb->cmnd, 12); + + /* Send it out. */ + result = usb_stor_bulk_msg (us, fcb, opipe, + FCM_PACKET_LENGTH, &partial); + + /* The Freecom device will only fail if there is something wrong in + * USB land. It returns the status in its own registers, which + * come back in the bulk pipe. */ + if (result != 0) { + US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", + result, partial); + + /* -ENOENT -- we canceled this transfer */ + if (result == -ENOENT) { + US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + return US_BULK_TRANSFER_ABORTED; + } + + return USB_STOR_TRANSPORT_ERROR; + } + + /* There are times we can optimize out this status read, but it + * doesn't hurt us to always do it now. */ + result = usb_stor_bulk_msg (us, fst, ipipe, + FCM_PACKET_LENGTH, &partial); + printk (KERN_DEBUG "foo Status result %d %d\n", result, partial); + /* -ENOENT -- we canceled this transfer */ + if (result == -ENOENT) { + US_DEBUGP("us_transfer_partial(): transfer aborted\n"); + return US_BULK_TRANSFER_ABORTED; + } + + pdump ((void *) fst, partial); + if (partial != 4 || result != 0) { + return USB_STOR_TRANSPORT_ERROR; + } + if ((fst->Reason & 1) != 0) { + printk (KERN_DEBUG "operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + + /* The device might not have as much data available as we + * requested. If you ask for more than the device has, this reads + * and such will hang. */ + printk (KERN_DEBUG "Device indicates that it has %d bytes available\n", + le16_to_cpu (fst->Count)); + + /* Find the length we desire to read. It is the lesser of the SCSI + * layer's requested length, and the length the device claims to + * have available. */ + length = us_transfer_length (srb); + printk (KERN_DEBUG "SCSI requested %d\n", length); + if (length > le16_to_cpu (fst->Count)) + length = le16_to_cpu (fst->Count); + + /* What we do now depends on what direction the data is supposed to + * move in. */ + + switch (us->srb->sc_data_direction) { + case SCSI_DATA_READ: + result = freecom_readdata (srb, us, ipipe, opipe, length); + if (result != USB_STOR_TRANSPORT_GOOD) + return result; + break; + + default: + US_DEBUGP ("freecom unimplemented direction: %d\n", + us->srb->sc_data_direction); + // Return fail, SCSI seems to handle this better. + return USB_STOR_TRANSPORT_FAILED; + break; + } + +#if 0 + /* After the transfer, we can read our status register. */ + printk (KERN_DEBUG "Going to read status register\n"); + result = usb_stor_bulk_msg (us, &fst, ipipe, + FCM_PACKET_LENGTH, &partial); + printk (KERN_DEBUG "Result from read %d %d\n", result, partial); + if (result != 0) { + return USB_STOR_TRANSPORT_ERROR; + } + if ((fst.Reason & 1) != 0) { + return USB_STOR_TRANSPORT_FAILED; + } +#endif + + return USB_STOR_TRANSPORT_GOOD; + + printk (KERN_DEBUG "Freecom: transfer_length = %d\n", + us_transfer_length (srb)); + + printk (KERN_DEBUG "Freecom: direction = %d\n", + srb->sc_data_direction); + + return USB_STOR_TRANSPORT_ERROR; +} + +int usb_stor_freecom_reset(struct us_data *us) +{ + printk (KERN_DEBUG "freecom reset called\n"); + + /* We don't really have this feature. */ + return USB_STOR_TRANSPORT_ERROR; +} + +static void pdump (void *ibuffer, int length) +{ + static char line[80]; + int offset = 0; + unsigned char *buffer = (unsigned char *) ibuffer; + int i, j; + int from, base; + + offset = 0; + for (i = 0; i < length; i++) { + if ((i & 15) == 0) { + if (i > 0) { + offset += sprintf (line+offset, " - "); + for (j = i - 16; j < i; j++) { + if (buffer[j] >= 32 && buffer[j] <= 126) + line[offset++] = buffer[j]; + else + line[offset++] = '.'; + } + line[offset] = 0; + printk (KERN_DEBUG "%s\n", line); + offset = 0; + } + offset += sprintf (line+offset, "%08x:", i); + } + else if ((i & 7) == 0) { + offset += sprintf (line+offset, " -"); + } + offset += sprintf (line+offset, " %02x", buffer[i] & 0xff); + } + + /* Add the last "chunk" of data. */ + from = (length - 1) % 16; + base = ((length - 1) / 16) * 16; + + for (i = from + 1; i < 16; i++) + offset += sprintf (line+offset, " "); + if (from < 8) + offset += sprintf (line+offset, " "); + offset += sprintf (line+offset, " - "); + + for (i = 0; i <= from; i++) { + if (buffer[base+i] >= 32 && buffer[base+i] <= 126) + line[offset++] = buffer[base+i]; + else + line[offset++] = '.'; + } + line[offset] = 0; + printk (KERN_DEBUG "%s\n", line); + offset = 0; +} + diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/freecom.h new file mode 100644 index 000000000..98ac919fa --- /dev/null +++ b/drivers/usb/storage/freecom.h @@ -0,0 +1,35 @@ +/* Driver for Freecom USB/IDE adaptor + * + * $Id: freecom.h,v 1.3 2000/08/25 00:13:51 mdharm Exp $ + * + * Freecom v0.1: + * + * First release + * + * Current development and maintenance by: + * (c) 2000 David Brown + * + * See freecom.c for more explanation + * + * 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 _FREECOM_USB_H +#define _FREECOM_USB_H + +extern int freecom_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int usb_stor_freecom_reset(struct us_data *us); + +#endif diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index aee6b420e..2aa83ea6d 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -1,8 +1,8 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: protocol.c,v 1.4 2000/08/01 22:01:19 mdharm Exp $ + * $Id: protocol.c,v 1.5 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: diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 239d37983..a9306e6c9 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * Protocol Functions Header File * - * $Id: protocol.h,v 1.2 2000/08/01 22:01:19 mdharm Exp $ + * $Id: protocol.h,v 1.3 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) * * This driver is based on the 'USB Mass Storage Class' document. This diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index c823aaed1..9d4f983fc 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * SCSI layer glue code * - * $Id: scsiglue.c,v 1.8 2000/08/11 23:15:05 mdharm Exp $ + * $Id: scsiglue.c,v 1.9 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: diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h index f81787678..13b9f3bec 100644 --- a/drivers/usb/storage/scsiglue.h +++ b/drivers/usb/storage/scsiglue.h @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * SCSI Connecting Glue Header File * - * $Id: scsiglue.h,v 1.3 2000/07/25 23:04:47 mdharm Exp $ + * $Id: scsiglue.h,v 1.4 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) * * This driver is based on the 'USB Mass Storage Class' document. This diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 6bf9f1477..5641a751a 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1,10 +1,12 @@ /* Driver for SanDisk SDDR-09 SmartMedia reader + * + * $Id: sddr09.c,v 1.10 2000/08/25 00:13:51 mdharm Exp $ * * SDDR09 driver v0.1: * * First release * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * * The SanDisk SDDR-09 SmartMedia reader uses the Shuttle EUSB-01 chip. @@ -316,9 +318,9 @@ int sddr09_read_data(struct us_data *us, // Figure out the initial LBA and page - pba = (address/info->pagesize)>>4; + pba = address >> (info->pageshift + info->blockshift); lba = info->pba_to_lba[pba]; - page = (address/info->pagesize)&0x0F; + page = (address >> info->pageshift) & info->blockmask; // This could be made much more efficient by checking for // contiguous LBA's. Another exercise left to the student. @@ -329,15 +331,16 @@ int sddr09_read_data(struct us_data *us, // Read as many sectors as possible in this block - pages = 0x10-page; + pages = info->blocksize - page; if (pages > sectors) pages = sectors; - US_DEBUGP("Read %01X pages, from PBA %04X" - " (LBA %04X) page %01X\n", + US_DEBUGP("Read %02X pages, from PBA %04X" + " (LBA %04X) page %02X\n", pages, pba, lba, page); - address = ((pba<<4)+page)*info->pagesize; + address = ( (pba << info->blockshift) + page ) << + info->pageshift; // Unlike in the documentation, the address is in // words of 2 bytes. @@ -370,7 +373,7 @@ int sddr09_read_data(struct us_data *us, result = sddr09_bulk_transport(us, SCSI_DATA_READ, ptr, - pages*info->pagesize, 0); + pages<pageshift, 0); if (result != USB_STOR_TRANSPORT_GOOD) { if (use_sg) @@ -381,7 +384,7 @@ int sddr09_read_data(struct us_data *us, page = 0; lba++; sectors -= pages; - ptr += pages*info->pagesize; + ptr += (pages << info->pageshift); } if (use_sg) { @@ -435,7 +438,7 @@ int sddr09_read_control(struct us_data *us, result = sddr09_bulk_transport(us, SCSI_DATA_READ, content, - blocks*0x40, use_sg); + blocks<<6, use_sg); // 0x40 bytes per block US_DEBUGP("Result for bulk read in read_control %d\n", result); @@ -525,7 +528,7 @@ int sddr09_reset(struct us_data *us) { } unsigned long sddr09_get_capacity(struct us_data *us, - unsigned int *pagesize) { + unsigned int *pagesize, unsigned int *blocksize) { unsigned char manufacturerID; unsigned char deviceID; @@ -547,6 +550,7 @@ unsigned long sddr09_get_capacity(struct us_data *us, US_DEBUGP("Manuf ID = %02X\n", manufacturerID); *pagesize = 512; + *blocksize = 16; switch (deviceID) { @@ -556,8 +560,8 @@ unsigned long sddr09_get_capacity(struct us_data *us, *pagesize = 256; return 0x00100000; - case 0x5d: // 2MB - case 0xea: + case 0xea: // 2MB + case 0x5d: // 5d is a ROM card with pagesize 512. case 0x64: if (deviceID!=0x5D) *pagesize = 256; @@ -574,9 +578,11 @@ unsigned long sddr09_get_capacity(struct us_data *us, return 0x00800000; case 0x73: // 16MB + *blocksize = 32; return 0x01000000; case 0x75: // 32MB + *blocksize = 32; return 0x02000000; default: // unknown @@ -587,7 +593,7 @@ unsigned long sddr09_get_capacity(struct us_data *us, int sddr09_read_map(struct us_data *us) { - unsigned char *control; + struct scatterlist *sg; struct sddr09_card_info *info = (struct sddr09_card_info *)(us->extra); int numblocks; int i; @@ -599,25 +605,60 @@ int sddr09_read_map(struct us_data *us) { 1, 0, 0, 1, 0, 1, 1, 0 }; int result; + int alloc_len; + int alloc_blocks; if (!info->capacity) return -1; - /* read 64 (2^6) bytes for every block (8192 (2^13) bytes) - of capacity: - 64*(capacity/8192) = capacity*(2^6)*(2^-13) = - capacity*2^(6-13) = capacity*(2^-7) - */ - - control = kmalloc(info->capacity>>7, GFP_KERNEL); + // read 64 (1<<6) bytes for every block + // ( 1 << ( blockshift + pageshift ) bytes) + // of capacity: + // (1<<6)*capacity/(1<<(b+p)) = + // ((1<<6)*capacity)>>(b+p) = + // capacity>>(b+p-6) + + alloc_len = info->capacity >> + (info->blockshift + info->pageshift - 6); + + // Allocate a number of scatterlist structures according to + // the number of 128k blocks in the alloc_len. Adding 128k-1 + // and then dividing by 128k gives the correct number of blocks. + // 128k = 1<<17 + + alloc_blocks = (alloc_len + (1<<17) - 1) >> 17; + sg = kmalloc(alloc_blocks*sizeof(struct scatterlist), + GFP_KERNEL); + if (sg == NULL) + return 0; + for (i=0; icapacity>>13; + numblocks = info->capacity >> (info->blockshift + info->pageshift); if ( (result = sddr09_read_control(us, 0, numblocks, - control, 0)) != + (unsigned char *)sg, alloc_blocks)) != USB_STOR_TRANSPORT_GOOD) { - kfree(control); + for (i=0; ipba_to_lba); info->lba_to_pba = kmalloc(numblocks*sizeof(int), GFP_KERNEL); info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_KERNEL); + + if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { + if (info->lba_to_pba != NULL) + kfree(info->lba_to_pba); + if (info->pba_to_lba != NULL) + kfree(info->pba_to_lba); + info->lba_to_pba = NULL; + info->pba_to_lba = NULL; + for (i=0; ilba_to_pba, 0, numblocks*sizeof(int)); memset(info->pba_to_lba, 0, numblocks*sizeof(int)); + // Each block is 64 bytes of control data, so block i is located in + // scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11) + for (i=0; i>11].address+(i<<6); if (ptr[0]!=0xFF || ptr[1]!=0xFF || ptr[2]!=0xFF || ptr[3]!=0xFF || ptr[4]!=0xFF || ptr[5]!=0xFF) continue; @@ -655,20 +713,30 @@ int sddr09_read_map(struct us_data *us) { lba = (lba&0x07FF)>>1; + /* Every 1024 physical blocks, the LBA numbers + * go back to zero, but are within a higher + * block of LBA's. In other words, in blocks + * 1024-2047 you will find LBA 0-1023 which are + * really LBA 1024-2047. + */ + + lba += (i&~0x3FF); + if (lba>=numblocks) { US_DEBUGP("Bad LBA %04X for block %04X\n", lba, i); continue; } - if (i<0x10) - US_DEBUGP("LBA %04X <-> PBA %04X\n", - lba, i); + if (lba<0x10) + US_DEBUGP("LBA %04X <-> PBA %04X\n", lba, i); info->pba_to_lba[i] = lba; info->lba_to_pba[lba] = i; } - kfree(control); + for (i=0; iextra); -/* - if (us->flags & US_FL_NEED_INIT) { - US_DEBUGP("SDDR-09: initializing\n"); - init_sddr09(us); - us->flags &= ~US_FL_NEED_INIT; - } -*/ - if (!us->extra) { us->extra = kmalloc( sizeof(struct sddr09_card_info), GFP_KERNEL); + if (!us->extra) + return USB_STOR_TRANSPORT_ERROR; memset(us->extra, 0, sizeof(struct sddr09_card_info)); us->extra_destructor = sddr09_card_info_destructor; } @@ -779,14 +840,29 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) respond to INQUIRY commands */ if (srb->cmnd[0] == INQUIRY) { - memcpy(ptr, inquiry_response, 36); + memset(inquiry_response+8, 0, 28); + fill_inquiry_response(us, inquiry_response, 36); return USB_STOR_TRANSPORT_GOOD; } if (srb->cmnd[0] == READ_CAPACITY) { - capacity = sddr09_get_capacity(us, &info->pagesize); + capacity = sddr09_get_capacity(us, &info->pagesize, + &info->blocksize); + + if (!capacity) + return USB_STOR_TRANSPORT_FAILED; + info->capacity = capacity; + for (info->pageshift=1; + (info->pagesize>>info->pageshift); + info->pageshift++); + info->pageshift--; + for (info->blockshift=1; + (info->blocksize>>info->blockshift); + info->blockshift++); + info->blockshift--; + info->blockmask = (1<blockshift)-1; // Last page in the card @@ -836,12 +912,14 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) // convert page to block and page-within-block - lba = page>>4; - page = page&0x0F; + lba = page >> info->blockshift; + page = page & info->blockmask; // locate physical block corresponding to logical block - if (lba>=(info->capacity>>13)) { + if (lba >= + (info->capacity >> + (info->pageshift + info->blockshift) ) ) { // FIXME: sense buffer? @@ -866,8 +944,8 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) pba, lba, page, pages); return sddr09_read_data(us, - ((pba<<4)+page)*info->pagesize, pages, - ptr, srb->use_sg); + ( (pba << info->blockshift) + page) << info->pageshift, + pages, ptr, srb->use_sg); } // Pass TEST_UNIT_READY and REQUEST_SENSE through diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h index ecd9b7611..ac984469f 100644 --- a/drivers/usb/storage/sddr09.h +++ b/drivers/usb/storage/sddr09.h @@ -1,7 +1,9 @@ /* Driver for SanDisk SDDR-09 SmartMedia reader * Header File * - * Current development and maintainance by: + * $Id: sddr09.h,v 1.5 2000/08/25 00:13:51 mdharm Exp $ + * + * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * * See sddr09.c for more explanation @@ -29,10 +31,14 @@ extern int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us); struct sddr09_card_info { - unsigned long capacity; /* Size of card in bytes */ - int pagesize; /* Size of page in bytes */ - int *lba_to_pba; /* logical to physical map */ - int *pba_to_lba; /* physical to logical map */ + unsigned long capacity; /* Size of card in bytes */ + int pagesize; /* Size of page in bytes */ + int pageshift; /* log2 of pagesize */ + int blocksize; /* Size of block in pages */ + int blockshift; /* log2 of blocksize */ + int blockmask; /* 2^blockshift - 1 */ + int *lba_to_pba; /* logical to physical map */ + int *pba_to_lba; /* physical to logical map */ }; #endif diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 492bc7259..6a96ad0a7 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1,6 +1,6 @@ /* Driver for SCM Microsystems USB-ATAPI cable * - * $Id: shuttle_usbat.c,v 1.2 2000/08/03 00:03:39 groovyjava Exp $ + * $Id: shuttle_usbat.c,v 1.4 2000/08/25 00:13:51 mdharm Exp $ * * SCM driver v0.2: * @@ -14,7 +14,7 @@ * * First release - hp8200e. * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * * Many originally ATAPI devices were slightly modified to meet the USB @@ -734,7 +734,7 @@ static int hp_8200e_select_and_test_registers(struct us_data *us) { return result; } -static int init_8200e(struct us_data *us) { +int init_8200e(struct us_data *us) { int result; unsigned char status; @@ -895,11 +895,11 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us) "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */ "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */ - if (us->flags & US_FL_NEED_INIT) { +/* if (us->flags & US_FL_NEED_INIT) { US_DEBUGP("8200e: initializing\n"); init_8200e(us); us->flags &= ~US_FL_NEED_INIT; - } + } */ len = srb->request_bufflen; diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h index ff5c07541..4bd2673c6 100644 --- a/drivers/usb/storage/shuttle_usbat.h +++ b/drivers/usb/storage/shuttle_usbat.h @@ -1,9 +1,9 @@ /* Driver for SCM Microsystems USB-ATAPI cable * Header File * - * $Id: shuttle_usbat.h,v 1.2 2000/08/03 00:03:39 groovyjava Exp $ + * $Id: shuttle_usbat.h,v 1.4 2000/08/25 00:13:51 mdharm Exp $ * - * Current development and maintainance by: + * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * * See scm.c for more explanation @@ -74,5 +74,6 @@ extern int usbat_write_user_io(struct us_data *us, /* HP 8200e stuff */ extern int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us); +extern int init_8200e(struct us_data *us); #endif diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index dd3c489f1..cad9253b3 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1,8 +1,8 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: transport.c,v 1.12 2000/08/08 15:22:38 gowdy Exp $ + * $Id: transport.c,v 1.18 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: @@ -59,43 +59,7 @@ /* Calculate the length of the data transfer (not the command) for any * given SCSI command */ -static unsigned int us_transfer_length(Scsi_Cmnd *srb, struct us_data *us) -{ - int i; - unsigned int total = 0; - struct scatterlist *sg; - - /* support those devices which need the length calculated - * differently - */ - if (srb->cmnd[0] == INQUIRY) { - srb->cmnd[4] = 36; - } - - if ((srb->cmnd[0] == INQUIRY) || (srb->cmnd[0] == MODE_SENSE)) - return srb->cmnd[4]; - - if (srb->cmnd[0] == TEST_UNIT_READY) - return 0; - - /* Are we going to scatter gather? */ - if (srb->use_sg) { - /* Add up the sizes of all the scatter-gather segments */ - sg = (struct scatterlist *) srb->request_buffer; - for (i = 0; i < srb->use_sg; i++) - total += sg[i].length; - - return total; - } - else - /* Just return the length of the buffer */ - return srb->request_bufflen; -} - -/* Calculate the length of the data transfer (not the command) for any - * given SCSI command - */ -static unsigned int us_transfer_length_new(Scsi_Cmnd *srb, struct us_data *us) +static unsigned int us_transfer_length(Scsi_Cmnd *srb) { int i; int doDefault = 0; @@ -245,10 +209,6 @@ static unsigned int us_transfer_length_new(Scsi_Cmnd *srb, struct us_data *us) WRITE_SAME 41 */ - /* Not sure this is right as an INQUIRY can contain nonstandard info */ - if (srb->cmnd[0] == INQUIRY) - srb->cmnd[4] = 36; - if (srb->sc_data_direction == SCSI_DATA_WRITE) { doDefault = 1; } @@ -611,6 +571,16 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) int i; int result = -1; struct scatterlist *sg; + unsigned int total_transferred = 0; + unsigned int transfer_amount; + + /* calculate how much we want to transfer */ + transfer_amount = us_transfer_length(srb); + + /* was someone foolish enough to request more data than available + * buffer space? */ + if (transfer_amount > srb->request_bufflen) + transfer_amount = srb->request_bufflen; /* are we scatter-gathering? */ if (srb->use_sg) { @@ -620,8 +590,19 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) */ sg = (struct scatterlist *) srb->request_buffer; for (i = 0; i < srb->use_sg; i++) { - result = us_transfer_partial(us, sg[i].address, - sg[i].length); + + /* transfer the lesser of the next buffer or the + * remaining data */ + if (transfer_amount - total_transferred >= + sg[i].length) { + result = us_transfer_partial(us, sg[i].address, + sg[i].length); + total_transferred += sg[i].length; + } else + result = us_transfer_partial(us, sg[i].address, + transfer_amount - total_transferred); + + /* if we get an error, end the loop here */ if (result) break; } @@ -629,7 +610,7 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us) else /* no scatter-gather, just make the request */ result = us_transfer_partial(us, srb->request_buffer, - srb->request_bufflen); + transfer_amount); /* return the result in the data structure itself */ srb->result = result; @@ -874,7 +855,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ - if (us_transfer_length(srb, us)) { + if (us_transfer_length(srb)) { us_transfer(srb, us); US_DEBUGP("CBI data stage result is 0x%x\n", srb->result); @@ -975,7 +956,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) /* DATA STAGE */ /* transfer the data payload for this command, if one exists*/ - if (us_transfer_length(srb, us)) { + if (us_transfer_length(srb)) { us_transfer(srb, us); US_DEBUGP("CB data stage result is 0x%x\n", srb->result); @@ -1039,10 +1020,12 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) /* set up the command wrapper */ bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb.DataTransferLength = cpu_to_le32(us_transfer_length(srb, us)); + bcb.DataTransferLength = cpu_to_le32(us_transfer_length(srb)); bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0; bcb.Tag = srb->serial_number; bcb.Lun = srb->cmnd[1] >> 5; + if (us->flags & US_FL_SCM_MULT_TARG) + bcb.Lun |= srb->target << 4; bcb.Length = srb->cmd_len; /* construct the pipe handle */ @@ -1053,8 +1036,9 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) memcpy(bcb.CDB, srb->cmnd, bcb.Length); /* send it to out endpoint */ - US_DEBUGP("Bulk command S 0x%x T 0x%x LUN %d L %d F %d CL %d\n", - le32_to_cpu(bcb.Signature), bcb.Tag, bcb.Lun, + US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n", + le32_to_cpu(bcb.Signature), bcb.Tag, + (bcb.Lun >> 4), (bcb.Lun & 0xFF), bcb.DataTransferLength, bcb.Flags, bcb.Length); result = usb_stor_bulk_msg(us, &bcb, pipe, US_BULK_CB_WRAP_LEN, &partial); diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 4615569f3..3f300053d 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * Transport Functions Header File * - * $Id: transport.h,v 1.8 2000/08/08 01:23:55 webbb Exp $ + * $Id: transport.h,v 1.11 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) * * This driver is based on the 'USB Mass Storage Class' document. This @@ -41,8 +41,8 @@ #ifndef _TRANSPORT_H_ #define _TRANSPORT_H_ -#include #include +#include #include "usb.h" #include "scsi.h" @@ -60,6 +60,10 @@ #endif #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ +#ifdef CONFIG_USB_STORAGE_FREECOM +#define US_PR_FREECOM 0xf1 /* Freecom */ +#endif + /* * Bulk only data structures */ 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 #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 #include #include #include #include +#include /* Some informational data */ MODULE_AUTHOR("Matthew Dharm "); @@ -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, diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 435ad9777..38b0d420a 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -1,9 +1,9 @@ /* Driver for USB Mass Storage compliant devices * Main Header File * - * $Id: usb.h,v 1.7 2000/08/15 00:06:38 mdharm Exp $ + * $Id: usb.h,v 1.8 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) * * Initial work by: -- cgit v1.2.3