Changes

Jump to navigation Jump to search
4,128 bytes added ,  15:41, 6 May 2019
Line 40: Line 40:  
|-
 
|-
 
| 11 || [5.0.0+] Disable
 
| 11 || [5.0.0+] Disable
 +
|-
 +
| 12 || [8.0.0+]
 
|}
 
|}
   Line 137: Line 139:     
== GetDsInterface ==
 
== GetDsInterface ==
Takes 2 type-5 buffers and returns an [[#IDsInterface]]. [[Manu_Services|Manu]] sends a 0x09-byte command (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.
    
When the strlen output for the second buffer is >=0x40, size 0x40 is used instead for copying the string. This is the interface name, it's not sent over USB.
 
When the strlen output for the second buffer is >=0x40, size 0x40 is used instead for copying the string. This is the interface name, it's not sent over USB.
Line 243: Line 245:     
=== GetDsEndpoint ===
 
=== GetDsEndpoint ===
Takes a type-5 buffer and returns 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
 
** bLength=0x7
 
** bLength=0x7
Line 318: Line 320:  
|-
 
|-
 
| 5 || || Takes an input u8, no output.
 
| 5 || || Takes an input u8, no output.
 +
|-
 +
| 6 || [7.0.0+] || No input, returns an output u8.
 +
|-
 +
| 7 || [7.0.0+] || No input, returns an output handle.
 
|}
 
|}
   Line 370: Line 376:  
Stops in-progress data-transfer done by [[#PostBufferAsync]].
 
Stops in-progress data-transfer done by [[#PostBufferAsync]].
   −
= usb:hs =
+
= 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"
Line 406: Line 414:     
== QueryAllInterfaces ==
 
== QueryAllInterfaces ==
Takes an [[#UsbHsInterfaceFilter]] and a type-0x6 output buffer, returns an output u32 total_entries.
+
Takes an [[#UsbHsInterfaceFilter]] 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 [[#UsbHsInterface]]. This returns the same interfaces as [[#QueryAvailableInterfaces]], followed by the interfaces also returned by [[#QueryAcquiredInterfaces]]. Except for the ID field in [[#UsbHsInterface]], which is set to -1.
    
== QueryAvailableInterfaces ==
 
== QueryAvailableInterfaces ==
 
Takes an [[#UsbHsInterfaceFilter]] and a type-0x6 output buffer, returns an output s32 total_entries.
 
Takes an [[#UsbHsInterfaceFilter]] 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 [[#UsbHsInterface]]. This only returns interfaces which are not acquired by any process.
    
== QueryAcquiredInterfaces ==
 
== QueryAcquiredInterfaces ==
Line 435: Line 443:  
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 [[#UsbHsInterface]] +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 [[#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 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 output buffer. The output buffer contains the first 0x1B8-bytes from [[#UsbHsInterface]].
+
This returns an error if the interface was already acquired by another process.
    
== GetDescriptorString ==
 
== GetDescriptorString ==
Line 492: Line 502:     
=== GetAlternateInterface ===
 
=== GetAlternateInterface ===
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 the first 0x1B8-bytes from [[#UsbHsInterface]]. The buffer size must match 0x1B8.
    
=== GetCurrentFrame ===
 
=== GetCurrentFrame ===
Line 517: Line 527:  
=== 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 550: Line 562:  
| [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 || [[#PostBufferMultiAsync]] ||  
 
|-
 
|-
| [4.0.0+] 7 || ||  
+
| [4.0.0+] 7 || || Takes a total of 0x10-bytes of input, no output.
 
|-
 
|-
| [4.0.0+] 8 || ||  
+
| [4.0.0+] 8 || || Takes a total of 0x4-bytes of input and an input handle, no output.
 
|}
 
|}
   Line 589: Line 601:     
==== 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.
    
The buffer contains an array of [[#XferReport]].
 
The buffer contains an array of [[#XferReport]].
 +
 +
==== PostBufferMultiAsync ====
 +
Unofficial name.
 +
 +
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'''.
    
= UsbHsInterface =
 
= UsbHsInterface =
Line 607: Line 630:  
| 0x0 || 0x4 || ID value passed to other cmds. This is -1 with [[#QueryAllInterfaces]] output, hence this field is unused with that cmd.
 
| 0x0 || 0x4 || ID value passed to other cmds. This is -1 with [[#QueryAllInterfaces]] output, hence this field is unused with that cmd.
 
|-
 
|-
| 0x4 || 0x4? || deviceID
+
| 0x4 || 0x4 || deviceID
 +
|-
 +
| 0x8 || 0x4 || ?
 +
|-
 +
| 0xC || 0x9 || usb_interface_descriptor
 
|-
 
|-
| 0x8 || 0x4? || ?
+
| 0x15 || 0x7 || Padding
 
|-
 
|-
| 0xC || || usb_interface_descriptor
+
| 0x1C || 0x69 || OUTPUT usb_endpoint_descriptors, 15 max.
 
|-
 
|-
| 0x23 || 0x69 || OUTPUT usb_endpoint_descriptors, 15 max.
+
| 0x85 || 0x7 || Padding
 
|-
 
|-
 
| 0x8C || 0x69 || INPUT usb_endpoint_descriptors, 15 max.
 
| 0x8C || 0x69 || INPUT usb_endpoint_descriptors, 15 max.
 +
|-
 +
| 0xF5 || 0x6 || Padding
 +
|-
 +
| 0xFB || 0x5A || OUTPUT usb_ss_endpoint_companion_descriptors(?), 15 max.
 +
|-
 +
| 0x155 || 0x6 || Padding
 +
|-
 +
| 0x15B || 0x5A || INPUT usb_ss_endpoint_companion_descriptors(?), 15 max.
 +
|-
 +
| 0x1B5 || 0x3 || Padding
 
|-
 
|-
 
| 0x1B8 || 0x40 || "HsDevice-/L<unk0>/P<portnum>/A<unk1>" string (this is "FsDevice..." for the Dock USB 3.0 bus).
 
| 0x1B8 || 0x40 || "HsDevice-/L<unk0>/P<portnum>/A<unk1>" string (this is "FsDevice..." for the Dock USB 3.0 bus).
 
|-
 
|-
| 0x1F8 || 0x4? || busID
+
| 0x1F8 || 0x4 || busID
 +
|-
 +
| 0x1FC || 0x4 || deviceID
 
|-
 
|-
| 0x1FC || 0x4? || Duplicate of +0x4.
+
| 0x200 || 0x12+0x9(0x1B) || usb_device_descriptor, then usb_config_descriptor immediately afterwards.
 
|-
 
|-
| 0x200 || || usb_device_descriptor, then usb_config_descriptor immediately afterwards.
+
| 0x21B || 0x5 || Padding
 
|-
 
|-
 
| 0x220 || 0x8 || Unknown u64 timestamp for when the device was inserted?
 
| 0x220 || 0x8 || Unknown u64 timestamp for when the device was inserted?
Line 661: Line 700:     
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 [[#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.
 +
 +
[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 683: Line 724:  
! 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 825: Line 866:     
USB Port Manager, only system-title using this is [[PTM_services|ptm]].
 
USB Port Manager, only system-title using this is [[PTM_services|ptm]].
 +
 +
= usb:qdb =
 +
Added with [[7.0.0]].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 ||
 +
|-
 +
| 1 ||
 +
|}
 +
 +
== Cmd0 ==
 +
No input/output, takes a type-0x5 input buffer.
 +
 +
This loads data for [[#HidGamepad]] with the input .json.
 +
 +
== Cmd1 ==
 +
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 =
 +
Added with [8.0.0+].
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 ||
 +
|-
 +
| 1 ||
 +
|}
 +
 +
= 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>
 +
  ]
    
[[Category:Services]]
 
[[Category:Services]]

Navigation menu