diff options
| author | thorpej <thorpej@NetBSD.org> | 1998-06-10 22:17:39 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 1998-06-10 22:17:39 +0000 |
| commit | b121e9e7727a2c28ea3cdb3595f3aa271c069bf0 (patch) | |
| tree | e8ddb9e7da36c12980b4508c277d27bc752ef962 /sys/dev | |
| parent | 7ea013ce828976fbb50800a5d48ef19721731992 (diff) | |
Add a shutdown hook for SCSI-2 and higher disks that issues a SYNCHRONIZE CACHE
operation with address 0 length 0, which, according to the SCSI-2 spec, should
be interpreted as "synchronize all remaining blocks beginning at address 0".
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/scsipi/sd_scsi.c | 49 | ||||
| -rw-r--r-- | sys/dev/scsipi/sdvar.h | 4 |
2 files changed, 51 insertions, 2 deletions
diff --git a/sys/dev/scsipi/sd_scsi.c b/sys/dev/scsipi/sd_scsi.c index 454aa402ca4..c630f101c74 100644 --- a/sys/dev/scsipi/sd_scsi.c +++ b/sys/dev/scsipi/sd_scsi.c @@ -1,4 +1,4 @@ -/* $NetBSD: sd_scsi.c,v 1.1 1998/01/15 02:21:40 cgd Exp $ */ +/* $NetBSD: sd_scsi.c,v 1.2 1998/06/10 22:17:39 thorpej Exp $ */ /* * Copyright (c) 1994, 1995, 1997 Charles M. Hannum. All rights reserved. @@ -103,6 +103,8 @@ const struct sd_ops sd_scsibus_ops = { sd_scsibus_get_parms, }; +static void sd_scsibus_shutdown __P((void *)); + int sd_scsibus_match(parent, match, aux) struct device *parent; @@ -150,6 +152,19 @@ sd_scsibus_attach(parent, self, aux) sd->flags |= SDF_ANCIENT; sdattach(parent, sd, sc_link, &sd_scsibus_ops); + + /* + * Establish a shutdown hook so that we can ensure that + * our data has actually made it onto the platter at + * shutdown time. Note that this relies on the fact + * that the shutdown hook code puts us at the head of + * the list (thus guaranteeing that our hook runs before + * our ancestors'). + */ + if ((sd->sc_sdhook = + shutdownhook_establish(sd_scsibus_shutdown, sd)) == NULL) + printf("%s: WARNING: unable to establish shutdown hook\n", + sd->sc_dev.dv_xname); } static int @@ -326,3 +341,35 @@ fake_it: dp->disksize = sectors; return (SDGP_RESULT_OK); } + +static void +sd_scsibus_shutdown(arg) + void *arg; +{ + struct sd_softc *sd = arg; + struct scsipi_link *sc_link = sd->sc_link; + struct scsi_synchronize_cache sync_cmd; + + /* + * 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. + * + * XXX What about older devices? + */ + if ((sc_link->scsipi_scsi.scsi_version & SID_ANSII) >= 2) { + bzero(&sync_cmd, sizeof(sync_cmd)); + sync_cmd.opcode = SCSI_SYNCHRONIZE_CACHE; + + if (scsipi_command(sc_link, + (struct scsipi_generic *)&sync_cmd, sizeof(sync_cmd), + NULL, 0, SDRETRIES, 100000, NULL, + SCSI_POLL|SCSI_IGNORE_ILLEGAL_REQUEST)) + printf("%s: WARNING: cache synchronization failed\n", + sd->sc_dev.dv_xname); + } +} diff --git a/sys/dev/scsipi/sdvar.h b/sys/dev/scsipi/sdvar.h index 90c00baa618..b7206aeb04f 100644 --- a/sys/dev/scsipi/sdvar.h +++ b/sys/dev/scsipi/sdvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sdvar.h,v 1.3 1998/02/13 08:28:57 enami Exp $ */ +/* $NetBSD: sdvar.h,v 1.4 1998/06/10 22:17:40 thorpej Exp $ */ /* * Copyright (c) 1994, 1995, 1997 Charles M. Hannum. All rights reserved. @@ -73,6 +73,8 @@ struct sd_softc { u_int8_t type; const struct sd_ops *sc_ops; /* our bus-dependent ops vector */ + void *sc_sdhook; /* our shutdown hook */ + #if NRND > 0 rndsource_element_t rnd_source; #endif |
