aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c90
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h14
3 files changed, 103 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 5c68cdd8736f..762d623018f3 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1210,8 +1210,10 @@ lpfc_get_stats(struct Scsi_Host *shost)
1210 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; 1210 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
1211 struct lpfc_sli *psli = &phba->sli; 1211 struct lpfc_sli *psli = &phba->sli;
1212 struct fc_host_statistics *hs = &phba->link_stats; 1212 struct fc_host_statistics *hs = &phba->link_stats;
1213 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
1213 LPFC_MBOXQ_t *pmboxq; 1214 LPFC_MBOXQ_t *pmboxq;
1214 MAILBOX_t *pmb; 1215 MAILBOX_t *pmb;
1216 unsigned long seconds;
1215 int rc = 0; 1217 int rc = 0;
1216 1218
1217 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 1219 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -1272,22 +1274,103 @@ lpfc_get_stats(struct Scsi_Host *shost)
1272 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; 1274 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
1273 hs->error_frames = pmb->un.varRdLnk.crcCnt; 1275 hs->error_frames = pmb->un.varRdLnk.crcCnt;
1274 1276
1277 hs->link_failure_count -= lso->link_failure_count;
1278 hs->loss_of_sync_count -= lso->loss_of_sync_count;
1279 hs->loss_of_signal_count -= lso->loss_of_signal_count;
1280 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
1281 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
1282 hs->invalid_crc_count -= lso->invalid_crc_count;
1283 hs->error_frames -= lso->error_frames;
1284
1275 if (phba->fc_topology == TOPOLOGY_LOOP) { 1285 if (phba->fc_topology == TOPOLOGY_LOOP) {
1276 hs->lip_count = (phba->fc_eventTag >> 1); 1286 hs->lip_count = (phba->fc_eventTag >> 1);
1287 hs->lip_count -= lso->link_events;
1277 hs->nos_count = -1; 1288 hs->nos_count = -1;
1278 } else { 1289 } else {
1279 hs->lip_count = -1; 1290 hs->lip_count = -1;
1280 hs->nos_count = (phba->fc_eventTag >> 1); 1291 hs->nos_count = (phba->fc_eventTag >> 1);
1292 hs->nos_count -= lso->link_events;
1281 } 1293 }
1282 1294
1283 hs->dumped_frames = -1; 1295 hs->dumped_frames = -1;
1284 1296
1285/* FIX ME */ 1297 seconds = get_seconds();
1286 /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/ 1298 if (seconds < psli->stats_start)
1299 hs->seconds_since_last_reset = seconds +
1300 ((unsigned long)-1 - psli->stats_start);
1301 else
1302 hs->seconds_since_last_reset = seconds - psli->stats_start;
1287 1303
1288 return hs; 1304 return hs;
1289} 1305}
1290 1306
1307static void
1308lpfc_reset_stats(struct Scsi_Host *shost)
1309{
1310 struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
1311 struct lpfc_sli *psli = &phba->sli;
1312 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
1313 LPFC_MBOXQ_t *pmboxq;
1314 MAILBOX_t *pmb;
1315 int rc = 0;
1316
1317 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1318 if (!pmboxq)
1319 return;
1320 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
1321
1322 pmb = &pmboxq->mb;
1323 pmb->mbxCommand = MBX_READ_STATUS;
1324 pmb->mbxOwner = OWN_HOST;
1325 pmb->un.varWords[0] = 0x1; /* reset request */
1326 pmboxq->context1 = NULL;
1327
1328 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1329 (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1330 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1331 else
1332 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1333
1334 if (rc != MBX_SUCCESS) {
1335 if (rc == MBX_TIMEOUT)
1336 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1337 else
1338 mempool_free(pmboxq, phba->mbox_mem_pool);
1339 return;
1340 }
1341
1342 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
1343 pmb->mbxCommand = MBX_READ_LNK_STAT;
1344 pmb->mbxOwner = OWN_HOST;
1345 pmboxq->context1 = NULL;
1346
1347 if ((phba->fc_flag & FC_OFFLINE_MODE) ||
1348 (!(psli->sli_flag & LPFC_SLI2_ACTIVE)))
1349 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
1350 else
1351 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1352
1353 if (rc != MBX_SUCCESS) {
1354 if (rc == MBX_TIMEOUT)
1355 pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1356 else
1357 mempool_free( pmboxq, phba->mbox_mem_pool);
1358 return;
1359 }
1360
1361 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
1362 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
1363 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
1364 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
1365 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
1366 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
1367 lso->error_frames = pmb->un.varRdLnk.crcCnt;
1368 lso->link_events = (phba->fc_eventTag >> 1);
1369
1370 psli->stats_start = get_seconds();
1371
1372 return;
1373}
1291 1374
1292/* 1375/*
1293 * The LPFC driver treats linkdown handling as target loss events so there 1376 * The LPFC driver treats linkdown handling as target loss events so there
@@ -1431,8 +1514,7 @@ struct fc_function_template lpfc_transport_functions = {
1431 */ 1514 */
1432 1515
1433 .get_fc_host_stats = lpfc_get_stats, 1516 .get_fc_host_stats = lpfc_get_stats,
1434 1517 .reset_fc_host_stats = lpfc_reset_stats,
1435 /* the LPFC driver doesn't support resetting stats yet */
1436 1518
1437 .dd_fcrport_size = sizeof(struct lpfc_rport_data), 1519 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
1438 .show_rport_maxframe_size = 1, 1520 .show_rport_maxframe_size = 1,
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 350a625fa224..f453fccd67c8 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1792,6 +1792,9 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
1792 1792
1793 spin_unlock_irq(phba->host->host_lock); 1793 spin_unlock_irq(phba->host->host_lock);
1794 1794
1795 memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
1796 psli->stats_start = get_seconds();
1797
1795 if (skip_post) 1798 if (skip_post)
1796 mdelay(100); 1799 mdelay(100);
1797 else 1800 else
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index d8ef0d2894d4..478e799c2bbf 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -172,6 +172,18 @@ struct lpfc_sli_stat {
172 uint32_t mbox_busy; /* Mailbox cmd busy */ 172 uint32_t mbox_busy; /* Mailbox cmd busy */
173}; 173};
174 174
175/* Structure to store link status values when port stats are reset */
176struct lpfc_lnk_stat {
177 uint32_t link_failure_count;
178 uint32_t loss_of_sync_count;
179 uint32_t loss_of_signal_count;
180 uint32_t prim_seq_protocol_err_count;
181 uint32_t invalid_tx_word_count;
182 uint32_t invalid_crc_count;
183 uint32_t error_frames;
184 uint32_t link_events;
185};
186
175/* Structure used to hold SLI information */ 187/* Structure used to hold SLI information */
176struct lpfc_sli { 188struct lpfc_sli {
177 uint32_t num_rings; 189 uint32_t num_rings;
@@ -201,6 +213,8 @@ struct lpfc_sli {
201 struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ 213 struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
202 size_t iocbq_lookup_len; /* current lengs of the array */ 214 size_t iocbq_lookup_len; /* current lengs of the array */
203 uint16_t last_iotag; /* last allocated IOTAG */ 215 uint16_t last_iotag; /* last allocated IOTAG */
216 unsigned long stats_start; /* in seconds */
217 struct lpfc_lnk_stat lnk_stat_offsets;
204}; 218};
205 219
206/* Given a pointer to the start of the ring, and the slot number of 220/* Given a pointer to the start of the ring, and the slot number of