From 6cbf0c704d7c3bb215ae7e0381b1ff2ad5931f35 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 4 May 2007 20:44:23 -0700 Subject: [PATCH] iomap: make the default iomap functions fail softer We used to BUG_ON() for a badly mapped IO port, which is certainly correct, but actually made it harder to debug the case where the ATA drivers had incorrectly mapped a nonconnected ATA port. So make badly mapped ports trigger a WARN_ON(), and throw the IO away instead (and return all ones for reads). For things like broken driver initialization - which is the most likely cause anyway - that should mean that the machine comes up and is usable (at least that was the case for the ATA breakage that triggered this patch). It tends to be a whole lot easier to do a "dmesg" on a working machine than to try to capture logs off a dead one. Signed-off-by: Linus Torvalds --- lib/iomap.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/iomap.c b/lib/iomap.c index 4d43f37c0154..a57d262a5ed9 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -35,20 +35,28 @@ #define PIO_RESERVED 0x40000UL #endif +static void bad_io_access(unsigned long port, const char *access) +{ + static int count = 10; + if (count) { + count--; + printk(KERN_ERR "Bad IO access at port %lx (%s)\n", port, access); + WARN_ON(1); + } +} + /* * Ugly macros are a way of life. */ -#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET) - #define IO_COND(addr, is_pio, is_mmio) do { \ unsigned long port = (unsigned long __force)addr; \ - if (port < PIO_RESERVED) { \ - VERIFY_PIO(port); \ + if (port >= PIO_RESERVED) { \ + is_mmio; \ + } else if (port > PIO_OFFSET) { \ port &= PIO_MASK; \ is_pio; \ - } else { \ - is_mmio; \ - } \ + } else \ + bad_io_access(port, #is_pio ); \ } while (0) #ifndef pio_read16be @@ -64,22 +72,27 @@ unsigned int fastcall ioread8(void __iomem *addr) { IO_COND(addr, return inb(port), return readb(addr)); + return 0xff; } unsigned int fastcall ioread16(void __iomem *addr) { IO_COND(addr, return inw(port), return readw(addr)); + return 0xffff; } unsigned int fastcall ioread16be(void __iomem *addr) { IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr)); + return 0xffff; } unsigned int fastcall ioread32(void __iomem *addr) { IO_COND(addr, return inl(port), return readl(addr)); + return 0xffffffff; } unsigned int fastcall ioread32be(void __iomem *addr) { IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr)); + return 0xffffffff; } EXPORT_SYMBOL(ioread8); EXPORT_SYMBOL(ioread16); -- 2.30.2