📄 mb87030lib.c
字号:
* RETURNS: OK.** NOMANUAL*/STATUS spcManBytesOut ( FAST SPC *pSpc, /* ptr to SPC info */ FAST UINT8 *pBuffer, /* ptr to the output buffer */ FAST int bufLength, /* length of the output buffer */ BOOL atnReset /* whether ATN should be reset on last byte */ ) { FAST int ix; for (ix = 0; ix < bufLength; ix++) { while (!(*pSpc->pPsnsReg & SPC_PSNS_REQ)) ; if (atnReset && (ix == bufLength - 1)) spcCommand (pSpc, SPC_SCMD_RESET_ATN); *pSpc->pTempReg = *pBuffer++; spcCommand (pSpc, SPC_SCMD_SET_ACK_REQ); while (*pSpc->pPsnsReg & SPC_PSNS_REQ) ; spcCommand (pSpc, SPC_SCMD_RESET_ACK_REQ); } return (OK); }/********************************************************************************* spcManBytesIn - input byte(s) from SCSI using manual transfer** RETURNS: OK.** NOMANUAL*/STATUS spcManBytesIn ( FAST SPC *pSpc, /* ptr to SPC info */ FAST UINT8 *pBuffer, /* ptr to the input buffer */ FAST int bufLength /* length of the input buffer */ ) { FAST int ix; for (ix = 0; ix < bufLength; ix++) { while (!(*pSpc->pPsnsReg & SPC_PSNS_REQ)) ; spcCommand (pSpc, SPC_SCMD_SET_ACK_REQ); while (*pSpc->pPsnsReg & SPC_PSNS_REQ) ; *pBuffer++ = *pSpc->pTempReg; spcCommand (pSpc, SPC_SCMD_RESET_ACK_REQ); } semGive (&pSpc->scsiCtrl.ctrlSyncSem); return (OK); }/********************************************************************************* spcMsgInAck - de-assert the ACK line to accept message** This routine should be called when an incoming message has been read and* accepted. If the incoming message did not imply an impending disconnect,* give the synchronization semaphore, so that subsequent phase can be* detected.** RETURNS: OK.*/LOCAL STATUS spcMsgInAck ( FAST SCSI_CTRL *pScsiCtrl, /* ptr to SPC info */ BOOL expectDisconn /* whether a disconnect is expected */ ) { spcCommand ((SPC *) pScsiCtrl, SPC_SCMD_RESET_ACK_REQ); if (!expectDisconn) semGive (&pScsiCtrl->ctrlSyncSem); return (OK); }/********************************************************************************* spcProgBytesOut - output bytes to SCSI using 'program' transfer** RETURNS: OK if successful, otherwise ERROR.** INTERNAL* Error handling is inadequate.** NOMANUAL*/STATUS spcProgBytesOut ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to physical device info */ FAST UINT8 *pBuffer, /* ptr to the data buffer */ FAST int bufLength, /* number of bytes to be transferred */ int scsiPhase /* phase of the transfer */ ) { FAST SPC *pSpc; /* ptr to SPC info */ SCSI_DEBUG_MSG ("spcProgBytesOut: bufLength = %d, scsiPhase = %d\n", bufLength, scsiPhase, 0, 0, 0, 0); pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; spcIntsDisable (pSpc); if (spcXferCountSet (pSpc, bufLength) == ERROR) return (ERROR); SPC_BUS_PHASE_SET(pSpc, scsiPhase); if (scsiPhase == SCSI_COMMAND_PHASE) spcTmodSet (pSpc, pScsiPhysDev->syncXfer, 0, 0); spcScmdSet (pSpc, SPC_SCMD_XFER, 0, 0, 1, 0); while (!(*pSpc->pSstsReg & SPC_SSTS_XFER)) ; while (bufLength >= 8) { while (!(*pSpc->pSstsReg & SPC_SSTS_DREG_EMPTY)) ; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; *pSpc->pDregReg = *pBuffer++; bufLength -= 8; } while (!(*pSpc->pSstsReg & SPC_SSTS_DREG_EMPTY)) ; while (bufLength > 0) { *pSpc->pDregReg = *pBuffer++; bufLength--; } spcIntsEnable (pSpc); return (OK); }/********************************************************************************* spcProgBytesIn - input bytes from SCSI using 'program' transfer** RETURNS: OK if successful, otherwise ERROR.** INTERNAL* Error handling is inadequate.** NOMANUAL*/STATUS spcProgBytesIn ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to physical device info */ FAST UINT8 *pBuffer, /* ptr to the data buffer */ FAST int bufLength, /* number of bytes to be transferred */ int scsiPhase /* phase of the transfer */ ) { FAST SPC *pSpc; /* ptr to SPC info */ SCSI_DEBUG_MSG ("spcProgBytesIn: bufLength = %d, scsiPhase = %d\n", bufLength, scsiPhase, 0, 0, 0, 0); pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; spcIntsDisable (pSpc); if (spcXferCountSet (pSpc, bufLength) == ERROR) return (ERROR); SPC_BUS_PHASE_SET(pSpc, scsiPhase); spcScmdSet (pSpc, SPC_SCMD_XFER, 0, 0, 1, 0); while (!(*pSpc->pSstsReg & SPC_SSTS_XFER)) ; while (bufLength >= 8) { while (!(*pSpc->pSstsReg & SPC_SSTS_DREG_FULL)) ; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; *pBuffer++ = *pSpc->pDregReg; bufLength -= 8; } while (bufLength > 0) { while (*pSpc->pSstsReg & SPC_SSTS_DREG_EMPTY) ; *pBuffer++ = *pSpc->pDregReg; bufLength--; } spcIntsEnable (pSpc); return (OK); }/******************************************************************************** spcDmaBytesOut - Setup DMA transfer on the device** RETURNS: OK, or ERROR if the count is not set properly.*/LOCAL STATUS spcDmaBytesOut ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to phys dev info */ UINT8 *pBuffer, /* prt to the data buffer */ int bufLength, /* nubmer of bytes to xfer */ int scsiPhase ) { FAST SPC *pSpc; /* ptr to SPC info */ SCSI_DEBUG_MSG ("spcDmaBytesOut: bufLength = %d, Address = %08x\n", bufLength, (int) &pBuffer, 0, 0, 0, 0); pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; spcIntsDisable (pSpc); if (spcXferCountSet (pSpc, bufLength) == ERROR) return (ERROR); SPC_BUS_PHASE_SET(pSpc, scsiPhase); if (scsiPhase == SCSI_COMMAND_PHASE) spcTmodSet (pSpc, pScsiPhysDev->syncXfer, 0, 0); spcScmdSet (pSpc, SPC_SCMD_XFER, 0, 0, 0, 0); return ((pSpc->scsiCtrl.scsiDmaBytesOut) (pScsiPhysDev, (UINT8 *) pBuffer, bufLength)); } /********************************************************************************* spcBytesOut - branch to the appropriate output routine dependent on SCSI phase** RETURNS: OK if specified bytes were output successfully, otherwise ERROR.*/LOCAL STATUS spcBytesOut ( FAST SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to SCSI physical dev info */ FAST char *pBuffer, /* ptr to byte buffer for output */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* SCSI bus phase of the transfer */ ) { FAST SPC *pSpc; /* ptr to SPC info */ pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; if ((scsiPhase != SCSI_DATA_OUT_PHASE) || (pSpc->scsiCtrl.scsiDmaBytesOut == NULL) || (bufLength < 10)) return (spcProgBytesOut (pScsiPhysDev, (UINT8 *) pBuffer, bufLength, scsiPhase)); else return ((spcDmaBytesOut) (pScsiPhysDev, (UINT8 *) pBuffer, bufLength, scsiPhase)); }/******************************************************************************** spcDmaBytesIn - Setup DMA transfer on the device** RETURNS: OK, or ERROR if the count is not set properly.*/LOCAL STATUS spcDmaBytesIn ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to phys dev info */ UINT8 *pBuffer, /* prt to the data buffer */ int bufLength, /* nubmer of bytes to xfer */ int scsiPhase ) { FAST SPC *pSpc; /* ptr to SPC info */ SCSI_DEBUG_MSG ("spcDmaBytesIn: bufLength = %d, Addr = %08x\n", bufLength, (int) &pBuffer, 0, 0, 0, 0); pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; spcIntsDisable (pSpc); if (spcXferCountSet (pSpc, bufLength) == ERROR) return (ERROR); SPC_BUS_PHASE_SET(pSpc, scsiPhase); spcScmdSet (pSpc, SPC_SCMD_XFER, 0, 0, 0, 0); return ((pSpc->scsiCtrl.scsiDmaBytesIn) (pScsiPhysDev, (UINT8 *) pBuffer, bufLength)); }/********************************************************************************* spcBytesIn - branch to the appropriate input routine dependent on SCSI phase** RETURNS: OK if requested bytes were input successfully, otherwise ERROR.*/LOCAL STATUS spcBytesIn ( FAST SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to SCSI physical dev info */ FAST char *pBuffer, /* ptr to byte buffer for output */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* SCSI bus phase of the transfer */ ) { FAST SPC *pSpc; /* ptr to SPC info */ pSpc = (SPC *) pScsiPhysDev->pScsiCtrl; switch (scsiPhase) { case SCSI_DATA_IN_PHASE: if ((pSpc->scsiCtrl.scsiDmaBytesIn == NULL) || (bufLength < 10)) return (spcProgBytesIn (pScsiPhysDev, (UINT8 *) pBuffer, bufLength, scsiPhase)); else return (spcDmaBytesIn (pScsiPhysDev, (UINT8 *) pBuffer, bufLength, scsiPhase)); case SCSI_STATUS_PHASE: return (spcProgBytesIn (pScsiPhysDev, (UINT8 *) pBuffer, bufLength, scsiPhase)); case SCSI_MSG_IN_PHASE: return (spcManBytesIn (pSpc, (UINT8 *) pBuffer, bufLength)); } return (ERROR); }#define CYCLES_PER_USEC 1/********************************************************************************* spcBusPhaseGet - return the current SCSI bus phase in *pBusPhase** INTERNAL* Should do an errnoSet.*/LOCAL STATUS spcBusPhaseGet ( FAST SCSI_CTRL *pScsiCtrl, /* ptr to SCSI controller info */ int timeOutInUsec, /* timeout in usec (0 == infinity) */ int *pBusPhase /* ptr to returned bus phase */ ) { FAST int ix = 0; /* loop index */ FAST SPC *pSpc; /* ptr to SPC info */ FAST int maxCycles; /* maximum cycles to wait for REQ signal */ pSpc = (SPC *) pScsiCtrl; maxCycles = timeOutInUsec * CYCLES_PER_USEC; if (semTake (&pScsiCtrl->ctrlSyncSem, sysClkRateGet() * 5) == ERROR) { spcScsiBusReset (pSpc); /* the bus is hung(?), reset it */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -