📄 i2o.c
字号:
/* 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 int *)pTil); /* modified by zoutl 2003/2/21 */
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 int *)pTil); /* modified by zoutl 2003/2/21 */
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
* LOCALA : 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 );
}
void useI2O(void)
{
(void) intConnect (INUM_TO_IVEC(0x12),I2O_ISR_host, NULL );
intEnable (0x12);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -