patch-2.4.0-test6 linux/drivers/usb/storage/transport.c

Next file: linux/drivers/usb/storage/transport.h
Previous file: linux/drivers/usb/storage/shuttle_usbat.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/drivers/usb/storage/transport.c linux/drivers/usb/storage/transport.c
@@ -1,6 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: transport.c,v 1.3 2000/07/20 01:06:40 mdharm Exp $
+ * $Id: transport.c,v 1.5 2000/07/28 22:40:20 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -203,7 +203,7 @@
 	int pipe;
 
 	/* calculate the appropriate pipe information */
-	if (US_DIRECTION(us->srb->cmnd[0]))
+	if (us->srb->sc_data_direction == SCSI_DATA_READ)
 		pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
 	else
 		pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
@@ -258,7 +258,7 @@
  * function simply determines if we're going to use scatter-gather or not,
  * and acts appropriately.  For now, it also re-interprets the error codes.
  */
-static void us_transfer(Scsi_Cmnd *srb, struct us_data* us, int dir_in)
+static void us_transfer(Scsi_Cmnd *srb, struct us_data* us)
 {
 	int i;
 	int result = -1;
@@ -414,8 +414,9 @@
 	if (need_auto_sense) {
 		int temp_result;
 		void* old_request_buffer;
-		int old_sg;
-		int old_request_bufflen;
+		unsigned short old_sg;
+		unsigned old_request_bufflen;
+		unsigned char old_sc_data_direction;
 		unsigned char old_cmnd[MAX_COMMAND_SIZE];
 
 		US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
@@ -431,13 +432,21 @@
 		srb->cmnd[4] = 18;
 		srb->cmnd[5] = 0;
 
-		/* set the buffer length for transfer */
+		/* set the transfer direction */
+		old_sc_data_direction = srb->sc_data_direction;
+		srb->sc_data_direction = SCSI_DATA_READ;
+
+		/* use the new buffer we have */
 		old_request_buffer = srb->request_buffer;
+		srb->request_buffer = srb->sense_buffer;
+
+		/* set the buffer length for transfer */
 		old_request_bufflen = srb->request_bufflen;
+		srb->request_bufflen = 18;
+
+		/* set up for no scatter-gather use */
 		old_sg = srb->use_sg;
 		srb->use_sg = 0;
-		srb->request_bufflen = 18;
-		srb->request_buffer = srb->sense_buffer;
 
 		/* issue the auto-sense command */
 		temp_result = us->transport(us->srb, us);
@@ -462,6 +471,7 @@
 		srb->request_buffer = old_request_buffer;
 		srb->request_bufflen = old_request_bufflen;
 		srb->use_sg = old_sg;
+		srb->sc_data_direction = old_sc_data_direction;
 		memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
 
 		/* If things are really okay, then let's show that */
@@ -555,7 +565,7 @@
 	/* DATA STAGE */
 	/* transfer the data payload for this command, if one exists*/
 	if (us_transfer_length(srb, us)) {
-		us_transfer(srb, us, US_DIRECTION(srb->cmnd[0]));
+		us_transfer(srb, us);
 		US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);
 
 		/* if it was aborted, we need to indicate that */
@@ -656,7 +666,7 @@
 	/* DATA STAGE */
 	/* transfer the data payload for this command, if one exists*/
 	if (us_transfer_length(srb, us)) {
-		us_transfer(srb, us, US_DIRECTION(srb->cmnd[0]));
+		us_transfer(srb, us);
 		US_DEBUGP("CB data stage result is 0x%x\n", srb->result);
 
 		/* if it was aborted, we need to indicate that */
@@ -707,6 +717,8 @@
 	return 0;
 }
 
+int usb_stor_Bulk_reset(struct us_data *us);
+
 int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
 {
 	struct bulk_cb_wrap bcb;
@@ -718,7 +730,7 @@
 	/* 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.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
+	bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
 	bcb.Tag = srb->serial_number;
 	bcb.Lun = srb->cmnd[1] >> 5;
 	bcb.Length = srb->cmd_len;
@@ -755,7 +767,7 @@
 	if (result == 0) {
 		/* send/receive data payload, if there is any */
 		if (bcb.DataTransferLength) {
-			us_transfer(srb, us, bcb.Flags);
+			us_transfer(srb, us);
 			US_DEBUGP("Bulk data transfer result 0x%x\n", 
 				  srb->result);
 
@@ -810,7 +822,7 @@
 	}
 	
 	/* check bulk status */
-	US_DEBUGP("Bulk status S 0x%x T 0x%x R %d V 0x%x\n",
+	US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
 		  le32_to_cpu(bcs.Signature), bcs.Tag, 
 		  bcs.Residue, bcs.Status);
 	if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || 
@@ -832,6 +844,7 @@
 		
 	case US_BULK_STAT_PHASE:
 		/* phase error */
+		usb_stor_Bulk_reset(us);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 	
@@ -873,10 +886,14 @@
 	return 0;
 }
 
-/* FIXME: Does this work? */
+/* This issues a Bulk-only Reset to the device in question, including
+ * clearing the subsequent endpoint halts that may occur.
+ */
 int usb_stor_Bulk_reset(struct us_data *us)
 {
 	int result;
+
+	US_DEBUGP("Bulk reset requested\n");
 
 	result = usb_control_msg(us->pusb_dev, 
 				 usb_sndctrlpipe(us->pusb_dev,0), 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)