Changes

Jump to navigation Jump to search
126 bytes removed ,  20:11, 11 April 2023
no edit summary
Line 1: Line 1: −
One symbol in USB-sysmodule is: "vtable for nn::usb::detail::UsbComplexTegra21x".
+
USB provides services for interacting with the USB stack.
   −
= usb:ds =
+
= Configuration =
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.
  −
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 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"
  −
|-
  −
! Cmd || Name
  −
|-
  −
| 0 || [[#BindDevice]]
  −
|-
  −
| 1 || [[#BindClientProcess]]
  −
|-
  −
| 2 || [[#AddInterface]]
  −
|-
  −
| 3 || [[#GetStateChangeEvent]]
  −
|-
  −
| 4 || [[#GetState]]
  −
|-
  −
| [2.0.0-4.1.0] 5 || [[#SetVidPidBcd]]
  −
|-
  −
| [5.0.0+] 5 || ClearDeviceData
  −
|-
  −
| 6 || [5.0.0+] AddUsbStringDescriptor
  −
|-
  −
| 7 || [5.0.0+] DeleteUsbStringDescriptor
  −
|-
  −
| 8 || [5.0.0+] SetUsbDeviceDescriptor
  −
|-
  −
| 9 || [5.0.0+] SetBinaryObjectStore
  −
|-
  −
| 10 || [5.0.0+] Enable
  −
|-
  −
| 11 || [5.0.0+] Disable
  −
|-
  −
| 12 || [8.0.0+]
  −
|}
  −
 
  −
Initialization done by [[Manu Services|manu]]:
  −
* Initial service init:
  −
** Get service/etc.
  −
** Uses [[#BindDevice]].
  −
** Uses [[#BindClientProcess]].
  −
** Uses [[#GetStateChangeEvent]].
  −
** Uses [[#SetVidPidBcd]].
  −
* Interface init:
  −
** Uses [[#AddInterface]], then uses commands from that with the rest of the following.
  −
** Uses [[#GetSetupEvent]].
  −
** Uses [[#GetCtrlInCompletionEvent]].
  −
** Uses [[#GetCtrlOutCompletionEvent]].
  −
* Initializes two endpoints via using [[#AddEndpoint]] twice.
  −
 
  −
== 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".
 
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
 
   Product: Nintendo Switch
Line 85: Line 9:  
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 [[#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]].
+
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.
 
When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000.
Line 147: Line 71:  
           bInterval              16
 
           bInterval              16
   −
== BindDevice ==
+
= usb:ds =
Takes an u32 ('''complexId'''). [[Manu_Services|Manu]] sends 0x02.
+
[1.0.0-10.2.0] This is "nn::usb::ds::IDsService".
   −
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.
+
[11.0.0+] This is "nn::usb::ds::IDsRootSession".
   −
Returns a not-found error when complexId isn't 0x02, for values 0x0-0x4 at least.
+
This service is used during [[Factory Setup|factory setup]] by [[Manu Services|manu]]. This is also used by [[Capmtp_services|capmtp]].
   −
== BindClientProcess ==
+
This service session is used as an IPC [[IPC_Marshalling|domain]] by [[Manu Services|manu]].
Takes 1 copy-handle for the current process (0xFFFF8001).
  −
 
  −
== 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.
  −
 
  −
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 [[#BindDevice]] wasn't used.
     −
Up to 4 interfaces can be used+[[#EnableInterface|enabled]].
+
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.
   −
Structure of the first buffer(this is the same as [http://libusb.sourceforge.net/api-1.0/structlibusb__interface__descriptor.html libusb__interface__descriptor]):
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Offset || Size || Description
+
! Cmd || Name
 
|-
 
|-
| 0x0 || 0x1 || bLength. Must match 0x9.
+
| 0 || [[#OpenDsService]]
|-
  −
| 0x1 || 0x1 || bDescriptorType. Must match 0x4.
  −
|-
  −
| 0x2 || 0x1 || bInterfaceNumber. When 0x4, the bInterfaceNumber is automatically allocated(error will be thrown if no space). Otherwise, it's used directly and must be <=3.
  −
|-
  −
| 0x3 || 0x1 || bAlternateSetting. Must match 0x0.
  −
|-
  −
| 0x4 || 0x1 || bNumEndpoints. Ignored.
  −
|-
  −
| 0x5 || 0x1 || bInterfaceClass
  −
|-
  −
| 0x6 || 0x1 || bInterfaceSubClass
  −
|-
  −
| 0x7 || 0x1 || bInterfaceProtocol
  −
|-
  −
| 0x8 || 0x1 || iInterface. Ignored.
   
|}
 
|}
   −
Only the first 0x9-bytes are used.
+
== OpenDsService ==
 +
Unofficial name.
   −
== GetStateChangeEvent ==
+
No input. Returns an [[#IDsService]].
Returns an event handle for when the state returned by [[#GetState]] changes. 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 ==
+
== IDsService ==
No input. Returns an output u32. Returns an error when [[#BindDevice]] wasn't used.
+
This is "nn::usb::ds::IDsService".
 
  −
Returns the current state.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Value || Name || Description
+
! Cmd || Name
 
|-
 
|-
| 0 || Detached || Device is not attached to USB.
+
| 0 || [[#BindComplex]]
 
|-
 
|-
| 1 || Attached || Device is attached, but is not powered.
+
| 1 || [11.0.0+] [[#RegisterInterface]] ([1.0.0-10.2.0] [[#BindClientProcess]]))
 
|-
 
|-
| 2 || Powered || Device is attached and powered, but has not been reset.
+
| 2 || [11.0.0+] [[#GetStateChangeEvent]] ([1.0.0-10.2.0] [[#RegisterInterface]])
 
|-
 
|-
| 3 || Default || Device is attached, powered, and has been reset, but does not have an address.
+
| 3 || [11.0.0+] [[#GetState]] ([1.0.0-10.2.0] [[#GetStateChangeEvent]])
 
|-
 
|-
| 4 || Address || Device is attached, powered, has been reset, has an address, but is not configured.
+
| 4 || [11.0.0+] ClearDeviceData ([1.0.0-10.2.0] [[#GetState]])
 
|-
 
|-
| 5 || Configured || Device is attached, powered, has been reset, has an address, configured, and may be used.
+
| 5 || [11.0.0+] AddUsbStringDescriptor ([5.0.0-10.2.0] ClearDeviceData, [2.0.0-4.1.0] [[#SetVidPidBcd]])
 
|-
 
|-
| 6 || Suspended || Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used.
+
| 6 || [11.0.0+] DeleteUsbStringDescriptor ([5.0.0-10.2.0] AddUsbStringDescriptor)
|}
  −
 
  −
== SetVidPidBcd ==
  −
Takes a type-5 buffer with 0x66 bytes of USB descriptor data (see [[Manu_Services#manu|manu]]).
  −
 
  −
{| class="wikitable" border="1"
   
|-
 
|-
! Offset || Size || Description
+
| 7 || [11.0.0+] SetUsbDeviceDescriptor ([5.0.0-10.2.0] DeleteUsbStringDescriptor)
 
|-
 
|-
| 0x0 || 0x2 || VID (idVendor)
+
| 8 || [11.0.0+] SetBinaryObjectStore ([5.0.0-10.2.0] SetUsbDeviceDescriptor)
 
|-
 
|-
| 0x2 || 0x2 || PID (idProduct)
+
| 9 || [11.0.0+] Enable ([5.0.0-10.2.0] SetBinaryObjectStore)
 
|-
 
|-
| 0x4 || 0x2 || bcdDevice
+
| 10 || [11.0.0+] Disable ([5.0.0-10.2.0] Enable)
 
|-
 
|-
| 0x6 || 0x20 || Manufacturer
+
| 11 || [11.0.0+] ([5.0.0-10.2.0] Disable)
 
|-
 
|-
| 0x26 || 0x20 || Product
+
| 12 || [8.0.0-10.2.0]
|-
  −
| 0x46 || 0x20 || SerialNumber
   
|}
 
|}
   −
The last 3 blocks are ASCII strings. The data following each string is all-zero, for padding to size 0x20.
+
== BindComplex ==
 +
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.
 +
 
 +
Returns a not-found error when '''ComplexId''' isn't 0x02, for values 0x0-0x4 at least.
 +
 
 +
== BindClientProcess ==
 +
Takes an input Process handle. No output.
 +
 
 +
== RegisterInterface ==
 +
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 [[#BindComplex]] wasn't used.
 +
 
 +
Up to 4 interfaces can be used and [[#EnableInterface|enabled]].
 +
 
 +
== GetStateChangeEvent ==
 +
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 ==
 +
No input. Returns an output [[#UsbState]].
 +
 
 +
Returns an error when [[#BindComplex]] wasn't used.
 +
 
 +
== SetVidPidBcd ==
 +
Takes a type-0x5 input buffer containing an [[#UsbVidPidBcd]]. No output.
    
== Cmd12 ==
 
== Cmd12 ==
Line 246: Line 173:  
== 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"
Line 253: Line 178:  
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || [[#AddEndpoint]]
+
| 0 || [[#RegisterEndpoint]]
 
|-
 
|-
 
| 1 || [[#GetSetupEvent]]
 
| 1 || [[#GetSetupEvent]]
Line 259: Line 184:  
| 2 || [[#GetSetupPacket]]
 
| 2 || [[#GetSetupPacket]]
 
|-
 
|-
| 3 || [[#Enable]]
+
| 3 || [11.0.0+] [[#CtrlIn]] ([1.0.0-10.2.0] [[#Enable]])
 
|-
 
|-
| 4 || [[#Disable]]
+
| 4 || [11.0.0+] [[#CtrlOut]] ([1.0.0-10.2.0] [[#Disable]])
 
|-
 
|-
| 5 || [[#CtrlIn]]
+
| 5 || [11.0.0+] [[#GetCtrlInCompletionEvent]] ([1.0.0-10.2.0] [[#CtrlIn]])
 
|-
 
|-
| 6 || [[#CtrlOut]]
+
| 6 || [11.0.0+] [[#GetCtrlInUrbReport]] ([1.0.0-10.2.0] [[#CtrlOut]])
 
|-
 
|-
| 7 || [[#GetCtrlInCompletionEvent]]
+
| 7 || [11.0.0+] [[#GetCtrlOutCompletionEvent]] ([1.0.0-10.2.0] [[#GetCtrlInCompletionEvent]])
 
|-
 
|-
| 8 || [[#GetCtrlInUrbReport]]
+
| 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 || [[#GetCtrlOutUrbReport]]
+
| 10 || [11.0.0+] AppendConfigurationData ([1.0.0-10.2.0] [[#GetCtrlOutUrbReport]])
 
|-
 
|-
| 11 || [[#CtrlStall]]
+
| 11 || [13.0.0+] ([1.0.0-10.2.0] [[#CtrlStall]])
 
|-
 
|-
| 12 || [5.0.0+] AppendConfigurationData
+
| 12 || [15.0.0+] ([5.0.0-10.2.0] AppendConfigurationData)
 
|}
 
|}
   −
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]].
+
=== 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]].
   −
=== AddEndpoint ===
+
[[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 292: Line 219:  
** 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).
  −
Each field is an u8, except for offset 0x4-0x5 which is an u16.
  −
  −
This structure matches [http://libusb.sourceforge.net/api-1.0/structlibusb__endpoint__descriptor.html libusb_endpoint_descriptor], with audio-only-devices fields bRefresh and bSynchAddress removed.
      
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 303: Line 226:     
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 event handle. Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init.
+
No input. Returns an output Event handle.
 +
 
 +
Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init.
    
=== GetSetupPacket ===
 
=== GetSetupPacket ===
Takes a type-0x6 output buffer, no other output. Memcpys data to outbuf with outsize, uses size 0x8 if outsize is too large.
+
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 ===
 
=== Enable ===
Takes no arguments. Enables the current interface.
+
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 [[#AddEndpoint]] 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 [[#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 ===
 
=== Disable ===
Takes no arguments. Disables the current interface.
+
No input/output.  
 +
 
 +
Disables the current interface.
    
=== CtrlIn ===
 
=== CtrlIn ===
Same as [[#PostBufferAsync]](with same input/output), except this uses control input endpoint 0x80.
+
Same as [[#PostBufferAsync]], except this uses control input endpoint 0x80.
 +
 
 +
Throws an error if the interface is not [[#EnableInterface|enabled]].
    
=== CtrlOut ===
 
=== CtrlOut ===
Same as [[#PostBufferAsync]](with same input/output), except this uses control output endpoint 0x00.
+
Same as [[#PostBufferAsync]], except this uses control output endpoint 0x00.
 +
 
 +
Throws an error if the interface is not [[#EnableInterface|enabled]].
    
=== GetCtrlInCompletionEvent ===
 
=== GetCtrlInCompletionEvent ===
Returns an event handle for polling the completion of input control commands. Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80.
+
Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80.
    
=== GetCtrlInUrbReport ===
 
=== GetCtrlInUrbReport ===
Same as [[#GetUrbReport]](with same input/output), except this uses control input endpoint 0x80.
+
Same as [[#GetUrbReport]], 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.
+
Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00.
    
=== GetCtrlOutUrbReport ===
 
=== GetCtrlOutUrbReport ===
Same as [[#GetUrbReport]](with same input/output), except this uses control output endpoint 0x00.
+
Same as [[#GetUrbReport]], except this uses control output endpoint 0x00.
    
=== CtrlStall ===
 
=== 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]].
    
=== IDsEndpoint ===
 
=== IDsEndpoint ===
Line 371: Line 312:  
|}
 
|}
   −
[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 ====
 +
Takes an input u32 '''Size''' and an input u64 '''Buffer'''. Returns an output u32 '''UrbId'''.
   −
==== PostBufferAsync ====
+
The output urbId can then be used while parsing the output of [[#GetUrbReport]], 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 390: Line 331:     
==== 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.
    
==== GetUrbReport ====
 
==== 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 an output [[#UrbReport]].
 
  −
{| class="wikitable" border="1"
  −
|-
  −
! Offset || Size || Description
  −
|-
  −
| 0x0 || 0x10*0x8(0x80) || 0x8 entries 0x10-bytes each for each report.
  −
|-
  −
| 0x80 || 0x4 || u32 report count
  −
|}
     −
Entry data:
+
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.
{| class="wikitable" border="1"
  −
|-
  −
! Offset || Size || Description
  −
|-
  −
| 0x0 || 0x4 || u32 id (urbId from post-buffer commands)
  −
|-
  −
| 0x4 || 0x4 || u32 requestedSize
  −
|-
  −
| 0x8 || 0x4 || u32 transferredSize
  −
|-
  −
| 0xC || 0x4 || u32 urb status, converted to error-codes. 0x3 = success, 0x4 = 0x828c, 0x5 = 0x748c. All other values are invalid.
  −
|-
  −
|}
      
==== Stall ====
 
==== Stall ====
Line 427: Line 346:     
==== SetZeroLengthTransfer ====
 
==== SetZeroLengthTransfer ====
Takes an input u8, no output.
+
Takes an input bool. No output.
    
==== Cmd6 ====
 
==== Cmd6 ====
No input, returns an output bool.
+
No input. Returns an output bool.
    
==== Cmd7 ====
 
==== Cmd7 ====
No input, returns an output handle.
+
No input. Returns an output handle.
    
==== Cmd8 ====
 
==== Cmd8 ====
Takes an input u64 and a handle, no output. Stubbed, just returns an error.
+
Takes an input u64 and an input handle. No output.
 +
 
 +
Stubbed, just returns an error.
    
==== Cmd9 ====
 
==== Cmd9 ====
Takes an input u32 size, an u64 offset, returns an u32 urbId. Stubbed, just returns an error.
+
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 632: Line 555:  
| 3 || [[#PopulateRing]] ([1.0.0] [[#Close]])
 
| 3 || [[#PopulateRing]] ([1.0.0] [[#Close]])
 
|-
 
|-
| [2.0.0+] 4 || [[#PostBufferAsync_2|#PostBufferAsync]]
+
| 4 || [2.0.0+] [[#PostBufferAsync_2|#PostBufferAsync]]
 
|-
 
|-
| [2.0.0+] 5 || [[#GetXferReport]]
+
| 5 || [2.0.0+] [[#GetXferReport]]
 
|-
 
|-
| [2.0.0+] 6 || [[#BatchBufferAsync]]
+
| 6 || [2.0.0+] [[#BatchBufferAsync]]
 
|-
 
|-
| [4.0.0+] 7 || [[#CreateSmmuSpace]]
+
| 7 || [4.0.0+] [[#CreateSmmuSpace]]
 
|-
 
|-
| [4.0.0+] 8 || [[#ShareReportRing]]
+
| 8 || [4.0.0+] [[#ShareReportRing]]
 
|}
 
|}
   Line 936: Line 859:  
|-
 
|-
 
| 1 ||  
 
| 1 ||  
 +
|}
 +
 +
= 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)
 
|}
 
|}
  

Navigation menu