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

📄 scsi_5380.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		    sz_scsistart(sc, targid, 0);		    DELAY(sz_wait_after_inquiry);		    /*		     * If the bus is wedged (BSY or SEL stuck)		     * reset the bus. This is painfull but should allow		     * remaining targets to be seen and prevent system		     * hang cause by a wedged SCSI bus.		     */		    wedged = 0;		    if ((szaddr->scs_curstat & SCS_BSY) &&			(szaddr->scs_curstat & SCS_BSY) &&			(szaddr->scs_curstat & SCS_BSY))			    wedged++;		    if ((szaddr->scs_curstat & SCS_SEL) &&			(szaddr->scs_curstat & SCS_SEL) &&			(szaddr->scs_curstat & SCS_SEL))			    wedged++;		    if (wedged) {			printf("szprobe: (bus=%d ID=%d) %s\n",cntlr, 				targid, "BSY or SEL stuck after start unit");			sz_dumpregs(cntlr, 0);	/* printf */			szaddr->scs_inicmd = SCS_INI_RST;			DELAY(sz_reset_width); /* hold bus reset 50 Usec */			szaddr->scs_inicmd = 0;			i = szaddr->scs_reset;			DELAY(sz_wait_for_devices * 1000000);			szaddr->scs_mode = SCS_PARCK;		    }		}		if (sdp->flags & SCSI_TESTUNITREADY) {		    sc->sc_curcmd[targid] = SZ_TUR;		    sz_bldpkt(sc, targid, SZ_TUR, 0, 1);		    sz_scsistart(sc, targid, 0);		}		if (sdp->flags & SCSI_READCAPACITY) {		    sc->sc_curcmd[targid] = SZ_RDCAP;		    sz_bldpkt(sc, targid, SZ_RDCAP, 0, 1);		    sz_scsistart(sc, targid, 0);		}		if (sdp->probedelay > 0)		    DELAY(sdp->probedelay);		if (sdp->flags & SCSI_NODIAG)		    sz_unit_rcvdiag[targid] = 1;		break;	    }		/* end of switch */	    /*	     * Just to be sure the bus is free after inquiry.	     * RRD40 may hold bus for a while.	     */	    DELAY(sz_wait_after_inquiry);	}		/* end of for loop */	/*	 * Clean out any left over interrupts.	 * NCR 5380 queues interrupts, so reset it	 * twice just to be safe.	 * Then re-enable interrupts.	 */	if (alive) {	    i = szaddr->scs_reset;	    i = szaddr->scs_reset;	    sziaddr->nb_int_reqclr = (SCS_IC_BIT >> cntlr);	    sziaddr->nb_int_msk |= (SCS_IC_BIT >> cntlr);	}	/*	 * NOTE: fixed allocation of the 128KB buffer is used for	 *	 this first release of the SCSI driver. A resource	 *	 map to manage the 128KB buffer is needed.	 *	 * If last (really 2nd) call to szprobe,	 * or only one controller configured,	 * assign 128K data buffer slots.	 *	 * 128K data buffer allocation strategy (512 byte chunks):	 *	19 - ST506 controller	 *	32 - each tape unit	 *	16 - each cdrom unit	 *	18 - each scsi floppy unit	 *	?? - each hard disk unit	 *	 1 - guard page	 * The guard page protects against accessing off the end of the	 * buffer due to the 5380 prefetching 1 extra byte on DMA writes.	 * ?? is what's left after tapes and cdroms divided by # of hard disks.	 * Any left over pages (fragment) allocated to the first disk.	 * ?? must be >= 8KB, should be >= 16KB, if not reduce	 * number of cdroms to 2, then number of tapes to 2.	 * If the 128KB buffer slot size for disks is still less	 * than 8KB, warn the user and try to continue. The	 * system may not function and will surely be slow.	 * In any "real" VS3100 configuration, we should	 * never hit these limits.	 */	if ((nNSCSI == 1) || (szp_firstcall == 0)) {	    if ((vs_cfgtst & VS_SC_TYPE) == VS_SCSI_SCSI)		dboff = 0x0;	    else		dboff = (19 * 512);	    /* determine rz slot size, must be > 16kb */	    while (1) {		rz_slotsize = 256 - 1;		/* guard page */		rz_slotsize -= (dboff / 512);		rz_slotsize -= (szp_ntz * 32);		rz_slotsize -= (szp_ncz * 16);		rz_slotsize -= (szp_nrx * 18);		if ((rz_slotsize > 0) && (szp_nrz - szp_nrx)) {		    rz_fragsize = rz_slotsize % (szp_nrz - szp_nrx);		    rz_slotsize = rz_slotsize / (szp_nrz - szp_nrx);		}		if (rz_slotsize < 32) {		    if (szp_ncz > 2) {			printf("Only 2 CDROM (too many other devices)\n");			szp_ncz = 2;			continue;		    }		}		if (rz_slotsize < 32) {		    if (szp_ntz > 2) {			printf("Only 2 tz (too many other devices)\n");			szp_ntz = 2;			continue;		    }		}		if (rz_slotsize < 32) {		    if (rz_slotsize >= 16)			printf("Poor disk performance (too many devices)\n");		    else			printf("System may not function (too many devices)\n");		}		break;	    }	    if (rz_slotsize > 128) {		rz_slotsize = 128;		rz_fragsize = 0;	    }	    if ((rz_slotsize + rz_fragsize) > 128)		rz_fragsize = 0;	    rz_slotsize *= 512;	    tz_slotsize = (32 * 512);	    cz_slotsize = (16 * 512);	    rx_slotsize = (18 * 512);	    ncz = ntz = 0;	    rz_fragused = 0;	    /* NOTE: must use ctlr NOT cntlr! */	    for (ctlr=0; ctlr<nNSCSI; ctlr++) {		sc = &sz_softc[ctlr];		for (targid=0; targid<NDPS; targid++) {		    if ((1 << targid) == sc->sc_sysid)			continue;		    if (sc->sc_alive[targid] == 0)			continue;		    if (sc->sc_devtyp[targid] & SZ_CDROM) {			if (++ncz > szp_ncz) {			    sc->sc_alive[targid] = 0;			    continue;			}			sc->sc_dboff[targid] = dboff;			sc->sc_segcnt[targid] = cz_slotsize;			dboff += cz_slotsize;		    }		    else if (sc->sc_devtyp[targid] & SZ_TAPE) {			if (++ntz > szp_ntz) {			    sc->sc_alive[targid] = 0;			    continue;			}			sc->sc_dboff[targid] = dboff;			sc->sc_segcnt[targid] = tz_slotsize;			dboff += tz_slotsize;		    }		    else if (sc->sc_devtyp[targid] & SZ_DISK) {			if ((sc->sc_devtyp[targid] == RX23) ||			    (sc->sc_devtyp[targid] == RX33)) {				sc->sc_dboff[targid] = dboff;				sc->sc_segcnt[targid] = rx_slotsize;				dboff += rx_slotsize;			}			else if (rz_fragused || (rz_fragsize == 0)) {			    sc->sc_dboff[targid] = dboff;			    sc->sc_segcnt[targid] = rz_slotsize;			    dboff += rz_slotsize;			}			else {			    sc->sc_dboff[targid] = dboff;			    sc->sc_segcnt[targid] = rz_slotsize;			    sc->sc_segcnt[targid] += (rz_fragsize * 512);			    dboff += (rz_slotsize + (rz_fragsize * 512));			    rz_fragused++;			}		    }		    else			continue;		}	    }	}	/*	 * Start timer on 2nd (last) call to szprobe.	 */	if (szp_firstcall) {	    szp_firstcall = 0;	}	else {	    /*	     * Zero the diagnostice timer register.	     * It is used by some optional driver stats code.	     */	    sziaddr->nb_diagtime = 0;	    /*	     * Start background timer (0.2 sec) to detect	     * hung bus when driver is not active.	     */	    timeout(sz_timer1, 0, 20);	}	if (alive) {	    sc = (struct sz_softc *)&sz_softc[cntlr];	    sc->sc_cntlr_alive = 1;	}	return(alive);}int	sz_do_timer1 = 1;	/* if 0, don't run driver idle bus hung timer */int	sz_t1_dorst = 1;	/* if 0, don't reset bus in timer1 *//* * * Name:		sz_timer2	-timeout disconnected disks * * Abstract:		A 10/30 second timeout starts when a hard/floppy *			disk disconnects from the bus. This routine is *			called if the disconnected disk has not done a *			reselect after 10/30 seconds. This routine sets an *			error condition on the disk and calls sz_start. *			NOTE: floppy timeout is 30 seconds because retires *			      can take a long time. *			NOTE: we cannot access the 5380's registers *			      the bus is active, so we backoff .1 sec. *			NOTE: just return if bus reset in progress. * * Inputs: * * unit			The ULTRIX logical unit number of the disk. This *			will be 0 -7 for bus A or 8 - 15 for bus B. * * Outputs:		None. * * Return Values:	None. * * Side Effects: *			IPL raised to 15. *			Another timeout queued if the bus is busy. *			Disk's context in sz_softc is modified. *			sz_start() called. * */sz_timer2(unit)int unit;{	register struct sz_softc *sc;	register int cntlr, targid;	register int s;	int flags;	s = spl5();	cntlr = (unit >> 3) & 1;	sc = &sz_softc[cntlr];	targid = unit & 7;	if (sc->sc_rip) {	/* Bus reset in progress, ignore timers */	    splx(s);	    return;	}	if (sc->sc_active) {	    /* TODO: may want variable backoff delay */	    timeout(sz_timer2, (caddr_t)unit, 10);	/* .1 sec */	    splx(s);	    return;	}	/* This does not happen unless something really went wrong */	flags = SZ_HARDERR | SZ_LOGCMD | SZ_LOGSELST;	scsi_logerr(sc, 0, targid, SZ_ET_DISTIMO, 0, 0, flags);	sc->sc_szflags[targid] &= ~SZ_TIMERON;	/* Do not think this can happen */	if (sc->sc_selstat[targid] != SZ_DISCONN) {#ifdef	notdef	    mprintf("sz_timer2: (bus=%d ID=%d) target not disconnected\n",		cntlr, targid);#endif	notdef	    splx(s);	    return;	}	sc->sc_selstat[targid] = SZ_IDLE;	sc->sc_szflags[targid] &= ~SZ_DID_DMA;	sc->sc_active = 0;	sc->sc_fstate = 0;	sc->sc_szflags[targid] |= SZ_NEED_SENSE;	/* force retry even if RQSNS data says NOSENSE */	sc->sc_szflags[targid] |= SZ_RSTIMEOUT;	if (sc->sc_dkn[targid] >= 0)	    dk_busy &= ~(1 << sc->sc_dkn[targid]);	sz_start(sc, targid);	splx(s);}/* * * Name:		sz_timer4	-timeout busy target * * Abstract:		If a target cannot accept a command it returns *			a BUSY status. In this case a timer is started. *			This routine is called when the timer expires. *			This routine calls sz_start() to send the command *			again. Timeout length is 0.5 seconds. *			NOTE: we cannot access the 5380's registers *			      the bus is active, so we backoff .1 sec. *			NOTE: just return if bus reset in progress. * * Inputs: * * unit			The ULTRIX logical unit number of the disk. This *			will be 0 -7 for bus A or 8 - 15 for bus B. * * Outputs:		None. * * Return Values:	None. * * Side Effects: *			IPL raised to 15. *			Another timeout queued if the bus is busy. *			sz_start() called. * */sz_timer4(unit)int unit;{	register struct sz_softc *sc;	register int cntlr, targid;	register int s;	s = spl5();	cntlr = (unit >> 3) & 1;	sc = &sz_softc[cntlr];	targid = unit & 7;	if (sc->sc_rip) {	/* Bus reset in progress, ignore timers */	    splx(s);	    return;	}	if (sc->sc_active) {	    /* TODO: may want variable backoff delay */	    timeout(sz_timer4, (caddr_t)unit, 10);	/* .1 sec */	    splx(s);	    return;	}	/* Do not think this can happen */	if ((sc->sc_szflags[targid] & SZ_BUSYTARG) == 0) {#ifdef	notdef	    mprintf("sz_timer4: (bus=%d ID=%d) target not busy\n",		cntlr, targid);#endif	notdef	    splx(s);	    return;	}	sc->sc_szflags[targid] &= ~SZ_BUSYTARG;	sz_start(sc, targid);	splx(s);}/* * * Name:		sz_timer3	-selection timeout timer * * Abstract:		This routine is part of the 250 MS selection *			timeout procedure. The first 20 MS is a spin *			loop in sz_scsistart(). If the target does not *			respond to the selection after 20 MS, then a *			30 MS timer is started. After 30 MS sz_timer3 *			is called, which starts a 50 MS timer 4 times. *			On each call sz_timer3 checks for BSY asserted. *			If BSY false and time less than 250 MS, then *			queue another 50 MS timeout. If BSY true or *			time greater than 250 MS, then call sz_start. *			NOTE: code assumes a bus reset cannot happen *			      while we are timing out a select. * * Inputs: * * unit			The ULTRIX logical unit number the target. *			Will be 0 - 7 for bus A or 8 - 15 for bus B. * * Outputs:		None. * * Return Values:	None. * * Side Effects: *			IPL raised to 15. *			sz_start() called. *			Another timer may be queued. * */sz_timer3(unit)int unit;{	register struct sz_regs *szaddr;	register struct sz_softc *sc;	register int cntlr, targid;	register int s;	s = spl5();	cntlr = (unit >> 3) & 1;	sc = &sz_softc[cntlr];	targid = unit & 7;	szaddr = (struct sz_regs *)szmem + cntlr;	/* Do not think this can ever happen */	if (sc->sc_active == 0) {	    splx(s);	    return;

⌨️ 快捷键说明

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