diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-10 01:53:47 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-10 01:53:47 +0100 |
commit | 92fff53b7191cae566be9ca6752069426c7f8241 (patch) | |
tree | 019396be4719ad3969d0395cfa0a90860be75f4a /drivers/scsi/qla2xxx/qla_attr.c | |
parent | Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma (diff) | |
parent | scsi: cxgb4i: validate tcp sequence number only if chip version <= T5 (diff) | |
download | linux-92fff53b7191cae566be9ca6752069426c7f8241.tar.xz linux-92fff53b7191cae566be9ca6752069426c7f8241.zip |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly update of the usual drivers: arcmsr, qla2xxx, lpfc,
hisi_sas, target/iscsi and target/core.
Additionally Christoph refactored gdth as part of the dma changes. The
major mid-layer change this time is the removal of bidi commands and
with them the whole of the osd/exofs driver and filesystem. This is a
major simplification for block and mq in particular"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (240 commits)
scsi: cxgb4i: validate tcp sequence number only if chip version <= T5
scsi: cxgb4i: get pf number from lldi->pf
scsi: core: replace GFP_ATOMIC with GFP_KERNEL in scsi_scan.c
scsi: mpt3sas: Add missing breaks in switch statements
scsi: aacraid: Fix missing break in switch statement
scsi: kill command serial number
scsi: csiostor: drop serial_number usage
scsi: mvumi: use request tag instead of serial_number
scsi: dpt_i2o: remove serial number usage
scsi: st: osst: Remove negative constant left-shifts
scsi: ufs-bsg: Allow reading descriptors
scsi: ufs: Allow reading descriptor via raw upiu
scsi: ufs-bsg: Change the calling convention for write descriptor
scsi: ufs: Remove unused device quirks
Revert "scsi: ufs: disable vccq if it's not needed by UFS device"
scsi: megaraid_sas: Remove a bunch of set but not used variables
scsi: clean obsolete return values of eh_timed_out
scsi: sd: Optimal I/O size should be a multiple of physical block size
scsi: MAINTAINERS: SCSI initiator and target tweaks
scsi: fcoe: make use of fip_mode enum complete
...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ac504a1ff0ff..2eb1ae721a7d 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -543,6 +543,9 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj, if (unlikely(pci_channel_offline(ha->pdev))) return 0; + if (qla2x00_chip_is_down(vha)) + return 0; + if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || !ha->isp_ops->write_nvram) return 0; @@ -1002,7 +1005,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon) /* Scsi_Host attributes. */ static ssize_t -qla2x00_drvr_version_show(struct device *dev, +qla2x00_driver_version_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); @@ -1632,6 +1635,92 @@ qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr, ha->max_speed_sup ? "32Gps" : "16Gps"); } +static ssize_t +qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); + ulong type, speed; + int oldspeed, rval; + int mode = QLA_SET_DATA_RATE_LR; + struct qla_hw_data *ha = vha->hw; + + if (!IS_QLA27XX(vha->hw)) { + ql_log(ql_log_warn, vha, 0x70d8, + "Speed setting not supported \n"); + return -EINVAL; + } + + rval = kstrtol(buf, 10, &type); + speed = type; + if (type == 40 || type == 80 || type == 160 || + type == 320) { + ql_dbg(ql_dbg_user, vha, 0x70d9, + "Setting will be affected after a loss of sync\n"); + type = type/10; + mode = QLA_SET_DATA_RATE_NOLR; + } + + oldspeed = ha->set_data_rate; + + switch (type) { + case 0: + ha->set_data_rate = PORT_SPEED_AUTO; + break; + case 4: + ha->set_data_rate = PORT_SPEED_4GB; + break; + case 8: + ha->set_data_rate = PORT_SPEED_8GB; + break; + case 16: + ha->set_data_rate = PORT_SPEED_16GB; + break; + case 32: + ha->set_data_rate = PORT_SPEED_32GB; + break; + default: + ql_log(ql_log_warn, vha, 0x1199, + "Unrecognized speed setting:%lx. Setting Autoneg\n", + speed); + ha->set_data_rate = PORT_SPEED_AUTO; + } + + if (qla2x00_chip_is_down(vha) || (oldspeed == ha->set_data_rate)) + return -EINVAL; + + ql_log(ql_log_info, vha, 0x70da, + "Setting speed to %lx Gbps \n", type); + + rval = qla2x00_set_data_rate(vha, mode); + if (rval != QLA_SUCCESS) + return -EIO; + + return strlen(buf); +} + +static ssize_t +qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); + struct qla_hw_data *ha = vha->hw; + ssize_t rval; + char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"}; + + rval = qla2x00_get_data_rate(vha); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x70db, + "Unable to get port speed rval:%zd\n", rval); + return -EINVAL; + } + + ql_log(ql_log_info, vha, 0x70d6, + "port speed:%d\n", ha->link_data_rate); + + return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); +} + /* ----- */ static ssize_t @@ -2059,7 +2148,21 @@ ql2xiniexchg_store(struct device *dev, struct device_attribute *attr, return strlen(buf); } -static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); +static ssize_t +qla2x00_dif_bundle_statistics_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; + + return scnprintf(buf, PAGE_SIZE, + "cross=%llu read=%llu write=%llu kalloc=%llu dma_alloc=%llu unusable=%u\n", + ha->dif_bundle_crossed_pages, ha->dif_bundle_reads, + ha->dif_bundle_writes, ha->dif_bundle_kallocs, + ha->dif_bundle_dma_allocs, ha->pool.unusable.count); +} + +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); static DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); @@ -2112,6 +2215,10 @@ static DEVICE_ATTR(zio_threshold, 0644, static DEVICE_ATTR_RW(qlini_mode); static DEVICE_ATTR_RW(ql2xexchoffld); static DEVICE_ATTR_RW(ql2xiniexchg); +static DEVICE_ATTR(dif_bundle_statistics, 0444, + qla2x00_dif_bundle_statistics_show, NULL); +static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show, + qla2x00_port_speed_store); struct device_attribute *qla2x00_host_attrs[] = { @@ -2150,6 +2257,8 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_min_link_speed, &dev_attr_max_speed_sup, &dev_attr_zio_threshold, + &dev_attr_dif_bundle_statistics, + &dev_attr_port_speed, NULL, /* reserve for qlini_mode */ NULL, /* reserve for ql2xiniexchg */ NULL, /* reserve for ql2xexchoffld */ |