Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Aug 2011 11:24:35 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-current@freebsd.org
Cc:        Jason Harmening <jason.harmening@gmail.com>
Subject:   Re: device_probe_and_attach() fails in kernel built w/ clang
Message-ID:  <201108181124.35122.jhb@freebsd.org>
In-Reply-To: <CAM=8qan9D45ovCMD46yQFRxv8VZJKTg0MWi_BS_vSpPBtb6RKg@mail.gmail.com>
References:  <CAM=8qan9D45ovCMD46yQFRxv8VZJKTg0MWi_BS_vSpPBtb6RKg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday, August 18, 2011 2:03:14 am Jason Harmening wrote:
> Hi everyone,
> 
> I have a driver for PCI devices that have onboard I2C buses, so my
> driver needs to create an iicbus child for the PCI device.  So in my
> driver I use DRIVER_MODULE(iicbus, <my_pci_driver>, iicbus_driver,
> iicbus_devclass, NULL, NULL).  This works because iicbus_driver and
> iicbus_devclass are declared extern in iicbus.h.
> 
> Then during device attachment I create the iicbus child using:
> 
> device_add_child(parent, "iicbus", -1);
> ...
> device_probe_and_attach(iicbus_dev);
> 
> This all works fine for a kernel built w/ gcc.  But if I build the
> same kernel w/ clang, the device_probe_and_attach() call returns
> ENXIO.  I was able to debug this far enough to determine that
> device_probe_child() in subr_bus.c wasn't finding any matching
> drivers, so first_matching_driver() returned NULL and the matching
> loops fell through.
> 
> Interestingly enough, I have another driver for a similar class of
> devices that also uses iicbus, and if I load that driver after loading
> the first one, the *first* driver will be re-probed, and this time it
> will successfully create its iicbus devices and attach to the PCI
> devices.  The *second* driver, though, will still fail to create its
> iicbuses.
> 
> I'm not sure if this is some weird problem w/ the iicbus driver, with
> the kernel's probing routines, or with the module data structures and
> init calls generated by DRIVER_MODULE().  Whatever it is seems to be
> clang-related; removing optimization and march= from CFLAGS had no
> effect.  I'm using r224899/amd64.
> 
> Any help would be really appreciated.

Hmm, I would add some tracing to see if the iicbus/<my_pci_driver> is being 
registered at all.

You might also just use kldstat -v to check for it without needing any extra 
tracing as a first step.

However, if you dig into DRIVER_MODULE() you will see it creates a structure 
that is passed to a MOD_EVENT handler in sys/kern/subr_bus.c that registers 
new drivers.  That is where I would add instrumentation to make sure the new
iicbus driver is being registered correctly.

-- 
John Baldwin



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