source: mainline/uspace/lib/usbhost/src/endpoint.c@ 479e32d

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

usbhost endpoint: endpoint→active replaced by tracking active batch

The mechanism is optional, synchronization over endpoint is now not forced. It will be used by xhci to utilize streams.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
3 * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libusbhost
31 * @{
32 */
33/** @file
34 * @brief UHCI host controller driver structure
35 */
36
37#include <usb/host/endpoint.h>
38#include <usb/host/usb_transfer_batch.h>
39#include <usb/host/bus.h>
40
41#include <assert.h>
42#include <atomic.h>
43#include <mem.h>
44#include <stdlib.h>
45
46/** Initialize provided endpoint structure.
47 */
48void endpoint_init(endpoint_t *ep, bus_t *bus)
49{
50 memset(ep, 0, sizeof(endpoint_t));
51
52 ep->bus = bus;
53 atomic_set(&ep->refcnt, 0);
54 link_initialize(&ep->link);
55 fibril_mutex_initialize(&ep->guard);
56 fibril_condvar_initialize(&ep->avail);
57}
58
59void endpoint_add_ref(endpoint_t *ep)
60{
61 atomic_inc(&ep->refcnt);
62}
63
64void endpoint_del_ref(endpoint_t *ep)
65{
66 if (atomic_predec(&ep->refcnt) == 0) {
67 if (ep->bus->ops.destroy_endpoint) {
68 ep->bus->ops.destroy_endpoint(ep);
69 }
70 else {
71 assert(ep->active_batch == NULL);
72
73 /* Assume mostly the eps will be allocated by malloc. */
74 free(ep);
75 }
76 }
77}
78
79/** Mark the endpoint as active and block access for further fibrils.
80 * @param ep endpoint_t structure.
81 */
82void endpoint_activate_locked(endpoint_t *ep, usb_transfer_batch_t *batch)
83{
84 assert(ep);
85 assert(batch);
86 assert(batch->ep == ep);
87 assert(fibril_mutex_is_locked(&ep->guard));
88
89 while (ep->active_batch != NULL)
90 fibril_condvar_wait(&ep->avail, &ep->guard);
91 ep->active_batch = batch;
92}
93
94/** Mark the endpoint as inactive and allow access for further fibrils.
95 * @param ep endpoint_t structure.
96 */
97void endpoint_deactivate_locked(endpoint_t *ep)
98{
99 assert(ep);
100 assert(fibril_mutex_is_locked(&ep->guard));
101
102 if (ep->active_batch && ep->active_batch->error == EOK)
103 usb_transfer_batch_reset_toggle(ep->active_batch);
104
105 ep->active_batch = NULL;
106 fibril_condvar_signal(&ep->avail);
107}
108
109/** Abort an active batch on endpoint, if any.
110 *
111 * @param[in] ep endpoint_t structure.
112 */
113void endpoint_abort(endpoint_t *ep)
114{
115 assert(ep);
116
117 fibril_mutex_lock(&ep->guard);
118 usb_transfer_batch_t *batch = ep->active_batch;
119 endpoint_deactivate_locked(ep);
120 fibril_mutex_unlock(&ep->guard);
121
122 if (batch)
123 usb_transfer_batch_abort(batch);
124}
125
126/** Get the value of toggle bit. Either uses the toggle_get op, or just returns
127 * the value of the toggle.
128 * @param ep endpoint_t structure.
129 */
130int endpoint_toggle_get(endpoint_t *ep)
131{
132 assert(ep);
133
134 return ep->bus->ops.endpoint_get_toggle
135 ? ep->bus->ops.endpoint_get_toggle(ep)
136 : ep->toggle;
137}
138
139/** Set the value of toggle bit. Either uses the toggle_set op, or just sets
140 * the toggle inside.
141 * @param ep endpoint_t structure.
142 */
143void endpoint_toggle_set(endpoint_t *ep, bool toggle)
144{
145 assert(ep);
146
147 if (ep->bus->ops.endpoint_set_toggle) {
148 ep->bus->ops.endpoint_set_toggle(ep, toggle);
149 }
150 else {
151 ep->toggle = toggle;
152 }
153}
154
155
156/**
157 * @}
158 */
Note: See TracBrowser for help on using the repository browser.