net/mlx4_core: Refactor mlx4_cmd_init and mlx4_cmd_cleanup
authorMatan Barak <matanb@mellanox.com>
Thu, 13 Nov 2014 12:45:29 +0000 (14:45 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 13 Nov 2014 20:16:17 +0000 (15:16 -0500)
Refactoring mlx4_cmd_init and mlx4_cmd_cleanup such that partial init
and cleanup are possible. After this refactoring, calling mlx4_cmd_init
several times is safe.

This is necessary in the VF init flow when mlx4_init_hca returns -EACCESS,
we need to issue cleanup and re-attempt to call it with the slave flag.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h

index 3c05e5878b49f07477d716160980ab63be07f70f..5c93d1451c449e328fe05505bc848a146af3df9e 100644 (file)
@@ -2117,50 +2117,52 @@ err_vhcr:
 int mlx4_cmd_init(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
+       int flags = 0;
+
+       if (!priv->cmd.initialized) {
+               mutex_init(&priv->cmd.hcr_mutex);
+               mutex_init(&priv->cmd.slave_cmd_mutex);
+               sema_init(&priv->cmd.poll_sem, 1);
+               priv->cmd.use_events = 0;
+               priv->cmd.toggle     = 1;
+               priv->cmd.initialized = 1;
+               flags |= MLX4_CMD_CLEANUP_STRUCT;
+       }
 
-       mutex_init(&priv->cmd.hcr_mutex);
-       mutex_init(&priv->cmd.slave_cmd_mutex);
-       sema_init(&priv->cmd.poll_sem, 1);
-       priv->cmd.use_events = 0;
-       priv->cmd.toggle     = 1;
-
-       priv->cmd.hcr = NULL;
-       priv->mfunc.vhcr = NULL;
-
-       if (!mlx4_is_slave(dev)) {
+       if (!mlx4_is_slave(dev) && !priv->cmd.hcr) {
                priv->cmd.hcr = ioremap(pci_resource_start(dev->pdev, 0) +
                                        MLX4_HCR_BASE, MLX4_HCR_SIZE);
                if (!priv->cmd.hcr) {
                        mlx4_err(dev, "Couldn't map command register\n");
-                       return -ENOMEM;
+                       goto err;
                }
+               flags |= MLX4_CMD_CLEANUP_HCR;
        }
 
-       if (mlx4_is_mfunc(dev)) {
+       if (mlx4_is_mfunc(dev) && !priv->mfunc.vhcr) {
                priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE,
                                                      &priv->mfunc.vhcr_dma,
                                                      GFP_KERNEL);
                if (!priv->mfunc.vhcr)
-                       goto err_hcr;
+                       goto err;
+
+               flags |= MLX4_CMD_CLEANUP_VHCR;
        }
 
-       priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev,
-                                        MLX4_MAILBOX_SIZE,
-                                        MLX4_MAILBOX_SIZE, 0);
-       if (!priv->cmd.pool)
-               goto err_vhcr;
+       if (!priv->cmd.pool) {
+               priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev,
+                                                MLX4_MAILBOX_SIZE,
+                                                MLX4_MAILBOX_SIZE, 0);
+               if (!priv->cmd.pool)
+                       goto err;
 
-       return 0;
+               flags |= MLX4_CMD_CLEANUP_POOL;
+       }
 
-err_vhcr:
-       if (mlx4_is_mfunc(dev))
-               dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
-                                 priv->mfunc.vhcr, priv->mfunc.vhcr_dma);
-       priv->mfunc.vhcr = NULL;
+       return 0;
 
-err_hcr:
-       if (!mlx4_is_slave(dev))
-               iounmap(priv->cmd.hcr);
+err:
+       mlx4_cmd_cleanup(dev, flags);
        return -ENOMEM;
 }
 
@@ -2184,18 +2186,28 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
        iounmap(priv->mfunc.comm);
 }
 
-void mlx4_cmd_cleanup(struct mlx4_dev *dev)
+void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
 
-       pci_pool_destroy(priv->cmd.pool);
+       if (priv->cmd.pool && (cleanup_mask & MLX4_CMD_CLEANUP_POOL)) {
+               pci_pool_destroy(priv->cmd.pool);
+               priv->cmd.pool = NULL;
+       }
 
-       if (!mlx4_is_slave(dev))
+       if (!mlx4_is_slave(dev) && priv->cmd.hcr &&
+           (cleanup_mask & MLX4_CMD_CLEANUP_HCR)) {
                iounmap(priv->cmd.hcr);
-       if (mlx4_is_mfunc(dev))
+               priv->cmd.hcr = NULL;
+       }
+       if (mlx4_is_mfunc(dev) && priv->mfunc.vhcr &&
+           (cleanup_mask & MLX4_CMD_CLEANUP_VHCR)) {
                dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
                                  priv->mfunc.vhcr, priv->mfunc.vhcr_dma);
-       priv->mfunc.vhcr = NULL;
+               priv->mfunc.vhcr = NULL;
+       }
+       if (priv->cmd.initialized && (cleanup_mask & MLX4_CMD_CLEANUP_STRUCT))
+               priv->cmd.initialized = 0;
 }
 
 /*
index 71f1f3be4ebe957b933f4730e6a3d716b45307a6..b2732eb82bf168f6d4a09631404c637e2eae8664 100644 (file)
@@ -2396,7 +2396,7 @@ slave_start:
                if (err == -EACCES) {
                        /* Not primary Physical function
                         * Running in slave mode */
-                       mlx4_cmd_cleanup(dev);
+                       mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL);
                        dev->flags |= MLX4_FLAG_SLAVE;
                        dev->flags &= ~MLX4_FLAG_MASTER;
                        goto slave_start;
@@ -2561,7 +2561,7 @@ err_mfunc:
                mlx4_multi_func_cleanup(dev);
 
 err_cmd:
-       mlx4_cmd_cleanup(dev);
+       mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL);
 
 err_sriov:
        if (dev->flags & MLX4_FLAG_SRIOV && !existing_vfs)
@@ -2805,7 +2805,7 @@ static void mlx4_unload_one(struct pci_dev *pdev)
        mlx4_close_hca(dev);
        if (mlx4_is_slave(dev))
                mlx4_multi_func_cleanup(dev);
-       mlx4_cmd_cleanup(dev);
+       mlx4_cmd_cleanup(dev, MLX4_CMD_CLEANUP_ALL);
 
        if (dev->flags & MLX4_FLAG_MSI_X)
                pci_disable_msix(pdev);
index f8fc7bd6f48bbfdc3368eada86ba9b4f1fb04409..f48e7c3eecf856f383050e88d3f4ab9105c94a11 100644 (file)
@@ -606,6 +606,7 @@ struct mlx4_cmd {
        u8                      use_events;
        u8                      toggle;
        u8                      comm_toggle;
+       u8                      initialized;
 };
 
 enum {
@@ -1126,8 +1127,16 @@ int mlx4_QUERY_QP_wrapper(struct mlx4_dev *dev, int slave,
 
 int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe);
 
+enum {
+       MLX4_CMD_CLEANUP_STRUCT = 1UL << 0,
+       MLX4_CMD_CLEANUP_POOL   = 1UL << 1,
+       MLX4_CMD_CLEANUP_HCR    = 1UL << 2,
+       MLX4_CMD_CLEANUP_VHCR   = 1UL << 3,
+       MLX4_CMD_CLEANUP_ALL    = (MLX4_CMD_CLEANUP_VHCR << 1) - 1
+};
+
 int mlx4_cmd_init(struct mlx4_dev *dev);
-void mlx4_cmd_cleanup(struct mlx4_dev *dev);
+void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask);
 int mlx4_multi_func_init(struct mlx4_dev *dev);
 void mlx4_multi_func_cleanup(struct mlx4_dev *dev);
 void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param);