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