hibyr1: route ADB through the usb-mode setting
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Sun, 12 Jul 2026 11:19:40 -0400
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 078a506dfd0deb18165a3ed80c7fcbdb3afb0d31 Author: Michael McAllister <[email protected]> Date: Mon Jul 6 22:47:01 2026 +0100 hibyr1: route ADB through the usb-mode setting hibyr1 defines HAVE_USB_ADB so the USB mode setting offers an ADB entry, but hiby_set_usb_mode() never handled USB_MODE_ADB (it fell through to default), so selecting ADB did nothing. Wire USB_MODE_ADB up to enable_adb(). It builds the adb function on the gadget and hands the functionfs mount and adbd to the vendor respawner /sbin/adbserver.sh, rather than mounting functionfs inline (which the original code flagged as flaky); adbd binds the UDC itself, so usb_enable() leaves the UDC alone in ADB mode. disable_adb() unlinks the adb function and unmounts its functionfs but leaves the function in place to be reused, matching how adbserver.sh cycles it, so re-enabling adb never re-creates it. The mass-storage LUN is removable, so the host clears its backing file when it ejects the volume (Linux does this on unmount). Re-arm the LUN in usb_enable() on each connect, so the disk is exported on every insert and not only the first. Assisted-by: Claude Opus 4.8 Change-Id: Ia8f119a1a599e6dd3c1219cb4e193c753725a06a diff --git a/firmware/target/hosted/hiby/usb-hiby-gadget.c b/firmware/target/hosted/hiby/usb-hiby-gadget.c index 651b25bb70..af04690248 100644 --- a/firmware/target/hosted/hiby/usb-hiby-gadget.c +++ b/firmware/target/hosted/hiby/usb-hiby-gadget.c @@ -65,6 +65,9 @@ void hiby_set_usb_mode(int mode) { usb_init_device(); } + if (_usb_mode == mode) + return; + switch(mode) { case USB_MODE_MASS_STORAGE: logf("Enabling Mass Storage\n"); @@ -74,6 +77,10 @@ void hiby_set_usb_mode(int mode) { logf("Enabling Charge\n"); enable_charging(); break; + case USB_MODE_ADB: + logf("Enabling ADB\n"); + enable_adb(); + break; default: break; } @@ -90,11 +97,29 @@ int usb_detect(void) return power_input_status() == POWER_INPUT_USB_CHARGER ? USB_INSERTED : USB_EXTRACTED; } +static void set_mass_storage_lun(void) +{ + const char *device = "/dev/mmcblk0p1"; + + // If partition 1 doesn't exist we'll try the main device + if (access(device, F_OK) != 0) + device = "/dev/mmcblk0"; + + sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/functions/mass_storage.0/lun.0/file", device); +} + void usb_enable(bool on) { logf(">>>>>>>>>>>>>>>>> usb_enable(%d)\n", on); logf("usb enable %d %d\n", on, _usb_mode); + if (_usb_mode == USB_MODE_ADB) + return; + + // Re-arm the LUN on each connect, otherwise the disk is only exported the first time. + if (on && _usb_mode == USB_MODE_MASS_STORAGE) + set_mass_storage_lun(); + sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/UDC", on ? "13500000.otg_new" : "\n"); } @@ -141,51 +166,49 @@ void enable_charging(void) { disable_adb(); } -#if 1 void enable_adb(void) { logf(">>>>>>>>>>>>>>>>> set_adb()\n"); // Disable mass storage if it was running disable_mass_storage(); - // Remove any lingering adb daemon - system("killall -9 adbd"); + // Remove any lingering adb daemon and its respawner + system("killall adbserver.sh adbd 2>/dev/null"); system("mkdir -p /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/strings/0x409"); system("mkdir -p /sys/kernel/config/usb_gadget/adb_demo/functions/ffs.adb"); + // Use the adb VID/PID so the host recognises the device + sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/idVendor", "0x18d1"); + sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/idProduct", "0xd002"); + // Now we'll override configuration and MaxPower sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/configs/c.1/strings/0x409/configuration", "adb"); sysfs_set_int("/sys/kernel/config/usb_gadget/adb_demo/configs/c.1/MaxPower", 120); // And link up the adb function to the usb gadget config - system("ln -s /sys/kernel/config/usb_gadget/adb_demo/functions/ffs.adb /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/"); + system("ln -sf /sys/kernel/config/usb_gadget/adb_demo/functions/ffs.adb /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/"); - int is_mounted = !system("mountpoint -q /dev/usb-ffs/adb"); + system("mkdir -p /dev/usb-ffs/adb"); - if (!is_mounted) { - system("mkdir -p /dev/usb-ffs/adb"); - /* This seems to fail, but adb will still work and then it will be mounted. Not sure what's up here... */ - system("mount -t functionfs adb /dev/usb-ffs/adb"); - } - - // Boot adb daemon - system("/usr/bin/adbd &"); + // Let the vendor respawner mount functionfs and run adbd, which binds the UDC. + system("/sbin/adbserver.sh 440 &"); } void disable_adb(void) { - // Remove any lingering adb daemon - system("killall -9 adbd"); + // Remove any lingering adb daemon and its respawner + system("killall adbserver.sh adbd 2>/dev/null"); - // Remove the adb link to config - if (access("/sys/kernel/config/usb_gadget/adb_demo/configs/c.1/ffs.adb", F_OK) == 0) { - system("rm /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/ffs.adb"); + // Unbind the UDC so the gadget can be reconfigured + if (access("/sys/kernel/config/usb_gadget/adb_demo/UDC", F_OK) == 0) { + sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/UDC", "\n"); } - // Remove the adb function - if (access("/sys/kernel/config/usb_gadget/adb_demo/functions/ffs.adb", F_OK) == 0) { - system("rm -rf /sys/kernel/config/usb_gadget/adb_demo/functions/ffs.adb"); + // Unlink the adb function from config (the function is left in place and + // reused, so re-creating it in enable_adb can't block) + if (access("/sys/kernel/config/usb_gadget/adb_demo/configs/c.1/ffs.adb", F_OK) == 0) { + system("rm /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/ffs.adb"); } // Reset the MaxPower to its default value @@ -200,13 +223,9 @@ void disable_adb(void) { // Unmount adb if (!system("mountpoint -q /dev/usb-ffs/adb")) { - system("unmount /dev/usb-ffs/adb"); + system("umount -l /dev/usb-ffs/adb"); } } -#else -void enable_adb(void) {} -void disable_adb(void) {} -#endif void enable_mass_storage(void) { logf(">>>>>>>>>>>>>>>>> set_mass_storage()\n"); @@ -226,15 +245,7 @@ void enable_mass_storage(void) { system("ln -s /sys/kernel/config/usb_gadget/adb_demo/functions/mass_storage.0 /sys/kernel/config/usb_gadget/adb_demo/configs/c.1/"); - char mount_device[32] = "/dev/mmcblk0p1"; - - // If partition 1 doesn't exist we'll try the main device - if (access(mount_device, F_OK) != 0) { - memset(mount_device, 0, sizeof(mount_device)); - strcpy(mount_device, "/dev/mmcblk0"); - } - - sysfs_set_string("/sys/kernel/config/usb_gadget/adb_demo/functions/mass_storage.0/lun.0/file", mount_device); + set_mass_storage_lun(); } void disable_mass_storage(void) { diff --git a/firmware/target/hosted/sysfs.c b/firmware/target/hosted/sysfs.c index 1c3fe8c396..7bacb3de54 100644 --- a/firmware/target/hosted/sysfs.c +++ b/firmware/target/hosted/sysfs.c @@ -178,7 +178,7 @@ bool sysfs_get_string(const char *path, char *value, int size) } -bool sysfs_set_string(const char *path, char *value) +bool sysfs_set_string(const char *path, const char *value) { FILE *f = open_write(path); if(f == NULL) diff --git a/firmware/target/hosted/sysfs.h b/firmware/target/hosted/sysfs.h index 639cc1c409..de2b8db31e 100644 --- a/firmware/target/hosted/sysfs.h +++ b/firmware/target/hosted/sysfs.h @@ -28,4 +28,4 @@ bool sysfs_set_int(const char *path, int value); bool sysfs_get_char(const char *path, char *value); bool sysfs_set_char(const char *path, char value); bool sysfs_get_string(const char *path, char *value, int size); -bool sysfs_set_string(const char *path, char *value); +bool sysfs_set_string(const char *path, const char *value); -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs