📄 pcifuction_haero.c
字号:
if (pDevice == NULL)
return ApiInvalidHandle;
pIoNode = IoPoolGetNode();
pIoNode->IoBuffer.DmaData.DmaChannel = dmaChannel;
/*************************************************************
* If the ReturnCode field is non-zero, the driver will
* assume a NULL descriptor and will, therefore, not
* modify the DMA mode parameters/registers. It will assume
* these are already setup correctly.
*************************************************************/
if (pDmaChannelDesc == NULL)
pIoNode->IoBuffer.DmaData.ReturnCode = 1234;
else
{
pIoNode->IoBuffer.DmaData.ReturnCode = 0;
pIoNode->IoBuffer.DmaData.DmaChannelDesc = *pDmaChannelDesc;
}
DeviceIoControl(
hDevice,
PLX_IOCTL_DMA_SGL_OPEN,
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pIoNode->Overlapped)
);
rc = pIoNode->IoBuffer.DmaData.ReturnCode;
IoPoolReleaseNode(
pIoNode
);
// Build the DMA I/O buffers list if it hasn't been done
if (pDevice->pDmaList == NULL)
{
DmaListBuild(
pDevice
);
}
return rc;
}
RETURN_CODE PlxIntrAttach(HANDLE hDevice,PLX_INTR intrTypes,HANDLE *pEventHdl)
{
IO_NODE *pEvent;
DEVICE_NODE *pDevice;
if (pEventHdl == NULL)
return ApiNullParam;
// Verify the handle
pDevice = DeviceListFind(
hDevice
);
if (pDevice == NULL)
return ApiInvalidHandle;
// Check to see if the Event handle has been allocated already
if (*pEventHdl != NULL)
{
pEvent = IoListFindByEventHandle(
pDevice->pEventList,
*pEventHdl
);
}
else
{
pEvent = NULL;
}
// Allocate resources if Event handle not previously used
if (pEvent == NULL)
{
// Create the event
*pEventHdl = CreateEvent(
NULL, // Not inheritable to child processes
TRUE, // Manual reset?
FALSE, // Intial state
NULL
);
if (*pEventHdl == NULL)
return ApiInsufficientResources;
// Save the resources for later release
pEvent = IoListAdd(&(pDevice->pEventList),*pEventHdl);
if (pEvent == NULL)
{
CloseHandle(*pEventHdl);
return ApiInsufficientResources;
}
}
// Fill in the I/O parameters
pEvent->IoBuffer.MiscData.IntrInfo = intrTypes;
pEvent->IoBuffer.MiscData.ReturnCode = ApiSuccess;
/*************************************************************
* Since this is an Overlapped message, the request will not
* complete it until the interrupt or an error occurs. In
* that case, the return code is only valid in error conditions,
* so we cannot rely on it; therefore, it is set beforehand.
*************************************************************/
// Send message to driver
DeviceIoControl(
hDevice,
PLX_IOCTL_INTR_ATTACH,
&(pEvent->IoBuffer),
sizeof(IOCTLDATA),
&(pEvent->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pEvent->Overlapped)
);
return pEvent->IoBuffer.MiscData.ReturnCode;
}
RETURN_CODE PlxDmaSglTransfer(HANDLE hDevice,DMA_CHANNEL dmaChannel,DMA_TRANSFER_ELEMENT *pDmaData,BOOLEAN returnImmediate)
{
DWORD StatusCode;
IO_NODE *pDmaNode;
DEVICE_NODE *pDevice;
if (pDmaData == NULL)
return ApiNullParam;
// Verify the handle
pDevice = DeviceListFind(
hDevice
);
if (pDevice == NULL)
return ApiInvalidHandle;
pDmaNode = DmaListGetNode(pDevice,(unsigned char)DmaIndex(dmaChannel));
if (pDmaNode == NULL)
return ApiDmaChannelUnavailable;
// Copy parameter information
pDmaNode->IoBuffer.DmaData.DmaChannel = dmaChannel;
pDmaNode->IoBuffer.DmaData.TransBlock1 = *pDmaData;
pDmaNode->IoBuffer.DmaData.ReturnCode = ApiSuccess;
/*************************************************************
* Since this is an Asynchronous operation, the request will not
* complete it until the interrupt or an error occurs. In
* that case, the return code is only valid in error conditions,
* so we cannot rely on it; therefore, it is set beforehand.
*************************************************************/
DeviceIoControl(
hDevice,
PLX_IOCTL_DMA_SGL_TRANSFER,
&(pDmaNode->IoBuffer),
sizeof(IOCTLDATA),
&(pDmaNode->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pDmaNode->Overlapped)
);
// Don't wait for completion if requested not to
if (returnImmediate)
return pDmaNode->IoBuffer.DmaData.ReturnCode;
if (pDmaNode->IoBuffer.DmaData.ReturnCode != ApiSuccess)
return pDmaNode->IoBuffer.DmaData.ReturnCode;
StatusCode = WaitForSingleObject(
pDmaNode->Overlapped.hEvent,
MAX_DMA_TIMEOUT
);
switch (StatusCode)
{
case WAIT_OBJECT_0:
return pDmaNode->IoBuffer.DmaData.ReturnCode;
case WAIT_TIMEOUT:
return ApiPciTimeout;
case WAIT_FAILED:
return ApiFailed;
}
return ApiFailed;
}
RETURN_CODE PlxDmaSglChannelClose(HANDLE hDevice,DMA_CHANNEL dmaChannel)
{
IO_NODE *pIoNode;
RETURN_CODE rc;
// Verify the handle
if (DeviceListFind(
hDevice
) == NULL)
{
return ApiInvalidHandle;
}
pIoNode = IoPoolGetNode();
pIoNode->IoBuffer.DmaData.DmaChannel = dmaChannel;
DeviceIoControl(
hDevice,
PLX_IOCTL_DMA_SGL_CLOSE,
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pIoNode->Overlapped)
);
rc = pIoNode->IoBuffer.DmaData.ReturnCode;
IoPoolReleaseNode(
pIoNode
);
return rc;
}
DEVICE_NODE *DeviceListFind(HANDLE hDevice)
{
DEVICE_NODE *pCurrentDevice;
LockGlobals();
pCurrentDevice = pDeviceList;
// Search for the node in the Device List
while (pCurrentDevice != NULL)
{
if (pCurrentDevice->Handle == hDevice)
{
UnlockGlobals();
return pCurrentDevice;
}
pCurrentDevice = pCurrentDevice->pNext;
}
UnlockGlobals();
return NULL;
}
BOOLEAN DmaListBuild(DEVICE_NODE *pDevice)
{
unsigned char i;
IO_NODE *pNewDma;
IO_NODE *pDmaList;
LockGlobals();
for (i=0; i<MAX_DMA_CHANNELS; i++)
{
// Allocate a new node
pNewDma = (IO_NODE *)malloc(sizeof(IO_NODE));
if (pNewDma == NULL)
{
UnlockGlobals();
return FALSE;
}
// Clear the overlapped structure
memset(
&(pNewDma->Overlapped),
0,
sizeof(OVERLAPPED)
);
// Allocate the Event handle
pNewDma->Overlapped.hEvent =
CreateEvent(
NULL, // Not inheritable to child processes
TRUE, // Manual reset?
FALSE, // Intial state
NULL
);
if (pNewDma->Overlapped.hEvent == NULL)
{
UnlockGlobals();
free(
pNewDma
);
return FALSE;
}
// Clear the next pointer
pNewDma->pNext = NULL;
// Add node to the list
if (pDevice->pDmaList == NULL)
pDevice->pDmaList = pNewDma;
else
pDmaList->pNext = pNewDma;
pDmaList = pNewDma;
}
UnlockGlobals();
return TRUE;
}
IO_NODE * DmaListGetNode(DEVICE_NODE *pDevice,unsigned char index)
{
unsigned char i;
IO_NODE *pDmaNode;
i = 0;
LockGlobals();
pDmaNode = pDevice->pDmaList;
while (pDmaNode != NULL)
{
if (i == index)
{
UnlockGlobals();
return pDmaNode;
}
i++;
pDmaNode = pDmaNode->pNext;
}
UnlockGlobals();
return NULL;
}
IO_NODE * IoListFindByEventHandle(IO_NODE *pIoList,HANDLE hEvent)
{
LockGlobals();
// Search for the node in the list
while (pIoList != NULL)
{
if (pIoList->Overlapped.hEvent == hEvent)
{
UnlockGlobals();
return pIoList;
}
pIoList = pIoList->pNext;
}
UnlockGlobals();
return NULL;
}
IO_NODE * IoListAdd(IO_NODE **pIoList,HANDLE hEvent)
{
IO_NODE *pNewNode;
IO_NODE *pCurrNode;
// Allocate a new node
pNewNode = (IO_NODE *)malloc(sizeof(IO_NODE));
if (pNewNode == NULL)
{
UnlockGlobals();
return NULL;
}
// Clear the overlapped structure
memset(
&(pNewNode->Overlapped),
0,
sizeof(OVERLAPPED)
);
// Save the Event handle
pNewNode->Overlapped.hEvent = hEvent;
pNewNode->pNext = NULL;
LockGlobals();
if (*pIoList != NULL)
{
pCurrNode = *pIoList;
while (pCurrNode->pNext != NULL)
{
pCurrNode = pCurrNode->pNext;
}
// Add node to the list
pCurrNode->pNext = pNewNode;
}
else
{
*pIoList = pNewNode;
}
UnlockGlobals();
return pNewNode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -