|
@@ -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;
|
|
|
}
|
|
|
|
|
|
/*
|