PCI设备驱动代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、搜索设备
根据PCI设备的VendorID和DeviceID搜索PCI设备,返回PCI配置信息和Slot Number:int DeviceSearch (int vendorID,int deviceID,
PCI_SLOT_NUMBER*pSlotNumber,PPCI_COMMON_CONFIG pPcidata)
{ULONG bus;
ULONG deviceNunber;
ULONG functionNumber;
ULONG bytesREAD;
BOOL bFlag=TURE;
pSlotNumber->u.bits.Reserved=0;
for(bus=0;bFlag;bus++)
{for(deviceNumber=0;deviceNumber
for(functionNumber=0;functionNumber {pSlotNumber->u.bits.FunctionNumber=functionNumber; bytesRead=RtGetBusDataByOffset(PCIConfiguration,bus,pSlotNumber->u.AsULONG,pPciData ,0, PCI_COMMON_HDR_LENGTH); If(bytesRead==0) {bFlag=FALSE; break; }\\没有发现bus if(bytesRead==VENDOR_ID_SIZE&&pPciData->Vendor==PCI_INVALID_VENDORID)\\\ continue;\\\没有发现device if((pPciData->VendorID==vendorID)&&(pPciData->DeviceID==deviceID)) return bus; }发现device } } Return DEVICE_NOT_FOUND; } 2、初始化设备 利用RtTranslateBusAddress()和RtMapMemory(), RtTranslateBusAddress()把PCI设备地址转化为CPU可直接访问的物理地址,RtMapMemory()把物理地址映射到虚拟地址。物理地址映射到虚拟地址映射范围一般为4K,RtMapMemory()函数默认最大可以映射的范围64M字节: BOOL DeviceStartup(int busNumber,PCI_SLOT_NUMBER*pSlotNumber,PPCI_COMMON_ CONFIG pPciData) { LARGE_INTEGER baseMemAddr; LARGE_INTEGER PhysMemAddr; ULONG AddressSpace=0; Int addressRange=4*1024; Int memoryRange=60*1024*1024; ULONG bytesWritten; Int i; If(!RTEnablePortlo((PCHAR)IOAddress,sizeof(DeviceIORegs))) Return FALSE;\\\ I/O允许 for(i=0;i { baseMemAddr.QuadPart=pPciData->u.type0.BaseAddresses{i}; if(!RtTranslateBusAddress(PCIBus,busNumber,baseMemAddr,&AddressSpace, &PhysMemAddr)) {vMemAddr[i]=NULL; continue; } if(i!=BASE_MEMORY_RSG) vMemAddr[i]=RtMapMemory(PhysMemAddr,addressRange,0); vMemAddr[i]=RtMapMemory(PhysMemAddr,memoryRange,0); }\\\基地址转换设备-物理-IO pPciData->Command=(PCI_ENABLE_IO_SPACE|PCI_ENABLE_MEMORY_SPACE| PCI_ENABLE_BUS_MASTER|PCI_ENABLEWRITE_AND_INVALIDATE); bytesWritten=RtSetBusDataByOffset(PCIConfiguration,busNumber,pSlotNumber->u.AsULONG, pPciData,0,PCI_COMMON_HDR_LENGTH); if(bytesWritten==0) return FALSE; RtSleep(500); return TURE; } 3、打开设备 为DMA通道发送、接受网络中断等硬件功能模块创建信号量。 int RFM2gOpen() { int EventType; char *MsgWait[RFM2GEVENT_LAST]; DMABusy=RtCreateSemaphore(NULL,1,1,”Message.DMA0busy”); if (DMABusy==NULL) MsgAndExit(“RtCreateSemaphore for DMA0Busy failed.”);\\DMA忙 DMADone=RtCreateSemaphore(NULL,0,1,”Message.DMA0done”); if (DMADone==NULL)