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