mtip32xx: Handle FTL rebuild failure state during device initialization
authorAsai Thambi SP <asamymuthupa@micron.com>
Thu, 25 Feb 2016 05:18:20 +0000 (21:18 -0800)
committerJens Axboe <axboe@fb.com>
Thu, 3 Mar 2016 16:08:43 +0000 (09:08 -0700)
Allow device initialization to finish gracefully when it is in
FTL rebuild failure state. Also, recover device out of this state
after successfully secure erasing it.

Signed-off-by: Selvan Mani <smani@micron.com>
Signed-off-by: Vignesh Gunasekaran <vgunasekaran@micron.com>
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/block/mtip32xx/mtip32xx.c

index 6268ea0..a64da08 100644 (file)
@@ -699,7 +699,7 @@ static void mtip_handle_tfe(struct driver_data *dd)
                        fail_reason = "thermal shutdown";
                }
                if (buf[288] == 0xBF) {
-                       set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag);
+                       set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
                        dev_info(&dd->pdev->dev,
                                "Drive indicates rebuild has failed. Secure erase required.\n");
                        fail_all_ncq_cmds = 1;
@@ -1000,6 +1000,7 @@ static bool mtip_pause_ncq(struct mtip_port *port,
                        (fis->features == 0x27 || fis->features == 0x72 ||
                         fis->features == 0x62 || fis->features == 0x26))) {
                clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
+               clear_bit(MTIP_DDF_REBUILD_FAILED_BIT, &port->dd->dd_flag);
                /* Com reset after secure erase or lowlevel format */
                mtip_restart_port(port);
                clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
@@ -1166,6 +1167,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                if ((rv = wait_for_completion_interruptible_timeout(
                                &wait,
                                msecs_to_jiffies(timeout))) <= 0) {
+
                        if (rv == -ERESTARTSYS) { /* interrupted */
                                dev_err(&dd->pdev->dev,
                                        "Internal command [%02X] was interrupted after %u ms\n",
@@ -3084,7 +3086,7 @@ static int mtip_hw_get_identify(struct driver_data *dd)
                if (buf[288] == 0xBF) {
                        dev_info(&dd->pdev->dev,
                                "Drive indicates rebuild has failed.\n");
-                       /* TODO */
+                       set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag);
                }
        }
 
@@ -3687,10 +3689,9 @@ static int mtip_submit_request(struct blk_mq_hw_ctx *hctx, struct request *rq)
                                rq_data_dir(rq))) {
                        return -ENODATA;
                }
-               if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)))
+               if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag) ||
+                       test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)))
                        return -ENODATA;
-               if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag))
-                       return -ENXIO;
        }
 
        if (rq->cmd_flags & REQ_DISCARD) {