📄 mb87030lib.c
字号:
for (delayVar = 0; delayVar < 0x2000; delayVar++) ; }LOCAL BOOL spcHardErrPrint = FALSE;LOCAL int hardErrors = 0;/********************************************************************************* spcIntr - interrupt service routine for the SPC** NOMANUAL*/void spcIntr ( SPC *pSpc /* ptr to SPC info */ ) { FAST SCSI_PHYS_DEV *pDevToSelect; FAST UINT8 tempInts; FAST UINT8 tempSerr; tempInts = *pSpc->pIntsReg; tempSerr = *pSpc->pSerrReg; if (scsiIntsDebug) logMsg ("*** SPC INTERRUPT: Ints %08x, Serr %08x", tempInts, tempSerr, 0, 0, 0, 0); if (tempInts & SPC_INTS_SELECTED) { /* this is currently not supported */ *pSpc->pIntsReg = SPC_INTS_SELECTED; if (scsiIntsDebug) logMsg ("Selected ", 0, 0, 0, 0, 0, 0); } if (tempInts & SPC_INTS_RESELECTED) { *pSpc->pIntsReg = SPC_INTS_RESELECTED; if (scsiIntsDebug) logMsg ("Reselected ", 0, 0, 0, 0, 0, 0); /* if a selection attempt has been made, report lost arbitration */ if (((pDevToSelect = pSpc->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_IN_PROGRESS)) { pDevToSelect->devStatus = SELECT_LOST_ARBIT; pSpc->pDevToSelect = (SCSI_PHYS_DEV *) NULL; semGive (&pDevToSelect->devSyncSem); } } if (tempInts & SPC_INTS_COM_COMPLETE) { *pSpc->pIntsReg = SPC_INTS_COM_COMPLETE; if (scsiIntsDebug) logMsg ("commComplete ", 0, 0, 0, 0, 0, 0); /* if a selection attempt has been made, report success */ if (((pDevToSelect = pSpc->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_IN_PROGRESS)) { pDevToSelect->devStatus = SELECT_SUCCESSFUL; pSpc->pDevToSelect = (SCSI_PHYS_DEV *) NULL; semGive (&pDevToSelect->devSyncSem); } semGive (&pSpc->scsiCtrl.ctrlSyncSem); } if (tempInts & SPC_INTS_TIMEOUT) { *pSpc->pIntsReg = SPC_INTS_TIMEOUT; if (scsiIntsDebug) logMsg ("Timeout ", 0, 0, 0, 0, 0, 0); /* if a selection attempt has been made, report the time-out */ if (((pDevToSelect = pSpc->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_IN_PROGRESS)) { pDevToSelect->devStatus = SELECT_TIMEOUT; pSpc->pDevToSelect = (SCSI_PHYS_DEV *) NULL; semGive (&pDevToSelect->devSyncSem); } } if (tempInts & SPC_INTS_DISCONNECT) { spcPctlSet (pSpc, SPC_RESET_BIT, SPC_PCTL_SELECT); *pSpc->pIntsReg = SPC_INTS_DISCONNECT; if (scsiIntsDebug) logMsg ("Disconnect ", 0, 0, 0, 0, 0, 0); /* if a device is to be selected, do so now */ if (((pDevToSelect = pSpc->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_REQUESTED)) { if (pDevToSelect->useIdentify) { spcCommand (pSpc, SPC_SCMD_SET_ATN); } *pSpc->pTempReg = pSpc->selectTempReg; (void) spcXferCountSet (pSpc, (int) (pDevToSelect->selTimeOut << 8) | (pSpc->busFreeDelay)); spcCommand (pSpc, SPC_SCMD_SELECT); pDevToSelect->devStatus = SELECT_IN_PROGRESS; } else { pSpc->scsiCtrl.scsiBusPhase = SCSI_BUS_FREE_PHASE; semGive (&pSpc->scsiCtrl.ctrlSyncSem); } } if (tempInts & SPC_INTS_SERVICE_REQ) { *pSpc->pIntsReg = SPC_INTS_SERVICE_REQ; if (scsiIntsDebug) { logMsg ("serviceReq (sstsReg = 0x%02x) ", *pSpc->pSstsReg, 0, 0, 0, 0, 0); } } if (tempInts & SPC_INTS_HARD_ERROR) { *pSpc->pIntsReg = SPC_INTS_HARD_ERROR; if (scsiIntsDebug) { hardErrors++; if (spcHardErrPrint) { logMsg ("hardError (serrReg = 0x%02x) ", tempSerr, 0, 0, 0, 0, 0); } } } /* the following condition should not attain under allowable SCSI * configurations (i.e., vxWorks target is the sole initiator) */ if (tempInts & SPC_INTS_RESET_COND) { *pSpc->pIntsReg = SPC_INTS_RESET_COND; if (scsiIntsDebug) logMsg ("Reset (unexpected, multiple intiators not supported)", 0, 0, 0, 0, 0, 0); } if (scsiIntsDebug) logMsg ("\n", 0, 0, 0, 0, 0, 0); }/********************************************************************************* spcHwInit - initialize the SPC chip to a known state** This routine puts the SPC into a known quiescent state and issues a reset* to the SCSI Bus if any signals are active, thus putting target devices in* some presumably known state. Currently the initial state is not configurable* and does not enable reselection.** INTERNAL* Needs to handle parity enable*/LOCAL void spcHwInit ( SPC *pSpc /* ptr to an SPC info structure */ ) { UINT8 tempSctl; tempSctl = SPC_SCTL_RESET_AND_DSBL | SPC_SCTL_INT_ENBL; if (pSpc->scsiCtrl.disconnect) tempSctl |= (SPC_SCTL_ARBIT_ENBL | SPC_SCTL_RESELECT_ENBL); *pSpc->pSctlReg = tempSctl; /* set SCSI bus ID of controller */ *pSpc->pBdidReg = pSpc->scsiCtrl.scsiCtrlBusId; *pSpc->pScmdReg = (UINT8) 0; /* set cmd to 'bus release' */ *pSpc->pTmodReg = (UINT8) 0; /* asynch data transfer initially */ *pSpc->pPctlReg = (UINT8) 0; /* bus free int disabled, no phase */ (void) spcXferCountSet (pSpc, 0x00); /* clear xfer counter */ *pSpc->pSctlReg &= ~SPC_SCTL_RESET_AND_DSBL; spcScsiBusReset (pSpc); }/********************************************************************************* mb87030Show - display the values of all readable MB87030 SPC registers** This routine displays the state of the SPC registers in a user-friendly * manner. It is useful primarily for debugging.** EXAMPLE:* .CS* -> mb87030Show* SCSI Bus ID: 7 * SCTL (0x01): intsEnbl * SCMD (0x00): busRlease * TMOD (0x00): asyncMode * INTS (0x00): * PSNS (0x00): req0 ack0 atn0 sel0 bsy0 msg0 c_d0 i_o0 * SSTS (0x05): noConIdle xferCnt=0 dregEmpty * SERR (0x00): noParErr * PCTL (0x00): bfIntDsbl phDataOut * MBC (0x00): 0 * XFER COUNT : 0x000000 = 0* .CE** RETURNS: OK, or ERROR if <pScsiCtrl> and <pSysScsiCtrl> are both NULL.*/STATUS mb87030Show ( FAST SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { int busId; FAST UINT8 tempReg; FAST SPC *pSpc; /* ptr to SPC info */ int xferCount; if (pScsiCtrl == NULL) { if (pSysScsiCtrl == NULL) { printErr ("No SCSI controller specified.\n"); return (ERROR); } pScsiCtrl = pSysScsiCtrl; } pSpc = (MB_87030_SCSI_CTRL *) pScsiCtrl; /* Display current SCSI Bus ID */ if (spcBusIdGet (pSpc, &busId) == OK) printf ("SCSI Bus ID: %-5d\n", busId); else printf ("SCSI Bus ID: ERROR\n"); /* Display SPC Control Register */ tempReg = *pSpc->pSctlReg; printf ("SCTL (0x%02x): ", (int) tempReg); printf ("%s", (tempReg & SPC_SCTL_RESET_AND_DSBL) ? "spcDisabl " : ""); printf ("%s", (tempReg & SPC_SCTL_CTRL_RESET) ? "ctrlReset " : ""); printf ("%s", (tempReg & SPC_SCTL_DIAG_MODE) ? "diagMode " : ""); printf ("%s", (tempReg & SPC_SCTL_ARBIT_ENBL) ? "arbitEnbl " : ""); printf ("%s", (tempReg & SPC_SCTL_PARITY_ENBL) ? "paritEnbl " : ""); printf ("%s", (tempReg & SPC_SCTL_SELECT_ENBL) ? "selecEnbl " : ""); printf ("%s", (tempReg & SPC_SCTL_RESELECT_ENBL) ? "reselEnbl " : ""); printf ("%s", (tempReg & SPC_SCTL_INT_ENBL) ? "intsEnbl " : ""); printf ("\n"); /* Display Command Register */ tempReg = *pSpc->pScmdReg; printf ("SCMD (0x%02x): ", (int) tempReg); switch (tempReg & SPC_SCMD_CMD_MASK) { case SPC_SCMD_BUS_RELEASE: printf ("busRlease "); break; case SPC_SCMD_SELECT: printf ("select "); break; case SPC_SCMD_RESET_ATN: printf ("resetAtn "); break; case SPC_SCMD_SET_ATN: printf ("setAtn "); break; case SPC_SCMD_XFER: printf ("transfer "); break; case SPC_SCMD_XFER_PAUSE: printf ("xferPause "); break; case SPC_SCMD_RESET_ACK_REQ: printf ("resAckReq "); break; case SPC_SCMD_SET_ACK_REQ: printf ("setAckReq "); break; } printf ("%s", (tempReg & SPC_SCMD_RESET_OUT) ? "resetOut " : ""); printf ("%s", (tempReg & SPC_SCMD_INTERCEPT_XFER) ? "intcptXfr " : ""); printf ("%s", (tempReg & SPC_SCMD_PRG_XFER) ? "progXfer " : ""); printf ("%s", (tempReg & SPC_SCMD_TERM_MODE) ? "termMode " : ""); printf ("\n"); /* Display Transfer Mode Register */ tempReg = *pSpc->pTmodReg; printf ("TMOD (0x%02x): ", (int) tempReg); printf ("%s", (tempReg & SPC_TMOD_SYNC_XFER) ? "syncMode " : "asyncMode "); /* JCC Should display offset and period params also */ printf ("\n"); /* Display Interrupt Sense Register */ tempReg = *pSpc->pIntsReg; printf ("INTS (0x%02x): ", (int) tempReg); printf ("%s", (tempReg & SPC_INTS_SELECTED) ? "selected " : ""); printf ("%s", (tempReg & SPC_INTS_RESELECTED) ? "reselect " : ""); printf ("%s", (tempReg & SPC_INTS_DISCONNECT) ? "disconnct " : ""); printf ("%s", (tempReg & SPC_INTS_COM_COMPLETE) ? "comComplt " : ""); printf ("%s", (tempReg & SPC_INTS_SERVICE_REQ) ? "servReq " : ""); printf ("%s", (tempReg & SPC_INTS_TIMEOUT) ? "timeout " : ""); printf ("%s", (tempReg & SPC_INTS_HARD_ERROR) ? "hardError " : ""); printf ("%s", (tempReg & SPC_INTS_RESET_COND) ? "resetCond " : ""); printf ("\n"); /* Display Phase Sense Register */ tempReg = *pSpc->pPsnsReg; printf ("PSNS (0x%02x): ", (int) tempReg); printf ("%s", (tempReg & SPC_PSNS_REQ) ? "REQ1 " : "req0 "); printf ("%s", (tempReg & SPC_PSNS_ACK) ? "ACK1 " : "ack0 "); printf ("%s", (tempReg & SPC_PSNS_ATN) ? "ATN1 " : "atn0 "); printf ("%s", (tempReg & SPC_PSNS_SEL) ? "SEL1 " : "sel0 "); printf ("%s", (tempReg & SPC_PSNS_BSY) ? "BSY1 " : "bsy0 "); printf ("%s", (tempReg & SPC_PSNS_MSG) ? "MSG1 " : "msg0 "); printf ("%s", (tempReg & SPC_PSNS_C_D) ? "C_D1 " : "c_d0 "); printf ("%s", (tempReg & SPC_PSNS_I_O) ? "I_O1 " : "i_o0 "); printf ("\n"); /* Display SPC Status Register */ tempReg = *pSpc->pSstsReg; printf ("SSTS (0x%02x): ", (int) tempReg); switch (tempReg & SPC_SSTS_OPER_STAT_MASK) { case SPC_SSTS_NO_CONNECT_IDLE: printf ("noConIdle "); break; case SPC_SSTS_SELECT_WAIT: printf ("waitSelec "); break; case SPC_SSTS_TARGET_MANUAL: printf ("trgManual "); break; case SPC_SSTS_RESELECT_EXEC: printf ("reselExec "); break; case SPC_SSTS_TARGET_XFER: printf ("targXfer "); break; case SPC_SSTS_INITIATOR_MANUAL: printf ("iniManual "); break; case SPC_SSTS_INITIATOR_WAIT: printf ("iniWait "); break; case SPC_SSTS_SELECT_EXEC: printf ("selecExec "); break; case SPC_SSTS_INITIATOR_XFER: printf ("iniXfer "); break; default: printf ("operUndef "); break; } printf ("%s", (tempReg & SPC_SSTS_SCSI_RESET) ? "scsiReset " : ""); printf ("%s", (tempReg & SPC_SSTS_TC_0) ? "xferCnt=0 " : ""); switch (tempReg & SPC_SSTS_DREG_STAT_MASK) { case SPC_SSTS_DREG_EMPTY: printf ("dregEmpty "); break; case SPC_SSTS_DREG_PARTIAL: printf ("dregPartl "); break; case SPC_SSTS_DREG_FULL: printf ("dregFull "); break; default: printf ("dregUndef "); break; } printf ("\n"); /* Display SPC Error Status Register */ tempReg = *pSpc->pSerrReg; printf ("SERR (0x%02x): ", (int) tempReg); switch (tempReg & SPC_SERR_PAR_ERROR_MASK) { case SPC_SERR_NO_PAR_ERROR: printf ("noParErr "); break; case SPC_SERR_PAR_ERROR_OUT: printf ("outParErr "); break; case SPC_SERR_PAR_ERROR_IN: printf ("inpParErr "); break; default: printf ("pErrUndef "); break; } printf ("%s", (tempReg & SPC_SERR_TC_PARITY) ? "tcParErr " : ""); printf ("%s", (tempReg & SPC_SERR_PHASE_ERROR) ? "phaseErr " : ""); printf ("%s", (tempReg & SPC_SERR_SHORT_PERIOD) ? "shortPeri " : ""); printf ("%s", (tempReg & SPC_SERR_OFFSET_ERROR) ? "offsetErr " : ""); printf ("\n"); /* Display Phase Control Register */ tempReg = *pSpc->pPctlReg; printf ("PCTL (0x%02x): ", (int) tempReg); printf ("%s", (tempReg & SPC_PCTL_BF_INT_ENBL) ? "bfIntEnbl " : "bfIntDsbl "); switch (tempReg & SPC_PCTL_PHASE_MASK) { case SPC_PCTL_DATA_OUT: printf ("phDataOut "); break; case SPC_PCTL_DATA_IN: printf ("phDataIn "); break; case SPC_PCTL_COMMAND: printf ("phCommand "); break; case SPC_PCTL_STATUS: printf ("phStatus "); break; case SPC_PCTL_UNUSED_0: printf ("phUnused0 "); break; case SPC_PCTL_UNUSED_1: printf ("phUnused1 "); break; case SPC_PCTL_MESS_OUT: printf ("phMessOut "); break; case SPC_PCTL_MESS_IN: printf ("phMessIn "); break; } printf ("\n"); /* Display Modified Byte Counter */ tempReg = *pSpc->pMbcReg; printf ("MBC (0x%02x): ", (int) tempReg); printf ("%-10d", (int) tempReg); printf ("\n"); /* Display Transfer Counter */ spcXferCountGet (pSpc, &xferCount); printf ("XFER COUNT : "); printf ("0x%06x =%10d", xferCount, xferCount); printf ("\n"); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -