aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2009-06-03 12:55:13 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-08 15:46:34 -0400
commitce0423f4a23317d0166addd7d6fcc4a0fa95e751 (patch)
treeae4124a1fecdefd5f19a1218c7b6684cff05a58a /drivers
parent7f774025171f626fc1a6a97781967c84a869d277 (diff)
[SCSI] qla2xxx: Export XGMAC statistics on supported ISPs.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c57
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c38
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c4
6 files changed, 107 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 524ceb9b9288..e8c1c9e01a7b 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -692,6 +692,58 @@ static struct bin_attribute sysfs_edc_status_attr = {
692 .read = qla2x00_sysfs_read_edc_status, 692 .read = qla2x00_sysfs_read_edc_status,
693}; 693};
694 694
695static ssize_t
696qla2x00_sysfs_read_xgmac_stats(struct kobject *kobj,
697 struct bin_attribute *bin_attr,
698 char *buf, loff_t off, size_t count)
699{
700 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
701 struct device, kobj)));
702 struct qla_hw_data *ha = vha->hw;
703 int rval;
704 uint16_t actual_size;
705
706 if (!capable(CAP_SYS_ADMIN) || off != 0 || count > XGMAC_DATA_SIZE)
707 return 0;
708
709 if (ha->xgmac_data)
710 goto do_read;
711
712 ha->xgmac_data = dma_alloc_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
713 &ha->xgmac_data_dma, GFP_KERNEL);
714 if (!ha->xgmac_data) {
715 qla_printk(KERN_WARNING, ha,
716 "Unable to allocate memory for XGMAC read-data.\n");
717 return 0;
718 }
719
720do_read:
721 actual_size = 0;
722 memset(ha->xgmac_data, 0, XGMAC_DATA_SIZE);
723
724 rval = qla2x00_get_xgmac_stats(vha, ha->xgmac_data_dma,
725 XGMAC_DATA_SIZE, &actual_size);
726 if (rval != QLA_SUCCESS) {
727 qla_printk(KERN_WARNING, ha,
728 "Unable to read XGMAC data (%x).\n", rval);
729 count = 0;
730 }
731
732 count = actual_size > count ? count: actual_size;
733 memcpy(buf, ha->xgmac_data, count);
734
735 return count;
736}
737
738static struct bin_attribute sysfs_xgmac_stats_attr = {
739 .attr = {
740 .name = "xgmac_stats",
741 .mode = S_IRUSR,
742 },
743 .size = 0,
744 .read = qla2x00_sysfs_read_xgmac_stats,
745};
746
695static struct sysfs_entry { 747static struct sysfs_entry {
696 char *name; 748 char *name;
697 struct bin_attribute *attr; 749 struct bin_attribute *attr;
@@ -706,6 +758,7 @@ static struct sysfs_entry {
706 { "reset", &sysfs_reset_attr, }, 758 { "reset", &sysfs_reset_attr, },
707 { "edc", &sysfs_edc_attr, 2 }, 759 { "edc", &sysfs_edc_attr, 2 },
708 { "edc_status", &sysfs_edc_status_attr, 2 }, 760 { "edc_status", &sysfs_edc_status_attr, 2 },
761 { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 },
709 { NULL }, 762 { NULL },
710}; 763};
711 764
@@ -721,6 +774,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
721 continue; 774 continue;
722 if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) 775 if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
723 continue; 776 continue;
777 if (iter->is4GBp_only == 3 && !IS_QLA81XX(vha->hw))
778 continue;
724 779
725 ret = sysfs_create_bin_file(&host->shost_gendev.kobj, 780 ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
726 iter->attr); 781 iter->attr);
@@ -743,6 +798,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
743 continue; 798 continue;
744 if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) 799 if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
745 continue; 800 continue;
801 if (iter->is4GBp_only == 3 && !IS_QLA81XX(ha))
802 continue;
746 803
747 sysfs_remove_bin_file(&host->shost_gendev.kobj, 804 sysfs_remove_bin_file(&host->shost_gendev.kobj,
748 iter->attr); 805 iter->attr);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 721bae94e437..da941be9b182 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2397,6 +2397,10 @@ struct qla_hw_data {
2397 dma_addr_t edc_data_dma; 2397 dma_addr_t edc_data_dma;
2398 uint16_t edc_data_len; 2398 uint16_t edc_data_len;
2399 2399
2400#define XGMAC_DATA_SIZE PAGE_SIZE
2401 void *xgmac_data;
2402 dma_addr_t xgmac_data_dma;
2403
2400 struct task_struct *dpc_thread; 2404 struct task_struct *dpc_thread;
2401 uint8_t dpc_active; /* DPC routine is active */ 2405 uint8_t dpc_active; /* DPC routine is active */
2402 2406
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index f389f3da0bab..80ab46cfaca6 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1405,6 +1405,7 @@ struct access_chip_rsp_84xx {
1405#define MBC_IDC_ACK 0x101 1405#define MBC_IDC_ACK 0x101
1406#define MBC_RESTART_MPI_FW 0x3d 1406#define MBC_RESTART_MPI_FW 0x3d
1407#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */ 1407#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */
1408#define MBC_GET_XGMAC_STATS 0x7a
1408 1409
1409/* Flash access control option field bit definitions */ 1410/* Flash access control option field bit definitions */
1410#define FAC_OPT_FORCE_SEMAPHORE BIT_15 1411#define FAC_OPT_FORCE_SEMAPHORE BIT_15
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f17d525897a0..66ba3997c91c 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -293,6 +293,9 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
293extern int 293extern int
294qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t); 294qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);
295 295
296extern int
297qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *);
298
296/* 299/*
297 * Global Function Prototypes in qla_isr.c source file. 300 * Global Function Prototypes in qla_isr.c source file.
298 */ 301 */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 7d0eeec9ba57..2497fe4ce5aa 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3462,3 +3462,41 @@ qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
3462 3462
3463 return rval; 3463 return rval;
3464} 3464}
3465
3466int
3467qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3468 uint16_t size_in_bytes, uint16_t *actual_size)
3469{
3470 int rval;
3471 mbx_cmd_t mc;
3472 mbx_cmd_t *mcp = &mc;
3473
3474 if (!IS_QLA81XX(vha->hw))
3475 return QLA_FUNCTION_FAILED;
3476
3477 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3478
3479 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3480 mcp->mb[2] = MSW(stats_dma);
3481 mcp->mb[3] = LSW(stats_dma);
3482 mcp->mb[6] = MSW(MSD(stats_dma));
3483 mcp->mb[7] = LSW(MSD(stats_dma));
3484 mcp->mb[8] = size_in_bytes >> 2;
3485 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3486 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3487 mcp->tov = MBX_TOV_SECONDS;
3488 mcp->flags = 0;
3489 rval = qla2x00_mailbox_command(vha, mcp);
3490
3491 if (rval != QLA_SUCCESS) {
3492 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x "
3493 "mb[1]=0x%x mb[2]=0x%x.\n", __func__, vha->host_no, rval,
3494 mcp->mb[0], mcp->mb[1], mcp->mb[2]));
3495 } else {
3496 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3497
3498 *actual_size = mcp->mb[2] << 2;
3499 }
3500
3501 return rval;
3502}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f4f535536952..642e976083e8 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2434,6 +2434,10 @@ qla2x00_mem_free(struct qla_hw_data *ha)
2434 vfree(ha->fw_dump); 2434 vfree(ha->fw_dump);
2435 } 2435 }
2436 2436
2437 if (ha->xgmac_data)
2438 dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
2439 ha->xgmac_data, ha->xgmac_data_dma);
2440
2437 if (ha->sns_cmd) 2441 if (ha->sns_cmd)
2438 dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), 2442 dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
2439 ha->sns_cmd, ha->sns_cmd_dma); 2443 ha->sns_cmd, ha->sns_cmd_dma);