Commit 39a11240 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[SCSI] qla2xxx: use kthread_ API

Use the kthread_ API instead of opencoding lots of hairy code for kernel
thread creation and teardown.

Also switch from semaphore-based thread wakeup to wake_up_process.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-By: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 7e6dff62
...@@ -2414,11 +2414,7 @@ typedef struct scsi_qla_host { ...@@ -2414,11 +2414,7 @@ typedef struct scsi_qla_host {
struct sns_cmd_pkt *sns_cmd; struct sns_cmd_pkt *sns_cmd;
dma_addr_t sns_cmd_dma; dma_addr_t sns_cmd_dma;
pid_t dpc_pid; struct task_struct *dpc_thread;
int dpc_should_die;
struct completion dpc_inited;
struct completion dpc_exited;
struct semaphore *dpc_wait;
uint8_t dpc_active; /* DPC routine is active */ uint8_t dpc_active; /* DPC routine is active */
/* Timeout timers. */ /* Timeout timers. */
......
...@@ -81,6 +81,8 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); ...@@ -81,6 +81,8 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
/* /*
* Global Function Prototypes in qla_iocb.c source file. * Global Function Prototypes in qla_iocb.c source file.
*/ */
......
...@@ -838,9 +838,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) ...@@ -838,9 +838,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n"); qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active) qla2xxx_wake_dpc(ha);
up(ha->dpc_wait);
return; return;
} }
cp = sp->cmd; cp = sp->cmd;
...@@ -1271,8 +1269,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) ...@@ -1271,8 +1269,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
"Error entry - invalid handle\n"); "Error entry - invalid handle\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active) qla2xxx_wake_dpc(ha);
up(ha->dpc_wait);
} }
} }
......
...@@ -284,9 +284,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) ...@@ -284,9 +284,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
"Mailbox command timeout occured. Scheduling ISP " "Mailbox command timeout occured. Scheduling ISP "
"abort.\n"); "abort.\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active) qla2xxx_wake_dpc(ha);
up(ha->dpc_wait);
} else if (!abort_active) { } else if (!abort_active) {
/* call abort directly since we are in the DPC thread */ /* call abort directly since we are in the DPC thread */
DEBUG(printk("%s(%ld): timeout calling abort_isp\n", DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kthread.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
...@@ -1307,8 +1307,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ...@@ -1307,8 +1307,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
ha->brd_info = brd_info; ha->brd_info = brd_info;
sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
ha->dpc_pid = -1;
/* Configure PCI I/O space */ /* Configure PCI I/O space */
ret = qla2x00_iospace_config(ha); ret = qla2x00_iospace_config(ha);
if (ret) if (ret)
...@@ -1449,9 +1447,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ...@@ -1449,9 +1447,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
*/ */
spin_lock_init(&ha->mbx_reg_lock); spin_lock_init(&ha->mbx_reg_lock);
init_completion(&ha->dpc_inited);
init_completion(&ha->dpc_exited);
qla2x00_config_dma_addressing(ha); qla2x00_config_dma_addressing(ha);
if (qla2x00_mem_alloc(ha)) { if (qla2x00_mem_alloc(ha)) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
...@@ -1478,16 +1473,14 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) ...@@ -1478,16 +1473,14 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
/* /*
* Startup the kernel thread for this host adapter * Startup the kernel thread for this host adapter
*/ */
ha->dpc_should_die = 0; ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0); "%s_dpc", ha->host_str);
if (ha->dpc_pid < 0) { if (IS_ERR(ha->dpc_thread)) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Unable to start DPC thread!\n"); "Unable to start DPC thread!\n");
ret = PTR_ERR(ha->dpc_thread);
ret = -ENODEV;
goto probe_failed; goto probe_failed;
} }
wait_for_completion(&ha->dpc_inited);
host->this_id = 255; host->this_id = 255;
host->cmd_per_lun = 3; host->cmd_per_lun = 3;
...@@ -1621,8 +1614,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one); ...@@ -1621,8 +1614,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one);
static void static void
qla2x00_free_device(scsi_qla_host_t *ha) qla2x00_free_device(scsi_qla_host_t *ha)
{ {
int ret;
/* Abort any outstanding IO descriptors. */ /* Abort any outstanding IO descriptors. */
if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
qla2x00_cancel_io_descriptors(ha); qla2x00_cancel_io_descriptors(ha);
...@@ -1632,18 +1623,15 @@ qla2x00_free_device(scsi_qla_host_t *ha) ...@@ -1632,18 +1623,15 @@ qla2x00_free_device(scsi_qla_host_t *ha)
qla2x00_stop_timer(ha); qla2x00_stop_timer(ha);
/* Kill the kernel thread for this host */ /* Kill the kernel thread for this host */
if (ha->dpc_pid >= 0) { if (ha->dpc_thread) {
ha->dpc_should_die = 1; struct task_struct *t = ha->dpc_thread;
wmb();
ret = kill_proc(ha->dpc_pid, SIGHUP, 1);
if (ret) {
qla_printk(KERN_ERR, ha,
"Unable to signal DPC thread -- (%d)\n", ret);
/* TODO: SOMETHING MORE??? */ /*
} else { * qla2xxx_wake_dpc checks for ->dpc_thread
wait_for_completion(&ha->dpc_exited); * so we need to zero it out.
} */
ha->dpc_thread = NULL;
kthread_stop(t);
} }
/* Stop currently executing firmware. */ /* Stop currently executing firmware. */
...@@ -1775,8 +1763,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) ...@@ -1775,8 +1763,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
atomic_set(&fcport->state, FCS_DEVICE_LOST); atomic_set(&fcport->state, FCS_DEVICE_LOST);
} }
if (defer && ha->dpc_wait && !ha->dpc_active) if (defer)
up(ha->dpc_wait); qla2xxx_wake_dpc(ha);
} }
/* /*
...@@ -1993,7 +1981,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ...@@ -1993,7 +1981,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
{ {
struct list_head *fcpl, *fcptemp; struct list_head *fcpl, *fcptemp;
fc_port_t *fcport; fc_port_t *fcport;
unsigned int wtime;/* max wait time if mbx cmd is busy. */
if (ha == NULL) { if (ha == NULL) {
/* error */ /* error */
...@@ -2001,11 +1988,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha) ...@@ -2001,11 +1988,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
return; return;
} }
/* Make sure all other threads are stopped. */
wtime = 60 * 1000;
while (ha->dpc_wait && wtime)
wtime = msleep_interruptible(wtime);
/* free ioctl memory */ /* free ioctl memory */
qla2x00_free_ioctl_mem(ha); qla2x00_free_ioctl_mem(ha);
...@@ -2156,7 +2138,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha) ...@@ -2156,7 +2138,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
static int static int
qla2x00_do_dpc(void *data) qla2x00_do_dpc(void *data)
{ {
DECLARE_MUTEX_LOCKED(sem);
scsi_qla_host_t *ha; scsi_qla_host_t *ha;
fc_port_t *fcport; fc_port_t *fcport;
uint8_t status; uint8_t status;
...@@ -2164,32 +2145,19 @@ qla2x00_do_dpc(void *data) ...@@ -2164,32 +2145,19 @@ qla2x00_do_dpc(void *data)
ha = (scsi_qla_host_t *)data; ha = (scsi_qla_host_t *)data;
lock_kernel();
daemonize("%s_dpc", ha->host_str);
allow_signal(SIGHUP);
ha->dpc_wait = &sem;
set_user_nice(current, -20); set_user_nice(current, -20);
unlock_kernel(); while (!kthread_should_stop()) {
complete(&ha->dpc_inited);
while (1) {
DEBUG3(printk("qla2x00: DPC handler sleeping\n")); DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
if (down_interruptible(&sem)) set_current_state(TASK_INTERRUPTIBLE);
break; schedule();
__set_current_state(TASK_RUNNING);
if (ha->dpc_should_die)
break;
DEBUG3(printk("qla2x00: DPC handler waking up\n")); DEBUG3(printk("qla2x00: DPC handler waking up\n"));
/* Initialization not yet finished. Don't do anything yet. */ /* Initialization not yet finished. Don't do anything yet. */
if (!ha->flags.init_done || ha->dpc_active) if (!ha->flags.init_done)
continue; continue;
DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no)); DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
...@@ -2356,10 +2324,16 @@ qla2x00_do_dpc(void *data) ...@@ -2356,10 +2324,16 @@ qla2x00_do_dpc(void *data)
/* /*
* Make sure that nobody tries to wake us up again. * Make sure that nobody tries to wake us up again.
*/ */
ha->dpc_wait = NULL;
ha->dpc_active = 0; ha->dpc_active = 0;
complete_and_exit(&ha->dpc_exited, 0); return 0;
}
void
qla2xxx_wake_dpc(scsi_qla_host_t *ha)
{
if (ha->dpc_thread)
wake_up_process(ha->dpc_thread);
} }
/* /*
...@@ -2540,11 +2514,8 @@ qla2x00_timer(scsi_qla_host_t *ha) ...@@ -2540,11 +2514,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
ha->dpc_wait && !ha->dpc_active) { qla2xxx_wake_dpc(ha);
up(ha->dpc_wait);
}
qla2x00_restart_timer(ha, WATCH_INTERVAL); qla2x00_restart_timer(ha, WATCH_INTERVAL);
} }
......
...@@ -1354,7 +1354,7 @@ qla2x00_resume_hba(struct scsi_qla_host *ha) ...@@ -1354,7 +1354,7 @@ qla2x00_resume_hba(struct scsi_qla_host *ha)
/* Resume HBA. */ /* Resume HBA. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
up(ha->dpc_wait); qla2xxx_wake_dpc(ha);
qla2x00_wait_for_hba_online(ha); qla2x00_wait_for_hba_online(ha);
scsi_unblock_requests(ha->host); scsi_unblock_requests(ha->host);
} }
...@@ -1652,7 +1652,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, ...@@ -1652,7 +1652,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
/* Resume HBA -- RISC reset needed. */ /* Resume HBA -- RISC reset needed. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
up(ha->dpc_wait); qla2xxx_wake_dpc(ha);
qla2x00_wait_for_hba_online(ha); qla2x00_wait_for_hba_online(ha);
scsi_unblock_requests(ha->host); scsi_unblock_requests(ha->host);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment