diff options
author | Warner Losh <imp@FreeBSD.org> | 2001-08-25 06:40:00 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2001-08-25 06:40:00 +0000 |
commit | 0b370908b2a4add159cc73842e41d0f4c57329b3 (patch) | |
tree | da052b3c37466ef4014af289c47c0ef2932bce88 /sys/pccard | |
parent | 3516c025ffced17aa5f2ec87f7d03b29af4ed256 (diff) | |
download | src-0b370908b2a4add159cc73842e41d0f4c57329b3.tar.gz src-0b370908b2a4add159cc73842e41d0f4c57329b3.zip |
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.
Notes
Notes:
svn path=/head/; revision=82316
Diffstat (limited to 'sys/pccard')
-rw-r--r-- | sys/pccard/pcic_pci.c | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/sys/pccard/pcic_pci.c b/sys/pccard/pcic_pci.c index 9c4c891a4d22..51539ea3a147 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)); |