Un peu d’USB3 dans vos homebrews ?

DarkMatterCore, à qui l’on doit (entre autre chose) la librairie homebrew USB « libusbhsfs », donne quelques nouvelles sur ce projet. En effet, il est loin d’avoir dit son dernier mot et l’améliore constamment. On apprend ainsi que les freezes aléatoires, qui pouvaient survenir lors de copies qui se passent mal, sont corrigés grâce à la réimplémentation de « usbHsEpPostBuffer »; et que les homebrews auront désormais accès à plus d’informations sur les périphériques connectés, ce qui laisse augurer des avancées dans le support de ces médias USB. Enfin, et c’est là une grande nouvelle qui méritait une petite news, le développeur indique travailler au support de l’USB3, ce qui démocratiserait d’autant plus le support de l’USB, peu importe le(s) homebrew(s).

Pour l’heure, il utilise une version modifiée du Custom Firmware Atmosphère, qui lui permet de patcher en temps réel le sysmodule USB pour forcer le support USB3, et les résultats sont plus que prometteurs, avec un gain de vitesse de l’ordre du double de la normale, y compris sur les petits fichiers (il n’a pas encore testé sur de gros morceaux, mais le gain de vitesse devrait être encore plus impressionnant).

↓ Message original (GBAtemp) (cliquer pour voir) ↓

I haven’t forgotten about this project just yet. I have been pretty busy since January, so I haven’t been able to work on this and nxdumptool as much as I did last year.

That being said, I have been slowly working on improving libusbhsfs and squashing some nasty bugs in the process. Some of these changes include:

  • A reimplementation of usbHsEpPostBuffer() to make it possible to use timeouts instead of indefinitely waiting for endpoint transfers to take place – which is pretty bad if an endpoint suddenly becomes stalled, resulting in those dreaded softlocks some of you guys have been experiencing.
  • Thanks to the previous point, the Bulk-Only Transport driver could also be updated to accurately follow some small error correction guidelines that weren’t being met.
  • PKGBUILD scripts for NTFS-3G and lwext4 were updated as well to fix build issues experienced by some users under specific Linux distros.
  • More data about each drive and mounted volume is now made available to homebrew applications using the library (VID, PID, mount flags and USB string descriptors).

Next up, here comes something I’m sure some people will be excited about: I have been working on a way to reenable USB 3.0 support under HOS 9.0.0+.

Some time ago, it was possible to use the « usb30_force_enabled » flag in Atmosphère’s system_settings.ini to achieve this. However, HOS 9.0.0 introduced a hard dependency on the USB sysmodule in FS services, which means the USB sysmodule is now launched before Atmosphère is capable of parsing the INI file, rendering this flag completely useless.

Using ExeFS IPS patches is totally out of the question for the very same reason. And modifying Atmosphère to make it enable the « usb30_force_enabled » flag on its own doesn’t work because SD card access is required at that point.

Looking for an alternate solution, I decided to modify Atmosphère to make it capable of hot-patching the USB sysmodule to override the flag check in its NSO before it’s launched. And it worked! USB 3.0 access is again a possibility. Here’s a dump of a raw UsbHsInterface element obtained from a USB 3.0 drive (HOS 11.0.2, AMS 0.18.1):

    (UsbHsInterfaceInfo) inf:
        (s32) ID: 0x50010000
        (u32) deviceID_2: 0x00000003
        (u32) unk_x8: 0x00000002
        (usb_interface_descriptor) interface_desc:
            (u8) bLength: 0x09
            (u8) bDescriptorType: 0x04
            (u8) bInterfaceNumber: 0x00
            (u8) bAlternateSetting: 0x00
            (u8) bNumEndpoints: 0x02
            (u8) bInterfaceClass: 0x08
            (u8) bInterfaceSubClass: 0x06
            (u8) bInterfaceProtocol: 0x50
            (u8) iInterface: 0x00
        (usb_endpoint_descriptor) input_endpoint_descs[0]:
            (u8) bLength: 0x07
            (u8) bDescriptorType: 0x05
            (u8) bEndpointAddress: 0x81
            (u8) bmAttributes: 0x02
            (u16) wMaxPacketSize: 0x0400
            (u8) bInterval: 0x00
        (usb_endpoint_descriptor) output_endpoint_descs[1]:
            (u8) bLength: 0x07
            (u8) bDescriptorType: 0x05
            (u8) bEndpointAddress: 0x02
            (u8) bmAttributes: 0x02
            (u16) wMaxPacketSize: 0x0400
            (u8) bInterval: 0x00
        (usb_ss_endpoint_companion_descriptor) input_ss_endpoint_companion_descs[0]:
            (u8) bLength: 0x06
            (u8) bDescriptorType: 0x30
            (u8) bMaxBurst: 0x0F
            (u8) bmAttributes: 0x00
            (u16) wBytesPerInterval: 0x0000
        (usb_ss_endpoint_companion_descriptor) output_ss_endpoint_companion_descs[1]:
            (u8) bLength: 0x06
            (u8) bDescriptorType: 0x30
            (u8) bMaxBurst: 0x0F
            (u8) bmAttributes: 0x00
            (u16) wBytesPerInterval: 0x0000
    (char) pathstr: "SsDevice3-/T2/P1/A01"
    (u32) busID: 0x00000004
    (u32) deviceID: 0x00000003
    (usb_device_descriptor) device_desc:
        (u8) bLength: 0x12
        (u8) bDescriptorType: 0x01
        (u16) bcdUSB: 0x0300
        (u8) bDeviceClass: 0x00
        (u8) bDeviceSubClass: 0x00
        (u8) bDeviceProtocol: 0x00
        (u8) bMaxPacketSize0: 0x09
        (u16) idVendor: 0x0BC2
        (u16) idProduct: 0x231A
        (u16) bcdDevice: 0x0708
        (u8) iManufacturer: 0x01
        (u8) iProduct: 0x02
        (u8) iSerialNumber: 0x03
        (u8) bNumConfigurations: 0x01
    (usb_config_descriptor) config_desc:
        (u8) bLength: 0x09
        (u8) bDescriptorType: 0x02
        (u16) wTotalLength: 0x0079
        (u8) bNumInterfaces: 0x01
        (u8) bConfigurationValue: 0x01
        (u8) iConfiguration: 0x00
        (u8) bmAttributes: 0x80
        (u8) MaxPower: 0x70
    (u64) timestamp: 0x0000000884CC1EDD

Pay special attention to the bcdUSB and wMaxPacketSize fields, as well as the availability of SuperSpeed endpoint companion descriptors.

Preliminary tests using the random reads carried out by NTFS-3G while getting filesystem stats from a mounted NTFS volume look very promising:

USB 2.1 (unmodified Atmosphère build):

[2021-03-01 01:11:36,7639944] -> statvfs() start.
[2021-03-01 01:11:42,135820152] -> statvfs() end.
Result: 5,371825752 seconds.

USB 3.0 (modified Atmosphère build):
[2021-03-01 01:13:19,911078844] -> statvfs() start.
[2021-03-01 01:13:22,876405504] -> statvfs() end.
Result: 2,96532666 seconds.

Furthermore, the current BOT driver works perfectly fine with BOT interfaces provided by USB 3.0 drives. I have yet to test sequential reads and writes, but judging by these small, random reads, I’m sure it’ll be awesome. :)

Even though transfers already are faster than before, BOT doesn’t support command queuing, so my endgoal is to implement a USB Attached SCSI (UAS) driver in libusbhsfs to fully take advantage of USB 3.0 speeds. Let me know what you think.


Un travail à suivre de très près…