示例#1
0
文件: sd.c 项目: sofuture/bitrig
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);
}
示例#2
0
/*
 * 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;
}
示例#3
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);
}
示例#4
0
文件: sd.c 项目: sofuture/bitrig
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);
}