diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 23:44:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 23:44:23 -0400 |
commit | 6cbf0c704d7c3bb215ae7e0381b1ff2ad5931f35 (patch) | |
tree | f2979bdafe0e0644fb82975a30993d03da7f8fd4 /lib | |
parent | 4d4700707c0d4be0efc968989fb1cd01c60c0a35 (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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/iomap.c | 27 |
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 | ||
38 | static 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 @@ | |||
64 | unsigned int fastcall ioread8(void __iomem *addr) | 72 | unsigned 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 | } |
68 | unsigned int fastcall ioread16(void __iomem *addr) | 77 | unsigned 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 | } |
72 | unsigned int fastcall ioread16be(void __iomem *addr) | 82 | unsigned 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 | } |
76 | unsigned int fastcall ioread32(void __iomem *addr) | 87 | unsigned 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 | } |
80 | unsigned int fastcall ioread32be(void __iomem *addr) | 92 | unsigned 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 | } |
84 | EXPORT_SYMBOL(ioread8); | 97 | EXPORT_SYMBOL(ioread8); |
85 | EXPORT_SYMBOL(ioread16); | 98 | EXPORT_SYMBOL(ioread16); |