summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c133
1 files changed, 118 insertions, 15 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index d7e7043f9eab..97cabd7e0014 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1324,6 +1324,79 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
}
static ssize_t
+qla2x00_beacon_config_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t led[3] = { 0 };
+
+ if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+ return -EPERM;
+
+ if (ql26xx_led_config(vha, 0, led))
+ return scnprintf(buf, PAGE_SIZE, "\n");
+
+ return scnprintf(buf, PAGE_SIZE, "%#04hx %#04hx %#04hx\n",
+ led[0], led[1], led[2]);
+}
+
+static ssize_t
+qla2x00_beacon_config_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t options = BIT_0;
+ uint16_t led[3] = { 0 };
+ uint16_t word[4];
+ int n;
+
+ if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+ return -EPERM;
+
+ n = sscanf(buf, "%hx %hx %hx %hx", word+0, word+1, word+2, word+3);
+ if (n == 4) {
+ if (word[0] == 3) {
+ options |= BIT_3|BIT_2|BIT_1;
+ led[0] = word[1];
+ led[1] = word[2];
+ led[2] = word[3];
+ goto write;
+ }
+ return -EINVAL;
+ }
+
+ if (n == 2) {
+ /* check led index */
+ if (word[0] == 0) {
+ options |= BIT_2;
+ led[0] = word[1];
+ goto write;
+ }
+ if (word[0] == 1) {
+ options |= BIT_3;
+ led[1] = word[1];
+ goto write;
+ }
+ if (word[0] == 2) {
+ options |= BIT_1;
+ led[2] = word[1];
+ goto write;
+ }
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+
+write:
+ if (ql26xx_led_config(vha, options, led))
+ return -EFAULT;
+
+ return count;
+}
+
+static ssize_t
qla2x00_optrom_bios_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -2250,6 +2323,26 @@ qla2x00_port_no_show(struct device *dev, struct device_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%u\n", vha->hw->port_no);
}
+static ssize_t
+qla2x00_dport_diagnostics_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+ if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
+ !IS_QLA28XX(vha->hw))
+ return scnprintf(buf, PAGE_SIZE, "\n");
+
+ if (!*vha->dport_data)
+ return scnprintf(buf, PAGE_SIZE, "\n");
+
+ return scnprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
+ vha->dport_data[0], vha->dport_data[1],
+ vha->dport_data[2], vha->dport_data[3]);
+}
+static DEVICE_ATTR(dport_diagnostics, 0444,
+ qla2x00_dport_diagnostics_show, NULL);
+
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -2264,6 +2357,8 @@ static DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
qla2x00_zio_timer_store);
static DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
qla2x00_beacon_store);
+static DEVICE_ATTR(beacon_config, 0644, qla2x00_beacon_config_show,
+ qla2x00_beacon_config_store);
static DEVICE_ATTR(optrom_bios_version, S_IRUGO,
qla2x00_optrom_bios_version_show, NULL);
static DEVICE_ATTR(optrom_efi_version, S_IRUGO,
@@ -2327,6 +2422,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_zio,
&dev_attr_zio_timer,
&dev_attr_beacon,
+ &dev_attr_beacon_config,
&dev_attr_optrom_bios_version,
&dev_attr_optrom_efi_version,
&dev_attr_optrom_fcode_version,
@@ -2355,6 +2451,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_port_speed,
&dev_attr_port_no,
&dev_attr_fw_attr,
+ &dev_attr_dport_diagnostics,
NULL, /* reserve for qlini_mode */
NULL, /* reserve for ql2xiniexchg */
NULL, /* reserve for ql2xexchoffld */
@@ -2648,22 +2745,28 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (rval != QLA_SUCCESS)
goto done_free;
- p->link_failure_count = stats->link_fail_cnt;
- p->loss_of_sync_count = stats->loss_sync_cnt;
- p->loss_of_signal_count = stats->loss_sig_cnt;
- p->prim_seq_protocol_err_count = stats->prim_seq_err_cnt;
- p->invalid_tx_word_count = stats->inval_xmit_word_cnt;
- p->invalid_crc_count = stats->inval_crc_cnt;
+ p->link_failure_count = le32_to_cpu(stats->link_fail_cnt);
+ p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt);
+ p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt);
+ p->prim_seq_protocol_err_count = le32_to_cpu(stats->prim_seq_err_cnt);
+ p->invalid_tx_word_count = le32_to_cpu(stats->inval_xmit_word_cnt);
+ p->invalid_crc_count = le32_to_cpu(stats->inval_crc_cnt);
if (IS_FWI2_CAPABLE(ha)) {
- p->lip_count = stats->lip_cnt;
- p->tx_frames = stats->tx_frames;
- p->rx_frames = stats->rx_frames;
- p->dumped_frames = stats->discarded_frames;
- p->nos_count = stats->nos_rcvd;
+ p->lip_count = le32_to_cpu(stats->lip_cnt);
+ p->tx_frames = le32_to_cpu(stats->tx_frames);
+ p->rx_frames = le32_to_cpu(stats->rx_frames);
+ p->dumped_frames = le32_to_cpu(stats->discarded_frames);
+ p->nos_count = le32_to_cpu(stats->nos_rcvd);
p->error_frames =
- stats->dropped_frames + stats->discarded_frames;
- p->rx_words = vha->qla_stats.input_bytes;
- p->tx_words = vha->qla_stats.output_bytes;
+ le32_to_cpu(stats->dropped_frames) +
+ le32_to_cpu(stats->discarded_frames);
+ if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
+ p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt);
+ p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt);
+ } else {
+ p->rx_words = vha->qla_stats.input_bytes;
+ p->tx_words = vha->qla_stats.output_bytes;
+ }
}
p->fcp_control_requests = vha->qla_stats.control_requests;
p->fcp_input_requests = vha->qla_stats.input_requests;
@@ -2671,7 +2774,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20;
p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20;
p->seconds_since_last_reset =
- get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
+ get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
do_div(p->seconds_since_last_reset, HZ);
done_free: