Message ID | 4F867083.2090200@jp.fujitsu.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Hi I'm so sorry, but there is a better way than this way with pcibios_enable_device() for issue. I will write another code soon, so please wait. Regards. Hiroo MATSUMOTO > Hi > > > I'm trying to use PCI Express Hot Plug on powerpc platform. > But PCI driver returns error when hotplug. > Error log is as below. > http://www.spinics.net/lists/linux-pci/msg14534.html > > Some of PCI driver needs dma_ops. > On x86 platform, dma_ops is getting from external variable. > On powerpc platform, dma_ops is getting from archdata.dma_ops in struct > device. > There is a problem that archdata.dma_ops is set only when boot with > pcibios_setup_bus_devices but not set when hotplug. > So when hotplug, PCI driver's probe will return error. > > I add code of checking and setting dma_ops in pcibios_enable_device. > It is called from pci_enable_device_xxx in PCI driver's probe before > checking dma_ops. > And PCI driver works good when hotplug. > > > Regards. > > Hiroo MATSUMOTO >
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 32656f1..080ff1d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -111,6 +111,17 @@ static resource_size_t pcibios_io_size(const struct pci_controller *hose) #endif } +static inline void pcibios_set_dma_ops(struct pci_dev *dev) +{ + /* Hook up default DMA ops */ + set_dma_ops(&dev->dev, pci_dma_ops); + set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); + + /* Additional platform DMA/iommu setup */ + if (ppc_md.pci_dma_dev_setup) + ppc_md.pci_dma_dev_setup(dev); +} + int pcibios_vaddr_is_ioport(void __iomem *address) { int ret = 0; @@ -1102,13 +1113,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) */ set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - /* Hook up default DMA ops */ - set_dma_ops(&dev->dev, pci_dma_ops); - set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); - - /* Additional platform DMA/iommu setup */ - if (ppc_md.pci_dma_dev_setup) - ppc_md.pci_dma_dev_setup(dev); + pcibios_set_dma_ops(dev); /* Read default IRQs and fixup if necessary */ pci_read_irq_line(dev); @@ -1547,6 +1552,10 @@ EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); int pcibios_enable_device(struct pci_dev *dev, int mask) { + /* dma_ops is NULL from hotplug */ + if (!get_dma_ops(&dev->dev)) + pcibios_set_dma_ops(dev); + if (ppc_md.pcibios_enable_device_hook) if (ppc_md.pcibios_enable_device_hook(dev)) return -EINVAL;
Hi I'm trying to use PCI Express Hot Plug on powerpc platform. But PCI driver returns error when hotplug. Error log is as below. http://www.spinics.net/lists/linux-pci/msg14534.html Some of PCI driver needs dma_ops. On x86 platform, dma_ops is getting from external variable. On powerpc platform, dma_ops is getting from archdata.dma_ops in struct device. There is a problem that archdata.dma_ops is set only when boot with pcibios_setup_bus_devices but not set when hotplug. So when hotplug, PCI driver's probe will return error. I add code of checking and setting dma_ops in pcibios_enable_device. It is called from pci_enable_device_xxx in PCI driver's probe before checking dma_ops. And PCI driver works good when hotplug. Regards. Hiroo MATSUMOTO Signed-off-by: Hiroo MATSUMOTO <matsumoto.hiroo@jp.fujitsu.com>