diff options
author | marcel <marcel@FreeBSD.org> | 2010-01-28 04:50:09 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2010-01-28 04:50:09 +0000 |
commit | 973b5fa5f2d400701ce9699f4118bd6ccc5a418c (patch) | |
tree | 5f2d1fe00f9b58cac133af3f072cf3f0b524644d /sys/ia64 | |
parent | cf9c897dddf676243f00ebc7355d80628655b60f (diff) | |
download | FreeBSD-src-973b5fa5f2d400701ce9699f4118bd6ccc5a418c.zip FreeBSD-src-973b5fa5f2d400701ce9699f4118bd6ccc5a418c.tar.gz |
In pci_cfgregread() and pci_cfgregwrite(), validate the arguments and check
that the alignment matches the width of the read or write.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/pci/pci_cfgreg.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/sys/ia64/pci/pci_cfgreg.c b/sys/ia64/pci/pci_cfgreg.c index cef743b..4858d94 100644 --- a/sys/ia64/pci/pci_cfgreg.c +++ b/sys/ia64/pci/pci_cfgreg.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2010 Marcel Moolenaar * Copyright (c) 2001 Doug Rabson * All rights reserved. * @@ -30,35 +31,69 @@ #include <machine/pci_cfgreg.h> #include <machine/sal.h> -#define SAL_PCI_ADDRESS(bus, slot, func, reg) \ - (((bus) << 16) | ((slot) << 11) | ((func) << 8) | (reg)) +static u_long +pci_sal_address(int dom, int bus, int slot, int func, int reg) +{ + u_long addr; + + addr = ~0ul; + if (dom >= 0 && dom <= 255 && bus >= 0 && bus <= 255 && + slot >= 0 && slot <= 31 && func >= 0 && func <= 7 && + reg >= 0 && reg <= 255) { + addr = ((u_long)dom << 24) | ((u_long)bus << 16) | + ((u_long)slot << 11) | ((u_long)func << 8) | (u_long)reg; + } + return (addr); +} + +static int +pci_valid_access(int reg, int len) +{ + int ok; + + ok = ((len == 1 || len == 2 || len == 4) && (reg & (len - 1)) == 0) + ? 1 : 0; + return (ok); +} int pci_cfgregopen(void) { - return 1; + return (1); } -u_int32_t -pci_cfgregread(int bus, int slot, int func, int reg, int bytes) +uint32_t +pci_cfgregread(int bus, int slot, int func, int reg, int len) { struct ia64_sal_result res; + u_long addr; - res = ia64_sal_entry(SAL_PCI_CONFIG_READ, - SAL_PCI_ADDRESS(bus, slot, func, reg), - bytes, 0, 0, 0, 0, 0); + addr = pci_sal_address(0, bus, slot, func, reg); + if (addr == ~0ul) + return (~0); + + if (!pci_valid_access(reg, len)) + return (~0); + + res = ia64_sal_entry(SAL_PCI_CONFIG_READ, addr, len, 0, 0, 0, 0, 0); if (res.sal_status < 0) return (~0); - else - return (res.sal_result[0]); + + return (res.sal_result[0]); } void -pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes) +pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len) { struct ia64_sal_result res; + u_long addr; + + addr = pci_sal_address(0, bus, slot, func, reg); + if (addr == ~0ul) + return; + + if (!pci_valid_access(reg, len)) + return; - res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, - SAL_PCI_ADDRESS(bus, slot, func, reg), - bytes, data, 0, 0, 0, 0); + res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, addr, len, data, 0, 0, 0, 0); } |