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