diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 101 |
1 files changed, 92 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5c68cdd8736f..d384c16f4a87 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -222,7 +222,7 @@ lpfc_issue_lip(struct Scsi_Host *host) | |||
222 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; | 222 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; |
223 | pmboxq->mb.mbxOwner = OWN_HOST; | 223 | pmboxq->mb.mbxOwner = OWN_HOST; |
224 | 224 | ||
225 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | 225 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); |
226 | 226 | ||
227 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { | 227 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { |
228 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 228 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
@@ -884,7 +884,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
884 | phba->sysfs_mbox.mbox == NULL ) { | 884 | phba->sysfs_mbox.mbox == NULL ) { |
885 | sysfs_mbox_idle(phba); | 885 | sysfs_mbox_idle(phba); |
886 | spin_unlock_irq(host->host_lock); | 886 | spin_unlock_irq(host->host_lock); |
887 | return -EINVAL; | 887 | return -EAGAIN; |
888 | } | 888 | } |
889 | } | 889 | } |
890 | 890 | ||
@@ -1000,14 +1000,15 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1000 | spin_unlock_irq(phba->host->host_lock); | 1000 | spin_unlock_irq(phba->host->host_lock); |
1001 | rc = lpfc_sli_issue_mbox_wait (phba, | 1001 | rc = lpfc_sli_issue_mbox_wait (phba, |
1002 | phba->sysfs_mbox.mbox, | 1002 | phba->sysfs_mbox.mbox, |
1003 | phba->fc_ratov * 2); | 1003 | lpfc_mbox_tmo_val(phba, |
1004 | phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); | ||
1004 | spin_lock_irq(phba->host->host_lock); | 1005 | spin_lock_irq(phba->host->host_lock); |
1005 | } | 1006 | } |
1006 | 1007 | ||
1007 | if (rc != MBX_SUCCESS) { | 1008 | if (rc != MBX_SUCCESS) { |
1008 | sysfs_mbox_idle(phba); | 1009 | sysfs_mbox_idle(phba); |
1009 | spin_unlock_irq(host->host_lock); | 1010 | spin_unlock_irq(host->host_lock); |
1010 | return -ENODEV; | 1011 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; |
1011 | } | 1012 | } |
1012 | phba->sysfs_mbox.state = SMBOX_READING; | 1013 | phba->sysfs_mbox.state = SMBOX_READING; |
1013 | } | 1014 | } |
@@ -1016,7 +1017,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1016 | printk(KERN_WARNING "mbox_read: Bad State\n"); | 1017 | printk(KERN_WARNING "mbox_read: Bad State\n"); |
1017 | sysfs_mbox_idle(phba); | 1018 | sysfs_mbox_idle(phba); |
1018 | spin_unlock_irq(host->host_lock); | 1019 | spin_unlock_irq(host->host_lock); |
1019 | return -EINVAL; | 1020 | return -EAGAIN; |
1020 | } | 1021 | } |
1021 | 1022 | ||
1022 | memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); | 1023 | memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); |
@@ -1210,8 +1211,10 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1210 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1211 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; |
1211 | struct lpfc_sli *psli = &phba->sli; | 1212 | struct lpfc_sli *psli = &phba->sli; |
1212 | struct fc_host_statistics *hs = &phba->link_stats; | 1213 | struct fc_host_statistics *hs = &phba->link_stats; |
1214 | struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; | ||
1213 | LPFC_MBOXQ_t *pmboxq; | 1215 | LPFC_MBOXQ_t *pmboxq; |
1214 | MAILBOX_t *pmb; | 1216 | MAILBOX_t *pmb; |
1217 | unsigned long seconds; | ||
1215 | int rc = 0; | 1218 | int rc = 0; |
1216 | 1219 | ||
1217 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1220 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -1272,22 +1275,103 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1272 | hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; | 1275 | hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; |
1273 | hs->error_frames = pmb->un.varRdLnk.crcCnt; | 1276 | hs->error_frames = pmb->un.varRdLnk.crcCnt; |
1274 | 1277 | ||
1278 | hs->link_failure_count -= lso->link_failure_count; | ||
1279 | hs->loss_of_sync_count -= lso->loss_of_sync_count; | ||
1280 | hs->loss_of_signal_count -= lso->loss_of_signal_count; | ||
1281 | hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count; | ||
1282 | hs->invalid_tx_word_count -= lso->invalid_tx_word_count; | ||
1283 | hs->invalid_crc_count -= lso->invalid_crc_count; | ||
1284 | hs->error_frames -= lso->error_frames; | ||
1285 | |||
1275 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 1286 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
1276 | hs->lip_count = (phba->fc_eventTag >> 1); | 1287 | hs->lip_count = (phba->fc_eventTag >> 1); |
1288 | hs->lip_count -= lso->link_events; | ||
1277 | hs->nos_count = -1; | 1289 | hs->nos_count = -1; |
1278 | } else { | 1290 | } else { |
1279 | hs->lip_count = -1; | 1291 | hs->lip_count = -1; |
1280 | hs->nos_count = (phba->fc_eventTag >> 1); | 1292 | hs->nos_count = (phba->fc_eventTag >> 1); |
1293 | hs->nos_count -= lso->link_events; | ||
1281 | } | 1294 | } |
1282 | 1295 | ||
1283 | hs->dumped_frames = -1; | 1296 | hs->dumped_frames = -1; |
1284 | 1297 | ||
1285 | /* FIX ME */ | 1298 | seconds = get_seconds(); |
1286 | /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/ | 1299 | if (seconds < psli->stats_start) |
1300 | hs->seconds_since_last_reset = seconds + | ||
1301 | ((unsigned long)-1 - psli->stats_start); | ||
1302 | else | ||
1303 | hs->seconds_since_last_reset = seconds - psli->stats_start; | ||
1287 | 1304 | ||
1288 | return hs; | 1305 | return hs; |
1289 | } | 1306 | } |
1290 | 1307 | ||
1308 | static void | ||
1309 | lpfc_reset_stats(struct Scsi_Host *shost) | ||
1310 | { | ||
1311 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | ||
1312 | struct lpfc_sli *psli = &phba->sli; | ||
1313 | struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; | ||
1314 | LPFC_MBOXQ_t *pmboxq; | ||
1315 | MAILBOX_t *pmb; | ||
1316 | int rc = 0; | ||
1317 | |||
1318 | pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1319 | if (!pmboxq) | ||
1320 | return; | ||
1321 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
1322 | |||
1323 | pmb = &pmboxq->mb; | ||
1324 | pmb->mbxCommand = MBX_READ_STATUS; | ||
1325 | pmb->mbxOwner = OWN_HOST; | ||
1326 | pmb->un.varWords[0] = 0x1; /* reset request */ | ||
1327 | pmboxq->context1 = NULL; | ||
1328 | |||
1329 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | ||
1330 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | ||
1331 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | ||
1332 | else | ||
1333 | rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | ||
1334 | |||
1335 | if (rc != MBX_SUCCESS) { | ||
1336 | if (rc == MBX_TIMEOUT) | ||
1337 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
1338 | else | ||
1339 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
1340 | return; | ||
1341 | } | ||
1342 | |||
1343 | memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); | ||
1344 | pmb->mbxCommand = MBX_READ_LNK_STAT; | ||
1345 | pmb->mbxOwner = OWN_HOST; | ||
1346 | pmboxq->context1 = NULL; | ||
1347 | |||
1348 | if ((phba->fc_flag & FC_OFFLINE_MODE) || | ||
1349 | (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) | ||
1350 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); | ||
1351 | else | ||
1352 | rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | ||
1353 | |||
1354 | if (rc != MBX_SUCCESS) { | ||
1355 | if (rc == MBX_TIMEOUT) | ||
1356 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
1357 | else | ||
1358 | mempool_free( pmboxq, phba->mbox_mem_pool); | ||
1359 | return; | ||
1360 | } | ||
1361 | |||
1362 | lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; | ||
1363 | lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt; | ||
1364 | lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt; | ||
1365 | lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt; | ||
1366 | lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; | ||
1367 | lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt; | ||
1368 | lso->error_frames = pmb->un.varRdLnk.crcCnt; | ||
1369 | lso->link_events = (phba->fc_eventTag >> 1); | ||
1370 | |||
1371 | psli->stats_start = get_seconds(); | ||
1372 | |||
1373 | return; | ||
1374 | } | ||
1291 | 1375 | ||
1292 | /* | 1376 | /* |
1293 | * The LPFC driver treats linkdown handling as target loss events so there | 1377 | * The LPFC driver treats linkdown handling as target loss events so there |
@@ -1431,8 +1515,7 @@ struct fc_function_template lpfc_transport_functions = { | |||
1431 | */ | 1515 | */ |
1432 | 1516 | ||
1433 | .get_fc_host_stats = lpfc_get_stats, | 1517 | .get_fc_host_stats = lpfc_get_stats, |
1434 | 1518 | .reset_fc_host_stats = lpfc_reset_stats, | |
1435 | /* the LPFC driver doesn't support resetting stats yet */ | ||
1436 | 1519 | ||
1437 | .dd_fcrport_size = sizeof(struct lpfc_rport_data), | 1520 | .dd_fcrport_size = sizeof(struct lpfc_rport_data), |
1438 | .show_rport_maxframe_size = 1, | 1521 | .show_rport_maxframe_size = 1, |