blob: b048ae17c61a64aae2515f662a593bd970a385ea [file] [log] [blame]
// 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;
}) -> ();
};