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.

937 lines
29 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. devhere.c
  5. Abstract:
  6. PCI_DEVICE_PRESENT_INTERFACE lives here
  7. Author:
  8. Andy Thornton (andrewth) 15-July-1999
  9. Revision History:
  10. --*/
  11. #include "pcip.h"
  12. #define DEVPRESENT_MINSIZE FIELD_OFFSET(PCI_DEVICE_PRESENT_INTERFACE, IsDevicePresentEx)
  13. BOOLEAN
  14. devpresent_IsDevicePresent(
  15. USHORT VendorID,
  16. USHORT DeviceID,
  17. UCHAR RevisionID,
  18. USHORT SubVendorID,
  19. USHORT SubSystemID,
  20. ULONG Flags
  21. );
  22. BOOLEAN
  23. devpresent_IsDevicePresentEx(
  24. IN PVOID Context,
  25. IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
  26. );
  27. NTSTATUS
  28. devpresent_Initializer(
  29. IN PPCI_ARBITER_INSTANCE Instance
  30. );
  31. NTSTATUS
  32. devpresent_Constructor(
  33. PVOID DeviceExtension,
  34. PVOID PciInterface,
  35. PVOID InterfaceSpecificData,
  36. USHORT Version,
  37. USHORT Size,
  38. PINTERFACE InterfaceReturn
  39. );
  40. VOID
  41. PciRefDereferenceNoop(
  42. IN PVOID Context
  43. );
  44. BOOLEAN
  45. PcipDevicePresentOnBus(
  46. IN PPCI_FDO_EXTENSION FdoExtension,
  47. IN PPCI_PDO_EXTENSION PdoExtension,
  48. IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
  49. );
  50. #ifdef ALLOC_PRAGMA
  51. #pragma alloc_text(PAGE, devpresent_IsDevicePresent)
  52. #pragma alloc_text(PAGE, devpresent_Initializer)
  53. #pragma alloc_text(PAGE, devpresent_Constructor)
  54. #pragma alloc_text(PAGE, PciRefDereferenceNoop)
  55. #endif
  56. PCI_INTERFACE PciDevicePresentInterface = {
  57. &GUID_PCI_DEVICE_PRESENT_INTERFACE, // InterfaceType
  58. DEVPRESENT_MINSIZE, // MinSize
  59. PCI_DEVICE_PRESENT_INTERFACE_VERSION, // MinVersion
  60. PCI_DEVICE_PRESENT_INTERFACE_VERSION, // MaxVersion
  61. PCIIF_PDO, // Flags
  62. 0, // ReferenceCount
  63. PciInterface_DevicePresent, // Signature
  64. devpresent_Constructor, // Constructor
  65. devpresent_Initializer // Instance Initializer
  66. };
  67. VOID
  68. PciRefDereferenceNoop(
  69. IN PVOID Context
  70. )
  71. {
  72. PAGED_CODE();
  73. return;
  74. }
  75. NTSTATUS
  76. devpresent_Initializer(
  77. IN PPCI_ARBITER_INSTANCE Instance
  78. )
  79. {
  80. PAGED_CODE();
  81. return STATUS_SUCCESS;
  82. }
  83. NTSTATUS
  84. devpresent_Constructor(
  85. PVOID DeviceExtension,
  86. PVOID PciInterface,
  87. PVOID InterfaceSpecificData,
  88. USHORT Version,
  89. USHORT Size,
  90. PINTERFACE InterfaceReturn
  91. )
  92. {
  93. PPCI_DEVICE_PRESENT_INTERFACE interface;
  94. PAGED_CODE();
  95. //
  96. // Have already verified that the InterfaceReturn variable
  97. // points to an area in memory large enough to contain a
  98. // PCI_DEVICE_PRESENT_INTERFACE. Fill it in for the caller.
  99. //
  100. interface = (PPCI_DEVICE_PRESENT_INTERFACE) InterfaceReturn;
  101. interface->Version = PCI_DEVICE_PRESENT_INTERFACE_VERSION;
  102. interface->InterfaceReference = PciRefDereferenceNoop;
  103. interface->InterfaceDereference = PciRefDereferenceNoop;
  104. interface->Context = DeviceExtension;
  105. interface->IsDevicePresent = devpresent_IsDevicePresent;
  106. //
  107. // This interface has been extended from the base interface (what was
  108. // filled in above), to a larger interface. If the buffer provided
  109. // is large enough to hold the whole thing, fill in the rest. Otherwise
  110. // don't.
  111. //
  112. if (Size >= sizeof(PCI_DEVICE_PRESENT_INTERFACE)) {
  113. interface->IsDevicePresentEx = devpresent_IsDevicePresentEx;
  114. interface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
  115. } else {
  116. interface->Size = DEVPRESENT_MINSIZE;
  117. }
  118. return STATUS_SUCCESS;
  119. }
  120. BOOLEAN
  121. devpresent_IsDevicePresent(
  122. IN USHORT VendorID,
  123. IN USHORT DeviceID,
  124. IN UCHAR RevisionID,
  125. IN USHORT SubVendorID,
  126. IN USHORT SubSystemID,
  127. IN ULONG Flags
  128. )
  129. /*++
  130. Routine Description:
  131. This routine searches the PCI device tree to see if the specific device
  132. is present in the system. Not devices that are explicitly not enumerated
  133. (such as PIIX4 power management function) are considered absent.
  134. Arguments:
  135. VendorID - Required VendorID of the device
  136. DeviceID - Required DeviceID of the device
  137. RevisionID - Optional Revision ID
  138. SubVendorID - Optional Subsystem Vendor ID
  139. SubSystemID - Optional Subsystem ID
  140. Flags - Bitfield which indicates if Revision and Sub* ID's should be used:
  141. PCI_USE_SUBSYSTEM_IDS, PCI_USE_REVISION_ID are valid all other bits
  142. should be 0
  143. Return Value:
  144. TRUE if the device is present in the system, FALSE otherwise.
  145. --*/
  146. {
  147. PCI_DEVICE_PRESENCE_PARAMETERS parameters;
  148. parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
  149. parameters.VendorID = VendorID;
  150. parameters.DeviceID = DeviceID;
  151. parameters.RevisionID = RevisionID;
  152. parameters.SubVendorID = SubVendorID;
  153. parameters.SubSystemID = SubSystemID;
  154. //
  155. // Clear out flags that this version of the interface didn't use,
  156. //
  157. parameters.Flags = Flags & (PCI_USE_SUBSYSTEM_IDS | PCI_USE_REVISION);
  158. //
  159. // This original version of the interface required vendor/device ID
  160. // matching. The new version doesn't, so set the flag indicating
  161. // that we do in fact want to do a vendor/device ID match.
  162. //
  163. parameters.Flags |= PCI_USE_VENDEV_IDS;
  164. return devpresent_IsDevicePresentEx(NULL,
  165. &parameters
  166. );
  167. }
  168. BOOLEAN
  169. devpresent_IsDevicePresentEx(
  170. IN PVOID Context,
  171. IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
  172. )
  173. /*++
  174. Routine Description:
  175. This routine searches the PCI device tree to see if the specific device
  176. is present in the system. Note devices that are explicitly not enumerated
  177. (such as PIIX4 power management function) are considered absent.
  178. Arguments:
  179. Context - The device extension of the device requesting the search.
  180. Parameters - Pointer to a structure containing the parameters of the device search,
  181. including VendorID, SubSystemID and ClassCode, among others.
  182. Return Value:
  183. TRUE if the device is present in the system, FALSE otherwise.
  184. --*/
  185. {
  186. PSINGLE_LIST_ENTRY nextEntry;
  187. PPCI_FDO_EXTENSION fdoExtension;
  188. PPCI_PDO_EXTENSION pdoExtension;
  189. BOOLEAN found = FALSE;
  190. ULONG flags;
  191. PAGED_CODE();
  192. //
  193. // Validate the parameters.
  194. //
  195. if (!ARGUMENT_PRESENT(Parameters)) {
  196. ASSERT(ARGUMENT_PRESENT(Parameters));
  197. return FALSE;
  198. }
  199. //
  200. // Validate the size of the structure passed in.
  201. //
  202. if (Parameters->Size < sizeof(PCI_DEVICE_PRESENCE_PARAMETERS)) {
  203. ASSERT(Parameters->Size >= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS));
  204. return FALSE;
  205. }
  206. flags = Parameters->Flags;
  207. //
  208. // We can either do a Vendor/Device ID match, or a Class/SubClass
  209. // match. If neither of these flags are present, fail.
  210. //
  211. if (!(flags & (PCI_USE_VENDEV_IDS | PCI_USE_CLASS_SUBCLASS))) {
  212. ASSERT(flags & (PCI_USE_VENDEV_IDS | PCI_USE_CLASS_SUBCLASS));
  213. return FALSE;
  214. }
  215. //
  216. // RevisionID, SubVendorID and SubSystemID are more precise flags.
  217. // They are only valid if we're doing a Vendor/Device ID match.
  218. //
  219. if (flags & (PCI_USE_REVISION | PCI_USE_SUBSYSTEM_IDS)) {
  220. if (!(flags & PCI_USE_VENDEV_IDS)) {
  221. ASSERT(flags & PCI_USE_VENDEV_IDS);
  222. return FALSE;
  223. }
  224. }
  225. //
  226. // Programming Interface is also a more precise flag.
  227. // It is only valid if we're doing a class code match.
  228. //
  229. if (flags & PCI_USE_PROGIF) {
  230. if (!(flags & PCI_USE_CLASS_SUBCLASS)) {
  231. ASSERT(flags & PCI_USE_CLASS_SUBCLASS);
  232. return FALSE;
  233. }
  234. }
  235. //
  236. // Okay, validation complete. Do the search.
  237. //
  238. ExAcquireFastMutex(&PciGlobalLock);
  239. pdoExtension = (PPCI_PDO_EXTENSION)Context;
  240. if (flags & (PCI_USE_LOCAL_BUS | PCI_USE_LOCAL_DEVICE)) {
  241. //
  242. // Limit the search to the same bus as the device that requested
  243. // the search. This requires a pdoExtension representing the device
  244. // requesting the search.
  245. //
  246. if (pdoExtension == NULL) {
  247. ASSERT(pdoExtension != NULL);
  248. goto cleanup;
  249. }
  250. fdoExtension = pdoExtension->ParentFdoExtension;
  251. found = PcipDevicePresentOnBus(fdoExtension,
  252. pdoExtension,
  253. Parameters
  254. );
  255. } else {
  256. //
  257. // We have not been told to limit the search to
  258. // the bus on which a particular device lives.
  259. // Do a global search, iterating over all the buses.
  260. //
  261. for ( nextEntry = PciFdoExtensionListHead.Next;
  262. nextEntry != NULL;
  263. nextEntry = nextEntry->Next ) {
  264. fdoExtension = CONTAINING_RECORD(nextEntry,
  265. PCI_FDO_EXTENSION,
  266. List
  267. );
  268. found = PcipDevicePresentOnBus(fdoExtension,
  269. NULL,
  270. Parameters
  271. );
  272. if (found) {
  273. break;
  274. }
  275. }
  276. }
  277. cleanup:
  278. ExReleaseFastMutex(&PciGlobalLock);
  279. return found;
  280. }
  281. BOOLEAN
  282. PcipDevicePresentOnBus(
  283. IN PPCI_FDO_EXTENSION FdoExtension,
  284. IN PPCI_PDO_EXTENSION PdoExtension,
  285. IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
  286. )
  287. /*++
  288. Routine Description:
  289. This routine searches the PCI device tree for a given device
  290. on the bus represented by the given FdoExtension.
  291. Arguments:
  292. FdoExtension - A pointer to the device extension of a PCI FDO.
  293. This represents the bus to be searched for the given device.
  294. PdoExtension - A pointer to the device extension of the PCI PDO that requested
  295. the search. Some device searches are limited to the same bus/device number
  296. as the requesting device, and this is used to get those numbers.
  297. Parameters - The parameters of the search.
  298. Flags - A bitfield indicating which fields of the Parameters structure to use for the search.
  299. Return Value:
  300. TRUE if the requested device is found.
  301. FALSE if it is not.
  302. --*/
  303. {
  304. IN PPCI_PDO_EXTENSION currentPdo;
  305. BOOLEAN found = FALSE;
  306. ULONG flags = Parameters->Flags;
  307. ExAcquireFastMutex(&FdoExtension->ChildListMutex);
  308. for (currentPdo = FdoExtension->ChildPdoList;
  309. currentPdo;
  310. currentPdo = currentPdo->Next) {
  311. //
  312. // If we're limiting the search to devices with the same
  313. // device number as the requesting device, make sure this
  314. // current PDO qualifies.
  315. //
  316. if (PdoExtension && (flags & PCI_USE_LOCAL_DEVICE)) {
  317. if (PdoExtension->Slot.u.bits.DeviceNumber !=
  318. currentPdo->Slot.u.bits.DeviceNumber) {
  319. continue;
  320. }
  321. }
  322. if (flags & PCI_USE_VENDEV_IDS) {
  323. if ((currentPdo->VendorId != Parameters->VendorID)
  324. || (currentPdo->DeviceId != Parameters->DeviceID)) {
  325. continue;
  326. }
  327. if ((flags & PCI_USE_SUBSYSTEM_IDS)
  328. && ((currentPdo->SubsystemVendorId != Parameters->SubVendorID) ||
  329. (currentPdo->SubsystemId != Parameters->SubSystemID))) {
  330. continue;
  331. }
  332. if ((flags & PCI_USE_REVISION)
  333. && (currentPdo->RevisionId != Parameters->RevisionID)) {
  334. continue;
  335. }
  336. }
  337. if (flags & PCI_USE_CLASS_SUBCLASS) {
  338. if ((currentPdo->BaseClass != Parameters->BaseClass) ||
  339. (currentPdo->SubClass != Parameters->SubClass)) {
  340. continue;
  341. }
  342. if ((flags & PCI_USE_PROGIF)
  343. && (currentPdo->ProgIf != Parameters->ProgIf)) {
  344. continue;
  345. }
  346. }
  347. found = TRUE;
  348. break;
  349. }
  350. ExReleaseFastMutex(&FdoExtension->ChildListMutex);
  351. return found;
  352. }
  353. #if DEVPRSNT_TESTING
  354. NTSTATUS
  355. PciRunDevicePresentInterfaceTest(
  356. IN PPCI_PDO_EXTENSION PdoExtension
  357. )
  358. /*++
  359. Routine Description:
  360. Arguments:
  361. FdoExtension - this PCI bus's FDO extension
  362. Return Value:
  363. STATUS_SUCCESS
  364. Notes:
  365. --*/
  366. {
  367. NTSTATUS status = STATUS_SUCCESS;
  368. PCI_DEVICE_PRESENT_INTERFACE interface;
  369. PDEVICE_OBJECT targetDevice = NULL;
  370. KEVENT irpCompleted;
  371. IO_STATUS_BLOCK statusBlock;
  372. PIRP irp = NULL;
  373. PIO_STACK_LOCATION irpStack;
  374. USHORT interfaceSize;
  375. ULONG pass;
  376. PCI_DEVICE_PRESENCE_PARAMETERS parameters;
  377. BOOLEAN result;
  378. PAGED_CODE();
  379. targetDevice = IoGetAttachedDeviceReference(PdoExtension->PhysicalDeviceObject);
  380. for (pass = 0; pass < 2; pass++) {
  381. if (pass == 0) {
  382. //
  383. // First pass test the old version.
  384. //
  385. interfaceSize = FIELD_OFFSET(PCI_DEVICE_PRESENT_INTERFACE, IsDevicePresentEx);
  386. } else {
  387. //
  388. // Second pass test the full new version.
  389. //
  390. interfaceSize = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
  391. }
  392. //
  393. // Get an IRP
  394. //
  395. //
  396. // Find out where we are sending the irp
  397. //
  398. KeInitializeEvent(&irpCompleted, SynchronizationEvent, FALSE);
  399. irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
  400. targetDevice,
  401. NULL, // Buffer
  402. 0, // Length
  403. 0, // StartingOffset
  404. &irpCompleted,
  405. &statusBlock
  406. );
  407. if (!irp) {
  408. status = STATUS_INSUFFICIENT_RESOURCES;
  409. goto cleanup;
  410. }
  411. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  412. irp->IoStatus.Information = 0;
  413. //
  414. // Initialize the stack location
  415. //
  416. irpStack = IoGetNextIrpStackLocation(irp);
  417. PCI_ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);
  418. irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
  419. irpStack->Parameters.QueryInterface.InterfaceType = (PGUID) &GUID_PCI_DEVICE_PRESENT_INTERFACE;
  420. irpStack->Parameters.QueryInterface.Version = PCI_DEVICE_PRESENT_INTERFACE_VERSION;
  421. irpStack->Parameters.QueryInterface.Size = interfaceSize;
  422. irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)&interface;
  423. irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
  424. //
  425. // Call the driver and wait for completion
  426. //
  427. status = IoCallDriver(targetDevice, irp);
  428. if (status == STATUS_PENDING) {
  429. KeWaitForSingleObject(&irpCompleted, Executive, KernelMode, FALSE, NULL);
  430. status = statusBlock.Status;
  431. }
  432. if (!NT_SUCCESS(status)) {
  433. PciDebugPrintf("Couldn't successfully retrieve interface\n");
  434. goto cleanup;
  435. }
  436. PciDebugPrintf("Testing PCI Device Presence Interface\n");
  437. if (pass==0) {
  438. PciDebugPrintf("Original Version\n");
  439. } else {
  440. PciDebugPrintf("New Version\n");
  441. }
  442. PciDebugPrintf("Interface values:\n");
  443. PciDebugPrintf("\tSize=%d\n",interface.Size);
  444. PciDebugPrintf("\tVersion=%d\n",interface.Version);
  445. PciDebugPrintf("\tContext=%d\n",interface.Context);
  446. PciDebugPrintf("\tInterfaceReference=%d\n",interface.InterfaceReference);
  447. PciDebugPrintf("\tInterfaceDereference=%d\n",interface.InterfaceDereference);
  448. PciDebugPrintf("\tIsDevicePresent=%d\n",interface.IsDevicePresent);
  449. PciDebugPrintf("\tIsDevicePresentEx=%d\n",interface.IsDevicePresentEx);
  450. PciDebugPrintf("Testing IsDevicePresent function\n");
  451. PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 No flags Should be TRUE, is ");
  452. result = interface.IsDevicePresent(0x8086,0x7190,3,0,0,0);
  453. if (result) {
  454. PciDebugPrintf("TRUE\n");
  455. } else {
  456. PciDebugPrintf("FALSE\n");
  457. }
  458. PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_REVISION Should be TRUE, is ");
  459. result = interface.IsDevicePresent(0x8086,0x7190,3,0,0,PCI_USE_REVISION);
  460. if (result) {
  461. PciDebugPrintf("TRUE\n");
  462. } else {
  463. PciDebugPrintf("FALSE\n");
  464. }
  465. PciDebugPrintf("\tTesting 8086:7190.01 0000:0000 PCI_USE_REVISION Should be FALSE, is ");
  466. result = interface.IsDevicePresent(0x8086,0x7190,1,0,0,PCI_USE_REVISION);
  467. if (result) {
  468. PciDebugPrintf("TRUE\n");
  469. } else {
  470. PciDebugPrintf("FALSE\n");
  471. }
  472. PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS Should be TRUE, is ");
  473. result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,9,PCI_USE_SUBSYSTEM_IDS);
  474. if (result) {
  475. PciDebugPrintf("TRUE\n");
  476. } else {
  477. PciDebugPrintf("FALSE\n");
  478. }
  479. PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be TRUE, is ");
  480. result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,9,PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION);
  481. if (result) {
  482. PciDebugPrintf("TRUE\n");
  483. } else {
  484. PciDebugPrintf("FALSE\n");
  485. }
  486. PciDebugPrintf("\tTesting 8086:1229.05 8086:0004 PCI_USE_SUBSYSTEM_IDS Should be FALSE, is ");
  487. result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,4,PCI_USE_SUBSYSTEM_IDS);
  488. if (result) {
  489. PciDebugPrintf("TRUE\n");
  490. } else {
  491. PciDebugPrintf("FALSE\n");
  492. }
  493. PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be FALSE, is ");
  494. result = interface.IsDevicePresent(0x8086,0x1229,5,0x8084,9,PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION);
  495. if (result) {
  496. PciDebugPrintf("TRUE\n");
  497. } else {
  498. PciDebugPrintf("FALSE\n");
  499. }
  500. PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 No flags Should ASSERT and be FALSE, is ");
  501. result = interface.IsDevicePresent(0,0,0,0,0,0);
  502. if (result) {
  503. PciDebugPrintf("TRUE\n");
  504. } else {
  505. PciDebugPrintf("FALSE\n");
  506. }
  507. PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 PCI_USE_SUBSYSTEM_IDS Should ASSERT and be FALSE, is ");
  508. result = interface.IsDevicePresent(0,0,0,0,0,PCI_USE_SUBSYSTEM_IDS);
  509. if (result) {
  510. PciDebugPrintf("TRUE\n");
  511. } else {
  512. PciDebugPrintf("FALSE\n");
  513. }
  514. if (pass == 1) {
  515. PciDebugPrintf("Testing IsDevicePresentEx function\n");
  516. PciDebugPrintf("Running the same tests as IsDevicePresent, but using new function\n");
  517. PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_VENDEV_IDS Should be TRUE, is ");
  518. parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
  519. parameters.Flags = PCI_USE_VENDEV_IDS;
  520. parameters.VendorID = 0x8086;
  521. parameters.DeviceID = 0x7190;
  522. parameters.RevisionID = 3;
  523. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  524. if (result) {
  525. PciDebugPrintf("TRUE\n");
  526. } else {
  527. PciDebugPrintf("FALSE\n");
  528. }
  529. PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_REVISION Should be TRUE, is ");
  530. parameters.Flags |= PCI_USE_REVISION;
  531. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  532. if (result) {
  533. PciDebugPrintf("TRUE\n");
  534. } else {
  535. PciDebugPrintf("FALSE\n");
  536. }
  537. PciDebugPrintf("\tTesting 8086:7190.01 0000:0000 PCI_USE_REVISION Should be FALSE, is ");
  538. parameters.RevisionID = 1;
  539. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  540. if (result) {
  541. PciDebugPrintf("TRUE\n");
  542. } else {
  543. PciDebugPrintf("FALSE\n");
  544. }
  545. PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS Should be TRUE, is ");
  546. parameters.DeviceID = 0x1229;
  547. parameters.RevisionID = 5;
  548. parameters.SubVendorID = 0x8086;
  549. parameters.SubSystemID = 9;
  550. parameters.Flags = PCI_USE_VENDEV_IDS | PCI_USE_SUBSYSTEM_IDS;
  551. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  552. if (result) {
  553. PciDebugPrintf("TRUE\n");
  554. } else {
  555. PciDebugPrintf("FALSE\n");
  556. }
  557. PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be TRUE, is ");
  558. parameters.Flags |= PCI_USE_REVISION;
  559. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  560. if (result) {
  561. PciDebugPrintf("TRUE\n");
  562. } else {
  563. PciDebugPrintf("FALSE\n");
  564. }
  565. PciDebugPrintf("\tTesting 8086:1229.05 8086:0004 PCI_USE_SUBSYSTEM_IDS Should be FALSE, is ");
  566. parameters.Flags &= ~PCI_USE_REVISION;
  567. parameters.SubSystemID = 4;
  568. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  569. if (result) {
  570. PciDebugPrintf("TRUE\n");
  571. } else {
  572. PciDebugPrintf("FALSE\n");
  573. }
  574. PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be FALSE, is ");
  575. parameters.SubVendorID = 0x8084;
  576. parameters.SubSystemID = 9;
  577. parameters.Flags |= PCI_USE_SUBSYSTEM_IDS;
  578. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  579. if (result) {
  580. PciDebugPrintf("TRUE\n");
  581. } else {
  582. PciDebugPrintf("FALSE\n");
  583. }
  584. PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 No flags Should ASSERT and be FALSE, is ");
  585. parameters.Flags = 0;
  586. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  587. if (result) {
  588. PciDebugPrintf("TRUE\n");
  589. } else {
  590. PciDebugPrintf("FALSE\n");
  591. }
  592. PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_VENDEV_IDS bad Size Should ASSERT and be FALSE, is ");
  593. parameters.SubVendorID = 0x8086;
  594. parameters.SubSystemID = 9;
  595. parameters.Flags = PCI_USE_VENDEV_IDS;
  596. parameters.Size = 3;
  597. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  598. if (result) {
  599. PciDebugPrintf("TRUE\n");
  600. } else {
  601. PciDebugPrintf("FALSE\n");
  602. }
  603. PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 No flags Should ASSERT and be FALSE, is ");
  604. RtlZeroMemory(&parameters, sizeof(PCI_DEVICE_PRESENCE_PARAMETERS));
  605. parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
  606. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  607. if (result) {
  608. PciDebugPrintf("TRUE\n");
  609. } else {
  610. PciDebugPrintf("FALSE\n");
  611. }
  612. PciDebugPrintf("Running tests on new flags\n");
  613. PciDebugPrintf("\tTesting Class USB Controller PCI_USE_CLASS_SUBCLASS Should be TRUE, is ");
  614. parameters.Flags = PCI_USE_CLASS_SUBCLASS;
  615. parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
  616. parameters.SubClass = PCI_SUBCLASS_SB_USB;
  617. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  618. if (result) {
  619. PciDebugPrintf("TRUE\n");
  620. } else {
  621. PciDebugPrintf("FALSE\n");
  622. }
  623. PciDebugPrintf("\tTesting Class USB Controller (UHCI) PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF Should be TRUE, is ");
  624. parameters.Flags = PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF;
  625. parameters.ProgIf = 0;
  626. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  627. if (result) {
  628. PciDebugPrintf("TRUE\n");
  629. } else {
  630. PciDebugPrintf("FALSE\n");
  631. }
  632. PciDebugPrintf("\tTesting Class USB Controller (OHCI) PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF Should be FALSE, is ");
  633. parameters.ProgIf = 0x10;
  634. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  635. if (result) {
  636. PciDebugPrintf("TRUE\n");
  637. } else {
  638. PciDebugPrintf("FALSE\n");
  639. }
  640. PciDebugPrintf("\tTesting Class Wireless RF PCI_USE_CLASS_SUBCLASS Should be FALSE, is ");
  641. parameters.BaseClass = PCI_CLASS_WIRELESS_CTLR;
  642. parameters.SubClass = PCI_SUBCLASS_WIRELESS_RF;
  643. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  644. if (result) {
  645. PciDebugPrintf("TRUE\n");
  646. } else {
  647. PciDebugPrintf("FALSE\n");
  648. }
  649. PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS Should be TRUE, is ");
  650. parameters.VendorID = 0x8086;
  651. parameters.DeviceID = 0x7112;
  652. parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
  653. parameters.SubClass = PCI_SUBCLASS_SB_USB;
  654. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS;
  655. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  656. if (result) {
  657. PciDebugPrintf("TRUE\n");
  658. } else {
  659. PciDebugPrintf("FALSE\n");
  660. }
  661. PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS Should be TRUE, is ");
  662. parameters.VendorID = 0x8086;
  663. parameters.DeviceID = 0x7112;
  664. parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
  665. parameters.SubClass = PCI_SUBCLASS_SB_USB;
  666. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS;
  667. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  668. if (result) {
  669. PciDebugPrintf("TRUE\n");
  670. } else {
  671. PciDebugPrintf("FALSE\n");
  672. }
  673. PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE Should be ?, is ");
  674. parameters.VendorID = 0x8086;
  675. parameters.DeviceID = 0x7112;
  676. parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
  677. parameters.SubClass = PCI_SUBCLASS_SB_USB;
  678. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE;
  679. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  680. if (result) {
  681. PciDebugPrintf("TRUE\n");
  682. } else {
  683. PciDebugPrintf("FALSE\n");
  684. }
  685. PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS|PCI_USE_LOCAL_DEVICE Should be ?, is ");
  686. parameters.VendorID = 0x8086;
  687. parameters.DeviceID = 0x7112;
  688. parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
  689. parameters.SubClass = PCI_SUBCLASS_SB_USB;
  690. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE|PCI_USE_LOCAL_BUS;
  691. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  692. if (result) {
  693. PciDebugPrintf("TRUE\n");
  694. } else {
  695. PciDebugPrintf("FALSE\n");
  696. }
  697. PciDebugPrintf("\tTesting 8086:7190 PCI_USE_VENDEV|PCI_USE_LOCAL_DEVICE Should be FALSE, is ");
  698. parameters.VendorID = 0x8086;
  699. parameters.DeviceID = 0x7190;
  700. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_LOCAL_DEVICE;
  701. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  702. if (result) {
  703. PciDebugPrintf("TRUE\n");
  704. } else {
  705. PciDebugPrintf("FALSE\n");
  706. }
  707. PciDebugPrintf("\tTesting 8086:7190 PCI_USE_VENDEV|PCI_USE_LOCAL_BUS Should be TRUE, is ");
  708. parameters.VendorID = 0x8086;
  709. parameters.DeviceID = 0x7190;
  710. parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_LOCAL_BUS;
  711. result = interface.IsDevicePresentEx(interface.Context,&parameters);
  712. if (result) {
  713. PciDebugPrintf("TRUE\n");
  714. } else {
  715. PciDebugPrintf("FALSE\n");
  716. }
  717. }
  718. }
  719. //
  720. // Ok we're done with this stack
  721. //
  722. ObDereferenceObject(targetDevice);
  723. return status;
  724. cleanup:
  725. if (targetDevice) {
  726. ObDereferenceObject(targetDevice);
  727. }
  728. return status;
  729. }
  730. #endif