Exemplo n.º 1
0
static int
ssdetach(device_t self, int flags)
{
	struct ss_softc *ss = device_private(self);
	int s, cmaj, mn;

	/* locate the major number */
	cmaj = cdevsw_lookup_major(&ss_cdevsw);

	/* kill any pending restart */
	callout_stop(&ss->sc_callout);

	s = splbio();

	/* Kill off any queued buffers. */
	bufq_drain(ss->buf_queue);

	bufq_free(ss->buf_queue);

	/* Kill off any pending commands. */
	scsipi_kill_pending(ss->sc_periph);

	splx(s);

	/* Nuke the vnodes for any open instances */
	mn = SSUNIT(device_unit(self));
	vdevgone(cmaj, mn, mn+SSNMINOR-1, VCHR);

	return 0;
}
Exemplo n.º 2
0
void
dk_drain(struct dk_softc *dksc)
{
	struct buf *bp;

	mutex_enter(&dksc->sc_iolock);
	bp = dksc->sc_deferred;
	dksc->sc_deferred = NULL;
	if (bp != NULL) {
		bp->b_error = EIO;
		bp->b_resid = bp->b_bcount;
		biodone(bp); 
	}
	bufq_drain(dksc->sc_bufq);
	mutex_exit(&dksc->sc_iolock);
}
Exemplo n.º 3
0
int
wddetach(struct device *self, int flags)
{
	struct wd_softc *sc = (struct wd_softc *)self;

	timeout_del(&sc->sc_restart_timeout);

	bufq_drain(&sc->sc_bufq);

	disk_gone(wdopen, self->dv_unit);

	/* Detach disk. */
	bufq_destroy(&sc->sc_bufq);
	disk_detach(&sc->sc_dk);

	return (0);
}
Exemplo n.º 4
0
int
sddetach(struct device *self, int flags)
{
	struct sd_softc *sc = (struct sd_softc *)self;

	bufq_drain(&sc->sc_bufq);

	disk_gone(sdopen, self->dv_unit);

	/* Get rid of the shutdown hook. */
	if (sc->sc_sdhook != NULL)
		shutdownhook_disestablish(sc->sc_sdhook);

	/* Detach disk. */
	bufq_destroy(&sc->sc_bufq);
	disk_detach(&sc->sc_dk);

	return (0);
}
Exemplo n.º 5
0
static int
fddetach(device_t self, int flags)
{
	struct fd_softc *fd = device_private(self);
	int bmaj, cmaj, i, mn;

	fd_motor_off(fd);

	/* locate the major number */
	bmaj = bdevsw_lookup_major(&fd_bdevsw);
	cmaj = cdevsw_lookup_major(&fd_cdevsw);

	/* Nuke the vnodes for any open instances. */
	for (i = 0; i < MAXPARTITIONS; i++) {
		mn = DISKMINOR(device_unit(self), i);
		vdevgone(bmaj, mn, mn, VBLK);
		vdevgone(cmaj, mn, mn, VCHR);
	}

	pmf_device_deregister(self);

#if 0 /* XXX need to undo at detach? */
	fd_set_properties(fd);
#endif
#if NRND > 0
	rnd_detach_source(&fd->rnd_source);
#endif

	disk_detach(&fd->sc_dk);
	disk_destroy(&fd->sc_dk);

	/* Kill off any queued buffers. */
	bufq_drain(fd->sc_q);

	bufq_free(fd->sc_q);

	callout_destroy(&fd->sc_motoroff_ch);
	callout_destroy(&fd->sc_motoron_ch);

	return 0;
}
Exemplo n.º 6
0
static int
fss_detach(device_t self, int flags)
{
	struct fss_softc *sc = device_private(self);

	if (sc->sc_flags & FSS_ACTIVE)
		return EBUSY;

	if (--fss_num_attached == 0)
		vfs_hooks_detach(&fss_vfs_hooks);

	pmf_device_deregister(self);
	mutex_destroy(&sc->sc_slock);
	mutex_destroy(&sc->sc_lock);
	cv_destroy(&sc->sc_work_cv);
	cv_destroy(&sc->sc_cache_cv);
	bufq_drain(sc->sc_bufq);
	bufq_free(sc->sc_bufq);
	disk_destroy(sc->sc_dkdev);
	free(sc->sc_dkdev, M_DEVBUF);

	return 0;
}
Exemplo n.º 7
0
/*
 * sdstart looks to see if there is a buf waiting for the device
 * and that the device is not already busy. If both are true,
 * It dequeues the buf and creates a scsi command to perform the
 * transfer in the buf. The transfer request will call scsi_done
 * on completion, which will in turn call this routine again
 * so that the next queued transfer is performed.
 * The bufs are queued by the strategy routine (sdstrategy)
 *
 * This routine is also called after other non-queued requests
 * have been made of the scsi driver, to ensure that the queue
 * continues to be drained.
 */
void
sdstart(struct scsi_xfer *xs)
{
	struct scsi_link *link = xs->sc_link;
	struct sd_softc *sc = link->device_softc;
	struct buf *bp;
	u_int64_t secno;
	int nsecs;
	int read;
	struct partition *p;

	if (sc->flags & SDF_DYING) {
		scsi_xs_put(xs);
		return;
	}
	if ((link->flags & SDEV_MEDIA_LOADED) == 0) {
		bufq_drain(&sc->sc_bufq);
		scsi_xs_put(xs);
		return;
	}

	bp = bufq_dequeue(&sc->sc_bufq);
	if (bp == NULL) {
		scsi_xs_put(xs);
		return;
	}

	secno = DL_BLKTOSEC(sc->sc_dk.dk_label, bp->b_blkno);

	p = &sc->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)];
	secno += DL_GETPOFFSET(p);
	nsecs = howmany(bp->b_bcount, sc->sc_dk.dk_label->d_secsize);
	read = bp->b_flags & B_READ;

	/*
	 *  Fill out the scsi command.  If the transfer will
	 *  fit in a "small" cdb, use it.
	 */
	if (!(link->flags & SDEV_ATAPI) &&
	    !(link->quirks & SDEV_ONLYBIG) &&
	    ((secno & 0x1fffff) == secno) &&
	    ((nsecs & 0xff) == nsecs))
		sd_cmd_rw6(xs, read, secno, nsecs);
	else if (((secno & 0xffffffff) == secno) &&
	    ((nsecs & 0xffff) == nsecs))
		sd_cmd_rw10(xs, read, secno, nsecs);
	else if (((secno & 0xffffffff) == secno) &&
	    ((nsecs & 0xffffffff) == nsecs))
		sd_cmd_rw12(xs, read, secno, nsecs);
	else
		sd_cmd_rw16(xs, read, secno, nsecs);

	xs->flags |= (read ? SCSI_DATA_IN : SCSI_DATA_OUT);
	xs->timeout = 60000;
	xs->data = bp->b_data;
	xs->datalen = bp->b_bcount;

	xs->done = sd_buf_done;
	xs->cookie = bp;
	xs->bp = bp;

	/* Instrumentation. */
	disk_busy(&sc->sc_dk);

	/* Mark disk as dirty. */
	if (!read)
		sc->flags |= SDF_DIRTY;

	scsi_xs_exec(xs);

	/* move onto the next io */
	if (ISSET(sc->flags, SDF_WAITING))
		CLR(sc->flags, SDF_WAITING);
	else if (bufq_peek(&sc->sc_bufq))
		scsi_xsh_add(&sc->sc_xsh);
}
Exemplo n.º 8
0
static void
vndclear(struct vnd_softc *vnd, int myminor)
{
	struct vnode *vp = vnd->sc_vp;
	int fflags = FREAD;
	int bmaj, cmaj, i, mn;
	int s;

#ifdef DEBUG
	if (vnddebug & VDB_FOLLOW)
		printf("vndclear(%p): vp %p\n", vnd, vp);
#endif
	/* locate the major number */
	bmaj = bdevsw_lookup_major(&vnd_bdevsw);
	cmaj = cdevsw_lookup_major(&vnd_cdevsw);

	/* Nuke the vnodes for any open instances */
	for (i = 0; i < MAXPARTITIONS; i++) {
		mn = DISKMINOR(device_unit(vnd->sc_dev), i);
		vdevgone(bmaj, mn, mn, VBLK);
		if (mn != myminor) /* XXX avoid to kill own vnode */
			vdevgone(cmaj, mn, mn, VCHR);
	}

	if ((vnd->sc_flags & VNF_READONLY) == 0)
		fflags |= FWRITE;

	s = splbio();
	bufq_drain(vnd->sc_tab);
	splx(s);

	vnd->sc_flags |= VNF_VUNCONF;
	wakeup(&vnd->sc_tab);
	while (vnd->sc_flags & VNF_KTHREAD)
		tsleep(&vnd->sc_kthread, PRIBIO, "vnthr", 0);

#ifdef VND_COMPRESSION
	/* free the compressed file buffers */
	if (vnd->sc_flags & VNF_COMP) {
		if (vnd->sc_comp_offsets) {
			free(vnd->sc_comp_offsets, M_DEVBUF);
			vnd->sc_comp_offsets = NULL;
		}
		if (vnd->sc_comp_buff) {
			free(vnd->sc_comp_buff, M_DEVBUF);
			vnd->sc_comp_buff = NULL;
		}
		if (vnd->sc_comp_decombuf) {
			free(vnd->sc_comp_decombuf, M_DEVBUF);
			vnd->sc_comp_decombuf = NULL;
		}
	}
#endif /* VND_COMPRESSION */
	vnd->sc_flags &=
	    ~(VNF_INITED | VNF_READONLY | VNF_VLABEL
	      | VNF_VUNCONF | VNF_COMP | VNF_CLEARING);
	if (vp == NULL)
		panic("vndclear: null vp");
	(void) vn_close(vp, fflags, vnd->sc_cred);
	kauth_cred_free(vnd->sc_cred);
	vnd->sc_vp = NULL;
	vnd->sc_cred = NULL;
	vnd->sc_size = 0;
}