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