Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1004 lines
25 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. busno.c
  5. Abstract:
  6. This module implements routines pertaining to PCI bus numbers.
  7. Author:
  8. Andy Thornton (andrewth) 9/5/98
  9. Revision History:
  10. --*/
  11. #include "pcip.h"
  12. VOID
  13. PciSpreadBridges(
  14. IN PPCI_FDO_EXTENSION Parent,
  15. IN UCHAR BridgeCount
  16. );
  17. UCHAR
  18. PciFindBridgeNumberLimit(
  19. IN PPCI_FDO_EXTENSION BridgeParent,
  20. IN UCHAR Base
  21. );
  22. VOID
  23. PciFitBridge(
  24. IN PPCI_FDO_EXTENSION ParentFdoExtension,
  25. IN PPCI_PDO_EXTENSION BridgePdoExtension
  26. );
  27. VOID
  28. PciSetBusNumbers(
  29. IN PPCI_PDO_EXTENSION PdoExtension,
  30. IN UCHAR Primary,
  31. IN UCHAR Secondary,
  32. IN UCHAR Subordinate
  33. );
  34. VOID
  35. PciUpdateAncestorSubordinateBuses(
  36. IN PPCI_FDO_EXTENSION FdoExtension,
  37. IN UCHAR Subordinate
  38. );
  39. VOID
  40. PciDisableBridge(
  41. IN PPCI_PDO_EXTENSION Bridge
  42. );
  43. UCHAR
  44. PciFindBridgeNumberLimitWorker(
  45. IN PPCI_FDO_EXTENSION BridgeParent,
  46. IN PPCI_FDO_EXTENSION CurrentParent,
  47. IN UCHAR Base,
  48. OUT PBOOLEAN RootConstrained
  49. );
  50. #ifdef ALLOC_PRAGMA
  51. #pragma alloc_text(PAGE, PciConfigureBusNumbers)
  52. #pragma alloc_text(PAGE, PciAreBusNumbersConfigured)
  53. #pragma alloc_text(PAGE, PciSpreadBridges)
  54. #pragma alloc_text(PAGE, PciFindBridgeNumberLimit)
  55. #pragma alloc_text(PAGE, PciFitBridge)
  56. #pragma alloc_text(PAGE, PciSetBusNumbers)
  57. #pragma alloc_text(PAGE, PciUpdateAncestorSubordinateBuses)
  58. #pragma alloc_text(PAGE, PciDisableBridge)
  59. #pragma alloc_text(PAGE, PciFindBridgeNumberLimitWorker)
  60. #endif
  61. VOID
  62. PciConfigureBusNumbers(
  63. PPCI_FDO_EXTENSION Parent
  64. )
  65. /*++
  66. Routine Description:
  67. This routine is called after scanning a PCI bus (root or bridge) and
  68. configures the bus numbers for any newly encountered bridges if possible.
  69. Any unconfigurable bridges will be set to Primary = Secondary = Subordinate = 0
  70. and their IO, Memory and BusMaster bits will be disabled. When PCI is later
  71. asked to Add to them it will fail.
  72. The Parent->Mutex lock should be held before calling this function
  73. Arguments:
  74. Parent - The bridge we have just enumerated.
  75. Return Value:
  76. Status.
  77. --*/
  78. {
  79. PPCI_PDO_EXTENSION current, parentPdo = NULL;
  80. UCHAR bridgeCount = 0, configuredBridgeCount = 0;
  81. PAGED_CODE();
  82. if (!PCI_IS_ROOT_FDO(Parent)) {
  83. parentPdo = (PPCI_PDO_EXTENSION)Parent->PhysicalDeviceObject->DeviceExtension;
  84. }
  85. //
  86. // Walk the list of child PDO's for this bus and count the number of
  87. // bridges and configured bridges
  88. //
  89. ExAcquireFastMutex(&Parent->ChildListMutex);
  90. for (current = Parent->ChildBridgePdoList;
  91. current;
  92. current = current->NextBridge) {
  93. if (current->NotPresent) {
  94. PciDebugPrint(PciDbgBusNumbers,
  95. "Skipping not present bridge PDOX @ %p\n",
  96. current
  97. );
  98. continue;
  99. }
  100. bridgeCount++;
  101. //
  102. // If we configured the parent then all the children are considered
  103. // to be unconfigured. Root buses are always configured
  104. //
  105. if ((parentPdo &&
  106. parentPdo->Dependent.type1.WeChangedBusNumbers &&
  107. (current->DeviceState == PciNotStarted))
  108. || (!PciAreBusNumbersConfigured(current))) {
  109. //
  110. // Disable this bridge and we will fix it later
  111. //
  112. PciDisableBridge(current);
  113. } else {
  114. //
  115. // The bios must have configured this bridge and it looks valid so
  116. // leave it alone!
  117. //
  118. configuredBridgeCount++;
  119. }
  120. }
  121. ExReleaseFastMutex(&Parent->ChildListMutex);
  122. //
  123. // Now there are four posibilities...
  124. //
  125. if (bridgeCount == 0) {
  126. //
  127. // There are no bridges so not a lot to do...
  128. //
  129. PciDebugPrint(PciDbgBusNumbers,
  130. "PCI - No bridges found on bus 0x%x\n",
  131. Parent->BaseBus
  132. );
  133. } else if (bridgeCount == configuredBridgeCount) {
  134. //
  135. // All the bridges are configured - still not a lot to do...
  136. //
  137. PciDebugPrint(PciDbgBusNumbers,
  138. "PCI - 0x%x bridges found on bus 0x%x - all already configured\n",
  139. bridgeCount,
  140. Parent->BaseBus
  141. );
  142. } else if (configuredBridgeCount == 0) {
  143. PciDebugPrint(PciDbgBusNumbers,
  144. "PCI - 0x%x bridges found on bus 0x%x - all need configuration\n",
  145. bridgeCount,
  146. Parent->BaseBus
  147. );
  148. //
  149. // All the bridges require configuration so we should use a spreading
  150. // out algorithm
  151. //
  152. PciSpreadBridges(Parent, bridgeCount);
  153. } else {
  154. //
  155. // Some of the bridges are configured and some are not - we should try
  156. // to fit the unconfigured ones into the holes left by the configured
  157. // ones
  158. //
  159. PCI_ASSERT(configuredBridgeCount < bridgeCount);
  160. PciDebugPrint(PciDbgBusNumbers,
  161. "PCI - 0x%x bridges found on bus 0x%x - 0x%x need configuration\n",
  162. bridgeCount,
  163. Parent->BaseBus,
  164. bridgeCount - configuredBridgeCount
  165. );
  166. //
  167. // Walk the list of PDO's again and configure each one seperatly
  168. //
  169. for (current = Parent->ChildBridgePdoList;
  170. current;
  171. current = current->NextBridge) {
  172. if (current->NotPresent) {
  173. PciDebugPrint(PciDbgBusNumbers,
  174. "Skipping not present bridge PDOX @ %p\n",
  175. current
  176. );
  177. continue;
  178. }
  179. //
  180. // Fit the bridge if we disabled it.
  181. //
  182. if ((parentPdo &&
  183. parentPdo->Dependent.type1.WeChangedBusNumbers &&
  184. (current->DeviceState == PciNotStarted))
  185. || (!PciAreBusNumbersConfigured(current))) {
  186. PCI_ASSERT(current->Dependent.type1.PrimaryBus == 0
  187. && current->Dependent.type1.SecondaryBus == 0
  188. && current->Dependent.type1.SubordinateBus == 0
  189. );
  190. PciFitBridge(Parent, current);
  191. }
  192. }
  193. }
  194. }
  195. BOOLEAN
  196. PciAreBusNumbersConfigured(
  197. IN PPCI_PDO_EXTENSION Bridge
  198. )
  199. /*++
  200. Routine Description:
  201. This checks if the bus numbers assigned to the bridge are valid
  202. Arguments:
  203. Bridge - the bridge to check
  204. Return Value:
  205. TRUE if numbers are valid FALSE otherwise.
  206. --*/
  207. {
  208. PAGED_CODE();
  209. //
  210. // Check this bridge is configured to run on the bus we found it.
  211. //
  212. if (Bridge->Dependent.type1.PrimaryBus != Bridge->ParentFdoExtension->BaseBus) {
  213. return FALSE;
  214. }
  215. //
  216. // Ensure the child bus number is greater than the parent bus.
  217. // (HP Omnibooks actually break this rule when not plugged into
  218. // their docking stations).
  219. //
  220. if (Bridge->Dependent.type1.SecondaryBus <= Bridge->Dependent.type1.PrimaryBus) {
  221. return FALSE;
  222. }
  223. //
  224. // And finally, make sure the secondary bus is in the range
  225. // of busses the bridge is programmed for. Paranoia.
  226. //
  227. if (Bridge->Dependent.type1.SubordinateBus < Bridge->Dependent.type1.SecondaryBus) {
  228. return FALSE;
  229. }
  230. return TRUE;
  231. }
  232. VOID
  233. PciSpreadBridges(
  234. IN PPCI_FDO_EXTENSION Parent,
  235. IN UCHAR BridgeCount
  236. )
  237. /*++
  238. Routine Description:
  239. This routine attemps to spread out the available bus numbers between the
  240. unconfigured bridges. It is only called if ALL the bridges on a particular
  241. bus are not configured - eg we just hot docked!
  242. If a particular brigde can not be configured it is disabled (Decodes OFF and
  243. bus number 0->0-0) and the subsequent AddDevice will fail.
  244. Arguments:
  245. Parent - The FDO extension for the bridge we are enumerating.
  246. BridgeCount - The number of bridges at this level
  247. Return Value:
  248. None
  249. --*/
  250. {
  251. UCHAR base, limit, numberCount, currentNumber, spread, maxAssigned = 0;
  252. PPCI_PDO_EXTENSION current;
  253. PAGED_CODE();
  254. PCI_ASSERT(Parent->BaseBus < PCI_MAX_BRIDGE_NUMBER);
  255. //
  256. // Seeing as we only get here if all the bridges arn't configured the base
  257. // is the lowest bus out parent passes
  258. //
  259. base = (UCHAR)Parent->BaseBus;
  260. //
  261. // The limit is constrained by the siblings of the parent bridge or in the
  262. // case that there are none, by the siblings of the parent's parent and so on
  263. // until we find a sibling or run out of buses in which case the constraint
  264. // is the maximum bus number passed by this root.
  265. //
  266. limit = PciFindBridgeNumberLimit(Parent, base);
  267. if (limit < base) {
  268. //
  269. // This normally means the BIOS or HAL messed up and got the subordinate
  270. // bus number for the root bus wrong. There's not much we can do..
  271. //
  272. PCI_ASSERT(limit >= base);
  273. return;
  274. }
  275. //
  276. // Now see if we have enough numbers available to number all the busses
  277. //
  278. numberCount = limit - base;
  279. if (numberCount == 0) {
  280. //
  281. // We don't have any bus numbers available - bail now
  282. //
  283. return;
  284. } else if (BridgeCount >= numberCount) {
  285. //
  286. // We have just/not enough - don't spread things out!
  287. //
  288. spread = 1;
  289. } else {
  290. //
  291. // Try and spread things out a bit so we can accomodate subordinate
  292. // bridges of the one we are configuring. Also leave some space on the
  293. // parent bus for any bridges that appear here (the + 1). As we have no idea
  294. // what is behind each bridge treat them equally...
  295. //
  296. spread = numberCount / (BridgeCount + 1);
  297. }
  298. //
  299. // Now assign the bus numbers - we have already disabled all the unconfigured
  300. // bridges
  301. //
  302. currentNumber = base + 1;
  303. for (current = Parent->ChildBridgePdoList;
  304. current;
  305. current = current->NextBridge) {
  306. if (current->NotPresent) {
  307. PciDebugPrint(PciDbgBusNumbers,
  308. "Skipping not present bridge PDOX @ %p\n",
  309. current
  310. );
  311. continue;
  312. }
  313. //
  314. // Now go and write it out to the hardware
  315. //
  316. PCI_ASSERT(!PciAreBusNumbersConfigured(current));
  317. //
  318. // Primary is the bus we are on, secondary is our bus number.
  319. // We don't know if there are any bridges there - we have left space
  320. // just in case - therefore we don't pass any bus numbers. If we
  321. // need to, the subordinate number can be updated later.
  322. //
  323. PciSetBusNumbers(current,
  324. base,
  325. currentNumber,
  326. currentNumber
  327. );
  328. //
  329. // Remember the max number we assigned
  330. //
  331. maxAssigned = currentNumber;
  332. //
  333. // Check if we have run out of numbers
  334. //
  335. if ((currentNumber + spread) < currentNumber // wrapped
  336. || (currentNumber + spread) > limit) {
  337. break;
  338. } else {
  339. //
  340. // Move onto the next number
  341. //
  342. //currentNumber += spread;
  343. currentNumber = currentNumber + spread;
  344. }
  345. }
  346. //
  347. // Now we have programmed the bridges - we need to go back and update the
  348. // subordinate bus numbers for all ancestor bridges.
  349. //
  350. PCI_ASSERT(maxAssigned > 0);
  351. PciUpdateAncestorSubordinateBuses(Parent, maxAssigned);
  352. }
  353. UCHAR
  354. PciFindBridgeNumberLimitWorker(
  355. IN PPCI_FDO_EXTENSION BridgeParent,
  356. IN PPCI_FDO_EXTENSION CurrentParent,
  357. IN UCHAR Base,
  358. OUT PBOOLEAN RootConstrained
  359. )
  360. /*++
  361. Routine Description:
  362. This determines the subordinate bus number a bridge on the bus BridgeParent
  363. with secondary number Base can have given the constraints of the configured
  364. busses in the system.
  365. Arguments:
  366. BridgeParent - The bus on which the bridge resides
  367. CurrentParent - The current bridge we are looking at (used for synchronization)
  368. Base - The primary bus number of this bridge (ie the parent's secondary bus number)
  369. Constraint - The number of the bus that constrains us
  370. RootConstrained - Set to TRUE if we were constrained by a root appeture, FALSE
  371. if constrained by another bridge
  372. Return Value:
  373. None
  374. --*/
  375. {
  376. PPCI_PDO_EXTENSION current;
  377. UCHAR currentNumber, closest = 0;
  378. PAGED_CODE();
  379. if (BridgeParent != CurrentParent) {
  380. //
  381. // We're going to mess with the child pdo list - lock the state...
  382. //
  383. ExAcquireFastMutex(&CurrentParent->ChildListMutex);
  384. }
  385. //
  386. // Look for any bridge that will constrain us
  387. //
  388. for (current = CurrentParent->ChildBridgePdoList;
  389. current;
  390. current = current->NextBridge) {
  391. if (current->NotPresent) {
  392. PciDebugPrint(PciDbgBusNumbers,
  393. "Skipping not present bridge PDOX @ %p\n",
  394. current
  395. );
  396. continue;
  397. }
  398. //
  399. // Unconfigured bridges can't constrain us
  400. //
  401. if (!PciAreBusNumbersConfigured(current)) {
  402. continue;
  403. }
  404. currentNumber = current->Dependent.type1.SecondaryBus;
  405. if (currentNumber > Base
  406. && (currentNumber < closest || closest == 0)) {
  407. closest = currentNumber;
  408. }
  409. }
  410. //
  411. // If we haven't found a closest bridge then move up one level - yes this
  412. // is recursive but is bounded by the depth of the pci tree is the best way
  413. // of dealing with the hierarchial locking.
  414. //
  415. if (closest == 0) {
  416. if (CurrentParent->ParentFdoExtension == NULL) {
  417. //
  418. // We have reached the root without finding a sibling
  419. //
  420. *RootConstrained = TRUE;
  421. closest = CurrentParent->MaxSubordinateBus;
  422. } else {
  423. closest = PciFindBridgeNumberLimitWorker(BridgeParent,
  424. CurrentParent->ParentFdoExtension,
  425. Base,
  426. RootConstrained
  427. );
  428. }
  429. } else {
  430. //
  431. // We are constrained by a bridge so by definition not by a root.
  432. //
  433. *RootConstrained = FALSE;
  434. }
  435. if (BridgeParent != CurrentParent) {
  436. ExReleaseFastMutex(&CurrentParent->ChildListMutex);
  437. }
  438. return closest;
  439. }
  440. UCHAR
  441. PciFindBridgeNumberLimit(
  442. IN PPCI_FDO_EXTENSION Bridge,
  443. IN UCHAR Base
  444. )
  445. /*++
  446. Routine Description:
  447. This determines the subordinate bus number a bridge on the bus BridgeParent
  448. with secondary number Base can have given the constraints of the configured
  449. busses in the system.
  450. Arguments:
  451. BridgeParent - The bus on which the bridge resides
  452. Base - The primary bus number of this bridge (ie the parent's secondary bus number)
  453. Return Value:
  454. The max subordinate value.
  455. --*/
  456. {
  457. BOOLEAN rootConstrained;
  458. UCHAR constraint;
  459. PAGED_CODE();
  460. constraint = PciFindBridgeNumberLimitWorker(Bridge,
  461. Bridge,
  462. Base,
  463. &rootConstrained
  464. );
  465. if (rootConstrained) {
  466. //
  467. // We are constrained by the maximum bus number that this root bus passes
  468. // - this is therefore the max subordinate bus.
  469. //
  470. return constraint;
  471. } else {
  472. //
  473. // If we are not constrained by a root bus we must be constrained by a
  474. // bridge and thus the max subordinate value we can assign to the bus is
  475. // one less that the bridge that constrained us. (A bridge must have a
  476. // bus number greater that 1 so we can't wrap)
  477. //
  478. PCI_ASSERT(constraint > 0);
  479. return constraint - 1;
  480. }
  481. }
  482. VOID
  483. PciFitBridge(
  484. IN PPCI_FDO_EXTENSION Parent,
  485. IN PPCI_PDO_EXTENSION Bridge
  486. )
  487. /*++
  488. Routine Description:
  489. This routine attemps to find a range of bus numbers for Bridge given the
  490. constraints of the already configured bridges.
  491. If a particular brigde can not be configured it is disabled (Decodes OFF and
  492. bus number 0->0-0) and the subsequent AddDevice will fail.
  493. Arguments:
  494. Parent - The FDO extension for the bridge we are enumerating.
  495. Bridge - The brige we want to configure
  496. Return Value:
  497. None
  498. --*/
  499. {
  500. PPCI_PDO_EXTENSION current;
  501. UCHAR base, limit, gap, bestBase = 0, biggestGap = 0, lowest = 0xFF;
  502. PAGED_CODE();
  503. for (current = Parent->ChildBridgePdoList;
  504. current;
  505. current = current->NextBridge) {
  506. if (current->NotPresent) {
  507. PciDebugPrint(PciDbgBusNumbers,
  508. "Skipping not present bridge PDOX @ %p\n",
  509. current
  510. );
  511. continue;
  512. }
  513. //
  514. // Only look at configured bridges - buses we disabled have
  515. // bus numbers 0->0-0 which is helpfully invalid
  516. //
  517. if (PciAreBusNumbersConfigured(current)) {
  518. //
  519. // Get the base and limit for each bridge and calculate which bridge
  520. // has the biggest gap.
  521. //
  522. base = (UCHAR) current->Dependent.type1.SubordinateBus;
  523. limit = PciFindBridgeNumberLimit(Parent, base);
  524. //
  525. // This ASSERT might fail if a BIOS or HAL misreported the limits
  526. // of a root bridge. For example, an ACPI BIOS might have a _CRS
  527. // for the root bridge that specifies bus-numbers 0 to 0 (length 1)
  528. // are passed down, even though the real range is 0 to 255.
  529. //
  530. PCI_ASSERT(limit >= base);
  531. gap = limit - base;
  532. if (gap > biggestGap) {
  533. PCI_ASSERT(gap > 0);
  534. biggestGap = gap;
  535. bestBase = base + 1;
  536. }
  537. if (current->Dependent.type1.SecondaryBus < lowest) {
  538. lowest = current->Dependent.type1.SecondaryBus;
  539. }
  540. }
  541. }
  542. //
  543. // Now make sure the gap between the bus we are on and the first bridge
  544. // is not the biggest - lowest must always be greater that the parents bus
  545. // number or it is miss configured and would have failed the
  546. // BusNumbersConfigured test above.
  547. //
  548. PCI_ASSERT(lowest > Parent->BaseBus);
  549. gap = lowest - (Parent->BaseBus + 1);
  550. if (gap > biggestGap) {
  551. PCI_ASSERT(gap > 0);
  552. biggestGap = gap;
  553. bestBase = Parent->BaseBus + 1;
  554. }
  555. //
  556. // Did we find anywhere to put the bridge?
  557. //
  558. if (biggestGap >= 1) {
  559. //
  560. // Ok - we have some space to play with so we can configure out bridge
  561. // right in the middle of the gap, if the bestGap is 1 (ie the bridge
  562. // just fits) then this still works.
  563. //
  564. base = bestBase + (biggestGap / 2);
  565. //
  566. // Set subordinate equal to secondary as we are just leaving room for
  567. // any bridges.
  568. //
  569. PciSetBusNumbers(Bridge, Parent->BaseBus, base, base);
  570. //
  571. // Update the ancestor subordinates if we configured the bridge
  572. //
  573. PciUpdateAncestorSubordinateBuses(Parent,
  574. Bridge->Dependent.type1.SecondaryBus
  575. );
  576. }
  577. }
  578. VOID
  579. PciSetBusNumbers(
  580. IN PPCI_PDO_EXTENSION PdoExtension,
  581. IN UCHAR Primary,
  582. IN UCHAR Secondary,
  583. IN UCHAR Subordinate
  584. )
  585. /*++
  586. Routine Description:
  587. This routine sets the bus numbers for a bridge and tracks if we have changed
  588. bus numbers.
  589. Arguments:
  590. PdoExtension - The PDO for the bridge
  591. Primary - The primary bus number to assign
  592. Secondary - The secondary bus number to assign
  593. Subordinate - The subordinate bus number to assign
  594. Return Value:
  595. None
  596. --*/
  597. {
  598. PCI_COMMON_HEADER commonHeader;
  599. PPCI_COMMON_CONFIG commonConfig = (PPCI_COMMON_CONFIG)&commonHeader;
  600. PAGED_CODE();
  601. PCI_ASSERT(Primary < Secondary || (Primary == 0 && Secondary == 0));
  602. PCI_ASSERT(Secondary <= Subordinate);
  603. //
  604. // Fill in in the config. Note that the Primary/Secondary/Subordinate bus
  605. // numbers are in the same place for type1 and type2 headers.
  606. //
  607. commonConfig->u.type1.PrimaryBus = Primary;
  608. commonConfig->u.type1.SecondaryBus = Secondary;
  609. commonConfig->u.type1.SubordinateBus = Subordinate;
  610. //
  611. // Grab the PCI Bus lock - this will let hwverifier reliably check the
  612. // config space against our extension.
  613. //
  614. ExAcquireFastMutex(&PciBusLock);
  615. //
  616. // Remember in the PDO
  617. //
  618. PdoExtension->Dependent.type1.PrimaryBus = Primary;
  619. PdoExtension->Dependent.type1.SecondaryBus = Secondary;
  620. PdoExtension->Dependent.type1.SubordinateBus = Subordinate;
  621. PdoExtension->Dependent.type1.WeChangedBusNumbers = TRUE;
  622. PciWriteDeviceConfig(
  623. PdoExtension,
  624. &commonConfig->u.type1.PrimaryBus,
  625. FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.PrimaryBus),
  626. sizeof(Primary) + sizeof(Secondary) + sizeof(Subordinate)
  627. );
  628. ExReleaseFastMutex(&PciBusLock);
  629. }
  630. VOID
  631. PciUpdateAncestorSubordinateBuses(
  632. IN PPCI_FDO_EXTENSION FdoExtension,
  633. IN UCHAR Subordinate
  634. )
  635. /*++
  636. Routine Description:
  637. This routine walks the bridge hierarchy updating the subordinate bus numbers
  638. of each ancestor to ensure that numbers up to Subordinate are passed.
  639. Arguments:
  640. FdoExtension - The Fdo for the parent of the bridge(s) we have just configured
  641. Subordinate - The maximum (subordinate) bus number to pass
  642. Return Value:
  643. None
  644. --*/
  645. {
  646. PPCI_FDO_EXTENSION current;
  647. PPCI_PDO_EXTENSION currentPdo;
  648. PAGED_CODE();
  649. //
  650. // For all ancestors except the root update the subordinate bus number
  651. //
  652. for (current = FdoExtension;
  653. current->ParentFdoExtension; // Root has no parent
  654. current = current->ParentFdoExtension) {
  655. currentPdo = (PPCI_PDO_EXTENSION)current->PhysicalDeviceObject->DeviceExtension;
  656. PCI_ASSERT(!currentPdo->NotPresent);
  657. if (currentPdo->Dependent.type1.SubordinateBus < Subordinate) {
  658. currentPdo->Dependent.type1.SubordinateBus = Subordinate;
  659. PciWriteDeviceConfig(currentPdo,
  660. &Subordinate,
  661. FIELD_OFFSET(PCI_COMMON_CONFIG,
  662. u.type1.SubordinateBus),
  663. sizeof(Subordinate)
  664. );
  665. }
  666. }
  667. //
  668. // Ok so now we're at the root - can't be too careful on a checked build
  669. // so lets make sure the subordinate value we came up with actually gets
  670. // down this root...
  671. //
  672. PCI_ASSERT(PCI_IS_ROOT_FDO(current));
  673. PCI_ASSERT(Subordinate <= current->MaxSubordinateBus);
  674. }
  675. VOID
  676. PciDisableBridge(
  677. IN PPCI_PDO_EXTENSION Bridge
  678. )
  679. /*++
  680. Routine Description:
  681. This routine disables a bridge by turing of its decodes and zeroing its
  682. bus numbers.
  683. Arguments:
  684. PdoExtension - The PDO for the bridge
  685. Return Value:
  686. node
  687. --*/
  688. {
  689. PAGED_CODE();
  690. PCI_ASSERT(Bridge->DeviceState == PciNotStarted);
  691. //
  692. // Zero all the bus numbers so we shouldn't pass any config cycles
  693. //
  694. PciSetBusNumbers(Bridge, 0, 0, 0);
  695. // NTRAID #62594 - 04/03/2000 - andrewth
  696. // Close the windows in case this is the VGA bridge which we must
  697. // leave decoding...
  698. //
  699. // Turn off the decodes so we don't pass IO or Memory cycles and bus
  700. // master so we don't generate any
  701. //
  702. PciDecodeEnable(Bridge, FALSE, NULL);
  703. }