[SCSI] qla2xxx: use kthread_ API
authorChristoph Hellwig <hch@lst.de>
Tue, 14 Feb 2006 17:46:22 +0000 (18:46 +0100)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Fri, 3 Mar 2006 04:56:40 +0000 (22:56 -0600)
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>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c

index b31a03bbd14f4fd495dcc44fe6bfe367aa0c4c6a..2e16f3285d5f9442e21d1f0d4ed6054fdbf56827 100644 (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. */
index ffdc2680f0490817f6d64a4dea44279fcef7831c..e897eadf0362ec06af9f1aa22bd14ad3e2a0e235 100644 (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.
  */
index 42aa7a7c1a7313795fc4f30a9362f14740e7ce54..c15458c2bf32993b51537e20be90be54e5a29b91 100644 (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);
        }
 }
 
index 363dfdd042b08871c04e637fea9454978c52ea85..584cc2f6dd35dbf23ef36562d6e239b56e5c9f35 100644 (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",
index 9f91f1a20542cde30379643072d127cc873a9c6a..43ca0d8ca3843a3d9718bda3fee7f26ea41b22d2 100644 (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);
 }
index 3866a5760f15b45966a2a3de8ebf40aaa88f9596..8d68c463cd5b347972bc61e03bdae9734aaadcc7 100644 (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);