summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-05-21 13:29:28 +0000
committermav <mav@FreeBSD.org>2010-05-21 13:29:28 +0000
commite4bb679c9979f72c905654db6d91def9c4c2340b (patch)
treec2c74ba78c41e535597ccdc90dfd2ea994bc193e /sys/dev/ata
parent890c865dcff99aec8227610af427901ad973cb96 (diff)
downloadFreeBSD-src-e4bb679c9979f72c905654db6d91def9c4c2340b.zip
FreeBSD-src-e4bb679c9979f72c905654db6d91def9c4c2340b.tar.gz
Improve suspend/resume support. Make sure controller is idle on suspend
and reset it on resume.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 5c6f0db..707cc8c 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -432,7 +432,13 @@ ata_suspend(device_t dev)
if (!dev || !(ch = device_get_softc(dev)))
return ENXIO;
-#ifndef ATA_CAM
+#ifdef ATA_CAM
+ mtx_lock(&ch->state_mtx);
+ xpt_freeze_simq(ch->sim, 1);
+ while (ch->state != ATA_IDLE)
+ msleep(ch, &ch->state_mtx, PRIBIO, "atasusp", hz/100);
+ mtx_unlock(&ch->state_mtx);
+#else
/* wait for the channel to be IDLE or detached before suspending */
while (ch->r_irq) {
mtx_lock(&ch->state_mtx);
@@ -452,16 +458,21 @@ ata_suspend(device_t dev)
int
ata_resume(device_t dev)
{
+ struct ata_channel *ch;
int error;
/* check for valid device */
- if (!dev || !device_get_softc(dev))
+ if (!dev || !(ch = device_get_softc(dev)))
return ENXIO;
+#ifdef ATA_CAM
+ mtx_lock(&ch->state_mtx);
+ error = ata_reinit(dev);
+ xpt_release_simq(ch->sim, TRUE);
+ mtx_unlock(&ch->state_mtx);
+#else
/* reinit the devices, we dont know what mode/state they are in */
error = ata_reinit(dev);
-
-#ifndef ATA_CAM
/* kick off requests on the queue */
ata_start(dev);
#endif
OpenPOWER on IntegriCloud