Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59155
b: refs/heads/master
c: d556ad4
h: refs/heads/master
i:
  59153: b4be79a
  59151: 70c8642
v: v3
  • Loading branch information
Peter Oruba authored and Greg Kroah-Hartman committed Jul 11, 2007
1 parent 4111322 commit ec1b8c3
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e4585da22ad04a055cbb5c863a37aa8cc02eac89
refs/heads/master: d556ad4bbe75faf17b239e151a9f003322b2e851
160 changes: 160 additions & 0 deletions trunk/drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,166 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
}
#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
* @dev: the PCI device for which BAR mask is made
Expand Down
16 changes: 16 additions & 0 deletions trunk/drivers/pci/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
#endif /* CONFIG_X86_IO_APIC */

/*
* Some settings of MMRBC can lead to data corruption so block changes.
* See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide
*/
static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev)
{
unsigned char revid;

pci_read_config_byte(dev, PCI_REVISION_ID, &revid);
if (dev->subordinate && revid <= 0x12) {
printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X MMRBC\n",
revid);
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc);

/*
* FIXME: it is questionable that quirk_via_acpi
Expand Down
7 changes: 6 additions & 1 deletion trunk/include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ enum pcie_reset_state {

typedef unsigned short __bitwise pci_bus_flags_t;
enum pci_bus_flags {
PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
};

struct pci_cap_saved_state {
Expand Down Expand Up @@ -549,6 +550,10 @@ void pci_intx(struct pci_dev *dev, int enable);
void pci_msi_off(struct pci_dev *dev);
int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
int pcix_get_max_mmrbc(struct pci_dev *dev);
int pcix_get_mmrbc(struct pci_dev *dev);
int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
int pcie_set_readrq(struct pci_dev *dev, int rq);
void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
Expand Down

0 comments on commit ec1b8c3

Please sign in to comment.