1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#pragma once 6 7#include <ddk/device.h> 8#include <ddk/protocol/usb.h> 9#include <ddk/usb-request/usb-request.h> 10#include <lib/sync/completion.h> 11#include <xdc-server-utils/packet.h> 12 13#include "xdc-hw.h" 14#include "xhci-transfer-common.h" 15#include "xhci-trb.h" 16 17#define TRANSFER_RING_SIZE (PAGE_SIZE / sizeof(xhci_trb_t)) 18 19// The type and length fields for a string descriptor are one byte each. 20#define STR_DESC_METADATA_LEN 2 21#define MAX_STR_LEN 64 22 23// There are only two endpoints, one for bulk OUT and one for bulk IN. 24#define OUT_EP_IDX 0 25#define IN_EP_IDX 1 26#define NUM_EPS 2 27 28// See XHCI Spec, 7.6.3.2 29#define EP_CTX_MAX_PACKET_SIZE 1024 30 31#define MAX_EP_DEBUG_NAME_LEN 4 32 33typedef enum { 34 XDC_EP_STATE_DEAD = 0, // device does not exist or has been removed 35 XDC_EP_STATE_RUNNING, // EP is accepting TRBs on the transfer ring 36 XDC_EP_STATE_HALTED, // EP halted due to stall 37 XDC_EP_STATE_STOPPED // EP halt has been cleared, but not yet accepting TRBs 38} xdc_ep_state_t; 39 40typedef struct { 41 xhci_transfer_ring_t transfer_ring; 42 list_node_t queued_reqs; // requests waiting to be processed 43 usb_request_t* current_req; // request currently being processed 44 list_node_t pending_reqs; // processed requests waiting for completion, including current_req 45 xhci_transfer_state_t transfer_state; // transfer state for current_req 46 uint8_t direction; // USB_DIR_OUT or USB_DIR_IN 47 48 xdc_ep_state_t state; 49 bool got_err_event; // encountered a TRB error on the event ring 50 51 char name[MAX_EP_DEBUG_NAME_LEN]; // For debug printing. 52} xdc_endpoint_t; 53 54typedef struct { 55 uint8_t len; 56 uint8_t type; 57 uint8_t string[MAX_STR_LEN]; 58} xdc_str_desc_t; 59 60typedef struct { 61 xdc_str_desc_t str_0_desc; 62 xdc_str_desc_t manufacturer_desc; 63 xdc_str_desc_t product_desc; 64 xdc_str_desc_t serial_num_desc; 65} xdc_str_descs_t; 66 67// This is used by the xdc_poll thread to monitors changes in the debug capability register state, 68// and handle completed requests. 69// TODO(jocelyndang): move this and all poll thread related functions into a single file. 70typedef struct { 71 // Whether a Root Hub Port is connected to a Debug Host and assigned to the Debug Capability. 72 bool connected; 73 // The last connection time in nanoseconds, with respect to the monotonic clock. 74 zx_time_t last_conn; 75 76 // Whether the Debug Device is in the Configured state. 77 // Changes to this are also copied to the xdc struct configured mmember. 78 bool configured; 79 80 bool halt_in; 81 bool halt_out; 82 83 // Requests that need their complete_cb called. 84 list_node_t completed_reqs; 85} xdc_poll_state_t; 86 87typedef struct { 88 zx_device_t* zxdev; 89 90 // Shared from XHCI. 91 zx_handle_t bti_handle; 92 void* mmio; 93 94 xdc_debug_cap_regs_t* debug_cap_regs; 95 96 // Underlying buffer for the event ring segment table 97 io_buffer_t erst_buffer; 98 erst_entry_t* erst_array; 99 100 xhci_event_ring_t event_ring; 101 102 // Underlying buffer for the context data and string descriptors. 103 io_buffer_t context_str_descs_buffer; 104 xdc_context_data_t* context_data; 105 xdc_str_descs_t* str_descs; 106 107 thrd_t start_thread; 108 109 // Whether to suspend all activity. 110 atomic_bool suspended; 111 112 xdc_endpoint_t eps[NUM_EPS]; 113 // Whether the Debug Device is in the Configured state. 114 bool configured; 115 // Needs to be acquired before accessing the eps and configured members. 116 // TODO(jocelyndang): make these separate locks? 117 mtx_t lock; 118 119 bool writable; 120 usb_request_pool_t free_write_reqs; 121 mtx_t write_lock; 122 123 list_node_t free_read_reqs; 124 xdc_packet_state_t cur_read_packet; 125 mtx_t read_lock; 126 127 list_node_t instance_list; 128 // Streams registered by the host. 129 list_node_t host_streams; 130 mtx_t instance_list_lock; 131 132 // At least one xdc instance has been opened. 133 sync_completion_t has_instance_completion; 134 atomic_int num_instances; 135} xdc_t; 136 137// TODO(jocelyndang): we should get our own handles rather than borrowing them from XHCI. 138zx_status_t xdc_bind(zx_device_t* parent, zx_handle_t bti_handle, void* mmio); 139 140void xdc_endpoint_set_halt_locked(xdc_t* xdc, xdc_poll_state_t* poll_state, xdc_endpoint_t* ep) 141 __TA_REQUIRES(xdc->lock); 142