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

📄 scsi_kzq.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef SZDEBUG    /* JAG make this a subroutine call with DEBUG */    PRINTD(targid, 0x20, ("kzq_sendcmd: scsi cmd pkt:"));     for(i=0; i < cmdcnt; i++)    {	PRINTD(targid, 0x20, (" %x", *(byteptr+i)));    }    PRINTD(targid, 0x20, ("	( %s )\n", scsi_cmdtable[cmd_type]));#endif SZDEBUG    /* Put the scsi command onto the scsi bus */    if(kzq_senddata(sc, byteptr, cmdcnt, 0) != SZ_SUCCESS)	{	return(SZ_RET_ABORT);	}    /* Statistics update for READS and WRITES */    if((cmd_type == SZ_WRITE) || (cmd_type == SZ_READ) ||        (cmd_type == SZ_WRITE_10) || (cmd_type == SZ_READ_10)) {	if(sc->sc_dkn[targid] >= 0) {	    dk_busy |= 1 << sc->sc_dkn[targid];	    dk_xfer[sc->sc_dkn[targid]]++;	    dk_wds[sc->sc_dkn[targid]] += sc->sc_bpcount[targid] >> 6;	}    }    return(SZ_SUCCESS);} /****************************************************************** * * Perform the STATUS PHASE on the SII chip. * ******************************************************************/kzq_getstatus(sc)register struct sz_softc *sc;{    int cntlr = sc->sc_siinum;    register struct kzq_regs *kzqaddr = (struct kzq_regs *)sc->sc_scsiaddr;    int targid = kzq_getactive_target(sc);    /* Get the status byte from the scsi bus */    if(kzq_recvdata(sc, &sc->sc_status[targid], 1) != SZ_SUCCESS)	return(SZ_RET_ABORT);    /* Save the status byte for the error log */    if (sc->sc_curcmd[targid] == sc->sc_actcmd[targid])	sc->sc_statlog[targid] = sc->sc_status[targid];    PRINTD(targid, 0x24, ("kzq_getstatus: status byte = 0x%x = ",   					 sc->sc_status[targid]));    PRINTD(targid, 0x24, ("", kzq_print_status((int)sc->sc_status[targid])));    /* Check the status a switch table is used to handle future abilitys    in status checking. */    switch( sc->sc_status[ targid ] )    {      /* All went well onto the next phase. Fall through to the return() */	case SZ_GOOD :	break;      /* Set the SZ_NEED_SENCE flag, the state mach. will handle the rest. */	case SZ_CHKCND :	    sc->sc_szflags[targid] |= SZ_NEED_SENSE;	break;      /* Have to wait a bit for the target to be able to handle the request.	Set the BUSYTARG flag to signal the interrupt handler of the BUSY	condition. */	case SZ_BUSY :	    sc->sc_szflags[targid] |= SZ_BUSYTARG;	/* set BUSY flag */	break;	case SZ_INTRM :			/* not handled for now */	case SZ_RESCNF :	default :	    return(SZ_RET_ABORT);	/* Assume bad failure for now */	break;    }    return(SZ_SUCCESS);			/* every thing went well */}/****************************************************************** * * Perform the MESSAGE OUT PHASE on the SII chip. * ******************************************************************/kzq_msgout(sc)register struct sz_softc *sc;{    int cntlr = sc->sc_siinum;    register struct kzq_regs *kzqaddr = (struct kzq_regs *)sc->sc_scsiaddr;#ifdef vax    u_char messg;#endif vax#ifdef mips    u_long messg;#endif mips    int targid = kzq_getactive_target(sc);    int lun = sc->sz_t_read.lun;    /*     * If the current state isn't SZ_SELECT then this message out     * phase is incorrect.  Send a NOP to get the target out of this     * phase.  NOTE -- this will need to be changed when we support     * targets as initiators.  This code is being added to get around     * the sii's selection problem where the select command is ignored     * leaving ATN asserted which causes the target to go to msgout.     */    if(sc->sc_selstat[targid] != SZ_SELECT) {	messg = SZ_NOP;#ifdef SZDEBUG        PRINTD(targid, 0x1,	    ("kzq_msgout: sending NOP Message\n"));#endif SZDEBUG        /* Put the NOP Message onto the scsi bus */        kzq_senddata(sc, &messg, 1, 0);	return(SZ_SUCCESS);    }    /* Check if we need to send a Message Reject Message */    if(kzq_reject_message) {	kzq_reject_message = 0;	messg = SZ_MSGREJ;        PRINTD(targid, 0x4, ("kzq_msgout: sending Message Reject Message\n"));        /* Put the Message Reject Message onto the scsi bus */        if(kzq_senddata(sc, &messg, 1, 0) != SZ_SUCCESS)	    {	    return(SZ_RET_ABORT);	    }    }    /* Send the Identify Message with or without disconnects */    else {    /* Clear the "kzq_assert_attn" flag */    kzq_assert_attn = 0;	/* Setup for disconnects or no disconnects */        if(sc->scsi_polled_mode)            messg = SZ_ID_NODIS | lun;	/* Allow no disconnects */        else            messg = SZ_ID_DIS | lun;  	/* Allow disconnects */        /* Check if we need to send a Synchronous DataXfer Message */	if(!sc->sc_siisentsync[targid]) {	    sc->sc_siisentsync[targid] = 1;	    PRINTD(targid, 0x4,		("kzq_msgout: sending Identify Message = 0x%x\n",messg));            /* Put the Identify Message onto the scsi bus */            if(kzq_senddata(sc, &messg, 1, SII_ATN) != SZ_SUCCESS)		{	        return(SZ_RET_ABORT);		}	    PRINTD(targid, 0x4,		("kzq_msgout: sending Sync Data Transfer Message\n"));            /* Put the Synchronous Data Xfer Message onto the scsi bus */            sc->sc_extmessg[targid][0] = SZ_EXTMSG;            sc->sc_extmessg[targid][1] = 0x3;            sc->sc_extmessg[targid][2] = SZ_SYNC_XFER;            sc->sc_extmessg[targid][3] = 63; /* 25, 12 is fast! */            sc->sc_extmessg[targid][4] = SII_SYNC;	    { int i;	    for(i=0; i < 4; i++)            if(kzq_senddata(sc, &sc->sc_extmessg[targid][i], 1, SII_ATN) 				!= SZ_SUCCESS) {		if(i == 1) {			/* For all those weird devices, can't do EXTMSG */			sc->sc_siireqack[targid] = 0;	        	return(SZ_SUCCESS);		}		return(SZ_RET_ABORT);	    }	    }	    /* The following should probably not ever return failure	       since there are non-synchronous devices that will just	       reset the bus if given this message. The devices that	       this works on will succeed in any case. */            if(kzq_senddata(sc, &sc->sc_extmessg[targid][4], 1, 0) 				!= SZ_SUCCESS) {		/* For all those weird devices, can't do SYNC */		sc->sc_siireqack[targid] = 0;	        return(SZ_SUCCESS);	    }        }	else {	    PRINTD(targid, 0x4,		("kzq_msgout: sending default Identify Msg = 0x%x\n",messg));            /* Put the Identify Message onto the scsi bus */            messg = SZ_ID_NODIS | lun;	/* Allow no disconnects */            if(kzq_senddata(sc, &messg, 1, 0) != SZ_SUCCESS)	        return(SZ_RET_ABORT);	}    }    return(SZ_SUCCESS);}/****************************************************************** * * Perform the MESSAGE IN PHASE on the SII chip. * ******************************************************************/#ifdef	ELDEBUG/* Set ID of target to cause DBBR message to be logged (on bus 0 only) */int	sz_eldb_dbbr0 = -1;int	sz_eldb_dbbr1 = -1;int	sz_eldb_dbbr2 = -1;int	sz_eldb_dbbr3 = -1;/* Set ID of target to cause unknown message error (bus 0 only) */int	sz_eldb_buserr73 = -1;#endif	ELDEBUGkzq_msgin(sc)register struct sz_softc *sc;{    int cntlr = sc->sc_siinum;    register struct kzq_regs *kzqaddr = (struct kzq_regs *)sc->sc_scsiaddr;    int len, i;    int retval;    int targid = kzq_getactive_target(sc);    u_short olddmlotc = kzqaddr->sii_dmlotc;    int flags;    /* Get the message from the scsi bus */    if(kzq_recvdata(sc, &sc->sc_message[targid], 1) != SZ_SUCCESS)	return(SZ_RET_ABORT);#ifdef	ELDEBUG    if ((cntlr == 0) && (targid == sz_eldb_buserr73)) {	    sc->sc_message[targid] = 0x5;	/* SZ_ID initiator detected error */	sz_eldb_buserr73 = -1;    }#endif	ELDEBUG    /* Switch on the type of message received */    switch(sc->sc_message[targid]) {    case SZ_CMDCPT:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_CMDCPT message\n"));	    sc->sc_fstate = 0;	    sc->sc_szflags[targid] &= ~SZ_DID_DMA;	    sc->sc_actbp[targid] = -1;	    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;#ifdef	ELDEBUG	    if ((sc->sc_curcmd[targid] == SZ_READ) && (cntlr == 0) &&		(targid == sz_eldb_dbbr0)) {		flags = SZ_HARDERR;/* ELDEBUG */	scsi_logerr(sc, sc->sc_bp[targid], targid, SZ_ET_DBBR, 0, 0, flags);		sz_eldb_dbbr0 = -1;	    }	    if ((sc->sc_curcmd[targid] == SZ_READ) && (cntlr == 0) &&		(targid == sz_eldb_dbbr1)) {		flags = SZ_HARDERR;/* ELDEBUG */	scsi_logerr(sc, sc->sc_bp[targid], targid, SZ_ET_DBBR, 1, 0, flags);		sz_eldb_dbbr1 = -1;	    }	    if ((sc->sc_curcmd[targid] == SZ_READ) && (cntlr == 0) &&		(targid == sz_eldb_dbbr2)) {		flags = SZ_SOFTERR;/* ELDEBUG */	scsi_logerr(sc, sc->sc_bp[targid], targid, SZ_ET_DBBR, 2, 0, flags);		sz_eldb_dbbr2 = -1;	    }	    if ((sc->sc_curcmd[targid] == SZ_READ) && (cntlr == 0) &&		(targid == sz_eldb_dbbr3)) {		flags = SZ_HARDERR;/* ELDEBUG */	scsi_logerr(sc, sc->sc_bp[targid], targid, SZ_ET_DBBR, 3, 0, flags);		sz_eldb_dbbr3 = -1;	    }#endif	ELDEBUG	    break;    case SZ_SDP:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_SDP message\n"));	    sc->sc_savcnt[targid] = olddmlotc;	    sc->sc_szflags[targid] &= ~SZ_DID_DMA;	sc->sc_dboff_len[targid][sc->sc_actbp[targid]] -= sc->sc_savcnt[targid];	kzqaddr->sii_dmlotc = 0;            /* Read the disconnect message now */            if(kzq_recvdata(sc, &sc->sc_message[targid], 1) != SZ_SUCCESS)	        return(SZ_RET_ABORT);	    if(sc->sc_message[targid] != SZ_DISCON)		break;	/* FALL THROUGH */    case SZ_DISCON:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_DISCON message\n"));	    sc->sc_szflags[targid] |= SZ_WAS_DISCON;	    kzqaddr->sii_dmlotc = 0;	    if(sc->sc_siidmacount[targid] !=0 )	        sc->sc_szflags[targid] |= SZ_DMA_DISCON;	    break;		    case SZ_EXTMSG:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_EXTMSG message\n"));	    sc->sc_extmessg[targid][0] = sc->sc_message[targid];            /* Read the extended message length */            if(kzq_recvdata(sc, &sc->sc_extmessg[targid][1], 1) != SZ_SUCCESS)	        return(SZ_RET_ABORT);	    len = (int)sc->sc_extmessg[targid][1];	    /*	     * At this time the only extended messaged which is	     * supported is SZ_SYNC_XFER.  If the incoming message	     * isn't a SZ_SYNC_XFER, assert ATN now!  This will	     * prevent the target from becomming confused and 	     * beleiving that the message was accepted.	     */	    if(sc->sc_extmessg[targid][0] != SZ_SYNC_XFER) {		    sc->sc_szflags[targid] |= SZ_REJECT_MSG;		    kzqaddr->sii_comm |= SII_ATN;	    }            /* Read the extended message */            if(kzq_recvdata(sc, &sc->sc_extmessg[targid][2], len) != SZ_SUCCESS)	        return(SZ_RET_ABORT);#ifdef SZDEBUG	    /* JAG make a subroutine w/DEBUG */	    PRINTD(targid, 0x4, ("kzq_msgin: extended message:"));     	    for(i=0; i<(len+2); i++)		PRINTD(targid, 0x4, (" %x", sc->sc_extmessg[targid][i]));	    PRINTD(targid, 0x4, ("\n"));#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.  Also reload the dmctrl register with	     * the new (possibly) offset.	     *	     */	    if(sc->sc_extmessg[targid][0] == SZ_SYNC_XFER) {		if(sc->sc_extmessg[targid][4] > SII_SYNC)		    sc->sc_extmessg[targid][4] = SII_SYNC;		sc->sc_siireqack[targid] = sc->sc_extmessg[targid][4];		kzqaddr->sii_dmctrl = sc->sc_siireqack[targid];	    }	    if(sc->sc_alive[targid] == 0) { /* PROBING */		u_long messg = SZ_MSGREJ;	    	kzq_assert_attn = 1;	    	kzq_reject_message = 0;        	kzq_senddata(sc, &messg, 1, SII_ATN);	    }	    break;    case SZ_ID_NODIS:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_ID_NODIS message\n"));	    break;    case SZ_ID_DIS:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_ID_DIS message\n"));	    break;	case SZ_RDP:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_RDP message\n"));	    break;	case SZ_MSGREJ:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_MSGREJ message\n"));	    break;	case SZ_LNKCMP:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_LNKCMP message\n"));	    break;	case SZ_LNKCMPF:	    PRINTD(targid, 0x4, ("kzq_msgin: SZ_LNKCMPF message\n"));	    break;    default:	    flags = SZ_HARDERR | SZ_LOGMSG;	    scsi_logerr(sc, 0, targid, SZ_ET_BUSERR, 0x73, 0, flags);	    PRINTD(targid, 0x4, ("kzq_msgin: unknown message = 0x%x\n",		sc->sc_message[targid]));	    return(SZ_RET_ABORT);    }    /*     * Assert attention as long as the "kzq_assert_attn" flag is     * set. Attention gets deasserted during a message out phase     * and the "kzq_assert_attn" flags gets cleared.     */    if(kzq_assert_attn) {	kzqaddr->sii_comm |= SII_ATN;        }#ifdef mips    wbflush();#endif mips    return(SZ_SUCCESS);}/****************************************************************** * * Send data to the scsi bus. * ******************************************************************/kzq_senddata(sc, data, count, attn)register struct sz_softc *sc;u_char *data;int count;int attn;{    int cnltr = sc->sc_siinum;    register struct kzq_regs *kzqaddr = (struct kzq_regs *)sc->sc_scsiaddr;    int retval;    int tmp_state;    int tmp_phase;    int i;    int targid = kzq_getactive_target(sc);    /* Move the SII to the new phase */

⌨️ 快捷键说明

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