UCLASS_BLK driver binding without devtree and U_BOOT_DEVICE

Simon Glass sjg at chromium.org
Thu Jun 4 15:00:58 CEST 2020


Hi Anastasiia,

On Thu, 4 Jun 2020 at 03:06, Anastasiia Lukianenko
<Anastasiia_Lukianenko at epam.com> wrote:
>
> Hello Simon,
>

Thanks for sending as plain text.

> We are adding support for Xen [1] para-virtualized block device as a u-boot
> driver and have some questions with respect to driver model and
> instantiation of new devices.
> Because of the nature of the device driver we cannot use device tree or
> define statically the device instances beforehand and those get known
> during some device enumeration.
> So, this makes us bind the new devices to the driver at run-time. For that we
> use:
> (init)
>     device_bind_by_name(gd->dm_root, false, &info, &udev);
> ...
>     ret = uclass_get(UCLASS_BLK, &uc);
>     if (ret) {
>         printk("UCLASS_BLK class has no registered entities\n");
>         return;
>     }
>     uclass_foreach_dev(udev, uc) {
>         ret = device_probe(udev);
>         if (ret < 0)
>             printk("Failed to probe " DRV_NAME " device\n");
>     }
> ...
> (probe)
>     struct blkfront_platdata *platdata = dev_get_platdata(udev);
>     struct blkfront_dev *blk_dev = dev_get_priv(udev);
>     struct blk_desc *desc = dev_get_uclass_platdata(udev);
>
> We create a device with [IF_TYPE_PVBLOCK] = "pvblock" (UCLASS_BLK)
> typename and UCLASS. Everything goes smooth, driver's probe is
> called, but the problem we are seeing is that when we call
> "part list pvblock 0" command with the device description and udev's
> parent not set or set to gd->dm_root then we see
> <** Bad device pvblock 0 **> from blk_get_device_by_str function.
>
> Digging into the code shows that there is a check (equality of block
> device's interface type and the uclass of the block device's parent) in
> blk_get_devnum_by_typename function in drivers/blk-uclass.c file,
> which makes us think that we should somehow set our parent to
> UCLASS_BLK or something. At the same time setting udev to
> udev->parent makes things work, but it doesn't seem to be correct.
> (For example, "pvblock part 0" command works properly, because it
> doesn't use blk_get_devnum_by_typename.)

At present BLK devices have a parent device which handles the actual
device access. For example, look at mmc-uclass.c where you can see
mmc_blk which is always a child of the MMC device. The block device
does not know how to access the hardware.

>
> 1. What is the right procedure to bind a device to a driver in such
> cases as ours? Can we still use what we have? (Is it okay to use
> device_bind_by_name function in init stage?)

I suspect you should create a new uclass for a xen device, perhaps one
specific to a xen device that provides block-level access.

> 2. How can we become a child of UCLASS_BLK or any other entity, so
> we are recognized by the framework properly? (Do we need to create
> child from our udev device in probe stage by using blk_create_devicef
> function?)

You should bind your BLK device in your XEN device bind() routine.

Probing should be automatic. You might find sunxi_mmc.c useful as an example.

> 3. Why parent's and device's U_CLASS must be the same? For what
> cases this check has been implemented?

U-Boot has a variety of block devices. The existing mechanism
(pre-dating driver model) uses an interface type to distinguish them
(IF_TYPE_...). You can see this in commands like:

fs ls usb 0:2
ext2ls usb 0:2

Here 'usb' is the interface type.

As above, you likely need to add a new interface type. See
IF_TYPE_VIRTIO, for eaxmple.

> 4. According to blk uclass implementation is it okay to have parent with
> UCLASS_ROOT for block device? If no, then what parent should we assign?

I think we might do that in tests in strange cases, but I think you
should have your own parent, as above.


>
> [1] - https://xenproject.org/

Regards,
Simon


More information about the U-Boot mailing list