source: mainline/uspace/drv/ohci/batch.c@ e7bc999

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e7bc999 was 41b96b4, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

OHCI stub

  • Property mode set to 100644
File size: 10.7 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/** @addtogroup drvusbohcihc
29 * @{
30 */
31/** @file
32 * @brief OHCI driver USB transaction structure
33 */
34#include <errno.h>
35#include <str_error.h>
36
37#include <usb/usb.h>
38#include <usb/debug.h>
39
40#include "batch.h"
41
42static void batch_call_in(batch_t *instance);
43static void batch_call_out(batch_t *instance);
44static void batch_call_in_and_dispose(batch_t *instance);
45static void batch_call_out_and_dispose(batch_t *instance);
46
47/** Allocate memory and initialize internal data structure.
48 *
49 * @param[in] fun DDF function to pass to callback.
50 * @param[in] target Device and endpoint target of the transaction.
51 * @param[in] transfer_type Interrupt, Control or Bulk.
52 * @param[in] max_packet_size maximum allowed size of data packets.
53 * @param[in] speed Speed of the transaction.
54 * @param[in] buffer Data source/destination.
55 * @param[in] size Size of the buffer.
56 * @param[in] setup_buffer Setup data source (if not NULL)
57 * @param[in] setup_size Size of setup_buffer (should be always 8)
58 * @param[in] func_in function to call on inbound transaction completion
59 * @param[in] func_out function to call on outbound transaction completion
60 * @param[in] arg additional parameter to func_in or func_out
61 * @param[in] manager Pointer to toggle management structure.
62 * @return Valid pointer if all substructures were successfully created,
63 * NULL otherwise.
64 *
65 * Determines the number of needed packets (TDs). Prepares a transport buffer
66 * (that is accessible by the hardware). Initializes parameters needed for the
67 * transaction and callback.
68 */
69batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
70 usb_transfer_type_t transfer_type, size_t max_packet_size,
71 usb_speed_t speed, char *buffer, size_t size,
72 char* setup_buffer, size_t setup_size,
73 usbhc_iface_transfer_in_callback_t func_in,
74 usbhc_iface_transfer_out_callback_t func_out, void *arg
75 )
76{
77 assert(func_in == NULL || func_out == NULL);
78 assert(func_in != NULL || func_out != NULL);
79
80#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
81 if (ptr == NULL) { \
82 usb_log_error(message); \
83 if (instance) { \
84 batch_dispose(instance); \
85 } \
86 return NULL; \
87 } else (void)0
88
89 batch_t *instance = malloc(sizeof(batch_t));
90 CHECK_NULL_DISPOSE_RETURN(instance,
91 "Failed to allocate batch instance.\n");
92 bzero(instance, sizeof(batch_t));
93
94 if (size > 0) {
95 /* TODO: use device accessible malloc here */
96 instance->transport_buffer = malloc(size);
97 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
98 "Failed to allocate device accessible buffer.\n");
99 }
100
101 if (setup_size > 0) {
102 /* TODO: use device accessible malloc here */
103 instance->setup_buffer = malloc(setup_size);
104 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
105 "Failed to allocate device accessible setup buffer.\n");
106 memcpy(instance->setup_buffer, setup_buffer, setup_size);
107 }
108
109 link_initialize(&instance->link);
110
111 instance->max_packet_size = max_packet_size;
112 instance->target = target;
113 instance->transfer_type = transfer_type;
114 instance->buffer = buffer;
115 instance->buffer_size = size;
116 instance->setup_size = setup_size;
117 instance->fun = fun;
118 instance->arg = arg;
119 instance->speed = speed;
120 instance->callback_out = func_out;
121 instance->callback_in = func_in;
122
123 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
124 instance, target.address, target.endpoint);
125 return instance;
126}
127/*----------------------------------------------------------------------------*/
128/** Mark batch as finished and continue with next step.
129 *
130 * @param[in] instance Batch structure to use.
131 *
132 */
133void batch_finish(batch_t *instance, int error)
134{
135 assert(instance);
136 instance->error = error;
137 instance->next_step(instance);
138}
139/*----------------------------------------------------------------------------*/
140/** Check batch TDs for activity.
141 *
142 * @param[in] instance Batch structure to use.
143 * @return False, if there is an active TD, true otherwise.
144 *
145 * Walk all TDs. Stop with false if there is an active one (it is to be
146 * processed). Stop with true if an error is found. Return true if the last TS
147 * is reached.
148 */
149bool batch_is_complete(batch_t *instance)
150{
151 assert(instance);
152 /* TODO: implement */
153 return true;
154}
155/*----------------------------------------------------------------------------*/
156/** Prepares control write transaction.
157 *
158 * @param[in] instance Batch structure to use.
159 *
160 * Uses genercir control function with pids OUT and IN.
161 */
162void batch_control_write(batch_t *instance)
163{
164 assert(instance);
165 /* We are data out, we are supposed to provide data */
166 memcpy(instance->transport_buffer, instance->buffer,
167 instance->buffer_size);
168 instance->next_step = batch_call_out_and_dispose;
169 /* TODO: implement */
170 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
171}
172/*----------------------------------------------------------------------------*/
173/** Prepares control read transaction.
174 *
175 * @param[in] instance Batch structure to use.
176 *
177 * Uses generic control with pids IN and OUT.
178 */
179void batch_control_read(batch_t *instance)
180{
181 assert(instance);
182 instance->next_step = batch_call_in_and_dispose;
183 /* TODO: implement */
184 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
185}
186/*----------------------------------------------------------------------------*/
187/** Prepare interrupt in transaction.
188 *
189 * @param[in] instance Batch structure to use.
190 *
191 * Data transaction with PID_IN.
192 */
193void batch_interrupt_in(batch_t *instance)
194{
195 assert(instance);
196 /* TODO: implement */
197 instance->next_step = batch_call_in_and_dispose;
198 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
199}
200/*----------------------------------------------------------------------------*/
201/** Prepare interrupt out transaction.
202 *
203 * @param[in] instance Batch structure to use.
204 *
205 * Data transaction with PID_OUT.
206 */
207void batch_interrupt_out(batch_t *instance)
208{
209 assert(instance);
210 /* We are data out, we are supposed to provide data */
211 memcpy(instance->transport_buffer, instance->buffer,
212 instance->buffer_size);
213 instance->next_step = batch_call_out_and_dispose;
214 /* TODO: implement */
215 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
216}
217/*----------------------------------------------------------------------------*/
218/** Prepare bulk in transaction.
219 *
220 * @param[in] instance Batch structure to use.
221 *
222 * Data transaction with PID_IN.
223 */
224void batch_bulk_in(batch_t *instance)
225{
226 assert(instance);
227 instance->next_step = batch_call_in_and_dispose;
228 /* TODO: implement */
229 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
230}
231/*----------------------------------------------------------------------------*/
232/** Prepare bulk out transaction.
233 *
234 * @param[in] instance Batch structure to use.
235 *
236 * Data transaction with PID_OUT.
237 */
238void batch_bulk_out(batch_t *instance)
239{
240 assert(instance);
241 /* We are data out, we are supposed to provide data */
242 memcpy(instance->transport_buffer, instance->buffer,
243 instance->buffer_size);
244 instance->next_step = batch_call_out_and_dispose;
245 /* TODO: implement */
246 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
247}
248/*----------------------------------------------------------------------------*/
249/** Prepare data, get error status and call callback in.
250 *
251 * @param[in] instance Batch structure to use.
252 * Copies data from transport buffer, and calls callback with appropriate
253 * parameters.
254 */
255void batch_call_in(batch_t *instance)
256{
257 assert(instance);
258 assert(instance->callback_in);
259
260 /* We are data in, we need data */
261 memcpy(instance->buffer, instance->transport_buffer,
262 instance->buffer_size);
263
264 int err = instance->error;
265 usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
266 instance, instance->transfer_type, str_error(err), err,
267 instance->transfered_size);
268
269 instance->callback_in(
270 instance->fun, err, instance->transfered_size, instance->arg);
271}
272/*----------------------------------------------------------------------------*/
273/** Get error status and call callback out.
274 *
275 * @param[in] instance Batch structure to use.
276 */
277void batch_call_out(batch_t *instance)
278{
279 assert(instance);
280 assert(instance->callback_out);
281
282 int err = instance->error;
283 usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n",
284 instance, instance->transfer_type, str_error(err), err);
285 instance->callback_out(instance->fun,
286 err, instance->arg);
287}
288/*----------------------------------------------------------------------------*/
289/** Helper function calls callback and correctly disposes of batch structure.
290 *
291 * @param[in] instance Batch structure to use.
292 */
293void batch_call_in_and_dispose(batch_t *instance)
294{
295 assert(instance);
296 batch_call_in(instance);
297 batch_dispose(instance);
298}
299/*----------------------------------------------------------------------------*/
300/** Helper function calls callback and correctly disposes of batch structure.
301 *
302 * @param[in] instance Batch structure to use.
303 */
304void batch_call_out_and_dispose(batch_t *instance)
305{
306 assert(instance);
307 batch_call_out(instance);
308 batch_dispose(instance);
309}
310/*----------------------------------------------------------------------------*/
311/** Correctly dispose all used data structures.
312 *
313 * @param[in] instance Batch structure to use.
314 */
315void batch_dispose(batch_t *instance)
316{
317 assert(instance);
318 usb_log_debug("Batch(%p) disposing.\n", instance);
319 if (instance->setup_buffer)
320 free(instance->setup_buffer);
321 if (instance->transport_buffer)
322 free(instance->transport_buffer);
323 free(instance);
324}
325/**
326 * @}
327 */
Note: See TracBrowser for help on using the repository browser.