diff options
Diffstat (limited to 'sys/scsi/cd.c')
-rw-r--r-- | sys/scsi/cd.c | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 628845d..030a192 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -14,7 +14,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 * - * $Id: cd.c,v 1.6 93/08/26 21:09:07 julian Exp Locker: julian $ + * $Id: cd.c,v 1.6 1993/08/28 03:08:49 rgrimes Exp $ */ #define SPLCD splbio @@ -94,7 +94,7 @@ struct cd_data int partflags[MAXPARTITIONS]; /* per partition flags */ #define CDOPEN 0x01 int openparts; /* one bit for each open partition */ -}cd_data[NCD]; +}*cd_data[NCD]; #define CD_STOP 0 #define CD_START 1 @@ -114,18 +114,31 @@ struct scsi_switch *scsi_switch; struct cd_data *cd; struct cd_parms *dp; - unit = next_cd_unit++; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("cdattach: "); +#endif /*CDDEBUG*/ /*******************************************************\ * Check we have the resources for another drive * \*******************************************************/ + unit = next_cd_unit++; if( unit >= NCD) { printf("Too many scsi CDs..(%d > %d) reconfigure kernel\n", (unit + 1),NCD); return(0); } - cd = cd_data + unit; + cd = cd_data[unit]; + if(cd_data[unit]) + { + printf("cd%d: Already has storage!\n",unit); + return(0); + } + cd = cd_data[unit] = malloc(sizeof(struct cd_data),M_DEVBUF,M_NOWAIT); + if(!cd) + { + printf("cd%d: malloc failed in cd.c\n",unit); + return(0); + } dp = &(cd->params); /*******************************************************\ * Store information needed to contact our base driver * @@ -136,7 +149,6 @@ struct scsi_switch *scsi_switch; cd->lu = lu; cd->cmdscount = CDOUTSTANDING; /* XXX (ask the board) */ - i = cd->cmdscount; while(i-- ) { @@ -173,14 +185,16 @@ cdopen(dev) int errcode = 0; int unit, part; struct cd_parms cd_parms; - struct cd_data *cd ; + struct cd_data *cd; unit = UNIT(dev); part = PARTITION(dev); - cd = cd_data + unit; + +#ifdef CDDEBUG if(scsi_debug & (PRINTROUTINES | TRACEOPENS)) printf("cdopen: dev=0x%x (unit %d (of %d),partition %d)\n" , dev, unit, NCD, part); +#endif /*CDDEBUG*/ /*******************************************************\ * Check the unit is legal * \*******************************************************/ @@ -188,12 +202,11 @@ cdopen(dev) { return(ENXIO); } + cd = cd_data[unit]; /*******************************************************\ - * Make sure the disk has been initialised * - * At some point in the future, get the scsi driver * - * to look for a new device if we are not initted * + * Make sure the device has been initialised * \*******************************************************/ - if (! (cd->flags & CDINIT)) + if ((cd == NULL) || (!(cd->flags & CDINIT))) return(ENXIO); /*******************************************************\ @@ -211,41 +224,53 @@ cdopen(dev) * disregard because the CDVALID flag is not yet set * \*******************************************************/ if (cd_req_sense(unit, SCSI_SILENT) != 0) { +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("not reponding\n"); +#endif /*CDDEBUG*/ return(ENXIO); } +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("Device present\n"); +#endif /*CDDEBUG*/ /*******************************************************\ * In case it is a funny one, tell it to start * * not needed for hard drives * \*******************************************************/ cd_start_unit(unit,part,CD_START); cd_prevent_unit(unit,PR_PREVENT,SCSI_SILENT); +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("started "); +#endif /*CDDEBUG*/ /*******************************************************\ * Load the physical device parameters * \*******************************************************/ cd_get_parms(unit, 0); +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("Params loaded "); +#endif /*CDDEBUG*/ /*******************************************************\ * Load the partition info if not already loaded * \*******************************************************/ cdgetdisklabel(unit); +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("Disklabel fabricated "); +#endif /*CDDEBUG*/ /*******************************************************\ * Check the partition is legal * \*******************************************************/ if (( part >= cd->disklabel.d_npartitions ) && (part != RAW_PART)) { +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("partition %d > %d\n",part ,cd->disklabel.d_npartitions); +#endif /*CDDEBUG*/ cd_prevent_unit(unit,PR_ALLOW,SCSI_SILENT); return(ENXIO); } @@ -257,14 +282,18 @@ cdopen(dev) { cd->partflags[part] |= CDOPEN; cd->openparts |= (1 << part); +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("open complete\n"); +#endif /*CDDEBUG*/ cd->flags |= CDVALID; } else { +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) printf("part %d type UNUSED\n",part); +#endif /*CDDEBUG*/ cd_prevent_unit(unit,PR_ALLOW,SCSI_SILENT); return(ENXIO); } @@ -347,7 +376,7 @@ int flags; void cdminphys(bp) struct buf *bp; { - (*(cd_data[UNIT(bp->b_dev)].sc_sw->scsi_minphys))(bp); + (*(cd_data[UNIT(bp->b_dev)]->sc_sw->scsi_minphys))(bp); } /*******************************************************\ @@ -362,15 +391,17 @@ struct buf *bp; { struct buf *dp; unsigned int opri; - struct cd_data *cd ; + struct cd_data *cd; int unit; cdstrats++; unit = UNIT((bp->b_dev)); - cd = cd_data + unit; + cd = cd_data[unit]; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("\ncdstrategy "); if(scsi_debug & SHOWREQUESTS) printf("cd%d: %d bytes @ blk%d\n", unit,bp->b_bcount,bp->b_blkno); +#endif /*CDDEBUG*/ cdminphys(bp); /*******************************************************\ * If the device has been made invalid, error out * @@ -466,10 +497,12 @@ int unit; struct scsi_xfer *xs; struct scsi_rw_big cmd; int blkno, nblk; - struct cd_data *cd = cd_data + unit; + struct cd_data *cd = cd_data[unit]; struct partition *p ; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("cdstart%d ",unit); +#endif /*CDDEBUG*/ /*******************************************************\ * See if there is a buf to do and we are not already * * doing one * @@ -575,7 +608,9 @@ struct scsi_xfer *xs; struct buf *bp; int retval; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("cd_done%d ",unit); +#endif /*CDDEBUG*/ if (! (xs->flags & INUSE)) /* paranoia always pays off */ panic("scsi_xfer not in use!"); if(bp = xs->bp) @@ -608,7 +643,7 @@ struct scsi_xfer *xs; { xs->error = XS_NOERROR; xs->flags &= ~ITSDONE; - if ( (*(cd_data[unit].sc_sw->scsi_cmd))(xs) + if ( (*(cd_data[unit]->sc_sw->scsi_cmd))(xs) == SUCCESSFULLY_QUEUED) { /* shhh! don't wake the job, ok? */ /* don't tell cdstart either, */ @@ -651,13 +686,15 @@ cdioctl(dev_t dev, int cmd, caddr_t addr, int flag) \*******************************************************/ unit = UNIT(dev); part = PARTITION(dev); - cd = &cd_data[unit]; + cd = cd_data[unit]; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("cdioctl%d ",unit); +#endif /*CDDEBUG*/ /*******************************************************\ * If the device is not valid.. abandon ship * \*******************************************************/ - if (!(cd_data[unit].flags & CDVALID)) + if (!(cd_data[unit]->flags & CDVALID)) return(EIO); switch(cmd) { @@ -961,10 +998,10 @@ unsigned char unit; /*unsigned int n, m;*/ char *errstring; struct dos_partition *dos_partition_p; - struct cd_data *cd = cd_data + unit; + struct cd_data *cd = cd_data[unit]; /*******************************************************\ - * If the inflo is already loaded, use it * + * If the info is already loaded, use it * \*******************************************************/ if(cd->flags & CDHAVELABEL) return; @@ -1043,9 +1080,11 @@ cd_size(unit, flags) blksize += rdcap.length_2 << 16; blksize += rdcap.length_3 << 24; } +#ifdef CDDEBUG if(cd_debug)printf("cd%d: %d %d byte blocks\n",unit,size,blksize); - cd_data[unit].params.disksize = size; - cd_data[unit].params.blksize = blksize; +#endif /*CDDEBUG*/ + cd_data[unit]->params.disksize = size; + cd_data[unit]->params.blksize = blksize; return(size); } @@ -1262,7 +1301,7 @@ cd_start_unit(unit,part,type) { struct scsi_start_stop scsi_cmd; - if(type==CD_EJECT && (cd_data[unit].openparts&~(1<<part)) == 0 ) { + if(type==CD_EJECT && (cd_data[unit]->openparts&~(1<<part)) == 0 ) { cd_prevent_unit(unit,CD_EJECT,0); } @@ -1290,7 +1329,7 @@ int unit,type,flags; { struct scsi_prevent scsi_cmd; - if(type==CD_EJECT || type==PR_PREVENT || cd_data[unit].openparts == 0 ) { + if(type==CD_EJECT || type==PR_PREVENT || cd_data[unit]->openparts == 0 ) { bzero(&scsi_cmd, sizeof(scsi_cmd)); scsi_cmd.op_code = PREVENT_ALLOW; scsi_cmd.how = (type==CD_EJECT)?PR_ALLOW:type; @@ -1383,7 +1422,7 @@ struct cd_toc_entry *data; int cd_get_parms(unit, flags) { - struct cd_data *cd = cd_data + unit; + struct cd_data *cd = cd_data[unit]; /*******************************************************\ * First check if we have it all loaded * @@ -1416,10 +1455,12 @@ dev_t dev; unit = UNIT(dev); part = PARTITION(dev); +#ifdef CDDEBUG if(scsi_debug & TRACEOPENS) - printf("closing cd%d part %d\n",unit,part); - cd_data[unit].partflags[part] &= ~CDOPEN; - cd_data[unit].openparts &= ~(1 << part); + printf("cd%d: closing part %d\n",unit,part); +#endif + cd_data[unit]->partflags[part] &= ~CDOPEN; + cd_data[unit]->openparts &= ~(1 << part); cd_prevent_unit(unit,PR_ALLOW,SCSI_SILENT); return(0); } @@ -1445,9 +1486,11 @@ int datalen; struct scsi_xfer *xs; int retval; int s; - struct cd_data *cd = cd_data + unit; + struct cd_data *cd = cd_data[unit]; +#ifdef CDDEBUG if(scsi_debug & PRINTROUTINES) printf("\ncd_scsi_cmd%d ",unit); +#endif /*CDDEBUG*/ if(cd->sc_sw) /* If we have a scsi driver */ { xs = cd_get_xs(unit,flags); /* should wait unless booting */ @@ -1617,8 +1660,8 @@ struct scsi_xfer *xs; return(EINVAL); case 0x6: if(!silent)printf("cd%d: Unit attention\n", unit); - if (cd_data[unit].openparts) - cd_data[unit].flags &= ~(CDVALID | CDHAVELABEL); + if (cd_data[unit]->openparts) + cd_data[unit]->flags &= ~(CDVALID | CDHAVELABEL); { return(EIO); } |