Source code of Windows XP (NT5)
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.

915 lines
23 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. config.c
  5. Abstract:
  6. Routines for accessing config space in the PCI-PCI bridge
  7. Author:
  8. John Vert (jvert) 10/27/1997
  9. Revision History:
  10. --*/
  11. #include "agplib.h"
  12. typedef struct _BUS_SLOT_ID {
  13. ULONG BusId;
  14. ULONG SlotId;
  15. } BUS_SLOT_ID, *PBUS_SLOT_ID;
  16. //
  17. // Local function prototypes
  18. //
  19. NTSTATUS
  20. ApGetSetDeviceBusData(
  21. IN PCOMMON_EXTENSION Extension,
  22. IN BOOLEAN Read,
  23. IN PVOID Buffer,
  24. IN ULONG Offset,
  25. IN ULONG Length
  26. );
  27. NTSTATUS
  28. ApGetSetBusData(
  29. IN PBUS_SLOT_ID BusSlotId,
  30. IN BOOLEAN Read,
  31. IN PVOID Buffer,
  32. IN ULONG Offset,
  33. IN ULONG Length
  34. );
  35. NTSTATUS
  36. ApFindAgpCapability(
  37. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  38. IN PVOID Context,
  39. OUT PPCI_AGP_CAPABILITY Capability,
  40. OUT UCHAR *pOffset,
  41. OUT PPCI_COMMON_CONFIG PciCommonConfig OPTIONAL
  42. );
  43. NTSTATUS
  44. ApQueryBusInterface(
  45. IN PDEVICE_OBJECT DeviceObject,
  46. OUT PBUS_INTERFACE_STANDARD BusInterface
  47. )
  48. /*++
  49. Routine Description:
  50. Sends a query-interface IRP to the specified device object
  51. to obtain the BUS_INTERFACE_STANDARD interface.
  52. Arguments:
  53. DeviceObject - Supplies the device object to send the BUS_INTERFACE_STANDARD to
  54. BusInterface - Returns the bus interface
  55. Return Value:
  56. STATUS_SUCCESS if successful
  57. NTSTATUS if unsuccessful
  58. --*/
  59. {
  60. PIRP Irp;
  61. KEVENT Event;
  62. PIO_STACK_LOCATION IrpSp;
  63. IO_STATUS_BLOCK IoStatusBlock;
  64. NTSTATUS Status;
  65. ULONG ReturnLength;
  66. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  67. Irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
  68. DeviceObject,
  69. NULL,
  70. 0,
  71. NULL,
  72. &Event,
  73. &IoStatusBlock );
  74. if (Irp == NULL) {
  75. return(STATUS_INSUFFICIENT_RESOURCES);
  76. }
  77. IrpSp = IoGetNextIrpStackLocation( Irp );
  78. ASSERT(IrpSp != NULL);
  79. Irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
  80. IrpSp->MajorFunction = IRP_MJ_PNP;
  81. IrpSp->MinorFunction = IRP_MN_QUERY_INTERFACE;
  82. IrpSp->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
  83. IrpSp->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
  84. IrpSp->Parameters.QueryInterface.Version = 1;
  85. IrpSp->Parameters.QueryInterface.Interface = (PINTERFACE) BusInterface;
  86. IrpSp->Parameters.QueryInterface.InterfaceSpecificData = NULL;
  87. Status = IoCallDriver(DeviceObject, Irp);
  88. if (Status == STATUS_PENDING) {
  89. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  90. Status = Irp->IoStatus.Status;
  91. }
  92. return(Status);
  93. }
  94. NTSTATUS
  95. ApGetSetDeviceBusData(
  96. IN PCOMMON_EXTENSION Extension,
  97. IN BOOLEAN Read,
  98. IN PVOID Buffer,
  99. IN ULONG Offset,
  100. IN ULONG Length
  101. )
  102. /*++
  103. Routine Description:
  104. Reads or writes PCI config space for the specified device.
  105. Arguments:
  106. Extension - Supplies the common AGP extension
  107. Read - if TRUE, this is a READ IRP
  108. if FALSE, this is a WRITE IRP
  109. Buffer - Returns the PCI config data
  110. Offset - Supplies the offset into the PCI config data where the read should begin
  111. Length - Supplies the number of bytes to be read
  112. Return Value:
  113. NTSTATUS
  114. --*/
  115. {
  116. NTSTATUS Status;
  117. ULONG ReturnLength;
  118. ULONG Transferred;
  119. //
  120. // First check our device extension. This must be either a master
  121. // or target extension, we don't care too much which.
  122. //
  123. ASSERT((Extension->Signature == TARGET_SIG) ||
  124. (Extension->Signature == MASTER_SIG));
  125. //
  126. // Now we simply use our bus interface to call directly to PCI.
  127. //
  128. if (Read) {
  129. Transferred = Extension->BusInterface.GetBusData(Extension->BusInterface.Context,
  130. PCI_WHICHSPACE_CONFIG,
  131. Buffer,
  132. Offset,
  133. Length);
  134. } else {
  135. Transferred = Extension->BusInterface.SetBusData(Extension->BusInterface.Context,
  136. PCI_WHICHSPACE_CONFIG,
  137. Buffer,
  138. Offset,
  139. Length);
  140. }
  141. if (Transferred == Length) {
  142. return(STATUS_SUCCESS);
  143. } else {
  144. return(STATUS_UNSUCCESSFUL);
  145. }
  146. }
  147. NTSTATUS
  148. ApGetSetBusData(
  149. IN PBUS_SLOT_ID BusSlotId,
  150. IN BOOLEAN Read,
  151. IN PVOID Buffer,
  152. IN ULONG Offset,
  153. IN ULONG Length
  154. )
  155. /*++
  156. Routine Description:
  157. Calls HalGet/SetBusData for the specified PCI bus/slot ID.
  158. Arguments:
  159. BusSlotId - Supplies the bus and slot ID.
  160. Read - if TRUE, this is a GetBusData
  161. if FALSE, this is a SetBusData
  162. Buffer - Returns the PCI config data
  163. Offset - Supplies the offset into the PCI config data where the read should begin
  164. Length - Supplies the number of bytes to be read
  165. Return Value:
  166. NTSTATUS
  167. --*/
  168. {
  169. ULONG Transferred;
  170. if (Read) {
  171. Transferred = HalGetBusDataByOffset(PCIConfiguration,
  172. BusSlotId->BusId,
  173. BusSlotId->SlotId,
  174. Buffer,
  175. Offset,
  176. Length);
  177. } else {
  178. Transferred = HalSetBusDataByOffset(PCIConfiguration,
  179. BusSlotId->BusId,
  180. BusSlotId->SlotId,
  181. Buffer,
  182. Offset,
  183. Length);
  184. }
  185. if (Transferred == Length) {
  186. return(STATUS_SUCCESS);
  187. } else {
  188. return(STATUS_UNSUCCESSFUL);
  189. }
  190. }
  191. NTSTATUS
  192. ApFindAgpCapability(
  193. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  194. IN PVOID Context,
  195. OUT PPCI_AGP_CAPABILITY Capability,
  196. OUT UCHAR *pOffset,
  197. OUT PPCI_COMMON_CONFIG PciCommonConfig OPTIONAL
  198. )
  199. /*++
  200. Routine Description:
  201. Finds the capability offset for the specified device and
  202. reads in the header.
  203. Arguments:
  204. pConfigFn - Supplies the function to call for accessing config space
  205. on the appropriate device.
  206. Context - Supplies the context to pass to pConfigFn
  207. Capabilities - Returns the AGP Capabilities common header
  208. pOffset - Returns the offset into config space.
  209. PciCommonConfig - NULL, or points to the PCI common configuration header
  210. Return Value:
  211. NTSTATUS
  212. --*/
  213. {
  214. PCI_COMMON_HEADER Header;
  215. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  216. NTSTATUS Status;
  217. UCHAR CapabilityOffset;
  218. //
  219. // Read the PCI common header to get the capabilities pointer
  220. //
  221. Status = (pConfigFn)(Context,
  222. TRUE,
  223. PciConfig,
  224. 0,
  225. sizeof(PCI_COMMON_HEADER));
  226. if (!NT_SUCCESS(Status)) {
  227. AGPLOG(AGP_CRITICAL,
  228. ("AgpLibGetAgpCapability - read PCI Config space for Context %08lx failed %08lx\n",
  229. Context,
  230. Status));
  231. return(Status);
  232. }
  233. //
  234. // Check the Status register to see if this device supports capability lists.
  235. // If not, it is not an AGP-compliant device.
  236. //
  237. if ((PciConfig->Status & PCI_STATUS_CAPABILITIES_LIST) == 0) {
  238. AGPLOG(AGP_CRITICAL,
  239. ("AgpLibGetAgpCapability - Context %08lx does not support Capabilities list, not an AGP device\n",
  240. Context));
  241. return(STATUS_NOT_IMPLEMENTED);
  242. }
  243. //
  244. // The device supports capability lists, find the AGP capabilities
  245. //
  246. if ((PciConfig->HeaderType & (~PCI_MULTIFUNCTION)) == PCI_BRIDGE_TYPE) {
  247. CapabilityOffset = PciConfig->u.type1.CapabilitiesPtr;
  248. } else {
  249. ASSERT((PciConfig->HeaderType & (~PCI_MULTIFUNCTION)) == PCI_DEVICE_TYPE);
  250. CapabilityOffset = PciConfig->u.type0.CapabilitiesPtr;
  251. }
  252. while (CapabilityOffset != 0) {
  253. //
  254. // Read the Capability at this offset
  255. //
  256. Status = (pConfigFn)(Context,
  257. TRUE,
  258. Capability,
  259. CapabilityOffset,
  260. sizeof(PCI_CAPABILITIES_HEADER));
  261. if (!NT_SUCCESS(Status)) {
  262. AGPLOG(AGP_CRITICAL,
  263. ("AgpLibGetAgpCapability - read PCI Capability at offset %x for Context %08lx failed %08lx\n",
  264. CapabilityOffset,
  265. Context,
  266. Status));
  267. return(Status);
  268. }
  269. if (Capability->Header.CapabilityID == PCI_CAPABILITY_ID_AGP) {
  270. //
  271. // Found the AGP Capability
  272. //
  273. break;
  274. } else {
  275. //
  276. // This is some other Capability, keep looking for the AGP Capability
  277. //
  278. CapabilityOffset = Capability->Header.Next;
  279. }
  280. }
  281. if (CapabilityOffset == 0) {
  282. //
  283. // No AGP capability was found
  284. //
  285. AGPLOG(AGP_CRITICAL,
  286. ("AgpLibGetAgpCapability - Context %08lx does have an AGP Capability entry, not an AGP device\n",
  287. Context));
  288. return(STATUS_NOT_IMPLEMENTED);
  289. }
  290. AGPLOG(AGP_NOISE,
  291. ("AgpLibGetAgpCapability - Context %08lx has AGP Capability at offset %x\n",
  292. Context,
  293. CapabilityOffset));
  294. *pOffset = CapabilityOffset;
  295. if (PciCommonConfig) {
  296. RtlCopyMemory(PciCommonConfig, PciConfig, sizeof(PCI_COMMON_HEADER));
  297. }
  298. return(STATUS_SUCCESS);
  299. }
  300. NTSTATUS
  301. AgpLibGetAgpCapability(
  302. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  303. IN PVOID Context,
  304. IN BOOLEAN DoSpecial,
  305. OUT PPCI_AGP_CAPABILITY Capability
  306. )
  307. /*++
  308. Routine Description:
  309. This routine finds and retrieves the AGP capabilities in the
  310. PCI config space of the AGP master (graphics card).
  311. Arguments:
  312. pConfigFn - Supplies the function to call for accessing config space
  313. on the appropriate device.
  314. Context - Supplies the context to pass to pConfigFn
  315. DoSpecial - Indicates whether we should apply any "pecial" tweaks
  316. Capabilities - Returns the current AGP Capabilities
  317. Return Value:
  318. NTSTATUS
  319. --*/
  320. {
  321. NTSTATUS Status;
  322. ULONGLONG DeviceFlags;
  323. UCHAR CapabilityOffset;
  324. PCI_COMMON_HEADER Header;
  325. USHORT SubVendorID, SubSystemID;
  326. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  327. Status = ApFindAgpCapability(pConfigFn,
  328. Context,
  329. Capability,
  330. &CapabilityOffset,
  331. PciConfig);
  332. if (!NT_SUCCESS(Status)) {
  333. return(Status);
  334. }
  335. //
  336. // Read the rest of the AGP capability
  337. //
  338. Status = (pConfigFn)(Context,
  339. TRUE,
  340. &Capability->Header + 1,
  341. CapabilityOffset + sizeof(PCI_CAPABILITIES_HEADER),
  342. sizeof(PCI_AGP_CAPABILITY) - sizeof(PCI_CAPABILITIES_HEADER));
  343. if (!NT_SUCCESS(Status)) {
  344. AGPLOG(AGP_CRITICAL,
  345. ("AgpLibGetAgpCapability - read AGP Capability at offset %x for Context %08lx failed %08lx\n",
  346. CapabilityOffset,
  347. Context,
  348. Status));
  349. return(Status);
  350. }
  351. //
  352. // Check device flags for broken HW, we may need to tweak caps
  353. //
  354. if ((PCI_CONFIGURATION_TYPE(PciConfig) == PCI_DEVICE_TYPE) &&
  355. (PciConfig->BaseClass != PCI_CLASS_BRIDGE_DEV)) {
  356. SubVendorID = PciConfig->u.type0.SubVendorID;
  357. SubSystemID = PciConfig->u.type0.SubSystemID;
  358. } else {
  359. SubVendorID = 0;
  360. SubSystemID = 0;
  361. }
  362. DeviceFlags = AgpGetDeviceFlags(AgpGlobalHackTable,
  363. PciConfig->VendorID,
  364. PciConfig->DeviceID,
  365. SubVendorID,
  366. SubSystemID,
  367. PciConfig->RevisionID);
  368. DeviceFlags |= AgpGetDeviceFlags(AgpDeviceHackTable,
  369. PciConfig->VendorID,
  370. PciConfig->DeviceID,
  371. SubVendorID,
  372. SubSystemID,
  373. PciConfig->RevisionID);
  374. if (DeviceFlags & AGP_FLAG_NO_1X_RATE) {
  375. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_1X;
  376. AGPLOG(AGP_WARNING,
  377. ("AGP HAMMER CAPS: NO_1X_RATE Vendor %x, Device %x.\n",
  378. PciConfig->VendorID,
  379. PciConfig->DeviceID));
  380. }
  381. if (DeviceFlags & AGP_FLAG_NO_2X_RATE) {
  382. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_2X;
  383. AGPLOG(AGP_WARNING,
  384. ("AGP HAMMER CAPS: NO_2X_RATE Vendor %x, Device %x.\n",
  385. PciConfig->VendorID,
  386. PciConfig->DeviceID));
  387. }
  388. if (DeviceFlags & AGP_FLAG_NO_4X_RATE) {
  389. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_4X;
  390. AGPLOG(AGP_WARNING,
  391. ("AGP HAMMER CAPS: NO_4X_RATE Vendor %x, Device %x.\n",
  392. PciConfig->VendorID,
  393. PciConfig->DeviceID));
  394. }
  395. if (DeviceFlags & AGP_FLAG_NO_8X_RATE) {
  396. Capability->AGPStatus.Rate &= ~8;
  397. AGPLOG(AGP_WARNING,
  398. ("AGP HAMMER CAPS: NO_8X_RATE Vendor %x, Device %x.\n",
  399. PciConfig->VendorID,
  400. PciConfig->DeviceID));
  401. }
  402. if (DeviceFlags & AGP_FLAG_NO_SBA_ENABLE) {
  403. Capability->AGPStatus.SideBandAddressing = 0;
  404. AGPLOG(AGP_WARNING,
  405. ("AGP HAMMER CAPS: NO_SBA_ENABLE Vendor %x, Device %x.\n",
  406. PciConfig->VendorID,
  407. PciConfig->DeviceID));
  408. }
  409. if (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION) {
  410. AGPLOG(AGP_WARNING,
  411. ("AGP GLOBAL HACK: REVERSE_INITIALIZATION Vendor %x, "
  412. "Device %x.\n",
  413. PciConfig->VendorID,
  414. PciConfig->DeviceID));
  415. }
  416. //
  417. // Test if this device requires any platform specific AGP tweaks
  418. //
  419. if (DoSpecial && (DeviceFlags > AGP_FLAG_SPECIAL_TARGET) ||
  420. (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION)) {
  421. AgpSpecialTarget(GET_AGP_CONTEXT_FROM_MASTER((PMASTER_EXTENSION)Context), ((DeviceFlags & ~AGP_FLAG_SPECIAL_TARGET) | (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION)));
  422. }
  423. AGPLOG(AGP_NOISE,
  424. ("AGP CAPABILITY: version %d.%d\n",Capability->Major, Capability->Minor));
  425. AGPLOG(AGP_NOISE,
  426. ("\tSTATUS - Rate: %x SBA: %x RQ: %02x\n",
  427. Capability->AGPStatus.Rate,
  428. Capability->AGPStatus.SideBandAddressing,
  429. Capability->AGPStatus.RequestQueueDepthMaximum));
  430. AGPLOG(AGP_NOISE,
  431. ("\tCOMMAND - Rate: %x SBA: %x RQ: %02x AGPEnable: %x\n",
  432. Capability->AGPCommand.Rate,
  433. Capability->AGPCommand.SBAEnable,
  434. Capability->AGPCommand.RequestQueueDepth,
  435. Capability->AGPCommand.AGPEnable));
  436. return(STATUS_SUCCESS);
  437. }
  438. NTSTATUS
  439. AgpLibGetTargetCapability(
  440. IN PVOID AgpExtension,
  441. OUT PPCI_AGP_CAPABILITY Capability
  442. )
  443. /*++
  444. Routine Description:
  445. Retrieves the AGP capability for the AGP target (AGP bridge)
  446. Arguments:
  447. AgpExtension - Supplies the AGP extension
  448. Capability - Returns the AGP capability
  449. Return Value:
  450. NTSTATUS
  451. --*/
  452. {
  453. PTARGET_EXTENSION Extension;
  454. GET_TARGET_EXTENSION(Extension, AgpExtension);
  455. return(AgpLibGetAgpCapability(ApGetSetDeviceBusData,
  456. Extension,
  457. FALSE,
  458. Capability));
  459. }
  460. NTSTATUS
  461. AgpLibGetMasterCapability(
  462. IN PVOID AgpExtension,
  463. OUT PPCI_AGP_CAPABILITY Capability
  464. )
  465. /*++
  466. Routine Description:
  467. Retrieves the AGP capability for the AGP master (graphics card)
  468. Arguments:
  469. AgpExtension - Supplies the AGP extension
  470. Capability - Returns the AGP capability
  471. Return Value:
  472. NTSTATUS
  473. --*/
  474. {
  475. PMASTER_EXTENSION Extension;
  476. GET_MASTER_EXTENSION(Extension, AgpExtension);
  477. return(AgpLibGetAgpCapability(ApGetSetDeviceBusData,
  478. Extension,
  479. TRUE,
  480. Capability));
  481. }
  482. NTSTATUS
  483. AgpLibGetPciDeviceCapability(
  484. IN ULONG BusId,
  485. IN ULONG SlotId,
  486. OUT PPCI_AGP_CAPABILITY Capability
  487. )
  488. /*++
  489. Routine Description:
  490. Retrieves the AGP capability for the specified PCI slot.
  491. Caller is responsible for figuring out what the correct
  492. Bus/Slot ID is. These are just passed right to HalGetBusData.
  493. Arguments:
  494. BusId - supplies the bus id
  495. SlotId - Supplies the slot id
  496. Capability - Returns the AGP capability
  497. Return Value:
  498. NTSTATUS
  499. --*/
  500. {
  501. BUS_SLOT_ID BusSlotId;
  502. BusSlotId.BusId = BusId;
  503. BusSlotId.SlotId = SlotId;
  504. return(AgpLibGetAgpCapability(ApGetSetBusData,
  505. &BusSlotId,
  506. FALSE,
  507. Capability));
  508. }
  509. NTSTATUS
  510. AgpLibSetAgpCapability(
  511. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  512. IN PVOID Context,
  513. OUT PPCI_AGP_CAPABILITY Capability
  514. )
  515. /*++
  516. Routine Description:
  517. This routine finds and retrieves the AGP capabilities in the
  518. PCI config space of the AGP master (graphics card).
  519. Arguments:
  520. pConfigFn - Supplies the function to call for accessing config space
  521. on the appropriate device.
  522. Context - Supplies the context to pass to pConfigFn
  523. Capabilities - Returns the current AGP Capabilities
  524. Return Value:
  525. NTSTATUS
  526. --*/
  527. {
  528. NTSTATUS Status;
  529. UCHAR CapabilityOffset;
  530. Status = ApFindAgpCapability(pConfigFn,
  531. Context,
  532. Capability,
  533. &CapabilityOffset,
  534. NULL);
  535. if (!NT_SUCCESS(Status)) {
  536. return(Status);
  537. }
  538. //
  539. // Now that we know the offset, write the supplied command register
  540. //
  541. Status = (pConfigFn)(Context,
  542. FALSE,
  543. &Capability->AGPCommand,
  544. CapabilityOffset + FIELD_OFFSET(PCI_AGP_CAPABILITY, AGPCommand),
  545. sizeof(Capability->AGPCommand));
  546. if (!NT_SUCCESS(Status)) {
  547. AGPLOG(AGP_CRITICAL,
  548. ("AgpLibSetAgpCapability - Set AGP command at offset %x for Context %08lx failed %08lx\n",
  549. CapabilityOffset,
  550. Context,
  551. Status));
  552. return(Status);
  553. }
  554. return(STATUS_SUCCESS);
  555. }
  556. NTSTATUS
  557. AgpLibSetTargetCapability(
  558. IN PVOID AgpExtension,
  559. OUT PPCI_AGP_CAPABILITY Capability
  560. )
  561. /*++
  562. Routine Description:
  563. Sets the AGP capability for the AGP target (AGP bridge)
  564. Arguments:
  565. AgpExtension - Supplies the AGP extension
  566. Capability - Returns the AGP capability
  567. Return Value:
  568. NTSTATUS
  569. --*/
  570. {
  571. PTARGET_EXTENSION Extension;
  572. GET_TARGET_EXTENSION(Extension, AgpExtension);
  573. return(AgpLibSetAgpCapability(ApGetSetDeviceBusData,
  574. Extension,
  575. Capability));
  576. }
  577. NTSTATUS
  578. AgpLibSetMasterCapability(
  579. IN PVOID AgpExtension,
  580. OUT PPCI_AGP_CAPABILITY Capability
  581. )
  582. /*++
  583. Routine Description:
  584. Sets the AGP capability for the AGP master (graphics card)
  585. Arguments:
  586. AgpExtension - Supplies the AGP extension
  587. Capability - Returns the AGP capability
  588. Return Value:
  589. NTSTATUS
  590. --*/
  591. {
  592. PMASTER_EXTENSION Extension;
  593. GET_MASTER_EXTENSION(Extension, AgpExtension);
  594. return(AgpLibSetAgpCapability(ApGetSetDeviceBusData,
  595. Extension,
  596. Capability));
  597. }
  598. NTSTATUS
  599. AgpLibSetPciDeviceCapability(
  600. IN ULONG BusId,
  601. IN ULONG SlotId,
  602. OUT PPCI_AGP_CAPABILITY Capability
  603. )
  604. /*++
  605. Routine Description:
  606. Sets the AGP capability for the specified PCI slot.
  607. Caller is responsible for figuring out what the correct
  608. Bus/Slot ID is. These are just passed right to HalSetBusData.
  609. Arguments:
  610. BusId - supplies the bus id
  611. SlotId - Supplies the slot id
  612. Capability - Returns the AGP capability
  613. Return Value:
  614. NTSTATUS
  615. --*/
  616. {
  617. BUS_SLOT_ID BusSlotId;
  618. BusSlotId.BusId = BusId;
  619. BusSlotId.SlotId = SlotId;
  620. return(AgpLibSetAgpCapability(ApGetSetBusData,
  621. &BusSlotId,
  622. Capability));
  623. }
  624. NTSTATUS
  625. AgpLibGetMasterDeviceId(
  626. IN PVOID AgpExtension,
  627. OUT PULONG DeviceId
  628. )
  629. /*++
  630. Routine Description:
  631. This function returns the PCI DeviceId/Vendo58rId of the master AGP
  632. device
  633. Arguments:
  634. DeviceId - Identifies PCI manufaturer and device of master
  635. Return Value:
  636. STATUS_SUCCESS or an appropriate error status
  637. --*/
  638. {
  639. PCI_COMMON_HEADER Header;
  640. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  641. NTSTATUS Status;
  642. PMASTER_EXTENSION Master = NULL;
  643. PTARGET_EXTENSION Target = NULL;
  644. //
  645. // Try to make this as idiot proof as possible for the case
  646. // where this is called from SetAperture on a system without
  647. // an AGP adapter, so we don't AV if some context hasn't been
  648. // initialized, or is missing...
  649. //
  650. Target = CONTAINING_RECORD(AgpExtension,
  651. TARGET_EXTENSION,
  652. AgpContext);
  653. if (Target) {
  654. if (Target->CommonExtension.Signature == TARGET_SIG) {
  655. if (Target->ChildDevice) {
  656. if (Target->ChildDevice->CommonExtension.Signature ==
  657. MASTER_SIG) {
  658. Master = Target->ChildDevice;
  659. }
  660. }
  661. }
  662. }
  663. if (Master) {
  664. //
  665. // Read the PCI common header to get the capabilities pointer
  666. //
  667. Status = (ApGetSetDeviceBusData)((PCOMMON_EXTENSION)Master,
  668. TRUE,
  669. PciConfig,
  670. 0,
  671. sizeof(PCI_COMMON_HEADER));
  672. if (!NT_SUCCESS(Status)) {
  673. AGPLOG(AGP_CRITICAL,
  674. ("AgpLibGetMasterDeviceId - read PCI Config space for Context %08lx failed %08lx\n",
  675. Master,
  676. Status));
  677. return Status;
  678. }
  679. *DeviceId = *(PULONG)PciConfig;
  680. } else {
  681. *DeviceId = (ULONG)-1;
  682. }
  683. return STATUS_SUCCESS;
  684. }