diff options
author | mav <mav@FreeBSD.org> | 2010-05-21 13:29:28 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-05-21 13:29:28 +0000 |
commit | e4bb679c9979f72c905654db6d91def9c4c2340b (patch) | |
tree | c2c74ba78c41e535597ccdc90dfd2ea994bc193e /sys/dev/ata | |
parent | 890c865dcff99aec8227610af427901ad973cb96 (diff) | |
download | FreeBSD-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.c | 19 |
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 |