1 /* $NetBSD: acpi_resource.c,v 1.9 2003/11/03 18:07:10 mycroft Exp $ */ 2 3 /* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /*- 39 * Copyright (c) 2000 Michael Smith 40 * Copyright (c) 2000 BSDi 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 */ 64 65 /* 66 * ACPI resource parsing. 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: acpi_resource.c,v 1.9 2003/11/03 18:07:10 mycroft Exp $"); 71 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/device.h> 75 76 #include <dev/acpi/acpica.h> 77 #include <dev/acpi/acpireg.h> 78 #include <dev/acpi/acpivar.h> 79 80 #define _COMPONENT ACPI_RESOURCE_COMPONENT 81 ACPI_MODULE_NAME("RESOURCE") 82 83 /* 84 * acpi_resource_parse: 85 * 86 * Parse a device node's resources and fill them in for the 87 * client. 88 * 89 * Note that it might be nice to also locate ACPI-specific resource 90 * items, such as GPE bits. 91 */ 92 ACPI_STATUS 93 acpi_resource_parse(struct device *dev, struct acpi_devnode *ad, 94 void *arg, const struct acpi_resource_parse_ops *ops) 95 { 96 ACPI_BUFFER buf; 97 ACPI_RESOURCE *res; 98 char *cur, *last; 99 ACPI_STATUS status; 100 void *context; 101 int i; 102 103 ACPI_FUNCTION_TRACE(__FUNCTION__); 104 105 /* 106 * XXX Note, this means we only get devices that are currently 107 * decoding their address space. This might not be what we 108 * want, in the long term. 109 */ 110 111 status = acpi_get(ad->ad_handle, &buf, AcpiGetCurrentResources); 112 if (ACPI_FAILURE(status)) { 113 printf("%s: ACPI: unable to get Current Resources: %s\n", 114 dev->dv_xname, AcpiFormatException(status)); 115 return_ACPI_STATUS(status); 116 } 117 118 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "got %d bytes of _CRS\n", 119 buf.Length)); 120 121 (*ops->init)(dev, arg, &context); 122 123 cur = buf.Pointer; 124 last = cur + buf.Length; 125 while (cur < last) { 126 res = (ACPI_RESOURCE *) cur; 127 cur += res->Length; 128 129 switch (res->Id) { 130 case ACPI_RSTYPE_END_TAG: 131 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n")); 132 cur = last; 133 break; 134 135 case ACPI_RSTYPE_FIXED_IO: 136 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 137 "FixedIo 0x%x/%d\n", 138 res->Data.FixedIo.BaseAddress, 139 res->Data.FixedIo.RangeLength)); 140 (*ops->ioport)(dev, context, 141 res->Data.FixedIo.BaseAddress, 142 res->Data.FixedIo.RangeLength); 143 break; 144 145 case ACPI_RSTYPE_IO: 146 if (res->Data.Io.MinBaseAddress == 147 res->Data.Io.MaxBaseAddress) { 148 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 149 "Io 0x%x/%d\n", 150 res->Data.Io.MinBaseAddress, 151 res->Data.Io.RangeLength)); 152 (*ops->ioport)(dev, context, 153 res->Data.Io.MinBaseAddress, 154 res->Data.Io.RangeLength); 155 } else { 156 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 157 "Io 0x%x-0x%x/%d\n", 158 res->Data.Io.MinBaseAddress, 159 res->Data.Io.MaxBaseAddress, 160 res->Data.Io.RangeLength)); 161 (*ops->iorange)(dev, context, 162 res->Data.Io.MinBaseAddress, 163 res->Data.Io.MaxBaseAddress, 164 res->Data.Io.RangeLength, 165 res->Data.Io.Alignment); 166 } 167 break; 168 169 case ACPI_RSTYPE_FIXED_MEM32: 170 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 171 "FixedMemory32 0x%x/%d\n", 172 res->Data.FixedMemory32.RangeBaseAddress, 173 res->Data.FixedMemory32.RangeLength)); 174 (*ops->memory)(dev, context, 175 res->Data.FixedMemory32.RangeBaseAddress, 176 res->Data.FixedMemory32.RangeLength); 177 break; 178 179 case ACPI_RSTYPE_MEM32: 180 if (res->Data.Memory32.MinBaseAddress == 181 res->Data.Memory32.MaxBaseAddress) { 182 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 183 "Memory32 0x%x/%d\n", 184 res->Data.Memory32.MinBaseAddress, 185 res->Data.Memory32.RangeLength)); 186 (*ops->memory)(dev, context, 187 res->Data.Memory32.MinBaseAddress, 188 res->Data.Memory32.RangeLength); 189 } else { 190 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 191 "Memory32 0x%x-0x%x/%d\n", 192 res->Data.Memory32.MinBaseAddress, 193 res->Data.Memory32.MaxBaseAddress, 194 res->Data.Memory32.RangeLength)); 195 (*ops->memrange)(dev, context, 196 res->Data.Memory32.MinBaseAddress, 197 res->Data.Memory32.MaxBaseAddress, 198 res->Data.Memory32.RangeLength, 199 res->Data.Memory32.Alignment); 200 } 201 break; 202 203 case ACPI_RSTYPE_MEM24: 204 if (res->Data.Memory24.MinBaseAddress == 205 res->Data.Memory24.MaxBaseAddress) { 206 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 207 "Memory24 0x%x/%d\n", 208 res->Data.Memory24.MinBaseAddress, 209 res->Data.Memory24.RangeLength)); 210 (*ops->memory)(dev, context, 211 res->Data.Memory24.MinBaseAddress, 212 res->Data.Memory24.RangeLength); 213 } else { 214 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 215 "Memory24 0x%x-0x%x/%d\n", 216 res->Data.Memory24.MinBaseAddress, 217 res->Data.Memory24.MaxBaseAddress, 218 res->Data.Memory24.RangeLength)); 219 (*ops->memrange)(dev, context, 220 res->Data.Memory24.MinBaseAddress, 221 res->Data.Memory24.MaxBaseAddress, 222 res->Data.Memory24.RangeLength, 223 res->Data.Memory24.Alignment); 224 } 225 break; 226 227 case ACPI_RSTYPE_IRQ: 228 for (i = 0; i < res->Data.Irq.NumberOfInterrupts; i++) { 229 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 230 "IRQ %d\n", res->Data.Irq.Interrupts[i])); 231 (*ops->irq)(dev, context, 232 res->Data.Irq.Interrupts[i], 233 res->Data.Irq.EdgeLevel); 234 } 235 break; 236 237 case ACPI_RSTYPE_DMA: 238 for (i = 0; i < res->Data.Dma.NumberOfChannels; i++) { 239 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 240 "DRQ %d\n", res->Data.Dma.Channels[i])); 241 (*ops->drq)(dev, context, 242 res->Data.Dma.Channels[i]); 243 } 244 break; 245 246 case ACPI_RSTYPE_START_DPF: 247 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 248 "Start dependant functions: %d\n", 249 res->Data.StartDpf.CompatibilityPriority)); 250 (*ops->start_dep)(dev, context, 251 res->Data.StartDpf.CompatibilityPriority); 252 break; 253 254 case ACPI_RSTYPE_END_DPF: 255 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 256 "End dependant functions\n")); 257 (*ops->end_dep)(dev, context); 258 259 case ACPI_RSTYPE_ADDRESS32: 260 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 261 "Address32 unimplemented\n")); 262 break; 263 264 case ACPI_RSTYPE_ADDRESS16: 265 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 266 "Address16 unimplemented\n")); 267 break; 268 269 case ACPI_RSTYPE_EXT_IRQ: 270 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 271 "ExtendedIrq unimplemented\n")); 272 break; 273 274 case ACPI_RSTYPE_VENDOR: 275 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 276 "VendorSpecific unimplemented\n")); 277 break; 278 279 default: 280 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, 281 "Unknown resource type: %d\n", res->Id)); 282 break; 283 } 284 } 285 286 AcpiOsFree(buf.Pointer); 287 (*ops->fini)(dev, context); 288 289 return_ACPI_STATUS(AE_OK); 290 } 291 292 /* 293 * acpi_resource_print: 294 * 295 * Print the resources assigned to a device. 296 */ 297 void 298 acpi_resource_print(struct device *dev, struct acpi_resources *res) 299 { 300 const char *sep; 301 302 if (SIMPLEQ_EMPTY(&res->ar_io) && 303 SIMPLEQ_EMPTY(&res->ar_iorange) && 304 SIMPLEQ_EMPTY(&res->ar_mem) && 305 SIMPLEQ_EMPTY(&res->ar_memrange) && 306 SIMPLEQ_EMPTY(&res->ar_irq) && 307 SIMPLEQ_EMPTY(&res->ar_drq)) 308 return; 309 310 printf("%s:", dev->dv_xname); 311 312 if (SIMPLEQ_EMPTY(&res->ar_io) == 0) { 313 struct acpi_io *ar; 314 315 sep = ""; 316 printf(" io "); 317 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) { 318 printf("%s0x%x", sep, ar->ar_base); 319 if (ar->ar_length > 1) 320 printf("-0x%x", ar->ar_base + 321 ar->ar_length - 1); 322 sep = ","; 323 } 324 } 325 326 /* XXX iorange */ 327 328 if (SIMPLEQ_EMPTY(&res->ar_mem) == 0) { 329 struct acpi_mem *ar; 330 331 sep = ""; 332 printf(" mem "); 333 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) { 334 printf("%s0x%x", sep, ar->ar_base); 335 if (ar->ar_length > 1) 336 printf("-0x%x", ar->ar_base + 337 ar->ar_length - 1); 338 sep = ","; 339 } 340 } 341 342 /* XXX memrange */ 343 344 if (SIMPLEQ_EMPTY(&res->ar_irq) == 0) { 345 struct acpi_irq *ar; 346 347 sep = ""; 348 printf(" irq "); 349 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) { 350 printf("%s%d", sep, ar->ar_irq); 351 sep = ","; 352 } 353 } 354 355 if (SIMPLEQ_EMPTY(&res->ar_drq) == 0) { 356 struct acpi_drq *ar; 357 358 sep = ""; 359 printf(" drq "); 360 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) { 361 printf("%s%d", sep, ar->ar_drq); 362 sep = ","; 363 } 364 } 365 366 printf("\n"); 367 } 368 369 struct acpi_io * 370 acpi_res_io(struct acpi_resources *res, int idx) 371 { 372 struct acpi_io *ar; 373 374 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) { 375 if (ar->ar_index == idx) 376 return (ar); 377 } 378 return (NULL); 379 } 380 381 struct acpi_iorange * 382 acpi_res_iorange(struct acpi_resources *res, int idx) 383 { 384 struct acpi_iorange *ar; 385 386 SIMPLEQ_FOREACH(ar, &res->ar_iorange, ar_list) { 387 if (ar->ar_index == idx) 388 return (ar); 389 } 390 return (NULL); 391 } 392 393 struct acpi_mem * 394 acpi_res_mem(struct acpi_resources *res, int idx) 395 { 396 struct acpi_mem *ar; 397 398 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) { 399 if (ar->ar_index == idx) 400 return (ar); 401 } 402 return (NULL); 403 } 404 405 struct acpi_memrange * 406 acpi_res_memrange(struct acpi_resources *res, int idx) 407 { 408 struct acpi_memrange *ar; 409 410 SIMPLEQ_FOREACH(ar, &res->ar_memrange, ar_list) { 411 if (ar->ar_index == idx) 412 return (ar); 413 } 414 return (NULL); 415 } 416 417 struct acpi_irq * 418 acpi_res_irq(struct acpi_resources *res, int idx) 419 { 420 struct acpi_irq *ar; 421 422 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) { 423 if (ar->ar_index == idx) 424 return (ar); 425 } 426 return (NULL); 427 } 428 429 struct acpi_drq * 430 acpi_res_drq(struct acpi_resources *res, int idx) 431 { 432 struct acpi_drq *ar; 433 434 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) { 435 if (ar->ar_index == idx) 436 return (ar); 437 } 438 return (NULL); 439 } 440 441 /***************************************************************************** 442 * Default ACPI resource parse operations. 443 *****************************************************************************/ 444 445 static void acpi_res_parse_init(struct device *, void *, void **); 446 static void acpi_res_parse_fini(struct device *, void *); 447 448 static void acpi_res_parse_ioport(struct device *, void *, uint32_t, 449 uint32_t); 450 static void acpi_res_parse_iorange(struct device *, void *, uint32_t, 451 uint32_t, uint32_t, uint32_t); 452 453 static void acpi_res_parse_memory(struct device *, void *, uint32_t, 454 uint32_t); 455 static void acpi_res_parse_memrange(struct device *, void *, uint32_t, 456 uint32_t, uint32_t, uint32_t); 457 458 static void acpi_res_parse_irq(struct device *, void *, uint32_t, uint32_t); 459 static void acpi_res_parse_drq(struct device *, void *, uint32_t); 460 461 static void acpi_res_parse_start_dep(struct device *, void *, int); 462 static void acpi_res_parse_end_dep(struct device *, void *); 463 464 const struct acpi_resource_parse_ops acpi_resource_parse_ops_default = { 465 acpi_res_parse_init, 466 acpi_res_parse_fini, 467 468 acpi_res_parse_ioport, 469 acpi_res_parse_iorange, 470 471 acpi_res_parse_memory, 472 acpi_res_parse_memrange, 473 474 acpi_res_parse_irq, 475 acpi_res_parse_drq, 476 477 acpi_res_parse_start_dep, 478 acpi_res_parse_end_dep, 479 }; 480 481 static void 482 acpi_res_parse_init(struct device *dev, void *arg, void **contextp) 483 { 484 struct acpi_resources *res = arg; 485 486 SIMPLEQ_INIT(&res->ar_io); 487 res->ar_nio = 0; 488 489 SIMPLEQ_INIT(&res->ar_iorange); 490 res->ar_niorange = 0; 491 492 SIMPLEQ_INIT(&res->ar_mem); 493 res->ar_nmem = 0; 494 495 SIMPLEQ_INIT(&res->ar_memrange); 496 res->ar_nmemrange = 0; 497 498 SIMPLEQ_INIT(&res->ar_irq); 499 res->ar_nirq = 0; 500 501 SIMPLEQ_INIT(&res->ar_drq); 502 res->ar_ndrq = 0; 503 504 *contextp = res; 505 } 506 507 static void 508 acpi_res_parse_fini(struct device *dev, void *context) 509 { 510 struct acpi_resources *res = context; 511 512 /* Print the resources we're using. */ 513 acpi_resource_print(dev, res); 514 } 515 516 static void 517 acpi_res_parse_ioport(struct device *dev, void *context, uint32_t base, 518 uint32_t length) 519 { 520 struct acpi_resources *res = context; 521 struct acpi_io *ar; 522 523 /* 524 * Check if there is another I/O port directly below/under 525 * this one. 526 */ 527 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) { 528 if (ar->ar_base == base + length ) { 529 /* 530 * Entry just below existing entry - adjust 531 * the entry and return. 532 */ 533 ar->ar_base = base; 534 ar->ar_length += length; 535 return; 536 } else if (ar->ar_base + ar->ar_length == base) { 537 /* 538 * Entry just above existing entry - adjust 539 * the entry and return. 540 */ 541 ar->ar_length += length; 542 return; 543 } 544 } 545 546 ar = AcpiOsAllocate(sizeof(*ar)); 547 if (ar == NULL) { 548 printf("%s: ACPI: unable to allocate I/O resource %d\n", 549 dev->dv_xname, res->ar_nio); 550 res->ar_nio++; 551 return; 552 } 553 554 ar->ar_index = res->ar_nio++; 555 ar->ar_base = base; 556 ar->ar_length = length; 557 558 SIMPLEQ_INSERT_TAIL(&res->ar_io, ar, ar_list); 559 } 560 561 static void 562 acpi_res_parse_iorange(struct device *dev, void *context, uint32_t low, 563 uint32_t high, uint32_t length, uint32_t align) 564 { 565 struct acpi_resources *res = context; 566 struct acpi_iorange *ar; 567 568 ar = AcpiOsAllocate(sizeof(*ar)); 569 if (ar == NULL) { 570 printf("%s: ACPI: unable to allocate I/O range resource %d\n", 571 dev->dv_xname, res->ar_niorange); 572 res->ar_niorange++; 573 return; 574 } 575 576 ar->ar_index = res->ar_niorange++; 577 ar->ar_low = low; 578 ar->ar_high = high; 579 ar->ar_length = length; 580 ar->ar_align = align; 581 582 SIMPLEQ_INSERT_TAIL(&res->ar_iorange, ar, ar_list); 583 } 584 585 static void 586 acpi_res_parse_memory(struct device *dev, void *context, uint32_t base, 587 uint32_t length) 588 { 589 struct acpi_resources *res = context; 590 struct acpi_mem *ar; 591 592 ar = AcpiOsAllocate(sizeof(*ar)); 593 if (ar == NULL) { 594 printf("%s: ACPI: unable to allocate Memory resource %d\n", 595 dev->dv_xname, res->ar_nmem); 596 res->ar_nmem++; 597 return; 598 } 599 600 ar->ar_index = res->ar_nmem++; 601 ar->ar_base = base; 602 ar->ar_length = length; 603 604 SIMPLEQ_INSERT_TAIL(&res->ar_mem, ar, ar_list); 605 } 606 607 static void 608 acpi_res_parse_memrange(struct device *dev, void *context, uint32_t low, 609 uint32_t high, uint32_t length, uint32_t align) 610 { 611 struct acpi_resources *res = context; 612 struct acpi_memrange *ar; 613 614 ar = AcpiOsAllocate(sizeof(*ar)); 615 if (ar == NULL) { 616 printf("%s: ACPI: unable to allocate Memory range resource " 617 "%d\n", dev->dv_xname, res->ar_nmemrange); 618 res->ar_nmemrange++; 619 return; 620 } 621 622 ar->ar_index = res->ar_nmemrange++; 623 ar->ar_low = low; 624 ar->ar_high = high; 625 ar->ar_length = length; 626 ar->ar_align = align; 627 628 SIMPLEQ_INSERT_TAIL(&res->ar_memrange, ar, ar_list); 629 } 630 631 static void 632 acpi_res_parse_irq(struct device *dev, void *context, uint32_t irq, uint32_t type) 633 { 634 struct acpi_resources *res = context; 635 struct acpi_irq *ar; 636 637 ar = AcpiOsAllocate(sizeof(*ar)); 638 if (ar == NULL) { 639 printf("%s: ACPI: unable to allocate IRQ resource %d\n", 640 dev->dv_xname, res->ar_nirq); 641 res->ar_nirq++; 642 return; 643 } 644 645 ar->ar_index = res->ar_nirq++; 646 ar->ar_irq = irq; 647 ar->ar_type = type; 648 649 SIMPLEQ_INSERT_TAIL(&res->ar_irq, ar, ar_list); 650 } 651 652 static void 653 acpi_res_parse_drq(struct device *dev, void *context, uint32_t drq) 654 { 655 struct acpi_resources *res = context; 656 struct acpi_drq *ar; 657 658 ar = AcpiOsAllocate(sizeof(*ar)); 659 if (ar == NULL) { 660 printf("%s: ACPI: unable to allocate DRQ resource %d\n", 661 dev->dv_xname, res->ar_ndrq); 662 res->ar_ndrq++; 663 return; 664 } 665 666 ar->ar_index = res->ar_ndrq++; 667 ar->ar_drq = drq; 668 669 SIMPLEQ_INSERT_TAIL(&res->ar_drq, ar, ar_list); 670 } 671 672 static void 673 acpi_res_parse_start_dep(struct device *dev, void *context, int preference) 674 { 675 676 printf("%s: ACPI: dependant functions not supported\n", 677 dev->dv_xname); 678 } 679 680 static void 681 acpi_res_parse_end_dep(struct device *dev, void *context) 682 { 683 684 /* Nothing to do. */ 685 } 686