📄 plxdrv.c
字号:
/* Copyright 1990-1994, PEP Modular Computers */
/* Copyright 1984-1994, Wind River Systems, Inc. */
/* includes */
#include "vxWorks.h"
#include "stdio.h"
#include "types.h"
#include "iosLib.h"
#include "errnoLib.h"
#include "dosFsLib.h"
// for plxdrv internal use
//#include "plxdrv.h"
#include "../../../include/windrvr.h"
#include "../../../samples/shared/pci_regs.h"
#include "../../../samples/shared/bits.h"
#define PLXDRV_DEBUG
#undef PLXDRV_DEBUG
#ifdef PLXDRV_DEBUG
#define plxdrv_printf printf
#else
#define plxdrv_printf
#endif
typedef struct
{
WD_INTERRUPT Int;
HANDLE hThread;
WD_TRANSFER Trans[2];
PVOID funcIntHandler;
} P9050_INTERRUPT_MY;
typedef struct
{
DWORD dwLocalBase;
DWORD dwMask;
DWORD dwBytes;
DWORD dwAddr;
DWORD dwAddrDirect;
BOOL fIsMemory;
} P9050_ADDR_DESC_MY;
typedef struct P9050_STRUCT_MY
{
HANDLE hWD;
WD_CARD cardLock;
WD_PCI_SLOT pciSlot;
WD_CARD_REGISTER cardReg;
P9050_ADDR_DESC_MY addrDesc[AD_PCI_BARS];
P9050_INTERRUPT_MY Int;
} P9050_STRUCT_MY;
// for plxdrv internal use
#define IVEC_TO_INUM(intVec) ((int) (intVec) >> 3)
#define INUM_TO_IVEC(intNum) ((VOIDFUNCPTR *) ((intNum) << 3))
#define INT_NUM_IRQ0 0x20 /* vector number for IRQ0 */
/* typedefs */
typedef struct /* PLX_DEV */
{
DEV_HDR ioDev;
BOOL created;
} PLX_DEV;
/* defines */
#define PLX_DEVICE "/plx9050"
/* locals */
LOCAL PLX_DEV plxDv = /* device descriptor */
{
{{NULL}},
FALSE
};
LOCAL int plxDrvNum; /* driver number assigned to this driver */
/* forward declarations */
LOCAL int plxDelete(void);
LOCAL int plxOpen (PLX_DEV *pPlxDv);
LOCAL int plxClose (PLX_DEV *pPlxDv);
LOCAL int plxWrite(PLX_DEV *pPlxDv,unsigned char *pBuffer,int size);
LOCAL int plxRead(PLX_DEV *pPlxDv,unsigned char *pBuffer,int size);
LOCAL STATUS plxIoctl (PLX_DEV *pPlxDv, int request, void *pParam);
LOCAL void PciScanCards (WD_PCI_SCAN_CARDS *pciScan);
LOCAL void Version(WD_VERSION *ver);
LOCAL void PciGetCardInfo (WD_PCI_CARD_INFO *pciCardInfo);
LOCAL void CardRegister(P9050_STRUCT_MY *hPlx);
LOCAL void CardUnregister(P9050_STRUCT_MY *hPlx);
LOCAL void PciConfigDump(WD_PCI_CONFIG_DUMP *pciCnf);
LOCAL void Sleep( WD_SLEEP *pParam );
LOCAL void Transfer(WD_TRANSFER *trans);
LOCAL int IntEnable( WD_INT *P9050_IntHandler );
LOCAL int IntDisable( WD_INT *P9050_IntHandler );
STATUS pciConfigInAddressSpace
(
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int address, /* address of the configuration space */
int * pData /* data read from the address */
);
/*******************************************************************************
*
* rtcDrv - adding the driver to the driver system
*
* This routine must be called in supervisor state.
*
* RETURNS: OK or ERROR
*/
STATUS plxDrv (void)
{
if (plxDrvNum > 0)
return (OK);
plxDrvNum = iosDrvInstall (plxOpen, plxDelete, plxOpen, //(FUNCPTR) NULL
plxClose, plxRead, plxWrite,
plxIoctl);
return (plxDrvNum == ERROR ? ERROR : OK);
}
/*******************************************************************************
*
* rtcDevCreate - create a device for the real time clock
*
* RETURN: OK or ERROR, if already created.
*/
STATUS plxDevCreate (void)
{
/* test if driver already installed */
if (plxDrvNum <= 0)
{
(void) errnoSet (S_ioLib_NO_DRIVER);
return (ERROR);
}
/* if there is a device already created, don't do it */
if (plxDv.created)
return (ERROR);
/*
* mark the device as having been created
* and add it to the I/O system
*/
plxDv.created = TRUE;
return (iosDevAdd ((DEV_HDR *) &plxDv, PLX_DEVICE, plxDrvNum));
}
/********************************************************
* Initialize the device "/plx9050"
*
*
*/
void plx9050(void)
{
plxDrv ();
plxDevCreate();
}
/*******************************************************************************
*
* plxDelete - delete PLX_DEVICE
*/
LOCAL int plxDelete
(
void
)
{
iosDevDelete((DEV_HDR *) &plxDv);
iosDrvRemove(plxDrvNum,TRUE);
return OK;
}
/*******************************************************************************
*
* plxOpen - open file to PLX_DEVICE
*/
LOCAL int plxOpen
(
PLX_DEV *pPlxDv
)
{
//plxdrv_printf("/plx9050 is opened!\n");
return ((int) pPlxDv);
}
/*******************************************************************************
*
* plxClose - close file to PLX_DEVICE
*/
LOCAL int plxClose
(
PLX_DEV *pPlxDv
)
{
//plxdrv_printf("/plx9050 is closed!\n");
return (OK);
}
/*******************************************************************************
*
* plxWrite - read data from PLX_DEVICE
*/
LOCAL int plxRead
(
PLX_DEV *pPlxDv,
unsigned char *pBuffer,
int size
)
{
plxdrv_printf("/plx9050 read has run!\n");
plxdrv_printf("%s",pBuffer);
return size;
}
/*******************************************************************************
*
* plxWrite - write data to PLX_DEVICE
*/
LOCAL int plxWrite
(
PLX_DEV *pPlxDv,
unsigned char *pBuffer,
int size
)
{
plxdrv_printf("/plx9050 write has run!\n");
plxdrv_printf("%s",pBuffer);
return size;
}
/*******************************************************************************
*
* plxIoctl - special device control
*
* This driver responds to the ioctl calls described in the header.
*/
LOCAL STATUS plxIoctl
(
PLX_DEV *pPlxDv, /* device to control */
int request, /* request code */
void *pParam /* print if TRUE, else only set structure */
)
{
STATUS state = OK; /* state of the ioctl calls */
switch (request)
{
case 1:
plxdrv_printf( "function 1 has run! print is 0x%s .\n",(char *)pParam );
break;
case IOCTL_WD_PCI_SCAN_CARDS:
plxdrv_printf( "function IOCTL_WD_PCI_SCAN_CARDS has run! \n");
PciScanCards ( (WD_PCI_SCAN_CARDS *)pParam );
break;
case IOCTL_WD_VERSION:
plxdrv_printf( "function IOCTL_WD_VERSION has run! \n");
Version( (WD_VERSION *)pParam);
break;
case IOCTL_WD_PCI_GET_CARD_INFO:
plxdrv_printf( "function IOCTL_WD_PCI_GET_CARD_INFO has run! \n");
PciGetCardInfo( (WD_PCI_CARD_INFO *)pParam );
break;
case IOCTL_WD_CARD_REGISTER:
plxdrv_printf( "function IOCTL_WD_CARD_REGISTER has run! \n");
CardRegister( (P9050_STRUCT_MY *)pParam );
break;
case IOCTL_WD_CARD_UNREGISTER:
plxdrv_printf( "function IOCTL_WD_CARD_UNREGISTER has run! \n");
CardUnregister( (P9050_STRUCT_MY *)pParam );
break;
case IOCTL_WD_PCI_CONFIG_DUMP:
// plxdrv_printf( "function IOCTL_WD_PCI_CONFIG_DUMP has run! \n");
PciConfigDump( (WD_PCI_CONFIG_DUMP *)pParam );
break;
case IOCTL_WD_TRANSFER:
// plxdrv_printf( "function IOCTL_WD_TRANSFER has run! \n");
Transfer( (WD_TRANSFER *)pParam );
break;
case IOCTL_WD_SLEEP:
// plxdrv_printf( "function IOCTL_WD_TRANSFER has run! \n");
Sleep( (WD_SLEEP *)pParam );
break;
case IOCTL_WD_INT_ENABLE:
// plxdrv_printf( "function IOCTL_WD_TRANSFER has run! \n");
IntEnable( (WD_INT *)pParam );
break;
case IOCTL_WD_INT_DISABLE:
// plxdrv_printf( "function IOCTL_WD_TRANSFER has run! \n");
IntDisable( (WD_INT *)pParam );
break;
default:
plxdrv_printf("No such functions!\n");
break;
}
return (state);
}
/////////////////////////////////////////////////////////////////////////////////
// //
// The following is the functions of implement low level pci operations //
// //
/////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
* scan the pci card
*/
LOCAL void PciScanCards (WD_PCI_SCAN_CARDS *pciScan)
{
int li;
int pBusNo;
int pDeviceNo;
int pFuncNo;
DWORD dwVendorID = pciScan->searchId.dwVendorId;
DWORD dwDeviceID = pciScan->searchId.dwDeviceId;
pciScan->dwCards = 0;
for(li = 0; li<32;li++)
{
if( pciFindDevice(dwVendorID,dwDeviceID,li,&pBusNo,&pDeviceNo,&pFuncNo)==0)
{
pciScan->dwCards++;
pciScan->cardSlot[li].dwBus = pBusNo;
pciScan->cardSlot[li].dwSlot = pDeviceNo;
pciScan->cardSlot[li].dwFunction = pFuncNo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -