Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153488358
D37585.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D37585.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D37585: ahci: extend init timeouts for Marvell 88SE9220 (Dell BOSS-S1) controller
Attached
Detach File
Event Timeline
Log In to Comment