?? i2o1.c
字號:
/* QBA must be aligned at 1Mbyte boundary */ return I2OQUEINVALID; } store_runtime_reg( eumbbar, I2O_QBAR, qba ); store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz ); store_runtime_reg( eumbbar, I2O_IFHPR, qba ); store_runtime_reg( eumbbar, I2O_IFTPR, qba ); store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 )); store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 )); store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 )); store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 )); store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 )); store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 )); fifo_stat.qsz = sz; fifo_stat.qba = qba; return I2OSUCCESS;}/************************************************** * function: I2OFIFOEnable * * description: Enable the circular queue * return I2OSUCCESS if no error. * Otherwise I2OQUEINVALID is returned. * * note: *************************************************/I2OSTATUS I2OFIFOEnable( unsigned int eumbbar ){ unsigned int val; if ( fifo_stat.qba == 0xfffffff ) { return I2OQUEINVALID; } val = load_runtime_reg( eumbbar, I2O_MUCR ); store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 ); return I2OSUCCESS;}/************************************************** * function: I2OFIFODisable * * description: Disable the circular queue * * note: *************************************************/void I2OFIFODisable( unsigned int eumbbar ){ if ( fifo_stat.qba == 0xffffffff ) { /* not enabled */ return; } unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR ); store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );}/**************************************************** * function: I2OFIFOAlloc * * description: Allocate a free MFA from free FIFO. * return I2OSUCCESS if no error. * return I2OQUEEMPTY if no more free MFA. * return I2OINVALID on other errors. * * A free MFA must be allocated before a * message can be posted. * * note: * PCI Master allocates a free MFA from inbound queue of device * (pcsrbar is the base,) through the inbound queue port of device * while local processor allocates a free MFA from its outbound * queue (eumbbar is the base.) * ****************************************************/I2OSTATUS I2OFIFOAlloc( LOCATION loc, unsigned int base, void **pMsg ){ I2OSTATUS stat = I2OSUCCESS; void *pHdr, *pTil; if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff ) { /* not configured */ return I2OQUEINVALID; } if ( loc == REMOTE ) { /* pcsrbar is the base and read the inbound free tail ptr */ pTil = (void *)load_runtime_reg( base, I2O_IFQPR ); if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF ) { stat = I2OQUEEMPTY; } else { *pMsg = pTil; } } else { /* eumbbar is the base and read the outbound free tail ptr */ pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */ pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */ /* check underflow */ if ( pHdr == pTil ) { /* hdr and til point to the same fifo item, no free MFA */ stat = I2OQUEEMPTY; } else { /* update OFTPR */ *pMsg = (void *)(*(unsigned char *)pTil); pTil = (void *)((unsigned int)pTil + 4); if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) ) { /* reach the upper limit */ pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) )); } store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil ); } } return stat;}/****************************************************** * function: I2OFIFOFree * * description: Free a used MFA back to free queue after * use. * return I2OSUCCESS if no error. * return I2OQUEFULL if inbound free queue * overflow * * note: PCI Master frees a MFA into device's outbound queue * (OFQPR) while local processor frees a MFA into its * inbound queue (IFHPR). *****************************************************/I2OSTATUS I2OFIFOFree( LOCATION loc, unsigned int base, void *pMsg ){ void **pHdr, **pTil; I2OSTATUS stat = I2OSUCCESS; if ( fifo_stat.qba == 0xffffffff || pMsg == 0 ) { return I2OQUEINVALID; } if ( loc == REMOTE ) { /* pcsrbar is the base */ store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg ); } else { /* eumbbar is the base */ pHdr = (void **)load_runtime_reg( base, I2O_IFHPR ); pTil = (void **)load_runtime_reg( base, I2O_IFTPR ); /* store MFA */ *pHdr = pMsg; /* update IFHPR */ pHdr += 4; if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) ) { /* reach the upper limit */ pHdr = (void **)fifo_stat.qba; } /* check inbound free queue overflow */ if ( pHdr != pTil ) { store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr); } else { stat = I2OQUEFULL; } } return stat;}/********************************************* * function: I2OFIFOPost * * description: Post a msg into FIFO post queue * the value of msg must be the one * returned by I2OFIFOAlloc * * note: PCI Master posts a msg into device's inbound queue * (IFQPR) while local processor post a msg into device's * outbound queue (OPHPR) *********************************************/I2OSTATUS I2OFIFOPost( LOCATION loc, unsigned int base, void *pMsg ){ void **pHdr, **pTil; I2OSTATUS stat = I2OSUCCESS; if ( fifo_stat.qba == 0xffffffff || pMsg == 0 ) { return I2OQUEINVALID; } if ( loc == REMOTE ) { /* pcsrbar is the base */ store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg ); } else { /* eumbbar is the base */ pHdr = (void **)load_runtime_reg( base, I2O_OPHPR ); pTil = (void **)load_runtime_reg( base, I2O_OPTPR ); /* store MFA */ *pHdr = pMsg; /* update IFHPR */ pHdr += 4; if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) ) { /* reach the upper limit */ pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) ); } /* check post queue overflow */ if ( pHdr != pTil ) { store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr); } else { stat = I2OQUEFULL; } } return stat;}/************************************************ * function: I2OFIFOGet * * description: Read a msg from FIFO * This function should be called * only when there is a corresponding * msg interrupt. * * note: PCI Master reads a msg from device's outbound queue * (OFQPR) while local processor reads a msg from device's * inbound queue (IPTPR) ************************************************/I2OSTATUS I2OFIFOGet( LOCATION loc, unsigned int base, void **pMsg ){ I2OSTATUS stat = I2OSUCCESS; void *pHdr, *pTil; if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff ) { /* not configured */ return I2OQUEINVALID; } if ( loc == REMOTE ) { /* pcsrbar is the base */ pTil = (void *)load_runtime_reg( base, I2O_OFQPR ); if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF ) { stat = I2OQUEEMPTY; } else { *pMsg = pTil; } } else { /* eumbbar is the base and read the outbound free tail ptr */ pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */ pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */ /* check underflow */ if ( pHdr == pTil ) { /* no free MFA */ stat = I2OQUEEMPTY; } else { /* update OFTPR */ *pMsg = (void *)(*(unsigned char *)pTil); pTil = (void *)((unsigned int)pTil + 4); if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) ) { /* reach the upper limit */ pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) ); } store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil ); } } return stat;}/******************************************************** * function: I2OIOP * * description: Get the I2O PCI configuration identification * register. * * note: PCI master should pass pcsrbar while local processor * should pass eumbbar. *********************************************************/I2OSTATUS I2OPCIConfigGet( LOCATION loc, unsigned int base, I2OIOP * val){ unsigned int tmp; if ( val == 0 ) { return I2OINVALID; } tmp = load_runtime_reg( base, PCI_CFG_CLA ); val->base_class = ( tmp & 0xFF) << 16; tmp = load_runtime_reg( base, PCI_CFG_SCL ); val->sub_class= ( (tmp & 0xFF) << 8 ); tmp = load_runtime_reg( base, PCI_CFG_PIC ); val->prg_code = (tmp & 0xFF); return I2OSUCCESS;}/********************************************************* * function: I2OFIFOIntEnable * * description: Enable the circular post queue interrupt * * note: * PCI master enables outbound FIFO interrupt of device * pscrbar is the base * Device enables its inbound FIFO interrupt * eumbbar is the base *******************************************************/void I2OFIFOIntEnable( LOCATION loc, unsigned int base ){ unsigned int reg, val; /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base * LOCAL : enable local inbound message, eumbbar as base */ reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR ); val = load_runtime_reg( base, reg ); val &= 0xffffffdf; /* clear the msg interrupt bits */ store_runtime_reg( base, reg, val );}/**************************************************** * function: I2OFIFOIntDisable * * description: Disable the circular post queue interrupt * * note: * PCI master disables outbound FIFO interrupt of device * (pscrbar is the base) * Device disables its inbound FIFO interrupt * (eumbbar is the base) *****************************************************/void I2OFIFOIntDisable( LOCATION loc, unsigned int base ){ /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base * LOCAL : disable local inbound message interrupt, eumbbar as base */ unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR ); unsigned int val = load_runtime_reg( base, reg ); val |= 0x00000020; /* masked out the msg interrupt bits */ store_runtime_reg( base, reg, val );}/********************************************************* * function: I2OFIFOOverflowIntEnable * * description: Enable the circular queue overflow interrupt * * note: * Device enables its inbound FIFO post overflow interrupt * and outbound free overflow interrupt. * eumbbar is the base *******************************************************/void I2OFIFOOverflowIntEnable( unsigned int eumbbar ){ unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR ); val &= 0xfffffe7f; /* clear the two overflow interrupt bits */ store_runtime_reg( eumbbar, I2O_IMIMR, val );}/**************************************************** * function: I2OFIFOOverflowIntDisable * * description: Disable the circular queue overflow interrupt * * note: * Device disables its inbound post FIFO overflow interrupt * and outbound free FIFO overflow interrupt * (eumbbar is the base) *****************************************************/void I2OFIFOOverflowIntDisable( unsigned int eumbbar ){ unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR ); val |= 0x00000180; /* masked out the msg overflow interrupt bits */ store_runtime_reg( eumbbar, I2O_IMIMR, val );}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -