acpi_resource.c revision 119969
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_resource.c 119969 2003-09-10 22:06:41Z marcel $");
30
31#include "opt_acpi.h"
32#include <sys/param.h>
33#include <sys/kernel.h>
34#include <sys/bus.h>
35
36#include <machine/bus.h>
37#include <machine/resource.h>
38#include <sys/rman.h>
39
40#include "acpi.h"
41#include <dev/acpica/acpivar.h>
42
43/* Hooks for the ACPI CA debugging infrastructure */
44#define _COMPONENT	ACPI_BUS
45ACPI_MODULE_NAME("RESOURCE")
46
47/*
48 * Fetch a device's resources and associate them with the device.
49 *
50 * Note that it might be nice to also locate ACPI-specific resource items, such
51 * as GPE bits.
52 *
53 * We really need to split the resource-fetching code out from the
54 * resource-parsing code, since we may want to use the parsing
55 * code for _PRS someday.
56 */
57ACPI_STATUS
58acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
59		     struct acpi_parse_resource_set *set)
60{
61    ACPI_BUFFER		buf;
62    ACPI_RESOURCE	*res;
63    char		*curr, *last;
64    ACPI_STATUS		status;
65    void		*context;
66
67    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
68
69    /*
70     * Special-case some devices that abuse _PRS/_CRS to mean
71     * something other than "I consume this resource".
72     *
73     * XXX do we really need this?  It's only relevant once
74     *     we start always-allocating these resources, and even
75     *     then, the only special-cased device is likely to be
76     *     the PCI interrupt link.
77     */
78
79    /* Fetch the device's current resources. */
80    buf.Length = ACPI_ALLOCATE_BUFFER;
81    if (ACPI_FAILURE((status = AcpiGetCurrentResources(handle, &buf)))) {
82	if (status != AE_NOT_FOUND)
83	    printf("can't fetch resources for %s - %s\n",
84		   acpi_name(handle), AcpiFormatException(status));
85	return_ACPI_STATUS (status);
86    }
87    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s - got %ld bytes of resources\n",
88		     acpi_name(handle), (long)buf.Length));
89    set->set_init(dev, &context);
90
91    /* Iterate through the resources */
92    curr = buf.Pointer;
93    last = (char *)buf.Pointer + buf.Length;
94    while (curr < last) {
95	res = (ACPI_RESOURCE *)curr;
96	curr += res->Length;
97
98	/* Handle the individual resource types */
99	switch(res->Id) {
100	case ACPI_RSTYPE_END_TAG:
101	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n"));
102	    curr = last;
103	    break;
104	case ACPI_RSTYPE_FIXED_IO:
105	    if (res->Data.FixedIo.RangeLength <= 0)
106		break;
107	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedIo 0x%x/%d\n",
108			     res->Data.FixedIo.BaseAddress,
109			     res->Data.FixedIo.RangeLength));
110	    set->set_ioport(dev, context,
111			    res->Data.FixedIo.BaseAddress,
112			    res->Data.FixedIo.RangeLength);
113	    break;
114	case ACPI_RSTYPE_IO:
115	    if (res->Data.Io.RangeLength <= 0)
116		break;
117	    if (res->Data.Io.MinBaseAddress == res->Data.Io.MaxBaseAddress) {
118		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x/%d\n",
119				 res->Data.Io.MinBaseAddress,
120				 res->Data.Io.RangeLength));
121		set->set_ioport(dev, context,
122				res->Data.Io.MinBaseAddress,
123				res->Data.Io.RangeLength);
124	    } else {
125		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x-0x%x/%d\n",
126				 res->Data.Io.MinBaseAddress,
127				 res->Data.Io.MaxBaseAddress,
128				 res->Data.Io.RangeLength));
129		set->set_iorange(dev, context,
130				 res->Data.Io.MinBaseAddress,
131				 res->Data.Io.MaxBaseAddress,
132				 res->Data.Io.RangeLength,
133				 res->Data.Io.Alignment);
134	    }
135	    break;
136	case ACPI_RSTYPE_FIXED_MEM32:
137	    if (res->Data.FixedMemory32.RangeLength <= 0)
138		break;
139	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedMemory32 0x%x/%d\n",
140			      res->Data.FixedMemory32.RangeBaseAddress,
141			      res->Data.FixedMemory32.RangeLength));
142	    set->set_memory(dev, context,
143			    res->Data.FixedMemory32.RangeBaseAddress,
144			    res->Data.FixedMemory32.RangeLength);
145	    break;
146	case ACPI_RSTYPE_MEM32:
147	    if (res->Data.Memory32.RangeLength <= 0)
148		break;
149	    if (res->Data.Memory32.MinBaseAddress ==
150		res->Data.Memory32.MaxBaseAddress) {
151
152		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x/%d\n",
153				  res->Data.Memory32.MinBaseAddress,
154				  res->Data.Memory32.RangeLength));
155		set->set_memory(dev, context,
156				res->Data.Memory32.MinBaseAddress,
157				res->Data.Memory32.RangeLength);
158	    } else {
159		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x-0x%x/%d\n",
160				 res->Data.Memory32.MinBaseAddress,
161				 res->Data.Memory32.MaxBaseAddress,
162				 res->Data.Memory32.RangeLength));
163		set->set_memoryrange(dev, context,
164				     res->Data.Memory32.MinBaseAddress,
165				     res->Data.Memory32.MaxBaseAddress,
166				     res->Data.Memory32.RangeLength,
167				     res->Data.Memory32.Alignment);
168	    }
169	    break;
170	case ACPI_RSTYPE_MEM24:
171	    if (res->Data.Memory24.RangeLength <= 0)
172		break;
173	    if (res->Data.Memory24.MinBaseAddress ==
174		res->Data.Memory24.MaxBaseAddress) {
175
176		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x/%d\n",
177				 res->Data.Memory24.MinBaseAddress,
178				 res->Data.Memory24.RangeLength));
179		set->set_memory(dev, context, res->Data.Memory24.MinBaseAddress,
180				res->Data.Memory24.RangeLength);
181	    } else {
182		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x-0x%x/%d\n",
183				 res->Data.Memory24.MinBaseAddress,
184				 res->Data.Memory24.MaxBaseAddress,
185				 res->Data.Memory24.RangeLength));
186		set->set_memoryrange(dev, context,
187				     res->Data.Memory24.MinBaseAddress,
188				     res->Data.Memory24.MaxBaseAddress,
189				     res->Data.Memory24.RangeLength,
190				     res->Data.Memory24.Alignment);
191	    }
192	    break;
193	case ACPI_RSTYPE_IRQ:
194	    /*
195	     * from 1.0b 6.4.2
196	     * "This structure is repeated for each separate interrupt
197	     * required"
198	     */
199	    set->set_irq(dev, context, res->Data.Irq.Interrupts,
200		res->Data.Irq.NumberOfInterrupts, res->Data.Irq.EdgeLevel,
201		res->Data.Irq.ActiveHighLow);
202	    break;
203	case ACPI_RSTYPE_DMA:
204	    /*
205	     * from 1.0b 6.4.3
206	     * "This structure is repeated for each separate dma channel
207	     * required"
208	     */
209	    set->set_drq(dev, context, res->Data.Dma.Channels,
210			 res->Data.Dma.NumberOfChannels);
211	    break;
212	case ACPI_RSTYPE_START_DPF:
213	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "start dependant functions\n"));
214	    set->set_start_dependant(dev, context,
215				     res->Data.StartDpf.CompatibilityPriority);
216	    break;
217	case ACPI_RSTYPE_END_DPF:
218	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "end dependant functions\n"));
219	    set->set_end_dependant(dev, context);
220	    break;
221	case ACPI_RSTYPE_ADDRESS32:
222	    if (res->Data.Address32.AddressLength <= 0)
223		break;
224	    if (res->Data.Address32.ProducerConsumer != ACPI_CONSUMER) {
225		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
226		    "ignored Address32 %s producer\n",
227		    res->Data.Address32.ResourceType == ACPI_IO_RANGE ?
228		    "IO" : "Memory"));
229		break;
230	    }
231	    if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE &&
232		res->Data.Address32.ResourceType != ACPI_IO_RANGE) {
233		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
234		    "ignored Address32 for non-memory, non-I/O\n"));
235		break;
236	    }
237
238	    if (res->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED &&
239		res->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
240
241		if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
242		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
243				     "Address32/Memory 0x%x/%d\n",
244				     res->Data.Address32.MinAddressRange,
245				     res->Data.Address32.AddressLength));
246		    set->set_memory(dev, context,
247				    res->Data.Address32.MinAddressRange,
248				    res->Data.Address32.AddressLength);
249		} else {
250		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
251				     "Address32/IO 0x%x/%d\n",
252				     res->Data.Address32.MinAddressRange,
253				     res->Data.Address32.AddressLength));
254		    set->set_ioport(dev, context,
255				    res->Data.Address32.MinAddressRange,
256				    res->Data.Address32.AddressLength);
257		}
258	    } else {
259		if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
260		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
261				     "Address32/Memory 0x%x-0x%x/%d\n",
262				     res->Data.Address32.MinAddressRange,
263				     res->Data.Address32.MaxAddressRange,
264				     res->Data.Address32.AddressLength));
265		    set->set_memoryrange(dev, context,
266					  res->Data.Address32.MinAddressRange,
267					  res->Data.Address32.MaxAddressRange,
268					  res->Data.Address32.AddressLength,
269					  res->Data.Address32.Granularity);
270		} else {
271		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
272				     "Address32/IO 0x%x-0x%x/%d\n",
273				     res->Data.Address32.MinAddressRange,
274				     res->Data.Address32.MaxAddressRange,
275				     res->Data.Address32.AddressLength));
276		    set->set_iorange(dev, context,
277				     res->Data.Address32.MinAddressRange,
278				     res->Data.Address32.MaxAddressRange,
279				     res->Data.Address32.AddressLength,
280				     res->Data.Address32.Granularity);
281		}
282	    }
283	    break;
284	case ACPI_RSTYPE_ADDRESS16:
285	    if (res->Data.Address16.AddressLength <= 0)
286		break;
287	    if (res->Data.Address16.ProducerConsumer != ACPI_CONSUMER) {
288		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
289		    "ignored Address16 %s producer\n",
290		    res->Data.Address16.ResourceType == ACPI_IO_RANGE ?
291		    "IO" : "Memory"));
292		break;
293	    }
294	    if (res->Data.Address16.ResourceType != ACPI_MEMORY_RANGE &&
295		res->Data.Address16.ResourceType != ACPI_IO_RANGE) {
296		ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
297			"ignored Address16 for non-memory, non-I/O\n"));
298		break;
299	    }
300
301	    if (res->Data.Address16.MinAddressFixed == ACPI_ADDRESS_FIXED &&
302		res->Data.Address16.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
303
304		if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
305		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
306				     "Address16/Memory 0x%x/%d\n",
307				     res->Data.Address16.MinAddressRange,
308				     res->Data.Address16.AddressLength));
309		    set->set_memory(dev, context,
310				    res->Data.Address16.MinAddressRange,
311				    res->Data.Address16.AddressLength);
312		} else {
313		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
314				     "Address16/IO 0x%x/%d\n",
315				     res->Data.Address16.MinAddressRange,
316				     res->Data.Address16.AddressLength));
317		    set->set_ioport(dev, context,
318				    res->Data.Address16.MinAddressRange,
319				    res->Data.Address16.AddressLength);
320		}
321	    } else {
322		if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
323		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
324				     "Address16/Memory 0x%x-0x%x/%d\n",
325				     res->Data.Address16.MinAddressRange,
326				     res->Data.Address16.MaxAddressRange,
327				     res->Data.Address16.AddressLength));
328		    set->set_memoryrange(dev, context,
329					  res->Data.Address16.MinAddressRange,
330					  res->Data.Address16.MaxAddressRange,
331					  res->Data.Address16.AddressLength,
332					  res->Data.Address16.Granularity);
333		} else {
334		    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
335				     "Address16/IO 0x%x-0x%x/%d\n",
336				     res->Data.Address16.MinAddressRange,
337				     res->Data.Address16.MaxAddressRange,
338				     res->Data.Address16.AddressLength));
339		    set->set_iorange(dev, context,
340				     res->Data.Address16.MinAddressRange,
341				     res->Data.Address16.MaxAddressRange,
342				     res->Data.Address16.AddressLength,
343				     res->Data.Address16.Granularity);
344		}
345	    }
346	    break;
347	case ACPI_RSTYPE_ADDRESS64:
348	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
349			     "unimplemented Address64 resource\n"));
350	    break;
351	case ACPI_RSTYPE_EXT_IRQ:
352	    /* XXX special handling? */
353	    set->set_irq(dev, context,res->Data.ExtendedIrq.Interrupts,
354		res->Data.ExtendedIrq.NumberOfInterrupts,
355		res->Data.ExtendedIrq.EdgeLevel,
356		res->Data.ExtendedIrq.ActiveHighLow);
357	    break;
358	case ACPI_RSTYPE_VENDOR:
359	    ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
360			     "unimplemented VendorSpecific resource\n"));
361	    break;
362	default:
363	    break;
364	}
365    }
366
367    AcpiOsFree(buf.Pointer);
368    set->set_done(dev, context);
369    return_ACPI_STATUS (AE_OK);
370}
371
372/*
373 * Resource-set vectors used to attach _CRS-derived resources
374 * to an ACPI device.
375 */
376static void	acpi_res_set_init(device_t dev, void **context);
377static void	acpi_res_set_done(device_t dev, void *context);
378static void	acpi_res_set_ioport(device_t dev, void *context,
379				    u_int32_t base, u_int32_t length);
380static void	acpi_res_set_iorange(device_t dev, void *context,
381				     u_int32_t low, u_int32_t high,
382				     u_int32_t length, u_int32_t align);
383static void	acpi_res_set_memory(device_t dev, void *context,
384				    u_int32_t base, u_int32_t length);
385static void	acpi_res_set_memoryrange(device_t dev, void *context,
386					 u_int32_t low, u_int32_t high,
387					 u_int32_t length, u_int32_t align);
388static void	acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq,
389				 int count, int trig, int pol);
390static void	acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq,
391				 int count);
392static void	acpi_res_set_start_dependant(device_t dev, void *context,
393					     int preference);
394static void	acpi_res_set_end_dependant(device_t dev, void *context);
395
396struct acpi_parse_resource_set acpi_res_parse_set = {
397    acpi_res_set_init,
398    acpi_res_set_done,
399    acpi_res_set_ioport,
400    acpi_res_set_iorange,
401    acpi_res_set_memory,
402    acpi_res_set_memoryrange,
403    acpi_res_set_irq,
404    acpi_res_set_drq,
405    acpi_res_set_start_dependant,
406    acpi_res_set_end_dependant
407};
408
409struct acpi_res_context {
410    int		ar_nio;
411    int		ar_nmem;
412    int		ar_nirq;
413    int		ar_ndrq;
414};
415
416static void
417acpi_res_set_init(device_t dev, void **context)
418{
419    struct acpi_res_context	*cp;
420
421    if ((cp = AcpiOsAllocate(sizeof(*cp))) != NULL) {
422	bzero(cp, sizeof(*cp));
423	*context = cp;
424    }
425}
426
427static void
428acpi_res_set_done(device_t dev, void *context)
429{
430    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
431
432    if (cp == NULL)
433	return;
434    AcpiOsFree(cp);
435}
436
437static void
438acpi_res_set_ioport(device_t dev, void *context, u_int32_t base,
439		    u_int32_t length)
440{
441    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
442
443    if (cp == NULL)
444	return;
445    bus_set_resource(dev, SYS_RES_IOPORT, cp->ar_nio++, base, length);
446}
447
448static void
449acpi_res_set_iorange(device_t dev, void *context, u_int32_t low,
450		     u_int32_t high, u_int32_t length, u_int32_t align)
451{
452    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
453
454    if (cp == NULL)
455	return;
456    device_printf(dev, "I/O range not supported\n");
457}
458
459static void
460acpi_res_set_memory(device_t dev, void *context, u_int32_t base,
461		    u_int32_t length)
462{
463    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
464
465    if (cp == NULL)
466	return;
467
468    bus_set_resource(dev, SYS_RES_MEMORY, cp->ar_nmem++, base, length);
469}
470
471static void
472acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low,
473			 u_int32_t high, u_int32_t length, u_int32_t align)
474{
475    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
476
477    if (cp == NULL)
478	return;
479    device_printf(dev, "memory range not supported\n");
480}
481
482static void
483acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq, int count,
484    int trig, int pol)
485{
486    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
487
488    if (cp == NULL || irq == NULL)
489	return;
490
491    /* This implements no resource relocation. */
492    if (count != 1)
493	return;
494
495    bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1);
496    BUS_CONFIG_INTR(dev, *irq, (trig == ACPI_EDGE_SENSITIVE) ?
497	INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ?
498	INTR_POLARITY_HIGH : INTR_POLARITY_LOW);
499}
500
501static void
502acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq, int count)
503{
504    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
505
506    if (cp == NULL || drq == NULL)
507	return;
508
509    /* This implements no resource relocation. */
510    if (count != 1)
511	return;
512
513    bus_set_resource(dev, SYS_RES_DRQ, cp->ar_ndrq++, *drq, 1);
514}
515
516static void
517acpi_res_set_start_dependant(device_t dev, void *context, int preference)
518{
519    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
520
521    if (cp == NULL)
522	return;
523    device_printf(dev, "dependant functions not supported\n");
524}
525
526static void
527acpi_res_set_end_dependant(device_t dev, void *context)
528{
529    struct acpi_res_context	*cp = (struct acpi_res_context *)context;
530
531    if (cp == NULL)
532	return;
533    device_printf(dev, "dependant functions not supported\n");
534}
535
536/*
537 * Resource-owning placeholders.
538 *
539 * This code "owns" system resource objects that aren't
540 * otherwise useful to devices, and which shouldn't be
541 * considered "free".
542 *
543 * Note that some systems claim *all* of the physical address space
544 * with a PNP0C01 device, so we cannot correctly "own" system memory
545 * here (must be done in the SMAP handler on x86 systems, for
546 * example).
547 */
548
549static int	acpi_sysresource_probe(device_t dev);
550static int	acpi_sysresource_attach(device_t dev);
551
552static device_method_t acpi_sysresource_methods[] = {
553    /* Device interface */
554    DEVMETHOD(device_probe,	acpi_sysresource_probe),
555    DEVMETHOD(device_attach,	acpi_sysresource_attach),
556
557    {0, 0}
558};
559
560static driver_t acpi_sysresource_driver = {
561    "acpi_sysresource",
562    acpi_sysresource_methods,
563    0,
564};
565
566static devclass_t acpi_sysresource_devclass;
567DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver,
568	      acpi_sysresource_devclass, 0, 0);
569
570static int
571acpi_sysresource_probe(device_t dev)
572{
573    if (!acpi_disabled("sysresource") && acpi_MatchHid(dev, "PNP0C02"))
574	device_set_desc(dev, "system resource");
575    else
576	return (ENXIO);
577
578    device_quiet(dev);
579    return (-100);
580}
581
582static int
583acpi_sysresource_attach(device_t dev)
584{
585    struct resource	*res;
586    int			i, rid;
587
588    /*
589     * Suck up all the resources that might have been assigned to us.
590     * Note that it's impossible to tell the difference between a
591     * resource that someone else has claimed, and one that doesn't
592     * exist.
593     */
594    for (i = 0; i < 100; i++) {
595	rid = i;
596	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 0);
597	rid = i;
598	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, 0);
599	rid = i;
600	res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
601				 RF_SHAREABLE);
602    }
603
604    return (0);
605}
606