aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_svc.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-07-20 20:02:11 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 06:48:52 -0400
commit37ea0558b87abb151245bc750070a4dcda490aca (patch)
tree352d00d22b8f9c91ace2dc8d72dc465deb6ffa7b /drivers/scsi/bfa/bfa_svc.c
parent42a8e6e298f39518445785c53a16357267db37ef (diff)
[SCSI] bfa: Added support to collect and reset fcport stats
- Added support to collect and reset fcport stats. - Modified design to allow multiple requests for fcport stats. - fcport will remember the stats request in its stats_pending queue and service each of the queued requests after receiving a firmware response for the prior request. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_svc.c')
-rw-r--r--drivers/scsi/bfa/bfa_svc.c130
1 files changed, 71 insertions, 59 deletions
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 6e1ed9a9aa2a..9884d6edfb57 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -2910,6 +2910,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
2910 2910
2911 port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 2911 port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
2912 2912
2913 INIT_LIST_HEAD(&fcport->stats_pending_q);
2914 INIT_LIST_HEAD(&fcport->statsclr_pending_q);
2915
2913 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 2916 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
2914} 2917}
2915 2918
@@ -3138,30 +3141,38 @@ bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
3138static void 3141static void
3139__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3142__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
3140{ 3143{
3141 struct bfa_fcport_s *fcport = cbarg; 3144 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg;
3145 struct bfa_cb_pending_q_s *cb;
3146 struct list_head *qe, *qen;
3147 union bfa_fcport_stats_u *ret;
3142 3148
3143 if (complete) { 3149 if (complete) {
3144 if (fcport->stats_status == BFA_STATUS_OK) { 3150 struct timeval tv;
3145 struct timeval tv; 3151 if (fcport->stats_status == BFA_STATUS_OK)
3146 3152 do_gettimeofday(&tv);
3147 /* Swap FC QoS or FCoE stats */ 3153
3148 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 3154 list_for_each_safe(qe, qen, &fcport->stats_pending_q) {
3149 bfa_fcport_qos_stats_swap( 3155 bfa_q_deq(&fcport->stats_pending_q, &qe);
3150 &fcport->stats_ret->fcqos, 3156 cb = (struct bfa_cb_pending_q_s *)qe;
3151 &fcport->stats->fcqos); 3157 if (fcport->stats_status == BFA_STATUS_OK) {
3152 } else { 3158 ret = (union bfa_fcport_stats_u *)cb->data;
3153 bfa_fcport_fcoe_stats_swap( 3159 /* Swap FC QoS or FCoE stats */
3154 &fcport->stats_ret->fcoe, 3160 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
3155 &fcport->stats->fcoe); 3161 bfa_fcport_qos_stats_swap(&ret->fcqos,
3156 3162 &fcport->stats->fcqos);
3157 do_gettimeofday(&tv); 3163 else {
3158 fcport->stats_ret->fcoe.secs_reset = 3164 bfa_fcport_fcoe_stats_swap(&ret->fcoe,
3165 &fcport->stats->fcoe);
3166 ret->fcoe.secs_reset =
3159 tv.tv_sec - fcport->stats_reset_time; 3167 tv.tv_sec - fcport->stats_reset_time;
3168 }
3160 } 3169 }
3170 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
3171 fcport->stats_status);
3161 } 3172 }
3162 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3173 fcport->stats_status = BFA_STATUS_OK;
3163 } else { 3174 } else {
3164 fcport->stats_busy = BFA_FALSE; 3175 INIT_LIST_HEAD(&fcport->stats_pending_q);
3165 fcport->stats_status = BFA_STATUS_OK; 3176 fcport->stats_status = BFA_STATUS_OK;
3166 } 3177 }
3167} 3178}
@@ -3179,8 +3190,7 @@ bfa_fcport_stats_get_timeout(void *cbarg)
3179 } 3190 }
3180 3191
3181 fcport->stats_status = BFA_STATUS_ETIMER; 3192 fcport->stats_status = BFA_STATUS_ETIMER;
3182 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get, 3193 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3183 fcport);
3184} 3194}
3185 3195
3186static void 3196static void
@@ -3210,7 +3220,9 @@ bfa_fcport_send_stats_get(void *cbarg)
3210static void 3220static void
3211__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3221__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3212{ 3222{
3213 struct bfa_fcport_s *fcport = cbarg; 3223 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3224 struct bfa_cb_pending_q_s *cb;
3225 struct list_head *qe, *qen;
3214 3226
3215 if (complete) { 3227 if (complete) {
3216 struct timeval tv; 3228 struct timeval tv;
@@ -3220,10 +3232,15 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3220 */ 3232 */
3221 do_gettimeofday(&tv); 3233 do_gettimeofday(&tv);
3222 fcport->stats_reset_time = tv.tv_sec; 3234 fcport->stats_reset_time = tv.tv_sec;
3223 3235 list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) {
3224 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); 3236 bfa_q_deq(&fcport->statsclr_pending_q, &qe);
3237 cb = (struct bfa_cb_pending_q_s *)qe;
3238 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
3239 fcport->stats_status);
3240 }
3241 fcport->stats_status = BFA_STATUS_OK;
3225 } else { 3242 } else {
3226 fcport->stats_busy = BFA_FALSE; 3243 INIT_LIST_HEAD(&fcport->statsclr_pending_q);
3227 fcport->stats_status = BFA_STATUS_OK; 3244 fcport->stats_status = BFA_STATUS_OK;
3228 } 3245 }
3229} 3246}
@@ -3241,8 +3258,7 @@ bfa_fcport_stats_clr_timeout(void *cbarg)
3241 } 3258 }
3242 3259
3243 fcport->stats_status = BFA_STATUS_ETIMER; 3260 fcport->stats_status = BFA_STATUS_ETIMER;
3244 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3261 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3245 __bfa_cb_fcport_stats_clr, fcport);
3246} 3262}
3247 3263
3248static void 3264static void
@@ -3462,28 +3478,26 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3462 /* 3478 /*
3463 * check for timer pop before processing the rsp 3479 * check for timer pop before processing the rsp
3464 */ 3480 */
3465 if (fcport->stats_busy == BFA_FALSE || 3481 if (list_empty(&fcport->stats_pending_q) ||
3466 fcport->stats_status == BFA_STATUS_ETIMER) 3482 (fcport->stats_status == BFA_STATUS_ETIMER))
3467 break; 3483 break;
3468 3484
3469 bfa_timer_stop(&fcport->timer); 3485 bfa_timer_stop(&fcport->timer);
3470 fcport->stats_status = i2hmsg.pstatsget_rsp->status; 3486 fcport->stats_status = i2hmsg.pstatsget_rsp->status;
3471 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3487 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3472 __bfa_cb_fcport_stats_get, fcport);
3473 break; 3488 break;
3474 3489
3475 case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3490 case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
3476 /* 3491 /*
3477 * check for timer pop before processing the rsp 3492 * check for timer pop before processing the rsp
3478 */ 3493 */
3479 if (fcport->stats_busy == BFA_FALSE || 3494 if (list_empty(&fcport->statsclr_pending_q) ||
3480 fcport->stats_status == BFA_STATUS_ETIMER) 3495 (fcport->stats_status == BFA_STATUS_ETIMER))
3481 break; 3496 break;
3482 3497
3483 bfa_timer_stop(&fcport->timer); 3498 bfa_timer_stop(&fcport->timer);
3484 fcport->stats_status = BFA_STATUS_OK; 3499 fcport->stats_status = BFA_STATUS_OK;
3485 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, 3500 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3486 __bfa_cb_fcport_stats_clr, fcport);
3487 break; 3501 break;
3488 3502
3489 case BFI_FCPORT_I2H_ENABLE_AEN: 3503 case BFI_FCPORT_I2H_ENABLE_AEN:
@@ -3815,25 +3829,25 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
3815 * Fetch port statistics (FCQoS or FCoE). 3829 * Fetch port statistics (FCQoS or FCoE).
3816 */ 3830 */
3817bfa_status_t 3831bfa_status_t
3818bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, 3832bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3819 bfa_cb_port_t cbfn, void *cbarg)
3820{ 3833{
3821 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3834 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3822 3835
3823 if (fcport->stats_busy) { 3836 if (bfa_ioc_is_disabled(&bfa->ioc))
3824 bfa_trc(bfa, fcport->stats_busy); 3837 return BFA_STATUS_IOC_DISABLED;
3825 return BFA_STATUS_DEVBUSY;
3826 }
3827 3838
3828 fcport->stats_busy = BFA_TRUE; 3839 if (!list_empty(&fcport->statsclr_pending_q))
3829 fcport->stats_ret = stats; 3840 return BFA_STATUS_DEVBUSY;
3830 fcport->stats_cbfn = cbfn;
3831 fcport->stats_cbarg = cbarg;
3832 3841
3833 bfa_fcport_send_stats_get(fcport); 3842 if (list_empty(&fcport->stats_pending_q)) {
3843 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
3844 bfa_fcport_send_stats_get(fcport);
3845 bfa_timer_start(bfa, &fcport->timer,
3846 bfa_fcport_stats_get_timeout,
3847 fcport, BFA_FCPORT_STATS_TOV);
3848 } else
3849 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
3834 3850
3835 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
3836 fcport, BFA_FCPORT_STATS_TOV);
3837 return BFA_STATUS_OK; 3851 return BFA_STATUS_OK;
3838} 3852}
3839 3853
@@ -3841,27 +3855,25 @@ bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
3841 * Reset port statistics (FCQoS or FCoE). 3855 * Reset port statistics (FCQoS or FCoE).
3842 */ 3856 */
3843bfa_status_t 3857bfa_status_t
3844bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg) 3858bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3845{ 3859{
3846 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3860 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3847 3861
3848 if (fcport->stats_busy) { 3862 if (!list_empty(&fcport->stats_pending_q))
3849 bfa_trc(bfa, fcport->stats_busy);
3850 return BFA_STATUS_DEVBUSY; 3863 return BFA_STATUS_DEVBUSY;
3851 }
3852 3864
3853 fcport->stats_busy = BFA_TRUE; 3865 if (list_empty(&fcport->statsclr_pending_q)) {
3854 fcport->stats_cbfn = cbfn; 3866 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
3855 fcport->stats_cbarg = cbarg; 3867 bfa_fcport_send_stats_clear(fcport);
3868 bfa_timer_start(bfa, &fcport->timer,
3869 bfa_fcport_stats_clr_timeout,
3870 fcport, BFA_FCPORT_STATS_TOV);
3871 } else
3872 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
3856 3873
3857 bfa_fcport_send_stats_clear(fcport);
3858
3859 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
3860 fcport, BFA_FCPORT_STATS_TOV);
3861 return BFA_STATUS_OK; 3874 return BFA_STATUS_OK;
3862} 3875}
3863 3876
3864
3865/* 3877/*
3866 * Fetch port attributes. 3878 * Fetch port attributes.
3867 */ 3879 */