source: mainline/uspace/drv/bus/usb/ehci/ehci_bus.c

Last change on this file was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
3 * Copyright (c) 2018 Ondrej Hlavaty
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 drvusbehci
31 * @{
32 */
33/** @file
34 * @brief EHCI driver
35 */
36
37#include <assert.h>
38#include <stdlib.h>
39#include <usb/host/bandwidth.h>
40#include <usb/debug.h>
41
42#include "ehci_bus.h"
43#include "ehci_batch.h"
44#include "hc.h"
45
46/**
47 * Callback to set toggle on ED.
48 *
49 * @param[in] hcd_ep hcd endpoint structure
50 * @param[in] toggle new value of toggle bit
51 */
52void ehci_ep_toggle_reset(endpoint_t *ep)
53{
54 ehci_endpoint_t *instance = ehci_endpoint_get(ep);
55 if (qh_toggle_from_td(instance->qh))
56 usb_log_warning("EP(%p): Resetting toggle bit for transfer "
57 "directed EP", instance);
58 qh_toggle_set(instance->qh, 0);
59}
60
61static int ehci_device_enumerate(device_t *dev)
62{
63 ehci_bus_t *bus = (ehci_bus_t *) dev->bus;
64 return usb2_bus_device_enumerate(&bus->helper, dev);
65}
66
67static void ehci_device_gone(device_t *dev)
68{
69 ehci_bus_t *bus = (ehci_bus_t *) dev->bus;
70 usb2_bus_device_gone(&bus->helper, dev);
71}
72
73/** Creates new hcd endpoint representation.
74 */
75static endpoint_t *ehci_endpoint_create(device_t *dev,
76 const usb_endpoint_descriptors_t *desc)
77{
78 assert(dev);
79
80 ehci_endpoint_t *ehci_ep = malloc(sizeof(ehci_endpoint_t));
81 if (ehci_ep == NULL)
82 return NULL;
83
84 endpoint_init(&ehci_ep->base, dev, desc);
85
86 if (dma_buffer_alloc(&ehci_ep->dma_buffer, sizeof(qh_t)))
87 return NULL;
88
89 ehci_ep->qh = ehci_ep->dma_buffer.virt;
90
91 link_initialize(&ehci_ep->eplist_link);
92 link_initialize(&ehci_ep->pending_link);
93 return &ehci_ep->base;
94}
95
96/** Disposes hcd endpoint structure
97 *
98 * @param[in] hcd driver using this instance.
99 * @param[in] ep endpoint structure.
100 */
101static void ehci_endpoint_destroy(endpoint_t *ep)
102{
103 assert(ep);
104 ehci_endpoint_t *instance = ehci_endpoint_get(ep);
105
106 dma_buffer_free(&instance->dma_buffer);
107 free(instance);
108}
109
110static int ehci_register_ep(endpoint_t *ep)
111{
112 bus_t *bus_base = endpoint_get_bus(ep);
113 ehci_bus_t *bus = (ehci_bus_t *) bus_base;
114 ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
115
116 const int err = usb2_bus_endpoint_register(&bus->helper, ep);
117 if (err)
118 return err;
119
120 qh_init(ehci_ep->qh, ep);
121 hc_enqueue_endpoint(bus->hc, ep);
122 endpoint_set_online(ep, &bus->hc->guard);
123 return EOK;
124}
125
126static void ehci_unregister_ep(endpoint_t *ep)
127{
128 bus_t *bus_base = endpoint_get_bus(ep);
129 ehci_bus_t *bus = (ehci_bus_t *) bus_base;
130 hc_t *hc = bus->hc;
131 assert(bus);
132 assert(ep);
133
134 usb2_bus_endpoint_unregister(&bus->helper, ep);
135 hc_dequeue_endpoint(hc, ep);
136 /*
137 * Now we can be sure the active transfer will not be completed,
138 * as it's out of the schedule, and HC acknowledged it.
139 */
140
141 ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
142
143 fibril_mutex_lock(&hc->guard);
144 endpoint_set_offline_locked(ep);
145 list_remove(&ehci_ep->pending_link);
146 usb_transfer_batch_t *const batch = ep->active_batch;
147 endpoint_deactivate_locked(ep);
148 fibril_mutex_unlock(&hc->guard);
149
150 if (batch) {
151 batch->error = EINTR;
152 batch->transferred_size = 0;
153 usb_transfer_batch_finish(batch);
154 }
155}
156
157static usb_transfer_batch_t *ehci_create_batch(endpoint_t *ep)
158{
159 ehci_transfer_batch_t *batch = ehci_transfer_batch_create(ep);
160 return &batch->base;
161}
162
163static void ehci_destroy_batch(usb_transfer_batch_t *batch)
164{
165 ehci_transfer_batch_destroy(ehci_transfer_batch_get(batch));
166}
167
168static const bus_ops_t ehci_bus_ops = {
169 .interrupt = ehci_hc_interrupt,
170 .status = ehci_hc_status,
171
172 .device_enumerate = ehci_device_enumerate,
173 .device_gone = ehci_device_gone,
174
175 .endpoint_destroy = ehci_endpoint_destroy,
176 .endpoint_create = ehci_endpoint_create,
177 .endpoint_register = ehci_register_ep,
178 .endpoint_unregister = ehci_unregister_ep,
179
180 .batch_create = ehci_create_batch,
181 .batch_destroy = ehci_destroy_batch,
182 .batch_schedule = ehci_hc_schedule,
183};
184
185int ehci_bus_init(ehci_bus_t *bus, hc_t *hc)
186{
187 assert(hc);
188 assert(bus);
189
190 bus_t *bus_base = (bus_t *) bus;
191 bus_init(bus_base, sizeof(device_t));
192 bus_base->ops = &ehci_bus_ops;
193
194 usb2_bus_helper_init(&bus->helper, &bandwidth_accounting_usb2);
195
196 bus->hc = hc;
197
198 return EOK;
199}
200
201/**
202 * @}
203 */
Note: See TracBrowser for help on using the repository browser.