diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 08a1feb3a195..9ce28c4f9812 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -318,6 +318,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, return -EINVAL; if (start > ha->optrom_size) return -EINVAL; + if (size > ha->optrom_size - start) + size = ha->optrom_size - start; mutex_lock(&ha->optrom_mutex); switch (val) { @@ -343,8 +345,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, } ha->optrom_region_start = start; - ha->optrom_region_size = start + size > ha->optrom_size ? - ha->optrom_size - start : size; + ha->optrom_region_size = start + size; ha->optrom_state = QLA_SREADING; ha->optrom_buffer = vmalloc(ha->optrom_region_size); @@ -417,8 +418,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, } ha->optrom_region_start = start; - ha->optrom_region_size = start + size > ha->optrom_size ? - ha->optrom_size - start : size; + ha->optrom_region_size = start + size; ha->optrom_state = QLA_SWRITING; ha->optrom_buffer = vmalloc(ha->optrom_region_size); @@ -565,47 +565,17 @@ qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj, { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); - struct qla_hw_data *ha = vha->hw; - uint16_t iter, addr, offset; int rval; - if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) + if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE) return 0; - if (ha->sfp_data) - goto do_read; - - ha->sfp_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, - &ha->sfp_data_dma); - if (!ha->sfp_data) { - ql_log(ql_log_warn, vha, 0x706c, - "Unable to allocate memory for SFP read-data.\n"); + if (qla2x00_reset_active(vha)) return 0; - } - -do_read: - memset(ha->sfp_data, 0, SFP_BLOCK_SIZE); - addr = 0xa0; - for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; - iter++, offset += SFP_BLOCK_SIZE) { - if (iter == 4) { - /* Skip to next device address. */ - addr = 0xa2; - offset = 0; - } - - rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data, - addr, offset, SFP_BLOCK_SIZE, BIT_1); - if (rval != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x706d, - "Unable to read SFP data (%x/%x/%x).\n", rval, - addr, offset); - return -EIO; - } - memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); - buf += SFP_BLOCK_SIZE; - } + rval = qla2x00_read_sfp_dev(vha, buf, count); + if (rval) + return -EIO; return count; } @@ -615,7 +585,7 @@ static struct bin_attribute sysfs_sfp_attr = { .name = "sfp", .mode = S_IRUSR | S_IWUSR, }, - .size = SFP_DEV_SIZE * 2, + .size = SFP_DEV_SIZE, .read = qla2x00_sysfs_read_sfp, }; @@ -1511,6 +1481,38 @@ qla2x00_pep_version_show(struct device *dev, struct device_attribute *attr, ha->pep_version[0], ha->pep_version[1], ha->pep_version[2]); } +static ssize_t +qla2x00_min_link_speed_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; + + if (!IS_QLA27XX(ha)) + return scnprintf(buf, PAGE_SIZE, "\n"); + + return scnprintf(buf, PAGE_SIZE, "%s\n", + ha->min_link_speed == 5 ? "32Gps" : + ha->min_link_speed == 4 ? "16Gps" : + ha->min_link_speed == 3 ? "8Gps" : + ha->min_link_speed == 2 ? "4Gps" : + ha->min_link_speed != 0 ? "unknown" : ""); +} + +static ssize_t +qla2x00_max_speed_sup_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; + + if (!IS_QLA27XX(ha)) + return scnprintf(buf, PAGE_SIZE, "\n"); + + return scnprintf(buf, PAGE_SIZE, "%s\n", + ha->max_speed_sup ? "32Gps" : "16Gps"); +} + static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_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); @@ -1556,6 +1558,8 @@ static DEVICE_ATTR(allow_cna_fw_dump, S_IRUGO | S_IWUSR, qla2x00_allow_cna_fw_dump_show, qla2x00_allow_cna_fw_dump_store); static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL); +static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL); +static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL); struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_driver_version, @@ -1590,6 +1594,8 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_fw_dump_size, &dev_attr_allow_cna_fw_dump, &dev_attr_pep_version, + &dev_attr_min_link_speed, + &dev_attr_max_speed_sup, NULL, }; |