diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-05 17:14:17 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-05 17:14:17 +0200 |
commit | cbf2f8a99a2337894c3592c9ac2170e8c1f8f73f (patch) | |
tree | c018fb3826ea8492641be62c2f3162fb67f5aa0e /drivers/infiniband/hw/hfi1/qsfp.c | |
parent | Linux 4.8-rc3 (diff) | |
parent | x86/efi: Use efi_exit_boot_services() (diff) | |
download | linux-cbf2f8a99a2337894c3592c9ac2170e8c1f8f73f.tar.xz linux-cbf2f8a99a2337894c3592c9ac2170e8c1f8f73f.zip |
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into efi/urgent
* Make for_each_efi_memory_desc_in_map() safe on Xen and prevent an
infinte loop - Jan Beulich
* Fix boot error on arm64 Qualcomm platforms by refactoring and
improving the ExitBootServices() hack we already for x86 and moving
it to the libstub - Jeffrey Hugo
* Use correct return data type for of_get_flat_dt_subnode_by_name()
so that we correctly handle errors - Andrzej Hajda
Diffstat (limited to 'drivers/infiniband/hw/hfi1/qsfp.c')
-rw-r--r-- | drivers/infiniband/hw/hfi1/qsfp.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/hfi1/qsfp.c b/drivers/infiniband/hw/hfi1/qsfp.c index a207717ade2a..4e95ad810847 100644 --- a/drivers/infiniband/hw/hfi1/qsfp.c +++ b/drivers/infiniband/hw/hfi1/qsfp.c @@ -706,8 +706,8 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len, u8 *data) { struct hfi1_pportdata *ppd; - u32 excess_len = 0; - int ret = 0; + u32 excess_len = len; + int ret = 0, offset = 0; if (port_num > dd->num_pports || port_num < 1) { dd_dev_info(dd, "%s: Invalid port number %d\n", @@ -740,6 +740,34 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len, } memcpy(data, &ppd->qsfp_info.cache[addr], len); + + if (addr <= QSFP_MONITOR_VAL_END && + (addr + len) >= QSFP_MONITOR_VAL_START) { + /* Overlap with the dynamic channel monitor range */ + if (addr < QSFP_MONITOR_VAL_START) { + if (addr + len <= QSFP_MONITOR_VAL_END) + len = addr + len - QSFP_MONITOR_VAL_START; + else + len = QSFP_MONITOR_RANGE; + offset = QSFP_MONITOR_VAL_START - addr; + addr = QSFP_MONITOR_VAL_START; + } else if (addr == QSFP_MONITOR_VAL_START) { + offset = 0; + if (addr + len > QSFP_MONITOR_VAL_END) + len = QSFP_MONITOR_RANGE; + } else { + offset = 0; + if (addr + len > QSFP_MONITOR_VAL_END) + len = QSFP_MONITOR_VAL_END - addr + 1; + } + /* Refresh the values of the dynamic monitors from the cable */ + ret = one_qsfp_read(ppd, dd->hfi1_id, addr, data + offset, len); + if (ret != len) { + ret = -EAGAIN; + goto set_zeroes; + } + } + return 0; set_zeroes: |