acpi_resource.c revision 1.13 1 /* $NetBSD: acpi_resource.c,v 1.13 2004/04/11 09:25:28 kochi 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.13 2004/04/11 09:25:28 kochi 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 static ACPI_STATUS acpi_resource_parse_callback(ACPI_RESOURCE *, void *);
84
85 struct resource_parse_callback_arg {
86 const struct acpi_resource_parse_ops *ops;
87 struct device *dev;
88 void *context;
89 };
90
91 static ACPI_STATUS
92 acpi_resource_parse_callback(ACPI_RESOURCE *res, void *context)
93 {
94 struct resource_parse_callback_arg *arg = context;
95 const struct acpi_resource_parse_ops *ops;
96 int i;
97
98 ops = arg->ops;
99
100 switch (res->Id) {
101 case ACPI_RSTYPE_FIXED_IO:
102 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
103 "FixedIo 0x%x/%d\n",
104 res->Data.FixedIo.BaseAddress,
105 res->Data.FixedIo.RangeLength));
106 if (ops->ioport)
107 (*ops->ioport)(arg->dev, arg->context,
108 res->Data.FixedIo.BaseAddress,
109 res->Data.FixedIo.RangeLength);
110 break;
111
112 case ACPI_RSTYPE_IO:
113 if (res->Data.Io.MinBaseAddress ==
114 res->Data.Io.MaxBaseAddress) {
115 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
116 "Io 0x%x/%d\n",
117 res->Data.Io.MinBaseAddress,
118 res->Data.Io.RangeLength));
119 if (ops->ioport)
120 (*ops->ioport)(arg->dev, arg->context,
121 res->Data.Io.MinBaseAddress,
122 res->Data.Io.RangeLength);
123 } else {
124 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
125 "Io 0x%x-0x%x/%d\n",
126 res->Data.Io.MinBaseAddress,
127 res->Data.Io.MaxBaseAddress,
128 res->Data.Io.RangeLength));
129 if (ops->ioport)
130 (*ops->iorange)(arg->dev, arg->context,
131 res->Data.Io.MinBaseAddress,
132 res->Data.Io.MaxBaseAddress,
133 res->Data.Io.RangeLength,
134 res->Data.Io.Alignment);
135 }
136 break;
137
138 case ACPI_RSTYPE_FIXED_MEM32:
139 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
140 "FixedMemory32 0x%x/%d\n",
141 res->Data.FixedMemory32.RangeBaseAddress,
142 res->Data.FixedMemory32.RangeLength));
143 if (ops->memory)
144 (*ops->memory)(arg->dev, arg->context,
145 res->Data.FixedMemory32.RangeBaseAddress,
146 res->Data.FixedMemory32.RangeLength);
147 break;
148
149 case ACPI_RSTYPE_MEM32:
150 if (res->Data.Memory32.MinBaseAddress ==
151 res->Data.Memory32.MaxBaseAddress) {
152 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
153 "Memory32 0x%x/%d\n",
154 res->Data.Memory32.MinBaseAddress,
155 res->Data.Memory32.RangeLength));
156 if (ops->memory)
157 (*ops->memory)(arg->dev, arg->context,
158 res->Data.Memory32.MinBaseAddress,
159 res->Data.Memory32.RangeLength);
160 } else {
161 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
162 "Memory32 0x%x-0x%x/%d\n",
163 res->Data.Memory32.MinBaseAddress,
164 res->Data.Memory32.MaxBaseAddress,
165 res->Data.Memory32.RangeLength));
166 if (ops->memrange)
167 (*ops->memrange)(arg->dev, arg->context,
168 res->Data.Memory32.MinBaseAddress,
169 res->Data.Memory32.MaxBaseAddress,
170 res->Data.Memory32.RangeLength,
171 res->Data.Memory32.Alignment);
172 }
173 break;
174
175 case ACPI_RSTYPE_MEM24:
176 if (res->Data.Memory24.MinBaseAddress ==
177 res->Data.Memory24.MaxBaseAddress) {
178 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
179 "Memory24 0x%x/%d\n",
180 res->Data.Memory24.MinBaseAddress,
181 res->Data.Memory24.RangeLength));
182 if (ops->memory)
183 (*ops->memory)(arg->dev, arg->context,
184 res->Data.Memory24.MinBaseAddress,
185 res->Data.Memory24.RangeLength);
186 } else {
187 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
188 "Memory24 0x%x-0x%x/%d\n",
189 res->Data.Memory24.MinBaseAddress,
190 res->Data.Memory24.MaxBaseAddress,
191 res->Data.Memory24.RangeLength));
192 if (ops->memrange)
193 (*ops->memrange)(arg->dev, arg->context,
194 res->Data.Memory24.MinBaseAddress,
195 res->Data.Memory24.MaxBaseAddress,
196 res->Data.Memory24.RangeLength,
197 res->Data.Memory24.Alignment);
198 }
199 break;
200
201 case ACPI_RSTYPE_IRQ:
202 for (i = 0; i < res->Data.Irq.NumberOfInterrupts; i++) {
203 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
204 "IRQ %d\n",
205 res->Data.Irq.Interrupts[i]));
206 if (ops->irq)
207 (*ops->irq)(arg->dev, arg->context,
208 res->Data.Irq.Interrupts[i],
209 res->Data.Irq.EdgeLevel);
210 }
211 break;
212
213 case ACPI_RSTYPE_DMA:
214 for (i = 0; i < res->Data.Dma.NumberOfChannels; i++) {
215 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
216 "DRQ %d\n",
217 res->Data.Dma.Channels[i]));
218 if (ops->drq)
219 (*ops->drq)(arg->dev, arg->context,
220 res->Data.Dma.Channels[i]);
221 }
222 break;
223
224 case ACPI_RSTYPE_START_DPF:
225 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
226 "Start dependant functions: %d\n",
227 res->Data.StartDpf.CompatibilityPriority));
228 if (ops->start_dep)
229 (*ops->start_dep)(arg->dev, arg->context,
230 res->Data.StartDpf.CompatibilityPriority);
231 break;
232
233 case ACPI_RSTYPE_END_DPF:
234 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
235 "End dependant functions\n"));
236 if (ops->end_dep)
237 (*ops->end_dep)(arg->dev, arg->context);
238
239 case ACPI_RSTYPE_ADDRESS32:
240 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
241 "Address32 unimplemented\n"));
242 break;
243
244 case ACPI_RSTYPE_ADDRESS16:
245 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
246 "Address16 unimplemented\n"));
247 break;
248
249 case ACPI_RSTYPE_EXT_IRQ:
250 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
251 "ExtendedIrq unimplemented\n"));
252 break;
253
254 case ACPI_RSTYPE_VENDOR:
255 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
256 "VendorSpecific unimplemented\n"));
257 break;
258
259 default:
260 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
261 "Unknown resource type: %d\n", res->Id));
262 break;
263 }
264
265 return AE_OK;
266 }
267
268
269 /*
270 * acpi_resource_parse:
271 *
272 * Parse a device node's resources and fill them in for the
273 * client.
274 *
275 * This API supports _CRS (current resources) and
276 * _PRS (possible resources).
277 *
278 * Note that it might be nice to also locate ACPI-specific resource
279 * items, such as GPE bits.
280 */
281 ACPI_STATUS
282 acpi_resource_parse(struct device *dev, ACPI_HANDLE handle, char *path,
283 void *arg, const struct acpi_resource_parse_ops *ops)
284 {
285 struct resource_parse_callback_arg cbarg;
286 ACPI_STATUS rv;
287
288 ACPI_FUNCTION_TRACE(__FUNCTION__);
289
290 if (ops->init)
291 (*ops->init)(dev, arg, &cbarg.context);
292 else
293 cbarg.context = arg;
294 cbarg.ops = ops;
295 cbarg.dev = dev;
296
297 rv =AcpiWalkResources(handle, path, acpi_resource_parse_callback,
298 &cbarg);
299 if (ACPI_FAILURE(rv)) {
300 printf("%s: ACPI: unable to get %s resources: %s\n",
301 dev->dv_xname, path, AcpiFormatException(rv));
302 return_ACPI_STATUS(rv);
303 }
304
305 if (ops->fini)
306 (*ops->fini)(dev, cbarg.context);
307
308 return_ACPI_STATUS(AE_OK);
309 }
310
311 /*
312 * acpi_resource_print:
313 *
314 * Print the resources assigned to a device.
315 */
316 void
317 acpi_resource_print(struct device *dev, struct acpi_resources *res)
318 {
319 const char *sep;
320
321 if (SIMPLEQ_EMPTY(&res->ar_io) &&
322 SIMPLEQ_EMPTY(&res->ar_iorange) &&
323 SIMPLEQ_EMPTY(&res->ar_mem) &&
324 SIMPLEQ_EMPTY(&res->ar_memrange) &&
325 SIMPLEQ_EMPTY(&res->ar_irq) &&
326 SIMPLEQ_EMPTY(&res->ar_drq))
327 return;
328
329 printf("%s:", dev->dv_xname);
330
331 if (SIMPLEQ_EMPTY(&res->ar_io) == 0) {
332 struct acpi_io *ar;
333
334 sep = "";
335 printf(" io ");
336 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
337 printf("%s0x%x", sep, ar->ar_base);
338 if (ar->ar_length > 1)
339 printf("-0x%x", ar->ar_base +
340 ar->ar_length - 1);
341 sep = ",";
342 }
343 }
344
345 /* XXX iorange */
346
347 if (SIMPLEQ_EMPTY(&res->ar_mem) == 0) {
348 struct acpi_mem *ar;
349
350 sep = "";
351 printf(" mem ");
352 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
353 printf("%s0x%x", sep, ar->ar_base);
354 if (ar->ar_length > 1)
355 printf("-0x%x", ar->ar_base +
356 ar->ar_length - 1);
357 sep = ",";
358 }
359 }
360
361 /* XXX memrange */
362
363 if (SIMPLEQ_EMPTY(&res->ar_irq) == 0) {
364 struct acpi_irq *ar;
365
366 sep = "";
367 printf(" irq ");
368 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
369 printf("%s%d", sep, ar->ar_irq);
370 sep = ",";
371 }
372 }
373
374 if (SIMPLEQ_EMPTY(&res->ar_drq) == 0) {
375 struct acpi_drq *ar;
376
377 sep = "";
378 printf(" drq ");
379 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
380 printf("%s%d", sep, ar->ar_drq);
381 sep = ",";
382 }
383 }
384
385 printf("\n");
386 }
387
388 struct acpi_io *
389 acpi_res_io(struct acpi_resources *res, int idx)
390 {
391 struct acpi_io *ar;
392
393 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
394 if (ar->ar_index == idx)
395 return ar;
396 }
397 return NULL;
398 }
399
400 struct acpi_iorange *
401 acpi_res_iorange(struct acpi_resources *res, int idx)
402 {
403 struct acpi_iorange *ar;
404
405 SIMPLEQ_FOREACH(ar, &res->ar_iorange, ar_list) {
406 if (ar->ar_index == idx)
407 return ar;
408 }
409 return NULL;
410 }
411
412 struct acpi_mem *
413 acpi_res_mem(struct acpi_resources *res, int idx)
414 {
415 struct acpi_mem *ar;
416
417 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
418 if (ar->ar_index == idx)
419 return ar;
420 }
421 return NULL;
422 }
423
424 struct acpi_memrange *
425 acpi_res_memrange(struct acpi_resources *res, int idx)
426 {
427 struct acpi_memrange *ar;
428
429 SIMPLEQ_FOREACH(ar, &res->ar_memrange, ar_list) {
430 if (ar->ar_index == idx)
431 return ar;
432 }
433 return NULL;
434 }
435
436 struct acpi_irq *
437 acpi_res_irq(struct acpi_resources *res, int idx)
438 {
439 struct acpi_irq *ar;
440
441 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
442 if (ar->ar_index == idx)
443 return ar;
444 }
445 return NULL;
446 }
447
448 struct acpi_drq *
449 acpi_res_drq(struct acpi_resources *res, int idx)
450 {
451 struct acpi_drq *ar;
452
453 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
454 if (ar->ar_index == idx)
455 return ar;
456 }
457 return NULL;
458 }
459
460 /*****************************************************************************
461 * Default ACPI resource parse operations.
462 *****************************************************************************/
463
464 static void acpi_res_parse_init(struct device *, void *, void **);
465 static void acpi_res_parse_fini(struct device *, void *);
466
467 static void acpi_res_parse_ioport(struct device *, void *, uint32_t,
468 uint32_t);
469 static void acpi_res_parse_iorange(struct device *, void *, uint32_t,
470 uint32_t, uint32_t, uint32_t);
471
472 static void acpi_res_parse_memory(struct device *, void *, uint32_t,
473 uint32_t);
474 static void acpi_res_parse_memrange(struct device *, void *, uint32_t,
475 uint32_t, uint32_t, uint32_t);
476
477 static void acpi_res_parse_irq(struct device *, void *, uint32_t, uint32_t);
478 static void acpi_res_parse_drq(struct device *, void *, uint32_t);
479
480 static void acpi_res_parse_start_dep(struct device *, void *, int);
481 static void acpi_res_parse_end_dep(struct device *, void *);
482
483 const struct acpi_resource_parse_ops acpi_resource_parse_ops_default = {
484 .init = acpi_res_parse_init,
485 .fini = acpi_res_parse_fini,
486
487 .ioport = acpi_res_parse_ioport,
488 .iorange = acpi_res_parse_iorange,
489
490 .memory = acpi_res_parse_memory,
491 .memrange = acpi_res_parse_memrange,
492
493 .irq = acpi_res_parse_irq,
494 .drq = acpi_res_parse_drq,
495
496 .start_dep = acpi_res_parse_start_dep,
497 .end_dep = acpi_res_parse_end_dep,
498 };
499
500 static void
501 acpi_res_parse_init(struct device *dev, void *arg, void **contextp)
502 {
503 struct acpi_resources *res = arg;
504
505 SIMPLEQ_INIT(&res->ar_io);
506 res->ar_nio = 0;
507
508 SIMPLEQ_INIT(&res->ar_iorange);
509 res->ar_niorange = 0;
510
511 SIMPLEQ_INIT(&res->ar_mem);
512 res->ar_nmem = 0;
513
514 SIMPLEQ_INIT(&res->ar_memrange);
515 res->ar_nmemrange = 0;
516
517 SIMPLEQ_INIT(&res->ar_irq);
518 res->ar_nirq = 0;
519
520 SIMPLEQ_INIT(&res->ar_drq);
521 res->ar_ndrq = 0;
522
523 *contextp = res;
524 }
525
526 static void
527 acpi_res_parse_fini(struct device *dev, void *context)
528 {
529 struct acpi_resources *res = context;
530
531 /* Print the resources we're using. */
532 acpi_resource_print(dev, res);
533 }
534
535 static void
536 acpi_res_parse_ioport(struct device *dev, void *context, uint32_t base,
537 uint32_t length)
538 {
539 struct acpi_resources *res = context;
540 struct acpi_io *ar;
541
542 /*
543 * Check if there is another I/O port directly below/under
544 * this one.
545 */
546 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
547 if (ar->ar_base == base + length ) {
548 /*
549 * Entry just below existing entry - adjust
550 * the entry and return.
551 */
552 ar->ar_base = base;
553 ar->ar_length += length;
554 return;
555 } else if (ar->ar_base + ar->ar_length == base) {
556 /*
557 * Entry just above existing entry - adjust
558 * the entry and return.
559 */
560 ar->ar_length += length;
561 return;
562 }
563 }
564
565 ar = AcpiOsAllocate(sizeof(*ar));
566 if (ar == NULL) {
567 printf("%s: ACPI: unable to allocate I/O resource %d\n",
568 dev->dv_xname, res->ar_nio);
569 res->ar_nio++;
570 return;
571 }
572
573 ar->ar_index = res->ar_nio++;
574 ar->ar_base = base;
575 ar->ar_length = length;
576
577 SIMPLEQ_INSERT_TAIL(&res->ar_io, ar, ar_list);
578 }
579
580 static void
581 acpi_res_parse_iorange(struct device *dev, void *context, uint32_t low,
582 uint32_t high, uint32_t length, uint32_t align)
583 {
584 struct acpi_resources *res = context;
585 struct acpi_iorange *ar;
586
587 ar = AcpiOsAllocate(sizeof(*ar));
588 if (ar == NULL) {
589 printf("%s: ACPI: unable to allocate I/O range resource %d\n",
590 dev->dv_xname, res->ar_niorange);
591 res->ar_niorange++;
592 return;
593 }
594
595 ar->ar_index = res->ar_niorange++;
596 ar->ar_low = low;
597 ar->ar_high = high;
598 ar->ar_length = length;
599 ar->ar_align = align;
600
601 SIMPLEQ_INSERT_TAIL(&res->ar_iorange, ar, ar_list);
602 }
603
604 static void
605 acpi_res_parse_memory(struct device *dev, void *context, uint32_t base,
606 uint32_t length)
607 {
608 struct acpi_resources *res = context;
609 struct acpi_mem *ar;
610
611 ar = AcpiOsAllocate(sizeof(*ar));
612 if (ar == NULL) {
613 printf("%s: ACPI: unable to allocate Memory resource %d\n",
614 dev->dv_xname, res->ar_nmem);
615 res->ar_nmem++;
616 return;
617 }
618
619 ar->ar_index = res->ar_nmem++;
620 ar->ar_base = base;
621 ar->ar_length = length;
622
623 SIMPLEQ_INSERT_TAIL(&res->ar_mem, ar, ar_list);
624 }
625
626 static void
627 acpi_res_parse_memrange(struct device *dev, void *context, uint32_t low,
628 uint32_t high, uint32_t length, uint32_t align)
629 {
630 struct acpi_resources *res = context;
631 struct acpi_memrange *ar;
632
633 ar = AcpiOsAllocate(sizeof(*ar));
634 if (ar == NULL) {
635 printf("%s: ACPI: unable to allocate Memory range resource "
636 "%d\n", dev->dv_xname, res->ar_nmemrange);
637 res->ar_nmemrange++;
638 return;
639 }
640
641 ar->ar_index = res->ar_nmemrange++;
642 ar->ar_low = low;
643 ar->ar_high = high;
644 ar->ar_length = length;
645 ar->ar_align = align;
646
647 SIMPLEQ_INSERT_TAIL(&res->ar_memrange, ar, ar_list);
648 }
649
650 static void
651 acpi_res_parse_irq(struct device *dev, void *context, uint32_t irq, uint32_t type)
652 {
653 struct acpi_resources *res = context;
654 struct acpi_irq *ar;
655
656 ar = AcpiOsAllocate(sizeof(*ar));
657 if (ar == NULL) {
658 printf("%s: ACPI: unable to allocate IRQ resource %d\n",
659 dev->dv_xname, res->ar_nirq);
660 res->ar_nirq++;
661 return;
662 }
663
664 ar->ar_index = res->ar_nirq++;
665 ar->ar_irq = irq;
666 ar->ar_type = type;
667
668 SIMPLEQ_INSERT_TAIL(&res->ar_irq, ar, ar_list);
669 }
670
671 static void
672 acpi_res_parse_drq(struct device *dev, void *context, uint32_t drq)
673 {
674 struct acpi_resources *res = context;
675 struct acpi_drq *ar;
676
677 ar = AcpiOsAllocate(sizeof(*ar));
678 if (ar == NULL) {
679 printf("%s: ACPI: unable to allocate DRQ resource %d\n",
680 dev->dv_xname, res->ar_ndrq);
681 res->ar_ndrq++;
682 return;
683 }
684
685 ar->ar_index = res->ar_ndrq++;
686 ar->ar_drq = drq;
687
688 SIMPLEQ_INSERT_TAIL(&res->ar_drq, ar, ar_list);
689 }
690
691 static void
692 acpi_res_parse_start_dep(struct device *dev, void *context, int preference)
693 {
694
695 printf("%s: ACPI: dependant functions not supported\n",
696 dev->dv_xname);
697 }
698
699 static void
700 acpi_res_parse_end_dep(struct device *dev, void *context)
701 {
702
703 /* Nothing to do. */
704 }
705