diff options
author | mav <mav@FreeBSD.org> | 2010-11-18 19:28:45 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-11-18 19:28:45 +0000 |
commit | dfc44b4d0bc56eb74bf3f28dc62e081ce7efc4d4 (patch) | |
tree | 486f52aa6da65c636d8cbd155c730d66d637fb82 /sys/dev/ata | |
parent | 04e0bb722d8317cd1c6b03227f1f49e480ee1c68 (diff) | |
download | FreeBSD-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.c | 19 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 1 |
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 |