summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsl147100 <none@none>2008-01-07 19:38:05 -0800
committersl147100 <none@none>2008-01-07 19:38:05 -0800
commit3fbbb872ea33adea240e8fd8c692f6d3131cc69b (patch)
tree678d2a431db6b7652b3a3888bf180798d1775f63
parent2850d85b7b93f31e578520dc3b3feb24db609c62 (diff)
downloadillumos-gate-3fbbb872ea33adea240e8fd8c692f6d3131cc69b.tar.gz
6634608 Super Top USB disk enclosure caused panic on nevada
6635751 ehci: data buffer error should not be considered transaction error
-rw-r--r--usr/src/uts/common/io/usb/hcd/ehci/ehci_intr.c38
-rw-r--r--usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c14
-rw-r--r--usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c32
-rw-r--r--usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h5
4 files changed, 68 insertions, 21 deletions
diff --git a/usr/src/uts/common/io/usb/hcd/ehci/ehci_intr.c b/usr/src/uts/common/io/usb/hcd/ehci/ehci_intr.c
index 273fca7ed3..4362d03110 100644
--- a/usr/src/uts/common/io/usb/hcd/ehci/ehci_intr.c
+++ b/usr/src/uts/common/io/usb/hcd/ehci/ehci_intr.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -519,17 +519,6 @@ ehci_check_for_error(
"ehci_check_for_error: Halted");
error = USB_CR_STALL;
break;
- case EHCI_QTD_CTRL_DATA_BUFFER_ERROR:
- if (tw->tw_direction == EHCI_QTD_CTRL_IN_PID) {
- USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
- "ehci_check_for_error: Buffer Overrun");
- error = USB_CR_BUFFER_OVERRUN;
- } else {
- USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
- "ehci_check_for_error: Buffer Underrun");
- error = USB_CR_BUFFER_UNDERRUN;
- }
- break;
case EHCI_QTD_CTRL_BABBLE_DETECTED:
USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_error: Babble Detected");
@@ -556,6 +545,31 @@ ehci_check_for_error(
error = USB_CR_OK;
}
break;
+ case EHCI_QTD_CTRL_DATA_BUFFER_ERROR:
+ /*
+ * Data buffer error is not necessarily an error,
+ * the transaction might have completed successfully
+ * after some retries. It can be ignored if the
+ * queue is not halted.
+ */
+ if (!(ctrl & EHCI_QTD_CTRL_HALTED_XACT)) {
+ USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
+ "ehci_check_for_error: Data buffer overrun or "
+ "underrun ignored");
+ error = USB_CR_OK;
+ break;
+ }
+
+ if (tw->tw_direction == EHCI_QTD_CTRL_IN_PID) {
+ USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
+ "ehci_check_for_error: Buffer Overrun");
+ error = USB_CR_BUFFER_OVERRUN;
+ } else {
+ USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
+ "ehci_check_for_error: Buffer Underrun");
+ error = USB_CR_BUFFER_UNDERRUN;
+ }
+ break;
case EHCI_QTD_CTRL_MISSED_uFRAME:
USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_check_for_error: Missed uFrame");
diff --git a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c
index 53f557d522..2bd46c2d14 100644
--- a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c
+++ b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -350,7 +350,11 @@ static struct blacklist {
/* ScanLogic USB Storage Device */
{MS_SCANLOGIC_VID, MS_SCANLOGIC_PID1, 0,
- SCSA2USB_ATTRS_NO_CAP_ADJUST}
+ SCSA2USB_ATTRS_NO_CAP_ADJUST},
+
+ /* Super Top USB 2.0 IDE Device */
+ {MS_SUPERTOP_VID, MS_SUPERTOP_DEVICE_6600, 0,
+ SCSA2USB_ATTRS_USE_CSW_RESIDUE}
};
@@ -5027,7 +5031,7 @@ scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
cmd->cmd_done = 1;
/* FALLTHROUGH */
- default:
+ default:
handle_data:
if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
/*
@@ -5041,8 +5045,8 @@ handle_data:
USB_DPRINTF_L3(DPRINT_MASK_SCSA,
scsa2usbp->scsa2usb_log_handle,
- "len = 0x%x total = 0x%lx",
- len, cmd->cmd_total_xfercount);
+ "len = 0x%x total = 0x%lx offset = 0x%lx",
+ len, cmd->cmd_total_xfercount, cmd->cmd_offset);
/*
* update total_xfercount now but it may be
diff --git a/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c b/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c
index 0398de1813..49b2ac4374 100644
--- a/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c
+++ b/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -676,9 +676,10 @@ scsa2usb_handle_csw_result(scsa2usb_state_t *scsa2usbp, mblk_t *data)
if (residue || cmd->cmd_resid_xfercount) {
USB_DPRINTF_L2(DPRINT_MASK_SCSA,
scsa2usbp->scsa2usb_log_handle,
- "total=0x%lx cmd_xfercount=0x%lx residue=0x%x",
+ "total=0x%lx cmd_xfercount=0x%lx residue=0x%x "
+ "cmd_offset=0x%lx",
cmd->cmd_total_xfercount, cmd->cmd_xfercount,
- residue);
+ residue, cmd->cmd_offset);
/*
* we need to adjust using the residue and
@@ -689,6 +690,13 @@ scsa2usb_handle_csw_result(scsa2usb_state_t *scsa2usbp, mblk_t *data)
*/
cmd->cmd_total_xfercount += cmd->cmd_xfercount -
cmd->cmd_resid_xfercount;
+ /*
+ * we need to adjust cmd_offset as well, or the data
+ * buffer for subsequent transfer may exceed the buffer
+ * boundary
+ */
+ cmd->cmd_offset -= cmd->cmd_xfercount -
+ cmd->cmd_resid_xfercount;
/*
* now take the min of the reported residue by
@@ -708,11 +716,29 @@ scsa2usb_handle_csw_result(scsa2usb_state_t *scsa2usbp, mblk_t *data)
/* some devices lie about the resid, ignore */
cmd->cmd_total_xfercount -=
cmd->cmd_xfercount - cmd->cmd_resid_xfercount;
+ cmd->cmd_offset +=
+ cmd->cmd_xfercount - cmd->cmd_resid_xfercount;
} else {
cmd->cmd_total_xfercount -=
cmd->cmd_xfercount -
max(min(residue, cmd->cmd_xfercount),
cmd->cmd_resid_xfercount);
+ cmd->cmd_offset +=
+ cmd->cmd_xfercount -
+ max(min(residue, cmd->cmd_xfercount),
+ cmd->cmd_resid_xfercount);
+ /*
+ * if HCD does not report residue while the device
+ * reports a residue equivalent to the xfercount,
+ * it is very likely the device lies about the
+ * residue. we need to stop the command, or we'll
+ * get into an infinite retry loop.
+ */
+ if ((cmd->cmd_resid_xfercount == 0) &&
+ (residue == cmd->cmd_xfercount)) {
+ cmd->cmd_xfercount = 0;
+ cmd->cmd_done = 1;
+ }
}
pkt->pkt_resid = cmd->cmd_total_xfercount;
diff --git a/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h b/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h
index 69326494f8..dffff30f20 100644
--- a/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h
+++ b/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,6 +103,9 @@ extern "C" {
#define MS_SCANLOGIC_VID 0x04ce /* VendorID of ScanLogic */
#define MS_SCANLOGIC_PID1 0x0002 /* SL USB Storage Device */
+#define MS_SUPERTOP_VID 0x14cd /* Super Top USB 2.0 IDE enclosure */
+#define MS_SUPERTOP_DEVICE_6600 0x6600
+
/*
* The AMI virtual floppy device is not a real USB storage device, but
* emulated by the SP firmware shipped together with important Sun x86