diff options
-rw-r--r-- | drivers/scsi/scsi_error.c | 46 |
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 | **/ |
1584 | int scsi_error_handler(void *data) | 1581 | int 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 | } |