return ++cmd->retries <= cmd->allowed;
 }
 
+static bool scsi_eh_should_retry_cmd(struct scsi_cmnd *cmd)
+{
+       struct scsi_device *sdev = cmd->device;
+       struct Scsi_Host *host = sdev->host;
+
+       if (host->hostt->eh_should_retry_cmd)
+               return  host->hostt->eh_should_retry_cmd(cmd);
+
+       return true;
+}
+
 /**
  * scmd_eh_abort_handler - Handle command aborts
  * @work:      command to be aborted.
                                                    "eh timeout, not retrying "
                                                    "aborted command\n"));
                        } else if (!scsi_noretry_cmd(scmd) &&
-                                  scsi_cmd_retry_allowed(scmd)) {
+                                  scsi_cmd_retry_allowed(scmd) &&
+                               scsi_eh_should_retry_cmd(scmd)) {
                                SCSI_LOG_ERROR_RECOVERY(3,
                                        scmd_printk(KERN_WARNING, scmd,
                                                    "retry aborted command\n"));
        list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
                list_del_init(&scmd->eh_entry);
                if (scsi_device_online(scmd->device) &&
-                   !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd)) {
+                   !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) &&
+                       scsi_eh_should_retry_cmd(scmd)) {
                        SCSI_LOG_ERROR_RECOVERY(3,
                                scmd_printk(KERN_INFO, scmd,
                                             "%s: flush retry cmd\n",
 
         * Status: OPTIONAL
         */
        enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
+       /*
+        * Optional routine that allows the transport to decide if a cmd
+        * is retryable. Return true if the transport is in a state the
+        * cmd should be retried on.
+        */
+       bool (*eh_should_retry_cmd)(struct scsi_cmnd *scmd);
 
        /* This is an optional routine that allows transport to initiate
         * LLD adapter or firmware reset using sysfs attribute.