1 /* $NetBSD: acpi_resource.c,v 1.9 2003/11/03 18:07:10 mycroft 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.9 2003/11/03 18:07:10 mycroft 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 /*
84 * acpi_resource_parse:
85 *
86 * Parse a device node's resources and fill them in for the
87 * client.
88 *
89 * Note that it might be nice to also locate ACPI-specific resource
90 * items, such as GPE bits.
91 */
92 ACPI_STATUS
93 acpi_resource_parse(struct device *dev, struct acpi_devnode *ad,
94 void *arg, const struct acpi_resource_parse_ops *ops)
95 {
96 ACPI_BUFFER buf;
97 ACPI_RESOURCE *res;
98 char *cur, *last;
99 ACPI_STATUS status;
100 void *context;
101 int i;
102
103 ACPI_FUNCTION_TRACE(__FUNCTION__);
104
105 /*
106 * XXX Note, this means we only get devices that are currently
107 * decoding their address space. This might not be what we
108 * want, in the long term.
109 */
110
111 status = acpi_get(ad->ad_handle, &buf, AcpiGetCurrentResources);
112 if (ACPI_FAILURE(status)) {
113 printf("%s: ACPI: unable to get Current Resources: %s\n",
114 dev->dv_xname, AcpiFormatException(status));
115 return_ACPI_STATUS(status);
116 }
117
118 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "got %d bytes of _CRS\n",
119 buf.Length));
120
121 (*ops->init)(dev, arg, &context);
122
123 cur = buf.Pointer;
124 last = cur + buf.Length;
125 while (cur < last) {
126 res = (ACPI_RESOURCE *) cur;
127 cur += res->Length;
128
129 switch (res->Id) {
130 case ACPI_RSTYPE_END_TAG:
131 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n"));
132 cur = last;
133 break;
134
135 case ACPI_RSTYPE_FIXED_IO:
136 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
137 "FixedIo 0x%x/%d\n",
138 res->Data.FixedIo.BaseAddress,
139 res->Data.FixedIo.RangeLength));
140 (*ops->ioport)(dev, context,
141 res->Data.FixedIo.BaseAddress,
142 res->Data.FixedIo.RangeLength);
143 break;
144
145 case ACPI_RSTYPE_IO:
146 if (res->Data.Io.MinBaseAddress ==
147 res->Data.Io.MaxBaseAddress) {
148 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
149 "Io 0x%x/%d\n",
150 res->Data.Io.MinBaseAddress,
151 res->Data.Io.RangeLength));
152 (*ops->ioport)(dev, context,
153 res->Data.Io.MinBaseAddress,
154 res->Data.Io.RangeLength);
155 } else {
156 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
157 "Io 0x%x-0x%x/%d\n",
158 res->Data.Io.MinBaseAddress,
159 res->Data.Io.MaxBaseAddress,
160 res->Data.Io.RangeLength));
161 (*ops->iorange)(dev, context,
162 res->Data.Io.MinBaseAddress,
163 res->Data.Io.MaxBaseAddress,
164 res->Data.Io.RangeLength,
165 res->Data.Io.Alignment);
166 }
167 break;
168
169 case ACPI_RSTYPE_FIXED_MEM32:
170 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
171 "FixedMemory32 0x%x/%d\n",
172 res->Data.FixedMemory32.RangeBaseAddress,
173 res->Data.FixedMemory32.RangeLength));
174 (*ops->memory)(dev, context,
175 res->Data.FixedMemory32.RangeBaseAddress,
176 res->Data.FixedMemory32.RangeLength);
177 break;
178
179 case ACPI_RSTYPE_MEM32:
180 if (res->Data.Memory32.MinBaseAddress ==
181 res->Data.Memory32.MaxBaseAddress) {
182 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
183 "Memory32 0x%x/%d\n",
184 res->Data.Memory32.MinBaseAddress,
185 res->Data.Memory32.RangeLength));
186 (*ops->memory)(dev, context,
187 res->Data.Memory32.MinBaseAddress,
188 res->Data.Memory32.RangeLength);
189 } else {
190 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
191 "Memory32 0x%x-0x%x/%d\n",
192 res->Data.Memory32.MinBaseAddress,
193 res->Data.Memory32.MaxBaseAddress,
194 res->Data.Memory32.RangeLength));
195 (*ops->memrange)(dev, context,
196 res->Data.Memory32.MinBaseAddress,
197 res->Data.Memory32.MaxBaseAddress,
198 res->Data.Memory32.RangeLength,
199 res->Data.Memory32.Alignment);
200 }
201 break;
202
203 case ACPI_RSTYPE_MEM24:
204 if (res->Data.Memory24.MinBaseAddress ==
205 res->Data.Memory24.MaxBaseAddress) {
206 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
207 "Memory24 0x%x/%d\n",
208 res->Data.Memory24.MinBaseAddress,
209 res->Data.Memory24.RangeLength));
210 (*ops->memory)(dev, context,
211 res->Data.Memory24.MinBaseAddress,
212 res->Data.Memory24.RangeLength);
213 } else {
214 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
215 "Memory24 0x%x-0x%x/%d\n",
216 res->Data.Memory24.MinBaseAddress,
217 res->Data.Memory24.MaxBaseAddress,
218 res->Data.Memory24.RangeLength));
219 (*ops->memrange)(dev, context,
220 res->Data.Memory24.MinBaseAddress,
221 res->Data.Memory24.MaxBaseAddress,
222 res->Data.Memory24.RangeLength,
223 res->Data.Memory24.Alignment);
224 }
225 break;
226
227 case ACPI_RSTYPE_IRQ:
228 for (i = 0; i < res->Data.Irq.NumberOfInterrupts; i++) {
229 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
230 "IRQ %d\n", res->Data.Irq.Interrupts[i]));
231 (*ops->irq)(dev, context,
232 res->Data.Irq.Interrupts[i],
233 res->Data.Irq.EdgeLevel);
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 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
318 printf("%s0x%x", sep, ar->ar_base);
319 if (ar->ar_length > 1)
320 printf("-0x%x", ar->ar_base +
321 ar->ar_length - 1);
322 sep = ",";
323 }
324 }
325
326 /* XXX iorange */
327
328 if (SIMPLEQ_EMPTY(&res->ar_mem) == 0) {
329 struct acpi_mem *ar;
330
331 sep = "";
332 printf(" mem ");
333 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
334 printf("%s0x%x", sep, ar->ar_base);
335 if (ar->ar_length > 1)
336 printf("-0x%x", ar->ar_base +
337 ar->ar_length - 1);
338 sep = ",";
339 }
340 }
341
342 /* XXX memrange */
343
344 if (SIMPLEQ_EMPTY(&res->ar_irq) == 0) {
345 struct acpi_irq *ar;
346
347 sep = "";
348 printf(" irq ");
349 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
350 printf("%s%d", sep, ar->ar_irq);
351 sep = ",";
352 }
353 }
354
355 if (SIMPLEQ_EMPTY(&res->ar_drq) == 0) {
356 struct acpi_drq *ar;
357
358 sep = "";
359 printf(" drq ");
360 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
361 printf("%s%d", sep, ar->ar_drq);
362 sep = ",";
363 }
364 }
365
366 printf("\n");
367 }
368
369 struct acpi_io *
370 acpi_res_io(struct acpi_resources *res, int idx)
371 {
372 struct acpi_io *ar;
373
374 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
375 if (ar->ar_index == idx)
376 return (ar);
377 }
378 return (NULL);
379 }
380
381 struct acpi_iorange *
382 acpi_res_iorange(struct acpi_resources *res, int idx)
383 {
384 struct acpi_iorange *ar;
385
386 SIMPLEQ_FOREACH(ar, &res->ar_iorange, ar_list) {
387 if (ar->ar_index == idx)
388 return (ar);
389 }
390 return (NULL);
391 }
392
393 struct acpi_mem *
394 acpi_res_mem(struct acpi_resources *res, int idx)
395 {
396 struct acpi_mem *ar;
397
398 SIMPLEQ_FOREACH(ar, &res->ar_mem, ar_list) {
399 if (ar->ar_index == idx)
400 return (ar);
401 }
402 return (NULL);
403 }
404
405 struct acpi_memrange *
406 acpi_res_memrange(struct acpi_resources *res, int idx)
407 {
408 struct acpi_memrange *ar;
409
410 SIMPLEQ_FOREACH(ar, &res->ar_memrange, ar_list) {
411 if (ar->ar_index == idx)
412 return (ar);
413 }
414 return (NULL);
415 }
416
417 struct acpi_irq *
418 acpi_res_irq(struct acpi_resources *res, int idx)
419 {
420 struct acpi_irq *ar;
421
422 SIMPLEQ_FOREACH(ar, &res->ar_irq, ar_list) {
423 if (ar->ar_index == idx)
424 return (ar);
425 }
426 return (NULL);
427 }
428
429 struct acpi_drq *
430 acpi_res_drq(struct acpi_resources *res, int idx)
431 {
432 struct acpi_drq *ar;
433
434 SIMPLEQ_FOREACH(ar, &res->ar_drq, ar_list) {
435 if (ar->ar_index == idx)
436 return (ar);
437 }
438 return (NULL);
439 }
440
441 /*****************************************************************************
442 * Default ACPI resource parse operations.
443 *****************************************************************************/
444
445 static void acpi_res_parse_init(struct device *, void *, void **);
446 static void acpi_res_parse_fini(struct device *, void *);
447
448 static void acpi_res_parse_ioport(struct device *, void *, uint32_t,
449 uint32_t);
450 static void acpi_res_parse_iorange(struct device *, void *, uint32_t,
451 uint32_t, uint32_t, uint32_t);
452
453 static void acpi_res_parse_memory(struct device *, void *, uint32_t,
454 uint32_t);
455 static void acpi_res_parse_memrange(struct device *, void *, uint32_t,
456 uint32_t, uint32_t, uint32_t);
457
458 static void acpi_res_parse_irq(struct device *, void *, uint32_t, uint32_t);
459 static void acpi_res_parse_drq(struct device *, void *, uint32_t);
460
461 static void acpi_res_parse_start_dep(struct device *, void *, int);
462 static void acpi_res_parse_end_dep(struct device *, void *);
463
464 const struct acpi_resource_parse_ops acpi_resource_parse_ops_default = {
465 acpi_res_parse_init,
466 acpi_res_parse_fini,
467
468 acpi_res_parse_ioport,
469 acpi_res_parse_iorange,
470
471 acpi_res_parse_memory,
472 acpi_res_parse_memrange,
473
474 acpi_res_parse_irq,
475 acpi_res_parse_drq,
476
477 acpi_res_parse_start_dep,
478 acpi_res_parse_end_dep,
479 };
480
481 static void
482 acpi_res_parse_init(struct device *dev, void *arg, void **contextp)
483 {
484 struct acpi_resources *res = arg;
485
486 SIMPLEQ_INIT(&res->ar_io);
487 res->ar_nio = 0;
488
489 SIMPLEQ_INIT(&res->ar_iorange);
490 res->ar_niorange = 0;
491
492 SIMPLEQ_INIT(&res->ar_mem);
493 res->ar_nmem = 0;
494
495 SIMPLEQ_INIT(&res->ar_memrange);
496 res->ar_nmemrange = 0;
497
498 SIMPLEQ_INIT(&res->ar_irq);
499 res->ar_nirq = 0;
500
501 SIMPLEQ_INIT(&res->ar_drq);
502 res->ar_ndrq = 0;
503
504 *contextp = res;
505 }
506
507 static void
508 acpi_res_parse_fini(struct device *dev, void *context)
509 {
510 struct acpi_resources *res = context;
511
512 /* Print the resources we're using. */
513 acpi_resource_print(dev, res);
514 }
515
516 static void
517 acpi_res_parse_ioport(struct device *dev, void *context, uint32_t base,
518 uint32_t length)
519 {
520 struct acpi_resources *res = context;
521 struct acpi_io *ar;
522
523 /*
524 * Check if there is another I/O port directly below/under
525 * this one.
526 */
527 SIMPLEQ_FOREACH(ar, &res->ar_io, ar_list) {
528 if (ar->ar_base == base + length ) {
529 /*
530 * Entry just below existing entry - adjust
531 * the entry and return.
532 */
533 ar->ar_base = base;
534 ar->ar_length += length;
535 return;
536 } else if (ar->ar_base + ar->ar_length == base) {
537 /*
538 * Entry just above existing entry - adjust
539 * the entry and return.
540 */
541 ar->ar_length += length;
542 return;
543 }
544 }
545
546 ar = AcpiOsAllocate(sizeof(*ar));
547 if (ar == NULL) {
548 printf("%s: ACPI: unable to allocate I/O resource %d\n",
549 dev->dv_xname, res->ar_nio);
550 res->ar_nio++;
551 return;
552 }
553
554 ar->ar_index = res->ar_nio++;
555 ar->ar_base = base;
556 ar->ar_length = length;
557
558 SIMPLEQ_INSERT_TAIL(&res->ar_io, ar, ar_list);
559 }
560
561 static void
562 acpi_res_parse_iorange(struct device *dev, void *context, uint32_t low,
563 uint32_t high, uint32_t length, uint32_t align)
564 {
565 struct acpi_resources *res = context;
566 struct acpi_iorange *ar;
567
568 ar = AcpiOsAllocate(sizeof(*ar));
569 if (ar == NULL) {
570 printf("%s: ACPI: unable to allocate I/O range resource %d\n",
571 dev->dv_xname, res->ar_niorange);
572 res->ar_niorange++;
573 return;
574 }
575
576 ar->ar_index = res->ar_niorange++;
577 ar->ar_low = low;
578 ar->ar_high = high;
579 ar->ar_length = length;
580 ar->ar_align = align;
581
582 SIMPLEQ_INSERT_TAIL(&res->ar_iorange, ar, ar_list);
583 }
584
585 static void
586 acpi_res_parse_memory(struct device *dev, void *context, uint32_t base,
587 uint32_t length)
588 {
589 struct acpi_resources *res = context;
590 struct acpi_mem *ar;
591
592 ar = AcpiOsAllocate(sizeof(*ar));
593 if (ar == NULL) {
594 printf("%s: ACPI: unable to allocate Memory resource %d\n",
595 dev->dv_xname, res->ar_nmem);
596 res->ar_nmem++;
597 return;
598 }
599
600 ar->ar_index = res->ar_nmem++;
601 ar->ar_base = base;
602 ar->ar_length = length;
603
604 SIMPLEQ_INSERT_TAIL(&res->ar_mem, ar, ar_list);
605 }
606
607 static void
608 acpi_res_parse_memrange(struct device *dev, void *context, uint32_t low,
609 uint32_t high, uint32_t length, uint32_t align)
610 {
611 struct acpi_resources *res = context;
612 struct acpi_memrange *ar;
613
614 ar = AcpiOsAllocate(sizeof(*ar));
615 if (ar == NULL) {
616 printf("%s: ACPI: unable to allocate Memory range resource "
617 "%d\n", dev->dv_xname, res->ar_nmemrange);
618 res->ar_nmemrange++;
619 return;
620 }
621
622 ar->ar_index = res->ar_nmemrange++;
623 ar->ar_low = low;
624 ar->ar_high = high;
625 ar->ar_length = length;
626 ar->ar_align = align;
627
628 SIMPLEQ_INSERT_TAIL(&res->ar_memrange, ar, ar_list);
629 }
630
631 static void
632 acpi_res_parse_irq(struct device *dev, void *context, uint32_t irq, uint32_t type)
633 {
634 struct acpi_resources *res = context;
635 struct acpi_irq *ar;
636
637 ar = AcpiOsAllocate(sizeof(*ar));
638 if (ar == NULL) {
639 printf("%s: ACPI: unable to allocate IRQ resource %d\n",
640 dev->dv_xname, res->ar_nirq);
641 res->ar_nirq++;
642 return;
643 }
644
645 ar->ar_index = res->ar_nirq++;
646 ar->ar_irq = irq;
647 ar->ar_type = type;
648
649 SIMPLEQ_INSERT_TAIL(&res->ar_irq, ar, ar_list);
650 }
651
652 static void
653 acpi_res_parse_drq(struct device *dev, void *context, uint32_t drq)
654 {
655 struct acpi_resources *res = context;
656 struct acpi_drq *ar;
657
658 ar = AcpiOsAllocate(sizeof(*ar));
659 if (ar == NULL) {
660 printf("%s: ACPI: unable to allocate DRQ resource %d\n",
661 dev->dv_xname, res->ar_ndrq);
662 res->ar_ndrq++;
663 return;
664 }
665
666 ar->ar_index = res->ar_ndrq++;
667 ar->ar_drq = drq;
668
669 SIMPLEQ_INSERT_TAIL(&res->ar_drq, ar, ar_list);
670 }
671
672 static void
673 acpi_res_parse_start_dep(struct device *dev, void *context, int preference)
674 {
675
676 printf("%s: ACPI: dependant functions not supported\n",
677 dev->dv_xname);
678 }
679
680 static void
681 acpi_res_parse_end_dep(struct device *dev, void *context)
682 {
683
684 /* Nothing to do. */
685 }
Cache object: 2870b4c9e0a0a25bb47dd7f444c8896b
|