aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-08-22 22:50:43 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:10:56 -0400
commitee1a4a42f6198c2b6e7c9fba6a952d1f4f89d627 (patch)
treeead7372ab22e9cf4734148b02f28a713f40c321d /drivers/scsi/bfa
parentebfe83921bd860e0b28a1a74e90be57baf2c8255 (diff)
[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')
-rw-r--r--drivers/scsi/bfa/bfa_defs_fcs.h5
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h10
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c56
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c3
-rw-r--r--drivers/scsi/bfa/bfad_attr.c7
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c14
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h2
7 files changed, 83 insertions, 14 deletions
diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h
index 3bbc583f65cf..5871a1b6e2bc 100644
--- a/drivers/scsi/bfa/bfa_defs_fcs.h
+++ b/drivers/scsi/bfa/bfa_defs_fcs.h
@@ -410,6 +410,11 @@ struct bfa_rport_remote_link_stats_s {
410 u32 icc; /* Invalid CRC Count */ 410 u32 icc; /* Invalid CRC Count */
411}; 411};
412 412
413struct bfa_rport_qualifier_s {
414 wwn_t pwwn; /* Port WWN */
415 u32 pid; /* port ID */
416 u32 rsvd;
417};
413 418
414#define BFA_MAX_IO_INDEX 7 419#define BFA_MAX_IO_INDEX 7
415#define BFA_NO_IO_INDEX 9 420#define BFA_NO_IO_INDEX 9
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index 050a7e900434..ef0ec66f714a 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -286,9 +286,8 @@ bfa_fcs_lport_get_drvport(struct bfa_fcs_lport_s *port)
286 286
287bfa_boolean_t bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port); 287bfa_boolean_t bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port);
288struct bfa_fcs_lport_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs); 288struct bfa_fcs_lport_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs);
289void bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, 289void bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
290 wwn_t rport_wwns[], int *nrports); 290 struct bfa_rport_qualifier_s rport[], int *nrports);
291
292wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, 291wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn,
293 int index, int nrports, bfa_boolean_t bwwn); 292 int index, int nrports, bfa_boolean_t bwwn);
294 293
@@ -326,10 +325,14 @@ void bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port);
326void bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port); 325void bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port);
327struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pid( 326struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pid(
328 struct bfa_fcs_lport_s *port, u32 pid); 327 struct bfa_fcs_lport_s *port, u32 pid);
328struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_old_pid(
329 struct bfa_fcs_lport_s *port, u32 pid);
329struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pwwn( 330struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pwwn(
330 struct bfa_fcs_lport_s *port, wwn_t pwwn); 331 struct bfa_fcs_lport_s *port, wwn_t pwwn);
331struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_nwwn( 332struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_nwwn(
332 struct bfa_fcs_lport_s *port, wwn_t nwwn); 333 struct bfa_fcs_lport_s *port, wwn_t nwwn);
334struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_qualifier(
335 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 pid);
333void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port, 336void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
334 struct bfa_fcs_rport_s *rport); 337 struct bfa_fcs_rport_s *rport);
335void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port, 338void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
@@ -421,6 +424,7 @@ struct bfa_fcs_rport_s {
421 struct bfa_fcs_s *fcs; /* fcs instance */ 424 struct bfa_fcs_s *fcs; /* fcs instance */
422 struct bfad_rport_s *rp_drv; /* driver peer instance */ 425 struct bfad_rport_s *rp_drv; /* driver peer instance */
423 u32 pid; /* port ID of rport */ 426 u32 pid; /* port ID of rport */
427 u32 old_pid; /* PID before rport goes offline */
424 u16 maxfrsize; /* maximum frame size */ 428 u16 maxfrsize; /* maximum frame size */
425 __be16 reply_oxid; /* OX_ID of inbound requests */ 429 __be16 reply_oxid; /* OX_ID of inbound requests */
426 enum fc_cos fc_cos; /* FC classes of service supp */ 430 enum fc_cos fc_cos; /* FC classes of service supp */
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)
854} 854}
855 855
856/* 856/*
857 * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
858 */
859struct bfa_fcs_rport_s *
860bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
861{
862 struct bfa_fcs_rport_s *rport;
863 struct list_head *qe;
864
865 list_for_each(qe, &port->rport_q) {
866 rport = (struct bfa_fcs_rport_s *) qe;
867 if (rport->old_pid == pid)
868 return rport;
869 }
870
871 bfa_trc(port->fcs, pid);
872 return NULL;
873}
874
875/*
857 * PWWN based Lookup for a R-Port in the Port R-Port Queue 876 * PWWN based Lookup for a R-Port in the Port R-Port Queue
858 */ 877 */
859struct bfa_fcs_rport_s * 878struct bfa_fcs_rport_s *
@@ -892,6 +911,26 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
892} 911}
893 912
894/* 913/*
914 * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
915 */
916struct bfa_fcs_rport_s *
917bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
918 wwn_t pwwn, u32 pid)
919{
920 struct bfa_fcs_rport_s *rport;
921 struct list_head *qe;
922
923 list_for_each(qe, &port->rport_q) {
924 rport = (struct bfa_fcs_rport_s *) qe;
925 if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
926 return rport;
927 }
928
929 bfa_trc(port->fcs, pwwn);
930 return NULL;
931}
932
933/*
895 * Called by rport module when new rports are discovered. 934 * Called by rport module when new rports are discovered.
896 */ 935 */
897void 936void
@@ -4759,6 +4798,9 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
4759 * Otherwise let rport handle the RSCN event. 4798 * Otherwise let rport handle the RSCN event.
4760 */ 4799 */
4761 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 4800 rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
4801 if (!rport)
4802 rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
4803
4762 if (rport == NULL) { 4804 if (rport == NULL) {
4763 /* 4805 /*
4764 * If min cfg mode is enabled, we donot need to 4806 * 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,
4951} 4993}
4952 4994
4953void 4995void
4954bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, 4996bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
4955 wwn_t rport_wwns[], int *nrports) 4997 struct bfa_rport_qualifier_s rports[], int *nrports)
4956{ 4998{
4957 struct list_head *qh, *qe; 4999 struct list_head *qh, *qe;
4958 struct bfa_fcs_rport_s *rport = NULL; 5000 struct bfa_fcs_rport_s *rport = NULL;
4959 int i; 5001 int i;
4960 struct bfa_fcs_s *fcs; 5002 struct bfa_fcs_s *fcs;
4961 5003
4962 if (port == NULL || rport_wwns == NULL || *nrports == 0) 5004 if (port == NULL || rports == NULL || *nrports == 0)
4963 return; 5005 return;
4964 5006
4965 fcs = port->fcs; 5007 fcs = port->fcs;
@@ -4979,7 +5021,13 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
4979 continue; 5021 continue;
4980 } 5022 }
4981 5023
4982 rport_wwns[i] = rport->pwwn; 5024 if (!rport->pwwn && !rport->pid) {
5025 qe = bfa_q_next(qe);
5026 continue;
5027 }
5028
5029 rports[i].pwwn = rport->pwwn;
5030 rports[i].pid = rport->pid;
4983 5031
4984 i++; 5032 i++;
4985 qe = bfa_q_next(qe); 5033 qe = bfa_q_next(qe);
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index fe0463a1db04..fa2df04d9662 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -397,6 +397,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
397 BFA_FCS_RETRY_TIMEOUT); 397 BFA_FCS_RETRY_TIMEOUT);
398 } else { 398 } else {
399 bfa_stats(rport->port, rport_del_max_plogi_retry); 399 bfa_stats(rport->port, rport_del_max_plogi_retry);
400 rport->old_pid = rport->pid;
400 rport->pid = 0; 401 rport->pid = 0;
401 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 402 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
402 bfa_timer_start(rport->fcs->bfa, &rport->timer, 403 bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -1296,6 +1297,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1296 bfa_fcs_rport_sm_nsdisc_sending); 1297 bfa_fcs_rport_sm_nsdisc_sending);
1297 bfa_fcs_rport_send_nsdisc(rport, NULL); 1298 bfa_fcs_rport_send_nsdisc(rport, NULL);
1298 } else { 1299 } else {
1300 rport->old_pid = rport->pid;
1299 rport->pid = 0; 1301 rport->pid = 0;
1300 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1302 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1301 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1303 bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -1981,6 +1983,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
1981 rport->rp_drv = rport_drv; 1983 rport->rp_drv = rport_drv;
1982 rport->pid = rpid; 1984 rport->pid = rpid;
1983 rport->pwwn = pwwn; 1985 rport->pwwn = pwwn;
1986 rport->old_pid = 0;
1984 1987
1985 /* 1988 /*
1986 * allocate BFA rport 1989 * allocate BFA rport
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 1d18a803cff0..91a204470a43 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -941,15 +941,16 @@ bfad_im_num_of_discovered_ports_show(struct device *dev,
941 struct bfad_port_s *port = im_port->port; 941 struct bfad_port_s *port = im_port->port;
942 struct bfad_s *bfad = im_port->bfad; 942 struct bfad_s *bfad = im_port->bfad;
943 int nrports = 2048; 943 int nrports = 2048;
944 wwn_t *rports = NULL; 944 struct bfa_rport_qualifier_s *rports = NULL;
945 unsigned long flags; 945 unsigned long flags;
946 946
947 rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); 947 rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports,
948 GFP_ATOMIC);
948 if (rports == NULL) 949 if (rports == NULL)
949 return snprintf(buf, PAGE_SIZE, "Failed\n"); 950 return snprintf(buf, PAGE_SIZE, "Failed\n");
950 951
951 spin_lock_irqsave(&bfad->bfad_lock, flags); 952 spin_lock_irqsave(&bfad->bfad_lock, flags);
952 bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports); 953 bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
953 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 954 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
954 kfree(rports); 955 kfree(rports);
955 956
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 9c1495b321d9..d9463d8249e3 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -535,7 +535,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
535 535
536 if (bfad_chk_iocmd_sz(payload_len, 536 if (bfad_chk_iocmd_sz(payload_len,
537 sizeof(struct bfa_bsg_lport_get_rports_s), 537 sizeof(struct bfa_bsg_lport_get_rports_s),
538 sizeof(wwn_t) * iocmd->nrports) != BFA_STATUS_OK) { 538 sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports)
539 != BFA_STATUS_OK) {
539 iocmd->status = BFA_STATUS_VERSION_FAIL; 540 iocmd->status = BFA_STATUS_VERSION_FAIL;
540 return 0; 541 return 0;
541 } 542 }
@@ -552,8 +553,9 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
552 goto out; 553 goto out;
553 } 554 }
554 555
555 bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr, 556 bfa_fcs_lport_get_rport_quals(fcs_port,
556 &iocmd->nrports); 557 (struct bfa_rport_qualifier_s *)iocmd_bufptr,
558 &iocmd->nrports);
557 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 559 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
558 iocmd->status = BFA_STATUS_OK; 560 iocmd->status = BFA_STATUS_OK;
559out: 561out:
@@ -578,7 +580,11 @@ bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd)
578 goto out; 580 goto out;
579 } 581 }
580 582
581 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); 583 if (iocmd->pid)
584 fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(fcs_port,
585 iocmd->rpwwn, iocmd->pid);
586 else
587 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
582 if (fcs_rport == NULL) { 588 if (fcs_rport == NULL) {
583 bfa_trc(bfad, 0); 589 bfa_trc(bfad, 0);
584 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 590 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 17ad67283130..8c569ddb750d 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -319,6 +319,8 @@ struct bfa_bsg_rport_attr_s {
319 u16 vf_id; 319 u16 vf_id;
320 wwn_t pwwn; 320 wwn_t pwwn;
321 wwn_t rpwwn; 321 wwn_t rpwwn;
322 u32 pid;
323 u32 rsvd;
322 struct bfa_rport_attr_s attr; 324 struct bfa_rport_attr_s attr;
323}; 325};
324 326