📄 pcifuction_haero.c
字号:
#include "PciFuction_Haero.h"
#define PLX_IOCTL_DEVICE_INIT IOCTL_MSG( 0x808 )
#define PLX_IOCTL_PCI_DEVICE_FIND IOCTL_MSG( 0x803 )
#define PLX_IOCTL_SEARCH_PCI_BUS IOCTL_MSG( 0x804 )
#define PLX_IOCTL_DRIVER_VERSION IOCTL_MSG( 0x8d0 )
#define PLX_IOCTL_CHIP_TYPE_GET IOCTL_MSG( 0x8d1 )
#define PLX_IOCTL_PCI_BOARD_RESET IOCTL_MSG( 0x8d2 )
#define PLX_IOCTL_BASE_ADDRESSES_GET IOCTL_MSG( 0x805 )
#define PLX_IOCTL_BASE_ADDRESSES_FREE IOCTL_MSG( 0x806 )
#define PLX_IOCTL_BAR_RANGE_GET IOCTL_MSG( 0x807 )
#define PLX_IOCTL_COMMON_BUFFER_GET IOCTL_MSG( 0x809 )
#define PLX_IOCTL_COMMON_BUFFER_FREE IOCTL_MSG( 0x80a )
#define PLX_IOCTL_CONFIG_REGISTER_READ IOCTL_MSG( 0x800 )
#define PLX_IOCTL_CONFIG_REGISTER_WRITE IOCTL_MSG( 0x801 )
#define PLX_IOCTL_CONFIG_REGISTER_READ_ALL IOCTL_MSG( 0x802 )
#define PLX_IOCTL_REGISTER_READ IOCTL_MSG( 0x820 )
#define PLX_IOCTL_REGISTER_WRITE IOCTL_MSG( 0x821 )
#define PLX_IOCTL_REGISTER_READ_ALL IOCTL_MSG( 0x822 )
#define PLX_IOCTL_INTR_ENABLE IOCTL_MSG( 0x832 )
#define PLX_IOCTL_INTR_DISABLE IOCTL_MSG( 0x833 )
#define PLX_IOCTL_INTR_ATTACH IOCTL_MSG( 0x830 )
#define PLX_IOCTL_INTR_DETACH IOCTL_MSG( 0x831 )
#define PLX_IOCTL_INTR_STATUS_GET IOCTL_MSG( 0x834 )
#define PLX_IOCTL_BUS_IOP_READ IOCTL_MSG( 0x840 )
#define PLX_IOCTL_BUS_IOP_WRITE IOCTL_MSG( 0x841 )
#define PLX_IOCTL_IO_PORT_READ IOCTL_MSG( 0x842 )
#define PLX_IOCTL_IO_PORT_WRITE IOCTL_MSG( 0x843 )
#define PLX_IOCTL_POWER_LEVEL_SET IOCTL_MSG( 0x880 )
#define PLX_IOCTL_POWER_LEVEL_GET IOCTL_MSG( 0x881 )
#define PLX_IOCTL_PM_ID_READ IOCTL_MSG( 0x8c8 )
#define PLX_IOCTL_PM_NCP_READ IOCTL_MSG( 0x8c9 )
#define PLX_IOCTL_HS_ID_READ IOCTL_MSG( 0x8c2 )
#define PLX_IOCTL_HS_NCP_READ IOCTL_MSG( 0x8c3 )
#define PLX_IOCTL_HS_STATUS IOCTL_MSG( 0x8c4 )
#define PLX_IOCTL_VPD_ID_READ IOCTL_MSG( 0x8ca )
#define PLX_IOCTL_VPD_NCP_READ IOCTL_MSG( 0x8cb )
#define PLX_IOCTL_VPD_READ IOCTL_MSG( 0x8cd )
#define PLX_IOCTL_VPD_WRITE IOCTL_MSG( 0x8ce )
#define PLX_IOCTL_EEPROM_PRESENT IOCTL_MSG( 0x8cc )
#define PLX_IOCTL_SERIAL_EEPROM_READ IOCTL_MSG( 0x882 )
#define PLX_IOCTL_SERIAL_EEPROM_READ_BY_OFFSET IOCTL_MSG( 0x8d5 )
#define PLX_IOCTL_SERIAL_EEPROM_WRITE IOCTL_MSG( 0x883 )
#define PLX_IOCTL_SERIAL_EEPROM_WRITE_BY_OFFSET IOCTL_MSG( 0x8d6 )
#define PLX_IOCTL_REGISTER_MAILBOX_READ IOCTL_MSG( 0x823 )
#define PLX_IOCTL_REGISTER_MAILBOX_WRITE IOCTL_MSG( 0x824 )
#define PLX_IOCTL_REGISTER_DOORBELL_SERVICE IOCTL_MSG( 0x825 )
#define PLX_IOCTL_REGISTER_DOORBELL_SET IOCTL_MSG( 0x826 )
#define PLX_IOCTL_MU_INBOUND_PORT_READ IOCTL_MSG( 0x870 )
#define PLX_IOCTL_MU_INBOUND_PORT_WRITE IOCTL_MSG( 0x871 )
#define PLX_IOCTL_MU_OUTBOUND_PORT_READ IOCTL_MSG( 0x872 )
#define PLX_IOCTL_MU_OUTBOUND_PORT_WRITE IOCTL_MSG( 0x873 )
#define PLX_IOCTL_MU_OUTINDEX_READ IOCTL_MSG( 0x8c5 )
#define PLX_IOCTL_MU_OUTINDEX_WRITE IOCTL_MSG( 0x8c6 )
#define PLX_IOCTL_USER_READ IOCTL_MSG( 0x884 )
#define PLX_IOCTL_USER_WRITE IOCTL_MSG( 0x885 )
#define PLX_IOCTL_DMA_CONTROL IOCTL_MSG( 0x8c0 )
#define PLX_IOCTL_DMA_STATUS IOCTL_MSG( 0x8c1 )
#define PLX_IOCTL_DMA_BLOCK_CHANNEL_OPEN IOCTL_MSG( 0x850 )
#define PLX_IOCTL_DMA_BLOCK_TRANSFER IOCTL_MSG( 0x852 )
#define PLX_IOCTL_DMA_BLOCK_TRANSFER_RESTART IOCTL_MSG( 0x853 )
#define PLX_IOCTL_DMA_BLOCK_CHANNEL_CLOSE IOCTL_MSG( 0x851 )
#define PLX_IOCTL_DMA_SGL_OPEN IOCTL_MSG( 0x890 )
#define PLX_IOCTL_DMA_SGL_TRANSFER IOCTL_MSG( 0x892 )
#define PLX_IOCTL_DMA_SGL_CLOSE IOCTL_MSG( 0x891 )
#define PLX_IOCTL_DMA_SHUTTLE_OPEN IOCTL_MSG( 0x8a0 )
#define PLX_IOCTL_DMA_SHUTTLE_TRANSFER IOCTL_MSG( 0x8a2 )
#define PLX_IOCTL_DMA_SHUTTLE_CLOSE IOCTL_MSG( 0x8a1 )
#define PLX_IOCTL_ABORTADDR_READ IOCTL_MSG( 0x8c7 )
/******************************************************************************
*
* Function : main
*
* Description: The main entry point
*
*****************************************************************************/
unsigned char Pci_Open_Clos_Fuction(unsigned char way)
{
unsigned char DeviceSelected;
HANDLE hDevice;
RETURN_CODE rc;
DEVICE_LOCATION Device;
hDevice = GL_hDevice;
if(way==1)
{
DeviceSelected =SelectDevice(&Device);
if (DeviceSelected <=0)
return 0;
rc = PlxPciDeviceOpen(&Device,&hDevice);
if (rc != ApiSuccess)
return 0;
}
else
{
DeviceSelected =SelectDevice(&Device);
if (DeviceSelected <=0)
return 0;
PlxPciDeviceClose(hDevice);
}
return 1;
}
/*********************************************************************
*
* Function : SelectDevice
*
* Description: Asks the user which PLX PCI device to select
*
* Returns : Total Plx devices found
* -1, if user cancelled the selection
*
********************************************************************/
unsigned char SelectDevice( DEVICE_LOCATION *pDevice)
{
unsigned long i;
unsigned long DeviceNum;
pDevice->BusNumber = (unsigned long)-1;
pDevice->SlotNumber = (unsigned long)-1;
pDevice->VendorId = (unsigned long)-1;
pDevice->DeviceId = (unsigned long)-1;
strcpy(pDevice->SerialNumber, "");
DeviceNum = FIND_AMOUNT_MATCHED;
if (PlxPciDeviceFind(pDevice,&DeviceNum) != ApiSuccess)
return 0;
if (DeviceNum == 0)
return 0;
for (i=0; i<DeviceNum; i++)
{
pDevice->BusNumber = (unsigned long)-1;
pDevice->SlotNumber = (unsigned long)-1;
pDevice->VendorId = (unsigned long)-1;
pDevice->DeviceId = (unsigned long)-1;
strcpy(pDevice->SerialNumber, "");
PlxPciDeviceFind( pDevice,&i);
if (pDevice->DeviceId==0x00009054 && pDevice->DeviceId==0x000010b5)
break;
}
return (unsigned char)DeviceNum;
}
/********************************************************
*
********************************************************/
BOOLEAN Haero9054SglDma(BOOLEAN Direction,unsigned long LocalAddress,unsigned short TransferCount,unsigned short DmaBuffer[])
{
unsigned char Revision;
unsigned long ChipType;
DWORD EventStatus;
HANDLE hInterruptEvent;
PLX_INTR PlxInterrupt;
RETURN_CODE rc;
DMA_CHANNEL_DESC DmaDesc;
DMA_TRANSFER_ELEMENT DmaData;
HANDLE hDevice;
hDevice = GL_hDevice;
PlxChipTypeGet(hDevice,&ChipType,&Revision);
if (ChipType != 0x9054)
return 1;
DmaDesc.EnableReadyInput = 1;
DmaDesc.EnableBTERMInput = 0;
DmaDesc.EnableIopBurst = 0;
DmaDesc.EnableWriteInvalidMode = 0;
DmaDesc.EnableDmaEOTPin = 0;
DmaDesc.DmaStopTransferMode = AssertBLAST;
DmaDesc.HoldIopAddrConst = 0;
DmaDesc.HoldIopSourceAddrConst = 0;
DmaDesc.HoldIopDestAddrConst = 0;
DmaDesc.DemandMode = 0;
DmaDesc.EnableTransferCountClear = 0;
DmaDesc.WaitStates = 0;
DmaDesc.IopBusWidth = 1;//for debug;
DmaDesc.EOTEndLink = 0;
DmaDesc.ValidStopControl = 0;
DmaDesc.ValidModeEnable = 0;
DmaDesc.EnableDualAddressCycles = 0;
DmaDesc.Reserved1 = 0;
DmaDesc.TholdForIopWrites = 0;
DmaDesc.TholdForIopReads = 0;
DmaDesc.TholdForPciWrites = 0;
DmaDesc.TholdForPciReads = 0;
DmaDesc.EnableFlybyMode = 0;
DmaDesc.FlybyDirection = 0;
DmaDesc.EnableDoneInt = 0;
DmaDesc.Reserved2 = 0;
DmaDesc.DmaChannelPriority = Channel0Highest;
rc = PlxDmaSglChannelOpen(hDevice,PrimaryPciChannel0,&DmaDesc);
if (rc != ApiSuccess)
return 1;
memset(&PlxInterrupt, 0, sizeof(PLX_INTR)); // Clear interrupt fields
PlxInterrupt.PciDmaChannel0 = 1;
rc = PlxIntrAttach(hDevice,PlxInterrupt,&hInterruptEvent);
if (rc != ApiSuccess)
return 1;
DmaData.Pci9054Dma.UserAddr = (unsigned long)DmaBuffer;
DmaData.Pci9054Dma.IopAddr = LocalAddress;
DmaData.Pci9054Dma.TransferCount = TransferCount*2;
DmaData.Pci9054Dma.IopToPciDma = Direction;//for debug;
DmaData.Pci9054Dma.TerminalCountIntr = 0;
rc = PlxDmaSglTransfer(hDevice,PrimaryPciChannel0,&DmaData,TRUE);// Don't wait for completion
if (rc == ApiSuccess)
{
EventStatus =WaitForSingleObject(hInterruptEvent,10 * 1000);
if (EventStatus!=WAIT_OBJECT_0)
return 1;
}
rc = PlxDmaSglChannelClose(hDevice,PrimaryPciChannel0);
if (rc == ApiSuccess)
return 0;
else
return 1;
}
RETURN_CODE PlxPciDeviceOpen(DEVICE_LOCATION *pDevice,HANDLE *pDrvHandle)
{
unsigned long i;
UCHAR DriverName[20];
IO_NODE *pIoNode;
RETURN_CODE rc;
if ((pDevice == NULL) || (pDrvHandle == NULL))
return ApiNullParam;
// Get the Serial number of the device, if not provided
if (strlen(pDevice->SerialNumber) == 0)
{
i = 0;
// Search for the device matching the criteria
rc = PlxPciDeviceFind(
pDevice,
&i
);
if (rc != ApiSuccess)
{
return rc;
}
}
// If provided, the SerialNumber is sufficient to open a device
strcpy(DriverName, "\\\\.\\");
strcat(DriverName, pDevice->SerialNumber);
*pDrvHandle = CreateFile(
DriverName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (*pDrvHandle == INVALID_HANDLE_VALUE)
{
*pDrvHandle = NULL;
return ApiInvalidDeviceInfo;
}
// Add the handle to the device list.
if (DeviceListAdd(*pDrvHandle) == NULL)
{
CloseHandle(*pDrvHandle);
*pDrvHandle = NULL;
return ApiInsufficientResources;
}
pIoNode = IoPoolGetNode();
// Send message to get device data from the device driver.
DeviceIoControl(
*pDrvHandle,
PLX_IOCTL_DEVICE_INIT,
NULL,
0,
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pIoNode->Overlapped)
);
*pDevice = pIoNode->IoBuffer.MgmtData.Device;
IoPoolReleaseNode(pIoNode);
return ApiSuccess;
}
RETURN_CODE PlxPciDeviceFind(DEVICE_LOCATION *pDevice,unsigned long *pRequestLimit)
{
unsigned long i;
unsigned long totalDevFound;
HANDLE hDevice;
BOOLEAN driverOpened;
IO_NODE *pIoNode;
RETURN_CODE rc;
DEVICE_LOCATION internalDevInfo;
// Check for null pointers
if (pDevice == NULL || pRequestLimit == NULL)
{
return ApiNullParam;
}
totalDevFound = 0;
driverOpened = FALSE;
pIoNode = IoPoolGetNode();
// Scan through present drivers for matches
for (i = 0; i < MAX_PLX_DRIVERS; i++)
{
strcpy(internalDevInfo.SerialNumber,PlxDrivers[i]);
rc = PlxPciDeviceOpen(
&internalDevInfo,
&hDevice
);
if (rc != ApiSuccess)
continue;
/*
we have an open driver. Now find the devices that have
matching vendor and device Ids.
*/
driverOpened = TRUE;
if (*pRequestLimit != FIND_AMOUNT_MATCHED)
pIoNode->IoBuffer.MgmtData.Value = *pRequestLimit - totalDevFound;
else
pIoNode->IoBuffer.MgmtData.Value = FIND_AMOUNT_MATCHED;
pIoNode->IoBuffer.MgmtData.Device = *pDevice;
DeviceIoControl(
hDevice,
PLX_IOCTL_PCI_DEVICE_FIND,
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
&(pIoNode->IoBuffer),
sizeof(IOCTLDATA),
NULL,
&(pIoNode->Overlapped)
);
totalDevFound += pIoNode->IoBuffer.MgmtData.Value;
if (*pRequestLimit != FIND_AMOUNT_MATCHED)
{
// Check to see if we have reached the specified device
if (*pRequestLimit < totalDevFound)
{
*pDevice = pIoNode->IoBuffer.MgmtData.Device;
IoPoolReleaseNode(
pIoNode
);
PlxPciDeviceClose(hDevice);
return ApiSuccess;
}
}
PlxPciDeviceClose(
hDevice
);
}
IoPoolReleaseNode(
pIoNode
);
if (driverOpened == FALSE)
{
if (*pRequestLimit == FIND_AMOUNT_MATCHED)
{
*pRequestLimit = 0;
}
return ApiNoActiveDriver;
}
if (*pRequestLimit == FIND_AMOUNT_MATCHED)
{
*pRequestLimit = totalDevFound;
if (totalDevFound == 0)
{
return ApiInvalidDeviceInfo;
}
else
{
return ApiSuccess;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -