patch-2.4.0-test9 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
- Lines: 198
- Date:
Sun Oct 1 19:42:40 2000
- Orig file:
v2.4.0-test8/linux/drivers/usb/storage/transport.c
- Orig date:
Mon Aug 28 16:59:14 2000
diff -u --recursive --new-file v2.4.0-test8/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.18 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: transport.c,v 1.27 2000/09/28 21:54:30 mdharm Exp $
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -43,6 +43,8 @@
* 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"
@@ -680,7 +682,7 @@
need_auto_sense = 1;
}
if (result == USB_STOR_TRANSPORT_ERROR) {
- /* FIXME: we need to invoke a transport reset here */
+ us->transport_reset(us);
US_DEBUGP("-- transport indicates transport failure\n");
need_auto_sense = 0;
srb->result = DID_ERROR << 16;
@@ -742,8 +744,15 @@
/* issue the auto-sense command */
temp_result = us->transport(us->srb, us);
if (temp_result != USB_STOR_TRANSPORT_GOOD) {
- /* FIXME: we need to invoke a transport reset here */
US_DEBUGP("-- auto-sense failure\n");
+
+ /* we skip the reset if this happens to be a
+ * multi-target device, since failure of an
+ * auto-sense is perfectly valid
+ */
+ if (!(us->flags & US_FL_SCM_MULT_TARG)) {
+ us->transport_reset(us);
+ }
srb->result = DID_ERROR << 16;
return;
}
@@ -754,9 +763,15 @@
srb->sense_buffer[2] & 0xf,
srb->sense_buffer[12],
srb->sense_buffer[13]);
+#ifdef CONFIG_USB_STORAGE_DEBUG
+ usb_stor_show_sense(
+ srb->sense_buffer[2] & 0xf,
+ srb->sense_buffer[12],
+ srb->sense_buffer[13]);
+#endif
/* set the result so the higher layers expect this data */
- srb->result = CHECK_CONDITION;
+ srb->result = CHECK_CONDITION << 1;
/* we're done here, let's clean up */
srb->request_buffer = old_request_buffer;
@@ -767,15 +782,15 @@
/* If things are really okay, then let's show that */
if ((srb->sense_buffer[2] & 0xf) == 0x0)
- srb->result = GOOD;
+ srb->result = GOOD << 1;
} else /* if (need_auto_sense) */
- srb->result = GOOD;
+ srb->result = GOOD << 1;
/* Regardless of auto-sense, if we _know_ we have an error
* condition, show that in the result code
*/
if (result == USB_STOR_TRANSPORT_FAILED)
- srb->result = CHECK_CONDITION;
+ srb->result = CHECK_CONDITION << 1;
/* If we think we're good, then make sure the sense data shows it.
* This is necessary because the auto-sense for some devices always
@@ -822,6 +837,9 @@
{
int result;
+ /* Set up for status notification */
+ us->ip_wanted = 1;
+
/* COMMAND STAGE */
/* let's send the command via the control pipe */
result = usb_stor_control_msg(us, usb_sndctrlpipe(us->pusb_dev,0),
@@ -832,6 +850,9 @@
/* check the return code for the command */
US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result);
if (result < 0) {
+ /* Reset flag for status notification */
+ us->ip_wanted = 0;
+
/* if the command was aborted, indicate that */
if (result == -ENOENT)
return USB_STOR_TRANSPORT_ABORTED;
@@ -850,9 +871,6 @@
return USB_STOR_TRANSPORT_ERROR;
}
- /* Set up for status notification */
- us->ip_wanted = 1;
-
/* DATA STAGE */
/* transfer the data payload for this command, if one exists*/
if (us_transfer_length(srb)) {
@@ -860,8 +878,12 @@
US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);
/* if it was aborted, we need to indicate that */
- if (srb->result == USB_STOR_TRANSPORT_ABORTED)
+ if (srb->result == USB_STOR_TRANSPORT_ABORTED) {
+ /* we need to reset the state of this semaphore */
+ down(&(us->ip_waitq));
+
return USB_STOR_TRANSPORT_ABORTED;
+ }
}
/* STATUS STAGE */
@@ -1038,7 +1060,7 @@
/* send it to out endpoint */
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.Lun >> 4), (bcb.Lun & 0x0F),
bcb.DataTransferLength, bcb.Flags, bcb.Length);
result = usb_stor_bulk_msg(us, &bcb, pipe, US_BULK_CB_WRAP_LEN,
&partial);
@@ -1137,8 +1159,9 @@
return USB_STOR_TRANSPORT_FAILED;
case US_BULK_STAT_PHASE:
- /* phase error */
- usb_stor_Bulk_reset(us);
+ /* phase error -- note that a transport reset will be
+ * invoked by the invoke_transport() function
+ */
return USB_STOR_TRANSPORT_ERROR;
}
@@ -1167,8 +1190,15 @@
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, cmd, sizeof(cmd), HZ*5);
+ if (result < 0) {
+ US_DEBUGP("CB[I] soft reset failed %d\n", result);
+ return FAILED;
+ }
+
/* long wait for reset */
+ set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ*6);
+ set_current_state(TASK_RUNNING);
US_DEBUGP("CB_reset: clearing endpoint halt\n");
clear_halt(us->pusb_dev,
@@ -1177,7 +1207,8 @@
usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
US_DEBUGP("CB_reset done\n");
- return 0;
+ /* return a result code based on the result of the control message */
+ return SUCCESS;
}
/* This issues a Bulk-only Reset to the device in question, including
@@ -1195,16 +1226,20 @@
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, NULL, 0, HZ*5);
- if (result < 0)
- US_DEBUGP("Bulk hard reset failed %d\n", result);
+ if (result < 0) {
+ US_DEBUGP("Bulk soft reset failed %d\n", result);
+ return FAILED;
+ }
+
+ /* long wait for reset */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ*6);
+ set_current_state(TASK_RUNNING);
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;
+ US_DEBUGP("Bulk soft reset completed\n");
+ return SUCCESS;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)