diff options
Diffstat (limited to 'sys/dev/mcd/mcd.c')
-rw-r--r-- | sys/dev/mcd/mcd.c | 129 |
1 files changed, 71 insertions, 58 deletions
diff --git a/sys/dev/mcd/mcd.c b/sys/dev/mcd/mcd.c index 2e98212..1665b01 100644 --- a/sys/dev/mcd/mcd.c +++ b/sys/dev/mcd/mcd.c @@ -40,7 +40,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: mcd.c,v 1.70 1996/02/03 14:33:56 ache Exp $ + * $Id: mcd.c,v 1.71 1996/02/13 02:32:36 ache Exp $ */ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; @@ -342,13 +342,22 @@ int mcdopen(dev_t dev, int flags, int fmt, struct proc *p) if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) || !(cd->status & MCDDSKIN)) for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) { - (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsns", hz/WAIT_FRAC); + (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsn1", hz/WAIT_FRAC); if ((r = mcd_getstat(unit,1)) == -1) return EIO; if (r != -2) break; } + if (( (cd->status & (MCDDOOROPEN|MCDDSKCHNG)) + || !(cd->status & MCDDSKIN) + ) + && major(dev) == CDEV_MAJOR && part == RAW_PART + ) { + cd->openflags |= (1<<part); + kdc_mcd[unit].kdc_state = DC_BUSY; + return 0; + } if (cd->status & MCDDOOROPEN) { printf("mcd%d: door is open\n", unit); return ENXIO; @@ -363,6 +372,11 @@ int mcdopen(dev_t dev, int flags, int fmt, struct proc *p) } if (mcdsize(dev) < 0) { + if (major(dev) == CDEV_MAJOR && part == RAW_PART) { + cd->openflags |= (1<<part); + kdc_mcd[unit].kdc_state = DC_BUSY; + return 0; + } printf("mcd%d: failed to get disk size\n",unit); return ENXIO; } else @@ -543,7 +557,7 @@ static void mcd_start(int unit) int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p) { struct mcd_data *cd; - int unit,part; + int unit,part,retry,r; unit = mcd_unit(dev); part = mcd_part(dev); @@ -554,18 +568,67 @@ int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p) MCD_TRACE("ioctl called 0x%x\n", cmd); switch (cmd) { - case DIOCSBAD: + case CDIOCSETPATCH: + case CDIOCGETVOL: + case CDIOCSETVOL: + case CDIOCSETMONO: + case CDIOCSETSTERIO: + case CDIOCSETMUTE: + case CDIOCSETLEFT: + case CDIOCSETRIGHT: + return EINVAL; + case CDIOCEJECT: + return mcd_eject(unit); + case CDIOCSETDEBUG: + cd->debug = 1; + return 0; + case CDIOCCLRDEBUG: + cd->debug = 0; + return 0; + case CDIOCRESET: + return mcd_hard_reset(unit); + case CDIOCALLOW: + return mcd_lock_door(unit, MCD_LK_UNLOCK); + case CDIOCPREVENT: + return mcd_lock_door(unit, MCD_LK_LOCK); + case CDIOCCLOSE: + return mcd_inject(unit); + } + + if (!(cd->flags & MCDVALID)) { + if ( major(dev) != CDEV_MAJOR + || !(cd->openflags & (1<<RAW_PART)) + ) + return ENXIO; + if ( (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) + || !(cd->status & MCDDSKIN)) + for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) { + (void) tsleep((caddr_t)cd, PSOCK | PCATCH, "mcdsn2", hz/WAIT_FRAC); + if ((r = mcd_getstat(unit,1)) == -1) + return EIO; + if (r != -2) + break; + } + if ( (cd->status & (MCDDOOROPEN|MCDDSKCHNG)) + || !(cd->status & MCDDSKIN) + || mcdsize(dev) < 0 + ) + return ENXIO; + cd->flags |= MCDVALID; + mcd_getdisklabel(unit); + cd->partflags[RAW_PART] |= MCDOPEN; + (void) mcd_lock_door(unit, MCD_LK_LOCK); if (!(cd->flags & MCDVALID)) return ENXIO; + } + + switch (cmd) { + case DIOCSBAD: return EINVAL; case DIOCGDINFO: - if (!(cd->flags & MCDVALID)) - return ENXIO; *(struct disklabel *) addr = cd->dlabel; return 0; case DIOCGPART: - if (!(cd->flags & MCDVALID)) - return ENXIO; ((struct partinfo *) addr)->disklab = &cd->dlabel; ((struct partinfo *) addr)->part = &cd->dlabel.d_partitions[mcd_part(dev)]; @@ -577,8 +640,6 @@ MCD_TRACE("ioctl called 0x%x\n", cmd); */ case DIOCWDINFO: case DIOCSDINFO: - if (!(cd->flags & MCDVALID)) - return ENXIO; if ((flags & FWRITE) == 0) return EBADF; else { @@ -587,76 +648,29 @@ MCD_TRACE("ioctl called 0x%x\n", cmd); 0); } case DIOCWLABEL: - if (!(cd->flags & MCDVALID)) - return ENXIO; return EBADF; case CDIOCPLAYTRACKS: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_playtracks(unit, (struct ioc_play_track *) addr); case CDIOCPLAYBLOCKS: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_playblocks(unit, (struct ioc_play_blocks *) addr); case CDIOCPLAYMSF: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_playmsf(unit, (struct ioc_play_msf *) addr); case CDIOCREADSUBCHANNEL: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_subchan(unit, (struct ioc_read_subchannel *) addr); case CDIOREADTOCHEADER: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_toc_header(unit, (struct ioc_toc_header *) addr); case CDIOREADTOCENTRYS: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_toc_entrys(unit, (struct ioc_read_toc_entry *) addr); - case CDIOCSETPATCH: - case CDIOCGETVOL: - case CDIOCSETVOL: - case CDIOCSETMONO: - case CDIOCSETSTERIO: - case CDIOCSETMUTE: - case CDIOCSETLEFT: - case CDIOCSETRIGHT: - return EINVAL; case CDIOCRESUME: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_resume(unit); case CDIOCPAUSE: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_pause(unit); case CDIOCSTART: - if (!(cd->flags & MCDVALID)) - return ENXIO; if (mcd_setmode(unit, MCD_MD_COOKED) != 0) return EIO; return 0; case CDIOCSTOP: - if (!(cd->flags & MCDVALID)) - return ENXIO; return mcd_stop(unit); - case CDIOCEJECT: - return mcd_eject(unit); - case CDIOCSETDEBUG: - cd->debug = 1; - return 0; - case CDIOCCLRDEBUG: - cd->debug = 0; - return 0; - case CDIOCRESET: - return mcd_hard_reset(unit); - case CDIOCALLOW: - return mcd_lock_door(unit, MCD_LK_UNLOCK); - case CDIOCPREVENT: - return mcd_lock_door(unit, MCD_LK_LOCK); - case CDIOCCLOSE: - return mcd_inject(unit); default: return ENOTTY; } @@ -1322,7 +1336,6 @@ mcd_soft_reset(int unit) struct mcd_data *cd = mcd_data + unit; int i; - cd->openflags = 0; cd->flags &= (MCDINIT|MCDPROBING|MCDNEWMODEL); cd->curr_mode = MCD_MD_UNKNOWN; for (i=0; i<MAXPARTITIONS; i++) cd->partflags[i] = 0; |