Changes

Jump to navigation Jump to search
8,486 bytes added ,  16:04, 11 October 2022
no edit summary
Line 2: Line 2:     
= usb:ds =
 
= usb:ds =
This is "nn::usb::ds::IDsService".
+
This is "nn::usb::ds::IDsRootSession".
 +
 
 +
Pre-11.0.0 this was [[#IDsService]].
    
Used for Switch<>PC USB comms, aka Switch-as-device. This seems to only be usable in handheld-mode with the Switch directly connected to a host via an USB cable, not(?) in docked-mode.
 
Used for Switch<>PC USB comms, aka Switch-as-device. This seems to only be usable in handheld-mode with the Switch directly connected to a host via an USB cable, not(?) in docked-mode.
This service is used during [[Factory Setup|factory setup]] by [[Manu Services|manu]].
+
This service is used during [[Factory Setup|factory setup]] by [[Manu Services|manu]]. This is also used by [[Capmtp_services|capmtp]].
   −
This service session is used as an IPC [[IPC_Marshalling|domain]] by [[Manu Services|manu]]. All of these {get-session} commands also return an output u8 and the u32 [[IPC_Marshalling|domainID]], for using those sessions as domains.
+
This service session is used as an IPC [[IPC_Marshalling|domain]] by [[Manu Services|manu]].
    
This service can be used by multiple processes at the same time, with separate interfaces. However, if one process does usbds shutdown, usbds will reset to defaults even if there's a process still using it.  
 
This service can be used by multiple processes at the same time, with separate interfaces. However, if one process does usbds shutdown, usbds will reset to defaults even if there's a process still using it.  
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#OpenDsService]]
 +
|}
 +
 +
== OpenDsService ==
 +
Unofficial name.
 +
 +
No input. Returns an [[#IDsService]].
 +
 +
== IDsService ==
 +
This is "nn::usb::ds::IDsService".
 +
 +
Various cmds were updated/moved with [11.0.0+].
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 19: Line 38:  
| 1 || [[#BindClientProcess]]
 
| 1 || [[#BindClientProcess]]
 
|-
 
|-
| 2 || [[#GetDsInterface]]
+
| 2 || [[#AddInterface]]
 
|-
 
|-
 
| 3 || [[#GetStateChangeEvent]]
 
| 3 || [[#GetStateChangeEvent]]
Line 40: Line 59:  
|-
 
|-
 
| 11 || [5.0.0+] Disable
 
| 11 || [5.0.0+] Disable
 +
|-
 +
| 12 || [8.0.0+]
 
|}
 
|}
   Line 50: Line 71:  
** Uses [[#SetVidPidBcd]].
 
** Uses [[#SetVidPidBcd]].
 
* Interface init:
 
* Interface init:
** Uses [[#GetDsInterface]], then uses commands from that with the rest of the following.
+
** Uses [[#AddInterface]], then uses commands from that with the rest of the following.
 
** Uses [[#GetSetupEvent]].
 
** Uses [[#GetSetupEvent]].
 
** Uses [[#GetCtrlInCompletionEvent]].
 
** Uses [[#GetCtrlInCompletionEvent]].
 
** Uses [[#GetCtrlOutCompletionEvent]].
 
** Uses [[#GetCtrlOutCompletionEvent]].
* Initializes two endpoints via using [[#GetDsEndpoint]] twice.
+
* Initializes two endpoints via using [[#AddEndpoint]] twice.
    
== Configuration ==
 
== Configuration ==
Line 64: Line 85:  
The following is the default <code>lsusb -v {...}</code> output when the usbds service wasn't used.
 
The following is the default <code>lsusb -v {...}</code> output when the usbds service wasn't used.
   −
pre-5.0.0: The endpoints are configured using [[#GetDsEndpoint]], the total number of endpoints is the number of open [[#IDsEndpoint]] sessions. bInterfaceNumber is {0-based index for the enabled [[#IDsInterface]] session.} Some of the interface fields are configured using [[#GetDsInterface]].
+
pre-5.0.0: The endpoints are configured using [[#AddEndpoint]], the total number of endpoints is the number of open [[#IDsEndpoint]] sessions. bInterfaceNumber is {0-based index for the enabled [[#IDsInterface]] session.} Some of the interface fields are configured using [[#AddInterface]].
    
When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000.
 
When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000.
Line 136: Line 157:  
Takes 1 copy-handle for the current process (0xFFFF8001).
 
Takes 1 copy-handle for the current process (0xFFFF8001).
   −
== GetDsInterface ==
+
== AddInterface ==
 
Takes 2 type-5 buffers and returns an output u8 and an [[#IDsInterface]]. [[Manu_Services|Manu]] sends a 0x09-byte descriptor (e.g.: 0x09, 0x04, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00) in the first buffer and a string ("usb") in the second buffer.
 
Takes 2 type-5 buffers and returns an output u8 and an [[#IDsInterface]]. [[Manu_Services|Manu]] sends a 0x09-byte descriptor (e.g.: 0x09, 0x04, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00) in the first buffer and a string ("usb") in the second buffer.
   Line 177: Line 198:  
No input. Returns an output u32. Returns an error when [[#BindDevice]] wasn't used.
 
No input. Returns an output u32. Returns an error when [[#BindDevice]] wasn't used.
   −
Returns the current state. Values:
+
Returns the current state.
* 0: Initial state.
+
 
* 6: Device init starting.
+
{| class="wikitable" border="1"
* 3: {Initialization}, previous state is 6.
+
|-
* 4: {Initialization}, previous state is 3.
+
! Value || Name || Description
* 5: Initialization done, data-transfer is now available.
+
|-
 +
| 0 || Detached || Device is not attached to USB.
 +
|-
 +
| 1 || Attached || Device is attached, but is not powered.
 +
|-
 +
| 2 || Powered || Device is attached and powered, but has not been reset.
 +
|-
 +
| 3 || Default || Device is attached, powered, and has been reset, but does not have an address.
 +
|-
 +
| 4 || Address || Device is attached, powered, has been reset, has an address, but is not configured.
 +
|-
 +
| 5 || Configured || Device is attached, powered, has been reset, has an address, configured, and may be used.
 +
|-
 +
| 6 || Suspended || Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used.
 +
|}
    
== SetVidPidBcd ==
 
== SetVidPidBcd ==
Line 205: Line 240:     
The last 3 blocks are ASCII strings. The data following each string is all-zero, for padding to size 0x20.
 
The last 3 blocks are ASCII strings. The data following each string is all-zero, for padding to size 0x20.
 +
 +
== Cmd12 ==
 +
No input. Returns an output u32.
    
== IDsInterface ==
 
== IDsInterface ==
 
This is "nn::usb::ds::IDsInterface".
 
This is "nn::usb::ds::IDsInterface".
 +
 +
Various cmds were updated/moved with [11.0.0+]. New Cmd11 was added with [13.0.0+].
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#GetDsEndpoint]] ||
+
| 0 || [[#AddEndpoint]]
 
|-
 
|-
| 1 || [[#GetSetupEvent]] ||
+
| 1 || [[#GetSetupEvent]]
 
|-
 
|-
| 2 || || Takes a type-0x6 output buffer, no other output. Memcpys data to outbuf with outsize, uses size 0x8 if outsize is too large.
+
| 2 || [[#GetSetupPacket]]
 
|-
 
|-
| 3 || [[#EnableInterface]] ||
+
| 3 || [[#Enable]]
 
|-
 
|-
| 4 || [[#DisableInterface]] ||
+
| 4 || [[#Disable]]
 
|-
 
|-
| 5 || [[#CtrlInPostBufferAsync]] ||
+
| 5 || [[#CtrlIn]]
 
|-
 
|-
| 6 || [[#CtrlOutPostBufferAsync]] ||
+
| 6 || [[#CtrlOut]]
 
|-
 
|-
| 7 || [[#GetCtrlInCompletionEvent]] ||
+
| 7 || [[#GetCtrlInCompletionEvent]]
 
|-
 
|-
| 8 || [[#GetCtrlInReportData]] ||
+
| 8 || [[#GetCtrlInUrbReport]]
 
|-
 
|-
| 9 || [[#GetCtrlOutCompletionEvent]] ||
+
| 9 || [[#GetCtrlOutCompletionEvent]]
 
|-
 
|-
| 10 || [[#GetCtrlOutReportData]] ||
+
| 10 || [[#GetCtrlOutUrbReport]]
 
|-
 
|-
| 11 || [[#StallCtrl]] ||
+
| 11 || [[#CtrlStall]]
 
|-
 
|-
| 12 || [5.0.0+] AppendConfigurationData ||
+
| 12 || [5.0.0+] AppendConfigurationData
 
|}
 
|}
   −
Commands cmd2, [[#CtrlInPostBufferAsync]], [[#CtrlOutPostBufferAsync]], and [[#StallCtrl]], will throw an error if the interface is not [[#EnableInterface|enabled]]. [[#GetDsEndpoint]] will throw an error if the interface is [[#EnableInterface|enabled]].
+
Commands [[#GetSetupPacket]], [[#CtrlIn]], [[#CtrlOut]], and [[#CtrlStall]], will throw an error if the interface is not [[#EnableInterface|enabled]]. [[#AddEndpoint]] will throw an error if the interface is [[#EnableInterface|enabled]].
   −
=== GetDsEndpoint ===
+
=== AddEndpoint ===
 
Takes a type-5 buffer and returns an output u8 and an [[#IDsEndpoint]]. [[Manu_Services|Manu]] uses this twice for getting two endpoint sessions, with the following 0x7-byte buffer data:
 
Takes a type-5 buffer and returns an output u8 and an [[#IDsEndpoint]]. [[Manu_Services|Manu]] uses this twice for getting two endpoint sessions, with the following 0x7-byte buffer data:
 
* First endpoint: 0x07, 0x05, 0x80, 0x02, 0x00, 0x02, 0x00
 
* First endpoint: 0x07, 0x05, 0x80, 0x02, 0x00, 0x02, 0x00
Line 267: Line 307:  
Returns an event handle. Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init.
 
Returns an event handle. Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init.
   −
=== EnableInterface ===
+
=== GetSetupPacket ===
 +
Takes a type-0x6 output buffer, no other output. Memcpys data to outbuf with outsize, uses size 0x8 if outsize is too large.
 +
 
 +
=== Enable ===
 
Takes no arguments. Enables the current interface.
 
Takes no arguments. Enables the current interface.
   −
Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[#GetDsEndpoint]] this isn't an issue since the final bInterfaceNumber will be unique.
+
Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[#AddEndpoint]] this isn't an issue since the final bInterfaceNumber will be unique.
    
Once enabled, the device/interface can then actually be used over USB.
 
Once enabled, the device/interface can then actually be used over USB.
   −
=== DisableInterface ===
+
=== Disable ===
 
Takes no arguments. Disables the current interface.
 
Takes no arguments. Disables the current interface.
   −
=== CtrlInPostBufferAsync ===
+
=== CtrlIn ===
 
Same as [[#PostBufferAsync]](with same input/output), except this uses control input endpoint 0x80.
 
Same as [[#PostBufferAsync]](with same input/output), except this uses control input endpoint 0x80.
   −
=== CtrlOutPostBufferAsync ===
+
=== CtrlOut ===
 
Same as [[#PostBufferAsync]](with same input/output), except this uses control output endpoint 0x00.
 
Same as [[#PostBufferAsync]](with same input/output), except this uses control output endpoint 0x00.
   Line 286: Line 329:  
Returns an event handle for polling the completion of input control commands. Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80.
 
Returns an event handle for polling the completion of input control commands. Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80.
   −
=== GetCtrlInReportData ===
+
=== GetCtrlInUrbReport ===
Same as [[#GetReportData]](with same input/output), except this uses control input endpoint 0x80.
+
Same as [[#GetUrbReport]](with same input/output), except this uses control input endpoint 0x80.
    
=== GetCtrlOutCompletionEvent ===
 
=== GetCtrlOutCompletionEvent ===
 
Returns an event handle for polling the completion of output control commands. Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00.
 
Returns an event handle for polling the completion of output control commands. Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00.
   −
=== GetCtrlOutReportData ===
+
=== GetCtrlOutUrbReport ===
Same as [[#GetReportData]](with same input/output), except this uses control output endpoint 0x00.
+
Same as [[#GetUrbReport]](with same input/output), except this uses control output endpoint 0x00.
   −
=== StallCtrl ===
+
=== CtrlStall ===
 
No input/output.
 
No input/output.
   Line 305: Line 348:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#PostBufferAsync]] ||
+
| 0 || [[#PostBufferAsync]]
 
|-
 
|-
| 1 || || No input/output.
+
| 1 || [[#Cancel]]
 
|-
 
|-
| 2 || [[#GetCompletionEvent]] ||
+
| 2 || [[#GetCompletionEvent]]
 
|-
 
|-
| 3 || [[#GetReportData]] ||
+
| 3 || [[#GetUrbReport]]
 
|-
 
|-
| 4 || [[#Stall]] ||
+
| 4 || [[#Stall]]
 
|-
 
|-
| 5 || || Takes an input u8, no output.
+
| 5 || [[#SetZeroLengthTransfer]]
 +
|-
 +
| 6 || [7.0.0+]
 +
|-
 +
| 7 || [7.0.0+]
 +
|-
 +
| 8 || [11.0.0-14.1.2]
 +
|-
 +
| 9 || [11.0.0-14.1.2]
 
|}
 
|}
 +
 +
[11.0.0+] The official sw wrapper for PostBufferAsync can optionally use cmd9 instead, if an object state flag is set. offset=input_addr-object_addr_field, this will Abort if offset is >= object_size_field.
    
==== PostBufferAsync ====
 
==== PostBufferAsync ====
Takes an u32 ('''size''') and an u64 ('''buffer'''). Returns an output u32 ('''urbId'''). The output urbId can then be used while parsing the output of [[#GetReportData]], after waiting for the CompletionEvent to be signalled.
+
Takes an u32 ('''size''') and an u64 ('''buffer'''). Returns an output u32 ('''urbId'''). The output urbId can then be used while parsing the output of [[#GetUrbReport]], after waiting for the CompletionEvent to be signalled.
    
The buffer address must be 0x1000-byte aligned. The input size doesn't matter. It helps to use svcSetMemoryAttribute to turn off caching on the buffer.
 
The buffer address must be 0x1000-byte aligned. The input size doesn't matter. It helps to use svcSetMemoryAttribute to turn off caching on the buffer.
Line 332: Line 385:     
For receiving data, if size is less than {actual received USB packet size} the rest of the packet will be discarded. Later PostBufferAsync cmd(s) will only return data from new packets, not the remainder of the earlier packet(s).
 
For receiving data, if size is less than {actual received USB packet size} the rest of the packet will be discarded. Later PostBufferAsync cmd(s) will only return data from new packets, not the remainder of the earlier packet(s).
 +
 +
==== Cancel ====
 +
No input/output.
    
==== GetCompletionEvent ====
 
==== GetCompletionEvent ====
 
No input. Returns an output event handle for polling the completion of [[#PostBufferAsync]], even when it finished via [[#Stall]].
 
No input. Returns an output event handle for polling the completion of [[#PostBufferAsync]], even when it finished via [[#Stall]].
   −
==== GetReportData ====
+
==== GetUrbReport ====
 
No input. Returns 0x84 bytes of report data from the endpoint. Seems to be eventually loaded from state, since this doesn't trigger any USB bus activity. All-zero before PostBufferAsync was used at least once.
 
No input. Returns 0x84 bytes of report data from the endpoint. Seems to be eventually loaded from state, since this doesn't trigger any USB bus activity. All-zero before PostBufferAsync was used at least once.
   Line 366: Line 422:  
No input/output.
 
No input/output.
   −
Calls the same function used by [[#StallCtrl]], except this uses the endpoint associated with the current session.
+
Calls the same function used by [[#CtrlStall]], except this uses the endpoint associated with the current session.
    
Stops in-progress data-transfer done by [[#PostBufferAsync]].
 
Stops in-progress data-transfer done by [[#PostBufferAsync]].
   −
= usb:hs =
+
==== SetZeroLengthTransfer ====
 +
Takes an input u8, no output.
 +
 
 +
==== Cmd6 ====
 +
No input, returns an output bool.
 +
 
 +
==== Cmd7 ====
 +
No input, returns an output handle.
 +
 
 +
==== Cmd8 ====
 +
Takes an input u64 and a handle, no output. Stubbed, just returns an error.
 +
 
 +
==== Cmd9 ====
 +
Takes an input u32 size, an u64 offset, returns an u32 urbId. Stubbed, just returns an error.
 +
 
 +
= usb:hs, usb:hs:a =
 
This is "nn::usb::hs::IClientRootSession".
 
This is "nn::usb::hs::IClientRootSession".
 +
 +
[7.0.0+] usb:hs:a opens an nn::usb::hs::IClientRootSession, but sets an "isSystemClient" field in the object (and in interfaces/eps opened by the session) to false.
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| [2.0.0+] 0 || [[#BindClientProcess_2|#BindClientProcess]] ||
+
| [2.0.0+] 0 || [[#BindClientProcess_2|#BindClientProcess]]
 
|-
 
|-
| 1 ([1.0.0] 0) || [[#QueryAllInterfaces]] ||
+
| 1 ([1.0.0] 0) || [[#QueryAllInterfaces]]
 
|-
 
|-
| 2 ([1.0.0] 1) || [[#QueryAvailableInterfaces]] ||
+
| 2 ([1.0.0] 1) || [[#QueryAvailableInterfaces]]
 
|-
 
|-
| 3 ([1.0.0] 2) || [[#QueryAcquiredInterfaces]] ||
+
| 3 ([1.0.0] 2) || [[#QueryAcquiredInterfaces]]
 
|-
 
|-
| 4 ([1.0.0] 3) || [[#CreateInterfaceAvailableEvent]] ||
+
| 4 ([1.0.0] 3) || [[#CreateInterfaceAvailableEvent]]
 
|-
 
|-
| 5 ([1.0.0] 4) || [[#DestroyInterfaceAvailableEvent]] ||
+
| 5 ([1.0.0] 4) || [[#DestroyInterfaceAvailableEvent]]
 
|-
 
|-
| 6 ([1.0.0] 5) || [[#GetInterfaceStateChangeEvent]] ||
+
| 6 ([1.0.0] 5) || [[#GetInterfaceStateChangeEvent]]
 
|-
 
|-
| 7 ([1.0.0] 6) || [[#AcquireUsbIf]] ||
+
| 7 ([1.0.0] 6) || [[#AcquireUsbIf]]
 
|-
 
|-
| 8 ([1.0.0] 7) || [6.0.0+] ([1.0.0] [[#GetDescriptorString]]) ||
+
| 8 ([1.0.0] 7) || [6.0.0+] SetTestMode ([1.0.0] [[#GetDescriptorString]])
 
|-
 
|-
| [1.0.0] 8 || || Takes an input u32, no output. Stubbed, just returns 0.
+
| [1.0.0] 8 || [[#ResetDevice]]
 
|}
 
|}
   Line 406: Line 479:     
== QueryAllInterfaces ==
 
== QueryAllInterfaces ==
Takes an [[#UsbHsInterfaceFilter]] and a type-0x6 output buffer, returns an output s32 total_entries.
+
Takes an [[#DeviceFilter]] and a type-0x6 output buffer, returns an output s32 total_entries.
   −
The output buffer contains an array of [[#UsbHsInterface]]. This returns the same interfaces as [[#QueryAvailableInterfaces]], followed by the interfaces also returned by [[#QueryAcquiredInterfaces]].
+
The output buffer contains an array of [[#InterfaceQueryOutput]]. This returns the same interfaces as [[#QueryAvailableInterfaces]], followed by the interfaces also returned by [[#QueryAcquiredInterfaces]]. Except for the ID field in [[#InterfaceQueryOutput]], which is set to -1.
    
== QueryAvailableInterfaces ==
 
== QueryAvailableInterfaces ==
Takes an [[#UsbHsInterfaceFilter]] and a type-0x6 output buffer, returns an output s32 total_entries.
+
Takes an [[#DeviceFilter]] and a type-0x6 output buffer, returns an output s32 total_entries.
   −
The output buffer contains an array of [[#UsbHsInterface]].
+
The output buffer contains an array of [[#InterfaceQueryOutput]]. This only returns interfaces which are not acquired by any process.
    
== QueryAcquiredInterfaces ==
 
== QueryAcquiredInterfaces ==
 
Takes a type-0x6 output buffer and returns an output s32 total_entries.
 
Takes a type-0x6 output buffer and returns an output s32 total_entries.
   −
The output buffer contains an array of [[#UsbHsInterface]], for each interface which was acquired with [[#AcquireUsbIf]].
+
The output buffer contains an array of [[#InterfaceQueryOutput]], for each interface which was acquired with [[#AcquireUsbIf]].
    
== CreateInterfaceAvailableEvent ==
 
== CreateInterfaceAvailableEvent ==
Takes an input u8 and an [[#UsbHsInterfaceFilter]], and returns an output handle. The input value must be 0..2. This is used as an index in a table.
+
Takes an input u8 and an [[#DeviceFilter]], and returns an output handle. The input value must be 0..2. This is used as an index in a table.
    
The struct is located at +2 from the u8 in IPC rawdata.
 
The struct is located at +2 from the u8 in IPC rawdata.
Line 435: Line 508:  
No input, returns an output event handle with autoclear disabled.
 
No input, returns an output event handle with autoclear disabled.
   −
When signaled, this indicates that the user-process should use [[#QueryAcquiredInterfaces]] and cleanup state for interfaces which were already initialized with a matching ID in [[#UsbHsInterface]] +0x0. When total_entries is less than 1, this indicates that cleanup should be done for all currently open interfaces.
+
When signaled, this indicates that the user-process should use [[#QueryAcquiredInterfaces]] and cleanup state for interfaces which were already initialized and don't have any matching ID in [[#InterfaceProfile]] +0x0. When total_entries is less than 1, this indicates that cleanup should be done for all currently open interfaces.
    
== AcquireUsbIf ==
 
== AcquireUsbIf ==
Takes an input u32 and a type-0x6 output buffer, returns an [[#IClientIfSession]].
+
Takes an input u32 and a type-0x6 output buffer, returns an [[#IClientIfSession]]. On [3.0.0+] this takes an additional type-0x6 output buffer, before the original buffer. On [3.0.0+] the first buffer is 0x70-bytes, while the second one is 0x1B8. The user-process has the second buffer address immediately after the first one, which allows getting a complete [[#InterfaceProfile]].
   −
The input u32 is from the u32 at entry+0 from the associated [[#QueryAvailableInterfaces]] output entry. User-processes use size 0x1B8 for the output buffer. The output buffer contains the first 0x1B8-bytes from [[#UsbHsInterface]].
+
The input u32 is from the u32 at entry+0 from the associated [[#QueryAvailableInterfaces]] output entry. User-processes use size 0x1B8 for the first output buffer. The first output buffer contains an [[#InterfaceProfile]].
 +
 
 +
This returns an error if the interface was already acquired by another process.
    
== GetDescriptorString ==
 
== GetDescriptorString ==
Line 452: Line 527:     
Official sw doesn't use this, [[#SubmitControlInRequest]] is used instead.
 
Official sw doesn't use this, [[#SubmitControlInRequest]] is used instead.
 +
 +
== ResetDevice ==
 +
[1.0.0] Takes an input u32, no output. Stubbed, just returns 0.
    
== IClientIfSession ==
 
== IClientIfSession ==
Line 458: Line 536:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name  
 
|-
 
|-
| 0 || || No input, returns an output handle.
+
| 0 || [[#GetStateChangeEvent]]
 
|-
 
|-
| 1 || [[#SetInterface]] ||
+
| 1 || [[#SetInterface]]
 
|-
 
|-
| 2 || [[#GetInterface]] ||
+
| 2 || [[#GetInterface]]
 
|-
 
|-
| 3 || [[#GetAlternateInterface]] ||
+
| 3 || [[#GetAlternateInterface]]
 
|-
 
|-
| 4 [1.0.0] 5) || [[#GetCurrentFrame]] ||
+
| 4 ([1.0.0] 5) || [[#GetCurrentFrame]]
 
|-
 
|-
| [2.0.0+] 5 || [[#CtrlXferAsync]] ||
+
| [2.0.0+] 5 || [[#CtrlXferAsync]]
 
|-
 
|-
| 6 || ([1.0.0] [[#SubmitControlInRequest]]) || No input, returns an output handle. Signaled when [[#CtrlXferAsync]] finishes.
+
| 6 || [[#GetCtrlXferCompletionEvent]] ([1.0.0] [[#SubmitControlInRequest]])
 
|-
 
|-
| 7 || [[#GetCtrlXferReport]] ([1.0.0] [[#SubmitControlOutRequest]]) ||
+
| 7 || [[#GetCtrlXferReport]] ([1.0.0] [[#SubmitControlOutRequest]])
 
|-
 
|-
| 8 || [[#ResetDevice]] ||
+
| 8 || [[#ResetDevice]]
 
|-
 
|-
| 9 ([1.0.0] 4) || [[#OpenUsbEp]] ||
+
| 9 ([1.0.0] 4) || [[#OpenUsbEp]]  
 
|}
 
|}
   Line 484: Line 562:     
Immediately after opening the session, official sw uses cmd0 and cmd6.
 
Immediately after opening the session, official sw uses cmd0 and cmd6.
 +
 +
=== GetStateChangeEvent ===
 +
No input, returns an output handle.
    
=== SetInterface ===
 
=== SetInterface ===
Takes an input u8 and a type-0x6 output buffer, no output. The output buffer contains the first 0x1B8-bytes from [[#UsbHsInterface]].
+
Takes an input u8 and a type-0x6 output buffer, no output. The output buffer contains an [[#InterfaceProfile]].
    
=== GetInterface ===
 
=== GetInterface ===
Takes a type-0x6 output buffer, no output. The output buffer contains the first 0x1B8-bytes from [[#UsbHsInterface]].
+
Takes a type-0x6 output buffer, no output. The output buffer contains an [[#InterfaceProfile]].
    
=== GetAlternateInterface ===
 
=== GetAlternateInterface ===
Takes an input u8 and a type-0x6 output buffer, no output. The output buffer contains the first 0x1B8-bytes from [[#UsbHsInterface]]. The buffer size must match 0x1B8.
+
Takes an input u8 and a type-0x6 output buffer, no output. The output buffer contains an [[#InterfaceProfile]]. The buffer size must match 0x1B8.
    
=== GetCurrentFrame ===
 
=== GetCurrentFrame ===
Line 501: Line 582:  
=== CtrlXferAsync ===
 
=== CtrlXferAsync ===
 
Takes 2 input u8s ('''bmRequestType''' and '''bRequest'''), 3 input u16s ('''wValue''', '''wIndex''', and '''wLength'''), and an input u64 '''buffer''', no output.
 
Takes 2 input u8s ('''bmRequestType''' and '''bRequest'''), 3 input u16s ('''wValue''', '''wIndex''', and '''wLength'''), and an input u64 '''buffer''', no output.
 +
 +
=== GetCtrlXferCompletionEvent ===
 +
No input, returns an output handle. Signaled when [[#CtrlXferAsync]] finishes.
    
=== GetCtrlXferReport ===
 
=== GetCtrlXferReport ===
Line 517: Line 601:  
=== ResetDevice ===
 
=== ResetDevice ===
 
No input/output.
 
No input/output.
 +
 +
Resets the device: has the same affect as unplugging the device and plugging it back in.
    
=== OpenUsbEp ===
 
=== OpenUsbEp ===
Line 536: Line 622:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 0 || [[#Open]] ([1.0.0] [[#SubmitOutRequest]]) ||
+
| 0 || [[#ReOpen]] ([1.0.0] [[#SubmitOutRequest]])
 
|-
 
|-
| 1 || [[#Close]] ([1.0.0] [[#SubmitInRequest]]) ||
+
| 1 || [[#Close]] ([1.0.0] [[#SubmitInRequest]])
 
|-
 
|-
| 2 || || No input, returns an output handle. Signaled when [[#PostBufferAsync_2|#PostBufferAsync]] finishes. ([1.0.0] [[#Open]])
+
| 2 || [[#GetCompletionEvent_2|GetCompletionEvent]] ([1.0.0] Reset)
 
|-
 
|-
| 3 || [[#Populate]] ([1.0.0] [[#Close]]) ||
+
| 3 || [[#PopulateRing]] ([1.0.0] [[#Close]])
 
|-
 
|-
| [2.0.0+] 4 || [[#PostBufferAsync_2|#PostBufferAsync]] ||
+
| [2.0.0+] 4 || [[#PostBufferAsync_2|#PostBufferAsync]]
 
|-
 
|-
| [2.0.0+] 5 || [[#GetXferReport]] ||
+
| [2.0.0+] 5 || [[#GetXferReport]]
 
|-
 
|-
| [2.0.0+] 6 || || Takes 3 input u32s, 2 input u64s, and a type-0x5 input buffer, returns an output u32.
+
| [2.0.0+] 6 || [[#BatchBufferAsync]]
 
|-
 
|-
| [4.0.0+] 7 || ||
+
| [4.0.0+] 7 || [[#CreateSmmuSpace]]
 
|-
 
|-
| [4.0.0+] 8 || ||
+
| [4.0.0+] 8 || [[#ShareReportRing]]
 
|}
 
|}
   Line 571: Line 657:  
Official user-processes uses a buffer where the buffer address/size is page-aligned, where '''size''' is the original size before alignment. The user-process also flushes dcache for this buffer using '''size''', before/after using this command. Official sw passes value 0 for '''unk'''.
 
Official user-processes uses a buffer where the buffer address/size is page-aligned, where '''size''' is the original size before alignment. The user-process also flushes dcache for this buffer using '''size''', before/after using this command. Official sw passes value 0 for '''unk'''.
   −
==== Open ====
+
==== ReOpen ====
 
No input/output.
 
No input/output.
   Line 583: Line 669:  
Used by official sw prior to closing the endpoint session.
 
Used by official sw prior to closing the endpoint session.
   −
==== Populate ====
+
==== GetCompletionEvent ====
 +
No input, returns an output handle. Signaled when [[#PostBufferAsync_2|#PostBufferAsync]] finishes. ([1.0.0] [[#Open]])
 +
 
 +
==== PopulateRing ====
 
No input/output.
 
No input/output.
   Line 589: Line 678:     
==== PostBufferAsync ====
 
==== PostBufferAsync ====
Takes an input u32 '''size''', an input u64 '''buffer''', and an input u64, returns an output u32 '''xferId'''.
+
Takes an input u32 '''size''', an input u64 '''buffer''', and an input u64 '''unk''', returns an output u32 '''xferId'''.
    
HID-sysmodule passes value 0 for the last u64.
 
HID-sysmodule passes value 0 for the last u64.
 +
 +
Starts a data transfer with a single urb.
    
==== GetXferReport ====
 
==== GetXferReport ====
Takes an input u32 and a type-0x6 output buffer, returns an output u32 '''count'''.
+
Takes an input u32 and a type-0x6 ([3.0.0+] type-0x22) output buffer, returns an output u32 '''count'''.
    
The input u32 specifies the total number of entries to read, this must fit within the specified buffer size. The output u32 is the total actual output entries.
 
The input u32 specifies the total number of entries to read, this must fit within the specified buffer size. The output u32 is the total actual output entries.
Line 600: Line 691:  
The buffer contains an array of [[#XferReport]].
 
The buffer contains an array of [[#XferReport]].
   −
= UsbHsInterface =
+
==== BatchBufferAsync ====
 +
 
 +
Takes 3 input u32s ('''urbCount''', '''unk1''', and '''unk2'''), an input u64 '''buffer''' and u64 '''unk''', and a type-0x5 ([3.0.0+] type-0x21) input buffer, returns an output u32 '''xferId'''.
 +
 
 +
Where '''unk''' is the same as [[#PostBufferAsync_2|#PostBufferAsync]].
 +
 
 +
This uses the same func internally as [[#PostBufferAsync_2|#PostBufferAsync]] except multiple urbs are specified by the user: the input buffer contains an array of u32s for the size of each urb, where '''urbCount''' is the total number of entries in this array. With [[#PostBufferAsync_2|#PostBufferAsync]] the last 2 params passed to the internal func are hard-coded to 0, while with this command it's '''unk1''' and '''unk2'''.
 +
 
 +
==== CreateSmmuSpace ====
 +
Takes a total of 0x10-bytes of input, no output.
 +
 
 +
==== ShareReportRing ====
 +
Takes a total of 0x4-bytes of input and an input handle, no output.
 +
 
 +
= usb:pd =
 +
This is "nn::usb::pd::detail::IPdManager".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#OpenSession]]
 +
|}
 +
 
 +
Only system-titles with access to this are [[PTM_services|ptm]] and [[AM_services|am]].
 +
 
 +
== OpenSession ==
 +
No input. Returns an [[#IPdSession]].
 +
 
 +
== IPdSession ==
 +
This is "nn::usb::pd::detail::IPdSession".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || BindNoticeEvent
 +
|-
 +
| 1 || UnbindNoticeEvent
 +
|-
 +
| 2 || GetStatus
 +
|-
 +
| 3 || GetNotice
 +
|-
 +
| 4 || EnablePowerRequestNotice
 +
|-
 +
| 5 || DisablePowerRequestNotice
 +
|-
 +
| 6 || ReplyPowerRequest
 +
|}
 +
 
 +
= usb:pd:c =
 +
This is "nn::usb::pd::detail::IPdCradleManager".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#OpenCradleSession]]
 +
|}
 +
 
 +
USB-sysmodule symbols for this refer to "Cradle", which is the [[Dock]].
 +
 
 +
== OpenCradleSession ==
 +
No input. Returns an [[#IPdCradleSession]].
 +
 
 +
== IPdCradleSession ==
 +
This is "nn::usb::pd::detail::IPdCradleSession".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#SetCradleVdo]]
 +
|-
 +
| 1 || [[#GetCradleVdo]]
 +
|-
 +
| 2 || [[#ResetCradleUsbHub]]
 +
|-
 +
| 3 || [2.0.0+] [[#GetHostPdcFirmwareType]]
 +
|-
 +
| 4 || [2.0.0+] [[#GetHostPdcFirmwareRevision]]
 +
|-
 +
| 5 || [2.0.0+] [[#GetHostPdcManufactureId]]
 +
|-
 +
| 6 || [2.0.0+] [[#GetHostPdcDeviceId]]
 +
|-
 +
| 7 || [3.0.0+] [[#EnableCradleRecovery]]
 +
|-
 +
| 8 || [3.0.0+] [[#DisableCradleRecovery]]
 +
|}
 +
 
 +
=== SetCradleVdo ===
 +
Takes an input u32 '''Value''' and a [[#CradleVdmCommand]]. No output.
 +
 
 +
[[#CradleVdmCommand]] is translated to the actual [[#VdmCommand]] to send.
 +
 
 +
=== GetCradleVdo ===
 +
Takes an input [[#CradleVdmCommand]]. Returns an u32 '''Value'''.
 +
 
 +
[[#CradleVdmCommand]] is translated to the actual [[#VdmCommand]] to send.
 +
 
 +
=== ResetCradleUsbHub ===
 +
No input/output.
 +
 
 +
Sends [[#VdmCommand|VdmCommands]] 32 and 30.
 +
 
 +
=== GetHostPdcFirmwareType ===
 +
No input. Returns an output u16.
 +
 
 +
=== GetHostPdcFirmwareRevision ===
 +
No input. Returns an output u16.
 +
 
 +
=== GetHostPdcManufactureId ===
 +
No input. Returns an output u16.
 +
 
 +
=== GetHostPdcDeviceId ===
 +
No input. Returns an output u16.
 +
 
 +
=== EnableCradleRecovery ===
 +
No input. Returns an output u8.
 +
 
 +
=== DisableCradleRecovery ===
 +
No input. Returns an output u8.
 +
 
 +
= usb:pd:m =
 +
This is "nn::usb::pd::detail::IPdManufactureManager".
 +
 
 +
[2.0.0+] This service was merged into [[#usb:pd:c|usb:pd:c]].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#OpenManufactureSession]]
 +
|}
 +
 
 +
== OpenManufactureSession ==
 +
No input. Returns an [[#IPdManufactureSession]].
 +
 
 +
== IPdManufactureSession ==
 +
This is "nn::usb::pd::detail::IPdManufactureSession".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#GetHostPdcFirmwareType]]
 +
|-
 +
| 1 || [[#GetHostPdcFirmwareRevision]]
 +
|-
 +
| 2 || [[#GetHostPdcManufactureId]]
 +
|-
 +
| 3 || [[#GetHostPdcDeviceId]]
 +
|}
 +
 
 +
= usb:pm =
 +
This is "nn::usb::pm::IPmService".
 +
 
 +
[8.0.0+] This is "nn::usb::pm::IPmMainService".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || GetPowerEvent
 +
|-
 +
| 1 || GetPowerState
 +
|-
 +
| 2 || GetDataEvent
 +
|-
 +
| 3 || GetDataRole
 +
|-
 +
| 4 || SetDiagData
 +
|-
 +
| 5 || GetDiagData
 +
|}
 +
 
 +
USB Port Manager, only system-title using this is [[PTM_services|ptm]].
 +
 
 +
= usb:qdb =
 +
This is "nn::usb::qdb::IQdbManager".
 +
 
 +
This was added with [7.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#ImportQuirkDevices]]
 +
|-
 +
| 1 || [[#HasQuirk]]
 +
|}
 +
 
 +
== ImportQuirkDevices ==
 +
No input/output, takes a type-0x5 input buffer.
 +
 
 +
This loads data for [[#HidGamepad]] with the input .json.
 +
 
 +
== HasQuirk ==
 +
Takes 6-bytes of input (u16s '''vid''', '''pid''', '''bcdDevice''') and a type-0x5 input buffer, returns an output u8 bool indicating success.
 +
 
 +
Locates an entry in the [[#HidGamepad]] state with the input u16s, and checks for a '''quirks''' array entry where '''name''' matches the input buffer string. Returns 1 when found, 0 otherwise.
 +
 
 +
= usb:obsv =
 +
This is "nn::usb::pm::IPmObserverService".
 +
 
 +
This was added with [8.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 ||
 +
|-
 +
| 1 ||
 +
|}
 +
 
 +
= InterfaceQueryOutput =
 +
This is "nn::usb::InterfaceQueryOutput".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset || Size || Description
 +
|-
 +
| 0x0 || 0x1B8 || [[#InterfaceProfile|InterfaceProfile]]
 +
|-
 +
| 0x1B8 || 0x40 || "HsDevice-/L<unk0>/P<portnum>/A<unk1>" string (this is "FsDevice..." for the Dock USB 3.0 bus).
 +
|-
 +
| 0x1F8 || 0x4 || busID
 +
|-
 +
| 0x1FC || 0x4 || deviceID
 +
|-
 +
| 0x200 || 0x12+0x9(0x1B) || usb_device_descriptor, then usb_config_descriptor immediately afterwards.
 +
|-
 +
| 0x21B || 0x5 || Padding
 +
|-
 +
| 0x220 || 0x8 || Unknown u64 timestamp for when the device was inserted?
 +
|}
 +
 
 +
The INPUT/OUTPUT endpoint descriptors (usb_endpoint_descriptors/usb_ss_endpoint_companion_descriptors) were swapped with [8.0.0+] (above layout has the pre-8.0.0 layout), however the sysmodule code which writes this output struct was basically unchanged.
 +
 
 +
= InterfaceProfile =
 +
This is "nn::usb::InterfaceProfile".
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 630: Line 965:  
|-
 
|-
 
| 0x1B5 || 0x3 || Padding
 
| 0x1B5 || 0x3 || Padding
|-
  −
| 0x1B8 || 0x40 || "HsDevice-/L<unk0>/P<portnum>/A<unk1>" string (this is "FsDevice..." for the Dock USB 3.0 bus).
  −
|-
  −
| 0x1F8 || 0x4 || busID
  −
|-
  −
| 0x1FC || 0x4 || deviceID
  −
|-
  −
| 0x200 || 0x12+0x9(0x1B) || usb_device_descriptor, then usb_config_descriptor immediately afterwards.
  −
|-
  −
| 0x21B || 0x5 || Padding
  −
|-
  −
| 0x220 || 0x8 || Unknown u64 timestamp for when the device was inserted?
   
|}
 
|}
   −
This is a 0x228-byte struct (unofficial name).
+
= DeviceFilter =
 +
This is "nn::usb::DeviceFilter".
   −
= UsbHsInterfaceFilter =
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 676: Line 999:  
This is a 0x10-byte struct (unofficial name).
 
This is a 0x10-byte struct (unofficial name).
   −
This is used to filter [[#UsbHsInterface]], the query commands will only return the interface when these checks pass. This is also used for events with [[#CreateInterfaceAvailableEvent]]. When a bit in Flags is set, the associated descriptor field and the field in this struct are compared, on mismatch the interface will be filtered out. Passing Flags=0 is equivalent to disabling filtering since none of these checks will run.
+
This is used to filter [[#InterfaceQueryOutput]], the query commands will only return the interface when these checks pass. This is also used for events with [[#CreateInterfaceAvailableEvent]]. When a bit in Flags is set, the associated descriptor field and the field in this struct are compared, on mismatch the interface will be filtered out. Passing Flags=0 is equivalent to disabling filtering since none of these checks will run.
 +
 
 +
[7.0.0+]: The filter struct has to be unique, it can't match any existing filter structs used by [[#CreateInterfaceAvailableEvent]] (including other processes). Hence, Flags has to be non-zero. When initialized with usb:hs:a and VID and/or PID filtering is enabled, the VID/PID will be checked [[#HidGamepad]], with an error being throw if a matching device is found with quirk "ApplicationBlacklist" ([[#usb:qdb|usb:qdb]] cmd1 is used internally for this with bcdDevice=0).
    
Flags bits 0..6 use usb_device_descriptor, while 7..9 use usb_interface_descriptor. Support for bits 2..6 and the associated fields was added with [6.0.0+].
 
Flags bits 0..6 use usb_device_descriptor, while 7..9 use usb_interface_descriptor. Support for bits 2..6 and the associated fields was added with [6.0.0+].
Line 699: Line 1,024:  
! Offset || Size || Description
 
! Offset || Size || Description
 
|-
 
|-
| 0x0 || 0x4 || ?
+
| 0x0 || 0x4 || xferId (Only set for [[#GetXferReport]])
 
|-
 
|-
 
| 0x4 || 0x4 || Result
 
| 0x4 || 0x4 || Result
 
|-
 
|-
| 0x8 || 0x4 || ?
+
| 0x8 || 0x4 || requestedSize
 
|-
 
|-
| 0xC || 0x4 || Actual transferred size.
+
| 0xC || 0x4 || transferredSize
 
|-
 
|-
 
| 0x10 || 0x8? || ?
 
| 0x10 || 0x8? || ?
Line 714: Line 1,039:  
Official sw only uses the Result/size fields.
 
Official sw only uses the Result/size fields.
   −
= usb:pd =
+
= CradleVdmCommand =
This is "nn::usb::pd::detail::IPdManager".
+
This is "nn::usb::pd::CradleVdmCommand".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name
+
! Value || Name
 +
|-
 +
| 0 ||
 +
|-
 +
| 1 ||
 +
|-
 +
| 2 ||
 +
|-
 +
| 3 ||
 +
|-
 +
| 4 ||
 +
|-
 +
| 5 ||
 +
|-
 +
| 6 ||
 +
|-
 +
| 7 ||
 +
|-
 +
| 8 ||
 +
|-
 +
| 9 ||
 
|-
 
|-
| 0 || GetPdSession
+
| 10 ||  
 
|}
 
|}
   −
Only system-titles with access to this are [[PTM_services|ptm]] and [[AM_services|am]].
+
= VdmCommand =
 
+
This is "nn::usb::pd::driver::detail::VdmCommand".
== IPdSession ==
  −
This is "nn::usb::pd::detail::IPdSession".
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name
+
! Value || [[#CradleVdmCommand|CradleVdmCommand]] || [[#VdmCommandType|VdmCommandType]] || VdmCommandLength || Name
 +
|-
 +
| 0 || - || -1 || 0 || None
 +
|-
 +
| 1 || 0 || 0 || 3 || LedControlRequest
 +
|-
 +
| 2 || - || 1 || 3 || LedControlReply
 +
|-
 +
| 3 || 10 || 0 || 3 || DeviceTypeRequest
 +
|-
 +
| 4 || - || 1 || 3 || DeviceTypeReply
 +
|-
 +
| 5 || - || -1 || 0 || UsbPowerErrorNotice
 +
|-
 +
| 6 || 1 || 0 || 2 || Dp2HdmiFwVerRequest
 
|-
 
|-
| 0 || BindNoticeEvent
+
| 7 || - || 1 || 3 || Dp2HdmiFwVerReply
 
|-
 
|-
| 1 || UnbindNoticeEvent
+
| 8 || - || -1 || 0 || Dp2HdmiFwUpdateRequest
 
|-
 
|-
| 2 || GetStatus
+
| 9 || - || -1 || 0 || Dp2HdmiFwUpdateReply
 
|-
 
|-
| 3 || GetNotice
+
| 10 || - || -1 || 0 || Dp2HdmiFwUpdateNotice
 
|-
 
|-
| 4 || EnablePowerRequestNotice
+
| 11 || 2 || 0 || 2 || PdcHFwVerRequest
 
|-
 
|-
| 5 || DisablePowerRequestNotice
+
| 12 || - || 1 || 3 || PdcHFwVerReply
 
|-
 
|-
| 6 || ReplyPowerRequest
+
| 13 || - || -1 || 0 || PdcHFwUpdateRequest
|}
  −
 
  −
= usb:pd:c =
  −
This is "nn::usb::pd::detail::IPdCradleManager".
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Cmd || Name || Notes
+
| 14 || - || -1 || 0 || PdcHFwUpdateReply
 
|-
 
|-
| 0 || GetPdCradleSession || Returns a session handle for the below.
+
| 15 || - || -1 || 0 || PdcHFwUpdateNotice
|}
  −
 
  −
USB-sysmodule symbols for this refer to "Cradle", which is the [[Dock]].
  −
 
  −
== IPdCradleSession ==
  −
This is "nn::usb::pd::detail::IPdCradleSession".
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Cmd || Name || Notes
+
| 16 || 3 || 0 || 2 || PdcAFwVerRequest
 
|-
 
|-
| 0 || VdmUserWrite || Input { u32 value; u32 VdmUserId; }. Output {}.
+
| 17 || - || 1 || 3 || PdcAFwVerReply
If Cradle or RelayBox is connected, issues given VDM with value.
   
|-
 
|-
| 1 || VdmUserRead || Input { u32 VdmUserId; }. Output { u32 value; }.
+
| 18 || - || -1 || 0 || PdcAFwUpdateRequest
If Cradle or RelayBox is connected, returns u32 response from issuing given VDM.
   
|-
 
|-
| 2 || Vdm20Init || No input/output.
+
| 19 || - || -1 || 0 || PdcAFwUpdateReply
If Cradle or RelayBox is connected, caches result of VDM 0x20.
   
|-
 
|-
| 3 || [2.0.0+] GetFwType || No input. Returns an output u16.
+
| 20 || - || -1 || 0 || PdcAFwUpdateNotice
 
|-
 
|-
| 4 || [2.0.0+] GetFwRevision || No input. Returns an output u16.
+
| 21 || - || 0 || 3 || DeviceErrorNotice
 
|-
 
|-
| 5 || [2.0.0+] GetManufacturerId || No input. Returns an output u16.
+
| 22 || 4 || 0 || 2 || DeviceStateRequest
 
|-
 
|-
| 6 || [2.0.0+] GetDeviceId || No input. Returns an output u16.
+
| 23 || - || 1 || 3 || DeviceStateReply
 
|-
 
|-
| 7 || [3.0.0+] ||
+
| 24 || 5 || 0 || 2 || McuFwVerRequest
 
|-
 
|-
| 8 || [3.0.0+] ||
+
| 25 || - || 1 || 3 || McuFwVerReply
|}
  −
 
  −
Note: The VdmUserId given to VdmUserRead/VdmUserWrite is translated from the given (enum) value to the actual cmd to send.
  −
 
  −
= usb:pd:m =
  −
This is "nn::usb::pd::detail::IPdManufactureManager". This is only available on 1.0.0.
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Cmd || Name || Notes
+
| 26 || 6 || 0 || 2 || McuFwUpdateRequest
 
|-
 
|-
| 0 || || No input, returns an [[#IPdManufactureSession]].
+
| 27 || - || 1 || 2 || McuFwUpdateReply
|}
  −
 
  −
== IPdManufactureSession ==
  −
This is "nn::usb::pd::detail::IPdManufactureSession".
  −
 
  −
These commands just load the u16 from global state.
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Cmd || Name || Notes
+
| 28 || 7 || 0 || 2 || UsbHubSleepRequest
 
|-
 
|-
| 0 || || No input, returns an output u16.
+
| 29 || - || 1 || 2 || UsbHubSleepReply
 
|-
 
|-
| 1 || || No input, returns an output u16.
+
| 30 || 8 || 0 || 2 || UsbHubResetRequest
 
|-
 
|-
| 2 || || No input, returns an output u16.
+
| 31 || - || 1 || 2 || UsbHubResetReply
 
|-
 
|-
| 3 || || No input, returns an output u16.
+
| 32 || 9 || 0 || 2 || UsbHubControlRequest
 
|-
 
|-
 +
| 33 || - || 1 || 2 || UsbHubControlReply
 
|}
 
|}
   −
= usb:pm =
+
= VdmCommandType =
This is "nn::usb::pm::IPmService".
+
This is "nn::usb::pd::driver::detail::VdmCommandType".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name
+
! Value || Name
 
|-
 
|-
| 0 ||
+
| -1 || None
 
|-
 
|-
| 1 ||
+
| 0 || Initiator
 
|-
 
|-
| 2 ||
+
| 1 || Ack
 
|-
 
|-
| 3 ||
+
| 2 || Nak
 
|-
 
|-
| 4 ||
+
| 3 || Busy
|-
  −
| 5 ||
   
|}
 
|}
   −
USB Port Manager, only system-title using this is [[PTM_services|ptm]].
+
= HidGamepad =
 +
With [7.0.0+] usb-sysmodule now has .json data embedded in the codebin.
 +
 
 +
This contains a list of USB devices' VID/PID, with the following structure:
 +
 
 +
  [
 +
      {
 +
          "vid" : "<VID>",
 +
          "pid" : "<PID>",
 +
          "quirks" : [
 +
              {
 +
                  "name" : "<string>" //The .json has the following for <string> for various devices: "HidGamepadWhitelist", "ApplicationBlacklist", and "NoClearHaltOnEpInit".
 +
              }
 +
              //There can be multiple entries here.
 +
          ]
 +
      },
 +
      <more entries>
 +
  ]
 +
 
 +
[12.1.0+]: The following entries were added in this json, all of which have quirks set for "HidGamepadWhitelist".
 +
** vid "0F0D", where pid is "0200" - "022F".
 +
** vid "33DD", where pid is "0001" - "000B".
    
[[Category:Services]]
 
[[Category:Services]]

Navigation menu