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>