summaryrefslogtreecommitdiff
path: root/drivers/scsi/bfa/bfa_fcs_lport.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-04-10 05:40:01 +0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-25 12:58:31 +0400
commit17c201b3281cfc2c7d7ecfabb33313b747e414cb (patch)
tree319c52a76dfc293881c00aef99c879d66f1b9923 /drivers/scsi/bfa/bfa_fcs_lport.c
parent42e22cac4e57f3e0b4b631c9489effe97f7d7d6c (diff)
downloadlinux-17c201b3281cfc2c7d7ecfabb33313b747e414cb.tar.xz
[SCSI] bfa: Fix to defer vport delete handler invocation till firmware logo response.
Made changes to avoid queuing the vport delete work to IM driver work queue in the bfa_fcb_lport_delete() - since at this stage we are not completely done with using the vport structure as we are still waiting for the LOGO response from the fw in online state or just doing some cleanup. Since queuing up the vport delete work at this stage will result in the FC transport layer to clean up the vport before we get the response from firmware. Made changes to queue the port delete work to the IM driver work queue - from the bfa_fcs_vport_free() function since at this state we are done with using the vport data structure and the FCS state machine is completely cleaned up. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs_lport.c')
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 5d2a1307e5ce..cd01fc02c4cd 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -709,14 +709,10 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
/* Base port will be deleted by the OS driver */
- if (port->vport) {
- bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles,
- port->fabric->vf_drv,
- port->vport ? port->vport->vport_drv : NULL);
+ if (port->vport)
bfa_fcs_vport_delete_comp(port->vport);
- } else {
+ else
bfa_wc_down(&port->fabric->wc);
- }
}
@@ -5714,17 +5710,23 @@ bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
(struct bfad_vport_s *)vport->vport_drv;
bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
+ bfa_lps_delete(vport->lps);
- if (vport_drv->comp_del)
+ if (vport_drv->comp_del) {
complete(vport_drv->comp_del);
- else
- kfree(vport_drv);
+ return;
+ }
- bfa_lps_delete(vport->lps);
+ /*
+ * We queue the vport delete work to the IM work_q from here.
+ * The memory for the bfad_vport_s is freed from the FC function
+ * template vport_delete entry point.
+ */
+ if (vport_drv)
+ bfad_im_port_delete(vport_drv->drv_port.bfad,
+ &vport_drv->drv_port);
}
-
-
/*
* fcs_vport_public FCS virtual port public interfaces
*/