summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-11-18 19:28:45 +0000
committermav <mav@FreeBSD.org>2010-11-18 19:28:45 +0000
commitdfc44b4d0bc56eb74bf3f28dc62e081ce7efc4d4 (patch)
tree486f52aa6da65c636d8cbd155c730d66d637fb82 /sys/dev/ata
parent04e0bb722d8317cd1c6b03227f1f49e480ee1c68 (diff)
downloadFreeBSD-src-dfc44b4d0bc56eb74bf3f28dc62e081ce7efc4d4.zip
FreeBSD-src-dfc44b4d0bc56eb74bf3f28dc62e081ce7efc4d4.tar.gz
Make ATA_CAM wrapper to report SATA power management capabilities to CAM to
make it configure device to initiate transitions if controller configured to accept them. This makes hint.ata.X.pm_level=1 mode working.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c19
-rw-r--r--sys/dev/ata/ata-all.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index c7fe9ba..9614ef1 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -171,7 +171,12 @@ ata_attach(device_t dev)
ch->user[i].bytecount = 8192;
else
ch->user[i].bytecount = MAXPHYS;
+ ch->user[i].caps = 0;
ch->curr[i] = ch->user[i];
+ if (ch->pm_level > 0)
+ ch->user[i].caps |= CTS_SATA_CAPS_H_PMREQ;
+ if (ch->pm_level > 1)
+ ch->user[i].caps |= CTS_SATA_CAPS_D_PMREQ;
}
#endif
callout_init(&ch->poll_callout, 1);
@@ -1627,6 +1632,8 @@ ataaction(struct cam_sim *sim, union ccb *ccb)
d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
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;
} else {
if (cts->xport_specific.ata.valid & CTS_ATA_VALID_MODE) {
if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
@@ -1672,9 +1679,21 @@ ataaction(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.atapi = d->atapi;
cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI;
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 17a28c0..1b792fc 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -535,6 +535,7 @@ struct ata_cam_device {
int mode;
u_int bytecount;
u_int atapi;
+ u_int caps;
};
#endif
OpenPOWER on IntegriCloud