aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>2003-05-02 13:47:44 +0000
committerSøren Schmidt <sos@FreeBSD.org>2003-05-02 13:47:44 +0000
commit93f307bbeae058eb65d1f7fff38d0fccfb139b4b (patch)
tree8bc5a20772d204c38e0a29546e4855994ee98d4a
parent3daf7274a169ad0e8985da35c11106fb14f944ed (diff)
Notes
-rw-r--r--sys/dev/ata/ata-all.c42
-rw-r--r--sys/dev/ata/ata-disk.c22
-rw-r--r--sys/dev/ata/ata-disk.h2
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 *);