diff options
author | Doug Rabson <dfr@FreeBSD.org> | 1999-05-22 15:18:28 +0000 |
---|---|---|
committer | Doug Rabson <dfr@FreeBSD.org> | 1999-05-22 15:18:28 +0000 |
commit | a3be63b3ce302593b470b6b6be5f609fb4735376 (patch) | |
tree | b19a178082c1780c902bd6134120160bd32c8928 /sys | |
parent | 7e082b48a2e0f32ad82cf7c02f56dc90b5ccbfa6 (diff) | |
download | src-a3be63b3ce302593b470b6b6be5f609fb4735376.tar.gz src-a3be63b3ce302593b470b6b6be5f609fb4735376.zip |
* Factor out the common code between the isa bus drivers for i386 and alpha.
* Re-work the resource allocation code to use helper functions in subr_bus.c.
* Add simple isa interface for manipulating the resource ranges which can be
allocated and remove the code from isa_write_ivar() which was previously
used for this purpose.
Notes
Notes:
svn path=/head/; revision=47398
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/isa/isa.c | 494 | ||||
-rw-r--r-- | sys/amd64/isa/isa.c | 463 | ||||
-rw-r--r-- | sys/conf/files | 15 | ||||
-rw-r--r-- | sys/i386/isa/isa.c | 463 | ||||
-rw-r--r-- | sys/i386/isa/isa_compat.c | 80 | ||||
-rw-r--r-- | sys/isa/isa_common.c | 395 | ||||
-rw-r--r-- | sys/isa/isa_common.h | 68 | ||||
-rw-r--r-- | sys/isa/isa_if.m | 55 | ||||
-rw-r--r-- | sys/isa/isahint.c | 35 | ||||
-rw-r--r-- | sys/isa/isavar.h | 5 |
10 files changed, 749 insertions, 1324 deletions
diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c index e3f2e829d302..3878e6a668b9 100644 --- a/sys/alpha/isa/isa.c +++ b/sys/alpha/isa/isa.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isa.c,v 1.14 1999/05/18 19:44:54 dfr Exp $ + * $Id: isa.c,v 1.15 1999/05/18 20:43:49 dfr Exp $ */ #include <sys/param.h> @@ -37,33 +37,12 @@ #include <isa/isareg.h> #include <isa/isavar.h> +#include <isa/isa_common.h> #include <alpha/isa/isavar.h> #include <machine/intr.h> #include <machine/intrcnt.h> #include <machine/resource.h> -MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device"); - -/* - * The structure used to attach devices to the Isa. - */ -struct isa_device { - int id_port[ISA_NPORT_IVARS]; - u_short id_portsize[ISA_NPORT_IVARS]; - vm_offset_t id_maddr[ISA_NMEM_IVARS]; - vm_size_t id_msize[ISA_NMEM_IVARS]; - int id_irq[ISA_NIRQ_IVARS]; - int id_drq[ISA_NDRQ_IVARS]; - int id_flags; - struct resource *id_portres[ISA_NPORT_IVARS]; - struct resource *id_memres[ISA_NMEM_IVARS]; - struct resource *id_irqres[ISA_NIRQ_IVARS]; - struct resource *id_drqres[ISA_NDRQ_IVARS]; -}; - -#define DEVTOISA(dev) ((struct isa_device*) device_get_ivars(dev)) - -static devclass_t isa_devclass; static struct rman isa_irq_rman; static void @@ -110,244 +89,14 @@ isa_irq_mask(void) return ((irr2 << 8) | irr1); } -/* - * At 'probe' time, we add all the devices which we know about to the - * bus. The generic attach routine will probe and attach them if they - * are alive. - */ -static int -isa_probe(device_t dev) +void +isa_init(void) { - device_set_desc(dev, "ISA bus"); isa_init_intr(); - return bus_generic_probe(dev); -} - -extern device_t isa_bus_device; - -static int -isa_attach(device_t dev) -{ - if (bootverbose) - printf("isa_attach: mask=%04x\n", isa_irq_mask()); - - /* - * Arrange for bus_generic_attach(dev) to be called later. - */ - isa_bus_device = dev; - return 0; -} - -/* - * Add a new child with default ivars. - */ -static device_t -isa_add_child(device_t dev, device_t place, const char *name, int unit) -{ - struct isa_device *idev; - - idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); - if (!idev) - return 0; - bzero(idev, sizeof *idev); - - idev->id_port[0] = -1; - idev->id_port[1] = -1; - idev->id_portsize[0] = 0; - idev->id_portsize[1] = 0; - idev->id_maddr[0] = 0; - idev->id_maddr[1] = 0; - idev->id_msize[0] = 0; - idev->id_msize[1] = 0; - idev->id_irq[0] = -1; - idev->id_irq[1] = -1; - idev->id_drq[0] = -1; - idev->id_drq[1] = -1; - idev->id_flags = 0; - - if (place) - return device_add_child_after(dev, place, name, unit, idev); - else - return device_add_child(dev, name, unit, idev); -} - -static void -isa_print_child(device_t bus, device_t dev) -{ - struct isa_device *id = DEVTOISA(dev); - - if (id->id_port[0] > 0 || id->id_port[1] > 0 - || id->id_maddr[0] > 0 || id->id_maddr[1] > 0 - || id->id_irq[0] >= 0 || id->id_irq[1] >= 0 - || id->id_drq[0] >= 0 || id->id_drq[1] >= 0) - printf(" at"); - if (id->id_port[0] > 0 && id->id_port[1] > 0) { - printf(" ports %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - printf(" and %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } else if (id->id_port[0] > 0) { - printf(" port %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - } else if (id->id_port[1] > 0) { - printf(" port %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } - if (id->id_maddr[0] && id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - printf(" and %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } else if (id->id_maddr[0]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - } else if (id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } -#if 0 - if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0) - printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]); - else if (id->id_irq[0] >= 0) - printf(" irq %d", id->id_irq[0]); - else if (id->id_irq[1] >= 0) - printf(" irq %d", id->id_irq[1]); -#endif - if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0) - printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]); - else if (id->id_drq[0] >= 0) - printf(" drq %d", id->id_drq[0]); - else if (id->id_drq[1] >= 0) - printf(" drq %d", id->id_drq[1]); - - if (id->id_flags) - printf(" flags %#x", id->id_flags); - - printf(" on %s%d", - device_get_name(bus), device_get_unit(bus)); -} - -static int -isa_read_ivar(device_t bus, device_t dev, - int index, u_long* result) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - *result = idev->id_port[0]; - break; - case ISA_IVAR_PORT_1: - *result = idev->id_port[1]; - break; - case ISA_IVAR_PORTSIZE_0: - *result = idev->id_portsize[0]; - break; - case ISA_IVAR_PORTSIZE_1: - *result = idev->id_portsize[1]; - break; - case ISA_IVAR_MADDR_0: - *result = idev->id_maddr[0]; - break; - case ISA_IVAR_MADDR_1: - *result = idev->id_maddr[1]; - break; - case ISA_IVAR_MSIZE_0: - *result = idev->id_msize[0]; - break; - case ISA_IVAR_MSIZE_1: - *result = idev->id_msize[1]; - break; - case ISA_IVAR_IRQ_0: - *result = idev->id_irq[0]; - break; - case ISA_IVAR_IRQ_1: - *result = idev->id_irq[1]; - break; - case ISA_IVAR_DRQ_0: - *result = idev->id_drq[0]; - break; - case ISA_IVAR_DRQ_1: - *result = idev->id_drq[1]; - break; - case ISA_IVAR_FLAGS: - *result = idev->id_flags; - break; - default: - return (ENOENT); - } - return (0); -} - -static int -isa_write_ivar(device_t bus, device_t dev, - int index, u_long value) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - idev->id_port[0] = value; - break; - case ISA_IVAR_PORT_1: - idev->id_port[1] = value; - break; - case ISA_IVAR_PORTSIZE_0: - idev->id_portsize[0] = value; - break; - case ISA_IVAR_PORTSIZE_1: - idev->id_portsize[1] = value; - break; - case ISA_IVAR_MADDR_0: - idev->id_maddr[0] = value; - break; - case ISA_IVAR_MADDR_1: - idev->id_maddr[1] = value; - break; - case ISA_IVAR_MSIZE_0: - idev->id_msize[0] = value; - break; - case ISA_IVAR_MSIZE_1: - idev->id_msize[1] = value; - break; - case ISA_IVAR_IRQ_0: - idev->id_irq[0] = value; - break; - case ISA_IVAR_IRQ_1: - idev->id_irq[1] = value; - break; - case ISA_IVAR_DRQ_0: - idev->id_drq[0] = value; - break; - case ISA_IVAR_DRQ_1: - idev->id_drq[1] = value; - break; - case ISA_IVAR_FLAGS: - idev->id_flags = value; - break; - default: - return (ENOENT); - } - return (0); } -void isa_init_intr(void) +void +isa_init_intr(void) { static int initted = 0; @@ -395,157 +144,90 @@ isa_release_intr(device_t bus, device_t child, struct resource *r) * We manage our own interrupt resources since ISA interrupts go through * the ISA PIC, not the PCI interrupt controller. */ -static struct resource * +struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - int isdefault; - struct resource *rv, **rvp; - struct isa_device *id; - - if (child) { - /* - * If this is our child, then use the isa_device to find - * defaults and to record results. - */ - if (device_get_devclass(device_get_parent(child)) == isa_devclass) - id = DEVTOISA(child); - else - id = NULL; - } else - id = NULL; - isdefault = (start == 0UL && end == ~0UL && *rid == 0); - if (*rid > 1) - return 0; - - switch (type) { - case SYS_RES_IRQ: - /* - * The hack implementation of intr_create() passes a - * NULL child device. - */ - if (isdefault && id && id->id_irq[0] >= 0) { - start = id->id_irq[0]; - end = id->id_irq[0]; - count = 1; - } - rv = rman_reserve_resource(&isa_irq_rman, - start, end, count, - 0, child); - if (!rv) - return 0; - if (id) { - id->id_irqres[*rid] = rv; - id->id_irq[*rid] = rv->r_start; + /* + * Consider adding a resource definition. We allow rid 0-1 for + * irq, drq and memory and rid 0-7 for ports which is sufficient for + * isapnp. + */ + int passthrough = (device_get_parent(child) != bus); + int isdefault = (start == 0UL && end == ~0UL); + struct resource_list *rl; + struct resource_list_entry *rle; + struct resource *res; + + if (!passthrough && !isdefault) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, type, *rid); + if (!rle) { + if (*rid < 0) + return 0; + if (type != SYS_RES_IOPORT && *rid > 1) + return 0; + if (type == SYS_RES_IOPORT && *rid > 7) + return 0; + resource_list_add(rl, type, *rid, start, end, count); } - return rv; + } - case SYS_RES_MEMORY: - if (isdefault && id->id_maddr[0]) { - start = id->id_maddr[0]; - count = max(count, (u_long)id->id_msize[0]); - end = id->id_maddr[0] + count; - } - rvp = &id->id_memres[*rid]; - break; - - case SYS_RES_IOPORT: - if (isdefault && id->id_port[0]) { - start = id->id_port[0]; - count = max(count, (u_long)id->id_portsize[0]); - end = id->id_port[0] + count; - } - rvp = &id->id_portres[*rid]; - break; + if (type != SYS_RES_IRQ) + return resource_list_alloc(bus, child, type, rid, + start, end, count, flags); - default: - return 0; + if (!passthrough) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, SYS_RES_IRQ, *rid); + if (!rle) + return 0; + if (rle->res) + panic("isa_alloc_resource: resource entry is busy"); + if (isdefault) { + start = end = rle->start; + count = 1; + } } - /* - * If the client attempts to reallocate a resource without - * releasing what was there previously, die horribly so that - * he knows how he !@#$ed up. - */ - if (*rvp != 0) - panic("%s%d: (%d, %d) not free for %s%d\n", - device_get_name(bus), device_get_unit(bus), - type, *rid, - device_get_name(child), device_get_unit(child)); + res = isa_alloc_intr(bus, child, start); - /* - * nexus_alloc_resource had better not change *rid... - */ - rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, - start, end, count, flags); - if ((*rvp = rv) != 0) { - switch (type) { - case SYS_RES_MEMORY: - id->id_maddr[*rid] = rv->r_start; - id->id_msize[*rid] = count; - break; - case SYS_RES_IOPORT: - id->id_port[*rid] = rv->r_start; - id->id_portsize[*rid] = count; - break; - } + if (res && !passthrough) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, SYS_RES_IRQ, *rid); + rle->start = rman_get_start(res); + rle->end = rman_get_end(res); + rle->count = 1; + rle->res = res; } - return rv; + + return res; } -static int +int isa_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) + struct resource *res) { - int rv; - struct isa_device *id = DEVTOISA(child); - - if (rid > 1) - return EINVAL; - - switch (type) { - case SYS_RES_IRQ: - return (rman_release_resource(r)); - case SYS_RES_DRQ: - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - break; - default: - return (ENOENT); - } + int passthrough = (device_get_parent(child) != bus); + struct resource_list *rl; + struct resource_list_entry *rle; + int error; - rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r); - - if (rv == 0) { - switch (type) { - case SYS_RES_IRQ: - id->id_irqres[rid] = 0; - id->id_irq[rid] = -1; - break; - - case SYS_RES_DRQ: - id->id_drqres[rid] = 0; - id->id_drq[rid] = -1; - break; - - case SYS_RES_MEMORY: - id->id_memres[rid] = 0; - id->id_maddr[rid] = 0; - id->id_msize[rid] = 0; - break; - - case SYS_RES_IOPORT: - id->id_portres[rid] = 0; - id->id_port[rid] = 0; - id->id_portsize[rid] = 0; - break; - - default: - return ENOENT; - } + if (type != SYS_RES_IRQ) + return resource_list_release(bus, child, type, rid, res); + + error = rman_release_resource(res); + + if (!passthrough && !error) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, SYS_RES_IRQ, rid); + if (rle) + rle->res = NULL; + else + error = ENOENT; } - return rv; + return error; } struct isa_intr { @@ -621,33 +303,3 @@ isa_teardown_intr(device_t dev, device_t child, return 0; } - -static device_method_t isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, isa_probe), - DEVMETHOD(device_attach, isa_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - /* Bus interface */ - DEVMETHOD(bus_add_child, isa_add_child), - DEVMETHOD(bus_print_child, isa_print_child), - DEVMETHOD(bus_read_ivar, isa_read_ivar), - DEVMETHOD(bus_write_ivar, isa_write_ivar), - DEVMETHOD(bus_alloc_resource, isa_alloc_resource), - DEVMETHOD(bus_release_resource, isa_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, isa_setup_intr), - DEVMETHOD(bus_teardown_intr, isa_teardown_intr), - - { 0, 0 } -}; - -static driver_t isa_driver = { - "isa", - isa_methods, - 1, /* no softc */ -}; - -DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c index 9078b5b3fece..a467cb5b0ba8 100644 --- a/sys/amd64/isa/isa.c +++ b/sys/amd64/isa/isa.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isa.c,v 1.125 1999/05/08 21:59:25 dfr Exp $ + * $Id: isa.c,v 1.126 1999/05/14 11:22:28 dfr Exp $ */ /* @@ -68,261 +68,12 @@ #include <machine/resource.h> #include <isa/isavar.h> +#include <isa/isa_common.h> -MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device"); - -/* - * The structure used to attach devices to the isa bus. - */ -struct isa_device { - int id_port[ISA_NPORT_IVARS]; - u_short id_portsize[ISA_NPORT_IVARS]; - vm_offset_t id_maddr[ISA_NMEM_IVARS]; - vm_size_t id_msize[ISA_NMEM_IVARS]; - int id_irq[ISA_NIRQ_IVARS]; - int id_drq[ISA_NDRQ_IVARS]; - int id_flags; - struct resource *id_portres[ISA_NPORT_IVARS]; - struct resource *id_memres[ISA_NMEM_IVARS]; - struct resource *id_irqres[ISA_NIRQ_IVARS]; - struct resource *id_drqres[ISA_NDRQ_IVARS]; -}; - -#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev)) - -static devclass_t isa_devclass; - -/* - * At 'probe' time, we add all the devices which we know about to the - * bus. The generic attach routine will probe and attach them if they - * are alive. - */ -static int -isa_probe(device_t dev) -{ - isa_wrap_old_drivers(); - return bus_generic_probe(dev); -} - -extern device_t isa_bus_device; - -static int -isa_attach(device_t dev) +void +isa_init(void) { - /* - * Arrange for bus_generic_attach(dev) to be called later. - */ - isa_bus_device = dev; - return 0; -} - -/* - * Add a new child with default ivars. - */ -static device_t -isa_add_child(device_t dev, device_t place, const char *name, int unit) -{ - struct isa_device *idev; - - idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); - if (!idev) - return 0; - bzero(idev, sizeof *idev); - - idev->id_port[0] = -1; - idev->id_port[1] = -1; - idev->id_portsize[0] = 0; - idev->id_portsize[1] = 0; - idev->id_maddr[0] = 0; - idev->id_maddr[1] = 0; - idev->id_msize[0] = 0; - idev->id_msize[1] = 0; - idev->id_irq[0] = -1; - idev->id_irq[1] = -1; - idev->id_drq[0] = -1; - idev->id_drq[1] = -1; - idev->id_flags = 0; - - if (place) - return device_add_child_after(dev, place, name, unit, idev); - else - return device_add_child(dev, name, unit, idev); -} - -static void -isa_print_child(device_t bus, device_t dev) -{ - struct isa_device *id = DEVTOISA(dev); - - if (id->id_port[0] > 0 || id->id_port[1] > 0 - || id->id_maddr[0] > 0 || id->id_maddr[1] > 0 - || id->id_irq[0] >= 0 || id->id_irq[1] >= 0 - || id->id_drq[0] >= 0 || id->id_drq[1] >= 0) - printf(" at"); - if (id->id_port[0] > 0 && id->id_port[1] > 0) { - printf(" ports %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - printf(" and %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } else if (id->id_port[0] > 0) { - printf(" port %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - } else if (id->id_port[1] > 0) { - printf(" port %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } - if (id->id_maddr[0] && id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - printf(" and %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } else if (id->id_maddr[0]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - } else if (id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } - if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0) - printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]); - else if (id->id_irq[0] >= 0) - printf(" irq %d", id->id_irq[0]); - else if (id->id_irq[1] >= 0) - printf(" irq %d", id->id_irq[1]); - if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0) - printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]); - else if (id->id_drq[0] >= 0) - printf(" drq %d", id->id_drq[0]); - else if (id->id_drq[1] >= 0) - printf(" drq %d", id->id_drq[1]); - - if (id->id_flags) - printf(" flags %#x", id->id_flags); - - printf(" on %s%d", - device_get_name(bus), device_get_unit(bus)); -} - -static int -isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - *result = idev->id_port[0]; - break; - case ISA_IVAR_PORT_1: - *result = idev->id_port[1]; - break; - case ISA_IVAR_PORTSIZE_0: - *result = idev->id_portsize[0]; - break; - case ISA_IVAR_PORTSIZE_1: - *result = idev->id_portsize[1]; - break; - case ISA_IVAR_MADDR_0: - *result = idev->id_maddr[0]; - break; - case ISA_IVAR_MADDR_1: - *result = idev->id_maddr[1]; - break; - case ISA_IVAR_MSIZE_0: - *result = idev->id_msize[0]; - break; - case ISA_IVAR_MSIZE_1: - *result = idev->id_msize[1]; - break; - case ISA_IVAR_IRQ_0: - *result = idev->id_irq[0]; - break; - case ISA_IVAR_IRQ_1: - *result = idev->id_irq[1]; - break; - case ISA_IVAR_DRQ_0: - *result = idev->id_drq[0]; - break; - case ISA_IVAR_DRQ_1: - *result = idev->id_drq[1]; - break; - case ISA_IVAR_FLAGS: - *result = idev->id_flags; - break; - } - return ENOENT; -} - -/* - * XXX -- this interface is pretty much irrelevant in the presence of - * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which - * are defined at this point). - */ -static int -isa_write_ivar(device_t bus, device_t dev, - int index, uintptr_t value) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - idev->id_port[0] = value; - break; - case ISA_IVAR_PORT_1: - idev->id_port[1] = value; - break; - case ISA_IVAR_PORTSIZE_0: - idev->id_portsize[0] = value; - break; - case ISA_IVAR_PORTSIZE_1: - idev->id_portsize[1] = value; - break; - case ISA_IVAR_MADDR_0: - idev->id_maddr[0] = value; - break; - case ISA_IVAR_MADDR_1: - idev->id_maddr[1] = value; - break; - case ISA_IVAR_MSIZE_0: - idev->id_msize[0] = value; - break; - case ISA_IVAR_MSIZE_1: - idev->id_msize[1] = value; - break; - case ISA_IVAR_IRQ_0: - idev->id_irq[0] = value; - break; - case ISA_IVAR_IRQ_1: - idev->id_irq[1] = value; - break; - case ISA_IVAR_DRQ_0: - idev->id_drq[0] = value; - break; - case ISA_IVAR_DRQ_1: - idev->id_drq[1] = value; - break; - case ISA_IVAR_FLAGS: - idev->id_flags = value; - break; - default: - return (ENOENT); - } - return (0); + isa_wrap_old_drivers(); } /* @@ -333,157 +84,43 @@ isa_write_ivar(device_t bus, device_t dev, * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ -static struct resource * +struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - int isdefault; - struct resource *rv, **rvp = 0; - struct isa_device *id = DEVTOISA(child); - - if (child) { - /* - * If this is our child, then use the isa_device to find - * defaults and to record results. - */ - if (device_get_devclass(device_get_parent(child)) == isa_devclass) - id = DEVTOISA(child); - else - id = NULL; - } else - id = NULL; - isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0); - if (*rid > 1) - return 0; - - switch (type) { - case SYS_RES_IRQ: - if (isdefault && id->id_irq[0] >= 0) { - start = id->id_irq[0]; - end = id->id_irq[0]; - count = 1; - } - if (id) - rvp = &id->id_irqres[*rid]; - break; - - case SYS_RES_DRQ: - if (isdefault && id->id_drq[0] >= 0) { - start = id->id_drq[0]; - end = id->id_drq[0]; - count = 1; - } - if (id) - rvp = &id->id_drqres[*rid]; - break; - - case SYS_RES_MEMORY: - if (isdefault && id->id_maddr[0]) { - start = id->id_maddr[0]; - count = max(count, (u_long)id->id_msize[0]); - end = id->id_maddr[0] + count; - } - if (id) - rvp = &id->id_memres[*rid]; - break; - - case SYS_RES_IOPORT: - if (isdefault && id->id_port[0]) { - start = id->id_port[0]; - count = max(count, (u_long)id->id_portsize[0]); - end = id->id_port[0] + count; - } - if (id) - rvp = &id->id_portres[*rid]; - break; - - default: - return 0; - } - /* - * If the client attempts to reallocate a resource without - * releasing what was there previously, die horribly so that - * he knows how he !@#$ed up. + * Consider adding a resource definition. We allow rid 0-1 for + * irq, drq and memory and rid 0-7 for ports which is sufficient for + * isapnp. */ - if (rvp && *rvp != 0) - panic("%s%d: (%d, %d) not free for %s%d\n", - device_get_name(bus), device_get_unit(bus), - type, *rid, - device_get_name(child), device_get_unit(child)); - - /* - * nexus_alloc_resource had better not change *rid... - */ - rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, - start, end, count, flags); - if (rvp && (*rvp = rv) != 0) { - switch (type) { - case SYS_RES_MEMORY: - id->id_maddr[*rid] = rv->r_start; - id->id_msize[*rid] = count; - break; - case SYS_RES_IOPORT: - id->id_port[*rid] = rv->r_start; - id->id_portsize[*rid] = count; - break; - case SYS_RES_IRQ: - id->id_irq[*rid] = rv->r_start; - break; - case SYS_RES_DRQ: - id->id_drq[*rid] = rv->r_start; - break; + int passthrough = (device_get_parent(child) != bus); + int isdefault = (start == 0UL && end == ~0UL); + struct resource_list *rl; + struct resource_list_entry *rle; + + if (!passthrough && !isdefault) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, type, *rid); + if (!rle) { + if (*rid < 0) + return 0; + if (type != SYS_RES_IOPORT && *rid > 1) + return 0; + if (type == SYS_RES_IOPORT && *rid > 7) + return 0; + resource_list_add(rl, type, *rid, start, end, count); } } - return rv; + + return resource_list_alloc(bus, child, type, rid, + start, end, count, flags); } -static int +int isa_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - int rv; - struct isa_device *id = DEVTOISA(child); - - if (rid > 1) - return EINVAL; - - switch (type) { - case SYS_RES_IRQ: - case SYS_RES_DRQ: - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - break; - default: - return (ENOENT); - } - - rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r); - - if (rv == 0) { - switch (type) { - case SYS_RES_IRQ: - id->id_irqres[rid] = 0; - break; - - case SYS_RES_DRQ: - id->id_drqres[rid] = 0; - break; - - case SYS_RES_MEMORY: - id->id_memres[rid] = 0; - break; - - case SYS_RES_IOPORT: - id->id_portres[rid] = 0; - break; - - default: - return ENOENT; - } - } - - return rv; + return resource_list_release(bus, child, type, rid, r); } /* @@ -492,7 +129,7 @@ isa_release_resource(device_t bus, device_t child, int type, int rid, * to pass the child (the i386 nexus knows about this and is prepared to * deal). */ -static int +int isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, void (*ihand)(void *), void *arg, void **cookiep) { @@ -500,45 +137,9 @@ isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, ihand, arg, cookiep)); } -static int +int isa_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie) { return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); } - -static device_method_t isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, isa_probe), - DEVMETHOD(device_attach, isa_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_add_child, isa_add_child), - DEVMETHOD(bus_print_child, isa_print_child), - DEVMETHOD(bus_read_ivar, isa_read_ivar), - DEVMETHOD(bus_write_ivar, isa_write_ivar), - DEVMETHOD(bus_alloc_resource, isa_alloc_resource), - DEVMETHOD(bus_release_resource, isa_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, isa_setup_intr), - DEVMETHOD(bus_teardown_intr, isa_teardown_intr), - - { 0, 0 } -}; - -static driver_t isa_driver = { - "isa", - isa_methods, - 1, /* no softc */ -}; - -/* - * ISA can be attached to a PCI-ISA bridge or directly to the nexus. - */ -DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); -DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0); diff --git a/sys/conf/files b/sys/conf/files index bdd7962f1199..f999c6f46e02 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -713,4 +713,19 @@ dev/usb/ulpt.c optional ulpt device-driver dev/usb/ukbd.c optional ukbd device-driver dev/usb/umass.c optional umass device-driver dev/usb/uhub.c optional usb device-driver +isa_if.o optional isa \ + dependency "isa_if.c isa_if.h" \ + compile-with "${NORMAL_C}" \ + no-implicit-rule local +isa_if.c optional isa \ + dependency "$S/kern/makedevops.pl $S/isa/isa_if.m" \ + compile-with "perl5 $S/kern/makedevops.pl -c $S/isa/isa_if.m" \ + no-obj no-implicit-rule before-depend local \ + clean "isa_if.c" +isa_if.h optional isa \ + dependency "$S/kern/makedevops.pl $S/isa/isa_if.m" \ + compile-with "perl5 $S/kern/makedevops.pl -h $S/isa/isa_if.m" \ + no-obj no-implicit-rule before-depend \ + clean "isa_if.h" +isa/isa_common.c optional isa device-driver isa/isahint.c optional isa device-driver diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c index 9078b5b3fece..a467cb5b0ba8 100644 --- a/sys/i386/isa/isa.c +++ b/sys/i386/isa/isa.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isa.c,v 1.125 1999/05/08 21:59:25 dfr Exp $ + * $Id: isa.c,v 1.126 1999/05/14 11:22:28 dfr Exp $ */ /* @@ -68,261 +68,12 @@ #include <machine/resource.h> #include <isa/isavar.h> +#include <isa/isa_common.h> -MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device"); - -/* - * The structure used to attach devices to the isa bus. - */ -struct isa_device { - int id_port[ISA_NPORT_IVARS]; - u_short id_portsize[ISA_NPORT_IVARS]; - vm_offset_t id_maddr[ISA_NMEM_IVARS]; - vm_size_t id_msize[ISA_NMEM_IVARS]; - int id_irq[ISA_NIRQ_IVARS]; - int id_drq[ISA_NDRQ_IVARS]; - int id_flags; - struct resource *id_portres[ISA_NPORT_IVARS]; - struct resource *id_memres[ISA_NMEM_IVARS]; - struct resource *id_irqres[ISA_NIRQ_IVARS]; - struct resource *id_drqres[ISA_NDRQ_IVARS]; -}; - -#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev)) - -static devclass_t isa_devclass; - -/* - * At 'probe' time, we add all the devices which we know about to the - * bus. The generic attach routine will probe and attach them if they - * are alive. - */ -static int -isa_probe(device_t dev) -{ - isa_wrap_old_drivers(); - return bus_generic_probe(dev); -} - -extern device_t isa_bus_device; - -static int -isa_attach(device_t dev) +void +isa_init(void) { - /* - * Arrange for bus_generic_attach(dev) to be called later. - */ - isa_bus_device = dev; - return 0; -} - -/* - * Add a new child with default ivars. - */ -static device_t -isa_add_child(device_t dev, device_t place, const char *name, int unit) -{ - struct isa_device *idev; - - idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); - if (!idev) - return 0; - bzero(idev, sizeof *idev); - - idev->id_port[0] = -1; - idev->id_port[1] = -1; - idev->id_portsize[0] = 0; - idev->id_portsize[1] = 0; - idev->id_maddr[0] = 0; - idev->id_maddr[1] = 0; - idev->id_msize[0] = 0; - idev->id_msize[1] = 0; - idev->id_irq[0] = -1; - idev->id_irq[1] = -1; - idev->id_drq[0] = -1; - idev->id_drq[1] = -1; - idev->id_flags = 0; - - if (place) - return device_add_child_after(dev, place, name, unit, idev); - else - return device_add_child(dev, name, unit, idev); -} - -static void -isa_print_child(device_t bus, device_t dev) -{ - struct isa_device *id = DEVTOISA(dev); - - if (id->id_port[0] > 0 || id->id_port[1] > 0 - || id->id_maddr[0] > 0 || id->id_maddr[1] > 0 - || id->id_irq[0] >= 0 || id->id_irq[1] >= 0 - || id->id_drq[0] >= 0 || id->id_drq[1] >= 0) - printf(" at"); - if (id->id_port[0] > 0 && id->id_port[1] > 0) { - printf(" ports %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - printf(" and %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } else if (id->id_port[0] > 0) { - printf(" port %#x", (u_int)id->id_port[0]); - if (id->id_portsize[0] > 1) - printf("-%#x", (u_int)(id->id_port[0] - + id->id_portsize[0] - 1)); - } else if (id->id_port[1] > 0) { - printf(" port %#x", (u_int)id->id_port[1]); - if (id->id_portsize[1] > 1) - printf("-%#x", (u_int)(id->id_port[1] - + id->id_portsize[1] - 1)); - } - if (id->id_maddr[0] && id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - printf(" and %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } else if (id->id_maddr[0]) { - printf(" iomem %#x", (u_int)id->id_maddr[0]); - if (id->id_msize[0]) - printf("-%#x", (u_int)(id->id_maddr[0] - + id->id_msize[0] - 1)); - } else if (id->id_maddr[1]) { - printf(" iomem %#x", (u_int)id->id_maddr[1]); - if (id->id_msize[1]) - printf("-%#x", (u_int)(id->id_maddr[1] - + id->id_msize[1] - 1)); - } - if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0) - printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]); - else if (id->id_irq[0] >= 0) - printf(" irq %d", id->id_irq[0]); - else if (id->id_irq[1] >= 0) - printf(" irq %d", id->id_irq[1]); - if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0) - printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]); - else if (id->id_drq[0] >= 0) - printf(" drq %d", id->id_drq[0]); - else if (id->id_drq[1] >= 0) - printf(" drq %d", id->id_drq[1]); - - if (id->id_flags) - printf(" flags %#x", id->id_flags); - - printf(" on %s%d", - device_get_name(bus), device_get_unit(bus)); -} - -static int -isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - *result = idev->id_port[0]; - break; - case ISA_IVAR_PORT_1: - *result = idev->id_port[1]; - break; - case ISA_IVAR_PORTSIZE_0: - *result = idev->id_portsize[0]; - break; - case ISA_IVAR_PORTSIZE_1: - *result = idev->id_portsize[1]; - break; - case ISA_IVAR_MADDR_0: - *result = idev->id_maddr[0]; - break; - case ISA_IVAR_MADDR_1: - *result = idev->id_maddr[1]; - break; - case ISA_IVAR_MSIZE_0: - *result = idev->id_msize[0]; - break; - case ISA_IVAR_MSIZE_1: - *result = idev->id_msize[1]; - break; - case ISA_IVAR_IRQ_0: - *result = idev->id_irq[0]; - break; - case ISA_IVAR_IRQ_1: - *result = idev->id_irq[1]; - break; - case ISA_IVAR_DRQ_0: - *result = idev->id_drq[0]; - break; - case ISA_IVAR_DRQ_1: - *result = idev->id_drq[1]; - break; - case ISA_IVAR_FLAGS: - *result = idev->id_flags; - break; - } - return ENOENT; -} - -/* - * XXX -- this interface is pretty much irrelevant in the presence of - * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which - * are defined at this point). - */ -static int -isa_write_ivar(device_t bus, device_t dev, - int index, uintptr_t value) -{ - struct isa_device* idev = DEVTOISA(dev); - - switch (index) { - case ISA_IVAR_PORT_0: - idev->id_port[0] = value; - break; - case ISA_IVAR_PORT_1: - idev->id_port[1] = value; - break; - case ISA_IVAR_PORTSIZE_0: - idev->id_portsize[0] = value; - break; - case ISA_IVAR_PORTSIZE_1: - idev->id_portsize[1] = value; - break; - case ISA_IVAR_MADDR_0: - idev->id_maddr[0] = value; - break; - case ISA_IVAR_MADDR_1: - idev->id_maddr[1] = value; - break; - case ISA_IVAR_MSIZE_0: - idev->id_msize[0] = value; - break; - case ISA_IVAR_MSIZE_1: - idev->id_msize[1] = value; - break; - case ISA_IVAR_IRQ_0: - idev->id_irq[0] = value; - break; - case ISA_IVAR_IRQ_1: - idev->id_irq[1] = value; - break; - case ISA_IVAR_DRQ_0: - idev->id_drq[0] = value; - break; - case ISA_IVAR_DRQ_1: - idev->id_drq[1] = value; - break; - case ISA_IVAR_FLAGS: - idev->id_flags = value; - break; - default: - return (ENOENT); - } - return (0); + isa_wrap_old_drivers(); } /* @@ -333,157 +84,43 @@ isa_write_ivar(device_t bus, device_t dev, * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ -static struct resource * +struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - int isdefault; - struct resource *rv, **rvp = 0; - struct isa_device *id = DEVTOISA(child); - - if (child) { - /* - * If this is our child, then use the isa_device to find - * defaults and to record results. - */ - if (device_get_devclass(device_get_parent(child)) == isa_devclass) - id = DEVTOISA(child); - else - id = NULL; - } else - id = NULL; - isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0); - if (*rid > 1) - return 0; - - switch (type) { - case SYS_RES_IRQ: - if (isdefault && id->id_irq[0] >= 0) { - start = id->id_irq[0]; - end = id->id_irq[0]; - count = 1; - } - if (id) - rvp = &id->id_irqres[*rid]; - break; - - case SYS_RES_DRQ: - if (isdefault && id->id_drq[0] >= 0) { - start = id->id_drq[0]; - end = id->id_drq[0]; - count = 1; - } - if (id) - rvp = &id->id_drqres[*rid]; - break; - - case SYS_RES_MEMORY: - if (isdefault && id->id_maddr[0]) { - start = id->id_maddr[0]; - count = max(count, (u_long)id->id_msize[0]); - end = id->id_maddr[0] + count; - } - if (id) - rvp = &id->id_memres[*rid]; - break; - - case SYS_RES_IOPORT: - if (isdefault && id->id_port[0]) { - start = id->id_port[0]; - count = max(count, (u_long)id->id_portsize[0]); - end = id->id_port[0] + count; - } - if (id) - rvp = &id->id_portres[*rid]; - break; - - default: - return 0; - } - /* - * If the client attempts to reallocate a resource without - * releasing what was there previously, die horribly so that - * he knows how he !@#$ed up. + * Consider adding a resource definition. We allow rid 0-1 for + * irq, drq and memory and rid 0-7 for ports which is sufficient for + * isapnp. */ - if (rvp && *rvp != 0) - panic("%s%d: (%d, %d) not free for %s%d\n", - device_get_name(bus), device_get_unit(bus), - type, *rid, - device_get_name(child), device_get_unit(child)); - - /* - * nexus_alloc_resource had better not change *rid... - */ - rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, - start, end, count, flags); - if (rvp && (*rvp = rv) != 0) { - switch (type) { - case SYS_RES_MEMORY: - id->id_maddr[*rid] = rv->r_start; - id->id_msize[*rid] = count; - break; - case SYS_RES_IOPORT: - id->id_port[*rid] = rv->r_start; - id->id_portsize[*rid] = count; - break; - case SYS_RES_IRQ: - id->id_irq[*rid] = rv->r_start; - break; - case SYS_RES_DRQ: - id->id_drq[*rid] = rv->r_start; - break; + int passthrough = (device_get_parent(child) != bus); + int isdefault = (start == 0UL && end == ~0UL); + struct resource_list *rl; + struct resource_list_entry *rle; + + if (!passthrough && !isdefault) { + rl = device_get_ivars(child); + rle = resource_list_find(rl, type, *rid); + if (!rle) { + if (*rid < 0) + return 0; + if (type != SYS_RES_IOPORT && *rid > 1) + return 0; + if (type == SYS_RES_IOPORT && *rid > 7) + return 0; + resource_list_add(rl, type, *rid, start, end, count); } } - return rv; + + return resource_list_alloc(bus, child, type, rid, + start, end, count, flags); } -static int +int isa_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - int rv; - struct isa_device *id = DEVTOISA(child); - - if (rid > 1) - return EINVAL; - - switch (type) { - case SYS_RES_IRQ: - case SYS_RES_DRQ: - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - break; - default: - return (ENOENT); - } - - rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r); - - if (rv == 0) { - switch (type) { - case SYS_RES_IRQ: - id->id_irqres[rid] = 0; - break; - - case SYS_RES_DRQ: - id->id_drqres[rid] = 0; - break; - - case SYS_RES_MEMORY: - id->id_memres[rid] = 0; - break; - - case SYS_RES_IOPORT: - id->id_portres[rid] = 0; - break; - - default: - return ENOENT; - } - } - - return rv; + return resource_list_release(bus, child, type, rid, r); } /* @@ -492,7 +129,7 @@ isa_release_resource(device_t bus, device_t child, int type, int rid, * to pass the child (the i386 nexus knows about this and is prepared to * deal). */ -static int +int isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, void (*ihand)(void *), void *arg, void **cookiep) { @@ -500,45 +137,9 @@ isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, ihand, arg, cookiep)); } -static int +int isa_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie) { return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); } - -static device_method_t isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, isa_probe), - DEVMETHOD(device_attach, isa_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_add_child, isa_add_child), - DEVMETHOD(bus_print_child, isa_print_child), - DEVMETHOD(bus_read_ivar, isa_read_ivar), - DEVMETHOD(bus_write_ivar, isa_write_ivar), - DEVMETHOD(bus_alloc_resource, isa_alloc_resource), - DEVMETHOD(bus_release_resource, isa_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, isa_setup_intr), - DEVMETHOD(bus_teardown_intr, isa_teardown_intr), - - { 0, 0 } -}; - -static driver_t isa_driver = { - "isa", - isa_methods, - 1, /* no softc */ -}; - -/* - * ISA can be attached to a PCI-ISA bridge or directly to the nexus. - */ -DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); -DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0); diff --git a/sys/i386/isa/isa_compat.c b/sys/i386/isa/isa_compat.c index e1959f6e50b9..2bf53779d0fe 100644 --- a/sys/i386/isa/isa_compat.c +++ b/sys/i386/isa/isa_compat.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isa_compat.c,v 1.8 1999/05/08 18:20:03 peter Exp $ + * $Id: isa_compat.c,v 1.9 1999/05/08 21:59:25 dfr Exp $ */ #include <sys/param.h> @@ -64,9 +64,12 @@ isa_compat_nextid(void) static void isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res) { + device_t parent = device_get_parent(dev); int rid; + u_long start, count; - if (isa_get_port(dev) != -1) { + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_IOPORT, 0, + &start, &count) == 0) { rid = 0; res->ports = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul, 1, @@ -77,7 +80,8 @@ isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res) } else res->ports = 0; - if (isa_get_maddr(dev) != 0) { + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0, + &start, &count) == 0) { rid = 0; res->memory = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0ul, ~0ul, 1, @@ -88,7 +92,8 @@ isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res) } else res->memory = 0; - if (isa_get_drq(dev) != -1) { + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_DRQ, 0, + &start, &count) == 0) { rid = 0; res->drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0ul, ~0ul, 1, @@ -99,7 +104,8 @@ isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res) } else res->drq = 0; - if (isa_get_irq(dev) != -1) { + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_IRQ, 0, + &start, &count) == 0) { rid = 0; res->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, @@ -137,9 +143,11 @@ isa_compat_release_resources(device_t dev, struct isa_compat_resources *res) static int isa_compat_probe(device_t dev) { + device_t parent = device_get_parent(dev); struct isa_device *dvp = device_get_softc(dev); struct isa_compat_resources res; struct old_isa_driver *op; + u_long start, count; bzero(&res, sizeof(res)); /* @@ -148,11 +156,29 @@ isa_compat_probe(device_t dev) op = device_get_driver(dev)->priv; dvp->id_id = isa_compat_nextid(); dvp->id_driver = op->driver; - dvp->id_iobase = isa_get_port(dev); - dvp->id_irq = irqmask(isa_get_irq(dev)); - dvp->id_drq = isa_get_drq(dev); - dvp->id_maddr = (void *)isa_get_maddr(dev); - dvp->id_msize = isa_get_msize(dev); + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_IOPORT, 0, + &start, &count) == 0) + dvp->id_iobase = start; + else + dvp->id_iobase = -1; + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_IRQ, 0, + &start, &count) == 0) + dvp->id_irq = irqmask(start); + else + dvp->id_irq = 0; + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_DRQ, 0, + &start, &count) == 0) + dvp->id_drq = start; + else + dvp->id_drq = -1; + if (ISA_GET_RESOURCE(parent, dev, SYS_RES_MEMORY, + 0, &start, &count) == 0) { + dvp->id_maddr = (void *)start; + dvp->id_msize = count; + } else { + dvp->id_maddr = NULL; + dvp->id_msize = 0; + } dvp->id_unit = device_get_unit(dev); dvp->id_flags = isa_get_flags(dev); dvp->id_enabled = device_is_enabled(dev); /* XXX unused */ @@ -164,6 +190,7 @@ isa_compat_probe(device_t dev) if (dvp->id_driver->probe) { int portsize; void *maddr; + struct isa_device old; isa_compat_alloc_resources(dev, &res); if (res.memory) @@ -171,26 +198,33 @@ isa_compat_probe(device_t dev) else maddr = 0; dvp->id_maddr = maddr; + old = *dvp; portsize = dvp->id_driver->probe(dvp); isa_compat_release_resources(dev, &res); if (portsize != 0) { - if (portsize > 0) - isa_set_portsize(dev, portsize); - if (dvp->id_iobase != isa_get_port(dev)) - isa_set_port(dev, dvp->id_iobase); - if (dvp->id_irq != irqmask(isa_get_irq(dev))) - isa_set_irq(dev, ffs(dvp->id_irq) - 1); - if (dvp->id_drq != isa_get_drq(dev)) - isa_set_drq(dev, dvp->id_drq); - if (dvp->id_maddr != maddr) { + if (portsize > 0 || dvp->id_iobase != old.id_iobase) + ISA_SET_RESOURCE(parent, dev, SYS_RES_IOPORT, + 0, dvp->id_iobase, portsize); + if (dvp->id_irq != old.id_irq) + ISA_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0, + ffs(dvp->id_irq) - 1, 1); + if (dvp->id_drq != old.id_drq) + ISA_SET_RESOURCE(parent, dev, SYS_RES_DRQ, 0, + dvp->id_drq, 1); + if (dvp->id_maddr != old.id_maddr + || dvp->id_msize != old.id_msize) { maddr = dvp->id_maddr; if (maddr != NULL) - isa_set_maddr(dev, kvtop(maddr)); + ISA_SET_RESOURCE(parent, dev, + SYS_RES_MEMORY, + 0, + kvtop(maddr), + dvp->id_msize); else - isa_set_maddr(dev, (int)maddr); + ISA_SET_RESOURCE(parent, dev, + SYS_RES_MEMORY, + 0, 0, 0); } - if (dvp->id_msize != isa_get_msize(dev)) - isa_set_msize(dev, dvp->id_msize); return 0; } } diff --git a/sys/isa/isa_common.c b/sys/isa/isa_common.c new file mode 100644 index 000000000000..2003eeb59352 --- /dev/null +++ b/sys/isa/isa_common.c @@ -0,0 +1,395 @@ +/*- + * Copyright (c) 1999 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +/* + * Modifications for Intel architecture by Garrett A. Wollman. + * Copyright 1998 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Parts of the ISA bus implementation common to all architectures. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <machine/bus.h> +#include <sys/rman.h> + +#include <machine/resource.h> + +#include <isa/isavar.h> +#include <isa/isa_common.h> +#ifdef __alpha__ /* XXX workaround a stupid warning */ +#include <alpha/isa/isavar.h> +#endif + +MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device"); + +static devclass_t isa_devclass; + +/* + * At 'probe' time, we add all the devices which we know about to the + * bus. The generic attach routine will probe and attach them if they + * are alive. + */ +static int +isa_probe(device_t dev) +{ + device_set_desc(dev, "ISA bus"); + isa_init(); /* Allow machdep code to initialise */ + return bus_generic_probe(dev); +} + +extern device_t isa_bus_device; + +static int +isa_attach(device_t dev) +{ + /* + * Arrange for bus_generic_attach(dev) to be called later. + */ + isa_bus_device = dev; + return 0; +} + +/* + * Add a new child with default ivars. + */ +static device_t +isa_add_child(device_t dev, device_t place, const char *name, int unit) +{ + struct isa_device *idev; + + idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); + if (!idev) + return 0; + bzero(idev, sizeof *idev); + + resource_list_init(&idev->id_resources); + idev->id_flags = 0; + + if (place) + return device_add_child_after(dev, place, name, unit, idev); + else + return device_add_child(dev, name, unit, idev); +} + +static void +isa_print_resources(struct resource_list *rl, const char *name, int type, + const char *format) +{ + struct resource_list_entry *rle0 = resource_list_find(rl, type, 0); + struct resource_list_entry *rle1 = resource_list_find(rl, type, 1); + + if (rle0 || rle1) { + printf(" %s ", name); + if (rle0) { + printf(format, rle0->start); + if (rle0->count > 1) { + printf("-"); + printf(format, rle0->start + rle0->count - 1); + } + } + if (rle1) { + if (rle0) + printf(","); + printf(format, rle1->start); + if (rle1->count > 1) { + printf("-"); + printf(format, rle1->start + rle1->count - 1); + } + } + } +} + +static void +isa_print_child(device_t bus, device_t dev) +{ + struct isa_device *idev = DEVTOISA(dev); + struct resource_list *rl = &idev->id_resources; + + if (SLIST_FIRST(rl) || idev->id_flags) + printf(" at"); + + isa_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); + isa_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); + isa_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); + isa_print_resources(rl, "drq", SYS_RES_DRQ, "%ld"); + if (idev->id_flags) + printf(" flags %#x", idev->id_flags); + + printf(" on %s%d", + device_get_name(bus), device_get_unit(bus)); +} + +static int +isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) +{ + struct isa_device* idev = DEVTOISA(dev); + struct resource_list *rl = &idev->id_resources; + struct resource_list_entry *rle; + + switch (index) { + case ISA_IVAR_PORT_0: + rle = resource_list_find(rl, SYS_RES_IOPORT, 0); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_PORT_1: + rle = resource_list_find(rl, SYS_RES_IOPORT, 1); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_PORTSIZE_0: + rle = resource_list_find(rl, SYS_RES_IOPORT, 0); + if (rle) + *result = rle->count; + else + *result = 0; + break; + + case ISA_IVAR_PORTSIZE_1: + rle = resource_list_find(rl, SYS_RES_IOPORT, 1); + if (rle) + *result = rle->count; + else + *result = 0; + break; + + case ISA_IVAR_MADDR_0: + rle = resource_list_find(rl, SYS_RES_MEMORY, 0); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_MADDR_1: + rle = resource_list_find(rl, SYS_RES_MEMORY, 1); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_MSIZE_0: + rle = resource_list_find(rl, SYS_RES_MEMORY, 0); + if (rle) + *result = rle->count; + else + *result = 0; + break; + + case ISA_IVAR_MSIZE_1: + rle = resource_list_find(rl, SYS_RES_MEMORY, 1); + if (rle) + *result = rle->count; + else + *result = 0; + break; + + case ISA_IVAR_IRQ_0: + rle = resource_list_find(rl, SYS_RES_IRQ, 0); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_IRQ_1: + rle = resource_list_find(rl, SYS_RES_IRQ, 1); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_DRQ_0: + rle = resource_list_find(rl, SYS_RES_DRQ, 0); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_DRQ_1: + rle = resource_list_find(rl, SYS_RES_DRQ, 1); + if (rle) + *result = rle->start; + else + *result = -1; + break; + + case ISA_IVAR_FLAGS: + *result = idev->id_flags; + break; + } + return ENOENT; +} + +static int +isa_write_ivar(device_t bus, device_t dev, + int index, uintptr_t value) +{ + struct isa_device* idev = DEVTOISA(dev); + + switch (index) { + case ISA_IVAR_PORT_0: + case ISA_IVAR_PORT_1: + case ISA_IVAR_PORTSIZE_0: + case ISA_IVAR_PORTSIZE_1: + case ISA_IVAR_MADDR_0: + case ISA_IVAR_MADDR_1: + case ISA_IVAR_MSIZE_0: + case ISA_IVAR_MSIZE_1: + case ISA_IVAR_IRQ_0: + case ISA_IVAR_IRQ_1: + case ISA_IVAR_DRQ_0: + case ISA_IVAR_DRQ_1: + return EINVAL; + + case ISA_IVAR_FLAGS: + idev->id_flags = value; + break; + default: + return (ENOENT); + } + return (0); +} + +static int +isa_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct isa_device* idev = DEVTOISA(child); + struct resource_list *rl = &idev->id_resources; + + if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY + && type != SYS_RES_IRQ && type != SYS_RES_DRQ) + return EINVAL; + if (rid < 0 || rid > 1) + return EINVAL; + + resource_list_add(rl, type, rid, start, start + count - 1, count); + + return 0; +} + +static int +isa_get_resource(device_t dev, device_t child, int type, int rid, + u_long *startp, u_long *countp) +{ + struct isa_device* idev = DEVTOISA(child); + struct resource_list *rl = &idev->id_resources; + struct resource_list_entry *rle; + + rle = resource_list_find(rl, type, rid); + if (!rle) + return ENOENT; + + *startp = rle->start; + *countp = rle->count; + + return 0; +} + +static device_method_t isa_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, isa_probe), + DEVMETHOD(device_attach, isa_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_add_child, isa_add_child), + DEVMETHOD(bus_print_child, isa_print_child), + DEVMETHOD(bus_read_ivar, isa_read_ivar), + DEVMETHOD(bus_write_ivar, isa_write_ivar), + DEVMETHOD(bus_alloc_resource, isa_alloc_resource), + DEVMETHOD(bus_release_resource, isa_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, isa_setup_intr), + DEVMETHOD(bus_teardown_intr, isa_teardown_intr), + + /* ISA interface */ + DEVMETHOD(isa_set_resource, isa_set_resource), + DEVMETHOD(isa_get_resource, isa_get_resource), + + { 0, 0 } +}; + +static driver_t isa_driver = { + "isa", + isa_methods, + 1, /* no softc */ +}; + +/* + * ISA can be attached to a PCI-ISA bridge or directly to the nexus. + */ +DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); +#ifdef __i386__ +DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0); +#endif diff --git a/sys/isa/isa_common.h b/sys/isa/isa_common.h new file mode 100644 index 000000000000..cb9f26c3ed75 --- /dev/null +++ b/sys/isa/isa_common.h @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 1999 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +/* + * Parts of the ISA bus implementation common to all architectures. + * + * Drivers must not depend on information in this file as it can change + * without notice. + */ + +MALLOC_DECLARE(M_ISADEV); + +/* + * The structure used to attach devices to the isa bus. + */ +struct isa_device { + struct resource_list id_resources; + int id_flags; +}; + +#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev)) + +/* + * These functions are architecture dependant. + */ +extern void isa_init(void); +extern struct resource *isa_alloc_resource(device_t bus, device_t child, + int type, int *rid, + u_long start, u_long end, + u_long count, u_int flags); +extern int isa_release_resource(device_t bus, device_t child, + int type, int rid, + struct resource *r); + +/* XXX alphe declares these elsewhere */ +#ifndef __alpha__ +extern int isa_setup_intr(device_t bus, device_t child, + struct resource *r, int flags, + void (*ihand)(void *), void *arg, void **cookiep); +extern int isa_teardown_intr(device_t bus, device_t child, + struct resource *r, void *cookie); +#endif + diff --git a/sys/isa/isa_if.m b/sys/isa/isa_if.m new file mode 100644 index 000000000000..32a54d799866 --- /dev/null +++ b/sys/isa/isa_if.m @@ -0,0 +1,55 @@ +# +# Copyright (c) 1999 Doug Rabson +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $Id: pci_if.m,v 1.1 1999/04/16 21:22:52 peter Exp $ +# + +INTERFACE isa; + +# +# Set the range used for a particular resource. Return EINVAL if +# the type or rid are out of range. +# +METHOD int set_resource { + device_t dev; + device_t child; + int type; + int rid; + u_long start; + u_long count; +}; + +# +# Get the range for a resource. Return ENOENT if the type or rid are +# out of range or have not been set. +# +METHOD int get_resource { + device_t dev; + device_t child; + int type; + int rid; + u_long *startp; + u_long *countp; +}; diff --git a/sys/isa/isahint.c b/sys/isa/isahint.c index 80101959eff1..c3dff33635a3 100644 --- a/sys/isa/isahint.c +++ b/sys/isa/isahint.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: isahint.c,v 1.1 1999/05/14 11:22:33 dfr Exp $ */ #include <sys/param.h> @@ -32,12 +32,13 @@ #include <sys/bus.h> #include <sys/module.h> #include <isa/isavar.h> +#include <machine/resource.h> static void isahint_add_device(device_t parent, const char *name, int unit) { device_t child; - int sensitive, t; + int sensitive, start, count, t; static device_t last_sensitive; /* device-specific flag overrides any wildcard */ @@ -54,27 +55,29 @@ isahint_add_device(device_t parent, const char *name, int unit) else if (sensitive) last_sensitive = child; - if (resource_int_value(name, unit, "port", &t) == 0) - isa_set_port(child, t); + start = 0; + count = 0; + if (resource_int_value(name, unit, "port", &start) == 0 + || resource_int_value(name, unit, "portsize", &count) == 0) + ISA_SET_RESOURCE(parent, child, SYS_RES_IOPORT, 0, + start, count); - if (resource_int_value(name, unit, "portsize", &t) == 0) - isa_set_portsize(child, t); + start = 0; + count = 0; + if (resource_int_value(name, unit, "maddr", &start) == 0 + || resource_int_value(name, unit, "msize", &count) == 0) + ISA_SET_RESOURCE(parent, child, SYS_RES_MEMORY, 0, + start, count); - if (resource_int_value(name, unit, "maddr", &t) == 0) - isa_set_maddr(child, t); + if (resource_int_value(name, unit, "irq", &start) == 0) + ISA_SET_RESOURCE(parent, child, SYS_RES_IRQ, 0, start, 1); - if (resource_int_value(name, unit, "msize", &t) == 0) - isa_set_msize(child, t); + if (resource_int_value(name, unit, "drq", &start) == 0) + ISA_SET_RESOURCE(parent, child, SYS_RES_DRQ, 0, start, 1); if (resource_int_value(name, unit, "flags", &t) == 0) isa_set_flags(child, t); - if (resource_int_value(name, unit, "irq", &t) == 0) - isa_set_irq(child, t); - - if (resource_int_value(name, unit, "drq", &t) == 0) - isa_set_drq(child, t); - if (resource_int_value(name, unit, "disabled", &t) == 0 && t != 0) device_disable(child); } diff --git a/sys/isa/isavar.h b/sys/isa/isavar.h index a20f66de54d6..b8a3a9d998b9 100644 --- a/sys/isa/isavar.h +++ b/sys/isa/isavar.h @@ -23,9 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isavar.h,v 1.5 1999/05/08 18:11:04 peter Exp $ + * $Id: isavar.h,v 1.6 1999/05/14 11:22:35 dfr Exp $ */ +#include "isa_if.h" + #define ISA_NPORT_IVARS 2 #define ISA_NMEM_IVARS 2 #define ISA_NIRQ_IVARS 2 @@ -84,4 +86,3 @@ ISA_ACCESSOR(drq, DRQ, int) ISA_ACCESSOR(maddr, MADDR, int) ISA_ACCESSOR(msize, MSIZE, int) ISA_ACCESSOR(flags, FLAGS, int) - |