summaryrefslogtreecommitdiffstats
path: root/sys/pccard
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-08-25 06:40:00 +0000
committerimp <imp@FreeBSD.org>2001-08-25 06:40:00 +0000
commit5cdc9f7c0cba2cd3c66acbe372a1a6d33d4141cc (patch)
treeda052b3c37466ef4014af289c47c0ef2932bce88 /sys/pccard
parente0dbc46fb066671b526f2bfe05114aaae8540f57 (diff)
downloadFreeBSD-src-5cdc9f7c0cba2cd3c66acbe372a1a6d33d4141cc.zip
FreeBSD-src-5cdc9f7c0cba2cd3c66acbe372a1a6d33d4141cc.tar.gz
First cut at getting the ISA routing working. If we can't route a PCI
interrupt for the CSC interrupt, then we revert to ISA. If we didn't have an interrupt set up with hw.pcic.irq, then do polling. Also, don't complain about ignoring function 1 for any devices except pcic devices. This would normally only show up if someone set hw.pcic.ignore_function_1=1. MFC: as soon as I can test it on some troublesome laptops.
Diffstat (limited to 'sys/pccard')
-rw-r--r--sys/pccard/pcic_pci.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/sys/pccard/pcic_pci.c b/sys/pccard/pcic_pci.c
index 9c4c891..51539ea 100644
--- a/sys/pccard/pcic_pci.c
+++ b/sys/pccard/pcic_pci.c
@@ -615,14 +615,14 @@ pcic_pci_probe(device_t dev)
struct resource *res;
int rid;
- if (pcic_ignore_function_1 && pci_get_function(dev) == 1) {
- PRVERB((dev, "Ignoring function 1\n"));
- return (ENXIO);
- }
-
device_id = pci_get_devid(dev);
desc = NULL;
itm = pcic_pci_lookup(device_id, &pcic_pci_devs[0]);
+ if (pcic_ignore_function_1 && pci_get_function(dev) == 1) {
+ if (itm != NULL)
+ PRVERB((dev, "Ignoring function 1\n"));
+ return (ENXIO);
+ }
if (itm != NULL)
desc = itm->descr;
if (desc == NULL && pci_get_class(dev) == PCIC_BRIDGE) {
@@ -637,7 +637,6 @@ pcic_pci_probe(device_t dev)
return (ENXIO);
device_set_desc(dev, desc);
-#if __FreeBSD_version >= 430002
/*
* Take us out of power down mode.
*/
@@ -647,7 +646,6 @@ pcic_pci_probe(device_t dev)
"-- setting to D0\n", pci_get_powerstate(dev));
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
}
-#endif
/*
* Allocated/deallocate interrupt. This forces the PCI BIOS or
@@ -716,10 +714,10 @@ pcic_pci_attach(device_t dev)
u_int32_t sockbase;
struct pcic_pci_table *itm;
int rid;
- struct resource *r;
+ struct resource *r = NULL;
int error;
- u_long start;
- u_long end;
+ u_long irq;
+ driver_intr_t *intr = NULL;
/*
* In sys/pci/pcireg.h, PCIR_COMMAND must be separated
@@ -773,39 +771,67 @@ pcic_pci_attach(device_t dev)
sc->flags = PCIC_DF_POWER;
}
}
- sp->slt = (struct slot *) 1;
sc->dev = dev;
sc->csc_route = pcic_intr_path;
sc->func_route = pcic_intr_path;
+ sp->slt = (struct slot *) 1;
+ if (sc->csc_route == pcic_iw_pci) {
+ rid = 0;
+ r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_ACTIVE | RF_SHAREABLE);
+ if (r == NULL) {
+ sc->csc_route = pcic_iw_isa;
+ sc->csc_route = pcic_iw_isa;
+ device_printf(dev,
+ "No PCI interrupt routed, trying ISA.\n");
+ }
+ intr = pcic_pci_intr;
+ }
+ if (sc->csc_route == pcic_iw_isa) {
+ rid = 0;
+ irq = pcic_override_irq;
+ if (irq != 0) {
+ r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq,
+ irq, 1, RF_ACTIVE);
+ if (r == NULL) {
+ device_printf(dev,
+ "Can't route ISA CSC interrupt.\n");
+ pcic_dealloc(dev);
+ return (ENXIO);
+ }
+ intr = pcic_isa_intr;
+ } else {
+ sc->slot_poll = pcic_timeout;
+ sc->timeout_ch = timeout(sc->slot_poll, (void *) sc,
+ hz/2);
+ device_printf(dev, "Polling mode\n");
+ intr = NULL;
+ }
+ }
+
+ /*
+ * Initialize AFTER we figure out what kind of interrupt we're
+ * going to be using, if any.
+ */
if (itm && itm->init)
itm->init(dev);
else
pcic_pci_cardbus_init(dev);
- if (sc->csc_route == pcic_iw_pci) {
- start = 0;
- end = ~0;
- } else {
- start = pcic_override_irq;
- end = pcic_override_irq;
- }
- rid = 0;
- r = NULL;
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, start, end, 1,
- RF_ACTIVE | RF_SHAREABLE);
- if (r == NULL) {
- device_printf(dev, "Failed to allocate managment irq\n");
- return (EIO);
- }
+ /*
+ * Now install the interrupt handler, if necessary.
+ */
sc->irqrid = rid;
sc->irqres = r;
sc->irq = rman_get_start(r);
- error = bus_setup_intr(dev, r, INTR_TYPE_AV, pcic_pci_intr,
- (void *) sc, &sc->ih);
- if (error) {
- pcic_dealloc(dev);
- return (error);
+ if (intr) {
+ error = bus_setup_intr(dev, r, INTR_TYPE_AV, intr,
+ (void *) sc, &sc->ih);
+ if (error) {
+ pcic_dealloc(dev);
+ return (error);
+ }
}
return (pcic_attach(dev));
OpenPOWER on IntegriCloud