diff options
| author | Søren Schmidt <sos@FreeBSD.org> | 2003-05-02 13:47:44 +0000 |
|---|---|---|
| committer | Søren Schmidt <sos@FreeBSD.org> | 2003-05-02 13:47:44 +0000 |
| commit | 93f307bbeae058eb65d1f7fff38d0fccfb139b4b (patch) | |
| tree | 8bc5a20772d204c38e0a29546e4855994ee98d4a /sys/dev | |
| parent | 3daf7274a169ad0e8985da35c11106fb14f944ed (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ata/ata-all.c | 42 | ||||
| -rw-r--r-- | sys/dev/ata/ata-disk.c | 22 | ||||
| -rw-r--r-- | sys/dev/ata/ata-disk.h | 2 |
3 files changed, 40 insertions, 26 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 54ae0906d8dc9..16c0229d10d3e 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -67,6 +67,7 @@ static void ata_boot_attach(void); static void ata_intr(void *); static int ata_getparam(struct ata_device *, u_int8_t); static int ata_service(struct ata_channel *); +static void ata_flush(struct ata_device *); static void bswap(int8_t *, int); static void btrim(int8_t *, int); static void bpack(int8_t *, int8_t *, int); @@ -198,9 +199,9 @@ ata_detach(device_t dev) s = splbio(); #ifdef DEV_ATADISK if (ch->devices & ATA_ATA_MASTER && ch->device[MASTER].driver) - ad_detach(&ch->device[MASTER], 1); + ad_detach(&ch->device[MASTER]); if (ch->devices & ATA_ATA_SLAVE && ch->device[SLAVE].driver) - ad_detach(&ch->device[SLAVE], 1); + ad_detach(&ch->device[SLAVE]); #endif #if DEV_ATAPIALL if (ch->devices & ATA_ATAPI_MASTER && ch->device[MASTER].driver) @@ -214,10 +215,12 @@ ata_detach(device_t dev) splx(s); if (ch->device[MASTER].param) { + ata_flush(&ch->device[MASTER]); free(ch->device[MASTER].param, M_ATA); ch->device[MASTER].param = NULL; } if (ch->device[SLAVE].param) { + ata_flush(&ch->device[SLAVE]); free(ch->device[SLAVE].param, M_ATA); ch->device[SLAVE].param = NULL; } @@ -818,9 +821,9 @@ ata_reinit(struct ata_channel *ch) if ((misdev = devices & ~ch->devices)) { #ifdef DEV_ATADISK if (misdev & ATA_ATA_MASTER && ch->device[MASTER].driver) - ad_detach(&ch->device[MASTER], 0); + ad_detach(&ch->device[MASTER]); if (misdev & ATA_ATA_SLAVE && ch->device[SLAVE].driver) - ad_detach(&ch->device[SLAVE], 0); + ad_detach(&ch->device[SLAVE]); #endif #if DEV_ATAPIALL if (misdev & ATA_ATAPI_MASTER && ch->device[MASTER].driver) @@ -916,6 +919,32 @@ ata_service(struct ata_channel *ch) return ATA_OP_FINISHED; } +static void +ata_flush(struct ata_device *atadev) +{ + if (ata_command(atadev, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_WAIT_READY)) + ata_prtdev(atadev, "flushing device failed\n"); +} + +static void +ata_shutdown(void *arg, int howto) +{ + struct ata_channel *ch; + int ctlr; + + /* flush cache on all devices */ + for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) { + if (!(ch = devclass_get_softc(ata_devclass, ctlr))) + continue; + ch->locking(ch, ATA_LF_LOCK); + if (ch->device[MASTER].param) + ata_flush(&ch->device[MASTER]); + if (ch->device[SLAVE].param) + ata_flush(&ch->device[SLAVE]); + ch->locking(ch, ATA_LF_UNLOCK); + } +} + int ata_wait(struct ata_device *atadev, u_int8_t mask) { @@ -1538,5 +1567,10 @@ ata_init(void) printf("ata: config_intrhook_establish failed\n"); free(ata_delayed_attach, M_TEMP); } + /* Register a handler to flush write caches on shutdown */ + if ((EVENTHANDLER_REGISTER(shutdown_post_sync, ata_shutdown, + NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) + printf("ata: shutdown event registration failed!\n"); + } SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL) diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index cb4e16364b407..ffd31fb2ed80d 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -53,7 +53,6 @@ /* prototypes */ static disk_open_t adopen; -static disk_close_t adclose; static disk_strategy_t adstrategy; static dumper_t addump; static void ad_invalidatequeue(struct ad_softc *, struct ad_request *); @@ -186,7 +185,6 @@ ad_attach(struct ata_device *atadev) ATA_UNLOCK_CH(atadev->channel); adp->disk.d_open = adopen; - adp->disk.d_close = adclose; adp->disk.d_strategy = adstrategy; adp->disk.d_dump = addump; adp->disk.d_name = "ad"; @@ -208,7 +206,7 @@ ad_attach(struct ata_device *atadev) } void -ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ +ad_detach(struct ata_device *atadev) { struct ad_softc *adp = atadev->driver; struct ad_request *request; @@ -229,10 +227,6 @@ ad_detach(struct ata_device *atadev, int flush) /* get rid of flush XXX SOS */ if (adp->flags & AD_F_RAID_SUBDISK) ata_raiddisk_detach(adp); - if (flush) { - if (ata_command(atadev, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_WAIT_READY)) - ata_prtdev(atadev, "flushing cache on detach failed\n"); - } ata_free_name(atadev); ata_free_lun(&adp_lun_map, adp->lun); atadev->driver = NULL; @@ -254,20 +248,6 @@ adopen(struct disk *dp) return 0; } -static int -adclose(struct disk *dp) -{ - struct ad_softc *adp = dp->d_drv1; - - adp->device->channel->locking(adp->device->channel, ATA_LF_LOCK); - ATA_SLEEPLOCK_CH(adp->device->channel, ATA_CONTROL); - if (ata_command(adp->device, ATA_C_FLUSHCACHE, 0, 0, 0, ATA_WAIT_READY)) - ata_prtdev(adp->device, "flushing cache on close failed\n"); - ATA_UNLOCK_CH(adp->device->channel); - adp->device->channel->locking(adp->device->channel, ATA_LF_UNLOCK); - return 0; -} - static void adstrategy(struct bio *bp) { diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h index f6809275b568f..11d58c1367b78 100644 --- a/sys/dev/ata/ata-disk.h +++ b/sys/dev/ata/ata-disk.h @@ -75,7 +75,7 @@ struct ad_softc { }; void ad_attach(struct ata_device *); -void ad_detach(struct ata_device *, int); +void ad_detach(struct ata_device *); void ad_reinit(struct ata_device *); void ad_start(struct ata_device *); int ad_transfer(struct ad_request *); |
