staticinlineint pa_pxp_offset_valid(u8 bus, u8 devfn, int offset)
{ /* Device 0 Function 0 is special: It's config space spans function 1 as * well, so allow larger offset. It's really a two-function device but the * second function does not probe.
*/ if (bus == 0 && devfn == 0) return offset < 8192; else return offset < 4096;
}
/* Workaround bug 5945: write 0 to a dummy register before reading, * and write back what we read. We must read/write the full 32-bit * contents so we need to shift and mask by hand.
*/
dummy = pa_pxp_cfg_addr(hose, bus->number, devfn, 0x10);
out_le32(dummy, 0);
tmp = in_le32(addr);
out_le32(addr, tmp);
/* * Note: the caller has already checked that offset is * suitably aligned and that len is 1, 2 or 4.
*/ switch (len) { case 1:
*val = in_8(addr); break; case 2:
*val = in_le16(addr); break; default:
*val = in_le32(addr); break;
}
return PCIBIOS_SUCCESSFUL;
}
staticint pa_pxp_write_config(struct pci_bus *bus, unsignedint devfn, int offset, int len, u32 val)
{ struct pci_controller *hose; voidvolatile __iomem *addr;
hose = pci_bus_to_host(bus); if (!hose) return PCIBIOS_DEVICE_NOT_FOUND;
if (!pa_pxp_offset_valid(bus->number, devfn, offset)) return PCIBIOS_BAD_REGISTER_NUMBER;
/* * Note: the caller has already checked that offset is * suitably aligned and that len is 1, 2 or 4.
*/ switch (len) { case 1:
out_8(addr, val); break; case 2:
out_le16(addr, val); break; default:
out_le32(addr, val); break;
} return PCIBIOS_SUCCESSFUL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.