12.x: USB matching a device with 2 configurations, one matched by built-in dext

I am writing a DEXT to support a USB to 5Gigabit Ethernet adapter.

Interestingly, this adapter is "supported" because it presents 2 configurations:

(1) the "native" fast vendor interface

(2) a slower ECM profile that is matched by AppleUserECM.dext

Unfortunately the vendor's high performance driver was written as an IOKit kext for x86 pre Big Sur, which is of no use at all for an M1. However, its performance on x86 MAC is vastly superior to the generic Apple ECM DEXT

However, no matter how I configure my DEXT which matches bConfiguration=1, the Apple DEXT which matches bConfiguration=2 always takes precedence.

Configuration Descriptors of actual hardware

>>> dev = usb.core.find()
>>> print(dev)
DEVICE ID 20f4:e05a on Bus 001 Address 001 =================
 bLength        : 0x12 (18 bytes)
 bDescriptorType    :  0x1 Device
 bcdUSB        : 0x320 USB 3.2
 bDeviceClass     :  0x0 Specified at interface
 bDeviceSubClass    :  0x0
 bDeviceProtocol    :  0x0
 bMaxPacketSize0    :  0x9 (9 bytes)
 idVendor       : 0x20f4
 idProduct       : 0xe05a
 bcdDevice       : 0x101 Device 1.01
 iManufacturer     :  0x1 TRENDnet
 iProduct       :  0x2 TRENDnet USB 5G Adapter
 iSerialNumber     :  0x3 000000DB
 bNumConfigurations  :  0x2
 CONFIGURATION 1: 224 mA ==================================
  bLength       :  0x9 (9 bytes)
  bDescriptorType   :  0x2 Configuration
  wTotalLength    : 0x39 (57 bytes)
  bNumInterfaces   :  0x1
  bConfigurationValue :  0x1
  iConfiguration   :  0x4 LAN
  bmAttributes    : 0xa0 Bus Powered, Remote Wakeup
  bMaxPower      : 0x70 (224 mA)
....
 CONFIGURATION 2: 224 mA ==================================
  bLength       :  0x9 (9 bytes)
  bDescriptorType   :  0x2 Configuration
  wTotalLength    : 0x62 (98 bytes)
  bNumInterfaces   :  0x2
  bConfigurationValue :  0x2
  iConfiguration   :  0x8 CDC LAN
  bmAttributes    : 0x80 Bus Powered
  bMaxPower      : 0x70 (224 mA)

Kernel logs with real hardware plugged in and my DEXT installed still matching Apple DEXT

2022-11-11 18:51:39.854308-0800 0x3aa6  Default  0x0         0   0  kernel: (IOUSBHostFamily) 000980.145603 usb-drd1-port-ss@01200000: AppleUSBHostPort::enumerateDeviceComplete_block_invoke: enumerated 0x20f4/e05a/0101 (TRENDnet USB 5G Adapter) at 5 Gbps
.....
2022-11-11 18:51:39.898925-0800 0x47bd  Default  0x0         0   0  kernel: Found class: IOUSBHostInterface
2022-11-11 18:51:39.899998-0800 0x47bd  Default  0x0         0   0  kernel: (com.apple.DriverKit.AppleUserECM.dext) OnQueue SDK version 0x150600
2022-11-11 18:51:39.902587-0800 0x47c0  Default  0x0         0   0  kernel: (com.apple.DriverKit.AppleUserECM.dext) AppleUserECMData interface 1 belongs to ECM, matched with UNF (0)
2022-11-11 18:51:39.902612-0800 0x47b3  Default  0x0         0   0  kernel: DK: AppleUserECMData-0x1000010bf::start(CDC Data 0-0x1000010bc) ok
2022-11-11 18:51:39.926256-0800 0x47b2  Default  0x0         0   0  kernel: DK: AppleUserECM-0x1000010bd::start(CDC Ctrl-0x1000010bb) ok

Configuration Descriptors of spoofed hardware with 2nd config descriptor removed

>>> dev = usb.core.find()
>>> print(dev)
DEVICE ID 20f4:e05a on Bus 001 Address 001 =================
 bLength        : 0x12 (18 bytes)
 bDescriptorType    :  0x1 Device
 bcdUSB        : 0x200 USB 2.0
 bDeviceClass     :  0x0 Specified at interface
 bDeviceSubClass    :  0x0
 bDeviceProtocol    :  0x0
 bMaxPacketSize0    :  0x9 (9 bytes)
 idVendor       : 0x20f4
 idProduct       : 0xe05a
 bcdDevice       : 0x101 Device 1.01
 iManufacturer     :  0x1 TrendWhatever
 iProduct       :  0x2 AQC!111
 iSerialNumber     :  0x3 123456789012
 bNumConfigurations  :  0x1
 CONFIGURATION 1: 224 mA ==================================
  bLength       :  0x9 (9 bytes)
  bDescriptorType   :  0x2 Configuration
  wTotalLength    : 0x39 (57 bytes)
  bNumInterfaces   :  0x1
  bConfigurationValue :  0x1
  iConfiguration   :  0x4 LAN
  bmAttributes    : 0xa0 Bus Powered, Remote Wakeup
  bMaxPower      : 0x70 (224 mA)

and proof, it matches with my driver (but obviously fails to work, since the driver isn't finished and the hardware is a mock)

2022-11-11 19:11:47.693212-0800 0x9a91  Default  0x0         0   0  kernel: DK: AQC111DrvExt-0x1000012b7 waiting for server au.com.jquirke.AQC111DrvExt-1000012b7
....
 (Sandbox) /Library/SystemExtensions/BD547468-F734-47F9-80B7-D2FBC5A2297C/au.com.jquirke.AQC111DrvExt.dext/au.com.jquirke.AQC111DrvExt[2904] ==> com.apple.dext
...
2022-11-11 19:11:47.723612-0800 0x9a98  Default  0x0         0   0  kernel: Found class: IOUserNetworkRxCompletionQueue
2022-11-11 19:11:47.724041-0800 0x9a98  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) OnQueue SDK version 0x150400
2022-11-11 19:11:47.725374-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz init
2022-11-11 19:11:47.725472-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz Start_Impl
2022-11-11 19:11:47.725485-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz super::start 0
2022-11-11 19:11:47.725488-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz odynamiccast 0
2022-11-11 19:11:47.725555-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz interfaceopen 0
2022-11-11 19:11:47.725563-0800 0x9a9b  Default  0x0         0   0  kernel: (au.com.jquirke.AQC111DrvExt.dext) foobaz selectalternate e00002f0
2022-11-11 19:11:47.725595-0800 0x9a91  Default  0x0         0   0  kernel: DK: AQC111DrvExt-0x1000012b7::start(IOUSBHostInterface-0x1000012b5) fail
Answered by jquirke1 in 735992022

For clarification , the "spoofed" hardware is just a simple STM microcontroller that is flashed to impersonate the descriptors of the real USB hardware, with the key difference that I removed the CDC-ECM descriptor.

Accepted Answer

For clarification , the "spoofed" hardware is just a simple STM microcontroller that is flashed to impersonate the descriptors of the real USB hardware, with the key difference that I removed the CDC-ECM descriptor.

[message to moderator] I accidentally marked my own reply as accepted answer. Can you undo this action

12.x: USB matching a device with 2 configurations, one matched by built-in dext
 
 
Q