📄 ncr710lib2.c
字号:
*/LOCAL void ncr710InitEvent ( NCR710_THREAD * pThread, NCR710_EVENT * pEvent ) { SCSI_EVENT * pScsiEvent = (SCSI_EVENT *) pEvent; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SCSI_CTRL * pScsiCtrl = pScsiThread->pScsiCtrl; /* * Update controller msg in/out state after script completes */ pScsiCtrl->msgOutState = pThread->nMsgOutState; pScsiCtrl->msgInState = pThread->nMsgInState; /* * Parse script exit status; handle as necessary */ switch (pScsiEvent->type) { case NCR710_DISCONNECTED: SCSI_DEBUG_MSG ("DISCONNECT message in\n", 0, 0, 0, 0, 0, 0); scsiMgrThreadEvent (pScsiThread, SCSI_THREAD_EVENT_DISCONNECTED); ncr710ThreadStateSet (pThread, SCSI_THREAD_DISCONNECTED); break; case NCR710_CMD_COMPLETE: SCSI_DEBUG_MSG ("COMMAND COMPLETE message in\n", 0, 0, 0, 0, 0, 0); ncr710ThreadComplete (pThread); break; case NCR710_SELECTED: case NCR710_RESELECTED: SCSI_DEBUG_MSG ("ncr710InitEvent: thread 0x%08x: (re)selection.\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadDefer (pThread); break; case NCR710_MESSAGE_OUT_SENT: (void) scsiMsgOutComplete (pScsiCtrl, pScsiThread); break; case NCR710_MESSAGE_IN_RECVD: (void) scsiMsgInComplete (pScsiCtrl, pScsiThread); break; case NCR710_NO_MSG_OUT: /* * The target has requested a message out when there is none * pending. Set up a NO-OP message to be sent when thread is * resumed. * * The script could handle this on its own, but arguably the * host should be involved as it may represent an error. */ pScsiCtrl->msgOutBuf[0] = SCSI_MSG_NO_OP; pScsiCtrl->msgOutLength = 1; pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE; /* sic */ break; case NCR710_EXT_MESSAGE_SIZE: /* * The SIOP has just read the length byte for an extended * message in. The shared memory area is updated with the * appropriate length just before the thread is resumed (see * "ncr710ThreadUpdate()". */ /* assert (pScsiCtrl->msgInState == SCSI_MSG_IN_EXT_MSG_DATA); */ break; case NCR710_PHASE_MISMATCH: if (ncr710PhaseMismatch (pThread, pThread->nBusPhase, pEvent->remCount) != OK) { ncr710ThreadFail (pThread, errno); } break; case NCR710_SCSI_TIMEOUT: SCSI_ERROR_MSG ("ncr710InitEvent: thread 0x%08x: select timeout.\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_SELECT_TIMEOUT); break; case NCR710_SCRIPT_ABORTED: SCSI_DEBUG_MSG ("ncr710InitEvent: thread 0x%08x: aborted\n", (int) pThread, 0, 0, 0, 0, 0); break; case NCR710_SCSI_BUS_RESET: SCSI_DEBUG_MSG ("ncr710InitEvent: thread 0x%08x: bus reset\n", (int) pThread, 0, 0, 0, 0, 0); /* * Do not try to resume this thread. SCSI mgr will tidy up. */ ncr710ThreadStateSet (pThread, SCSI_THREAD_INACTIVE); break; case NCR710_UNEXPECTED_DISCON: /* not really unexpected after an abort message ... */ SCSI_ERROR_MSG ("ncr710InitEvent: thread 0x%08x: " "unexpected disconnection\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_DISCONNECTED); break; case NCR710_ILLEGAL_PHASE: SCSI_ERROR_MSG ("ncr710InitEvent: thread 0x%08x: " "illegal phase requested.\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_INVALID_PHASE); break; default: logMsg ("ncr710InitEvent: invalid event type (%d)\n", pScsiEvent->type, 0, 0, 0, 0, 0); break; } } /******************************************************************************** ncr710InitIdentEvent - NCR 53C710 identification thread event processing routine** Parse the event type and handle it accordingly. This may result in state* changes for the thread, state variables being updated, etc.** RETURNS: N/A** NOMANUAL*/LOCAL void ncr710InitIdentEvent ( NCR710_THREAD * pThread, NCR710_EVENT * pEvent ) { SCSI_EVENT * pScsiEvent = (SCSI_EVENT *) pEvent; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SCSI_CTRL * pScsiCtrl = pScsiThread->pScsiCtrl; /* * Update controller msg in/out state after script completes */ pScsiCtrl->msgOutState = pThread->nMsgOutState; pScsiCtrl->msgInState = pThread->nMsgInState; /* * Parse script exit status; handle as necessary */ switch (pScsiEvent->type) { case NCR710_RESELECTED: pScsiThread->nBytesIdent = pScsiEvent->nBytesIdent; bcopy ((char *) pScsiCtrl->identBuf, (char *) pScsiThread->identMsg, pScsiThread->nBytesIdent); ncr710ThreadStateSet (pThread, SCSI_THREAD_IDENT_IN); ncr710IdentInContinue (pThread); break; case NCR710_MESSAGE_OUT_SENT: /* * This will be after we have sent an "ABORT (TAG)" msg. * The target will disconnect any time; it may have already * done so, in which case we won't be able to resume the * thread, but no matter. */ break; case NCR710_MESSAGE_IN_RECVD: /* * Continue parsing the identification message. It * should by now be complete. */ /* * First byte of ident msg is already in ident buffer. * Remaining bytes are in the normal message input buffer. * This should always be a two-byte message (viz. QUEUE TAG); * it would be nicer if there were a way to avoid hard-coding * this. */ bcopy ((char *) pScsiCtrl->msgInBuf, (char *) pScsiThread->identMsg + pScsiThread->nBytesIdent, 2); pScsiThread->nBytesIdent += 2; ncr710IdentInContinue (pThread); break; case NCR710_SCRIPT_ABORTED: SCSI_DEBUG_MSG ("ncr710InitIdentEvent: thread 0x%08x: aborted\n", (int) pThread, 0, 0, 0, 0, 0); break; case NCR710_DISCONNECTED: SCSI_DEBUG_MSG ("ncr710InitIdentEvent: thread 0x%08x: disconnected\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_DISCONNECTED); break; case NCR710_SCSI_BUS_RESET: SCSI_DEBUG_MSG ("ncr710InitIdentEvent: thread 0x%08x: bus reset\n", (int) pThread, 0, 0, 0, 0, 0); /* * Do not try to resume this thread. SCSI mgr will tidy up. */ ncr710ThreadStateSet (pThread, SCSI_THREAD_INACTIVE); break; case NCR710_UNEXPECTED_DISCON: /* not really unexpected after an abort message ... */ SCSI_ERROR_MSG ("ncr710InitIdentEvent: thread 0x%08x: " "unexpected disconnection\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_DISCONNECTED); break; case NCR710_ILLEGAL_PHASE: SCSI_ERROR_MSG ("ncr710InitIdentEvent: thread 0x%08x: " "illegal phase requested.\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_INVALID_PHASE); break; default: logMsg ("ncr710InitIdentEvent: invalid event type (%d)\n", pScsiEvent->type, 0, 0, 0, 0, 0); break; } } /******************************************************************************** ncr710TargIdentEvent - NCR 53C710 identification thread event processing routine** Parse the event type and handle it accordingly. This may result in state* changes for the thread, state variables being updated, etc.** RETURNS: N/A** NOMANUAL*/LOCAL void ncr710TargIdentEvent ( NCR710_THREAD * pThread, NCR710_EVENT * pEvent ) { SCSI_EVENT * pScsiEvent = (SCSI_EVENT *) pEvent; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SCSI_CTRL * pScsiCtrl = pScsiThread->pScsiCtrl; /* * Update controller msg in/out state after script completes */ pScsiCtrl->msgOutState = pThread->nMsgOutState; pScsiCtrl->msgInState = pThread->nMsgInState; /* * Parse script exit status; handle as necessary */ switch (pScsiEvent->type) { case NCR710_SELECTED: pScsiThread->nBytesIdent = pScsiEvent->nBytesIdent; bcopy ((char *) pScsiCtrl->identBuf, (char *) pScsiThread->identMsg, pScsiThread->nBytesIdent); ncr710ThreadStateSet (pThread, SCSI_THREAD_IDENT_IN); break; case NCR710_DISCONNECTED: SCSI_DEBUG_MSG ("ncr710TargIdentEvent: thread 0x%08x: disconnected\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadStateSet (pThread, SCSI_THREAD_INACTIVE); break; case NCR710_SCSI_BUS_RESET: SCSI_DEBUG_MSG ("ncr710TargIdentEvent: thread 0x%08x: bus reset\n", (int) pThread, 0, 0, 0, 0, 0); /* * Do not try to resume this thread. SCSI mgr will tidy up. */ ncr710ThreadStateSet (pThread, SCSI_THREAD_INACTIVE); break; case NCR710_UNEXPECTED_DISCON: SCSI_ERROR_MSG ("ncr710TargIdentEvent: thread 0x%08x: " "unexpected disconnection\n", (int) pThread, 0, 0, 0, 0, 0); ncr710ThreadStateSet (pThread, SCSI_THREAD_INACTIVE); break; default: logMsg ("ncr710TargIdentEvent: invalid event type (%d)\n", pScsiEvent->type, 0, 0, 0, 0, 0); break; } } /********************************************************************************* ncr710PhaseMismatch - recover from a SCSI bus phase mismatch** This routine does whatever is required to keep the pointers, counts, etc.* used by task-level software in step when a SCSI phase mismatch occurs.** The interrupt-level mismatch processing has stored the phase of the* information transfer before the mismatch, and the number of bytes* remaining to be transferred. See "ncr710RemainderGet()".** Note that the only phase mismatches supported at this level are:** 1) during data in/out phases - presumably because the target has* transferred as much data as it intends to before sending a message* in (typically DISCONNECT or COMMAND COMPLETE). Recovery consists* of updating the active data pointer/count according to the number* of data bytes actually transferred before the mismatch.** 2) during a message out phase - presumably because the target does not* understand our outgoing message and is sending a MESSAGE REJECT* message, or similar. No recovery is needed here - it's all done* when the MESSAGE REJECT message has been received (see routine* "scsiMsgOutReject()").** 3) during a message in phase - presumably because we have asserted ATN* to abort or reject an incoming message. No recovery is needed here -* it's done by the thread management code, which should have enough* state information to know what to do.** RETURNS: OK, or ERROR for an unsupported or invalid phase** NOMANUAL*/LOCAL STATUS ncr710PhaseMismatch ( NCR710_THREAD * pThread, /* ptr to thread info */ int phase, /* bus phase before mismatch */ UINT remCount /* # bytes not yet transferred */ ) { SCSI_THREAD *pScsiThread = (SCSI_THREAD *) pThread; UINT xferCount; switch (phase) { case SCSI_DATA_IN_PHASE: case SCSI_DATA_OUT_PHASE: xferCount = pThread->pShMem->data.size - remCount; pScsiThread->activeDataAddress += xferCount; pScsiThread->activeDataLength -= xferCount; SCSI_DEBUG_MSG ("ncr710PhaseMismatch: data transfer aborted " "(%d of %d bytes transferred).\n", xferCount, pThread->pShMem->data.size, 0, 0, 0, 0); break; case SCSI_MSG_OUT_PHASE: SCSI_DEBUG_MSG("ncr710PhaseMismatch: message out aborted " "(%d of %d bytes sent).\n", pScsiThread->pScsiCtrl->msgOutLength, pScsiThread->pScsiCtrl->msgOutLength - remCount, 0, 0, 0, 0); /* Abort the Out message */ pScsiThread->pScsiCtrl->msgOutLength = 0; pScsiThread->pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE; ncr710ResetATN(pScsiThread->pScsiCtrl); break; case SCSI_MSG_IN_PHASE: SCSI_DEBUG_MSG("ncr710PhaseMismatch: message in aborted " "(%d bytes received).\n", pScsiThread->pScsiCtrl->msgInLength, 0, 0, 0, 0, 0); break; case SCSI_COMMAND_PHASE: case SCSI_STATUS_PHASE: SCSI_ERROR_MSG ("ncr710PhaseMismatch: unsupported phase (%d).\n", phase, 0, 0, 0, 0, 0); return (ERROR); d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -