USB services: Difference between revisions
No edit summary |
|||
(27 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
USB provides services for interacting with the USB stack. | |||
= usb:ds = | = usb:ds = | ||
[1.0.0-10.2.0] This is "nn::usb::ds::IDsService". | |||
[11.0.0+] This is "nn::usb::ds::IDsRootSession". | |||
This service is used during [[Factory Setup|factory setup]] by [[Manu Services|manu]]. This is also used by [[Capmtp_services|capmtp]]. | 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]]. | 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" | {| class="wikitable" border="1" | ||
Line 15: | Line 16: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || | | 0 || [[#CreateDsService]] | ||
|} | |} | ||
== | == CreateDsService == | ||
No input. Returns an [[#IDsService]]. | No input. Returns an [[#IDsService]]. | ||
== IDsService == | == IDsService == | ||
This is "nn::usb::ds::IDsService". | This is "nn::usb::ds::IDsService". | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 30: | Line 29: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || [[# | | 0 || [[#Initialize]] | ||
|- | |- | ||
| | | 1 || [11.0.0+] [[#RegisterInterface]] ([1.0.0-10.2.0] [[#BindClientProcess]])) | ||
|- | |- | ||
| | | 2 || [11.0.0+] [[#GetStateChangeEvent]] ([1.0.0-10.2.0] [[#RegisterInterface]]) | ||
|- | |- | ||
| | | 3 || [11.0.0+] [[#GetState]] ([1.0.0-10.2.0] [[#GetStateChangeEvent]]) | ||
|- | |- | ||
| [ | | 4 || [11.0.0+] ClearDeviceData ([1.0.0-10.2.0] [[#GetState]]) | ||
|- | |- | ||
| [ | | 5 || [11.0.0+] AddUsbStringDescriptor ([5.0.0-10.2.0] ClearDeviceData, [2.0.0-4.1.0] [[#SetVidPidBcd]]) | ||
|- | |- | ||
| 6 || [5.0.0 | | 6 || [11.0.0+] DeleteUsbStringDescriptor ([5.0.0-10.2.0] AddUsbStringDescriptor) | ||
|- | |- | ||
| 7 || [5.0.0 | | 7 || [11.0.0+] SetUsbDeviceDescriptor ([5.0.0-10.2.0] DeleteUsbStringDescriptor) | ||
|- | |- | ||
| 8 || [5.0.0 | | 8 || [11.0.0+] SetBinaryObjectStore ([5.0.0-10.2.0] SetUsbDeviceDescriptor) | ||
|- | |- | ||
| 9 || [5.0.0 | | 9 || [11.0.0+] EnableDevice ([5.0.0-10.2.0] SetBinaryObjectStore) | ||
|- | |- | ||
| 10 || [5.0.0 | | 10 || [11.0.0+] DisableDevice ([5.0.0-10.2.0] EnableDevice) | ||
|- | |- | ||
| 11 || [5.0.0 | | 11 || [11.0.0+] [[#GetSpeed]] ([5.0.0-10.2.0] DisableDevice) | ||
|- | |- | ||
| 12 || [8.0.0 | | 12 || [8.0.0-10.2.0] [[#GetSpeed]] | ||
|} | |} | ||
== Initialize == | |||
Takes an input u32 '''ComplexId'''. No output. | |||
== | |||
[11.0.0+] Now takes an additional input Process handle. | |||
[[Manu_Services|Manu]] uses '''ComplexId''' 0x02. | |||
Binding more than once with the current session is not allowed. Once this command is used, the USB device will not be listed with <code>lsusb</code> until [[#EnableInterface]] is used. | Binding more than once with the current session is not allowed. Once this command is used, the USB device will not be listed with <code>lsusb</code> until [[#EnableInterface]] is used. | ||
Returns a not-found error when | Returns a not-found error when '''ComplexId''' isn't 0x02, for values 0x0-0x4 at least. | ||
== BindClientProcess == | == BindClientProcess == | ||
Takes | Takes an input Process handle. No output. | ||
== | == RegisterInterface == | ||
Takes | Takes two type-0x5 input buffers containing an [[#UsbInterfaceDescriptor]] and an [[#UsbStringDescriptor]], respectively. Returns an output u8 '''InterfaceNumber''' and an [[#IDsInterface]]. | ||
[5.0.0+] This now only takes an input u8 and returns 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. | |||
Returns an error when [[#Initialize]] wasn't used. | |||
Up to 4 interfaces can be used and [[#EnableInterface|enabled]]. | |||
== GetStateChangeEvent == | == GetStateChangeEvent == | ||
Returns an | No input. Returns an output Event handle. | ||
Signalled when Switch<->host USB comms change between started/stopped. USB cable connected/disconnected while at least 1 interface was enabled, or interface enabled/disabled while the USB cable was connected which then caused USB-comms state to change. | |||
== GetState == | == GetState == | ||
No input. Returns an output | No input. Returns an output [[#UsbState]]. | ||
Returns | Returns an error when [[#Initialize]] wasn't used. | ||
== SetVidPidBcd == | == SetVidPidBcd == | ||
Takes a type- | Takes a type-0x5 input buffer containing an [[#UsbVidPidBcd]]. No output. | ||
== | == GetSpeed == | ||
No input. Returns an output | No input. Returns an output [[#UsbDeviceSpeed]]. | ||
== IDsInterface == | == IDsInterface == | ||
This is "nn::usb::ds::IDsInterface". | This is "nn::usb::ds::IDsInterface". | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 250: | Line 106: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || [[# | | 0 || [[#RegisterEndpoint]] | ||
|- | |- | ||
| 1 || [[#GetSetupEvent]] | | 1 || [[#GetSetupEvent]] | ||
|- | |- | ||
| 2 || | | 2 || [[#GetSetupPacket]] | ||
|- | |- | ||
| 3 || [[# | | 3 || [11.0.0+] [[#CtrlInAsync]] ([1.0.0-10.2.0] [[#Enable]]) | ||
|- | |- | ||
| 4 || [[# | | 4 || [11.0.0+] [[#CtrlOutAsync]] ([1.0.0-10.2.0] [[#Disable]]) | ||
|- | |- | ||
| 5 || [[# | | 5 || [11.0.0+] [[#GetCtrlInCompletionEvent]] ([1.0.0-10.2.0] [[#CtrlInAsync]]) | ||
|- | |- | ||
| 6 || [[# | | 6 || [11.0.0+] [[#GetCtrlInUrbReport]] ([1.0.0-10.2.0] [[#CtrlOutAsync]]) | ||
|- | |- | ||
| 7 || [[#GetCtrlInCompletionEvent]] | | 7 || [11.0.0+] [[#GetCtrlOutCompletionEvent]] ([1.0.0-10.2.0] [[#GetCtrlInCompletionEvent]]) | ||
|- | |- | ||
| 8 || [[# | | 8 || [11.0.0+] [[#GetCtrlOutUrbReport]] ([1.0.0-10.2.0] [[#GetCtrlInUrbReport]]) | ||
|- | |- | ||
| 9 || [[#GetCtrlOutCompletionEvent]] | | 9 || [11.0.0+] [[#CtrlStall]] ([1.0.0-10.2.0] [[#GetCtrlOutCompletionEvent]]) | ||
|- | |- | ||
| 10 || [[# | | 10 || [11.0.0+] [[#AppendConfigurationData]] ([1.0.0-10.2.0] [[#GetCtrlOutUrbReport]]) | ||
|- | |- | ||
| 11 || [[# | | 11 || [13.0.0+] [[#SetGuid]] ([1.0.0-10.2.0] [[#CtrlStall]]) | ||
|- | |- | ||
| 12 || [5.0.0 | | 12 || [15.0.0+] [[#RegisterTransferMemory]] ([5.0.0-10.2.0] [[#AppendConfigurationData]]) | ||
|} | |} | ||
=== RegisterEndpoint === | |||
Takes a type-0x5 input buffer containing an [[#UsbEndpointDescriptor]]. Returns an output u8 '''EndpointNumber''' and an [[#IDsEndpoint]]. | |||
[5.0.0+] This now only takes an input u8 and returns 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 289: | Line 147: | ||
** bInterval=0 | ** bInterval=0 | ||
* Second endpoint: Same as above except byte2 is 0x00(bEndpointAddress=LIBUSB_ENDPOINT_OUT). | * Second endpoint: Same as above except byte2 is 0x00(bEndpointAddress=LIBUSB_ENDPOINT_OUT). | ||
The buffer size must be >=0x7. Only the first 0x7-bytes from the buffer are used. | The buffer size must be >=0x7. Only the first 0x7-bytes from the buffer are used. | ||
Line 300: | Line 154: | ||
From the Tegra datasheet: "The maximum packet size supported on any endpoint is 1024 bytes in high-speed mode, for both device and host modes." | From the Tegra datasheet: "The maximum packet size supported on any endpoint is 1024 bytes in high-speed mode, for both device and host modes." | ||
Throws an error if the interface is [[#EnableInterface|enabled]]. | |||
=== GetSetupEvent === | === GetSetupEvent === | ||
Returns an | No input. Returns an output Event handle. | ||
Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init. | |||
=== GetSetupPacket === | |||
Takes a type-0x6 output buffer. No output. | |||
Memcpys data to outbuf with outsize, uses size 0x8 if outsize is too large. | |||
Throws an error if the interface is not [[#EnableInterface|enabled]]. | |||
=== | === Enable === | ||
No input/output. | |||
Enables the current interface. | |||
Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[# | Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[#RegisterEndpoint]] 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. | ||
=== | === Disable === | ||
No input/output. | |||
Disables the current interface. | |||
=== CtrlInAsync === | |||
Same as [[#PostBufferAsync]], except this uses control input endpoint 0x80. | |||
Throws an error if the interface is not [[#EnableInterface|enabled]]. | |||
=== | === CtrlOutAsync === | ||
Same as [[#PostBufferAsync]] | Same as [[#PostBufferAsync]], except this uses control output endpoint 0x00. | ||
Throws an error if the interface is not [[#EnableInterface|enabled]]. | |||
=== GetCtrlInCompletionEvent === | === GetCtrlInCompletionEvent === | ||
Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80. | |||
=== | === GetCtrlInUrbReport === | ||
Same as [[# | Same as [[#GetUrbReport]], except this uses control input endpoint 0x80. | ||
=== GetCtrlOutCompletionEvent === | === GetCtrlOutCompletionEvent === | ||
Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00. | |||
=== | === GetCtrlOutUrbReport === | ||
Same as [[# | Same as [[#GetUrbReport]], except this uses control output endpoint 0x00. | ||
=== | === CtrlStall === | ||
No input/output. | No input/output. | ||
Calls a function with both control endpoints(0x80 and 0x00) with the same function. From strings: "m_pProtocol->Stall(0x80)" "m_pProtocol->Stall(0x00)". | Calls a function with both control endpoints (0x80 and 0x00) with the same function. From strings: "m_pProtocol->Stall(0x80)" "m_pProtocol->Stall(0x00)". | ||
Throws an error if the interface is not [[#EnableInterface|enabled]]. | |||
=== AppendConfigurationData === | |||
Takes an input u32 '''InterfaceNumber''', an input [[#UsbDeviceSpeed]] and a type-0x5 input buffer. No output. | |||
[5.0.0+] This now only takes an input [[#UsbDeviceSpeed]] and a type-0x5 input buffer. | |||
=== SetGuid === | |||
Takes a type-0x5 input buffer. No output. | |||
=== RegisterTransferMemory === | |||
Takes an input u64 and an input handle. No output. | |||
Stubbed, just returns an error. | |||
=== IDsEndpoint === | === IDsEndpoint === | ||
Line 349: | Line 234: | ||
| 0 || [[#PostBufferAsync]] | | 0 || [[#PostBufferAsync]] | ||
|- | |- | ||
| 1 || | | 1 || [[#Cancel]] | ||
|- | |- | ||
| 2 || [[#GetCompletionEvent]] | | 2 || [[#GetCompletionEvent]] | ||
|- | |- | ||
| 3 || [[# | | 3 || [[#GetUrbReport]] | ||
|- | |- | ||
| 4 || [[#Stall]] | | 4 || [[#Stall]] | ||
|- | |- | ||
| 5 || | | 5 || [[#SetZlt]] | ||
|- | |- | ||
| 6 || [7.0.0+] | | 6 || [7.0.0+] [[#IsStalled]] | ||
|- | |- | ||
| 7 || [7.0.0+] | | 7 || [7.0.0+] [[#GetStallClearedEvent]] | ||
|- | |- | ||
| 8 || [11.0.0 | | 8 || [11.0.0-14.1.2] | ||
|- | |- | ||
| 9 || [11.0.0 | | 9 || [11.0.0-14.1.2] | ||
|} | |} | ||
==== PostBufferAsync ==== | |||
Takes an input u32 '''Size''' and an input 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 383: | Line 268: | ||
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. | No input/output. | ||
==== GetCompletionEvent ==== | ==== GetCompletionEvent ==== | ||
No input. Returns an output | No input. Returns an output Event handle. | ||
==== | ==== GetUrbReport ==== | ||
No input. Returns | No input. Returns an output [[#UrbReport]]. | ||
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. | |||
==== Stall ==== | ==== Stall ==== | ||
No input/output. | No input/output. | ||
Calls the same function used by [[# | 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]]. | ||
==== | ==== SetZlt ==== | ||
Takes an input | Takes an input bool. No output. | ||
==== | ==== IsStalled ==== | ||
No input | No input. Returns an output bool. | ||
==== | ==== GetStallClearedEvent ==== | ||
No input | No input. Returns an output Event handle. | ||
==== Cmd8 ==== | ==== Cmd8 ==== | ||
Takes an input u64 and | Takes an input u64 and an input handle. No output. | ||
Stubbed, just returns an error. | |||
==== Cmd9 ==== | ==== Cmd9 ==== | ||
Takes an input u32 | Takes an input u32 '''Size''' and an input u64 '''Offset'''. Returns an u32 '''UrbId'''. | ||
Stubbed, just returns an error. | |||
= usb:hs, usb:hs:a = | = usb:hs, usb:hs:a = | ||
Line 447: | Line 314: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| [2.0.0+] | | 0 || [2.0.0+] [[#BindClientProcess_2|#BindClientProcess]] ([1.0.0] [[#QueryAllInterfaces]]) | ||
|- | |- | ||
| | | 1 || [[#QueryAllInterfaces]] ([1.0.0] [[#QueryAvailableInterfaces]]) | ||
|- | |- | ||
| | | 2 || [[#QueryAvailableInterfaces]] ([1.0.0] [[#QueryAcquiredInterfaces]]) | ||
|- | |- | ||
| | | 3 || [[#QueryAcquiredInterfaces]] ([1.0.0] [[#CreateInterfaceAvailableEvent]]) | ||
|- | |- | ||
| | | 4 || [[#CreateInterfaceAvailableEvent]] ([1.0.0] [[#DestroyInterfaceAvailableEvent]]) | ||
|- | |- | ||
| | | 5 || [[#DestroyInterfaceAvailableEvent]] ([1.0.0] [[#GetInterfaceStateChangeEvent]]) | ||
|- | |- | ||
| | | 6 || [[#GetInterfaceStateChangeEvent]] ([1.0.0] [[#AcquireUsbIf]]) | ||
|- | |- | ||
| | | 7 || [[#AcquireUsbIf]] ([1.0.0] [[#GetDescriptorString]]) | ||
|- | |- | ||
| [1.0.0] | | 8 || [6.0.0+] SetTestMode ([1.0.0] [[#ResetDevice]]) | ||
|} | |} | ||
Line 526: | Line 391: | ||
== ResetDevice == | == ResetDevice == | ||
Takes an input u32, no output. Stubbed, just returns 0. | |||
== IClientIfSession == | == IClientIfSession == | ||
Line 543: | Line 408: | ||
| 3 || [[#GetAlternateInterface]] | | 3 || [[#GetAlternateInterface]] | ||
|- | |- | ||
| 4 ([1.0.0] | | 4 || [[#GetCurrentFrame]] ([1.0.0] [[#CtrlXferAsync]]) | ||
|- | |- | ||
| [2.0.0+] | | 5 || [2.0.0+] [[#CtrlXferAsync]] | ||
|- | |- | ||
| 6 || ([1.0.0] [[#SubmitControlInRequest]]) | | 6 || [[#GetCtrlXferCompletionEvent]] ([1.0.0] [[#SubmitControlInRequest]]) | ||
|- | |- | ||
| 7 || [[#GetCtrlXferReport]] ([1.0.0] [[#SubmitControlOutRequest]]) | | 7 || [[#GetCtrlXferReport]] ([1.0.0] [[#SubmitControlOutRequest]]) | ||
Line 553: | Line 418: | ||
| 8 || [[#ResetDevice]] | | 8 || [[#ResetDevice]] | ||
|- | |- | ||
| 9 ([1.0.0] | | 9 || [[#OpenUsbEp]] ([1.0.0] [[#GetCurrentFrame]]) | ||
|} | |} | ||
Line 580: | Line 445: | ||
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. | No input, returns an output handle. Signaled when [[#CtrlXferAsync]] finishes. | ||
Line 625: | Line 490: | ||
| 1 || [[#Close]] ([1.0.0] [[#SubmitInRequest]]) | | 1 || [[#Close]] ([1.0.0] [[#SubmitInRequest]]) | ||
|- | |- | ||
| 2 || GetCompletionEvent ([1.0.0] Reset) | | 2 || [[#GetCompletionEvent_2|GetCompletionEvent]] ([1.0.0] Reset) | ||
|- | |- | ||
| 3 || [[#PopulateRing]] ([1.0.0] [[#Close]]) | | 3 || [[#PopulateRing]] ([1.0.0] [[#Close]]) | ||
|- | |- | ||
| [2.0.0+] | | 4 || [2.0.0+] [[#PostBufferAsync_2|#PostBufferAsync]] | ||
|- | |- | ||
| [2.0.0+] | | 5 || [2.0.0+] [[#GetXferReport]] | ||
|- | |- | ||
| [2.0.0+] | | 6 || [2.0.0+] [[#BatchBufferAsync]] | ||
|- | |- | ||
| [4.0.0+] | | 7 || [4.0.0+] [[#CreateSmmuSpace]] | ||
|- | |- | ||
| [4.0.0+] | | 8 || [4.0.0+] [[#ShareReportRing]] | ||
|} | |} | ||
Line 659: | Line 524: | ||
This is similar to [[#OpenUsbEp]] with the params being loaded from state instead. | This is similar to [[#OpenUsbEp]] with the params being loaded from state instead. | ||
This is | This is for re-opening after [[#Close]] was used. | ||
==== Close ==== | ==== Close ==== | ||
No input/output. | No input/output. | ||
Used by official sw prior to closing the endpoint session. | Used by official sw prior to closing the endpoint session. The func for this is also called automatically by the sysmodule during the IClientEpSession dtor. | ||
==== | ==== GetCompletionEvent ==== | ||
No input, returns an output handle. Signaled when [[#PostBufferAsync_2|#PostBufferAsync]] finishes. ([1.0.0] [[#Open]]) | No input, returns an output handle. Signaled when [[#PostBufferAsync_2|#PostBufferAsync]] finishes. ([1.0.0] [[#Open]]) | ||
Line 675: | Line 540: | ||
==== PostBufferAsync ==== | ==== PostBufferAsync ==== | ||
Takes an input u32 '''size''', an input u64 '''buffer''', and an input u64 ''' | Takes an input u32 '''size''', an input u64 '''buffer''', and an input u64 '''Id''', returns an output u32 '''xferId'''. | ||
Starts a data transfer with a single urb. | |||
The official sw func which uses this cmd and handles waiting on the Event passes value 0 for the '''Id'''. The async version which exposes this cmd directly uses '''Id''' from user input - the user funcs pass a value starting at 0 then increment it each time (for sending multiple requests at once, with 0 for the first request in this set of requests). Note that '''Id''' can be arbitrary, the sysmodule doesn't require a certain range for this. | |||
On newer sysvers the state fields setup by [[#CreateSmmuSpace]] are compared with '''buffer'''. If it's within bounds of the SmmuSpace (which won't be the case when [[#CreateSmmuSpace]] wasn't used), it will then verify that buffer+buffer_size is within bounds throwing an error otherwise. Note that a buffer from [[#CreateSmmuSpace]] can't be reused by another endpoint with PostBufferAsync. | |||
==== GetXferReport ==== | ==== GetXferReport ==== | ||
Line 687: | Line 554: | ||
The buffer contains an array of [[#XferReport]]. | The buffer contains an array of [[#XferReport]]. | ||
On newer sysvers this runs code which is the same as the user-process code handling the tmem from [[#ShareReportRing]]. This cmd can handle getting reports from that tmem as well, however normally user-processes would just access the tmem [[#ShareReportRing|directly]]. | |||
==== BatchBufferAsync ==== | ==== BatchBufferAsync ==== | ||
Takes 3 input u32s ('''urbCount''', '''unk1''', and '''unk2'''), an input u64 '''buffer''' and u64 '''Id''', and a type-0x5 ([3.0.0+] type-0x21) input buffer, returns an output u32 '''xferId'''. | |||
Where '''Id''' is the same as [[#PostBufferAsync_2|#PostBufferAsync]]. | |||
Where ''' | |||
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'''. | 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 ==== | ==== CreateSmmuSpace ==== | ||
Takes | Takes an input u32 '''size''' and an u64 '''buffer''', no output. | ||
This validates that both input params are page-aligned. Official user-processes also validate this. | |||
This maps the specified buffer as devicemem and stores the fields for this in object state. If this was already used with this IClientEpSession object, an error is thrown. | |||
==== ShareReportRing ==== | ==== ShareReportRing ==== | ||
Takes | Takes an input u32 '''size''' and an input TransferMemory handle, no output. | ||
Official user-processes create the TransferMemory with permissions=RW. This validates that the input size is page-aligned, and this is also validated against data from state. Official user-processes also do this same validation. | |||
When this was used, official user-processes read data from this TransferMemory buffer instead of using [[#GetXferReport]]. | |||
This maps a TransferMemory buffer which is used for the [[#XferReport]] Ring, replacing the heap Ring buffer which was setup during [[#PopulateRing]]. | |||
Structure of the tmem: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x8 || Write index | |||
|- | |||
| 0x8 || 0x8 || Read index | |||
|- | |||
| 0x10 || 0x18*count || Array of [[#XferReport]] | |||
|} | |||
write_index!=read_index indicates that report data is available. The index fields are updated with: <code>index = index+1 % count;</code> write_index is updated by sysmodule, read_index is updated by the user-process. If the index field being used is >=count, this will Abort. | |||
= usb:pd = | = usb:pd = | ||
Line 775: | Line 668: | ||
| 6 || [2.0.0+] [[#GetHostPdcDeviceId]] | | 6 || [2.0.0+] [[#GetHostPdcDeviceId]] | ||
|- | |- | ||
| 7 || [3.0.0+] | | 7 || [3.0.0+] [[#EnableCradleRecovery]] | ||
|- | |- | ||
| 8 || [3.0.0+] | | 8 || [3.0.0+] [[#DisableCradleRecovery]] | ||
|} | |} | ||
=== SetCradleVdo === | === SetCradleVdo === | ||
Takes | Takes an input u32 '''Value''' and a [[#CradleVdmCommand]]. No output. | ||
[[#CradleVdmCommand]] is translated to the actual [[#VdmCommand]] to send. | |||
=== GetCradleVdo === | === GetCradleVdo === | ||
Takes an input | Takes an input [[#CradleVdmCommand]]. Returns an u32 '''Value'''. | ||
[[#CradleVdmCommand]] is translated to the actual [[#VdmCommand]] to send. | |||
=== ResetCradleUsbHub === | === ResetCradleUsbHub === | ||
Line 807: | Line 700: | ||
No input. Returns an output u16. | No input. Returns an output u16. | ||
=== | === EnableCradleRecovery === | ||
No input. Returns an output u8. | No input. Returns an output u8. | ||
=== | === DisableCradleRecovery === | ||
No input. Returns an output u8. | No input. Returns an output u8. | ||
Line 846: | Line 739: | ||
= usb:pm = | = usb:pm = | ||
This is "nn::usb::pm::IPmService". | This is "nn::usb::pm::IPmService". | ||
[8.0.0+] This is "nn::usb::pm::IPmMainService". | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 851: | Line 746: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || GetPowerEvent | | 0 || [[#GetPowerEvent|GetPowerEvent]] | ||
|- | |- | ||
| 1 || GetPowerState | | 1 || [[#GetPowerState|GetPowerState]] | ||
|- | |- | ||
| 2 || GetDataEvent | | 2 || [[#GetDataEvent|GetDataEvent]] | ||
|- | |- | ||
| 3 || GetDataRole | | 3 || [[#GetDataRole|GetDataRole]] | ||
|- | |- | ||
| 4 || SetDiagData | | 4 || [[#SetDiagData|SetDiagData]] | ||
|- | |- | ||
| 5 || GetDiagData | | 5 || [[#GetDiagData|GetDiagData]] | ||
|} | |} | ||
USB Port Manager, only system-title using this is [[PTM_services|ptm]]. | USB Port Manager, only system-title using this is [[PTM_services|ptm]]. | ||
== GetPowerEvent == | |||
No input. Returns an output Event handle. | |||
== GetPowerState == | |||
Takes a type-0x6 output buffer containing an [[#UsbPowerState]]. No output. | |||
== GetDataEvent == | |||
No input. Returns an output Event handle. | |||
== GetDataRole == | |||
No input. Returns an output [[#UsbDataRole]]. | |||
== SetDiagData == | |||
Takes two input u32s. No output. | |||
[8.0.0+] Stubbed, just returns 0. | |||
== GetDiagData == | |||
Takes an input u32. Returns an output u32. | |||
[8.0.0+] Stubbed, just returns 0. | |||
= usb:qdb = | = usb:qdb = | ||
This is "nn::usb::qdb::IQdbManager". | |||
This was added with [7.0.0+]. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 873: | Line 792: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || | | 0 || [[#ImportQuirkDevices]] | ||
|- | |- | ||
| 1 || | | 1 || [[#HasQuirk]] | ||
|} | |} | ||
== | == ImportQuirkDevices == | ||
No input/output, takes a type-0x5 input buffer. | No input/output, takes a type-0x5 input buffer. | ||
This loads data for [[#HidGamepad]] with the input .json. | 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. | Takes 6-bytes of input (u16s '''vid''', '''pid''', '''bcdDevice''') and a type-0x5 input buffer, returns an output u8 bool indicating success. | ||
Line 889: | Line 808: | ||
= usb:obsv = | = usb:obsv = | ||
This is "nn::usb::pm::IPmObserverService". | |||
This was added with [8.0.0+]. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 895: | Line 816: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || | | 0 || GetTopologyChangeEvent | ||
|- | |||
| 1 || GetFlattenedTopology | |||
|} | |||
= UsbInterfaceDescriptor = | |||
This is "nn::usb::UsbInterfaceDescriptor". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || bLength | |||
|- | |||
| 0x1 || 0x1 || bDescriptorType | |||
|- | |||
| 0x2 || 0x1 || bInterfaceNumber | |||
|- | |||
| 0x3 || 0x1 || bAlternateSetting | |||
|- | |||
| 0x4 || 0x1 || bNumEndpoints | |||
|- | |||
| 0x5 || 0x1 || bInterfaceClass | |||
|- | |||
| 0x6 || 0x1 || bInterfaceSubClass | |||
|- | |||
| 0x7 || 0x1 || bInterfaceProtocol | |||
|- | |||
| 0x8 || 0x1 || iInterface | |||
|} | |||
= UsbStringDescriptor = | |||
This is "nn::usb::UsbStringDescriptor". This is a string. | |||
= UsbEndpointDescriptor = | |||
This is "nn::usb::UsbEndpointDescriptor". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || bLength | |||
|- | |||
| 0x1 || 0x1 || bDescriptorType | |||
|- | |||
| 0x2 || 0x1 || bEndpointAddress | |||
|- | |||
| 0x3 || 0x1 || bmAttributes | |||
|- | |||
| 0x4 || 0x2 || wMaxPacketSize | |||
|- | |||
| 0x6 || 0x1 || bInterval | |||
|- | |||
| 0x7 || 0x1 || bRefresh | |||
|- | |||
| 0x8 || 0x1 || bSynchAddress | |||
|} | |||
= UsbState = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name || Description | |||
|- | |||
| 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. | |||
|} | |||
= UsbVidPidBcd = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x2 || Vid (idVendor) | |||
|- | |||
| 0x2 || 0x2 || Pid (idProduct) | |||
|- | |||
| 0x4 || 0x2 || bcdDevice | |||
|- | |||
| 0x6 || 0x20 || Manufacturer (ASCII string padded to 0x20 bytes) | |||
|- | |||
| 0x26 || 0x20 || Product (ASCII string padded to 0x20 bytes) | |||
|- | |||
| 0x46 || 0x20 || SerialNumber (ASCII string padded to 0x20 bytes) | |||
|} | |||
= UrbReport = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x10 * 8 || Array of [[#UrbReportEntry]] | |||
|- | |||
| 0x80 || 0x4 || ReportEntryCount | |||
|} | |||
= UrbReportEntry = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x4 || Id | |||
|- | |||
| 0x4 || 0x4 || RequestedSize | |||
|- | |||
| 0x8 || 0x4 || TransferredSize | |||
|- | |||
| 0xC || 0x4 || Status (converted to error-codes: 0x3 = success, 0x4 = 0x828c, 0x5 = 0x748c; all other values are invalid) | |||
|} | |||
= UsbDeviceSpeed = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || None | |||
|- | |||
| 1 || Low | |||
|- | |||
| 2 || Full | |||
|- | |||
| 3 || High | |||
|- | |- | ||
| | | 4 || Super | ||
|} | |} | ||
Line 987: | Line 1,039: | ||
| 0xF || 0x1 || bInterfaceProtocol | | 0xF || 0x1 || bInterfaceProtocol | ||
|} | |} | ||
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. | 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. | ||
Line 1,023: | Line 1,073: | ||
| 0xC || 0x4 || transferredSize | | 0xC || 0x4 || transferredSize | ||
|- | |- | ||
| 0x10 || 0x8 | | 0x10 || 0x8 || [[#PostBufferAsync_2|Id]] | ||
|} | |} | ||
Line 1,029: | Line 1,079: | ||
Official sw only uses the Result/size fields. | Official sw only uses the Result/size fields. | ||
= CradleVdmCommand = | |||
This is "nn::usb::pd::CradleVdmCommand". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || | |||
|- | |||
| 1 || | |||
|- | |||
| 2 || | |||
|- | |||
| 3 || | |||
|- | |||
| 4 || | |||
|- | |||
| 5 || | |||
|- | |||
| 6 || | |||
|- | |||
| 7 || | |||
|- | |||
| 8 || | |||
|- | |||
| 9 || | |||
|- | |||
| 10 || | |||
|} | |||
= VdmCommand = | = VdmCommand = | ||
This is "nn::usb::pd::driver::detail::VdmCommand". | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Value || | ! 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 | |||
|- | |- | ||
| | | 7 || - || 1 || 3 || Dp2HdmiFwVerReply | ||
|- | |- | ||
| 1 || 0 || | | 8 || - || -1 || 0 || Dp2HdmiFwUpdateRequest | ||
|- | |- | ||
| | | 9 || - || -1 || 0 || Dp2HdmiFwUpdateReply | ||
|- | |- | ||
| | | 10 || - || -1 || 0 || Dp2HdmiFwUpdateNotice | ||
|- | |- | ||
| | | 11 || 2 || 0 || 2 || PdcHFwVerRequest | ||
|- | |- | ||
| | | 12 || - || 1 || 3 || PdcHFwVerReply | ||
|- | |- | ||
| | | 13 || - || -1 || 0 || PdcHFwUpdateRequest | ||
|- | |- | ||
| | | 14 || - || -1 || 0 || PdcHFwUpdateReply | ||
|- | |- | ||
| | | 15 || - || -1 || 0 || PdcHFwUpdateNotice | ||
|- | |- | ||
| | | 16 || 3 || 0 || 2 || PdcAFwVerRequest | ||
|- | |- | ||
| | | 17 || - || 1 || 3 || PdcAFwVerReply | ||
|- | |- | ||
| | | 18 || - || -1 || 0 || PdcAFwUpdateRequest | ||
|- | |- | ||
| | | 19 || - || -1 || 0 || PdcAFwUpdateReply | ||
|- | |- | ||
| | | 20 || - || -1 || 0 || PdcAFwUpdateNotice | ||
|- | |- | ||
| | | 21 || - || 0 || 3 || DeviceErrorNotice | ||
|- | |- | ||
| | | 22 || 4 || 0 || 2 || DeviceStateRequest | ||
|- | |- | ||
| | | 23 || - || 1 || 3 || DeviceStateReply | ||
|- | |- | ||
| | | 24 || 5 || 0 || 2 || McuFwVerRequest | ||
|- | |- | ||
| | | 25 || - || 1 || 3 || McuFwVerReply | ||
|- | |- | ||
| | | 26 || 6 || 0 || 2 || McuFwUpdateRequest | ||
|- | |- | ||
| | | 27 || - || 1 || 2 || McuFwUpdateReply | ||
|- | |- | ||
| | | 28 || 7 || 0 || 2 || UsbHubSleepRequest | ||
|- | |- | ||
| | | 29 || - || 1 || 2 || UsbHubSleepReply | ||
|- | |- | ||
| | | 30 || 8 || 0 || 2 || UsbHubResetRequest | ||
|- | |- | ||
| | | 31 || - || 1 || 2 || UsbHubResetReply | ||
|- | |- | ||
| | | 32 || 9 || 0 || 2 || UsbHubControlRequest | ||
|- | |- | ||
| | | 33 || - || 1 || 2 || UsbHubControlReply | ||
|} | |||
= VdmCommandType = | |||
This is "nn::usb::pd::driver::detail::VdmCommandType". | |||
{| class="wikitable" border="1" | |||
|- | |- | ||
| | ! Value || Name | ||
|- | |- | ||
| | | -1 || None | ||
|- | |- | ||
| | | 0 || Initiator | ||
|- | |- | ||
| | | 1 || Ack | ||
|- | |- | ||
| | | 2 || Nak | ||
|- | |- | ||
| | | 3 || Busy | ||
|} | |||
= UsbPowerState = | |||
This is "nn::usb::UsbPowerState". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x4 || [[#UsbPowerRole|UsbPowerRole]] | |||
|- | |||
| 0x4 || 0x4 || [[#UsbChargerType|UsbChargerType]] | |||
|- | |||
| 0x8 || 0x4 || Voltage | |||
|- | |||
| 0xC || 0x4 || Current | |||
|- | |||
| 0x10 || 0x4 || [[#Pdo|Pdo]] | |||
|- | |||
| 0x14 || 0x4 || [[#Rdo|Rdo]] | |||
|} | |||
= UsbPowerRole = | |||
This is "nn::usb::UsbPowerRole". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || Unknown | |||
|- | |||
| 1 || Sink | |||
|- | |||
| 2 || Source | |||
|} | |||
= UsbChargerType = | |||
This is "nn::usb::UsbChargerType". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || Unknown | |||
|- | |||
| 1 || Pd | |||
|- | |||
| 2 || TypeC15 | |||
|- | |||
| 3 || TypeC30 | |||
|- | |||
| 4 || Dcp | |||
|- | |||
| 5 || Cdp | |||
|- | |||
| 6 || Sdp | |||
|- | |||
| 7 || Apple500 | |||
|- | |||
| 8 || Apple1000 | |||
|- | |||
| 9 || Apple2000 | |||
|} | |||
= SupplyType = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || Fixed | |||
|- | |||
| 1 || Battery | |||
|- | |||
| 2 || Variable | |||
|} | |||
= Pdo = | |||
When [[#SupplyType|SupplyType]] is Fixed this is: | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 | |||
| MaximumCurrent | |||
|- | |||
| 10-19 | |||
| Voltage | |||
|- | |||
| 20-21 | |||
| PeakCurrent | |||
|- | |||
| 22-24 | |||
| Reserved | |||
|- | |||
| 25 | |||
| DataRoleSwap | |||
|- | |||
| 26 | |||
| UsbCommunicationsCapable | |||
|- | |||
| 27 | |||
| ExternallyPowered | |||
|- | |||
| 28 | |||
| UsbSuspendSupported | |||
|- | |||
| 29 | |||
| DualRolePower | |||
|- | |||
| 30-31 | |||
| [[#SupplyType|SupplyType]] | |||
|} | |||
When [[#SupplyType|SupplyType]] is Battery this is: | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 | |||
| MaximumAllowablePower | |||
|- | |||
| 10-19 | |||
| MinimumVoltage | |||
|- | |||
| 20-29 | |||
| MaximumVoltage | |||
|- | |||
| 30-31 | |||
| [[#SupplyType|SupplyType]] | |||
|} | |||
When [[#SupplyType|SupplyType]] is Variable this is: | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 | |||
| MaximumCurrent | |||
|- | |||
| 10-19 | |||
| MinimumVoltage | |||
|- | |||
| 20-29 | |||
| MaximumVoltage | |||
|- | |||
| 30-31 | |||
| [[#SupplyType|SupplyType]] | |||
|} | |||
= Rdo = | |||
When Pdo's [[#SupplyType|SupplyType]] is Fixed or Variable this is: | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 | |||
| MaximumOperatingCurrent (GiveBackFlag is true) or MinimumOperatingCurrent (GiveBackFlag is false) | |||
|- | |||
| 10-19 | |||
| OperatingCurrent | |||
|- | |||
| 20-23 | |||
| Reserved | |||
|- | |||
| 24 | |||
| NoUsbSuspend | |||
|- | |||
| 25 | |||
| UsbCommunicationsCapable | |||
|- | |||
| 26 | |||
| CapabilityMismatch | |||
|- | |||
| 27 | |||
| GiveBackFlag | |||
|- | |||
| 28-30 | |||
| ObjectPosition | |||
|- | |||
| 31 | |||
| Reserved | |||
|} | |||
When Pdo's [[#SupplyType|SupplyType]] is Battery this is: | |||
{| class="wikitable" border="1" | |||
! Bits | |||
! Description | |||
|- | |||
| 0-9 | |||
| MaximumOperatingPower (GiveBackFlag is true) or MinimumOperatingPower (GiveBackFlag is false) | |||
|- | |||
| 10-19 | |||
| OperatingPower | |||
|- | |||
| 20-23 | |||
| Reserved | |||
|- | |||
| 24 | |||
| NoUsbSuspend | |||
|- | |||
| 25 | |||
| UsbCommunicationsCapable | |||
|- | |||
| 26 | |||
| CapabilityMismatch | |||
|- | |||
| 27 | |||
| GiveBackFlag | |||
|- | |||
| 28-30 | |||
| ObjectPosition | |||
|- | |||
| 31 | |||
| Reserved | |||
|} | |||
= UsbDataRole = | |||
This is "nn::usb::UsbDataRole". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Name | |||
|- | |||
| 0 || Unknown | |||
|- | |||
| 1 || DFP | |||
|- | |||
| 2 || UFP | |||
|} | |} | ||
Line 1,120: | Line 1,450: | ||
<more entries> | <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". | |||
= Configuration = | |||
The following is the default USB config strings, while the usbds service isn't being used. All of the below configuration will reset to the defaults when all usbds-related sessions are closed. These can be set with [[#SetVidPidBcd]]. The default string for Product is loaded from [[Settings_services|settings]] config. The default is referred to by usb-sysmodule as "Dummy". | |||
Product: Nintendo Switch | |||
Manufacturer: Nintendo | |||
SerialNumber: SerialNumber | |||
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 [[#RegisterEndpoint]], 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 [[#RegisterInterface]]. | |||
When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000. | |||
Bus 003 Device 006: ID 057e:2000 Nintendo Co., Ltd | |||
Couldn't open device, some information will be missing | |||
Device Descriptor: | |||
bLength 18 | |||
bDescriptorType 1 | |||
bcdUSB 2.00 | |||
bDeviceClass 0 (Defined at Interface level) | |||
bDeviceSubClass 0 | |||
bDeviceProtocol 0 | |||
bMaxPacketSize0 64 | |||
idVendor 0x057e Nintendo Co., Ltd | |||
idProduct 0x2000 | |||
bcdDevice 1.00 | |||
iManufacturer 1 | |||
iProduct 2 | |||
iSerial 3 | |||
bNumConfigurations 1 | |||
Configuration Descriptor: | |||
bLength 9 | |||
bDescriptorType 2 | |||
wTotalLength 34 | |||
bNumInterfaces 1 | |||
bConfigurationValue 1 | |||
iConfiguration 0 | |||
bmAttributes 0xc0 | |||
Self Powered | |||
MaxPower {...} | |||
Interface Descriptor: | |||
bLength 9 | |||
bDescriptorType 4 | |||
bInterfaceNumber 0 | |||
bAlternateSetting 0 | |||
bNumEndpoints 1 | |||
bInterfaceClass 3 Human Interface Device | |||
bInterfaceSubClass 0 No Subclass | |||
bInterfaceProtocol 0 None | |||
iInterface 0 | |||
HID Device Descriptor: | |||
bLength 9 | |||
bDescriptorType 33 | |||
bcdHID 2.00 | |||
bCountryCode 0 Not supported | |||
bNumDescriptors 1 | |||
bDescriptorType 34 Report | |||
wDescriptorLength 26 | |||
Report Descriptors: | |||
** UNAVAILABLE ** | |||
Endpoint Descriptor: | |||
bLength 7 | |||
bDescriptorType 5 | |||
bEndpointAddress 0x81 EP 1 IN | |||
bmAttributes 3 | |||
Transfer Type Interrupt | |||
Synch Type None | |||
Usage Type Data | |||
wMaxPacketSize 0x0001 1x 1 bytes | |||
bInterval 16 | |||
[[Category:Services]] | [[Category:Services]] |