Skip to contentSkip to conversation

powerpc: set_dma_ops for pci hotplug

RFC In review Hiroo Matsumoto 1 participant 2 messages Apr 12, 2012 – Apr 13, 2012 PowerPC

lore
Share & tools
lore
#0 lore raw

RFC 1/1 powerpc: set_dma_ops for pci hotplug

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

arch/powerpc/kernel/pci-common.c +16 -7
index 32656f1..080ff1d 100644
@@ -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;
#1 lore raw

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

Quoted 26 lines

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