source: mainline/uspace/drv/bus/usb/xhci/commands.h@ 889146e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 889146e was 889146e, checked in by Ondřej Hlavatý <aearsis@…>, 8 years ago

xhci: commands shall not just timeout

Previous behavior was breaking semantic: if a command was successful,
but just took too long to complete, we returned an error, and the caller
had no way to know if the command's effect has taken place.

This commit implements command aborting. The wait_for_command now cannot
just timeout - instead it aborts currently running (probably blocked)
command, and then gets back to waiting. So now, if command_sync returns
an error, it means the command was really unsuccessful.

If aborting the command takes too long, we should reset the whole HC.
This is not yet implemented.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbxhci
30 * @{
31 */
32/** @file
33 * Utility functions used to place TRBs onto the command ring.
34 */
35
36#ifndef XHCI_COMMANDS_H
37#define XHCI_COMMANDS_H
38
39#include <adt/list.h>
40#include <stdbool.h>
41#include <fibril_synch.h>
42#include <usb/host/dma_buffer.h>
43#include "hw_struct/trb.h"
44#include "trb_ring.h"
45
46#define XHCI_COMMAND_TIMEOUT 10000
47#define XHCI_CR_ABORT_TIMEOUT 5000
48
49typedef struct xhci_hc xhci_hc_t;
50typedef struct xhci_input_ctx xhci_input_ctx_t;
51typedef struct xhci_port_bandwidth_ctx xhci_port_bandwidth_ctx_t;
52
53typedef enum xhci_cmd_type {
54 XHCI_CMD_ENABLE_SLOT,
55 XHCI_CMD_DISABLE_SLOT,
56 XHCI_CMD_ADDRESS_DEVICE,
57 XHCI_CMD_CONFIGURE_ENDPOINT,
58 XHCI_CMD_EVALUATE_CONTEXT,
59 XHCI_CMD_RESET_ENDPOINT,
60 XHCI_CMD_STOP_ENDPOINT,
61 XHCI_CMD_SET_TR_DEQUEUE_POINTER,
62 XHCI_CMD_RESET_DEVICE,
63 XHCI_CMD_FORCE_EVENT,
64 XHCI_CMD_NEGOTIATE_BANDWIDTH,
65 XHCI_CMD_SET_LATENCY_TOLERANCE_VALUE,
66 XHCI_CMD_GET_PORT_BANDWIDTH,
67 XHCI_CMD_FORCE_HEADER,
68 XHCI_CMD_NO_OP,
69} xhci_cmd_type_t;
70
71typedef enum {
72 XHCI_CR_STATE_CLOSED, /**< Commands are rejected with ENAK. */
73 XHCI_CR_STATE_OPEN, /**< Commands are enqueued normally. */
74 XHCI_CR_STATE_CHANGING, /**< Commands wait until state changes. */
75} xhci_cr_state;
76
77typedef struct xhci_command_ring {
78 xhci_trb_ring_t trb_ring;
79
80 fibril_mutex_t guard; /**< Guard access to this structure. */
81 list_t cmd_list;
82
83 xhci_cr_state state; /**< Whether commands are allowed to be
84 added. */
85 fibril_condvar_t state_cv; /**< For waiting on CR state change. */
86
87 fibril_condvar_t stopped_cv; /**< For waiting on CR stopped event. */
88} xhci_cmd_ring_t;
89
90typedef struct xhci_command {
91 /** Internal fields used for bookkeeping. Need not worry about these. */
92 struct {
93 link_t link;
94
95 xhci_cmd_type_t cmd;
96
97 xhci_trb_t trb;
98 uintptr_t trb_phys;
99
100 bool async;
101 bool completed;
102
103 /* Will broadcast after command completes. */
104 fibril_mutex_t completed_mtx;
105 fibril_condvar_t completed_cv;
106 } _header;
107
108 /** Below are arguments of all commands mixed together.
109 * Be sure to know which command accepts what arguments. */
110
111 uint32_t slot_id;
112 uint32_t endpoint_id;
113 uint16_t stream_id;
114
115 dma_buffer_t input_ctx, bandwidth_ctx;
116 uintptr_t dequeue_ptr;
117
118 uint8_t tcs;
119 uint8_t susp;
120 uint8_t device_speed;
121 uint32_t status;
122 bool deconfigure;
123} xhci_cmd_t;
124
125/* Command handling control */
126int xhci_init_commands(xhci_hc_t *);
127void xhci_fini_commands(xhci_hc_t *);
128
129void xhci_stop_command_ring(xhci_hc_t *);
130void xhci_abort_command_ring(xhci_hc_t *);
131void xhci_start_command_ring(xhci_hc_t *);
132
133int xhci_handle_command_completion(xhci_hc_t *, xhci_trb_t *);
134
135/* Command lifecycle */
136void xhci_cmd_init(xhci_cmd_t *, xhci_cmd_type_t);
137void xhci_cmd_fini(xhci_cmd_t *);
138
139/* Issuing commands */
140int xhci_cmd_sync(xhci_hc_t *, xhci_cmd_t *);
141int xhci_cmd_sync_fini(xhci_hc_t *, xhci_cmd_t *);
142int xhci_cmd_async_fini(xhci_hc_t *, xhci_cmd_t *);
143
144static inline int xhci_cmd_sync_inline_wrapper(xhci_hc_t *hc, xhci_cmd_t cmd)
145{
146 /* Poor man's xhci_cmd_init (everything else is zeroed) */
147 link_initialize(&cmd._header.link);
148 fibril_mutex_initialize(&cmd._header.completed_mtx);
149 fibril_condvar_initialize(&cmd._header.completed_cv);
150
151 /* Issue the command */
152 const int err = xhci_cmd_sync(hc, &cmd);
153 xhci_cmd_fini(&cmd);
154
155 return err;
156}
157
158/** The inline macro expects:
159 * - hc - HC to schedule command on (xhci_hc_t *).
160 * - command - Member of `xhci_cmd_type_t` without the "XHCI_CMD_" prefix.
161 * - VA_ARGS - (optional) Command arguments in struct initialization notation.
162 *
163 * The return code and semantics matches those of `xhci_cmd_sync_fini`.
164 *
165 * Example:
166 * int err = xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = 42);
167 */
168
169#define xhci_cmd_sync_inline(hc, command, ...) \
170 xhci_cmd_sync_inline_wrapper(hc, \
171 (xhci_cmd_t) { ._header.cmd = XHCI_CMD_##command, ##__VA_ARGS__ })
172
173#endif
174
175
176
177/**
178 * @}
179 */
Note: See TracBrowser for help on using the repository browser.