aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pccbb/pccbb.c
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2002-02-10 03:28:37 +0000
committerWarner Losh <imp@FreeBSD.org>2002-02-10 03:28:37 +0000
commitcebd67fba367d9c947719229241919d62c97cfed (patch)
treeab763821be98153b42376e0318ccd1c8710a422b /sys/dev/pccbb/pccbb.c
parentd63e76cc218ee426a046143d10d4fdebe7dbc0ca (diff)
downloadsrc-cebd67fba367d9c947719229241919d62c97cfed.tar.gz
src-cebd67fba367d9c947719229241919d62c97cfed.zip
o Use INTR_TYPE_AV (the highest possible) rather than INTR_TYPE_BIO
o Don't allow INTR_TYPE_FAST. Since we are sharing the interrupt between CSC and the functions, they can't be FAST because fast interrupts can't be shared. o Add the same workaround for resume that we have in OLDCARD. o Also, return the error from bus_generic_resume rather than ignoring it.
Notes
Notes: svn path=/head/; revision=90444
Diffstat (limited to 'sys/dev/pccbb/pccbb.c')
-rw-r--r--sys/dev/pccbb/pccbb.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c
index 0cf27750a27f..12d444c4f7ce 100644
--- a/sys/dev/pccbb/pccbb.c
+++ b/sys/dev/pccbb/pccbb.c
@@ -547,8 +547,7 @@ pccbb_attach(device_t brdev)
return (ENOMEM);
}
- /* XXX INTR_TYPE_BIO IS WRONG here */
- if (bus_setup_intr(brdev, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc,
+ if (bus_setup_intr(brdev, sc->sc_irq_res, INTR_TYPE_AV, pccbb_intr, sc,
&sc->sc_intrhand)) {
device_printf(brdev, "couldn't establish interrupt");
bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->sc_irq_res);
@@ -653,6 +652,38 @@ pccbb_shutdown(device_t brdev)
return (0);
}
+static int
+pccbb_setup_intr(device_t dev, device_t child, struct resource *irq,
+ int flags, driver_intr_t *intr, void *arg, void **cookiep)
+{
+ int err;
+
+ /*
+ * You aren't allowed to have fast interrupts for pccard/cardbus
+ * things since those interrupts are PCI and shared. Since we use
+ * the PCI interrupt for the status change interrupts, it can't be
+ * free for use by the driver. Fast interrupts must not be shared.
+ */
+ if ((flags & INTR_FAST) != 0)
+ return (EINVAL);
+ err = bus_generic_setup_intr(dev, child, irq, flags, intr, arg,
+ cookiep);
+ /*
+ * XXX need to turn on ISA interrupts, if we ever support them, but
+ * XXX for now that's all we need to do.
+ */
+ return (err);
+}
+
+static int
+pccbb_teardown_intr(device_t dev, device_t child, struct resource *irq,
+ void *cookie)
+{
+ /* XXX Need to do different things for ISA interrupts. */
+ return (bus_generic_teardown_intr(dev, child, irq, cookie));
+}
+
+
static void
pccbb_driver_added(device_t brdev, driver_t *driver)
{
@@ -1721,8 +1752,7 @@ pccbb_resume(device_t self)
pccbb_set(sc, PCCBB_SOCKET_EVENT, tmp);
/* re-establish the interrupt. */
- /* XXX INTR_TYPE_BIOS IS WRONG here */
- if (bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc,
+ if (bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_AV, pccbb_intr, sc,
&sc->sc_intrhand)) {
device_printf(self, "couldn't re-establish interrupt");
bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
@@ -1731,7 +1761,21 @@ pccbb_resume(device_t self)
mtx_destroy(&sc->sc_mtx);
error = ENOMEM;
}
- bus_generic_resume(self);
+
+ /*
+ * Some BIOSes will not save the BARs for the pci chips, so we
+ * must do it ourselves. If the BAR is reset to 0 for an I/O
+ * device, it will read back as 0x1, so no explicit test for
+ * memory devices are needed.
+ *
+ * Note: The PCI bus code should do this automatically for us on
+ * suspend/resume, but until it does, we have to cope.
+ */
+ if (pci_read_config(self, PCCBBR_SOCKBASE, 4) == 0)
+ pci_write_config(self, PCCBBR_SOCKBASE,
+ rman_get_start(sc->sc_base_res), 4);
+
+ error = bus_generic_resume(self);
/* wakeup thread */
if (!error) {
@@ -1761,8 +1805,8 @@ static device_method_t pccbb_methods[] = {
DEVMETHOD(bus_deactivate_resource, pccbb_deactivate_resource),
DEVMETHOD(bus_driver_added, pccbb_driver_added),
DEVMETHOD(bus_child_detached, pccbb_child_detached),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_setup_intr, pccbb_setup_intr),
+ DEVMETHOD(bus_teardown_intr, pccbb_teardown_intr),
/* 16-bit card interface */
DEVMETHOD(card_set_res_flags, pccbb_pcic_set_res_flags),