int sdactivate(struct device *self, int act) { struct sd_softc *sc = (struct sd_softc *)self; int rv = 0; switch (act) { case DVACT_SUSPEND: /* * Stop the disk. Stopping the disk should flush the * cache, but we are paranoid so we flush the cache * first. */ if ((sc->flags & SDF_DIRTY) != 0) sd_flush(sc, SCSI_AUTOCONF); scsi_start(sc->sc_link, SSS_STOP, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF); break; case DVACT_RESUME: scsi_start(sc->sc_link, SSS_START, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF); break; case DVACT_DEACTIVATE: sc->flags |= SDF_DYING; scsi_xsh_del(&sc->sc_xsh); break; } return (rv); }
/* * Close the device. Only called if we are the last occurrence of an open * device. Convenient now but usually a pain. */ int sdclose(dev_t dev, int flag, int fmt, struct proc *p) { struct sd_softc *sc; int part = DISKPART(dev); sc = sdlookup(DISKUNIT(dev)); if (sc == NULL) return (ENXIO); if (sc->flags & SDF_DYING) { device_unref(&sc->sc_dev); return (ENXIO); } disk_lock_nointr(&sc->sc_dk); disk_closepart(&sc->sc_dk, part, fmt); if (sc->sc_dk.dk_openmask == 0) { if ((sc->flags & SDF_DIRTY) != 0) sd_flush(sc, 0); if ((sc->sc_link->flags & SDEV_REMOVABLE) != 0) scsi_prevent(sc->sc_link, PR_ALLOW, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY | SCSI_SILENT); sc->sc_link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED); if (sc->sc_link->flags & SDEV_EJECTING) { scsi_start(sc->sc_link, SSS_STOP|SSS_LOEJ, 0); sc->sc_link->flags &= ~SDEV_EJECTING; } timeout_del(&sc->sc_timeout); scsi_xsh_del(&sc->sc_xsh); } disk_unlock(&sc->sc_dk); device_unref(&sc->sc_dev); return 0; }
int sdactivate(struct device *self, int act) { struct sd_softc *sc = (struct sd_softc *)self; int rv = 0; switch (act) { case DVACT_SUSPEND: /* * We flush the cache, since we our next step before * DVACT_POWERDOWN might be a hibernate operation. */ if ((sc->flags & SDF_DIRTY) != 0) sd_flush(sc, SCSI_AUTOCONF); break; case DVACT_POWERDOWN: /* * Stop the disk. Stopping the disk should flush the * cache, but we are paranoid so we flush the cache * first. */ if ((sc->flags & SDF_DIRTY) != 0) sd_flush(sc, SCSI_AUTOCONF); if (boothowto & RB_POWERDOWN) scsi_start(sc->sc_link, SSS_STOP, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF); break; case DVACT_RESUME: scsi_start(sc->sc_link, SSS_START, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF); break; case DVACT_DEACTIVATE: sc->flags |= SDF_DYING; scsi_xsh_del(&sc->sc_xsh); break; } return (rv); }
void sd_shutdown(void *arg) { struct sd_softc *sc = (struct sd_softc *)arg; /* * If the disk cache needs to be flushed, and the disk supports * it, flush it. We're cold at this point, so we poll for * completion. */ if ((sc->flags & SDF_DIRTY) != 0) sd_flush(sc, SCSI_AUTOCONF); if (boothowto & RB_POWERDOWN) scsi_start(sc->sc_link, SSS_STOP, SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF); /* * There should be no outstanding IO at this point, but lets stop * it just in case. */ timeout_del(&sc->sc_timeout); scsi_xsh_del(&sc->sc_xsh); }