mtip32xx: Fix to handle TFE for PIO(IOCTL/internal) commands
authorAsai Thambi S P <asamymuthupa@micron.com>
Wed, 30 May 2012 01:42:27 +0000 (18:42 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 31 May 2012 06:36:55 +0000 (08:36 +0200)
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>
drivers/block/mtip32xx/mtip32xx.c

index 73d7caa3cae114520532d2cf4441ca10fb0fcf13..4e7275cb67b08767278c89bdf8232b4c5692cf6a 100644 (file)
@@ -781,13 +781,24 @@ static void mtip_handle_tfe(struct driver_data *dd)
 
        /* Stop the timer to prevent command timeouts. */
        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 */
        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 */
        for (group = 0; group < dd->slot_groups; 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);
 
+handle_tfe_exit:
        /* clear eh_active */
        clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
        wake_up_interruptible(&port->svc_wait);
@@ -1328,22 +1340,6 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                        }
                        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 {
                /* Spin for <timeout> checking if command still outstanding */
                timeout = jiffies + msecs_to_jiffies(timeout);
@@ -1360,21 +1356,25 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
+                       if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) {
+                               atomic_inc(&int_cmd->active); /* error */
+                               break;
+                       }
                }
+       }
 
-               if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
+       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])
                        & (1 << MTIP_TAG_INTERNAL)) {
-                       dev_err(&port->dd->pdev->dev,
-                               "Internal command did not complete [atomic]\n");
+               rv = -ENXIO;
+               if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                                       &port->dd->dd_flag)) {
+                       mtip_restart_port(port);
                        rv = -EAGAIN;
-                       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;
-                       }
                }
        }
 exec_ic_exit: