Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Aug 2006 19:14:10 +0400
From:      Roman Kurakin <rik@inse.ru>
To:        "M. Warner Losh" <imp@bsdimp.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: global data via module howto
Message-ID:  <44EF13C2.7080809@inse.ru>
In-Reply-To: <20060821.105429.1649766410.imp@bsdimp.com>
References:  <44E87CCD.30105@inse.ru> <20060820.220124.387191884.imp@bsdimp.com>	<44E994AF.6040805@inse.ru> <20060821.105429.1649766410.imp@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

    I've done it. Thanks for the road map.
M. Warner Losh wrote:
> In message: <44E994AF.6040805@inse.ru>
>             Roman Kurakin <rik@inse.ru> writes:
> : M. Warner Losh wrote:
> : > In message: <44E87CCD.30105@inse.ru>
> : >             Roman Kurakin <rik@inse.ru> writes:
> : > :     I have the following problem:
> : > : module A
> : > :     int x;
> : > : 
> : > : module B
> : > :     extern int x;
> : > : 
> : > :     Module A is loaded, module B can't be loaded cause of unknow 'x'.
> : > : What should I do to make x global?
> : >
> : > Better to make module B depend on module A.  Making it global is
> : > generally a bad idea.
> : >
> : > in module A:
> : > MODULE_VERSION(A, 1);
> : >
> : > In module B:
> : > MODULE_DEPEND(B, A, 1, 1, 1);
> : >   
> : Module dependence is not the goal.
>
> Right.  That's how symbols are visible to other modules.
>   
Yes, it works. And it is still needed for class/subclass scheme.
> : >
> : > : PS. I am working on porting irda support for USB devices from NetBSD.
> : > : The current model consists of two layers hw and sw. hw is the usb device
> : > : driver. sw is some software layer the same for all device and it is a
> : > : child on top of hw 'bus'. To make this working I need to add
> : > : DRIVER_MODULE for each 'bus'. To make sw independent from the
> : > : bus I need to export _driver and _class structures and put DRIVER_MODULE
> : > : in 'bus' code instead of 'child'.
> : >
> : > Are you sure that you need to do this?  I'm pretty sure that you can
> : > create a base class irdabus and then derive all the hw modules that
> : > implement irdabus from than and all the children will automatically
> : > probe.  No need to export the driver/class structures.
>   
This was a bit wrong. You still need to export kobj_class (eq driver_t 
structure,
DECLARE_CLASS).
> : >   
> : I have a bit reversed case. In common case we have a driver for "bus" 
> : with many
> : consumers. And we have children that declares itself via DRIVER_MODULE.
> : If child could work on several buses it declares itself several times 
> : one for each
> : bus. In my case I have several drivers that could be treated as bus 
> : driver for the
> : same child:
> : 
> :  -----------USB------------
> :  |            |           |
> : ustir       uirda     smth_else
> :  \            |           /
> :   ---------irframe--------
> : 
> : Imagine, if the network interface was implemented as a child of every 
> : network
> : adapter. This is the same. In common case I'll put DRIVER_MODULE in a child
> : for each bus and recompile after adding a new one. In this case I do no 
> : want to
> : recompile the child for every new "bus" since child do not depend on 
> : such "bus"
> : - it is the same for all. So we may call this a pseudo-device with 
> : unknown list
> : of buses. I know, I could implement this other way, but I just want to 
> : play with
> : newbus a bit and the original NetBSD driver was implemented this way.
>
> I think I must have not been clear before.  I thought gave a solution
> to this that doesn't require a new DRIVER_MODULE for each new device.
> Let me try again.
>
> I'd hoped to say make ustir, uirda and smth_else all subclasses of a
> irbridge class, just like we do for pci and cardbus today.  Then
> irframe would attach to irbridge and you'd only need to list
> DRIVER_MODULE lines once.  This isn't a reversed case at all.  It is
> actually quite common, but has been 'papered over' until now via
> multiple DRIVER_MODULE lines, except in the case of pci/cardbus[*].
>
> I can provide more details on actually doing this.  Right now I'm
> doing something similar for all the iic bridges that we have in the
> kernel.  The number of devices with iicbus children is way too large
> and we can eliminate that issue via the technique.  I'd be happy to
> flesh it out a bit, or provide you with sample code if you need that.
>   
For curious:
==============irda_bus==============
static device_probe_t irda_bus_probe;
static device_attach_t irda_bus_attach;
static device_detach_t irda_bus_detach;

static device_method_t irda_bus_methods[] = {
       /* stub functions */
        DEVMETHOD(device_probe, irda_bus_probe), /* aka match */
        DEVMETHOD(device_attach, irda_bus_attach),
        DEVMETHOD(device_detach, irda_bus_detach),
        {0,0}
};

struct irda_bus_softc {
};

MODULE_VERSION(irda_bus, 1);
DEFINE_CLASS_0(irda_bus, irda_bus_driver, irda_bus_methods,
        sizeof(struct irda_bus_softc));

===================================
================ustir================
Static device_probe_t ustir_match;
Static device_attach_t ustir_attach;
Static device_detach_t ustir_detach;

Static devclass_t ustir_devclass;

Static device_method_t ustir_methods[] = {
        DEVMETHOD(device_probe, ustir_match),
        DEVMETHOD(device_attach, ustir_attach),
        DEVMETHOD(device_detach, ustir_detach),
        {0,0}
};

MODULE_DEPEND(ustir, usb, 1, 1, 1);
MODULE_DEPEND(ustir, irda_bus, 1, 1, 1);

DECLARE_CLASS(irda_bus_driver);
DEFINE_CLASS_1(irda_bus, ustir_driver, ustir_methods,
        sizeof(struct ustir_softc), irda_bus_driver);

DRIVER_MODULE(ustir, uhub, ustir_driver, ustir_devclass, 
usbd_driver_load, 0);
==========================================
===================ir_frame=================
static device_probe_t irframe_match;
static device_attach_t irframe_attach;
static device_detach_t irframe_detach;

devclass_t irframe_devclass;

static device_method_t irframe_methods[] = {
        DEVMETHOD(device_probe, irframe_match),
        DEVMETHOD(device_attach, irframe_attach),
        DEVMETHOD(device_detach, irframe_detach),
        {0,0}
};

driver_t irframe_driver = {
        "irframe",
        irframe_methods,
        sizeof(struct irframe_softc)
};

DRIVER_MODULE(irframe, irda_bus, irframe_driver, irframe_devclass, NULL, 
NULL);
==========================================

Method functions are called from a subclass, so in base class you may
use stub functions. As I mentioned, you still need to export, in this case
irframe_driver. One bad thing, that with usb devices you can't use
USB_DECLARE_DRIVER(). In case of other such cases we could for
sure define USB_DECLARE_DRIVER_x().

PS. I'll cleanup a bit what I've done and will put ported drivers to 
perforce. As
I usually do, I'll keep original driver via #ifdef, so it could be used 
as a reference
material for usb driver porters.

I know that ustir/irframe were ported before from NetBSD, but a posted 
link seems
to be dead. In any case I've also ported uirda. irframe_tty is on the 
way in case I'll
find a hardware for testings.

rik
> Warner
>
> [*] There's still pci and cardbus DRIVER_MODULE lines in many drivers,
> but they are almost not needed.  There's a newbus bug that I've not
> had the time to track down that prevents kldload from working
> competely correctly in some cases (like when loading the cardbus
> module).  Once I get that fixed...
>
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
>   




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