int next;
u64 out_param;
u16 token;
+ u8 status;
};
static int mlx4_status_to_errno(u8 status) {
return trans_table[status];
}
-static int cmd_pending(struct mlx4_dev *dev)
+static int cmd_pending(struct mlx4_dev *dev, u32 *p_status)
{
- u32 status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET);
+ *p_status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET);
- return (status & swab32(1 << HCR_GO_BIT)) ||
+ return (*p_status & swab32(1 << HCR_GO_BIT)) ||
(mlx4_priv(dev)->cmd.toggle ==
- !!(status & swab32(1 << HCR_T_BIT)));
+ !!(*p_status & swab32(1 << HCR_T_BIT)));
}
static int mlx4_cmd_post(struct mlx4_dev *dev, u64 in_param, u64 out_param,
u32 __iomem *hcr = (u32 __iomem *)cmd->hcr;
int ret = -EAGAIN;
u64 end;
+ u32 hcr_status;
mutex_lock(&cmd->hcr_mutex);
if (event)
end += msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS);
- while (cmd_pending(dev)) {
- if (time_after_eq(jiffies, end))
+ while (cmd_pending(dev, &hcr_status)) {
+ if (time_after_eq(jiffies, end)) {
+ mlx4_err(dev, "Failed to post command %02x during %d msecs, hcr_status %#x, toggle %#x\n",
+ op, GO_BIT_TIMEOUT_MSECS, hcr_status, mlx4_priv(dev)->cmd.toggle );
goto out;
+ }
cond_resched();
}
u8 __iomem *hcr = priv->cmd.hcr;
int err = 0;
u64 end;
- u8 status;
+ u8 status = 0xff; /* means "unknown" */
long do_reset;
+ u32 hcr_status;
down(&priv->cmd.poll_sem);
goto out;
end = msecs_to_jiffies(timeout) + jiffies;
- while (cmd_pending(dev) && time_before(jiffies, end))
+ while (cmd_pending(dev, &hcr_status) && time_before(jiffies, end))
cond_resched();
- if (cmd_pending(dev)) {
+ if (cmd_pending(dev, &hcr_status)) {
err = -ETIMEDOUT;
- mlx4_err(dev, "mlx4_cmd_poll: Command %02x completed with timeout after %d msecs \n",
- op, timeout);
+ mlx4_err(dev, "mlx4_cmd_poll: Command %02x: timeout after %d msecs, hcr_status %#x, toggle %#x \n",
+ op, timeout, hcr_status, mlx4_priv(dev)->cmd.toggle);
do_reset = InterlockedCompareExchange(&dev->reset_pending, 1, 0);
if (!do_reset) {
status = (u8)(be32_to_cpu((__force __be32)__raw_readl(hcr + HCR_STATUS_OFFSET)) >> 24);
err = mlx4_status_to_errno(status);
- if (status && status != 0x50)
- mlx4_err(dev, "Command failed: op %#hx, status %#02x, errno %d.\n",
- op, status, err);
out:
+ if (status && status != 0x50)
+ mlx4_err(dev, "mlx4_cmd_poll: Command failed: op %#hx, status %#02x, errno %d.\n",
+ op, status, err);
up(&priv->cmd.poll_sem);
return err;
}
&priv->cmd.context[token & priv->cmd.token_mask];
/* previously timed out command completing at long last */
- if (token != context->token)
+ if (token != context->token) {
+ mlx4_err(dev, "mlx4_cmd_event: Command skipped: token %#hx, ctx_token %#hx\n",
+ token, context->token);
return;
+ }
context->result = mlx4_status_to_errno(status);
-
- if (status)
- mlx4_err(dev, "Command failed: token %#hx, status %#02x, errno %d.\n",
- token, status, context->result);
+ context->status = status;
context->out_param = out_param;
complete(&context->done);
int err = 0;
u64 out_prm = out_param ? *out_param : 0;
long do_reset;
+ u8 status = 0xff; /* means "unknown" */
down(&cmd->event_sem);
if ( dev->flags & MLX4_FLAG_RESET_DRIVER ) {
init_completion(&context->done);
- mlx4_cmd_post(dev, in_param, out_prm,
+ err = mlx4_cmd_post(dev, in_param, out_prm,
in_modifier, op_modifier, op, context->token, 1);
+ if (err)
+ goto out;
if (wait_for_completion_timeout(&context->done, msecs_to_jiffies(timeout))) {
if (!context->done.done) {
}
else {
err = -EFAULT;
- mlx4_err(dev, "mlx4_cmd_wait: Unexpected end of waiting for a comand \n");
+ mlx4_err(dev, "mlx4_cmd_wait: Unexpected end of waiting for a command \n");
ASSERT(0);
}
}
- else
+ else {
err = context->result;
+ status = context->status;
+ }
if (err)
goto out;
context->next = cmd->free_head;
cmd->free_head = (int)(context - cmd->context);
spin_unlock(&cmd->context_lock);
+ if (status && status != 0x50)
+ mlx4_err(dev, "mlx4_cmd_wait: Command failed: op %#hx, status %#02x, errno %d, token %#hx.\n",
+ op, status, err, context->token);
exit:
up(&cmd->event_sem);