Changeset c3d926f in mainline for uspace/drv/bus/usb/xhci/commands.h


Ignore:
Timestamp:
2017-10-25T08:03:13Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a5b3de6
Parents:
0206d35
Message:

Big command refactoring. Unified and encapsulated command function API. Removed explicit heap command (de)allocation functions. Added three functions for (a)synchronous command issuing and neat inline macro with syntax sugar.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/commands.h

    r0206d35 rc3d926f  
    4242#include "hw_struct/trb.h"
    4343
    44 /* Useful timeouts for `xhci_cmd_wait()` */
    45 #define XHCI_DEFAULT_TIMEOUT             1000000
    46 #define XHCI_BLOCK_INDEFINITELY              0
     44#define XHCI_DEFAULT_TIMEOUT       1000000
     45#define XHCI_BLOCK_INDEFINITELY    0
    4746
    4847typedef struct xhci_hc xhci_hc_t;
     
    5049typedef struct xhci_port_bandwidth_ctx xhci_port_bandwidth_ctx_t;
    5150
     51typedef enum xhci_cmd_type {
     52        XHCI_CMD_ENABLE_SLOT,
     53        XHCI_CMD_DISABLE_SLOT,
     54        XHCI_CMD_ADDRESS_DEVICE,
     55        XHCI_CMD_CONFIGURE_ENDPOINT,
     56        XHCI_CMD_EVALUATE_CONTEXT,
     57        XHCI_CMD_RESET_ENDPOINT,
     58        XHCI_CMD_STOP_ENDPOINT,
     59        XHCI_CMD_SET_TR_DEQUEUE_POINTER,
     60        XHCI_CMD_RESET_DEVICE,
     61        XHCI_CMD_FORCE_EVENT,
     62        XHCI_CMD_NEGOTIATE_BANDWIDTH,
     63        XHCI_CMD_SET_LATENCY_TOLERANCE_VALUE,
     64        XHCI_CMD_GET_PORT_BANDWIDTH,
     65        XHCI_CMD_FORCE_HEADER,
     66        XHCI_CMD_NO_OP,
     67} xhci_cmd_type_t;
     68
    5269typedef struct xhci_command {
    53         link_t link;
     70        /** Internal fields used for bookkeeping. Need not worry about these. */
     71        struct {
     72                link_t link;
    5473
    55         xhci_trb_t trb;
    56         uintptr_t trb_phys;
     74                xhci_cmd_type_t cmd;
     75                suseconds_t timeout;
     76
     77                xhci_trb_t trb;
     78                uintptr_t trb_phys;
     79
     80                bool async;
     81                bool completed;
     82
     83                /* Will broadcast after command completes. */
     84                fibril_mutex_t completed_mtx;
     85                fibril_condvar_t completed_cv;
     86        } _header;
     87
     88        /** Below are arguments of all commands mixed together.
     89         *  Be sure to know which command accepts what arguments. */
    5790
    5891        uint32_t slot_id;
     92        uint32_t endpoint_id;
     93        uint16_t stream_id;
     94
     95        xhci_input_ctx_t *input_ctx;
     96        xhci_port_bandwidth_ctx_t *bandwidth_ctx;
     97        uintptr_t dequeue_ptr;
     98
     99        uint8_t tcs;
     100        uint8_t susp;
     101        uint8_t device_speed;
    59102        uint32_t status;
    60103        bool deconfigure;
    61 
    62         bool completed;
    63 
    64         /* Will broadcast after command completes. */
    65         fibril_mutex_t completed_mtx;
    66         fibril_condvar_t completed_cv;
    67104} xhci_cmd_t;
    68105
     106/* Command handling control */
    69107int xhci_init_commands(xhci_hc_t *);
    70108void xhci_fini_commands(xhci_hc_t *);
    71 
    72 xhci_cmd_t *xhci_cmd_alloc(void);
    73 void xhci_cmd_init(xhci_cmd_t *);
    74 int xhci_cmd_wait(xhci_cmd_t *, suseconds_t);
    75 void xhci_cmd_fini(xhci_cmd_t *);
    76 void xhci_cmd_free(xhci_cmd_t *);
    77109
    78110void xhci_stop_command_ring(xhci_hc_t *);
     
    80112void xhci_start_command_ring(xhci_hc_t *);
    81113
    82 int xhci_send_no_op_command(xhci_hc_t *, xhci_cmd_t *);
    83 int xhci_send_enable_slot_command(xhci_hc_t *, xhci_cmd_t *);
    84 int xhci_send_disable_slot_command(xhci_hc_t *, xhci_cmd_t *);
    85 int xhci_send_address_device_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
    86 int xhci_send_configure_endpoint_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
    87 int xhci_send_evaluate_context_command(xhci_hc_t *, xhci_cmd_t *, xhci_input_ctx_t *);
    88 int xhci_send_reset_endpoint_command(xhci_hc_t *, xhci_cmd_t *, uint32_t, uint8_t);
    89 int xhci_send_stop_endpoint_command(xhci_hc_t *, xhci_cmd_t *, uint32_t, uint8_t);
    90 int xhci_send_set_dequeue_ptr_command(xhci_hc_t *, xhci_cmd_t *, uintptr_t, uint16_t, uint32_t);
    91 int xhci_send_reset_device_command(xhci_hc_t *, xhci_cmd_t *);
    92 // TODO: Force event (optional normative, for VMM, section 4.6.12).
    93 // TODO: Negotiate bandwidth (optional normative, section 4.6.13).
    94 // TODO: Set latency tolerance value (optional normative, section 4.6.14).
    95 int xhci_get_port_bandwidth_command(xhci_hc_t *, xhci_cmd_t *, xhci_port_bandwidth_ctx_t *, uint8_t);
    96 // TODO: Get port bandwidth (mandatory, but needs root hub implementation, section 4.6.15).
    97 // TODO: Force header (mandatory, but needs root hub implementation, section 4.6.16).
     114int xhci_handle_command_completion(xhci_hc_t *, xhci_trb_t *);
    98115
    99 int xhci_handle_command_completion(xhci_hc_t *, xhci_trb_t *);
     116/* Command lifecycle */
     117void xhci_cmd_init(xhci_cmd_t *, xhci_cmd_type_t);
     118void xhci_cmd_fini(xhci_cmd_t *);
     119
     120/* Issuing commands */
     121int xhci_cmd_sync(xhci_hc_t *, xhci_cmd_t *);
     122int xhci_cmd_sync_fini(xhci_hc_t *, xhci_cmd_t *);
     123int xhci_cmd_async_fini(xhci_hc_t *, xhci_cmd_t *);
     124
     125static inline int xhci_cmd_sync_inline_wrapper(xhci_hc_t *hc, xhci_cmd_t cmd)
     126{
     127        /* Poor man's xhci_cmd_init (everything else is zeroed) */
     128        link_initialize(&cmd._header.link);
     129        fibril_mutex_initialize(&cmd._header.completed_mtx);
     130        fibril_condvar_initialize(&cmd._header.completed_cv);
     131
     132        if (!cmd._header.timeout) {
     133                cmd._header.timeout = XHCI_DEFAULT_TIMEOUT;
     134        }
     135
     136        /* Issue the command */
     137        const int err = xhci_cmd_sync(hc, &cmd);
     138        xhci_cmd_fini(&cmd);
     139
     140        return err;
     141}
     142
     143/** The inline macro expects:
     144 *    - hc      - HC to schedule command on (xhci_hc_t *).
     145 *    - command - Member of `xhci_cmd_type_t` without the "XHCI_CMD_" prefix.
     146 *    - VA_ARGS - (optional) Command arguments in struct initialization notation.
     147 *
     148 *  The return code and semantics matches those of `xhci_cmd_sync_fini`.
     149 *
     150 *  Example:
     151 *    int err = xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = 42);
     152 */
     153
     154#define xhci_cmd_sync_inline(hc, command, ...) \
     155        xhci_cmd_sync_inline_wrapper(hc, \
     156        (xhci_cmd_t) { ._header.cmd = XHCI_CMD_##command, ##__VA_ARGS__ })
    100157
    101158#endif
Note: See TracChangeset for help on using the changeset viewer.