schedule_work(&cmd->se_dev->qf_work_queue);
 }
 
+static bool target_check_read_strip(struct se_cmd *cmd)
+{
+       sense_reason_t rc;
+
+       if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) {
+               rc = sbc_dif_read_strip(cmd);
+               if (rc) {
+                       cmd->pi_err = rc;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static void target_complete_ok_work(struct work_struct *work)
 {
        struct se_cmd *cmd = container_of(work, struct se_cmd, work);
                                        cmd->data_length;
                }
                spin_unlock(&cmd->se_lun->lun_sep_lock);
+               /*
+                * Perform READ_STRIP of PI using software emulation when
+                * backend had PI enabled, if the transport will not be
+                * performing hardware READ_STRIP offload.
+                */
+               if (cmd->prot_op == TARGET_PROT_DIN_STRIP &&
+                   target_check_read_strip(cmd)) {
+                       ret = transport_send_check_condition_and_sense(cmd,
+                                               cmd->pi_err, 0);
+                       if (ret == -EAGAIN || ret == -ENOMEM)
+                               goto queue_full;
+
+                       transport_lun_remove_cmd(cmd);
+                       transport_cmd_check_stop_to_fabric(cmd);
+                       return;
+               }
 
                trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_data_in(cmd);