Date: Wed, 10 Jun 2009 13:43:15 -0400 From: John Baldwin <jhb@freebsd.org> To: "M. Warner Losh" <imp@bsdimp.com> Cc: freebsd-arch@freebsd.org Subject: Re: devclass_find_free_unit Message-ID: <200906101343.15311.jhb@freebsd.org> In-Reply-To: <20090610.112813.623117012.imp@bsdimp.com> References: <200906100822.15516.jhb@freebsd.org> <200906101302.03211.jhb@freebsd.org> <20090610.112813.623117012.imp@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 10 June 2009 1:28:13 pm M. Warner Losh wrote: > In message: <200906101302.03211.jhb@freebsd.org> > John Baldwin <jhb@freebsd.org> writes: > : On Wednesday 10 June 2009 12:21:44 pm M. Warner Losh wrote: > : > In message: <200906100822.15516.jhb@freebsd.org> > : > John Baldwin <jhb@freebsd.org> writes: > : > : On Tuesday 09 June 2009 7:42:49 pm M. Warner Losh wrote: > : > : > What purpose does devclass_find_free_unit serve? I think it can safely > : be > : > : > eliminated from the tree. The current design is racy. > : > : > > : > : > Comments? > : > : > > : > : > It is currently used: > : > : > > : > : > ./arm/xscale/ixp425/.svn/text-base/avila_ata.c.svn-base: > : > : device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0)); > : > : > ./arm/xscale/ixp425/avila_ata.c: device_add_child(dev, "ata", > : > : devclass_find_free_unit(ata_devclass, 0)); > : > : > ./arm/at91/.svn/text-base/at91_cfata.c.svn-base: > : > : device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0)); > : > : > ./arm/at91/at91_cfata.c: device_add_child(dev, "ata", > : > : devclass_find_free_unit(ata_devclass, 0)); > : > : > ./powerpc/psim/.svn/text-base/ata_iobus.c.svn-base: > : > : devclass_find_free_unit(ata_devclass, 0)); > : > : > > : > : > # All the above can be replaced with a simple '-1'. > : > : > > : > : > ata/ata-pci.c: unit : devclass_find_free_unit(ata_devclass, 2)); > : > : > ata/ata-usb.c: devclass_find_free_unit(ata_devclass, 2))) > : == > : > : NULL) { > : > : > > : > : > These can likely be replaced by '2', but that may result in a warning > : > : > message being printed that likely can be eliminated... > : > : > : > : ata does this so it can reserve ata0 and ata1 for the "legacy" ATA > : channels on > : > : legacy ATA PCI adapters. That is, if you have both SATA controllers and a > : > : PATA controller, this allows the two PATA channels to always be ata0 and > : ata1 > : > : and the PATA drivers to always be ad0 - ad3. You could perhaps implement > : > : this in 8.x now by a really horrendous hack of having ISA hints for ata0 > : and > : > : ata1 and letting bus_hint_device_unit() in the atapci driver claim those > : > : hints for the channels on PATA controllers. > : > > : > I think it already does something akin to this: > : > > : > /* attach all channels on this controller */ > : > for (unit = 0; unit < ctlr->channels; unit++) { > : > if ((ctlr->ichannels & (1 << unit)) == 0) > : > continue; > : > child = device_add_child(dev, "ata", > : > ((unit == 0 || unit == 1) && ctlr->legacy) ? > : > unit : devclass_find_free_unit(ata_devclass, 2)); > : > if (child == NULL) > : > device_printf(dev, "failed to add ata child device\n"); > : > else > : > device_set_ivars(child, (void *)(intptr_t)unit); > : > } > : > > : > Why not just replace devclass_find_free_unit with '2'? > : > : Because if you add 'ata2', and 'ata2' exists it will fail, it won't rename it > : to ata3. And that is what ata is trying to do. It basically wants > : to "reserve" ata0 and ata1 and then use device_add_child(..., -1). However, > : device_add_child(..., -1) will not "reserve" ata0 and ata1. > > Ah yes. It does just fail. However, setting the unit here is racy. > If we were to make the device tree probe more parallel, then we may > have a case where devclass_find_free_unit gets called from two > different threads, returning the same number, then the > device_child_add works for only one of these threads... Yes, it is quite racey. > : > All the other users in the tree aer bogus and should be replaced by > : > -1. Well, I'm not 100% sure about the ata-usb.c patch, since that > : > would also be necessary to avoid collision. And the above code really > : > only applies to x86-based machine, right? There's no need to do that > : > for non-intel boxes. Or is the assumption on those boxes the > : > controller would never be in legacy. > : > : Any machine that can have a PCI PATA controller or a PCI SATA controller > : operating in "legacy" mode. That said, the compatability bits probably don't > : matter as much on non-x86 as there are not older releases to be compatible > : with (or the impact would be less severe if we renumber people's drives at > : least). > > Yes. I guess I was asking if we need an ifdef for this behavior or > not... I guess not.. > > I think we need to have a better way to 'reserve' a unit than we have > today. I think this will be better to do that and retire > devclass_find_free_unit. I think that only one or two uses in the > tree are legit... Well, that was why I suggested possibly depending on the (already-existing) ata[01] ISA hints and having a bus_hint_device_unit() method for the atapci driver that let PATA channels claim ata[01]. Then the ata driver could always use device_add_unit(..., -1) to add "ata" devices. It is sort of odd, but it actually maps what the code is trying to do: let the PATA ATA channels "look like" the old ISA channels. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906101343.15311.jhb>