acpi_resource.c revision 1.14 1 /* $NetBSD: acpi_resource.c,v 1.14 2004/04/11 10:36:35 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.14 2004/04/11 10:36:35 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 /*
389 * acpi_resource_cleanup:
390 *
391 * Free all allocated buffers
392 */
393 void
394 acpi_resource_cleanup(struct acpi_resources *res)
395 {
396 while (!SIMPLEQ_EMPTY(&res->ar_io)) {
397 struct acpi_io *ar;
398 ar = SIMPLEQ_FIRST(&res->ar_io);
399 SIMPLEQ_REMOVE_HEAD(&res->ar_io, ar_list);
400 AcpiOsFree(ar);
401 }
402
403 while (!SIMPLEQ_EMPTY(&res->ar_iorange)) {
404 struct acpi_iorange *ar;
405 ar = SIMPLEQ_FIRST(&res->ar_iorange);
406 SIMPLEQ_REMOVE_HEAD(&res->ar_iorange, ar_list);
407 AcpiOsFree(ar);
408 }
409
410 while (!SIMPLEQ_EMPTY(&res->ar_mem)) {
411 struct acpi_mem *ar;
412 ar = SIMPLEQ_FIRST(&res->ar_mem);
413 SIMPLEQ_REMOVE_HEAD(&res->ar_mem, ar_list);
414 AcpiOsFree(ar);
415 }
416
417 while (!SIMPLEQ_EMPTY(&res->ar_memrange)) {
418 struct acpi_memrange *ar;
419 ar = SIMPLEQ_FIRST(&res->ar_memrange);
420 SIMPLEQ_REMOVE_HEAD(&res->ar_memrange, ar_list);
421 AcpiOsFree(ar);
422 }
423
424 while (!SIMPLEQ_EMPTY(&res->ar_irq)) {
425 struct acpi_irq *ar;
426 ar = SIMPLEQ_FIRST(&res->ar_irq);
427 SIMPLEQ_REMOVE_HEAD(&res->ar_irq, ar_list);
428 AcpiOsFree(ar);
429 }
430
431 while (!SIMPLEQ_EMPTY(&res->ar_drq)) {
432 struct acpi_drq *ar;
433 ar = SIMPLEQ_FIRST(&res->ar_drq);
434 SIMPLEQ_REMOVE_HEAD(&res->ar_drq, ar_list);
435 AcpiOsFree(ar);
436 }
437
438 res->ar_nio = res->ar_niorange = res->ar_nmem =
439 res->ar_nmemrange = res->ar_nirq = res->ar_ndrq = 0;
440 }
441
442 struct acpi_io *
443 acpi_res_io(struct acpi_resources *res, int idx)
444 {
445 struct acpi_io *ar;
446
447 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
448 if (ar->ar_index == idx)
449 return ar;
450 }
451 return NULL;
452 }
453
454 struct acpi_iorange *
455 acpi_res_iorange(struct acpi_resources *res, int idx)
456 {
457 struct acpi_iorange *ar;
458
459 SIMPLEQ_FOREACH(ar, &res->ar_iorange, ar_list) {
460 if (ar->ar_index == idx)
461 return ar;
462 }
463 return NULL;
464 }
465
466 struct acpi_mem *
467 acpi_res_mem(struct acpi_resources *res, int idx)
468 {
469 struct acpi_mem *ar;
470
471 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
472 if (ar->ar_index == idx)
473 return ar;
474 }
475 return NULL;
476 }
477
478 struct acpi_memrange *
479 acpi_res_memrange(struct acpi_resources *res, int idx)
480 {
481 struct acpi_memrange *ar;
482
483 SIMPLEQ_FOREACH(ar, &res->ar_memrange, ar_list) {
484 if (ar->ar_index == idx)
485 return ar;
486 }
487 return NULL;
488 }
489
490 struct acpi_irq *
491 acpi_res_irq(struct acpi_resources *res, int idx)
492 {
493 struct acpi_irq *ar;
494
495 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
496 if (ar->ar_index == idx)
497 return ar;
498 }
499 return NULL;
500 }
501
502 struct acpi_drq *
503 acpi_res_drq(struct acpi_resources *res, int idx)
504 {
505 struct acpi_drq *ar;
506
507 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
508 if (ar->ar_index == idx)
509 return ar;
510 }
511 return NULL;
512 }
513
514 /*****************************************************************************
515 * Default ACPI resource parse operations.
516 *****************************************************************************/
517
518 static void acpi_res_parse_init(struct device *, void *, void **);
519 static void acpi_res_parse_fini(struct device *, void *);
520
521 static void acpi_res_parse_ioport(struct device *, void *, uint32_t,
522 uint32_t);
523 static void acpi_res_parse_iorange(struct device *, void *, uint32_t,
524 uint32_t, uint32_t, uint32_t);
525
526 static void acpi_res_parse_memory(struct device *, void *, uint32_t,
527 uint32_t);
528 static void acpi_res_parse_memrange(struct device *, void *, uint32_t,
529 uint32_t, uint32_t, uint32_t);
530
531 static void acpi_res_parse_irq(struct device *, void *, uint32_t, uint32_t);
532 static void acpi_res_parse_drq(struct device *, void *, uint32_t);
533
534 static void acpi_res_parse_start_dep(struct device *, void *, int);
535 static void acpi_res_parse_end_dep(struct device *, void *);
536
537 const struct acpi_resource_parse_ops acpi_resource_parse_ops_default = {
538 .init = acpi_res_parse_init,
539 .fini = acpi_res_parse_fini,
540
541 .ioport = acpi_res_parse_ioport,
542 .iorange = acpi_res_parse_iorange,
543
544 .memory = acpi_res_parse_memory,
545 .memrange = acpi_res_parse_memrange,
546
547 .irq = acpi_res_parse_irq,
548 .drq = acpi_res_parse_drq,
549
550 .start_dep = acpi_res_parse_start_dep,
551 .end_dep = acpi_res_parse_end_dep,
552 };
553
554 static void
555 acpi_res_parse_init(struct device *dev, void *arg, void **contextp)
556 {
557 struct acpi_resources *res = arg;
558
559 SIMPLEQ_INIT(&res->ar_io);
560 res->ar_nio = 0;
561
562 SIMPLEQ_INIT(&res->ar_iorange);
563 res->ar_niorange = 0;
564
565 SIMPLEQ_INIT(&res->ar_mem);
566 res->ar_nmem = 0;
567
568 SIMPLEQ_INIT(&res->ar_memrange);
569 res->ar_nmemrange = 0;
570
571 SIMPLEQ_INIT(&res->ar_irq);
572 res->ar_nirq = 0;
573
574 SIMPLEQ_INIT(&res->ar_drq);
575 res->ar_ndrq = 0;
576
577 *contextp = res;
578 }
579
580 static void
581 acpi_res_parse_fini(struct device *dev, void *context)
582 {
583 struct acpi_resources *res = context;
584
585 /* Print the resources we're using. */
586 acpi_resource_print(dev, res);
587 }
588
589 static void
590 acpi_res_parse_ioport(struct device *dev, void *context, uint32_t base,
591 uint32_t length)
592 {
593 struct acpi_resources *res = context;
594 struct acpi_io *ar;
595
596 /*
597 * Check if there is another I/O port directly below/under
598 * this one.
599 */
600 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
601 if (ar->ar_base == base + length ) {
602 /*
603 * Entry just below existing entry - adjust
604 * the entry and return.
605 */
606 ar->ar_base = base;
607 ar->ar_length += length;
608 return;
609 } else if (ar->ar_base + ar->ar_length == base) {
610 /*
611 * Entry just above existing entry - adjust
612 * the entry and return.
613 */
614 ar->ar_length += length;
615 return;
616 }
617 }
618
619 ar = AcpiOsAllocate(sizeof(*ar));
620 if (ar == NULL) {
621 printf("%s: ACPI: unable to allocate I/O resource %d\n",
622 dev->dv_xname, res->ar_nio);
623 res->ar_nio++;
624 return;
625 }
626
627 ar->ar_index = res->ar_nio++;
628 ar->ar_base = base;
629 ar->ar_length = length;
630
631 SIMPLEQ_INSERT_TAIL(&res->ar_io, ar, ar_list);
632 }
633
634 static void
635 acpi_res_parse_iorange(struct device *dev, void *context, uint32_t low,
636 uint32_t high, uint32_t length, uint32_t align)
637 {
638 struct acpi_resources *res = context;
639 struct acpi_iorange *ar;
640
641 ar = AcpiOsAllocate(sizeof(*ar));
642 if (ar == NULL) {
643 printf("%s: ACPI: unable to allocate I/O range resource %d\n",
644 dev->dv_xname, res->ar_niorange);
645 res->ar_niorange++;
646 return;
647 }
648
649 ar->ar_index = res->ar_niorange++;
650 ar->ar_low = low;
651 ar->ar_high = high;
652 ar->ar_length = length;
653 ar->ar_align = align;
654
655 SIMPLEQ_INSERT_TAIL(&res->ar_iorange, ar, ar_list);
656 }
657
658 static void
659 acpi_res_parse_memory(struct device *dev, void *context, uint32_t base,
660 uint32_t length)
661 {
662 struct acpi_resources *res = context;
663 struct acpi_mem *ar;
664
665 ar = AcpiOsAllocate(sizeof(*ar));
666 if (ar == NULL) {
667 printf("%s: ACPI: unable to allocate Memory resource %d\n",
668 dev->dv_xname, res->ar_nmem);
669 res->ar_nmem++;
670 return;
671 }
672
673 ar->ar_index = res->ar_nmem++;
674 ar->ar_base = base;
675 ar->ar_length = length;
676
677 SIMPLEQ_INSERT_TAIL(&res->ar_mem, ar, ar_list);
678 }
679
680 static void
681 acpi_res_parse_memrange(struct device *dev, void *context, uint32_t low,
682 uint32_t high, uint32_t length, uint32_t align)
683 {
684 struct acpi_resources *res = context;
685 struct acpi_memrange *ar;
686
687 ar = AcpiOsAllocate(sizeof(*ar));
688 if (ar == NULL) {
689 printf("%s: ACPI: unable to allocate Memory range resource "
690 "%d\n", dev->dv_xname, res->ar_nmemrange);
691 res->ar_nmemrange++;
692 return;
693 }
694
695 ar->ar_index = res->ar_nmemrange++;
696 ar->ar_low = low;
697 ar->ar_high = high;
698 ar->ar_length = length;
699 ar->ar_align = align;
700
701 SIMPLEQ_INSERT_TAIL(&res->ar_memrange, ar, ar_list);
702 }
703
704 static void
705 acpi_res_parse_irq(struct device *dev, void *context, uint32_t irq, uint32_t type)
706 {
707 struct acpi_resources *res = context;
708 struct acpi_irq *ar;
709
710 ar = AcpiOsAllocate(sizeof(*ar));
711 if (ar == NULL) {
712 printf("%s: ACPI: unable to allocate IRQ resource %d\n",
713 dev->dv_xname, res->ar_nirq);
714 res->ar_nirq++;
715 return;
716 }
717
718 ar->ar_index = res->ar_nirq++;
719 ar->ar_irq = irq;
720 ar->ar_type = type;
721
722 SIMPLEQ_INSERT_TAIL(&res->ar_irq, ar, ar_list);
723 }
724
725 static void
726 acpi_res_parse_drq(struct device *dev, void *context, uint32_t drq)
727 {
728 struct acpi_resources *res = context;
729 struct acpi_drq *ar;
730
731 ar = AcpiOsAllocate(sizeof(*ar));
732 if (ar == NULL) {
733 printf("%s: ACPI: unable to allocate DRQ resource %d\n",
734 dev->dv_xname, res->ar_ndrq);
735 res->ar_ndrq++;
736 return;
737 }
738
739 ar->ar_index = res->ar_ndrq++;
740 ar->ar_drq = drq;
741
742 SIMPLEQ_INSERT_TAIL(&res->ar_drq, ar, ar_list);
743 }
744
745 static void
746 acpi_res_parse_start_dep(struct device *dev, void *context, int preference)
747 {
748
749 printf("%s: ACPI: dependant functions not supported\n",
750 dev->dv_xname);
751 }
752
753 static void
754 acpi_res_parse_end_dep(struct device *dev, void *context)
755 {
756
757 /* Nothing to do. */
758 }
759