1 /* 2 * pnpacpi -- PnP ACPI driver 3 * 4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> 5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 #include <linux/kernel.h> 22 #include <linux/acpi.h> 23 #include <linux/pci.h> 24 #include "pnpacpi.h" 25 26 #ifdef CONFIG_IA64 27 #define valid_IRQ(i) (1) 28 #else 29 #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) 30 #endif 31 32 /* 33 * Allocated Resources 34 */ 35 static int irq_flags(int triggering, int polarity) 36 { 37 if (triggering == ACPI_LEVEL_SENSITIVE) { 38 if (polarity == ACPI_ACTIVE_LOW) 39 return IORESOURCE_IRQ_LOWLEVEL; 40 else 41 return IORESOURCE_IRQ_HIGHLEVEL; 42 } else { 43 if (polarity == ACPI_ACTIVE_LOW) 44 return IORESOURCE_IRQ_LOWEDGE; 45 else 46 return IORESOURCE_IRQ_HIGHEDGE; 47 } 48 } 49 50 static void decode_irq_flags(int flag, int *triggering, int *polarity) 51 { 52 switch (flag) { 53 case IORESOURCE_IRQ_LOWLEVEL: 54 *triggering = ACPI_LEVEL_SENSITIVE; 55 *polarity = ACPI_ACTIVE_LOW; 56 break; 57 case IORESOURCE_IRQ_HIGHLEVEL: 58 *triggering = ACPI_LEVEL_SENSITIVE; 59 *polarity = ACPI_ACTIVE_HIGH; 60 break; 61 case IORESOURCE_IRQ_LOWEDGE: 62 *triggering = ACPI_EDGE_SENSITIVE; 63 *polarity = ACPI_ACTIVE_LOW; 64 break; 65 case IORESOURCE_IRQ_HIGHEDGE: 66 *triggering = ACPI_EDGE_SENSITIVE; 67 *polarity = ACPI_ACTIVE_HIGH; 68 break; 69 } 70 } 71 72 static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, 73 u32 gsi, int triggering, 74 int polarity, int shareable) 75 { 76 int i = 0; 77 int irq; 78 79 if (!valid_IRQ(gsi)) 80 return; 81 82 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && 83 i < PNP_MAX_IRQ) 84 i++; 85 if (i >= PNP_MAX_IRQ) 86 return; 87 88 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag 89 res->irq_resource[i].flags |= irq_flags(triggering, polarity); 90 irq = acpi_register_gsi(gsi, triggering, polarity); 91 if (irq < 0) { 92 res->irq_resource[i].flags |= IORESOURCE_DISABLED; 93 return; 94 } 95 96 if (shareable) 97 res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE; 98 99 res->irq_resource[i].start = irq; 100 res->irq_resource[i].end = irq; 101 pcibios_penalize_isa_irq(irq, 1); 102 } 103 104 static int dma_flags(int type, int bus_master, int transfer) 105 { 106 int flags = 0; 107 108 if (bus_master) 109 flags |= IORESOURCE_DMA_MASTER; 110 switch (type) { 111 case ACPI_COMPATIBILITY: 112 flags |= IORESOURCE_DMA_COMPATIBLE; 113 break; 114 case ACPI_TYPE_A: 115 flags |= IORESOURCE_DMA_TYPEA; 116 break; 117 case ACPI_TYPE_B: 118 flags |= IORESOURCE_DMA_TYPEB; 119 break; 120 case ACPI_TYPE_F: 121 flags |= IORESOURCE_DMA_TYPEF; 122 break; 123 default: 124 /* Set a default value ? */ 125 flags |= IORESOURCE_DMA_COMPATIBLE; 126 pnp_err("Invalid DMA type"); 127 } 128 switch (transfer) { 129 case ACPI_TRANSFER_8: 130 flags |= IORESOURCE_DMA_8BIT; 131 break; 132 case ACPI_TRANSFER_8_16: 133 flags |= IORESOURCE_DMA_8AND16BIT; 134 break; 135 case ACPI_TRANSFER_16: 136 flags |= IORESOURCE_DMA_16BIT; 137 break; 138 default: 139 /* Set a default value ? */ 140 flags |= IORESOURCE_DMA_8AND16BIT; 141 pnp_err("Invalid DMA transfer type"); 142 } 143 144 return flags; 145 } 146 147 static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, 148 u32 dma, int type, 149 int bus_master, int transfer) 150 { 151 int i = 0; 152 153 while (i < PNP_MAX_DMA && 154 !(res->dma_resource[i].flags & IORESOURCE_UNSET)) 155 i++; 156 if (i < PNP_MAX_DMA) { 157 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag 158 res->dma_resource[i].flags |= 159 dma_flags(type, bus_master, transfer); 160 if (dma == -1) { 161 res->dma_resource[i].flags |= IORESOURCE_DISABLED; 162 return; 163 } 164 res->dma_resource[i].start = dma; 165 res->dma_resource[i].end = dma; 166 } 167 } 168 169 static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, 170 u64 io, u64 len, int io_decode) 171 { 172 int i = 0; 173 174 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && 175 i < PNP_MAX_PORT) 176 i++; 177 if (i < PNP_MAX_PORT) { 178 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag 179 if (io_decode == ACPI_DECODE_16) 180 res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR; 181 if (len <= 0 || (io + len - 1) >= 0x10003) { 182 res->port_resource[i].flags |= IORESOURCE_DISABLED; 183 return; 184 } 185 res->port_resource[i].start = io; 186 res->port_resource[i].end = io + len - 1; 187 } 188 } 189 190 static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, 191 u64 mem, u64 len, 192 int write_protect) 193 { 194 int i = 0; 195 196 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && 197 (i < PNP_MAX_MEM)) 198 i++; 199 if (i < PNP_MAX_MEM) { 200 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag 201 if (len <= 0) { 202 res->mem_resource[i].flags |= IORESOURCE_DISABLED; 203 return; 204 } 205 if (write_protect == ACPI_READ_WRITE_MEMORY) 206 res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE; 207 208 res->mem_resource[i].start = mem; 209 res->mem_resource[i].end = mem + len - 1; 210 } 211 } 212 213 static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, 214 struct acpi_resource *res) 215 { 216 struct acpi_resource_address64 addr, *p = &addr; 217 acpi_status status; 218 219 status = acpi_resource_to_address64(res, p); 220 if (!ACPI_SUCCESS(status)) { 221 pnp_warn("PnPACPI: failed to convert resource type %d", 222 res->type); 223 return; 224 } 225 226 if (p->producer_consumer == ACPI_PRODUCER) 227 return; 228 229 if (p->resource_type == ACPI_MEMORY_RANGE) 230 pnpacpi_parse_allocated_memresource(res_table, 231 p->minimum, p->address_length, 232 p->info.mem.write_protect); 233 else if (p->resource_type == ACPI_IO_RANGE) 234 pnpacpi_parse_allocated_ioresource(res_table, 235 p->minimum, p->address_length, 236 p->granularity == 0xfff ? ACPI_DECODE_10 : 237 ACPI_DECODE_16); 238 } 239 240 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, 241 void *data) 242 { 243 struct pnp_resource_table *res_table = data; 244 int i; 245 246 switch (res->type) { 247 case ACPI_RESOURCE_TYPE_IRQ: 248 /* 249 * Per spec, only one interrupt per descriptor is allowed in 250 * _CRS, but some firmware violates this, so parse them all. 251 */ 252 for (i = 0; i < res->data.irq.interrupt_count; i++) { 253 pnpacpi_parse_allocated_irqresource(res_table, 254 res->data.irq.interrupts[i], 255 res->data.irq.triggering, 256 res->data.irq.polarity, 257 res->data.irq.sharable); 258 } 259 break; 260 261 case ACPI_RESOURCE_TYPE_DMA: 262 if (res->data.dma.channel_count > 0) 263 pnpacpi_parse_allocated_dmaresource(res_table, 264 res->data.dma.channels[0], 265 res->data.dma.type, 266 res->data.dma.bus_master, 267 res->data.dma.transfer); 268 break; 269 270 case ACPI_RESOURCE_TYPE_IO: 271 pnpacpi_parse_allocated_ioresource(res_table, 272 res->data.io.minimum, 273 res->data.io.address_length, 274 res->data.io.io_decode); 275 break; 276 277 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 278 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 279 break; 280 281 case ACPI_RESOURCE_TYPE_FIXED_IO: 282 pnpacpi_parse_allocated_ioresource(res_table, 283 res->data.fixed_io.address, 284 res->data.fixed_io.address_length, 285 ACPI_DECODE_10); 286 break; 287 288 case ACPI_RESOURCE_TYPE_VENDOR: 289 break; 290 291 case ACPI_RESOURCE_TYPE_END_TAG: 292 break; 293 294 case ACPI_RESOURCE_TYPE_MEMORY24: 295 pnpacpi_parse_allocated_memresource(res_table, 296 res->data.memory24.minimum, 297 res->data.memory24.address_length, 298 res->data.memory24.write_protect); 299 break; 300 case ACPI_RESOURCE_TYPE_MEMORY32: 301 pnpacpi_parse_allocated_memresource(res_table, 302 res->data.memory32.minimum, 303 res->data.memory32.address_length, 304 res->data.memory32.write_protect); 305 break; 306 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 307 pnpacpi_parse_allocated_memresource(res_table, 308 res->data.fixed_memory32.address, 309 res->data.fixed_memory32.address_length, 310 res->data.fixed_memory32.write_protect); 311 break; 312 case ACPI_RESOURCE_TYPE_ADDRESS16: 313 case ACPI_RESOURCE_TYPE_ADDRESS32: 314 case ACPI_RESOURCE_TYPE_ADDRESS64: 315 pnpacpi_parse_allocated_address_space(res_table, res); 316 break; 317 318 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 319 if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER) 320 return AE_OK; 321 break; 322 323 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 324 if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER) 325 return AE_OK; 326 327 for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { 328 pnpacpi_parse_allocated_irqresource(res_table, 329 res->data.extended_irq.interrupts[i], 330 res->data.extended_irq.triggering, 331 res->data.extended_irq.polarity, 332 res->data.extended_irq.sharable); 333 } 334 break; 335 336 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 337 break; 338 339 default: 340 pnp_warn("PnPACPI: unknown resource type %d", res->type); 341 return AE_ERROR; 342 } 343 344 return AE_OK; 345 } 346 347 acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, 348 struct pnp_resource_table * res) 349 { 350 /* Blank the resource table values */ 351 pnp_init_resource_table(res); 352 353 return acpi_walk_resources(handle, METHOD_NAME__CRS, 354 pnpacpi_allocated_resource, res); 355 } 356 357 static void pnpacpi_parse_dma_option(struct pnp_option *option, 358 struct acpi_resource_dma *p) 359 { 360 int i; 361 struct pnp_dma *dma; 362 363 if (p->channel_count == 0) 364 return; 365 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); 366 if (!dma) 367 return; 368 369 for (i = 0; i < p->channel_count; i++) 370 dma->map |= 1 << p->channels[i]; 371 372 dma->flags = dma_flags(p->type, p->bus_master, p->transfer); 373 374 pnp_register_dma_resource(option, dma); 375 } 376 377 static void pnpacpi_parse_irq_option(struct pnp_option *option, 378 struct acpi_resource_irq *p) 379 { 380 int i; 381 struct pnp_irq *irq; 382 383 if (p->interrupt_count == 0) 384 return; 385 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); 386 if (!irq) 387 return; 388 389 for (i = 0; i < p->interrupt_count; i++) 390 if (p->interrupts[i]) 391 __set_bit(p->interrupts[i], irq->map); 392 irq->flags = irq_flags(p->triggering, p->polarity); 393 394 pnp_register_irq_resource(option, irq); 395 } 396 397 static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, 398 struct acpi_resource_extended_irq *p) 399 { 400 int i; 401 struct pnp_irq *irq; 402 403 if (p->interrupt_count == 0) 404 return; 405 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); 406 if (!irq) 407 return; 408 409 for (i = 0; i < p->interrupt_count; i++) 410 if (p->interrupts[i]) 411 __set_bit(p->interrupts[i], irq->map); 412 irq->flags = irq_flags(p->triggering, p->polarity); 413 414 pnp_register_irq_resource(option, irq); 415 } 416 417 static void pnpacpi_parse_port_option(struct pnp_option *option, 418 struct acpi_resource_io *io) 419 { 420 struct pnp_port *port; 421 422 if (io->address_length == 0) 423 return; 424 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 425 if (!port) 426 return; 427 port->min = io->minimum; 428 port->max = io->maximum; 429 port->align = io->alignment; 430 port->size = io->address_length; 431 port->flags = ACPI_DECODE_16 == io->io_decode ? 432 PNP_PORT_FLAG_16BITADDR : 0; 433 pnp_register_port_resource(option, port); 434 } 435 436 static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, 437 struct acpi_resource_fixed_io *io) 438 { 439 struct pnp_port *port; 440 441 if (io->address_length == 0) 442 return; 443 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 444 if (!port) 445 return; 446 port->min = port->max = io->address; 447 port->size = io->address_length; 448 port->align = 0; 449 port->flags = PNP_PORT_FLAG_FIXED; 450 pnp_register_port_resource(option, port); 451 } 452 453 static void pnpacpi_parse_mem24_option(struct pnp_option *option, 454 struct acpi_resource_memory24 *p) 455 { 456 struct pnp_mem *mem; 457 458 if (p->address_length == 0) 459 return; 460 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 461 if (!mem) 462 return; 463 mem->min = p->minimum; 464 mem->max = p->maximum; 465 mem->align = p->alignment; 466 mem->size = p->address_length; 467 468 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 469 IORESOURCE_MEM_WRITEABLE : 0; 470 471 pnp_register_mem_resource(option, mem); 472 } 473 474 static void pnpacpi_parse_mem32_option(struct pnp_option *option, 475 struct acpi_resource_memory32 *p) 476 { 477 struct pnp_mem *mem; 478 479 if (p->address_length == 0) 480 return; 481 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 482 if (!mem) 483 return; 484 mem->min = p->minimum; 485 mem->max = p->maximum; 486 mem->align = p->alignment; 487 mem->size = p->address_length; 488 489 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 490 IORESOURCE_MEM_WRITEABLE : 0; 491 492 pnp_register_mem_resource(option, mem); 493 } 494 495 static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, 496 struct acpi_resource_fixed_memory32 *p) 497 { 498 struct pnp_mem *mem; 499 500 if (p->address_length == 0) 501 return; 502 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 503 if (!mem) 504 return; 505 mem->min = mem->max = p->address; 506 mem->size = p->address_length; 507 mem->align = 0; 508 509 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 510 IORESOURCE_MEM_WRITEABLE : 0; 511 512 pnp_register_mem_resource(option, mem); 513 } 514 515 static void pnpacpi_parse_address_option(struct pnp_option *option, 516 struct acpi_resource *r) 517 { 518 struct acpi_resource_address64 addr, *p = &addr; 519 acpi_status status; 520 struct pnp_mem *mem; 521 struct pnp_port *port; 522 523 status = acpi_resource_to_address64(r, p); 524 if (!ACPI_SUCCESS(status)) { 525 pnp_warn("PnPACPI: failed to convert resource type %d", 526 r->type); 527 return; 528 } 529 530 if (p->address_length == 0) 531 return; 532 533 if (p->resource_type == ACPI_MEMORY_RANGE) { 534 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 535 if (!mem) 536 return; 537 mem->min = mem->max = p->minimum; 538 mem->size = p->address_length; 539 mem->align = 0; 540 mem->flags = (p->info.mem.write_protect == 541 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE 542 : 0; 543 pnp_register_mem_resource(option, mem); 544 } else if (p->resource_type == ACPI_IO_RANGE) { 545 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 546 if (!port) 547 return; 548 port->min = port->max = p->minimum; 549 port->size = p->address_length; 550 port->align = 0; 551 port->flags = PNP_PORT_FLAG_FIXED; 552 pnp_register_port_resource(option, port); 553 } 554 } 555 556 struct acpipnp_parse_option_s { 557 struct pnp_option *option; 558 struct pnp_option *option_independent; 559 struct pnp_dev *dev; 560 }; 561 562 static acpi_status pnpacpi_option_resource(struct acpi_resource *res, 563 void *data) 564 { 565 int priority = 0; 566 struct acpipnp_parse_option_s *parse_data = data; 567 struct pnp_dev *dev = parse_data->dev; 568 struct pnp_option *option = parse_data->option; 569 570 switch (res->type) { 571 case ACPI_RESOURCE_TYPE_IRQ: 572 pnpacpi_parse_irq_option(option, &res->data.irq); 573 break; 574 575 case ACPI_RESOURCE_TYPE_DMA: 576 pnpacpi_parse_dma_option(option, &res->data.dma); 577 break; 578 579 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 580 switch (res->data.start_dpf.compatibility_priority) { 581 case ACPI_GOOD_CONFIGURATION: 582 priority = PNP_RES_PRIORITY_PREFERRED; 583 break; 584 585 case ACPI_ACCEPTABLE_CONFIGURATION: 586 priority = PNP_RES_PRIORITY_ACCEPTABLE; 587 break; 588 589 case ACPI_SUB_OPTIMAL_CONFIGURATION: 590 priority = PNP_RES_PRIORITY_FUNCTIONAL; 591 break; 592 default: 593 priority = PNP_RES_PRIORITY_INVALID; 594 break; 595 } 596 /* TBD: Consider performance/robustness bits */ 597 option = pnp_register_dependent_option(dev, priority); 598 if (!option) 599 return AE_ERROR; 600 parse_data->option = option; 601 break; 602 603 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 604 /*only one EndDependentFn is allowed */ 605 if (!parse_data->option_independent) { 606 pnp_warn("PnPACPI: more than one EndDependentFn"); 607 return AE_ERROR; 608 } 609 parse_data->option = parse_data->option_independent; 610 parse_data->option_independent = NULL; 611 break; 612 613 case ACPI_RESOURCE_TYPE_IO: 614 pnpacpi_parse_port_option(option, &res->data.io); 615 break; 616 617 case ACPI_RESOURCE_TYPE_FIXED_IO: 618 pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io); 619 break; 620 621 case ACPI_RESOURCE_TYPE_VENDOR: 622 case ACPI_RESOURCE_TYPE_END_TAG: 623 break; 624 625 case ACPI_RESOURCE_TYPE_MEMORY24: 626 pnpacpi_parse_mem24_option(option, &res->data.memory24); 627 break; 628 629 case ACPI_RESOURCE_TYPE_MEMORY32: 630 pnpacpi_parse_mem32_option(option, &res->data.memory32); 631 break; 632 633 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 634 pnpacpi_parse_fixed_mem32_option(option, 635 &res->data.fixed_memory32); 636 break; 637 638 case ACPI_RESOURCE_TYPE_ADDRESS16: 639 case ACPI_RESOURCE_TYPE_ADDRESS32: 640 case ACPI_RESOURCE_TYPE_ADDRESS64: 641 pnpacpi_parse_address_option(option, res); 642 break; 643 644 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 645 break; 646 647 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 648 pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq); 649 break; 650 651 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 652 break; 653 654 default: 655 pnp_warn("PnPACPI: unknown resource type %d", res->type); 656 return AE_ERROR; 657 } 658 659 return AE_OK; 660 } 661 662 acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, 663 struct pnp_dev * dev) 664 { 665 acpi_status status; 666 struct acpipnp_parse_option_s parse_data; 667 668 parse_data.option = pnp_register_independent_option(dev); 669 if (!parse_data.option) 670 return AE_ERROR; 671 parse_data.option_independent = parse_data.option; 672 parse_data.dev = dev; 673 status = acpi_walk_resources(handle, METHOD_NAME__PRS, 674 pnpacpi_option_resource, &parse_data); 675 676 return status; 677 } 678 679 static int pnpacpi_supported_resource(struct acpi_resource *res) 680 { 681 switch (res->type) { 682 case ACPI_RESOURCE_TYPE_IRQ: 683 case ACPI_RESOURCE_TYPE_DMA: 684 case ACPI_RESOURCE_TYPE_IO: 685 case ACPI_RESOURCE_TYPE_FIXED_IO: 686 case ACPI_RESOURCE_TYPE_MEMORY24: 687 case ACPI_RESOURCE_TYPE_MEMORY32: 688 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 689 case ACPI_RESOURCE_TYPE_ADDRESS16: 690 case ACPI_RESOURCE_TYPE_ADDRESS32: 691 case ACPI_RESOURCE_TYPE_ADDRESS64: 692 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 693 return 1; 694 } 695 return 0; 696 } 697 698 /* 699 * Set resource 700 */ 701 static acpi_status pnpacpi_count_resources(struct acpi_resource *res, 702 void *data) 703 { 704 int *res_cnt = data; 705 706 if (pnpacpi_supported_resource(res)) 707 (*res_cnt)++; 708 return AE_OK; 709 } 710 711 static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) 712 { 713 struct acpi_resource **resource = data; 714 715 if (pnpacpi_supported_resource(res)) { 716 (*resource)->type = res->type; 717 (*resource)->length = sizeof(struct acpi_resource); 718 (*resource)++; 719 } 720 721 return AE_OK; 722 } 723 724 int pnpacpi_build_resource_template(acpi_handle handle, 725 struct acpi_buffer *buffer) 726 { 727 struct acpi_resource *resource; 728 int res_cnt = 0; 729 acpi_status status; 730 731 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 732 pnpacpi_count_resources, &res_cnt); 733 if (ACPI_FAILURE(status)) { 734 pnp_err("Evaluate _CRS failed"); 735 return -EINVAL; 736 } 737 if (!res_cnt) 738 return -EINVAL; 739 buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1; 740 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL); 741 if (!buffer->pointer) 742 return -ENOMEM; 743 pnp_dbg("Res cnt %d", res_cnt); 744 resource = (struct acpi_resource *)buffer->pointer; 745 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 746 pnpacpi_type_resources, &resource); 747 if (ACPI_FAILURE(status)) { 748 kfree(buffer->pointer); 749 pnp_err("Evaluate _CRS failed"); 750 return -EINVAL; 751 } 752 /* resource will pointer the end resource now */ 753 resource->type = ACPI_RESOURCE_TYPE_END_TAG; 754 755 return 0; 756 } 757 758 static void pnpacpi_encode_irq(struct acpi_resource *resource, 759 struct resource *p) 760 { 761 int triggering, polarity; 762 763 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 764 resource->data.irq.triggering = triggering; 765 resource->data.irq.polarity = polarity; 766 if (triggering == ACPI_EDGE_SENSITIVE) 767 resource->data.irq.sharable = ACPI_EXCLUSIVE; 768 else 769 resource->data.irq.sharable = ACPI_SHARED; 770 resource->data.irq.interrupt_count = 1; 771 resource->data.irq.interrupts[0] = p->start; 772 } 773 774 static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, 775 struct resource *p) 776 { 777 int triggering, polarity; 778 779 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 780 resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; 781 resource->data.extended_irq.triggering = triggering; 782 resource->data.extended_irq.polarity = polarity; 783 if (triggering == ACPI_EDGE_SENSITIVE) 784 resource->data.irq.sharable = ACPI_EXCLUSIVE; 785 else 786 resource->data.irq.sharable = ACPI_SHARED; 787 resource->data.extended_irq.interrupt_count = 1; 788 resource->data.extended_irq.interrupts[0] = p->start; 789 } 790 791 static void pnpacpi_encode_dma(struct acpi_resource *resource, 792 struct resource *p) 793 { 794 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 795 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 796 case IORESOURCE_DMA_TYPEA: 797 resource->data.dma.type = ACPI_TYPE_A; 798 break; 799 case IORESOURCE_DMA_TYPEB: 800 resource->data.dma.type = ACPI_TYPE_B; 801 break; 802 case IORESOURCE_DMA_TYPEF: 803 resource->data.dma.type = ACPI_TYPE_F; 804 break; 805 default: 806 resource->data.dma.type = ACPI_COMPATIBILITY; 807 } 808 809 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { 810 case IORESOURCE_DMA_8BIT: 811 resource->data.dma.transfer = ACPI_TRANSFER_8; 812 break; 813 case IORESOURCE_DMA_8AND16BIT: 814 resource->data.dma.transfer = ACPI_TRANSFER_8_16; 815 break; 816 default: 817 resource->data.dma.transfer = ACPI_TRANSFER_16; 818 } 819 820 resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); 821 resource->data.dma.channel_count = 1; 822 resource->data.dma.channels[0] = p->start; 823 } 824 825 static void pnpacpi_encode_io(struct acpi_resource *resource, 826 struct resource *p) 827 { 828 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ 829 resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? 830 ACPI_DECODE_16 : ACPI_DECODE_10; 831 resource->data.io.minimum = p->start; 832 resource->data.io.maximum = p->end; 833 resource->data.io.alignment = 0; /* Correct? */ 834 resource->data.io.address_length = p->end - p->start + 1; 835 } 836 837 static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, 838 struct resource *p) 839 { 840 resource->data.fixed_io.address = p->start; 841 resource->data.fixed_io.address_length = p->end - p->start + 1; 842 } 843 844 static void pnpacpi_encode_mem24(struct acpi_resource *resource, 845 struct resource *p) 846 { 847 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ 848 resource->data.memory24.write_protect = 849 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 850 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 851 resource->data.memory24.minimum = p->start; 852 resource->data.memory24.maximum = p->end; 853 resource->data.memory24.alignment = 0; 854 resource->data.memory24.address_length = p->end - p->start + 1; 855 } 856 857 static void pnpacpi_encode_mem32(struct acpi_resource *resource, 858 struct resource *p) 859 { 860 resource->data.memory32.write_protect = 861 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 862 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 863 resource->data.memory32.minimum = p->start; 864 resource->data.memory32.maximum = p->end; 865 resource->data.memory32.alignment = 0; 866 resource->data.memory32.address_length = p->end - p->start + 1; 867 } 868 869 static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, 870 struct resource *p) 871 { 872 resource->data.fixed_memory32.write_protect = 873 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 874 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 875 resource->data.fixed_memory32.address = p->start; 876 resource->data.fixed_memory32.address_length = p->end - p->start + 1; 877 } 878 879 int pnpacpi_encode_resources(struct pnp_resource_table *res_table, 880 struct acpi_buffer *buffer) 881 { 882 int i = 0; 883 /* pnpacpi_build_resource_template allocates extra mem */ 884 int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1; 885 struct acpi_resource *resource = buffer->pointer; 886 int port = 0, irq = 0, dma = 0, mem = 0; 887 888 pnp_dbg("res cnt %d", res_cnt); 889 while (i < res_cnt) { 890 switch (resource->type) { 891 case ACPI_RESOURCE_TYPE_IRQ: 892 pnp_dbg("Encode irq"); 893 pnpacpi_encode_irq(resource, 894 &res_table->irq_resource[irq]); 895 irq++; 896 break; 897 898 case ACPI_RESOURCE_TYPE_DMA: 899 pnp_dbg("Encode dma"); 900 pnpacpi_encode_dma(resource, 901 &res_table->dma_resource[dma]); 902 dma++; 903 break; 904 case ACPI_RESOURCE_TYPE_IO: 905 pnp_dbg("Encode io"); 906 pnpacpi_encode_io(resource, 907 &res_table->port_resource[port]); 908 port++; 909 break; 910 case ACPI_RESOURCE_TYPE_FIXED_IO: 911 pnp_dbg("Encode fixed io"); 912 pnpacpi_encode_fixed_io(resource, 913 &res_table-> 914 port_resource[port]); 915 port++; 916 break; 917 case ACPI_RESOURCE_TYPE_MEMORY24: 918 pnp_dbg("Encode mem24"); 919 pnpacpi_encode_mem24(resource, 920 &res_table->mem_resource[mem]); 921 mem++; 922 break; 923 case ACPI_RESOURCE_TYPE_MEMORY32: 924 pnp_dbg("Encode mem32"); 925 pnpacpi_encode_mem32(resource, 926 &res_table->mem_resource[mem]); 927 mem++; 928 break; 929 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 930 pnp_dbg("Encode fixed mem32"); 931 pnpacpi_encode_fixed_mem32(resource, 932 &res_table-> 933 mem_resource[mem]); 934 mem++; 935 break; 936 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 937 pnp_dbg("Encode ext irq"); 938 pnpacpi_encode_ext_irq(resource, 939 &res_table->irq_resource[irq]); 940 irq++; 941 break; 942 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 943 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 944 case ACPI_RESOURCE_TYPE_VENDOR: 945 case ACPI_RESOURCE_TYPE_END_TAG: 946 case ACPI_RESOURCE_TYPE_ADDRESS16: 947 case ACPI_RESOURCE_TYPE_ADDRESS32: 948 case ACPI_RESOURCE_TYPE_ADDRESS64: 949 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 950 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 951 default: /* other type */ 952 pnp_warn("unknown resource type %d", resource->type); 953 return -EINVAL; 954 } 955 resource++; 956 i++; 957 } 958 return 0; 959 } 960