?? 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 + -