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; |
