aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-08-22 22:51:08 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:10:56 -0400
commitc3f1b123d0573b47aea540c711e6ca83737c5d86 (patch)
tree8dc44b30a38398fed676526d1a29d921974ae34e
parentee1a4a42f6198c2b6e7c9fba6a952d1f4f89d627 (diff)
[SCSI] bfa: Make changes to FCXP resource management.
- Made changes to split FCXP resources as request and response resources. - The split will reduce the contention for FCXP resources in an open zone config. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/bfa/bfa_cs.h4
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c2
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h13
-rw-r--r--drivers/scsi/bfa/bfa_fcs_fcpim.c5
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c77
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c42
-rw-r--r--drivers/scsi/bfa/bfa_svc.c80
-rw-r--r--drivers/scsi/bfa/bfa_svc.h22
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c4
9 files changed, 156 insertions, 93 deletions
diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h
index 12bfeed268eb..91a8aa394db5 100644
--- a/drivers/scsi/bfa/bfa_cs.h
+++ b/drivers/scsi/bfa/bfa_cs.h
@@ -168,7 +168,7 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
168/* 168/*
169 * bfa_q_deq - dequeue an element from head of the queue 169 * bfa_q_deq - dequeue an element from head of the queue
170 */ 170 */
171#define bfa_q_deq(_q, _qe) { \ 171#define bfa_q_deq(_q, _qe) do { \
172 if (!list_empty(_q)) { \ 172 if (!list_empty(_q)) { \
173 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \ 173 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \
174 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \ 174 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
@@ -177,7 +177,7 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
177 } else { \ 177 } else { \
178 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\ 178 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\
179 } \ 179 } \
180} 180} while (0)
181 181
182/* 182/*
183 * bfa_q_deq_tail - dequeue an element from tail of the queue 183 * bfa_q_deq_tail - dequeue an element from tail of the queue
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index eaac57e1ddec..3f71d504e398 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -1294,7 +1294,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1294 u16 reqlen; 1294 u16 reqlen;
1295 struct fchs_s fchs; 1295 struct fchs_s fchs;
1296 1296
1297 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs); 1297 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs, BFA_FALSE);
1298 /* 1298 /*
1299 * Do not expect this failure -- expect remote node to retry 1299 * Do not expect this failure -- expect remote node to retry
1300 */ 1300 */
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index ef0ec66f714a..10c93bf09846 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -511,12 +511,13 @@ struct bfa_fcs_itnim_s {
511 struct bfa_fcxp_s *fcxp; /* FCXP in use */ 511 struct bfa_fcxp_s *fcxp; /* FCXP in use */
512 struct bfa_itnim_stats_s stats; /* itn statistics */ 512 struct bfa_itnim_stats_s stats; /* itn statistics */
513}; 513};
514#define bfa_fcs_fcxp_alloc(__fcs) \ 514#define bfa_fcs_fcxp_alloc(__fcs, __req) \
515 bfa_fcxp_alloc(NULL, (__fcs)->bfa, 0, 0, NULL, NULL, NULL, NULL) 515 bfa_fcxp_req_rsp_alloc(NULL, (__fcs)->bfa, 0, 0, \
516 516 NULL, NULL, NULL, NULL, __req)
517#define bfa_fcs_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, __alloc_cbarg) \ 517#define bfa_fcs_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, \
518 bfa_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, __alloc_cbarg, \ 518 __alloc_cbarg, __req) \
519 NULL, 0, 0, NULL, NULL, NULL, NULL) 519 bfa_fcxp_req_rsp_alloc_wait(__bfa, __wqe, __alloc_cbfn, \
520 __alloc_cbarg, NULL, 0, 0, NULL, NULL, NULL, NULL, __req)
520 521
521static inline struct bfad_port_s * 522static inline struct bfad_port_s *
522bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim) 523bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim)
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c
index 9272840a2409..59c062f71f6e 100644
--- a/drivers/scsi/bfa/bfa_fcs_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c
@@ -426,11 +426,12 @@ bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
426 426
427 bfa_trc(itnim->fcs, itnim->rport->pwwn); 427 bfa_trc(itnim->fcs, itnim->rport->pwwn);
428 428
429 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 429 fcxp = fcxp_alloced ? fcxp_alloced :
430 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
430 if (!fcxp) { 431 if (!fcxp) {
431 itnim->stats.fcxp_alloc_wait++; 432 itnim->stats.fcxp_alloc_wait++;
432 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe, 433 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
433 bfa_fcs_itnim_send_prli, itnim); 434 bfa_fcs_itnim_send_prli, itnim, BFA_TRUE);
434 return; 435 return;
435 } 436 }
436 itnim->fcxp = fcxp; 437 itnim->fcxp = fcxp;
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 5392df5c51ab..e5661703d469 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -340,7 +340,7 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
340 bfa_trc(port->fcs, rx_fchs->d_id); 340 bfa_trc(port->fcs, rx_fchs->d_id);
341 bfa_trc(port->fcs, rx_fchs->s_id); 341 bfa_trc(port->fcs, rx_fchs->s_id);
342 342
343 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 343 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
344 if (!fcxp) 344 if (!fcxp)
345 return; 345 return;
346 346
@@ -370,7 +370,7 @@ bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
370 bfa_trc(port->fcs, rx_fchs->d_id); 370 bfa_trc(port->fcs, rx_fchs->d_id);
371 bfa_trc(port->fcs, rx_fchs->s_id); 371 bfa_trc(port->fcs, rx_fchs->s_id);
372 372
373 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 373 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
374 if (!fcxp) 374 if (!fcxp)
375 return; 375 return;
376 376
@@ -507,7 +507,7 @@ bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
507 bfa_trc(port->fcs, rx_fchs->s_id); 507 bfa_trc(port->fcs, rx_fchs->s_id);
508 bfa_trc(port->fcs, rx_fchs->d_id); 508 bfa_trc(port->fcs, rx_fchs->d_id);
509 509
510 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 510 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
511 if (!fcxp) 511 if (!fcxp)
512 return; 512 return;
513 513
@@ -552,7 +552,7 @@ bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
552 bfa_trc(port->fcs, rx_fchs->d_id); 552 bfa_trc(port->fcs, rx_fchs->d_id);
553 bfa_trc(port->fcs, rx_len); 553 bfa_trc(port->fcs, rx_len);
554 554
555 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 555 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
556 if (!fcxp) 556 if (!fcxp)
557 return; 557 return;
558 558
@@ -684,7 +684,7 @@ bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
684 bfa_trc(port->fcs, rx_fchs->d_id); 684 bfa_trc(port->fcs, rx_fchs->d_id);
685 bfa_trc(port->fcs, rx_fchs->s_id); 685 bfa_trc(port->fcs, rx_fchs->s_id);
686 686
687 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 687 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
688 if (!fcxp) 688 if (!fcxp)
689 return; 689 return;
690 690
@@ -1696,10 +1696,11 @@ bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1696 1696
1697 bfa_trc(port->fcs, port->port_cfg.pwwn); 1697 bfa_trc(port->fcs, port->port_cfg.pwwn);
1698 1698
1699 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1699 fcxp = fcxp_alloced ? fcxp_alloced :
1700 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1700 if (!fcxp) { 1701 if (!fcxp) {
1701 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1702 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1702 bfa_fcs_lport_fdmi_send_rhba, fdmi); 1703 bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
1703 return; 1704 return;
1704 } 1705 }
1705 fdmi->fcxp = fcxp; 1706 fdmi->fcxp = fcxp;
@@ -1970,10 +1971,11 @@ bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1970 1971
1971 bfa_trc(port->fcs, port->port_cfg.pwwn); 1972 bfa_trc(port->fcs, port->port_cfg.pwwn);
1972 1973
1973 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1974 fcxp = fcxp_alloced ? fcxp_alloced :
1975 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1974 if (!fcxp) { 1976 if (!fcxp) {
1975 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 1977 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1976 bfa_fcs_lport_fdmi_send_rprt, fdmi); 1978 bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
1977 return; 1979 return;
1978 } 1980 }
1979 fdmi->fcxp = fcxp; 1981 fdmi->fcxp = fcxp;
@@ -2185,10 +2187,11 @@ bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2185 2187
2186 bfa_trc(port->fcs, port->port_cfg.pwwn); 2188 bfa_trc(port->fcs, port->port_cfg.pwwn);
2187 2189
2188 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2190 fcxp = fcxp_alloced ? fcxp_alloced :
2191 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2189 if (!fcxp) { 2192 if (!fcxp) {
2190 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, 2193 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2191 bfa_fcs_lport_fdmi_send_rpa, fdmi); 2194 bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
2192 return; 2195 return;
2193 } 2196 }
2194 fdmi->fcxp = fcxp; 2197 fdmi->fcxp = fcxp;
@@ -2775,10 +2778,11 @@ bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2775 2778
2776 bfa_trc(port->fcs, port->pid); 2779 bfa_trc(port->fcs, port->pid);
2777 2780
2778 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2781 fcxp = fcxp_alloced ? fcxp_alloced :
2782 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2779 if (!fcxp) { 2783 if (!fcxp) {
2780 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2784 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2781 bfa_fcs_lport_ms_send_gmal, ms); 2785 bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
2782 return; 2786 return;
2783 } 2787 }
2784 ms->fcxp = fcxp; 2788 ms->fcxp = fcxp;
@@ -2975,10 +2979,11 @@ bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2975 2979
2976 bfa_trc(port->fcs, port->pid); 2980 bfa_trc(port->fcs, port->pid);
2977 2981
2978 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2982 fcxp = fcxp_alloced ? fcxp_alloced :
2983 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2979 if (!fcxp) { 2984 if (!fcxp) {
2980 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 2985 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2981 bfa_fcs_lport_ms_send_gfn, ms); 2986 bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
2982 return; 2987 return;
2983 } 2988 }
2984 ms->fcxp = fcxp; 2989 ms->fcxp = fcxp;
@@ -3051,11 +3056,12 @@ bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3051 3056
3052 bfa_trc(port->fcs, port->pid); 3057 bfa_trc(port->fcs, port->pid);
3053 3058
3054 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3059 fcxp = fcxp_alloced ? fcxp_alloced :
3060 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3055 if (!fcxp) { 3061 if (!fcxp) {
3056 port->stats.ms_plogi_alloc_wait++; 3062 port->stats.ms_plogi_alloc_wait++;
3057 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, 3063 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3058 bfa_fcs_lport_ms_send_plogi, ms); 3064 bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
3059 return; 3065 return;
3060 } 3066 }
3061 ms->fcxp = fcxp; 3067 ms->fcxp = fcxp;
@@ -3809,11 +3815,12 @@ bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3809 3815
3810 bfa_trc(port->fcs, port->pid); 3816 bfa_trc(port->fcs, port->pid);
3811 3817
3812 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3818 fcxp = fcxp_alloced ? fcxp_alloced :
3819 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3813 if (!fcxp) { 3820 if (!fcxp) {
3814 port->stats.ns_plogi_alloc_wait++; 3821 port->stats.ns_plogi_alloc_wait++;
3815 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3822 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3816 bfa_fcs_lport_ns_send_plogi, ns); 3823 bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
3817 return; 3824 return;
3818 } 3825 }
3819 ns->fcxp = fcxp; 3826 ns->fcxp = fcxp;
@@ -3909,11 +3916,12 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3909 3916
3910 bfa_trc(port->fcs, port->port_cfg.pwwn); 3917 bfa_trc(port->fcs, port->port_cfg.pwwn);
3911 3918
3912 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 3919 fcxp = fcxp_alloced ? fcxp_alloced :
3920 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3913 if (!fcxp) { 3921 if (!fcxp) {
3914 port->stats.ns_rspnid_alloc_wait++; 3922 port->stats.ns_rspnid_alloc_wait++;
3915 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 3923 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
3916 bfa_fcs_lport_ns_send_rspn_id, ns); 3924 bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
3917 return; 3925 return;
3918 } 3926 }
3919 ns->fcxp = fcxp; 3927 ns->fcxp = fcxp;
@@ -4010,11 +4018,12 @@ bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4010 4018
4011 bfa_trc(port->fcs, port->port_cfg.pwwn); 4019 bfa_trc(port->fcs, port->port_cfg.pwwn);
4012 4020
4013 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4021 fcxp = fcxp_alloced ? fcxp_alloced :
4022 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4014 if (!fcxp) { 4023 if (!fcxp) {
4015 port->stats.ns_rftid_alloc_wait++; 4024 port->stats.ns_rftid_alloc_wait++;
4016 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4025 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4017 bfa_fcs_lport_ns_send_rft_id, ns); 4026 bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
4018 return; 4027 return;
4019 } 4028 }
4020 ns->fcxp = fcxp; 4029 ns->fcxp = fcxp;
@@ -4083,11 +4092,12 @@ bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4083 4092
4084 bfa_trc(port->fcs, port->port_cfg.pwwn); 4093 bfa_trc(port->fcs, port->port_cfg.pwwn);
4085 4094
4086 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4095 fcxp = fcxp_alloced ? fcxp_alloced :
4096 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4087 if (!fcxp) { 4097 if (!fcxp) {
4088 port->stats.ns_rffid_alloc_wait++; 4098 port->stats.ns_rffid_alloc_wait++;
4089 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4099 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4090 bfa_fcs_lport_ns_send_rff_id, ns); 4100 bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
4091 return; 4101 return;
4092 } 4102 }
4093 ns->fcxp = fcxp; 4103 ns->fcxp = fcxp;
@@ -4166,11 +4176,12 @@ bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4166 4176
4167 bfa_trc(port->fcs, port->pid); 4177 bfa_trc(port->fcs, port->pid);
4168 4178
4169 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4179 fcxp = fcxp_alloced ? fcxp_alloced :
4180 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4170 if (!fcxp) { 4181 if (!fcxp) {
4171 port->stats.ns_gidft_alloc_wait++; 4182 port->stats.ns_gidft_alloc_wait++;
4172 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4183 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4173 bfa_fcs_lport_ns_send_gid_ft, ns); 4184 bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
4174 return; 4185 return;
4175 } 4186 }
4176 ns->fcxp = fcxp; 4187 ns->fcxp = fcxp;
@@ -4419,11 +4430,12 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
4419 memset(symbl, 0, sizeof(symbl)); 4430 memset(symbl, 0, sizeof(symbl));
4420 bfa_trc(port->fcs, port->port_cfg.pwwn); 4431 bfa_trc(port->fcs, port->port_cfg.pwwn);
4421 4432
4422 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4433 fcxp = fcxp_alloced ? fcxp_alloced :
4434 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
4423 if (!fcxp) { 4435 if (!fcxp) {
4424 port->stats.ns_rspnid_alloc_wait++; 4436 port->stats.ns_rspnid_alloc_wait++;
4425 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, 4437 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4426 bfa_fcs_lport_ns_util_send_rspn_id, ns); 4438 bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE);
4427 return; 4439 return;
4428 } 4440 }
4429 4441
@@ -4631,10 +4643,11 @@ bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4631 bfa_trc(port->fcs, port->pid); 4643 bfa_trc(port->fcs, port->pid);
4632 bfa_trc(port->fcs, port->port_cfg.pwwn); 4644 bfa_trc(port->fcs, port->port_cfg.pwwn);
4633 4645
4634 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 4646 fcxp = fcxp_alloced ? fcxp_alloced :
4647 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
4635 if (!fcxp) { 4648 if (!fcxp) {
4636 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, 4649 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
4637 bfa_fcs_lport_scn_send_scr, scn); 4650 bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
4638 return; 4651 return;
4639 } 4652 }
4640 scn->fcxp = fcxp; 4653 scn->fcxp = fcxp;
@@ -4716,7 +4729,7 @@ bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
4716 4729
4717 bfa_trc(port->fcs, rx_fchs->s_id); 4730 bfa_trc(port->fcs, rx_fchs->s_id);
4718 4731
4719 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 4732 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
4720 if (!fcxp) 4733 if (!fcxp)
4721 return; 4734 return;
4722 4735
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index fa2df04d9662..8efa3a3ded1d 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -1372,10 +1372,11 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1372 1372
1373 bfa_trc(rport->fcs, rport->pwwn); 1373 bfa_trc(rport->fcs, rport->pwwn);
1374 1374
1375 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1375 fcxp = fcxp_alloced ? fcxp_alloced :
1376 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1376 if (!fcxp) { 1377 if (!fcxp) {
1377 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1378 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1378 bfa_fcs_rport_send_plogi, rport); 1379 bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1379 return; 1380 return;
1380 } 1381 }
1381 rport->fcxp = fcxp; 1382 rport->fcxp = fcxp;
@@ -1492,10 +1493,11 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1492 bfa_trc(rport->fcs, rport->pwwn); 1493 bfa_trc(rport->fcs, rport->pwwn);
1493 bfa_trc(rport->fcs, rport->reply_oxid); 1494 bfa_trc(rport->fcs, rport->reply_oxid);
1494 1495
1495 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1496 fcxp = fcxp_alloced ? fcxp_alloced :
1497 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1496 if (!fcxp) { 1498 if (!fcxp) {
1497 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1499 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1498 bfa_fcs_rport_send_plogiacc, rport); 1500 bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1499 return; 1501 return;
1500 } 1502 }
1501 rport->fcxp = fcxp; 1503 rport->fcxp = fcxp;
@@ -1524,10 +1526,11 @@ bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1524 1526
1525 bfa_trc(rport->fcs, rport->pwwn); 1527 bfa_trc(rport->fcs, rport->pwwn);
1526 1528
1527 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1529 fcxp = fcxp_alloced ? fcxp_alloced :
1530 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1528 if (!fcxp) { 1531 if (!fcxp) {
1529 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1532 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1530 bfa_fcs_rport_send_adisc, rport); 1533 bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1531 return; 1534 return;
1532 } 1535 }
1533 rport->fcxp = fcxp; 1536 rport->fcxp = fcxp;
@@ -1587,10 +1590,11 @@ bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1587 1590
1588 bfa_trc(rport->fcs, rport->pid); 1591 bfa_trc(rport->fcs, rport->pid);
1589 1592
1590 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1593 fcxp = fcxp_alloced ? fcxp_alloced :
1594 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1591 if (!fcxp) { 1595 if (!fcxp) {
1592 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1596 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1593 bfa_fcs_rport_send_nsdisc, rport); 1597 bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1594 return; 1598 return;
1595 } 1599 }
1596 rport->fcxp = fcxp; 1600 rport->fcxp = fcxp;
@@ -1743,10 +1747,11 @@ bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1743 1747
1744 port = rport->port; 1748 port = rport->port;
1745 1749
1746 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 1750 fcxp = fcxp_alloced ? fcxp_alloced :
1751 bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1747 if (!fcxp) { 1752 if (!fcxp) {
1748 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, 1753 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1749 bfa_fcs_rport_send_logo, rport); 1754 bfa_fcs_rport_send_logo, rport, BFA_FALSE);
1750 return; 1755 return;
1751 } 1756 }
1752 rport->fcxp = fcxp; 1757 rport->fcxp = fcxp;
@@ -1780,7 +1785,7 @@ bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1780 1785
1781 port = rport->port; 1786 port = rport->port;
1782 1787
1783 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1788 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1784 if (!fcxp) 1789 if (!fcxp)
1785 return; 1790 return;
1786 1791
@@ -1851,7 +1856,7 @@ bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1851 bfa_fcs_itnim_is_initiator(rport->itnim); 1856 bfa_fcs_itnim_is_initiator(rport->itnim);
1852 } 1857 }
1853 1858
1854 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1859 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1855 if (!fcxp) 1860 if (!fcxp)
1856 return; 1861 return;
1857 1862
@@ -1888,7 +1893,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1888 1893
1889 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); 1894 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1890 1895
1891 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1896 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1892 if (!fcxp) 1897 if (!fcxp)
1893 return; 1898 return;
1894 1899
@@ -1922,7 +1927,7 @@ bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1922 */ 1927 */
1923 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) { 1928 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1924 1929
1925 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 1930 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1926 if (!fcxp) 1931 if (!fcxp)
1927 return; 1932 return;
1928 1933
@@ -2511,7 +2516,7 @@ bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2511 2516
2512 bfa_trc(rport->fcs, rport->pid); 2517 bfa_trc(rport->fcs, rport->pid);
2513 2518
2514 fcxp = bfa_fcs_fcxp_alloc(port->fcs); 2519 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2515 if (!fcxp) 2520 if (!fcxp)
2516 return; 2521 return;
2517 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 2522 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
@@ -2537,7 +2542,7 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2537 2542
2538 bfa_trc(rport->fcs, rx_fchs->s_id); 2543 bfa_trc(rport->fcs, rx_fchs->s_id);
2539 2544
2540 fcxp = bfa_fcs_fcxp_alloc(rport->fcs); 2545 fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2541 if (!fcxp) 2546 if (!fcxp)
2542 return; 2547 return;
2543 2548
@@ -2943,10 +2948,11 @@ bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2943 2948
2944 bfa_trc(rport->fcs, rport->pwwn); 2949 bfa_trc(rport->fcs, rport->pwwn);
2945 2950
2946 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); 2951 fcxp = fcxp_alloced ? fcxp_alloced :
2952 bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2947 if (!fcxp) { 2953 if (!fcxp) {
2948 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, 2954 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
2949 bfa_fcs_rpf_send_rpsc2, rpf); 2955 bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
2950 return; 2956 return;
2951 } 2957 }
2952 rpf->fcxp = fcxp; 2958 rpf->fcxp = fcxp;
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 2e856e6710f7..849eac95caed 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -440,9 +440,11 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod)
440 fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod); 440 fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod);
441 memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps); 441 memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
442 442
443 INIT_LIST_HEAD(&mod->fcxp_free_q); 443 INIT_LIST_HEAD(&mod->fcxp_req_free_q);
444 INIT_LIST_HEAD(&mod->fcxp_rsp_free_q);
444 INIT_LIST_HEAD(&mod->fcxp_active_q); 445 INIT_LIST_HEAD(&mod->fcxp_active_q);
445 INIT_LIST_HEAD(&mod->fcxp_unused_q); 446 INIT_LIST_HEAD(&mod->fcxp_req_unused_q);
447 INIT_LIST_HEAD(&mod->fcxp_rsp_unused_q);
446 448
447 mod->fcxp_list = fcxp; 449 mod->fcxp_list = fcxp;
448 450
@@ -450,7 +452,14 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod)
450 fcxp->fcxp_mod = mod; 452 fcxp->fcxp_mod = mod;
451 fcxp->fcxp_tag = i; 453 fcxp->fcxp_tag = i;
452 454
453 list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 455 if (i < (mod->num_fcxps / 2)) {
456 list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q);
457 fcxp->req_rsp = BFA_TRUE;
458 } else {
459 list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q);
460 fcxp->req_rsp = BFA_FALSE;
461 }
462
454 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); 463 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
455 fcxp->reqq_waiting = BFA_FALSE; 464 fcxp->reqq_waiting = BFA_FALSE;
456 465
@@ -514,7 +523,8 @@ bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
514 if (!cfg->drvcfg.min_cfg) 523 if (!cfg->drvcfg.min_cfg)
515 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; 524 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
516 525
517 INIT_LIST_HEAD(&mod->wait_q); 526 INIT_LIST_HEAD(&mod->req_wait_q);
527 INIT_LIST_HEAD(&mod->rsp_wait_q);
518 528
519 claim_fcxps_mem(mod); 529 claim_fcxps_mem(mod);
520} 530}
@@ -542,7 +552,8 @@ bfa_fcxp_iocdisable(struct bfa_s *bfa)
542 struct list_head *qe, *qen; 552 struct list_head *qe, *qen;
543 553
544 /* Enqueue unused fcxp resources to free_q */ 554 /* Enqueue unused fcxp resources to free_q */
545 list_splice_tail_init(&mod->fcxp_unused_q, &mod->fcxp_free_q); 555 list_splice_tail_init(&mod->fcxp_req_unused_q, &mod->fcxp_req_free_q);
556 list_splice_tail_init(&mod->fcxp_rsp_unused_q, &mod->fcxp_rsp_free_q);
546 557
547 list_for_each_safe(qe, qen, &mod->fcxp_active_q) { 558 list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
548 fcxp = (struct bfa_fcxp_s *) qe; 559 fcxp = (struct bfa_fcxp_s *) qe;
@@ -559,11 +570,14 @@ bfa_fcxp_iocdisable(struct bfa_s *bfa)
559} 570}
560 571
561static struct bfa_fcxp_s * 572static struct bfa_fcxp_s *
562bfa_fcxp_get(struct bfa_fcxp_mod_s *fm) 573bfa_fcxp_get(struct bfa_fcxp_mod_s *fm, bfa_boolean_t req)
563{ 574{
564 struct bfa_fcxp_s *fcxp; 575 struct bfa_fcxp_s *fcxp;
565 576
566 bfa_q_deq(&fm->fcxp_free_q, &fcxp); 577 if (req)
578 bfa_q_deq(&fm->fcxp_req_free_q, &fcxp);
579 else
580 bfa_q_deq(&fm->fcxp_rsp_free_q, &fcxp);
567 581
568 if (fcxp) 582 if (fcxp)
569 list_add_tail(&fcxp->qe, &fm->fcxp_active_q); 583 list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
@@ -642,7 +656,11 @@ bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
642 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 656 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
643 struct bfa_fcxp_wqe_s *wqe; 657 struct bfa_fcxp_wqe_s *wqe;
644 658
645 bfa_q_deq(&mod->wait_q, &wqe); 659 if (fcxp->req_rsp)
660 bfa_q_deq(&mod->req_wait_q, &wqe);
661 else
662 bfa_q_deq(&mod->rsp_wait_q, &wqe);
663
646 if (wqe) { 664 if (wqe) {
647 bfa_trc(mod->bfa, fcxp->fcxp_tag); 665 bfa_trc(mod->bfa, fcxp->fcxp_tag);
648 666
@@ -657,7 +675,11 @@ bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
657 675
658 WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); 676 WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
659 list_del(&fcxp->qe); 677 list_del(&fcxp->qe);
660 list_add_tail(&fcxp->qe, &mod->fcxp_free_q); 678
679 if (fcxp->req_rsp)
680 list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q);
681 else
682 list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q);
661} 683}
662 684
663static void 685static void
@@ -900,21 +922,23 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
900 * Address (given the sge index). 922 * Address (given the sge index).
901 * @param[in] get_rsp_sglen function ptr to be called to get a response SG 923 * @param[in] get_rsp_sglen function ptr to be called to get a response SG
902 * len (given the sge index). 924 * len (given the sge index).
925 * @param[in] req Allocated FCXP is used to send req or rsp?
926 * request - BFA_TRUE, response - BFA_FALSE
903 * 927 *
904 * @return FCXP instance. NULL on failure. 928 * @return FCXP instance. NULL on failure.
905 */ 929 */
906struct bfa_fcxp_s * 930struct bfa_fcxp_s *
907bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, 931bfa_fcxp_req_rsp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
908 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 932 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
909 bfa_fcxp_get_sglen_t req_sglen_cbfn, 933 bfa_fcxp_get_sglen_t req_sglen_cbfn,
910 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 934 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
911 bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 935 bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req)
912{ 936{
913 struct bfa_fcxp_s *fcxp = NULL; 937 struct bfa_fcxp_s *fcxp = NULL;
914 938
915 WARN_ON(bfa == NULL); 939 WARN_ON(bfa == NULL);
916 940
917 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa)); 941 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa), req);
918 if (fcxp == NULL) 942 if (fcxp == NULL)
919 return NULL; 943 return NULL;
920 944
@@ -1071,17 +1095,20 @@ bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
1071} 1095}
1072 1096
1073void 1097void
1074bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 1098bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
1075 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg, 1099 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg,
1076 void *caller, int nreq_sgles, 1100 void *caller, int nreq_sgles,
1077 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 1101 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
1078 bfa_fcxp_get_sglen_t req_sglen_cbfn, 1102 bfa_fcxp_get_sglen_t req_sglen_cbfn,
1079 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 1103 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
1080 bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 1104 bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req)
1081{ 1105{
1082 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1106 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1083 1107
1084 WARN_ON(!list_empty(&mod->fcxp_free_q)); 1108 if (req)
1109 WARN_ON(!list_empty(&mod->fcxp_req_free_q));
1110 else
1111 WARN_ON(!list_empty(&mod->fcxp_rsp_free_q));
1085 1112
1086 wqe->alloc_cbfn = alloc_cbfn; 1113 wqe->alloc_cbfn = alloc_cbfn;
1087 wqe->alloc_cbarg = alloc_cbarg; 1114 wqe->alloc_cbarg = alloc_cbarg;
@@ -1094,7 +1121,10 @@ bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
1094 wqe->rsp_sga_cbfn = rsp_sga_cbfn; 1121 wqe->rsp_sga_cbfn = rsp_sga_cbfn;
1095 wqe->rsp_sglen_cbfn = rsp_sglen_cbfn; 1122 wqe->rsp_sglen_cbfn = rsp_sglen_cbfn;
1096 1123
1097 list_add_tail(&wqe->qe, &mod->wait_q); 1124 if (req)
1125 list_add_tail(&wqe->qe, &mod->req_wait_q);
1126 else
1127 list_add_tail(&wqe->qe, &mod->rsp_wait_q);
1098} 1128}
1099 1129
1100void 1130void
@@ -1102,7 +1132,8 @@ bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
1102{ 1132{
1103 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1133 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1104 1134
1105 WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe)); 1135 WARN_ON(!bfa_q_is_on_q(&mod->req_wait_q, wqe) ||
1136 !bfa_q_is_on_q(&mod->rsp_wait_q, wqe));
1106 list_del(&wqe->qe); 1137 list_del(&wqe->qe);
1107} 1138}
1108 1139
@@ -1153,8 +1184,13 @@ bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw)
1153 int i; 1184 int i;
1154 1185
1155 for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) { 1186 for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) {
1156 bfa_q_deq_tail(&mod->fcxp_free_q, &qe); 1187 if (i < ((mod->num_fcxps - num_fcxp_fw) / 2)) {
1157 list_add_tail(qe, &mod->fcxp_unused_q); 1188 bfa_q_deq_tail(&mod->fcxp_req_free_q, &qe);
1189 list_add_tail(qe, &mod->fcxp_req_unused_q);
1190 } else {
1191 bfa_q_deq_tail(&mod->fcxp_rsp_free_q, &qe);
1192 list_add_tail(qe, &mod->fcxp_rsp_unused_q);
1193 }
1158 } 1194 }
1159} 1195}
1160 1196
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index f30067564639..4da2b58c8eb7 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -97,10 +97,13 @@ struct bfa_fcxp_mod_s {
97 struct bfa_s *bfa; /* backpointer to BFA */ 97 struct bfa_s *bfa; /* backpointer to BFA */
98 struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */ 98 struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */
99 u16 num_fcxps; /* max num FCXP requests */ 99 u16 num_fcxps; /* max num FCXP requests */
100 struct list_head fcxp_free_q; /* free FCXPs */ 100 struct list_head fcxp_req_free_q; /* free FCXPs used for sending req */
101 struct list_head fcxp_active_q; /* active FCXPs */ 101 struct list_head fcxp_rsp_free_q; /* free FCXPs used for sending req */
102 struct list_head wait_q; /* wait queue for free fcxp */ 102 struct list_head fcxp_active_q; /* active FCXPs */
103 struct list_head fcxp_unused_q; /* unused fcxps */ 103 struct list_head req_wait_q; /* wait queue for free req_fcxp */
104 struct list_head rsp_wait_q; /* wait queue for free rsp_fcxp */
105 struct list_head fcxp_req_unused_q; /* unused req_fcxps */
106 struct list_head fcxp_rsp_unused_q; /* unused rsp_fcxps */
104 u32 req_pld_sz; 107 u32 req_pld_sz;
105 u32 rsp_pld_sz; 108 u32 rsp_pld_sz;
106 struct bfa_mem_dma_s dma_seg[BFA_FCXP_DMA_SEGS]; 109 struct bfa_mem_dma_s dma_seg[BFA_FCXP_DMA_SEGS];
@@ -197,6 +200,7 @@ struct bfa_fcxp_s {
197 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */ 200 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
198 struct bfa_reqq_wait_s reqq_wqe; 201 struct bfa_reqq_wait_s reqq_wqe;
199 bfa_boolean_t reqq_waiting; 202 bfa_boolean_t reqq_waiting;
203 bfa_boolean_t req_rsp; /* Used to track req/rsp fcxp */
200}; 204};
201 205
202struct bfa_fcxp_wqe_s { 206struct bfa_fcxp_wqe_s {
@@ -586,20 +590,22 @@ void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
586/* 590/*
587 * bfa fcxp API functions 591 * bfa fcxp API functions
588 */ 592 */
589struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa, 593struct bfa_fcxp_s *bfa_fcxp_req_rsp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
590 int nreq_sgles, int nrsp_sgles, 594 int nreq_sgles, int nrsp_sgles,
591 bfa_fcxp_get_sgaddr_t get_req_sga, 595 bfa_fcxp_get_sgaddr_t get_req_sga,
592 bfa_fcxp_get_sglen_t get_req_sglen, 596 bfa_fcxp_get_sglen_t get_req_sglen,
593 bfa_fcxp_get_sgaddr_t get_rsp_sga, 597 bfa_fcxp_get_sgaddr_t get_rsp_sga,
594 bfa_fcxp_get_sglen_t get_rsp_sglen); 598 bfa_fcxp_get_sglen_t get_rsp_sglen,
595void bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 599 bfa_boolean_t req);
600void bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
596 bfa_fcxp_alloc_cbfn_t alloc_cbfn, 601 bfa_fcxp_alloc_cbfn_t alloc_cbfn,
597 void *cbarg, void *bfad_fcxp, 602 void *cbarg, void *bfad_fcxp,
598 int nreq_sgles, int nrsp_sgles, 603 int nreq_sgles, int nrsp_sgles,
599 bfa_fcxp_get_sgaddr_t get_req_sga, 604 bfa_fcxp_get_sgaddr_t get_req_sga,
600 bfa_fcxp_get_sglen_t get_req_sglen, 605 bfa_fcxp_get_sglen_t get_req_sglen,
601 bfa_fcxp_get_sgaddr_t get_rsp_sga, 606 bfa_fcxp_get_sgaddr_t get_rsp_sga,
602 bfa_fcxp_get_sglen_t get_rsp_sglen); 607 bfa_fcxp_get_sglen_t get_rsp_sglen,
608 bfa_boolean_t req);
603void bfa_fcxp_walloc_cancel(struct bfa_s *bfa, 609void bfa_fcxp_walloc_cancel(struct bfa_s *bfa,
604 struct bfa_fcxp_wqe_s *wqe); 610 struct bfa_fcxp_wqe_s *wqe);
605void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp); 611void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp);
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index d9463d8249e3..0db905531a70 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -2955,13 +2955,13 @@ bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
2955 spin_lock_irqsave(&bfad->bfad_lock, flags); 2955 spin_lock_irqsave(&bfad->bfad_lock, flags);
2956 2956
2957 /* Allocate bfa_fcxp structure */ 2957 /* Allocate bfa_fcxp structure */
2958 hal_fcxp = bfa_fcxp_alloc(drv_fcxp, &bfad->bfa, 2958 hal_fcxp = bfa_fcxp_req_rsp_alloc(drv_fcxp, &bfad->bfa,
2959 drv_fcxp->num_req_sgles, 2959 drv_fcxp->num_req_sgles,
2960 drv_fcxp->num_rsp_sgles, 2960 drv_fcxp->num_rsp_sgles,
2961 bfad_fcxp_get_req_sgaddr_cb, 2961 bfad_fcxp_get_req_sgaddr_cb,
2962 bfad_fcxp_get_req_sglen_cb, 2962 bfad_fcxp_get_req_sglen_cb,
2963 bfad_fcxp_get_rsp_sgaddr_cb, 2963 bfad_fcxp_get_rsp_sgaddr_cb,
2964 bfad_fcxp_get_rsp_sglen_cb); 2964 bfad_fcxp_get_rsp_sglen_cb, BFA_TRUE);
2965 if (!hal_fcxp) { 2965 if (!hal_fcxp) {
2966 bfa_trc(bfad, 0); 2966 bfa_trc(bfad, 0);
2967 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2967 spin_unlock_irqrestore(&bfad->bfad_lock, flags);