1ac19f918SStefan Eßer /************************************************************************** 2ac19f918SStefan Eßer ** 3d7ea35fcSStefan Eßer ** $Id: pcibus.c,v 1.11 1995/09/13 17:03:47 se Exp $ 4ac19f918SStefan Eßer ** 5ac19f918SStefan Eßer ** pci bus subroutines for i386 architecture. 6ac19f918SStefan Eßer ** 7ac19f918SStefan Eßer ** FreeBSD 8ac19f918SStefan Eßer ** 9ac19f918SStefan Eßer **------------------------------------------------------------------------- 10ac19f918SStefan Eßer ** 11ac19f918SStefan Eßer ** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. 12ac19f918SStefan Eßer ** 13ac19f918SStefan Eßer ** Redistribution and use in source and binary forms, with or without 14ac19f918SStefan Eßer ** modification, are permitted provided that the following conditions 15ac19f918SStefan Eßer ** are met: 16ac19f918SStefan Eßer ** 1. Redistributions of source code must retain the above copyright 17ac19f918SStefan Eßer ** notice, this list of conditions and the following disclaimer. 18ac19f918SStefan Eßer ** 2. Redistributions in binary form must reproduce the above copyright 19ac19f918SStefan Eßer ** notice, this list of conditions and the following disclaimer in the 20ac19f918SStefan Eßer ** documentation and/or other materials provided with the distribution. 21ac19f918SStefan Eßer ** 3. The name of the author may not be used to endorse or promote products 22ac19f918SStefan Eßer ** derived from this software without specific prior written permission. 23ac19f918SStefan Eßer ** 24ac19f918SStefan Eßer ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25ac19f918SStefan Eßer ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26ac19f918SStefan Eßer ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27ac19f918SStefan Eßer ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28ac19f918SStefan Eßer ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29ac19f918SStefan Eßer ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30ac19f918SStefan Eßer ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31ac19f918SStefan Eßer ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32ac19f918SStefan Eßer ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33ac19f918SStefan Eßer ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34ac19f918SStefan Eßer ** 35ac19f918SStefan Eßer *************************************************************************** 36ac19f918SStefan Eßer */ 37ac19f918SStefan Eßer 385b3f532eSStefan Eßer #define __PCIBUS_C___ "pl4 95/03/21" 39ac19f918SStefan Eßer 40550f8550SBruce Evans #include <sys/param.h> 41550f8550SBruce Evans #include <sys/systm.h> 42550f8550SBruce Evans #include <sys/kernel.h> 43550f8550SBruce Evans 44550f8550SBruce Evans #include <i386/isa/icu.h> 45ac19f918SStefan Eßer #include <i386/isa/isa.h> 46ac19f918SStefan Eßer #include <i386/isa/isa_device.h> 47ac19f918SStefan Eßer 48ac19f918SStefan Eßer #include <pci/pcivar.h> 49ac19f918SStefan Eßer #include <pci/pcireg.h> 50ac19f918SStefan Eßer #include <pci/pcibus.h> 51ac19f918SStefan Eßer 52ac19f918SStefan Eßer /*----------------------------------------------------------------- 53ac19f918SStefan Eßer ** 54ac19f918SStefan Eßer ** The following functions are provided by the pci bios. 55ac19f918SStefan Eßer ** They are used only by the pci configuration. 56ac19f918SStefan Eßer ** 575b3f532eSStefan Eßer ** pcibus_setup(): 58ac19f918SStefan Eßer ** Probes for a pci system. 595b3f532eSStefan Eßer ** Sets pci_maxdevice and pci_mechanism. 60ac19f918SStefan Eßer ** 61ac19f918SStefan Eßer ** pcibus_tag(): 625b3f532eSStefan Eßer ** Creates a handle for pci configuration space access. 635b3f532eSStefan Eßer ** This handle is given to the read/write functions. 645b3f532eSStefan Eßer ** 655b3f532eSStefan Eßer ** pcibus_ftag(): 665b3f532eSStefan Eßer ** Creates a modified handle. 67ac19f918SStefan Eßer ** 68ac19f918SStefan Eßer ** pcibus_read(): 69ac19f918SStefan Eßer ** Read a long word from the pci configuration space. 70ac19f918SStefan Eßer ** Requires a tag (from pcitag) and the register 71ac19f918SStefan Eßer ** number (should be a long word alligned one). 72ac19f918SStefan Eßer ** 73ac19f918SStefan Eßer ** pcibus_write(): 74ac19f918SStefan Eßer ** Writes a long word to the pci configuration space. 75ac19f918SStefan Eßer ** Requires a tag (from pcitag), the register number 76ac19f918SStefan Eßer ** (should be a long word alligned one), and a value. 77ac19f918SStefan Eßer ** 78ac19f918SStefan Eßer ** pcibus_regirq(): 79ac19f918SStefan Eßer ** Register an interupt handler for a pci device. 80ac19f918SStefan Eßer ** Requires a tag (from pcitag), the register number 81ac19f918SStefan Eßer ** (should be a long word alligned one), and a value. 82ac19f918SStefan Eßer ** 83ac19f918SStefan Eßer **----------------------------------------------------------------- 84ac19f918SStefan Eßer */ 85ac19f918SStefan Eßer 86d7ea35fcSStefan Eßer static int 87d7ea35fcSStefan Eßer pcibus_check (void); 88d7ea35fcSStefan Eßer 895b3f532eSStefan Eßer static void 905b3f532eSStefan Eßer pcibus_setup (void); 91ac19f918SStefan Eßer 92ac19f918SStefan Eßer static pcici_t 93ac19f918SStefan Eßer pcibus_tag (u_char bus, u_char device, u_char func); 94ac19f918SStefan Eßer 955b3f532eSStefan Eßer static pcici_t 965b3f532eSStefan Eßer pcibus_ftag (pcici_t tag, u_char func); 975b3f532eSStefan Eßer 98ac19f918SStefan Eßer static u_long 99ac19f918SStefan Eßer pcibus_read (pcici_t tag, u_long reg); 100ac19f918SStefan Eßer 101ac19f918SStefan Eßer static void 102ac19f918SStefan Eßer pcibus_write (pcici_t tag, u_long reg, u_long data); 103ac19f918SStefan Eßer 104ac19f918SStefan Eßer static int 1055b3f532eSStefan Eßer pcibus_ihandler_attach (int irq, void(*ihandler)(), int arg, unsigned* maskp); 1065b3f532eSStefan Eßer 1075b3f532eSStefan Eßer static int 1085b3f532eSStefan Eßer pcibus_ihandler_detach (int irq, void(*handler)()); 1095b3f532eSStefan Eßer 1105b3f532eSStefan Eßer static int 1115b3f532eSStefan Eßer pcibus_imask_include (int irq, unsigned* maskptr); 1125b3f532eSStefan Eßer 1135b3f532eSStefan Eßer static int 1145b3f532eSStefan Eßer pcibus_imask_exclude (int irq, unsigned* maskptr); 115ac19f918SStefan Eßer 116ac19f918SStefan Eßer struct pcibus i386pci = { 117ac19f918SStefan Eßer "pci", 1185b3f532eSStefan Eßer pcibus_setup, 119ac19f918SStefan Eßer pcibus_tag, 1205b3f532eSStefan Eßer pcibus_ftag, 121ac19f918SStefan Eßer pcibus_read, 122ac19f918SStefan Eßer pcibus_write, 1235b3f532eSStefan Eßer ICU_LEN, 1245b3f532eSStefan Eßer pcibus_ihandler_attach, 1255b3f532eSStefan Eßer pcibus_ihandler_detach, 1265b3f532eSStefan Eßer pcibus_imask_include, 1275b3f532eSStefan Eßer pcibus_imask_exclude, 128ac19f918SStefan Eßer }; 129ac19f918SStefan Eßer 130ac19f918SStefan Eßer /* 131ac19f918SStefan Eßer ** Announce structure to generic driver 132ac19f918SStefan Eßer */ 133ac19f918SStefan Eßer 134ac19f918SStefan Eßer DATA_SET (pcibus_set, i386pci); 135ac19f918SStefan Eßer 136ac19f918SStefan Eßer /*-------------------------------------------------------------------- 137ac19f918SStefan Eßer ** 138ac19f918SStefan Eßer ** Determine configuration mode 139ac19f918SStefan Eßer ** 140ac19f918SStefan Eßer **-------------------------------------------------------------------- 141ac19f918SStefan Eßer */ 142ac19f918SStefan Eßer 143ac19f918SStefan Eßer 144ac19f918SStefan Eßer #define CONF1_ENABLE 0x80000000ul 145cda67911SStefan Eßer #define CONF1_ENABLE_CHK1 0xF0000000ul 146cda67911SStefan Eßer #define CONF1_ENABLE_CHK2 0xfffffffful 147cda67911SStefan Eßer #define CONF1_ENABLE_RES2 0x80fffffcul 148ac19f918SStefan Eßer #define CONF1_ADDR_PORT 0x0cf8 149ac19f918SStefan Eßer #define CONF1_DATA_PORT 0x0cfc 150ac19f918SStefan Eßer 151ac19f918SStefan Eßer 152ac19f918SStefan Eßer #define CONF2_ENABLE_PORT 0x0cf8 153ac19f918SStefan Eßer #define CONF2_FORWARD_PORT 0x0cfa 154ac19f918SStefan Eßer 155ac19f918SStefan Eßer 156d7ea35fcSStefan Eßer static int 157d7ea35fcSStefan Eßer pcibus_check (void) 158d7ea35fcSStefan Eßer { 159d7ea35fcSStefan Eßer u_char device; 160d7ea35fcSStefan Eßer 161d7ea35fcSStefan Eßer for (device = 0; device < pci_maxdevice; device++) { 162d7ea35fcSStefan Eßer if (pcibus_read (pcibus_tag (0,device,0), 0) != 0xfffffffful) 163d7ea35fcSStefan Eßer return 1; 164d7ea35fcSStefan Eßer } 165d7ea35fcSStefan Eßer return 0; 166d7ea35fcSStefan Eßer } 167d7ea35fcSStefan Eßer 1685b3f532eSStefan Eßer static void 1695b3f532eSStefan Eßer pcibus_setup (void) 170ac19f918SStefan Eßer { 171ac19f918SStefan Eßer u_long result, oldval; 172ac19f918SStefan Eßer 173ac19f918SStefan Eßer /*--------------------------------------- 1740847c06dSStefan Eßer ** Configuration mode 1 ? 1750847c06dSStefan Eßer **--------------------------------------- 1760847c06dSStefan Eßer */ 1770847c06dSStefan Eßer 1780847c06dSStefan Eßer oldval = inl (CONF1_ADDR_PORT); 179cda67911SStefan Eßer outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK1); 1800847c06dSStefan Eßer outb (CONF1_ADDR_PORT +3, 0); 1810847c06dSStefan Eßer result = inl (CONF1_ADDR_PORT); 1820847c06dSStefan Eßer outl (CONF1_ADDR_PORT, oldval); 1830847c06dSStefan Eßer 184d2a2d5ecSStefan Eßer if (result & CONF1_ENABLE) { 1850847c06dSStefan Eßer pci_mechanism = 1; 1860847c06dSStefan Eßer pci_maxdevice = 32; 187d7ea35fcSStefan Eßer if (pcibus_check()) 1880847c06dSStefan Eßer return; 1890847c06dSStefan Eßer }; 1900847c06dSStefan Eßer 1910847c06dSStefan Eßer /*--------------------------------------- 192ac19f918SStefan Eßer ** Configuration mode 2 ? 193ac19f918SStefan Eßer **--------------------------------------- 194ac19f918SStefan Eßer */ 195ac19f918SStefan Eßer 196ac19f918SStefan Eßer outb (CONF2_ENABLE_PORT, 0); 197ac19f918SStefan Eßer outb (CONF2_FORWARD_PORT, 0); 198ac19f918SStefan Eßer if (!inb (CONF2_ENABLE_PORT) && !inb (CONF2_FORWARD_PORT)) { 1995b3f532eSStefan Eßer pci_mechanism = 2; 2005b3f532eSStefan Eßer pci_maxdevice = 16; 201d7ea35fcSStefan Eßer if (pcibus_check()) 2020f29bf01SStefan Eßer return; 203ac19f918SStefan Eßer }; 204ac19f918SStefan Eßer 205cda67911SStefan Eßer 206cda67911SStefan Eßer /*----------------------------------------------------- 207cda67911SStefan Eßer ** Well, is it Configuration mode 1, after all ? 208cda67911SStefan Eßer **----------------------------------------------------- 209cda67911SStefan Eßer */ 210cda67911SStefan Eßer 211cda67911SStefan Eßer oldval = inl (CONF1_ADDR_PORT); 212cda67911SStefan Eßer outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK2); 213cda67911SStefan Eßer result = inl (CONF1_ADDR_PORT); 214cda67911SStefan Eßer outl (CONF1_ADDR_PORT, oldval); 215cda67911SStefan Eßer 216cda67911SStefan Eßer if (result == CONF1_ENABLE_RES2) { 217cda67911SStefan Eßer pci_mechanism = 1; 218cda67911SStefan Eßer pci_maxdevice = 32; 219d7ea35fcSStefan Eßer if (pcibus_check()) 220cda67911SStefan Eßer return; 221cda67911SStefan Eßer } 222cda67911SStefan Eßer if (result != 0xfffffffful) 223cda67911SStefan Eßer printf ("pcibus_setup: " 224cda67911SStefan Eßer "wrote 0x%08x, read back 0x%08x, expected 0x%08x\n", 225cda67911SStefan Eßer CONF1_ENABLE_CHK2, result, CONF1_ENABLE_RES2); 226cda67911SStefan Eßer 227ac19f918SStefan Eßer /*--------------------------------------- 228cda67911SStefan Eßer ** No PCI bus host bridge found 229ac19f918SStefan Eßer **--------------------------------------- 230ac19f918SStefan Eßer */ 231cda67911SStefan Eßer 232cda67911SStefan Eßer pci_mechanism = 0; 233cda67911SStefan Eßer pci_maxdevice = 0; 234ac19f918SStefan Eßer } 2355b3f532eSStefan Eßer 236ac19f918SStefan Eßer /*-------------------------------------------------------------------- 237ac19f918SStefan Eßer ** 238ac19f918SStefan Eßer ** Build a pcitag from bus, device and function number 239ac19f918SStefan Eßer ** 240ac19f918SStefan Eßer **-------------------------------------------------------------------- 241ac19f918SStefan Eßer */ 242ac19f918SStefan Eßer 243ac19f918SStefan Eßer static pcici_t 244ac19f918SStefan Eßer pcibus_tag (unsigned char bus, unsigned char device, unsigned char func) 245ac19f918SStefan Eßer { 246ac19f918SStefan Eßer pcici_t tag; 247ac19f918SStefan Eßer 248ac19f918SStefan Eßer tag.cfg1 = 0; 249ac19f918SStefan Eßer if (device >= 32) return tag; 250ac19f918SStefan Eßer if (func >= 8) return tag; 251ac19f918SStefan Eßer 2525b3f532eSStefan Eßer switch (pci_mechanism) { 253ac19f918SStefan Eßer 254ac19f918SStefan Eßer case 1: 255ac19f918SStefan Eßer tag.cfg1 = CONF1_ENABLE 256ac19f918SStefan Eßer | (((u_long) bus ) << 16ul) 257ac19f918SStefan Eßer | (((u_long) device) << 11ul) 258ac19f918SStefan Eßer | (((u_long) func ) << 8ul); 259ac19f918SStefan Eßer break; 260ac19f918SStefan Eßer case 2: 261ac19f918SStefan Eßer if (device >= 16) break; 262ac19f918SStefan Eßer tag.cfg2.port = 0xc000 | (device << 8ul); 263ac19f918SStefan Eßer tag.cfg2.enable = 0xf1 | (func << 1ul); 264ac19f918SStefan Eßer tag.cfg2.forward = bus; 265ac19f918SStefan Eßer break; 266ac19f918SStefan Eßer }; 267ac19f918SStefan Eßer return tag; 268ac19f918SStefan Eßer } 2695b3f532eSStefan Eßer 2705b3f532eSStefan Eßer static pcici_t 2715b3f532eSStefan Eßer pcibus_ftag (pcici_t tag, u_char func) 2725b3f532eSStefan Eßer { 2735b3f532eSStefan Eßer switch (pci_mechanism) { 2745b3f532eSStefan Eßer 2755b3f532eSStefan Eßer case 1: 2765b3f532eSStefan Eßer tag.cfg1 &= ~0x700ul; 2775b3f532eSStefan Eßer tag.cfg1 |= (((u_long) func) << 8ul); 2785b3f532eSStefan Eßer break; 2795b3f532eSStefan Eßer case 2: 2805b3f532eSStefan Eßer tag.cfg2.enable = 0xf1 | (func << 1ul); 2815b3f532eSStefan Eßer break; 2825b3f532eSStefan Eßer }; 2835b3f532eSStefan Eßer return tag; 2845b3f532eSStefan Eßer } 2855b3f532eSStefan Eßer 286ac19f918SStefan Eßer /*-------------------------------------------------------------------- 287ac19f918SStefan Eßer ** 288ac19f918SStefan Eßer ** Read register from configuration space. 289ac19f918SStefan Eßer ** 290ac19f918SStefan Eßer **-------------------------------------------------------------------- 291ac19f918SStefan Eßer */ 292ac19f918SStefan Eßer 293ac19f918SStefan Eßer static u_long 294ac19f918SStefan Eßer pcibus_read (pcici_t tag, u_long reg) 295ac19f918SStefan Eßer { 296ac19f918SStefan Eßer u_long addr, data = 0; 297ac19f918SStefan Eßer 298ac19f918SStefan Eßer if (!tag.cfg1) return (0xfffffffful); 299ac19f918SStefan Eßer 3005b3f532eSStefan Eßer switch (pci_mechanism) { 301ac19f918SStefan Eßer 302ac19f918SStefan Eßer case 1: 303ac19f918SStefan Eßer addr = tag.cfg1 | (reg & 0xfc); 304ac19f918SStefan Eßer #ifdef PCI_DEBUG 305ac19f918SStefan Eßer printf ("pci_conf_read(1): addr=%x ", addr); 306ac19f918SStefan Eßer #endif 307ac19f918SStefan Eßer outl (CONF1_ADDR_PORT, addr); 308ac19f918SStefan Eßer data = inl (CONF1_DATA_PORT); 309ac19f918SStefan Eßer outl (CONF1_ADDR_PORT, 0 ); 310ac19f918SStefan Eßer break; 311ac19f918SStefan Eßer 312ac19f918SStefan Eßer case 2: 313ac19f918SStefan Eßer addr = tag.cfg2.port | (reg & 0xfc); 314ac19f918SStefan Eßer #ifdef PCI_DEBUG 315ac19f918SStefan Eßer printf ("pci_conf_read(2): addr=%x ", addr); 316ac19f918SStefan Eßer #endif 317ac19f918SStefan Eßer outb (CONF2_ENABLE_PORT , tag.cfg2.enable ); 318ac19f918SStefan Eßer outb (CONF2_FORWARD_PORT, tag.cfg2.forward); 319ac19f918SStefan Eßer 320ac19f918SStefan Eßer data = inl ((u_short) addr); 321ac19f918SStefan Eßer 322ac19f918SStefan Eßer outb (CONF2_ENABLE_PORT, 0); 323ac19f918SStefan Eßer outb (CONF2_FORWARD_PORT, 0); 324ac19f918SStefan Eßer break; 325ac19f918SStefan Eßer }; 326ac19f918SStefan Eßer 327ac19f918SStefan Eßer #ifdef PCI_DEBUG 328ac19f918SStefan Eßer printf ("data=%x\n", data); 329ac19f918SStefan Eßer #endif 330ac19f918SStefan Eßer 331ac19f918SStefan Eßer return (data); 332ac19f918SStefan Eßer } 3335b3f532eSStefan Eßer 334ac19f918SStefan Eßer /*-------------------------------------------------------------------- 335ac19f918SStefan Eßer ** 336ac19f918SStefan Eßer ** Write register into configuration space. 337ac19f918SStefan Eßer ** 338ac19f918SStefan Eßer **-------------------------------------------------------------------- 339ac19f918SStefan Eßer */ 340ac19f918SStefan Eßer 341ac19f918SStefan Eßer static void 342ac19f918SStefan Eßer pcibus_write (pcici_t tag, u_long reg, u_long data) 343ac19f918SStefan Eßer { 344ac19f918SStefan Eßer u_long addr; 345ac19f918SStefan Eßer 346ac19f918SStefan Eßer if (!tag.cfg1) return; 347ac19f918SStefan Eßer 3485b3f532eSStefan Eßer switch (pci_mechanism) { 349ac19f918SStefan Eßer 350ac19f918SStefan Eßer case 1: 351ac19f918SStefan Eßer addr = tag.cfg1 | (reg & 0xfc); 352ac19f918SStefan Eßer #ifdef PCI_DEBUG 353ac19f918SStefan Eßer printf ("pci_conf_write(1): addr=%x data=%x\n", 354ac19f918SStefan Eßer addr, data); 355ac19f918SStefan Eßer #endif 356ac19f918SStefan Eßer outl (CONF1_ADDR_PORT, addr); 357ac19f918SStefan Eßer outl (CONF1_DATA_PORT, data); 358ac19f918SStefan Eßer outl (CONF1_ADDR_PORT, 0 ); 359ac19f918SStefan Eßer break; 360ac19f918SStefan Eßer 361ac19f918SStefan Eßer case 2: 362ac19f918SStefan Eßer addr = tag.cfg2.port | (reg & 0xfc); 363ac19f918SStefan Eßer #ifdef PCI_DEBUG 364ac19f918SStefan Eßer printf ("pci_conf_write(2): addr=%x data=%x\n", 365ac19f918SStefan Eßer addr, data); 366ac19f918SStefan Eßer #endif 367ac19f918SStefan Eßer outb (CONF2_ENABLE_PORT, tag.cfg2.enable); 368ac19f918SStefan Eßer outb (CONF2_FORWARD_PORT, tag.cfg2.forward); 369ac19f918SStefan Eßer 370ac19f918SStefan Eßer outl ((u_short) addr, data); 371ac19f918SStefan Eßer 372ac19f918SStefan Eßer outb (CONF2_ENABLE_PORT, 0); 373ac19f918SStefan Eßer outb (CONF2_FORWARD_PORT, 0); 374ac19f918SStefan Eßer break; 375ac19f918SStefan Eßer }; 376ac19f918SStefan Eßer } 3775b3f532eSStefan Eßer 378ac19f918SStefan Eßer /*----------------------------------------------------------------------- 379ac19f918SStefan Eßer ** 380ac19f918SStefan Eßer ** Register an interupt handler for a pci device. 381ac19f918SStefan Eßer ** 382ac19f918SStefan Eßer **----------------------------------------------------------------------- 383ac19f918SStefan Eßer */ 384ac19f918SStefan Eßer 385ac19f918SStefan Eßer static int 3865b3f532eSStefan Eßer pcibus_ihandler_attach (int irq, void(*func)(), int arg, unsigned * maskptr) 387ac19f918SStefan Eßer { 3885b3f532eSStefan Eßer int result; 3895b3f532eSStefan Eßer result = register_intr( 390ac19f918SStefan Eßer irq, /* isa irq */ 391ac19f918SStefan Eßer 0, /* deviced?? */ 392ac19f918SStefan Eßer 0, /* flags? */ 393ac19f918SStefan Eßer (inthand2_t*) func, /* handler */ 394ac19f918SStefan Eßer maskptr, /* mask pointer */ 3955b3f532eSStefan Eßer arg); /* handler arg */ 396ac19f918SStefan Eßer 3975b3f532eSStefan Eßer if (result) { 3985b3f532eSStefan Eßer printf ("@@@ pcibus_ihandler_attach: result=%d\n", result); 3995b3f532eSStefan Eßer return (result); 400ac19f918SStefan Eßer }; 4015b3f532eSStefan Eßer update_intr_masks(); 402ac19f918SStefan Eßer 4035b3f532eSStefan Eßer INTREN ((1ul<<irq)); 4045b3f532eSStefan Eßer return (0); 4055b3f532eSStefan Eßer } 406ac19f918SStefan Eßer 4075b3f532eSStefan Eßer static int 4085b3f532eSStefan Eßer pcibus_ihandler_detach (int irq, void(*func)()) 4095b3f532eSStefan Eßer { 4105b3f532eSStefan Eßer int result; 4115b3f532eSStefan Eßer 4125b3f532eSStefan Eßer INTRDIS ((1ul<<irq)); 4135b3f532eSStefan Eßer 4145b3f532eSStefan Eßer result = unregister_intr (irq, (inthand2_t*) func); 4155b3f532eSStefan Eßer 4165b3f532eSStefan Eßer if (result) 4175b3f532eSStefan Eßer printf ("@@@ pcibus_ihandler_detach: result=%d\n", result); 4185b3f532eSStefan Eßer 4195b3f532eSStefan Eßer update_intr_masks(); 4205b3f532eSStefan Eßer 4215b3f532eSStefan Eßer return (result); 4225b3f532eSStefan Eßer } 4235b3f532eSStefan Eßer 4245b3f532eSStefan Eßer static int 4255b3f532eSStefan Eßer pcibus_imask_include (int irq, unsigned* maskptr) 4265b3f532eSStefan Eßer { 4275b3f532eSStefan Eßer unsigned mask; 4285b3f532eSStefan Eßer 4295b3f532eSStefan Eßer if (!maskptr) return (0); 4305b3f532eSStefan Eßer 4315b3f532eSStefan Eßer mask = 1ul << irq; 4325b3f532eSStefan Eßer 4335b3f532eSStefan Eßer if (*maskptr & mask) 4345b3f532eSStefan Eßer return (-1); 4355b3f532eSStefan Eßer 4365b3f532eSStefan Eßer INTRMASK (*maskptr, mask); 4375b3f532eSStefan Eßer update_intr_masks(); 4385b3f532eSStefan Eßer 4395b3f532eSStefan Eßer return (0); 4405b3f532eSStefan Eßer } 4415b3f532eSStefan Eßer 4425b3f532eSStefan Eßer static int 4435b3f532eSStefan Eßer pcibus_imask_exclude (int irq, unsigned* maskptr) 4445b3f532eSStefan Eßer { 4455b3f532eSStefan Eßer unsigned mask; 4465b3f532eSStefan Eßer 4475b3f532eSStefan Eßer if (!maskptr) return (0); 4485b3f532eSStefan Eßer 4495b3f532eSStefan Eßer mask = 1ul << irq; 4505b3f532eSStefan Eßer 4515b3f532eSStefan Eßer if (! (*maskptr & mask)) 4525b3f532eSStefan Eßer return (-1); 4535b3f532eSStefan Eßer 4545b3f532eSStefan Eßer *maskptr &= ~mask; 4555b3f532eSStefan Eßer update_intr_masks(); 4565b3f532eSStefan Eßer 4575b3f532eSStefan Eßer return (0); 458ac19f918SStefan Eßer } 459