[SCSI] bfa: Fix to defer vport delete handler invocation till firmware logo response.
authorKrishna Gudipati <kgudipat@brocade.com>
Tue, 10 Apr 2012 01:40:01 +0000 (18:40 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 25 Apr 2012 08:58:31 +0000 (09:58 +0100)
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>
drivers/scsi/bfa/bfa_fcs.h
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_attr.c

index e75e07d25915250b7ec16d6d1087b220c882c85d..51c9e134571986399fe1a6b9d1738ac3c36f876e 100644 (file)
@@ -799,9 +799,6 @@ struct bfad_port_s *bfa_fcb_lport_new(struct bfad_s *bfad,
                                      enum bfa_lport_role roles,
                                      struct bfad_vf_s *vf_drv,
                                      struct bfad_vport_s *vp_drv);
-void bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
-                         struct bfad_vf_s *vf_drv,
-                         struct bfad_vport_s *vp_drv);
 
 /*
  * vport callbacks
index 5d2a1307e5cea333a73356a56ff4a054af5009d2..cd01fc02c4cd095f05bcdd87dd62e157148de5d1 100644 (file)
@@ -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
  */
index 404fd10ddb21cd6b89821694807e402d30e3bf21..2e4b0be14a20e76f344123f77167c70332957d56 100644 (file)
@@ -456,23 +456,6 @@ bfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port,
        return port_drv;
 }
 
-void
-bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
-                   struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
-{
-       struct bfad_port_s    *port_drv;
-
-       /* this will be only called from rmmod context */
-       if (vp_drv && !vp_drv->comp_del) {
-               port_drv = (vp_drv) ? (&(vp_drv)->drv_port) :
-                               ((vf_drv) ? (&(vf_drv)->base_port) :
-                               (&(bfad)->pport));
-               bfa_trc(bfad, roles);
-               if (roles & BFA_LPORT_ROLE_FCP_IM)
-                       bfad_im_port_delete(bfad, port_drv);
-       }
-}
-
 /*
  * FCS RPORT alloc callback, after successful PLOGI by FCS
  */
index 7b1ecd2b3ffe8b382689429c6e91d01ae04e45a1..d12be9dff4ba6be5fb5ec10f1df7c21b2ed1e231 100644 (file)
@@ -497,6 +497,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
        if (im_port->flags & BFAD_PORT_DELETE) {
                bfad_scsi_host_free(bfad, im_port);
                list_del(&vport->list_entry);
+               kfree(vport);
                return 0;
        }