aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-04-09 21:40:01 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-25 04:58:31 -0400
commit17c201b3281cfc2c7d7ecfabb33313b747e414cb (patch)
tree319c52a76dfc293881c00aef99c879d66f1b9923 /drivers/scsi/bfa
parent42e22cac4e57f3e0b4b631c9489effe97f7d7d6c (diff)
[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')
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h3
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c26
-rw-r--r--drivers/scsi/bfa/bfad.c17
-rw-r--r--drivers/scsi/bfa/bfad_attr.c1
4 files changed, 15 insertions, 32 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index e75e07d25915..51c9e1345719 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -799,9 +799,6 @@ struct bfad_port_s *bfa_fcb_lport_new(struct bfad_s *bfad,
799 enum bfa_lport_role roles, 799 enum bfa_lport_role roles,
800 struct bfad_vf_s *vf_drv, 800 struct bfad_vf_s *vf_drv,
801 struct bfad_vport_s *vp_drv); 801 struct bfad_vport_s *vp_drv);
802void bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
803 struct bfad_vf_s *vf_drv,
804 struct bfad_vport_s *vp_drv);
805 802
806/* 803/*
807 * vport callbacks 804 * vport callbacks
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)
709 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE); 709 bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
710 710
711 /* Base port will be deleted by the OS driver */ 711 /* Base port will be deleted by the OS driver */
712 if (port->vport) { 712 if (port->vport)
713 bfa_fcb_lport_delete(port->fcs->bfad, port->port_cfg.roles,
714 port->fabric->vf_drv,
715 port->vport ? port->vport->vport_drv : NULL);
716 bfa_fcs_vport_delete_comp(port->vport); 713 bfa_fcs_vport_delete_comp(port->vport);
717 } else { 714 else
718 bfa_wc_down(&port->fabric->wc); 715 bfa_wc_down(&port->fabric->wc);
719 }
720} 716}
721 717
722 718
@@ -5714,17 +5710,23 @@ bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
5714 (struct bfad_vport_s *)vport->vport_drv; 5710 (struct bfad_vport_s *)vport->vport_drv;
5715 5711
5716 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); 5712 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
5713 bfa_lps_delete(vport->lps);
5717 5714
5718 if (vport_drv->comp_del) 5715 if (vport_drv->comp_del) {
5719 complete(vport_drv->comp_del); 5716 complete(vport_drv->comp_del);
5720 else 5717 return;
5721 kfree(vport_drv); 5718 }
5722 5719
5723 bfa_lps_delete(vport->lps); 5720 /*
5721 * We queue the vport delete work to the IM work_q from here.
5722 * The memory for the bfad_vport_s is freed from the FC function
5723 * template vport_delete entry point.
5724 */
5725 if (vport_drv)
5726 bfad_im_port_delete(vport_drv->drv_port.bfad,
5727 &vport_drv->drv_port);
5724} 5728}
5725 5729
5726
5727
5728/* 5730/*
5729 * fcs_vport_public FCS virtual port public interfaces 5731 * fcs_vport_public FCS virtual port public interfaces
5730 */ 5732 */
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 404fd10ddb21..2e4b0be14a20 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -456,23 +456,6 @@ bfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port,
456 return port_drv; 456 return port_drv;
457} 457}
458 458
459void
460bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
461 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
462{
463 struct bfad_port_s *port_drv;
464
465 /* this will be only called from rmmod context */
466 if (vp_drv && !vp_drv->comp_del) {
467 port_drv = (vp_drv) ? (&(vp_drv)->drv_port) :
468 ((vf_drv) ? (&(vf_drv)->base_port) :
469 (&(bfad)->pport));
470 bfa_trc(bfad, roles);
471 if (roles & BFA_LPORT_ROLE_FCP_IM)
472 bfad_im_port_delete(bfad, port_drv);
473 }
474}
475
476/* 459/*
477 * FCS RPORT alloc callback, after successful PLOGI by FCS 460 * FCS RPORT alloc callback, after successful PLOGI by FCS
478 */ 461 */
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 7b1ecd2b3ffe..d12be9dff4ba 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -497,6 +497,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
497 if (im_port->flags & BFAD_PORT_DELETE) { 497 if (im_port->flags & BFAD_PORT_DELETE) {
498 bfad_scsi_host_free(bfad, im_port); 498 bfad_scsi_host_free(bfad, im_port);
499 list_del(&vport->list_entry); 499 list_del(&vport->list_entry);
500 kfree(vport);
500 return 0; 501 return 0;
501 } 502 }
502 503