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>