diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 89 |
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); | |||
1621 | static void | 1614 | static void |
1622 | qla2x00_free_device(scsi_qla_host_t *ha) | 1615 | qla2x00_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) | |||
2156 | static int | 2138 | static int |
2157 | qla2x00_do_dpc(void *data) | 2139 | qla2x00_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 | |||
2332 | void | ||
2333 | qla2xxx_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 | } |