📄 plx9054.c
字号:
sprintf(pPlxSpace->spaceName, "Pci I/O For Local Reg");
pPlxSpace->dwPciBar = pDrvCtrl->pDevice[index]->PlxPciRsrc.iobaseCsr;
pPlxSpace->dwRange = 256;
pPlxSpace->fIsEnable = TRUE;
pPlxSpace->fIsMemory = FALSE;
return OK;
break;
case P9054_ADDR_SPACE0: /* local space 0*/
PLX9054_Local_Reg_Read(index, P9054_LAS0RR, &range);
PLX9054_Local_Reg_Read(index, P9054_LAS0BA, &localBase);
PLX9054_Pci_Reg_Read(index, PCI_BAR2, &pciBase, DATA_DWORD);
sprintf(pPlxSpace->spaceName, "PLX9054 Local Space 0");
break;
case P9054_ADDR_SPACE1: /* local space 1*/
PLX9054_Local_Reg_Read(index, P9054_LAS1RR, &range);
PLX9054_Local_Reg_Read(index, P9054_LAS1BA, &localBase);
PLX9054_Pci_Reg_Read(index, PCI_BAR3, &pciBase, DATA_DWORD);
sprintf(pPlxSpace->spaceName, "PLX9054 Local Space 1");
break;
case P9054_ADDR_EPROM: /* local EPROM space*/
PLX9054_Local_Reg_Read(index, P9054_EROMRR, &range);
PLX9054_Local_Reg_Read(index, P9054_EROMBA, &localBase);
PLX9054_Pci_Reg_Read(index, PCI_ERBAR, &pciBase, DATA_DWORD);
sprintf(pPlxSpace->spaceName, "PLX9054 Local Eprom Space");
break;
default:
return ERROR;
break;
}
/*初始化结构体*/
pPlxSpace->fIsMemory = (BIT0 == (range & BIT0));
if(pPlxSpace->fIsMemory)
{
pPlxSpace->fIsPrefetch = (BIT3 == (range & BIT3));
pPlxSpace->dwRange = (~(range & PCI_MEMBASE_MASK)) + 1;
}
else
{
pPlxSpace->dwRange = (~(range & 0xfffffff8)) + 1;
}
pPlxSpace->fIsEnable = (BIT0 == (localBase & BIT0));
if(pPlxSpace->fIsMemory) /* memory base */
{
pPlxSpace->dwLocalBase = (localBase & PCI_MEMBASE_MASK);
}
else /* i/o base */
{
pPlxSpace->dwLocalBase = (localBase & 0xfffffffc);
}
if(pPlxSpace->fIsEnable)
{
pPlxSpace->dwPciBar = pciBase & PCI_MEMBASE_MASK;
}
return OK;
}
/*
PLX9054_GetSpaceInfo
获取PLX9054 所有本地空间信息Space0、Space1、Programe ROM Space
input
int index: 设备索引
*/
STATUS PLX9054_GetAllSpaceInfo(int index)
{
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_SPACE_DESC plxSpace;
int i;
pDrvCtrl = pPlxDrvCtrl;
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index(%d) out of range file:%s, line:%d.\n", index, __FILE__, __LINE__);
return ERROR;
}
for(i = 0; i < AD_PCI_BAR_EPROM; i++)
{
memset((void *)(&plxSpace), 0, sizeof(PLX9054_SPACE_DESC));
if(OK == PLX9054_GetSpaceInfo(index, (PLX9054_SPACE_INDEX)i, &plxSpace))
{
pDrvCtrl->pDevice[index]->spaceDesc[i] = plxSpace;
}
}
return OK;
}
/********************************************************************
PLX9054_Int
PLX9054中断入口函数
*/
void PLX9054_Int(int index)
{
UINT32 intcsr, intSource;
UCHAR dmacsr;
int level;
PLX9054_DMA_CH ch;
PLX9054_DRVCTRL * pDrvCtrl;
level = intLock ();
pDrvCtrl = PLX9054_GetDrvCtrl( );
ch = pDrvCtrl->pDevice[index]->channel;
/* 读取中断控制/状态寄存器*/
PLX9054_Local_Reg_Read (index, P9054_INTCSR, &intcsr);
/* 计算中断源*/
if(0xffffffff == intcsr)
{
return;
}
/* Check for master PCI interrupt enable */
if ((intcsr & (1 << 8)) == 0)
return;
#if 0
intSource = INTR_TYPE_NONE;
/* Check if PCI Doorbell Interrupt is active and not masked*/
if ((intcsr & (1 << 13)) && (intcsr & (1 << 9)))
{
intSource |= INTR_TYPE_DOORBELL;
}
/* Check if PCI Abort Interrupt is active and not masked */
if ((intcsr & (1 << 14)) && (intcsr & (1 << 10)))
{
intSource |= INTR_TYPE_PCI_ABORT;
}
/* Check if Local->PCI Interrupt is active and not masked */
if ((intcsr & (1 << 15)) && (intcsr & (1 << 11)))
{
intSource |= INTR_TYPE_LOCAL_1;
}
#endif
if((intcsr & BIT21) && (intcsr & BIT18)) /* DMA 通道0 产生中断*/
{
/*采集来的数据已经经DMA 传输到内存中,这里通过 释放信号量激活数据处理任务*/
semGive(pDrvCtrl->pDevice[index]->dmaCh[ch].syncSem);
/* 清中断*/
dmacsr = *(UCHAR *)(pPlxDrvCtrl->pDevice[index]->spaceDesc[AD_PCI_BAR0].dwPciBar + P9054_DMACSR);
*(UCHAR *)(pPlxDrvCtrl->pDevice[index]->spaceDesc[AD_PCI_BAR0].dwPciBar + P9054_DMACSR) = dmacsr | (1 << 3);
}
intUnlock(level);
}
/********************************************************************
PLX9054_Ioctl
PLX9054的配置与控制接口函数
*/
STATUS PLX9054_Ioctl(int index, PLX9054_IOCTL_CMD cmd, UINT32 * pData)
{
return OK;
}
/*
PLX9054_IntEnable
开中断
*/
void PLX9054_IntEnable (int index)
{
UINT32 dwIntStatus;
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DEVICE * pDevCtrl;
pDrvCtrl = pPlxDrvCtrl;
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
return;
}
if(0) /*如果中断已经使能,直接返回*/
{
return;
}
pDevCtrl = pDrvCtrl->pDevice[index];
/* this enables interrupts*/
PLX9054_Local_Reg_Read (index, P9054_INTCSR, &dwIntStatus);
PLX9054_Local_Reg_Write (index, P9054_INTCSR, dwIntStatus | (BIT8|BIT10 | BIT18));
pDevCtrl->intIsEnable = TRUE;
}
/*
PLX9054_IntDisable
关中断
*/
void PLX9054_IntDisable (int index)
{
UINT32 dwIntStatus;
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DEVICE * pDevCtrl;
pDrvCtrl = pPlxDrvCtrl;
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
return;
}
if(0) /*如果中断已经使能,直接返回*/
{
return;
}
pDevCtrl = pDrvCtrl->pDevice[index];
/* this disables interrupts*/
dwIntStatus = PLX9054_Local_Reg_Read (index, P9054_INTCSR, &dwIntStatus);
PLX9054_Local_Reg_Write (index, P9054_INTCSR, dwIntStatus & ~(BIT8|BIT10));
pDevCtrl->intIsEnable = FALSE;
}
/**************************************************************************
* PLX9054_DMAReadWriteBlock
* 对外接口
* DMA块方式读写
*/
STATUS PLX9054_DMAReadWriteBlock (int index, UINT32 dwLocalAddr, UINT32 buffer, UINT32 dwBytes, BOOL fIsRead)
{
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DMA * pDmaCtrl = NULL;
int channel;
pDrvCtrl = PLX9054_GetDrvCtrl();
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
return ERROR;
}
channel = pDrvCtrl->pDevice[index]->channel; /* 获取设置使用的DMA通道*/
pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[channel]);
pDmaCtrl->pDmaDesc->pciAddr = buffer; /* 设置DMAPADR0/1 寄存器*/
pDmaCtrl->pDmaDesc->localAddr = dwLocalAddr; /* 设置DMALADR0/1 寄存器*/
pDmaCtrl->pDmaDesc->nBytes = dwBytes; /* 设置DMASIZ0/1 寄存器*/
if(fIsRead)
{
pDmaCtrl->pDmaDesc->descPointer = BIT3;
}
else
{
pDmaCtrl->pDmaDesc->descPointer = 0;
}
PLX9054_DMAStart(pDmaCtrl);
return OK;
}
/*
PLX9054_DmaCtrl
对外接口
DMA控制与配置模块,与IOCTL类似
input
index: 设备索引
cmd: 命令(设置项索引)
pData: 数据指针
*/
STATUS PLX9054_DMACtl(int index, PLX9054_DMA_CMD cmd, UINT32 * pData)
{
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DMA * pDmaCtrl = NULL;
int channel;
UINT32 data;
pDrvCtrl = PLX9054_GetDrvCtrl();
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
return ERROR;
}
channel = pDrvCtrl->pDevice[index]->channel;
pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[channel]);
switch(cmd)
{
case DMA_CHANNEL_SET: /* 设置DMA 通道号*/
pDrvCtrl->pDevice[index]->channel = (PLX9054_DMA_CH)(pData);
break;
case DMA_CHANNEL_GET: /* 获取DMA 通道号*/
*pData = (UINT32)(pDrvCtrl->pDevice[index]->channel);
break;
case DMA_READ_ENABLE: /* 设置DMA 读*/
pDmaCtrl->fIsRead = TRUE;
break;
case DMA_WRITE_ENABLE: /* 设置DMA 写*/
pDmaCtrl->fIsRead = FALSE;
break;
case DMA_BUS_WIDTH_SET: /* Set Local Bus Width*/
data = *(pDmaCtrl->pDmaMode);
*(pDmaCtrl->pDmaMode) = (data & (~(BIT0 | BIT1))) | (UINT32)(pData);
break;
case DMA_BUS_WIDTH_GET: /* Get Local Bus Width*/
data = *(pDmaCtrl->pDmaMode);
*pData = data & (BIT0 | BIT1);
break;
case DMA_WAIT_SET: /* Set Internal Wait States */
break;
case DMA_WAIT_GET: /* Get Internal Wait States */
break;
case DMA_BURST_ENABLE: /* Local Burst Enable */
data = *(pDmaCtrl->pDmaMode);
*(pDmaCtrl->pDmaMode) = data | BIT8;
break;
case DMA_BURST_DISABLE: /* Local Burst Disable */
data = *(pDmaCtrl->pDmaMode);
*(pDmaCtrl->pDmaMode) = data & (~BIT8);
break;
case DMA_GATHER_MODE_ENABLE: /* Scatter/Gather mode Enable */
break;
case DMA_GATHER_MODE_DISABLE: /* Scatter/Gather mode Disable */
break;
case DMA_INT_ENABLE: /* Done Interrupt Enable */
break;
case DMA_INT_DISABLE: /* Done Interrupt Disable */
break;
case DMA_LOCAL_ADDR_INC: /* 本地地址递增*/
data = *(pDmaCtrl->pDmaMode);
*(pDmaCtrl->pDmaMode) = data & (~BIT11);
break;
case DMA_LOCAL_ADDR_HOLD: /* 本地地址保持不变*/
data = *(pDmaCtrl->pDmaMode);
*(pDmaCtrl->pDmaMode) = data | BIT11;
break;
default:
break;
}
return OK;
}
/*
PLX9054_DMA_Init
DMA初始化函数
*/
STATUS PLX9054_DMA_Init(int index)
{
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DMA * pDmaCtrl = NULL;
UINT32 membaseCsr;
int i;
pDrvCtrl = PLX9054_GetDrvCtrl();
/* 输入参数判断*/
if( (index < 0) || (index > (pDrvCtrl->plxCardNum - 1)))
{
printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
return ERROR;
}
/* 获取寄存器映射到PCI Memory空间的基地址*/
membaseCsr = pDrvCtrl->pDevice[index]->PlxPciRsrc.membaseCsr;
/*初始化DMA结构体,包括设置一些初始状态,寄存器地址*/
for(i = 0; i < PLX9054_DMA_NUM; i++)
{
pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[i]);
if(NULL == pDmaCtrl)
{
break;
}
pDmaCtrl->pDmaMode = (UINT32 *)(membaseCsr + P9054_DMAMODE + i * PLX9054_DMA_CHANNEL_SHIFT);
pDmaCtrl->pDmaDesc = (PLX9054_DMA_DESC *)(membaseCsr + P9054_DMAPADR + i * PLX9054_DMA_CHANNEL_SHIFT);
pDmaCtrl->pDmaCs = (UINT8 *)(membaseCsr + P9054_DMACSR + i);
pDmaCtrl->fIschkDone = TRUE; /* 默认查询模式*/
pDmaCtrl->fIsRead = TRUE; /* 默认DMA用于读FIFO*/
pDmaCtrl->semTimeOut = PLX9054_DMA_TIME_OUT;
pDmaCtrl->timeOutCount = 0;
pDmaCtrl->syncSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY); /*创建信号量*/
/* DMA 模式初始化
BIT0: 16-bit lOCAL bus
BIT10: Done Interrupt Enable
BIT11:LocaL address hold
BIT17:DMA Interrupt INTA*/
*(pDmaCtrl->pDmaMode) = BIT0 | BIT10 |BIT11|BIT17;
}
PLX9054_DMACtl(index, DMA_CHANNEL_SET, (UINT32 *)PLX9054_DMA_CH_0); /* 设置使用DMA 0 */
PLX9054_DMACtl(index, DMA_BUS_WIDTH_SET, (UINT32 *)PLX9054_BUS_WORD); /* 设置本地总线为16 位*/
#if 1
PLX9054_DMACtl(index, DMA_BURST_DISABLE, NULL); /* 本地总线禁止BURST 操作*/
#else
PLX9054_DMACtl(index, DMA_BURST_ENABLE, NULL); /* 本地总线使能BURST 操作*/
#endif
return OK;
}
/*
PLX9054_DMAIsDone
查询DMA传输是否完成
*/
BOOL PLX9054_DMAIsDone (PLX9054_DMA * pDmaCtrl)
{
return(BIT4 == (*(pDmaCtrl->pDmaCs) & BIT4));
}
/*
PLX9054_DMAStart
启动DMA传输
*/
STATUS PLX9054_DMAStart (PLX9054_DMA * pDmaCtrl)
{
int semStatus;
*(pDmaCtrl->pDmaCs) = BIT0 | BIT1;
#if 0
/* Busy wait for plx to finish DMA transfer*/
if (pDmaCtrl->fIschkDone)
{
while (!PLX9054_DMAIsDone(pDmaCtrl))
;
}
printf("DMA Done.\n");
else /* 中断方式, 调试用*/
#else
{
semStatus = semTake(pDmaCtrl->syncSem, PLX9054_DMA_TIME_OUT); /*需要 在中断处理中释放信号量*/
if(ERROR == semStatus)
{
printf("DMA Operation TIME_OUT.file:%s, line:%d.\n", __FILE__, __LINE__);
pDmaCtrl->timeOutCount++;
return ERROR;
}
}
#endif
return OK;
}
/*
PLX9054PciShow
显示所有PLX9054扩展卡的PCI资源信息
*/
void PLX9054_Pci_Show(void)
{
int unit;
PLX9054_DRVCTRL * pDrvCtrl;
PLX9054_DEVICE * pDevCtrl;
pDrvCtrl = PLX9054_GetDrvCtrl();
if (0 == pDrvCtrl->plxCardNum)
{
printf("No Plx9054 Card Installed!\n");
return;
}
for(unit = 0; unit < (pDrvCtrl->plxCardNum); unit++)
{
pDevCtrl = pDrvCtrl->pDevice[unit];
printf("Bus:%d Device:%d Function:%d MemBase:0x%08x IOBase:0x%04x Irq:%d\n",
pDevCtrl->PlxPciRsrc.pciBus, pDevCtrl->PlxPciRsrc.pciDevice, pDevCtrl->PlxPciRsrc.pciFunc,
pDevCtrl->PlxPciRsrc.membaseCsr, pDevCtrl->PlxPciRsrc.iobaseCsr, pDevCtrl->PlxPciRsrc.irq);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -