root/arch/alpha/kernel/irq.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. disable_irq
  2. enable_irq
  3. get_irq_list
  4. ack_irq
  5. mask_irq
  6. unmask_irq
  7. request_irq
  8. free_irq
  9. handle_nmi
  10. unexpected_irq
  11. handle_irq
  12. device_interrupt
  13. isa_device_interrupt
  14. cabriolet_and_eb66p_device_interrupt
  15. eb66_and_eb64p_device_interrupt
  16. srm_device_interrupt
  17. probe_irq_on
  18. probe_irq_off
  19. machine_check
  20. do_entInt
  21. init_IRQ

   1 /*
   2  *      linux/arch/alpha/kernel/irq.c
   3  *
   4  *      Copyright (C) 1995 Linus Torvalds
   5  *
   6  * This file contains the code used by various IRQ handling routines:
   7  * asking for different IRQ's should be done through these routines
   8  * instead of just grabbing them. Thus setups with different IRQ numbers
   9  * shouldn't result in any weird surprises, and installing new handlers
  10  * should be easier.
  11  */
  12 
  13 #include <linux/config.h>
  14 #include <linux/ptrace.h>
  15 #include <linux/errno.h>
  16 #include <linux/kernel_stat.h>
  17 #include <linux/signal.h>
  18 #include <linux/sched.h>
  19 #include <linux/interrupt.h>
  20 #include <linux/random.h>
  21 
  22 #include <asm/system.h>
  23 #include <asm/io.h>
  24 #include <asm/irq.h>
  25 #include <asm/bitops.h>
  26 #include <asm/dma.h>
  27 
  28 extern void timer_interrupt(struct pt_regs * regs);
  29 
  30 static unsigned char cache_21 = 0xff;
  31 static unsigned char cache_A1 = 0xff;
  32 
  33 #if NR_IRQS == 33
  34   static unsigned char cache_804 = 0xef;
  35   static unsigned char cache_805 = 0xff;
  36   static unsigned char cache_806 = 0xff;
  37 #elif NR_IRQS == 32
  38   static unsigned char cache_26 = 0xdf;
  39   static unsigned char cache_27 = 0xff;
  40 #endif
  41 
  42 void disable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         unsigned long flags;
  45         unsigned char mask;
  46 
  47         save_flags(flags);
  48         cli();
  49         mask = 1 << (irq_nr & 7);
  50 
  51         if (irq_nr < 8) {
  52                 cache_21 |= mask;
  53                 outb(cache_21,0x21);
  54         } else if (irq_nr < 16) {
  55                 cache_A1 |= mask;
  56                 outb(cache_A1,0xA1);
  57 #if NR_IRQS == 33
  58         } else if (irq_nr < 24) {
  59                 cache_804 |= mask;
  60                 outb(cache_804, 0x804);
  61         } else if (irq_nr < 32) {
  62                 cache_805 |= mask;
  63                 outb(cache_805, 0x805);
  64         } else {
  65                 cache_806 |= mask;
  66                 outb(cache_806, 0x806);
  67 #elif NR_IRQS == 32 
  68         } else if (irq_nr < 24) {
  69                 cache_26 |= mask;
  70                 outb(cache_26, 0x26);
  71         } else {
  72                 cache_27 |= mask;
  73                 outb(cache_27, 0x27);
  74 #endif
  75         }
  76         restore_flags(flags);
  77 }
  78 
  79 void enable_irq(unsigned int irq_nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         unsigned long flags;
  82         unsigned char mask;
  83 
  84         mask = ~(1 << (irq_nr & 7));
  85         save_flags(flags);
  86         cli();
  87 
  88         if (irq_nr < 8) {
  89                 cache_21 &= mask;
  90                 outb(cache_21,0x21);
  91         } else if (irq_nr < 16) {
  92                 cache_A1 &= mask;
  93                 outb(cache_A1,0xA1);
  94 #if NR_IRQS == 33
  95         } else if (irq_nr < 24) {
  96                 cache_804 &= mask;
  97                 outb(cache_804, 0x804);
  98         } else if (irq_nr < 32) {
  99                 cache_805 &= mask;
 100                 outb(cache_805, 0x805);
 101         } else {
 102                 cache_806 &= mask;
 103                 outb(cache_806, 0x806);
 104 #elif NR_IRQS == 32
 105         } else if (irq_nr < 24) {
 106                 cache_26 &= mask;
 107                 outb(cache_26, 0x26);
 108         } else {
 109                 cache_27 &= mask;
 110                 outb(cache_27, 0x27);
 111 #endif
 112         }
 113         restore_flags(flags);
 114 }
 115 
 116 /*
 117  * Initial irq handlers.
 118  */
 119 struct irqaction {
 120         void (*handler)(int, struct pt_regs *);
 121         unsigned long flags;
 122         unsigned long mask;
 123         const char *name;
 124 };
 125 
 126 static struct irqaction irq_action[NR_IRQS];
 127 
 128 int get_irq_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         int i, len = 0;
 131         struct irqaction * action = irq_action;
 132 
 133         for (i = 0 ; i < NR_IRQS ; i++, action++) {
 134                 if (!action->handler)
 135                         continue;
 136                 len += sprintf(buf+len, "%2d: %8d %c %s\n",
 137                         i, kstat.interrupts[i],
 138                         (action->flags & SA_INTERRUPT) ? '+' : ' ',
 139                         action->name);
 140         }
 141         return len;
 142 }
 143 
 144 static inline void ack_irq(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146         if (irq < 16) {
 147                 /* ACK the interrupt making it the lowest priority */
 148                 /*  First the slave .. */
 149                 if (irq > 7) {
 150                         outb(0xE0 | (irq - 8), 0xa0);
 151                         irq = 2;
 152                 }
 153                 /* .. then the master */
 154                 outb(0xE0 | irq, 0x20);
 155         }
 156 }
 157 
 158 static inline void mask_irq(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         unsigned char mask;
 161 
 162         mask = 1 << (irq & 7);
 163         if (irq < 8) {
 164                 cache_21 |= mask;
 165                 outb(cache_21, 0x21);
 166         } else if (irq < 16) {
 167                 cache_A1 |= mask;
 168                 outb(cache_A1, 0xA1);
 169 #if NR_IRQS == 33
 170         } else if (irq < 24) {
 171                 cache_804 |= mask;
 172                 outb(cache_804, 0x804);
 173         } else if (irq < 32) {
 174                 cache_805 |= mask;
 175                 outb(cache_805, 0x805);
 176         } else {
 177                 cache_806 |= mask;
 178                 outb(cache_806, 0x806);
 179 #elif NR_IRQS == 32
 180         } else if (irq < 24) {
 181                 cache_26 |= mask;
 182                 outb(cache_26, 0x26);
 183         } else {
 184                 cache_27 |= mask;
 185                 outb(cache_27, 0x27);
 186 #endif
 187         }
 188 }
 189 
 190 static inline void unmask_irq(unsigned long irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         unsigned char mask = ~(1 << (irq & 7));
 193 
 194         if (irq < 8) {
 195                 cache_21 &= mask;
 196                 outb(cache_21, 0x21);
 197         } else if (irq < 16) {
 198                 cache_A1 &= mask;
 199                 outb(cache_A1, 0xA1);
 200 #if NR_IRQS == 33
 201         } else if (irq < 24) {
 202                 cache_804 &= mask;
 203                 outb(cache_804, 0x804);
 204         } else if (irq < 32) {
 205                 cache_805 &= mask;
 206                 outb(cache_805, 0x805);
 207         } else {
 208                 cache_806 &= mask;
 209                 outb(cache_806, 0x806);
 210 #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P)
 211         } else if (irq < 24) {
 212                 cache_26 &= mask;
 213                 outb(cache_26, 0x26);
 214         } else {
 215                 cache_27 &= mask;
 216                 outb(cache_27, 0x27);
 217 #endif
 218         }
 219 }
 220 
 221 int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
     /* [previous][next][first][last][top][bottom][index][help] */
 222         unsigned long irqflags, const char * devname)
 223 {
 224         struct irqaction * action;
 225         unsigned long flags;
 226 
 227         if (irq >= NR_IRQS)
 228                 return -EINVAL;
 229         /* don't accept requests for irq #0 */
 230         if (!irq)
 231                 return -EINVAL;
 232         action = irq + irq_action;
 233         if (action->handler)
 234                 return -EBUSY;
 235         if (!handler)
 236                 return -EINVAL;
 237         save_flags(flags);
 238         cli();
 239         action->handler = handler;
 240         action->flags = irqflags;
 241         action->mask = 0;
 242         action->name = devname;
 243         enable_irq(irq);
 244         if (irq >= 8 && irq < 16) {
 245                 enable_irq(2);  /* ensure cascade is enabled too */
 246         }
 247         restore_flags(flags);
 248         return 0;
 249 }
 250 
 251 void free_irq(unsigned int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 252 {
 253         struct irqaction * action = irq + irq_action;
 254         unsigned long flags;
 255 
 256         if (irq >= NR_IRQS) {
 257                 printk("Trying to free IRQ%d\n", irq);
 258                 return;
 259         }
 260         if (!action->handler) {
 261                 printk("Trying to free free IRQ%d\n", irq);
 262                 return;
 263         }
 264         save_flags(flags);
 265         cli();
 266         mask_irq(irq);
 267         action->handler = NULL;
 268         action->flags = 0;
 269         action->mask = 0;
 270         action->name = NULL;
 271         restore_flags(flags);
 272 }
 273 
 274 static inline void handle_nmi(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276         printk("Whee.. NMI received. Probable hardware error\n");
 277         printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
 278 }
 279 
 280 static void unexpected_irq(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         int i;
 283 
 284         printk("IO device interrupt, irq = %d\n", irq);
 285         printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
 286         printk("Expecting: ");
 287         for (i = 0; i < 16; i++)
 288                 if (irq_action[i].handler)
 289                         printk("[%s:%d] ", irq_action[i].name, i);
 290         printk("\n");
 291 #if defined(CONFIG_ALPHA_JENSEN)
 292         printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
 293                 inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
 294         outb(0x0c, 0x3fc);
 295         outb(0x0c, 0x2fc);
 296         outb(0,0x61);
 297         outb(0,0x461);
 298 #endif
 299 }
 300 
 301 static inline void handle_irq(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 302 {
 303         struct irqaction * action = irq + irq_action;
 304 
 305         kstat.interrupts[irq]++;
 306         if (!action->handler) {
 307                 unexpected_irq(irq, regs);
 308                 return;
 309         }
 310         action->handler(irq, regs);
 311 }
 312 
 313 static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 314 {
 315         struct irqaction * action;
 316 
 317         if ((unsigned) irq > NR_IRQS) {
 318                 printk("device_interrupt: unexpected interrupt %d\n", irq);
 319                 return;
 320         }
 321 
 322         kstat.interrupts[irq]++;
 323         action = irq_action + irq;
 324         if (action->flags & SA_SAMPLE_RANDOM)
 325                 add_interrupt_randomness(irq);
 326         /* quick interrupts get executed with no extra overhead */
 327         if (action->flags & SA_INTERRUPT) {
 328                 action->handler(irq, regs);
 329                 ack_irq(ack);
 330                 return;
 331         }
 332         /*
 333          * For normal interrupts, we mask it out, and then ACK it.
 334          * This way another (more timing-critical) interrupt can
 335          * come through while we're doing this one.
 336          *
 337          * Note! A irq without a handler gets masked and acked, but
 338          * never unmasked. The autoirq stuff depends on this (it looks
 339          * at the masks before and after doing the probing).
 340          */
 341         mask_irq(ack);
 342         ack_irq(ack);
 343         if (!action->handler)
 344                 return;
 345         action->handler(irq, regs);
 346         unmask_irq(ack);
 347 }
 348 
 349 /*
 350  * Handle ISA interrupt via the PICs.
 351  */
 352 static inline void isa_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 353                                         struct pt_regs * regs)
 354 {
 355 #if defined(CONFIG_ALPHA_APECS)
 356 #       define IACK_SC  APECS_IACK_SC
 357 #elif defined(CONFIG_ALPHA_LCA)
 358 #       define IACK_SC  LCA_IACK_SC
 359 #else
 360         /*
 361          * This is bogus but necessary to get it to compile
 362          * on all platforms.  If you try to use this on any
 363          * other than the intended platforms, you'll notice
 364          * real fast...
 365          */
 366 #       define IACK_SC  1L
 367 #endif
 368         int j;
 369 
 370         /*
 371          * Generate a PCI interrupt acknowledge cycle.  The PIC will
 372          * respond with the interrupt vector of the highest priority
 373          * interrupt that is pending.  The PALcode sets up the
 374          * interrupts vectors such that irq level L generates vector
 375          * L.
 376          */
 377         j = *(volatile int *) IACK_SC;
 378         j &= 0xff;
 379         if (j == 7) {
 380             if (!(inb(0x20) & 0x80)) {
 381                 /* it's only a passive release... */
 382                 return;
 383             }
 384         }
 385         device_interrupt(j, j, regs);
 386 #if 0
 387         unsigned long pic;
 388 
 389         /*
 390          * It seems to me that the probability of two or more *device*
 391          * interrupts occuring at almost exactly the same time is
 392          * pretty low.  So why pay the price of checking for
 393          * additional interrupts here if the common case can be
 394          * handled so much easier?
 395          */
 396         /* 
 397          *  The first read of gives you *all* interrupting lines.
 398          *  Therefore, read the mask register and and out those lines
 399          *  not enabled.  Note that some documentation has 21 and a1 
 400          *  write only.  This is not true.
 401          */
 402         pic = inb(0x20) | (inb(0xA0) << 8);     /* read isr */
 403         pic &= ~((cache_A1 << 8) | cache_21);   /* apply mask */
 404         pic &= 0xFFFB;                          /* mask out cascade */
 405 
 406         while (pic) {
 407                 j = ffz(~pic);
 408                 pic &= pic - 1;
 409                 device_interrupt(j, j, regs);
 410         }
 411 #endif
 412 }
 413 
 414 static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 415                                                         struct pt_regs * regs)
 416 {
 417         unsigned long pld;
 418         unsigned int i;
 419         unsigned long flags;
 420 
 421         save_flags(flags);
 422         cli();
 423 
 424         /* read the interrupt summary registers */
 425         pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
 426 
 427         /*
 428          * Now for every possible bit set, work through them and call
 429          * the appropriate interrupt handler.
 430          */
 431         while (pld) {
 432                 i = ffz(~pld);
 433                 pld &= pld - 1; /* clear least bit set */
 434                 if (i == 4) {
 435                         isa_device_interrupt(vector, regs);
 436                 } else {
 437                         device_interrupt(16 + i, 16 + i, regs);
 438                 }
 439         }
 440         restore_flags(flags);
 441 }
 442 
 443 static inline void eb66_and_eb64p_device_interrupt(unsigned long vector,
     /* [previous][next][first][last][top][bottom][index][help] */
 444                                                    struct pt_regs * regs)
 445 {
 446         unsigned long pld;
 447         unsigned int i;
 448         unsigned long flags;
 449 
 450         save_flags(flags);
 451         cli();
 452 
 453         /* read the interrupt summary registers */
 454         pld = inb(0x26) | (inb(0x27) << 8);
 455         /*
 456          * Now, for every possible bit set, work through
 457          * them and call the appropriate interrupt handler.
 458          */
 459         while (pld) {
 460                 i = ffz(~pld);
 461                 pld &= pld - 1; /* clear least bit set */
 462 
 463                 if (i == 5) {
 464                         isa_device_interrupt(vector, regs);
 465                 } else {
 466                         device_interrupt(16 + i, 16 + i, regs);
 467                 }
 468         }
 469         restore_flags(flags);
 470 }
 471 
 472 /*
 473  * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
 474  * 0x9X0 for the local motherboard interrupts..
 475  *
 476  *      0x660 - NMI
 477  *
 478  *      0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
 479  *      0x810 - IRQ1  line printer (duh..)
 480  *      0x860 - IRQ6  floppy disk
 481  *      0x8E0 - IRQ14 SCSI controller
 482  *
 483  *      0x900 - COM1
 484  *      0x920 - COM2
 485  *      0x980 - keyboard
 486  *      0x990 - mouse
 487  *
 488  * PCI-based systems are more sane: they don't have the local
 489  * interrupts at all, and have only normal PCI interrupts from
 490  * devices.  Happily it's easy enough to do a sane mapping from the
 491  * Jensen..  Note that this means that we may have to do a hardware
 492  * "ack" to a different interrupt than we report to the rest of the
 493  * world.
 494  */
 495 static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 496 {
 497         int irq, ack;
 498 
 499         ack = irq = (vector - 0x800) >> 4;
 500 
 501 #ifdef CONFIG_ALPHA_JENSEN
 502         switch (vector) {
 503               case 0x660: handle_nmi(regs); return;
 504                 /* local device interrupts: */
 505               case 0x900: handle_irq(4, regs); return;  /* com1 -> irq 4 */
 506               case 0x920: handle_irq(3, regs); return;  /* com2 -> irq 3 */
 507               case 0x980: handle_irq(1, regs); return;  /* kbd -> irq 1 */
 508               case 0x990: handle_irq(9, regs); return;  /* mouse -> irq 9 */
 509               default:
 510                 if (vector > 0x900) {
 511                         printk("Unknown local interrupt %lx\n", vector);
 512                 }
 513         }
 514         /* irq1 is supposed to be the keyboard, silly Jensen (is this really needed??) */
 515         if (irq == 1)
 516                 irq = 7;
 517 #endif /* CONFIG_ALPHA_JENSEN */
 518 
 519         device_interrupt(irq, ack, regs);
 520 }
 521 
 522 #if NR_IRQS > 64
 523 #  error Number of irqs limited to 64 due to interrupt-probing.
 524 #endif
 525 
 526 /*
 527  * Start listening for interrupts..
 528  */
 529 unsigned long probe_irq_on(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531         unsigned long irqs = 0, irqmask;
 532         unsigned long delay;
 533         unsigned int i;
 534 
 535         for (i = NR_IRQS - 1; i > 0; i--) {
 536                 if (!irq_action[i].handler) {
 537                         enable_irq(i);
 538                         irqs |= (1 << i);
 539                 }
 540         }
 541 
 542         /* wait for spurious interrupts to mask themselves out again */
 543         for (delay = jiffies + HZ/10; delay > jiffies; )
 544                 /* about 100 ms delay */;
 545         
 546         /* now filter out any obviously spurious interrupts */
 547         irqmask = (((unsigned long)cache_A1)<<8) | (unsigned long) cache_21;
 548 #if NR_IRQS == 33
 549         irqmask |= ((((unsigned long)cache_804)<<16) |
 550                     (((unsigned long)cache_805)<<24) |
 551                     (((unsigned long)cache_806)<<24));
 552 #elif NR_IRQS == 32
 553         irqmask |= ((((unsigned long)cache_26)<<16) |
 554                     (((unsigned long)cache_27)<<24));
 555 #endif
 556         irqs &= ~irqmask;
 557         return irqs;
 558 }
 559 
 560 /*
 561  * Get the result of the IRQ probe.. A negative result means that
 562  * we have several candidates (but we return the lowest-numbered
 563  * one).
 564  */
 565 int probe_irq_off(unsigned long irqs)
     /* [previous][next][first][last][top][bottom][index][help] */
 566 {
 567         unsigned long irqmask;
 568         int i;
 569         
 570         irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
 571 #if NR_IRQS == 33
 572         irqmask |= ((((unsigned long)cache_804)<<16) |
 573                     (((unsigned long)cache_805)<<24) |
 574                     (((unsigned long)cache_806)<<24));
 575 #elif NR_IRQS == 32
 576         irqmask |= ((((unsigned long)cache_26)<<16) |
 577                     (((unsigned long)cache_27)<<24));
 578 #endif
 579         irqs &= irqmask & ~1;   /* always mask out irq 0---it's the unused timer */
 580         if (!irqs)
 581                 return 0;
 582         i = ffz(~irqs);
 583         if (irqs != (1UL << i))
 584                 i = -i;
 585         return i;
 586 }
 587 
 588 static void machine_check(unsigned long vector, unsigned long la, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 589 {
 590 #if defined(CONFIG_ALPHA_LCA)
 591         extern void lca_machine_check (unsigned long vector, unsigned long la,
 592                                        struct pt_regs *regs);
 593         lca_machine_check(vector, la, regs);
 594 #elif defined(CONFIG_ALPHA_APECS)
 595         extern void apecs_machine_check(unsigned long vector, unsigned long la,
 596                                         struct pt_regs * regs);
 597         apecs_machine_check(vector, la, regs);
 598 #else
 599         printk("Machine check\n");
 600 #endif
 601 }
 602 
 603 asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
     /* [previous][next][first][last][top][bottom][index][help] */
 604         unsigned long a3, unsigned long a4, unsigned long a5,
 605         struct pt_regs regs)
 606 {
 607         switch (type) {
 608                 case 0:
 609                         printk("Interprocessor interrupt? You must be kidding\n");
 610                         break;
 611                 case 1:
 612                         timer_interrupt(&regs);
 613                         return;
 614                 case 2:
 615                         machine_check(vector, la_ptr, &regs);
 616                         return;
 617                 case 3:
 618 #if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_ALPHA_NONAME) || \
 619     defined(CONFIG_ALPHA_SRM)
 620                         srm_device_interrupt(vector, &regs);
 621 #elif NR_IRQS == 33
 622                         cabriolet_and_eb66p_device_interrupt(vector, &regs);
 623 #elif NR_IRQS == 32
 624                         eb66_and_eb64p_device_interrupt(vector, &regs);
 625 #endif
 626                         return;
 627                 case 4:
 628                         printk("Performance counter interrupt\n");
 629                         break;;
 630                 default:
 631                         printk("Hardware intr %ld %lx? Huh?\n", type, vector);
 632         }
 633         printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps);
 634 }
 635 
 636 extern asmlinkage void entInt(void);
 637 
 638 void init_IRQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640         wrent(entInt, 0);
 641         dma_outb(0, DMA1_RESET_REG);
 642         dma_outb(0, DMA2_RESET_REG);
 643         dma_outb(0, DMA1_CLR_MASK_REG);
 644         dma_outb(0, DMA2_CLR_MASK_REG);
 645 #if NR_IRQS == 33
 646         outb(cache_804, 0x804);
 647         outb(cache_805, 0x805);
 648         outb(cache_806, 0x806);
 649 #elif NR_IRQS == 32
 650         outb(cache_26, 0x26);
 651         outb(cache_27, 0x27);
 652 #endif
 653 }

/* [previous][next][first][last][top][bottom][index][help] */