class RequestBase

Defined at line 149 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

Usage notes:

usb::Request is a c++ wrapper around the usb_request_t object. It provides

capabilities to interact with a usb_req buffer which is used to traverse the

usb stack. On deletion, it will automatically free itself.

usb::BorrowedRequest provides an unowned variant of usb::Request. It adds

functionality to store and call a complete callback which isn't present in

usb::Request. In addition, it will call the completion on destruction if it

wasn't already triggered.

usb::RequestPool provides pooling functionality for usb::Request reuse.

usb::RequestQueue provides a queue interface for tracking usb::Request and

usb::BorrowedRequest objects.

usb::RequestList provides a list interface for tracking usb::Request and

usb::BorrowedRequest objects.

A Request or BorrowedRequest cannot be stored simultaneously in both a

usb::RequestQueue and usb::RequestList in the same driver layer.

A CallbackRequest is a Request which maintains ownership of a request,

and contains a callback which will be invoked upon completion.

Since the parent request size is often not known at compile-time,

it is necessary for the device driver to implement its own wrapper

and call the Invoke function on the callback when a completion

is received. Invoke will then invoke the associated lambda function.

Available methods for both Request and BorrowedRequest include:

usb_request_t* request(); // accessor for inner type.

// Takes ownership of inner type. Should only be used when transferring

// ownership to another driver.

usb_request_t* take();

All methods implemented in RequestBase (scroll below for additional info).

Available to Request and BorrowedRequest if they templatize of Storage:

Storage* private_storage(); // accessor for private storage.

Available to Request:

void Release(); // Frees the inner type.

Available to BorrowedRequest:

void Complete(zx_status_t); // Completes the Request.

////////////////////////////////////////////////////////////////////////////

Example: Basic allocation with a pool:

usb::RequestPool

<

> pool;

const size_t op_size = usb::Request

<

>::RequestSize(parent_req_size);

for (int i = 0; i

<

kNumRequest; i++) {

std::optional

<usb

::Request> request;

request = usb::Request::Alloc(op_size, DATA_SIZE, EP_ADDRESS, parent_req_size);

if (!request) return ZX_ERR_NO_MEMORY;

pool.add(*std::move(request));

}

////////////////////////////////////////////////////////////////////////////

Example: Enqueue incoming requests into a usb::RequestQueue:

class Driver {

public:

<

...>

private:

usb::BorrowedRequestQueue

<

> request_;

const size_t parent_req_size_;

};

void Driver::UsbRequestQueue(usb_request_t* req, const usb_request_callback_t* completion_cb) {

request_.push(usb::BorrowedRequest

<

>(op, cb, parent_req_size_));

}

////////////////////////////////////////////////////////////////////////////

Example: Add incoming requests into a usb::RequestList:

class Driver {

public:

<

...>

private:

usb::BorrowedRequestList

<

> request_;

const size_t parent_req_size_;

};

void Driver::UsbRequestQueue(usb_request_t* req, const usb_request_callback_t* completion_cb) {

auto opt_unowned = usb::BorrowedRequest

<

>(op, cb, parent_req_size);

auto unowned = *std::move(opt_unowned);

request_.push_back(

&unowned

);

// Pass unowned_.take() to next layer.

}

////////////////////////////////////////////////////////////////////////////

Example: Using private context only visible to your driver:

struct PrivateStorage {

bool valid;

size_t count_metric;

}

using UsbRequest = usb::BorrowedRequest

<PrivateStorage

>;

void Driver::UsbRequestQueue(usb_request_t* req, const usb_request_t* completion_cb) {

UsbRequest usb_req(op, cb, parent_req_size_));

ZX_DEBUG_ASSERT(usb_req.request()->command == USB_ERASE);

usb_req.private_storage()->valid = true;

usb_req.private_storage()->count_metric += 1;

<

...>

}

////////////////////////////////////////////////////////////////////////////

Example: Using CallbackRequest

using UsbRequest = CallbackRequest

<

32>;

...

UsbRequest::Queue(std::move(request), [=](UsbRequest request) {...});

Public Methods

zx_status_t SetScatterGatherList (const sg_entry_t * sg_list, size_t sg_count)

Copies the scatter gather list to the request.

Future transfers using this request will determine where in the VMO to store read/write data.

using the scatter gather list.

This will free any existing scatter gather list stored in the request.

Defined at line 155 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

ssize_t CopyFrom (void * data, size_t length, size_t offset)

Copies data from the Request's vm object.

Out of range operations are ignored.

Defined at line 161 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

ssize_t CopyTo (const void * data, size_t length, size_t offset)

Copies data into a Request's vm object.

Out of range operations are ignored.

Defined at line 167 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

zx_status_t Mmap (void ** data)

Maps the Request's vm object. The 'data' field is set with the mapped address if this

function succeeds.

Defined at line 173 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

zx_status_t CacheFlush (zx_off_t offset, size_t length)

Performs a cache flush on a range of memory in the request's buffer.

Defined at line 176 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

zx_status_t CacheFlushInvalidate (zx_off_t offset, size_t length)

Performs a cache flush and invalidate on a range of memory in the request's buffer.

Defined at line 181 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

zx_status_t PhysMap (const zx::bti & bti)

Looks up the physical pages backing this request's vm object.

Defined at line 186 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

void TraceFlow ()

Starts or adds a step in a trace flow for the passed in request

Defined at line 189 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

io_buffer::PhysIter phys_iter (size_t max_length)

Initializes a io_buffer::PhysIter for a usb request.

|max_length| is the maximum length of a range returned the iterator.

|max_length| must be either a positive multiple of the system page size, or zero for no limit.

Defined at line 194 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

size_t alloc_size ()

Defined at line 208 of file ../../src/devices/usb/lib/usb/include/usb/request-cpp.h

usb_request_t * request ()