Add a check to avoid dommed (by null pointer dereference) recursive call, not only for UCLASS_BLK.
When booting my Rock Pi 4B+ with a USB mass storage stick plugged into one of the USB 2 ports (EHCI), when it is plugged before power on, when issuing a usb tree or usb info command I get a "Synchronous Error" and a reset just after printing the mass storage device in the usb tree or usb info. It might depend on the contents of the USB stick too, I'm not sure. It seems like I have two devices as children of the mass storage device. When there's only a UCLASS_BLK it works fine, but when there's a UCLASS_BLK and a UCLASS_BOOTDEV, it recurses with a null udev as first parameter and fails. Likewise for usb_show_info(). Not sure if this should be a patch, an RFC or a bug report. There may be a better way to solve this, I haven't researched commit 201417d700a2ab09 ("bootstd: Add the bootdev uclass") and bootdev flow properly, or thought about cases where udev is not null but the recursive call might need preventing too. Feel free to think it over before merging (or after). But this at least fixes a reset at an innocent looking usb tree or usb info command. Maybe we can improve it later? Cc: Simon Glass <s...@chromium.org> Cc: Lukasz Majewski <lu...@denx.de> Cc: Marek Vasut <ma...@denx.de> Signed-off-by: Xavier Drudis Ferran <xdru...@tinet.cat> --- cmd/usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/usb.c b/cmd/usb.c index 73addb04c4..7e6065aa51 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -421,7 +421,8 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) * Ignore emulators and block child devices, we only want * real devices */ - if ((device_get_uclass_id(child) != UCLASS_USB_EMUL) && + if (udev && + (device_get_uclass_id(child) != UCLASS_USB_EMUL) && (device_get_uclass_id(child) != UCLASS_BLK)) { usb_show_tree_graph(udev, pre); pre[index] = 0; @@ -607,7 +608,8 @@ static void usb_show_info(struct usb_device *udev) (device_get_uclass_id(child) != UCLASS_USB_EMUL) && (device_get_uclass_id(child) != UCLASS_BLK)) { udev = dev_get_parent_priv(child); - usb_show_info(udev); + if (udev) + usb_show_info(udev); } } } -- 2.20.1