diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2012-08-23 06:50:43 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-24 12:10:56 +0400 |
commit | ee1a4a42f6198c2b6e7c9fba6a952d1f4f89d627 (patch) | |
tree | ead7372ab22e9cf4734148b02f28a713f40c321d /drivers/scsi/bfa/bfa_fcs_lport.c | |
parent | ebfe83921bd860e0b28a1a74e90be57baf2c8255 (diff) | |
download | linux-ee1a4a42f6198c2b6e7c9fba6a952d1f4f89d627.tar.xz |
[SCSI] bfa: FCS remote port enhancements.
- Introduced rport qualifier structure and modified design to
export remote ports with valid pid or valid pwwn to the user space.
- Introduced old_pid field in the rport structure and made changes to
prevent re-creating a new remote port for an already existing rport
that is transitioning to a delete state. (Happens if we receive a RSCN
on the existing remote port that is getting deleted).
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.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index f8e801747ea7..5392df5c51ab 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -854,6 +854,25 @@ bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) } /* + * OLD_PID based Lookup for a R-Port in the Port R-Port Queue + */ +struct bfa_fcs_rport_s * +bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid) +{ + struct bfa_fcs_rport_s *rport; + struct list_head *qe; + + list_for_each(qe, &port->rport_q) { + rport = (struct bfa_fcs_rport_s *) qe; + if (rport->old_pid == pid) + return rport; + } + + bfa_trc(port->fcs, pid); + return NULL; +} + +/* * PWWN based Lookup for a R-Port in the Port R-Port Queue */ struct bfa_fcs_rport_s * @@ -892,6 +911,26 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) } /* + * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue + */ +struct bfa_fcs_rport_s * +bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port, + wwn_t pwwn, u32 pid) +{ + struct bfa_fcs_rport_s *rport; + struct list_head *qe; + + list_for_each(qe, &port->rport_q) { + rport = (struct bfa_fcs_rport_s *) qe; + if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid) + return rport; + } + + bfa_trc(port->fcs, pwwn); + return NULL; +} + +/* * Called by rport module when new rports are discovered. */ void @@ -4759,6 +4798,9 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) * Otherwise let rport handle the RSCN event. */ rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); + if (!rport) + rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid); + if (rport == NULL) { /* * If min cfg mode is enabled, we donot need to @@ -4951,15 +4993,15 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, } void -bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, - wwn_t rport_wwns[], int *nrports) +bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port, + struct bfa_rport_qualifier_s rports[], int *nrports) { struct list_head *qh, *qe; struct bfa_fcs_rport_s *rport = NULL; int i; struct bfa_fcs_s *fcs; - if (port == NULL || rport_wwns == NULL || *nrports == 0) + if (port == NULL || rports == NULL || *nrports == 0) return; fcs = port->fcs; @@ -4979,7 +5021,13 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, continue; } - rport_wwns[i] = rport->pwwn; + if (!rport->pwwn && !rport->pid) { + qe = bfa_q_next(qe); + continue; + } + + rports[i].pwwn = rport->pwwn; + rports[i].pid = rport->pid; i++; qe = bfa_q_next(qe); |