diff options
Diffstat (limited to 'drivers/pnp/pnpbios/rsparser.c')
-rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 326 |
1 files changed, 146 insertions, 180 deletions
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index caade3531416..2e2c457a0fea 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | #include <linux/ctype.h> | 5 | #include <linux/ctype.h> |
6 | #include <linux/pnp.h> | 6 | #include <linux/pnp.h> |
7 | #include <linux/pnpbios.h> | ||
8 | #include <linux/string.h> | 7 | #include <linux/string.h> |
9 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
10 | 9 | ||
@@ -16,6 +15,7 @@ inline void pcibios_penalize_isa_irq(int irq, int active) | |||
16 | } | 15 | } |
17 | #endif /* CONFIG_PCI */ | 16 | #endif /* CONFIG_PCI */ |
18 | 17 | ||
18 | #include "../base.h" | ||
19 | #include "pnpbios.h" | 19 | #include "pnpbios.h" |
20 | 20 | ||
21 | /* standard resource tags */ | 21 | /* standard resource tags */ |
@@ -53,97 +53,43 @@ inline void pcibios_penalize_isa_irq(int irq, int active) | |||
53 | * Allocated Resources | 53 | * Allocated Resources |
54 | */ | 54 | */ |
55 | 55 | ||
56 | static void pnpbios_parse_allocated_irqresource(struct pnp_resource_table *res, | 56 | static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev, |
57 | int irq) | 57 | int start, int len) |
58 | { | 58 | { |
59 | int i = 0; | 59 | int flags = 0; |
60 | 60 | int end = start + len - 1; | |
61 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) | ||
62 | && i < PNP_MAX_IRQ) | ||
63 | i++; | ||
64 | if (i < PNP_MAX_IRQ) { | ||
65 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag | ||
66 | if (irq == -1) { | ||
67 | res->irq_resource[i].flags |= IORESOURCE_DISABLED; | ||
68 | return; | ||
69 | } | ||
70 | res->irq_resource[i].start = | ||
71 | res->irq_resource[i].end = (unsigned long)irq; | ||
72 | pcibios_penalize_isa_irq(irq, 1); | ||
73 | } | ||
74 | } | ||
75 | 61 | ||
76 | static void pnpbios_parse_allocated_dmaresource(struct pnp_resource_table *res, | 62 | if (len <= 0 || end >= 0x10003) |
77 | int dma) | 63 | flags |= IORESOURCE_DISABLED; |
78 | { | ||
79 | int i = 0; | ||
80 | |||
81 | while (i < PNP_MAX_DMA && | ||
82 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) | ||
83 | i++; | ||
84 | if (i < PNP_MAX_DMA) { | ||
85 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | ||
86 | if (dma == -1) { | ||
87 | res->dma_resource[i].flags |= IORESOURCE_DISABLED; | ||
88 | return; | ||
89 | } | ||
90 | res->dma_resource[i].start = | ||
91 | res->dma_resource[i].end = (unsigned long)dma; | ||
92 | } | ||
93 | } | ||
94 | 64 | ||
95 | static void pnpbios_parse_allocated_ioresource(struct pnp_resource_table *res, | 65 | pnp_add_io_resource(dev, start, end, flags); |
96 | int io, int len) | ||
97 | { | ||
98 | int i = 0; | ||
99 | |||
100 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) | ||
101 | && i < PNP_MAX_PORT) | ||
102 | i++; | ||
103 | if (i < PNP_MAX_PORT) { | ||
104 | res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag | ||
105 | if (len <= 0 || (io + len - 1) >= 0x10003) { | ||
106 | res->port_resource[i].flags |= IORESOURCE_DISABLED; | ||
107 | return; | ||
108 | } | ||
109 | res->port_resource[i].start = (unsigned long)io; | ||
110 | res->port_resource[i].end = (unsigned long)(io + len - 1); | ||
111 | } | ||
112 | } | 66 | } |
113 | 67 | ||
114 | static void pnpbios_parse_allocated_memresource(struct pnp_resource_table *res, | 68 | static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev, |
115 | int mem, int len) | 69 | int start, int len) |
116 | { | 70 | { |
117 | int i = 0; | 71 | int flags = 0; |
118 | 72 | int end = start + len - 1; | |
119 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) | 73 | |
120 | && i < PNP_MAX_MEM) | 74 | if (len <= 0) |
121 | i++; | 75 | flags |= IORESOURCE_DISABLED; |
122 | if (i < PNP_MAX_MEM) { | 76 | |
123 | res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag | 77 | pnp_add_mem_resource(dev, start, end, flags); |
124 | if (len <= 0) { | ||
125 | res->mem_resource[i].flags |= IORESOURCE_DISABLED; | ||
126 | return; | ||
127 | } | ||
128 | res->mem_resource[i].start = (unsigned long)mem; | ||
129 | res->mem_resource[i].end = (unsigned long)(mem + len - 1); | ||
130 | } | ||
131 | } | 78 | } |
132 | 79 | ||
133 | static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | 80 | static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, |
134 | unsigned char *end, | 81 | unsigned char *p, |
135 | struct | 82 | unsigned char *end) |
136 | pnp_resource_table | ||
137 | *res) | ||
138 | { | 83 | { |
139 | unsigned int len, tag; | 84 | unsigned int len, tag; |
140 | int io, size, mask, i; | 85 | int io, size, mask, i, flags; |
141 | 86 | ||
142 | if (!p) | 87 | if (!p) |
143 | return NULL; | 88 | return NULL; |
144 | 89 | ||
145 | /* Blank the resource table values */ | 90 | dev_dbg(&dev->dev, "parse allocated resources\n"); |
146 | pnp_init_resource_table(res); | 91 | |
92 | pnp_init_resources(dev); | ||
147 | 93 | ||
148 | while ((char *)p < (char *)end) { | 94 | while ((char *)p < (char *)end) { |
149 | 95 | ||
@@ -163,7 +109,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
163 | goto len_err; | 109 | goto len_err; |
164 | io = *(short *)&p[4]; | 110 | io = *(short *)&p[4]; |
165 | size = *(short *)&p[10]; | 111 | size = *(short *)&p[10]; |
166 | pnpbios_parse_allocated_memresource(res, io, size); | 112 | pnpbios_parse_allocated_memresource(dev, io, size); |
167 | break; | 113 | break; |
168 | 114 | ||
169 | case LARGE_TAG_ANSISTR: | 115 | case LARGE_TAG_ANSISTR: |
@@ -179,7 +125,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
179 | goto len_err; | 125 | goto len_err; |
180 | io = *(int *)&p[4]; | 126 | io = *(int *)&p[4]; |
181 | size = *(int *)&p[16]; | 127 | size = *(int *)&p[16]; |
182 | pnpbios_parse_allocated_memresource(res, io, size); | 128 | pnpbios_parse_allocated_memresource(dev, io, size); |
183 | break; | 129 | break; |
184 | 130 | ||
185 | case LARGE_TAG_FIXEDMEM32: | 131 | case LARGE_TAG_FIXEDMEM32: |
@@ -187,29 +133,37 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
187 | goto len_err; | 133 | goto len_err; |
188 | io = *(int *)&p[4]; | 134 | io = *(int *)&p[4]; |
189 | size = *(int *)&p[8]; | 135 | size = *(int *)&p[8]; |
190 | pnpbios_parse_allocated_memresource(res, io, size); | 136 | pnpbios_parse_allocated_memresource(dev, io, size); |
191 | break; | 137 | break; |
192 | 138 | ||
193 | case SMALL_TAG_IRQ: | 139 | case SMALL_TAG_IRQ: |
194 | if (len < 2 || len > 3) | 140 | if (len < 2 || len > 3) |
195 | goto len_err; | 141 | goto len_err; |
142 | flags = 0; | ||
196 | io = -1; | 143 | io = -1; |
197 | mask = p[1] + p[2] * 256; | 144 | mask = p[1] + p[2] * 256; |
198 | for (i = 0; i < 16; i++, mask = mask >> 1) | 145 | for (i = 0; i < 16; i++, mask = mask >> 1) |
199 | if (mask & 0x01) | 146 | if (mask & 0x01) |
200 | io = i; | 147 | io = i; |
201 | pnpbios_parse_allocated_irqresource(res, io); | 148 | if (io != -1) |
149 | pcibios_penalize_isa_irq(io, 1); | ||
150 | else | ||
151 | flags = IORESOURCE_DISABLED; | ||
152 | pnp_add_irq_resource(dev, io, flags); | ||
202 | break; | 153 | break; |
203 | 154 | ||
204 | case SMALL_TAG_DMA: | 155 | case SMALL_TAG_DMA: |
205 | if (len != 2) | 156 | if (len != 2) |
206 | goto len_err; | 157 | goto len_err; |
158 | flags = 0; | ||
207 | io = -1; | 159 | io = -1; |
208 | mask = p[1]; | 160 | mask = p[1]; |
209 | for (i = 0; i < 8; i++, mask = mask >> 1) | 161 | for (i = 0; i < 8; i++, mask = mask >> 1) |
210 | if (mask & 0x01) | 162 | if (mask & 0x01) |
211 | io = i; | 163 | io = i; |
212 | pnpbios_parse_allocated_dmaresource(res, io); | 164 | if (io == -1) |
165 | flags = IORESOURCE_DISABLED; | ||
166 | pnp_add_dma_resource(dev, io, flags); | ||
213 | break; | 167 | break; |
214 | 168 | ||
215 | case SMALL_TAG_PORT: | 169 | case SMALL_TAG_PORT: |
@@ -217,7 +171,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
217 | goto len_err; | 171 | goto len_err; |
218 | io = p[2] + p[3] * 256; | 172 | io = p[2] + p[3] * 256; |
219 | size = p[7]; | 173 | size = p[7]; |
220 | pnpbios_parse_allocated_ioresource(res, io, size); | 174 | pnpbios_parse_allocated_ioresource(dev, io, size); |
221 | break; | 175 | break; |
222 | 176 | ||
223 | case SMALL_TAG_VENDOR: | 177 | case SMALL_TAG_VENDOR: |
@@ -229,7 +183,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
229 | goto len_err; | 183 | goto len_err; |
230 | io = p[1] + p[2] * 256; | 184 | io = p[1] + p[2] * 256; |
231 | size = p[3]; | 185 | size = p[3]; |
232 | pnpbios_parse_allocated_ioresource(res, io, size); | 186 | pnpbios_parse_allocated_ioresource(dev, io, size); |
233 | break; | 187 | break; |
234 | 188 | ||
235 | case SMALL_TAG_END: | 189 | case SMALL_TAG_END: |
@@ -239,9 +193,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | |||
239 | 193 | ||
240 | default: /* an unkown tag */ | 194 | default: /* an unkown tag */ |
241 | len_err: | 195 | len_err: |
242 | printk(KERN_ERR | 196 | dev_err(&dev->dev, "unknown tag %#x length %d\n", |
243 | "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", | 197 | tag, len); |
244 | tag, len); | ||
245 | break; | 198 | break; |
246 | } | 199 | } |
247 | 200 | ||
@@ -252,8 +205,7 @@ len_err: | |||
252 | p += len + 1; | 205 | p += len + 1; |
253 | } | 206 | } |
254 | 207 | ||
255 | printk(KERN_ERR | 208 | dev_err(&dev->dev, "no end tag in resource structure\n"); |
256 | "PnPBIOS: Resource structure does not contain an end tag.\n"); | ||
257 | 209 | ||
258 | return NULL; | 210 | return NULL; |
259 | } | 211 | } |
@@ -262,7 +214,8 @@ len_err: | |||
262 | * Resource Configuration Options | 214 | * Resource Configuration Options |
263 | */ | 215 | */ |
264 | 216 | ||
265 | static __init void pnpbios_parse_mem_option(unsigned char *p, int size, | 217 | static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, |
218 | unsigned char *p, int size, | ||
266 | struct pnp_option *option) | 219 | struct pnp_option *option) |
267 | { | 220 | { |
268 | struct pnp_mem *mem; | 221 | struct pnp_mem *mem; |
@@ -275,10 +228,11 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size, | |||
275 | mem->align = (p[9] << 8) | p[8]; | 228 | mem->align = (p[9] << 8) | p[8]; |
276 | mem->size = ((p[11] << 8) | p[10]) << 8; | 229 | mem->size = ((p[11] << 8) | p[10]) << 8; |
277 | mem->flags = p[3]; | 230 | mem->flags = p[3]; |
278 | pnp_register_mem_resource(option, mem); | 231 | pnp_register_mem_resource(dev, option, mem); |
279 | } | 232 | } |
280 | 233 | ||
281 | static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, | 234 | static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, |
235 | unsigned char *p, int size, | ||
282 | struct pnp_option *option) | 236 | struct pnp_option *option) |
283 | { | 237 | { |
284 | struct pnp_mem *mem; | 238 | struct pnp_mem *mem; |
@@ -291,10 +245,11 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, | |||
291 | mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; | 245 | mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; |
292 | mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; | 246 | mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; |
293 | mem->flags = p[3]; | 247 | mem->flags = p[3]; |
294 | pnp_register_mem_resource(option, mem); | 248 | pnp_register_mem_resource(dev, option, mem); |
295 | } | 249 | } |
296 | 250 | ||
297 | static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | 251 | static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, |
252 | unsigned char *p, int size, | ||
298 | struct pnp_option *option) | 253 | struct pnp_option *option) |
299 | { | 254 | { |
300 | struct pnp_mem *mem; | 255 | struct pnp_mem *mem; |
@@ -306,11 +261,12 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | |||
306 | mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; | 261 | mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; |
307 | mem->align = 0; | 262 | mem->align = 0; |
308 | mem->flags = p[3]; | 263 | mem->flags = p[3]; |
309 | pnp_register_mem_resource(option, mem); | 264 | pnp_register_mem_resource(dev, option, mem); |
310 | } | 265 | } |
311 | 266 | ||
312 | static __init void pnpbios_parse_irq_option(unsigned char *p, int size, | 267 | static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, |
313 | struct pnp_option *option) | 268 | unsigned char *p, int size, |
269 | struct pnp_option *option) | ||
314 | { | 270 | { |
315 | struct pnp_irq *irq; | 271 | struct pnp_irq *irq; |
316 | unsigned long bits; | 272 | unsigned long bits; |
@@ -324,11 +280,12 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size, | |||
324 | irq->flags = p[3]; | 280 | irq->flags = p[3]; |
325 | else | 281 | else |
326 | irq->flags = IORESOURCE_IRQ_HIGHEDGE; | 282 | irq->flags = IORESOURCE_IRQ_HIGHEDGE; |
327 | pnp_register_irq_resource(option, irq); | 283 | pnp_register_irq_resource(dev, option, irq); |
328 | } | 284 | } |
329 | 285 | ||
330 | static __init void pnpbios_parse_dma_option(unsigned char *p, int size, | 286 | static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, |
331 | struct pnp_option *option) | 287 | unsigned char *p, int size, |
288 | struct pnp_option *option) | ||
332 | { | 289 | { |
333 | struct pnp_dma *dma; | 290 | struct pnp_dma *dma; |
334 | 291 | ||
@@ -337,10 +294,11 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size, | |||
337 | return; | 294 | return; |
338 | dma->map = p[1]; | 295 | dma->map = p[1]; |
339 | dma->flags = p[2]; | 296 | dma->flags = p[2]; |
340 | pnp_register_dma_resource(option, dma); | 297 | pnp_register_dma_resource(dev, option, dma); |
341 | } | 298 | } |
342 | 299 | ||
343 | static __init void pnpbios_parse_port_option(unsigned char *p, int size, | 300 | static __init void pnpbios_parse_port_option(struct pnp_dev *dev, |
301 | unsigned char *p, int size, | ||
344 | struct pnp_option *option) | 302 | struct pnp_option *option) |
345 | { | 303 | { |
346 | struct pnp_port *port; | 304 | struct pnp_port *port; |
@@ -353,10 +311,11 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size, | |||
353 | port->align = p[6]; | 311 | port->align = p[6]; |
354 | port->size = p[7]; | 312 | port->size = p[7]; |
355 | port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; | 313 | port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; |
356 | pnp_register_port_resource(option, port); | 314 | pnp_register_port_resource(dev, option, port); |
357 | } | 315 | } |
358 | 316 | ||
359 | static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | 317 | static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, |
318 | unsigned char *p, int size, | ||
360 | struct pnp_option *option) | 319 | struct pnp_option *option) |
361 | { | 320 | { |
362 | struct pnp_port *port; | 321 | struct pnp_port *port; |
@@ -368,7 +327,7 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | |||
368 | port->size = p[3]; | 327 | port->size = p[3]; |
369 | port->align = 0; | 328 | port->align = 0; |
370 | port->flags = PNP_PORT_FLAG_FIXED; | 329 | port->flags = PNP_PORT_FLAG_FIXED; |
371 | pnp_register_port_resource(option, port); | 330 | pnp_register_port_resource(dev, option, port); |
372 | } | 331 | } |
373 | 332 | ||
374 | static __init unsigned char * | 333 | static __init unsigned char * |
@@ -382,6 +341,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
382 | if (!p) | 341 | if (!p) |
383 | return NULL; | 342 | return NULL; |
384 | 343 | ||
344 | dev_dbg(&dev->dev, "parse resource options\n"); | ||
345 | |||
385 | option_independent = option = pnp_register_independent_option(dev); | 346 | option_independent = option = pnp_register_independent_option(dev); |
386 | if (!option) | 347 | if (!option) |
387 | return NULL; | 348 | return NULL; |
@@ -402,37 +363,37 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
402 | case LARGE_TAG_MEM: | 363 | case LARGE_TAG_MEM: |
403 | if (len != 9) | 364 | if (len != 9) |
404 | goto len_err; | 365 | goto len_err; |
405 | pnpbios_parse_mem_option(p, len, option); | 366 | pnpbios_parse_mem_option(dev, p, len, option); |
406 | break; | 367 | break; |
407 | 368 | ||
408 | case LARGE_TAG_MEM32: | 369 | case LARGE_TAG_MEM32: |
409 | if (len != 17) | 370 | if (len != 17) |
410 | goto len_err; | 371 | goto len_err; |
411 | pnpbios_parse_mem32_option(p, len, option); | 372 | pnpbios_parse_mem32_option(dev, p, len, option); |
412 | break; | 373 | break; |
413 | 374 | ||
414 | case LARGE_TAG_FIXEDMEM32: | 375 | case LARGE_TAG_FIXEDMEM32: |
415 | if (len != 9) | 376 | if (len != 9) |
416 | goto len_err; | 377 | goto len_err; |
417 | pnpbios_parse_fixed_mem32_option(p, len, option); | 378 | pnpbios_parse_fixed_mem32_option(dev, p, len, option); |
418 | break; | 379 | break; |
419 | 380 | ||
420 | case SMALL_TAG_IRQ: | 381 | case SMALL_TAG_IRQ: |
421 | if (len < 2 || len > 3) | 382 | if (len < 2 || len > 3) |
422 | goto len_err; | 383 | goto len_err; |
423 | pnpbios_parse_irq_option(p, len, option); | 384 | pnpbios_parse_irq_option(dev, p, len, option); |
424 | break; | 385 | break; |
425 | 386 | ||
426 | case SMALL_TAG_DMA: | 387 | case SMALL_TAG_DMA: |
427 | if (len != 2) | 388 | if (len != 2) |
428 | goto len_err; | 389 | goto len_err; |
429 | pnpbios_parse_dma_option(p, len, option); | 390 | pnpbios_parse_dma_option(dev, p, len, option); |
430 | break; | 391 | break; |
431 | 392 | ||
432 | case SMALL_TAG_PORT: | 393 | case SMALL_TAG_PORT: |
433 | if (len != 7) | 394 | if (len != 7) |
434 | goto len_err; | 395 | goto len_err; |
435 | pnpbios_parse_port_option(p, len, option); | 396 | pnpbios_parse_port_option(dev, p, len, option); |
436 | break; | 397 | break; |
437 | 398 | ||
438 | case SMALL_TAG_VENDOR: | 399 | case SMALL_TAG_VENDOR: |
@@ -442,7 +403,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
442 | case SMALL_TAG_FIXEDPORT: | 403 | case SMALL_TAG_FIXEDPORT: |
443 | if (len != 3) | 404 | if (len != 3) |
444 | goto len_err; | 405 | goto len_err; |
445 | pnpbios_parse_fixed_port_option(p, len, option); | 406 | pnpbios_parse_fixed_port_option(dev, p, len, option); |
446 | break; | 407 | break; |
447 | 408 | ||
448 | case SMALL_TAG_STARTDEP: | 409 | case SMALL_TAG_STARTDEP: |
@@ -460,9 +421,10 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
460 | if (len != 0) | 421 | if (len != 0) |
461 | goto len_err; | 422 | goto len_err; |
462 | if (option_independent == option) | 423 | if (option_independent == option) |
463 | printk(KERN_WARNING | 424 | dev_warn(&dev->dev, "missing " |
464 | "PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n"); | 425 | "SMALL_TAG_STARTDEP tag\n"); |
465 | option = option_independent; | 426 | option = option_independent; |
427 | dev_dbg(&dev->dev, "end dependent options\n"); | ||
466 | break; | 428 | break; |
467 | 429 | ||
468 | case SMALL_TAG_END: | 430 | case SMALL_TAG_END: |
@@ -470,9 +432,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
470 | 432 | ||
471 | default: /* an unkown tag */ | 433 | default: /* an unkown tag */ |
472 | len_err: | 434 | len_err: |
473 | printk(KERN_ERR | 435 | dev_err(&dev->dev, "unknown tag %#x length %d\n", |
474 | "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", | 436 | tag, len); |
475 | tag, len); | ||
476 | break; | 437 | break; |
477 | } | 438 | } |
478 | 439 | ||
@@ -483,8 +444,7 @@ len_err: | |||
483 | p += len + 1; | 444 | p += len + 1; |
484 | } | 445 | } |
485 | 446 | ||
486 | printk(KERN_ERR | 447 | dev_err(&dev->dev, "no end tag in resource structure\n"); |
487 | "PnPBIOS: Resource structure does not contain an end tag.\n"); | ||
488 | 448 | ||
489 | return NULL; | 449 | return NULL; |
490 | } | 450 | } |
@@ -493,32 +453,12 @@ len_err: | |||
493 | * Compatible Device IDs | 453 | * Compatible Device IDs |
494 | */ | 454 | */ |
495 | 455 | ||
496 | #define HEX(id,a) hex[((id)>>a) & 15] | ||
497 | #define CHAR(id,a) (0x40 + (((id)>>a) & 31)) | ||
498 | |||
499 | void pnpid32_to_pnpid(u32 id, char *str) | ||
500 | { | ||
501 | const char *hex = "0123456789abcdef"; | ||
502 | |||
503 | id = be32_to_cpu(id); | ||
504 | str[0] = CHAR(id, 26); | ||
505 | str[1] = CHAR(id, 21); | ||
506 | str[2] = CHAR(id, 16); | ||
507 | str[3] = HEX(id, 12); | ||
508 | str[4] = HEX(id, 8); | ||
509 | str[5] = HEX(id, 4); | ||
510 | str[6] = HEX(id, 0); | ||
511 | str[7] = '\0'; | ||
512 | } | ||
513 | |||
514 | #undef CHAR | ||
515 | #undef HEX | ||
516 | |||
517 | static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, | 456 | static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, |
518 | unsigned char *end, | 457 | unsigned char *end, |
519 | struct pnp_dev *dev) | 458 | struct pnp_dev *dev) |
520 | { | 459 | { |
521 | int len, tag; | 460 | int len, tag; |
461 | u32 eisa_id; | ||
522 | char id[8]; | 462 | char id[8]; |
523 | struct pnp_id *dev_id; | 463 | struct pnp_id *dev_id; |
524 | 464 | ||
@@ -548,13 +488,11 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, | |||
548 | case SMALL_TAG_COMPATDEVID: /* compatible ID */ | 488 | case SMALL_TAG_COMPATDEVID: /* compatible ID */ |
549 | if (len != 4) | 489 | if (len != 4) |
550 | goto len_err; | 490 | goto len_err; |
551 | dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); | 491 | eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24; |
492 | pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id); | ||
493 | dev_id = pnp_add_id(dev, id); | ||
552 | if (!dev_id) | 494 | if (!dev_id) |
553 | return NULL; | 495 | return NULL; |
554 | pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << | ||
555 | 24, id); | ||
556 | memcpy(&dev_id->id, id, 7); | ||
557 | pnp_add_id(dev_id, dev); | ||
558 | break; | 496 | break; |
559 | 497 | ||
560 | case SMALL_TAG_END: | 498 | case SMALL_TAG_END: |
@@ -564,9 +502,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, | |||
564 | 502 | ||
565 | default: /* an unkown tag */ | 503 | default: /* an unkown tag */ |
566 | len_err: | 504 | len_err: |
567 | printk(KERN_ERR | 505 | dev_err(&dev->dev, "unknown tag %#x length %d\n", |
568 | "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", | 506 | tag, len); |
569 | tag, len); | ||
570 | break; | 507 | break; |
571 | } | 508 | } |
572 | 509 | ||
@@ -577,8 +514,7 @@ len_err: | |||
577 | p += len + 1; | 514 | p += len + 1; |
578 | } | 515 | } |
579 | 516 | ||
580 | printk(KERN_ERR | 517 | dev_err(&dev->dev, "no end tag in resource structure\n"); |
581 | "PnPBIOS: Resource structure does not contain an end tag.\n"); | ||
582 | 518 | ||
583 | return NULL; | 519 | return NULL; |
584 | } | 520 | } |
@@ -587,7 +523,8 @@ len_err: | |||
587 | * Allocated Resource Encoding | 523 | * Allocated Resource Encoding |
588 | */ | 524 | */ |
589 | 525 | ||
590 | static void pnpbios_encode_mem(unsigned char *p, struct resource *res) | 526 | static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, |
527 | struct resource *res) | ||
591 | { | 528 | { |
592 | unsigned long base = res->start; | 529 | unsigned long base = res->start; |
593 | unsigned long len = res->end - res->start + 1; | 530 | unsigned long len = res->end - res->start + 1; |
@@ -598,9 +535,13 @@ static void pnpbios_encode_mem(unsigned char *p, struct resource *res) | |||
598 | p[7] = ((base >> 8) >> 8) & 0xff; | 535 | p[7] = ((base >> 8) >> 8) & 0xff; |
599 | p[10] = (len >> 8) & 0xff; | 536 | p[10] = (len >> 8) & 0xff; |
600 | p[11] = ((len >> 8) >> 8) & 0xff; | 537 | p[11] = ((len >> 8) >> 8) & 0xff; |
538 | |||
539 | dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n", | ||
540 | (unsigned long long) res->start, (unsigned long long) res->end); | ||
601 | } | 541 | } |
602 | 542 | ||
603 | static void pnpbios_encode_mem32(unsigned char *p, struct resource *res) | 543 | static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, |
544 | struct resource *res) | ||
604 | { | 545 | { |
605 | unsigned long base = res->start; | 546 | unsigned long base = res->start; |
606 | unsigned long len = res->end - res->start + 1; | 547 | unsigned long len = res->end - res->start + 1; |
@@ -617,9 +558,13 @@ static void pnpbios_encode_mem32(unsigned char *p, struct resource *res) | |||
617 | p[17] = (len >> 8) & 0xff; | 558 | p[17] = (len >> 8) & 0xff; |
618 | p[18] = (len >> 16) & 0xff; | 559 | p[18] = (len >> 16) & 0xff; |
619 | p[19] = (len >> 24) & 0xff; | 560 | p[19] = (len >> 24) & 0xff; |
561 | |||
562 | dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n", | ||
563 | (unsigned long long) res->start, (unsigned long long) res->end); | ||
620 | } | 564 | } |
621 | 565 | ||
622 | static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res) | 566 | static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, |
567 | struct resource *res) | ||
623 | { | 568 | { |
624 | unsigned long base = res->start; | 569 | unsigned long base = res->start; |
625 | unsigned long len = res->end - res->start + 1; | 570 | unsigned long len = res->end - res->start + 1; |
@@ -632,26 +577,36 @@ static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res) | |||
632 | p[9] = (len >> 8) & 0xff; | 577 | p[9] = (len >> 8) & 0xff; |
633 | p[10] = (len >> 16) & 0xff; | 578 | p[10] = (len >> 16) & 0xff; |
634 | p[11] = (len >> 24) & 0xff; | 579 | p[11] = (len >> 24) & 0xff; |
580 | |||
581 | dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n", | ||
582 | (unsigned long long) res->start, (unsigned long long) res->end); | ||
635 | } | 583 | } |
636 | 584 | ||
637 | static void pnpbios_encode_irq(unsigned char *p, struct resource *res) | 585 | static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, |
586 | struct resource *res) | ||
638 | { | 587 | { |
639 | unsigned long map = 0; | 588 | unsigned long map = 0; |
640 | 589 | ||
641 | map = 1 << res->start; | 590 | map = 1 << res->start; |
642 | p[1] = map & 0xff; | 591 | p[1] = map & 0xff; |
643 | p[2] = (map >> 8) & 0xff; | 592 | p[2] = (map >> 8) & 0xff; |
593 | |||
594 | dev_dbg(&dev->dev, " encode irq %d\n", res->start); | ||
644 | } | 595 | } |
645 | 596 | ||
646 | static void pnpbios_encode_dma(unsigned char *p, struct resource *res) | 597 | static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, |
598 | struct resource *res) | ||
647 | { | 599 | { |
648 | unsigned long map = 0; | 600 | unsigned long map = 0; |
649 | 601 | ||
650 | map = 1 << res->start; | 602 | map = 1 << res->start; |
651 | p[1] = map & 0xff; | 603 | p[1] = map & 0xff; |
604 | |||
605 | dev_dbg(&dev->dev, " encode dma %d\n", res->start); | ||
652 | } | 606 | } |
653 | 607 | ||
654 | static void pnpbios_encode_port(unsigned char *p, struct resource *res) | 608 | static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, |
609 | struct resource *res) | ||
655 | { | 610 | { |
656 | unsigned long base = res->start; | 611 | unsigned long base = res->start; |
657 | unsigned long len = res->end - res->start + 1; | 612 | unsigned long len = res->end - res->start + 1; |
@@ -661,9 +616,13 @@ static void pnpbios_encode_port(unsigned char *p, struct resource *res) | |||
661 | p[4] = base & 0xff; | 616 | p[4] = base & 0xff; |
662 | p[5] = (base >> 8) & 0xff; | 617 | p[5] = (base >> 8) & 0xff; |
663 | p[7] = len & 0xff; | 618 | p[7] = len & 0xff; |
619 | |||
620 | dev_dbg(&dev->dev, " encode io %#llx-%#llx\n", | ||
621 | (unsigned long long) res->start, (unsigned long long) res->end); | ||
664 | } | 622 | } |
665 | 623 | ||
666 | static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res) | 624 | static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, |
625 | struct resource *res) | ||
667 | { | 626 | { |
668 | unsigned long base = res->start; | 627 | unsigned long base = res->start; |
669 | unsigned long len = res->end - res->start + 1; | 628 | unsigned long len = res->end - res->start + 1; |
@@ -671,13 +630,15 @@ static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res) | |||
671 | p[1] = base & 0xff; | 630 | p[1] = base & 0xff; |
672 | p[2] = (base >> 8) & 0xff; | 631 | p[2] = (base >> 8) & 0xff; |
673 | p[3] = len & 0xff; | 632 | p[3] = len & 0xff; |
633 | |||
634 | dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", | ||
635 | (unsigned long long) res->start, (unsigned long long) res->end); | ||
674 | } | 636 | } |
675 | 637 | ||
676 | static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, | 638 | static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev |
677 | unsigned char *end, | 639 | *dev, |
678 | struct | 640 | unsigned char *p, |
679 | pnp_resource_table | 641 | unsigned char *end) |
680 | *res) | ||
681 | { | 642 | { |
682 | unsigned int len, tag; | 643 | unsigned int len, tag; |
683 | int port = 0, irq = 0, dma = 0, mem = 0; | 644 | int port = 0, irq = 0, dma = 0, mem = 0; |
@@ -701,42 +662,48 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, | |||
701 | case LARGE_TAG_MEM: | 662 | case LARGE_TAG_MEM: |
702 | if (len != 9) | 663 | if (len != 9) |
703 | goto len_err; | 664 | goto len_err; |
704 | pnpbios_encode_mem(p, &res->mem_resource[mem]); | 665 | pnpbios_encode_mem(dev, p, |
666 | pnp_get_resource(dev, IORESOURCE_MEM, mem)); | ||
705 | mem++; | 667 | mem++; |
706 | break; | 668 | break; |
707 | 669 | ||
708 | case LARGE_TAG_MEM32: | 670 | case LARGE_TAG_MEM32: |
709 | if (len != 17) | 671 | if (len != 17) |
710 | goto len_err; | 672 | goto len_err; |
711 | pnpbios_encode_mem32(p, &res->mem_resource[mem]); | 673 | pnpbios_encode_mem32(dev, p, |
674 | pnp_get_resource(dev, IORESOURCE_MEM, mem)); | ||
712 | mem++; | 675 | mem++; |
713 | break; | 676 | break; |
714 | 677 | ||
715 | case LARGE_TAG_FIXEDMEM32: | 678 | case LARGE_TAG_FIXEDMEM32: |
716 | if (len != 9) | 679 | if (len != 9) |
717 | goto len_err; | 680 | goto len_err; |
718 | pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]); | 681 | pnpbios_encode_fixed_mem32(dev, p, |
682 | pnp_get_resource(dev, IORESOURCE_MEM, mem)); | ||
719 | mem++; | 683 | mem++; |
720 | break; | 684 | break; |
721 | 685 | ||
722 | case SMALL_TAG_IRQ: | 686 | case SMALL_TAG_IRQ: |
723 | if (len < 2 || len > 3) | 687 | if (len < 2 || len > 3) |
724 | goto len_err; | 688 | goto len_err; |
725 | pnpbios_encode_irq(p, &res->irq_resource[irq]); | 689 | pnpbios_encode_irq(dev, p, |
690 | pnp_get_resource(dev, IORESOURCE_IRQ, irq)); | ||
726 | irq++; | 691 | irq++; |
727 | break; | 692 | break; |
728 | 693 | ||
729 | case SMALL_TAG_DMA: | 694 | case SMALL_TAG_DMA: |
730 | if (len != 2) | 695 | if (len != 2) |
731 | goto len_err; | 696 | goto len_err; |
732 | pnpbios_encode_dma(p, &res->dma_resource[dma]); | 697 | pnpbios_encode_dma(dev, p, |
698 | pnp_get_resource(dev, IORESOURCE_DMA, dma)); | ||
733 | dma++; | 699 | dma++; |
734 | break; | 700 | break; |
735 | 701 | ||
736 | case SMALL_TAG_PORT: | 702 | case SMALL_TAG_PORT: |
737 | if (len != 7) | 703 | if (len != 7) |
738 | goto len_err; | 704 | goto len_err; |
739 | pnpbios_encode_port(p, &res->port_resource[port]); | 705 | pnpbios_encode_port(dev, p, |
706 | pnp_get_resource(dev, IORESOURCE_IO, port)); | ||
740 | port++; | 707 | port++; |
741 | break; | 708 | break; |
742 | 709 | ||
@@ -747,7 +714,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, | |||
747 | case SMALL_TAG_FIXEDPORT: | 714 | case SMALL_TAG_FIXEDPORT: |
748 | if (len != 3) | 715 | if (len != 3) |
749 | goto len_err; | 716 | goto len_err; |
750 | pnpbios_encode_fixed_port(p, &res->port_resource[port]); | 717 | pnpbios_encode_fixed_port(dev, p, |
718 | pnp_get_resource(dev, IORESOURCE_IO, port)); | ||
751 | port++; | 719 | port++; |
752 | break; | 720 | break; |
753 | 721 | ||
@@ -758,9 +726,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, | |||
758 | 726 | ||
759 | default: /* an unkown tag */ | 727 | default: /* an unkown tag */ |
760 | len_err: | 728 | len_err: |
761 | printk(KERN_ERR | 729 | dev_err(&dev->dev, "unknown tag %#x length %d\n", |
762 | "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", | 730 | tag, len); |
763 | tag, len); | ||
764 | break; | 731 | break; |
765 | } | 732 | } |
766 | 733 | ||
@@ -771,8 +738,7 @@ len_err: | |||
771 | p += len + 1; | 738 | p += len + 1; |
772 | } | 739 | } |
773 | 740 | ||
774 | printk(KERN_ERR | 741 | dev_err(&dev->dev, "no end tag in resource structure\n"); |
775 | "PnPBIOS: Resource structure does not contain an end tag.\n"); | ||
776 | 742 | ||
777 | return NULL; | 743 | return NULL; |
778 | } | 744 | } |
@@ -787,7 +753,7 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev, | |||
787 | unsigned char *p = (char *)node->data; | 753 | unsigned char *p = (char *)node->data; |
788 | unsigned char *end = (char *)(node->data + node->size); | 754 | unsigned char *end = (char *)(node->data + node->size); |
789 | 755 | ||
790 | p = pnpbios_parse_allocated_resource_data(p, end, &dev->res); | 756 | p = pnpbios_parse_allocated_resource_data(dev, p, end); |
791 | if (!p) | 757 | if (!p) |
792 | return -EIO; | 758 | return -EIO; |
793 | p = pnpbios_parse_resource_option_data(p, end, dev); | 759 | p = pnpbios_parse_resource_option_data(p, end, dev); |
@@ -799,25 +765,25 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev, | |||
799 | return 0; | 765 | return 0; |
800 | } | 766 | } |
801 | 767 | ||
802 | int pnpbios_read_resources_from_node(struct pnp_resource_table *res, | 768 | int pnpbios_read_resources_from_node(struct pnp_dev *dev, |
803 | struct pnp_bios_node *node) | 769 | struct pnp_bios_node *node) |
804 | { | 770 | { |
805 | unsigned char *p = (char *)node->data; | 771 | unsigned char *p = (char *)node->data; |
806 | unsigned char *end = (char *)(node->data + node->size); | 772 | unsigned char *end = (char *)(node->data + node->size); |
807 | 773 | ||
808 | p = pnpbios_parse_allocated_resource_data(p, end, res); | 774 | p = pnpbios_parse_allocated_resource_data(dev, p, end); |
809 | if (!p) | 775 | if (!p) |
810 | return -EIO; | 776 | return -EIO; |
811 | return 0; | 777 | return 0; |
812 | } | 778 | } |
813 | 779 | ||
814 | int pnpbios_write_resources_to_node(struct pnp_resource_table *res, | 780 | int pnpbios_write_resources_to_node(struct pnp_dev *dev, |
815 | struct pnp_bios_node *node) | 781 | struct pnp_bios_node *node) |
816 | { | 782 | { |
817 | unsigned char *p = (char *)node->data; | 783 | unsigned char *p = (char *)node->data; |
818 | unsigned char *end = (char *)(node->data + node->size); | 784 | unsigned char *end = (char *)(node->data + node->size); |
819 | 785 | ||
820 | p = pnpbios_encode_allocated_resource_data(p, end, res); | 786 | p = pnpbios_encode_allocated_resource_data(dev, p, end); |
821 | if (!p) | 787 | if (!p) |
822 | return -EIO; | 788 | return -EIO; |
823 | return 0; | 789 | return 0; |