]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/x86/isa/atpic.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / x86 / isa / atpic.c
1 /*-
2  * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of any co-contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /*
31  * PIC driver for the 8259A Master and Slave PICs in PC/AT machines.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_auto_eoi.h"
38 #include "opt_isa.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/bus.h>
43 #include <sys/interrupt.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/module.h>
47
48 #include <machine/cpufunc.h>
49 #include <machine/frame.h>
50 #include <machine/intr_machdep.h>
51 #include <machine/md_var.h>
52 #include <machine/resource.h>
53 #include <machine/segments.h>
54
55 #include <dev/ic/i8259.h>
56 #ifdef __amd64__
57 #include <amd64/isa/icu.h>
58 #include <amd64/isa/isa.h>
59 #else
60 #include <i386/isa/icu.h>
61 #ifdef PC98
62 #include <pc98/cbus/cbus.h>
63 #else
64 #include <i386/isa/isa.h>
65 #endif
66 #endif
67 #include <isa/isavar.h>
68
69 #ifdef __amd64__
70 #define SDT_ATPIC       SDT_SYSIGT
71 #define GSEL_ATPIC      0
72 #else
73 #define SDT_ATPIC       SDT_SYS386IGT
74 #define GSEL_ATPIC      GSEL(GCODE_SEL, SEL_KPL)
75 #endif
76
77 #define MASTER  0
78 #define SLAVE   1
79
80 /*
81  * PC-98 machines wire the slave 8259A to pin 7 on the master PIC, and
82  * PC-AT machines wire the slave PIC to pin 2 on the master PIC.
83  */
84 #ifdef PC98
85 #define ICU_SLAVEID     7
86 #else
87 #define ICU_SLAVEID     2
88 #endif
89
90 /*
91  * Determine the base master and slave modes not including auto EOI support.
92  * All machines that FreeBSD supports use 8086 mode.
93  */
94 #ifdef PC98
95 /*
96  * PC-98 machines do not support auto EOI on the second PIC.  Also, it
97  * seems that PC-98 machine PICs use buffered mode, and the master PIC
98  * uses special fully nested mode.
99  */
100 #define BASE_MASTER_MODE        (ICW4_SFNM | ICW4_BUF | ICW4_MS | ICW4_8086)
101 #define BASE_SLAVE_MODE         (ICW4_BUF | ICW4_8086)
102 #else
103 #define BASE_MASTER_MODE        ICW4_8086
104 #define BASE_SLAVE_MODE         ICW4_8086
105 #endif
106
107 /* Enable automatic EOI if requested. */
108 #ifdef AUTO_EOI_1
109 #define MASTER_MODE             (BASE_MASTER_MODE | ICW4_AEOI)
110 #else
111 #define MASTER_MODE             BASE_MASTER_MODE
112 #endif
113 #ifdef AUTO_EOI_2
114 #define SLAVE_MODE              (BASE_SLAVE_MODE | ICW4_AEOI)
115 #else
116 #define SLAVE_MODE              BASE_SLAVE_MODE
117 #endif
118
119 #define IRQ_MASK(irq)           (1 << (irq))
120 #define IMEN_MASK(ai)           (IRQ_MASK((ai)->at_irq))
121
122 #define NUM_ISA_IRQS            16
123
124 static void     atpic_init(void *dummy);
125
126 unsigned int imen;      /* XXX */
127
128 inthand_t
129         IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
130         IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
131         IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
132         IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11),
133         IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14),
134         IDTVEC(atpic_intr15);
135
136 #define IRQ(ap, ai)     ((ap)->at_irqbase + (ai)->at_irq)
137
138 #define ATPIC(io, base, eoi, imenptr)                                   \
139         { { atpic_enable_source, atpic_disable_source, (eoi),           \
140             atpic_enable_intr, atpic_disable_intr, atpic_vector,        \
141             atpic_source_pending, NULL, atpic_resume, atpic_config_intr,\
142             atpic_assign_cpu }, (io), (base), IDT_IO_INTS + (base),     \
143             (imenptr) }
144
145 #define INTSRC(irq)                                                     \
146         { { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ),    \
147             (irq) % 8 }
148
149 struct atpic {
150         struct pic at_pic;
151         int     at_ioaddr;
152         int     at_irqbase;
153         uint8_t at_intbase;
154         uint8_t *at_imen;
155 };
156
157 struct atpic_intsrc {
158         struct intsrc at_intsrc;
159         inthand_t *at_intr;
160         int     at_irq;                 /* Relative to PIC base. */
161         enum intr_trigger at_trigger;
162         u_long  at_count;
163         u_long  at_straycount;
164 };
165
166 static void atpic_enable_source(struct intsrc *isrc);
167 static void atpic_disable_source(struct intsrc *isrc, int eoi);
168 static void atpic_eoi_master(struct intsrc *isrc);
169 static void atpic_eoi_slave(struct intsrc *isrc);
170 static void atpic_enable_intr(struct intsrc *isrc);
171 static void atpic_disable_intr(struct intsrc *isrc);
172 static int atpic_vector(struct intsrc *isrc);
173 static void atpic_resume(struct pic *pic);
174 static int atpic_source_pending(struct intsrc *isrc);
175 static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
176     enum intr_polarity pol);
177 static int atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
178 static void i8259_init(struct atpic *pic, int slave);
179
180 static struct atpic atpics[] = {
181         ATPIC(IO_ICU1, 0, atpic_eoi_master, (uint8_t *)&imen),
182         ATPIC(IO_ICU2, 8, atpic_eoi_slave, ((uint8_t *)&imen) + 1)
183 };
184
185 static struct atpic_intsrc atintrs[] = {
186         INTSRC(0),
187         INTSRC(1),
188         INTSRC(2),
189         INTSRC(3),
190         INTSRC(4),
191         INTSRC(5),
192         INTSRC(6),
193         INTSRC(7),
194         INTSRC(8),
195         INTSRC(9),
196         INTSRC(10),
197         INTSRC(11),
198         INTSRC(12),
199         INTSRC(13),
200         INTSRC(14),
201         INTSRC(15),
202 };
203
204 CTASSERT(sizeof(atintrs) / sizeof(atintrs[0]) == NUM_ISA_IRQS);
205
206 static __inline void
207 _atpic_eoi_master(struct intsrc *isrc)
208 {
209
210         KASSERT(isrc->is_pic == &atpics[MASTER].at_pic,
211             ("%s: mismatched pic", __func__));
212 #ifndef AUTO_EOI_1
213         outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
214 #endif
215 }
216
217 /*
218  * The data sheet says no auto-EOI on slave, but it sometimes works.
219  * So, if AUTO_EOI_2 is enabled, we use it.
220  */
221 static __inline void
222 _atpic_eoi_slave(struct intsrc *isrc)
223 {
224
225         KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic,
226             ("%s: mismatched pic", __func__));
227 #ifndef AUTO_EOI_2
228         outb(atpics[SLAVE].at_ioaddr, OCW2_EOI);
229 #ifndef AUTO_EOI_1
230         outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
231 #endif
232 #endif
233 }
234
235 static void
236 atpic_enable_source(struct intsrc *isrc)
237 {
238         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
239         struct atpic *ap = (struct atpic *)isrc->is_pic;
240
241         spinlock_enter();
242         if (*ap->at_imen & IMEN_MASK(ai)) {
243                 *ap->at_imen &= ~IMEN_MASK(ai);
244                 outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
245         }
246         spinlock_exit();
247 }
248
249 static void
250 atpic_disable_source(struct intsrc *isrc, int eoi)
251 {
252         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
253         struct atpic *ap = (struct atpic *)isrc->is_pic;
254
255         spinlock_enter();
256         if (ai->at_trigger != INTR_TRIGGER_EDGE) {
257                 *ap->at_imen |= IMEN_MASK(ai);
258                 outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
259         }
260
261         /*
262          * Take care to call these functions directly instead of through
263          * a function pointer.  All of the referenced variables should
264          * still be hot in the cache.
265          */
266         if (eoi == PIC_EOI) {
267                 if (isrc->is_pic == &atpics[MASTER].at_pic)
268                         _atpic_eoi_master(isrc);
269                 else
270                         _atpic_eoi_slave(isrc);
271         }
272
273         spinlock_exit();
274 }
275
276 static void
277 atpic_eoi_master(struct intsrc *isrc)
278 {
279 #ifndef AUTO_EOI_1
280         spinlock_enter();
281         _atpic_eoi_master(isrc);
282         spinlock_exit();
283 #endif
284 }
285
286 static void
287 atpic_eoi_slave(struct intsrc *isrc)
288 {
289 #ifndef AUTO_EOI_2
290         spinlock_enter();
291         _atpic_eoi_slave(isrc);
292         spinlock_exit();
293 #endif
294 }
295
296 static void
297 atpic_enable_intr(struct intsrc *isrc)
298 {
299 }
300
301 static void
302 atpic_disable_intr(struct intsrc *isrc)
303 {
304 }
305
306
307 static int
308 atpic_vector(struct intsrc *isrc)
309 {
310         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
311         struct atpic *ap = (struct atpic *)isrc->is_pic;
312
313         return (IRQ(ap, ai));
314 }
315
316 static int
317 atpic_source_pending(struct intsrc *isrc)
318 {
319         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
320         struct atpic *ap = (struct atpic *)isrc->is_pic;
321
322         return (inb(ap->at_ioaddr) & IMEN_MASK(ai));
323 }
324
325 static void
326 atpic_resume(struct pic *pic)
327 {
328         struct atpic *ap = (struct atpic *)pic;
329
330         i8259_init(ap, ap == &atpics[SLAVE]);
331 #ifndef PC98
332         if (ap == &atpics[SLAVE] && elcr_found)
333                 elcr_resume();
334 #endif
335 }
336
337 static int
338 atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
339     enum intr_polarity pol)
340 {
341         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
342         u_int vector;
343
344         /* Map conforming values to edge/hi and sanity check the values. */
345         if (trig == INTR_TRIGGER_CONFORM)
346                 trig = INTR_TRIGGER_EDGE;
347         if (pol == INTR_POLARITY_CONFORM)
348                 pol = INTR_POLARITY_HIGH;
349         vector = atpic_vector(isrc);
350         if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) ||
351             (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) {
352                 printf(
353                 "atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n",
354                     vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level",
355                     pol == INTR_POLARITY_HIGH ? "high" : "low");
356                 return (EINVAL);
357         }
358
359         /* If there is no change, just return. */
360         if (ai->at_trigger == trig)
361                 return (0);
362
363 #ifdef PC98
364         if ((vector == 0 || vector == 1 || vector == 7 || vector == 8) &&
365             trig == INTR_TRIGGER_LEVEL) {
366                 if (bootverbose)
367                         printf(
368                 "atpic: Ignoring invalid level/low configuration for IRQ%u\n",
369                             vector);
370                 return (EINVAL);
371         }
372         return (ENXIO);
373 #else
374         /*
375          * Certain IRQs can never be level/lo, so don't try to set them
376          * that way if asked.  At least some ELCR registers ignore setting
377          * these bits as well.
378          */
379         if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) &&
380             trig == INTR_TRIGGER_LEVEL) {
381                 if (bootverbose)
382                         printf(
383                 "atpic: Ignoring invalid level/low configuration for IRQ%u\n",
384                             vector);
385                 return (EINVAL);
386         }
387         if (!elcr_found) {
388                 if (bootverbose)
389                         printf("atpic: No ELCR to configure IRQ%u as %s\n",
390                             vector, trig == INTR_TRIGGER_EDGE ? "edge/high" :
391                             "level/low");
392                 return (ENXIO);
393         }
394         if (bootverbose)
395                 printf("atpic: Programming IRQ%u as %s\n", vector,
396                     trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low");
397         spinlock_enter();
398         elcr_write_trigger(atpic_vector(isrc), trig);
399         ai->at_trigger = trig;
400         spinlock_exit();
401         return (0);
402 #endif /* PC98 */
403 }
404
405 static int
406 atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
407 {
408
409         /*
410          * 8259A's are only used in UP in which case all interrupts always
411          * go to the sole CPU and this function shouldn't even be called.
412          */
413         panic("%s: bad cookie", __func__);
414 }
415
416 static void
417 i8259_init(struct atpic *pic, int slave)
418 {
419         int imr_addr;
420
421         /* Reset the PIC and program with next four bytes. */
422         spinlock_enter();
423 #ifdef DEV_MCA
424         /* MCA uses level triggered interrupts. */
425         if (MCA_system)
426                 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4 | ICW1_LTIM);
427         else
428 #endif
429                 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4);
430         imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
431
432         /* Start vector. */
433         outb(imr_addr, pic->at_intbase);
434
435         /*
436          * Setup slave links.  For the master pic, indicate what line
437          * the slave is configured on.  For the slave indicate
438          * which line on the master we are connected to.
439          */
440         if (slave)
441                 outb(imr_addr, ICU_SLAVEID);
442         else
443                 outb(imr_addr, IRQ_MASK(ICU_SLAVEID));
444
445         /* Set mode. */
446         if (slave)
447                 outb(imr_addr, SLAVE_MODE);
448         else
449                 outb(imr_addr, MASTER_MODE);
450
451         /* Set interrupt enable mask. */
452         outb(imr_addr, *pic->at_imen);
453
454         /* Reset is finished, default to IRR on read. */
455         outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR);
456
457 #ifndef PC98
458         /* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */
459         if (!slave)
460                 outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1);
461 #endif
462         spinlock_exit();
463 }
464
465 void
466 atpic_startup(void)
467 {
468         struct atpic_intsrc *ai;
469         int i;
470
471         /* Start off with all interrupts disabled. */
472         imen = 0xffff;
473         i8259_init(&atpics[MASTER], 0);
474         i8259_init(&atpics[SLAVE], 1);
475         atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
476
477         /* Install low-level interrupt handlers for all of our IRQs. */
478         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
479                 if (i == ICU_SLAVEID)
480                         continue;
481                 ai->at_intsrc.is_count = &ai->at_count;
482                 ai->at_intsrc.is_straycount = &ai->at_straycount;
483                 setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
484                     ai->at_irq, ai->at_intr, SDT_ATPIC, SEL_KPL, GSEL_ATPIC);
485         }
486
487 #ifdef DEV_MCA
488         /* For MCA systems, all interrupts are level triggered. */
489         if (MCA_system)
490                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
491                         ai->at_trigger = INTR_TRIGGER_LEVEL;
492         else
493 #endif
494
495 #ifdef PC98
496         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
497                 switch (i) {
498                 case 0:
499                 case 1:
500                 case 7:
501                 case 8:
502                         ai->at_trigger = INTR_TRIGGER_EDGE;
503                         break;
504                 default:
505                         ai->at_trigger = INTR_TRIGGER_LEVEL;
506                         break;
507                 }
508 #else
509         /*
510          * Look for an ELCR.  If we find one, update the trigger modes.
511          * If we don't find one, assume that IRQs 0, 1, 2, and 13 are
512          * edge triggered and that everything else is level triggered.
513          * We only use the trigger information to reprogram the ELCR if
514          * we have one and as an optimization to avoid masking edge
515          * triggered interrupts.  For the case that we don't have an ELCR,
516          * it doesn't hurt to mask an edge triggered interrupt, so we
517          * assume level trigger for any interrupt that we aren't sure is
518          * edge triggered.
519          */
520         if (elcr_found) {
521                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
522                         ai->at_trigger = elcr_read_trigger(i);
523         } else {
524                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
525                         switch (i) {
526                         case 0:
527                         case 1:
528                         case 2:
529                         case 8:
530                         case 13:
531                                 ai->at_trigger = INTR_TRIGGER_EDGE;
532                                 break;
533                         default:
534                                 ai->at_trigger = INTR_TRIGGER_LEVEL;
535                                 break;
536                         }
537         }
538 #endif /* PC98 */
539 }
540
541 static void
542 atpic_init(void *dummy __unused)
543 {
544         struct atpic_intsrc *ai;
545         int i;
546
547         /*
548          * Register our PICs, even if we aren't going to use any of their
549          * pins so that they are suspended and resumed.
550          */
551         if (intr_register_pic(&atpics[0].at_pic) != 0 ||
552             intr_register_pic(&atpics[1].at_pic) != 0)
553                 panic("Unable to register ATPICs");
554
555         /*
556          * If any of the ISA IRQs have an interrupt source already, then
557          * assume that the APICs are being used and don't register any
558          * of our interrupt sources.  This makes sure we don't accidentally
559          * use mixed mode.  The "accidental" use could otherwise occur on
560          * machines that route the ACPI SCI interrupt to a different ISA
561          * IRQ (at least one machines routes it to IRQ 13) thus disabling
562          * that APIC ISA routing and allowing the ATPIC source for that IRQ
563          * to leak through.  We used to depend on this feature for routing
564          * IRQ0 via mixed mode, but now we don't use mixed mode at all.
565          */
566         for (i = 0; i < NUM_ISA_IRQS; i++)
567                 if (intr_lookup_source(i) != NULL)
568                         return;
569
570         /* Loop through all interrupt sources and add them. */
571         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
572                 if (i == ICU_SLAVEID)
573                         continue;
574                 intr_register_source(&ai->at_intsrc);
575         }
576 }
577 SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL);
578
579 void
580 atpic_handle_intr(u_int vector, struct trapframe *frame)
581 {
582         struct intsrc *isrc;
583
584         KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
585         isrc = &atintrs[vector].at_intsrc;
586
587         /*
588          * If we don't have an event, see if this is a spurious
589          * interrupt.
590          */
591         if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
592                 int port, isr;
593
594                 /*
595                  * Read the ISR register to see if IRQ 7/15 is really
596                  * pending.  Reset read register back to IRR when done.
597                  */
598                 port = ((struct atpic *)isrc->is_pic)->at_ioaddr;
599                 spinlock_enter();
600                 outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS);
601                 isr = inb(port);
602                 outb(port, OCW3_SEL | OCW3_RR);
603                 spinlock_exit();
604                 if ((isr & IRQ_MASK(7)) == 0)
605                         return;
606         }
607         intr_execute_handlers(isrc, frame);
608 }
609
610 #ifdef DEV_ISA
611 /*
612  * Bus attachment for the ISA PIC.
613  */
614 static struct isa_pnp_id atpic_ids[] = {
615         { 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
616         { 0 }
617 };
618
619 static int
620 atpic_probe(device_t dev)
621 {
622         int result;
623         
624         result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
625         if (result <= 0)
626                 device_quiet(dev);
627         return (result);
628 }
629
630 /*
631  * We might be granted IRQ 2, as this is typically consumed by chaining
632  * between the two PIC components.  If we're using the APIC, however,
633  * this may not be the case, and as such we should free the resource.
634  * (XXX untested)
635  *
636  * The generic ISA attachment code will handle allocating any other resources
637  * that we don't explicitly claim here.
638  */
639 static int
640 atpic_attach(device_t dev)
641 {
642         struct resource *res;
643         int rid;
644
645         /* Try to allocate our IRQ and then free it. */
646         rid = 0;
647         res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
648         if (res != NULL)
649                 bus_release_resource(dev, SYS_RES_IRQ, rid, res);
650         return (0);
651 }
652
653 static device_method_t atpic_methods[] = {
654         /* Device interface */
655         DEVMETHOD(device_probe,         atpic_probe),
656         DEVMETHOD(device_attach,        atpic_attach),
657         DEVMETHOD(device_detach,        bus_generic_detach),
658         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
659         DEVMETHOD(device_suspend,       bus_generic_suspend),
660         DEVMETHOD(device_resume,        bus_generic_resume),
661         { 0, 0 }
662 };
663
664 static driver_t atpic_driver = {
665         "atpic",
666         atpic_methods,
667         1,              /* no softc */
668 };
669
670 static devclass_t atpic_devclass;
671
672 DRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0);
673 #ifndef PC98
674 DRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0);
675 #endif
676
677 /*
678  * Return a bitmap of the current interrupt requests.  This is 8259-specific
679  * and is only suitable for use at probe time.
680  */
681 intrmask_t
682 isa_irq_pending(void)
683 {
684         u_char irr1;
685         u_char irr2;
686
687         irr1 = inb(IO_ICU1);
688         irr2 = inb(IO_ICU2);
689         return ((irr2 << 8) | irr1);
690 }
691 #endif /* DEV_ISA */