source: mainline/uspace/drv/bus/usb/ohci/ohci_bus.c@ bf0398c

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

usb2_bus: no longer be a bus

As the number of implemented functions got to 3, it's not so beneficial
to inherit usb2 bus to get the functionality. Overall, four trampolines
needed to be added, which is an acceptable number.

Now, the usb2_bus has become a usb2_bus_helper, to be used as
a companion to the common bus.

This is mostly a preparation to remove the runtime binding of the bus
methods.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
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 drvusbohci
30 * @{
31 */
32/** @file
33 * @brief OHCI driver
34 */
35
36#include <assert.h>
37#include <stdlib.h>
38#include <usb/host/utils/malloc32.h>
39#include <usb/host/bandwidth.h>
40
41#include "ohci_bus.h"
42#include "ohci_batch.h"
43#include "hc.h"
44
45/**
46 * Callback to reset toggle on ED.
47 *
48 * @param[in] hcd_ep hcd endpoint structure
49 * @param[in] toggle new value of toggle bit
50 */
51void ohci_ep_toggle_reset(endpoint_t *ep)
52{
53 ohci_endpoint_t *instance = ohci_endpoint_get(ep);
54 assert(instance);
55 assert(instance->ed);
56 ed_toggle_set(instance->ed, 0);
57}
58
59static int ohci_device_enumerate(device_t *dev)
60{
61 ohci_bus_t *bus = (ohci_bus_t *) dev->bus;
62 return usb2_bus_device_enumerate(&bus->helper, dev);
63}
64
65/** Creates new hcd endpoint representation.
66 */
67static endpoint_t *ohci_endpoint_create(device_t *dev, const usb_endpoint_descriptors_t *desc)
68{
69 assert(dev);
70
71 ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t));
72 if (ohci_ep == NULL)
73 return NULL;
74
75 endpoint_init(&ohci_ep->base, dev, desc);
76
77 ohci_ep->ed = malloc32(sizeof(ed_t));
78 if (ohci_ep->ed == NULL) {
79 free(ohci_ep);
80 return NULL;
81 }
82
83 ohci_ep->td = malloc32(sizeof(td_t));
84 if (ohci_ep->td == NULL) {
85 free32(ohci_ep->ed);
86 free(ohci_ep);
87 return NULL;
88 }
89
90 link_initialize(&ohci_ep->eplist_link);
91 link_initialize(&ohci_ep->pending_link);
92 return &ohci_ep->base;
93}
94
95/** Disposes hcd endpoint structure
96 *
97 * @param[in] hcd driver using this instance.
98 * @param[in] ep endpoint structure.
99 */
100static void ohci_endpoint_destroy(endpoint_t *ep)
101{
102 assert(ep);
103 ohci_endpoint_t *instance = ohci_endpoint_get(ep);
104
105 free32(instance->ed);
106 free32(instance->td);
107 free(instance);
108}
109
110
111static int ohci_register_ep(endpoint_t *ep)
112{
113 bus_t *bus_base = endpoint_get_bus(ep);
114 ohci_bus_t *bus = (ohci_bus_t *) bus_base;
115 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
116
117 const int err = usb2_bus_endpoint_register(&bus->helper, ep);
118 if (err)
119 return err;
120
121 ed_init(ohci_ep->ed, ep, ohci_ep->td);
122 hc_enqueue_endpoint(bus->hc, ep);
123 endpoint_set_online(ep, &bus->hc->guard);
124
125 return EOK;
126}
127
128static void ohci_unregister_ep(endpoint_t *ep)
129{
130 ohci_bus_t * const bus = (ohci_bus_t *) endpoint_get_bus(ep);
131 hc_t * const hc = bus->hc;
132 assert(ep);
133
134 usb2_bus_endpoint_unregister(&bus->helper, ep);
135 hc_dequeue_endpoint(bus->hc, ep);
136
137 /*
138 * Now we can be sure the active transfer will not be completed,
139 * as it's out of the schedule, and HC acknowledged it.
140 */
141
142 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
143
144 fibril_mutex_lock(&hc->guard);
145 endpoint_set_offline_locked(ep);
146 list_remove(&ohci_ep->pending_link);
147 usb_transfer_batch_t * const batch = ep->active_batch;
148 endpoint_deactivate_locked(ep);
149 fibril_mutex_unlock(&hc->guard);
150
151 if (batch) {
152 batch->error = EINTR;
153 batch->transferred_size = 0;
154 usb_transfer_batch_finish(batch);
155 }
156}
157
158static usb_transfer_batch_t *ohci_create_batch(endpoint_t *ep)
159{
160 ohci_transfer_batch_t *batch = ohci_transfer_batch_create(ep);
161 return &batch->base;
162}
163
164static void ohci_destroy_batch(usb_transfer_batch_t *batch)
165{
166 ohci_transfer_batch_destroy(ohci_transfer_batch_get(batch));
167}
168
169static const bus_ops_t ohci_bus_ops = {
170 .interrupt = ohci_hc_interrupt,
171 .status = ohci_hc_status,
172
173 .device_enumerate = ohci_device_enumerate,
174
175 .endpoint_destroy = ohci_endpoint_destroy,
176 .endpoint_create = ohci_endpoint_create,
177 .endpoint_register = ohci_register_ep,
178 .endpoint_unregister = ohci_unregister_ep,
179
180 .batch_create = ohci_create_batch,
181 .batch_destroy = ohci_destroy_batch,
182 .batch_schedule = ohci_hc_schedule,
183};
184
185
186int ohci_bus_init(ohci_bus_t *bus, hc_t *hc)
187{
188 assert(hc);
189 assert(bus);
190
191 bus_t *bus_base = (bus_t *) bus;
192 bus_init(bus_base, sizeof(device_t));
193 bus_base->ops = &ohci_bus_ops;
194
195 usb2_bus_helper_init(&bus->helper, &bandwidth_accounting_usb11);
196
197 bus->hc = hc;
198
199 return EOK;
200}
201
202/**
203 * @}
204 */
Note: See TracBrowser for help on using the repository browser.