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>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101212130.f0LLUM901851>