summaryrefslogtreecommitdiffstats
path: root/sys/dev/ahci
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-05-02 12:07:47 +0000
committermav <mav@FreeBSD.org>2010-05-02 12:07:47 +0000
commit90843ddc5c2afced3e89219701abb4384aba3190 (patch)
treeb5c5b295203637665fed48360b91930d6b26ea37 /sys/dev/ahci
parent4e502e1ceb65ddf828e427fe014e2a31cff0307a (diff)
downloadFreeBSD-src-90843ddc5c2afced3e89219701abb4384aba3190.zip
FreeBSD-src-90843ddc5c2afced3e89219701abb4384aba3190.tar.gz
Make SATA XPT negotiate and enable some additional SATA features, such as:
- device initiated power management (some devices support only this way); - Automatic Partial to Slumber Transition (more power saving); - DMA auto-activation (expected to slightly improve performance). More features could be added later, when hardware supports.
Diffstat (limited to 'sys/dev/ahci')
-rw-r--r--sys/dev/ahci/ahci.c166
-rw-r--r--sys/dev/ahci/ahci.h1
2 files changed, 97 insertions, 70 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 34f1be4..60fb851 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -111,6 +111,7 @@ static struct {
#define AHCI_Q_EDGEIS 64
#define AHCI_Q_SATA2 128
#define AHCI_Q_NOBSYRES 256
+#define AHCI_Q_NOAA 512
} ahci_ids[] = {
{0x43801002, 0x00, "ATI IXP600", 0},
{0x43901002, 0x00, "ATI IXP700", 0},
@@ -167,75 +168,75 @@ static struct {
{0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS},
{0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES},
{0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES},
- {0x044c10de, 0x00, "NVIDIA MCP65", 0},
- {0x044d10de, 0x00, "NVIDIA MCP65", 0},
- {0x044e10de, 0x00, "NVIDIA MCP65", 0},
- {0x044f10de, 0x00, "NVIDIA MCP65", 0},
- {0x045c10de, 0x00, "NVIDIA MCP65", 0},
- {0x045d10de, 0x00, "NVIDIA MCP65", 0},
- {0x045e10de, 0x00, "NVIDIA MCP65", 0},
- {0x045f10de, 0x00, "NVIDIA MCP65", 0},
- {0x055010de, 0x00, "NVIDIA MCP67", 0},
- {0x055110de, 0x00, "NVIDIA MCP67", 0},
- {0x055210de, 0x00, "NVIDIA MCP67", 0},
- {0x055310de, 0x00, "NVIDIA MCP67", 0},
- {0x055410de, 0x00, "NVIDIA MCP67", 0},
- {0x055510de, 0x00, "NVIDIA MCP67", 0},
- {0x055610de, 0x00, "NVIDIA MCP67", 0},
- {0x055710de, 0x00, "NVIDIA MCP67", 0},
- {0x055810de, 0x00, "NVIDIA MCP67", 0},
- {0x055910de, 0x00, "NVIDIA MCP67", 0},
- {0x055A10de, 0x00, "NVIDIA MCP67", 0},
- {0x055B10de, 0x00, "NVIDIA MCP67", 0},
- {0x058410de, 0x00, "NVIDIA MCP67", 0},
- {0x07f010de, 0x00, "NVIDIA MCP73", 0},
- {0x07f110de, 0x00, "NVIDIA MCP73", 0},
- {0x07f210de, 0x00, "NVIDIA MCP73", 0},
- {0x07f310de, 0x00, "NVIDIA MCP73", 0},
- {0x07f410de, 0x00, "NVIDIA MCP73", 0},
- {0x07f510de, 0x00, "NVIDIA MCP73", 0},
- {0x07f610de, 0x00, "NVIDIA MCP73", 0},
- {0x07f710de, 0x00, "NVIDIA MCP73", 0},
- {0x07f810de, 0x00, "NVIDIA MCP73", 0},
- {0x07f910de, 0x00, "NVIDIA MCP73", 0},
- {0x07fa10de, 0x00, "NVIDIA MCP73", 0},
- {0x07fb10de, 0x00, "NVIDIA MCP73", 0},
- {0x0ad010de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad110de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad210de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad310de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad410de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad510de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad610de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad710de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad810de, 0x00, "NVIDIA MCP77", 0},
- {0x0ad910de, 0x00, "NVIDIA MCP77", 0},
- {0x0ada10de, 0x00, "NVIDIA MCP77", 0},
- {0x0adb10de, 0x00, "NVIDIA MCP77", 0},
- {0x0ab410de, 0x00, "NVIDIA MCP79", 0},
- {0x0ab510de, 0x00, "NVIDIA MCP79", 0},
- {0x0ab610de, 0x00, "NVIDIA MCP79", 0},
- {0x0ab710de, 0x00, "NVIDIA MCP79", 0},
- {0x0ab810de, 0x00, "NVIDIA MCP79", 0},
- {0x0ab910de, 0x00, "NVIDIA MCP79", 0},
- {0x0aba10de, 0x00, "NVIDIA MCP79", 0},
- {0x0abb10de, 0x00, "NVIDIA MCP79", 0},
- {0x0abc10de, 0x00, "NVIDIA MCP79", 0},
- {0x0abd10de, 0x00, "NVIDIA MCP79", 0},
- {0x0abe10de, 0x00, "NVIDIA MCP79", 0},
- {0x0abf10de, 0x00, "NVIDIA MCP79", 0},
- {0x0d8410de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8510de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8610de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8710de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8810de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8910de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8a10de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8b10de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8c10de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8d10de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8e10de, 0x00, "NVIDIA MCP89", 0},
- {0x0d8f10de, 0x00, "NVIDIA MCP89", 0},
+ {0x044c10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x044d10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x044e10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x044f10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x045c10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x045d10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x045e10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x045f10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
+ {0x055010de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055110de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055210de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055310de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055410de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055510de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055610de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055710de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055810de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055910de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055A10de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x055B10de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x058410de, 0x00, "NVIDIA MCP67", AHCI_Q_NOAA},
+ {0x07f010de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f110de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f210de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f310de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f410de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f510de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f610de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f710de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f810de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07f910de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07fa10de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x07fb10de, 0x00, "NVIDIA MCP73", AHCI_Q_NOAA},
+ {0x0ad010de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad110de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad210de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad310de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad410de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad510de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad610de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad710de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad810de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ad910de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ada10de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0adb10de, 0x00, "NVIDIA MCP77", AHCI_Q_NOAA},
+ {0x0ab410de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0ab510de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0ab610de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0ab710de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0ab810de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0ab910de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0aba10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0abb10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0abc10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0abd10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0abe10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0abf10de, 0x00, "NVIDIA MCP79", AHCI_Q_NOAA},
+ {0x0d8410de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8510de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8610de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8710de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8810de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8910de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8a10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8b10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8c10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8d10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8e10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
+ {0x0d8f10de, 0x00, "NVIDIA MCP89", AHCI_Q_NOAA},
{0x33491106, 0x00, "VIA VT8251", 0},
{0x62871106, 0x00, "VIA VT8251", 0},
{0x11841039, 0x00, "SiS 966", 0},
@@ -860,7 +861,14 @@ ahci_ch_attach(device_t dev)
ch->user[i].mode = 0;
ch->user[i].bytecount = 8192;
ch->user[i].tags = ch->numslots;
+ ch->user[i].caps = 0;
ch->curr[i] = ch->user[i];
+ if (ch->pm_level) {
+ ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ |
+ CTS_SATA_CAPS_H_APST |
+ CTS_SATA_CAPS_D_PMREQ | CTS_SATA_CAPS_D_APST;
+ }
+ ch->user[i].caps |= CTS_SATA_CAPS_H_DMAAA;
}
rid = ch->unit;
if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -1960,7 +1968,8 @@ ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
et != AHCI_ERR_TIMEOUT)
ahci_rearm_timeout(dev);
/* Start PM timer. */
- if (ch->numrslots == 0 && ch->pm_level > 3) {
+ if (ch->numrslots == 0 && ch->pm_level > 3 &&
+ (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
callout_schedule(&ch->pm_timer,
(ch->pm_level == 4) ? hz / 1000 : hz / 8);
}
@@ -2464,6 +2473,8 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
ch->pm_present = cts->xport_specific.sata.pm_present;
if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI)
d->atapi = cts->xport_specific.sata.atapi;
+ if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
+ d->caps = cts->xport_specific.sata.caps;
ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
@@ -2496,9 +2507,24 @@ ahciaction(struct cam_sim *sim, union ccb *ccb)
cts->xport_specific.sata.valid |=
CTS_SATA_VALID_REVISION;
}
+ cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D;
+ if (ch->pm_level) {
+ if (ch->caps & (AHCI_CAP_PSC | AHCI_CAP_SSC))
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ;
+ if (ch->caps2 & AHCI_CAP2_APST)
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_APST;
+ }
+ if ((ch->caps & AHCI_CAP_SNCQ) &&
+ (ch->quirks & AHCI_Q_NOAA) == 0)
+ cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_DMAAA;
+ cts->xport_specific.sata.caps &=
+ ch->user[ccb->ccb_h.target_id].caps;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
} else {
cts->xport_specific.sata.revision = d->revision;
cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
+ cts->xport_specific.sata.caps = d->caps;
+ cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
}
cts->xport_specific.sata.mode = d->mode;
cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index d4c73c9..1473962 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -372,6 +372,7 @@ struct ahci_device {
u_int bytecount;
u_int atapi;
u_int tags;
+ u_int caps;
};
/* structure describing an ATA channel */
OpenPOWER on IntegriCloud