Re: [RFC/PATCH 1/4] pci: Add pci_enable_device_{io,mem} intefaces

Benjamin Herrenschmidt
2007-12-18T00:03:57Z

On Tue, 2007-12-18 at 00:49 +0100, Johannes Weiner wrote:

> These two functions should be refactored, the only difference is the
> flag checking.

FYI. Here's what it looks like in my next version of the patch:

Index: linux-work/drivers/pci/pci.c
===================================================================
--- linux-work.orig/drivers/pci/pci.c 2007-10-15 11:19:38.000000000 +1000
+++ linux-work/drivers/pci/pci.c 2007-12-18 11:01:20.000000000 +1100
@@ -736,6 +736,51 @@ pci_enable_device_bars(struct pci_dev *d
return err;
}

+static int __pci_enable_device_flags(struct pci_dev *dev,
+ resource_size_t flags)
+{
+ int err;
+ int i, bars = 0;
+
+ if (atomic_add_return(1, &dev->enable_cnt) > 1)
+ return 0; /* already enabled */
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ if (dev->resource[i].flags & flags)
+ bars |= (1 << i);
+
+ err = do_pci_enable_device(dev, bars);
+ if (err < 0)
+ atomic_dec(&dev->enable_cnt);
+ return err;
+}
+
+/**
+ * pci_enable_device_io - Initialize a device for use with IO space
+ * @dev: PCI device to be initialized
+ *
+ * Initialize device before it's used by a driver. Ask low-level code
+ * to enable I/O resources. Wake up the device if it was suspended.
+ * Beware, this function can fail.
+ */
+int pci_enable_device_io(struct pci_dev *dev)
+{
+ return __pci_enable_device_flags(dev, IORESOURCE_IO);
+}
+
+/**
+ * pci_enable_device_mem - Initialize a device for use with Memory space
+ * @dev: PCI device to be initialized
+ *
+ * Initialize device before it's used by a driver. Ask low-level code
+ * to enable Memory resources. Wake up the device if it was suspended.
+ * Beware, this function can fail.
+ */
+int pci_enable_device_mem(struct pci_dev *dev)
+{
+ return __pci_enable_device_flags(dev, IORESOURCE_MEM);
+}
+
/**
* pci_enable_device - Initialize device before it's used by a driver.
* @dev: PCI device to be initialized
@@ -749,7 +794,7 @@ pci_enable_device_bars(struct pci_dev *d
*/
int pci_enable_device(struct pci_dev *dev)
{
- return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+ return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
}

/*
@@ -1621,6 +1666,8 @@ device_initcall(pci_init);
EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(pci_reenable_device);
EXPORT_SYMBOL(pci_enable_device_bars);
+EXPORT_SYMBOL(pci_enable_device_io);
+EXPORT_SYMBOL(pci_enable_device_mem);
EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pcim_enable_device);
EXPORT_SYMBOL(pcim_pin_device);
Index: linux-work/include/linux/pci.h
===================================================================
--- linux-work.orig/include/linux/pci.h 2007-12-18 11:00:32.000000000 +1100
+++ linux-work/include/linux/pci.h 2007-12-18 11:00:33.000000000 +1100
@@ -548,6 +548,8 @@ static inline int pci_write_config_dword

int __must_check pci_enable_device(struct pci_dev *dev);
int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask);
+int __must_check pci_enable_device_io(struct pci_dev *dev);
+int __must_check pci_enable_device_mem(struct pci_dev *dev);
int __must_check pci_reenable_device(struct pci_dev *);
int __must_check pcim_enable_device(struct pci_dev *pdev);
void pcim_pin_device(struct pci_dev *pdev);