⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Outputs:		None. * * Return Values:	None. * * Side Effects:	None. * */szattach(ui)	register struct uba_device *ui;{	register struct uba_ctlr *um;	register struct sz_softc *sc;	register struct scsi_devtab *sdp;	int i;	sc = &sz_softc[ui->ui_ctlr];	sdp = (struct scsi_devtab *)sc->sc_devtab[ui->ui_slave];	/*	 * NOTE:	 *	This cannot happen, because the slave number for	 *	the initator is never alive. We check anyway to be sure.	 */	if ((1 << ui->ui_slave) == sc->sc_sysid)	    return;	ui->ui_flags = 0;	um = ui->ui_mi;	szutab[ui->ui_unit].b_actf = NULL;	szutab[ui->ui_unit].b_actl = NULL;	sc->sc_attached[ui->ui_slave] = 1;		/*	 * Initialize iostat sec/word transfer rate	 * for each disk/cdrom.	 * RZ22  1.0 / (60 * 33 * 256) (max data per one revolution)	 * RZ23  1.0 / (60 * 33 * 256) (max data per one revolution)	 * RZ55  1.0 / (60 * 36 * 256) (max data per one revolution)	 * RRD40 176.4 Kilobytes/second from spec	 */	if (ui->ui_dk >= 0) {	    sc->sc_dkn[ui->ui_slave] = ui->ui_dk;#ifdef NOWAY	    if (sc->sc_devtyp[ui->ui_slave] == RZ22)		    dk_mspw[ui->ui_dk] = 0.000002;	    else if (sc->sc_devtyp[ui->ui_slave] == RZ23)		    dk_mspw[ui->ui_dk] = 0.000002;	    else if (sc->sc_devtyp[ui->ui_slave] == RZ55)		    dk_mspw[ui->ui_dk] = 0.0000018;	    else if (sc->sc_devtyp[ui->ui_slave] == RRD40)		    dk_mspw[ui->ui_dk] = 0.0000113;	    else {		    sc->sc_dkn[ui->ui_slave] = -1;		    dk_mspw[ui->ui_dk] = 0.0;#endif NOWAY        }	else {	    sc->sc_dkn[ui->ui_slave] = -1;	}#ifdef mips	/*	 * This flag means that the drive is alive.	 */	dk_mspw[ui->ui_dk] = 1;#endif mips	/* so device name appears after slave printout in autoconf */	printf(" (%s)", sc->sc_device[ui->ui_slave]);	/* print vendor/product ID & rev level if non-DEC disk */	if ((sc->sc_devtyp[ui->ui_slave] == RZxx) ||	    (sc->sc_devtyp[ui->ui_slave] == TZxx)) {	    for (i = 0; i < SZ_DNSIZE; i++)		sz_devname[i] = sc->sc_devnam[ui->ui_slave][i];	    sz_devname[SZ_DNSIZE] = 0;	    for (i = 0; i < SZ_REV_LEN; i++)		sz_revlevel[i] = sc->sc_revlvl[ui->ui_slave][i];	    sz_revlevel[SZ_REV_LEN] = 0;	    printf(" [ %s %s ]", sz_devname, sz_revlevel);	}}/* * Name:		szslave		-Slave routine * * Abstract:		This routines determines whether or not a slave *			device is alive during autoconfigure. * * Inputs: * * ui			Unit information structure pointer. * * Outputs:		None. * * Return Values: * * 0			Slave is not alive. * * 1			Slave is alive. * * Side Effects: *			IPL raised to 15. * */szslave(ui)	register struct uba_device *ui;{	register struct uba_ctlr *um = szminfo[ui->ui_ctlr];	register struct sz_softc *sc;	register int s = splbio();	int alive;	alive = 1;	while(1) {	    /* dead cntlr */	    if (um->um_alive == 0) {		alive = 0;		break;	    }	    sc = &sz_softc[ui->ui_ctlr];	    /* not target ID alive for this slave number */	    if (sc->sc_alive[ui->ui_slave] == 0) {		alive = 0;		break;	    }	    /* see if correct device type, i.e., rz=disk or cdrom, tz=tape */	    if ((strcmp("rz", ui->ui_devname) == 0) &&		(sc->sc_devtyp[ui->ui_slave] & SZ_DISK)) {		    break;	    }	    if ((strcmp("rz", ui->ui_devname) == 0) &&		(sc->sc_devtyp[ui->ui_slave] & SZ_CDROM)) {		    break;	    }	    if ((strcmp("tz", ui->ui_devname) == 0) &&		(sc->sc_devtyp[ui->ui_slave] & SZ_TAPE)) {		    break;	    }	    alive = 0;	    break;	}	if (alive) {	    sc->sc_unit[ui->ui_slave] = ui->ui_unit;        }	/* end if alive */			splx(s);	return(alive);}int	sz_bp_pf = 0;/****************************************************************** * * Name:	sz_bldpkt * * Abstract:	Build a packet that is then passed one byte at a time * 		to the SCSI device. * * Inputs: * 	sc	Pointer to softc structure for controller. *	targid  Target. *	cmd	The SCSI command to build. *	addr	The logical block address. *	count	The number of blocks. * * Outputs:	None. * * Return values: None. * ******************************************************************/sz_bldpkt(sc, targid, cmd, addr, count)register struct sz_softc *sc;int	targid;long	cmd;daddr_t	addr;long	count;{	register u_char *byteptr;	register int i;	struct scsi_devtab *sdp;	struct buf *bp = sc->sc_bp[targid]; /* get our bp filled in sz_start */	struct format_params *fp;	struct read_defect_params *rdp;	struct verify_params *vp;	struct reassign_params *rp;	struct mode_sel_sns_params *msp;	struct io_uxfer *iox;	struct sz_rwl_cm *prwl;	int len;	struct tape_opt_tab *todp; /* our tape option table pointer */	struct disk_opt_tab *dodp; /* our disk option table pointer */	struct tape_info *ddp;  /* our density struct for tapes */	sdp = (struct scsi_devtab *)sc->sc_devtab[targid];	/*	 * Save cmd in sc_actcmd, so we know what command	 * we are really working on. For example, the current	 * command could be read, but the actual command	 * might be a request sense after the read.	 */	sc->sc_actcmd[targid] = cmd;	/*	 * Get a byte address of the begining of sc->sz_cmd space,	 * and clear the data space	 */	byteptr = (u_char *)&sc->sz_command;	for (i=0; i < SZ_MAX_CMD_LEN; i++)		*byteptr++ = 0;	PRINTD(targid, 0x20, ("sz_bldpkt: command = 0x%x\n", cmd));	/* build the comand packet */	bzero((char *)&sc->sz_dat[targid], sizeof(sc->sz_dat[targid]));	switch (cmd) {		case SZ_READ:		case SZ_WRITE:		case SZ_RBD:		    if (sc->sc_devtyp[targid] & SZ_TAPE) {	/* TAPE r/w */			/*			 * Check to see if we have an option table			 * if we do use those values in the table to set			 * things up.......			*/			if( sdp->opt_tab != NULL ){			    /*			     * we have an option table use it.			     * must cast the pointer			    */			    todp = (struct tape_opt_tab *)sdp->opt_tab;			    /* 			     * get our density struct pointer...			    */			    ddp = &todp->tape_info[DENS_IDX( bp )];			    /* 			     * since this is just a simple read/write			     * all we have to do is determine if fixed			     * block add convert to bytes/block..			    */			    /* 			     * lets see if this density selection is valid..			    */			    if( ddp->tape_flags & DENS_VAL ){				/*				 * this is valid lets get our stuff				*/				if( ddp->blk_size != NULL ){  				    /* 				     * since blk size is non 0 				     * this must be a fixed block tape dens				    */				    sc->sz_t_read.fixed = 1; /* fixed blocks */				    /*				     * since fixed the count is in blocks not				     * bytes				    */				    i = count/ddp->blk_size;				    sc->sz_t_read.xferlen2 = LTOB( i, 2);				    sc->sz_t_read.xferlen1 = LTOB( i, 1);				    sc->sz_t_read.xferlen0 = LTOB( i, 0);				}				else {				    sc->sz_t_read.fixed = 0; 				    /*				     * we don't have to convert the btye				     * count to blocks				    */				    sc->sz_t_read.xferlen2 = LTOB( count, 2);				    sc->sz_t_read.xferlen1 = LTOB( count, 1);				    sc->sz_t_read.xferlen0 = LTOB( count, 0);				}			    }			    /*			     * well we have a option table but this density			     * struct is not valid.... We must do something			     * but is it QIC 9trk 8mm etc... 			    */			    else {								/* ERRLOG_MARK */				cprintf("scsi OPTTABLE off id = %X\n", targid);			        sc->sz_t_read.fixed = 0; 			        sc->sz_t_read.xferlen2 = LTOB( count, 2);			        sc->sz_t_read.xferlen1 = LTOB( count, 1);			        sc->sz_t_read.xferlen0 = LTOB( count, 0);			    }			    			/* end of if tape option table */			} 							/* 			 * There is no option table... The default is			 * a normal tape drive......			*/			else{			    sc->sz_t_read.fixed = 0;	/* only records */			    sc->sz_t_read.xferlen2 = LTOB(count,2);			    sc->sz_t_read.xferlen1 = LTOB(count,1);			    sc->sz_t_read.xferlen0 = LTOB(count,0);			}		    /* end of if tape */		    }				    else {		/* DISK r/w */			sc->sz_d_read.lbaddr2 = LTOB(addr,2);			sc->sz_d_read.lbaddr1 = LTOB(addr,1);			sc->sz_d_read.lbaddr0 = LTOB(addr,0);			sc->sz_d_read.xferlen = LTOB(count/512,0);		    }		    break;		case SZ_READ_10:		case SZ_WRITE_10: {		    int blocks = (count / 512);		    sc->sz_d_rw10.lbaddr3 = LTOB(addr, 3);		    sc->sz_d_rw10.lbaddr2 = LTOB(addr, 2);		    sc->sz_d_rw10.lbaddr1 = LTOB(addr, 1);		    sc->sz_d_rw10.lbaddr0 = LTOB(addr, 0);		    sc->sz_d_rw10.xferlen1 = LTOB(blocks, 1);		    sc->sz_d_rw10.xferlen0 = LTOB(blocks, 0);		    break;		}		case SZ_FORMAT:		    fp = (struct format_params *)					    sc->sc_rzparams[targid];		    if(fp->fp_defects == VENDOR_DEFECTS) {			    sc->sz_d_fu.fmtdat = 1;			    sc->sz_d_fu.cmplst = 1;		    }		    else if(fp->fp_defects == KNOWN_DEFECTS) {			    sc->sz_d_fu.fmtdat = 1;			    sc->sz_d_fu.cmplst = 0;		    }		    else if(fp->fp_defects == NO_DEFECTS) {			    sc->sz_d_fu.fmtdat = 0;			    sc->sz_d_fu.cmplst = 0;		    }		    sc->sz_d_fu.dlf = fp->fp_format;		    sc->sz_d_fu.pattern = fp->fp_pattern;		    sc->sz_d_fu.interleave1 = LTOB(fp->fp_interleave,1);		    sc->sz_d_fu.interleave0 = LTOB(fp->fp_interleave,0);		    break;		case SZ_REASSIGN:		    break;		case SZ_RDD:		    rdp = (struct read_defect_params *)					    sc->sc_rzparams[targid];		    sc->sz_d_rdd.m = 1;		    sc->sz_d_rdd.g = 1;		    sc->sz_d_rdd.dlf = rdp->rdp_format;		    sc->sz_d_rdd.alclen1 = LTOB(rdp->rdp_alclen,1);		    sc->sz_d_rdd.alclen0 = LTOB(rdp->rdp_alclen,0);		    break;		case SZ_VFY_DATA:		    vp = (struct verify_params *)					    sc->sc_rzparams[targid];		    sc->sz_d_vd.reladr = 0;		    sc->sz_d_vd.bytchk = 0;		    sc->sz_d_vd.lbaddr3 = LTOB(vp->vp_lbn,3);		    sc->sz_d_vd.lbaddr2 = LTOB(vp->vp_lbn,2);		    sc->sz_d_vd.lbaddr1 = LTOB(vp->vp_lbn,1);		    sc->sz_d_vd.lbaddr0 = LTOB(vp->vp_lbn,0);		    sc->sz_d_vd.verflen1 = LTOB(vp->vp_length,1);		    sc->sz_d_vd.verflen0 = LTOB(vp->vp_length,0);		    break;		case SZ_READL:		case SZ_WRITEL:		    iox = (struct io_uxfer *) sc->sc_rzparams[targid];		    prwl = (struct sz_rwl_cm *) &(iox->io_cdb[1]);		    sc->sz_rwl.reladr = prwl->reladr;		    sc->sz_rwl.lun = prwl->lun;		    sc->sz_rwl.phad = prwl->phad;		    sc->sz_rwl.lbaddr3 = prwl->lbaddr3;		    sc->sz_rwl.lbaddr2 = prwl->lbaddr2;		    sc->sz_rwl.lbaddr1 = prwl->lbaddr1;		    sc->sz_rwl.lbaddr0 = prwl->lbaddr0;		    sc->sz_rwl.dspec = prwl->dspec;		    break;		case SZ_RQSNS:		    /*		     * Check to see if we have an option table		     * if we do use those values in the table to set		     * things up.......		    */		    if( sdp->opt_tab != NULL ){			/*			* we have an option table use it.			* must cast the pointer			*/			if (sc->sc_devtyp[targid] & SZ_TAPE) {				    todp = (struct tape_opt_tab *)sdp->opt_tab;			    /* 			     * lets see if the request sense is valid			    */			    if( todp->opt_flags & RSNS_ALLOCL_VAL){			    	/* 			       	 * is the request size larger then storage			    	*/			    	if( todp->rsns_allocl > 					sizeof( struct sz_exsns_dt)){				    /*			 	     * truncate the size				    */				    sc->sz_rqsns.alclen = 					sizeof(struct sz_exsns_dt);			        }			        else { 				    sc->sz_rqsns.alclen = todp->rsns_allocl;			        }			    }			    /* 			     * we have an option table but they never validated			     * the request sense size default it....			    */			    else {			        sc->sz_rqsns.alclen = SZ_RQSNS_LEN;			    }			}			else { /* must be disk */			    dodp = (struct disk_opt_tab *)sdp->opt_tab;			    /* 			     * lets see if the request sense is valid

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -