diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 57 |
1 files changed, 57 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 | ||
695 | static ssize_t | ||
696 | qla2x00_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 | |||
720 | do_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 | |||
738 | static 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 | |||
695 | static struct sysfs_entry { | 747 | static 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); |