📄 ncr710lib2.c
字号:
if (scsiStatus & B_STO) { SCSI_INT_DEBUG_MSG ("ncr710EventTypeGet: SCSI bus timeout.\n", 0, 0, 0, 0, 0, 0); *pSiop->pCtest8 |= B_CLF; /* clear FIFOs */ return (NCR710_SCSI_TIMEOUT); } if (scsiStatus & B_MA) { /* * workaround for problem with ATN when selected * by ncr710 (negates and then briefly re-asserts * ATN during REQ/ACK cycle, causing an ATN * interrupt even though ATN ends up negated). * * The "phase mismatch" interrupt is used to indicate assertion of * ATN in target mode. This interrupt should have been disabled * by the script when in target mode, because the current code does * not know how to handle it. */ if (*pSiop->pScntl0 & B_TRG) { if (*pSiop->pSien & B_MA) { logMsg ("ncr710EventTypeGet: enabled ATN interrupt!\n", 0, 0, 0, 0, 0, 0); return (NCR710_FATAL_ERROR); } } else { SCSI_INT_DEBUG_MSG ("ncr710EventTypeGet: phase mismatch.\n", 0, 0, 0, 0, 0, 0); return (NCR710_PHASE_MISMATCH); } } if (dmaStatus & B_ABT) { SCSI_INT_DEBUG_MSG ("ncr710EventTypeGet: script aborted.\n", 0, 0, 0, 0, 0, 0); return (NCR710_SCRIPT_ABORTED); } if (dmaStatus & B_SIR) { SCSI_INT_DEBUG_MSG ("ncr710EventTypeGet: script completed.\n", 0, 0, 0, 0, 0, 0); return (*pSiop->pDsps); } if (dmaStatus & B_SSI) { SCSI_INT_DEBUG_MSG ("ncr710EventTypeGet: single-step.\n", 0, 0, 0, 0, 0, 0); return (NCR710_SINGLE_STEP); } /* * No (expected) reason for the interrupt ! */ logMsg ("ncr710EventTypeGet: spurious interrupt !\n", 0, 0, 0, 0, 0, 0); return (NCR710_FATAL_ERROR); }/******************************************************************************** ncr710ThreadActivate - activate a SCSI connection for an initiator thread** Set whatever thread/controller state variables need to be set. Ensure that* all buffers used by the thread are coherent with the contents of the* system caches (if any).** Set transfer parameters for the thread based on what its target device* last negotiated.** Update the thread context (including shared memory area) and note that* there is a new client script to be activated (see "ncr710Activate()").** Set the thread's state to ESTABLISHED. This is strictly a bit premature,* but there is no distinction as far as this driver is concerned between a* thread which is connecting and one which has connected (i.e., the script* just runs to completion and we have to examine its exit status to determine* how far through the process the thread got).** Do not wait for the script to be activated. Completion of the script will* be signalled by an event which is handled by "ncr710Event()".** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS ncr710ThreadActivate ( SIOP * pSiop, /* ptr to controller info */ NCR710_THREAD * pThread /* ptr to thread info */ ) { SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SCSI_TARGET * pScsiTarget = pScsiThread->pScsiTarget; SCSI_DEBUG_MSG ("ncr710ThreadActivate: thread 0x%08x: activating\n", (int) pThread, 0, 0, 0, 0, 0); scsiCacheSynchronize (pScsiThread, SCSI_CACHE_PRE_COMMAND); /* * Reset controller state variables: set sync xfer parameters */ pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE; pScsiCtrl->msgInState = SCSI_MSG_IN_NONE; scsiSyncXferNegotiate (pScsiCtrl, pScsiTarget, SYNC_XFER_NEW_THREAD); if (ncr710ThreadParamsSet (pThread, pScsiTarget->xferOffset, pScsiTarget->xferPeriod) != OK) { SCSI_ERROR_MSG ("ncr710ThreadActivate: failed to set thread params.\n", 0, 0, 0, 0, 0, 0); return (ERROR); } /* * Concatenate the ident message with a pending 'normal' message out, * if possible. This allows the script to send the first message out * within the same MSG OUT phase as the IDENTIFY message - needed on * some target systems (e.g. DG Clariion RAID) to avoid the message * being rejected(!). */ pSiop->identMsgLength = 0; bcopy (pScsiThread->identMsg, pSiop->identMsg, pScsiThread->identMsgLength); pSiop->identMsgLength += pScsiThread->identMsgLength; if (pScsiCtrl->msgOutState == SCSI_MSG_OUT_PENDING) { bcopy (pScsiCtrl->msgOutBuf, pSiop->identMsg + pSiop->identMsgLength, pScsiCtrl->msgOutLength); pSiop->identMsgLength += pScsiCtrl->msgOutLength; } /* * Update thread context; activate the thread */ ncr710ThreadUpdate (pThread); if (ncr710Activate (pSiop, pThread) != OK) { SCSI_ERROR_MSG ("ncr710ThreadActivate: failed to activate thread.\n", 0, 0, 0, 0, 0, 0); return (ERROR); } pScsiCtrl->pThread = pScsiThread; ncr710ThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED); return (OK); }/******************************************************************************** ncr710ThreadAbort - abort a thread** If the thread is not currently connected, do nothing and return FALSE to* indicate that the SCSI manager should abort the thread.** Otherwise (the thread is active onthe controller), build an ABORT or* ABORT TAG message which will (eventually) be sent, causing the taget to* disconnect. Abort the current script run so that this message can be* sent. Set the state of the thread accordingly, and return TRUE to* indicate that the controller driver will handle the abort process.** RETURNS: TRUE if the thread is being aborted by this driver (i.e. it is* currently active on the controller, else FALSE.** NOMANUAL*/LOCAL BOOL ncr710ThreadAbort ( SIOP * pSiop, /* ptr to controller info */ NCR710_THREAD * pThread /* ptr to thread info */ ) { BOOL tagged; SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SCSI_DEBUG_MSG ("ncr710ThreadAbort: thread 0x%08x (state = %d) aborting\n", (int) pThread, pScsiThread->state, 0, 0, 0, 0); if (pScsiThread != pScsiCtrl->pThread) return (FALSE); switch (pScsiThread->state) { case SCSI_THREAD_INACTIVE: case SCSI_THREAD_WAITING: case SCSI_THREAD_DISCONNECTED: return (FALSE); break; default: /* * Build an ABORT (or ABORT TAG) message. When this has been * sent, the target should disconnect. Mark the thread aborted * and continue until disconnection. */ tagged = (pScsiThread->tagNumber != NONE); pScsiCtrl->msgOutBuf[0] = tagged ? SCSI_MSG_ABORT_TAG : SCSI_MSG_ABORT; pScsiCtrl->msgOutLength = 1; pScsiCtrl->msgOutState = SCSI_MSG_OUT_PENDING; ncr710Abort (pSiop); ncr710ThreadStateSet (pThread, SCSI_THREAD_ABORTING); break; } return (TRUE); }/******************************************************************************** ncr710Event - NCR 53C710 SCSI controller event processing routine** Parse the event type and act accordingly. Controller-level events are* handled within this function, and the event is then passed to the current* thread (if any) for thread-level processing.** Note the special case when (re)selection occurs: if there is a current* thread when the event occurs, it receives the event (and is assumed to* defer itself) before the identification thread is made current. The* event is then forwarded to the identification thread.** RETURNS: N/A*/LOCAL void ncr710Event ( SIOP * pSiop, NCR710_EVENT * pEvent ) { SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; SCSI_EVENT * pScsiEvent = (SCSI_EVENT *) pEvent; NCR710_THREAD * pThread = (NCR710_THREAD *) pScsiCtrl->pThread; SCSI_DEBUG_MSG ("ncr710Event: received event %d (thread = 0x%08x)\n", pScsiEvent->type, (int) pThread, 0, 0, 0, 0); /* * Do controller-level event processing */ switch (pScsiEvent->type) { case NCR710_SELECTED: case NCR710_RESELECTED: /* * Forward event to current thread, if any (it should defer) * then install a reserved thread for identification purposes. */ if (pThread != 0) ncr710ThreadEvent (pThread, pEvent); pScsiCtrl->peerBusId = pScsiEvent->busId; pScsiCtrl->pThread = pScsiCtrl->pIdentThread; pScsiCtrl->pThread->role = (pScsiEvent->type == NCR710_SELECTED) ? SCSI_ROLE_IDENT_TARG : SCSI_ROLE_IDENT_INIT; pThread = (NCR710_THREAD *) pScsiCtrl->pThread; scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_CONNECTED); break; case NCR710_DISCONNECTED: case NCR710_CMD_COMPLETE: case NCR710_UNEXPECTED_DISCON: case NCR710_SCSI_TIMEOUT: pScsiCtrl->peerBusId = NONE; pScsiCtrl->pThread = 0; scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_DISCONNECTED); /* assert (pThread != 0); */ break; case NCR710_SCSI_BUS_RESET: pScsiCtrl->peerBusId = NONE; pScsiCtrl->pThread = 0; scsiMgrBusReset (pScsiCtrl); break; default: /* * Any other event type is assumed to be thread-specific. * The thread event handler will report an error if it's * not a valid type. */ if (pThread == 0) { logMsg ("ncr710Event: invalid event type (%d)\n", pScsiEvent->type, 0, 0, 0, 0, 0); } break; } /* * If there's a thread on the controller, forward the event to it */ if (pThread != 0) ncr710ThreadEvent (pThread, pEvent); } /******************************************************************************** ncr710ThreadEvent - NCR 53C710 thread event processing routine** Forward the event to the proper handler for the thread's current role.** If the thread is still active, update the thread context (including* shared memory area) and resume the thread.** RETURNS: N/A** NOMANUAL*/LOCAL void ncr710ThreadEvent ( NCR710_THREAD * pThread, NCR710_EVENT * pEvent ) { SCSI_EVENT * pScsiEvent = (SCSI_EVENT *) pEvent; SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SIOP * pSiop = (SIOP *) pScsiThread->pScsiCtrl; NCR710_SCRIPT_ENTRY entryPt; SCSI_DEBUG_MSG ("ncr710ThreadEvent: thread 0x%08x: received event %d\n", (int) pThread, pScsiEvent->type, 0, 0, 0, 0); switch (pScsiThread->role) { case SCSI_ROLE_INITIATOR: ncr710InitEvent (pThread, pEvent); entryPt = NCR710_SCRIPT_INIT_CONTINUE; break; case SCSI_ROLE_IDENT_INIT: ncr710InitIdentEvent (pThread, pEvent); entryPt = NCR710_SCRIPT_INIT_CONTINUE; break; case SCSI_ROLE_IDENT_TARG: ncr710TargIdentEvent (pThread, pEvent); entryPt = NCR710_SCRIPT_TGT_DISCONNECT; break; case SCSI_ROLE_TARGET: default: logMsg ("ncr710ThreadEvent: thread 0x%08x: invalid role (%d)\n", (int) pThread, pScsiThread->role, 0, 0, 0, 0); entryPt = NCR710_SCRIPT_TGT_DISCONNECT; break; } /* * Resume thread iff it is still connected */ switch (pScsiThread->state) { case SCSI_THREAD_INACTIVE: case SCSI_THREAD_WAITING: case SCSI_THREAD_DISCONNECTED: break; default: ncr710ThreadUpdate (pThread); if (ncr710Resume (pSiop, pThread, entryPt) != OK) { SCSI_ERROR_MSG ("ncr710ThreadEvent: failed to resume thread\n", 0, 0, 0, 0, 0, 0); ncr710ThreadFail (pThread, S_scsiLib_DISCONNECTED); } break; } }/******************************************************************************** ncr710InitEvent - NCR 53C710 initiator thread event processing routine** Parse the event type and handle it accordingly. This may result in state
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -