📄 ncr710lib.c
字号:
/* choose the selWithAtn if useIdentify or/and useMsgout and build * Identify msgout. */ if ((pScsiPhysDev->useIdentify == TRUE) || (pScsiPhysDev->useMsgout != SCSI_NO_MSGOUT)) pNcrCtl->scriptAddr = (UINT) &selWithAtn; else pNcrCtl->scriptAddr = (UINT) &selWithoutAtn; if (pScsiPhysDev->useIdentify == TRUE) { /* build identify message */ pNcrCtl->pMsgOut = (UINT8 *) SCSI_GET_PTR_IDENTIFY(pScsiPhysDev); identMsg = SCSI_MSG_IDENTIFY | (pSiop->scsiCtrl.disconnect ? SCSI_MSG_IDENT_DISCONNECT : 0) | (UINT8) pScsiPhysDev->scsiDevLUN; *pNcrCtl->pMsgOut = identMsg; if (pScsiPhysDev->useMsgout == SCSI_NO_MSGOUT) pNcrCtl->msgOutCount = 1; else pNcrCtl->msgOutCount++; } /* Call the siopScriptPhase to perform a run on ncr chip */ SCSI_DEBUG_MSG("ncr710ScsiPhase:FirstStartPhase \n", 0, 0, 0, 0, 0, 0); transactEnd = FALSE; /* Set device status in SELECT_REQUESTED state */ pScsiPhysDev->devStatus = SELECT_REQUESTED; status = ncr710FirstStartPhase (pSiop, pNcrCtl, pScsiPhysDev, ncr710TimeOut); if (status == ERROR) return(status); while (transactEnd != TRUE) { NCR710_DEBUG_MSG("siopIntrStatus=0x%08x", pSiop->saveScriptIntrStat); NCR710_DEBUG_MSG(" saveSstat0=0x%02x", pSiop->saveSstat0); NCR710_DEBUG_MSG(" saveDstat=0x%02x\n", pSiop->saveDstat); /* local pointer to msg out array */ pMsgOut = SCSI_GET_PTR_MSGOUT(pScsiPhysDev); if ((pSiop->saveDstat & B_SIR) != B_SIR) { /* Check for status registers interrupt */ status = ncr710CheckStatRegs(pSiop, pScsiPhysDev, (UINT *)&localStart); if (status == OK ) goto contTransaction; /* all of these conditions are fatal */ SCSI_DEBUG_MSG("out from phase with error\n", 0, 0, 0, 0, 0, 0); SCSI_DEBUG_MSG("Scsi Phase End = 0x%02x\n",*pSiop->pSbcl, 0, 0, 0, 0, 0); goto exitPhase; } localSwitch = (pSiop->saveScriptIntrStat); /* No error what's kind of intr script */ switch (localSwitch) { case BAD_MSGIN_BEFORE_CMD: case BAD_MSG_AFTER_CMD: case BAD_MSG_AFTER_DATA: case BAD_MSG_INSTEAD_CMDCOMP: /* invalidate msgin array */ CACHE_USER_INVALIDATE (pNcrCtl->pMsgIn, MAX_MSG_IN_BYTES); LOG_ERR("Not an expected msg received!! msgin = 0x%02\n", msgIn[0]); LOG_ERR_CTXT; /* Check if it's an ident message */ if (msgIn[0] == identMsg) { /* Accept and restart to the next phase requested */ if ((localSwitch == BAD_MSG_AFTER_DATA) || (localSwitch == BAD_MSG_INSTEAD_CMDCOMP)) localStart = &ackMsg3; else localStart = &ackMsg1; } else { /* reject Msg */ LOG_ERR("Not an expected msg ..send reject msg!!\n"); pNcrCtl->pMsgOut = SCSI_GET_PTR_MSGOUT(pScsiPhysDev); *pNcrCtl->pMsgOut = (UINT8)SCSI_MSG_MESSAGE_REJECT; pNcrCtl->msgOutCount = 1; localStart = (UINT *)&ackAtnMsg; /* flush msgout array */ CACHE_USER_FLUSH (pNcrCtl->pMsgOut,1); } break; case MSGIN_EXPECT_AFTER_ST: /* not a msgIn phase after a status */ LOG_ERR("msgIn expect after status!!\n"); LOG_ERR_CTXT; localStart = &checkPhData; break; case MSGOUT_EXPECT: /* result of a select with atn and no msgout phase income, * goto the requested target phase. */ LOG_ERR("Bad phase after select with atn!!\n"); LOG_ERR_CTXT; localStart = &asortPh; break; case BAD_PH_AFTER_CMD: LOG_ERR("Bad phase after a command phase!!\n"); LOG_ERR_CTXT; /* it`s not data/status/msgin ?, restart to the requested * phase. */ localStart = &checkPhData; break; case EXTMSG_BEFORE_CMD: case EXTMSG_AFTER_CMD: case EXTMSG_AFTER_DATA: LOG_ERR("Extended msg received!!\n"); /* invalidate Msgin array */ CACHE_USER_INVALIDATE (msgIn, sizeof(msgIn)); localStart = ncr710ExtMsgRecv(pSiop, pScsiPhysDev, pNcrCtl, &msgIn[0]); /* Flush msgout array in case of reject msg */ CACHE_USER_FLUSH (pNcrCtl->pMsgOut, MAX_MSG_OUT_BYTES); break; case REJECT_MSG1: LOG_ERR("reject message received!!\n"); LOG_ERR_CTXT; localStart = ncr710RejectRecv(pSiop, pScsiPhysDev, pNcrCtl); /* flush msgout array */ CACHE_USER_FLUSH (pNcrCtl->pMsgOut, MAX_MSG_OUT_BYTES); break; case BAD_NEW_CMD: LOG_ERR("BAD NEW CMD!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; case GOOD_END: NCR710_DEBUG_MSG("ncr710ScsiPhase:good end\n"); transactEnd = (TBOOL) TRUE; break; case ABORT_CLEAR_END: /* in this case return error ,because that means that you * sent a message reset device and the target goes directly * in bus free phase. */ LOG_ERR("ncr710ScsiPhase:abort end!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; case BAD_PH_BEFORE_CMD: LOG_ERR("bad phase before cmd!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; case PH_UNKNOWN: LOG_ERR("scsi phase unknown!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; case RES_IN_DETECTED: case RES_OUT_DETECTED: LOG_ERR("RES4 RES5 phase detected!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; case SAVDATP_BEFORE_CMD: case SAVDATP_AFTER_CMD: NCR710_DEBUG_MSG("save pointer before the data phase\n"); localStart = &ackMsg1; break; case SAVDATP_AFTER_DATA: NCR710_DEBUG_MSG("save pointer after the data phase\n"); /* Restart to accept message at a data phase point */ localStart = &ackMsg3; break; case DISC_BEFORE_CMD: case DISC_AFTER_CMD: case DISC_AFTER_DATA: NCR710_DEBUG_MSG("disconnect message\n"); /* If it's a first disconnection ,clear commandRequest. * The normal sequence is * IDLE->SELECT_REQUESTED->DISCONNECTED->RECONNECTED..->IDLE. */ semTake (pSiop->pMutexData,WAIT_FOREVER); if (pScsiPhysDev->devStatus == SELECT_REQUESTED) { pSiop->commandRequest = FALSE; } if (pSiop->commandRequest == TRUE) *pSiop->pIstat |= B_SIGP; semGive(pSiop->pMutexData); /* Save reconnect re-start script entry point */ if (pSiop->saveScriptIntrStat == DISC_AFTER_DATA) localStart = &ackMsg3; else localStart = &ackMsg1; if (pScsiPhysDev->devStatus == SELECT_REQUESTED) { semGive (&pScsiCtrl->ctrlMutexSem); } /* Update devStatus */ pScsiPhysDev->devStatus = DISCONNECTED; /* Restart script to the idle point */ ncr710StartScript(pSiop, pSiop->pNcrCtl, pScsiPhysDev, &waitSelect); /* Suspend disconnected device */ semTake(&pScsiPhysDev->devSyncSem, WAIT_FOREVER); /* The reconnect will occur and restart the current SCSI * transaction at this point for this device */ /* Restore nexus context */ pSiop->pNcrCtl = pNcrCtl; /* Update dev status */ pScsiPhysDev->devStatus = RECONNECTED; break; case RESTORE_POINTER: NCR710_DEBUG_MSG("restore pointer received\n"); pNcrCtl->pData = pScsiPhysDev->savedTransAddress; pNcrCtl->dataCount = pScsiPhysDev->savedTransLength; localStart = &ackMsg1; break; case SELECT_AS_TARGET: LOG_ERR("selected as a target!!\n"); LOG_ERR_CTXT; status = ERROR; goto exitPhase; default: LOG_ERR("unknown intr script value!!\n"); LOG_ERR("INT STATUS UNKNOWN:0x%08x pScsiPhysDev=0x%08x\n", pSiop->saveScriptIntrStat, pScsiPhysDev); LOG_ERR_CTXT; status = ERROR; transactEnd = (TBOOL) TRUE; break; }contTransaction: /* transaction not yet finish restart script to next phase */ if (transactEnd == FALSE) status = ncr710StartPhase(pSiop, pNcrCtl, localStart,ncr710TimeOut); }exitPhase: if (status == ERROR) NCR710_DEBUG_MSG("exit ERROR from Phase\n"); else NCR710_DEBUG_MSG("exit OK from Phase\n"); /* restore pending command context in case of reselect during a select of a current starting */ semTake (pSiop->pMutexData,WAIT_FOREVER); if ((pScsiPhysDev->devStatus == SELECT_REQUESTED) || (pScsiPhysDev->devStatus == SELECT_TIMEOUT)) pSiop->commandRequest = FALSE; if (pSiop->commandRequest == TRUE) *pSiop->pIstat |= B_SIGP; semGive(pSiop->pMutexData); /* Give semaphore only if it's not after a disconnect/reconnect */ if ((pScsiPhysDev->devStatus == SELECT_REQUESTED) || (pScsiPhysDev->devStatus == SELECT_TIMEOUT)) semGive (&pScsiCtrl->ctrlMutexSem); if (pNcrCtl->dataCount < 0x800) /* flush data */ CACHE_USER_FLUSH (pNcrCtl->pData, pNcrCtl->dataCount); else CACHE_USER_FLUSH (0, ENTIRE_CACHE); /* invalidate scsi status */ CACHE_USER_FLUSH (pNcrCtl->pScsiStatus, pNcrCtl->statusCount); /* Restart Script at the Idle point */ ncr710StartScript (pSiop, pSiop->pNcrCtl, pScsiPhysDev, &waitSelect); return (status); }/********************************************************************************* ncr710ScsiTransact - obtain exclusive use of SCSI controller for a transaction** This routine calls ncr710ScsiPhase() to execute the specified* command. If there are physical path management errors, then* this routine returns ERROR. If not, then the status returned* from the command is checked. If it is "Check Condition", then* a "Request Sense" CCS command is executed and the sense key is* examined. An indication of the success of the command is* returned (OK or ERROR). This routine is almost the same as the* scsiLib. If some modification occurs in the scsiLib.c, the same* change should be done here. ** RETURNS: OK if successful, or ERROR if a path management error occurs* or the status or sense information indicates an error.** NOMANUAL*/LOCAL STATUS ncr710ScsiTransact ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to the target device */ SCSI_TRANSACTION *pScsiXaction /* ptr to the transaction info */ ) { SCSI_CTRL *pScsiCtrl; /* SCSI controller info for device */ SCSI_BLK_DEV_NODE *pBlkDevNode; /* ptr for looping through BLK_DEV list */ STATUS status; /* routine return status */ int senseKey; /* extended sense key from target */ int addSenseCode; /* additional sense code from target */ int taskId = taskIdSelf (); /* calling task's ID */ int taskPriority; /* calling task's current priority */ pScsiCtrl = pScsiPhysDev->pScsiCtrl; /* set task priority to SCSI controller's (if != NONE) */ if (pScsiCtrl->scsiPriority != NONE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -