Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 08 Nov 2000 16:00:15 -0800
From:      Mike Smith <msmith@freebsd.org>
To:        hackers@freebsd.org
Subject:   PCI interrupt routing across PCI:PCI bridges
Message-ID:  <200011090000.eA900F311423@mass.osd.bsdi.com>

next in thread | raw e-mail | index | archive | help
This is a multipart MIME message.

--==_Exmh_14741562390
Content-Type: text/plain; charset=us-ascii


Following is a patch to route interrupts for devices on the child side of 
a PCI:PCI bridge.  I don't have any easy way to test this, unfortunately. 

If anyone would care to eyeball it before I commit it, I'd greatly 
appreciate that.




--==_Exmh_14741562390
Content-Type: text/plain ; name="pcisupport.diff"; charset=us-ascii
Content-Description: pcisupport.diff
Content-Disposition: attachment; filename="pcisupport.diff"

Index: pcisupport.c
===================================================================
RCS file: /local0/src/src/sys/pci/pcisupport.c,v
retrieving revision 1.177
diff -u -r1.177 pcisupport.c
--- pcisupport.c	2000/10/29 16:27:40	1.177
+++ pcisupport.c	2000/11/08 23:36:33
@@ -831,6 +831,42 @@
 			  b, s, f, reg, val, width);
 }
 
+/*
+ * Route an interrupt across a PCI bridge.
+ */
+static int
+pcib_route_interrupt(device_t dev, int device, int pin)
+{
+	device_t	bridge, bus;
+	int		parent_intpin;
+	int		intnum;
+
+	/*	
+	 *
+	 * The PCI standard defines a swizzle of the child-side device/intpin to
+	 * the parent-side intpin as follows.
+	 *
+	 * device = device on child bus
+	 * child_intpin = intpin on child bus slot (0-3)
+	 * parent_intpin = intpin on parent bus slot (0-3)
+	 *
+	 * parent_intpin = (device + child_intpin) % 4
+	 */
+	parent_intpin = (pci_get_slot(dev) + (pin - 1)) % 4;
+
+	/*
+	 * Our parent is a PCI bus.  Its parent must export the pcib interface
+	 * which includes the ability to route interrupts.
+	 */
+	bridge = device_get_parent(dev);
+	bus = device_get_parent(bridge);
+	intnum = PCIB_ROUTE_INTERRUPT(device_get_parent(bus),
+				      pci_get_slot(bridge), parent_intpin + 1);
+	device_printf(bridge, "routed slot %d INT%c to irq %d\n", pci_get_slot(dev), 
+		      'A' + pin - 1, intnum);
+	return(intnum);
+}
+
 static device_method_t pcib_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		pcib_probe),
@@ -854,6 +890,7 @@
 	DEVMETHOD(pcib_maxslots,	pcib_maxslots),
 	DEVMETHOD(pcib_read_config,	pcib_read_config),
 	DEVMETHOD(pcib_write_config,	pcib_write_config),
+	DEVMETHOD(pcib_route_interrupt,	pcib_route_interrupt),
 
 	{ 0, 0 }
 };

--==_Exmh_14741562390
Content-Type: text/plain; charset=us-ascii

... every activity meets with opposition, everyone who acts has his
rivals and unfortunately opponents also.  But not because people want
to be opponents, rather because the tasks and relationships force
people to take different points of view.  [Dr. Fritz Todt]
           V I C T O R Y   N O T   V E N G E A N C E

--==_Exmh_14741562390--




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?200011090000.eA900F311423>