/* * This is the entry routine for all system bus drivers,it is called by DeviceManager when * it is initializing. * This routine checks if there is(are) PCI bus(es) in system,if not,returns FALSE,else,scan * all PCI buses,configure all devices reside on the PCI buses,and returns TRUE. */ BOOL PciBusDriver(__DEVICE_MANAGER* lpDevMgr) { BOOL bResult = FALSE; BUG_ON(NULL == lpDevMgr); /* Only available in process of system initialization. */ BUG_ON(!IN_SYSINITIALIZATION()); /* Probe if there is PCI bus present. */ bResult = PciBusProbe(); if (!bResult) { /* No PCI bus presents. */ return FALSE; } /* Scan all PCI device(s) attaching on the PCI bus system. */ PciScanBus(lpDevMgr,NULL,0); return TRUE; }
// //The implementation of PciBusDriver routine. //This is the entry routine for all system bus drivers,it is called by DeviceManager when //this object is initializing. //This routine checks if there is(are) PCI bus(es) in system,if not,returns FALSE,else,scan //all PCI buses,configure all devices reside on the PCI buses,and returns TRUE. // BOOL PciBusDriver(__DEVICE_MANAGER* lpDevMgr) { BOOL bResult = FALSE; if(NULL == lpDevMgr) return FALSE; // //First,probe if there is PCI bus present. // bResult = PciBusProbe(); if(!bResult) //No PCI bus. return FALSE; // //Now,should scan all PCI devices. // PciScanBus(lpDevMgr,NULL,0); return TRUE; }
/* * Scans a PCI bus and all it's child buses(if exist).For each bus,use * one element of SystemBus array(in DeviceManager object) to record it. * This routine returns the largest bus number in this bus tree,if failed, * returns MAX_DWORD_VALUE, which is 0xFFFFFFFF currently. */ static DWORD PciScanBus(__DEVICE_MANAGER* lpDevMgr, __PHYSICAL_DEVICE* lpBridge, DWORD dwBusNum) { DWORD dwLoop = 0; __PHYSICAL_DEVICE* lpPhyDev = NULL; DWORD dwSubNum = dwBusNum; /* Basic checking. */ BUG_ON(NULL == lpDevMgr); /* * This routine can be called only in process of system * initialization,so no locks are obtained when initialize * the physial device list or other global data structures. */ BUG_ON(!IN_SYSINITIALIZATION()); if(255 <= dwBusNum) { /* Maximal bus number should not exceed 255. */ return MAX_DWORD_VALUE; } for(dwLoop = 0;dwLoop < MAX_BUS_NUM;dwLoop ++) { if (BUS_TYPE_NULL == lpDevMgr->SystemBus[dwLoop].dwBusType) { break; } } if(MAX_BUS_NUM == dwLoop) { /* Can not find a free bus,the number of system buses exceed MAX_BUS_NUM. */ return MAX_DWORD_VALUE; } /* Now we have found a free system bus element,initialize it. */ lpDevMgr->SystemBus[dwLoop].dwBusType = BUS_TYPE_PCI; lpDevMgr->SystemBus[dwLoop].dwBusNum = dwBusNum; lpDevMgr->SystemBus[dwLoop].lpHomeBridge = lpBridge; if(lpBridge) { /* If the current bus is not root bus. */ lpDevMgr->SystemBus[dwLoop].lpParentBus = lpBridge->lpHomeBus; lpBridge->lpChildBus = &lpDevMgr->SystemBus[dwLoop]; } //Set PCI bus operations. lpDevMgr->SystemBus[dwLoop].ReadConfig = PciReadConfig; lpDevMgr->SystemBus[dwLoop].WriteConfig = PciWriteConfig; /* Scan all devices on this bus. */ PciScanDevices(&lpDevMgr->SystemBus[dwLoop]); lpPhyDev = lpDevMgr->SystemBus[dwLoop].lpDevListHdr; /* Scan all child buses of the current bus. */ while(lpPhyDev) { if(PCI_DEVICE_TYPE_BRIDGE == ((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->dwDeviceType) { /* PCI bridge. */ dwSubNum = PciScanBus(lpDevMgr, lpPhyDev, ((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->ucSecondary); } lpPhyDev = lpPhyDev->lpNext; } return dwSubNum; }
// //The following routine scans a PCI bus and all it's child buses(if exist),for each bus,use //one element of SystemBus array(in DeviceManager object) to record it. //This routine returns the largest bus number in this bus tree,if failed,returns MAX_DWORD_VALUE, //which is 0xFFFFFFFF currently. // static DWORD PciScanBus(__DEVICE_MANAGER* lpDevMgr, __PHYSICAL_DEVICE* lpBridge, DWORD dwBusNum) { DWORD dwLoop = 0; DWORD dwFlags = 0; //__PCI_DEVICE_INFO* lpDevInfo = NULL; __PHYSICAL_DEVICE* lpPhyDev = NULL; DWORD dwSubNum = dwBusNum; if(NULL == lpDevMgr) //Parameter check. { return MAX_DWORD_VALUE; } if(255 <= dwBusNum) //Maximal bus number should not exceed 255. { return MAX_DWORD_VALUE; } __ENTER_CRITICAL_SECTION(NULL,dwFlags); for(dwLoop = 0;dwLoop < MAX_BUS_NUM;dwLoop ++) { if(BUS_TYPE_NULL == lpDevMgr->SystemBus[dwLoop].dwBusType) break; } if(MAX_BUS_NUM == dwLoop) //Can not find a free bus,the number of system buses exceed //MAX_BUS_NUM. { __LEAVE_CRITICAL_SECTION(NULL,dwFlags); return MAX_DWORD_VALUE; } // //Now,we have found a free system bus element,so initialize it. // lpDevMgr->SystemBus[dwLoop].dwBusType = BUS_TYPE_PCI; lpDevMgr->SystemBus[dwLoop].dwBusNum = dwBusNum; lpDevMgr->SystemBus[dwLoop].lpHomeBridge = lpBridge; if(lpBridge) //If the current bus is not root bus. { lpDevMgr->SystemBus[dwLoop].lpParentBus = lpBridge->lpHomeBus; lpBridge->lpChildBus = &lpDevMgr->SystemBus[dwLoop]; } //Set PCI bus operations. lpDevMgr->SystemBus[dwLoop].ReadConfig = PciReadConfig; lpDevMgr->SystemBus[dwLoop].WriteConfig = PciWriteConfig; PciScanDevices(&lpDevMgr->SystemBus[dwLoop]); //Scan all devices on this bus. lpPhyDev = lpDevMgr->SystemBus[dwLoop].lpDevListHdr; while(lpPhyDev) //Now,scan all child buses of the current bus. { if(PCI_DEVICE_TYPE_BRIDGE == ((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->dwDeviceType) //This is a PCI-PCI //bridge. { dwSubNum = PciScanBus(lpDevMgr,lpPhyDev,//++dwBusNum); //Scan child bus. ((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->ucSecondary); } lpPhyDev = lpPhyDev->lpNext; } __LEAVE_CRITICAL_SECTION(NULL,dwFlags); return dwSubNum; }