aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-06-27 18:56:56 -0400
committerAndi Kleen <andi@basil.nowhere.org>2008-07-16 17:27:05 -0400
commit20bfdbba7212d19613b93dcea93f26cb65af91fe (patch)
treeae75729ddb1cb82931d740fd6a812f295749f706
parent9fdee4e02e3b214cde8e4f3beb6776075a3d08a7 (diff)
PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources
Some callers use pnp_port_start() and similar functions without making sure the resource is valid. This patch makes us fall back to returning the initial values if the resource is not valid or not even present. This mostly preserves the previous behavior, where we would just return the initial values set by pnp_init_resource_table(). The original 2.6.25 code didn't range-check the "bar", so it would return garbage if the bar exceeded the table size. This code returns sensible values instead. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--include/linux/pnp.h72
1 files changed, 60 insertions, 12 deletions
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 63b128d512fb..8b607aecd959 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -40,19 +40,31 @@ static inline resource_size_t pnp_resource_len(struct resource *res)
40static inline resource_size_t pnp_port_start(struct pnp_dev *dev, 40static inline resource_size_t pnp_port_start(struct pnp_dev *dev,
41 unsigned int bar) 41 unsigned int bar)
42{ 42{
43 return pnp_get_resource(dev, IORESOURCE_IO, bar)->start; 43 struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
44
45 if (pnp_resource_valid(res))
46 return res->start;
47 return 0;
44} 48}
45 49
46static inline resource_size_t pnp_port_end(struct pnp_dev *dev, 50static inline resource_size_t pnp_port_end(struct pnp_dev *dev,
47 unsigned int bar) 51 unsigned int bar)
48{ 52{
49 return pnp_get_resource(dev, IORESOURCE_IO, bar)->end; 53 struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
54
55 if (pnp_resource_valid(res))
56 return res->end;
57 return 0;
50} 58}
51 59
52static inline unsigned long pnp_port_flags(struct pnp_dev *dev, 60static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
53 unsigned int bar) 61 unsigned int bar)
54{ 62{
55 return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags; 63 struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
64
65 if (pnp_resource_valid(res))
66 return res->flags;
67 return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
56} 68}
57 69
58static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) 70static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
@@ -63,25 +75,41 @@ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
63static inline resource_size_t pnp_port_len(struct pnp_dev *dev, 75static inline resource_size_t pnp_port_len(struct pnp_dev *dev,
64 unsigned int bar) 76 unsigned int bar)
65{ 77{
66 return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar)); 78 struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
79
80 if (pnp_resource_valid(res))
81 return pnp_resource_len(res);
82 return 0;
67} 83}
68 84
69 85
70static inline resource_size_t pnp_mem_start(struct pnp_dev *dev, 86static inline resource_size_t pnp_mem_start(struct pnp_dev *dev,
71 unsigned int bar) 87 unsigned int bar)
72{ 88{
73 return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start; 89 struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
90
91 if (pnp_resource_valid(res))
92 return res->start;
93 return 0;
74} 94}
75 95
76static inline resource_size_t pnp_mem_end(struct pnp_dev *dev, 96static inline resource_size_t pnp_mem_end(struct pnp_dev *dev,
77 unsigned int bar) 97 unsigned int bar)
78{ 98{
79 return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end; 99 struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
100
101 if (pnp_resource_valid(res))
102 return res->end;
103 return 0;
80} 104}
81 105
82static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar) 106static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
83{ 107{
84 return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags; 108 struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
109
110 if (pnp_resource_valid(res))
111 return res->flags;
112 return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
85} 113}
86 114
87static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) 115static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
@@ -92,18 +120,30 @@ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
92static inline resource_size_t pnp_mem_len(struct pnp_dev *dev, 120static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
93 unsigned int bar) 121 unsigned int bar)
94{ 122{
95 return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar)); 123 struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
124
125 if (pnp_resource_valid(res))
126 return pnp_resource_len(res);
127 return 0;
96} 128}
97 129
98 130
99static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar) 131static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
100{ 132{
101 return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start; 133 struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
134
135 if (pnp_resource_valid(res))
136 return res->start;
137 return -1;
102} 138}
103 139
104static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar) 140static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
105{ 141{
106 return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags; 142 struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
143
144 if (pnp_resource_valid(res))
145 return res->flags;
146 return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
107} 147}
108 148
109static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) 149static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
@@ -114,12 +154,20 @@ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
114 154
115static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar) 155static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar)
116{ 156{
117 return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start; 157 struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
158
159 if (pnp_resource_valid(res))
160 return res->start;
161 return -1;
118} 162}
119 163
120static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar) 164static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
121{ 165{
122 return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags; 166 struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
167
168 if (pnp_resource_valid(res))
169 return res->flags;
170 return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
123} 171}
124 172
125static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) 173static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)