diff options
author | Dhananjay Phadke <dhananjay.phadke@qlogic.com> | 2010-04-01 19:01:29 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 14:19:13 -0700 |
commit | 897e8c7c450dac2912b677c6e6bf8b04aa5bdf72 (patch) | |
tree | 9bd6fa9ef5c643e08c17847871703f8b0deafead /drivers/net/qlcnic/qlcnic_main.c | |
parent | 0bc92b5b4987ab55f2b75ef42251476b2e049e3d (diff) |
qlcnic: handle queue manager access
Check the access by tools for hardware queue engine and handle it
separately than other block registers, otherwise incorrect data
is returned.
Signed-off-by: Dhananjay Phadke <dhananjay.phadke@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index fc721564e69e..a2346229312e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -2386,14 +2386,21 @@ static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, loff_t offset, size_t size) { + size_t crb_size = 4; + if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) return -EIO; - if ((size != 4) || (offset & 0x3)) - return -EINVAL; + if (offset < QLCNIC_PCI_CRBSPACE) { + if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, + QLCNIC_PCI_CAMQM_END)) + crb_size = 8; + else + return -EINVAL; + } - if (offset < QLCNIC_PCI_CRBSPACE) - return -EINVAL; + if ((size != crb_size) || (offset & (crb_size-1))) + return -EINVAL; return 0; } @@ -2405,14 +2412,20 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); u32 data; + u64 qmdata; int ret; ret = qlcnic_sysfs_validate_crb(adapter, offset, size); if (ret != 0) return ret; - data = QLCRD32(adapter, offset); - memcpy(buf, &data, size); + if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { + qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata); + memcpy(buf, &qmdata, size); + } else { + data = QLCRD32(adapter, offset); + memcpy(buf, &data, size); + } return size; } @@ -2423,14 +2436,20 @@ qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); u32 data; + u64 qmdata; int ret; ret = qlcnic_sysfs_validate_crb(adapter, offset, size); if (ret != 0) return ret; - memcpy(&data, buf, size); - QLCWR32(adapter, offset, data); + if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { + memcpy(&qmdata, buf, size); + qlcnic_pci_camqm_write_2M(adapter, offset, qmdata); + } else { + memcpy(&data, buf, size); + QLCWR32(adapter, offset, data); + } return size; } |