aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c89
1 files changed, 30 insertions, 59 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9f91f1a20542..43ca0d8ca384 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -8,8 +8,8 @@
8 8
9#include <linux/moduleparam.h> 9#include <linux/moduleparam.h>
10#include <linux/vmalloc.h> 10#include <linux/vmalloc.h>
11#include <linux/smp_lock.h>
12#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/kthread.h>
13 13
14#include <scsi/scsi_tcq.h> 14#include <scsi/scsi_tcq.h>
15#include <scsi/scsicam.h> 15#include <scsi/scsicam.h>
@@ -1307,8 +1307,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1307 ha->brd_info = brd_info; 1307 ha->brd_info = brd_info;
1308 sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); 1308 sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
1309 1309
1310 ha->dpc_pid = -1;
1311
1312 /* Configure PCI I/O space */ 1310 /* Configure PCI I/O space */
1313 ret = qla2x00_iospace_config(ha); 1311 ret = qla2x00_iospace_config(ha);
1314 if (ret) 1312 if (ret)
@@ -1449,9 +1447,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1449 */ 1447 */
1450 spin_lock_init(&ha->mbx_reg_lock); 1448 spin_lock_init(&ha->mbx_reg_lock);
1451 1449
1452 init_completion(&ha->dpc_inited);
1453 init_completion(&ha->dpc_exited);
1454
1455 qla2x00_config_dma_addressing(ha); 1450 qla2x00_config_dma_addressing(ha);
1456 if (qla2x00_mem_alloc(ha)) { 1451 if (qla2x00_mem_alloc(ha)) {
1457 qla_printk(KERN_WARNING, ha, 1452 qla_printk(KERN_WARNING, ha,
@@ -1478,16 +1473,14 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1478 /* 1473 /*
1479 * Startup the kernel thread for this host adapter 1474 * Startup the kernel thread for this host adapter
1480 */ 1475 */
1481 ha->dpc_should_die = 0; 1476 ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
1482 ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0); 1477 "%s_dpc", ha->host_str);
1483 if (ha->dpc_pid < 0) { 1478 if (IS_ERR(ha->dpc_thread)) {
1484 qla_printk(KERN_WARNING, ha, 1479 qla_printk(KERN_WARNING, ha,
1485 "Unable to start DPC thread!\n"); 1480 "Unable to start DPC thread!\n");
1486 1481 ret = PTR_ERR(ha->dpc_thread);
1487 ret = -ENODEV;
1488 goto probe_failed; 1482 goto probe_failed;
1489 } 1483 }
1490 wait_for_completion(&ha->dpc_inited);
1491 1484
1492 host->this_id = 255; 1485 host->this_id = 255;
1493 host->cmd_per_lun = 3; 1486 host->cmd_per_lun = 3;
@@ -1621,8 +1614,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one);
1621static void 1614static void
1622qla2x00_free_device(scsi_qla_host_t *ha) 1615qla2x00_free_device(scsi_qla_host_t *ha)
1623{ 1616{
1624 int ret;
1625
1626 /* Abort any outstanding IO descriptors. */ 1617 /* Abort any outstanding IO descriptors. */
1627 if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) 1618 if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
1628 qla2x00_cancel_io_descriptors(ha); 1619 qla2x00_cancel_io_descriptors(ha);
@@ -1632,18 +1623,15 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1632 qla2x00_stop_timer(ha); 1623 qla2x00_stop_timer(ha);
1633 1624
1634 /* Kill the kernel thread for this host */ 1625 /* Kill the kernel thread for this host */
1635 if (ha->dpc_pid >= 0) { 1626 if (ha->dpc_thread) {
1636 ha->dpc_should_die = 1; 1627 struct task_struct *t = ha->dpc_thread;
1637 wmb();
1638 ret = kill_proc(ha->dpc_pid, SIGHUP, 1);
1639 if (ret) {
1640 qla_printk(KERN_ERR, ha,
1641 "Unable to signal DPC thread -- (%d)\n", ret);
1642 1628
1643 /* TODO: SOMETHING MORE??? */ 1629 /*
1644 } else { 1630 * qla2xxx_wake_dpc checks for ->dpc_thread
1645 wait_for_completion(&ha->dpc_exited); 1631 * so we need to zero it out.
1646 } 1632 */
1633 ha->dpc_thread = NULL;
1634 kthread_stop(t);
1647 } 1635 }
1648 1636
1649 /* Stop currently executing firmware. */ 1637 /* Stop currently executing firmware. */
@@ -1775,8 +1763,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1775 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1763 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1776 } 1764 }
1777 1765
1778 if (defer && ha->dpc_wait && !ha->dpc_active) 1766 if (defer)
1779 up(ha->dpc_wait); 1767 qla2xxx_wake_dpc(ha);
1780} 1768}
1781 1769
1782/* 1770/*
@@ -1993,7 +1981,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
1993{ 1981{
1994 struct list_head *fcpl, *fcptemp; 1982 struct list_head *fcpl, *fcptemp;
1995 fc_port_t *fcport; 1983 fc_port_t *fcport;
1996 unsigned int wtime;/* max wait time if mbx cmd is busy. */
1997 1984
1998 if (ha == NULL) { 1985 if (ha == NULL) {
1999 /* error */ 1986 /* error */
@@ -2001,11 +1988,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2001 return; 1988 return;
2002 } 1989 }
2003 1990
2004 /* Make sure all other threads are stopped. */
2005 wtime = 60 * 1000;
2006 while (ha->dpc_wait && wtime)
2007 wtime = msleep_interruptible(wtime);
2008
2009 /* free ioctl memory */ 1991 /* free ioctl memory */
2010 qla2x00_free_ioctl_mem(ha); 1992 qla2x00_free_ioctl_mem(ha);
2011 1993
@@ -2156,7 +2138,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
2156static int 2138static int
2157qla2x00_do_dpc(void *data) 2139qla2x00_do_dpc(void *data)
2158{ 2140{
2159 DECLARE_MUTEX_LOCKED(sem);
2160 scsi_qla_host_t *ha; 2141 scsi_qla_host_t *ha;
2161 fc_port_t *fcport; 2142 fc_port_t *fcport;
2162 uint8_t status; 2143 uint8_t status;
@@ -2164,32 +2145,19 @@ qla2x00_do_dpc(void *data)
2164 2145
2165 ha = (scsi_qla_host_t *)data; 2146 ha = (scsi_qla_host_t *)data;
2166 2147
2167 lock_kernel();
2168
2169 daemonize("%s_dpc", ha->host_str);
2170 allow_signal(SIGHUP);
2171
2172 ha->dpc_wait = &sem;
2173
2174 set_user_nice(current, -20); 2148 set_user_nice(current, -20);
2175 2149
2176 unlock_kernel(); 2150 while (!kthread_should_stop()) {
2177
2178 complete(&ha->dpc_inited);
2179
2180 while (1) {
2181 DEBUG3(printk("qla2x00: DPC handler sleeping\n")); 2151 DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
2182 2152
2183 if (down_interruptible(&sem)) 2153 set_current_state(TASK_INTERRUPTIBLE);
2184 break; 2154 schedule();
2185 2155 __set_current_state(TASK_RUNNING);
2186 if (ha->dpc_should_die)
2187 break;
2188 2156
2189 DEBUG3(printk("qla2x00: DPC handler waking up\n")); 2157 DEBUG3(printk("qla2x00: DPC handler waking up\n"));
2190 2158
2191 /* Initialization not yet finished. Don't do anything yet. */ 2159 /* Initialization not yet finished. Don't do anything yet. */
2192 if (!ha->flags.init_done || ha->dpc_active) 2160 if (!ha->flags.init_done)
2193 continue; 2161 continue;
2194 2162
2195 DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no)); 2163 DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
@@ -2356,10 +2324,16 @@ qla2x00_do_dpc(void *data)
2356 /* 2324 /*
2357 * Make sure that nobody tries to wake us up again. 2325 * Make sure that nobody tries to wake us up again.
2358 */ 2326 */
2359 ha->dpc_wait = NULL;
2360 ha->dpc_active = 0; 2327 ha->dpc_active = 0;
2361 2328
2362 complete_and_exit(&ha->dpc_exited, 0); 2329 return 0;
2330}
2331
2332void
2333qla2xxx_wake_dpc(scsi_qla_host_t *ha)
2334{
2335 if (ha->dpc_thread)
2336 wake_up_process(ha->dpc_thread);
2363} 2337}
2364 2338
2365/* 2339/*
@@ -2540,11 +2514,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
2540 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2514 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2541 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2515 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
2542 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || 2516 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
2543 test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && 2517 test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
2544 ha->dpc_wait && !ha->dpc_active) { 2518 qla2xxx_wake_dpc(ha);
2545
2546 up(ha->dpc_wait);
2547 }
2548 2519
2549 qla2x00_restart_timer(ha, WATCH_INTERVAL); 2520 qla2x00_restart_timer(ha, WATCH_INTERVAL);
2550} 2521}