summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ahci/ahci.c17
-rw-r--r--sys/dev/ahci/ahci.h4
-rw-r--r--sys/dev/ahci/ahci_pci.c18
3 files changed, 26 insertions, 13 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index f8807e7..a9061bc 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -711,7 +711,7 @@ ahci_ch_attach(device_t dev)
/* Construct SIM entry */
ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch,
device_get_unit(dev), (struct mtx *)&ch->mtx,
- min(2, ch->numslots),
+ (ch->quirks & AHCI_Q_NOCCS) ? 1 : min(2, ch->numslots),
(ch->caps & AHCI_CAP_SNCQ) ? ch->numslots : 0,
devq);
if (ch->sim == NULL) {
@@ -1224,8 +1224,19 @@ ahci_ch_intr_main(struct ahci_channel *ch, uint32_t istatus)
/* Process command errors */
if (istatus & (AHCI_P_IX_OF | AHCI_P_IX_IF |
AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
- ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
- >> AHCI_P_CMD_CCS_SHIFT;
+ if (ch->quirks & AHCI_Q_NOCCS) {
+ /*
+ * ASMedia chips sometimes report failed commands as
+ * completed. Count all running commands as failed.
+ */
+ cstatus |= ch->rslots;
+
+ /* They also report wrong CCS, so try to guess one. */
+ ccs = powerof2(cstatus) ? ffs(cstatus) - 1 : -1;
+ } else {
+ ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) &
+ AHCI_P_CMD_CCS_MASK) >> AHCI_P_CMD_CCS_SHIFT;
+ }
//device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x fbs %08x ccs %d\n",
// __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
// serr, ATA_INL(ch->r_mem, AHCI_P_FBS), ccs);
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index 61643c1..ca7631e 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -574,6 +574,7 @@ enum ahci_err_type {
#define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */
#define AHCI_Q_ABAR0 0x00010000
#define AHCI_Q_1MSI 0x00020000
+#define AHCI_Q_NOCCS 0x00400000
#define AHCI_Q_BIT_STRING \
"\020" \
@@ -594,7 +595,8 @@ enum ahci_err_type {
"\017MAXIO_64K" \
"\020SATA1_UNIT0" \
"\021ABAR0" \
- "\0221MSI"
+ "\0221MSI" \
+ "\027NOCCS"
int ahci_attach(device_t dev);
int ahci_detach(device_t dev);
diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c
index 054422f..7f4a1b6 100644
--- a/sys/dev/ahci/ahci_pci.c
+++ b/sys/dev/ahci/ahci_pci.c
@@ -73,15 +73,15 @@ static const struct {
{0x78021022, 0x00, "AMD Hudson-2", 0},
{0x78031022, 0x00, "AMD Hudson-2", 0},
{0x78041022, 0x00, "AMD Hudson-2", 0},
- {0x06011b21, 0x00, "ASMedia ASM1060", 0},
- {0x06021b21, 0x00, "ASMedia ASM1060", 0},
- {0x06111b21, 0x00, "ASMedia ASM1061", 0},
- {0x06121b21, 0x00, "ASMedia ASM1062", 0},
- {0x06201b21, 0x00, "ASMedia ASM106x", 0},
- {0x06211b21, 0x00, "ASMedia ASM106x", 0},
- {0x06221b21, 0x00, "ASMedia ASM106x", 0},
- {0x06241b21, 0x00, "ASMedia ASM106x", 0},
- {0x06251b21, 0x00, "ASMedia ASM106x", 0},
+ {0x06011b21, 0x00, "ASMedia ASM1060", AHCI_Q_NOCCS},
+ {0x06021b21, 0x00, "ASMedia ASM1060", AHCI_Q_NOCCS},
+ {0x06111b21, 0x00, "ASMedia ASM1061", AHCI_Q_NOCCS},
+ {0x06121b21, 0x00, "ASMedia ASM1062", AHCI_Q_NOCCS},
+ {0x06201b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS},
+ {0x06211b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS},
+ {0x06221b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS},
+ {0x06241b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS},
+ {0x06251b21, 0x00, "ASMedia ASM106x", AHCI_Q_NOCCS},
{0x26528086, 0x00, "Intel ICH6", AHCI_Q_NOFORCE},
{0x26538086, 0x00, "Intel ICH6M", AHCI_Q_NOFORCE},
{0x26818086, 0x00, "Intel ESB2", 0},
OpenPOWER on IntegriCloud