From: Joe Carnuccio <[email protected]>

This patch adds workqueue mechanism for deleting fcport
via BSG interface.

Signed-off-by: Joe Carnuccio <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
---
 drivers/scsi/qla2xxx/qla_bsg.c | 18 +++++++++++++++++-
 drivers/scsi/qla2xxx/qla_def.h |  1 +
 drivers/scsi/qla2xxx/qla_os.c  | 11 +++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 4a9fd8d944d6..d9b6af975691 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -11,6 +11,14 @@
 #include <linux/delay.h>
 #include <linux/bsg-lib.h>
 
+static void qla2xxx_free_fcport_work(struct work_struct *work)
+{
+       struct fc_port *fcport = container_of(work, typeof(*fcport),
+           free_work);
+
+       qla2x00_free_fcport(fcport);
+}
+
 /* BSG support for ELS/CT pass through */
 void
 qla2x00_bsg_job_done(void *ptr, int res)
@@ -57,8 +65,16 @@ qla2x00_bsg_sp_free(void *ptr)
 
        if (sp->type == SRB_CT_CMD ||
            sp->type == SRB_FXIOCB_BCMD ||
-           sp->type == SRB_ELS_CMD_HST)
+           sp->type == SRB_ELS_CMD_HST) {
+               if (ha->free_fcport) {
+                       INIT_WORK(&sp->fcport->free_work,
+                           qla2xxx_free_fcport_work);
+                       queue_work(ha->free_fcport, &sp->fcport->free_work);
+                       goto done;
+               }
                kfree(sp->fcport);
+       }
+done:
        qla2x00_rel_sp(sp);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c0f7593666a1..a0304746e8a5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4190,6 +4190,7 @@ struct qla_hw_data {
        struct work_struct idc_state_handler;
        struct work_struct nic_core_unrecoverable;
        struct work_struct board_disable;
+       struct workqueue_struct *free_fcport;
 
        struct mr_data_fx00 mr;
        uint32_t chip_reset;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7bf23943c815..8bc60ba7fd13 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3196,6 +3196,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
            host->max_cmd_len, host->max_channel, host->max_lun,
            host->transportt, sht->vendor_id);
 
+       ha->free_fcport = create_workqueue("free_fcport");
+       if (!ha->free_fcport) {
+               ql_log(ql_log_info, base_vha, 0xee00,
+                   "Failed to allocate workqueue ha->free_fcport\n");
+       }
+
        INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn);
 
        /* Set up the irqs */
@@ -3650,6 +3656,11 @@ qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
                ha->dpc_hp_wq = NULL;
        }
 
+       if (ha->free_fcport) {
+               destroy_workqueue(ha->free_fcport);
+               ha->free_fcport = NULL;
+       }
+
        /* Kill the kernel thread for this host */
        if (ha->dpc_thread) {
                struct task_struct *t = ha->dpc_thread;
-- 
2.12.0

Reply via email to