2 * Copyright (c) 1999 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/isa/isa_common.c,v 1.16.2.1 2000/09/16 15:49:52 roger Exp $
27 * $DragonFly: src/sys/bus/isa/isa_common.c,v 1.14 2008/10/18 01:15:33 dillon Exp $
30 * Modifications for Intel architecture by Garrett A. Wollman.
31 * Copyright 1998 Massachusetts Institute of Technology
33 * Permission to use, copy, modify, and distribute this software and
34 * its documentation for any purpose and without fee is hereby
35 * granted, provided that both the above copyright notice and this
36 * permission notice appear in all copies, that both the above
37 * copyright notice and this permission notice appear in all
38 * supporting documentation, and that the name of M.I.T. not be used
39 * in advertising or publicity pertaining to distribution of the
40 * software without specific, written prior permission. M.I.T. makes
41 * no representations about the suitability of this software for any
42 * purpose. It is provided "as is" without express or implied
45 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
46 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
47 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
48 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
49 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * Parts of the ISA bus implementation common to all architectures.
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
67 #include <sys/malloc.h>
68 #include <sys/module.h>
72 #include "isa_common.h"
74 static int isa_print_child (device_t
, device_t
);
76 MALLOC_DEFINE(M_ISADEV
, "isadev", "ISA device");
78 static devclass_t isa_devclass
;
79 static int isa_running
;
82 * At 'probe' time, we add all the devices which we know about to the
83 * bus. The generic attach routine will probe and attach them if they
87 isa_probe(device_t dev
)
89 device_set_desc(dev
, "ISA bus");
90 isa_init(); /* Allow machdep code to initialise */
94 extern device_t isa_bus_device
;
97 isa_attach(device_t dev
)
100 * Arrange for isa_probe_children(dev) to be called later. XXX
102 isa_bus_device
= dev
;
107 * Find a working set of memory regions for a child using the ranges
108 * in *config and return the regions in *result. Returns non-zero if
109 * a set of ranges was found.
112 isa_find_memory(device_t child
,
113 struct isa_config
*config
,
114 struct isa_config
*result
)
117 struct resource
*res
[ISA_NMEM
];
120 * First clear out any existing resource definitions.
122 for (i
= 0; i
< ISA_NMEM
; i
++) {
123 bus_delete_resource(child
, SYS_RES_MEMORY
, i
);
128 result
->ic_nmem
= config
->ic_nmem
;
129 for (i
= 0; i
< config
->ic_nmem
; i
++) {
130 u_int32_t start
, end
, size
, align
;
131 for (start
= config
->ic_mem
[i
].ir_start
,
132 end
= config
->ic_mem
[i
].ir_end
,
133 size
= config
->ic_mem
[i
].ir_size
,
134 align
= config
->ic_mem
[i
].ir_align
;
135 start
+ size
- 1 <= end
;
136 start
+= MAX(align
, 1)) {
137 bus_set_resource(child
, SYS_RES_MEMORY
, i
,
139 res
[i
] = bus_alloc_resource(child
,
141 0, ~0, 1, 0 /* !RF_ACTIVE */);
143 result
->ic_mem
[i
].ir_start
= start
;
144 result
->ic_mem
[i
].ir_end
= start
+ size
- 1;
145 result
->ic_mem
[i
].ir_size
= size
;
146 result
->ic_mem
[i
].ir_align
= align
;
152 * If we didn't find a place for memory range i, then
161 for (i
= 0; i
< ISA_NMEM
; i
++) {
163 bus_release_resource(child
, SYS_RES_MEMORY
,
171 * Find a working set of port regions for a child using the ranges
172 * in *config and return the regions in *result. Returns non-zero if
173 * a set of ranges was found.
176 isa_find_port(device_t child
,
177 struct isa_config
*config
,
178 struct isa_config
*result
)
181 struct resource
*res
[ISA_NPORT
];
184 * First clear out any existing resource definitions.
186 for (i
= 0; i
< ISA_NPORT
; i
++) {
187 bus_delete_resource(child
, SYS_RES_IOPORT
, i
);
192 result
->ic_nport
= config
->ic_nport
;
193 for (i
= 0; i
< config
->ic_nport
; i
++) {
194 u_int32_t start
, end
, size
, align
;
195 for (start
= config
->ic_port
[i
].ir_start
,
196 end
= config
->ic_port
[i
].ir_end
,
197 size
= config
->ic_port
[i
].ir_size
,
198 align
= config
->ic_port
[i
].ir_align
;
199 start
+ size
- 1 <= end
;
201 bus_set_resource(child
, SYS_RES_IOPORT
, i
,
203 res
[i
] = bus_alloc_resource(child
,
205 0, ~0, 1, 0 /* !RF_ACTIVE */);
207 result
->ic_port
[i
].ir_start
= start
;
208 result
->ic_port
[i
].ir_end
= start
+ size
- 1;
209 result
->ic_port
[i
].ir_size
= size
;
210 result
->ic_port
[i
].ir_align
= align
;
216 * If we didn't find a place for port range i, then
225 for (i
= 0; i
< ISA_NPORT
; i
++) {
227 bus_release_resource(child
, SYS_RES_IOPORT
,
235 * Return the index of the first bit in the mask (or -1 if mask is empty.
238 find_first_bit(u_int32_t mask
)
240 return ffs(mask
) - 1;
244 * Return the index of the next bit in the mask, or -1 if there are no more.
247 find_next_bit(u_int32_t mask
, int bit
)
250 while (bit
< 32 && !(mask
& (1 << bit
)))
258 * Find a working set of irqs for a child using the masks in *config
259 * and return the regions in *result. Returns non-zero if a set of
263 isa_find_irq(device_t child
,
264 struct isa_config
*config
,
265 struct isa_config
*result
)
268 struct resource
*res
[ISA_NIRQ
];
271 * First clear out any existing resource definitions.
273 for (i
= 0; i
< ISA_NIRQ
; i
++) {
274 bus_delete_resource(child
, SYS_RES_IRQ
, i
);
279 result
->ic_nirq
= config
->ic_nirq
;
280 for (i
= 0; i
< config
->ic_nirq
; i
++) {
281 u_int32_t mask
= config
->ic_irqmask
[i
];
283 for (irq
= find_first_bit(mask
);
285 irq
= find_next_bit(mask
, irq
)) {
286 bus_set_resource(child
, SYS_RES_IRQ
, i
,
288 res
[i
] = bus_alloc_resource(child
,
290 0, ~0, 1, 0 /* !RF_ACTIVE */ );
292 result
->ic_irqmask
[i
] = (1 << irq
);
298 * If we didn't find a place for irq range i, then
307 for (i
= 0; i
< ISA_NIRQ
; i
++) {
309 bus_release_resource(child
, SYS_RES_IRQ
,
317 * Find a working set of drqs for a child using the masks in *config
318 * and return the regions in *result. Returns non-zero if a set of
322 isa_find_drq(device_t child
,
323 struct isa_config
*config
,
324 struct isa_config
*result
)
327 struct resource
*res
[ISA_NDRQ
];
330 * First clear out any existing resource definitions.
332 for (i
= 0; i
< ISA_NDRQ
; i
++) {
333 bus_delete_resource(child
, SYS_RES_DRQ
, i
);
338 result
->ic_ndrq
= config
->ic_ndrq
;
339 for (i
= 0; i
< config
->ic_ndrq
; i
++) {
340 u_int32_t mask
= config
->ic_drqmask
[i
];
342 for (drq
= find_first_bit(mask
);
344 drq
= find_next_bit(mask
, drq
)) {
345 bus_set_resource(child
, SYS_RES_DRQ
, i
,
347 res
[i
] = bus_alloc_resource(child
,
349 0, ~0, 1, 0 /* !RF_ACTIVE */);
351 result
->ic_drqmask
[i
] = (1 << drq
);
357 * If we didn't find a place for drq range i, then
366 for (i
= 0; i
< ISA_NDRQ
; i
++) {
368 bus_release_resource(child
, SYS_RES_DRQ
,
376 * Attempt to find a working set of resources for a device. Return
377 * non-zero if a working configuration is found.
380 isa_assign_resources(device_t child
)
382 struct isa_device
*idev
= DEVTOISA(child
);
383 struct isa_config_entry
*ice
;
384 struct isa_config config
;
385 char *reason
= "Empty ISA id_configs";
387 bzero(&config
, sizeof config
);
388 TAILQ_FOREACH(ice
, &idev
->id_configs
, ice_link
) {
390 if (!isa_find_memory(child
, &ice
->ice_config
, &config
))
393 if (!isa_find_port(child
, &ice
->ice_config
, &config
))
396 if (!isa_find_irq(child
, &ice
->ice_config
, &config
))
399 if (!isa_find_drq(child
, &ice
->ice_config
, &config
))
403 * A working configuration was found enable the device
404 * with this configuration.
406 reason
= "no callback";
407 if (idev
->id_config_cb
) {
408 idev
->id_config_cb(idev
->id_config_arg
,
415 * Disable the device.
417 bus_print_child_header(device_get_parent(child
), child
);
418 kprintf(" can't assign resources (%s)\n", reason
);
420 isa_print_child(device_get_parent(child
), child
);
421 bzero(&config
, sizeof config
);
422 if (idev
->id_config_cb
)
423 idev
->id_config_cb(idev
->id_config_arg
, &config
, 0);
424 device_disable(child
);
430 * Called after other devices have initialised to probe for isa devices.
433 isa_probe_children(device_t dev
)
439 * Create all the children by calling driver's identify methods.
440 * Since this routine is called long after the ISA bus had been
441 * attached, yet never probed, we have to call a hack function that
442 * temporarily sets the bus back to DS_ALIVE to run the probe.
444 bus_generic_probe_hack(dev
);
446 if (device_get_children(dev
, &children
, &nchildren
))
450 * First disable all pnp devices so that they don't get
451 * matched by legacy probes.
454 kprintf("isa_probe_children: disabling PnP devices\n");
455 for (i
= 0; i
< nchildren
; i
++) {
456 device_t child
= children
[i
];
457 struct isa_device
*idev
= DEVTOISA(child
);
458 struct isa_config config
;
460 bzero(&config
, sizeof config
);
461 if (idev
->id_config_cb
)
462 idev
->id_config_cb(idev
->id_config_arg
, &config
, 0);
466 * Next probe all non-pnp devices so that they claim their
470 kprintf("isa_probe_children: probing non-PnP devices\n");
471 for (i
= 0; i
< nchildren
; i
++) {
472 device_t child
= children
[i
];
473 struct isa_device
*idev
= DEVTOISA(child
);
475 if (TAILQ_FIRST(&idev
->id_configs
))
478 device_probe_and_attach(child
);
482 * Finally assign resource to pnp devices and probe them.
485 kprintf("isa_probe_children: probing PnP devices\n");
486 for (i
= 0; i
< nchildren
; i
++) {
487 device_t child
= children
[i
];
488 struct isa_device
* idev
= DEVTOISA(child
);
490 if (!TAILQ_FIRST(&idev
->id_configs
))
493 if (isa_assign_resources(child
)) {
494 struct resource_list
*rl
= &idev
->id_resources
;
495 struct resource_list_entry
*rle
;
497 device_probe_and_attach(child
);
500 * Claim any unallocated resources to keep other
501 * devices from using them.
503 SLIST_FOREACH(rle
, rl
, link
) {
506 resource_list_alloc(rl
, dev
, child
,
516 kfree(children
, M_TEMP
);
522 * Add a new child with default ivars.
525 isa_add_child(device_t bus
, device_t parent
, int order
, const char *name
, int unit
)
528 struct isa_device
*idev
;
530 idev
= kmalloc(sizeof(struct isa_device
), M_ISADEV
, M_WAITOK
| M_ZERO
);
532 resource_list_init(&idev
->id_resources
);
533 TAILQ_INIT(&idev
->id_configs
);
535 child
= device_add_child_ordered(parent
, order
, name
, unit
);
536 device_set_ivars(child
, idev
);
542 isa_print_resources(struct resource_list
*rl
, const char *name
, int type
,
543 int count
, const char *format
)
545 struct resource_list_entry
*rle
;
550 for (i
= 0; i
< count
; i
++) {
551 rle
= resource_list_find(rl
, type
, i
);
554 retval
+= kprintf(" %s ", name
);
555 else if (printed
> 0)
556 retval
+= kprintf(",");
558 retval
+= kprintf(format
, rle
->start
);
559 if (rle
->count
> 1) {
560 retval
+= kprintf("-");
561 retval
+= kprintf(format
,
562 rle
->start
+ rle
->count
- 1);
565 /* check the first few regardless */
573 isa_print_all_resources(device_t dev
)
575 struct isa_device
*idev
= DEVTOISA(dev
);
576 struct resource_list
*rl
= &idev
->id_resources
;
579 if (SLIST_FIRST(rl
) || device_get_flags(dev
))
580 retval
+= kprintf(" at");
582 retval
+= isa_print_resources(rl
, "port", SYS_RES_IOPORT
,
584 retval
+= isa_print_resources(rl
, "iomem", SYS_RES_MEMORY
,
586 retval
+= isa_print_resources(rl
, "irq", SYS_RES_IRQ
,
588 retval
+= isa_print_resources(rl
, "drq", SYS_RES_DRQ
,
590 if (device_get_flags(dev
))
591 retval
+= kprintf(" flags %#x", device_get_flags(dev
));
597 isa_print_child(device_t bus
, device_t dev
)
601 retval
+= bus_print_child_header(bus
, dev
);
602 retval
+= isa_print_all_resources(dev
);
603 retval
+= bus_print_child_footer(bus
, dev
);
609 isa_probe_nomatch(device_t dev
, device_t child
)
612 bus_print_child_header(dev
, child
);
613 kprintf(" failed to probe");
614 isa_print_all_resources(child
);
615 bus_print_child_footer(dev
, child
);
622 isa_read_ivar(device_t bus
, device_t dev
, int index
, uintptr_t * result
)
624 struct isa_device
* idev
= DEVTOISA(dev
);
625 struct resource_list
*rl
= &idev
->id_resources
;
626 struct resource_list_entry
*rle
;
629 case ISA_IVAR_PORT_0
:
630 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 0);
632 *result
= rle
->start
;
637 case ISA_IVAR_PORT_1
:
638 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 1);
640 *result
= rle
->start
;
645 case ISA_IVAR_PORTSIZE_0
:
646 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 0);
648 *result
= rle
->count
;
653 case ISA_IVAR_PORTSIZE_1
:
654 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 1);
656 *result
= rle
->count
;
661 case ISA_IVAR_MADDR_0
:
662 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 0);
664 *result
= rle
->start
;
669 case ISA_IVAR_MADDR_1
:
670 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 1);
672 *result
= rle
->start
;
677 case ISA_IVAR_MSIZE_0
:
678 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 0);
680 *result
= rle
->count
;
685 case ISA_IVAR_MSIZE_1
:
686 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 1);
688 *result
= rle
->count
;
694 rle
= resource_list_find(rl
, SYS_RES_IRQ
, 0);
696 *result
= rle
->start
;
702 rle
= resource_list_find(rl
, SYS_RES_IRQ
, 1);
704 *result
= rle
->start
;
710 rle
= resource_list_find(rl
, SYS_RES_DRQ
, 0);
712 *result
= rle
->start
;
718 rle
= resource_list_find(rl
, SYS_RES_DRQ
, 1);
720 *result
= rle
->start
;
725 case ISA_IVAR_VENDORID
:
726 *result
= idev
->id_vendorid
;
729 case ISA_IVAR_SERIAL
:
730 *result
= idev
->id_serial
;
733 case ISA_IVAR_LOGICALID
:
734 *result
= idev
->id_logicalid
;
737 case ISA_IVAR_COMPATID
:
738 *result
= idev
->id_compatid
;
749 isa_write_ivar(device_t bus
, device_t dev
,
750 int index
, uintptr_t value
)
752 struct isa_device
* idev
= DEVTOISA(dev
);
755 case ISA_IVAR_PORT_0
:
756 case ISA_IVAR_PORT_1
:
757 case ISA_IVAR_PORTSIZE_0
:
758 case ISA_IVAR_PORTSIZE_1
:
759 case ISA_IVAR_MADDR_0
:
760 case ISA_IVAR_MADDR_1
:
761 case ISA_IVAR_MSIZE_0
:
762 case ISA_IVAR_MSIZE_1
:
769 case ISA_IVAR_VENDORID
:
770 idev
->id_vendorid
= value
;
773 case ISA_IVAR_SERIAL
:
774 idev
->id_serial
= value
;
777 case ISA_IVAR_LOGICALID
:
778 idev
->id_logicalid
= value
;
781 case ISA_IVAR_COMPATID
:
782 idev
->id_compatid
= value
;
793 * Free any resources which the driver missed or which we were holding for
794 * it (see isa_probe_children).
797 isa_child_detached(device_t dev
, device_t child
)
799 struct isa_device
* idev
= DEVTOISA(child
);
800 struct resource_list
*rl
= &idev
->id_resources
;
801 struct resource_list_entry
*rle
;
803 if (TAILQ_FIRST(&idev
->id_configs
)) {
805 * Claim any unallocated resources to keep other
806 * devices from using them.
808 SLIST_FOREACH(rle
, rl
, link
) {
811 resource_list_alloc(rl
, dev
, child
,
820 isa_driver_added(device_t dev
, driver_t
*driver
)
826 * Don't do anything if drivers are dynamically
827 * added during autoconfiguration (cf. ymf724).
828 * since that would end up calling identify
834 DEVICE_IDENTIFY(driver
, dev
);
835 if (device_get_children(dev
, &children
, &nchildren
))
838 for (i
= 0; i
< nchildren
; i
++) {
839 device_t child
= children
[i
];
840 struct isa_device
*idev
= DEVTOISA(child
);
841 struct resource_list
*rl
= &idev
->id_resources
;
842 struct resource_list_entry
*rle
;
844 if (device_get_state(child
) != DS_NOTPRESENT
)
846 if (!device_is_enabled(child
))
850 * Free resources which we were holding on behalf of
853 SLIST_FOREACH(rle
, &idev
->id_resources
, link
) {
855 resource_list_release(rl
, dev
, child
,
861 if (TAILQ_FIRST(&idev
->id_configs
))
862 if (!isa_assign_resources(child
))
865 device_probe_and_attach(child
);
867 if (TAILQ_FIRST(&idev
->id_configs
)) {
869 * Claim any unallocated resources to keep other
870 * devices from using them.
872 SLIST_FOREACH(rle
, rl
, link
) {
875 resource_list_alloc(rl
, dev
, child
,
885 kfree(children
, M_TEMP
);
889 isa_set_resource(device_t dev
, device_t child
, int type
, int rid
,
890 u_long start
, u_long count
)
892 struct isa_device
* idev
= DEVTOISA(child
);
893 struct resource_list
*rl
= &idev
->id_resources
;
895 if (type
!= SYS_RES_IOPORT
&& type
!= SYS_RES_MEMORY
896 && type
!= SYS_RES_IRQ
&& type
!= SYS_RES_DRQ
)
900 if (type
== SYS_RES_IOPORT
&& rid
>= ISA_NPORT
)
902 if (type
== SYS_RES_MEMORY
&& rid
>= ISA_NMEM
)
904 if (type
== SYS_RES_IRQ
&& rid
>= ISA_NIRQ
)
906 if (type
== SYS_RES_DRQ
&& rid
>= ISA_NDRQ
)
909 resource_list_add(rl
, type
, rid
, start
, start
+ count
- 1, count
);
915 isa_get_resource(device_t dev
, device_t child
, int type
, int rid
,
916 u_long
*startp
, u_long
*countp
)
918 struct isa_device
* idev
= DEVTOISA(child
);
919 struct resource_list
*rl
= &idev
->id_resources
;
920 struct resource_list_entry
*rle
;
922 rle
= resource_list_find(rl
, type
, rid
);
927 *startp
= rle
->start
;
929 *countp
= rle
->count
;
935 isa_delete_resource(device_t dev
, device_t child
, int type
, int rid
)
937 struct isa_device
* idev
= DEVTOISA(child
);
938 struct resource_list
*rl
= &idev
->id_resources
;
939 resource_list_delete(rl
, type
, rid
);
943 isa_add_config(device_t dev
, device_t child
,
944 int priority
, struct isa_config
*config
)
946 struct isa_device
* idev
= DEVTOISA(child
);
947 struct isa_config_entry
*newice
, *ice
;
949 newice
= kmalloc(sizeof *ice
, M_DEVBUF
, M_WAITOK
);
950 newice
->ice_priority
= priority
;
951 newice
->ice_config
= *config
;
953 TAILQ_FOREACH(ice
, &idev
->id_configs
, ice_link
) {
954 if (ice
->ice_priority
> priority
)
958 TAILQ_INSERT_BEFORE(ice
, newice
, ice_link
);
960 TAILQ_INSERT_TAIL(&idev
->id_configs
, newice
, ice_link
);
966 isa_set_config_callback(device_t dev
, device_t child
,
967 isa_config_cb
*fn
, void *arg
)
969 struct isa_device
* idev
= DEVTOISA(child
);
971 idev
->id_config_cb
= fn
;
972 idev
->id_config_arg
= arg
;
976 isa_pnp_probe(device_t dev
, device_t child
, struct isa_pnp_id
*ids
)
978 struct isa_device
* idev
= DEVTOISA(child
);
980 if (!idev
->id_vendorid
)
985 * Really ought to support >1 compat id per device.
987 if (idev
->id_logicalid
== ids
->ip_id
988 || idev
->id_compatid
== ids
->ip_id
) {
990 device_set_desc(child
, ids
->ip_desc
);
999 static device_method_t isa_methods
[] = {
1000 /* Device interface */
1001 DEVMETHOD(device_probe
, isa_probe
),
1002 DEVMETHOD(device_attach
, isa_attach
),
1003 DEVMETHOD(device_detach
, bus_generic_detach
),
1004 DEVMETHOD(device_shutdown
, bus_generic_shutdown
),
1005 DEVMETHOD(device_suspend
, bus_generic_suspend
),
1006 DEVMETHOD(device_resume
, bus_generic_resume
),
1009 DEVMETHOD(bus_add_child
, isa_add_child
),
1010 DEVMETHOD(bus_print_child
, isa_print_child
),
1011 DEVMETHOD(bus_probe_nomatch
, isa_probe_nomatch
),
1012 DEVMETHOD(bus_read_ivar
, isa_read_ivar
),
1013 DEVMETHOD(bus_write_ivar
, isa_write_ivar
),
1014 DEVMETHOD(bus_child_detached
, isa_child_detached
),
1015 DEVMETHOD(bus_driver_added
, isa_driver_added
),
1016 DEVMETHOD(bus_alloc_resource
, isa_alloc_resource
),
1017 DEVMETHOD(bus_release_resource
, isa_release_resource
),
1018 DEVMETHOD(bus_activate_resource
, bus_generic_activate_resource
),
1019 DEVMETHOD(bus_deactivate_resource
, bus_generic_deactivate_resource
),
1020 DEVMETHOD(bus_setup_intr
, isa_setup_intr
),
1021 DEVMETHOD(bus_teardown_intr
, isa_teardown_intr
),
1022 DEVMETHOD(bus_set_resource
, isa_set_resource
),
1023 DEVMETHOD(bus_get_resource
, isa_get_resource
),
1024 DEVMETHOD(bus_delete_resource
, isa_delete_resource
),
1027 DEVMETHOD(isa_add_config
, isa_add_config
),
1028 DEVMETHOD(isa_set_config_callback
, isa_set_config_callback
),
1029 DEVMETHOD(isa_pnp_probe
, isa_pnp_probe
),
1034 static driver_t isa_driver
= {
1041 * ISA can be attached to a PCI-ISA bridge or directly to the nexus.
1043 DRIVER_MODULE(isa
, isab
, isa_driver
, isa_devclass
, 0, 0);
1045 DRIVER_MODULE(isa
, nexus
, isa_driver
, isa_devclass
, 0, 0);
1049 * Code common to ISA bridges.
1052 isab_attach(device_t dev
)
1056 child
= device_add_child(dev
, "isa", 0);
1058 return (bus_generic_attach(dev
));