summaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/Makefile6
-rw-r--r--drivers/usb/storage/scm.c461
-rw-r--r--drivers/usb/storage/scm.h5
-rw-r--r--drivers/usb/storage/scsiglue.c8
-rw-r--r--drivers/usb/storage/transport.h6
-rw-r--r--drivers/usb/storage/usb.c40
6 files changed, 374 insertions, 152 deletions
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 7ede92c88..aaf1072db 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -4,7 +4,7 @@
O_TARGET := usb-storage.o
M_OBJS := usb-storage.o
-O_OBJS := scsiglue.o protocol.o transport.o debug.o usb.o
+O_OBJS := scsiglue.o protocol.o transport.o usb.o
MOD_LIST_NAME := USB_STORAGE_MODULES
CFLAGS_scsiglue.o:= -I../../scsi/
@@ -22,6 +22,10 @@ ifeq ($(CONFIG_USB_STORAGE_HP8200e),y)
O_OBJS += scm.o
endif
+ifeq ($(CONFIG_USB_STORAGE_SDDR09),y)
+ O_OBJS += scm.o
+endif
+
ifeq ($(CONFIG_USB_STORAGE_FREECOM),y)
O_OBJS += freecom.o
endif
diff --git a/drivers/usb/storage/scm.c b/drivers/usb/storage/scm.c
index 2d3ca7051..7bae5e623 100644
--- a/drivers/usb/storage/scm.c
+++ b/drivers/usb/storage/scm.c
@@ -1,6 +1,18 @@
/* Driver for SCM Microsystems USB-ATAPI cable
*
- * SCM driver v0.1
+ * $Id: scm.c,v 1.4 2000/07/24 19:19:52 mdharm Exp $
+ *
+ * SCM driver v0.2:
+ *
+ * Removed any reference to maxlen for bulk transfers.
+ * Changed scm_bulk_transport to allow for transfers without commands.
+ * Changed hp8200e transport to use the request_bufflen field in the
+ * SCSI command for the length of the transfer, rather than calculating
+ * it ourselves based on the command.
+ *
+ * SCM driver v0.1:
+ *
+ * First release - hp8200e.
*
* Current development and maintainance by:
* (c) 2000 Robert Baruch (autophile@dol.net)
@@ -143,148 +155,118 @@ static int scm_send_control(struct us_data *us,
}
static int scm_raw_bulk(struct us_data *us,
- int pipe, int maxlen,
+ int direction,
unsigned char *data,
unsigned short len) {
- int transferred = 0;
int result;
int act_len;
- int partial_len;
- unsigned char status;
-
- maxlen = len;
-
- // while (transferred < len) {
-
- // We want to transfer up to maxlen bytes
-
- partial_len = len-transferred > maxlen ?
- maxlen :
- len-transferred;
-
- result = usb_stor_bulk_msg(us,
- data+transferred,
- pipe,
- partial_len,
- &act_len);
+ int pipe;
- /* if we stall, we need to clear it before we go on */
- if (result == -EPIPE) {
- US_DEBUGP("EPIPE: clearing endpoint halt for"
- " pipe 0x%x, stalled at %d bytes\n",
- pipe, act_len);
- usb_clear_halt(us->pusb_dev, pipe);
+ if (direction == SCSI_DATA_READ)
+ pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+ else
+ pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
- // What the hey is goin' on?
+ result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
- /* US_DEBUGP("EPIPE: Trying to retransmit bulk data...\n");
+ /* if we stall, we need to clear it before we go on */
+ if (result == -EPIPE) {
+ US_DEBUGP("EPIPE: clearing endpoint halt for"
+ " pipe 0x%x, stalled at %d bytes\n",
+ pipe, act_len);
+ usb_clear_halt(us->pusb_dev, pipe);
+ }
- wait_ms(10);
-
- result = usb_stor_bulk_msg(us, data+act_len,
- pipe, len-act_len, &act_len);
+ if (result) {
- if (result==0)
- US_DEBUGP("EPIPE: Retransmit successful\n"); */
+ /* NAK - that means we've retried a few times already */
+ if (result == -ETIMEDOUT) {
+ US_DEBUGP("scm_raw_bulk():"
+ " device NAKed\n");
+ return US_BULK_TRANSFER_FAILED;
+ }
- wait_ms(1000);
- US_DEBUGP("Trying to get status\n");
- result = scm_read(us, SCM_ATA, 0x17, &status);
- US_DEBUGP("SCM: Write ATA data status is %02X\n",
- status);
-
- result = -EPIPE;
- }
-
- if (result) {
-
- /* NAK - that means we've retried a few times already */
- if (result == -ETIMEDOUT) {
- US_DEBUGP("scm_raw_bulk():"
- " device NAKed\n");
- return US_BULK_TRANSFER_FAILED;
- }
-
- /* -ENOENT -- we canceled this transfer */
- if (result == -ENOENT) {
- US_DEBUGP("scm_raw_bulk():"
- " transfer aborted\n");
- return US_BULK_TRANSFER_ABORTED;
- }
-
- if (result == -EPIPE) {
- US_DEBUGP("scm_raw_bulk():"
- " output pipe stalled\n");
- return USB_STOR_TRANSPORT_FAILED;
- }
+ /* -ENOENT -- we canceled this transfer */
+ if (result == -ENOENT) {
+ US_DEBUGP("scm_raw_bulk():"
+ " transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
- /* the catch-all case */
- US_DEBUGP("us_transfer_partial(): unknown error\n");
- return US_BULK_TRANSFER_FAILED;
- }
-
- if (act_len != partial_len) {
- US_DEBUGP("Warning: Transferred only %d bytes\n",
- act_len);
- return US_BULK_TRANSFER_SHORT;
+ if (result == -EPIPE) {
+ US_DEBUGP("scm_raw_bulk():"
+ " output pipe stalled\n");
+ return USB_STOR_TRANSPORT_FAILED;
}
- US_DEBUGP("Transfered %d of %d bytes\n", act_len, partial_len);
+ /* the catch-all case */
+ US_DEBUGP("us_transfer_partial(): unknown error\n");
+ return US_BULK_TRANSFER_FAILED;
+ }
+
+ if (act_len != len) {
+ US_DEBUGP("Warning: Transferred only %d bytes\n",
+ act_len);
+ return US_BULK_TRANSFER_SHORT;
+ }
- transferred += act_len;
- // } // while transferred < len
+ US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
return US_BULK_TRANSFER_GOOD;
}
+/*
+ * Note: direction must be set if command_len == 0.
+ */
+
static int scm_bulk_transport(struct us_data *us,
unsigned char *command,
unsigned short command_len,
+ int direction,
unsigned char *data,
unsigned short len,
int use_sg) {
- int result;
+ int result = USB_STOR_TRANSPORT_GOOD;
int transferred = 0;
- int maxlen;
unsigned char execute[8] = {
0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int i;
- int pipe;
struct scatterlist *sg;
char string[64];
- maxlen = us->pusb_dev->actconfig->
- interface[0].altsetting[0].endpoint[
- ( (command[0]&0x80) ? us->ep_in : us->ep_out)-1].
- wMaxPacketSize;
+ if (command_len != 0) {
- /* Fix up the command's data length */
+ /* Fix up the command's data length */
- command[6] = len&0xFF;
- command[7] = (len>>8)&0xFF;
+ command[6] = len&0xFF;
+ command[7] = (len>>8)&0xFF;
- result = scm_send_control(us,
- execute,
- command,
- command_len);
+ result = scm_send_control(us,
+ execute,
+ command,
+ command_len);
- if (result != USB_STOR_TRANSPORT_GOOD)
- return result;
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+ }
if (len==0)
- return result;
+ return USB_STOR_TRANSPORT_GOOD;
+
/* transfer the data payload for the command, if there is any */
- if (command[0]&0x80)
- pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
- else {
- pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
- /* Debug-print the first 48 bytes of the transfer */
+ if (command_len != 0)
+ direction = (command[0]&0x80) ? SCSI_DATA_READ :
+ SCSI_DATA_WRITE;
+
+ if (direction == SCSI_DATA_WRITE) {
+
+ /* Debug-print the first 48 bytes of the write transfer */
if (!use_sg) {
string[0] = 0;
@@ -302,17 +284,16 @@ static int scm_bulk_transport(struct us_data *us,
}
- US_DEBUGP("HP 8200e data %s maxlen %d transfer %d sg buffers %d\n",
- ( (command[0]&0x80) ? "in" : "out"),
- maxlen, len, use_sg);
+ US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
+ ( direction==SCSI_DATA_READ ? "in" : "out"),
+ len, use_sg);
if (!use_sg)
- result = scm_raw_bulk(us, pipe, maxlen,
- data, len);
+ result = scm_raw_bulk(us, direction, data, len);
else {
sg = (struct scatterlist *)data;
for (i=0; i<use_sg && transferred<len; i++) {
- result = scm_raw_bulk(us, pipe, maxlen,
+ result = scm_raw_bulk(us, direction,
sg[i].address,
len-transferred > sg[i].length ?
sg[i].length : len-transferred);
@@ -379,7 +360,7 @@ int scm_set_shuttle_features(struct us_data *us,
test_pattern, mask_byte, subcountL, subcountH
};
- result = scm_bulk_transport(us, command, 8, NULL, 0, 0);
+ result = scm_bulk_transport(us, command, 8, 0, NULL, 0, 0);
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
@@ -400,7 +381,7 @@ int scm_read_block(struct us_data *us,
};
result = scm_bulk_transport(us,
- command, 8, content, len, use_sg);
+ command, 8, 0, content, len, use_sg);
if (result != USB_STOR_TRANSPORT_GOOD)
return result;
@@ -431,6 +412,8 @@ int scm_wait_not_busy(struct us_data *us) {
return result;
if (status&0x01) // check condition
return USB_STOR_TRANSPORT_FAILED;
+ if (status&0x20) // device fault
+ return USB_STOR_TRANSPORT_FAILED;
if ((status&0x80)!=0x80) // not busy
break;
if (i<5)
@@ -460,11 +443,9 @@ int scm_write_block(struct us_data *us,
unsigned char command[8] = {
0x40, access|0x03, reg, 0x00, 0x00, 0x00, 0x00, 0x00
};
- int i;
- unsigned char status;
result = scm_bulk_transport(us,
- command, 8, content, len, use_sg);
+ command, 8, 0, content, len, use_sg);
if (result!=USB_STOR_TRANSPORT_GOOD)
return result;
@@ -492,11 +473,8 @@ int scm_write_block_test(struct us_data *us,
qualifier, timeout, 0x00, 0x00
};
int i;
- unsigned char status;
unsigned char data[num_registers*2];
- int maxlen;
int transferred;
- int pipe;
struct scatterlist *sg;
char string[64];
@@ -509,16 +487,11 @@ int scm_write_block_test(struct us_data *us,
}
result = scm_bulk_transport(us,
- command, 16, data, num_registers*2, 0);
+ command, 16, 0, data, num_registers*2, 0);
if (result!=USB_STOR_TRANSPORT_GOOD)
return result;
- maxlen = us->pusb_dev->actconfig->
- interface[0].altsetting[0].endpoint[us->ep_out-1].
- wMaxPacketSize;
-
- pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
transferred = 0;
US_DEBUGP("Transfer out %d bytes, sg buffers %d\n",
@@ -528,28 +501,25 @@ int scm_write_block_test(struct us_data *us,
/* Debug-print the first 48 bytes of the transfer */
- if (!use_sg) {
- string[0] = 0;
- for (i=0; i<len && i<48; i++) {
- sprintf(string+strlen(string), "%02X ",
- content[i]);
- if ((i%16)==15) {
- US_DEBUGP("%s\n", string);
- string[0] = 0;
- }
- }
- if (string[0]!=0)
+ string[0] = 0;
+ for (i=0; i<len && i<48; i++) {
+ sprintf(string+strlen(string), "%02X ",
+ content[i]);
+ if ((i%16)==15) {
US_DEBUGP("%s\n", string);
+ string[0] = 0;
+ }
}
+ if (string[0]!=0)
+ US_DEBUGP("%s\n", string);
- result = scm_raw_bulk(us, pipe, maxlen,
- content, len);
+ result = scm_raw_bulk(us, SCSI_DATA_WRITE, content, len);
} else {
sg = (struct scatterlist *)content;
for (i=0; i<use_sg && transferred<len; i++) {
- result = scm_raw_bulk(us, pipe, maxlen,
+ result = scm_raw_bulk(us, SCSI_DATA_WRITE,
sg[i].address,
len-transferred > sg[i].length ?
sg[i].length : len-transferred);
@@ -577,14 +547,13 @@ int scm_multiple_write(struct us_data *us,
unsigned char cmd[8] = {
0x40, access|0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
- unsigned char status;
for (i=0; i<num_registers; i++) {
data[i<<1] = registers[i];
data[1+(i<<1)] = data_out[i];
}
- result = scm_bulk_transport(us, cmd, 8, data, num_registers*2, 0);
+ result = scm_bulk_transport(us, cmd, 8, 0, data, num_registers*2, 0);
if (result!=USB_STOR_TRANSPORT_GOOD)
return result;
@@ -679,6 +648,52 @@ int scm_write_user_io(struct us_data *us,
return result;
}
+static int init_sddr09(struct us_data *us) {
+
+ int result;
+ unsigned char data[14];
+ unsigned char command[8] = {
+ 0xc1, 0x01, 0, 0, 0, 0, 0, 0
+ };
+ unsigned char command2[8] = {
+ 0x41, 0, 0, 0, 0, 0, 0, 0
+ };
+ unsigned char tur[12] = {
+ 0x03, 0x20, 0, 0, 0x0e, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ if ( (result = scm_send_control(us, command, data, 2)) !=
+ USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
+
+ command[1] = 0x08;
+
+ if ( (result = scm_send_control(us, command, data, 2)) !=
+ USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
+/*
+ if ( (result = scm_send_control(us, command2, tur, 12)) !=
+ USB_STOR_TRANSPORT_GOOD) {
+ US_DEBUGP("SDDR09: request sense failed\n");
+ return result;
+ }
+
+ if ( (result = scm_raw_bulk(
+ us, SCSI_DATA_READ, data, 14)) !=
+ USB_STOR_TRANSPORT_GOOD) {
+ US_DEBUGP("SDDR09: request sense bulk in failed\n");
+ return result;
+ }
+
+ US_DEBUGP("SDDR09: request sense worked\n");
+*/
+ return result;
+}
+
static int init_8200e(struct us_data *us) {
int result;
@@ -810,18 +825,15 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
"XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */
"XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
- /* FIXME: B9 (READ CD MSF) has unknown length! */
-
- /* US_DEBUGP("XXXXXXXX 8200e transport called, tid %08X\n",
- current->pid); */
-
if (us->flags & US_FL_NEED_INIT) {
US_DEBUGP("8200e: initializing\n");
init_8200e(us);
us->flags &= ~US_FL_NEED_INIT;
}
- if (srb->sc_data_direction == SCSI_DATA_WRITE)
+ len = srb->request_bufflen;
+
+/* if (srb->sc_data_direction == SCSI_DATA_WRITE)
len = srb->request_bufflen;
else {
@@ -863,12 +875,17 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
case 'W':
len = 24;
break;
+ case 'B':
+ // Let's try using the command structure's
+ // request_bufflen here
+ len = srb->request_bufflen;
+ break;
default:
US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
srb->cmnd[0]);
return USB_STOR_TRANSPORT_ERROR;
}
- }
+ } */
if (len > 0xFFFF) {
US_DEBUGP("Error: len = %08X... what do I do now?\n",
@@ -977,3 +994,163 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
return result;
}
+
+
+/*
+ * Transport for the Sandisk SDDR-09
+ */
+int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+ int result;
+ unsigned int len;
+ unsigned char send_scsi_command[8] = {
+ 0x41, 0, 0, 0, 0, 0, 0, 0
+ };
+ int i;
+ char string[64];
+ unsigned char *ptr;
+ unsigned char inquiry_response[36] = {
+ 0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00,
+ 'S', 'a', 'n', 'D', 'i', 's', 'k', ' ',
+ 'I', 'm', 'a', 'g', 'e', 'M', 'a', 't',
+ 'e', ' ', 'S', 'D', 'D', 'R', '0', '9',
+ ' ', ' ', ' ', ' '
+ };
+
+ /* This table tells us:
+ X = command not supported
+ L = return length in cmnd[4] (8 bits).
+ H = return length in cmnd[7] and cmnd[8] (16 bits).
+ D = return length in cmnd[6] to cmnd[9] (32 bits).
+ B = return length/blocksize in cmnd[6] to cmnd[8].
+ T = return length in cmnd[6] to cmnd[8] (24 bits).
+ 0-9 = fixed return length
+ W = 24 bytes
+ h = return length/2048 in cmnd[7-8].
+ */
+
+ static char *lengths =
+
+ /* 0123456789ABCDEF 0123456789ABCDEF */
+
+ "0XXL0XXXXXXXXXXX" "XXLXXXXXXXX0XX0X" /* 00-1F */
+ "XXXXX8XXhXH0XXX0" "XXXXX0XXXXXXXXXX" /* 20-3F */
+ "XXHHL0X0XXH0XX0X" "XHH00HXX0TH0H0XX" /* 40-5F */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 60-7F */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 80-9F */
+ "X0XXX0XXDXDXXXXX" "XXXXXXXXX000XHBX" /* A0-BF */
+ "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */
+ "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
+
+ if (us->flags & US_FL_NEED_INIT) {
+ US_DEBUGP("SDDR-09: initializing\n");
+ init_sddr09(us);
+ us->flags &= ~US_FL_NEED_INIT;
+ }
+
+ /* if (srb->sc_data_direction == SCSI_DATA_WRITE) */
+ len = srb->request_bufflen;
+ /* else {
+
+ switch (lengths[srb->cmnd[0]]) {
+
+ case 'L':
+ len = srb->cmnd[4];
+ 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 'H':
+ len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
+ break;
+ case 'h':
+ len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
+ len <<= 11; // *2048
+ break;
+ case 'T':
+ len = (((unsigned int)srb->cmnd[6])<<16) |
+ (((unsigned int)srb->cmnd[7])<<8) |
+ srb->cmnd[8];
+ 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 'W':
+ len = 24;
+ break;
+ case 'B':
+ // Let's try using the command structure's
+ // request_bufflen here
+ len = srb->request_bufflen;
+ break;
+ default:
+ US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
+ srb->cmnd[0]);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ } */
+
+ if (srb->request_bufflen > 0xFFFF) {
+ US_DEBUGP("Error: len = %08X... what do I do now?\n",
+ len);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ /* Dummy up a response for INQUIRY since SDDR09 doesn't
+ respond to INQUIRY commands */
+
+ if (srb->cmnd[0] == INQUIRY) {
+ memcpy(srb->request_buffer, inquiry_response, 36);
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+
+ for (; srb->cmd_len<12; srb->cmd_len++)
+ srb->cmnd[srb->cmd_len] = 0;
+
+ srb->cmnd[1] = 0x20;
+
+ string[0] = 0;
+ for (i=0; i<12; i++)
+ sprintf(string+strlen(string), "%02X ", srb->cmnd[i]);
+
+ US_DEBUGP("SDDR09: Send control for command %s\n",
+ string);
+
+ if ( (result = scm_send_control(us, send_scsi_command,
+ srb->cmnd, 12)) != USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ US_DEBUGP("SDDR09: Control for command OK\n");
+
+ if (srb->sc_data_direction == SCSI_DATA_WRITE ||
+ srb->sc_data_direction == SCSI_DATA_READ) {
+
+ US_DEBUGP("SDDR09: %s %d bytes\n",
+ srb->sc_data_direction==SCSI_DATA_WRITE ?
+ "sending" : "receiving",
+ len);
+
+ result = scm_bulk_transport(us,
+ NULL, 0, srb->sc_data_direction,
+ srb->request_buffer,
+ len, srb->use_sg);
+
+ return result;
+
+ }
+
+ return result;
+}
+
diff --git a/drivers/usb/storage/scm.h b/drivers/usb/storage/scm.h
index edc324a84..f57463a1e 100644
--- a/drivers/usb/storage/scm.h
+++ b/drivers/usb/storage/scm.h
@@ -1,6 +1,8 @@
/* Driver for SCM Microsystems USB-ATAPI cable
* Header File
*
+ * $Id: scm.h,v 1.3 2000/07/24 19:19:52 mdharm Exp $
+ *
* Current development and maintainance by:
* (c) 2000 Robert Baruch (autophile@dol.net)
*
@@ -73,5 +75,8 @@ extern int scm_write_user_io(struct us_data *us,
extern int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us);
+/* Sandisk SDDR-09 stuff */
+
+extern int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us);
#endif
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index ad0df666b..21fe3ec97 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.4 2000/07/20 01:14:56 mdharm Exp $
+ * $Id: scsiglue.c,v 1.5 2000/07/24 18:55:39 mdharm Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -192,7 +192,7 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
static int command_abort( Scsi_Cmnd *srb )
{
struct us_data *us = (struct us_data *)srb->host->hostdata[0];
- api_wrapper_data *awd = (api_wrapper_data *)us->current_urb->context;
+ wait_queue_head_t *wqh = (wait_queue_head_t *)us->current_urb->context;
US_DEBUGP("command_abort() called\n");
@@ -209,8 +209,8 @@ static int command_abort( Scsi_Cmnd *srb )
usb_unlink_urb(us->current_urb);
/* wake the control thread up */
- if (waitqueue_active(awd->wakeup))
- wake_up(awd->wakeup);
+ if (waitqueue_active(wqh))
+ wake_up(wqh);
/* wait for us to be done */
down(&(us->notify));
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index e5445f21b..55e12f79f 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.3 2000/07/20 23:36:22 mdharm Exp $
+ * $Id: transport.h,v 1.4 2000/07/23 18:40:38 groovyjava Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -41,6 +41,7 @@
#ifndef _TRANSPORT_H_
#define _TRANSPORT_H_
+#include <linux/config.h>
#include <linux/blk.h>
#include "usb.h"
#include "scsi.h"
@@ -57,6 +58,9 @@ extern unsigned char us_direction[256/8];
#ifdef CONFIG_USB_STORAGE_HP8200e
#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_SCM_SCSI 0x81 /* SCM-SCSI bridge */
+#endif
/*
* Bulk only data structures
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 060c8f4c0..99986371f 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.6 2000/07/20 23:36:22 mdharm Exp $
+ * $Id: usb.c,v 1.11 2000/07/24 20:37:24 mdharm Exp $
*
* Current development and maintainance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -43,12 +43,14 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/config.h>
+
#include "usb.h"
#include "scsiglue.h"
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#ifdef CONFIG_USB_STORAGE_HP8200e
+#if defined(CONFIG_USB_STORAGE_HP8200e) || defined(CONFIG_USB_STORAGE_SDDR09)
#include "scm.h"
#endif
@@ -98,6 +100,9 @@ static int usb_stor_control_thread(void * __us)
* This thread doesn't need any user-level access,
* so get rid of all our resources..
*/
+ exit_files(current);
+ current->files = init_task.files;
+ atomic_inc(&current->files->count);
daemonize();
/* set our name for identification purposes */
@@ -250,6 +255,11 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
{ 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-01)",
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_SCM_SCSI,
+ US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_NEED_INIT},
+#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",
@@ -436,7 +446,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
/* set the interface -- STALL is an acceptable response here */
+#ifdef CONFIG_USB_STORAGE_SDDR09
+ if (protocol != US_PR_SCM_SCSI)
+ result = usb_set_interface(dev,
+ altsetting->bInterfaceNumber, 0);
+ else
+ 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);
if (result == -EPIPE) {
US_DEBUGP("-- clearing stall on control interface\n");
@@ -509,6 +527,12 @@ 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;
@@ -603,8 +627,17 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
ss->transport = hp8200e_transport;
ss->transport_reset = usb_stor_CB_reset;
ss->max_lun = 1;
+ break;
#endif
+
+#ifdef CONFIG_USB_STORAGE_SDDR09
+ case US_PR_SCM_SCSI:
+ ss->transport_name = "SCM/SCSI";
+ ss->transport = sddr09_transport;
+ ss->transport_reset = usb_stor_CB_reset;
+ ss->max_lun = 1;
break;
+#endif
default:
ss->transport_name = "Unknown";
@@ -691,8 +724,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
/* start up our control thread */
ss->pid = kernel_thread(usb_stor_control_thread, ss,
- CLONE_FS | CLONE_FILES |
- CLONE_SIGHAND);
+ CLONE_VM);
if (ss->pid < 0) {
printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n");