From 2499ae4d6f8e22c6fb9509842c2765109edf9276 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Tue, 6 Nov 2007 02:49:20 +0000 Subject: Fix SDF_DIRTY handling, eliminate useless SDF_FLUSHING. The sd_flush() called from the last sdclose() on a device will now reset SDF_DIRTY after submitting the SYNCHRONIZE CACHE command. sddone() need not worry about SDF_DIRTY since it was never called for the SYNCHRONIZE CACHE command anyway. This eliminates a spurious SYNCHRONIZE CACHE command being issued for every sd device from sd_shutdown(). ok dlg@ --- sys/scsi/scsiconf.c | 7 +++++-- sys/scsi/sd.c | 50 +++++++++++++++++--------------------------------- sys/scsi/sdvar.h | 5 ++--- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index a32a29ec168..b2c4e367216 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.c,v 1.126 2007/09/16 15:54:52 krw Exp $ */ +/* $OpenBSD: scsiconf.c,v 1.127 2007/11/06 02:49:19 krw Exp $ */ /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ /* @@ -799,7 +799,10 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun) sc_link->quirks &= ~SDEV_NOSYNC; if ((inqbuf.flags & SID_WBus16) != 0) sc_link->quirks &= ~SDEV_NOWIDE; - } + } else + /* Older devices do not have SYNCHRONIZE CACHE capability. */ + sc_link->quirks |= SDEV_NOSYNCCACHE; + /* * Now apply any quirks from the table. */ diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index ea85c9bb31a..c8027ef918c 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.137 2007/09/15 19:22:18 bluhm Exp $ */ +/* $OpenBSD: sd.c,v 1.138 2007/11/06 02:49:19 krw Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -773,11 +773,6 @@ sddone(struct scsi_xfer *xs) { struct sd_softc *sd = xs->sc_link->device_softc; - if (sd->flags & SDF_FLUSHING) { - /* Flush completed, no longer dirty. */ - sd->flags &= ~(SDF_FLUSHING|SDF_DIRTY); - } - if (xs->bp != NULL) disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid), (xs->bp->b_flags & B_READ)); @@ -1470,36 +1465,25 @@ void sd_flush(struct sd_softc *sd, int flags) { struct scsi_link *sc_link = sd->sc_link; - struct scsi_synchronize_cache sync_cmd; + struct scsi_generic cmd; + + if (sc_link->quirks & SDEV_NOSYNCCACHE) + return; /* - * If the device is SCSI-2, issue a SYNCHRONIZE CACHE. - * We issue with address 0 length 0, which should be - * interpreted by the device as "all remaining blocks - * starting at address 0". We ignore ILLEGAL REQUEST - * in the event that the command is not supported by - * the device, and poll for completion so that we know - * that the cache has actually been flushed. - * - * Unless, that is, the device can't handle the SYNCHRONIZE CACHE - * command, as indicated by our quirks flags. - * - * XXX What about older devices? + * Issue a SYNCHRONIZE CACHE. Address 0, length 0 means "all remaining + * blocks starting at address 0". Ignore ILLEGAL REQUEST in the event + * that the command is not supported by the device. */ - if (SCSISPC(sc_link->inqdata.version) >= 2 && - (sc_link->quirks & SDEV_NOSYNCCACHE) == 0) { - bzero(&sync_cmd, sizeof(sync_cmd)); - sync_cmd.opcode = SYNCHRONIZE_CACHE; - - if (scsi_scsi_cmd(sc_link, - (struct scsi_generic *)&sync_cmd, sizeof(sync_cmd), - NULL, 0, SDRETRIES, 100000, NULL, - flags|SCSI_IGNORE_ILLEGAL_REQUEST)) - printf("%s: WARNING: cache synchronization failed\n", - sd->sc_dev.dv_xname); - else - sd->flags |= SDF_FLUSHING; - } + + bzero(&cmd, sizeof(cmd)); + cmd.opcode = SYNCHRONIZE_CACHE; + + if (scsi_scsi_cmd(sc_link, &cmd, sizeof(cmd), NULL, 0, SDRETRIES, + 100000, NULL, flags | SCSI_IGNORE_ILLEGAL_REQUEST)) { + SC_DEBUG(sc_link, SDEV_DB1, ("cache sync failed\n")); + } else + sd->flags &= ~SDF_DIRTY; } /* diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h index e525098edaa..d81c3058bea 100644 --- a/sys/scsi/sdvar.h +++ b/sys/scsi/sdvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sdvar.h,v 1.12 2007/09/15 19:22:18 bluhm Exp $ */ +/* $OpenBSD: sdvar.h,v 1.13 2007/11/06 02:49:19 krw Exp $ */ /* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */ /*- @@ -67,8 +67,7 @@ struct sd_softc { #define SDF_LABELLING 0x08 /* writing label */ #define SDF_ANCIENT 0x10 /* disk is ancient; for minphys */ #define SDF_DIRTY 0x20 /* disk is dirty; needs cache flush */ -#define SDF_FLUSHING 0x40 /* flushing, for sddone() */ -#define SDF_DYING 0x80 /* dying, when deactivated */ +#define SDF_DYING 0x40 /* dying, when deactivated */ struct scsi_link *sc_link; /* contains our targ, lun, etc. */ struct disk_parms { u_long heads; /* number of heads */ -- cgit v1.2.3