aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 23:44:23 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 23:44:23 -0400
commit6cbf0c704d7c3bb215ae7e0381b1ff2ad5931f35 (patch)
treef2979bdafe0e0644fb82975a30993d03da7f8fd4
parent4d4700707c0d4be0efc968989fb1cd01c60c0a35 (diff)
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 <torvalds@linux-foundation.org>
-rw-r--r--lib/iomap.c27
1 files 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 @@
35#define PIO_RESERVED 0x40000UL 35#define PIO_RESERVED 0x40000UL
36#endif 36#endif
37 37
38static void bad_io_access(unsigned long port, const char *access)
39{
40 static int count = 10;
41 if (count) {
42 count--;
43 printk(KERN_ERR "Bad IO access at port %lx (%s)\n", port, access);
44 WARN_ON(1);
45 }
46}
47
38/* 48/*
39 * Ugly macros are a way of life. 49 * Ugly macros are a way of life.
40 */ 50 */
41#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)
42
43#define IO_COND(addr, is_pio, is_mmio) do { \ 51#define IO_COND(addr, is_pio, is_mmio) do { \
44 unsigned long port = (unsigned long __force)addr; \ 52 unsigned long port = (unsigned long __force)addr; \
45 if (port < PIO_RESERVED) { \ 53 if (port >= PIO_RESERVED) { \
46 VERIFY_PIO(port); \ 54 is_mmio; \
55 } else if (port > PIO_OFFSET) { \
47 port &= PIO_MASK; \ 56 port &= PIO_MASK; \
48 is_pio; \ 57 is_pio; \
49 } else { \ 58 } else \
50 is_mmio; \ 59 bad_io_access(port, #is_pio ); \
51 } \
52} while (0) 60} while (0)
53 61
54#ifndef pio_read16be 62#ifndef pio_read16be
@@ -64,22 +72,27 @@
64unsigned int fastcall ioread8(void __iomem *addr) 72unsigned int fastcall ioread8(void __iomem *addr)
65{ 73{
66 IO_COND(addr, return inb(port), return readb(addr)); 74 IO_COND(addr, return inb(port), return readb(addr));
75 return 0xff;
67} 76}
68unsigned int fastcall ioread16(void __iomem *addr) 77unsigned int fastcall ioread16(void __iomem *addr)
69{ 78{
70 IO_COND(addr, return inw(port), return readw(addr)); 79 IO_COND(addr, return inw(port), return readw(addr));
80 return 0xffff;
71} 81}
72unsigned int fastcall ioread16be(void __iomem *addr) 82unsigned int fastcall ioread16be(void __iomem *addr)
73{ 83{
74 IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr)); 84 IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
85 return 0xffff;
75} 86}
76unsigned int fastcall ioread32(void __iomem *addr) 87unsigned int fastcall ioread32(void __iomem *addr)
77{ 88{
78 IO_COND(addr, return inl(port), return readl(addr)); 89 IO_COND(addr, return inl(port), return readl(addr));
90 return 0xffffffff;
79} 91}
80unsigned int fastcall ioread32be(void __iomem *addr) 92unsigned int fastcall ioread32be(void __iomem *addr)
81{ 93{
82 IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr)); 94 IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
95 return 0xffffffff;
83} 96}
84EXPORT_SYMBOL(ioread8); 97EXPORT_SYMBOL(ioread8);
85EXPORT_SYMBOL(ioread16); 98EXPORT_SYMBOL(ioread16);