aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2010-02-19 18:07:51 +0000
committerAlexander Motin <mav@FreeBSD.org>2010-02-19 18:07:51 +0000
commit210a19d01411b66aac312de8ddc7d39280106c56 (patch)
tree8a22c5e7a7589e22582c4b3a9e13a48e2c0539e1 /sys/dev/pci
parentc48c2a2389744dbc0db797db5a044b9725e7f869 (diff)
Notes
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c34
-rw-r--r--sys/dev/pci/pcivar.h3
2 files changed, 37 insertions, 0 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index b76e2e7103b9..650e2141b701 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1592,6 +1592,40 @@ pci_ht_map_msi(device_t dev, uint64_t addr)
}
}
+int
+pci_get_max_read_req(device_t dev)
+{
+ int cap;
+ uint16_t val;
+
+ if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0)
+ return (0);
+ val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2);
+ val &= PCIM_EXP_CTL_MAX_READ_REQUEST;
+ val >>= 12;
+ return (1 << (val + 7));
+}
+
+int
+pci_set_max_read_req(device_t dev, int size)
+{
+ int cap;
+ uint16_t val;
+
+ if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) != 0)
+ return (0);
+ if (size < 128)
+ size = 128;
+ if (size > 4096)
+ size = 4096;
+ size = (1 << (fls(size) - 1));
+ val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2);
+ val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST;
+ val |= (fls(size) - 8) << 12;
+ pci_write_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, val, 2);
+ return (size);
+}
+
/*
* Support for MSI message signalled interrupts.
*/
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index d7de96e65625..948370813e2d 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -458,6 +458,9 @@ int pci_msi_device_blacklisted(device_t dev);
void pci_ht_map_msi(device_t dev, uint64_t addr);
+int pci_get_max_read_req(device_t dev);
+int pci_set_max_read_req(device_t dev, int size);
+
#endif /* _SYS_BUS_H_ */
/*