diff options
| author | Warner Losh <imp@FreeBSD.org> | 2000-01-03 06:45:16 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2000-01-03 06:45:16 +0000 |
| commit | fe98624bbbe09125f4467ea5b13884429395c4c3 (patch) | |
| tree | 66dcc17aa812ae983684e9a553b30840e87b3f7f /sys/dev/pcic | |
| parent | 2fdb1532b41d2c56d017dbbcac54ba19c9ee6424 (diff) | |
Notes
Diffstat (limited to 'sys/dev/pcic')
| -rw-r--r-- | sys/dev/pcic/i82365.c | 145 | ||||
| -rw-r--r-- | sys/dev/pcic/i82365_isa.c | 112 | ||||
| -rw-r--r-- | sys/dev/pcic/i82365var.h | 20 |
3 files changed, 193 insertions, 84 deletions
diff --git a/sys/dev/pcic/i82365.c b/sys/dev/pcic/i82365.c index 4bb534a9fae2..74c774267ff5 100644 --- a/sys/dev/pcic/i82365.c +++ b/sys/dev/pcic/i82365.c @@ -62,6 +62,8 @@ int pcic_debug = 0; #else #define DPRINTF(arg) #endif +/* To later turn into debug */ +#define DEVPRINTF(arg) device_printf arg; #define DETACH_FORCE 0x1 @@ -80,11 +82,15 @@ int pcic_debug = 0; static void pcic_init_socket(struct pcic_handle *); -int pcic_intr_socket(struct pcic_handle *); +static void pcic_intr_socket(struct pcic_handle *); -void pcic_attach_card(struct pcic_handle *); -void pcic_detach_card(struct pcic_handle *, int); -void pcic_deactivate_card(struct pcic_handle *); +static void pcic_deactivate(device_t dev); +static int pcic_activate(device_t dev); +static void pcic_intr(void *arg); + +void pcic_attach_card(struct pcic_handle *); +void pcic_detach_card(struct pcic_handle *, int); +void pcic_deactivate_card(struct pcic_handle *); static void pcic_chip_do_mem_map(struct pcic_handle *, int); static void pcic_chip_do_io_map(struct pcic_handle *, int); @@ -172,21 +178,104 @@ pcic_vendor_to_string(int vendor) return ("Unknown controller"); } -void +static int +pcic_activate(device_t dev) +{ + struct pcic_softc *sc = (struct pcic_softc *) + device_get_softc(dev); + int err; + + sc->port_rid = 0; + sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, + 0, ~0, PCIC_IOSIZE, RF_ACTIVE); + if (!sc->port_res) { +#ifdef PCIC_DEBUG + device_printf(dev, "Cannot allocate ioport\n"); +#endif + return ENOMEM; + } + + sc->irq_rid = 0; + sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, + 0, ~0, 1, RF_ACTIVE); + if (!sc->irq_res) { +#ifdef PCIC_DEBUG + device_printf(dev, "Cannot allocate irq\n"); +#endif + pcic_deactivate(dev); + return ENOMEM; + } + sc->irq = rman_get_start(sc->irq_res); + if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, pcic_intr, + sc, &sc->intrhand)) != 0) { + pcic_deactivate(dev); + return err; + } + + sc->mem_rid = 0; + sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, + 0, ~0, 1 << 13, RF_ACTIVE); + if (!sc->mem_res) { +#ifdef PCIC_DEBUG + device_printf(dev, "Cannot allocate mem\n"); +#endif + pcic_deactivate(dev); + return ENOMEM; + } + sc->subregionmask = (1 << + ((rman_get_end(sc->mem_res) - rman_get_start(sc->mem_res) + 1) / + PCIC_MEM_PAGESIZE)) - 1; + + sc->iot = rman_get_bustag(sc->port_res); + sc->ioh = rman_get_bushandle(sc->port_res);; + sc->memt = rman_get_bustag(sc->mem_res); + sc->memh = rman_get_bushandle(sc->mem_res);; + + return (0); +} + +static void +pcic_deactivate(device_t dev) +{ + struct pcic_softc *sc = device_get_softc(dev); + + if (sc->intrhand) + bus_teardown_intr(dev, sc->irq_res, sc->intrhand); + sc->intrhand = 0; + if (sc->port_res) + bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, + sc->port_res); + sc->port_res = 0; + if (sc->irq_res) + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, + sc->irq_res); + sc->irq_res = 0; + if (sc->mem_res) + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, + sc->mem_res); + sc->mem_res = 0; + return; +} + +int pcic_attach(device_t dev) { struct pcic_softc *sc = (struct pcic_softc *) device_get_softc(dev); struct pcic_handle *h; - int vendor, count, i, reg; + int vendor, count, i, reg, error; sc->dev = dev; + /* Activate our resources */ + if ((error = pcic_activate(dev)) != 0) + return error; + /* now check for each controller/socket */ /* * this could be done with a loop, but it would violate the - * abstraction + * abstraction... so? --imp */ count = 0; @@ -349,6 +438,14 @@ pcic_attach(device_t dev) device_set_ivars(h->dev, h); pcic_init_socket(h); } + + /* + * Probe and attach any children as were configured above. + */ + error = bus_generic_attach(dev); + if (error) + pcic_deactivate(dev); + return error; } void @@ -512,22 +609,20 @@ pcic_init_socket(struct pcic_handle *h) } } -int +static void pcic_intr(void *arg) { struct pcic_softc *sc = arg; - int i, ret = 0; + int i; - DPRINTF(("%s: intr\n", sc->dev.dv_xname)); + DEVPRINTF((sc->dev, "intr\n")); for (i = 0; i < PCIC_NSLOTS; i++) if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) - ret += pcic_intr_socket(&sc->handle[i]); - - return (ret ? 1 : 0); + pcic_intr_socket(&sc->handle[i]); } -int +static void pcic_intr_socket(struct pcic_handle *h) { int cscreg; @@ -581,7 +676,6 @@ pcic_intr_socket(struct pcic_handle *h) if (cscreg & PCIC_CSC_BATTDEAD) { DPRINTF(("%s: %02x BATTDEAD\n", h->ph_parent->dv_xname, h->sock)); } - return (cscreg ? 1 : 0); } void @@ -1377,6 +1471,27 @@ pcic_release_resource(device_t dev, device_t child, int type, int rid, return bus_generic_release_resource(dev, child, type, rid, r); } +int +pcic_suspend(device_t dev) +{ + /* + * Do nothing for now, maybe in time do what FreeBSD's current + * pccard code does and detach my children. That's the safest thing + * to do since we don't want to wake up and have different hardware + * in the slots. + */ + + return 0; +} + +int +pcic_resume(device_t dev) +{ + /* Need to port pcic_power from newer netbsd versions of this file */ + + return 0; +} + static void pcic_start_threads(void *arg) { diff --git a/sys/dev/pcic/i82365_isa.c b/sys/dev/pcic/i82365_isa.c index 1360c93b9f13..c390be1e708e 100644 --- a/sys/dev/pcic/i82365_isa.c +++ b/sys/dev/pcic/i82365_isa.c @@ -225,7 +225,7 @@ pcic_isa_bus_width_probe (device_t dev) } static int -pcic_isa_probe(device_t dev) +pcic_isa_check(device_t dev, u_int16_t addr) { bus_space_tag_t iot; bus_space_handle_t ioh; @@ -233,13 +233,9 @@ pcic_isa_probe(device_t dev) int rid; struct resource *res; - /* Check isapnp ids */ - if (ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids) == ENXIO) - return (ENXIO); - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, PCIC_IOSIZE, - RF_ACTIVE); + res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, addr, addr, + PCIC_IOSIZE, RF_ACTIVE); if (!res) return(ENXIO); iot = rman_get_bustag(res); @@ -272,67 +268,65 @@ pcic_isa_probe(device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - /* XXX DO I NEED TO WORRY ABOUT the IRQ? XXX */ + return (found); +} - if (!found) - return (ENXIO); +static void +pcic_isa_identify(driver_t *driver, device_t parent) +{ + device_t child; + u_int16_t ioaddrs[] = { 0x3e0, 0x3e2, 0x3e4, 0x3e6, 0 }; + u_int16_t ioaddr; + int i; - return (0); + for (i = 0; ioaddrs[i]; i++) { + ioaddr = ioaddrs[i]; + if (pcic_isa_check(parent, ioaddr)) { + child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, + "pcic", -1); + device_set_driver(child, driver); +/* XXX */ + bus_set_resource(child, SYS_RES_IRQ, 0, 10, 1); + bus_set_resource(child, SYS_RES_MEMORY, 0, 0xd0000, 1 << 12); + bus_set_resource(child, SYS_RES_IOPORT, 0, ioaddr, + PCIC_IOSIZE); + } + } } static int -pcic_isa_attach(device_t dev) +pcic_isa_probe(device_t dev) { - struct pcic_softc *sc = (struct pcic_softc *) device_get_softc(dev); + int error; - sc->port_rid = 0; - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, - 0, ~0, PCIC_IOSIZE, RF_ACTIVE); - if (!sc->port_res) { - device_printf(dev, "Unable to allocate I/O ports\n"); - goto error; - } - - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1 << 13, RF_ACTIVE); - if (!sc->mem_res) { - device_printf(dev, "Unable to allocate memory range\n"); - goto error; + /* Check isapnp ids */ + error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); + if (error == ENXIO) + return (ENXIO); + + /* If we had some other problem. */ + if (!(error == 0 || error == ENOENT)) { + return (error); } - - sc->subregionmask = (1 << - ((rman_get_end(sc->mem_res) - rman_get_start(sc->mem_res) + 1) / - PCIC_MEM_PAGESIZE)) - 1; - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, - 0, ~0, 1, RF_ACTIVE); - if (!sc->irq_res) { - device_printf(dev, "Unable to allocate irq\n"); - goto error; + /* If we have the resources we need then we're good to go. */ + if ((bus_get_resource_start(dev, SYS_RES_IOPORT, 0) != 0) && + (bus_get_resource_start(dev, SYS_RES_IRQ, 0) != 0)) { + return (0); } - - sc->iot = rman_get_bustag(sc->port_res); - sc->ioh = rman_get_bushandle(sc->port_res);; - sc->memt = rman_get_bustag(sc->mem_res); - sc->memh = rman_get_bushandle(sc->mem_res);; - pcic_attach(dev); - pcic_isa_bus_width_probe (dev); + return (ENXIO); +} - return 0; - error: - if (sc->port_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, - sc->port_res); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, - sc->mem_res); - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, - sc->irq_res); - return ENOMEM; +static int +pcic_isa_attach(device_t dev) +{ + int err = 0; + + if ((err = pcic_attach(dev)) == 0) + pcic_isa_bus_width_probe (dev); + + return err; } static int @@ -343,15 +337,17 @@ pcic_isa_detach(device_t dev) static device_method_t pcic_isa_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, pcic_isa_identify), DEVMETHOD(device_probe, pcic_isa_probe), DEVMETHOD(device_attach, pcic_isa_attach), DEVMETHOD(device_detach, pcic_isa_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_suspend, pcic_suspend), + DEVMETHOD(device_resume, pcic_resume), /* Bus Interface */ DEVMETHOD(bus_driver_added, bus_generic_driver_added), + DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_alloc_resource, pcic_alloc_resource), DEVMETHOD(bus_release_resource, pcic_release_resource), DEVMETHOD(bus_activate_resource, pcic_activate_resource), diff --git a/sys/dev/pcic/i82365var.h b/sys/dev/pcic/i82365var.h index 01b501026011..e6d0f7eebb01 100644 --- a/sys/dev/pcic/i82365var.h +++ b/sys/dev/pcic/i82365var.h @@ -101,16 +101,13 @@ struct pcic_softc { bus_space_tag_t iot; bus_space_handle_t ioh; - struct resource *port_res; - int port_rid; - struct resource *mem_res; - int mem_rid; + void *intrhand; struct resource *irq_res; - int irq_rid; - - - /* XXX isa_chipset_tag_t, pci_chipset_tag_t, etc. */ - void *intr_est; + int irq_rid; + struct resource *mem_res; + int mem_rid; + struct resource *port_res; + int port_rid; /* this needs to be large enough to hold PCIC_MEM_PAGES bits */ int subregionmask; @@ -140,8 +137,7 @@ int pcic_ident_ok(int); int pcic_vendor(struct pcic_handle *); char *pcic_vendor_to_string(int); -void pcic_attach(device_t dev); -int pcic_intr(void *arg); +int pcic_attach(device_t dev); #if 0 @@ -193,3 +189,5 @@ int pcic_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_intr_t intr, void *arg, void **cookiep); int pcic_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookiep); +int pcic_suspend(device_t dev); +int pcic_resume(device_t dev); |
