diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 90 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.h | 14 |
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 | ||
1307 | static void | ||
1308 | lpfc_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 */ | ||
176 | struct 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 */ |
176 | struct lpfc_sli { | 188 | struct 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 |