On Sat, Jan 09, 2016 at 01:22:54PM +0100, Alexander Gordeev wrote: > Cc: Andrew Jones <drjones@xxxxxxxxxx> > Signed-off-by: Alexander Gordeev <agordeev@xxxxxxxxxx> > --- > arm/pci-test.c | 2 +- > lib/pci-testdev.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- > lib/pci.h | 2 +- > 3 files changed, 138 insertions(+), 5 deletions(-) > > diff --git a/arm/pci-test.c b/arm/pci-test.c > index 695acf9..44e2857 100644 > --- a/arm/pci-test.c > +++ b/arm/pci-test.c > @@ -23,7 +23,7 @@ int main(void) > report("PCI bus scanning detected %d devices", true, ret); > > ret = pci_testdev(pci); > - report("PCI test device", ret); > + report("PCI test device passed %d tests", (ret >= 6), ret); > > pci_shutdown(pci); > > diff --git a/lib/pci-testdev.c b/lib/pci-testdev.c > index a7e0995..de97f82 100644 > --- a/lib/pci-testdev.c > +++ b/lib/pci-testdev.c > @@ -11,21 +11,154 @@ > #define PCI_VENDOR_ID_REDHAT 0x1b36 > #define PCI_DEVICE_ID_REDHAT_TEST 0x0005 > > -bool pci_testdev(struct pci *pci) > +struct pci_test_dev_hdr { > + u8 test; > + u8 width; > + u8 pad0[2]; > + u32 offset; > + u32 data; > + u32 count; > + u8 name[]; > +}; > + > +struct pci_testdev_ops { > + u8 (*read8)(const volatile void *addr); > + u16 (*read16)(const volatile void *addr); > + u32 (*read32)(const volatile void *addr); > + void (*write8)(u8 value, volatile void *addr); > + void (*write16)(u16 value, volatile void *addr); > + void (*write32)(u32 value, volatile void *addr); Please use the standard 'b', 'w', 'l' in these names. > +}; > + > +static u8 ioread8(const volatile void *addr) > +{ > + return readb(addr); > +} > + > +static u16 ioread16(const volatile void *addr) > +{ > + return readw(addr); > +} > + > +static u32 ioread32(const volatile void *addr) > +{ > + return readl(addr); > +} > + > +static void iowrite8(u8 value, volatile void *addr) > +{ > + writeb(value, addr); > +} > + > +static void iowrite16(u16 value, volatile void *addr) > +{ > + writew(value, addr); > +} > + > +static void iowrite32(u32 value, volatile void *addr) > +{ > + writel(value, addr); > +} > + > +static struct pci_testdev_ops pci_testdev_io_ops = { > + .read8 = ioread8, > + .read16 = ioread16, > + .read32 = ioread32, > + .write8 = iowrite8, > + .write16 = iowrite16, > + .write32 = iowrite32 > +}; > + > +static u8 memread8(const volatile void *addr) > +{ > + return *(const volatile u8 __force *)addr; > +} > + > +static u16 memread16(const volatile void *addr) > +{ > + return *(const volatile u16 __force *)addr; > +} > + > +static u32 memread32(const volatile void *addr) > +{ > + return *(const volatile u32 __force *)addr; > +} > + > +static void memwrite8(u8 value, volatile void *addr) > +{ > + *(volatile u8 __force *)addr = value; > +} > + > +static void memwrite16(u16 value, volatile void *addr) > +{ > + *(volatile u16 __force *)addr = value; > +} > + > +static void memwrite32(u32 value, volatile void *addr) > +{ > + *(volatile u32 __force *)addr = value; > +} > + > +static struct pci_testdev_ops pci_testdev_mem_ops = { > + .read8 = memread8, > + .read16 = memread16, > + .read32 = memread32, > + .write8 = memwrite8, > + .write16 = memwrite16, > + .write32 = memwrite32 > +}; > + > +static bool pci_testdev_one(struct pci_test_dev_hdr *test, > + int test_nr, > + struct pci_testdev_ops *ops) > +{ > + u8 width; > + > + ops->write8(test_nr, &test->test); > + assert(ops->read32(&test->count) == 0); > + > + width = ops->read8(&test->width); > + if ((width != 1) && (width != 2) && (width != 4)) > + return false; > + > + return true; > +} > + > +static int pci_testdev_all(struct pci_test_dev_hdr *test, > + struct pci_testdev_ops *ops) > +{ > + int i; > + > + for (i = 0;; i++) { > + if (!pci_testdev_one(test, i, ops)) > + break; > + } > + > + return i; > +} > + > +int pci_testdev(struct pci *pci) > { > phys_addr_t addr; > + void __iomem *mem, *io; > + int nr_tests = 0; > pcidevaddr_t dev = pci_find_dev(pci, > PCI_VENDOR_ID_REDHAT, > PCI_DEVICE_ID_REDHAT_TEST); > > if (dev == PCIDEVADDR_INVALID) > - return false; > + return 0; > > addr = pci_bar_addr(pci, dev, 0); > assert(addr); > + mem = ioremap(addr, 0); > > addr = pci_bar_addr(pci, dev, 1); > assert(addr); > + io = (void*)addr; > > - return true; > + nr_tests += pci_testdev_all(mem, &pci_testdev_mem_ops); > + nr_tests += pci_testdev_all(io, &pci_testdev_io_ops); > + > + return nr_tests; > } > diff --git a/lib/pci.h b/lib/pci.h > index 6af5599..0cb0e27 100644 > --- a/lib/pci.h > +++ b/lib/pci.h > @@ -24,7 +24,7 @@ typedef enum { > > extern struct pci *pci_dt_probe(void); > extern int pci_bus_scan(struct pci *pci); > -extern bool pci_testdev(struct pci *pci); > +extern int pci_testdev(struct pci *pci); > extern void pci_shutdown(struct pci *pci); > > extern pcidevaddr_t pci_find_dev(struct pci *pci, u16 vendor_id, u16 device_id); > -- > 1.8.3.1 > This patch can be squashed into the last one. Thanks, drew _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm