From owner-freebsd-hackers Wed Nov 8 15:54:39 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from mass.osd.bsdi.com (dhcp244.osd.bsdi.com [204.216.28.244]) by hub.freebsd.org (Postfix) with ESMTP id 7DD5237B479 for ; Wed, 8 Nov 2000 15:54:36 -0800 (PST) Received: from mass.osd.bsdi.com (localhost [127.0.0.1]) by mass.osd.bsdi.com (8.11.0/8.11.1) with ESMTP id eA900F311423 for ; Wed, 8 Nov 2000 16:00:15 -0800 (PST) (envelope-from msmith@mass.osd.bsdi.com) Message-Id: <200011090000.eA900F311423@mass.osd.bsdi.com> X-Mailer: exmh version 2.1.1 10/15/1999 To: hackers@freebsd.org Subject: PCI interrupt routing across PCI:PCI bridges Mime-Version: 1.0 Content-Type: multipart/mixed ; boundary="==_Exmh_14741562390" Date: Wed, 08 Nov 2000 16:00:15 -0800 From: Mike Smith Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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