diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2012-05-29 21:42:27 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-05-31 02:36:55 -0400 |
commit | d02e1f0ad098b3b36853d639e9befeb273c63cc5 (patch) | |
tree | df509f0f4c8c24807df9973fd12db5c3ef13823f /drivers/block | |
parent | 971890f25834e1e81ccb97b9413d0c2852d49208 (diff) |
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>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 73d7caa3cae1..4e7275cb67b0 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -781,13 +781,24 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
781 | 781 | ||
782 | /* Stop the timer to prevent command timeouts. */ | 782 | /* Stop the timer to prevent command timeouts. */ |
783 | del_timer(&port->cmd_timer); | 783 | del_timer(&port->cmd_timer); |
784 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
785 | |||
786 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && | ||
787 | test_bit(MTIP_TAG_INTERNAL, port->allocated)) { | ||
788 | cmd = &port->commands[MTIP_TAG_INTERNAL]; | ||
789 | dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); | ||
790 | |||
791 | atomic_inc(&cmd->active); /* active > 1 indicates error */ | ||
792 | if (cmd->comp_data && cmd->comp_func) { | ||
793 | cmd->comp_func(port, MTIP_TAG_INTERNAL, | ||
794 | cmd->comp_data, PORT_IRQ_TF_ERR); | ||
795 | } | ||
796 | goto handle_tfe_exit; | ||
797 | } | ||
784 | 798 | ||
785 | /* clear the tag accumulator */ | 799 | /* clear the tag accumulator */ |
786 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); | 800 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); |
787 | 801 | ||
788 | /* Set eh_active */ | ||
789 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
790 | |||
791 | /* Loop through all the groups */ | 802 | /* Loop through all the groups */ |
792 | for (group = 0; group < dd->slot_groups; group++) { | 803 | for (group = 0; group < dd->slot_groups; group++) { |
793 | completed = readl(port->completed[group]); | 804 | completed = readl(port->completed[group]); |
@@ -939,6 +950,7 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
939 | } | 950 | } |
940 | print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); | 951 | print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); |
941 | 952 | ||
953 | handle_tfe_exit: | ||
942 | /* clear eh_active */ | 954 | /* clear eh_active */ |
943 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 955 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
944 | wake_up_interruptible(&port->svc_wait); | 956 | wake_up_interruptible(&port->svc_wait); |
@@ -1328,22 +1340,6 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1328 | } | 1340 | } |
1329 | rv = -EAGAIN; | 1341 | rv = -EAGAIN; |
1330 | } | 1342 | } |
1331 | |||
1332 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | ||
1333 | & (1 << MTIP_TAG_INTERNAL)) { | ||
1334 | dev_warn(&port->dd->pdev->dev, | ||
1335 | "Retiring internal command but CI is 1.\n"); | ||
1336 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | ||
1337 | &port->dd->dd_flag)) { | ||
1338 | hba_reset_nosleep(port->dd); | ||
1339 | rv = -ENXIO; | ||
1340 | } else { | ||
1341 | mtip_restart_port(port); | ||
1342 | rv = -EAGAIN; | ||
1343 | } | ||
1344 | goto exec_ic_exit; | ||
1345 | } | ||
1346 | |||
1347 | } else { | 1343 | } else { |
1348 | /* Spin for <timeout> checking if command still outstanding */ | 1344 | /* Spin for <timeout> checking if command still outstanding */ |
1349 | timeout = jiffies + msecs_to_jiffies(timeout); | 1345 | timeout = jiffies + msecs_to_jiffies(timeout); |
@@ -1360,21 +1356,25 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1360 | rv = -ENXIO; | 1356 | rv = -ENXIO; |
1361 | goto exec_ic_exit; | 1357 | goto exec_ic_exit; |
1362 | } | 1358 | } |
1359 | if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) { | ||
1360 | atomic_inc(&int_cmd->active); /* error */ | ||
1361 | break; | ||
1362 | } | ||
1363 | } | 1363 | } |
1364 | } | ||
1364 | 1365 | ||
1365 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | 1366 | if (atomic_read(&int_cmd->active) > 1) { |
1367 | dev_err(&port->dd->pdev->dev, | ||
1368 | "Internal command [%02X] failed\n", fis->command); | ||
1369 | rv = -EIO; | ||
1370 | } | ||
1371 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | ||
1366 | & (1 << MTIP_TAG_INTERNAL)) { | 1372 | & (1 << MTIP_TAG_INTERNAL)) { |
1367 | dev_err(&port->dd->pdev->dev, | 1373 | rv = -ENXIO; |
1368 | "Internal command did not complete [atomic]\n"); | 1374 | if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, |
1375 | &port->dd->dd_flag)) { | ||
1376 | mtip_restart_port(port); | ||
1369 | rv = -EAGAIN; | 1377 | rv = -EAGAIN; |
1370 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | ||
1371 | &port->dd->dd_flag)) { | ||
1372 | hba_reset_nosleep(port->dd); | ||
1373 | rv = -ENXIO; | ||
1374 | } else { | ||
1375 | mtip_restart_port(port); | ||
1376 | rv = -EAGAIN; | ||
1377 | } | ||
1378 | } | 1378 | } |
1379 | } | 1379 | } |
1380 | exec_ic_exit: | 1380 | exec_ic_exit: |