Skip site navigation (1)Skip section navigation (2)
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>