aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 0fc8b48f052b..895c9452be4c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -20,6 +20,7 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/kthread.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/blkdev.h> 25#include <linux/blkdev.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
@@ -75,7 +76,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
75 76
76 scmd->eh_eflags |= eh_flag; 77 scmd->eh_eflags |= eh_flag;
77 list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); 78 list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
78 set_bit(SHOST_RECOVERY, &shost->shost_state); 79 scsi_host_set_state(shost, SHOST_RECOVERY);
79 shost->host_failed++; 80 shost->host_failed++;
80 scsi_eh_wakeup(shost); 81 scsi_eh_wakeup(shost);
81 spin_unlock_irqrestore(shost->host_lock, flags); 82 spin_unlock_irqrestore(shost->host_lock, flags);
@@ -115,7 +116,6 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
115 116
116 add_timer(&scmd->eh_timeout); 117 add_timer(&scmd->eh_timeout);
117} 118}
118EXPORT_SYMBOL(scsi_add_timer);
119 119
120/** 120/**
121 * scsi_delete_timer - Delete/cancel timer for a given function. 121 * scsi_delete_timer - Delete/cancel timer for a given function.
@@ -143,7 +143,6 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
143 143
144 return rtn; 144 return rtn;
145} 145}
146EXPORT_SYMBOL(scsi_delete_timer);
147 146
148/** 147/**
149 * scsi_times_out - Timeout function for normal scsi commands. 148 * scsi_times_out - Timeout function for normal scsi commands.
@@ -197,7 +196,8 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
197{ 196{
198 int online; 197 int online;
199 198
200 wait_event(sdev->host->host_wait, (!test_bit(SHOST_RECOVERY, &sdev->host->shost_state))); 199 wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
200 SHOST_RECOVERY));
201 201
202 online = scsi_device_online(sdev); 202 online = scsi_device_online(sdev);
203 203
@@ -775,9 +775,11 @@ retry_tur:
775 __FUNCTION__, scmd, rtn)); 775 __FUNCTION__, scmd, rtn));
776 if (rtn == SUCCESS) 776 if (rtn == SUCCESS)
777 return 0; 777 return 0;
778 else if (rtn == NEEDS_RETRY) 778 else if (rtn == NEEDS_RETRY) {
779 if (retry_cnt--) 779 if (retry_cnt--)
780 goto retry_tur; 780 goto retry_tur;
781 return 0;
782 }
781 return 1; 783 return 1;
782} 784}
783 785
@@ -1458,7 +1460,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
1458 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", 1460 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
1459 __FUNCTION__)); 1461 __FUNCTION__));
1460 1462
1461 clear_bit(SHOST_RECOVERY, &shost->shost_state); 1463 scsi_host_set_state(shost, SHOST_RUNNING);
1462 1464
1463 wake_up(&shost->host_wait); 1465 wake_up(&shost->host_wait);
1464 1466
@@ -1582,16 +1584,8 @@ int scsi_error_handler(void *data)
1582 int rtn; 1584 int rtn;
1583 DECLARE_MUTEX_LOCKED(sem); 1585 DECLARE_MUTEX_LOCKED(sem);
1584 1586
1585 /*
1586 * Flush resources
1587 */
1588
1589 daemonize("scsi_eh_%d", shost->host_no);
1590
1591 current->flags |= PF_NOFREEZE; 1587 current->flags |= PF_NOFREEZE;
1592
1593 shost->eh_wait = &sem; 1588 shost->eh_wait = &sem;
1594 shost->ehandler = current;
1595 1589
1596 /* 1590 /*
1597 * Wake up the thread that created us. 1591 * Wake up the thread that created us.
@@ -1599,8 +1593,6 @@ int scsi_error_handler(void *data)
1599 SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of" 1593 SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
1600 " scsi_eh_%d\n",shost->host_no)); 1594 " scsi_eh_%d\n",shost->host_no));
1601 1595
1602 complete(shost->eh_notify);
1603
1604 while (1) { 1596 while (1) {
1605 /* 1597 /*
1606 * If we get a signal, it means we are supposed to go 1598 * If we get a signal, it means we are supposed to go
@@ -1621,7 +1613,7 @@ int scsi_error_handler(void *data)
1621 * semaphores isn't unreasonable. 1613 * semaphores isn't unreasonable.
1622 */ 1614 */
1623 down_interruptible(&sem); 1615 down_interruptible(&sem);
1624 if (shost->eh_kill) 1616 if (kthread_should_stop())
1625 break; 1617 break;
1626 1618
1627 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" 1619 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
@@ -1660,22 +1652,6 @@ int scsi_error_handler(void *data)
1660 * Make sure that nobody tries to wake us up again. 1652 * Make sure that nobody tries to wake us up again.
1661 */ 1653 */
1662 shost->eh_wait = NULL; 1654 shost->eh_wait = NULL;
1663
1664 /*
1665 * Knock this down too. From this point on, the host is flying
1666 * without a pilot. If this is because the module is being unloaded,
1667 * that's fine. If the user sent a signal to this thing, we are
1668 * potentially in real danger.
1669 */
1670 shost->eh_active = 0;
1671 shost->ehandler = NULL;
1672
1673 /*
1674 * If anyone is waiting for us to exit (i.e. someone trying to unload
1675 * a driver), then wake up that process to let them know we are on
1676 * the way out the door.
1677 */
1678 complete_and_exit(shost->eh_notify, 0);
1679 return 0; 1655 return 0;
1680} 1656}
1681 1657
@@ -1846,12 +1822,16 @@ EXPORT_SYMBOL(scsi_reset_provider);
1846int scsi_normalize_sense(const u8 *sense_buffer, int sb_len, 1822int scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
1847 struct scsi_sense_hdr *sshdr) 1823 struct scsi_sense_hdr *sshdr)
1848{ 1824{
1849 if (!sense_buffer || !sb_len || (sense_buffer[0] & 0x70) != 0x70) 1825 if (!sense_buffer || !sb_len)
1850 return 0; 1826 return 0;
1851 1827
1852 memset(sshdr, 0, sizeof(struct scsi_sense_hdr)); 1828 memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
1853 1829
1854 sshdr->response_code = (sense_buffer[0] & 0x7f); 1830 sshdr->response_code = (sense_buffer[0] & 0x7f);
1831
1832 if (!scsi_sense_valid(sshdr))
1833 return 0;
1834
1855 if (sshdr->response_code >= 0x72) { 1835 if (sshdr->response_code >= 0x72) {
1856 /* 1836 /*
1857 * descriptor format 1837 * descriptor format