Date: Sat, 7 Sep 2002 13:34:10 +0100 From: Bruce M Simpson <bms@spc.org> To: "M. Warner Losh" <imp@bsdimp.com> Cc: freebsd-hackers@FreeBSD.ORG Subject: OLDCARD function interrupt routing -- patch. Message-ID: <20020907123409.GQ15218@spc.org> In-Reply-To: <20020906.235110.108188889.imp@bsdimp.com> References: <20020905191546.GF15218@spc.org> <20020905.145936.39157187.imp@bsdimp.com> <20020906093215.GI15218@spc.org> <20020906.235110.108188889.imp@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--rS8CxjVDS/+yyDmU Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Warner, Thanks again for making all of that much more clear. Since I originally composed this mail I've hacked out a patch to OLDCARD to bit-bang the registers on the 5C475E. I also mapped out which IRQs were actually in use and which were not; and manually changed the 'irq' entry in /etc/pccard.conf to reflect this. It looks as though being able to flip function routing separately from CSC routing is what does the trick, correct me if I'm wrong; things have suddenly decided to work. pccard0: Assigning gpr400: io 0x300-0x31f irq 3 mem 0xd4000-0xd4fff - I've tested with a CDROM drive and a CF card, as well as a ZoomAir wireless card. The offending GPR400 card gets its irq from pccardd just fine now. Aside from some PRISM2 bitching when placed into monitor mode (sometimes to be expected), everything seems to be fine. - I've placed the datasheet online in case anyone needs to grab it for reference: http://www.incunabulum.com/tmp/5C475E.pdf - Please see patch (and whine) attached. If I'm barking up the wrong tree totally, comments would be appreciated. Thanks! Now I'll tackle that nasty driver. BMS --rS8CxjVDS/+yyDmU Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pccard-func-isa-routing.patch" diff -uNr pccard.orig/i82365.h pccard/i82365.h --- pccard.orig/i82365.h Wed Jul 31 21:01:10 2002 +++ pccard/i82365.h Sat Sep 7 03:32:48 2002 @@ -146,6 +146,7 @@ #define PCIC_IOCARD 0x20 #define PCIC_MEMCARD 0x00 #define PCIC_INTR_ENA 0x10 /* PCI CSC Interrupt enable */ +#define PCIC_INTR_MASK 0x0F /* Ricoh: Mask for routed ISA IRQ */ /* For the Card Status Change register (PCIC_STAT_CHG) */ #define PCIC_CDTCH 0x08 /* Card Detect Change */ diff -uNr pccard.orig/pcic_pci.c pccard/pcic_pci.c --- pccard.orig/pcic_pci.c Wed Jul 31 21:01:11 2002 +++ pccard/pcic_pci.c Sat Sep 7 13:50:48 2002 @@ -73,10 +73,20 @@ * routing doesn't work. It is purposely vague and undocumented * at the moment. Sadly, this seems to be needed way too often. */ -static int pcic_intr_path = (int)pcic_iw_pci; -TUNABLE_INT("hw.pcic.intr_path", &pcic_intr_path); -SYSCTL_INT(_hw_pcic, OID_AUTO, intr_path, CTLFLAG_RD, &pcic_intr_path, 0, - "Which path to send the interrupts over."); +static int pcic_csc_intr_path = (int)pcic_iw_pci; +TUNABLE_INT("hw.pcic.csc_intr_path", &pcic_csc_intr_path); /* XXX */ +SYSCTL_INT(_hw_pcic, OID_AUTO, csc_intr_path, CTLFLAG_RD, +&pcic_csc_intr_path, 0, "Which path to send card services interrupts over."); + +static int pcic_func_intr_path = (int)pcic_iw_pci; +TUNABLE_INT("hw.pcic.func_intr_path", &pcic_func_intr_path); +SYSCTL_INT(_hw_pcic, OID_AUTO, func_intr_path, CTLFLAG_RD, +&pcic_func_intr_path, 0, "Which path to send function interrupts over."); + +static int pcic_func_irq = 0; +TUNABLE_INT("hw.pcic.func_irq", &pcic_func_irq); +SYSCTL_INT(_hw_pcic, OID_AUTO, func_irq, CTLFLAG_RD, +&pcic_func_irq, 0, "Override IRQ for routing of function interrupt via ISA. "); static int pcic_init_routing = 0; TUNABLE_INT("hw.pcic.init_routing", &pcic_init_routing); @@ -575,8 +585,19 @@ static void pcic_pci_ricoh_init(device_t dev) { - u_int16_t brgcntl; - u_int32_t device_id = pci_get_devid(dev); +#if defined(PCIC_ISA_FUNC_ROUTING) + struct pcic_softc *sc; + struct pcic_slot *sp; + struct resource *res; + u_int16_t intgen; +#endif + u_int16_t brgcntl; + u_int32_t device_id = pci_get_devid(dev); + +#if defined(PCIC_ISA_FUNC_ROUTING) + sc = (struct pcic_softc *) device_get_softc(dev); + sp = &sc->slots[0]; +#endif switch (device_id) { case PCI_DEVICE_ID_RICOH_RL5C465: @@ -592,6 +613,38 @@ break; } pcic_pci_cardbus_init(dev); + +#if defined(PCIC_ISA_FUNC_ROUTING) + /* + * Force ISA interrupt routing for the function interrupt, + * and not the CSC interrupt. + */ + if ((sc->func_route == pcic_iw_isa) && pcic_func_irq != 0) { + int rid; + + /* Allocate the ISA function IRQ. This never gets freed. */ + res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + pcic_func_irq, pcic_func_irq, 1, RF_ACTIVE); + if (!res) + panic("Could not allocate ISA function IRQ!\N"); + + device_printf(dev, "using ISA function irq %d\n", + pcic_func_irq); + + pcic_pci_gen_func(sp, pcic_iw_isa); + intgen = sp->getb(sp, PCIC_INT_GEN); + intgen &= ~(PCIC_INTR_MASK); + intgen |= pcic_func_irq; + sp->putb(sp, PCIC_INT_GEN, intgen); + + /* + * XXX: Blindly catch any interrupts which might have been + * generated as a result of writing to PCIC_INT_GEN. + */ + bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_EVENT, + 0xffffffff); + } +#endif } /* @@ -1057,7 +1110,7 @@ * for an explaination of ISA vs PCI interrupts. XXX Might be other * special cases as well. */ - if (pcic_intr_path == pcic_iw_pci && + if (pcic_csc_intr_path == pcic_iw_pci && device_id != PCI_DEVICE_ID_PCIC_CLPD6729) { rid = 0; #ifdef __i386__ @@ -1238,8 +1291,8 @@ sc->flags = PCIC_CARDBUS_POWER; } sp->slt = (struct slot *) 1; - sc->csc_route = pcic_intr_path; - sc->func_route = pcic_intr_path; + sc->csc_route = pcic_csc_intr_path; + sc->func_route = pcic_func_intr_path; stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE); sc->cd_present = (stat & CB_SS_CD) == 0; } --rS8CxjVDS/+yyDmU Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="whine.txt" It appears to be academic for the time being, though, as pccardd can't allocate the resources the card needs. On my Sony Vaio, when the ACPI bios is told to configure non-boot devices (Plug and Play OS = NO), it muxes everything onto IRQ 9. This includes the pcic0 device (both for card services, and for function). Unfortunately the device I'm working with doesn't support IRQ 9. Now I see that some good work had been done around the problem of PCI and ISA interrupt routing. When I put the bridge on this system into polling mode, and run pccardd, the box hangs (forcing a break into DDB reveals that other interrupts are still being serviced, but pccardd is hanging). I've been doing my testing from single user with filesystems except /var mounted readonly, /var also has softupdates enabled (4.6-STABLE). I managed to pull the data sheet for the Ricoh 5C475E controller. Apparently setting the CB_BCR_INT_EXCA bit on this variant allows the IREQ#/CREQ# line for 16-bit cards to be routed to an ISA IRQ. I assume this is what sc->func_route in pcic*.c refers to. My guess is that the Win2k cardbus driver has enough smarts to set things up in this way, as it allocates IRQ 7 for the 16-bit device, even though the cardbus controller itself is sharing IRQ 9. However, without being able to snapshot registers, I can't be entirely sure. I realize that I'm doing this work on OLDCARD, but I'm quite desperate to get things working, so I've attached a patch with what I'm currently doing. --rS8CxjVDS/+yyDmU-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020907123409.GQ15218>