summaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-08-28 22:00:09 +0000
commit1a1d77dd589de5a567fa95e36aa6999c704ceca4 (patch)
tree141e31f89f18b9fe0831f31852e0435ceaccafc5 /drivers/usb/storage
parentfb9c690a18b3d66925a65b17441c37fa14d4370b (diff)
Merge with 2.4.0-test7.
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/Makefile6
-rw-r--r--drivers/usb/storage/dpcm.c83
-rw-r--r--drivers/usb/storage/dpcm.h34
-rw-r--r--drivers/usb/storage/scsiglue.c8
-rw-r--r--drivers/usb/storage/shuttle_usbat.c2
-rw-r--r--drivers/usb/storage/shuttle_usbat.h2
-rw-r--r--drivers/usb/storage/transport.c435
-rw-r--r--drivers/usb/storage/transport.h5
-rw-r--r--drivers/usb/storage/usb.c285
-rw-r--r--drivers/usb/storage/usb.h20
10 files changed, 752 insertions, 128 deletions
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 7da59f78e..e7761863e 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -5,6 +5,7 @@
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/
@@ -13,6 +14,7 @@ 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
@@ -37,5 +39,9 @@ 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
diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c
new file mode 100644
index 000000000..8b7195bfc
--- /dev/null
+++ b/drivers/usb/storage/dpcm.c
@@ -0,0 +1,83 @@
+/* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader
+ *
+ * $Id: dpcm.c,v 1.1 2000/08/08 01:26:12 webbb Exp $
+ *
+ * DPCM driver v0.1:
+ *
+ * First release
+ *
+ * Current development and maintainance by:
+ * (c) 2000 Brian Webb (webbb@earthlink.net)
+ *
+ * This device contains both a CompactFlash card reader, which
+ * usest the Control/Bulk w/o Interrupt protocol and
+ * a SmartMedia card reader that uses the same protocol
+ * as the SDDR09.
+ *
+ * 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 <linux/config.h>
+#include "transport.h"
+#include "protocol.h"
+#include "usb.h"
+#include "debug.h"
+#include "dpcm.h"
+#include "sddr09.h"
+
+
+/*
+ * Transport for the Microtech DPCM-USB
+ *
+ */
+int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+ int ret;
+
+ if(srb == NULL)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ US_DEBUGP("dpcm_transport: LUN=%d\n", srb->lun);
+
+ switch(srb->lun) {
+ case 0:
+
+ /*
+ * LUN 0 corresponds to the CompactFlash card reader.
+ */
+ return usb_stor_CB_transport(srb, us);
+
+#ifdef CONFIG_USB_STORAGE_SDDR09
+ case 1:
+
+ /*
+ * LUN 1 corresponds to the SmartMedia card reader.
+ */
+
+ /*
+ * Set the LUN to 0 (just in case).
+ */
+ srb->lun = 0; us->srb->lun = 0;
+ ret = sddr09_transport(srb, us);
+ srb->lun = 1; us->srb->lun = 1;
+
+ return ret;
+#endif
+
+ default:
+ US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->lun);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+}
diff --git a/drivers/usb/storage/dpcm.h b/drivers/usb/storage/dpcm.h
new file mode 100644
index 000000000..d6e5f86ad
--- /dev/null
+++ b/drivers/usb/storage/dpcm.h
@@ -0,0 +1,34 @@
+/* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader
+ *
+ * $Id: dpcm.h,v 1.1 2000/08/08 01:26:12 webbb Exp $
+ *
+ * DPCM driver v0.1:
+ *
+ * First release
+ *
+ * Current development and maintainance by:
+ * (c) 2000 Brian Webb (webbb@earthlink.net)
+ *
+ * See dpcm.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 _MICROTECH_DPCM_USB_H
+#define _MICROTECH_DPCM_USB_H
+
+extern int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us);
+
+#endif
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 7517d63bc..c823aaed1 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -1,7 +1,7 @@
/* Driver for USB Mass Storage compliant devices
* SCSI layer glue code
*
- * $Id: scsiglue.c,v 1.7 2000/07/28 20:33:18 gowdy Exp $
+ * $Id: scsiglue.c,v 1.8 2000/08/11 23:15:05 mdharm Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -189,6 +189,12 @@ static int command_abort( Scsi_Cmnd *srb )
return SUCCESS;
}
+ /* This is a sanity check that we should never hit */
+ if (in_interrupt()) {
+ printk(KERN_ERR "usb-storage: command_abort() called from an interrupt!!! BAD!!! BAD!! BAD!!\n");
+ return FAILED;
+ }
+
/* if we have an urb pending, let's wake the control thread up */
if (us->current_urb->status == -EINPROGRESS) {
/* cancel the URB */
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index f68595c47..492bc7259 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -1,5 +1,7 @@
/* Driver for SCM Microsystems USB-ATAPI cable
*
+ * $Id: shuttle_usbat.c,v 1.2 2000/08/03 00:03:39 groovyjava Exp $
+ *
* SCM driver v0.2:
*
* Removed any reference to maxlen for bulk transfers.
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
index eede2651f..ff5c07541 100644
--- a/drivers/usb/storage/shuttle_usbat.h
+++ b/drivers/usb/storage/shuttle_usbat.h
@@ -1,6 +1,8 @@
/* Driver for SCM Microsystems USB-ATAPI cable
* Header File
*
+ * $Id: shuttle_usbat.h,v 1.2 2000/08/03 00:03:39 groovyjava Exp $
+ *
* Current development and maintainance by:
* (c) 2000 Robert Baruch (autophile@dol.net)
*
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index a0fb2407c..dd3c489f1 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -1,12 +1,13 @@
/* Driver for USB Mass Storage compliant devices
*
- * $Id: transport.c,v 1.5 2000/07/28 22:40:20 mdharm Exp $
+ * $Id: transport.c,v 1.12 2000/08/08 15:22:38 gowdy Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
*
* Developed with the assistance of:
* (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
+ * (c) 2000 Stephen J. Gowdy (SGowdy@lbl.gov)
*
* Initial work by:
* (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -52,6 +53,353 @@
#include <linux/malloc.h>
/***********************************************************************
+ * Helper routines
+ ***********************************************************************/
+
+/* 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)
+{
+ int i;
+ int doDefault = 0;
+ unsigned int len = 0;
+ unsigned int total = 0;
+ struct scatterlist *sg;
+
+ /* This table tells us:
+ X = command not supported
+ L = return length in cmnd[4] (8 bits).
+ M = return length in cmnd[8] (8 bits).
+ G = return length in cmnd[3] and cmnd[4] (16 bits)
+ H = return length in cmnd[7] and cmnd[8] (16 bits)
+ I = return length in cmnd[8] and cmnd[9] (16 bits)
+ C = return length in cmnd[2] to cmnd[5] (32 bits)
+ D = return length in cmnd[6] to cmnd[9] (32 bits)
+ B = return length in blocksize so we use buff_len
+ R = return length in cmnd[2] to cmnd[4] (24 bits)
+ S = return length in cmnd[3] to cmnd[5] (24 bits)
+ T = return length in cmnd[6] to cmnd[8] (24 bits)
+ U = return length in cmnd[7] to cmnd[9] (24 bits)
+ 0-9 = fixed return length
+ V = 20 bytes
+ W = 24 bytes
+ Z = return length is mode dependant or not in command, use buff_len
+ */
+
+ static char *lengths =
+
+ /* 0123456789ABCDEF 0123456789ABCDEF */
+
+ "00XLZ6XZBXBBXXXB" "00LBBLG0R0L0GG0X" /* 00-1F */
+ "XXXXT8XXB4B0BBBB" "ZZZ0B00HCSSZTBHH" /* 20-3F */
+ "M0HHB0X000H0HH0X" "XHH00HXX0TH0H0XX" /* 40-5F */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 60-7F */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 80-9F */
+ "X0XXX00XB0BXBXBB" "ZZZ0XUIDU000XHBX" /* A0-BF */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */
+ "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
+
+ /* Commands checked in table:
+
+ CHANGE_DEFINITION 40
+ COMPARE 39
+ COPY 18
+ COPY_AND_VERIFY 3a
+ ERASE 19
+ ERASE_10 2c
+ ERASE_12 ac
+ EXCHANGE_MEDIUM a6
+ FORMAT_UNIT 04
+ GET_DATA_BUFFER_STATUS 34
+ GET_MESSAGE_10 28
+ GET_MESSAGE_12 a8
+ GET_WINDOW 25 !!! Has more data than READ_CAPACITY, need to fix table
+ INITIALIZE_ELEMENT_STATUS 07 !!! REASSIGN_BLOCKS luckily uses buff_len
+ INQUIRY 12
+ LOAD_UNLOAD 1b
+ LOCATE 2b
+ LOCK_UNLOCK_CACHE 36
+ LOG_SELECT 4c
+ LOG_SENSE 4d
+ MEDIUM_SCAN 38 !!! This was M
+ MODE_SELECT6 15
+ MODE_SELECT_10 55
+ MODE_SENSE_6 1a
+ MODE_SENSE_10 5a
+ MOVE_MEDIUM a5
+ OBJECT_POSITION 31 !!! Same as SEARCH_DATA_EQUAL
+ PAUSE_RESUME 4b
+ PLAY_AUDIO_10 45
+ PLAY_AUDIO_12 a5
+ PLAY_AUDIO_MSF 47
+ PLAY_AUDIO_TRACK_INDEX 48
+ PLAY_AUDIO_TRACK_RELATIVE_10 49
+ PLAY_AUDIO_TRACK_RELATIVE_12 a9
+ POSITION_TO_ELEMENT 2b
+ PRE-FETCH 34
+ PREVENT_ALLOW_MEDIUM_REMOVAL 1e
+ PRINT 0a !!! Same as WRITE_6 but is always in bytes
+ READ_6 08
+ READ_10 28
+ READ_12 a8
+ READ_BLOCK_LIMITS 05
+ READ_BUFFER 3c
+ READ_CAPACITY 25
+ READ_CDROM_CAPACITY 25
+ READ_DEFECT_DATA 37
+ READ_DEFECT_DATA_12 b7
+ READ_ELEMENT_STATUS b8 !!! Think this is in bytes
+ READ_GENERATION 29 !!! Could also be M?
+ READ_HEADER 44 !!! This was L
+ READ_LONG 3e
+ READ_POSITION 34 !!! This should be V but conflicts with PRE-FETCH
+ READ_REVERSE 0f
+ READ_SUB-CHANNEL 42 !!! Is this in bytes?
+ READ_TOC 43 !!! Is this in bytes?
+ READ_UPDATED_BLOCK 2d
+ REASSIGN_BLOCKS 07
+ RECEIVE 08 !!! Same as READ_6 probably in bytes though
+ RECEIVE_DIAGNOSTIC_RESULTS 1c
+ RECOVER_BUFFERED_DATA 14 !!! For PRINTERs this is bytes
+ RELEASE_UNIT 17
+ REQUEST_SENSE 03
+ REQUEST_VOLUME_ELEMENT_ADDRESS b5 !!! Think this is in bytes
+ RESERVE_UNIT 16
+ REWIND 01
+ REZERO_UNIT 01
+ SCAN 1b !!! Conflicts with various commands, should be L
+ SEARCH_DATA_EQUAL 31
+ SEARCH_DATA_EQUAL_12 b1
+ SEARCH_DATA_LOW 30
+ SEARCH_DATA_LOW_12 b0
+ SEARCH_DATA_HIGH 32
+ SEARCH_DATA_HIGH_12 b2
+ SEEK_6 0b !!! Conflicts with SLEW_AND_PRINT
+ SEEK_10 2b
+ SEND 0a !!! Same as WRITE_6, probably in bytes though
+ SEND 2a !!! Similar to WRITE_10 but for scanners
+ SEND_DIAGNOSTIC 1d
+ SEND_MESSAGE_6 0a !!! Same as WRITE_6 - is in bytes
+ SEND_MESSAGE_10 2a !!! Same as WRITE_10 - is in bytes
+ SEND_MESSAGE_12 aa !!! Same as WRITE_12 - is in bytes
+ SEND_VOLUME_TAG b6 !!! Think this is in bytes
+ SET_LIMITS 33
+ SET_LIMITS_12 b3
+ SET_WINDOW 24
+ SLEW_AND_PRINT 0b !!! Conflicts with SEEK_6
+ SPACE 11
+ START_STOP_UNIT 1b
+ STOP_PRINT 1b
+ SYNCHRONIZE_BUFFER 10
+ SYNCHRONIZE_CACHE 35
+ TEST_UNIT_READY 00
+ UPDATE_BLOCK 3d
+ VERIFY 13
+ VERIFY 2f
+ VERIFY_12 af
+ WRITE_6 0a
+ WRITE_10 2a
+ WRITE_12 aa
+ WRITE_AND_VERIFY 2e
+ WRITE_AND_VERIFY_12 ae
+ WRITE_BUFFER 3b
+ WRITE_FILEMARKS 10
+ WRITE_LONG 3f
+ 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;
+ }
+ else
+ switch (lengths[srb->cmnd[0]]) {
+ case 'L':
+ len = srb->cmnd[4];
+ break;
+
+ case 'M':
+ len = srb->cmnd[8];
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ len = lengths[srb->cmnd[0]]-'0';
+ break;
+
+ case 'G':
+ len = (((unsigned int)srb->cmnd[3])<<8) |
+ srb->cmnd[4];
+ break;
+
+ case 'H':
+ len = (((unsigned int)srb->cmnd[7])<<8) |
+ srb->cmnd[8];
+ break;
+
+ case 'I':
+ len = (((unsigned int)srb->cmnd[8])<<8) |
+ srb->cmnd[9];
+ break;
+
+ case 'R':
+ len = (((unsigned int)srb->cmnd[2])<<16) |
+ (((unsigned int)srb->cmnd[3])<<8) |
+ srb->cmnd[4];
+ break;
+
+ case 'S':
+ len = (((unsigned int)srb->cmnd[3])<<16) |
+ (((unsigned int)srb->cmnd[4])<<8) |
+ srb->cmnd[5];
+ break;
+
+ case 'T':
+ len = (((unsigned int)srb->cmnd[6])<<16) |
+ (((unsigned int)srb->cmnd[7])<<8) |
+ srb->cmnd[8];
+ break;
+
+ case 'U':
+ len = (((unsigned int)srb->cmnd[7])<<16) |
+ (((unsigned int)srb->cmnd[8])<<8) |
+ srb->cmnd[9];
+ break;
+
+ case 'C':
+ len = (((unsigned int)srb->cmnd[2])<<24) |
+ (((unsigned int)srb->cmnd[3])<<16) |
+ (((unsigned int)srb->cmnd[4])<<8) |
+ srb->cmnd[5];
+ break;
+
+ case 'D':
+ len = (((unsigned int)srb->cmnd[6])<<24) |
+ (((unsigned int)srb->cmnd[7])<<16) |
+ (((unsigned int)srb->cmnd[8])<<8) |
+ srb->cmnd[9];
+ break;
+
+ case 'V':
+ len = 20;
+ break;
+
+ case 'W':
+ len = 24;
+ break;
+
+ case 'B':
+ /* Use buffer size due to different block sizes */
+ doDefault = 1;
+ break;
+
+ case 'X':
+ US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
+ srb->cmnd[0]);
+ doDefault = 1;
+ break;
+
+ case 'Z':
+ /* Use buffer size due to mode dependence */
+ doDefault = 1;
+ break;
+
+ default:
+ US_DEBUGP("Error: COMMAND %02X out of range or table inconsistent (%c).\n",
+ srb->cmnd[0], lengths[srb->cmnd[0]] );
+ doDefault = 1;
+ }
+
+ if ( doDefault == 1 ) {
+ /* Are we going to scatter gather? */
+ if (srb->use_sg) {
+ /* Add up the sizes of all the sg segments */
+ sg = (struct scatterlist *) srb->request_buffer;
+ for (i = 0; i < srb->use_sg; i++)
+ total += sg[i].length;
+ len = total;
+ }
+ else
+ /* Just return the length of the buffer */
+ len = srb->request_bufflen;
+ }
+
+ return len;
+}
+
+/* This is a version of usb_clear_halt() that doesn't read the status from
+ * the device -- this is because some devices crash their internal firmware
+ * when the status is requested after a halt
+ */
+static int clear_halt(struct usb_device *dev, int pipe)
+{
+ int result;
+ int endp = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
+
+ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0,
+ endp, NULL, 0, HZ * 3);
+
+ /* this is a failure case */
+ if (result < 0)
+ return result;
+
+ /* reset the toggles and endpoint flags */
+ usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+
+ return 0;
+}
+
+/***********************************************************************
* Data transfer routines
***********************************************************************/
@@ -217,7 +565,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length)
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
- usb_clear_halt(us->pusb_dev, pipe);
+ clear_halt(us->pusb_dev, pipe);
}
/* did we send all the data? */
@@ -287,44 +635,6 @@ static void us_transfer(Scsi_Cmnd *srb, struct us_data* us)
srb->result = result;
}
-/* 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 (us->flags & US_FL_ALT_LENGTH) {
- 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;
-}
-
/***********************************************************************
* Transport routines
***********************************************************************/
@@ -363,7 +673,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* of determining status on it's own, we need to auto-sense almost
* every time.
*/
- if (us->protocol == US_PR_CB) {
+ if (us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) {
US_DEBUGP("-- CB transport device requiring auto-sense\n");
need_auto_sense = 1;
@@ -490,7 +800,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* This is necessary because the auto-sense for some devices always
* sets byte 0 == 0x70, even if there is no error
*/
- if ((us->protocol == US_PR_CB) &&
+ if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) &&
(result == USB_STOR_TRANSPORT_GOOD) &&
((srb->sense_buffer[2] & 0xf) == 0x0))
srb->sense_buffer[0] = 0x0;
@@ -548,10 +858,10 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* STALL must be cleared when they are detected */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe. Clearing\n");
- result = usb_clear_halt(us->pusb_dev,
- usb_sndctrlpipe(us->pusb_dev,
- 0));
- US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+ result = clear_halt(us->pusb_dev,
+ usb_sndctrlpipe(us->pusb_dev,
+ 0));
+ US_DEBUGP("-- clear_halt() returns %d\n", result);
return USB_STOR_TRANSPORT_FAILED;
}
@@ -652,10 +962,10 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
/* a stall is a fatal condition from the device */
if (result == -EPIPE) {
US_DEBUGP("-- Stall on control pipe. Clearing\n");
- result = usb_clear_halt(us->pusb_dev,
- usb_sndctrlpipe(us->pusb_dev,
- 0));
- US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+ result = clear_halt(us->pusb_dev,
+ usb_sndctrlpipe(us->pusb_dev,
+ 0));
+ US_DEBUGP("-- clear_halt() returns %d\n", result);
return USB_STOR_TRANSPORT_FAILED;
}
@@ -710,7 +1020,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
/* if we get a STALL, clear the stall */
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
- usb_clear_halt(us->pusb_dev, pipe);
+ clear_halt(us->pusb_dev, pipe);
}
/* return the default -- no LUNs */
@@ -757,7 +1067,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
- usb_clear_halt(us->pusb_dev, pipe);
+ clear_halt(us->pusb_dev, pipe);
} else if (result) {
/* unknown error -- we've got a problem */
return USB_STOR_TRANSPORT_ERROR;
@@ -796,7 +1106,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* did the attempt to read the CSW fail? */
if (result == -EPIPE) {
US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
- usb_clear_halt(us->pusb_dev, pipe);
+ clear_halt(us->pusb_dev, pipe);
/* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n");
@@ -810,7 +1120,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* if it fails again, we need a reset and return an error*/
if (result == -EPIPE) {
US_DEBUGP("clearing halt for pipe 0x%x\n", pipe);
- usb_clear_halt(us->pusb_dev, pipe);
+ clear_halt(us->pusb_dev, pipe);
return USB_STOR_TRANSPORT_ERROR;
}
}
@@ -877,10 +1187,10 @@ int usb_stor_CB_reset(struct us_data *us)
schedule_timeout(HZ*6);
US_DEBUGP("CB_reset: clearing endpoint halt\n");
- usb_clear_halt(us->pusb_dev,
- usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
- usb_clear_halt(us->pusb_dev,
- usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
+ clear_halt(us->pusb_dev,
+ usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+ clear_halt(us->pusb_dev,
+ usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
US_DEBUGP("CB_reset done\n");
return 0;
@@ -904,14 +1214,13 @@ int usb_stor_Bulk_reset(struct us_data *us)
if (result < 0)
US_DEBUGP("Bulk hard reset failed %d\n", result);
- usb_clear_halt(us->pusb_dev,
- usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
- usb_clear_halt(us->pusb_dev,
- usb_sndbulkpipe(us->pusb_dev, us->ep_out));
+ clear_halt(us->pusb_dev,
+ usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+ clear_halt(us->pusb_dev,
+ usb_sndbulkpipe(us->pusb_dev, us->ep_out));
/* long wait for reset */
schedule_timeout(HZ*6);
return result;
}
-
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index 9d0993c1e..4615569f3 100644
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -1,7 +1,7 @@
/* Driver for USB Mass Storage compliant devices
* Transport Functions Header File
*
- * $Id: transport.h,v 1.6 2000/07/27 14:42:43 groovyjava Exp $
+ * $Id: transport.h,v 1.8 2000/08/08 01:23:55 webbb Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -58,6 +58,7 @@
#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for
SDDR-09 */
#endif
+#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
/*
* Bulk only data structures
@@ -133,4 +134,6 @@ extern int usb_stor_Bulk_reset(struct us_data*);
void usb_stor_invoke_transport(Scsi_Cmnd *, struct us_data *);
+extern int dpcm_transport(Scsi_Cmnd *srb, struct us_data *us);
+
#endif
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index fc70bc72a..50ebddd6f 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -1,6 +1,6 @@
/* Driver for USB Mass Storage compliant devices
*
- * $Id: usb.c,v 1.16 2000/08/01 22:01:19 mdharm Exp $
+ * $Id: usb.c,v 1.23 2000/08/08 20:46:45 mdharm Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -44,7 +44,6 @@
*/
#include <linux/config.h>
-
#include "usb.h"
#include "scsiglue.h"
#include "transport.h"
@@ -56,6 +55,9 @@
#ifdef CONFIG_USB_STORAGE_SDDR09
#include "sddr09.h"
#endif
+#ifdef CONFIG_USB_STORAGE_DPCM
+#include "dpcm.h"
+#endif
#include <linux/module.h>
#include <linux/sched.h>
@@ -63,6 +65,10 @@
#include <linux/init.h>
#include <linux/malloc.h>
+/* Some informational data */
+MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
+MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
+
/*
* Per device data
*/
@@ -91,6 +97,58 @@ static struct usb_driver storage_driver = {
disconnect: storage_disconnect,
};
+/*
+ * fill_inquiry_response takes an unsigned char array (which must
+ * be at least 36 characters) and populates the vendor name,
+ * product name, and revision fields. Then the array is copied
+ * into the SCSI command's response buffer (oddly enough
+ * called request_buffer). data_len contains the length of the
+ * data array, which again must be at least 36.
+ */
+
+void fill_inquiry_response(struct us_data *us, unsigned char *data,
+ unsigned int data_len) {
+
+ int i;
+ struct scatterlist *sg;
+ int len =
+ us->srb->request_bufflen > data_len ? data_len :
+ us->srb->request_bufflen;
+ int transferred;
+ int amt;
+
+ if (data_len<36) // You lose.
+ return;
+
+ memcpy(data+8, us->unusual_dev->vendorName,
+ strlen(us->unusual_dev->vendorName) > 8 ? 8 :
+ strlen(us->unusual_dev->vendorName));
+ memcpy(data+16, us->unusual_dev->productName,
+ strlen(us->unusual_dev->productName) > 16 ? 16 :
+ strlen(us->unusual_dev->productName));
+ data[32] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>12) & 0x0F);
+ data[33] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>8) & 0x0F);
+ data[34] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice>>4) & 0x0F);
+ data[35] = 0x30 + ((us->pusb_dev->descriptor.bcdDevice) & 0x0F);
+
+ if (us->srb->use_sg) {
+ sg = (struct scatterlist *)us->srb->request_buffer;
+ for (i=0; i<us->srb->use_sg; i++)
+ memset(sg[i].address, 0, sg[i].length);
+ for (i=0, transferred=0;
+ i<us->srb->use_sg && transferred < len;
+ i++) {
+ amt = sg[i].length > len-transferred ?
+ len-transferred : sg[i].length;
+ memcpy(sg[i].address, data+transferred, amt);
+ transferred -= amt;
+ }
+ } else {
+ memset(us->srb->request_buffer, 0, us->srb->request_bufflen);
+ memcpy(us->srb->request_buffer, data, len);
+ }
+}
+
static int usb_stor_control_thread(void * __us)
{
wait_queue_t wait;
@@ -176,7 +234,7 @@ static int usb_stor_control_thread(void * __us)
us->srb = NULL;
break;
}
-
+
/* lock the device pointers */
down(&(us->dev_semaphore));
@@ -246,50 +304,140 @@ static int usb_stor_control_thread(void * __us)
}
/* This is the list of devices we recognize, along with their flag data */
+
+/* The vendor name should be kept at eight characters or less, and
+ * the product name should be kept at 16 characters or less. If a device
+ * has the US_FL_DUMMY_INQUIRY flag, then the vendor and product names
+ * normally generated by a device thorugh the INQUIRY response will be
+ * taken from this list, and this is the reason for the above size
+ * restriction. However, if the flag is not present, then you
+ * are free to use as many characters as you like.
+ */
+
static struct us_unusual_dev us_unusual_dev_list[] = {
- { 0x03f0, 0x0107, 0x0200, 0x0200, "HP USB CD-Writer Plus",
- US_SC_8070, US_PR_CB, 0},
+
+ { 0x03f0, 0x0107, 0x0200, 0x0200,
+ "HP",
+ "CD-Writer+",
+ US_SC_8070, US_PR_CB, NULL,
+ 0},
+
#ifdef CONFIG_USB_STORAGE_HP8200e
- { 0x03f0, 0x0207, 0x0001, 0x0001, "HP USB CD-Writer Plus 8200e",
- US_SC_8070, US_PR_SCM_ATAPI,
- US_FL_ALT_LENGTH | US_FL_NEED_INIT | US_FL_SINGLE_LUN},
+ { 0x03f0, 0x0207, 0x0001, 0x0001,
+ "HP",
+ "CD-Writer+ 8200e",
+ US_SC_8070, US_PR_SCM_ATAPI, init_8200e,
+ US_FL_SINGLE_LUN},
#endif
- { 0x04e6, 0x0001, 0x0200, 0x0200, "Matshita LS-120",
- US_SC_8020, US_PR_CB, US_FL_SINGLE_LUN},
- { 0x04e6, 0x0002, 0x0100, 0x0100, "Shuttle eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0x04e6, 0x0006, 0x0100, 0x0100, "Shuttle eUSB MMC Adapter",
- US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN},
- { 0x054c, 0x0010, 0x0210, 0x0210, "Sony DSC-S30/S70",
- US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP |
- US_FL_MODE_XLATE | US_FL_ALT_LENGTH | US_FL_ALT_LENGTH},
- { 0x054c, 0x002d, 0x0100, 0x0100, "Sony Memorystick MSAC-US1",
- US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP |
- US_FL_MODE_XLATE | US_FL_ALT_LENGTH},
- { 0x057b, 0x0000, 0x0000, 0x0299, "Y-E Data Flashbuster-U",
- US_SC_UFI, US_PR_CB, US_FL_SINGLE_LUN},
- { 0x057b, 0x0000, 0x0300, 0x9999, "Y-E Data Flashbuster-U",
- US_SC_UFI, US_PR_CBI, US_FL_SINGLE_LUN},
- { 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara FlashGate SmartMedia",
- US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-05a)",
- US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP},
-#ifdef CONFIG_USB_STORAGE_SDDR09
- { 0x0781, 0x0200, 0x0100, 0x0100, "Sandisk ImageMate (SDDR-09)",
- US_SC_SCSI, US_PR_EUSB_SDDR09,
+
+ { 0x04e6, 0x0001, 0x0200, 0x0200,
+ "Matshita",
+ "LS-120",
+ US_SC_8020, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN},
+
+ { 0x04e6, 0x0002, 0x0100, 0x0100,
+ "Shuttle",
+ "eUSCSI Bridge",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ 0 },
+
+ { 0x04e6, 0x0006, 0x0100, 0x0100,
+ "Shuttle",
+ "eUSB MMC Adapter",
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN},
+
+ { 0x054c, 0x0010, 0x0210, 0x0210,
+ "Sony",
+ "DSC-S30/S70",
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE },
+
+ { 0x054c, 0x002d, 0x0100, 0x0100,
+ "Sony",
+ "Memorystick MSAC-US1",
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE },
+
+ { 0x057b, 0x0000, 0x0000, 0x0299,
+ "Y-E Data",
+ "Flashbuster-U",
+ US_SC_UFI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN},
+
+ { 0x057b, 0x0000, 0x0300, 0x9999,
+ "Y-E Data",
+ "Flashbuster-U",
+ US_SC_UFI, US_PR_CBI, NULL,
+ US_FL_SINGLE_LUN},
+
+ { 0x0693, 0x0002, 0x0100, 0x0100,
+ "Hagiwara",
+ "FlashGate SmartMedia",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ 0 },
+
+ { 0x0781, 0x0001, 0x0200, 0x0200,
+ "Sandisk",
+ "ImageMate SDDR05a",
+ US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP},
+
+#ifdef CONFIG_USB_STORAGE_SDDR09
+ { 0x0781, 0x0200, 0x0100, 0x0100,
+ "Sandisk",
+ "ImageMate SDDR09",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
+ US_FL_SINGLE_LUN | US_FL_START_STOP },
+#endif
+
+ { 0x0781, 0x0002, 0x0009, 0x0009,
+ "Sandisk",
+ "ImageMate SDDR31",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ US_FL_IGNORE_SER},
+
+ { 0x07af, 0x0004, 0x0100, 0x0100,
+ "Microtech",
+ "USB-SCSI-DB25",
+ US_SC_SCSI, US_PR_BULK, NULL,
+ 0 },
+
+ { 0x059f, 0xa601, 0x0200, 0x0200,
+ "LaCie",
+ "USB Hard Disk",
+ US_SC_RBC, US_PR_CB, NULL,
+ 0 },
+
+#ifdef CONFIG_USB_STORAGE_DPCM
+ { 0x07af, 0x0006, 0x0100, 0x0100,
+ "Microtech",
+ "CameraMate (DPCM_USB)",
+ US_SC_SCSI, US_PR_DPCM_USB, NULL,
+ US_FL_START_STOP },
#endif
- { 0x0781, 0x0002, 0x0009, 0x0009, "Sandisk Imagemate (SDDR-31)",
- US_SC_SCSI, US_PR_BULK, US_FL_IGNORE_SER},
- { 0x07af, 0x0004, 0x0100, 0x0100, "Microtech USB-SCSI-DB25",
- US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0x07af, 0x0005, 0x0100, 0x0100, "Microtech USB-SCSI-HD50",
- US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0x05ab, 0x0031, 0x0100, 0x0100, "In-System USB/IDE Bridge",
- US_SC_8070, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0x0693, 0x0005, 0x0100, 0x0100, "Hagiwara Flashgate",
- US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
- { 0 }};
+
+ { 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 }
+};
/* Search our ususual device list, based on vendor/product combinations
* to see if we can support this device. Returns a pointer to a structure
@@ -319,7 +467,8 @@ static struct us_unusual_dev* us_find_dev(u16 idVendor, u16 idProduct,
}
/* otherwise, we found one! */
- US_DEBUGP("-- found matching device: %s\n", ptr->name);
+ US_DEBUGP("-- found matching device: %s %s\n", ptr->vendorName,
+ ptr->productName);
return ptr;
}
@@ -546,15 +695,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
USB_ENDPOINT_NUMBER_MASK;
ss->ep_int = ep_int;
- /* Reset the device's NEED_INIT flag if it needs to be
- initialized with a magic sequence */
-
- if (flags & US_FL_NEED_INIT)
- ss->flags |= US_FL_NEED_INIT;
-
/* allocate an IRQ callback if one is needed */
if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
return NULL;
+
+ /* Re-Initialize the device if it needs it */
+
+ if (unusual_dev && unusual_dev->initFunction)
+ (*unusual_dev->initFunction)(ss);
+
} else {
/* New device -- allocate memory and initialize */
US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
@@ -586,6 +735,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
ss->subclass = subclass;
ss->protocol = protocol;
ss->flags = flags;
+ ss->unusual_dev = unusual_dev;
/* copy over the endpoint data */
if (ep_in)
@@ -604,10 +754,22 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
strncpy(ss->vendor, mf, USB_STOR_STRING_LEN);
strncpy(ss->product, prod, USB_STOR_STRING_LEN);
strncpy(ss->serial, serial, USB_STOR_STRING_LEN);
- if (strlen(ss->vendor) == 0)
- strncpy(ss->vendor, "Unknown", USB_STOR_STRING_LEN);
- if (strlen(ss->product) == 0)
- strncpy(ss->product, "Unknown", USB_STOR_STRING_LEN);
+ if (strlen(ss->vendor) == 0) {
+ if (unusual_dev)
+ strncpy(ss->vendor, unusual_dev->vendorName,
+ USB_STOR_STRING_LEN);
+ else
+ strncpy(ss->vendor, "Unknown",
+ USB_STOR_STRING_LEN);
+ }
+ if (strlen(ss->product) == 0) {
+ if (unusual_dev)
+ strncpy(ss->product, unusual_dev->productName,
+ USB_STOR_STRING_LEN);
+ else
+ strncpy(ss->product, "Unknown",
+ USB_STOR_STRING_LEN);
+ }
if (strlen(ss->serial) == 0)
strncpy(ss->serial, "None", USB_STOR_STRING_LEN);
@@ -657,6 +819,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
ss->max_lun = 1;
break;
#endif
+
+#ifdef CONFIG_USB_STORAGE_DPCM
+ case US_PR_DPCM_USB:
+ ss->transport_name = "Control/Bulk-EUSB/SDDR09";
+ ss->transport = dpcm_transport;
+ ss->transport_reset = usb_stor_CB_reset;
+ ss->max_lun = 1;
+ break;
+#endif
default:
ss->transport_name = "Unknown";
@@ -734,6 +905,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
* we to do it?
*/
(struct us_data *)ss->htmplt.proc_dir = ss;
+
+ /* Just before we start our control thread, initialize
+ * the device if it needs initialization */
+ if (unusual_dev && unusual_dev->initFunction)
+ (*unusual_dev->initFunction)(ss);
/* start up our control thread */
ss->pid = kernel_thread(usb_stor_control_thread, ss,
@@ -878,6 +1054,3 @@ void __exit usb_stor_exit(void)
module_init(usb_stor_init) ;
module_exit(usb_stor_exit) ;
-
-MODULE_AUTHOR("Michael Gee <michael@linuxspecific.com>, David L. Brown, Jr. <usb-storage@davidb.org>, Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
-MODULE_DESCRIPTION("USB Mass Storage driver");
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index b376d39ee..435ad9777 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -1,7 +1,7 @@
/* Driver for USB Mass Storage compliant devices
* Main Header File
*
- * $Id: usb.h,v 1.4 2000/07/28 20:14:49 groovyjava Exp $
+ * $Id: usb.h,v 1.7 2000/08/15 00:06:38 mdharm Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -77,6 +77,8 @@ static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *seri
}
}
+struct us_data;
+
/*
* Unusual device list definitions
*/
@@ -89,9 +91,11 @@ struct us_unusual_dev {
__u16 bcdDeviceMax;
/* the list specifies these parameters */
- const char* name;
+ const char* vendorName;
+ const char* productName;
__u8 useProtocol;
__u8 useTransport;
+ int (*initFunction)(struct us_data *);
unsigned int flags;
};
@@ -100,15 +104,11 @@ struct us_unusual_dev {
#define US_FL_MODE_XLATE 0x00000002 /* translate _6 to _10 comands for
Win/MacOS compatibility */
#define US_FL_START_STOP 0x00000004 /* ignore START_STOP commands */
-#define US_FL_ALT_LENGTH 0x00000008 /* use the alternate algorithm for
- us_transfer_length() */
#define US_FL_IGNORE_SER 0x00000010 /* Ignore the serial number given */
-#define US_FL_NEED_INIT 0x00000020 /* Device needs initialization */
+#define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */
#define USB_STOR_STRING_LEN 32
-struct us_data;
-
typedef int (*trans_cmnd)(Scsi_Cmnd*, struct us_data*);
typedef int (*trans_reset)(struct us_data*);
typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*);
@@ -176,6 +176,7 @@ struct us_data {
/* mutual exclusion structures */
struct semaphore notify; /* thread begin/end */
struct semaphore queue_exclusion; /* to protect data structs */
+ struct us_unusual_dev *unusual_dev; /* If unusual device */
void *extra; /* Any extra data */
void (*extra_destructor)(void *); /* extra data destructor */
};
@@ -184,4 +185,9 @@ struct us_data {
extern struct us_data *us_list;
extern struct semaphore us_list_semaphore;
+/* Function to fill an inquiry response. See usb.c for details */
+
+extern void fill_inquiry_response(struct us_data *us,
+ unsigned char *data, unsigned int data_len);
+
#endif