[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: Christoph Hellwig <hch@lst.de>
Acked-By: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
Christoph Hellwig 2006-02-14 18:46:22 +01:00 committed by James Bottomley
parent 7e6dff62da
commit 39a112403f
6 changed files with 38 additions and 74 deletions

View File

@ -2414,11 +2414,7 @@ typedef struct scsi_qla_host {
struct sns_cmd_pkt *sns_cmd;
dma_addr_t sns_cmd_dma;
pid_t dpc_pid;
int dpc_should_die;
struct completion dpc_inited;
struct completion dpc_exited;
struct semaphore *dpc_wait;
struct task_struct *dpc_thread;
uint8_t dpc_active; /* DPC routine is active */
/* Timeout timers. */

View File

@ -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 void qla2xxx_wake_dpc(scsi_qla_host_t *);
/*
* Global Function Prototypes in qla_iocb.c source file.
*/

View File

@ -838,9 +838,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active)
up(ha->dpc_wait);
qla2xxx_wake_dpc(ha);
return;
}
cp = sp->cmd;
@ -1271,8 +1269,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
"Error entry - invalid handle\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active)
up(ha->dpc_wait);
qla2xxx_wake_dpc(ha);
}
}

View File

@ -284,9 +284,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
"Mailbox command timeout occured. Scheduling ISP "
"abort.\n");
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
if (ha->dpc_wait && !ha->dpc_active)
up(ha->dpc_wait);
qla2xxx_wake_dpc(ha);
} else if (!abort_active) {
/* call abort directly since we are in the DPC thread */
DEBUG(printk("%s(%ld): timeout calling abort_isp\n",

View File

@ -8,8 +8,8 @@
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
@ -1307,8 +1307,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
ha->brd_info = brd_info;
sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
ha->dpc_pid = -1;
/* Configure PCI I/O space */
ret = qla2x00_iospace_config(ha);
if (ret)
@ -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);
init_completion(&ha->dpc_inited);
init_completion(&ha->dpc_exited);
qla2x00_config_dma_addressing(ha);
if (qla2x00_mem_alloc(ha)) {
qla_printk(KERN_WARNING, ha,
@ -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
*/
ha->dpc_should_die = 0;
ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0);
if (ha->dpc_pid < 0) {
ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
"%s_dpc", ha->host_str);
if (IS_ERR(ha->dpc_thread)) {
qla_printk(KERN_WARNING, ha,
"Unable to start DPC thread!\n");
ret = -ENODEV;
ret = PTR_ERR(ha->dpc_thread);
goto probe_failed;
}
wait_for_completion(&ha->dpc_inited);
host->this_id = 255;
host->cmd_per_lun = 3;
@ -1621,8 +1614,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one);
static void
qla2x00_free_device(scsi_qla_host_t *ha)
{
int ret;
/* Abort any outstanding IO descriptors. */
if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
qla2x00_cancel_io_descriptors(ha);
@ -1632,18 +1623,15 @@ qla2x00_free_device(scsi_qla_host_t *ha)
qla2x00_stop_timer(ha);
/* Kill the kernel thread for this host */
if (ha->dpc_pid >= 0) {
ha->dpc_should_die = 1;
wmb();
ret = kill_proc(ha->dpc_pid, SIGHUP, 1);
if (ret) {
qla_printk(KERN_ERR, ha,
"Unable to signal DPC thread -- (%d)\n", ret);
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
/* TODO: SOMETHING MORE??? */
} else {
wait_for_completion(&ha->dpc_exited);
}
/*
* qla2xxx_wake_dpc checks for ->dpc_thread
* so we need to zero it out.
*/
ha->dpc_thread = NULL;
kthread_stop(t);
}
/* Stop currently executing firmware. */
@ -1775,8 +1763,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
atomic_set(&fcport->state, FCS_DEVICE_LOST);
}
if (defer && ha->dpc_wait && !ha->dpc_active)
up(ha->dpc_wait);
if (defer)
qla2xxx_wake_dpc(ha);
}
/*
@ -1993,7 +1981,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
{
struct list_head *fcpl, *fcptemp;
fc_port_t *fcport;
unsigned int wtime;/* max wait time if mbx cmd is busy. */
if (ha == NULL) {
/* error */
@ -2001,11 +1988,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
return;
}
/* Make sure all other threads are stopped. */
wtime = 60 * 1000;
while (ha->dpc_wait && wtime)
wtime = msleep_interruptible(wtime);
/* free ioctl memory */
qla2x00_free_ioctl_mem(ha);
@ -2156,7 +2138,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
static int
qla2x00_do_dpc(void *data)
{
DECLARE_MUTEX_LOCKED(sem);
scsi_qla_host_t *ha;
fc_port_t *fcport;
uint8_t status;
@ -2164,32 +2145,19 @@ qla2x00_do_dpc(void *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);
unlock_kernel();
complete(&ha->dpc_inited);
while (1) {
while (!kthread_should_stop()) {
DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
if (down_interruptible(&sem))
break;
if (ha->dpc_should_die)
break;
set_current_state(TASK_INTERRUPTIBLE);
schedule();
__set_current_state(TASK_RUNNING);
DEBUG3(printk("qla2x00: DPC handler waking up\n"));
/* Initialization not yet finished. Don't do anything yet. */
if (!ha->flags.init_done || ha->dpc_active)
if (!ha->flags.init_done)
continue;
DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
@ -2356,10 +2324,16 @@ qla2x00_do_dpc(void *data)
/*
* Make sure that nobody tries to wake us up again.
*/
ha->dpc_wait = NULL;
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)
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) &&
ha->dpc_wait && !ha->dpc_active) {
up(ha->dpc_wait);
}
test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
qla2xxx_wake_dpc(ha);
qla2x00_restart_timer(ha, WATCH_INTERVAL);
}

View File

@ -1354,7 +1354,7 @@ qla2x00_resume_hba(struct scsi_qla_host *ha)
/* Resume HBA. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
up(ha->dpc_wait);
qla2xxx_wake_dpc(ha);
qla2x00_wait_for_hba_online(ha);
scsi_unblock_requests(ha->host);
}
@ -1652,7 +1652,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
/* Resume HBA -- RISC reset needed. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
up(ha->dpc_wait);
qla2xxx_wake_dpc(ha);
qla2x00_wait_for_hba_online(ha);
scsi_unblock_requests(ha->host);