📄 sym895lib.c
字号:
if (((pSiop->pCurThread->sxfer) & SYM895_SXFER_OFF_MASK) != 0) { if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT0) & SYM895_SSTAT0_OLF) tmpCount++; if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) & SYM895_SSTAT2_OLF1) tmpCount++; } /* Finally, add this to "remCount" to get the complete count */ remCount += tmpCount; break; case PHASE_DATA_IN : case PHASE_MSG_IN : case PHASE_STATUS : /* These are input phases check for data in input registers */ /* The following for asynchronous transfers */ if (((pSiop->pCurThread->sxfer) & SYM895_SXFER_OFF_MASK) == 0) { if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT0) & SYM895_SSTAT0_ILF) tmpCount++; if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) & SYM895_SSTAT2_ILF1) tmpCount++; } else { /* * For Sync. transfers add the total count, the number of bytes * in the sync FIFO. */ tmpCount += (((SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT1) & 0xf0)>>4) | (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) & 0x10)); } break; default : SCSI_MSG ("sym895RemainderGet: Invalid Phase %d\n", phase, 0, 0, 0, 0, 0); } /* Clear FiFos */ SYM895_REG8_WRITE (pSiop, SYM895_OFF_CTEST3, SYM895_REG8_READ (pSiop,SYM895_OFF_CTEST3)| SYM895_CTEST3_CLF); return (remCount); } /********************************************************************************* sym895Event - 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 sym895Event ( SIOP * pSiop, SYM895_EVENT * pEvent ) { SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; SCSI_EVENT * pScsiEvent = &pEvent->scsiEvent; SYM895_THREAD * pThread = (SYM895_THREAD *) pScsiCtrl->pThread; SYM895_SCSI_DEBUG_MSG ("sym895Event:received event %d (thread = 0x%08x)\n", pScsiEvent->type, (int) pThread, 0, 0, 0, 0); /* Do controller-level event processing */ switch (pScsiEvent->type) { case SYM895_SELECTED: case SYM895_RESELECTED: /* * Forward event to current thread, if any (it should defer) * then install a reserved thread for identification purposes. */ if (pThread != 0) sym895ThreadEvent (pThread, pEvent); pScsiCtrl->peerBusId = pScsiEvent->busId; pScsiCtrl->pThread = pScsiCtrl->pIdentThread; pScsiCtrl->pThread->role = (pScsiEvent->type == SCSI_EVENT_SELECTED) ? SCSI_ROLE_IDENT_TARG : SCSI_ROLE_IDENT_INIT; pThread = (SYM895_THREAD *) pScsiCtrl->pThread; scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_CONNECTED); break; case SYM895_DISCONNECTED: case SYM895_CMD_COMPLETE: case SYM895_UNEXPECTED_DISCON: case SYM895_SCSI_TIMEOUT: pScsiCtrl->peerBusId = NONE; pScsiCtrl->pThread = 0; scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_DISCONNECTED); break; case SYM895_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) { SCSI_MSG ("sym895Event 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) sym895ThreadEvent (pThread, pEvent); } /******************************************************************************** sym895ThreadInit - initialize a client thread structure** Initialize the fixed data for a thread (i.e., independent of the command).* Called once when a thread structure is first created.** RETURNS OK, or ERROR if an error occurs** NOMANUAL*/LOCAL STATUS sym895ThreadInit ( SIOP * pSiop, SYM895_THREAD * pThread ) { if (scsiThreadInit (&pThread->scsiThread) != OK) return (ERROR); pThread->pShMem = pSiop->pClientShMem; pThread->scntl3 = pSiop->clkDiv; return (OK); }/******************************************************************************** sym895IdentThreadInit - initialize an identification thread structure** Set up pointers and counts for all buffers other than messages. Also set* transfer parameters for asynchronous mode, and update the shared memory* area to match this thread.** NOTE:* The pointers/counts set here are normally never used by the identification* thread; however, when an identification thread is aborted, it's possible* that the target will attempt to transfer one or more non-message bytes* before requesting the abort message out. To handle this, the thread's* pointers and counts all specify a dummy buffer. There is no re-entrancy* problem here because we do not care what data is transferred. This might* be handled more elegantly if there were a special script entry to abort* an identification thread.** RETURNS: OK, or ERROR if an error occurs** NOMANUAL*/LOCAL STATUS sym895IdentThreadInit ( SYM895_THREAD * pThread ) { SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread; SIOP * pSiop = (SIOP *) pScsiThread->pScsiCtrl; static UINT8 dummy; /* * Initialise Pointers and counts in thread */ pScsiThread->cmdLength = 1; pScsiThread->cmdAddress = &dummy; pScsiThread->dataLength = 1; pScsiThread->dataAddress = &dummy; pScsiThread->activeDataLength = 1; pScsiThread->activeDataAddress = &dummy; pScsiThread->savedDataLength = 1; pScsiThread->savedDataAddress = &dummy; pScsiThread->statusLength = 1; pScsiThread->statusAddress = &dummy; pScsiThread->identMsgLength = 1; /* * Initialise SIOP register context in thread */ pThread->nHostFlags = 0; pThread->msgOutStatus = SCSI_MSG_OUT_NONE; pThread->msgInStatus = SCSI_MSG_IN_NONE; pThread->sxfer = SYM895_ASYNC_SXFER; /* * The value set in scntl3 for the ident message is chosen based on the. * following reasons ... * 1. Ident message is Async by default. So the bits SCFx donot matter now. * 2. The target can be an Ultra SCSI or just FAST SCSI, so can't * enable those ULTRA bits now, effectively ruling out the possibility * of using 160/80 MHz SCSI Clocks for ident message. * 3. We chose to hardcode the value of 50 Mhz into scntl3 for ident * message. After negotiation, these values will suitably be changed. */ pThread->scntl3 = SYM895_3750MHZ_ASYNC_DIV; /* Hard Code */ /* pThread->scntl3 = pSiop->clkDiv; */ /* Initialise shared memory area */ pThread->pShMem = pSiop->pIdentShMem; sym895SharedMemInit (pSiop, pThread->pShMem); sym895ThreadUpdate (pThread); return (OK); }/******************************************************************************** sym895SharedMemInit - initialize the fields in a shared memory area** Initialise pointers and counts for all message transfers. These are* always directed to buffers provided by the SCSI_CTRL structure.** RETURNS: N/A** NOMANUAL*/LOCAL void sym895SharedMemInit ( SIOP * pSiop, SYM895_SHARED * pShMem ) { /* * Note: All the values being set in the shared memory need to be * 32 bit byte swapped. Actual swapping takes place when, when memory * is big endian (since the SYM895 is a little endian PCI device. * Otherwise, if memory is little endian then the byte swapping * does not do anything. The "endianness" is configurable at compile * time. * * Similarly, a PCI offset is added to all addresses so that the * SYM895 PCI chip can get to memory. This value is also configurable * at compile time. */ pShMem->identIn.size = SYM895_SWAP_32 (1); pShMem->identIn.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS (pSiop->scsiCtrl.identBuf)); pShMem->msgOut.size = SYM895_SWAP_32 (0); /* set dynamically */ pShMem->msgOut.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS (pSiop->scsiCtrl.msgOutBuf)); pShMem->msgIn.size = SYM895_SWAP_32 (1); pShMem->msgIn.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS (pSiop->scsiCtrl.msgInBuf)); pShMem->msgInSecond.size = SYM895_SWAP_32 (1); pShMem->msgInSecond.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS (pSiop->scsiCtrl.msgInBuf) + (UINT) 1); pShMem->msgInRest.size = SYM895_SWAP_32 (0); /* set dynamically */ pShMem->msgInRest.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS (pSiop->scsiCtrl.msgInBuf) + (UINT) 2); }/******************************************************************************** sym895ThreadActivate - 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 "sym895Activate()").** Set the thread's state to ESTABLISHED.* Do not wait for the script to be activated. Completion of the script will* be signalled by an event which is handled by "sym895Event()".** RETURNS OK or ERROR** NOMANUAL*/LOCAL STATUS sym895ThreadActivate ( SIOP * pSiop, /* pointer to SIOP structure */ SYM895_THREAD * pThread /* pointer to thread structure */ ) { SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; SCSI_THREAD * pScsiThread = &pThread->scsiThread; SCSI_TARGET * pScsiTarget = pScsiThread->pScsiTarget; SYM895_SCSI_DEBUG_MSG ("sym895ThreadActivate: thread 0x%08x activating\n", (int) pThread, 0, 0, 0, 0, 0); /* Ensure buffers used by the thread are coherent with system cache */ scsiCacheSynchronize (pScsiThread, SCSI_CACHE_PRE_COMMAND); /* Reset controller state variables set sync xfer parameters */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -