⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcifuction_haero.c

📁 一个 PCI 驱动,实现PC 机与 PCI9045 的通信
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -