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 $
29 * Modifications for Intel architecture by Garrett A. Wollman.
30 * Copyright 1998 Massachusetts Institute of Technology
32 * Permission to use, copy, modify, and distribute this software and
33 * its documentation for any purpose and without fee is hereby
34 * granted, provided that both the above copyright notice and this
35 * permission notice appear in all copies, that both the above
36 * copyright notice and this permission notice appear in all
37 * supporting documentation, and that the name of M.I.T. not be used
38 * in advertising or publicity pertaining to distribution of the
39 * software without specific, written prior permission. M.I.T. makes
40 * no representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied
44 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
45 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
46 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
48 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
51 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * Parts of the ISA bus implementation common to all architectures.
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/kernel.h>
66 #include <sys/malloc.h>
67 #include <sys/module.h>
69 #include <sys/machintr.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");
93 extern device_t isa_bus_device
;
96 isa_attach(device_t dev
)
99 * Arrange for isa_probe_children(dev) to be called later. XXX
101 isa_bus_device
= dev
;
106 * Find a working set of memory regions for a child using the ranges
107 * in *config and return the regions in *result. Returns non-zero if
108 * a set of ranges was found.
111 isa_find_memory(device_t child
,
112 struct isa_config
*config
,
113 struct isa_config
*result
)
116 struct resource
*res
[ISA_NMEM
];
119 * First clear out any existing resource definitions.
121 for (i
= 0; i
< ISA_NMEM
; i
++) {
122 bus_delete_resource(child
, SYS_RES_MEMORY
, i
);
127 result
->ic_nmem
= config
->ic_nmem
;
128 for (i
= 0; i
< config
->ic_nmem
; i
++) {
129 u_int32_t start
, end
, size
, align
;
130 for (start
= config
->ic_mem
[i
].ir_start
,
131 end
= config
->ic_mem
[i
].ir_end
,
132 size
= config
->ic_mem
[i
].ir_size
,
133 align
= config
->ic_mem
[i
].ir_align
;
134 start
+ size
- 1 <= end
;
135 start
+= MAX(align
, 1)) {
136 bus_set_resource(child
, SYS_RES_MEMORY
, i
,
138 res
[i
] = bus_alloc_resource(child
,
140 0, ~0, 1, 0 /* !RF_ACTIVE */);
142 result
->ic_mem
[i
].ir_start
= start
;
143 result
->ic_mem
[i
].ir_end
= start
+ size
- 1;
144 result
->ic_mem
[i
].ir_size
= size
;
145 result
->ic_mem
[i
].ir_align
= align
;
151 * If we didn't find a place for memory range i, then
160 for (i
= 0; i
< ISA_NMEM
; i
++) {
162 bus_release_resource(child
, SYS_RES_MEMORY
,
170 * Find a working set of port regions for a child using the ranges
171 * in *config and return the regions in *result. Returns non-zero if
172 * a set of ranges was found.
175 isa_find_port(device_t child
,
176 struct isa_config
*config
,
177 struct isa_config
*result
)
180 struct resource
*res
[ISA_NPORT
];
183 * First clear out any existing resource definitions.
185 for (i
= 0; i
< ISA_NPORT
; i
++) {
186 bus_delete_resource(child
, SYS_RES_IOPORT
, i
);
191 result
->ic_nport
= config
->ic_nport
;
192 for (i
= 0; i
< config
->ic_nport
; i
++) {
193 u_int32_t start
, end
, size
, align
;
194 for (start
= config
->ic_port
[i
].ir_start
,
195 end
= config
->ic_port
[i
].ir_end
,
196 size
= config
->ic_port
[i
].ir_size
,
197 align
= config
->ic_port
[i
].ir_align
;
198 start
+ size
- 1 <= end
;
200 bus_set_resource(child
, SYS_RES_IOPORT
, i
,
202 res
[i
] = bus_alloc_resource(child
,
204 0, ~0, 1, 0 /* !RF_ACTIVE */);
206 result
->ic_port
[i
].ir_start
= start
;
207 result
->ic_port
[i
].ir_end
= start
+ size
- 1;
208 result
->ic_port
[i
].ir_size
= size
;
209 result
->ic_port
[i
].ir_align
= align
;
215 * If we didn't find a place for port range i, then
224 for (i
= 0; i
< ISA_NPORT
; i
++) {
226 bus_release_resource(child
, SYS_RES_IOPORT
,
234 * Return the index of the first bit in the mask (or -1 if mask is empty.
237 find_first_bit(u_int32_t mask
)
239 return ffs(mask
) - 1;
243 * Return the index of the next bit in the mask, or -1 if there are no more.
246 find_next_bit(u_int32_t mask
, int bit
)
249 while (bit
< 32 && !(mask
& (1 << bit
)))
257 * Find a working set of irqs for a child using the masks in *config
258 * and return the regions in *result. Returns non-zero if a set of
262 isa_find_irq(device_t child
,
263 struct isa_config
*config
,
264 struct isa_config
*result
)
267 struct resource
*res
[ISA_NIRQ
];
270 * First clear out any existing resource definitions.
272 for (i
= 0; i
< ISA_NIRQ
; i
++) {
273 bus_delete_resource(child
, SYS_RES_IRQ
, i
);
278 result
->ic_nirq
= config
->ic_nirq
;
279 for (i
= 0; i
< config
->ic_nirq
; i
++) {
280 u_int32_t mask
= config
->ic_irqmask
[i
];
282 for (irq
= find_first_bit(mask
);
284 irq
= find_next_bit(mask
, irq
)) {
285 bus_set_resource(child
, SYS_RES_IRQ
, i
,
286 irq
, 1, machintr_legacy_intr_cpuid(irq
));
287 res
[i
] = bus_alloc_resource(child
,
289 0, ~0, 1, 0 /* !RF_ACTIVE */ );
291 result
->ic_irqmask
[i
] = (1 << irq
);
297 * If we didn't find a place for irq range i, then
306 for (i
= 0; i
< ISA_NIRQ
; i
++) {
308 bus_release_resource(child
, SYS_RES_IRQ
,
316 * Find a working set of drqs for a child using the masks in *config
317 * and return the regions in *result. Returns non-zero if a set of
321 isa_find_drq(device_t child
,
322 struct isa_config
*config
,
323 struct isa_config
*result
)
326 struct resource
*res
[ISA_NDRQ
];
329 * First clear out any existing resource definitions.
331 for (i
= 0; i
< ISA_NDRQ
; i
++) {
332 bus_delete_resource(child
, SYS_RES_DRQ
, i
);
337 result
->ic_ndrq
= config
->ic_ndrq
;
338 for (i
= 0; i
< config
->ic_ndrq
; i
++) {
339 u_int32_t mask
= config
->ic_drqmask
[i
];
341 for (drq
= find_first_bit(mask
);
343 drq
= find_next_bit(mask
, drq
)) {
344 bus_set_resource(child
, SYS_RES_DRQ
, i
,
346 res
[i
] = bus_alloc_resource(child
,
348 0, ~0, 1, 0 /* !RF_ACTIVE */);
350 result
->ic_drqmask
[i
] = (1 << drq
);
356 * If we didn't find a place for drq range i, then
365 for (i
= 0; i
< ISA_NDRQ
; i
++) {
367 bus_release_resource(child
, SYS_RES_DRQ
,
375 * Attempt to find a working set of resources for a device. Return
376 * non-zero if a working configuration is found.
379 isa_assign_resources(device_t child
)
381 struct isa_device
*idev
= DEVTOISA(child
);
382 struct isa_config_entry
*ice
;
383 struct isa_config config
;
384 char *reason
= "Empty ISA id_configs";
386 bzero(&config
, sizeof config
);
387 TAILQ_FOREACH(ice
, &idev
->id_configs
, ice_link
) {
389 if (!isa_find_memory(child
, &ice
->ice_config
, &config
))
392 if (!isa_find_port(child
, &ice
->ice_config
, &config
))
395 if (!isa_find_irq(child
, &ice
->ice_config
, &config
))
398 if (!isa_find_drq(child
, &ice
->ice_config
, &config
))
402 * A working configuration was found enable the device
403 * with this configuration.
405 reason
= "no callback";
406 if (idev
->id_config_cb
) {
407 idev
->id_config_cb(idev
->id_config_arg
,
414 * Disable the device.
416 bus_print_child_header(device_get_parent(child
), child
);
417 kprintf(" can't assign resources (%s)\n", reason
);
419 isa_print_child(device_get_parent(child
), child
);
420 bzero(&config
, sizeof config
);
421 if (idev
->id_config_cb
)
422 idev
->id_config_cb(idev
->id_config_arg
, &config
, 0);
423 device_disable(child
);
429 * Called after other devices have initialised to probe for isa devices.
432 isa_probe_children(device_t dev
)
438 * Create all the children by calling driver's identify methods.
439 * Since this routine is called long after the ISA bus had been
440 * attached, yet never probed, we have to call a hack function that
441 * temporarily sets the bus back to DS_ALIVE to run the probe.
443 bus_generic_probe_hack(dev
);
445 if (device_get_children(dev
, &children
, &nchildren
))
449 * First disable all pnp devices so that they don't get
450 * matched by legacy probes.
453 kprintf("isa_probe_children: disabling PnP devices\n");
454 for (i
= 0; i
< nchildren
; i
++) {
455 device_t child
= children
[i
];
456 struct isa_device
*idev
= DEVTOISA(child
);
457 struct isa_config config
;
459 bzero(&config
, sizeof config
);
460 if (idev
->id_config_cb
)
461 idev
->id_config_cb(idev
->id_config_arg
, &config
, 0);
465 * Next probe all non-pnp devices so that they claim their
469 kprintf("isa_probe_children: probing non-PnP devices\n");
470 for (i
= 0; i
< nchildren
; i
++) {
471 device_t child
= children
[i
];
472 struct isa_device
*idev
= DEVTOISA(child
);
474 if (TAILQ_FIRST(&idev
->id_configs
))
477 device_probe_and_attach(child
);
481 * Finally assign resource to pnp devices and probe them.
484 kprintf("isa_probe_children: probing PnP devices\n");
485 for (i
= 0; i
< nchildren
; i
++) {
486 device_t child
= children
[i
];
487 struct isa_device
* idev
= DEVTOISA(child
);
489 if (!TAILQ_FIRST(&idev
->id_configs
))
492 if (isa_assign_resources(child
)) {
493 struct resource_list
*rl
= &idev
->id_resources
;
494 struct resource_list_entry
*rle
;
496 device_probe_and_attach(child
);
499 * Claim any unallocated resources to keep other
500 * devices from using them.
502 SLIST_FOREACH(rle
, rl
, link
) {
505 resource_list_alloc(rl
, dev
, child
,
506 rle
->type
, &rid
, 0, ~0, 1,
507 0 /* !RF_ACTIVE */, -1);
513 kfree(children
, M_TEMP
);
519 * Add a new child with default ivars.
522 isa_add_child(device_t bus
, device_t parent
, int order
, const char *name
, int unit
)
525 struct isa_device
*idev
;
527 idev
= kmalloc(sizeof(struct isa_device
), M_ISADEV
, M_WAITOK
| M_ZERO
);
529 resource_list_init(&idev
->id_resources
);
530 TAILQ_INIT(&idev
->id_configs
);
532 child
= device_add_child_ordered(parent
, order
, name
, unit
);
533 device_set_ivars(child
, idev
);
539 isa_print_resources(struct resource_list
*rl
, const char *name
, int type
,
540 int count
, const char *format
)
542 struct resource_list_entry
*rle
;
547 for (i
= 0; i
< count
; i
++) {
548 rle
= resource_list_find(rl
, type
, i
);
551 retval
+= kprintf(" %s ", name
);
552 else if (printed
> 0)
553 retval
+= kprintf(",");
555 retval
+= kprintf(format
, rle
->start
);
556 if (rle
->count
> 1) {
557 retval
+= kprintf("-");
558 retval
+= kprintf(format
,
559 rle
->start
+ rle
->count
- 1);
562 /* check the first few regardless */
570 isa_print_all_resources(device_t dev
)
572 struct isa_device
*idev
= DEVTOISA(dev
);
573 struct resource_list
*rl
= &idev
->id_resources
;
576 if (SLIST_FIRST(rl
) || device_get_flags(dev
))
577 retval
+= kprintf(" at");
579 retval
+= isa_print_resources(rl
, "port", SYS_RES_IOPORT
,
581 retval
+= isa_print_resources(rl
, "iomem", SYS_RES_MEMORY
,
583 retval
+= isa_print_resources(rl
, "irq", SYS_RES_IRQ
,
585 retval
+= isa_print_resources(rl
, "drq", SYS_RES_DRQ
,
587 if (device_get_flags(dev
))
588 retval
+= kprintf(" flags %#x", device_get_flags(dev
));
594 isa_print_child(device_t bus
, device_t dev
)
598 retval
+= bus_print_child_header(bus
, dev
);
599 retval
+= isa_print_all_resources(dev
);
600 retval
+= bus_print_child_footer(bus
, dev
);
606 isa_probe_nomatch(device_t dev
, device_t child
)
609 bus_print_child_header(dev
, child
);
610 kprintf(" failed to probe");
611 isa_print_all_resources(child
);
612 bus_print_child_footer(dev
, child
);
619 isa_read_ivar(device_t bus
, device_t dev
, int index
, uintptr_t * result
)
621 struct isa_device
* idev
= DEVTOISA(dev
);
622 struct resource_list
*rl
= &idev
->id_resources
;
623 struct resource_list_entry
*rle
;
626 case ISA_IVAR_PORT_0
:
627 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 0);
629 *result
= rle
->start
;
634 case ISA_IVAR_PORT_1
:
635 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 1);
637 *result
= rle
->start
;
642 case ISA_IVAR_PORTSIZE_0
:
643 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 0);
645 *result
= rle
->count
;
650 case ISA_IVAR_PORTSIZE_1
:
651 rle
= resource_list_find(rl
, SYS_RES_IOPORT
, 1);
653 *result
= rle
->count
;
658 case ISA_IVAR_MADDR_0
:
659 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 0);
661 *result
= rle
->start
;
666 case ISA_IVAR_MADDR_1
:
667 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 1);
669 *result
= rle
->start
;
674 case ISA_IVAR_MSIZE_0
:
675 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 0);
677 *result
= rle
->count
;
682 case ISA_IVAR_MSIZE_1
:
683 rle
= resource_list_find(rl
, SYS_RES_MEMORY
, 1);
685 *result
= rle
->count
;
691 rle
= resource_list_find(rl
, SYS_RES_IRQ
, 0);
693 *result
= rle
->start
;
699 rle
= resource_list_find(rl
, SYS_RES_IRQ
, 1);
701 *result
= rle
->start
;
707 rle
= resource_list_find(rl
, SYS_RES_DRQ
, 0);
709 *result
= rle
->start
;
715 rle
= resource_list_find(rl
, SYS_RES_DRQ
, 1);
717 *result
= rle
->start
;
722 case ISA_IVAR_VENDORID
:
723 *result
= idev
->id_vendorid
;
726 case ISA_IVAR_SERIAL
:
727 *result
= idev
->id_serial
;
730 case ISA_IVAR_LOGICALID
:
731 *result
= idev
->id_logicalid
;
734 case ISA_IVAR_COMPATID
:
735 *result
= idev
->id_compatid
;
746 isa_write_ivar(device_t bus
, device_t dev
,
747 int index
, uintptr_t value
)
749 struct isa_device
* idev
= DEVTOISA(dev
);
752 case ISA_IVAR_PORT_0
:
753 case ISA_IVAR_PORT_1
:
754 case ISA_IVAR_PORTSIZE_0
:
755 case ISA_IVAR_PORTSIZE_1
:
756 case ISA_IVAR_MADDR_0
:
757 case ISA_IVAR_MADDR_1
:
758 case ISA_IVAR_MSIZE_0
:
759 case ISA_IVAR_MSIZE_1
:
766 case ISA_IVAR_VENDORID
:
767 idev
->id_vendorid
= value
;
770 case ISA_IVAR_SERIAL
:
771 idev
->id_serial
= value
;
774 case ISA_IVAR_LOGICALID
:
775 idev
->id_logicalid
= value
;
778 case ISA_IVAR_COMPATID
:
779 idev
->id_compatid
= value
;
790 * Free any resources which the driver missed or which we were holding for
791 * it (see isa_probe_children).
794 isa_child_detached(device_t dev
, device_t child
)
796 struct isa_device
* idev
= DEVTOISA(child
);
797 struct resource_list
*rl
= &idev
->id_resources
;
798 struct resource_list_entry
*rle
;
800 if (TAILQ_FIRST(&idev
->id_configs
)) {
802 * Claim any unallocated resources to keep other
803 * devices from using them.
805 SLIST_FOREACH(rle
, rl
, link
) {
808 resource_list_alloc(rl
, dev
, child
,
809 rle
->type
, &rid
, 0, ~0, 1,
810 0 /* !RF_ACTIVE */, -1);
817 isa_driver_added(device_t dev
, driver_t
*driver
)
823 * Don't do anything if drivers are dynamically
824 * added during autoconfiguration (cf. ymf724).
825 * since that would end up calling identify
831 DEVICE_IDENTIFY(driver
, dev
);
832 if (device_get_children(dev
, &children
, &nchildren
))
835 for (i
= 0; i
< nchildren
; i
++) {
836 device_t child
= children
[i
];
837 struct isa_device
*idev
= DEVTOISA(child
);
838 struct resource_list
*rl
= &idev
->id_resources
;
839 struct resource_list_entry
*rle
;
841 if (device_get_state(child
) != DS_NOTPRESENT
)
843 if (!device_is_enabled(child
))
847 * Free resources which we were holding on behalf of
850 SLIST_FOREACH(rle
, &idev
->id_resources
, link
) {
852 resource_list_release(rl
, dev
, child
,
858 if (TAILQ_FIRST(&idev
->id_configs
))
859 if (!isa_assign_resources(child
))
862 device_probe_and_attach(child
);
864 if (TAILQ_FIRST(&idev
->id_configs
)) {
866 * Claim any unallocated resources to keep other
867 * devices from using them.
869 SLIST_FOREACH(rle
, rl
, link
) {
872 resource_list_alloc(rl
, dev
, child
,
873 rle
->type
, &rid
, 0, ~0, 1,
874 0 /* !RF_ACTIVE */, -1);
880 kfree(children
, M_TEMP
);
884 isa_set_resource(device_t dev
, device_t child
, int type
, int rid
,
885 u_long start
, u_long count
, int cpuid
)
887 struct isa_device
* idev
= DEVTOISA(child
);
888 struct resource_list
*rl
= &idev
->id_resources
;
890 if (type
!= SYS_RES_IOPORT
&& type
!= SYS_RES_MEMORY
891 && type
!= SYS_RES_IRQ
&& type
!= SYS_RES_DRQ
)
895 if (type
== SYS_RES_IOPORT
&& rid
>= ISA_NPORT
)
897 if (type
== SYS_RES_MEMORY
&& rid
>= ISA_NMEM
)
899 if (type
== SYS_RES_IRQ
&& rid
>= ISA_NIRQ
)
901 if (type
== SYS_RES_DRQ
&& rid
>= ISA_NDRQ
)
904 resource_list_add(rl
, type
, rid
, start
, start
+ count
- 1, count
,
911 isa_get_resource(device_t dev
, device_t child
, int type
, int rid
,
912 u_long
*startp
, u_long
*countp
)
914 struct isa_device
* idev
= DEVTOISA(child
);
915 struct resource_list
*rl
= &idev
->id_resources
;
916 struct resource_list_entry
*rle
;
918 rle
= resource_list_find(rl
, type
, rid
);
923 *startp
= rle
->start
;
925 *countp
= rle
->count
;
931 isa_delete_resource(device_t dev
, device_t child
, int type
, int rid
)
933 struct isa_device
* idev
= DEVTOISA(child
);
934 struct resource_list
*rl
= &idev
->id_resources
;
935 resource_list_delete(rl
, type
, rid
);
939 isa_add_config(device_t dev
, device_t child
,
940 int priority
, struct isa_config
*config
)
942 struct isa_device
* idev
= DEVTOISA(child
);
943 struct isa_config_entry
*newice
, *ice
;
945 newice
= kmalloc(sizeof *ice
, M_DEVBUF
, M_WAITOK
);
946 newice
->ice_priority
= priority
;
947 newice
->ice_config
= *config
;
949 TAILQ_FOREACH(ice
, &idev
->id_configs
, ice_link
) {
950 if (ice
->ice_priority
> priority
)
954 TAILQ_INSERT_BEFORE(ice
, newice
, ice_link
);
956 TAILQ_INSERT_TAIL(&idev
->id_configs
, newice
, ice_link
);
962 isa_set_config_callback(device_t dev
, device_t child
,
963 isa_config_cb
*fn
, void *arg
)
965 struct isa_device
* idev
= DEVTOISA(child
);
967 idev
->id_config_cb
= fn
;
968 idev
->id_config_arg
= arg
;
972 isa_pnp_probe(device_t dev
, device_t child
, struct isa_pnp_id
*ids
)
974 struct isa_device
* idev
= DEVTOISA(child
);
976 if (!idev
->id_vendorid
)
981 * Really ought to support >1 compat id per device.
983 if (idev
->id_logicalid
== ids
->ip_id
984 || idev
->id_compatid
== ids
->ip_id
) {
986 device_set_desc(child
, ids
->ip_desc
);
995 static device_method_t isa_methods
[] = {
996 /* Device interface */
997 DEVMETHOD(device_probe
, isa_probe
),
998 DEVMETHOD(device_attach
, isa_attach
),
999 DEVMETHOD(device_detach
, bus_generic_detach
),
1000 DEVMETHOD(device_shutdown
, bus_generic_shutdown
),
1001 DEVMETHOD(device_suspend
, bus_generic_suspend
),
1002 DEVMETHOD(device_resume
, bus_generic_resume
),
1005 DEVMETHOD(bus_add_child
, isa_add_child
),
1006 DEVMETHOD(bus_print_child
, isa_print_child
),
1007 DEVMETHOD(bus_probe_nomatch
, isa_probe_nomatch
),
1008 DEVMETHOD(bus_read_ivar
, isa_read_ivar
),
1009 DEVMETHOD(bus_write_ivar
, isa_write_ivar
),
1010 DEVMETHOD(bus_child_detached
, isa_child_detached
),
1011 DEVMETHOD(bus_driver_added
, isa_driver_added
),
1012 DEVMETHOD(bus_alloc_resource
, isa_alloc_resource
),
1013 DEVMETHOD(bus_release_resource
, isa_release_resource
),
1014 DEVMETHOD(bus_activate_resource
, bus_generic_activate_resource
),
1015 DEVMETHOD(bus_deactivate_resource
, bus_generic_deactivate_resource
),
1016 DEVMETHOD(bus_setup_intr
, isa_setup_intr
),
1017 DEVMETHOD(bus_teardown_intr
, isa_teardown_intr
),
1018 DEVMETHOD(bus_set_resource
, isa_set_resource
),
1019 DEVMETHOD(bus_get_resource
, isa_get_resource
),
1020 DEVMETHOD(bus_delete_resource
, isa_delete_resource
),
1023 DEVMETHOD(isa_add_config
, isa_add_config
),
1024 DEVMETHOD(isa_set_config_callback
, isa_set_config_callback
),
1025 DEVMETHOD(isa_pnp_probe
, isa_pnp_probe
),
1030 static driver_t isa_driver
= {
1037 * ISA can be attached to a PCI-ISA bridge or directly to the nexus.
1039 DRIVER_MODULE(isa
, isab
, isa_driver
, isa_devclass
, NULL
, NULL
);
1040 MODULE_VERSION(isa
, 1);
1043 * Code common to ISA bridges.
1046 isab_attach(device_t dev
)
1050 child
= device_add_child(dev
, "isa", 0);
1052 return (bus_generic_attach(dev
));