📄 templatescsi1.c
字号:
}/********************************************************************************* templateProgBytesOut - output bytes using programmed i/o** This routine is called from templateBytesOut to output data in programmed* i/o mode. This presumes that no DMA output routine exists, or we are* not in data out phase.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS templateProgBytesOut ( SCSI_PHYS_DEV* pScsiPhysDev,/* ptr to physical device info */ UINT8* pBuffer, /* ptr to the data buffer */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* phase of the transfer */ ) { TEMPLATE_DEV *pDev; /* ptr to TEMPLATE_DEV info */ pDev = (TEMPLATE_DEV *) pScsiPhysDev->pScsiCtrl; if (bufLength <= 0) return OK; /* TODO - give any setup commands */ while (bufLength > 0) { /* TODO - output byte at pBuffer, exit on error */ pBuffer++; bufLength--; } return (OK); }/********************************************************************************* templateProgBytesIn - input bytes from SCSI using programmed i/o** Read bytes during any input mode.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS templateProgBytesIn ( SCSI_PHYS_DEV *pScsiPhysDev,/* ptr to physical device info */ UINT8 *pBuffer, /* ptr to the data buffer */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* phase of the transfer */ ) { TEMPLATE_DEV *pDev; /* ptr to TEMPLATE_DEV info */ if (bufLength <= 0) return OK; pDev = (TEMPLATE_DEV *) pScsiPhysDev->pScsiCtrl; /* TODO - give any appropriate setup commands */ while (bufLength > 0) { *pBuffer++ = 0; /* TODO - transfer one byte to *pBuffer, exit on error */ bufLength--; } /* send ack to terminate msgin phase */ if (scsiPhase == SCSI_MSG_IN_PHASE) { templateMsgInAck ((SCSI_CTRL *) pScsiPhysDev->pScsiCtrl, TRUE); } return (OK); }/********************************************************************************* templateBytesOut - write bytes to SCSI data-out phase** This routine is called from scsi1Lib to output data.* Data is written using either the programmed out routine, or the dma* out routine. DMA is only used during the data out* phase. Programmed output is used for all other phases.** RETURNS: OK if specified bytes were output successfully, otherwise ERROR.*/LOCAL STATUS templateBytesOut ( SCSI_PHYS_DEV* pScsiPhysDev, /* ptr to SCSI physical dev info */ char* pBuffer, /* ptr to byte buffer for output */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* SCSI bus phase of the transfer */ ) { TEMPLATE_DEV *pDev; /* ptr to TEMPLATE_DEV info */ STATUS status; /* local status for iterative xfers */ int xferLength; /* local length for iterative xfers */ pDev = (TEMPLATE_DEV *) pScsiPhysDev->pScsiCtrl; while (bufLength > 0) { xferLength = min (bufLength, TEMPLATE_MAX_XFER_LENGTH); if ((scsiPhase != SCSI_DATA_OUT_PHASE) || (pDev->scsiCtrl.scsiDmaBytesOut == NULL)) { status = templateProgBytesOut (pScsiPhysDev, (UINT8 *) pBuffer, xferLength, scsiPhase); } else { status = (pDev->scsiCtrl.scsiDmaBytesOut) (pScsiPhysDev, (UINT8 *) pBuffer, xferLength); } /* if ERROR was returned, exit now */ if (status != OK) break; pBuffer += TEMPLATE_MAX_XFER_LENGTH; bufLength -= TEMPLATE_MAX_XFER_LENGTH; } return (status); }/********************************************************************************* templateBytesIn - read bytes from SCSI data in phase** Read data from SCSI. Programmed i/o is used for all phases other than* data in. For data in phase, DMA input will be used if available, otherwise* programmed input is used for data in phase too.** RETURNS: OK if requested bytes were input successfully, otherwise ERROR.*/LOCAL STATUS templateBytesIn ( SCSI_PHYS_DEV* pScsiPhysDev,/* ptr to SCSI physical dev info */ char* pBuffer, /* ptr to byte buffer for output */ int bufLength, /* number of bytes to be transferred */ int scsiPhase /* SCSI bus phase of the transfer */ ) { TEMPLATE_DEV* pDev; /* ptr to TEMPLATE_DEV info */ STATUS status = OK; /* local status for iterative xfers */ int xferLength; /* local length for iterative xfers */ pDev = (TEMPLATE_DEV *) pScsiPhysDev->pScsiCtrl; while (bufLength > 0) { xferLength = min (bufLength, TEMPLATE_MAX_XFER_LENGTH); if ((scsiPhase != SCSI_DATA_IN_PHASE) || (pDev->scsiCtrl.scsiDmaBytesIn == NULL)) { status = templateProgBytesIn (pScsiPhysDev, (UINT8 *) pBuffer, xferLength, scsiPhase); } else { status = (pDev->scsiCtrl.scsiDmaBytesIn) (pScsiPhysDev, (UINT8 *) pBuffer, xferLength); } if (status != OK) break; pBuffer += TEMPLATE_MAX_XFER_LENGTH; bufLength -= TEMPLATE_MAX_XFER_LENGTH; } return (status); }/********************************************************************************* templateBusPhaseGet - return the current SCSI bus phase in *pBusPhase** This template driver tries to remember the current bus state with* each interrupt. It is usually more efficient to return data from* memory than to do an i/o cycle.** RETURNS: OK, always.*/LOCAL STATUS templateBusPhaseGet ( SCSI_CTRL* pScsiCtrl, /* ptr to SCSI controller info */ int timeOutInUsec, /* timeout in usec (0 == infinity) */ int* pBusPhase /* ptr to returned bus phase */ ) { TEMPLATE_DEV *pDev; /* ptr to TEMPLATE_DEV info */ pDev = (TEMPLATE_DEV *) pScsiCtrl; /* * TODO - if current bus phase was stored in memory from * last interrupt cycle, then return that information. * Otherwise, read bus phase from device. */ return (OK); }/********************************************************************************* templateSelTimeOutCvt - convert a select time-out in microseconds to its* equivalent TEMPLATE_DEV setting** Also, the TEMPLATE_DEV accepts up to a 8 bit time-out, so a maximum value* of 0xff is returned in *pTimeOutSetting.*/LOCAL void templateSelTimeOutCvt ( SCSI_CTRL* pScsiCtrl, /* ptr to SCSI controller info */ UINT timeOutInUsec, /* time-out in microsecs */ UINT* pTimeOutSetting /* time-out equivalent setting */ ) { /* * TODO - convert microseconds to device data. * Store at *pTimeOutSetting */ }/********************************************************************************* templateBusIdGet - get the current SCSI bus ID of the TEMPLATE_DEV.** Copies the bus ID to <pBusId>.** RETURNS:* OK if Bus ID register holds a legal value, otherwise ERROR.*/LOCAL STATUS templateBusIdGet ( TEMPLATE_DEV* pDev, /* ptr to TEMPLATE_DEV info */ int* pBusId /* ptr to returned bus ID */ ) { /* TODO - put device id into *pBusId location */ return (OK); }/********************************************************************************* templateCommand - write a command code to the TEMPLATE_DEV Command Register** NOMANUAL*/LOCAL void templateCommand ( TEMPLATE_DEV* pDev, /* ptr to TEMPLATE_DEV info */ int cmdCode /* new command code */ ) { /* * Clear the sync semaphore, just in case this command generates an * interrupt. */ semTake (&pDev->scsiCtrl.ctrlSyncSem, NO_WAIT); /* TODO - issue command to device */ }/********************************************************************************* templateScsiBusReset - assert the RST line on the SCSI bus** Issue a SCSI Bus Reset command to the NCR 5390. This should put all devices* on the SCSI bus in an initial quiescent state.*/LOCAL void templateScsiBusReset ( TEMPLATE_DEV *pDev /* ptr to TEMPLATE_DEV info */ ) { /* TODO - issue bus reset command */ semTake (&pDev->scsiCtrl.ctrlSyncSem, WAIT_FOREVER); /* TODO - set remembered bus phase to be BUS_FREE */ /* allow time for reset signal to become inactive */ taskDelay (2); }/********************************************************************************* templateIntr - interrupt service routine for the TEMPLATE_DEV** NOMANUAL*/void templateIntr ( TEMPLATE_DEV *pDev /* ptr to TEMPLATE_DEV info */ ) { SCSI_PHYS_DEV *pDevToSelect; /* TODO - read current device state, including bus phase */ /* Quick exit if no interrupt present, this is not an error. */ if (DEVICE_IS_NOT_INTERRUPTING) return; /* TODO - save status registers as needed */ if (DMA_TERMINAL_COUNT_REACHED) { /* TODO - if necessary, clear the DMA TC condition */ } if (DEVICE_FUNC_COMPLETE) { /* if a selection attempt has been made, report success */ if (((pDevToSelect = pDev->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_IN_PROGRESS)) { pDevToSelect->devStatus = SELECT_SUCCESSFUL; pDev->pDevToSelect = (SCSI_PHYS_DEV *) NULL; } } else if (DEVICE_IS_DISCONNECTED) { /* if a device has not been selected, then a timeout has occurred */ if (((pDevToSelect = pDev->pDevToSelect) != (SCSI_PHYS_DEV *) NULL) && (pDevToSelect->devStatus == SELECT_IN_PROGRESS)) { pDevToSelect->devStatus = SELECT_TIMEOUT; pDev->pDevToSelect = (SCSI_PHYS_DEV *) NULL; } else { pDev->scsiCtrl.scsiBusPhase = SCSI_BUS_FREE_PHASE; } } /* send synch signal to controlling task */ semGive (&pDev->scsiCtrl.ctrlSyncSem); /* * TODO - If device is slow, check that the interrupt line has * actually gone low, but don't loop forever. */ }/********************************************************************************* templateHwInit - initialize the TEMPLATE_DEV chip to a known state** This routine puts the TEMPLATE_DEV into a known quiescent state and issues a reset* to the SCSI Bus if any signals are active, thus putting target devices in* some presumably known state. Currently the initial state is not configurable* and does not enable reselection.** INTERNAL* Needs to handle parity enable*/LOCAL void templateHwInit ( TEMPLATE_DEV* pDev /* ptr to an TEMPLATE_DEV info structure */ ) { /* TODO - reset the device to its initial state */ templateScsiBusReset (pDev); /* Reset the bus */ }#ifdef INCLUDE_SHOW_ROUTINES/********************************************************************************* templateShow - display the status of the TEMPLATE_DEV device** This routine displays the state of the TEMPLATE_DEV registers in a* user-friendly manner. It is useful primarily for debugging.** EXAMPLE:* .CS* -> templateShow* pTclReg = 0x00* pTchReg = 0x02* pFifoReg = 0x00 * pCmdReg = 0x12* pStatReg = 0x00* pIntrReg = 0x00 * pStepReg = 0xc4* pFlgsReg = 0x00 * pCfg1Reg = 0x07* .CE** RETURNS: OK, or ERROR if <pScsiCtrl> and <pSysScsiCtrl> are both NULL.*/LOCAL STATUS templateShow ( SCSI_CTRL *pScsiCtrl /* ptr to TEMPLATE_DEV info */ ) { TEMPLATE_DEV *pDev; if (pScsiCtrl == NULL) { if (pSysScsiCtrl == NULL) { printErr ("No SCSI controller specified.\n"); return (ERROR); } pScsiCtrl = pSysScsiCtrl; } pDev = (TEMPLATE_DEV *) pScsiCtrl; /* TODO - access and display all the device registers */ return (OK); }#endif /* INCLUDE_SHOW_ROUTINES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -