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

📄 scsi_asc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
    int	flags;    PRINTD(targid, SCSID_DISCONNECT,       ("asc_mi: sc_message = 0x%x, sc_messgptr = 0x%x\n",	    sc->sc_message[targid], sc->sc_messgptr[targid]));    /* Switch on the type of message received */    switch(sc->sc_message[targid]) {    case SZ_CMDCPT:	PRINTD(targid, SCSID_PHASE_STATE, 	       ("asc_mi: SZ_CMDCPT message\n"));	sc->sc_fstate = 0;	sc->sc_szflags[targid] &= ~SZ_DID_DMA;	sc->sc_actbp[targid] = BPFREE;	sc->sc_dboff_busy[targid][0] = 0;	sc->sc_dboff_busy[targid][1] = 0;	/* Assumes one command at a time for each target */	if (sc->sc_dkn[targid] >= 0)	    dk_busy &= ~(1 << sc->sc_dkn[targid]);	sc->scsi_completed[targid] = 1;	break;    case SZ_SDP:	PRINTD(targid, (SCSID_PHASE_STATE | SCSID_DISCONNECT),	   ("\nasc_mi: ==> SZ_SDP message, sc_savcnt = %d\n\n", 	        sc->sc_savcnt[targid]));	sc->sc_szflags[targid] &= ~SZ_DID_DMA;	sc->sc_dboff_len[targid][sc->sc_actbp[targid]] -= sc->sc_savcnt[targid];	ASC_LOADCNTR(ascaddr, 0);	wbflush();	break;    case SZ_DISCON:	PRINTD(targid, (SCSID_PHASE_STATE | SCSID_DISCONNECT),	   ("asc_mi: SZ_DISCON message\n")); 	sc->sc_szflags[targid] |= SZ_WAS_DISCON;	ASC_LOADCNTR(ascaddr, 0);	wbflush();/*	if ((sc->sc_prevpha == SZ_DATAI_PHA) || (sc->sc_prevpha == SZ_DATAO_PHA))*/	if (sc->sc_szflags[targid] & SZ_DMA_INTR) {	    sc->sc_szflags[targid] &= ~SZ_DMA_INTR;	    sc->sc_szflags[targid] |= SZ_DMA_DISCON;		    PRINTD(targid, SCSID_DISCONNECT,	       ("asc_mi: DMA_INTR -> DMA_DISCON\n"));	}	/* end if DMA_INTR */	break;		    case SZ_EXTMSG:	PRINTD(targid, (SCSID_PHASE_STATE | SCSID_DISCONNECT),	   ("asc_mi: SZ_EXTMSG msg, targ = %x, sc_szflags = 0x%x\n",	        targid, sc->sc_szflags[targid]));	sc->sc_extmessg[targid][0] = sc->sc_message[targid];	if (!(sc->sc_szflags[targid] & SZ_EXTMESSG)) {	    sc->sc_szflags[targid] |= SZ_EXTMESSG;            sc->sc_messgptr [targid] = &sc->sc_extmessg [targid][0];	    sc->sc_messg_len[targid] = -1;	    break;	}	/* end if */	else if (sc->sc_messg_len [targid] == 0) {	    PRINTD(targid, SCSID_DISCONNECT,	        ("\n===>>>> asc_mi: think we have complete ext. messg\n"));	    SZDEBUG_EXPAND(targid, &sc->sc_extmessg[targid][0], 		    (int)(sc->sc_extmessg[targid][1]) + 2);#ifdef SZDEBUG	    DELAY(20000);	/* time to look at message */#endif SZDEBUG	    /*	     * If the extended message is a Synchronous Data	     * Transfer Request message then set the REQ/ACK	     * offset for the current target otherwise reject	     * the message.	     *	     */	    if (sc->sc_extmessg[targid][2] == SZ_SYNC_XFER) {		if (sc->sc_extmessg[targid][4] > sc->asc_sync_offset) {		    sc->sc_extmessg[targid][4] = sc->asc_sync_offset;		}		sc->sc_ascreqack[targid] = sc->sc_extmessg[targid][4];		sc->sc_ascsyncper[targid] = asc_sync_xfer_reg;		PRINTD(targid, SCSID_CMD_EXP,		   ("asc_mi: req ack offset = 0x%x, sync per = 0x%x\n",		        sc->sc_ascreqack[targid], sc->sc_ascsyncper[targid]));	    }	/* end if SYNC_XFER */	    else  		cprintf("asc_msgin: recv extmessg %x\n", 		       sc->sc_extmessg[targid][2]);	    sc->sc_szflags[targid] &= ~SZ_EXTMESSG;	    if (sc->sc_alive[targid] == 0) { 		/* PROBING */		u_long messg = SZ_MSGREJ;		cprintf("asc_mi: recvd SYNC req in probe\n");		asc_assert_attn = 1;		asc_reject_message = 0;		asc_FIFOsenddata(sc, ASC_XINFO, &messg, 1);		break;	    }	/* end if alive == 0 */        }	/* end else */	break;    case SZ_ID_NODIS:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: SZ_ID_NODIS message\n"));	break;    case SZ_ID_DIS:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: SZ_ID_DIS message\n"));	break;    case SZ_RDP:	PRINTD(targid, SCSID_PHASE_STATE, ("asc_mi: SZ_RDP message\n"));	break;    case SZ_MSGREJ:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: SZ_MSGREJ message\n"));	break;    case SZ_LNKCMP:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: SZ_LNKCMP message\n"));	break;    case SZ_LNKCMPF:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: SZ_LNKCMPF message\n"));	break;    default:	PRINTD(targid, SCSID_PHASE_STATE, 	   ("asc_mi: unknown message = 0x%x\n", sc->sc_message[targid]));#ifdef ASC_LOGERR	flags = SZ_HARDERR | SZ_LOGMSG;	scsi_logerr(sc, 0, targid, SZ_ET_BUSERR, 0x73, 0, flags);#endif ASC_LOGERR	return(SZ_RET_ABORT);    }	/* end switch */    /*     * Assert attention as long as the "asc_assert_attn" flag is     * set. Attention gets deasserted during a message out phase     * and the "asc_assert_attn" flags gets cleared.     */    if (asc_assert_attn) {	cprintf("asc_mi: asc_assert_atn TRUE, issuing ASC_SETATN\n");	ascaddr->asc_cmd = ASC_SETATN;	wbflush();    }	/* end if asc_assert_atn */    /* Note: this should generate a Disconnect Interrupt */    PRINTD(targid, (SCSID_FLOW | SCSID_DISCONNECT),       ("asc_mi: issuing MSGACPT command\n"));    sc->sc_asccmd = ASC_MSGACPT;    ascaddr->asc_cmd = ASC_MSGACPT;    wbflush();    return(SZ_SUCCESS);}	/* end asc_msgin *//****************************************************************** * * name:	asc_clear_discon_io_tasks * * abstract:	Clear any disconnected io requests due to a bus reset. * * inputs: * * 	sc	- the softc data structure * * outputs:		none. * * return values: none. * ******************************************************************/asc_clear_discon_io_tasks(sc)register struct sz_softc *sc;{    int targid;    int unit;    struct buf *dp, *bp;    /* Find out if any targets have I/O requests that disconnected */    for (targid = 0; targid < NDPS; targid++) {	sc->sc_ascsentsync[targid] = 0;	if (targid == sc->sc_sysid)	/* skip initiator */	    continue;	if (sc->sc_alive[targid] == 0)	/* non existent target */	    continue;	if (sc->sc_attached[targid] == 0)	    continue;	unit = sc->sc_unit[targid];	dp = (struct buf *)&szutab[unit];	if (!dp->b_active)		/* target not active */	    continue;	if (dp->b_actf == NULL)	    continue;			/* no IO requests pending */	if (!(sc->sc_szflags[targid] & SZ_WAS_DISCON))	    continue;			/* was not disconnected */	PRINTD(targid, SCSID_ERRORS,	       ("asc_clear_discon_io_tasks: clearing target %d\n", targid));	printf("asc_clear_discon_io_tasks: clearing target %d\n", targid);	bp = dp->b_actf;	dp->b_actf = bp->av_forw;	dp->b_active = 0;	bp->b_resid = sc->sc_resid[targid];	bp->b_flags |= B_ERROR;	bp->b_error = EIO;	biodone(bp);	sc->sc_xstate[targid] = SZ_NEXT;	sc->sc_xevent[targid] = SZ_BEGIN;    }	/* end for */}	/* end asc_clear_disc_io_tasks *//****************************************************************** * * name:	asc_reset * * abstract:	Reset the ASC chip.	 * * inputs: * * 	sc	- the softc data structure * * outputs:		none. * * return values: none. * ******************************************************************/asc_reset(sc)register struct sz_softc *sc;{    int cntlr = sc->sc_ascnum;    ASC_REG *ascaddr = ASC_REG_ADDR; /* setup the register pointer */    int	i, retval;    char modname[TC_ROMNAMLEN+1];    char max[TC_ROMNAMLEN+1];    char min[TC_ROMNAMLEN+1];    int opt_type=0;    /* Reset the ASC chip. */    ascaddr->asc_cmd = ASC_RESET;    wbflush();    DELAY(25);				/* Just in case... */    ascaddr->asc_cmd = ASC_NOOP;	/* recommended for some parts.. */    wbflush();    DELAY(25);    ascaddr->asc_srto = 0xff;		/* Set select/reselect timeout to max*/    wbflush();    DELAY(25);    /* Set the clock conversion factor up for 25 MHz system */    ascaddr->asc_so = 0;    wbflush();    ascaddr->asc_ffss = 0;    wbflush();    /* Set our SCSI id and indicate use parity */    ascaddr->asc_cnf1 = asc_def_cnf1 | sc->sc_sysid;    wbflush();    DELAY(25);    ascaddr->asc_cnf2 = asc_def_cnf2;    wbflush();    DELAY(25);    ascaddr->asc_cnf3 = asc_def_cnf3;    wbflush();    DELAY(25);    sc->asc_sync_offset = ASC_SYNC_OFFSET;    /* check if 3MIN or 3MAX card */    if( cpu != DS_5500)  {       if( tc_addr_to_name(sc->sc_slotvaddr, modname) == -1)          cprintf("asc_reset():tc_addr_to_name failed ");       if( !strcmp(modname, "PMAZ-AA ") )  {          opt_type = DS_5000;       }       else       if( !strcmp(modname, "PMAZ-BA ") )  {          opt_type = DS_5000_100;       }       else  {          cprintf("asc_reset: tc_... returned '%s', assuming 3MAX\n", modname);          opt_type = DS_5000;       }    }    sc->ioasicp = 0;		/* default to no IOASIC in use */    switch (cpu) {      case DS_5500:         ascaddr->asc_ccf = 5;		         wbflush();         DELAY(25);         break;      case DS_5000:             ascaddr->asc_ccf = 5;		         wbflush();         DELAY(25);	 break;      case DS_5000_100:	 if(opt_type == DS_5000)  {     /* 3MAX option card */            ascaddr->asc_ccf = 3;		            wbflush();            DELAY(25);         }         else  {                   /* 3MIN opt. or base controller */            ascaddr->asc_ccf = 5;		            wbflush();            DELAY(25);            sc->ioasicp =  (char *) PHYS_TO_K1( BASE_IOASIC );                      /* to tell the isr that an ioasic is here */                      /* This will have to be modified to point to other */                      /* addresses when the IOASIC based option cards */                      /* become available */         }	 break;      default:	 panic ("asc_reset(): Unknown cpu type\n");	 break;    }    /*     * Assert SCSI bus reset for at least 25 Usec to clear the      * world.      */    sc->sc_asccmd = ASC_RSTBUS;    ascaddr->asc_cmd = ASC_RSTBUS;    wbflush();    DELAY(35);  /* 25 - ok for 3MAX 35 - ok for 3MIN */    /*     * Clear any pending interrupts from the reset.     */    sc->sc_asc_ssr = ascaddr->asc_ss;    sc->sc_asc_sr = ascaddr->asc_stat;    sc->sc_asc_isr = ascaddr->asc_intr;	/* will clear the interrupt */    asc_clear_discon_io_tasks(sc);/*  RPS - removing to avoid re-kmalloc'ing memory in init routine.    perhaps pdma should have a reset entry point as well.    (*sc->dma_init)(sc);*/    DELAY(sz_wait_for_devices * 1000000);}	/* end asc_reset *//****************************************************************** * * Name:	ascintr * * Abstract:	Handle interrupts from the 53c94 chip.  Check for any * 		gross errors, then process the SCSI phase as reported in *		the status register if the bus service bit is set. *		Make sure that the sequence step register indicates  *		that the CDB bytes were sent.   *		When disconnect interrupt received AND not running  *		at probe time, start a new I/O. * *		Interrupt status register processing: * *		Disconnect - Ordinarily set after command completion *		when the target disconnects.  May be set to indicate *		select/reselect timeout. * *		Bus Service - Indicates that a target is requesting *		an information transfer phase. * *		Function Complete - When this bit is set, it indicates *		that the Selection of the target is complete (although *		the CDB may not have been transferred 

⌨️ 快捷键说明

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