diff --git a/sys/arch/i386/isa/mcd.c b/sys/arch/i386/isa/mcd.c index 82de4cd420ca..b4582d3a0641 100644 --- a/sys/arch/i386/isa/mcd.c +++ b/sys/arch/i386/isa/mcd.c @@ -1,7 +1,7 @@ /* + * Copyright (c) 1993, 1994 Charles Hannum. * Copyright 1993 by Holger Veit (data part) * Copyright 1993 by Brian Moore (audio part) - * CHANGES Copyright 1993 Gary Clark II (gclarkii@freefall.cdrom.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,16 +35,18 @@ * 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.5 1994/02/09 21:13:48 mycroft Exp $ + * $Id: mcd.c,v 1.6 1994/02/21 15:23:11 mycroft Exp $ */ -static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; +/*static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";*/ #include "mcd.h" -#if NMCD > 0 + #include #include #include +#include +#include #include #include #include @@ -55,30 +57,24 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; #include #include #include +#include +#include #include #include #include #include -/* user definable options */ -/*#define MCD_TO_WARNING_ON*/ /* define to get timeout messages */ -/*#define MCDMINI*/ /* define for a mini configuration for boot kernel */ - - -#ifdef MCDMINI +#ifndef MCDDEBUG #define MCD_TRACE(fmt,a,b,c,d) -#ifdef MCD_TO_WARNING_ON -#undef MCD_TO_WARNING_ON -#endif #else -#define MCD_TRACE(fmt,a,b,c,d) {if (mcd_data[unit].debug) {printf("mcd%d st=%02x: ",unit,mcd_data[unit].status); printf(fmt,a,b,c,d);}} +#define MCD_TRACE(fmt,a,b,c,d) {if (sc->debug) {printf("%s: st=%02x: ", sc->sc_dev.dv_xname, sc->status); printf(fmt,a,b,c,d);}} #endif -#define mcd_part(dev) ((minor(dev)) & 7) -#define mcd_unit(dev) (((minor(dev)) & 0x38) >> 3) -#define mcd_phys(dev) (((minor(dev)) & 0x40) >> 6) +#define MCDPART(dev) (((minor(dev)) & 0x07) ) +#define MCDUNIT(dev) (((minor(dev)) & 0x78) >> 3) +#define MCDPHYS(dev) (((minor(dev)) & 0x80) >> 7) #define RAW_PART 3 /* flags */ @@ -87,11 +83,10 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; #define MCDINIT 0x0004 /* device is init'd */ #define MCDWAIT 0x0008 /* waiting for something */ #define MCDLABEL 0x0010 /* label is read */ -#define MCDPROBING 0x0020 /* probing */ -#define MCDREADRAW 0x0040 /* read raw mode (2352 bytes) */ -#define MCDVOLINFO 0x0080 /* already read volinfo */ -#define MCDTOC 0x0100 /* already read toc */ -#define MCDMBXBSY 0x0200 /* local mbx is busy */ +#define MCDREADRAW 0x0020 /* read raw mode (2352 bytes) */ +#define MCDVOLINFO 0x0040 /* already read volinfo */ +#define MCDTOC 0x0080 /* already read toc */ +#define MCDMBXBSY 0x0100 /* local mbx is busy */ /* status */ #define MCDAUDIOBSY MCD_ST_AUDIOBSY /* playing audio */ @@ -105,7 +100,7 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; struct mcd_mbx { short unit; - short port; + u_short iobase; short retry; short nblk; int sz; @@ -115,78 +110,70 @@ struct mcd_mbx { short count; }; -struct mcd_data { +struct mcd_softc { + struct device sc_dev; + + u_short iobase; short config; short flags; short status; int blksize; u_long disksize; - int iobase; - struct disklabel dlabel; + struct disklabel dlabel; int partflags[MAXPARTITIONS]; int openflags; - struct mcd_volinfo volinfo; -#ifndef MCDMINI - struct mcd_qchninfo toc[MCD_MAXTOCS]; + struct mcd_volinfo volinfo; + struct mcd_qchninfo toc[MCD_MAXTOCS]; short audio_status; - struct mcd_read2 lastpb; -#endif + struct mcd_read2 lastpb; short debug; - struct buf head; /* head of buf queue */ - struct mcd_mbx mbx; -} mcd_data[NMCD]; - -/* reader state machine */ -#define MCD_S_BEGIN 0 -#define MCD_S_BEGIN1 1 -#define MCD_S_WAITSTAT 2 -#define MCD_S_WAITMODE 3 -#define MCD_S_WAITREAD 4 + struct buf head; /* head of buf queue */ + struct mcd_mbx mbx; +} mcd_softc[NMCD]; /* prototypes */ -int mcdopen(dev_t dev); -int mcdclose(dev_t dev); -int mcdstrategy(struct buf *bp); -int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p); -int mcdsize(dev_t dev); -static void mcd_done(struct mcd_mbx *mbx); -static void mcd_start(int unit); -static int mcd_getdisklabel(int unit); -static void mcd_configure(struct mcd_data *cd); -static int mcd_get(int unit, char *buf, int nmax); -static void mcd_setflags(int unit,struct mcd_data *cd); -static int mcd_getstat(int unit,int sflg); -static int mcd_send(int unit, int cmd,int nretrys); -static int bcd2bin(bcd_t b); -static bcd_t bin2bcd(int b); -static void hsg2msf(int hsg, bcd_t *msf); -static int msf2hsg(bcd_t *msf); -static int mcd_volinfo(int unit); -static int mcd_waitrdy(int port,int dly); -static void mcd_doread(int state, struct mcd_mbx *mbxin); -#ifndef MCDMINI -static int mcd_setmode(int unit, int mode); -static int mcd_getqchan(int unit, struct mcd_qchninfo *q); -static int mcd_subchan(int unit, struct ioc_read_subchannel *sc); -static int mcd_toc_header(int unit, struct ioc_toc_header *th); -static int mcd_read_toc(int unit); -static int mcd_toc_entry(int unit, struct ioc_read_toc_entry *te); -static int mcd_stop(int unit); -static int mcd_playtracks(int unit, struct ioc_play_track *pt); -static int mcd_play(int unit, struct mcd_read2 *pb); -static int mcd_pause(int unit); -static int mcd_resume(int unit); -#endif +int mcdprobe __P((struct isa_device *)); +int mcdattach __P((struct isa_device *)); +int mcdopen __P((dev_t)); +int mcdclose __P((dev_t)); +int mcd_start __P((struct mcd_softc *)); +int mcdioctl __P((dev_t, int, caddr_t, int, struct proc *)); +int mcd_getdisklabel __P((struct mcd_softc *)); +int mcdsize __P((dev_t)); +void mcd_configure __P((struct mcd_softc *)); +int mcd_waitrdy __P((u_short, int)); +int mcd_getreply __P((struct mcd_softc *, int)); +int mcd_getstat __P((struct mcd_softc *, int)); +void mcd_setflags __P((struct mcd_softc *)); +int mcd_get __P((struct mcd_softc *, char *, int)); +int mcd_send __P((struct mcd_softc *, int, int)); +int bcd2bin __P((bcd_t)); +bcd_t bin2bcd __P((int)); +void hsg2msf __P((int, bcd_t *)); +int msf2hsg __P((bcd_t *)); +int mcd_volinfo __P((struct mcd_softc *)); +int mcdintr __P((int)); +void mcd_doread __P((int, struct mcd_mbx *)); +int mcd_setmode __P((struct mcd_softc *, int)); +int mcd_toc_header __P((struct mcd_softc *, struct ioc_toc_header *)); +int mcd_read_toc __P((struct mcd_softc *)); +int mcd_toc_entry __P((struct mcd_softc *, struct ioc_read_toc_entry *)); +int mcd_stop __P((struct mcd_softc *)); +int mcd_getqchan __P((struct mcd_softc *, struct mcd_qchninfo *)); +int mcd_subchan __P((struct mcd_softc *, struct ioc_read_subchannel *)); +int mcd_playtracks __P((struct mcd_softc *, struct ioc_play_track *)); +int mcd_play __P((struct mcd_softc *, struct mcd_read2 *)); +int mcd_pause __P((struct mcd_softc *)); +int mcd_resume __P((struct mcd_softc *)); -extern int hz; -extern int mcd_probe(struct isa_device *dev); -extern int mcd_attach(struct isa_device *dev); -struct isa_driver mcddriver = { mcd_probe, mcd_attach, "mcd" }; +struct isa_driver mcddriver = { + mcdprobe, mcdattach, "mcd" +}; #define mcd_put(port,byte) outb(port,byte) -#define MCD_RETRYS 5 -#define MCD_RDRETRYS 8 +#define MCD_RETRIES 5 +#define MCD_RDRETRIES 8 #define MCDBLK 2048 /* for cooked mode */ #define MCDRBLK 2352 /* for raw mode */ @@ -199,160 +186,153 @@ struct isa_driver mcddriver = { mcd_probe, mcd_attach, "mcd" }; #define DELAY_STATUS 10000l /* 10000 * 1us */ #define DELAY_GETREPLY 200000l /* 200000 * 2us */ #define DELAY_SEEKREAD 20000l /* 20000 * 1us */ -#define mcd_delay DELAY -int mcd_attach(struct isa_device *dev) +/* reader state machine */ +#define MCD_S_BEGIN 0 +#define MCD_S_BEGIN1 1 +#define MCD_S_WAITSTAT 2 +#define MCD_S_WAITMODE 3 +#define MCD_S_WAITREAD 4 + +int +mcdattach(isa_dev) + struct isa_device *isa_dev; { - struct mcd_data *cd = mcd_data + dev->id_unit; - int i; - - cd->iobase = dev->id_iobase; - cd->flags |= MCDINIT; - cd->openflags = 0; - for (i=0; ipartflags[i] = 0; + struct mcd_softc *sc = &mcd_softc[isa_dev->id_unit]; -#ifdef NOTYET - /* wire controller for interrupts and dma */ +#ifdef notyet + /* Wire controller for interrupts and DMA. */ mcd_configure(cd); #endif - - return 1; + + sc->flags = MCDINIT; } -int mcdopen(dev_t dev) +int +mcdopen(dev) + dev_t dev; { - int unit,part,phys; - struct mcd_data *cd; + int unit, part, phys; + struct mcd_softc *sc; - unit = mcd_unit(dev); + unit = MCDUNIT(dev); if (unit >= NMCD) return ENXIO; + sc = &mcd_softc[unit]; + if (!sc->iobase || !(sc->flags & MCDINIT)) + return ENXIO; - cd = mcd_data + unit; - part = mcd_part(dev); - phys = mcd_phys(dev); + part = MCDPART(dev); + phys = MCDPHYS(dev); - /* not initialized*/ - if (!(cd->flags & MCDINIT)) + /* Invalidated in the meantime? Mark all open part's invalid. */ + if (!(sc->flags & MCDVALID) && sc->openflags) return ENXIO; - /* invalidated in the meantime? mark all open part's invalid */ - if (!(cd->flags & MCDVALID) && cd->openflags) + if (mcd_getstat(sc, 1) < 0) return ENXIO; - if (mcd_getstat(unit,1) < 0) - return ENXIO; - - /* XXX get a default disklabel */ - mcd_getdisklabel(unit); + /* XXX Get a default disklabel. */ + mcd_getdisklabel(sc); if (mcdsize(dev) < 0) { - printf("mcd%d: failed to get disk size\n",unit); + printf("%s: failed to get disk size\n", sc->sc_dev.dv_xname); return ENXIO; } else - cd->flags |= MCDVALID; + sc->flags |= MCDVALID; -MCD_TRACE("open: partition=%d, disksize = %d, blksize=%d\n", - part,cd->disksize,cd->blksize,0); + MCD_TRACE("open: partition=%d disksize=%d blksize=%d\n", part, + sc->disksize, sc->blksize, 0); - if (part == RAW_PART || - (part < cd->dlabel.d_npartitions && - cd->dlabel.d_partitions[part].p_fstype != FS_UNUSED)) { - cd->partflags[part] |= MCDOPEN; - cd->openflags |= (1<partflags[part] |= MCDREADRAW; - return 0; - } - - return ENXIO; + if (part != RAW_PART && + (part >= sc->dlabel.d_npartitions || + sc->dlabel.d_partitions[part].p_fstype == FS_UNUSED)) + return ENXIO; + + sc->partflags[part] |= MCDOPEN; + sc->openflags |= (1 << part); + if (part == RAW_PART && phys != 0) + sc->partflags[part] |= MCDREADRAW; + return 0; } -int mcdclose(dev_t dev) +int +mcdclose(dev) + dev_t dev; { - int unit,part,phys; - struct mcd_data *cd; + int unit, part; + struct mcd_softc *sc; - unit = mcd_unit(dev); - if (unit >= NMCD) - return ENXIO; + unit = MCDUNIT(dev); + part = MCDPART(dev); + sc = &mcd_softc[unit]; - cd = mcd_data + unit; - part = mcd_part(dev); - phys = mcd_phys(dev); - - if (!(cd->flags & MCDINIT)) - return ENXIO; + /* Get status. */ + mcd_getstat(sc, 1); - mcd_getstat(unit,1); /* get status */ - - /* close channel */ - cd->partflags[part] &= ~(MCDOPEN|MCDREADRAW); - cd->openflags &= ~(1<partflags[part] &= ~(MCDOPEN | MCDREADRAW); + sc->openflags &= ~(1 << part); + MCD_TRACE("close: partition=%d\n", part, 0, 0, 0); return 0; } -int mcdstrategy(struct buf *bp) +void +mcdstrategy(bp) + struct buf *bp; { - struct mcd_data *cd; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(bp->b_dev)]; struct buf *qp; int s; - int unit = mcd_unit(bp->b_dev); - - cd = mcd_data + unit; - - /* test validity */ -/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n", - bp,unit,bp->b_blkno,bp->b_bcount);*/ - if (unit >= NMCD || bp->b_blkno < 0) { - printf("mcdstrategy: unit = %d, blkno = %d, bcount = %d\n", - unit, bp->b_blkno, bp->b_bcount); - pg("mcd: mcdstratregy failure"); + /* Test validity. */ + MCD_TRACE("strategy: buf=0x%lx blkno=%ld bcount=%ld\n", bp, + bp->b_blkno, bp->b_bcount, 0); + if (bp->b_blkno < 0) { + printf("%s: strategy: blkno=%d bcount=%d\n", + sc->sc_dev.dv_xname, bp->b_blkno, bp->b_bcount); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto bad; } - /* if device invalidated (e.g. media change, door open), error */ - if (!(cd->flags & MCDVALID)) { -MCD_TRACE("strategy: drive not valid\n",0,0,0,0); + /* If device invalidated (e.g. media change, door open), error. */ + if (!(sc->flags & MCDVALID)) { + MCD_TRACE("strategy: drive not valid\n", 0, 0, 0, 0); bp->b_error = EIO; goto bad; } - /* read only */ + /* Check for read only. */ if (!(bp->b_flags & B_READ)) { bp->b_error = EROFS; goto bad; } - /* no data to read */ + /* No data to read. */ if (bp->b_bcount == 0) goto done; - /* for non raw access, check partition limits */ - if (mcd_part(bp->b_dev) != RAW_PART) { - if (!(cd->flags & MCDLABEL)) { + /* For non raw access, check partition limits. */ + if (MCDPART(bp->b_dev) != RAW_PART) { + if (!(sc->flags & MCDLABEL)) { bp->b_error = EIO; goto bad; } - /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) { + /* Adjust transfer if necessary. */ + if (bounds_check_with_label(bp, &sc->dlabel, 1) <= 0) goto done; - } } - /* queue it */ - qp = &cd->head; + /* Queue it. */ + qp = &sc->head; s = splbio(); - disksort(qp,bp); + disksort(qp, bp); splx(s); - /* now check whether we can perform processing */ - mcd_start(unit); + /* Now check whether we can perform processing. */ + mcd_start(sc); return; bad: @@ -363,64 +343,61 @@ done: return; } -static void mcd_start(int unit) +int +mcd_start(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - struct buf *bp, *qp = &cd->head; + struct buf *bp, *qp = &sc->head; struct partition *p; - int part; - register s = splbio(); + int s = splbio(); - if (cd->flags & MCDMBXBSY) + if (sc->flags & MCDMBXBSY) return; if ((bp = qp->b_actf) != 0) { - /* block found to process, dequeue */ - /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/ + /* Block found to process; dequeue. */ + MCD_TRACE("start: found block bp=0x%x\n", bp, 0, 0, 0); qp->b_actf = bp->b_actf; splx(s); } else { - /* nothing to do */ + /* Nothing to do; */ splx(s); return; } - /* changed media? */ - if (!(cd->flags & MCDVALID)) { - MCD_TRACE("mcd_start: drive not valid\n",0,0,0,0); + /* Changed media? */ + if (!(sc->flags & MCDVALID)) { + MCD_TRACE("start: drive not valid\n", 0, 0, 0, 0); return; } - p = cd->dlabel.d_partitions + mcd_part(bp->b_dev); + p = &sc->dlabel.d_partitions[MCDPART(bp->b_dev)]; - cd->flags |= MCDMBXBSY; - cd->mbx.unit = unit; - cd->mbx.port = cd->iobase; - cd->mbx.retry = MCD_RETRYS; - cd->mbx.bp = bp; - cd->mbx.p_offset = p->p_offset; + sc->flags |= MCDMBXBSY; + sc->mbx.unit = sc->sc_dev.dv_unit; + sc->mbx.iobase = sc->iobase; + sc->mbx.retry = MCD_RETRIES; + sc->mbx.bp = bp; + sc->mbx.p_offset = p->p_offset; - /* calling the read routine */ - mcd_doread(MCD_S_BEGIN,&(cd->mbx)); - /* triggers mcd_start, when successful finished */ - return; + /* Calling the read routine. */ + mcd_doread(MCD_S_BEGIN, &sc->mbx); + /* triggers mcd_start, when successful finished. */ } -int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p) +int +mcdioctl(dev, cmd, addr, flags, p) + dev_t dev; + int cmd; + caddr_t addr; + int flags; + struct proc *p; { - struct mcd_data *cd; - int unit,part; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)]; - unit = mcd_unit(dev); - part = mcd_part(dev); - cd = mcd_data + unit; - -#ifdef MCDMINI - return ENOTTY; -#else - if (!(cd->flags & MCDVALID)) + if (!(sc->flags & MCDVALID)) return EIO; -MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); + MCD_TRACE("ioctl: cmd=0x%x\n", cmd, 0, 0, 0); switch (cmd) { case DIOCSBAD: @@ -432,15 +409,15 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); case DIOCWLABEL: return ENOTTY; case CDIOCPLAYTRACKS: - return mcd_playtracks(unit, (struct ioc_play_track *) addr); + return mcd_playtracks(sc, (struct ioc_play_track *) addr); case CDIOCPLAYBLOCKS: - return mcd_play(unit, (struct mcd_read2 *) addr); + return mcd_play(sc, (struct mcd_read2 *) addr); case CDIOCREADSUBCHANNEL: - return mcd_subchan(unit, (struct ioc_read_subchannel *) addr); + return mcd_subchan(sc, (struct ioc_read_subchannel *) addr); case CDIOREADTOCHEADER: - return mcd_toc_header(unit, (struct ioc_toc_header *) addr); + return mcd_toc_header(sc, (struct ioc_toc_header *) addr); case CDIOREADTOCENTRYS: - return mcd_toc_entry(unit, (struct ioc_read_toc_entry *) addr); + return mcd_toc_entry(sc, (struct ioc_read_toc_entry *) addr); case CDIOCSETPATCH: case CDIOCGETVOL: case CDIOCSETVOL: @@ -451,74 +428,78 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); case CDIOCSETRIGHT: return EINVAL; case CDIOCRESUME: - return mcd_resume(unit); + return mcd_resume(sc); case CDIOCPAUSE: - return mcd_pause(unit); + return mcd_pause(sc); case CDIOCSTART: return EINVAL; case CDIOCSTOP: - return mcd_stop(unit); + return mcd_stop(sc); case CDIOCEJECT: return EINVAL; case CDIOCSETDEBUG: - cd->debug = 1; + sc->debug = 1; return 0; case CDIOCCLRDEBUG: - cd->debug = 0; + sc->debug = 0; return 0; case CDIOCRESET: return EINVAL; default: return ENOTTY; } - /*NOTREACHED*/ -#endif /*!MCDMINI*/ +#ifdef DIAGNOSTIC + panic("mcdioctl: impossible"); +#endif } -/* this could have been taken from scsi/cd.c, but it is not clear - * whether the scsi cd driver is linked in +/* + * This could have been taken from scsi/cd.c, but it is not clear + * whether the scsi cd driver is linked in. */ -static int mcd_getdisklabel(int unit) +int +mcd_getdisklabel(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (cd->flags & MCDLABEL) + if (sc->flags & MCDLABEL) return -1; - bzero(&cd->dlabel,sizeof(struct disklabel)); - strncpy(cd->dlabel.d_typename,"Mitsumi CD ROM ",16); - strncpy(cd->dlabel.d_packname,"unknown ",16); - cd->dlabel.d_secsize = cd->blksize; - cd->dlabel.d_nsectors = 100; - cd->dlabel.d_ntracks = 1; - cd->dlabel.d_ncylinders = (cd->disksize/100)+1; - cd->dlabel.d_secpercyl = 100; - cd->dlabel.d_secperunit = cd->disksize; - cd->dlabel.d_rpm = 300; - cd->dlabel.d_interleave = 1; - cd->dlabel.d_flags = D_REMOVABLE; - cd->dlabel.d_npartitions= 1; - cd->dlabel.d_partitions[0].p_offset = 0; - cd->dlabel.d_partitions[0].p_size = cd->disksize; - cd->dlabel.d_partitions[0].p_fstype = 9; - cd->dlabel.d_magic = DISKMAGIC; - cd->dlabel.d_magic2 = DISKMAGIC; - cd->dlabel.d_checksum = dkcksum(&cd->dlabel); + bzero(&sc->dlabel, sizeof(struct disklabel)); + strncpy(sc->dlabel.d_typename, "Mitsumi CD ROM ", 16); + strncpy(sc->dlabel.d_packname, "unknown ", 16); + sc->dlabel.d_secsize = sc->blksize; + sc->dlabel.d_nsectors = 100; + sc->dlabel.d_ntracks = 1; + sc->dlabel.d_ncylinders = (sc->disksize /100) + 1; + sc->dlabel.d_secpercyl = 100; + sc->dlabel.d_secperunit = sc->disksize; + sc->dlabel.d_rpm = 300; + sc->dlabel.d_interleave = 1; + sc->dlabel.d_flags = D_REMOVABLE; + sc->dlabel.d_npartitions= 1; + sc->dlabel.d_partitions[0].p_offset = 0; + sc->dlabel.d_partitions[0].p_size = sc->disksize; + sc->dlabel.d_partitions[0].p_fstype = 9; + sc->dlabel.d_magic = DISKMAGIC; + sc->dlabel.d_magic2 = DISKMAGIC; + sc->dlabel.d_checksum = dkcksum(&sc->dlabel); - cd->flags |= MCDLABEL; + sc->flags |= MCDLABEL; return 0; } -int mcdsize(dev_t dev) +int +mcdsize(dev) + dev_t dev; { int size; - int unit = mcd_unit(dev); - struct mcd_data *cd = mcd_data + unit; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)]; - if (mcd_volinfo(unit) >= 0) { - cd->blksize = MCDBLK; - size = msf2hsg(cd->volinfo.vol_msf); - cd->disksize = size * (MCDBLK/DEV_BSIZE); + if (mcd_volinfo(sc) >= 0) { + sc->blksize = MCDBLK; + size = msf2hsg(sc->volinfo.vol_msf); + sc->disksize = size * (MCDBLK / DEV_BSIZE); return 0; } return -1; @@ -528,187 +509,199 @@ int mcdsize(dev_t dev) * lower level of driver starts here **************************************************************/ -#ifdef NOTDEF +#ifdef notyet static char irqs[] = { - 0x00,0x00,0x10,0x20,0x00,0x30,0x00,0x00, - 0x00,0x10,0x40,0x50,0x00,0x00,0x00,0x00 + 0x00, 0x00, 0x10, 0x20, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00 }; static char drqs[] = { - 0x00,0x01,0x00,0x03,0x00,0x05,0x06,0x07, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x06, 0x07 }; #endif -static void mcd_configure(struct mcd_data *cd) +void +mcd_configure(sc) + struct mcd_softc *sc; { - outb(cd->iobase+mcd_config,cd->config); + + outb(sc->iobase + mcd_config, sc->config); } -/* check if there is a cdrom */ -/* Heavly hacked by gclarkii@sugar.neosoft.com */ - -int mcd_probe(struct isa_device *dev) +int +mcdprobe(isa_dev) + struct isa_device *isa_dev; { - int port = dev->id_iobase; - int unit = dev->id_unit; + int unit = isa_dev->id_unit; + struct mcd_softc *sc = &mcd_softc[unit]; + u_short iobase = isa_dev->id_iobase; int i; - int st; - int check; - int junk; + int st, check; - mcd_data[unit].flags = MCDPROBING; + /* XXX HACK */ + sprintf(sc->sc_dev.dv_xname, "%s%d", mcddriver.name, isa_dev->id_unit); + sc->sc_dev.dv_unit = isa_dev->id_unit; -#ifdef NOTDEF - /* get irq/drq configuration word */ - mcd_data[unit].config = irqs[dev->id_irq]; /* | drqs[dev->id_drq];*/ -#else - mcd_data[unit].config = 0; +#ifdef notyet + /* Get irq/drq configuration word. */ + sc->config = irqs[isa_dev->id_irq]; #endif + sc->iobase = iobase; - /* send a reset */ - outb(port+MCD_FLAGS,0); - DELAY(100000); - /* get any pending status and throw away...*/ - for (i=10; i != 0; i--) { - inb(port+MCD_DATA); - } + /* Send a reset. */ + outb(iobase + mcd_reset, 0); + DELAY(300000); + /* Get any pending status and throw away. */ + for (i = 10; i; i--) + inb(iobase + mcd_status); DELAY(1000); - outb(port+MCD_DATA,MCD_CMDGETSTAT); /* Send get status command */ + /* Send get status command. */ + outb(iobase + mcd_command, MCD_CMDGETSTAT); + i = mcd_getreply(sc, DELAY_GETREPLY); - /* Loop looking for avail of status */ - /* XXX May have to increase for fast machinces */ - for (i = 1000; i != 0; i--) { - if ((inb(port+MCD_FLAGS) & 0xF ) == STATUS_AVAIL) { - break; - } - DELAY(10); - } - /* get status */ - - if (i == 0) { + if (i < 0) { #ifdef DEBUG - printf ("Mitsumi drive NOT detected\n"); + printf("Mitsumi drive NOT detected\n"); #endif - return 0; + return 0; } /* * The following code uses the 0xDC command, it returns a M from the - * second byte and a number in the third. Does anyone know what the - * number is for? Better yet, how about someone thats REAL good in - * i80x86 asm looking at the Dos driver... Most of this info came - * from a friend of mine spending a whole weekend..... + * second byte and a number in the third. + * (I hope you have the right drive for that, most drives don't do!) + * Whole code entirely rewriten by veit@gmd.de, the changes accessed + * the drive in an illegal way. Proper way is to use the timeout + * driven routines mcd_getreply etc. rather than arbitrary delays. */ DELAY (2000); - outb(port+MCD_DATA,MCD_CMDCONTINFO); - for (i = 0; i < 100000; i++) { - if ((inb(port+MCD_FLAGS) & 0xF) == STATUS_AVAIL) - break; - } - if (i > 100000) { -#ifdef DEBUG - printf ("Mitsumi drive error\n"); -#endif - return 0; - } - DELAY (40000); - st = inb(port+MCD_DATA); - DELAY (500); - check = inb(port+MCD_DATA); - DELAY (500); - junk = inb(port+MCD_DATA); /* What is byte used for?!?!? */ + outb(iobase + mcd_command, MCD_CMDCONTINFO); + i = mcd_getreply(sc, DELAY_GETREPLY); - if (check = 'M') { + if (i < 0) { #ifdef DEBUG - printf("Mitsumi drive detected\n"); -#endif - return 4; - } else { - printf("Mitsumi drive NOT detected\n"); printf("Mitsumi drive error\n"); +#endif return 0; } + st = mcd_getreply(sc, DELAY_GETREPLY); + if (st < 0) + return 0; + check = mcd_getreply(sc, DELAY_GETREPLY); + if (check < 0) + return 0; + /* Flush junk. */ + (void) mcd_getreply(sc, DELAY_GETREPLY); + + /* + * The following is code which is not guaranteed to work for all + * drives, because the meaning of the expected 'M' is not clear + * (M_itsumi is an obvious assumption, but I don't trust that). + * Also, the original hack had a bogus condition that always + * returned true. + */ +#ifdef notdef + if (check != 'M') { +#ifdef DEBUG + printf("Mitsumi drive NOT detected\n"); +#endif + return 0; + } +#endif + +#ifdef DEBUG + printf("Mitsumi drive detected\n"); +#endif + return 4; } -static int mcd_waitrdy(int port,int dly) +int +mcd_waitrdy(iobase, dly) + u_short iobase; + int dly; { int i; - /* wait until xfer port senses data ready */ - for (i=0; iiobase; + u_short iobase = sc->iobase; - /* wait data to become ready */ - if (mcd_waitrdy(port,dly)<0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout getreply\n",unit); -#endif + /* Wait data to become ready. */ + if (mcd_waitrdy(iobase, dly) < 0) { + printf("%s: timeout in getreply\n", sc->sc_dev.dv_xname); return -1; } - /* get the data */ - return inb(port+mcd_status) & 0xFF; + /* Get the data. */ + return inb(iobase + mcd_status); } -static int mcd_getstat(int unit,int sflg) +int +mcd_getstat(sc, sflg) + struct mcd_softc *sc; + int sflg; { - int i; - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + int i; + u_short iobase = sc->iobase; - /* get the status */ + /* Get the status. */ if (sflg) - outb(port+mcd_command, MCD_CMDGETSTAT); - i = mcd_getreply(unit,DELAY_GETREPLY); - if (i<0) return -1; - - cd->status = i; - - mcd_setflags(unit,cd); - return cd->status; -} - -static void mcd_setflags(int unit, struct mcd_data *cd) -{ - /* check flags */ - if (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) { - MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n",0,0,0,0); - cd->flags &= ~MCDVALID; + outb(iobase + mcd_command, MCD_CMDGETSTAT); + i = mcd_getreply(sc, DELAY_GETREPLY); + if (i < 0) { + printf("%s: timeout in getstat\n", sc->sc_dev.dv_xname); + return -1; } -#ifndef MCDMINI - if (cd->status & MCDAUDIOBSY) - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; - else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) - cd->audio_status = CD_AS_PLAY_COMPLETED; -#endif + sc->status = i; + + mcd_setflags(sc); + return sc->status; } -static int mcd_get(int unit, char *buf, int nmax) +void +mcd_setflags(sc) + struct mcd_softc *sc; { - int port = mcd_data[unit].iobase; - int i,k; - - for (i=0; istatus & (MCDDSKCHNG | MCDDOOROPEN)) { + MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n", 0, 0, 0, 0); + sc->flags &= ~MCDVALID; + } + + if (sc->status & MCDAUDIOBSY) + sc->audio_status = CD_AS_PLAY_IN_PROGRESS; + else if (sc->audio_status == CD_AS_PLAY_IN_PROGRESS) + sc->audio_status = CD_AS_PLAY_COMPLETED; +} + +int +mcd_get(sc, buf, nmax) + struct mcd_softc *sc; + char *buf; + int nmax; +{ + int i, k; + + for (i = 0; i < nmax; i++) { + /* Wait for data. */ + if ((k = mcd_getreply(sc, DELAY_GETREPLY)) < 0) { + printf("%s: timeout in get\n", sc->sc_dev.dv_xname); return -1; } buf[i] = k; @@ -716,37 +709,53 @@ static int mcd_get(int unit, char *buf, int nmax) return i; } -static int mcd_send(int unit, int cmd,int nretrys) +int +mcd_send(sc, cmd, nretries) + struct mcd_softc *sc; + int cmd, nretries; { - int i,k; - int port = mcd_data[unit].iobase; + int i, k; + u_short iobase = sc->iobase; -/*MCD_TRACE("mcd_send: command = 0x%x\n",cmd,0,0,0);*/ - for (i=0; isc_dev.dv_xname); return -1; } -/*MCD_TRACE("mcd_send: status = 0x%x\n",k,0,0,0);*/ + + MCD_TRACE("send: status=0x%x\n", k, 0, 0, 0); + return 0; } -static int bcd2bin(bcd_t b) +int +bcd2bin(b) + bcd_t b; { + return (b >> 4) * 10 + (b & 15); } -static bcd_t bin2bcd(int b) +bcd_t +bin2bcd(b) + int b; { + return ((b / 10) << 4) | (b % 10); } -static void hsg2msf(int hsg, bcd_t *msf) +void +hsg2msf(hsg, msf) + int hsg; + bcd_t *msf; { + hsg += 150; M_msf(msf) = bin2bcd(hsg / 4500); hsg %= 4500; @@ -754,76 +763,88 @@ static void hsg2msf(int hsg, bcd_t *msf) F_msf(msf) = bin2bcd(hsg % 75); } -static int msf2hsg(bcd_t *msf) +int +msf2hsg(msf) + bcd_t *msf; { + return (bcd2bin(M_msf(msf)) * 60 + bcd2bin(S_msf(msf))) * 75 + bcd2bin(F_msf(msf)) - 150; } -static int mcd_volinfo(int unit) +int +mcd_volinfo(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - int i; -/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/ + MCD_TRACE("volinfo: enter\n", 0, 0, 0, 0); - /* Get the status, in case the disc has been changed */ - if (mcd_getstat(unit, 1) < 0) return EIO; + /* Get the status, in case the disc has been changed. */ + if (mcd_getstat(sc, 1) < 0) + return EIO; - /* Just return if we already have it */ - if (cd->flags & MCDVOLINFO) return 0; + /* Just return if we already have it. */ + if (sc->flags & MCDVOLINFO) + return 0; - /* send volume info command */ - if (mcd_send(unit,MCD_CMDGETVOLINFO,MCD_RETRYS) < 0) + /* Send volume info command. */ + if (mcd_send(sc, MCD_CMDGETVOLINFO, MCD_RETRIES) < 0) return -1; - /* get data */ - if (mcd_get(unit,(char*) &cd->volinfo,sizeof(struct mcd_volinfo)) < 0) { - printf("mcd%d: mcd_volinfo: error read data\n",unit); + /* Get the data. */ + if (mcd_get(sc, (char*) &sc->volinfo, sizeof(struct mcd_volinfo)) < 0) { + printf("%s: volinfo: error reading data\n", + sc->sc_dev.dv_xname); return -1; } - if (cd->volinfo.trk_low != 0 || cd->volinfo.trk_high != 0) { - cd->flags |= MCDVOLINFO; /* volinfo is OK */ + if (sc->volinfo.trk_low != 0 || sc->volinfo.trk_high != 0) { + /* Volinfo is OK. */ + sc->flags |= MCDVOLINFO; return 0; } return -1; } -int mcdintr(unit) +int +mcdintr(unit) + int unit; { - int port = mcd_data[unit].iobase; - u_int i; + struct mcd_softc *sc = &mcd_softc[unit]; + u_short iobase = sc->iobase; - MCD_TRACE("stray interrupt xfer=0x%x\n",inb(port+mcd_xfer),0,0,0); + MCD_TRACE("stray interrupt xfer=0x%x\n", inb(iobase + mcd_xfer), + 0, 0, 0); - /* just read out status and ignore the rest */ - if ((inb(port+mcd_xfer)&0xFF) != 0xFF) { - i = inb(port+mcd_status); - } + /* Just read out status and ignore the rest. */ + if (inb(iobase + mcd_xfer) != 0xff) + (void) inb(iobase + mcd_status); } -/* state machine to process read requests - * initialize with MCD_S_BEGIN: calculate sizes, and read status +/* + * State machine to process read requests. + * Initialize with MCD_S_BEGIN: calculate sizes, and read status * MCD_S_WAITSTAT: wait for status reply, set mode * MCD_S_WAITMODE: waits for status reply from set mode, set read command - * MCD_S_WAITREAD: wait for read ready, read data + * MCD_S_WAITREAD: wait for read ready, read data. */ -static struct mcd_mbx *mbxsave; +struct mcd_mbx *mbxsave; -static void mcd_doread(int state, struct mcd_mbx *mbxin) +void +mcd_doread(state, mbxin) + int state; + struct mcd_mbx *mbxin; { - struct mcd_mbx *mbx = (state!=MCD_S_BEGIN) ? mbxsave : mbxin; - int unit = mbx->unit; - int port = mbx->port; - struct buf *bp = mbx->bp; - struct mcd_data *cd = mcd_data + unit; + struct mcd_mbx *mbx = (state != MCD_S_BEGIN) ? mbxsave : mbxin; + struct mcd_softc *sc = &mcd_softc[mbx->unit]; + u_short iobase = mbx->iobase; + struct buf *bp = mbx->bp; - int rm,i,k; + int rm, i, k; struct mcd_read2 rbuf; - int blknum; + int blkno; caddr_t addr; loop: @@ -832,438 +853,467 @@ loop: mbx = mbxsave = mbxin; case MCD_S_BEGIN1: - /* get status */ - outb(port+mcd_command, MCD_CMDGETSTAT); + /* Get status. */ + outb(iobase + mcd_command, MCD_CMDGETSTAT); mbx->count = RDELAY_WAITSTAT; - timeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITSTAT,hz/100); + timeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITSTAT, + hz/100); return; + case MCD_S_WAITSTAT: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITSTAT); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITSTAT); if (mbx->count-- >= 0) { - if (inb(port+mcd_xfer) & MCD_ST_BUSY) { + if (inb(iobase + mcd_xfer) & MCD_ST_BUSY) { timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITSTAT,hz/100); + (caddr_t) MCD_S_WAITSTAT, hz/100); return; } - mcd_setflags(unit,cd); - MCD_TRACE("got WAITSTAT delay=%d\n",RDELAY_WAITSTAT-mbx->count,0,0,0); - /* reject, if audio active */ - if (cd->status & MCDAUDIOBSY) { - printf("mcd%d: audio is active\n",unit); + mcd_setflags(sc); + MCD_TRACE("doread: got WAITSTAT delay=%d\n", + RDELAY_WAITSTAT - mbx->count, 0, 0, 0); + /* Reject, if audio active. */ + if (sc->status & MCDAUDIOBSY) { + printf("%s: audio is active\n", + sc->sc_dev.dv_xname); goto readerr; } - /* to check for raw/cooked mode */ - if (cd->flags & MCDREADRAW) { + /* Check for raw/cooked mode. */ + if (sc->flags & MCDREADRAW) { rm = MCD_MD_RAW; mbx->sz = MCDRBLK; } else { rm = MCD_MD_COOKED; - mbx->sz = cd->blksize; + mbx->sz = sc->blksize; } mbx->count = RDELAY_WAITMODE; - mcd_put(port+mcd_command, MCD_CMDSETMODE); - mcd_put(port+mcd_command, rm); + mcd_put(iobase + mcd_command, MCD_CMDSETMODE); + mcd_put(iobase + mcd_command, rm); timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITMODE,hz/100); + (caddr_t) MCD_S_WAITMODE, hz/100); return; } else { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout getstatus\n",unit); -#endif + printf("%s: timeout getting status\n", + sc->sc_dev.dv_xname); goto readerr; } case MCD_S_WAITMODE: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITMODE); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITMODE); if (mbx->count-- < 0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout set mode\n",unit); -#endif + printf("%s: timeout setting mode\n", + sc->sc_dev.dv_xname); goto readerr; } - if (inb(port+mcd_xfer) & MCD_ST_BUSY) { + if (inb(iobase + mcd_xfer) & MCD_ST_BUSY) { timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITMODE,hz/100); + (caddr_t) MCD_S_WAITMODE, hz/100); return; } - mcd_setflags(unit,cd); - MCD_TRACE("got WAITMODE delay=%d\n",RDELAY_WAITMODE-mbx->count,0,0,0); - /* for first block */ - mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; + mcd_setflags(sc); + MCD_TRACE("doread: got WAITMODE delay=%d\n", + RDELAY_WAITMODE - mbx->count, 0, 0, 0); + /* For first block. */ + mbx->nblk = (bp->b_bcount + (mbx->sz - 1)) / mbx->sz; mbx->skip = 0; nextblock: - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) - + mbx->p_offset + mbx->skip/mbx->sz; + blkno = (bp->b_blkno / (mbx->sz / DEV_BSIZE)) + mbx->p_offset + + (mbx->skip / mbx->sz); - MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n",blknum,bp,0,0); + MCD_TRACE("doread: read blkno=%d for bp=0x%x\n", blkno, bp, 0, + 0); - /* build parameter block */ - hsg2msf(blknum,rbuf.start_msf); + /* Build parameter block. */ + hsg2msf(blkno, rbuf.start_msf); - /* send the read command */ - mcd_put(port+mcd_command,MCD_CMDREAD2); - mcd_put(port+mcd_command,rbuf.start_msf[0]); - mcd_put(port+mcd_command,rbuf.start_msf[1]); - mcd_put(port+mcd_command,rbuf.start_msf[2]); - mcd_put(port+mcd_command,0); - mcd_put(port+mcd_command,0); - mcd_put(port+mcd_command,1); + /* Send the read command. */ + mcd_put(iobase + mcd_command, MCD_CMDREAD2); + mcd_put(iobase + mcd_command, rbuf.start_msf[0]); + mcd_put(iobase + mcd_command, rbuf.start_msf[1]); + mcd_put(iobase + mcd_command, rbuf.start_msf[2]); + mcd_put(iobase + mcd_command, 0); + mcd_put(iobase + mcd_command, 0); + mcd_put(iobase + mcd_command, 1); mbx->count = RDELAY_WAITREAD; - timeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITREAD,hz/100); + timeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITREAD, + hz/100); return; + case MCD_S_WAITREAD: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITREAD); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITREAD); if (mbx->count-- > 0) { - k = inb(port+mcd_xfer); - if ((k & 2)==0) { - MCD_TRACE("got data delay=%d\n",RDELAY_WAITREAD-mbx->count,0,0,0); - /* data is ready */ - addr = bp->b_un.b_addr + mbx->skip; - outb(port+mcd_ctl2,0x04); /* XXX */ - for (i=0; isz; i++) - *addr++ = inb(port+mcd_rdata); - outb(port+mcd_ctl2,0x0c); /* XXX */ + k = inb(iobase + mcd_xfer); + if ((k & 2) == 0) { /* XXX MCD_ST_AUDIOBSY? */ + MCD_TRACE("doread: got data delay=%d\n", + RDELAY_WAITREAD - mbx->count, 0, 0, 0); + /* Data is ready. */ + addr = bp->b_un.b_addr + mbx->skip; + outb(iobase + mcd_ctl2, 0x04); /* XXX */ + for (i = 0; i < mbx->sz; i++) + *addr++ = inb(iobase + mcd_rdata); + outb(iobase + mcd_ctl2, 0x0c); /* XXX */ if (--mbx->nblk > 0) { mbx->skip += mbx->sz; goto nextblock; } - /* return buffer */ + /* Return buffer. */ bp->b_resid = 0; biodone(bp); - cd->flags &= ~MCDMBXBSY; - mcd_start(mbx->unit); + sc->flags &= ~MCDMBXBSY; + mcd_start(sc); return; } - if ((k & 4)==0) - mcd_getstat(unit,0); + if ((k & MCD_ST_BUSY) == 0) + mcd_getstat(sc, 0); timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITREAD,hz/100); + (caddr_t) MCD_S_WAITREAD, hz/100); return; } else { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout read data\n",unit); -#endif + printf("%s: timeout reading data\n", + sc->sc_dev.dv_xname); goto readerr; } } readerr: if (mbx->retry-- > 0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: retrying\n",unit); -#endif + printf("%s: retrying\n", sc->sc_dev.dv_xname); state = MCD_S_BEGIN1; goto loop; } - /* invalidate the buffer */ + /* Invalidate the buffer. */ bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; biodone(bp); - mcd_start(mbx->unit); - return; + mcd_start(sc); -#ifdef NOTDEF - printf("mcd%d: unit timeout, resetting\n",mbx->unit); - outb(mbx->port+mcd_reset,MCD_CMDRESET); +#ifdef notyet + printf("%s: unit timeout; resetting\n", sc->sc_dev.dv_xname); + outb(mbx->iobase + mcd_reset, MCD_CMDRESET); DELAY(300000); - (void)mcd_getstat(mbx->unit,1); - (void)mcd_getstat(mbx->unit,1); - /*cd->status &= ~MCDDSKCHNG; */ - cd->debug = 1; /* preventive set debug mode */ - + (void)mcd_getstat(sc, 1); + (void)mcd_getstat(sc, 1); + /*sc->status &= ~MCDDSKCHNG; */ + sc->debug = 1; /* preventive set debug mode */ #endif - } -#ifndef MCDMINI -static int mcd_setmode(int unit, int mode) +int +mcd_setmode(sc, mode) + struct mcd_softc *sc; + int mode; { - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + u_short iobase = sc->iobase; int retry; - printf("mcd%d: setting mode to %d\n", unit, mode); - for(retry=0; retrysc_dev.dv_xname, mode); + for (retry = MCD_RETRIES; retry; retry--) { + outb(iobase + mcd_command, MCD_CMDSETMODE); + outb(iobase + mcd_command, mode); + if (mcd_getstat(sc, 0) != -1) + return 0; } return -1; } -static int mcd_toc_header(int unit, struct ioc_toc_header *th) +int +mcd_toc_header(sc, th) + struct mcd_softc *sc; + struct ioc_toc_header *th; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_volinfo(unit) < 0) + if (mcd_volinfo(sc) < 0) return ENXIO; - th->len = msf2hsg(cd->volinfo.vol_msf); - th->starting_track = bcd2bin(cd->volinfo.trk_low); - th->ending_track = bcd2bin(cd->volinfo.trk_high); + th->len = msf2hsg(sc->volinfo.vol_msf); + th->starting_track = bcd2bin(sc->volinfo.trk_low); + th->ending_track = bcd2bin(sc->volinfo.trk_high); return 0; } -static int mcd_read_toc(int unit) +int +mcd_read_toc(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; struct ioc_toc_header th; struct mcd_qchninfo q; int rc, trk, idx, retry; - /* Only read TOC if needed */ - if (cd->flags & MCDTOC) return 0; + /* Only read TOC if needed. */ + if (sc->flags & MCDTOC) + return 0; - printf("mcd%d: reading toc header\n", unit); - if (mcd_toc_header(unit, &th) != 0) + if (sc->debug) + printf("%s: read_toc: reading toc header\n", + sc->sc_dev.dv_xname); + if (mcd_toc_header(sc, &th) != 0) return ENXIO; - printf("mcd%d: stopping play\n", unit); - if ((rc=mcd_stop(unit)) != 0) + if (sc->debug) + printf("%s: read_toc: stopping play\n", sc->sc_dev.dv_xname); + if ((rc = mcd_stop(sc)) != 0) return rc; - /* try setting the mode twice */ - if (mcd_setmode(unit, MCD_MD_TOC) != 0) + /* Try setting the mode twice. */ + if (mcd_setmode(sc, MCD_MD_TOC) != 0) return EIO; - if (mcd_setmode(unit, MCD_MD_TOC) != 0) + if (mcd_setmode(sc, MCD_MD_TOC) != 0) return EIO; - printf("mcd%d: get_toc reading qchannel info\n",unit); - for(trk=th.starting_track; trk<=th.ending_track; trk++) - cd->toc[trk].idx_no = 0; + if (sc->debug) + printf("%s: read_toc: reading qchannel info\n", + sc->sc_dev.dv_xname); + for (trk = th.starting_track; trk <= th.ending_track; trk++) + sc->toc[trk].idx_no = 0; trk = th.ending_track - th.starting_track + 1; - for(retry=0; retry<300 && trk>0; retry++) - { - if (mcd_getqchan(unit, &q) < 0) break; + for (retry = 300; retry && trk > 0; retry--) { + if (mcd_getqchan(sc, &q) < 0) + break; idx = bcd2bin(q.idx_no); - if (idx>0 && idx < MCD_MAXTOCS && q.trk_no==0) - if (cd->toc[idx].idx_no == 0) - { - cd->toc[idx] = q; - trk--; - } + if (idx > 0 && idx < MCD_MAXTOCS && q.trk_no == 0 && + sc->toc[idx].idx_no == 0) { + sc->toc[idx] = q; + trk--; + } } - if (mcd_setmode(unit, MCD_MD_COOKED) != 0) + if (mcd_setmode(sc, MCD_MD_COOKED) != 0) return EIO; - if (trk != 0) return ENXIO; + if (trk != 0) + return ENXIO; - /* add a fake last+1 */ + /* Add a fake last+1. */ idx = th.ending_track + 1; - cd->toc[idx].ctrl_adr = cd->toc[idx-1].ctrl_adr; - cd->toc[idx].trk_no = 0; - cd->toc[idx].idx_no = 0xAA; - cd->toc[idx].hd_pos_msf[0] = cd->volinfo.vol_msf[0]; - cd->toc[idx].hd_pos_msf[1] = cd->volinfo.vol_msf[1]; - cd->toc[idx].hd_pos_msf[2] = cd->volinfo.vol_msf[2]; + sc->toc[idx].ctrl_adr = sc->toc[idx-1].ctrl_adr; + sc->toc[idx].trk_no = 0; + sc->toc[idx].idx_no = 0xaa; + sc->toc[idx].hd_pos_msf[0] = sc->volinfo.vol_msf[0]; + sc->toc[idx].hd_pos_msf[1] = sc->volinfo.vol_msf[1]; + sc->toc[idx].hd_pos_msf[2] = sc->volinfo.vol_msf[2]; - cd->flags |= MCDTOC; + sc->flags |= MCDTOC; return 0; } -static int mcd_toc_entry(int unit, struct ioc_read_toc_entry *te) +int +mcd_toc_entry(sc, te) + struct mcd_softc *sc; + struct ioc_read_toc_entry *te; { - struct mcd_data *cd = mcd_data + unit; - struct ret_toc - { + struct ret_toc { struct ioc_toc_header th; struct cd_toc_entry rt; } ret_toc; struct ioc_toc_header th; int rc, i; - /* Make sure we have a valid toc */ - if ((rc=mcd_read_toc(unit)) != 0) + /* Make sure we have a valid TOC. */ + if ((rc = mcd_read_toc(sc)) != 0) return rc; - /* find the toc to copy*/ + /* Find the TOC to copy. */ i = te->starting_track; if (i == MCD_LASTPLUS1) - i = bcd2bin(cd->volinfo.trk_high) + 1; + i = bcd2bin(sc->volinfo.trk_high) + 1; - /* verify starting track */ - if (i < bcd2bin(cd->volinfo.trk_low) || - i > bcd2bin(cd->volinfo.trk_high)+1) + /* Verify starting track. */ + if (i < bcd2bin(sc->volinfo.trk_low) || + i > bcd2bin(sc->volinfo.trk_high) + 1) return EINVAL; - /* do we have room */ + /* Do we have room? */ if (te->data_len < sizeof(struct ioc_toc_header) + - sizeof(struct cd_toc_entry)) return EINVAL; + sizeof(struct cd_toc_entry)) + return EINVAL; - /* Copy the toc header */ - if (mcd_toc_header(unit, &th) < 0) return EIO; + /* Copy the TOC header. */ + if (mcd_toc_header(sc, &th) < 0) + return EIO; ret_toc.th = th; - /* copy the toc data */ - ret_toc.rt.control = cd->toc[i].ctrl_adr; + /* Copy the TOC data. */ + ret_toc.rt.control = sc->toc[i].ctrl_adr; ret_toc.rt.addr_type = te->address_format; ret_toc.rt.track = i; - if (te->address_format == CD_MSF_FORMAT) - { - ret_toc.rt.addr[1] = cd->toc[i].hd_pos_msf[0]; - ret_toc.rt.addr[2] = cd->toc[i].hd_pos_msf[1]; - ret_toc.rt.addr[3] = cd->toc[i].hd_pos_msf[2]; + if (te->address_format == CD_MSF_FORMAT) { + ret_toc.rt.addr[1] = sc->toc[i].hd_pos_msf[0]; + ret_toc.rt.addr[2] = sc->toc[i].hd_pos_msf[1]; + ret_toc.rt.addr[3] = sc->toc[i].hd_pos_msf[2]; } - /* copy the data back */ - copyout(&ret_toc, te->data, sizeof(struct cd_toc_entry) - + sizeof(struct ioc_toc_header)); + /* Copy the data back. */ + copyout(&ret_toc, te->data, + sizeof(struct cd_toc_entry) + sizeof(struct ioc_toc_header)); return 0; } -static int mcd_stop(int unit) +int +mcd_stop(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) + if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRIES) < 0) return ENXIO; - cd->audio_status = CD_AS_PLAY_COMPLETED; + sc->audio_status = CD_AS_PLAY_COMPLETED; return 0; } -static int mcd_getqchan(int unit, struct mcd_qchninfo *q) +int +mcd_getqchan(sc, q) + struct mcd_softc *sc; + struct mcd_qchninfo *q; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_send(unit, MCD_CMDGETQCHN, MCD_RETRYS) < 0) + if (mcd_send(sc, MCD_CMDGETQCHN, MCD_RETRIES) < 0) return -1; - if (mcd_get(unit, (char *) q, sizeof(struct mcd_qchninfo)) < 0) + if (mcd_get(sc, (char *) q, sizeof(struct mcd_qchninfo)) < 0) return -1; - if (cd->debug) - printf("mcd%d: qchannel ctl=%d, t=%d, i=%d, ttm=%d:%d.%d dtm=%d:%d.%d\n", - unit, - q->ctrl_adr, q->trk_no, q->idx_no, - q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], - q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); + if (sc->debug) + printf("%s: getqchan: ctl=%d t=%d i=%d ttm=%d:%d.%d dtm=%d:%d.%d\n", + sc->sc_dev.dv_xname, q->ctrl_adr, q->trk_no, q->idx_no, + q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], + q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); return 0; } -static int mcd_subchan(int unit, struct ioc_read_subchannel *sc) +int +mcd_subchan(sc, ch) + struct mcd_softc *sc; + struct ioc_read_subchannel *ch; { - struct mcd_data *cd = mcd_data + unit; struct mcd_qchninfo q; struct cd_sub_channel_info data; - printf("mcd%d: subchan af=%d, df=%d\n", unit, - sc->address_format, - sc->data_format); - if (sc->address_format != CD_MSF_FORMAT) return EIO; - if (sc->data_format != CD_CURRENT_POSITION) return EIO; + if (sc->debug) + printf("%s: subchan: af=%d df=%d\n", sc->sc_dev.dv_xname, + ch->address_format, ch->data_format); - if (mcd_getqchan(unit, &q) < 0) return EIO; + if (ch->address_format != CD_MSF_FORMAT) + return EIO; + if (ch->data_format != CD_CURRENT_POSITION) + return EIO; + if (mcd_getqchan(sc, &q) < 0) + return EIO; - data.header.audio_status = cd->audio_status; + data.header.audio_status = sc->audio_status; data.what.position.data_format = CD_MSF_FORMAT; data.what.position.track_number = bcd2bin(q.trk_no); - if (copyout(&data, sc->data, sizeof(struct cd_sub_channel_info))!=0) + if (copyout(&data, ch->data, sizeof(struct cd_sub_channel_info)) != 0) return EFAULT; return 0; } -static int mcd_playtracks(int unit, struct ioc_play_track *pt) +int +mcd_playtracks(sc, pt) + struct mcd_softc *sc; + struct ioc_play_track *pt; { - struct mcd_data *cd = mcd_data + unit; struct mcd_read2 pb; int a = pt->start_track; int z = pt->end_track; int rc; - if ((rc = mcd_read_toc(unit)) != 0) return rc; + if ((rc = mcd_read_toc(sc)) != 0) + return rc; - printf("mcd%d: playtracks from %d:%d to %d:%d\n", unit, - a, pt->start_index, z, pt->end_index); + printf("%s: playtracks: from %d:%d to %d:%d\n", sc->sc_dev.dv_xname, + a, pt->start_index, z, pt->end_index); - if (a < cd->volinfo.trk_low || a > cd->volinfo.trk_high || a > z || - z < cd->volinfo.trk_low || z > cd->volinfo.trk_high) + if (a < sc->volinfo.trk_low || a > sc->volinfo.trk_high || a > z || + z < sc->volinfo.trk_low || z > sc->volinfo.trk_high) return EINVAL; - pb.start_msf[0] = cd->toc[a].hd_pos_msf[0]; - pb.start_msf[1] = cd->toc[a].hd_pos_msf[1]; - pb.start_msf[2] = cd->toc[a].hd_pos_msf[2]; - pb.end_msf[0] = cd->toc[z+1].hd_pos_msf[0]; - pb.end_msf[1] = cd->toc[z+1].hd_pos_msf[1]; - pb.end_msf[2] = cd->toc[z+1].hd_pos_msf[2]; + pb.start_msf[0] = sc->toc[a].hd_pos_msf[0]; + pb.start_msf[1] = sc->toc[a].hd_pos_msf[1]; + pb.start_msf[2] = sc->toc[a].hd_pos_msf[2]; + pb.end_msf[0] = sc->toc[z+1].hd_pos_msf[0]; + pb.end_msf[1] = sc->toc[z+1].hd_pos_msf[1]; + pb.end_msf[2] = sc->toc[z+1].hd_pos_msf[2]; - return mcd_play(unit, &pb); + return mcd_play(sc, &pb); } -static int mcd_play(int unit, struct mcd_read2 *pb) +int +mcd_play(sc, pb) + struct mcd_softc *sc; + struct mcd_read2 *pb; { - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + u_short iobase = sc->iobase; int retry, st; - cd->lastpb = *pb; - for(retry=0; retrystart_msf[0]); - outb(port+mcd_command, pb->start_msf[1]); - outb(port+mcd_command, pb->start_msf[2]); - outb(port+mcd_command, pb->end_msf[0]); - outb(port+mcd_command, pb->end_msf[1]); - outb(port+mcd_command, pb->end_msf[2]); - if ((st=mcd_getstat(unit, 0)) != -1) break; + sc->lastpb = *pb; + for (retry = MCD_RETRIES; retry; retry--) { + outb(iobase + mcd_command, MCD_CMDREAD2); + outb(iobase + mcd_command, pb->start_msf[0]); + outb(iobase + mcd_command, pb->start_msf[1]); + outb(iobase + mcd_command, pb->start_msf[2]); + outb(iobase + mcd_command, pb->end_msf[0]); + outb(iobase + mcd_command, pb->end_msf[1]); + outb(iobase + mcd_command, pb->end_msf[2]); + if ((st = mcd_getstat(sc, 0)) != -1) + break; } + if (sc->debug) + printf("%s: play: retry=%d status=%d\n", sc->sc_dev.dv_xname, + retry, st); + if (!retry) + return ENXIO; - if (cd->debug) - printf("mcd%d: mcd_play retry=%d, status=%d\n", unit, retry, st); - if (st == -1) return ENXIO; - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; + sc->audio_status = CD_AS_PLAY_IN_PROGRESS; return 0; } -static int mcd_pause(int unit) +int +mcd_pause(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; struct mcd_qchninfo q; int rc; - /* Verify current status */ - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) - { - printf("mcd%d: pause attempted when not playing\n", unit); + /* Verify current status. */ + if (sc->audio_status != CD_AS_PLAY_IN_PROGRESS) { + printf("%s: pause: attempted when not playing\n", + sc->sc_dev.dv_xname); return EINVAL; } - /* Get the current position */ - if (mcd_getqchan(unit, &q) < 0) return EIO; + /* Get the current position. */ + if (mcd_getqchan(sc, &q) < 0) + return EIO; - /* Copy it into lastpb */ - cd->lastpb.start_msf[0] = q.hd_pos_msf[0]; - cd->lastpb.start_msf[1] = q.hd_pos_msf[1]; - cd->lastpb.start_msf[2] = q.hd_pos_msf[2]; + /* Copy it into lastpb. */ + sc->lastpb.start_msf[0] = q.hd_pos_msf[0]; + sc->lastpb.start_msf[1] = q.hd_pos_msf[1]; + sc->lastpb.start_msf[2] = q.hd_pos_msf[2]; - /* Stop playing */ - if ((rc=mcd_stop(unit)) != 0) return rc; + /* Stop playing. */ + if ((rc = mcd_stop(sc)) != 0) + return rc; - /* Set the proper status and exit */ - cd->audio_status = CD_AS_PLAY_PAUSED; + /* Set the proper status and exit. */ + sc->audio_status = CD_AS_PLAY_PAUSED; return 0; } -static int mcd_resume(int unit) +int +mcd_resume(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (cd->audio_status != CD_AS_PLAY_PAUSED) return EINVAL; - return mcd_play(unit, &cd->lastpb); + if (sc->audio_status != CD_AS_PLAY_PAUSED) + return EINVAL; + return mcd_play(sc, &sc->lastpb); } -#endif /*!MCDMINI*/ - -#endif /* NMCD > 0 */ diff --git a/sys/arch/i386/isa/mcdreg.h b/sys/arch/i386/isa/mcdreg.h index 6bc603fac31e..70912393e62b 100644 --- a/sys/arch/i386/isa/mcdreg.h +++ b/sys/arch/i386/isa/mcdreg.h @@ -41,12 +41,9 @@ * the manufacturer or anyone else might provide better documentation, * so this file (and the driver) will then have a better quality. * - * $Id: mcdreg.h,v 1.2 1993/11/17 12:22:57 cgd Exp $ + * $Id: mcdreg.h,v 1.3 1994/02/21 15:23:12 mycroft Exp $ */ -#ifndef MCD_H -#define MCD_H - #ifdef __GNUC__ #if __GNUC__ >= 2 #pragma pack(1) @@ -77,15 +74,6 @@ typedef unsigned char bcd_t; /* 011 = int 5 */ /* 100 = int 10 */ /* 101 = int 11 */ -/* flags */ -#define STATUS_AVAIL 0xb -#define DATA_AVAIL 0xf - -/* ports */ -#define MCD_DATA 0 -#define MCD_FLAGS 1 -#define MCD_DONT_KNOW 2 /* What are these two ports for??? */ -#define CHANNEL 3 /* Status bits */ #define MCD_ST_DOOROPEN 0x80 @@ -148,4 +136,3 @@ struct mcd_read2 { bcd_t start_msf[3]; bcd_t end_msf[3]; }; -#endif /* MCD_H */ diff --git a/sys/dev/isa/mcd.c b/sys/dev/isa/mcd.c index 82de4cd420ca..b4582d3a0641 100644 --- a/sys/dev/isa/mcd.c +++ b/sys/dev/isa/mcd.c @@ -1,7 +1,7 @@ /* + * Copyright (c) 1993, 1994 Charles Hannum. * Copyright 1993 by Holger Veit (data part) * Copyright 1993 by Brian Moore (audio part) - * CHANGES Copyright 1993 Gary Clark II (gclarkii@freefall.cdrom.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,16 +35,18 @@ * 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.5 1994/02/09 21:13:48 mycroft Exp $ + * $Id: mcd.c,v 1.6 1994/02/21 15:23:11 mycroft Exp $ */ -static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; +/*static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore";*/ #include "mcd.h" -#if NMCD > 0 + #include #include #include +#include +#include #include #include #include @@ -55,30 +57,24 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; #include #include #include +#include +#include #include #include #include #include -/* user definable options */ -/*#define MCD_TO_WARNING_ON*/ /* define to get timeout messages */ -/*#define MCDMINI*/ /* define for a mini configuration for boot kernel */ - - -#ifdef MCDMINI +#ifndef MCDDEBUG #define MCD_TRACE(fmt,a,b,c,d) -#ifdef MCD_TO_WARNING_ON -#undef MCD_TO_WARNING_ON -#endif #else -#define MCD_TRACE(fmt,a,b,c,d) {if (mcd_data[unit].debug) {printf("mcd%d st=%02x: ",unit,mcd_data[unit].status); printf(fmt,a,b,c,d);}} +#define MCD_TRACE(fmt,a,b,c,d) {if (sc->debug) {printf("%s: st=%02x: ", sc->sc_dev.dv_xname, sc->status); printf(fmt,a,b,c,d);}} #endif -#define mcd_part(dev) ((minor(dev)) & 7) -#define mcd_unit(dev) (((minor(dev)) & 0x38) >> 3) -#define mcd_phys(dev) (((minor(dev)) & 0x40) >> 6) +#define MCDPART(dev) (((minor(dev)) & 0x07) ) +#define MCDUNIT(dev) (((minor(dev)) & 0x78) >> 3) +#define MCDPHYS(dev) (((minor(dev)) & 0x80) >> 7) #define RAW_PART 3 /* flags */ @@ -87,11 +83,10 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; #define MCDINIT 0x0004 /* device is init'd */ #define MCDWAIT 0x0008 /* waiting for something */ #define MCDLABEL 0x0010 /* label is read */ -#define MCDPROBING 0x0020 /* probing */ -#define MCDREADRAW 0x0040 /* read raw mode (2352 bytes) */ -#define MCDVOLINFO 0x0080 /* already read volinfo */ -#define MCDTOC 0x0100 /* already read toc */ -#define MCDMBXBSY 0x0200 /* local mbx is busy */ +#define MCDREADRAW 0x0020 /* read raw mode (2352 bytes) */ +#define MCDVOLINFO 0x0040 /* already read volinfo */ +#define MCDTOC 0x0080 /* already read toc */ +#define MCDMBXBSY 0x0100 /* local mbx is busy */ /* status */ #define MCDAUDIOBSY MCD_ST_AUDIOBSY /* playing audio */ @@ -105,7 +100,7 @@ static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; struct mcd_mbx { short unit; - short port; + u_short iobase; short retry; short nblk; int sz; @@ -115,78 +110,70 @@ struct mcd_mbx { short count; }; -struct mcd_data { +struct mcd_softc { + struct device sc_dev; + + u_short iobase; short config; short flags; short status; int blksize; u_long disksize; - int iobase; - struct disklabel dlabel; + struct disklabel dlabel; int partflags[MAXPARTITIONS]; int openflags; - struct mcd_volinfo volinfo; -#ifndef MCDMINI - struct mcd_qchninfo toc[MCD_MAXTOCS]; + struct mcd_volinfo volinfo; + struct mcd_qchninfo toc[MCD_MAXTOCS]; short audio_status; - struct mcd_read2 lastpb; -#endif + struct mcd_read2 lastpb; short debug; - struct buf head; /* head of buf queue */ - struct mcd_mbx mbx; -} mcd_data[NMCD]; - -/* reader state machine */ -#define MCD_S_BEGIN 0 -#define MCD_S_BEGIN1 1 -#define MCD_S_WAITSTAT 2 -#define MCD_S_WAITMODE 3 -#define MCD_S_WAITREAD 4 + struct buf head; /* head of buf queue */ + struct mcd_mbx mbx; +} mcd_softc[NMCD]; /* prototypes */ -int mcdopen(dev_t dev); -int mcdclose(dev_t dev); -int mcdstrategy(struct buf *bp); -int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p); -int mcdsize(dev_t dev); -static void mcd_done(struct mcd_mbx *mbx); -static void mcd_start(int unit); -static int mcd_getdisklabel(int unit); -static void mcd_configure(struct mcd_data *cd); -static int mcd_get(int unit, char *buf, int nmax); -static void mcd_setflags(int unit,struct mcd_data *cd); -static int mcd_getstat(int unit,int sflg); -static int mcd_send(int unit, int cmd,int nretrys); -static int bcd2bin(bcd_t b); -static bcd_t bin2bcd(int b); -static void hsg2msf(int hsg, bcd_t *msf); -static int msf2hsg(bcd_t *msf); -static int mcd_volinfo(int unit); -static int mcd_waitrdy(int port,int dly); -static void mcd_doread(int state, struct mcd_mbx *mbxin); -#ifndef MCDMINI -static int mcd_setmode(int unit, int mode); -static int mcd_getqchan(int unit, struct mcd_qchninfo *q); -static int mcd_subchan(int unit, struct ioc_read_subchannel *sc); -static int mcd_toc_header(int unit, struct ioc_toc_header *th); -static int mcd_read_toc(int unit); -static int mcd_toc_entry(int unit, struct ioc_read_toc_entry *te); -static int mcd_stop(int unit); -static int mcd_playtracks(int unit, struct ioc_play_track *pt); -static int mcd_play(int unit, struct mcd_read2 *pb); -static int mcd_pause(int unit); -static int mcd_resume(int unit); -#endif +int mcdprobe __P((struct isa_device *)); +int mcdattach __P((struct isa_device *)); +int mcdopen __P((dev_t)); +int mcdclose __P((dev_t)); +int mcd_start __P((struct mcd_softc *)); +int mcdioctl __P((dev_t, int, caddr_t, int, struct proc *)); +int mcd_getdisklabel __P((struct mcd_softc *)); +int mcdsize __P((dev_t)); +void mcd_configure __P((struct mcd_softc *)); +int mcd_waitrdy __P((u_short, int)); +int mcd_getreply __P((struct mcd_softc *, int)); +int mcd_getstat __P((struct mcd_softc *, int)); +void mcd_setflags __P((struct mcd_softc *)); +int mcd_get __P((struct mcd_softc *, char *, int)); +int mcd_send __P((struct mcd_softc *, int, int)); +int bcd2bin __P((bcd_t)); +bcd_t bin2bcd __P((int)); +void hsg2msf __P((int, bcd_t *)); +int msf2hsg __P((bcd_t *)); +int mcd_volinfo __P((struct mcd_softc *)); +int mcdintr __P((int)); +void mcd_doread __P((int, struct mcd_mbx *)); +int mcd_setmode __P((struct mcd_softc *, int)); +int mcd_toc_header __P((struct mcd_softc *, struct ioc_toc_header *)); +int mcd_read_toc __P((struct mcd_softc *)); +int mcd_toc_entry __P((struct mcd_softc *, struct ioc_read_toc_entry *)); +int mcd_stop __P((struct mcd_softc *)); +int mcd_getqchan __P((struct mcd_softc *, struct mcd_qchninfo *)); +int mcd_subchan __P((struct mcd_softc *, struct ioc_read_subchannel *)); +int mcd_playtracks __P((struct mcd_softc *, struct ioc_play_track *)); +int mcd_play __P((struct mcd_softc *, struct mcd_read2 *)); +int mcd_pause __P((struct mcd_softc *)); +int mcd_resume __P((struct mcd_softc *)); -extern int hz; -extern int mcd_probe(struct isa_device *dev); -extern int mcd_attach(struct isa_device *dev); -struct isa_driver mcddriver = { mcd_probe, mcd_attach, "mcd" }; +struct isa_driver mcddriver = { + mcdprobe, mcdattach, "mcd" +}; #define mcd_put(port,byte) outb(port,byte) -#define MCD_RETRYS 5 -#define MCD_RDRETRYS 8 +#define MCD_RETRIES 5 +#define MCD_RDRETRIES 8 #define MCDBLK 2048 /* for cooked mode */ #define MCDRBLK 2352 /* for raw mode */ @@ -199,160 +186,153 @@ struct isa_driver mcddriver = { mcd_probe, mcd_attach, "mcd" }; #define DELAY_STATUS 10000l /* 10000 * 1us */ #define DELAY_GETREPLY 200000l /* 200000 * 2us */ #define DELAY_SEEKREAD 20000l /* 20000 * 1us */ -#define mcd_delay DELAY -int mcd_attach(struct isa_device *dev) +/* reader state machine */ +#define MCD_S_BEGIN 0 +#define MCD_S_BEGIN1 1 +#define MCD_S_WAITSTAT 2 +#define MCD_S_WAITMODE 3 +#define MCD_S_WAITREAD 4 + +int +mcdattach(isa_dev) + struct isa_device *isa_dev; { - struct mcd_data *cd = mcd_data + dev->id_unit; - int i; - - cd->iobase = dev->id_iobase; - cd->flags |= MCDINIT; - cd->openflags = 0; - for (i=0; ipartflags[i] = 0; + struct mcd_softc *sc = &mcd_softc[isa_dev->id_unit]; -#ifdef NOTYET - /* wire controller for interrupts and dma */ +#ifdef notyet + /* Wire controller for interrupts and DMA. */ mcd_configure(cd); #endif - - return 1; + + sc->flags = MCDINIT; } -int mcdopen(dev_t dev) +int +mcdopen(dev) + dev_t dev; { - int unit,part,phys; - struct mcd_data *cd; + int unit, part, phys; + struct mcd_softc *sc; - unit = mcd_unit(dev); + unit = MCDUNIT(dev); if (unit >= NMCD) return ENXIO; + sc = &mcd_softc[unit]; + if (!sc->iobase || !(sc->flags & MCDINIT)) + return ENXIO; - cd = mcd_data + unit; - part = mcd_part(dev); - phys = mcd_phys(dev); + part = MCDPART(dev); + phys = MCDPHYS(dev); - /* not initialized*/ - if (!(cd->flags & MCDINIT)) + /* Invalidated in the meantime? Mark all open part's invalid. */ + if (!(sc->flags & MCDVALID) && sc->openflags) return ENXIO; - /* invalidated in the meantime? mark all open part's invalid */ - if (!(cd->flags & MCDVALID) && cd->openflags) + if (mcd_getstat(sc, 1) < 0) return ENXIO; - if (mcd_getstat(unit,1) < 0) - return ENXIO; - - /* XXX get a default disklabel */ - mcd_getdisklabel(unit); + /* XXX Get a default disklabel. */ + mcd_getdisklabel(sc); if (mcdsize(dev) < 0) { - printf("mcd%d: failed to get disk size\n",unit); + printf("%s: failed to get disk size\n", sc->sc_dev.dv_xname); return ENXIO; } else - cd->flags |= MCDVALID; + sc->flags |= MCDVALID; -MCD_TRACE("open: partition=%d, disksize = %d, blksize=%d\n", - part,cd->disksize,cd->blksize,0); + MCD_TRACE("open: partition=%d disksize=%d blksize=%d\n", part, + sc->disksize, sc->blksize, 0); - if (part == RAW_PART || - (part < cd->dlabel.d_npartitions && - cd->dlabel.d_partitions[part].p_fstype != FS_UNUSED)) { - cd->partflags[part] |= MCDOPEN; - cd->openflags |= (1<partflags[part] |= MCDREADRAW; - return 0; - } - - return ENXIO; + if (part != RAW_PART && + (part >= sc->dlabel.d_npartitions || + sc->dlabel.d_partitions[part].p_fstype == FS_UNUSED)) + return ENXIO; + + sc->partflags[part] |= MCDOPEN; + sc->openflags |= (1 << part); + if (part == RAW_PART && phys != 0) + sc->partflags[part] |= MCDREADRAW; + return 0; } -int mcdclose(dev_t dev) +int +mcdclose(dev) + dev_t dev; { - int unit,part,phys; - struct mcd_data *cd; + int unit, part; + struct mcd_softc *sc; - unit = mcd_unit(dev); - if (unit >= NMCD) - return ENXIO; + unit = MCDUNIT(dev); + part = MCDPART(dev); + sc = &mcd_softc[unit]; - cd = mcd_data + unit; - part = mcd_part(dev); - phys = mcd_phys(dev); - - if (!(cd->flags & MCDINIT)) - return ENXIO; + /* Get status. */ + mcd_getstat(sc, 1); - mcd_getstat(unit,1); /* get status */ - - /* close channel */ - cd->partflags[part] &= ~(MCDOPEN|MCDREADRAW); - cd->openflags &= ~(1<partflags[part] &= ~(MCDOPEN | MCDREADRAW); + sc->openflags &= ~(1 << part); + MCD_TRACE("close: partition=%d\n", part, 0, 0, 0); return 0; } -int mcdstrategy(struct buf *bp) +void +mcdstrategy(bp) + struct buf *bp; { - struct mcd_data *cd; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(bp->b_dev)]; struct buf *qp; int s; - int unit = mcd_unit(bp->b_dev); - - cd = mcd_data + unit; - - /* test validity */ -/*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n", - bp,unit,bp->b_blkno,bp->b_bcount);*/ - if (unit >= NMCD || bp->b_blkno < 0) { - printf("mcdstrategy: unit = %d, blkno = %d, bcount = %d\n", - unit, bp->b_blkno, bp->b_bcount); - pg("mcd: mcdstratregy failure"); + /* Test validity. */ + MCD_TRACE("strategy: buf=0x%lx blkno=%ld bcount=%ld\n", bp, + bp->b_blkno, bp->b_bcount, 0); + if (bp->b_blkno < 0) { + printf("%s: strategy: blkno=%d bcount=%d\n", + sc->sc_dev.dv_xname, bp->b_blkno, bp->b_bcount); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto bad; } - /* if device invalidated (e.g. media change, door open), error */ - if (!(cd->flags & MCDVALID)) { -MCD_TRACE("strategy: drive not valid\n",0,0,0,0); + /* If device invalidated (e.g. media change, door open), error. */ + if (!(sc->flags & MCDVALID)) { + MCD_TRACE("strategy: drive not valid\n", 0, 0, 0, 0); bp->b_error = EIO; goto bad; } - /* read only */ + /* Check for read only. */ if (!(bp->b_flags & B_READ)) { bp->b_error = EROFS; goto bad; } - /* no data to read */ + /* No data to read. */ if (bp->b_bcount == 0) goto done; - /* for non raw access, check partition limits */ - if (mcd_part(bp->b_dev) != RAW_PART) { - if (!(cd->flags & MCDLABEL)) { + /* For non raw access, check partition limits. */ + if (MCDPART(bp->b_dev) != RAW_PART) { + if (!(sc->flags & MCDLABEL)) { bp->b_error = EIO; goto bad; } - /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) { + /* Adjust transfer if necessary. */ + if (bounds_check_with_label(bp, &sc->dlabel, 1) <= 0) goto done; - } } - /* queue it */ - qp = &cd->head; + /* Queue it. */ + qp = &sc->head; s = splbio(); - disksort(qp,bp); + disksort(qp, bp); splx(s); - /* now check whether we can perform processing */ - mcd_start(unit); + /* Now check whether we can perform processing. */ + mcd_start(sc); return; bad: @@ -363,64 +343,61 @@ done: return; } -static void mcd_start(int unit) +int +mcd_start(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - struct buf *bp, *qp = &cd->head; + struct buf *bp, *qp = &sc->head; struct partition *p; - int part; - register s = splbio(); + int s = splbio(); - if (cd->flags & MCDMBXBSY) + if (sc->flags & MCDMBXBSY) return; if ((bp = qp->b_actf) != 0) { - /* block found to process, dequeue */ - /*MCD_TRACE("mcd_start: found block bp=0x%x\n",bp,0,0,0);*/ + /* Block found to process; dequeue. */ + MCD_TRACE("start: found block bp=0x%x\n", bp, 0, 0, 0); qp->b_actf = bp->b_actf; splx(s); } else { - /* nothing to do */ + /* Nothing to do; */ splx(s); return; } - /* changed media? */ - if (!(cd->flags & MCDVALID)) { - MCD_TRACE("mcd_start: drive not valid\n",0,0,0,0); + /* Changed media? */ + if (!(sc->flags & MCDVALID)) { + MCD_TRACE("start: drive not valid\n", 0, 0, 0, 0); return; } - p = cd->dlabel.d_partitions + mcd_part(bp->b_dev); + p = &sc->dlabel.d_partitions[MCDPART(bp->b_dev)]; - cd->flags |= MCDMBXBSY; - cd->mbx.unit = unit; - cd->mbx.port = cd->iobase; - cd->mbx.retry = MCD_RETRYS; - cd->mbx.bp = bp; - cd->mbx.p_offset = p->p_offset; + sc->flags |= MCDMBXBSY; + sc->mbx.unit = sc->sc_dev.dv_unit; + sc->mbx.iobase = sc->iobase; + sc->mbx.retry = MCD_RETRIES; + sc->mbx.bp = bp; + sc->mbx.p_offset = p->p_offset; - /* calling the read routine */ - mcd_doread(MCD_S_BEGIN,&(cd->mbx)); - /* triggers mcd_start, when successful finished */ - return; + /* Calling the read routine. */ + mcd_doread(MCD_S_BEGIN, &sc->mbx); + /* triggers mcd_start, when successful finished. */ } -int mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p) +int +mcdioctl(dev, cmd, addr, flags, p) + dev_t dev; + int cmd; + caddr_t addr; + int flags; + struct proc *p; { - struct mcd_data *cd; - int unit,part; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)]; - unit = mcd_unit(dev); - part = mcd_part(dev); - cd = mcd_data + unit; - -#ifdef MCDMINI - return ENOTTY; -#else - if (!(cd->flags & MCDVALID)) + if (!(sc->flags & MCDVALID)) return EIO; -MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); + MCD_TRACE("ioctl: cmd=0x%x\n", cmd, 0, 0, 0); switch (cmd) { case DIOCSBAD: @@ -432,15 +409,15 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); case DIOCWLABEL: return ENOTTY; case CDIOCPLAYTRACKS: - return mcd_playtracks(unit, (struct ioc_play_track *) addr); + return mcd_playtracks(sc, (struct ioc_play_track *) addr); case CDIOCPLAYBLOCKS: - return mcd_play(unit, (struct mcd_read2 *) addr); + return mcd_play(sc, (struct mcd_read2 *) addr); case CDIOCREADSUBCHANNEL: - return mcd_subchan(unit, (struct ioc_read_subchannel *) addr); + return mcd_subchan(sc, (struct ioc_read_subchannel *) addr); case CDIOREADTOCHEADER: - return mcd_toc_header(unit, (struct ioc_toc_header *) addr); + return mcd_toc_header(sc, (struct ioc_toc_header *) addr); case CDIOREADTOCENTRYS: - return mcd_toc_entry(unit, (struct ioc_read_toc_entry *) addr); + return mcd_toc_entry(sc, (struct ioc_read_toc_entry *) addr); case CDIOCSETPATCH: case CDIOCGETVOL: case CDIOCSETVOL: @@ -451,74 +428,78 @@ MCD_TRACE("ioctl called 0x%x\n",cmd,0,0,0); case CDIOCSETRIGHT: return EINVAL; case CDIOCRESUME: - return mcd_resume(unit); + return mcd_resume(sc); case CDIOCPAUSE: - return mcd_pause(unit); + return mcd_pause(sc); case CDIOCSTART: return EINVAL; case CDIOCSTOP: - return mcd_stop(unit); + return mcd_stop(sc); case CDIOCEJECT: return EINVAL; case CDIOCSETDEBUG: - cd->debug = 1; + sc->debug = 1; return 0; case CDIOCCLRDEBUG: - cd->debug = 0; + sc->debug = 0; return 0; case CDIOCRESET: return EINVAL; default: return ENOTTY; } - /*NOTREACHED*/ -#endif /*!MCDMINI*/ +#ifdef DIAGNOSTIC + panic("mcdioctl: impossible"); +#endif } -/* this could have been taken from scsi/cd.c, but it is not clear - * whether the scsi cd driver is linked in +/* + * This could have been taken from scsi/cd.c, but it is not clear + * whether the scsi cd driver is linked in. */ -static int mcd_getdisklabel(int unit) +int +mcd_getdisklabel(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (cd->flags & MCDLABEL) + if (sc->flags & MCDLABEL) return -1; - bzero(&cd->dlabel,sizeof(struct disklabel)); - strncpy(cd->dlabel.d_typename,"Mitsumi CD ROM ",16); - strncpy(cd->dlabel.d_packname,"unknown ",16); - cd->dlabel.d_secsize = cd->blksize; - cd->dlabel.d_nsectors = 100; - cd->dlabel.d_ntracks = 1; - cd->dlabel.d_ncylinders = (cd->disksize/100)+1; - cd->dlabel.d_secpercyl = 100; - cd->dlabel.d_secperunit = cd->disksize; - cd->dlabel.d_rpm = 300; - cd->dlabel.d_interleave = 1; - cd->dlabel.d_flags = D_REMOVABLE; - cd->dlabel.d_npartitions= 1; - cd->dlabel.d_partitions[0].p_offset = 0; - cd->dlabel.d_partitions[0].p_size = cd->disksize; - cd->dlabel.d_partitions[0].p_fstype = 9; - cd->dlabel.d_magic = DISKMAGIC; - cd->dlabel.d_magic2 = DISKMAGIC; - cd->dlabel.d_checksum = dkcksum(&cd->dlabel); + bzero(&sc->dlabel, sizeof(struct disklabel)); + strncpy(sc->dlabel.d_typename, "Mitsumi CD ROM ", 16); + strncpy(sc->dlabel.d_packname, "unknown ", 16); + sc->dlabel.d_secsize = sc->blksize; + sc->dlabel.d_nsectors = 100; + sc->dlabel.d_ntracks = 1; + sc->dlabel.d_ncylinders = (sc->disksize /100) + 1; + sc->dlabel.d_secpercyl = 100; + sc->dlabel.d_secperunit = sc->disksize; + sc->dlabel.d_rpm = 300; + sc->dlabel.d_interleave = 1; + sc->dlabel.d_flags = D_REMOVABLE; + sc->dlabel.d_npartitions= 1; + sc->dlabel.d_partitions[0].p_offset = 0; + sc->dlabel.d_partitions[0].p_size = sc->disksize; + sc->dlabel.d_partitions[0].p_fstype = 9; + sc->dlabel.d_magic = DISKMAGIC; + sc->dlabel.d_magic2 = DISKMAGIC; + sc->dlabel.d_checksum = dkcksum(&sc->dlabel); - cd->flags |= MCDLABEL; + sc->flags |= MCDLABEL; return 0; } -int mcdsize(dev_t dev) +int +mcdsize(dev) + dev_t dev; { int size; - int unit = mcd_unit(dev); - struct mcd_data *cd = mcd_data + unit; + struct mcd_softc *sc = &mcd_softc[MCDUNIT(dev)]; - if (mcd_volinfo(unit) >= 0) { - cd->blksize = MCDBLK; - size = msf2hsg(cd->volinfo.vol_msf); - cd->disksize = size * (MCDBLK/DEV_BSIZE); + if (mcd_volinfo(sc) >= 0) { + sc->blksize = MCDBLK; + size = msf2hsg(sc->volinfo.vol_msf); + sc->disksize = size * (MCDBLK / DEV_BSIZE); return 0; } return -1; @@ -528,187 +509,199 @@ int mcdsize(dev_t dev) * lower level of driver starts here **************************************************************/ -#ifdef NOTDEF +#ifdef notyet static char irqs[] = { - 0x00,0x00,0x10,0x20,0x00,0x30,0x00,0x00, - 0x00,0x10,0x40,0x50,0x00,0x00,0x00,0x00 + 0x00, 0x00, 0x10, 0x20, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00 }; static char drqs[] = { - 0x00,0x01,0x00,0x03,0x00,0x05,0x06,0x07, + 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x06, 0x07 }; #endif -static void mcd_configure(struct mcd_data *cd) +void +mcd_configure(sc) + struct mcd_softc *sc; { - outb(cd->iobase+mcd_config,cd->config); + + outb(sc->iobase + mcd_config, sc->config); } -/* check if there is a cdrom */ -/* Heavly hacked by gclarkii@sugar.neosoft.com */ - -int mcd_probe(struct isa_device *dev) +int +mcdprobe(isa_dev) + struct isa_device *isa_dev; { - int port = dev->id_iobase; - int unit = dev->id_unit; + int unit = isa_dev->id_unit; + struct mcd_softc *sc = &mcd_softc[unit]; + u_short iobase = isa_dev->id_iobase; int i; - int st; - int check; - int junk; + int st, check; - mcd_data[unit].flags = MCDPROBING; + /* XXX HACK */ + sprintf(sc->sc_dev.dv_xname, "%s%d", mcddriver.name, isa_dev->id_unit); + sc->sc_dev.dv_unit = isa_dev->id_unit; -#ifdef NOTDEF - /* get irq/drq configuration word */ - mcd_data[unit].config = irqs[dev->id_irq]; /* | drqs[dev->id_drq];*/ -#else - mcd_data[unit].config = 0; +#ifdef notyet + /* Get irq/drq configuration word. */ + sc->config = irqs[isa_dev->id_irq]; #endif + sc->iobase = iobase; - /* send a reset */ - outb(port+MCD_FLAGS,0); - DELAY(100000); - /* get any pending status and throw away...*/ - for (i=10; i != 0; i--) { - inb(port+MCD_DATA); - } + /* Send a reset. */ + outb(iobase + mcd_reset, 0); + DELAY(300000); + /* Get any pending status and throw away. */ + for (i = 10; i; i--) + inb(iobase + mcd_status); DELAY(1000); - outb(port+MCD_DATA,MCD_CMDGETSTAT); /* Send get status command */ + /* Send get status command. */ + outb(iobase + mcd_command, MCD_CMDGETSTAT); + i = mcd_getreply(sc, DELAY_GETREPLY); - /* Loop looking for avail of status */ - /* XXX May have to increase for fast machinces */ - for (i = 1000; i != 0; i--) { - if ((inb(port+MCD_FLAGS) & 0xF ) == STATUS_AVAIL) { - break; - } - DELAY(10); - } - /* get status */ - - if (i == 0) { + if (i < 0) { #ifdef DEBUG - printf ("Mitsumi drive NOT detected\n"); + printf("Mitsumi drive NOT detected\n"); #endif - return 0; + return 0; } /* * The following code uses the 0xDC command, it returns a M from the - * second byte and a number in the third. Does anyone know what the - * number is for? Better yet, how about someone thats REAL good in - * i80x86 asm looking at the Dos driver... Most of this info came - * from a friend of mine spending a whole weekend..... + * second byte and a number in the third. + * (I hope you have the right drive for that, most drives don't do!) + * Whole code entirely rewriten by veit@gmd.de, the changes accessed + * the drive in an illegal way. Proper way is to use the timeout + * driven routines mcd_getreply etc. rather than arbitrary delays. */ DELAY (2000); - outb(port+MCD_DATA,MCD_CMDCONTINFO); - for (i = 0; i < 100000; i++) { - if ((inb(port+MCD_FLAGS) & 0xF) == STATUS_AVAIL) - break; - } - if (i > 100000) { -#ifdef DEBUG - printf ("Mitsumi drive error\n"); -#endif - return 0; - } - DELAY (40000); - st = inb(port+MCD_DATA); - DELAY (500); - check = inb(port+MCD_DATA); - DELAY (500); - junk = inb(port+MCD_DATA); /* What is byte used for?!?!? */ + outb(iobase + mcd_command, MCD_CMDCONTINFO); + i = mcd_getreply(sc, DELAY_GETREPLY); - if (check = 'M') { + if (i < 0) { #ifdef DEBUG - printf("Mitsumi drive detected\n"); -#endif - return 4; - } else { - printf("Mitsumi drive NOT detected\n"); printf("Mitsumi drive error\n"); +#endif return 0; } + st = mcd_getreply(sc, DELAY_GETREPLY); + if (st < 0) + return 0; + check = mcd_getreply(sc, DELAY_GETREPLY); + if (check < 0) + return 0; + /* Flush junk. */ + (void) mcd_getreply(sc, DELAY_GETREPLY); + + /* + * The following is code which is not guaranteed to work for all + * drives, because the meaning of the expected 'M' is not clear + * (M_itsumi is an obvious assumption, but I don't trust that). + * Also, the original hack had a bogus condition that always + * returned true. + */ +#ifdef notdef + if (check != 'M') { +#ifdef DEBUG + printf("Mitsumi drive NOT detected\n"); +#endif + return 0; + } +#endif + +#ifdef DEBUG + printf("Mitsumi drive detected\n"); +#endif + return 4; } -static int mcd_waitrdy(int port,int dly) +int +mcd_waitrdy(iobase, dly) + u_short iobase; + int dly; { int i; - /* wait until xfer port senses data ready */ - for (i=0; iiobase; + u_short iobase = sc->iobase; - /* wait data to become ready */ - if (mcd_waitrdy(port,dly)<0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout getreply\n",unit); -#endif + /* Wait data to become ready. */ + if (mcd_waitrdy(iobase, dly) < 0) { + printf("%s: timeout in getreply\n", sc->sc_dev.dv_xname); return -1; } - /* get the data */ - return inb(port+mcd_status) & 0xFF; + /* Get the data. */ + return inb(iobase + mcd_status); } -static int mcd_getstat(int unit,int sflg) +int +mcd_getstat(sc, sflg) + struct mcd_softc *sc; + int sflg; { - int i; - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + int i; + u_short iobase = sc->iobase; - /* get the status */ + /* Get the status. */ if (sflg) - outb(port+mcd_command, MCD_CMDGETSTAT); - i = mcd_getreply(unit,DELAY_GETREPLY); - if (i<0) return -1; - - cd->status = i; - - mcd_setflags(unit,cd); - return cd->status; -} - -static void mcd_setflags(int unit, struct mcd_data *cd) -{ - /* check flags */ - if (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) { - MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n",0,0,0,0); - cd->flags &= ~MCDVALID; + outb(iobase + mcd_command, MCD_CMDGETSTAT); + i = mcd_getreply(sc, DELAY_GETREPLY); + if (i < 0) { + printf("%s: timeout in getstat\n", sc->sc_dev.dv_xname); + return -1; } -#ifndef MCDMINI - if (cd->status & MCDAUDIOBSY) - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; - else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) - cd->audio_status = CD_AS_PLAY_COMPLETED; -#endif + sc->status = i; + + mcd_setflags(sc); + return sc->status; } -static int mcd_get(int unit, char *buf, int nmax) +void +mcd_setflags(sc) + struct mcd_softc *sc; { - int port = mcd_data[unit].iobase; - int i,k; - - for (i=0; istatus & (MCDDSKCHNG | MCDDOOROPEN)) { + MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n", 0, 0, 0, 0); + sc->flags &= ~MCDVALID; + } + + if (sc->status & MCDAUDIOBSY) + sc->audio_status = CD_AS_PLAY_IN_PROGRESS; + else if (sc->audio_status == CD_AS_PLAY_IN_PROGRESS) + sc->audio_status = CD_AS_PLAY_COMPLETED; +} + +int +mcd_get(sc, buf, nmax) + struct mcd_softc *sc; + char *buf; + int nmax; +{ + int i, k; + + for (i = 0; i < nmax; i++) { + /* Wait for data. */ + if ((k = mcd_getreply(sc, DELAY_GETREPLY)) < 0) { + printf("%s: timeout in get\n", sc->sc_dev.dv_xname); return -1; } buf[i] = k; @@ -716,37 +709,53 @@ static int mcd_get(int unit, char *buf, int nmax) return i; } -static int mcd_send(int unit, int cmd,int nretrys) +int +mcd_send(sc, cmd, nretries) + struct mcd_softc *sc; + int cmd, nretries; { - int i,k; - int port = mcd_data[unit].iobase; + int i, k; + u_short iobase = sc->iobase; -/*MCD_TRACE("mcd_send: command = 0x%x\n",cmd,0,0,0);*/ - for (i=0; isc_dev.dv_xname); return -1; } -/*MCD_TRACE("mcd_send: status = 0x%x\n",k,0,0,0);*/ + + MCD_TRACE("send: status=0x%x\n", k, 0, 0, 0); + return 0; } -static int bcd2bin(bcd_t b) +int +bcd2bin(b) + bcd_t b; { + return (b >> 4) * 10 + (b & 15); } -static bcd_t bin2bcd(int b) +bcd_t +bin2bcd(b) + int b; { + return ((b / 10) << 4) | (b % 10); } -static void hsg2msf(int hsg, bcd_t *msf) +void +hsg2msf(hsg, msf) + int hsg; + bcd_t *msf; { + hsg += 150; M_msf(msf) = bin2bcd(hsg / 4500); hsg %= 4500; @@ -754,76 +763,88 @@ static void hsg2msf(int hsg, bcd_t *msf) F_msf(msf) = bin2bcd(hsg % 75); } -static int msf2hsg(bcd_t *msf) +int +msf2hsg(msf) + bcd_t *msf; { + return (bcd2bin(M_msf(msf)) * 60 + bcd2bin(S_msf(msf))) * 75 + bcd2bin(F_msf(msf)) - 150; } -static int mcd_volinfo(int unit) +int +mcd_volinfo(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - int i; -/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/ + MCD_TRACE("volinfo: enter\n", 0, 0, 0, 0); - /* Get the status, in case the disc has been changed */ - if (mcd_getstat(unit, 1) < 0) return EIO; + /* Get the status, in case the disc has been changed. */ + if (mcd_getstat(sc, 1) < 0) + return EIO; - /* Just return if we already have it */ - if (cd->flags & MCDVOLINFO) return 0; + /* Just return if we already have it. */ + if (sc->flags & MCDVOLINFO) + return 0; - /* send volume info command */ - if (mcd_send(unit,MCD_CMDGETVOLINFO,MCD_RETRYS) < 0) + /* Send volume info command. */ + if (mcd_send(sc, MCD_CMDGETVOLINFO, MCD_RETRIES) < 0) return -1; - /* get data */ - if (mcd_get(unit,(char*) &cd->volinfo,sizeof(struct mcd_volinfo)) < 0) { - printf("mcd%d: mcd_volinfo: error read data\n",unit); + /* Get the data. */ + if (mcd_get(sc, (char*) &sc->volinfo, sizeof(struct mcd_volinfo)) < 0) { + printf("%s: volinfo: error reading data\n", + sc->sc_dev.dv_xname); return -1; } - if (cd->volinfo.trk_low != 0 || cd->volinfo.trk_high != 0) { - cd->flags |= MCDVOLINFO; /* volinfo is OK */ + if (sc->volinfo.trk_low != 0 || sc->volinfo.trk_high != 0) { + /* Volinfo is OK. */ + sc->flags |= MCDVOLINFO; return 0; } return -1; } -int mcdintr(unit) +int +mcdintr(unit) + int unit; { - int port = mcd_data[unit].iobase; - u_int i; + struct mcd_softc *sc = &mcd_softc[unit]; + u_short iobase = sc->iobase; - MCD_TRACE("stray interrupt xfer=0x%x\n",inb(port+mcd_xfer),0,0,0); + MCD_TRACE("stray interrupt xfer=0x%x\n", inb(iobase + mcd_xfer), + 0, 0, 0); - /* just read out status and ignore the rest */ - if ((inb(port+mcd_xfer)&0xFF) != 0xFF) { - i = inb(port+mcd_status); - } + /* Just read out status and ignore the rest. */ + if (inb(iobase + mcd_xfer) != 0xff) + (void) inb(iobase + mcd_status); } -/* state machine to process read requests - * initialize with MCD_S_BEGIN: calculate sizes, and read status +/* + * State machine to process read requests. + * Initialize with MCD_S_BEGIN: calculate sizes, and read status * MCD_S_WAITSTAT: wait for status reply, set mode * MCD_S_WAITMODE: waits for status reply from set mode, set read command - * MCD_S_WAITREAD: wait for read ready, read data + * MCD_S_WAITREAD: wait for read ready, read data. */ -static struct mcd_mbx *mbxsave; +struct mcd_mbx *mbxsave; -static void mcd_doread(int state, struct mcd_mbx *mbxin) +void +mcd_doread(state, mbxin) + int state; + struct mcd_mbx *mbxin; { - struct mcd_mbx *mbx = (state!=MCD_S_BEGIN) ? mbxsave : mbxin; - int unit = mbx->unit; - int port = mbx->port; - struct buf *bp = mbx->bp; - struct mcd_data *cd = mcd_data + unit; + struct mcd_mbx *mbx = (state != MCD_S_BEGIN) ? mbxsave : mbxin; + struct mcd_softc *sc = &mcd_softc[mbx->unit]; + u_short iobase = mbx->iobase; + struct buf *bp = mbx->bp; - int rm,i,k; + int rm, i, k; struct mcd_read2 rbuf; - int blknum; + int blkno; caddr_t addr; loop: @@ -832,438 +853,467 @@ loop: mbx = mbxsave = mbxin; case MCD_S_BEGIN1: - /* get status */ - outb(port+mcd_command, MCD_CMDGETSTAT); + /* Get status. */ + outb(iobase + mcd_command, MCD_CMDGETSTAT); mbx->count = RDELAY_WAITSTAT; - timeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITSTAT,hz/100); + timeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITSTAT, + hz/100); return; + case MCD_S_WAITSTAT: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITSTAT); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITSTAT); if (mbx->count-- >= 0) { - if (inb(port+mcd_xfer) & MCD_ST_BUSY) { + if (inb(iobase + mcd_xfer) & MCD_ST_BUSY) { timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITSTAT,hz/100); + (caddr_t) MCD_S_WAITSTAT, hz/100); return; } - mcd_setflags(unit,cd); - MCD_TRACE("got WAITSTAT delay=%d\n",RDELAY_WAITSTAT-mbx->count,0,0,0); - /* reject, if audio active */ - if (cd->status & MCDAUDIOBSY) { - printf("mcd%d: audio is active\n",unit); + mcd_setflags(sc); + MCD_TRACE("doread: got WAITSTAT delay=%d\n", + RDELAY_WAITSTAT - mbx->count, 0, 0, 0); + /* Reject, if audio active. */ + if (sc->status & MCDAUDIOBSY) { + printf("%s: audio is active\n", + sc->sc_dev.dv_xname); goto readerr; } - /* to check for raw/cooked mode */ - if (cd->flags & MCDREADRAW) { + /* Check for raw/cooked mode. */ + if (sc->flags & MCDREADRAW) { rm = MCD_MD_RAW; mbx->sz = MCDRBLK; } else { rm = MCD_MD_COOKED; - mbx->sz = cd->blksize; + mbx->sz = sc->blksize; } mbx->count = RDELAY_WAITMODE; - mcd_put(port+mcd_command, MCD_CMDSETMODE); - mcd_put(port+mcd_command, rm); + mcd_put(iobase + mcd_command, MCD_CMDSETMODE); + mcd_put(iobase + mcd_command, rm); timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITMODE,hz/100); + (caddr_t) MCD_S_WAITMODE, hz/100); return; } else { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout getstatus\n",unit); -#endif + printf("%s: timeout getting status\n", + sc->sc_dev.dv_xname); goto readerr; } case MCD_S_WAITMODE: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITMODE); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITMODE); if (mbx->count-- < 0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout set mode\n",unit); -#endif + printf("%s: timeout setting mode\n", + sc->sc_dev.dv_xname); goto readerr; } - if (inb(port+mcd_xfer) & MCD_ST_BUSY) { + if (inb(iobase + mcd_xfer) & MCD_ST_BUSY) { timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITMODE,hz/100); + (caddr_t) MCD_S_WAITMODE, hz/100); return; } - mcd_setflags(unit,cd); - MCD_TRACE("got WAITMODE delay=%d\n",RDELAY_WAITMODE-mbx->count,0,0,0); - /* for first block */ - mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; + mcd_setflags(sc); + MCD_TRACE("doread: got WAITMODE delay=%d\n", + RDELAY_WAITMODE - mbx->count, 0, 0, 0); + /* For first block. */ + mbx->nblk = (bp->b_bcount + (mbx->sz - 1)) / mbx->sz; mbx->skip = 0; nextblock: - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) - + mbx->p_offset + mbx->skip/mbx->sz; + blkno = (bp->b_blkno / (mbx->sz / DEV_BSIZE)) + mbx->p_offset + + (mbx->skip / mbx->sz); - MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n",blknum,bp,0,0); + MCD_TRACE("doread: read blkno=%d for bp=0x%x\n", blkno, bp, 0, + 0); - /* build parameter block */ - hsg2msf(blknum,rbuf.start_msf); + /* Build parameter block. */ + hsg2msf(blkno, rbuf.start_msf); - /* send the read command */ - mcd_put(port+mcd_command,MCD_CMDREAD2); - mcd_put(port+mcd_command,rbuf.start_msf[0]); - mcd_put(port+mcd_command,rbuf.start_msf[1]); - mcd_put(port+mcd_command,rbuf.start_msf[2]); - mcd_put(port+mcd_command,0); - mcd_put(port+mcd_command,0); - mcd_put(port+mcd_command,1); + /* Send the read command. */ + mcd_put(iobase + mcd_command, MCD_CMDREAD2); + mcd_put(iobase + mcd_command, rbuf.start_msf[0]); + mcd_put(iobase + mcd_command, rbuf.start_msf[1]); + mcd_put(iobase + mcd_command, rbuf.start_msf[2]); + mcd_put(iobase + mcd_command, 0); + mcd_put(iobase + mcd_command, 0); + mcd_put(iobase + mcd_command, 1); mbx->count = RDELAY_WAITREAD; - timeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITREAD,hz/100); + timeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITREAD, + hz/100); return; + case MCD_S_WAITREAD: - untimeout((timeout_t) mcd_doread,(caddr_t) MCD_S_WAITREAD); + untimeout((timeout_t) mcd_doread, (caddr_t) MCD_S_WAITREAD); if (mbx->count-- > 0) { - k = inb(port+mcd_xfer); - if ((k & 2)==0) { - MCD_TRACE("got data delay=%d\n",RDELAY_WAITREAD-mbx->count,0,0,0); - /* data is ready */ - addr = bp->b_un.b_addr + mbx->skip; - outb(port+mcd_ctl2,0x04); /* XXX */ - for (i=0; isz; i++) - *addr++ = inb(port+mcd_rdata); - outb(port+mcd_ctl2,0x0c); /* XXX */ + k = inb(iobase + mcd_xfer); + if ((k & 2) == 0) { /* XXX MCD_ST_AUDIOBSY? */ + MCD_TRACE("doread: got data delay=%d\n", + RDELAY_WAITREAD - mbx->count, 0, 0, 0); + /* Data is ready. */ + addr = bp->b_un.b_addr + mbx->skip; + outb(iobase + mcd_ctl2, 0x04); /* XXX */ + for (i = 0; i < mbx->sz; i++) + *addr++ = inb(iobase + mcd_rdata); + outb(iobase + mcd_ctl2, 0x0c); /* XXX */ if (--mbx->nblk > 0) { mbx->skip += mbx->sz; goto nextblock; } - /* return buffer */ + /* Return buffer. */ bp->b_resid = 0; biodone(bp); - cd->flags &= ~MCDMBXBSY; - mcd_start(mbx->unit); + sc->flags &= ~MCDMBXBSY; + mcd_start(sc); return; } - if ((k & 4)==0) - mcd_getstat(unit,0); + if ((k & MCD_ST_BUSY) == 0) + mcd_getstat(sc, 0); timeout((timeout_t) mcd_doread, - (caddr_t) MCD_S_WAITREAD,hz/100); + (caddr_t) MCD_S_WAITREAD, hz/100); return; } else { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: timeout read data\n",unit); -#endif + printf("%s: timeout reading data\n", + sc->sc_dev.dv_xname); goto readerr; } } readerr: if (mbx->retry-- > 0) { -#ifdef MCD_TO_WARNING_ON - printf("mcd%d: retrying\n",unit); -#endif + printf("%s: retrying\n", sc->sc_dev.dv_xname); state = MCD_S_BEGIN1; goto loop; } - /* invalidate the buffer */ + /* Invalidate the buffer. */ bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; biodone(bp); - mcd_start(mbx->unit); - return; + mcd_start(sc); -#ifdef NOTDEF - printf("mcd%d: unit timeout, resetting\n",mbx->unit); - outb(mbx->port+mcd_reset,MCD_CMDRESET); +#ifdef notyet + printf("%s: unit timeout; resetting\n", sc->sc_dev.dv_xname); + outb(mbx->iobase + mcd_reset, MCD_CMDRESET); DELAY(300000); - (void)mcd_getstat(mbx->unit,1); - (void)mcd_getstat(mbx->unit,1); - /*cd->status &= ~MCDDSKCHNG; */ - cd->debug = 1; /* preventive set debug mode */ - + (void)mcd_getstat(sc, 1); + (void)mcd_getstat(sc, 1); + /*sc->status &= ~MCDDSKCHNG; */ + sc->debug = 1; /* preventive set debug mode */ #endif - } -#ifndef MCDMINI -static int mcd_setmode(int unit, int mode) +int +mcd_setmode(sc, mode) + struct mcd_softc *sc; + int mode; { - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + u_short iobase = sc->iobase; int retry; - printf("mcd%d: setting mode to %d\n", unit, mode); - for(retry=0; retrysc_dev.dv_xname, mode); + for (retry = MCD_RETRIES; retry; retry--) { + outb(iobase + mcd_command, MCD_CMDSETMODE); + outb(iobase + mcd_command, mode); + if (mcd_getstat(sc, 0) != -1) + return 0; } return -1; } -static int mcd_toc_header(int unit, struct ioc_toc_header *th) +int +mcd_toc_header(sc, th) + struct mcd_softc *sc; + struct ioc_toc_header *th; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_volinfo(unit) < 0) + if (mcd_volinfo(sc) < 0) return ENXIO; - th->len = msf2hsg(cd->volinfo.vol_msf); - th->starting_track = bcd2bin(cd->volinfo.trk_low); - th->ending_track = bcd2bin(cd->volinfo.trk_high); + th->len = msf2hsg(sc->volinfo.vol_msf); + th->starting_track = bcd2bin(sc->volinfo.trk_low); + th->ending_track = bcd2bin(sc->volinfo.trk_high); return 0; } -static int mcd_read_toc(int unit) +int +mcd_read_toc(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; struct ioc_toc_header th; struct mcd_qchninfo q; int rc, trk, idx, retry; - /* Only read TOC if needed */ - if (cd->flags & MCDTOC) return 0; + /* Only read TOC if needed. */ + if (sc->flags & MCDTOC) + return 0; - printf("mcd%d: reading toc header\n", unit); - if (mcd_toc_header(unit, &th) != 0) + if (sc->debug) + printf("%s: read_toc: reading toc header\n", + sc->sc_dev.dv_xname); + if (mcd_toc_header(sc, &th) != 0) return ENXIO; - printf("mcd%d: stopping play\n", unit); - if ((rc=mcd_stop(unit)) != 0) + if (sc->debug) + printf("%s: read_toc: stopping play\n", sc->sc_dev.dv_xname); + if ((rc = mcd_stop(sc)) != 0) return rc; - /* try setting the mode twice */ - if (mcd_setmode(unit, MCD_MD_TOC) != 0) + /* Try setting the mode twice. */ + if (mcd_setmode(sc, MCD_MD_TOC) != 0) return EIO; - if (mcd_setmode(unit, MCD_MD_TOC) != 0) + if (mcd_setmode(sc, MCD_MD_TOC) != 0) return EIO; - printf("mcd%d: get_toc reading qchannel info\n",unit); - for(trk=th.starting_track; trk<=th.ending_track; trk++) - cd->toc[trk].idx_no = 0; + if (sc->debug) + printf("%s: read_toc: reading qchannel info\n", + sc->sc_dev.dv_xname); + for (trk = th.starting_track; trk <= th.ending_track; trk++) + sc->toc[trk].idx_no = 0; trk = th.ending_track - th.starting_track + 1; - for(retry=0; retry<300 && trk>0; retry++) - { - if (mcd_getqchan(unit, &q) < 0) break; + for (retry = 300; retry && trk > 0; retry--) { + if (mcd_getqchan(sc, &q) < 0) + break; idx = bcd2bin(q.idx_no); - if (idx>0 && idx < MCD_MAXTOCS && q.trk_no==0) - if (cd->toc[idx].idx_no == 0) - { - cd->toc[idx] = q; - trk--; - } + if (idx > 0 && idx < MCD_MAXTOCS && q.trk_no == 0 && + sc->toc[idx].idx_no == 0) { + sc->toc[idx] = q; + trk--; + } } - if (mcd_setmode(unit, MCD_MD_COOKED) != 0) + if (mcd_setmode(sc, MCD_MD_COOKED) != 0) return EIO; - if (trk != 0) return ENXIO; + if (trk != 0) + return ENXIO; - /* add a fake last+1 */ + /* Add a fake last+1. */ idx = th.ending_track + 1; - cd->toc[idx].ctrl_adr = cd->toc[idx-1].ctrl_adr; - cd->toc[idx].trk_no = 0; - cd->toc[idx].idx_no = 0xAA; - cd->toc[idx].hd_pos_msf[0] = cd->volinfo.vol_msf[0]; - cd->toc[idx].hd_pos_msf[1] = cd->volinfo.vol_msf[1]; - cd->toc[idx].hd_pos_msf[2] = cd->volinfo.vol_msf[2]; + sc->toc[idx].ctrl_adr = sc->toc[idx-1].ctrl_adr; + sc->toc[idx].trk_no = 0; + sc->toc[idx].idx_no = 0xaa; + sc->toc[idx].hd_pos_msf[0] = sc->volinfo.vol_msf[0]; + sc->toc[idx].hd_pos_msf[1] = sc->volinfo.vol_msf[1]; + sc->toc[idx].hd_pos_msf[2] = sc->volinfo.vol_msf[2]; - cd->flags |= MCDTOC; + sc->flags |= MCDTOC; return 0; } -static int mcd_toc_entry(int unit, struct ioc_read_toc_entry *te) +int +mcd_toc_entry(sc, te) + struct mcd_softc *sc; + struct ioc_read_toc_entry *te; { - struct mcd_data *cd = mcd_data + unit; - struct ret_toc - { + struct ret_toc { struct ioc_toc_header th; struct cd_toc_entry rt; } ret_toc; struct ioc_toc_header th; int rc, i; - /* Make sure we have a valid toc */ - if ((rc=mcd_read_toc(unit)) != 0) + /* Make sure we have a valid TOC. */ + if ((rc = mcd_read_toc(sc)) != 0) return rc; - /* find the toc to copy*/ + /* Find the TOC to copy. */ i = te->starting_track; if (i == MCD_LASTPLUS1) - i = bcd2bin(cd->volinfo.trk_high) + 1; + i = bcd2bin(sc->volinfo.trk_high) + 1; - /* verify starting track */ - if (i < bcd2bin(cd->volinfo.trk_low) || - i > bcd2bin(cd->volinfo.trk_high)+1) + /* Verify starting track. */ + if (i < bcd2bin(sc->volinfo.trk_low) || + i > bcd2bin(sc->volinfo.trk_high) + 1) return EINVAL; - /* do we have room */ + /* Do we have room? */ if (te->data_len < sizeof(struct ioc_toc_header) + - sizeof(struct cd_toc_entry)) return EINVAL; + sizeof(struct cd_toc_entry)) + return EINVAL; - /* Copy the toc header */ - if (mcd_toc_header(unit, &th) < 0) return EIO; + /* Copy the TOC header. */ + if (mcd_toc_header(sc, &th) < 0) + return EIO; ret_toc.th = th; - /* copy the toc data */ - ret_toc.rt.control = cd->toc[i].ctrl_adr; + /* Copy the TOC data. */ + ret_toc.rt.control = sc->toc[i].ctrl_adr; ret_toc.rt.addr_type = te->address_format; ret_toc.rt.track = i; - if (te->address_format == CD_MSF_FORMAT) - { - ret_toc.rt.addr[1] = cd->toc[i].hd_pos_msf[0]; - ret_toc.rt.addr[2] = cd->toc[i].hd_pos_msf[1]; - ret_toc.rt.addr[3] = cd->toc[i].hd_pos_msf[2]; + if (te->address_format == CD_MSF_FORMAT) { + ret_toc.rt.addr[1] = sc->toc[i].hd_pos_msf[0]; + ret_toc.rt.addr[2] = sc->toc[i].hd_pos_msf[1]; + ret_toc.rt.addr[3] = sc->toc[i].hd_pos_msf[2]; } - /* copy the data back */ - copyout(&ret_toc, te->data, sizeof(struct cd_toc_entry) - + sizeof(struct ioc_toc_header)); + /* Copy the data back. */ + copyout(&ret_toc, te->data, + sizeof(struct cd_toc_entry) + sizeof(struct ioc_toc_header)); return 0; } -static int mcd_stop(int unit) +int +mcd_stop(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) + if (mcd_send(sc, MCD_CMDSTOPAUDIO, MCD_RETRIES) < 0) return ENXIO; - cd->audio_status = CD_AS_PLAY_COMPLETED; + sc->audio_status = CD_AS_PLAY_COMPLETED; return 0; } -static int mcd_getqchan(int unit, struct mcd_qchninfo *q) +int +mcd_getqchan(sc, q) + struct mcd_softc *sc; + struct mcd_qchninfo *q; { - struct mcd_data *cd = mcd_data + unit; - if (mcd_send(unit, MCD_CMDGETQCHN, MCD_RETRYS) < 0) + if (mcd_send(sc, MCD_CMDGETQCHN, MCD_RETRIES) < 0) return -1; - if (mcd_get(unit, (char *) q, sizeof(struct mcd_qchninfo)) < 0) + if (mcd_get(sc, (char *) q, sizeof(struct mcd_qchninfo)) < 0) return -1; - if (cd->debug) - printf("mcd%d: qchannel ctl=%d, t=%d, i=%d, ttm=%d:%d.%d dtm=%d:%d.%d\n", - unit, - q->ctrl_adr, q->trk_no, q->idx_no, - q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], - q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); + if (sc->debug) + printf("%s: getqchan: ctl=%d t=%d i=%d ttm=%d:%d.%d dtm=%d:%d.%d\n", + sc->sc_dev.dv_xname, q->ctrl_adr, q->trk_no, q->idx_no, + q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], + q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); return 0; } -static int mcd_subchan(int unit, struct ioc_read_subchannel *sc) +int +mcd_subchan(sc, ch) + struct mcd_softc *sc; + struct ioc_read_subchannel *ch; { - struct mcd_data *cd = mcd_data + unit; struct mcd_qchninfo q; struct cd_sub_channel_info data; - printf("mcd%d: subchan af=%d, df=%d\n", unit, - sc->address_format, - sc->data_format); - if (sc->address_format != CD_MSF_FORMAT) return EIO; - if (sc->data_format != CD_CURRENT_POSITION) return EIO; + if (sc->debug) + printf("%s: subchan: af=%d df=%d\n", sc->sc_dev.dv_xname, + ch->address_format, ch->data_format); - if (mcd_getqchan(unit, &q) < 0) return EIO; + if (ch->address_format != CD_MSF_FORMAT) + return EIO; + if (ch->data_format != CD_CURRENT_POSITION) + return EIO; + if (mcd_getqchan(sc, &q) < 0) + return EIO; - data.header.audio_status = cd->audio_status; + data.header.audio_status = sc->audio_status; data.what.position.data_format = CD_MSF_FORMAT; data.what.position.track_number = bcd2bin(q.trk_no); - if (copyout(&data, sc->data, sizeof(struct cd_sub_channel_info))!=0) + if (copyout(&data, ch->data, sizeof(struct cd_sub_channel_info)) != 0) return EFAULT; return 0; } -static int mcd_playtracks(int unit, struct ioc_play_track *pt) +int +mcd_playtracks(sc, pt) + struct mcd_softc *sc; + struct ioc_play_track *pt; { - struct mcd_data *cd = mcd_data + unit; struct mcd_read2 pb; int a = pt->start_track; int z = pt->end_track; int rc; - if ((rc = mcd_read_toc(unit)) != 0) return rc; + if ((rc = mcd_read_toc(sc)) != 0) + return rc; - printf("mcd%d: playtracks from %d:%d to %d:%d\n", unit, - a, pt->start_index, z, pt->end_index); + printf("%s: playtracks: from %d:%d to %d:%d\n", sc->sc_dev.dv_xname, + a, pt->start_index, z, pt->end_index); - if (a < cd->volinfo.trk_low || a > cd->volinfo.trk_high || a > z || - z < cd->volinfo.trk_low || z > cd->volinfo.trk_high) + if (a < sc->volinfo.trk_low || a > sc->volinfo.trk_high || a > z || + z < sc->volinfo.trk_low || z > sc->volinfo.trk_high) return EINVAL; - pb.start_msf[0] = cd->toc[a].hd_pos_msf[0]; - pb.start_msf[1] = cd->toc[a].hd_pos_msf[1]; - pb.start_msf[2] = cd->toc[a].hd_pos_msf[2]; - pb.end_msf[0] = cd->toc[z+1].hd_pos_msf[0]; - pb.end_msf[1] = cd->toc[z+1].hd_pos_msf[1]; - pb.end_msf[2] = cd->toc[z+1].hd_pos_msf[2]; + pb.start_msf[0] = sc->toc[a].hd_pos_msf[0]; + pb.start_msf[1] = sc->toc[a].hd_pos_msf[1]; + pb.start_msf[2] = sc->toc[a].hd_pos_msf[2]; + pb.end_msf[0] = sc->toc[z+1].hd_pos_msf[0]; + pb.end_msf[1] = sc->toc[z+1].hd_pos_msf[1]; + pb.end_msf[2] = sc->toc[z+1].hd_pos_msf[2]; - return mcd_play(unit, &pb); + return mcd_play(sc, &pb); } -static int mcd_play(int unit, struct mcd_read2 *pb) +int +mcd_play(sc, pb) + struct mcd_softc *sc; + struct mcd_read2 *pb; { - struct mcd_data *cd = mcd_data + unit; - int port = cd->iobase; + u_short iobase = sc->iobase; int retry, st; - cd->lastpb = *pb; - for(retry=0; retrystart_msf[0]); - outb(port+mcd_command, pb->start_msf[1]); - outb(port+mcd_command, pb->start_msf[2]); - outb(port+mcd_command, pb->end_msf[0]); - outb(port+mcd_command, pb->end_msf[1]); - outb(port+mcd_command, pb->end_msf[2]); - if ((st=mcd_getstat(unit, 0)) != -1) break; + sc->lastpb = *pb; + for (retry = MCD_RETRIES; retry; retry--) { + outb(iobase + mcd_command, MCD_CMDREAD2); + outb(iobase + mcd_command, pb->start_msf[0]); + outb(iobase + mcd_command, pb->start_msf[1]); + outb(iobase + mcd_command, pb->start_msf[2]); + outb(iobase + mcd_command, pb->end_msf[0]); + outb(iobase + mcd_command, pb->end_msf[1]); + outb(iobase + mcd_command, pb->end_msf[2]); + if ((st = mcd_getstat(sc, 0)) != -1) + break; } + if (sc->debug) + printf("%s: play: retry=%d status=%d\n", sc->sc_dev.dv_xname, + retry, st); + if (!retry) + return ENXIO; - if (cd->debug) - printf("mcd%d: mcd_play retry=%d, status=%d\n", unit, retry, st); - if (st == -1) return ENXIO; - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; + sc->audio_status = CD_AS_PLAY_IN_PROGRESS; return 0; } -static int mcd_pause(int unit) +int +mcd_pause(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; struct mcd_qchninfo q; int rc; - /* Verify current status */ - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) - { - printf("mcd%d: pause attempted when not playing\n", unit); + /* Verify current status. */ + if (sc->audio_status != CD_AS_PLAY_IN_PROGRESS) { + printf("%s: pause: attempted when not playing\n", + sc->sc_dev.dv_xname); return EINVAL; } - /* Get the current position */ - if (mcd_getqchan(unit, &q) < 0) return EIO; + /* Get the current position. */ + if (mcd_getqchan(sc, &q) < 0) + return EIO; - /* Copy it into lastpb */ - cd->lastpb.start_msf[0] = q.hd_pos_msf[0]; - cd->lastpb.start_msf[1] = q.hd_pos_msf[1]; - cd->lastpb.start_msf[2] = q.hd_pos_msf[2]; + /* Copy it into lastpb. */ + sc->lastpb.start_msf[0] = q.hd_pos_msf[0]; + sc->lastpb.start_msf[1] = q.hd_pos_msf[1]; + sc->lastpb.start_msf[2] = q.hd_pos_msf[2]; - /* Stop playing */ - if ((rc=mcd_stop(unit)) != 0) return rc; + /* Stop playing. */ + if ((rc = mcd_stop(sc)) != 0) + return rc; - /* Set the proper status and exit */ - cd->audio_status = CD_AS_PLAY_PAUSED; + /* Set the proper status and exit. */ + sc->audio_status = CD_AS_PLAY_PAUSED; return 0; } -static int mcd_resume(int unit) +int +mcd_resume(sc) + struct mcd_softc *sc; { - struct mcd_data *cd = mcd_data + unit; - if (cd->audio_status != CD_AS_PLAY_PAUSED) return EINVAL; - return mcd_play(unit, &cd->lastpb); + if (sc->audio_status != CD_AS_PLAY_PAUSED) + return EINVAL; + return mcd_play(sc, &sc->lastpb); } -#endif /*!MCDMINI*/ - -#endif /* NMCD > 0 */ diff --git a/sys/dev/isa/mcdreg.h b/sys/dev/isa/mcdreg.h index 6bc603fac31e..70912393e62b 100644 --- a/sys/dev/isa/mcdreg.h +++ b/sys/dev/isa/mcdreg.h @@ -41,12 +41,9 @@ * the manufacturer or anyone else might provide better documentation, * so this file (and the driver) will then have a better quality. * - * $Id: mcdreg.h,v 1.2 1993/11/17 12:22:57 cgd Exp $ + * $Id: mcdreg.h,v 1.3 1994/02/21 15:23:12 mycroft Exp $ */ -#ifndef MCD_H -#define MCD_H - #ifdef __GNUC__ #if __GNUC__ >= 2 #pragma pack(1) @@ -77,15 +74,6 @@ typedef unsigned char bcd_t; /* 011 = int 5 */ /* 100 = int 10 */ /* 101 = int 11 */ -/* flags */ -#define STATUS_AVAIL 0xb -#define DATA_AVAIL 0xf - -/* ports */ -#define MCD_DATA 0 -#define MCD_FLAGS 1 -#define MCD_DONT_KNOW 2 /* What are these two ports for??? */ -#define CHANNEL 3 /* Status bits */ #define MCD_ST_DOOROPEN 0x80 @@ -148,4 +136,3 @@ struct mcd_read2 { bcd_t start_msf[3]; bcd_t end_msf[3]; }; -#endif /* MCD_H */