|
@@ -1374,6 +1374,166 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count
|
|
|
|
+ * @dev: PCI device to query
|
|
|
|
+ *
|
|
|
|
+ * Returns mmrbc: maximum designed memory read count in bytes
|
|
|
|
+ * or appropriate error value.
|
|
|
|
+ */
|
|
|
|
+int pcix_get_max_mmrbc(struct pci_dev *dev)
|
|
|
|
+{
|
|
|
|
+ int ret, err, cap;
|
|
|
|
+ u32 stat;
|
|
|
|
+
|
|
|
|
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
|
|
|
+ if (!cap)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
|
|
|
|
+ if (err)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ret = (stat & PCI_X_STATUS_MAX_READ) >> 12;
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(pcix_get_max_mmrbc);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * pcix_get_mmrbc - get PCI-X maximum memory read byte count
|
|
|
|
+ * @dev: PCI device to query
|
|
|
|
+ *
|
|
|
|
+ * Returns mmrbc: maximum memory read count in bytes
|
|
|
|
+ * or appropriate error value.
|
|
|
|
+ */
|
|
|
|
+int pcix_get_mmrbc(struct pci_dev *dev)
|
|
|
|
+{
|
|
|
|
+ int ret, cap;
|
|
|
|
+ u32 cmd;
|
|
|
|
+
|
|
|
|
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
|
|
|
+ if (!cap)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
|
|
|
|
+ if (!ret)
|
|
|
|
+ ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(pcix_get_mmrbc);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * pcix_set_mmrbc - set PCI-X maximum memory read byte count
|
|
|
|
+ * @dev: PCI device to query
|
|
|
|
+ * @mmrbc: maximum memory read count in bytes
|
|
|
|
+ * valid values are 512, 1024, 2048, 4096
|
|
|
|
+ *
|
|
|
|
+ * If possible sets maximum memory read byte count, some bridges have erratas
|
|
|
|
+ * that prevent this.
|
|
|
|
+ */
|
|
|
|
+int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
|
|
|
|
+{
|
|
|
|
+ int cap, err = -EINVAL;
|
|
|
|
+ u32 stat, cmd, v, o;
|
|
|
|
+
|
|
|
|
+ if (mmrbc < 512 || mmrbc > 4096 || (mmrbc & (mmrbc-1)))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ v = ffs(mmrbc) - 10;
|
|
|
|
+
|
|
|
|
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
|
|
|
+ if (!cap)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
|
|
|
|
+ return -E2BIG;
|
|
|
|
+
|
|
|
|
+ err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
|
|
|
|
+ if (o != v) {
|
|
|
|
+ if (v > o && dev->bus &&
|
|
|
|
+ (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
|
|
|
|
+ return -EIO;
|
|
|
|
+
|
|
|
|
+ cmd &= ~PCI_X_CMD_MAX_READ;
|
|
|
|
+ cmd |= v << 2;
|
|
|
|
+ err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
|
|
|
|
+ }
|
|
|
|
+out:
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(pcix_set_mmrbc);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * pcie_get_readrq - get PCI Express read request size
|
|
|
|
+ * @dev: PCI device to query
|
|
|
|
+ *
|
|
|
|
+ * Returns maximum memory read request in bytes
|
|
|
|
+ * or appropriate error value.
|
|
|
|
+ */
|
|
|
|
+int pcie_get_readrq(struct pci_dev *dev)
|
|
|
|
+{
|
|
|
|
+ int ret, cap;
|
|
|
|
+ u16 ctl;
|
|
|
|
+
|
|
|
|
+ cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
|
|
|
+ if (!cap)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
|
|
|
|
+ if (!ret)
|
|
|
|
+ ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(pcie_get_readrq);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * pcie_set_readrq - set PCI Express maximum memory read request
|
|
|
|
+ * @dev: PCI device to query
|
|
|
|
+ * @count: maximum memory read count in bytes
|
|
|
|
+ * valid values are 128, 256, 512, 1024, 2048, 4096
|
|
|
|
+ *
|
|
|
|
+ * If possible sets maximum read byte count
|
|
|
|
+ */
|
|
|
|
+int pcie_set_readrq(struct pci_dev *dev, int rq)
|
|
|
|
+{
|
|
|
|
+ int cap, err = -EINVAL;
|
|
|
|
+ u16 ctl, v;
|
|
|
|
+
|
|
|
|
+ if (rq < 128 || rq > 4096 || (rq & (rq-1)))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ v = (ffs(rq) - 8) << 12;
|
|
|
|
+
|
|
|
|
+ cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
|
|
|
|
+ if (!cap)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
|
|
|
|
+ if (err)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) {
|
|
|
|
+ ctl &= ~PCI_EXP_DEVCTL_READRQ;
|
|
|
|
+ ctl |= v;
|
|
|
|
+ err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(pcie_set_readrq);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* pci_select_bars - Make BAR mask from the type of resource
|
|
* pci_select_bars - Make BAR mask from the type of resource
|
|
* @dev: the PCI device for which BAR mask is made
|
|
* @dev: the PCI device for which BAR mask is made
|