USB services: Difference between revisions
No edit summary |
|||
Line 15: | Line 15: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || | | 0 || [[#OpenDsService]] | ||
|} | |} | ||
== | == OpenDsService == | ||
Unofficial name. | |||
No input. Returns an [[#IDsService]]. | No input. Returns an [[#IDsService]]. | ||
Line 34: | Line 36: | ||
| 1 || [[#BindClientProcess]] | | 1 || [[#BindClientProcess]] | ||
|- | |- | ||
| 2 || [[# | | 2 || [[#AddInterface]] | ||
|- | |- | ||
| 3 || [[#GetStateChangeEvent]] | | 3 || [[#GetStateChangeEvent]] | ||
Line 67: | Line 69: | ||
** Uses [[#SetVidPidBcd]]. | ** Uses [[#SetVidPidBcd]]. | ||
* Interface init: | * Interface init: | ||
** Uses [[# | ** Uses [[#AddInterface]], then uses commands from that with the rest of the following. | ||
** Uses [[#GetSetupEvent]]. | ** Uses [[#GetSetupEvent]]. | ||
** Uses [[#GetCtrlInCompletionEvent]]. | ** Uses [[#GetCtrlInCompletionEvent]]. | ||
** Uses [[#GetCtrlOutCompletionEvent]]. | ** Uses [[#GetCtrlOutCompletionEvent]]. | ||
* Initializes two endpoints via using [[# | * Initializes two endpoints via using [[#AddEndpoint]] twice. | ||
== Configuration == | == Configuration == | ||
Line 81: | Line 83: | ||
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 [[# | pre-5.0.0: The endpoints are configured using [[#AddEndpoint]], the total number of endpoints is the number of open [[#IDsEndpoint]] sessions. bInterfaceNumber is {0-based index for the enabled [[#IDsInterface]] session.} Some of the interface fields are configured using [[#AddInterface]]. | ||
When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000. | When usbds is in use where [[#SetVidPidBcd]] wasn't used, the VID/PID is 057e:3000. | ||
Line 153: | Line 155: | ||
Takes 1 copy-handle for the current process (0xFFFF8001). | 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. | Takes 2 type-5 buffers and returns an output u8 and an [[#IDsInterface]]. [[Manu_Services|Manu]] sends a 0x09-byte descriptor (e.g.: 0x09, 0x04, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00) in the first buffer and a string ("usb") in the second buffer. | ||
Line 213: | Line 215: | ||
|- | |- | ||
| 6 || Suspended || Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used. | | 6 || Suspended || Device is attached and powered, but has not seen bus activity for 3ms. Device is suspended and cannot be used. | ||
|} | |} | ||
Line 250: | Line 251: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || [[# | | 0 || [[#AddEndpoint]] | ||
|- | |- | ||
| 1 || [[#GetSetupEvent]] | | 1 || [[#GetSetupEvent]] | ||
|- | |- | ||
| 2 || | | 2 || [[#GetSetupPacket]] | ||
|- | |- | ||
| 3 || [[# | | 3 || [[#Enable]] | ||
|- | |- | ||
| 4 || [[# | | 4 || [[#Disable]] | ||
|- | |- | ||
| 5 || [[# | | 5 || [[#CtrlIn]] | ||
|- | |- | ||
| 6 || [[# | | 6 || [[#CtrlOut]] | ||
|- | |- | ||
| 7 || [[#GetCtrlInCompletionEvent]] | | 7 || [[#GetCtrlInCompletionEvent]] | ||
|- | |- | ||
| 8 || [[# | | 8 || [[#GetCtrlInUrbReport]] | ||
|- | |- | ||
| 9 || [[#GetCtrlOutCompletionEvent]] | | 9 || [[#GetCtrlOutCompletionEvent]] | ||
|- | |- | ||
| 10 || [[# | | 10 || [[#GetCtrlOutUrbReport]] | ||
|- | |- | ||
| 11 || [[# | | 11 || [[#CtrlStall]] | ||
|- | |- | ||
| 12 || [5.0.0+] AppendConfigurationData | | 12 || [5.0.0+] AppendConfigurationData | ||
|} | |} | ||
Commands | 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]]. | ||
=== | === AddEndpoint === | ||
Takes a type-5 buffer and returns an output u8 and an [[#IDsEndpoint]]. [[Manu_Services|Manu]] uses this twice for getting two endpoint sessions, with the following 0x7-byte buffer data: | Takes a type-5 buffer and returns an output u8 and an [[#IDsEndpoint]]. [[Manu_Services|Manu]] uses this twice for getting two endpoint sessions, with the following 0x7-byte buffer data: | ||
* First endpoint: 0x07, 0x05, 0x80, 0x02, 0x00, 0x02, 0x00 | * First endpoint: 0x07, 0x05, 0x80, 0x02, 0x00, 0x02, 0x00 | ||
Line 304: | Line 305: | ||
Returns an event handle. Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init. | Returns an event handle. Unknown what triggers signalling, not signalled during interface-enable / device<>host USB-comms init. | ||
=== | === 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 other output. Memcpys data to outbuf with outsize, uses size 0x8 if outsize is too large. | ||
=== | === Enable === | ||
Takes no arguments. Enables the current interface. | Takes no arguments. Enables the current interface. | ||
Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[# | Only one interface can be enabled at a time per bInterfaceNumber. When bInterfaceNumber is auto-allocate(0x4) for [[#AddEndpoint]] this isn't an issue since the final bInterfaceNumber will be unique. | ||
Once enabled, the device/interface can then actually be used over USB. | Once enabled, the device/interface can then actually be used over USB. | ||
=== | === Disable === | ||
Takes no arguments. Disables the current interface. | Takes no arguments. Disables the current interface. | ||
=== | === CtrlIn === | ||
Same as [[#PostBufferAsync]](with same input/output), except this uses control input endpoint 0x80. | Same as [[#PostBufferAsync]](with same input/output), except this uses control input endpoint 0x80. | ||
=== | === CtrlOut === | ||
Same as [[#PostBufferAsync]](with same input/output), except this uses control output endpoint 0x00. | Same as [[#PostBufferAsync]](with same input/output), except this uses control output endpoint 0x00. | ||
Line 326: | Line 327: | ||
Returns an event handle for polling the completion of input control commands. Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80. | Returns an event handle for polling the completion of input control commands. Same as [[#GetCompletionEvent]], except this uses control input endpoint 0x80. | ||
=== | === GetCtrlInUrbReport === | ||
Same as [[# | Same as [[#GetUrbReport]](with same input/output), except this uses control input endpoint 0x80. | ||
=== GetCtrlOutCompletionEvent === | === GetCtrlOutCompletionEvent === | ||
Returns an event handle for polling the completion of output control commands. Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00. | Returns an event handle for polling the completion of output control commands. Same as [[#GetCompletionEvent]], except this uses control output endpoint 0x00. | ||
=== | === GetCtrlOutUrbReport === | ||
Same as [[# | Same as [[#GetUrbReport]](with same input/output), except this uses control output endpoint 0x00. | ||
=== | === CtrlStall === | ||
No input/output. | No input/output. | ||
Line 349: | Line 350: | ||
| 0 || [[#PostBufferAsync]] | | 0 || [[#PostBufferAsync]] | ||
|- | |- | ||
| 1 || | | 1 || [[#Cancel]] | ||
|- | |- | ||
| 2 || [[#GetCompletionEvent]] | | 2 || [[#GetCompletionEvent]] | ||
|- | |- | ||
| 3 || [[# | | 3 || [[#GetUrbReport]] | ||
|- | |- | ||
| 4 || [[#Stall]] | | 4 || [[#Stall]] | ||
|- | |- | ||
| 5 || | | 5 || [[#SetZeroLengthTransfer]] | ||
|- | |- | ||
| 6 || [7.0.0+] | | 6 || [7.0.0+] | ||
Line 371: | Line 372: | ||
==== PostBufferAsync ==== | ==== PostBufferAsync ==== | ||
Takes an u32 ('''size''') and an u64 ('''buffer'''). Returns an output u32 ('''urbId'''). The output urbId can then be used while parsing the output of [[# | 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 383: | Line 384: | ||
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. | ||
Line 389: | Line 390: | ||
No input. Returns an output event handle for polling the completion of [[#PostBufferAsync]], even when it finished via [[#Stall]]. | No input. Returns an output event handle for polling the completion of [[#PostBufferAsync]], even when it finished via [[#Stall]]. | ||
==== | ==== GetUrbReport ==== | ||
No input. Returns 0x84 bytes of report data from the endpoint. Seems to be eventually loaded from state, since this doesn't trigger any USB bus activity. All-zero before PostBufferAsync was used at least once. | No input. Returns 0x84 bytes of report data from the endpoint. Seems to be eventually loaded from state, since this doesn't trigger any USB bus activity. All-zero before PostBufferAsync was used at least once. | ||
Line 419: | Line 420: | ||
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]]. | ||
==== | ==== SetZeroLengthTransfer ==== | ||
Takes an input u8, no output. | Takes an input u8, no output. | ||
Line 625: | Line 626: | ||
| 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]]) | ||
Line 666: | Line 667: | ||
Used by official sw prior to closing the endpoint session. | Used by official sw prior to closing the endpoint session. | ||
==== | ==== 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]]) | ||