+/**\r
+ Disable Bus Master Enable bit in all devices in the list.\r
+\r
+ @param Devices A device list.\r
+**/\r
+VOID\r
+DisableBmeOnTree (\r
+ IN LIST_ENTRY *Devices\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ UINT16 Command;\r
+\r
+ for ( Link = GetFirstNode (Devices)\r
+ ; !IsNull (Devices, Link)\r
+ ; Link = GetNextNode (Devices, Link)\r
+ ) {\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);\r
+ //\r
+ // Turn off all children's Bus Master, if any\r
+ //\r
+ DisableBmeOnTree (&PciIoDevice->ChildList);\r
+\r
+ //\r
+ // If this is a device that supports BME, disable BME on this device.\r
+ //\r
+ if ((PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) {\r
+ PCI_READ_COMMAND_REGISTER(PciIoDevice, &Command);\r
+ if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) {\r
+ Command &= ~EFI_PCI_COMMAND_BUS_MASTER;\r
+ PCI_SET_COMMAND_REGISTER (PciIoDevice, Command);\r
+ DEBUG ((\r
+ DEBUG_INFO," %02x %02x %02x %04x\n",\r
+ PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,\r
+ Command\r
+ ));\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Exit Boot Services Event notification handler.\r
+\r
+ Disable Bus Master on any that were enabled during BDS.\r
+\r
+ @param[in] Event Event whose notification function is being invoked.\r
+ @param[in] Context Pointer to the notification function's context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnExitBootServices (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "PciBus: Disable Bus Master of all devices...\n"\r
+ " Bus# Device# Function# NewCommand\n"\r
+ ));\r
+ DisableBmeOnTree(&mPciDevicePool);\r
+}\r
+\r