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]] |