Commit ffc39f6d authored by Matan Barak's avatar Matan Barak Committed by David S. Miller

net/mlx4_core: Refactor mlx4_cmd_init and mlx4_cmd_cleanup

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: default avatarMatan Barak <matanb@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 225c6c8c
......@@ -2117,50 +2117,52 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
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;
}
/*
......
......@@ -2396,7 +2396,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
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 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
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);
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment