aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_error.c46
1 files changed, 17 insertions, 29 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 0c5b02d4c7f8..56353e878130 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1571,48 +1571,41 @@ static void scsi_unjam_host(struct Scsi_Host *shost)
1571} 1571}
1572 1572
1573/** 1573/**
1574 * scsi_error_handler - Handle errors/timeouts of SCSI cmds. 1574 * scsi_error_handler - SCSI error handler thread
1575 * @data: Host for which we are running. 1575 * @data: Host for which we are running.
1576 * 1576 *
1577 * Notes: 1577 * Notes:
1578 * This is always run in the context of a kernel thread. The idea is 1578 * This is the main error handling loop. This is run as a kernel thread
1579 * that we start this thing up when the kernel starts up (one per host 1579 * for every SCSI host and handles all error handling activity.
1580 * that we detect), and it immediately goes to sleep and waits for some
1581 * event (i.e. failure). When this takes place, we have the job of
1582 * trying to unjam the bus and restarting things.
1583 **/ 1580 **/
1584int scsi_error_handler(void *data) 1581int scsi_error_handler(void *data)
1585{ 1582{
1586 struct Scsi_Host *shost = (struct Scsi_Host *) data; 1583 struct Scsi_Host *shost = data;
1587 int rtn;
1588 1584
1589 current->flags |= PF_NOFREEZE; 1585 current->flags |= PF_NOFREEZE;
1590 1586
1591
1592 /* 1587 /*
1593 * Note - we always use TASK_INTERRUPTIBLE even if the module 1588 * We use TASK_INTERRUPTIBLE so that the thread is not
1594 * was loaded as part of the kernel. The reason is that 1589 * counted against the load average as a running process.
1595 * UNINTERRUPTIBLE would cause this thread to be counted in 1590 * We never actually get interrupted because kthread_run
1596 * the load average as a running process, and an interruptible 1591 * disables singal delivery for the created thread.
1597 * wait doesn't.
1598 */ 1592 */
1599 set_current_state(TASK_INTERRUPTIBLE); 1593 set_current_state(TASK_INTERRUPTIBLE);
1600 while (!kthread_should_stop()) { 1594 while (!kthread_should_stop()) {
1601 if (shost->host_failed == 0 || 1595 if (shost->host_failed == 0 ||
1602 shost->host_failed != shost->host_busy) { 1596 shost->host_failed != shost->host_busy) {
1603 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" 1597 SCSI_LOG_ERROR_RECOVERY(1,
1604 " scsi_eh_%d" 1598 printk("Error handler scsi_eh_%d sleeping\n",
1605 " sleeping\n", 1599 shost->host_no));
1606 shost->host_no));
1607 schedule(); 1600 schedule();
1608 set_current_state(TASK_INTERRUPTIBLE); 1601 set_current_state(TASK_INTERRUPTIBLE);
1609 continue; 1602 continue;
1610 } 1603 }
1611 1604
1612 __set_current_state(TASK_RUNNING); 1605 __set_current_state(TASK_RUNNING);
1613 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" 1606 SCSI_LOG_ERROR_RECOVERY(1,
1614 " scsi_eh_%d waking" 1607 printk("Error handler scsi_eh_%d waking up\n",
1615 " up\n",shost->host_no)); 1608 shost->host_no));
1616 1609
1617 shost->eh_active = 1; 1610 shost->eh_active = 1;
1618 1611
@@ -1622,7 +1615,7 @@ int scsi_error_handler(void *data)
1622 * If we fail, we end up taking the thing offline. 1615 * If we fail, we end up taking the thing offline.
1623 */ 1616 */
1624 if (shost->hostt->eh_strategy_handler) 1617 if (shost->hostt->eh_strategy_handler)
1625 rtn = shost->hostt->eh_strategy_handler(shost); 1618 shost->hostt->eh_strategy_handler(shost);
1626 else 1619 else
1627 scsi_unjam_host(shost); 1620 scsi_unjam_host(shost);
1628 1621
@@ -1638,15 +1631,10 @@ int scsi_error_handler(void *data)
1638 scsi_restart_operations(shost); 1631 scsi_restart_operations(shost);
1639 set_current_state(TASK_INTERRUPTIBLE); 1632 set_current_state(TASK_INTERRUPTIBLE);
1640 } 1633 }
1641
1642 __set_current_state(TASK_RUNNING); 1634 __set_current_state(TASK_RUNNING);
1643 1635
1644 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d" 1636 SCSI_LOG_ERROR_RECOVERY(1,
1645 " exiting\n",shost->host_no)); 1637 printk("Error handler scsi_eh_%d exiting\n", shost->host_no));
1646
1647 /*
1648 * Make sure that nobody tries to wake us up again.
1649 */
1650 shost->ehandler = NULL; 1638 shost->ehandler = NULL;
1651 return 0; 1639 return 0;
1652} 1640}