diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index a5d630f5f519..2bf98469dc4c 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -307,6 +307,19 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
307 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) | 307 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) |
308 | return FAILED; | 308 | return FAILED; |
309 | 309 | ||
310 | if (sshdr.asc == 0x3f && sshdr.ascq == 0x0e) | ||
311 | scmd_printk(KERN_WARNING, scmd, | ||
312 | "Warning! Received an indication that the " | ||
313 | "LUN assignments on this target have " | ||
314 | "changed. The Linux SCSI layer does not " | ||
315 | "automatically remap LUN assignments.\n"); | ||
316 | else if (sshdr.asc == 0x3f) | ||
317 | scmd_printk(KERN_WARNING, scmd, | ||
318 | "Warning! Received an indication that the " | ||
319 | "operating parameters on this target have " | ||
320 | "changed. The Linux SCSI layer does not " | ||
321 | "automatically adjust these parameters.\n"); | ||
322 | |||
310 | if (blk_barrier_rq(scmd->request)) | 323 | if (blk_barrier_rq(scmd->request)) |
311 | /* | 324 | /* |
312 | * barrier requests should always retry on UA | 325 | * barrier requests should always retry on UA |
@@ -1762,6 +1775,14 @@ int scsi_error_handler(void *data) | |||
1762 | * what we need to do to get it up and online again (if we can). | 1775 | * what we need to do to get it up and online again (if we can). |
1763 | * If we fail, we end up taking the thing offline. | 1776 | * If we fail, we end up taking the thing offline. |
1764 | */ | 1777 | */ |
1778 | if (scsi_autopm_get_host(shost) != 0) { | ||
1779 | SCSI_LOG_ERROR_RECOVERY(1, | ||
1780 | printk(KERN_ERR "Error handler scsi_eh_%d " | ||
1781 | "unable to autoresume\n", | ||
1782 | shost->host_no)); | ||
1783 | continue; | ||
1784 | } | ||
1785 | |||
1765 | if (shost->transportt->eh_strategy_handler) | 1786 | if (shost->transportt->eh_strategy_handler) |
1766 | shost->transportt->eh_strategy_handler(shost); | 1787 | shost->transportt->eh_strategy_handler(shost); |
1767 | else | 1788 | else |
@@ -1775,6 +1796,7 @@ int scsi_error_handler(void *data) | |||
1775 | * which are still online. | 1796 | * which are still online. |
1776 | */ | 1797 | */ |
1777 | scsi_restart_operations(shost); | 1798 | scsi_restart_operations(shost); |
1799 | scsi_autopm_put_host(shost); | ||
1778 | set_current_state(TASK_INTERRUPTIBLE); | 1800 | set_current_state(TASK_INTERRUPTIBLE); |
1779 | } | 1801 | } |
1780 | __set_current_state(TASK_RUNNING); | 1802 | __set_current_state(TASK_RUNNING); |
@@ -1872,12 +1894,16 @@ scsi_reset_provider_done_command(struct scsi_cmnd *scmd) | |||
1872 | int | 1894 | int |
1873 | scsi_reset_provider(struct scsi_device *dev, int flag) | 1895 | scsi_reset_provider(struct scsi_device *dev, int flag) |
1874 | { | 1896 | { |
1875 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); | 1897 | struct scsi_cmnd *scmd; |
1876 | struct Scsi_Host *shost = dev->host; | 1898 | struct Scsi_Host *shost = dev->host; |
1877 | struct request req; | 1899 | struct request req; |
1878 | unsigned long flags; | 1900 | unsigned long flags; |
1879 | int rtn; | 1901 | int rtn; |
1880 | 1902 | ||
1903 | if (scsi_autopm_get_host(shost) < 0) | ||
1904 | return FAILED; | ||
1905 | |||
1906 | scmd = scsi_get_command(dev, GFP_KERNEL); | ||
1881 | blk_rq_init(NULL, &req); | 1907 | blk_rq_init(NULL, &req); |
1882 | scmd->request = &req; | 1908 | scmd->request = &req; |
1883 | 1909 | ||
@@ -1934,6 +1960,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1934 | scsi_run_host_queues(shost); | 1960 | scsi_run_host_queues(shost); |
1935 | 1961 | ||
1936 | scsi_next_command(scmd); | 1962 | scsi_next_command(scmd); |
1963 | scsi_autopm_put_host(shost); | ||
1937 | return rtn; | 1964 | return rtn; |
1938 | } | 1965 | } |
1939 | EXPORT_SYMBOL(scsi_reset_provider); | 1966 | EXPORT_SYMBOL(scsi_reset_provider); |