mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
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.
This commit is contained in:
parent
f930c0db49
commit
da6808c111
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=207499
@ -2855,6 +2855,10 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
|
||||
fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
|
||||
sata->tags);
|
||||
}
|
||||
if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
|
||||
fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
|
||||
sata->caps);
|
||||
}
|
||||
}
|
||||
if (cts->protocol == PROTO_SCSI) {
|
||||
struct ccb_trans_settings_scsi *scsi=
|
||||
|
@ -101,6 +101,7 @@ struct pmp_softc {
|
||||
int events;
|
||||
#define PMP_EV_RESET 1
|
||||
#define PMP_EV_RESCAN 2
|
||||
u_int caps;
|
||||
struct task sysctl_task;
|
||||
struct sysctl_ctx_list sysctl_ctx;
|
||||
struct sysctl_oid *sysctl_tree;
|
||||
@ -457,6 +458,14 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
ata_pm_read_cmd(ataio, 2, 15);
|
||||
break;
|
||||
case PMP_STATE_PRECONFIG:
|
||||
/* Get/update host SATA capabilities. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
|
||||
softc->caps = cts.xport_specific.sata.caps;
|
||||
cam_fill_ataio(ataio,
|
||||
pmp_retry_count,
|
||||
pmpdone,
|
||||
@ -644,14 +653,16 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
(done_ccb->ataio.res.lba_mid << 16) +
|
||||
(done_ccb->ataio.res.lba_low << 8) +
|
||||
done_ccb->ataio.res.sector_count;
|
||||
if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
|
||||
if (((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) ||
|
||||
(res & 0x600) != 0) {
|
||||
if (bootverbose) {
|
||||
printf("%s%d: port %d status: %08x\n",
|
||||
periph->periph_name, periph->unit_number,
|
||||
softc->pm_step, res);
|
||||
}
|
||||
/* Report device speed. */
|
||||
if (xpt_create_path(&dpath, periph,
|
||||
/* Report device speed if it is online. */
|
||||
if ((res & 0xf0f) == 0x103 &&
|
||||
xpt_create_path(&dpath, periph,
|
||||
xpt_path_path_id(periph->path),
|
||||
softc->pm_step, 0) == CAM_REQ_CMP) {
|
||||
bzero(&cts, sizeof(cts));
|
||||
@ -660,6 +671,9 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
cts.xport_specific.sata.revision = (res & 0x0f0) >> 4;
|
||||
cts.xport_specific.sata.valid = CTS_SATA_VALID_REVISION;
|
||||
cts.xport_specific.sata.caps = softc->caps &
|
||||
(CTS_SATA_CAPS_H_PMREQ | CTS_SATA_CAPS_H_DMAAA);
|
||||
cts.xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
xpt_free_path(dpath);
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ typedef enum {
|
||||
PROBE_IDENTIFY,
|
||||
PROBE_SPINUP,
|
||||
PROBE_SETMODE,
|
||||
PROBE_SETPM,
|
||||
PROBE_SETAPST,
|
||||
PROBE_SETDMAAA,
|
||||
PROBE_SET_MULTI,
|
||||
PROBE_INQUIRY,
|
||||
PROBE_FULL_INQUIRY,
|
||||
@ -101,6 +104,9 @@ static char *probe_action_text[] = {
|
||||
"PROBE_IDENTIFY",
|
||||
"PROBE_SPINUP",
|
||||
"PROBE_SETMODE",
|
||||
"PROBE_SETPM",
|
||||
"PROBE_SETAPST",
|
||||
"PROBE_SETDMAAA",
|
||||
"PROBE_SET_MULTI",
|
||||
"PROBE_INQUIRY",
|
||||
"PROBE_FULL_INQUIRY",
|
||||
@ -132,6 +138,7 @@ typedef struct {
|
||||
uint32_t pm_prv;
|
||||
int restart;
|
||||
int spinup;
|
||||
u_int caps;
|
||||
struct cam_periph *periph;
|
||||
} probe_softc;
|
||||
|
||||
@ -393,6 +400,45 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
|
||||
break;
|
||||
}
|
||||
case PROBE_SETPM:
|
||||
cam_fill_ataio(ataio,
|
||||
1,
|
||||
probedone,
|
||||
CAM_DIR_NONE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
30*1000);
|
||||
ata_28bit_cmd(ataio, ATA_SETFEATURES,
|
||||
(softc->caps & CTS_SATA_CAPS_H_PMREQ) ? 0x10 : 0x90,
|
||||
0, 0x03);
|
||||
break;
|
||||
case PROBE_SETAPST:
|
||||
cam_fill_ataio(ataio,
|
||||
1,
|
||||
probedone,
|
||||
CAM_DIR_NONE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
30*1000);
|
||||
ata_28bit_cmd(ataio, ATA_SETFEATURES,
|
||||
(softc->caps & CTS_SATA_CAPS_H_APST) ? 0x10 : 0x90,
|
||||
0, 0x07);
|
||||
break;
|
||||
case PROBE_SETDMAAA:
|
||||
cam_fill_ataio(ataio,
|
||||
1,
|
||||
probedone,
|
||||
CAM_DIR_NONE,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
30*1000);
|
||||
ata_28bit_cmd(ataio, ATA_SETFEATURES,
|
||||
(softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90,
|
||||
0, 0x02);
|
||||
break;
|
||||
case PROBE_SET_MULTI:
|
||||
{
|
||||
u_int sectors, bytecount;
|
||||
@ -685,6 +731,7 @@ probedone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
probe_softc *softc;
|
||||
struct cam_path *path;
|
||||
u_int32_t priority;
|
||||
u_int caps;
|
||||
int found = 1;
|
||||
|
||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
|
||||
@ -879,6 +926,67 @@ device_fail: if ((!softc->restart) &&
|
||||
xpt_schedule(periph, priority);
|
||||
return;
|
||||
case PROBE_SETMODE:
|
||||
if (path->device->transport != XPORT_SATA)
|
||||
goto notsata;
|
||||
/* Set supported bits. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
|
||||
caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H;
|
||||
else
|
||||
caps = 0;
|
||||
if (ident_buf->satacapabilities != 0xffff) {
|
||||
if (ident_buf->satacapabilities & ATA_SUPPORT_IFPWRMNGTRCV)
|
||||
caps |= CTS_SATA_CAPS_D_PMREQ;
|
||||
if (ident_buf->satacapabilities & ATA_SUPPORT_HAPST)
|
||||
caps |= CTS_SATA_CAPS_D_APST;
|
||||
}
|
||||
/* Mask unwanted bits. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_USER_SETTINGS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
|
||||
caps &= cts.xport_specific.sata.caps;
|
||||
/* Store result to SIM. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
cts.xport_specific.sata.caps = caps;
|
||||
cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
softc->caps = caps;
|
||||
if (ident_buf->satasupport & ATA_SUPPORT_IFPWRMNGT) {
|
||||
PROBE_SET_ACTION(softc, PROBE_SETPM);
|
||||
xpt_release_ccb(done_ccb);
|
||||
xpt_schedule(periph, priority);
|
||||
return;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case PROBE_SETPM:
|
||||
if (ident_buf->satacapabilities != 0xffff &&
|
||||
ident_buf->satacapabilities & ATA_SUPPORT_DAPST) {
|
||||
PROBE_SET_ACTION(softc, PROBE_SETAPST);
|
||||
xpt_release_ccb(done_ccb);
|
||||
xpt_schedule(periph, priority);
|
||||
return;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case PROBE_SETAPST:
|
||||
if (ident_buf->satasupport & ATA_SUPPORT_AUTOACTIVATE) {
|
||||
PROBE_SET_ACTION(softc, PROBE_SETDMAAA);
|
||||
xpt_release_ccb(done_ccb);
|
||||
xpt_schedule(periph, priority);
|
||||
return;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case PROBE_SETDMAAA:
|
||||
notsata:
|
||||
if (path->device->protocol == PROTO_ATA) {
|
||||
PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
|
||||
} else {
|
||||
@ -964,6 +1072,35 @@ device_fail: if ((!softc->restart) &&
|
||||
snprintf(ident_buf->revision, sizeof(ident_buf->revision),
|
||||
"%04x", softc->pm_prv);
|
||||
path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
|
||||
/* Set supported bits. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
|
||||
caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H;
|
||||
else
|
||||
caps = 0;
|
||||
/* All PMPs must support PM requests. */
|
||||
caps |= CTS_SATA_CAPS_D_PMREQ;
|
||||
/* Mask unwanted bits. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_USER_SETTINGS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
|
||||
caps &= cts.xport_specific.sata.caps;
|
||||
/* Store result to SIM. */
|
||||
bzero(&cts, sizeof(cts));
|
||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
|
||||
cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
cts.xport_specific.sata.caps = caps;
|
||||
cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS;
|
||||
xpt_action((union ccb *)&cts);
|
||||
softc->caps = caps;
|
||||
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
|
||||
path->device->flags &= ~CAM_DEV_UNCONFIGURED;
|
||||
xpt_acquire_device(path->device);
|
||||
|
@ -837,12 +837,21 @@ struct ccb_trans_settings_sata {
|
||||
#define CTS_SATA_VALID_PM 0x08
|
||||
#define CTS_SATA_VALID_TAGS 0x10
|
||||
#define CTS_SATA_VALID_ATAPI 0x20
|
||||
#define CTS_SATA_VALID_CAPS 0x40
|
||||
int mode; /* Legacy PATA mode */
|
||||
u_int bytecount; /* Length of PIO transaction */
|
||||
int revision; /* SATA revision */
|
||||
u_int pm_present; /* PM is present (XPT->SIM) */
|
||||
u_int tags; /* Number of allowed tags */
|
||||
u_int atapi; /* Length of ATAPI CDB */
|
||||
u_int caps; /* Device and host SATA caps. */
|
||||
#define CTS_SATA_CAPS_H 0x0000ffff
|
||||
#define CTS_SATA_CAPS_H_PMREQ 0x00000001
|
||||
#define CTS_SATA_CAPS_H_APST 0x00000002
|
||||
#define CTS_SATA_CAPS_H_DMAAA 0x00000010 /* Auto-activation */
|
||||
#define CTS_SATA_CAPS_D 0xffff0000
|
||||
#define CTS_SATA_CAPS_D_PMREQ 0x00010000
|
||||
#define CTS_SATA_CAPS_D_APST 0x00020000
|
||||
};
|
||||
|
||||
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
|
||||
|
@ -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;
|
||||
|
@ -372,6 +372,7 @@ struct ahci_device {
|
||||
u_int bytecount;
|
||||
u_int atapi;
|
||||
u_int tags;
|
||||
u_int caps;
|
||||
};
|
||||
|
||||
/* structure describing an ATA channel */
|
||||
|
@ -448,6 +448,8 @@ siis_ch_attach(device_t dev)
|
||||
ch->user[i].bytecount = 8192;
|
||||
ch->user[i].tags = SIIS_MAX_SLOTS;
|
||||
ch->curr[i] = ch->user[i];
|
||||
if (ch->pm_level)
|
||||
ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ;
|
||||
}
|
||||
mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF);
|
||||
rid = ch->unit;
|
||||
@ -1697,6 +1699,8 @@ siisaction(struct cam_sim *sim, union ccb *ccb)
|
||||
}
|
||||
if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
|
||||
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;
|
||||
}
|
||||
@ -1729,9 +1733,17 @@ siisaction(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)
|
||||
cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ;
|
||||
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;
|
||||
|
@ -358,6 +358,7 @@ struct siis_device {
|
||||
u_int bytecount;
|
||||
u_int atapi;
|
||||
u_int tags;
|
||||
u_int caps;
|
||||
};
|
||||
|
||||
/* structure describing an ATA channel */
|
||||
|
Loading…
Reference in New Issue
Block a user