Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
PCI/portdrv: Only disable Bus Master on kexec reboot and connected PC…
…I devices After commit 745be2e ("PCIe: portdrv: call pci_disable_device during remove") and commit cc27b73 ("PCI/portdrv: Turn off PCIe services during shutdown"), it also calls pci_disable_device() during shutdown, this leads to shutdown or reboot failure occasionally due to clear PCI_COMMAND_MASTER on the device in do_pci_disable_device(). drivers/pci/pci.c static void do_pci_disable_device(struct pci_dev *dev) { u16 pci_command; pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { pci_command &= ~PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, pci_command); } pcibios_disable_device(dev); } When remove "pci_command &= ~PCI_COMMAND_MASTER;", it can work well. As Oliver O'Halloran said, no need to call pci_disable_device() when actually shutting down, but we should call pci_disable_device() before handing over to the new kernel on kexec reboot, so we can do some condition checks which are similar with pci_device_shutdown(), this is done by commit 4fc9bbf ("PCI: Disable Bus Master only on kexec reboot") and commit 6e0eda3 ("PCI: Don't try to disable Bus Master on disconnected PCI devices"). drivers/pci/pci-driver.c static void pci_device_shutdown(struct device *dev) { ... /* * If this is a kexec reboot, turn off Bus Master bit on the * device to tell it to not continue to do DMA. Don't touch * devices in D3cold or unknown states. * If it is not a kexec reboot, firmware will hit the PCI * devices with big hammer and stop their DMA any way. */ if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot)) pci_clear_master(pci_dev); } Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
- Loading branch information