Commit 72be84f1 authored by Yevgeny Petrilin's avatar Yevgeny Petrilin Committed by David S. Miller

mlx4: Fixing wrong error codes in communication channel

The communication channel is HW interface from PF point of view
So the command return status should be stored as HW error code
and only then translated to errno values.
Reporetd-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarYevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 996b0541
...@@ -152,6 +152,26 @@ static int mlx4_status_to_errno(u8 status) ...@@ -152,6 +152,26 @@ static int mlx4_status_to_errno(u8 status)
return trans_table[status]; return trans_table[status];
} }
static u8 mlx4_errno_to_status(int errno)
{
switch (errno) {
case -EPERM:
return CMD_STAT_BAD_OP;
case -EINVAL:
return CMD_STAT_BAD_PARAM;
case -ENXIO:
return CMD_STAT_BAD_SYS_STATE;
case -EBUSY:
return CMD_STAT_RESOURCE_BUSY;
case -ENOMEM:
return CMD_STAT_EXCEED_LIM;
case -ENFILE:
return CMD_STAT_ICM_ERROR;
default:
return CMD_STAT_INTERNAL_ERR;
}
}
static int comm_pending(struct mlx4_dev *dev) static int comm_pending(struct mlx4_dev *dev)
{ {
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
...@@ -361,10 +381,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, ...@@ -361,10 +381,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
mlx4_err(dev, "response expected while" mlx4_err(dev, "response expected while"
"output mailbox is NULL for " "output mailbox is NULL for "
"command 0x%x\n", op); "command 0x%x\n", op);
vhcr->status = -EINVAL; vhcr->status = CMD_STAT_BAD_PARAM;
} }
} }
ret = vhcr->status; ret = mlx4_status_to_errno(vhcr->status);
} }
} else { } else {
ret = mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_POST, 0, ret = mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_POST, 0,
...@@ -378,10 +398,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, ...@@ -378,10 +398,10 @@ static int mlx4_slave_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
mlx4_err(dev, "response expected while" mlx4_err(dev, "response expected while"
"output mailbox is NULL for " "output mailbox is NULL for "
"command 0x%x\n", op); "command 0x%x\n", op);
vhcr->status = -EINVAL; vhcr->status = CMD_STAT_BAD_PARAM;
} }
} }
ret = vhcr->status; ret = mlx4_status_to_errno(vhcr->status);
} else } else
mlx4_err(dev, "failed execution of VHCR_POST command" mlx4_err(dev, "failed execution of VHCR_POST command"
"opcode 0x%x\n", op); "opcode 0x%x\n", op);
...@@ -1066,6 +1086,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1066,6 +1086,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
u64 out_param; u64 out_param;
int ret = 0; int ret = 0;
int i; int i;
int err = 0;
/* Create sw representation of Virtual HCR */ /* Create sw representation of Virtual HCR */
vhcr = kzalloc(sizeof(struct mlx4_vhcr), GFP_KERNEL); vhcr = kzalloc(sizeof(struct mlx4_vhcr), GFP_KERNEL);
...@@ -1105,7 +1126,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1105,7 +1126,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
if (!cmd) { if (!cmd) {
mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n", mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n",
vhcr->op, slave); vhcr->op, slave);
vhcr_cmd->status = -EINVAL; vhcr_cmd->status = CMD_STAT_BAD_PARAM;
goto out_status; goto out_status;
} }
...@@ -1114,18 +1135,18 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1114,18 +1135,18 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
vhcr->in_param &= INBOX_MASK; vhcr->in_param &= INBOX_MASK;
inbox = mlx4_alloc_cmd_mailbox(dev); inbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(inbox)) { if (IS_ERR(inbox)) {
ret = PTR_ERR(inbox); vhcr_cmd->status = CMD_STAT_BAD_SIZE;
inbox = NULL; inbox = NULL;
goto out; goto out_status;
} }
ret = mlx4_ACCESS_MEM(dev, inbox->dma, slave, if (mlx4_ACCESS_MEM(dev, inbox->dma, slave,
vhcr->in_param, vhcr->in_param,
MLX4_MAILBOX_SIZE, 1); MLX4_MAILBOX_SIZE, 1)) {
if (ret) {
mlx4_err(dev, "%s: Failed reading inbox (cmd:0x%x)\n", mlx4_err(dev, "%s: Failed reading inbox (cmd:0x%x)\n",
__func__, cmd->opcode); __func__, cmd->opcode);
goto out; vhcr_cmd->status = CMD_STAT_INTERNAL_ERR;
goto out_status;
} }
} }
...@@ -1134,7 +1155,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1134,7 +1155,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
mlx4_warn(dev, "Command:0x%x from slave: %d failed protection " mlx4_warn(dev, "Command:0x%x from slave: %d failed protection "
"checks for resource_id:%d\n", vhcr->op, slave, "checks for resource_id:%d\n", vhcr->op, slave,
vhcr->in_modifier); vhcr->in_modifier);
vhcr_cmd->status = -EPERM; vhcr_cmd->status = CMD_STAT_BAD_OP;
goto out_status; goto out_status;
} }
...@@ -1142,15 +1163,15 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1142,15 +1163,15 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
if (cmd->has_outbox) { if (cmd->has_outbox) {
outbox = mlx4_alloc_cmd_mailbox(dev); outbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(outbox)) { if (IS_ERR(outbox)) {
ret = PTR_ERR(outbox); vhcr_cmd->status = CMD_STAT_BAD_SIZE;
outbox = NULL; outbox = NULL;
goto out; goto out_status;
} }
} }
/* Execute the command! */ /* Execute the command! */
if (cmd->wrapper) { if (cmd->wrapper) {
vhcr_cmd->status = cmd->wrapper(dev, slave, vhcr, inbox, outbox, err = cmd->wrapper(dev, slave, vhcr, inbox, outbox,
cmd); cmd);
if (cmd->out_is_imm) if (cmd->out_is_imm)
vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param); vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param);
...@@ -1159,33 +1180,36 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, ...@@ -1159,33 +1180,36 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
vhcr->in_param; vhcr->in_param;
out_param = cmd->has_outbox ? (u64) outbox->dma : out_param = cmd->has_outbox ? (u64) outbox->dma :
vhcr->out_param; vhcr->out_param;
vhcr_cmd->status = __mlx4_cmd(dev, in_param, &out_param, err = __mlx4_cmd(dev, in_param, &out_param,
cmd->out_is_imm, vhcr->in_modifier, cmd->out_is_imm, vhcr->in_modifier,
vhcr->op_modifier, vhcr->op, vhcr->op_modifier, vhcr->op,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_NATIVE); MLX4_CMD_NATIVE);
if (vhcr_cmd->status) {
mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with"
" error:%d, status %d\n",
vhcr->op, slave, vhcr->errno,
vhcr_cmd->status);
ret = vhcr_cmd->status;
goto out;
}
if (cmd->out_is_imm) { if (cmd->out_is_imm) {
vhcr->out_param = out_param; vhcr->out_param = out_param;
vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param); vhcr_cmd->out_param = cpu_to_be64(vhcr->out_param);
} }
} }
if (err) {
mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with"
" error:%d, status %d\n",
vhcr->op, slave, vhcr->errno, err);
vhcr_cmd->status = mlx4_errno_to_status(err);
goto out_status;
}
/* Write outbox if command completed successfully */ /* Write outbox if command completed successfully */
if (cmd->has_outbox && !vhcr->errno) { if (cmd->has_outbox && !vhcr_cmd->status) {
ret = mlx4_ACCESS_MEM(dev, outbox->dma, slave, ret = mlx4_ACCESS_MEM(dev, outbox->dma, slave,
vhcr->out_param, vhcr->out_param,
MLX4_MAILBOX_SIZE, MLX4_CMD_WRAPPED); MLX4_MAILBOX_SIZE, MLX4_CMD_WRAPPED);
if (ret) { if (ret) {
/* If we failed to write back the outbox after the
*command was successfully executed, we must fail this
* slave, as it is now in undefined state */
mlx4_err(dev, "%s:Failed writing outbox\n", __func__); mlx4_err(dev, "%s:Failed writing outbox\n", __func__);
goto out; goto out;
} }
......
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