Generalize strict PCI-specific initialization and uninitialization steps and
prepare the code to be easily reused for other infrastructures. API of the
eth_driver stays backwards compatible. The previously introduced magic is
utilized to test whether we are working with a PCI device or not.

Signed-off-by: Jan Viktorin <viktorin at rehivetech.com>
---
 lib/librte_ether/rte_ethdev.c | 118 ++++++++++++++++++++++++++++--------------
 lib/librte_ether/rte_ethdev.h |   9 ++--
 2 files changed, 85 insertions(+), 42 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 21fc0d7..826d4b9 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -216,16 +216,23 @@ rte_eth_dev_allocate(const char *name, enum 
rte_eth_dev_type type)

 static int
 rte_eth_dev_create_unique_device_name(char *name, size_t size,
-               struct rte_pci_device *pci_dev)
+               union rte_device *dev)
 {
        int ret;

-       if ((name == NULL) || (pci_dev == NULL))
+       if ((name == NULL) || (dev == NULL))
                return -EINVAL;

-       ret = snprintf(name, size, "%d:%d.%d",
-                       pci_dev->addr.bus, pci_dev->addr.devid,
-                       pci_dev->addr.function);
+       switch (dev->magic) {
+       case RTE_PCI_DEVICE_MAGIC:
+               ret = snprintf(name, size, "%d:%d.%d",
+                       dev->pci.addr.bus, dev->pci.addr.devid,
+                       dev->pci.addr.function);
+               break;
+       default:
+               ret = -ENODEV;
+       }
+
        if (ret < 0)
                return ret;
        return 0;
@@ -243,33 +250,41 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
 }

 static int
-rte_eth_dev_init(struct rte_pci_driver *pci_drv,
-                struct rte_pci_device *pci_dev)
+rte_device_get_dev_type(union rte_device *dev)
+{
+       switch (dev->magic) {
+       case RTE_PCI_DEVICE_MAGIC:
+               return RTE_ETH_DEV_PCI;
+       default:
+               return RTE_ETH_DEV_UNKNOWN;
+       }
+}
+
+static int
+rte_eth_dev_init(struct eth_driver *eth_drv, union rte_device *dev)
 {
-       struct eth_driver    *eth_drv;
        struct rte_eth_dev *eth_dev;
        char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-
        int diag;

-       eth_drv = (struct eth_driver *)pci_drv;
-
-       /* Create unique Ethernet device name using PCI address */
+       /* Create unique Ethernet device name */
        rte_eth_dev_create_unique_device_name(ethdev_name,
-                       sizeof(ethdev_name), pci_dev);
+                       sizeof(ethdev_name), dev);

-       eth_dev = rte_eth_dev_allocate(ethdev_name, RTE_ETH_DEV_PCI);
+       eth_dev = rte_eth_dev_allocate(ethdev_name,
+                       rte_device_get_dev_type(dev));
        if (eth_dev == NULL)
                return -ENOMEM;

        if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
                eth_dev->data->dev_private = rte_zmalloc("ethdev private 
structure",
-                                 eth_drv->dev_private_size,
-                                 RTE_CACHE_LINE_SIZE);
+                               eth_drv->dev_private_size,
+                               RTE_CACHE_LINE_SIZE);
                if (eth_dev->data->dev_private == NULL)
                        rte_panic("Cannot allocate memzone for private port 
data\n");
        }
-       eth_dev->pci_dev = pci_dev;
+
+       eth_dev->dev = dev;
        eth_dev->driver = eth_drv;
        eth_dev->data->rx_mbuf_alloc_failed = 0;

@@ -286,10 +301,6 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
        if (diag == 0)
                return 0;

-       RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(vendor_id=0x%u 
device_id=0x%x) failed\n",
-                       pci_drv->name,
-                       (unsigned) pci_dev->id.vendor_id,
-                       (unsigned) pci_dev->id.device_id);
        if (rte_eal_process_type() == RTE_PROC_PRIMARY)
                rte_free(eth_dev->data->dev_private);
        rte_eth_dev_release_port(eth_dev);
@@ -297,29 +308,41 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
 }

 static int
-rte_eth_dev_uninit(struct rte_pci_device *pci_dev)
+rte_eth_dev_pci_init(struct rte_pci_driver *pci_drv,
+                struct rte_pci_device *pci_dev)
+{
+       struct eth_driver *eth_drv = (struct eth_driver *)pci_drv;
+       union rte_device *dev = (union rte_device *) pci_dev;
+       int rc;
+
+       if ((rc = rte_eth_dev_init(eth_drv, dev))) {
+               RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(vendor_id=0x%u 
device_id=0x%x) failed\n",
+                               pci_drv->name,
+                               (unsigned) pci_dev->id.vendor_id,
+                               (unsigned) pci_dev->id.device_id);
+               return rc;
+       }
+
+       return 0;
+}
+
+static int
+rte_eth_dev_uninit(struct eth_driver *eth_drv)
 {
-       const struct eth_driver *eth_drv;
+       union rte_device *dev = (union rte_device *) eth_drv;
        struct rte_eth_dev *eth_dev;
        char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-       int ret;

-       if (pci_dev == NULL)
-               return -EINVAL;
-
-       /* Create unique Ethernet device name using PCI address */
+       /* Create unique Ethernet device name */
        rte_eth_dev_create_unique_device_name(ethdev_name,
-                       sizeof(ethdev_name), pci_dev);
+                       sizeof(ethdev_name), dev);

        eth_dev = rte_eth_dev_allocated(ethdev_name);
        if (eth_dev == NULL)
                return -ENODEV;

-       eth_drv = (const struct eth_driver *)pci_dev->driver;
-
-       /* Invoke PMD device uninit function */
        if (*eth_drv->eth_dev_uninit) {
-               ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+               int ret = (*eth_drv->eth_dev_uninit)(eth_dev);
                if (ret)
                        return ret;
        }
@@ -330,13 +353,26 @@ rte_eth_dev_uninit(struct rte_pci_device *pci_dev)
        if (rte_eal_process_type() == RTE_PROC_PRIMARY)
                rte_free(eth_dev->data->dev_private);

-       eth_dev->pci_dev = NULL;
+       eth_dev->dev = NULL;
        eth_dev->driver = NULL;
        eth_dev->data = NULL;

        return 0;
 }

+static int
+rte_eth_dev_pci_uninit(struct rte_pci_device *pci_dev)
+{
+       struct eth_driver *eth_drv;
+
+       if (pci_dev == NULL || pci_dev->driver == NULL)
+               return -EINVAL;
+
+       eth_drv = (struct eth_driver *) pci_dev->driver;
+
+       return rte_eth_dev_uninit(eth_drv);
+}
+
 /**
  * Register an Ethernet [Poll Mode] driver.
  *
@@ -345,18 +381,22 @@ rte_eth_dev_uninit(struct rte_pci_device *pci_dev)
  * Poll Mode Driver.
  * Invokes the rte_eal_pci_register() function to register the *pci_drv*
  * structure embedded in the *eth_drv* structure, after having stored the
- * address of the rte_eth_dev_init() function in the *devinit* field of
+ * address of the rte_eth_dev_pci_init() function in the *devinit* field of
  * the *pci_drv* structure.
- * During the PCI probing phase, the rte_eth_dev_init() function is
+ * During the PCI probing phase, the rte_eth_dev_pci_init() function is
  * invoked for each PCI [Ethernet device] matching the embedded PCI
  * identifiers provided by the driver.
  */
 void
 rte_eth_driver_register(struct eth_driver *eth_drv)
 {
-       eth_drv->pci_drv.devinit = rte_eth_dev_init;
-       eth_drv->pci_drv.devuninit = rte_eth_dev_uninit;
-       rte_eal_pci_register(&eth_drv->pci_drv);
+       if (eth_drv->magic == RTE_PCI_DRV_MAGIC) {
+               eth_drv->pci_drv.devinit = rte_eth_dev_pci_init;
+               eth_drv->pci_drv.devuninit = rte_eth_dev_pci_uninit;
+               rte_eal_pci_register(&eth_drv->pci_drv);
+       } else {
+               rte_panic("%s(): bad magic: %08x\n", __func__, eth_drv->magic);
+       }
 }

 int
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 5a267e4..5dd2e1a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -824,7 +824,7 @@ struct rte_eth_conf {
 #define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100

 struct rte_eth_dev_info {
-       struct rte_pci_device *pci_dev; /**< Device PCI information. */
+       RTE_DEVICE_PTR_DECL(pci_dev); /**< Device information. */
        const char *driver_name; /**< Device Driver name. */
        unsigned int if_index; /**< Index to bound host interface, or 0 if none.
                Use if_indextoname() to translate into an interface name. */
@@ -1534,7 +1534,7 @@ struct rte_eth_dev {
        struct rte_eth_dev_data *data;  /**< Pointer to device data */
        const struct eth_driver *driver;/**< Driver for this device */
        const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
-       struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+       RTE_DEVICE_PTR_DECL(pci_dev); /**< Device information. */
        /** User application callbacks for NIC interrupts */
        struct rte_eth_dev_cb_list link_intr_cbs;
        /**
@@ -1767,7 +1767,10 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev 
*eth_dev);
  * - The size of the private data to allocate for each matching device.
  */
 struct eth_driver {
-       struct rte_pci_driver pci_drv;    /**< The PMD is also a PCI driver. */
+       union {
+               unsigned int magic;
+               struct rte_pci_driver pci_drv; /**< The PMD is a PCI driver. */
+       };
        eth_dev_init_t eth_dev_init;      /**< Device init function. */
        eth_dev_uninit_t eth_dev_uninit;  /**< Device uninit function. */
        unsigned int dev_private_size;    /**< Size of device private data. */
-- 
2.6.3

Reply via email to