global data via module howto
Roman Kurakin
rik at inse.ru
Fri Aug 25 15:03:41 UTC 2006
Hi,
I've done it. Thanks for the road map.
M. Warner Losh wrote:
> In message: <44E994AF.6040805 at inse.ru>
> Roman Kurakin <rik at inse.ru> writes:
> : M. Warner Losh wrote:
> : > In message: <44E87CCD.30105 at inse.ru>
> : > Roman Kurakin <rik at 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 at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>
More information about the freebsd-hackers
mailing list