#include <net/netlink.h>
#include <scsi/scsi_netlink_fc.h>
#include <scsi/scsi_bsg_fc.h>
+#include <uapi/scsi/fc/fc_els.h>
#include "scsi_priv.h"
static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
fc_host->fabric_name = -1;
memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
+ memset(&fc_host->fpin_stats, 0, sizeof(fc_host->fpin_stats));
fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
static FC_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo);
+#define fc_rport_fpin_statistic(name) \
+static ssize_t fc_rport_fpinstat_##name(struct device *cd, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct fc_rport *rport = transport_class_to_rport(cd); \
+ \
+ return snprintf(buf, 20, "0x%llx\n", rport->fpin_stats.name); \
+} \
+static FC_DEVICE_ATTR(rport, fpin_##name, 0444, fc_rport_fpinstat_##name, NULL)
+
+fc_rport_fpin_statistic(dn);
+fc_rport_fpin_statistic(dn_unknown);
+fc_rport_fpin_statistic(dn_timeout);
+fc_rport_fpin_statistic(dn_unable_to_route);
+fc_rport_fpin_statistic(dn_device_specific);
+fc_rport_fpin_statistic(cn);
+fc_rport_fpin_statistic(cn_clear);
+fc_rport_fpin_statistic(cn_lost_credit);
+fc_rport_fpin_statistic(cn_credit_stall);
+fc_rport_fpin_statistic(cn_oversubscription);
+fc_rport_fpin_statistic(cn_device_specific);
+fc_rport_fpin_statistic(li);
+fc_rport_fpin_statistic(li_failure_unknown);
+fc_rport_fpin_statistic(li_link_failure_count);
+fc_rport_fpin_statistic(li_loss_of_sync_count);
+fc_rport_fpin_statistic(li_loss_of_signals_count);
+fc_rport_fpin_statistic(li_prim_seq_err_count);
+fc_rport_fpin_statistic(li_invalid_tx_word_count);
+fc_rport_fpin_statistic(li_invalid_crc_count);
+fc_rport_fpin_statistic(li_device_specific);
+
+static struct attribute *fc_rport_statistics_attrs[] = {
+ &device_attr_rport_fpin_dn.attr,
+ &device_attr_rport_fpin_dn_unknown.attr,
+ &device_attr_rport_fpin_dn_timeout.attr,
+ &device_attr_rport_fpin_dn_unable_to_route.attr,
+ &device_attr_rport_fpin_dn_device_specific.attr,
+ &device_attr_rport_fpin_li.attr,
+ &device_attr_rport_fpin_li_failure_unknown.attr,
+ &device_attr_rport_fpin_li_link_failure_count.attr,
+ &device_attr_rport_fpin_li_loss_of_sync_count.attr,
+ &device_attr_rport_fpin_li_loss_of_signals_count.attr,
+ &device_attr_rport_fpin_li_prim_seq_err_count.attr,
+ &device_attr_rport_fpin_li_invalid_tx_word_count.attr,
+ &device_attr_rport_fpin_li_invalid_crc_count.attr,
+ &device_attr_rport_fpin_li_device_specific.attr,
+ &device_attr_rport_fpin_cn.attr,
+ &device_attr_rport_fpin_cn_clear.attr,
+ &device_attr_rport_fpin_cn_lost_credit.attr,
+ &device_attr_rport_fpin_cn_credit_stall.attr,
+ &device_attr_rport_fpin_cn_oversubscription.attr,
+ &device_attr_rport_fpin_cn_device_specific.attr,
+ NULL
+};
+
+static struct attribute_group fc_rport_statistics_group = {
+ .name = "statistics",
+ .attrs = fc_rport_statistics_attrs,
+};
+
/*
* FC SCSI Target Attribute Management
fc_host_statistic(fc_seq_not_found);
fc_host_statistic(fc_non_bls_resp);
+#define fc_host_fpin_statistic(name) \
+static ssize_t fc_host_fpinstat_##name(struct device *cd, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct Scsi_Host *shost = transport_class_to_shost(cd); \
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost); \
+ \
+ return snprintf(buf, 20, "0x%llx\n", fc_host->fpin_stats.name); \
+} \
+static FC_DEVICE_ATTR(host, fpin_##name, 0444, fc_host_fpinstat_##name, NULL)
+
+fc_host_fpin_statistic(dn);
+fc_host_fpin_statistic(dn_unknown);
+fc_host_fpin_statistic(dn_timeout);
+fc_host_fpin_statistic(dn_unable_to_route);
+fc_host_fpin_statistic(dn_device_specific);
+fc_host_fpin_statistic(cn);
+fc_host_fpin_statistic(cn_clear);
+fc_host_fpin_statistic(cn_lost_credit);
+fc_host_fpin_statistic(cn_credit_stall);
+fc_host_fpin_statistic(cn_oversubscription);
+fc_host_fpin_statistic(cn_device_specific);
+fc_host_fpin_statistic(li);
+fc_host_fpin_statistic(li_failure_unknown);
+fc_host_fpin_statistic(li_link_failure_count);
+fc_host_fpin_statistic(li_loss_of_sync_count);
+fc_host_fpin_statistic(li_loss_of_signals_count);
+fc_host_fpin_statistic(li_prim_seq_err_count);
+fc_host_fpin_statistic(li_invalid_tx_word_count);
+fc_host_fpin_statistic(li_invalid_crc_count);
+fc_host_fpin_statistic(li_device_specific);
+
static ssize_t
fc_reset_statistics(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
&device_attr_host_fc_seq_not_found.attr,
&device_attr_host_fc_non_bls_resp.attr,
&device_attr_host_reset_statistics.attr,
+ &device_attr_host_fpin_dn.attr,
+ &device_attr_host_fpin_dn_unknown.attr,
+ &device_attr_host_fpin_dn_timeout.attr,
+ &device_attr_host_fpin_dn_unable_to_route.attr,
+ &device_attr_host_fpin_dn_device_specific.attr,
+ &device_attr_host_fpin_li.attr,
+ &device_attr_host_fpin_li_failure_unknown.attr,
+ &device_attr_host_fpin_li_link_failure_count.attr,
+ &device_attr_host_fpin_li_loss_of_sync_count.attr,
+ &device_attr_host_fpin_li_loss_of_signals_count.attr,
+ &device_attr_host_fpin_li_prim_seq_err_count.attr,
+ &device_attr_host_fpin_li_invalid_tx_word_count.attr,
+ &device_attr_host_fpin_li_invalid_crc_count.attr,
+ &device_attr_host_fpin_li_device_specific.attr,
+ &device_attr_host_fpin_cn.attr,
+ &device_attr_host_fpin_cn_clear.attr,
+ &device_attr_host_fpin_cn_lost_credit.attr,
+ &device_attr_host_fpin_cn_credit_stall.attr,
+ &device_attr_host_fpin_cn_oversubscription.attr,
+ &device_attr_host_fpin_cn_device_specific.attr,
NULL
};
i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
i->rport_attr_cont.ac.class = &fc_rport_class.class;
i->rport_attr_cont.ac.match = fc_rport_match;
+ i->rport_attr_cont.statistics = &fc_rport_statistics_group;
transport_container_register(&i->rport_attr_cont);
i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];