Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Nov 2019 21:23:21 -0700
From:      Oleksandr Tymoshenko <gonzo@bluezbox.com>
To:        Milan Obuch <freebsd-hackers@dino.sk>
Cc:        freebsd-hackers@freebsd.org, Oliver Pinter <oliver.pinter@hardenedbsd.org>
Subject:   Re: UART driver as kld - how?
Message-ID:  <20191103042321.GA49790@bluezbox.com>
In-Reply-To: <20191102214100.500ba493@zeta.dino.sk>
References:  <20191027214209.712d62ca@zeta.dino.sk> <CAPQ4ffuoHRFghwo=okFoNVHw9TYdwFw_wgUxa5_rm6FqjsNVsg@mail.gmail.com> <20191027232956.28b11772@zeta.dino.sk> <20191028191005.GA89835@bluezbox.com> <20191028201952.20a92307@zeta.dino.sk> <20191102214100.500ba493@zeta.dino.sk>

next in thread | previous in thread | raw e-mail | index | archive | help
Milan Obuch (freebsd-hackers@dino.sk) wrote:
> On Mon, 28 Oct 2019 20:19:52 +0100
> Milan Obuch <freebsd-hackers@dino.sk> wrote:
> 
> [ snip ]
> 
> > Hi,
> > 
> > I found uart_dev_snps.c being somewhat near what I need. I am trying
> > to extract necessary bits from this and other files (what you wrote is
> > just one bit), it seems our docs are lacking in this area.
> > 
> > Regards,
> > Milan
> >
> 
> After studying other uart_dev_xxx.c files I am able to create working
> skeleton uart driver. I can compile it, kldload, and get some console
> output. Right now, I hit another problem - uart framework is not
> documented well, at least no man page is found in share/man directory.
> 
> My probe function is similar to that in uart_dev_snps.c file,
> simplified, and I need to know what arguments should uart_bus_probe
> function be invoked with. In many device drivers there are mostly
> zeros, but this does not work for me.
> 
> Currently I am getting error 6, ENXIO, so I am not correctly attaching
> my driver to device. Putting some printf here and there, I found test
> at line 508, file uart_core.c, fails - sc->sc_class is null. Question
> is, now, where and how should this field in this structure be
> initialized...
> 
> I am sure I need docs/description for other functions as well, so if
> anybody knows where good uart framework description could be found,
> please advice. Or if somebody already has good understanding of it and
> could help me with my issues, it wil be greatly appreciated.

if you follow uart_dev_snsps.c template, the sc_class is set in
probe function:

        uart_class = (struct uart_class *)ofw_bus_search_compatible(dev,
            compat_data)->ocd_data;
        if (uart_class == NULL)
                return (ENXIO);

        freq = 0;
        sc = device_get_softc(dev);
        sc->ns8250.base.sc_class = uart_class;


ocd_data is the second element in your compat_data var:

static struct ofw_compat_data compat_data[] = {
        { "snps,dw-apb-uart",           (uintptr_t)&uart_snps_class },
        { "marvell,armada-38x-uart",    (uintptr_t)&uart_snps_class },
        { NULL,                         (uintptr_t)NULL }
};

Every uart_dev_ driver has its own softc structure (device-specific data
associated with the device instance): struct uart_pl011_softc, struct
snps_softc. uart_core operates with uart_softc. Device-specific
softc is supposed to have uart_softc variable as the very first member:

struct uart_pl011_softc {
        struct uart_softc       base;
        uint16_t                imsc; /* Interrupt mask */
};

This way it can be converted to uart_softc by a pointer cast. Poor man's
OOP so to say.

In your case, my guess would be: you either do not set the sc_class
member var in probe function or your base var is not the first in the
struct.

-- 
gonzo



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191103042321.GA49790>