|
@@ -1210,8 +1210,10 @@ lpfc_get_stats(struct Scsi_Host *shost)
|
|
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
|
|
struct lpfc_sli *psli = &phba->sli;
|
|
|
struct fc_host_statistics *hs = &phba->link_stats;
|
|
|
+ struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
|
|
|
LPFC_MBOXQ_t *pmboxq;
|
|
|
MAILBOX_t *pmb;
|
|
|
+ unsigned long seconds;
|
|
|
int rc = 0;
|
|
|
|
|
|
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
@@ -1272,22 +1274,103 @@ lpfc_get_stats(struct Scsi_Host *shost)
|
|
|
hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
|
|
|
hs->error_frames = pmb->un.varRdLnk.crcCnt;
|
|
|
|
|
|
+ hs->link_failure_count -= lso->link_failure_count;
|
|
|
+ hs->loss_of_sync_count -= lso->loss_of_sync_count;
|
|
|
+ hs->loss_of_signal_count -= lso->loss_of_signal_count;
|
|
|
+ hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
|
|
|
+ hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
|
|
|
+ hs->invalid_crc_count -= lso->invalid_crc_count;
|
|
|
+ hs->error_frames -= lso->error_frames;
|
|
|
+
|
|
|
if (phba->fc_topology == TOPOLOGY_LOOP) {
|
|
|
hs->lip_count = (phba->fc_eventTag >> 1);
|
|
|
+ hs->lip_count -= lso->link_events;
|
|
|
hs->nos_count = -1;
|
|
|
} else {
|
|
|
hs->lip_count = -1;
|
|
|
hs->nos_count = (phba->fc_eventTag >> 1);
|
|
|
+ hs->nos_count -= lso->link_events;
|
|
|
}
|
|
|
|
|
|
hs->dumped_frames = -1;
|
|
|
|
|
|
-/* FIX ME */
|
|
|
- /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/
|
|
|
+ seconds = get_seconds();
|
|
|
+ if (seconds < psli->stats_start)
|
|
|
+ hs->seconds_since_last_reset = seconds +
|
|
|
+ ((unsigned long)-1 - psli->stats_start);
|
|
|
+ else
|
|
|
+ hs->seconds_since_last_reset = seconds - psli->stats_start;
|
|
|
|
|
|
return hs;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+lpfc_reset_stats(struct Scsi_Host *shost)
|
|
|
+{
|
|
|
+ struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
|
|
+ struct lpfc_sli *psli = &phba->sli;
|
|
|
+ struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
|
|
|
+ LPFC_MBOXQ_t *pmboxq;
|
|
|
+ MAILBOX_t *pmb;
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
|
+ if (!pmboxq)
|
|
|
+ return;
|
|
|
+ memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
|
|
|
+
|
|
|
+ pmb = &pmboxq->mb;
|
|
|
+ pmb->mbxCommand = MBX_READ_STATUS;
|
|
|
+ pmb->mbxOwner = OWN_HOST;
|
|
|
+ pmb->un.varWords[0] = 0x1; /* reset request */
|
|
|
+ pmboxq->context1 = NULL;
|
|
|
+
|
|
|
+ if ((phba->fc_flag & FC_OFFLINE_MODE) ||
|
|
|
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
|
|
|
+ else
|
|
|
+ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
|
|
|
+
|
|
|
+ if (rc != MBX_SUCCESS) {
|
|
|
+ if (rc == MBX_TIMEOUT)
|
|
|
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
|
|
+ else
|
|
|
+ mempool_free(pmboxq, phba->mbox_mem_pool);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
|
|
|
+ pmb->mbxCommand = MBX_READ_LNK_STAT;
|
|
|
+ pmb->mbxOwner = OWN_HOST;
|
|
|
+ pmboxq->context1 = NULL;
|
|
|
+
|
|
|
+ if ((phba->fc_flag & FC_OFFLINE_MODE) ||
|
|
|
+ (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
|
|
|
+ else
|
|
|
+ rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
|
|
|
+
|
|
|
+ if (rc != MBX_SUCCESS) {
|
|
|
+ if (rc == MBX_TIMEOUT)
|
|
|
+ pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
|
|
+ else
|
|
|
+ mempool_free( pmboxq, phba->mbox_mem_pool);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
|
|
|
+ lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
|
|
|
+ lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
|
|
|
+ lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
|
|
|
+ lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
|
|
|
+ lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
|
|
|
+ lso->error_frames = pmb->un.varRdLnk.crcCnt;
|
|
|
+ lso->link_events = (phba->fc_eventTag >> 1);
|
|
|
+
|
|
|
+ psli->stats_start = get_seconds();
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* The LPFC driver treats linkdown handling as target loss events so there
|
|
@@ -1431,8 +1514,7 @@ struct fc_function_template lpfc_transport_functions = {
|
|
|
*/
|
|
|
|
|
|
.get_fc_host_stats = lpfc_get_stats,
|
|
|
-
|
|
|
- /* the LPFC driver doesn't support resetting stats yet */
|
|
|
+ .reset_fc_host_stats = lpfc_reset_stats,
|
|
|
|
|
|
.dd_fcrport_size = sizeof(struct lpfc_rport_data),
|
|
|
.show_rport_maxframe_size = 1,
|