diff options
author | sl147100 <none@none> | 2008-01-07 19:38:05 -0800 |
---|---|---|
committer | sl147100 <none@none> | 2008-01-07 19:38:05 -0800 |
commit | 3fbbb872ea33adea240e8fd8c692f6d3131cc69b (patch) | |
tree | 678d2a431db6b7652b3a3888bf180798d1775f63 | |
parent | 2850d85b7b93f31e578520dc3b3feb24db609c62 (diff) | |
download | illumos-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.c | 38 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/scsa2usb/scsa2usb.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c | 32 | ||||
-rw-r--r-- | usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h | 5 |
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 |