In Yocto notes - 3, we did the following update to drivers/usb/musb/musb_gadget.c to notify MUSB gedget setup/cleanup
int musb_gadget_setup(struct musb *musb) will notify the gadget-setup
and
void musb_gadget_cleanup(struct musb *musb) will notify the gadget-cleanup
To get the details in writing a udev rule for setup/cleanup, we can use udevadm(8)
For example, with the config fragment update usb_configfs.cfg, we get the musb
Module Size Used by
musb_dsps 16384 0
musb_hdrc 135168 1 musb_dsps
Run the udevadm (in the background), then unload the musb_dsps (rmmod musb_dsps), and we'll see gadget_cleanup in action.
Similarly, if we now insmod musb_dsps, we'll see gadget_setup in action.
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
:
:
Add a udev rule for gedget-setup at startp. We are matching SUBSYSTEM, ACTION and EVENT keys, then RUN key assignment/append to run our script.
echo "SUBSYSTEM==\"platform\",ACTION==\"change\",ENV{EVENT}==\"gadget_setup\",RUN+=\"/home/root/setup.sh\"" > /etc/udev/rules.d/20-musb-setup-test.rules
setup.sh has the same content as we had in 'USB notes - 2'
modprobe libcomposite
mount -t configfs none /sys/kernel/config/
cd /sys/kernel/config/usb_gadget/
mkdir g
cd g/
echo "0xA55A" > idVendor
echo "0x0111" > idProduct
mkdir strings/0x409
echo "0123" > strings/0x409/serialnumber
echo "hello" > strings/0x409/manufacturer
echo "ncm" > strings/0x409/product
mkdir functions/ncm.usb0
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "ncm" > configs/c.1/strings/0x409/configuration
ln -s functions/ncm.usb0 configs/c.1/
echo "musb-hdrc.0" > UDC
Now, after booting the beagle and checking
ifconfig -a
we'lll see usb0
To get the eth working, from host,
ifconfig usb0 169.254.211.10 up
Instead of using the gadget_setup EVENT we added, we can use bind ACTION and the DRIVER name to get this working:
echo "SUBSYSTEM==\"platform\",ACTION==\"bind\",DRIVER==\"musb-hdrc\",RUN+=\"/home/root/setup.sh\"" > /etc/udev/rules.d/20-musb-setup-test.rules
Driver binding is the process of associating a device with a device driver that can control it (ref: Documentation/driver-api/driver-model/binding.rst).
Refer udev(7) for udev related details.
Here's the musb-gadget update where we have added the gadget_setup for demonstration (see Upstream-Status: Denied noted in Yocto notes - 3):
meta-mylayer/recipes-kernel/linux/linux-yocto/0001-musb-gadget-udev-notification.patch
---
drivers/usb/musb/musb_gadget.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 051c6da7cf6d..e6e0fe52659a 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1770,6 +1770,15 @@ static inline void musb_g_init_endpoints(struct musb *musb)
}
}
+static void send_gadget_uevent(struct device *dev, const char *event)
+{
+ char event_string[32];
+ char *envp[] = { event_string, NULL };
+ snprintf(event_string, sizeof(event_string), "%s", event);
+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+}
+
+
/* called once during driver setup to initialize and link into
* the driver model; memory is zeroed.
*/
@@ -1803,6 +1812,8 @@ int musb_gadget_setup(struct musb *musb)
if (status)
goto err;
+ send_gadget_uevent(musb->controller, "EVENT=gadget_setup");
+
return 0;
err:
musb->g.dev.parent = NULL;
@@ -1815,6 +1826,8 @@ void musb_gadget_cleanup(struct musb *musb)
if (musb->port_mode == MUSB_HOST)
return;
+ send_gadget_uevent(musb->controller, "EVENT=gadget_cleanup");
+
cancel_delayed_work_sync(&musb->gadget_work);
usb_del_gadget_udc(&musb->g);
}