📄 ncr710lib.c
字号:
/* restart scsi phase routine for this device */ semGive (&pScsiPhysDev->devSyncSem); return; case RECONNECT_IN_SELECT:#ifdef NCR710_INT_LOG_MEM LOG_MEM_INTR;#endif /* NCR710_INT_LOG_MEM */ SCSI_INT_DEBUG_MSG("ncr710Intr:reconnect in select\n", 0, 0, 0, 0, 0, 0); ncr710StartScript(pSiop, pSiop->pNcrCtl, (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev, &checkNewCmd); return; case BAD_NEW_CMD: logMsg ("BAD_NEW_CMD\n", 0, 0, 0, 0, 0, 0);#ifdef NCR710_INT_LOG_MEM LOG_MEM_INTR;#endif /* NCR710_INT_LOG_MEM */ ncr710StartScript(pSiop,pSiop->pNcrCtl, (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev, &waitSelect); return; default: break; }#ifdef NCR710_INT_LOG_MEM LOG_MEM_INTR;#endif /* NCR710_INT_LOG_MEM */ pScsiPhysDev = (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev; /* handle the mismatch case at interrupt level because some count and * pointer have to be adjust with few chip register informations. */ if ((tmpReg = (pSiop->saveSstat0 & B_MA)) == B_MA) { localStart = ncr710PhaseMismatch(pSiop, (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev, pSiop->pNcrCtl,(UINT)phaseReqReg); ncr710StartScript(pSiop,pSiop->pNcrCtl, (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev, localStart); SCSI_INT_DEBUG_MSG("mismatch intr\n", 0, 0, 0, 0, 0, 0); return; } /* give the synchronize semaphore to any startscript caller * and check for single step feature. If single step is enable * check to give semaphore only if it an INT script opcode * occurred. */ if (siopSStep != TRUE) { semGive (&pScsiPhysDev->devSyncSem); } else { /* Give single step Semaphore */ semGive (&pSiop->singleStepSem); if (scriptIntr == TRUE) { /* Give only if it's an INT Script opcode executed */ logMsg ("ncr710Intr : INTR OPCODE DETECTED \n", 0, 0, 0, 0, 0, 0); semGive (&pScsiPhysDev->devSyncSem); } } }/********************************************************************************* ncr710HwInit - initialize the SIOP chip to a known state** This routine puts the SIOP into a known quiescent state. Because the value* of some registers are coupled with the hardware implemetation of the chip you * have to use ncr710SetHwRegister() to adjust the software/hardware couple.* This routine does not touch the bits in register that are set by * the ncr710SetHwRegister() routine.** SEE ALSO * ncr710SetHwRegister()*/LOCAL void ncr710HwInit ( SIOP *pSiop /* ptr to an SIOP info structure */ ) { int scratch; /* Disable single step feature */ siopSStep = FALSE; /* Perform a soft reset on Chip to get a known state */ *pSiop->pIstat = B_SOFTRST; *pSiop->pIstat = 0; /* Init hardware dependant Registers */ ncr710SetHwRegister (pSiop, &pSiop->hwRegs); /* set clock conversion factor, already checked in xxCtrlCreate */ scratch = pSiop->scsiCtrl.clkPeriod; if (scratch >= NCR710_25MHZ) *pSiop->pDcntl |= NCR710_16MHZ_DIV; /* 16.67 - 25Mhz range */ if ((scratch >= NCR710_3750MHZ) && (scratch < NCR710_25MHZ)) *pSiop->pDcntl |= NCR710_25MHZ_DIV; /* 25.01 - 37.50Mhz range */ if ((scratch >= NCR710_50MHZ) && (scratch < NCR710_3750MHZ)) *pSiop->pDcntl |= NCR710_50MHZ_DIV; /* 37.51 - 50Mhz range */ if (scratch < NCR710_50MHZ) *pSiop->pDcntl |= NCR710_66MHZ_DIV; /* 50 - 66.66Mhz range */ /* Manual start mode Program data bit hardware implementation dependant */ *pSiop->pDmode |= B_MAN; /* Enable Manual script start and 710 mode */ *pSiop->pDcntl |= B_COM; /* check for slow cable mode & Select /reselect */ if (pSiop->slowCableMode == TRUE) *pSiop->pScntl1 |= B_EXC; if (pSiop->scsiCtrl.disconnect == TRUE) { *pSiop->pScntl1 |= B_ESR; /* full arbitration */ *pSiop->pScntl0 = (B_ARB1 | B_ARB0); } else { /* Simple arbitration */ *pSiop->pScntl0 &= ~(B_ARB1 | B_ARB0); } /* Parity from chip */ *pSiop->pScntl0 |= B_EPG; /* Check for checking parity */ if (pSiop->parityCheckEnbl == TRUE) *pSiop->pScntl0 |= B_EPC; /* Set own scsi ID Value check in CtrlInit */ *pSiop->pScid = (1 << pSiop->scsiCtrl.scsiCtrlBusId); /* enable Scsi Interrupt:the select timeout, unexpected disconnect, * , phase mismatch interrupt, parity error. */ *pSiop->pSien = (B_STO | B_UDC | B_MA | B_PAR); /* enable Dma interrrupt: bus fault ,abort ,watchdog timeout, * illegal instruction. */ *pSiop->pDien |= (B_BF | B_ABT | B_WTD | B_IID); /* StartScript at the Idle point */ ncr710StartScript (pSiop, (NCR_CTL *) NULL, (SCSI_PHYS_DEV *) NULL, &waitSelect); }/********************************************************************************* ncr710SetHwRegister - set hardware-dependent registers for the NCR 53C710 SIOP** This routine sets up the registers used in the hardware* implementation of the chip. Typically, this routine is called by * the sysScsiInit() routine from the board support package. * * The input parameters are as follows:* .iP <pSiop> 4* a pointer to the NCR_710_SCSI_CTRL structure created with* ncr710CtrlCreate().* .iP <pHwRegs>* a pointer to a NCR710_HW_REGS structure that is filled with the logical * values 0 or 1 for each bit of each register described below.** This routine includes only the bit registers that can be used to modify * the behavior of the chip. The default configuration used during * ncr710CtlrCreate() and ncr710CrtlInit() is {0,0,0,0,1,0,0,0,0,0,0,0,0,1,0}.** .CS* typedef struct* {* int ctest4Bit7; /@ host bus multiplex mode @/* int ctest7Bit7; /@ disable/enable burst cache capability @/* int ctest7Bit6; /@ snoop control bit1 @/* int ctest7Bit5; /@ snoop control bit0 @/* int ctest7Bit1; /@ invert tt1 pin (sync bus host mode only) @/* int ctest7Bit0; /@ enable differential SCSI bus capability @/* int ctest8Bit0; /@ set snoop pins mode @/* int dmodeBit7; /@ burst length transfer bit 1 @/* int dmodeBit6; /@ burst length transfer bit 0 @/* int dmodeBit5; /@ function code bit FC2 @/* int dmodeBit4; /@ function code bit FC1 @/* int dmodeBit3; /@ program data bit (FC0) @/* int dmodeBit1; /@ user-programmable transfer type @/* int dcntlBit5; /@ enable ACK pin @/* int dcntlBit1; /@ enable fast arbitration on host port @/* } NCR710_HW_REGS;* .CE* For a more detailed description of the register bits,* see the * .I "NCR 53C710 SCSI I/O Processor Programming Guide."** NOTE* Because this routine writes to the NCR 53C710 chip registers, it cannot* be used when there is any SCSI bus activity.** RETURNS: OK, or ERROR if an input parameter is NULL.** SEE ALSO: ncr710CtlrCreate(),* .I "NCR 53C710 SCSI I/O Processor Programming Guide"*/STATUS ncr710SetHwRegister ( SIOP *pSiop, /* pointer to SIOP info */ NCR710_HW_REGS *pHwRegs /* pointer to NCR710_HW_REGS info */ ) { /* check input parameters */ if ((pSiop == NULL) || (pHwRegs == NULL)) return (ERROR); /* fill the SIOP structure with new parameters */ bcopy ((char *)pHwRegs, (char *) &pSiop->hwRegs, sizeof(NCR710_HW_REGS)); /* Set Each bit register to the new value */ /* This bit must be set first else the chip will no anwser to a slave * acces in some hardware implementation. */ ((pHwRegs->dcntlBit5) ? *pSiop->pDcntl = B_EA : (*pSiop->pDcntl &= ~B_EA)); ((pHwRegs->ctest4Bit7) ? *pSiop->pCtest4 |= B_MUX : (*pSiop->pCtest4 &= ~B_MUX)); ((pHwRegs->ctest7Bit7) ? *pSiop->pCtest7 |= B_CDIS : (*pSiop->pCtest7 &= ~B_CDIS)); ((pHwRegs->ctest7Bit6) ? *pSiop->pCtest7 |= B_SC1 : (*pSiop->pCtest7 &= ~B_SC1)); ((pHwRegs->ctest7Bit5) ? *pSiop->pCtest7 |= B_SC0: (*pSiop->pCtest7 &= ~B_SC0)); ((pHwRegs->ctest7Bit1) ? *pSiop->pCtest7 |= B_TT1 : (*pSiop->pCtest7 &= ~B_TT1)); ((pHwRegs->ctest7Bit0) ? *pSiop->pCtest7 |= B_DIFF : (*pSiop->pCtest7 &= ~B_DIFF)); ((pHwRegs->ctest8Bit0) ? *pSiop->pCtest8 |= B_SM : (*pSiop->pCtest8 &= ~B_SM)); ((pHwRegs->dmodeBit7) ? *pSiop->pDmode |= B_BL1 : (*pSiop->pDmode &= ~B_BL1)); ((pHwRegs->dmodeBit6) ? *pSiop->pDmode |= B_BL0 : (*pSiop->pDmode &= ~B_BL0)); ((pHwRegs->dmodeBit5) ? *pSiop->pDmode |= B_FC2 : (*pSiop->pDmode &= ~B_FC2)); ((pHwRegs->dmodeBit4) ? *pSiop->pDmode |= B_FC1 : (*pSiop->pDmode &= ~B_FC1)); ((pHwRegs->dmodeBit3) ? *pSiop->pDmode |= B_PD : (*pSiop->pDmode &= ~B_PD)); ((pHwRegs->dmodeBit1) ? *pSiop->pDmode |= B_U0TT0 : (*pSiop->pDmode &= ~B_U0TT0)); ((pHwRegs->dcntlBit1) ? *pSiop->pDcntl |= B_FA : (*pSiop->pDcntl &= ~B_FA)); return (OK); }/********************************************************************************* ncr710ScsiPhase - process a scsi transaction with the script code** This routine is called by ncr710ScsiTransact() to start the script * that performs the scsi phase transaction. The ncrCtl shared data* structure is filled with the apropriate parameters, pointer to the * command block,message out area,local message in area,scsi status * byte and data in/out buffer.* The interrupt status is also processing in this routine. This can * be done here because the mutex semaphore is taken in ncr710ScsiTransact.** RETURNS: OK, or ERROR if not successful for any reason.** NOMANUAL*/LOCAL STATUS ncr710ScsiPhase ( SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to the target device */ SCSI_TRANSACTION *pScsiXaction /* ptr to the transaction info */ ) { SIOP *pSiop; /* Driver controller info for device */ SCSI_CTRL *pScsiCtrl; /* SCSI controller info for device */ STATUS status; /* routine return status */ LOCAL UINT8 msgIn [MAX_MSG_IN_BYTES]; /* local msg in array */ NCR_CTL *pNcrCtl; /* local pNcrCtl nexus pointer */ TBOOL transactEnd; /* global flag for end of transaction */ UINT localSwitch; /* local intr return switch status */ UINT8 identMsg; /* local to build identify byte message */ UINT8* pMsgOut; /* local msgout pointer */ UINT *localStart = 0; /* local current script restart address */ /* Debug info print */ SCSI_DEBUG_MSG("ncr710Phase scsiAction=0x%x -------\n", (int) pScsiXaction, 0, 0, 0, 0, 0); SCSI_DEBUG_MSG("pScsiPhysDev = 0x%08x", (int) pScsiPhysDev, 0 ,0 ,0 ,0 ,0); /* controller info */ pScsiCtrl = pScsiPhysDev->pScsiCtrl; pSiop = (SIOP *) (pScsiPhysDev->pScsiCtrl); /* save current scsi command context requested */ pScsiPhysDev->pScsiXaction = pScsiXaction; /* init current pointer to scsi info structure */ pSiop->pDevToSelect = pScsiPhysDev; /* init current siop context structure */ pNcrCtl = &pSiop->pNcrCtxt->ncrCtl [pScsiPhysDev->scsiDevBusId][pScsiPhysDev->scsiDevLUN]; /* If a disconnect will occur, retain physDev info pointer */ pNcrCtl->pScsiPhysDev = (UINT *)pScsiPhysDev; /* initialise pointer in a shared data area pointer by pNcrCtl */ /* check and init target ID */ if (pScsiCtrl->scsiCtrlBusId == (UINT8)pScsiPhysDev->scsiDevBusId) return(ERROR); /* Set target id in a data memory structure 00IDSY00 expects by the chip */ pNcrCtl->device = (INIT_BUS_ID) << (pScsiPhysDev->scsiDevBusId); /* Init Cmd count and pointer */ pNcrCtl->cmdCount = pScsiXaction->cmdLength; pNcrCtl->pCmd = pScsiXaction->cmdAddress; /* Init data count and pointer */ pNcrCtl->dataCount = pScsiXaction->dataLength; pNcrCtl->pData = pScsiXaction->dataAddress; pScsiPhysDev->savedTransLength = pScsiXaction->dataLength; pScsiPhysDev->savedTransAddress = pScsiXaction->dataAddress; /* init message IN pointer */ pNcrCtl->pMsgIn = msgIn; pNcrCtl->pExtMsgIn = (UINT8 *) &msgIn[1]; /* init status address */ pNcrCtl->pScsiStatus = &pScsiXaction->statusByte; /* Check if some message out have to be built.The useMsgout tag will * decide what 's kind of message has to be built. */ status = ncr710BuildMsgOut(pScsiPhysDev); if (status == ERROR) return (ERROR); /* Init message out count and pointer */ pNcrCtl->msgOutCount = pScsiPhysDev->msgLength; pNcrCtl->pMsgOut = (UINT8 *) SCSI_GET_PTR_MSGOUT(pScsiPhysDev);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -