mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-13 14:14:37 +00:00
mtip32xx: Fix to handle TFE for PIO(IOCTL/internal) commands
If a PIO (IOCTL/internal) command resulted in TFE, signal the wait event or break out of polling. Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
971890f258
commit
d02e1f0ad0
1 changed files with 33 additions and 33 deletions
|
@ -781,13 +781,24 @@ static void mtip_handle_tfe(struct driver_data *dd)
|
||||||
|
|
||||||
/* Stop the timer to prevent command timeouts. */
|
/* Stop the timer to prevent command timeouts. */
|
||||||
del_timer(&port->cmd_timer);
|
del_timer(&port->cmd_timer);
|
||||||
|
set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
|
||||||
|
|
||||||
|
if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) &&
|
||||||
|
test_bit(MTIP_TAG_INTERNAL, port->allocated)) {
|
||||||
|
cmd = &port->commands[MTIP_TAG_INTERNAL];
|
||||||
|
dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n");
|
||||||
|
|
||||||
|
atomic_inc(&cmd->active); /* active > 1 indicates error */
|
||||||
|
if (cmd->comp_data && cmd->comp_func) {
|
||||||
|
cmd->comp_func(port, MTIP_TAG_INTERNAL,
|
||||||
|
cmd->comp_data, PORT_IRQ_TF_ERR);
|
||||||
|
}
|
||||||
|
goto handle_tfe_exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* clear the tag accumulator */
|
/* clear the tag accumulator */
|
||||||
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
|
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
|
||||||
|
|
||||||
/* Set eh_active */
|
|
||||||
set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
|
|
||||||
|
|
||||||
/* Loop through all the groups */
|
/* Loop through all the groups */
|
||||||
for (group = 0; group < dd->slot_groups; group++) {
|
for (group = 0; group < dd->slot_groups; group++) {
|
||||||
completed = readl(port->completed[group]);
|
completed = readl(port->completed[group]);
|
||||||
|
@ -939,6 +950,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
|
||||||
}
|
}
|
||||||
print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
|
print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
|
||||||
|
|
||||||
|
handle_tfe_exit:
|
||||||
/* clear eh_active */
|
/* clear eh_active */
|
||||||
clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
|
clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
|
||||||
wake_up_interruptible(&port->svc_wait);
|
wake_up_interruptible(&port->svc_wait);
|
||||||
|
@ -1328,22 +1340,6 @@ static int mtip_exec_internal_command(struct mtip_port *port,
|
||||||
}
|
}
|
||||||
rv = -EAGAIN;
|
rv = -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
|
|
||||||
& (1 << MTIP_TAG_INTERNAL)) {
|
|
||||||
dev_warn(&port->dd->pdev->dev,
|
|
||||||
"Retiring internal command but CI is 1.\n");
|
|
||||||
if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
|
|
||||||
&port->dd->dd_flag)) {
|
|
||||||
hba_reset_nosleep(port->dd);
|
|
||||||
rv = -ENXIO;
|
|
||||||
} else {
|
|
||||||
mtip_restart_port(port);
|
|
||||||
rv = -EAGAIN;
|
|
||||||
}
|
|
||||||
goto exec_ic_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Spin for <timeout> checking if command still outstanding */
|
/* Spin for <timeout> checking if command still outstanding */
|
||||||
timeout = jiffies + msecs_to_jiffies(timeout);
|
timeout = jiffies + msecs_to_jiffies(timeout);
|
||||||
|
@ -1360,23 +1356,27 @@ static int mtip_exec_internal_command(struct mtip_port *port,
|
||||||
rv = -ENXIO;
|
rv = -ENXIO;
|
||||||
goto exec_ic_exit;
|
goto exec_ic_exit;
|
||||||
}
|
}
|
||||||
|
if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) {
|
||||||
|
atomic_inc(&int_cmd->active); /* error */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (atomic_read(&int_cmd->active) > 1) {
|
||||||
|
dev_err(&port->dd->pdev->dev,
|
||||||
|
"Internal command [%02X] failed\n", fis->command);
|
||||||
|
rv = -EIO;
|
||||||
|
}
|
||||||
if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
|
if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
|
||||||
& (1 << MTIP_TAG_INTERNAL)) {
|
& (1 << MTIP_TAG_INTERNAL)) {
|
||||||
dev_err(&port->dd->pdev->dev,
|
|
||||||
"Internal command did not complete [atomic]\n");
|
|
||||||
rv = -EAGAIN;
|
|
||||||
if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
|
|
||||||
&port->dd->dd_flag)) {
|
|
||||||
hba_reset_nosleep(port->dd);
|
|
||||||
rv = -ENXIO;
|
rv = -ENXIO;
|
||||||
} else {
|
if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
|
||||||
|
&port->dd->dd_flag)) {
|
||||||
mtip_restart_port(port);
|
mtip_restart_port(port);
|
||||||
rv = -EAGAIN;
|
rv = -EAGAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
exec_ic_exit:
|
exec_ic_exit:
|
||||||
/* Clear the allocated and active bits for the internal command. */
|
/* Clear the allocated and active bits for the internal command. */
|
||||||
atomic_set(&int_cmd->active, 0);
|
atomic_set(&int_cmd->active, 0);
|
||||||
|
|
Loading…
Reference in a new issue