panic: bus_add_child is not implemented
Matías Perret Cantoni
perretcantonim at gmail.com
Tue Mar 3 04:18:17 UTC 2015
Oops! I found the error. In my system there's no simplebus node:
root at zedboard: # devinfo
nexus0
ofwbus0
simplebus0
zy7_slcr0
gic0
l2cache0
zy7_devcfg0
mp_tmr0
simplebus1
uart0
zy7_gpio0
gpioc0
gpiobus0
cgem0
miibus0
ukphy0
sdhci_fdt0
mmc0
mmcsd0
ehci0
usbus0
uhub0
---
I changed: DRIVER_MODULE(simple_register, simplebus, reg_driver,
reg_devclass, 0, 0);
for: DRIVER_MODULE(simple_register, simplebus0, reg_driver, reg_devclass,
0, 0);
and now I can load it without a kernel panic.
Now I have a new problem: after loading it I can't find the new node
neither under /dev nor with devinfo.
Thanks!
2015-03-03 0:54 GMT-03:00 Matías Perret Cantoni <perretcantonim at gmail.com>:
> Yes Warner, here it is. I think I got yours from here:
> http://people.freebsd.org/~imp/led.tar.gz
>
> /*
> * Prototipo 3 - Driver newbus simple para escribir un registro de la FPGA
> */
>
> /*
> * Copyright (c) 2000. M. Warner Losh. All Rights Reserved.
> *
> * "THE BEER-WARE LICENSE" (Revision 42):
> * <imp at FreeBSD.ORG> wrote this file. As long as you retain this notice
> you
> * can do whatever you want with this stuff. If we meet some day, and you
> think
> * this stuff is worth it, you can buy me a beer in return. M. Warner
> Losh
> */
>
> /*
> * Simple driver for the I-Opener LED, but likely could be adapted
> * to any led driver. This is intended to be a thought excersize
> * as well as a useful sample driver. Since I don't have a hackable
> * iopener around to test it out on.
> *
> * The LED is located at 0x404c on the iopener. Likely we should find this
> * in the pci space, and then do stuff from tehre. However, it appears to
> * be controlled in some way by acpi, so I'm going to try to write this
> driver
> * to not interfere with that.
> *
> * the lower two bits of this register control the state of the LED. The
> left
> * led, with the mail ICON, is controlled by bit 0. The phone led is
> * controlled by bit 1.
> *
> * This is a bog simple ISA driver... Would make a useful example, imho.
> *
> * Since I'm lazy, I have only a write interface. The characters recieved
> * by the driver are masked and the results sent to these gpios. This
> * allows things like '1' to turn on the led and '0' to turn off the led.
> * There is a minor number for each led controlled.
> *
> * The read interface returns 1 character ('0' off '1' on) for the state
> * of the led.
> *
> * thanks to "roastbeef" who posted technical information about this to the
> * I-Opener BBS web site.
> */
>
>
> #include <sys/param.h>
> #include <sys/module.h>
> #include <sys/kernel.h>
> #include <sys/systm.h>
>
> #include <sys/bus.h>
> #include <sys/conf.h>
> #include <sys/uio.h>
>
> #include <machine/bus.h>
> #include <sys/rman.h>
> #include <machine/resource.h>
>
> #define REG_IOADDR 0x67000000
>
> struct reg_softc
> {
> struct cdev *dev0;
> struct resource *res;
> int rid;
> };
>
> static d_open_t reg_open;
> static d_close_t reg_close;
> static d_read_t reg_read;
> static d_write_t reg_write;
>
> static struct cdevsw reg_cdevsw = {
> .d_version = D_VERSION,
> .d_open = reg_open,
> .d_close = reg_close,
> .d_read = reg_read,
> .d_write = reg_write,
> .d_name = "simple_register",
> };
>
> static devclass_t reg_devclass;
>
> static int reg_open(struct cdev *dev, int flags, int fmt, struct thread *p)
> {
> uprintf("Open: simple_register.\n");
> return 0;
> }
> static int
> reg_close(struct cdev *dev, int flags, int fmt, struct thread *p)
> {
> uprintf("Close: simple_register.\n");
> return 0;
> }
>
> static int
> reg_read(struct cdev *dev, struct uio *uio, int flag)
> {
> struct reg_softc *sc = dev->si_drv1;
> int err;
> u_int8_t ch;
>
> ch = bus_read_1(sc->res, 0);
> err = uiomove(&ch, 1, uio);
>
> return err;
> }
>
> static int
> reg_write(struct cdev *dev, struct uio *uio, int flag)
> {
>
> struct reg_softc *sc = dev->si_drv1;
> int err;
> u_int8_t ch;
>
> err = uiomove(&ch, 1, uio);
> if (err != 0)
> return (err);
> bus_write_1(sc->res, 0, ch);
> return err;
> }
> static void
> reg_identify (driver_t *driver, device_t parent)
> {
> device_t child;
> child= device_find_child(parent, "simple_register", -1);
>
> if (!child) {
> child = BUS_ADD_CHILD(parent, 0, "simple_register", -1);
> bus_set_resource(child, SYS_RES_IOPORT, 0, REG_IOADDR, 1);
> }
> }
>
> static int
> reg_probe(device_t dev)
> {
> if ( 0 == bus_get_resource_start(dev, SYS_RES_IOPORT, 0) )
> return (ENXIO);
> device_set_desc(dev, "simple_register_driver");
> return(BUS_PROBE_SPECIFIC);
> }
>
> static int
> reg_attach(device_t dev)
> {
>
> struct reg_softc *sc;
> sc = (struct reg_softc *) device_get_softc(dev);
> sc->rid = 0;
> /* Solicita el recurso */
> sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->rid, RF_ACTIVE);
> if (sc->res == NULL){
> device_printf(dev, "No se pudo obtener el puerto de E/S\n");
> return ENXIO;
> }
> /* Crea el nodo correspondiente en </dev> */
> sc->dev0 = make_dev(®_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644,
> "simple_reg");
>
> return 0;
> }
>
> static int
> reg_detach(device_t dev)
> {
> struct reg_softc *sc;
> sc = (struct reg_softc *) device_get_softc(dev);
> /* Destruye el nodo */
> destroy_dev(sc->dev0);
>
> /* Devuelve los recursos */
> bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->res);
> return 0;
> }
>
> static device_method_t reg_methods[] = {
> /* Device interface */
> DEVMETHOD(device_identify, reg_identify),
> DEVMETHOD(device_probe, reg_probe),
> DEVMETHOD(device_attach, reg_attach),
> DEVMETHOD(device_detach, reg_detach),
>
> { 0, 0 }
> };
>
> /* Declaracion del driver */
> static driver_t reg_driver = {
> "simple_register",
> reg_methods,
> sizeof(struct reg_softc),
> };
>
> DRIVER_MODULE(simple_register, simplebus, reg_driver, reg_devclass, 0, 0);
>
>
> 2015-03-02 22:48 GMT-03:00 Warner Losh <imp at bsdimp.com>:
>
> can you send me the source?
>>
>> Warner
>>
>> > On Mar 2, 2015, at 6:11 PM, Matías Perret Cantoni <
>> perretcantonim at gmail.com> wrote:
>> >
>> > Hello!
>> >
>> > I wrote a simple newbus driver for reading and writing a specific I/O
>> port,
>> > which is basically a copy of the Warner Losh example driver for the
>> iOpener
>> > Led. I compiled with no errors, but I get a kernel panic "
>> bus_add_child is
>> > not implemented" when I try to load it in my development board which is
>> a
>> > Zedboard with FreeBSD.
>> >
>> >
>> > The way I compiled it:
>> >
>> > # cd /usr/src
>> > root at matiBSD:/usr/src # make buildenv TARGET_ARCH=armv6
>> > BUILDENV_SHELL=/usr/local/bin/bash
>> > KERNBUILDDIR=/usr/obj/arm.armv6/usr/src/sys/ZEDBOARD
>> > Entering world for armv6:arm
>> > [root at matiBSD /usr/src]# cd /home/drivers/p3
>> > [root at matiBSD /home/drivers/p3]# make
>> >
>> >
>> > The content of the Makefile I used:
>> >
>> > KMOD =p3
>> > SRCS =p3.c device_if.c bus_if.h
>> > .include <bsd.knod.mk>
>> >
>> >
>> > The way I tried to load it:
>> >
>> > root at zedboard:/usr # kldload /boot/msdos/p3.ko
>> > panic: bus_add_child is not implemented
>> > cpuid = 1
>> >
>> >
>> > My only guess here is that I should compile the driver with the kernel
>> so
>> > that the linker can properly link the BUS_ADD_CHILD() method call in the
>> > drivers identify() method.
>> >
>> > My host is: FreeBSD matiBSD 10.1-BETA2 FreeBSD 10.1-BETA2
>> > My target is: FreeBSD zedboard 10.1-BETA2 FreeBSD 10.1-BETA2
>> >
>> >
>> > I'm new at this, so any income is appreciated!
>> >
>> > Regards,
>> > Matias.
>> > _______________________________________________
>> > freebsd-arm at freebsd.org mailing list
>> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm
>> > To unsubscribe, send any mail to "freebsd-arm-unsubscribe at freebsd.org"
>>
>>
>
More information about the freebsd-arm
mailing list