Date: Sun, 21 Jan 2001 14:30:22 -0700 From: Warner Losh <imp@harmony.village.org> To: "Alex" <d_f0rce@gmx.de> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Problems attaching an interrupt handler Message-ID: <200101212130.f0LLUM901851@harmony.village.org> In-Reply-To: Your message of "Sun, 21 Jan 2001 17:10:30 %2B0100." <NEBBIKIHMLCDHCFEOMAHOEKCCAAA.d_f0rce@gmx.de> References: <NEBBIKIHMLCDHCFEOMAHOEKCCAAA.d_f0rce@gmx.de>
index | next in thread | previous in thread | raw e-mail
In message <NEBBIKIHMLCDHCFEOMAHOEKCCAAA.d_f0rce@gmx.de> "Alex" writes:
: This is a multi-part message in MIME format.
:
: ------=_NextPart_000_0000_01C083CD.0EB2B120
: Content-Type: text/plain;
: charset="iso-8859-1"
: Content-Transfer-Encoding: 7bit
:
: Hi,
:
: I started experimenting with kernel hacking to write an
: infrared device driver. Therfore I read Alexander Langer's
: article on DaemonNews and started modifying the led.c
: example code.
:
: Unfortunately I can't get my interrupt handler working.
:
: Could anyone please have a short look on my code.
:
: On loading the module the first time everything stays
: stable and vmstat -i shows 1 INT on my device. After
: unloading the module and reloading it the kernel
: crashes on the next incoming interrupt.
:
: Any ideas?
:
: Alex
:
: ------=_NextPart_000_0000_01C083CD.0EB2B120
: Content-Type: application/octet-stream;
: name="mydev.c"
: Content-Transfer-Encoding: quoted-printable
: Content-Disposition: attachment;
: filename="mydev.c"
:
: /*=0A=
: * Copyright (c) 2000. M. Warner Losh. All Rights Reserved.=0A=
: *=0A=
: * "THE BEER-WARE LICENSE" (Revision 42):=0A=
: * <imp@FreeBSD.ORG> wrote this file. As long as you retain this notice =
: you=0A=
: * can do whatever you want with this stuff. If we meet some day, and =
: you think=0A=
: * this stuff is worth it, you can buy me a beer in return. M. Warner =
: Losh=0A=
: */=0A=
: =0A=
: /*=0A=
: * Simple driver for the I-Opener LED, but likely could be adapted=0A=
: * to any led driver. This is intended to be a thought excersize=0A=
: * as well as a useful sample driver. Since I don't have a hackable=0A=
: * iopener around to test it out on.=0A=
: *=0A=
: * The LED is located at 0x404c on the iopener. Likely we should find =
: this=0A=
: * in the pci space, and then do stuff from tehre. However, it appears =
: to=0A=
: * be controlled in some way by acpi, so I'm going to try to write this =
: driver=0A=
: * to not interfere with that.=0A=
: *=0A=
: * the lower two bits of this register control the state of the LED. =
: The left=0A=
: * led, with the mail ICON, is controlled by bit 0. The phone led is=0A=
: * controlled by bit 1.=0A=
: *=0A=
: * This is a bog simple ISA driver... Would make a useful example, imho.=0A=
: *=0A=
: * Since I'm lazy, I have only a write interface. The characters =
: recieved=0A=
: * by the driver are masked and the results sent to these gpios. This=0A=
: * allows things like '1' to turn on the led and '0' to turn off the led.=0A=
: * There is a minor number for each led controlled.=0A=
: *=0A=
: * The read interface returns 1 character ('0' off '1' on) for the state =0A=
: * of the led.=0A=
: *=0A=
: * thanks to "roastbeef" who posted technical information about this to =
: the=0A=
: * I-Opener BBS web site.=0A=
: */=0A=
: =0A=
: #include <sys/types.h>=0A=
: #include <sys/param.h>=0A=
: #include <sys/systm.h>=0A=
: #include <sys/malloc.h>=0A=
: #include <sys/kernel.h>=0A=
: #include <sys/bus.h>=0A=
: #include <sys/errno.h>=0A=
: #include <sys/conf.h>=0A=
: #include <sys/module.h>=0A=
: #include <sys/uio.h>=0A=
: #include <machine/bus.h>=0A=
: #include <machine/resource.h>=0A=
: #include <sys/rman.h>=0A=
: =0A=
: =0A=
: struct ir_softc =0A=
: {=0A=
: bus_space_tag_t bst;=0A=
: bus_space_handle_t bsh;=0A=
: dev_t dev0;=0A=
: dev_t dev1;=0A=
: u_int32_t open_mask;=0A=
: u_int32_t read_mask;=0A=
: struct resource *res;=0A=
: int rid;=0A=
: struct resource *irq;=0A=
: void *ih;=0A=
: int irqid;=0A=
: };=0A=
: =0A=
: static devclass_t ir_devclass;=0A=
: =0A=
: #define IR_IOADDR 0x3f8=0A=
: =0A=
: static void ir_intr( void *p );=0A=
: void get_sio_status( struct ir_softc *sc );=0A=
: =0A=
: =0A=
: static void=0A=
: ir_identify (driver_t *driver, device_t parent)=0A=
: {=0A=
: devclass_t dc;=0A=
: device_t child;=0A=
: =0A=
: dc =3D devclass_find("ir");=0A=
: if (devclass_get_device(dc, 0) =3D=3D NULL) {=0A=
: child =3D BUS_ADD_CHILD(parent, 0, "ir", -1);=0A=
: bus_set_resource(child, SYS_RES_IOPORT, 0, IR_IOADDR, 7);=0A=
: bus_set_resource(child, SYS_RES_IRQ, 0, 4, 1);=0A=
: }=0A=
: uprintf("IR Ident\n");=0A=
: }=0A=
: =0A=
: static int=0A=
: ir_probe(device_t dev)=0A=
: {=0A=
: if (device_get_unit(dev) !=3D 0)=0A=
: return (ENXIO);=0A=
: if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) =3D=3D 0)=0A=
: return (ENXIO);=0A=
: =0A=
: uprintf("IR Probe\n");=0A=
: return (0);=0A=
: }=0A=
: =0A=
: static int=0A=
: ir_attach(device_t dev)=0A=
: {=0A=
: struct ir_softc *sc;=0A=
: u_int8_t old;=0A=
: =0A=
: sc =3D (struct ir_softc *) device_get_softc(dev);=0A=
: sc->rid =3D 0;=0A=
: sc->res =3D bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid, 0ul, =
: ~0ul, 7,=0A=
: RF_ACTIVE);=0A=
: if (sc->res =3D=3D NULL)=0A=
: return ENXIO;=0A=
: sc->bst =3D rman_get_bustag(sc->res);=0A=
: sc->bsh =3D rman_get_bushandle(sc->res);=0A=
: sc->open_mask =3D 0;=0A=
: sc->read_mask =3D 0;=0A=
: =0A=
: uprintf("IR Attach\nTrying to access device ....\n");=0A=
: =0A=
: get_sio_status( sc );=0A=
: =0A=
: /* FIFO Puffer aktivieren */=0A=
: bus_space_write_1(sc->bst, sc->bsh,2,(u_int8_t) 7);=0A=
: /* keine Kontrolle, da IIR fuer FIFO-Operation write only */=0A=
: =0A=
: /* LCR Bit 7 auf 0 */=0A=
: old =3D bus_space_read_1(sc->bst, sc->bsh,3);=0A=
: old &=3D ~128; /* Bit 7 ausnullen */=0A=
: bus_space_write_1(sc->bst, sc->bsh,3,(u_int8_t) old);=0A=
: =0A=
: /* IER setzen, um Interrupt bei Modem Status Aenderung auszuloesen */=0A=
: old =3D bus_space_read_1(sc->bst, sc->bsh,1);=0A=
: old &=3D ~1; /* Bit 0 ausnullen =3D> kein INT ausloesen, sobald ein =
: neues Zeichen im RBR */=0A=
: old &=3D ~2; /* Bit 1 ausnullen =3D> kein INT sobald THR leer */=0A=
: old &=3D ~4; /* Bit 2 ausnullen =3D> kein INT sobald Aenderung im LSR */=0A=
: old |=3D 8; /* Bit 3 setzen =3D> INT bei Aenderung im MSR */=0A=
: bus_space_write_1(sc->bst, sc->bsh,1,(u_int8_t) old);=0A=
: =0A=
: /* RTS im MCR auf high setzen */=0A=
: old =3D bus_space_read_1(sc->bst, sc->bsh,4);=0A=
: old |=3D 1; /* Bit 0 setzen - DTR auf 0 -> PC bereit */=0A=
: old |=3D 2; /* Bit 1 setzen - RTS auf 0 -> PC will senden */=0A=
: old |=3D 8; /* Bit 3 setzen - UART loest INTs gemaess den =
: Einstellungen im IER aus */=0A=
: old &=3D ~16; /* Bit 4 ausnullen =3D> Selbsttest aus. */=0A=
: bus_space_write_1(sc->bst, sc->bsh,4,(u_int8_t) old);=0A=
: =0A=
: get_sio_status( sc );=0A=
: =0A=
: /* Interrupt Handler */=0A=
: sc->irqid=3D0;=0A=
: static void ir_intr( void *p ){=0A=
: uprintf("GOT INTERUPT!\n");=0A=
: }=0A=
Don't use uprintf in the interrupt handler.
Have you set an irq hint for the device?
Warner
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101212130.f0LLUM901851>
