示例#1
0
文件: mcd.c 项目: MarginC/kame
static int
mcdopen(dev_t dev, int flags, int fmt, struct thread *td)
{
	struct mcd_softc *sc;
	int r,retry;

	sc = (struct mcd_softc *)dev->si_drv1;

	/* not initialized*/
	if (!(sc->data.flags & MCDINIT))
		return (ENXIO);

	/* invalidated in the meantime? mark all open part's invalid */
	if (!(sc->data.flags & MCDVALID) && sc->data.openflags)
		return (ENXIO);

	if (mcd_getstat(sc, 1) == -1)
		return (EIO);

	if (    (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN))
	    || !(sc->data.status & MCDDSKIN))
		for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
			(void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn1", hz/WAIT_FRAC);
			if ((r = mcd_getstat(sc, 1)) == -1)
				return (EIO);
			if (r != -2)
				break;
		}

	if (sc->data.status & MCDDOOROPEN) {
		device_printf(sc->dev, "door is open\n");
		return (ENXIO);
	}
	if (!(sc->data.status & MCDDSKIN)) {
		device_printf(sc->dev, "no CD inside\n");
		return (ENXIO);
	}
	if (sc->data.status & MCDDSKCHNG) {
		device_printf(sc->dev, "CD not sensed\n");
		return (ENXIO);
	}

	if (mcdsize(dev) < 0) {
		device_printf(sc->dev, "failed to get disk size\n");
		return (ENXIO);
	}

	dev->si_bsize_phys = sc->data.blksize;

	sc->data.openflags = 1;
	sc->data.partflags |= MCDREADRAW;
	sc->data.flags |= MCDVALID;

	(void) mcd_lock_door(sc, MCD_LK_LOCK);
	if (!(sc->data.flags & MCDVALID))
		return (ENXIO);

	return mcd_read_toc(sc);
}
示例#2
0
文件: mcd.c 项目: MarginC/kame
static int
mcdclose(dev_t dev, int flags, int fmt, struct thread *td)
{
	struct mcd_softc *sc;

	sc = (struct mcd_softc *)dev->si_drv1;

	if (!(sc->data.flags & MCDINIT) || !sc->data.openflags)
		return (ENXIO);

	(void) mcd_lock_door(sc, MCD_LK_UNLOCK);
	sc->data.openflags = 0;
	sc->data.partflags &= ~MCDREADRAW;

	return (0);
}
示例#3
0
文件: mcd.c 项目: LynYang/freebsd
static int
mcdclose(struct cdev *dev, int flags, int fmt, struct thread *td)
{
	struct mcd_softc *sc;

	sc = (struct mcd_softc *)dev->si_drv1;

	MCD_LOCK(sc);
	KASSERT(sc->data.openflags, ("device not open"));

	(void) mcd_lock_door(sc, MCD_LK_UNLOCK);
	sc->data.openflags = 0;
	sc->data.partflags &= ~MCDREADRAW;
	MCD_UNLOCK(sc);

	return (0);
}
示例#4
0
文件: mcd.c 项目: MarginC/kame
static int
mcdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
	struct mcd_softc *sc;
	int retry,r;

	sc = (struct mcd_softc *)dev->si_drv1;

	if (mcd_getstat(sc, 1) == -1) /* detect disk change too */
		return (EIO);
MCD_TRACE("ioctl called 0x%lx\n", cmd);

	switch (cmd) {
	case CDIOCSETPATCH:
	case CDIOCGETVOL:
	case CDIOCSETVOL:
	case CDIOCSETMONO:
	case CDIOCSETSTERIO:
	case CDIOCSETMUTE:
	case CDIOCSETLEFT:
	case CDIOCSETRIGHT:
		return (EINVAL);
	case CDIOCEJECT:
		return mcd_eject(sc);
	case CDIOCSETDEBUG:
		sc->data.debug = 1;
		return (0);
	case CDIOCCLRDEBUG:
		sc->data.debug = 0;
		return (0);
	case CDIOCRESET:
		return mcd_hard_reset(sc);
	case CDIOCALLOW:
		return mcd_lock_door(sc, MCD_LK_UNLOCK);
	case CDIOCPREVENT:
		return mcd_lock_door(sc, MCD_LK_LOCK);
	case CDIOCCLOSE:
		return mcd_inject(sc);
	}

	if (!(sc->data.flags & MCDVALID)) {
		if (    (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN))
		    || !(sc->data.status & MCDDSKIN))
			for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) {
				(void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn2", hz/WAIT_FRAC);
				if ((r = mcd_getstat(sc, 1)) == -1)
					return (EIO);
				if (r != -2)
					break;
			}
		if (   (sc->data.status & (MCDDOOROPEN|MCDDSKCHNG))
		    || !(sc->data.status & MCDDSKIN)
		    || mcdsize(dev) < 0
		   )
			return (ENXIO);
		sc->data.flags |= MCDVALID;
		sc->data.partflags |= MCDREADRAW;
		(void) mcd_lock_door(sc, MCD_LK_LOCK);
		if (!(sc->data.flags & MCDVALID))
			return (ENXIO);
	}

	switch (cmd) {
	case DIOCGMEDIASIZE:
		*(off_t *)addr = (off_t)sc->data.disksize * sc->data.blksize;
		return (0);
		break;
	case DIOCGSECTORSIZE:
		*(u_int *)addr = sc->data.blksize;
		return (0);
		break;

	case CDIOCPLAYTRACKS:
		return mcd_playtracks(sc, (struct ioc_play_track *) addr);
	case CDIOCPLAYBLOCKS:
		return mcd_playblocks(sc, (struct ioc_play_blocks *) addr);
	case CDIOCPLAYMSF:
		return mcd_playmsf(sc, (struct ioc_play_msf *) addr);
	case CDIOCREADSUBCHANNEL:
		return mcd_subchan(sc, (struct ioc_read_subchannel *) addr);
	case CDIOREADTOCHEADER:
		return mcd_toc_header(sc, (struct ioc_toc_header *) addr);
	case CDIOREADTOCENTRYS:
		return mcd_toc_entrys(sc, (struct ioc_read_toc_entry *) addr);
	case CDIOCRESUME:
		return mcd_resume(sc);
	case CDIOCPAUSE:
		return mcd_pause(sc);
	case CDIOCSTART:
		if (mcd_setmode(sc, MCD_MD_COOKED) != 0)
			return (EIO);
		return (0);
	case CDIOCSTOP:
		return mcd_stop(sc);
	default:
		return (ENOTTY);
	}
	/*NOTREACHED*/
}