summaryrefslogtreecommitdiff
path: root/sys/dev/pcic
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2000-01-03 06:45:16 +0000
committerWarner Losh <imp@FreeBSD.org>2000-01-03 06:45:16 +0000
commitfe98624bbbe09125f4467ea5b13884429395c4c3 (patch)
tree66dcc17aa812ae983684e9a553b30840e87b3f7f /sys/dev/pcic
parent2fdb1532b41d2c56d017dbbcac54ba19c9ee6424 (diff)
Notes
Diffstat (limited to 'sys/dev/pcic')
-rw-r--r--sys/dev/pcic/i82365.c145
-rw-r--r--sys/dev/pcic/i82365_isa.c112
-rw-r--r--sys/dev/pcic/i82365var.h20
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);