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.

1019 lines
26 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. #ifdef AGP3
  148. NTSTATUS
  149. AgpLibReadAgpDeviceConfig(
  150. IN PVOID AgpExtension,
  151. OUT PVOID Buffer,
  152. IN ULONG Offset,
  153. IN ULONG Size
  154. );
  155. /*++
  156. Routine Description:
  157. Read PCI config space for the specified device
  158. Arguments:
  159. Extension - Supplies the common AGP extension
  160. Buffer - Returns the PCI config data
  161. Offset - Supplies the offset into the PCI config data where the read
  162. should begin
  163. Length - Supplies the number of bytes to be read
  164. Return Value:
  165. NTSTATUS
  166. --*/
  167. {
  168. return ApGetSetDeviceBusData(AgpExtension,
  169. TRUE,
  170. Buffer,
  171. Offset,
  172. Size
  173. );
  174. }
  175. NTSTATUS
  176. AgpLibWriteAgpDeviceConfig(
  177. IN PVOID AgpExtension,
  178. IN PVOID Buffer,
  179. IN ULONG Offset,
  180. IN ULONG Size
  181. )
  182. /*++
  183. Routine Description:
  184. Write PCI config space for the specified AGP device
  185. Arguments:
  186. Extension - Supplies the common AGP extension
  187. Buffer - Returns the PCI config data
  188. Offset - Supplies the offset into the PCI config data where the write
  189. should begin
  190. Length - Supplies the number of bytes to be write
  191. Return Value:
  192. NTSTATUS
  193. --*/
  194. {
  195. return ApGetSetDeviceBusData(AgpExtension,
  196. FALSE,
  197. Buffer,
  198. Offset,
  199. Size
  200. );
  201. }
  202. #else // AGP3
  203. NTSTATUS
  204. ApGetSetBusData(
  205. IN PBUS_SLOT_ID BusSlotId,
  206. IN BOOLEAN Read,
  207. IN PVOID Buffer,
  208. IN ULONG Offset,
  209. IN ULONG Length
  210. )
  211. /*++
  212. Routine Description:
  213. Calls HalGet/SetBusData for the specified PCI bus/slot ID.
  214. Arguments:
  215. BusSlotId - Supplies the bus and slot ID.
  216. Read - if TRUE, this is a GetBusData
  217. if FALSE, this is a SetBusData
  218. Buffer - Returns the PCI config data
  219. Offset - Supplies the offset into the PCI config data where the read should begin
  220. Length - Supplies the number of bytes to be read
  221. Return Value:
  222. NTSTATUS
  223. --*/
  224. {
  225. ULONG Transferred;
  226. if (Read) {
  227. Transferred = HalGetBusDataByOffset(PCIConfiguration,
  228. BusSlotId->BusId,
  229. BusSlotId->SlotId,
  230. Buffer,
  231. Offset,
  232. Length);
  233. } else {
  234. Transferred = HalSetBusDataByOffset(PCIConfiguration,
  235. BusSlotId->BusId,
  236. BusSlotId->SlotId,
  237. Buffer,
  238. Offset,
  239. Length);
  240. }
  241. if (Transferred == Length) {
  242. return(STATUS_SUCCESS);
  243. } else {
  244. return(STATUS_UNSUCCESSFUL);
  245. }
  246. }
  247. #endif // AGP3
  248. NTSTATUS
  249. ApFindAgpCapability(
  250. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  251. IN PVOID Context,
  252. OUT PPCI_AGP_CAPABILITY Capability,
  253. OUT UCHAR *pOffset,
  254. OUT PPCI_COMMON_CONFIG PciCommonConfig OPTIONAL
  255. )
  256. /*++
  257. Routine Description:
  258. Finds the capability offset for the specified device and
  259. reads in the header.
  260. Arguments:
  261. pConfigFn - Supplies the function to call for accessing config space
  262. on the appropriate device.
  263. Context - Supplies the context to pass to pConfigFn
  264. Capabilities - Returns the AGP Capabilities common header
  265. pOffset - Returns the offset into config space.
  266. PciCommonConfig - NULL, or points to the PCI common configuration header
  267. Return Value:
  268. NTSTATUS
  269. --*/
  270. {
  271. PCI_COMMON_HEADER Header;
  272. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  273. NTSTATUS Status;
  274. UCHAR CapabilityOffset;
  275. //
  276. // Read the PCI common header to get the capabilities pointer
  277. //
  278. Status = (pConfigFn)(Context,
  279. TRUE,
  280. PciConfig,
  281. 0,
  282. sizeof(PCI_COMMON_HEADER));
  283. if (!NT_SUCCESS(Status)) {
  284. AGPLOG(AGP_CRITICAL,
  285. ("AgpLibGetAgpCapability - read PCI Config space for Context %08lx failed %08lx\n",
  286. Context,
  287. Status));
  288. return(Status);
  289. }
  290. //
  291. // Check the Status register to see if this device supports capability lists.
  292. // If not, it is not an AGP-compliant device.
  293. //
  294. if ((PciConfig->Status & PCI_STATUS_CAPABILITIES_LIST) == 0) {
  295. AGPLOG(AGP_CRITICAL,
  296. ("AgpLibGetAgpCapability - Context %08lx does not support Capabilities list, not an AGP device\n",
  297. Context));
  298. return(STATUS_NOT_IMPLEMENTED);
  299. }
  300. //
  301. // The device supports capability lists, find the AGP capabilities
  302. //
  303. if ((PciConfig->HeaderType & (~PCI_MULTIFUNCTION)) == PCI_BRIDGE_TYPE) {
  304. CapabilityOffset = PciConfig->u.type1.CapabilitiesPtr;
  305. } else {
  306. ASSERT((PciConfig->HeaderType & (~PCI_MULTIFUNCTION)) == PCI_DEVICE_TYPE);
  307. CapabilityOffset = PciConfig->u.type0.CapabilitiesPtr;
  308. }
  309. while (CapabilityOffset != 0) {
  310. //
  311. // Read the Capability at this offset
  312. //
  313. Status = (pConfigFn)(Context,
  314. TRUE,
  315. Capability,
  316. CapabilityOffset,
  317. sizeof(PCI_CAPABILITIES_HEADER));
  318. if (!NT_SUCCESS(Status)) {
  319. AGPLOG(AGP_CRITICAL,
  320. ("AgpLibGetAgpCapability - read PCI Capability at offset %x for Context %08lx failed %08lx\n",
  321. CapabilityOffset,
  322. Context,
  323. Status));
  324. return(Status);
  325. }
  326. if (Capability->Header.CapabilityID == PCI_CAPABILITY_ID_AGP) {
  327. //
  328. // Found the AGP Capability
  329. //
  330. break;
  331. } else {
  332. //
  333. // This is some other Capability, keep looking for the AGP Capability
  334. //
  335. CapabilityOffset = Capability->Header.Next;
  336. }
  337. }
  338. if (CapabilityOffset == 0) {
  339. //
  340. // No AGP capability was found
  341. //
  342. AGPLOG(AGP_CRITICAL,
  343. ("AgpLibGetAgpCapability - Context %08lx does have an AGP Capability entry, not an AGP device\n",
  344. Context));
  345. return(STATUS_NOT_IMPLEMENTED);
  346. }
  347. AGPLOG(AGP_NOISE,
  348. ("AgpLibGetAgpCapability - Context %08lx has AGP Capability at offset %x\n",
  349. Context,
  350. CapabilityOffset));
  351. *pOffset = CapabilityOffset;
  352. if (PciCommonConfig) {
  353. RtlCopyMemory(PciCommonConfig, PciConfig, sizeof(PCI_COMMON_HEADER));
  354. }
  355. return(STATUS_SUCCESS);
  356. }
  357. NTSTATUS
  358. AgpLibGetAgpCapability(
  359. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  360. IN PVOID Context,
  361. IN BOOLEAN DoSpecial,
  362. OUT PPCI_AGP_CAPABILITY Capability
  363. )
  364. /*++
  365. Routine Description:
  366. This routine finds and retrieves the AGP capabilities in the
  367. PCI config space of the AGP master (graphics card).
  368. Arguments:
  369. pConfigFn - Supplies the function to call for accessing config space
  370. on the appropriate device.
  371. Context - Supplies the context to pass to pConfigFn
  372. DoSpecial - Indicates whether we should apply any "pecial" tweaks
  373. Capabilities - Returns the current AGP Capabilities
  374. Return Value:
  375. NTSTATUS
  376. --*/
  377. {
  378. NTSTATUS Status;
  379. ULONGLONG DeviceFlags;
  380. UCHAR CapabilityOffset;
  381. PCI_COMMON_HEADER Header;
  382. USHORT SubVendorID, SubSystemID;
  383. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  384. Status = ApFindAgpCapability(pConfigFn,
  385. Context,
  386. Capability,
  387. &CapabilityOffset,
  388. PciConfig);
  389. if (!NT_SUCCESS(Status)) {
  390. return(Status);
  391. }
  392. //
  393. // Read the rest of the AGP capability
  394. //
  395. Status = (pConfigFn)(Context,
  396. TRUE,
  397. &Capability->Header + 1,
  398. CapabilityOffset + sizeof(PCI_CAPABILITIES_HEADER),
  399. sizeof(PCI_AGP_CAPABILITY) - sizeof(PCI_CAPABILITIES_HEADER));
  400. if (!NT_SUCCESS(Status)) {
  401. AGPLOG(AGP_CRITICAL,
  402. ("AgpLibGetAgpCapability - read AGP Capability at offset %x for Context %08lx failed %08lx\n",
  403. CapabilityOffset,
  404. Context,
  405. Status));
  406. return(Status);
  407. }
  408. //
  409. // Check device flags for broken HW, we may need to tweak caps
  410. //
  411. if ((PCI_CONFIGURATION_TYPE(PciConfig) == PCI_DEVICE_TYPE) &&
  412. (PciConfig->BaseClass != PCI_CLASS_BRIDGE_DEV)) {
  413. SubVendorID = PciConfig->u.type0.SubVendorID;
  414. SubSystemID = PciConfig->u.type0.SubSystemID;
  415. } else {
  416. SubVendorID = 0;
  417. SubSystemID = 0;
  418. }
  419. DeviceFlags = AgpGetDeviceFlags(AgpGlobalHackTable,
  420. PciConfig->VendorID,
  421. PciConfig->DeviceID,
  422. SubVendorID,
  423. SubSystemID,
  424. PciConfig->RevisionID);
  425. DeviceFlags |= AgpGetDeviceFlags(AgpDeviceHackTable,
  426. PciConfig->VendorID,
  427. PciConfig->DeviceID,
  428. SubVendorID,
  429. SubSystemID,
  430. PciConfig->RevisionID);
  431. if (DeviceFlags & AGP_FLAG_NO_1X_RATE) {
  432. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_1X;
  433. AGPLOG(AGP_WARNING,
  434. ("AGP HAMMER CAPS: NO_1X_RATE Vendor %x, Device %x.\n",
  435. PciConfig->VendorID,
  436. PciConfig->DeviceID));
  437. }
  438. if (DeviceFlags & AGP_FLAG_NO_2X_RATE) {
  439. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_2X;
  440. AGPLOG(AGP_WARNING,
  441. ("AGP HAMMER CAPS: NO_2X_RATE Vendor %x, Device %x.\n",
  442. PciConfig->VendorID,
  443. PciConfig->DeviceID));
  444. }
  445. if (DeviceFlags & AGP_FLAG_NO_4X_RATE) {
  446. Capability->AGPStatus.Rate &= ~PCI_AGP_RATE_4X;
  447. AGPLOG(AGP_WARNING,
  448. ("AGP HAMMER CAPS: NO_4X_RATE Vendor %x, Device %x.\n",
  449. PciConfig->VendorID,
  450. PciConfig->DeviceID));
  451. }
  452. if (DeviceFlags & AGP_FLAG_NO_8X_RATE) {
  453. Capability->AGPStatus.Rate &= ~8;
  454. AGPLOG(AGP_WARNING,
  455. ("AGP HAMMER CAPS: NO_8X_RATE Vendor %x, Device %x.\n",
  456. PciConfig->VendorID,
  457. PciConfig->DeviceID));
  458. }
  459. if (DeviceFlags & AGP_FLAG_NO_SBA_ENABLE) {
  460. Capability->AGPStatus.SideBandAddressing = 0;
  461. AGPLOG(AGP_WARNING,
  462. ("AGP HAMMER CAPS: NO_SBA_ENABLE Vendor %x, Device %x.\n",
  463. PciConfig->VendorID,
  464. PciConfig->DeviceID));
  465. }
  466. if (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION) {
  467. AGPLOG(AGP_WARNING,
  468. ("AGP GLOBAL HACK: REVERSE_INITIALIZATION Vendor %x, "
  469. "Device %x.\n",
  470. PciConfig->VendorID,
  471. PciConfig->DeviceID));
  472. }
  473. //
  474. // Test if this device requires any platform specific AGP tweaks
  475. //
  476. if (DoSpecial && (DeviceFlags > AGP_FLAG_SPECIAL_TARGET) ||
  477. (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION)) {
  478. AgpSpecialTarget(GET_AGP_CONTEXT_FROM_MASTER((PMASTER_EXTENSION)Context), ((DeviceFlags & ~AGP_FLAG_SPECIAL_TARGET) | (DeviceFlags & AGP_FLAG_REVERSE_INITIALIZATION)));
  479. }
  480. AGPLOG(AGP_NOISE,
  481. ("AGP CAPABILITY: version %d.%d\n",Capability->Major, Capability->Minor));
  482. AGPLOG(AGP_NOISE,
  483. ("\tSTATUS - Rate: %x SBA: %x RQ: %02x\n",
  484. Capability->AGPStatus.Rate,
  485. Capability->AGPStatus.SideBandAddressing,
  486. Capability->AGPStatus.RequestQueueDepthMaximum));
  487. AGPLOG(AGP_NOISE,
  488. ("\tCOMMAND - Rate: %x SBA: %x RQ: %02x AGPEnable: %x\n",
  489. Capability->AGPCommand.Rate,
  490. Capability->AGPCommand.SBAEnable,
  491. Capability->AGPCommand.RequestQueueDepth,
  492. Capability->AGPCommand.AGPEnable));
  493. return(STATUS_SUCCESS);
  494. }
  495. NTSTATUS
  496. AgpLibGetTargetCapability(
  497. IN PVOID AgpExtension,
  498. OUT PPCI_AGP_CAPABILITY Capability
  499. )
  500. /*++
  501. Routine Description:
  502. Retrieves the AGP capability for the AGP target (AGP bridge)
  503. Arguments:
  504. AgpExtension - Supplies the AGP extension
  505. Capability - Returns the AGP capability
  506. Return Value:
  507. NTSTATUS
  508. --*/
  509. {
  510. NTSTATUS Status;
  511. PTARGET_EXTENSION Extension;
  512. GET_TARGET_EXTENSION(Extension, AgpExtension);
  513. Status = AgpLibGetAgpCapability(ApGetSetDeviceBusData,
  514. Extension,
  515. FALSE,
  516. Capability);
  517. if (NT_SUCCESS(Status)) {
  518. Globals.AgpStatus = *(PULONG)&Capability->AGPStatus;
  519. }
  520. return Status;
  521. }
  522. NTSTATUS
  523. AgpLibGetMasterCapability(
  524. IN PVOID AgpExtension,
  525. OUT PPCI_AGP_CAPABILITY Capability
  526. )
  527. /*++
  528. Routine Description:
  529. Retrieves the AGP capability for the AGP master (graphics card)
  530. Arguments:
  531. AgpExtension - Supplies the AGP extension
  532. Capability - Returns the AGP capability
  533. Return Value:
  534. NTSTATUS
  535. --*/
  536. {
  537. PMASTER_EXTENSION Extension;
  538. GET_MASTER_EXTENSION(Extension, AgpExtension);
  539. return(AgpLibGetAgpCapability(ApGetSetDeviceBusData,
  540. Extension,
  541. TRUE,
  542. Capability));
  543. }
  544. #ifndef AGP3
  545. NTSTATUS
  546. AgpLibGetPciDeviceCapability(
  547. IN ULONG BusId,
  548. IN ULONG SlotId,
  549. OUT PPCI_AGP_CAPABILITY Capability
  550. )
  551. /*++
  552. Routine Description:
  553. Retrieves the AGP capability for the specified PCI slot.
  554. Caller is responsible for figuring out what the correct
  555. Bus/Slot ID is. These are just passed right to HalGetBusData.
  556. Arguments:
  557. BusId - supplies the bus id
  558. SlotId - Supplies the slot id
  559. Capability - Returns the AGP capability
  560. Return Value:
  561. NTSTATUS
  562. --*/
  563. {
  564. NTSTATUS Status;
  565. BUS_SLOT_ID BusSlotId;
  566. BusSlotId.BusId = BusId;
  567. BusSlotId.SlotId = SlotId;
  568. Status = AgpLibGetAgpCapability(ApGetSetBusData,
  569. &BusSlotId,
  570. FALSE,
  571. Capability);
  572. if (NT_SUCCESS(Status)) {
  573. Globals.AgpStatus = *(PULONG)&Capability->AGPStatus;
  574. }
  575. return Status;
  576. }
  577. #endif // AGP3
  578. NTSTATUS
  579. AgpLibSetAgpCapability(
  580. IN PAGP_GETSET_CONFIG_SPACE pConfigFn,
  581. IN PVOID Context,
  582. OUT PPCI_AGP_CAPABILITY Capability
  583. )
  584. /*++
  585. Routine Description:
  586. This routine finds and retrieves the AGP capabilities in the
  587. PCI config space of the AGP master (graphics card).
  588. Arguments:
  589. pConfigFn - Supplies the function to call for accessing config space
  590. on the appropriate device.
  591. Context - Supplies the context to pass to pConfigFn
  592. Capabilities - Returns the current AGP Capabilities
  593. Return Value:
  594. NTSTATUS
  595. --*/
  596. {
  597. NTSTATUS Status;
  598. UCHAR CapabilityOffset;
  599. Status = ApFindAgpCapability(pConfigFn,
  600. Context,
  601. Capability,
  602. &CapabilityOffset,
  603. NULL);
  604. if (!NT_SUCCESS(Status)) {
  605. return(Status);
  606. }
  607. //
  608. // Now that we know the offset, write the supplied command register
  609. //
  610. Status = (pConfigFn)(Context,
  611. FALSE,
  612. &Capability->AGPCommand,
  613. CapabilityOffset + FIELD_OFFSET(PCI_AGP_CAPABILITY, AGPCommand),
  614. sizeof(Capability->AGPCommand));
  615. if (!NT_SUCCESS(Status)) {
  616. AGPLOG(AGP_CRITICAL,
  617. ("AgpLibSetAgpCapability - Set AGP command at offset %x for Context %08lx failed %08lx\n",
  618. CapabilityOffset,
  619. Context,
  620. Status));
  621. return(Status);
  622. }
  623. return(STATUS_SUCCESS);
  624. }
  625. NTSTATUS
  626. AgpLibSetTargetCapability(
  627. IN PVOID AgpExtension,
  628. OUT PPCI_AGP_CAPABILITY Capability
  629. )
  630. /*++
  631. Routine Description:
  632. Sets the AGP capability for the AGP target (AGP bridge)
  633. Arguments:
  634. AgpExtension - Supplies the AGP extension
  635. Capability - Returns the AGP capability
  636. Return Value:
  637. NTSTATUS
  638. --*/
  639. {
  640. PTARGET_EXTENSION Extension;
  641. Globals.AgpCommand = *(PULONG)&Capability->AGPCommand;
  642. GET_TARGET_EXTENSION(Extension, AgpExtension);
  643. return(AgpLibSetAgpCapability(ApGetSetDeviceBusData,
  644. Extension,
  645. Capability));
  646. }
  647. NTSTATUS
  648. AgpLibSetMasterCapability(
  649. IN PVOID AgpExtension,
  650. OUT PPCI_AGP_CAPABILITY Capability
  651. )
  652. /*++
  653. Routine Description:
  654. Sets the AGP capability for the AGP master (graphics card)
  655. Arguments:
  656. AgpExtension - Supplies the AGP extension
  657. Capability - Returns the AGP capability
  658. Return Value:
  659. NTSTATUS
  660. --*/
  661. {
  662. PMASTER_EXTENSION Extension;
  663. GET_MASTER_EXTENSION(Extension, AgpExtension);
  664. return(AgpLibSetAgpCapability(ApGetSetDeviceBusData,
  665. Extension,
  666. Capability));
  667. }
  668. #ifndef AGP3
  669. NTSTATUS
  670. AgpLibSetPciDeviceCapability(
  671. IN ULONG BusId,
  672. IN ULONG SlotId,
  673. OUT PPCI_AGP_CAPABILITY Capability
  674. )
  675. /*++
  676. Routine Description:
  677. Sets the AGP capability for the specified PCI slot.
  678. Caller is responsible for figuring out what the correct
  679. Bus/Slot ID is. These are just passed right to HalSetBusData.
  680. Arguments:
  681. BusId - supplies the bus id
  682. SlotId - Supplies the slot id
  683. Capability - Returns the AGP capability
  684. Return Value:
  685. NTSTATUS
  686. --*/
  687. {
  688. BUS_SLOT_ID BusSlotId;
  689. Globals.AgpCommand = *(PULONG)&Capability->AGPCommand;
  690. BusSlotId.BusId = BusId;
  691. BusSlotId.SlotId = SlotId;
  692. return(AgpLibSetAgpCapability(ApGetSetBusData,
  693. &BusSlotId,
  694. Capability));
  695. }
  696. #endif // AGP3
  697. NTSTATUS
  698. AgpLibGetMasterDeviceId(
  699. IN PVOID AgpExtension,
  700. OUT PULONG DeviceId
  701. )
  702. /*++
  703. Routine Description:
  704. This function returns the PCI DeviceId/Vendo58rId of the master AGP
  705. device
  706. Arguments:
  707. DeviceId - Identifies PCI manufaturer and device of master
  708. Return Value:
  709. STATUS_SUCCESS or an appropriate error status
  710. --*/
  711. {
  712. PCI_COMMON_HEADER Header;
  713. PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)&Header;
  714. NTSTATUS Status;
  715. PMASTER_EXTENSION Master = NULL;
  716. PTARGET_EXTENSION Target = NULL;
  717. //
  718. // Try to make this as idiot proof as possible for the case
  719. // where this is called from SetAperture on a system without
  720. // an AGP adapter, so we don't AV if some context hasn't been
  721. // initialized, or is missing...
  722. //
  723. Target = CONTAINING_RECORD(AgpExtension,
  724. TARGET_EXTENSION,
  725. AgpContext);
  726. if (Target) {
  727. if (Target->CommonExtension.Signature == TARGET_SIG) {
  728. if (Target->ChildDevice) {
  729. if (Target->ChildDevice->CommonExtension.Signature ==
  730. MASTER_SIG) {
  731. Master = Target->ChildDevice;
  732. }
  733. }
  734. }
  735. }
  736. if (Master) {
  737. //
  738. // Read the PCI common header to get the capabilities pointer
  739. //
  740. Status = (ApGetSetDeviceBusData)((PCOMMON_EXTENSION)Master,
  741. TRUE,
  742. PciConfig,
  743. 0,
  744. sizeof(PCI_COMMON_HEADER));
  745. if (!NT_SUCCESS(Status)) {
  746. AGPLOG(AGP_CRITICAL,
  747. ("AgpLibGetMasterDeviceId - read PCI Config space for Context %08lx failed %08lx\n",
  748. Master,
  749. Status));
  750. return Status;
  751. }
  752. *DeviceId = *(PULONG)PciConfig;
  753. } else {
  754. *DeviceId = (ULONG)-1;
  755. }
  756. return STATUS_SUCCESS;
  757. }