atpic.c revision 121985
164562Sgshapiro/*-
273188Sgshapiro * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
364562Sgshapiro * All rights reserved.
464562Sgshapiro *
564562Sgshapiro * Redistribution and use in source and binary forms, with or without
664562Sgshapiro * modification, are permitted provided that the following conditions
764562Sgshapiro * are met:
864562Sgshapiro * 1. Redistributions of source code must retain the above copyright
964562Sgshapiro *    notice, this list of conditions and the following disclaimer.
1064562Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright
1164562Sgshapiro *    notice, this list of conditions and the following disclaimer in the
1277349Sgshapiro *    documentation and/or other materials provided with the distribution.
1364562Sgshapiro * 3. Neither the name of the author nor the names of any co-contributors
1464562Sgshapiro *    may be used to endorse or promote products derived from this software
1564562Sgshapiro *    without specific prior written permission.
1664562Sgshapiro *
1764562Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1864562Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1964562Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2064562Sgshapiro * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2164562Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2264562Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2364562Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2464562Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2564562Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2664562Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2764562Sgshapiro * SUCH DAMAGE.
2864562Sgshapiro */
2964562Sgshapiro
3064562Sgshapiro/*
3164562Sgshapiro * PIC driver for the 8259A Master and Slave PICs in PC/AT machines.
3264562Sgshapiro */
3373188Sgshapiro
3473188Sgshapiro#include <sys/cdefs.h>
3564562Sgshapiro__FBSDID("$FreeBSD: head/sys/i386/isa/atpic.c 121985 2003-11-03 21:34:45Z jhb $");
3664562Sgshapiro
3764562Sgshapiro#include "opt_auto_eoi.h"
3864562Sgshapiro#include "opt_isa.h"
3964562Sgshapiro
4066494Sgshapiro#include <sys/param.h>
4173188Sgshapiro#include <sys/systm.h>
4264562Sgshapiro#include <sys/bus.h>
4364562Sgshapiro#include <sys/interrupt.h>
4464562Sgshapiro#include <sys/kernel.h>
4573188Sgshapiro#include <sys/lock.h>
4664562Sgshapiro#include <sys/mutex.h>
4764562Sgshapiro
4866494Sgshapiro#include <machine/cpufunc.h>
4964562Sgshapiro#include <machine/frame.h>
5064562Sgshapiro#include <machine/intr_machdep.h>
5164562Sgshapiro#include <machine/md_var.h>
5264562Sgshapiro#include <machine/resource.h>
5364562Sgshapiro#include <machine/segments.h>
5464562Sgshapiro
5564562Sgshapiro#include <i386/isa/icu.h>
5664562Sgshapiro#include <i386/isa/isa.h>
5764562Sgshapiro#include <isa/isavar.h>
5864562Sgshapiro
5966494Sgshapiro#define	MASTER	0
6064562Sgshapiro#define	SLAVE	1
6164562Sgshapiro
6264562Sgshapiro/* XXX: Magic numbers */
6364562Sgshapiro#ifdef PC98
6464562Sgshapiro#ifdef AUTO_EOI_1
6564562Sgshapiro#define	MASTER_MODE	0x1f	/* Master auto EOI, 8086 mode */
6664562Sgshapiro#else
6764562Sgshapiro#define	MASTER_MODE	0x1d	/* Master 8086 mode */
6864562Sgshapiro#endif
6964562Sgshapiro#define	SLAVE_MODE	9	/* 8086 mode */
7064562Sgshapiro#else /* IBM-PC */
7164562Sgshapiro#ifdef AUTO_EOI_1
7264562Sgshapiro#define	MASTER_MODE	(2 | 1)	/* Auto EOI, 8086 mode */
7364562Sgshapiro#else
7464562Sgshapiro#define	MASTER_MODE	1	/* 8086 mode */
7564562Sgshapiro#endif
7664562Sgshapiro#ifdef AUTO_EOI_2
7764562Sgshapiro#define	SLAVE_MODE	(2 | 1)	/* Auto EOI, 8086 mode */
7864562Sgshapiro#else
7964562Sgshapiro#define	SLAVE_MODE	1	/* 8086 mode */
8064562Sgshapiro#endif
8164562Sgshapiro#endif /* PC98 */
8264562Sgshapiro
8364562Sgshapirostatic void	atpic_init(void *dummy);
8464562Sgshapiro
8564562Sgshapirounsigned int imen;	/* XXX */
8664562Sgshapiro
8764562Sgshapirointhand_t
8864562Sgshapiro	IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
8964562Sgshapiro	IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
9064562Sgshapiro	IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
9166494Sgshapiro	IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11),
9264562Sgshapiro	IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14),
9364562Sgshapiro	IDTVEC(atpic_intr15);
9464562Sgshapiro
9564562Sgshapiro#define	IRQ(ap, ai)	((ap)->at_irqbase + (ai)->at_irq)
9664562Sgshapiro
9764562Sgshapiro#define	ATPIC(io, base, eoi, imenptr)				\
9864562Sgshapiro     	{ { atpic_enable_source, atpic_disable_source, (eoi),		\
9964562Sgshapiro	    atpic_enable_intr, atpic_vector, atpic_source_pending, NULL, \
10064562Sgshapiro	    atpic_resume }, (io), (base), IDT_IO_INTS + (base), (imenptr) }
10164562Sgshapiro
10264562Sgshapiro#define	INTSRC(irq)							\
10364562Sgshapiro	{ { &atpics[(irq) / 8].at_pic }, (irq) % 8,			\
10464562Sgshapiro	    IDTVEC(atpic_intr ## irq ) }
10564562Sgshapiro
10664562Sgshapirostruct atpic {
10764562Sgshapiro	struct pic at_pic;
10864562Sgshapiro	int	at_ioaddr;
10964562Sgshapiro	int	at_irqbase;
11064562Sgshapiro	uint8_t	at_intbase;
11164562Sgshapiro	uint8_t	*at_imen;
11264562Sgshapiro};
11364562Sgshapiro
11464562Sgshapirostruct atpic_intsrc {
11564562Sgshapiro	struct intsrc at_intsrc;
11664562Sgshapiro	int	at_irq;		/* Relative to PIC base. */
11764562Sgshapiro	inthand_t *at_intr;
11864562Sgshapiro};
11964562Sgshapiro
12064562Sgshapirostatic void atpic_enable_source(struct intsrc *isrc);
12164562Sgshapirostatic void atpic_disable_source(struct intsrc *isrc);
12266494Sgshapirostatic void atpic_eoi_master(struct intsrc *isrc);
12364562Sgshapirostatic void atpic_eoi_slave(struct intsrc *isrc);
12464562Sgshapirostatic void atpic_enable_intr(struct intsrc *isrc);
12564562Sgshapirostatic int atpic_vector(struct intsrc *isrc);
12664562Sgshapirostatic void atpic_resume(struct intsrc *isrc);
12764562Sgshapirostatic int atpic_source_pending(struct intsrc *isrc);
12864562Sgshapirostatic void i8259_init(struct atpic *pic, int slave);
12964562Sgshapiro
13064562Sgshapirostatic struct atpic atpics[] = {
13164562Sgshapiro	ATPIC(IO_ICU1, 0, atpic_eoi_master, (uint8_t *)&imen),
13264562Sgshapiro	ATPIC(IO_ICU2, 8, atpic_eoi_slave, ((uint8_t *)&imen) + 1)
13364562Sgshapiro};
13464562Sgshapiro
13564562Sgshapirostatic struct atpic_intsrc atintrs[] = {
13664562Sgshapiro	INTSRC(0),
13764562Sgshapiro	INTSRC(1),
13864562Sgshapiro	INTSRC(2),
13964562Sgshapiro	INTSRC(3),
14064562Sgshapiro	INTSRC(4),
14164562Sgshapiro	INTSRC(5),
14264562Sgshapiro	INTSRC(6),
14364562Sgshapiro	INTSRC(7),
14464562Sgshapiro	INTSRC(8),
14564562Sgshapiro	INTSRC(9),
14666494Sgshapiro	INTSRC(10),
14764562Sgshapiro	INTSRC(11),
14864562Sgshapiro	INTSRC(12),
14964562Sgshapiro	INTSRC(13),
15064562Sgshapiro	INTSRC(14),
15164562Sgshapiro	INTSRC(15),
15264562Sgshapiro};
15364562Sgshapiro
15464562Sgshapirostatic void
15564562Sgshapiroatpic_enable_source(struct intsrc *isrc)
15664562Sgshapiro{
15764562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
15864562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
15964562Sgshapiro
16064562Sgshapiro	mtx_lock_spin(&icu_lock);
16164562Sgshapiro	*ap->at_imen &= ~(1 << ai->at_irq);
16264562Sgshapiro	outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
16364562Sgshapiro	mtx_unlock_spin(&icu_lock);
16464562Sgshapiro}
16564562Sgshapiro
16664562Sgshapirostatic void
16766494Sgshapiroatpic_disable_source(struct intsrc *isrc)
16864562Sgshapiro{
16964562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
17064562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
17164562Sgshapiro
17264562Sgshapiro	mtx_lock_spin(&icu_lock);
17364562Sgshapiro	*ap->at_imen |= (1 << ai->at_irq);
17464562Sgshapiro	outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
17564562Sgshapiro	mtx_unlock_spin(&icu_lock);
17664562Sgshapiro}
17764562Sgshapiro
17864562Sgshapirostatic void
17966494Sgshapiroatpic_eoi_master(struct intsrc *isrc)
18064562Sgshapiro{
18164562Sgshapiro
18264562Sgshapiro	KASSERT(isrc->is_pic == &atpics[MASTER].at_pic,
18364562Sgshapiro	    ("%s: mismatched pic", __func__));
18464562Sgshapiro#ifndef AUTO_EOI_1
18564562Sgshapiro	mtx_lock_spin(&icu_lock);
18664562Sgshapiro	outb(atpics[MASTER].at_ioaddr, ICU_EOI);
18764562Sgshapiro	mtx_unlock_spin(&icu_lock);
18864562Sgshapiro#endif
18964562Sgshapiro}
19064562Sgshapiro
19164562Sgshapirostatic void
19264562Sgshapiroatpic_eoi_slave(struct intsrc *isrc)
19364562Sgshapiro{
19464562Sgshapiro
19564562Sgshapiro	KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic,
19664562Sgshapiro	    ("%s: mismatched pic", __func__));
19764562Sgshapiro#ifndef AUTO_EOI_2
19864562Sgshapiro	mtx_lock_spin(&icu_lock);
19964562Sgshapiro	outb(atpics[SLAVE].at_ioaddr, ICU_EOI);
20064562Sgshapiro#ifndef AUTO_EOI_1
20164562Sgshapiro	outb(atpics[MASTER].at_ioaddr, ICU_EOI);
20264562Sgshapiro#endif
20364562Sgshapiro	mtx_unlock_spin(&icu_lock);
20464562Sgshapiro#endif
20564562Sgshapiro}
20664562Sgshapiro
20764562Sgshapirostatic void
20864562Sgshapiroatpic_enable_intr(struct intsrc *isrc)
20964562Sgshapiro{
21064562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
21164562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
21264562Sgshapiro	register_t eflags;
21364562Sgshapiro
21464562Sgshapiro	mtx_lock_spin(&icu_lock);
21564562Sgshapiro	eflags = intr_disable();
21664562Sgshapiro	setidt(ap->at_intbase + ai->at_irq, ai->at_intr, SDT_SYS386IGT,
21764562Sgshapiro	    SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
21864562Sgshapiro	intr_restore(eflags);
21964562Sgshapiro	mtx_unlock_spin(&icu_lock);
22064562Sgshapiro}
22164562Sgshapiro
22264562Sgshapirostatic int
22364562Sgshapiroatpic_vector(struct intsrc *isrc)
22464562Sgshapiro{
22564562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
22664562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
22764562Sgshapiro
22864562Sgshapiro	return (IRQ(ap, ai));
22964562Sgshapiro}
23066494Sgshapiro
23164562Sgshapirostatic int
23264562Sgshapiroatpic_source_pending(struct intsrc *isrc)
23364562Sgshapiro{
23464562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
23564562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
23664562Sgshapiro
23764562Sgshapiro	return (inb(ap->at_ioaddr) & (1 << ai->at_irq));
23864562Sgshapiro}
23964562Sgshapiro
24066494Sgshapirostatic void
24164562Sgshapiroatpic_resume(struct intsrc *isrc)
24264562Sgshapiro{
24364562Sgshapiro	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
24464562Sgshapiro	struct atpic *ap = (struct atpic *)isrc->is_pic;
24564562Sgshapiro
24664562Sgshapiro	if (ai->at_irq == 0)
24764562Sgshapiro		i8259_init(ap, ap == &atpics[SLAVE]);
24864562Sgshapiro}
24964562Sgshapiro
25064562Sgshapirostatic void
25164562Sgshapiroi8259_init(struct atpic *pic, int slave)
25264562Sgshapiro{
25364562Sgshapiro	int imr_addr;
25464562Sgshapiro
25564562Sgshapiro	/* Reset the PIC and program with next four bytes. */
25664562Sgshapiro	mtx_lock_spin(&icu_lock);
25764562Sgshapiro#ifdef DEV_MCA
25864562Sgshapiro	if (MCA_system)
25964562Sgshapiro		outb(pic->at_ioaddr, 0x19);
26064562Sgshapiro	else
26164562Sgshapiro#endif
26264562Sgshapiro		outb(pic->at_ioaddr, 0x11);
26364562Sgshapiro	imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
26464562Sgshapiro
26564562Sgshapiro	/* Start vector. */
26664562Sgshapiro	outb(imr_addr, pic->at_intbase);
26764562Sgshapiro
26864562Sgshapiro	/*
26964562Sgshapiro	 * Setup slave links.  For the master pic, indicate what line
27064562Sgshapiro	 * the slave is configured on.  For the slave indicate
27164562Sgshapiro	 * which line on the master we are connected to.
27264562Sgshapiro	 */
27364562Sgshapiro	if (slave)
27464562Sgshapiro		outb(imr_addr, ICU_SLAVEID);	/* my slave id is 7 */
27564562Sgshapiro	else
27664562Sgshapiro		outb(imr_addr, IRQ_SLAVE);	/* slave on line 7 */
27764562Sgshapiro
27864562Sgshapiro	/* Set mode. */
27964562Sgshapiro	if (slave)
28064562Sgshapiro		outb(imr_addr, SLAVE_MODE);
28164562Sgshapiro	else
28264562Sgshapiro		outb(imr_addr, MASTER_MODE);
28364562Sgshapiro
28464562Sgshapiro	/* Set interrupt enable mask. */
28564562Sgshapiro	outb(imr_addr, *pic->at_imen);
28664562Sgshapiro
28764562Sgshapiro	/* Reset is finished, default to IRR on read. */
28864562Sgshapiro	outb(pic->at_ioaddr, 0x0a);
28964562Sgshapiro
29064562Sgshapiro#ifndef PC98
29166494Sgshapiro	/* Set priority order to 3-7, 0-2 (com2 first). */
29264562Sgshapiro	if (!slave)
29364562Sgshapiro		outb(pic->at_ioaddr, 0xc0 | (3 - 1));
29464562Sgshapiro#endif
29564562Sgshapiro	mtx_unlock_spin(&icu_lock);
29664562Sgshapiro}
29764562Sgshapiro
29864562Sgshapirovoid
29966494Sgshapiroatpic_startup(void)
30064562Sgshapiro{
30164562Sgshapiro
30264562Sgshapiro	/* Start off with all interrupts disabled. */
30364562Sgshapiro	imen = 0xffff;
30471345Sgshapiro	i8259_init(&atpics[MASTER], 0);
30571345Sgshapiro	i8259_init(&atpics[SLAVE], 1);
30664562Sgshapiro	atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
30764562Sgshapiro}
30864562Sgshapiro
30964562Sgshapirostatic void
31064562Sgshapiroatpic_init(void *dummy __unused)
31164562Sgshapiro{
31266494Sgshapiro	struct atpic_intsrc *ai;
31364562Sgshapiro	int i;
31464562Sgshapiro
31564562Sgshapiro	/* Loop through all interrupt sources and add them. */
31664562Sgshapiro	for (i = 0; i < sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) {
31764562Sgshapiro		if (i == ICU_SLAVEID)
31864562Sgshapiro			continue;
31964562Sgshapiro		ai = &atintrs[i];
32064562Sgshapiro		intr_register_source(&ai->at_intsrc);
32164562Sgshapiro	}
32264562Sgshapiro}
32364562SgshapiroSYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
32464562Sgshapiro
32564562Sgshapirovoid
32664562Sgshapiroatpic_sched_ithd(struct intrframe iframe)
32764562Sgshapiro{
32864562Sgshapiro	struct intsrc *isrc;
32964562Sgshapiro
33064562Sgshapiro	KASSERT((uint)iframe.if_vec < ICU_LEN,
33164562Sgshapiro	    ("unknown int %d\n", iframe.if_vec));
33264562Sgshapiro	isrc = &atintrs[iframe.if_vec].at_intsrc;
33364562Sgshapiro	intr_execute_handlers(isrc, &iframe);
33464562Sgshapiro}
33564562Sgshapiro
33664562Sgshapiro#ifdef DEV_ISA
33764562Sgshapiro/*
33864562Sgshapiro * Bus attachment for the ISA PIC.
33966494Sgshapiro */
34064562Sgshapirostatic struct isa_pnp_id atpic_ids[] = {
34171345Sgshapiro	{ 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
34271345Sgshapiro	{ 0 }
34371345Sgshapiro};
34464562Sgshapiro
34564562Sgshapirostatic int
34664562Sgshapiroatpic_probe(device_t dev)
34764562Sgshapiro{
34864562Sgshapiro	int result;
34964562Sgshapiro
35064562Sgshapiro	result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
35164562Sgshapiro	if (result <= 0)
35264562Sgshapiro		device_quiet(dev);
35364562Sgshapiro	return (result);
35464562Sgshapiro}
35564562Sgshapiro
35664562Sgshapiro/*
35764562Sgshapiro * We might be granted IRQ 2, as this is typically consumed by chaining
35864562Sgshapiro * between the two PIC components.  If we're using the APIC, however,
35964562Sgshapiro * this may not be the case, and as such we should free the resource.
36064562Sgshapiro * (XXX untested)
36164562Sgshapiro *
36264562Sgshapiro * The generic ISA attachment code will handle allocating any other resources
36364562Sgshapiro * that we don't explicitly claim here.
36464562Sgshapiro */
36564562Sgshapirostatic int
36664562Sgshapiroatpic_attach(device_t dev)
36764562Sgshapiro{
36864562Sgshapiro	struct resource *res;
36964562Sgshapiro	int rid;
37064562Sgshapiro
37166494Sgshapiro	/* Try to allocate our IRQ and then free it. */
37264562Sgshapiro	rid = 0;
37364562Sgshapiro	res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 0);
37464562Sgshapiro	if (res != NULL)
37564562Sgshapiro		bus_release_resource(dev, SYS_RES_IRQ, rid, res);
37664562Sgshapiro	return (0);
37764562Sgshapiro}
37864562Sgshapiro
37964562Sgshapirostatic device_method_t atpic_methods[] = {
38066494Sgshapiro	/* Device interface */
38164562Sgshapiro	DEVMETHOD(device_probe,		atpic_probe),
38264562Sgshapiro	DEVMETHOD(device_attach,	atpic_attach),
38364562Sgshapiro	DEVMETHOD(device_detach,	bus_generic_detach),
38464562Sgshapiro	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
38564562Sgshapiro	DEVMETHOD(device_suspend,	bus_generic_suspend),
38664562Sgshapiro	DEVMETHOD(device_resume,	bus_generic_resume),
38764562Sgshapiro	{ 0, 0 }
38864562Sgshapiro};
38966494Sgshapiro
39064562Sgshapirostatic driver_t atpic_driver = {
39164562Sgshapiro	"atpic",
39264562Sgshapiro	atpic_methods,
39364562Sgshapiro	1,		/* no softc */
39464562Sgshapiro};
39564562Sgshapiro
39664562Sgshapirostatic devclass_t atpic_devclass;
39766494Sgshapiro
39864562SgshapiroDRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0);
39973188SgshapiroDRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0);
40064562Sgshapiro
40164562Sgshapiro/*
40264562Sgshapiro * Return a bitmap of the current interrupt requests.  This is 8259-specific
40364562Sgshapiro * and is only suitable for use at probe time.
40464562Sgshapiro */
40564562Sgshapirointrmask_t
40664562Sgshapiroisa_irq_pending(void)
40764562Sgshapiro{
40864562Sgshapiro	u_char irr1;
40964562Sgshapiro	u_char irr2;
41064562Sgshapiro
41164562Sgshapiro	irr1 = inb(IO_ICU1);
41264562Sgshapiro	irr2 = inb(IO_ICU2);
41364562Sgshapiro	return ((irr2 << 8) | irr1);
41464562Sgshapiro}
41564562Sgshapiro#endif /* DEV_ISA */
41664562Sgshapiro