xref: /netbsd/sys/dev/acpi/acpi_resource.c (revision bf9ec67e)
1 /*	$NetBSD: acpi_resource.c,v 1.2 2001/11/13 13:01:57 lukem 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.2 2001/11/13 13:01:57 lukem 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_BUS
82 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 	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 			}
235 			break;
236 
237 		case ACPI_RSTYPE_DMA:
238 			for (i = 0; i < res->Data.Dma.NumberOfChannels; i++) {
239 				ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
240 				    "DRQ %d\n", res->Data.Dma.Channels[i]));
241 				(*ops->drq)(dev, context,
242 				    res->Data.Dma.Channels[i]);
243 			}
244 			break;
245 
246 		case ACPI_RSTYPE_START_DPF:
247 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
248 			    "Start dependant functions: %d\n",
249 			     res->Data.StartDpf.CompatibilityPriority));
250 			(*ops->start_dep)(dev, context,
251 			    res->Data.StartDpf.CompatibilityPriority);
252 			break;
253 
254 		case ACPI_RSTYPE_END_DPF:
255 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
256 			    "End dependant functions\n"));
257 			(*ops->end_dep)(dev, context);
258 
259 		case ACPI_RSTYPE_ADDRESS32:
260 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
261 			    "Address32 unimplemented\n"));
262 			break;
263 
264 		case ACPI_RSTYPE_ADDRESS16:
265 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
266 			    "Address16 unimplemented\n"));
267 			break;
268 
269 		case ACPI_RSTYPE_EXT_IRQ:
270 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
271 			    "ExtendedIrq unimplemented\n"));
272 			break;
273 
274 		case ACPI_RSTYPE_VENDOR:
275 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
276 			    "VendorSpecific unimplemented\n"));
277 			break;
278 
279 		default:
280 			ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
281 			    "Unknown resource type: %d\n", res->Id));
282 			break;
283 		}
284 	}
285 
286 	AcpiOsFree(buf.Pointer);
287 	(*ops->fini)(dev, context);
288 
289 	return_ACPI_STATUS(AE_OK);
290 }
291 
292 /*
293  * acpi_resource_print:
294  *
295  *	Print the resources assigned to a device.
296  */
297 void
298 acpi_resource_print(struct device *dev, struct acpi_resources *res)
299 {
300 	const char *sep;
301 
302 	if (SIMPLEQ_EMPTY(&res->ar_io) &&
303 	    SIMPLEQ_EMPTY(&res->ar_iorange) &&
304 	    SIMPLEQ_EMPTY(&res->ar_mem) &&
305 	    SIMPLEQ_EMPTY(&res->ar_memrange) &&
306 	    SIMPLEQ_EMPTY(&res->ar_irq) &&
307 	    SIMPLEQ_EMPTY(&res->ar_drq))
308 		return;
309 
310 	printf("%s:", dev->dv_xname);
311 
312 	if (SIMPLEQ_EMPTY(&res->ar_io) == 0) {
313 		struct acpi_io *ar;
314 
315 		sep = "";
316 		printf(" io ");
317 		for (ar = SIMPLEQ_FIRST(&res->ar_io); ar != NULL;
318 		     ar = SIMPLEQ_NEXT(ar, 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 		for (ar = SIMPLEQ_FIRST(&res->ar_mem); ar != NULL;
335 		     ar = SIMPLEQ_NEXT(ar, ar_list)) {
336 			printf("%s0x%x", sep, ar->ar_base);
337 			if (ar->ar_length > 1)
338 				printf("-0x%x", ar->ar_base +
339 				    ar->ar_length - 1);
340 			sep = ",";
341 		}
342 	}
343 
344 	/* XXX memrange */
345 
346 	if (SIMPLEQ_EMPTY(&res->ar_irq) == 0) {
347 		struct acpi_irq *ar;
348 
349 		sep = "";
350 		printf(" irq ");
351 		for (ar = SIMPLEQ_FIRST(&res->ar_irq); ar != NULL;
352 		     ar = SIMPLEQ_NEXT(ar, ar_list)) {
353 			printf("%s%d", sep, ar->ar_irq);
354 			sep = ",";
355 		}
356 	}
357 
358 	if (SIMPLEQ_EMPTY(&res->ar_drq) == 0) {
359 		struct acpi_drq *ar;
360 
361 		sep = "";
362 		printf(" drq ");
363 		for (ar = SIMPLEQ_FIRST(&res->ar_drq); ar != NULL;
364 		     ar = SIMPLEQ_NEXT(ar, ar_list)) {
365 			printf("%s%d", sep, ar->ar_drq);
366 			sep = ",";
367 		}
368 	}
369 
370 	printf("\n");
371 }
372 
373 struct acpi_io *
374 acpi_res_io(struct acpi_resources *res, int idx)
375 {
376 	struct acpi_io *ar;
377 
378 	SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
379 		if (ar->ar_index == idx)
380 			return (ar);
381 	}
382 	return (NULL);
383 }
384 
385 struct acpi_iorange *
386 acpi_res_iorange(struct acpi_resources *res, int idx)
387 {
388 	struct acpi_iorange *ar;
389 
390 	SIMPLEQ_FOREACH(ar, &res->ar_iorange, ar_list) {
391 		if (ar->ar_index == idx)
392 			return (ar);
393 	}
394 	return (NULL);
395 }
396 
397 struct acpi_mem *
398 acpi_res_mem(struct acpi_resources *res, int idx)
399 {
400 	struct acpi_mem *ar;
401 
402 	SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
403 		if (ar->ar_index == idx)
404 			return (ar);
405 	}
406 	return (NULL);
407 }
408 
409 struct acpi_memrange *
410 acpi_res_memrange(struct acpi_resources *res, int idx)
411 {
412 	struct acpi_memrange *ar;
413 
414 	SIMPLEQ_FOREACH(ar, &res->ar_memrange, ar_list) {
415 		if (ar->ar_index == idx)
416 			return (ar);
417 	}
418 	return (NULL);
419 }
420 
421 struct acpi_irq *
422 acpi_res_irq(struct acpi_resources *res, int idx)
423 {
424 	struct acpi_irq *ar;
425 
426 	SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
427 		if (ar->ar_index == idx)
428 			return (ar);
429 	}
430 	return (NULL);
431 }
432 
433 struct acpi_drq *
434 acpi_res_drq(struct acpi_resources *res, int idx)
435 {
436 	struct acpi_drq *ar;
437 
438 	SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
439 		if (ar->ar_index == idx)
440 			return (ar);
441 	}
442 	return (NULL);
443 }
444 
445 /*****************************************************************************
446  * Default ACPI resource parse operations.
447  *****************************************************************************/
448 
449 static void	acpi_res_parse_init(struct device *, void *, void **);
450 static void	acpi_res_parse_fini(struct device *, void *);
451 
452 static void	acpi_res_parse_ioport(struct device *, void *, uint32_t,
453 		    uint32_t);
454 static void	acpi_res_parse_iorange(struct device *, void *, uint32_t,
455 		    uint32_t, uint32_t, uint32_t);
456 
457 static void	acpi_res_parse_memory(struct device *, void *, uint32_t,
458 		    uint32_t);
459 static void	acpi_res_parse_memrange(struct device *, void *, uint32_t,
460 		    uint32_t, uint32_t, uint32_t);
461 
462 static void	acpi_res_parse_irq(struct device *, void *, uint32_t);
463 static void	acpi_res_parse_drq(struct device *, void *, uint32_t);
464 
465 static void	acpi_res_parse_start_dep(struct device *, void *, int);
466 static void	acpi_res_parse_end_dep(struct device *, void *);
467 
468 const struct acpi_resource_parse_ops acpi_resource_parse_ops_default = {
469 	acpi_res_parse_init,
470 	acpi_res_parse_fini,
471 
472 	acpi_res_parse_ioport,
473 	acpi_res_parse_iorange,
474 
475 	acpi_res_parse_memory,
476 	acpi_res_parse_memrange,
477 
478 	acpi_res_parse_irq,
479 	acpi_res_parse_drq,
480 
481 	acpi_res_parse_start_dep,
482 	acpi_res_parse_end_dep,
483 };
484 
485 static void
486 acpi_res_parse_init(struct device *dev, void *arg, void **contextp)
487 {
488 	struct acpi_resources *res = arg;
489 
490 	SIMPLEQ_INIT(&res->ar_io);
491 	res->ar_nio = 0;
492 
493 	SIMPLEQ_INIT(&res->ar_iorange);
494 	res->ar_niorange = 0;
495 
496 	SIMPLEQ_INIT(&res->ar_mem);
497 	res->ar_nmem = 0;
498 
499 	SIMPLEQ_INIT(&res->ar_memrange);
500 	res->ar_nmemrange = 0;
501 
502 	SIMPLEQ_INIT(&res->ar_irq);
503 	res->ar_nirq = 0;
504 
505 	SIMPLEQ_INIT(&res->ar_drq);
506 	res->ar_ndrq = 0;
507 
508 	*contextp = res;
509 }
510 
511 static void
512 acpi_res_parse_fini(struct device *dev, void *context)
513 {
514 	struct acpi_resources *res = context;
515 
516 	/* Print the resources we're using. */
517 	acpi_resource_print(dev, res);
518 }
519 
520 static void
521 acpi_res_parse_ioport(struct device *dev, void *context, uint32_t base,
522     uint32_t length)
523 {
524 	struct acpi_resources *res = context;
525 	struct acpi_io *ar;
526 
527 	ar = AcpiOsAllocate(sizeof(*ar));
528 	if (ar == NULL) {
529 		printf("%s: ACPI: unable to allocate I/O resource %d\n",
530 		    dev->dv_xname, res->ar_nio);
531 		res->ar_nio++;
532 		return;
533 	}
534 
535 	ar->ar_index = res->ar_nio++;
536 	ar->ar_base = base;
537 	ar->ar_length = length;
538 
539 	SIMPLEQ_INSERT_TAIL(&res->ar_io, ar, ar_list);
540 }
541 
542 static void
543 acpi_res_parse_iorange(struct device *dev, void *context, uint32_t low,
544     uint32_t high, uint32_t length, uint32_t align)
545 {
546 	struct acpi_resources *res = context;
547 	struct acpi_iorange *ar;
548 
549 	ar = AcpiOsAllocate(sizeof(*ar));
550 	if (ar == NULL) {
551 		printf("%s: ACPI: unable to allocate I/O range resource %d\n",
552 		    dev->dv_xname, res->ar_niorange);
553 		res->ar_niorange++;
554 		return;
555 	}
556 
557 	ar->ar_index = res->ar_niorange++;
558 	ar->ar_low = low;
559 	ar->ar_high = high;
560 	ar->ar_length = length;
561 	ar->ar_align = align;
562 
563 	SIMPLEQ_INSERT_TAIL(&res->ar_iorange, ar, ar_list);
564 }
565 
566 static void
567 acpi_res_parse_memory(struct device *dev, void *context, uint32_t base,
568     uint32_t length)
569 {
570 	struct acpi_resources *res = context;
571 	struct acpi_mem *ar;
572 
573 	ar = AcpiOsAllocate(sizeof(*ar));
574 	if (ar == NULL) {
575 		printf("%s: ACPI: unable to allocate Memory resource %d\n",
576 		    dev->dv_xname, res->ar_nmem);
577 		res->ar_nmem++;
578 		return;
579 	}
580 
581 	ar->ar_index = res->ar_nmem++;
582 	ar->ar_base = base;
583 	ar->ar_length = length;
584 
585 	SIMPLEQ_INSERT_TAIL(&res->ar_mem, ar, ar_list);
586 }
587 
588 static void
589 acpi_res_parse_memrange(struct device *dev, void *context, uint32_t low,
590     uint32_t high, uint32_t length, uint32_t align)
591 {
592 	struct acpi_resources *res = context;
593 	struct acpi_memrange *ar;
594 
595 	ar = AcpiOsAllocate(sizeof(*ar));
596 	if (ar == NULL) {
597 		printf("%s: ACPI: unable to allocate Memory range resource "
598 		    "%d\n", dev->dv_xname, res->ar_nmemrange);
599 		res->ar_nmemrange++;
600 		return;
601 	}
602 
603 	ar->ar_index = res->ar_nmemrange++;
604 	ar->ar_low = low;
605 	ar->ar_high = high;
606 	ar->ar_length = length;
607 	ar->ar_align = align;
608 
609 	SIMPLEQ_INSERT_TAIL(&res->ar_memrange, ar, ar_list);
610 }
611 
612 static void
613 acpi_res_parse_irq(struct device *dev, void *context, uint32_t irq)
614 {
615 	struct acpi_resources *res = context;
616 	struct acpi_irq *ar;
617 
618 	ar = AcpiOsAllocate(sizeof(*ar));
619 	if (ar == NULL) {
620 		printf("%s: ACPI: unable to allocate IRQ resource %d\n",
621 		    dev->dv_xname, res->ar_nirq);
622 		res->ar_nirq++;
623 		return;
624 	}
625 
626 	ar->ar_index = res->ar_nirq++;
627 	ar->ar_irq = irq;
628 
629 	SIMPLEQ_INSERT_TAIL(&res->ar_irq, ar, ar_list);
630 }
631 
632 static void
633 acpi_res_parse_drq(struct device *dev, void *context, uint32_t drq)
634 {
635 	struct acpi_resources *res = context;
636 	struct acpi_drq *ar;
637 
638 	ar = AcpiOsAllocate(sizeof(*ar));
639 	if (ar == NULL) {
640 		printf("%s: ACPI: unable to allocate DRQ resource %d\n",
641 		    dev->dv_xname, res->ar_ndrq);
642 		res->ar_ndrq++;
643 		return;
644 	}
645 
646 	ar->ar_index = res->ar_ndrq++;
647 	ar->ar_drq = drq;
648 
649 	SIMPLEQ_INSERT_TAIL(&res->ar_drq, ar, ar_list);
650 }
651 
652 static void
653 acpi_res_parse_start_dep(struct device *dev, void *context, int preference)
654 {
655 
656 	printf("%s: ACPI: dependant functions not supported\n",
657 	    dev->dv_xname);
658 }
659 
660 static void
661 acpi_res_parse_end_dep(struct device *dev, void *context)
662 {
663 
664 	/* Nothing to do. */
665 }
666