pci_cfgreg.c (6734) | pci_cfgreg.c (7234) |
---|---|
1/************************************************************************** 2** | 1/************************************************************************** 2** |
3** $Id: pcibus.c,v 1.3 1995/02/25 17:51:18 se Exp $ | 3** $Id: pcibus.c,v 1.4 1995/02/26 05:14:51 bde Exp $ |
4** 5** pci bus subroutines for i386 architecture. 6** 7** FreeBSD 8** 9**------------------------------------------------------------------------- 10** 11** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. --- 18 unchanged lines hidden (view full) --- 30** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34** 35*************************************************************************** 36*/ 37 | 4** 5** pci bus subroutines for i386 architecture. 6** 7** FreeBSD 8** 9**------------------------------------------------------------------------- 10** 11** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. --- 18 unchanged lines hidden (view full) --- 30** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34** 35*************************************************************************** 36*/ 37 |
38#ifndef __FreeBSD2__ 39#if __FreeBSD__ >= 2 40#define __FreeBSD2__ 41#endif 42#endif | 38#define __PCIBUS_C___ "pl4 95/03/21" |
43 | 39 |
44#ifdef __FreeBSD2__ 45#define HAS_CPUFUNC_H 46#endif 47 | |
48#include <sys/param.h> 49#include <sys/systm.h> 50#include <sys/kernel.h> 51 52#include <i386/isa/icu.h> 53#include <i386/isa/isa.h> 54#include <i386/isa/isa_device.h> 55 56#include <pci/pcivar.h> 57#include <pci/pcireg.h> 58#include <pci/pcibus.h> 59 | 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43 44#include <i386/isa/icu.h> 45#include <i386/isa/isa.h> 46#include <i386/isa/isa_device.h> 47 48#include <pci/pcivar.h> 49#include <pci/pcireg.h> 50#include <pci/pcibus.h> 51 |
60static char pci_mode; 61 | 52extern int printf(); 53 54#ifdef DENTARO 55 56#define SFAKE (32) 57 58static void 59dec21050 (u_int*reg) { 60 reg[0] = 0x00011011; 61 reg[1]&= 0x000001e7; 62 reg[2] = 0x06040001; 63 reg[3]&= 0x0000f8ff; 64 reg[3]|= 0x000100ff; 65 reg[4] = 0x00000000; 66 reg[5] = 0x00000000; 67 reg[6]&= 0xf8ffffff; 68 reg[7]&= 0x0000f0f0; /* io-limit */ 69 reg[8]&= 0xfff0fff0; /* mem-limit, non prefatchable */ 70 reg[9]&= 0xfff0fff0; /* mem-limit, prefetchable memory */ 71 reg[10] = 0x00000000; 72 reg[11] = 0x00000000; 73 reg[12] = 0x00000000; 74 reg[13] = 0x00000000; 75 reg[14] = 0x00000000; 76 reg[15]&= 0x00ef0000; 77} 78 79static void 80dec21140 (u_int*reg) { 81 reg[0] = 0x00091011u; 82 reg[4]&= 0xfffffffdu; 83 reg[4]|= 0x00000001u; 84 reg[5]&= 0xffffff00u; 85} 86 87struct fake { 88 u_int tag; 89 void (*proc)(u_int*); 90}; 91 92struct fake faketable [] = { 93{ 0xc70000f1, dec21050 }, 94{ 0xc00001f1, dec21140 }, 95{ 0xc40001f1, dec21140 }, 96{ 0xc80001f1, dec21140 }, 97{ 0xcc0001f1, dec21140 }, 98}; 99 100#define NFAKE (sizeof faketable / sizeof (struct fake)) 101 102static u_int fakedata[NFAKE * SFAKE]; 103 104u_int* findfake (pcici_t tag) 105{ 106 u_int *p; 107 int i; 108 for (i=0; i<NFAKE; i++) 109 if (faketable[i].tag == tag.tag) 110 break; 111 112 if (i>=NFAKE) 113 return (0); 114 p = &fakedata[i*SFAKE]; 115 (*faketable[i].proc)(p); 116 return (p); 117} 118#endif /*DENTARO*/ 119 |
62/*----------------------------------------------------------------- 63** 64** The following functions are provided by the pci bios. 65** They are used only by the pci configuration. 66** | 120/*----------------------------------------------------------------- 121** 122** The following functions are provided by the pci bios. 123** They are used only by the pci configuration. 124** |
67** pcibus_mode(): | 125** pcibus_setup(): |
68** Probes for a pci system. | 126** Probes for a pci system. |
69** Returns 1 or 2 for pci configuration mechanism. 70** Returns 0 if no pci system. | 127** Sets pci_maxdevice and pci_mechanism. |
71** 72** pcibus_tag(): | 128** 129** pcibus_tag(): |
73** Gets a handle for accessing the pci configuration 74** space. 75** This handle is given to the mapping functions (see 76** above) or to the read/write functions. | 130** Creates a handle for pci configuration space access. 131** This handle is given to the read/write functions. |
77** | 132** |
133** pcibus_ftag(): 134** Creates a modified handle. 135** |
|
78** pcibus_read(): 79** Read a long word from the pci configuration space. 80** Requires a tag (from pcitag) and the register 81** number (should be a long word alligned one). 82** 83** pcibus_write(): 84** Writes a long word to the pci configuration space. 85** Requires a tag (from pcitag), the register number 86** (should be a long word alligned one), and a value. 87** 88** pcibus_regirq(): 89** Register an interupt handler for a pci device. 90** Requires a tag (from pcitag), the register number 91** (should be a long word alligned one), and a value. 92** 93**----------------------------------------------------------------- 94*/ 95 | 136** pcibus_read(): 137** Read a long word from the pci configuration space. 138** Requires a tag (from pcitag) and the register 139** number (should be a long word alligned one). 140** 141** pcibus_write(): 142** Writes a long word to the pci configuration space. 143** Requires a tag (from pcitag), the register number 144** (should be a long word alligned one), and a value. 145** 146** pcibus_regirq(): 147** Register an interupt handler for a pci device. 148** Requires a tag (from pcitag), the register number 149** (should be a long word alligned one), and a value. 150** 151**----------------------------------------------------------------- 152*/ 153 |
96static int 97pcibus_mode (void); | 154static void 155pcibus_setup (void); |
98 99static pcici_t 100pcibus_tag (u_char bus, u_char device, u_char func); 101 | 156 157static pcici_t 158pcibus_tag (u_char bus, u_char device, u_char func); 159 |
160static pcici_t 161pcibus_ftag (pcici_t tag, u_char func); 162 |
|
102static u_long 103pcibus_read (pcici_t tag, u_long reg); 104 105static void 106pcibus_write (pcici_t tag, u_long reg, u_long data); 107 108static int | 163static u_long 164pcibus_read (pcici_t tag, u_long reg); 165 166static void 167pcibus_write (pcici_t tag, u_long reg, u_long data); 168 169static int |
109pcibus_regint (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr); | 170pcibus_ihandler_attach (int irq, void(*ihandler)(), int arg, unsigned* maskp); |
110 | 171 |
172static int 173pcibus_ihandler_detach (int irq, void(*handler)()); 174 175static int 176pcibus_imask_include (int irq, unsigned* maskptr); 177 178static int 179pcibus_imask_exclude (int irq, unsigned* maskptr); 180 |
|
111struct pcibus i386pci = { 112 "pci", | 181struct pcibus i386pci = { 182 "pci", |
113 pcibus_mode, | 183 pcibus_setup, |
114 pcibus_tag, | 184 pcibus_tag, |
185 pcibus_ftag, |
|
115 pcibus_read, 116 pcibus_write, | 186 pcibus_read, 187 pcibus_write, |
117 pcibus_regint, | 188 ICU_LEN, 189 pcibus_ihandler_attach, 190 pcibus_ihandler_detach, 191 pcibus_imask_include, 192 pcibus_imask_exclude, |
118}; 119 120/* 121** Announce structure to generic driver 122*/ 123 124DATA_SET (pcibus_set, i386pci); | 193}; 194 195/* 196** Announce structure to generic driver 197*/ 198 199DATA_SET (pcibus_set, i386pci); |
125 126/*-------------------------------------------------------------------- 127** 128** Port access 129** 130**-------------------------------------------------------------------- 131*/ | |
132 | 200 |
133#ifndef HAS_CPUFUNC_H 134 135#undef inl 136#define inl(port) \ 137({ u_long data; \ 138 __asm __volatile("inl %1, %0": "=a" (data): "d" ((u_short)(port))); \ 139 data; }) 140 141 142#undef outl 143#define outl(port, data) \ 144{__asm __volatile("outl %0, %1"::"a" ((u_long)(data)), "d" ((u_short)(port)));} 145 146 147#undef inb 148#define inb(port) \ 149({ u_char data; \ 150 __asm __volatile("inb %1, %0": "=a" (data): "d" ((u_short)(port))); \ 151 data; }) 152 153 154#undef outb 155#define outb(port, data) \ 156{__asm __volatile("outb %0, %1"::"a" ((u_char)(data)), "d" ((u_short)(port)));} 157 158#endif /* HAS_CPUFUNC_H */ 159 | |
160/*-------------------------------------------------------------------- 161** 162** Determine configuration mode 163** 164**-------------------------------------------------------------------- 165*/ 166 167 168#define CONF1_ENABLE 0x80000000ul 169#define CONF1_ADDR_PORT 0x0cf8 170#define CONF1_DATA_PORT 0x0cfc 171 172 173#define CONF2_ENABLE_PORT 0x0cf8 174#define CONF2_FORWARD_PORT 0x0cfa 175 176 | 201/*-------------------------------------------------------------------- 202** 203** Determine configuration mode 204** 205**-------------------------------------------------------------------- 206*/ 207 208 209#define CONF1_ENABLE 0x80000000ul 210#define CONF1_ADDR_PORT 0x0cf8 211#define CONF1_DATA_PORT 0x0cfc 212 213 214#define CONF2_ENABLE_PORT 0x0cf8 215#define CONF2_FORWARD_PORT 0x0cfa 216 217 |
177static int 178pcibus_mode (void) | 218static void 219pcibus_setup (void) |
179{ | 220{ |
180#ifdef PCI_CONF_MODE 181 pci_mode = PCI_CONF_MODE; 182 return (PCI_CONF_MODE) 183#else /* PCI_CONF_MODE */ | |
184 u_long result, oldval; 185 186 /*--------------------------------------- 187 ** Configuration mode 2 ? 188 **--------------------------------------- 189 */ 190 191 outb (CONF2_ENABLE_PORT, 0); 192 outb (CONF2_FORWARD_PORT, 0); 193 if (!inb (CONF2_ENABLE_PORT) && !inb (CONF2_FORWARD_PORT)) { | 221 u_long result, oldval; 222 223 /*--------------------------------------- 224 ** Configuration mode 2 ? 225 **--------------------------------------- 226 */ 227 228 outb (CONF2_ENABLE_PORT, 0); 229 outb (CONF2_FORWARD_PORT, 0); 230 if (!inb (CONF2_ENABLE_PORT) && !inb (CONF2_FORWARD_PORT)) { |
194 pci_mode = 2; 195 return (2); | 231 pci_mechanism = 2; 232 pci_maxdevice = 16; |
196 }; 197 198 /*--------------------------------------- 199 ** Configuration mode 1 ? 200 **--------------------------------------- 201 */ 202 203 oldval = inl (CONF1_ADDR_PORT); 204 outl (CONF1_ADDR_PORT, CONF1_ENABLE); 205 result = inl (CONF1_ADDR_PORT); 206 outl (CONF1_ADDR_PORT, oldval); 207 208 if (result == CONF1_ENABLE) { | 233 }; 234 235 /*--------------------------------------- 236 ** Configuration mode 1 ? 237 **--------------------------------------- 238 */ 239 240 oldval = inl (CONF1_ADDR_PORT); 241 outl (CONF1_ADDR_PORT, CONF1_ENABLE); 242 result = inl (CONF1_ADDR_PORT); 243 outl (CONF1_ADDR_PORT, oldval); 244 245 if (result == CONF1_ENABLE) { |
209 pci_mode = 1; 210 return (1); | 246 pci_mechanism = 1; 247 pci_maxdevice = 32; |
211 }; 212 213 /*--------------------------------------- 214 ** No PCI bus available. 215 **--------------------------------------- 216 */ | 248 }; 249 250 /*--------------------------------------- 251 ** No PCI bus available. 252 **--------------------------------------- 253 */ |
217 return (0); 218#endif /* PCI_CONF_MODE */ | |
219} | 254} |
220 | 255 |
221/*-------------------------------------------------------------------- 222** 223** Build a pcitag from bus, device and function number 224** 225**-------------------------------------------------------------------- 226*/ 227 228static pcici_t 229pcibus_tag (unsigned char bus, unsigned char device, unsigned char func) 230{ 231 pcici_t tag; 232 233 tag.cfg1 = 0; 234 if (device >= 32) return tag; 235 if (func >= 8) return tag; 236 | 256/*-------------------------------------------------------------------- 257** 258** Build a pcitag from bus, device and function number 259** 260**-------------------------------------------------------------------- 261*/ 262 263static pcici_t 264pcibus_tag (unsigned char bus, unsigned char device, unsigned char func) 265{ 266 pcici_t tag; 267 268 tag.cfg1 = 0; 269 if (device >= 32) return tag; 270 if (func >= 8) return tag; 271 |
237 switch (pci_mode) { | 272 switch (pci_mechanism) { |
238 239 case 1: 240 tag.cfg1 = CONF1_ENABLE 241 | (((u_long) bus ) << 16ul) 242 | (((u_long) device) << 11ul) 243 | (((u_long) func ) << 8ul); 244 break; 245 case 2: 246 if (device >= 16) break; 247 tag.cfg2.port = 0xc000 | (device << 8ul); 248 tag.cfg2.enable = 0xf1 | (func << 1ul); 249 tag.cfg2.forward = bus; 250 break; 251 }; 252 return tag; 253} | 273 274 case 1: 275 tag.cfg1 = CONF1_ENABLE 276 | (((u_long) bus ) << 16ul) 277 | (((u_long) device) << 11ul) 278 | (((u_long) func ) << 8ul); 279 break; 280 case 2: 281 if (device >= 16) break; 282 tag.cfg2.port = 0xc000 | (device << 8ul); 283 tag.cfg2.enable = 0xf1 | (func << 1ul); 284 tag.cfg2.forward = bus; 285 break; 286 }; 287 return tag; 288} |
254 | 289 290static pcici_t 291pcibus_ftag (pcici_t tag, u_char func) 292{ 293 switch (pci_mechanism) { 294 295 case 1: 296 tag.cfg1 &= ~0x700ul; 297 tag.cfg1 |= (((u_long) func) << 8ul); 298 break; 299 case 2: 300 tag.cfg2.enable = 0xf1 | (func << 1ul); 301 break; 302 }; 303 return tag; 304} 305 |
255/*-------------------------------------------------------------------- 256** 257** Read register from configuration space. 258** 259**-------------------------------------------------------------------- 260*/ 261 | 306/*-------------------------------------------------------------------- 307** 308** Read register from configuration space. 309** 310**-------------------------------------------------------------------- 311*/ 312 |
262 | |
263static u_long 264pcibus_read (pcici_t tag, u_long reg) 265{ 266 u_long addr, data = 0; 267 | 313static u_long 314pcibus_read (pcici_t tag, u_long reg) 315{ 316 u_long addr, data = 0; 317 |
318#ifdef DENTARO 319 u_int*p = findfake(tag); 320 if (p) { 321#if 0 322 printf ("fake conf_read (tag=%x reg=%d val=%08x).\n", 323 tag.tag, (unsigned) reg, (unsigned) p[reg/4]); 324#endif 325 return (p[reg/4]); 326 } 327#endif 328 |
|
268 if (!tag.cfg1) return (0xfffffffful); 269 | 329 if (!tag.cfg1) return (0xfffffffful); 330 |
270 switch (pci_mode) { | 331 switch (pci_mechanism) { |
271 272 case 1: 273 addr = tag.cfg1 | (reg & 0xfc); 274#ifdef PCI_DEBUG 275 printf ("pci_conf_read(1): addr=%x ", addr); 276#endif 277 outl (CONF1_ADDR_PORT, addr); 278 data = inl (CONF1_DATA_PORT); --- 16 unchanged lines hidden (view full) --- 295 }; 296 297#ifdef PCI_DEBUG 298 printf ("data=%x\n", data); 299#endif 300 301 return (data); 302} | 332 333 case 1: 334 addr = tag.cfg1 | (reg & 0xfc); 335#ifdef PCI_DEBUG 336 printf ("pci_conf_read(1): addr=%x ", addr); 337#endif 338 outl (CONF1_ADDR_PORT, addr); 339 data = inl (CONF1_DATA_PORT); --- 16 unchanged lines hidden (view full) --- 356 }; 357 358#ifdef PCI_DEBUG 359 printf ("data=%x\n", data); 360#endif 361 362 return (data); 363} |
303 | 364 |
304/*-------------------------------------------------------------------- 305** 306** Write register into configuration space. 307** 308**-------------------------------------------------------------------- 309*/ 310 | 365/*-------------------------------------------------------------------- 366** 367** Write register into configuration space. 368** 369**-------------------------------------------------------------------- 370*/ 371 |
311 | |
312static void 313pcibus_write (pcici_t tag, u_long reg, u_long data) 314{ 315 u_long addr; 316 | 372static void 373pcibus_write (pcici_t tag, u_long reg, u_long data) 374{ 375 u_long addr; 376 |
377#ifdef DENTARO 378 u_int*p = findfake(tag); 379 if (p) { 380#if 0 381 printf ("fake conf_write (tag=%x reg=%d val=%08x).\n", 382 tag.tag, (unsigned) reg, (unsigned) data); 383#endif 384 p[reg/4]=data; 385 return; 386 } 387#endif 388 |
|
317 if (!tag.cfg1) return; 318 | 389 if (!tag.cfg1) return; 390 |
319 switch (pci_mode) { | 391 switch (pci_mechanism) { |
320 321 case 1: 322 addr = tag.cfg1 | (reg & 0xfc); 323#ifdef PCI_DEBUG 324 printf ("pci_conf_write(1): addr=%x data=%x\n", 325 addr, data); 326#endif 327 outl (CONF1_ADDR_PORT, addr); --- 12 unchanged lines hidden (view full) --- 340 341 outl ((u_short) addr, data); 342 343 outb (CONF2_ENABLE_PORT, 0); 344 outb (CONF2_FORWARD_PORT, 0); 345 break; 346 }; 347} | 392 393 case 1: 394 addr = tag.cfg1 | (reg & 0xfc); 395#ifdef PCI_DEBUG 396 printf ("pci_conf_write(1): addr=%x data=%x\n", 397 addr, data); 398#endif 399 outl (CONF1_ADDR_PORT, addr); --- 12 unchanged lines hidden (view full) --- 412 413 outl ((u_short) addr, data); 414 415 outb (CONF2_ENABLE_PORT, 0); 416 outb (CONF2_FORWARD_PORT, 0); 417 break; 418 }; 419} |
348 | 420 |
349/*----------------------------------------------------------------------- 350** 351** Register an interupt handler for a pci device. 352** 353**----------------------------------------------------------------------- 354*/ 355 | 421/*----------------------------------------------------------------------- 422** 423** Register an interupt handler for a pci device. 424** 425**----------------------------------------------------------------------- 426*/ 427 |
356#ifndef __FreeBSD2__ 357/* 358 * Type of the first (asm) part of an interrupt handler. 359 */ 360typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); | 428static int 429pcibus_ihandler_attach (int irq, void(*func)(), int arg, unsigned * maskptr) 430{ 431 int result; 432 result = register_intr( 433 irq, /* isa irq */ 434 0, /* deviced?? */ 435 0, /* flags? */ 436 (inthand2_t*) func, /* handler */ 437 maskptr, /* mask pointer */ 438 arg); /* handler arg */ |
361 | 439 |
362/* 363 * Usual type of the second (C) part of an interrupt handler. Some bogus 364 * ones need the arg to be the interrupt frame (and not a copy of it, which 365 * is all that is possible in C). 366 */ 367typedef void inthand2_t __P((int unit)); | 440 if (result) { 441 printf ("@@@ pcibus_ihandler_attach: result=%d\n", result); 442 return (result); 443 }; 444 update_intr_masks(); |
368 | 445 |
369/* 370** XXX @FreeBSD2@ 371** 372** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD. 373** We would prefer a pointer because it enables us to install 374** new interrupt handlers at any time. 375** (This is just going to be changed ... <se> :) 376** In 2.0 FreeBSD later installed interrupt handlers may change 377** the xyz_imask, but this would not be recognized by handlers 378** which are installed before. 379*/ | 446 INTREN ((1ul<<irq)); 447 return (0); 448} |
380 381static int | 449 450static int |
382register_intr __P((int intr, int device_id, unsigned int flags, 383 inthand2_t *handler, unsigned int * mptr, int unit)); 384extern unsigned intr_mask[ICU_LEN]; | 451pcibus_ihandler_detach (int irq, void(*func)()) 452{ 453 int result; |
385 | 454 |
386#endif /* !__FreeBSD2__ */ 387static unsigned int pci_int_mask [16]; | 455 INTRDIS ((1ul<<irq)); |
388 | 456 |
389int pcibus_regint (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr) | 457 result = unregister_intr (irq, (inthand2_t*) func); 458 459 if (result) 460 printf ("@@@ pcibus_ihandler_detach: result=%d\n", result); 461 462 update_intr_masks(); 463 464 return (result); 465} 466 467static int 468pcibus_imask_include (int irq, unsigned* maskptr) |
390{ | 469{ |
391 int irq; 392 unsigned mask, oldmask; | 470 unsigned mask; |
393 | 471 |
394 irq = PCI_INTERRUPT_LINE_EXTRACT( 395 pci_conf_read (tag, PCI_INTERRUPT_REG)); | 472 if (!maskptr) return (0); |
396 397 mask = 1ul << irq; 398 | 473 474 mask = 1ul << irq; 475 |
399 if (!maskptr) 400 maskptr = &pci_int_mask[irq]; 401 oldmask = *maskptr; | 476 if (*maskptr & mask) 477 return (-1); |
402 403 INTRMASK (*maskptr, mask); | 478 479 INTRMASK (*maskptr, mask); |
480 update_intr_masks(); |
|
404 | 481 |
405 register_intr( 406 irq, /* isa irq */ 407 0, /* deviced?? */ 408 0, /* flags? */ 409 (inthand2_t*) func, /* handler */ 410 maskptr, /* mask pointer */ 411 (int) arg); /* handler arg */ | 482 return (0); 483} |
412 | 484 |
413#ifdef __FreeBSD2__ 414 /* 415 ** XXX See comment at beginning of file. 416 ** 417 ** Have to update all the interrupt masks ... Grrrrr!!! 418 */ 419 { 420 unsigned * mp = &intr_mask[0]; 421 /* 422 ** update the isa interrupt masks. 423 */ 424 for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++) 425 if ((~*mp & oldmask)==0) 426 *mp |= mask; 427 /* 428 ** update the pci interrupt masks. 429 */ 430 for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++) 431 if ((~*mp & oldmask)==0) 432 *mp |= mask; 433 }; 434#endif | 485static int 486pcibus_imask_exclude (int irq, unsigned* maskptr) 487{ 488 unsigned mask; |
435 | 489 |
436 INTREN (mask); | 490 if (!maskptr) return (0); |
437 | 491 |
438 return (1); | 492 mask = 1ul << irq; 493 494 if (! (*maskptr & mask)) 495 return (-1); 496 497 *maskptr &= ~mask; 498 update_intr_masks(); 499 500 return (0); |
439} | 501} |