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