| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @available(added=7) |
| library fuchsia.hardware.usb.request; |
| |
| using ddk.hw.physiter; |
| using fuchsia.hardware.usb.descriptor; |
| using zx; |
| |
| /// Should be set by the requestor. |
| type UsbHeader = struct { |
| /// Frame number for scheduling isochronous transfers. |
| frame uint64; |
| device_id uint32; |
| /// bEndpointAddress from endpoint descriptor. |
| ep_address uint8; |
| /// Number of bytes to transfer. |
| length zx.off; |
| /// Send zero length packet if length is multiple of max packet size. |
| send_zlp bool; |
| }; |
| |
| /// Response data. |
| /// (Filled in by processor before |UsbRequestComplete()| is called) |
| type UsbResponse = struct { |
| /// Status of transaction. |
| /// ZX_ERR_IO_INVALID indicates that the device stalled the transfer. |
| status zx.status; |
| /// Number of bytes actually transferred (on success). |
| actual zx.off; |
| /// Number of consecutive requests that were silently completed immediately prior to this |
| /// request. |
| /// This only needs to be checked if the client has set |cb_on_error_only| on any requests, |
| /// otherwise it will always be zero. |
| silent_completions_count uint64; |
| }; |
| |
| type UsbRequest = resource struct { |
| header UsbHeader; |
| |
| /// For control transactions. |
| setup fuchsia.hardware.usb.descriptor.UsbSetup; |
| |
| /// VMO handle for payload. |
| vmo_handle zx.handle:VMO; |
| size uint64; |
| /// Offset of the start of data from first page address of the vmo. |
| offset zx.off; |
| /// Mapped address of the first page of the vmo. |
| /// Add offset to get actual data. |
| virt uint64; |
| |
| pmt zx.handle; |
| /// Phys addresses of the payload. |
| @mutable |
| phys vector<zx.paddr>:MAX; |
| |
| @mutable |
| sg vector<ddk.hw.physiter.SgEntry>:MAX; |
| |
| response UsbResponse; |
| |
| /// usb_request_release() frees the request if this is true. |
| release_frees bool; |
| |
| alloc_size uint64; |
| |
| /// Set by the requester if the callback should be skipped on successful completion. |
| /// This is useful for isochronous requests, where the requester does not care about |
| /// most callbacks. |
| /// The requester is in charge of keeping track of the order of queued requests and |
| /// requeuing silently completed requests. |
| /// |
| /// There may be cases where a request completes out of order. For example, errors |
| /// are reported as soon as possible, rather than preserving queue order. |
| /// Due to this, the requester may receive additional callbacks on top of those requested. |
| /// |
| /// If the requester receives a callback, they should check the response's |
| /// |silent_completions_count| to know how many consecutive requests prior to this one |
| /// (in relation to queue order for the endpoint) have completed successfully. |
| cb_on_error_only bool; |
| /// Direct mode -- if set to true, this packet is handled with high priority directly |
| /// in interrupt context. It will NOT be safe to block in any callbacks, and all layers |
| /// should take the most direct path to route the packet to the requesting driver from |
| /// hardware. |
| direct bool; |
| /// If true, resets an endpoint and does not transfer any data. |
| reset bool; |
| /// The address of the endpoint to reset. |
| reset_address uint8; |
| }; |
| |
| @transport("Banjo") |
| @banjo_layout("ddk-callback") |
| protocol UsbRequestCompleteCallback { |
| Callback(resource struct { |
| @in_out |
| req UsbRequest; |
| }) -> (); |
| }; |