Page MenuHomeFreeBSD

D37585.diff
No OneTemporary

D37585.diff

Index: sys/dev/ahci/ahci.h
===================================================================
--- sys/dev/ahci/ahci.h
+++ sys/dev/ahci/ahci.h
@@ -621,6 +621,8 @@
#define AHCI_Q_NOCCS 0x00400000
#define AHCI_Q_NOAUX 0x00800000
#define AHCI_Q_IOMMU_BUSWIDE 0x01000000
+#define AHCI_Q_NOSPD 0x01000000 /* Ignore SPD field in status */
+#define AHCI_Q_SLOWDEV 0x02000000 /* Device is slow in detecting drives */
#define AHCI_Q_BIT_STRING \
"\020" \
@@ -648,7 +650,9 @@
"\026MRVL_SR_DEL" \
"\027NOCCS" \
"\030NOAUX" \
- "\031IOMMU_BUSWIDE"
+ "\031IOMMU_BUSWIDE" \
+ "\031NOSPD" \
+ "\032SLOWDEV"
int ahci_attach(device_t dev);
int ahci_detach(device_t dev);
Index: sys/dev/ahci/ahci.c
===================================================================
--- sys/dev/ahci/ahci.c
+++ sys/dev/ahci/ahci.c
@@ -2335,19 +2335,62 @@
{
u_int32_t cmd;
int timeout;
+ int delay_time = 10;
+ int timeout_limit = 100000; /* 50000 */
+ int ci = -1;
+ int last_ci = 0;
+ int sact = -1;
+ int last_sact = 0;
+ int ccs = -1;
+ int last_ccs = 0;
+ int cr = 1;
+ int last_cr = 0;
/* Kill all activity on this channel */
cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
+ if ((cmd & AHCI_P_CMD_ST) == 0) {
+ return;
+ }
+ last_cr = ((cmd & AHCI_P_CMD_CR) != 0);
+ if (!last_cr) {
+ /* No Commands Running */
+ }
+
ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_ST);
/* Wait for activity stop. */
timeout = 0;
do {
- DELAY(10);
- if (timeout++ > 50000) {
- device_printf(ch->dev, "stopping AHCI engine failed\n");
+ DELAY(delay_time);
+ if (++timeout >= timeout_limit) {
+ device_printf(ch->dev,
+ "stopping AHCI engine: timeout at %d us (cr=%d, ccs=%d, ci=%d, sact=%d)\n",
+ timeout*delay_time, cr, ccs, ci, sact);
break;
}
- } while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CR);
+
+ cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
+ cr = ((cmd & AHCI_P_CMD_CR) != 0);
+ ccs = ((cmd & AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT);
+
+ ci = ATA_INL(ch->r_mem, AHCI_P_CI);
+ sact = ATA_INL(ch->r_mem, AHCI_P_SACT);
+
+ if (cr != last_cr) {
+ last_cr = cr;
+ }
+
+ if (ci != last_ci) {
+ last_ci = ci;
+ }
+
+ if (sact != last_sact) {
+ last_sact = sact;
+ }
+
+ if (ccs != last_ccs) {
+ last_ccs = ccs;
+ }
+ } while (cr);
ch->eslots = 0;
}
@@ -2606,14 +2649,26 @@
{
u_int32_t status;
int timeout, found = 0;
-
- /* Wait up to 100ms for "connect well" */
- for (timeout = 0; timeout < 1000 ; timeout++) {
+ int last_status = 0;
+ int delay_time = 10; /* 10 us */
+ int timeout_full_limit = 100000 / delay_time; /* 100ms */
+ int timeout_detect_limit = 10000 / delay_time; /* 10ms */
+
+ for (timeout = 0; timeout < timeout_full_limit ; timeout++) {
status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
- if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE)
+
+ if (status != last_status) {
+ last_status = status;
+ }
+ if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE) {
found = 1;
+ /* Increase timeout to 500ms after first status change to allow for slow devices
+ (needed on Dell BOSS-S1 with later firmwares) */
+ if (ch->quirks & AHCI_Q_SLOWDEV)
+ timeout_full_limit = 500000 / delay_time;
+ }
if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
- ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+ ((ch->quirks & AHCI_Q_NOSPD) || (status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
break;
if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) {
@@ -2623,15 +2678,15 @@
}
return (0);
}
- if (found == 0 && timeout >= 100)
+ if (found == 0 && timeout >= timeout_detect_limit)
break;
- DELAY(100);
+ DELAY(delay_time);
}
- if (timeout >= 1000 || !found) {
+ if (!found || timeout >= timeout_full_limit) {
if (bootverbose) {
device_printf(ch->dev,
- "SATA connect timeout time=%dus status=%08x\n",
- timeout * 100, status);
+ "SATA connect timeout status 0x%08x at time=%dus\n",
+ status, timeout * delay_time);
}
return (0);
}
Index: sys/dev/ahci/ahci_pci.c
===================================================================
--- sys/dev/ahci/ahci_pci.c
+++ sys/dev/ahci/ahci_pci.c
@@ -1,4 +1,4 @@
-/*-
+/*
* Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
@@ -291,8 +291,9 @@
{0x92151b4b, 0x00, "Marvell 88SE9215", 0},
{0x92201b4b, 0x00, "Marvell 88SE9220", AHCI_Q_ALTSIG |
AHCI_Q_IOMMU_BUSWIDE},
+ {0x92201b4b, 0x00, "Marvell 88SE9220", AHCI_Q_ALTSIG},
{0x92301b4b, 0x00, "Marvell 88SE9230", AHCI_Q_ALTSIG |
- AHCI_Q_IOMMU_BUSWIDE},
+ AHCI_Q_IOMMU_BUSWIDE | AHCI_Q_SLOWDEV},
{0x92351b4b, 0x00, "Marvell 88SE9235", 0},
{0x06201103, 0x00, "HighPoint RocketRAID 620", 0},
{0x06201b4b, 0x00, "HighPoint RocketRAID 620", 0},

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 10:49 AM (13 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31971661
Default Alt Text
D37585.diff (4 KB)

Event Timeline