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

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

Implement TD initialization

  • Property mode set to 100644
File size: 8.1 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 drvusbohci
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#include "utils/malloc32.h"
42#include "hw_struct/endpoint_descriptor.h"
43#include "hw_struct/transfer_descriptor.h"
44
45typedef struct ohci_batch {
46 ed_t *ed;
47 td_t *tds;
48 size_t td_count;
49} ohci_batch_t;
50
51static void batch_control(usb_transfer_batch_t *instance);
52static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
53static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
54
55#define DEFAULT_ERROR_COUNT 3
56usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
57 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
58 usbhc_iface_transfer_in_callback_t func_in,
59 usbhc_iface_transfer_out_callback_t func_out, void *arg)
60{
61#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
62 if (ptr == NULL) { \
63 usb_log_error(message); \
64 if (instance) { \
65 batch_dispose(instance); \
66 } \
67 return NULL; \
68 } else (void)0
69
70 usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
71 CHECK_NULL_DISPOSE_RETURN(instance,
72 "Failed to allocate batch instance.\n");
73 usb_target_t target =
74 { .address = ep->address, .endpoint = ep->endpoint };
75 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
76 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
77 func_in, func_out, arg, fun, ep, NULL);
78
79 ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
80 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
81 bzero(data, sizeof(ohci_batch_t));
82 instance->private_data = data;
83
84 /* we needs + 1 transfer descriptor as the last one won't be executed */
85 data->td_count = 1 +
86 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
87 if (ep->transfer_type == USB_TRANSFER_CONTROL) {
88 data->td_count += 2;
89 }
90
91 data->tds = malloc32(sizeof(td_t) * data->td_count);
92 CHECK_NULL_DISPOSE_RETURN(data->tds,
93 "Failed to allocate transfer descriptors.\n");
94 bzero(data->tds, sizeof(td_t) * data->td_count);
95
96 data->ed = malloc32(sizeof(ed_t));
97 CHECK_NULL_DISPOSE_RETURN(data->ed,
98 "Failed to allocate endpoint descriptor.\n");
99
100 if (buffer_size > 0) {
101 instance->transport_buffer = malloc32(buffer_size);
102 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
103 "Failed to allocate device accessible buffer.\n");
104 }
105
106 if (setup_size > 0) {
107 instance->setup_buffer = malloc32(setup_size);
108 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
109 "Failed to allocate device accessible setup buffer.\n");
110 memcpy(instance->setup_buffer, setup_buffer, setup_size);
111 }
112
113 return instance;
114}
115/*----------------------------------------------------------------------------*/
116void batch_dispose(usb_transfer_batch_t *instance)
117{
118 assert(instance);
119 free32(instance->transport_buffer);
120 free32(instance->setup_buffer);
121 free(instance);
122}
123/*----------------------------------------------------------------------------*/
124bool batch_is_complete(usb_transfer_batch_t *instance)
125{
126 // TODO: implement
127 return false;
128}
129/*----------------------------------------------------------------------------*/
130void batch_control_write(usb_transfer_batch_t *instance)
131{
132 assert(instance);
133 /* We are data out, we are supposed to provide data */
134 memcpy(instance->transport_buffer, instance->buffer,
135 instance->buffer_size);
136 instance->next_step = batch_call_out_and_dispose;
137 batch_control(instance);
138 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
139}
140/*----------------------------------------------------------------------------*/
141void batch_control_read(usb_transfer_batch_t *instance)
142{
143 assert(instance);
144 instance->next_step = batch_call_in_and_dispose;
145 batch_control(instance);
146 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
147}
148/*----------------------------------------------------------------------------*/
149void batch_interrupt_in(usb_transfer_batch_t *instance)
150{
151 assert(instance);
152 assert(instance->direction == USB_DIRECTION_IN);
153 instance->next_step = batch_call_in_and_dispose;
154 /* TODO: implement */
155 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
156}
157/*----------------------------------------------------------------------------*/
158void batch_interrupt_out(usb_transfer_batch_t *instance)
159{
160 assert(instance);
161 assert(instance->direction == USB_DIRECTION_OUT);
162 /* We are data out, we are supposed to provide data */
163 memcpy(instance->transport_buffer, instance->buffer,
164 instance->buffer_size);
165 instance->next_step = batch_call_out_and_dispose;
166 /* TODO: implement */
167 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
168}
169/*----------------------------------------------------------------------------*/
170void batch_bulk_in(usb_transfer_batch_t *instance)
171{
172 assert(instance);
173 instance->direction = USB_DIRECTION_IN;
174 instance->next_step = batch_call_in_and_dispose;
175 /* TODO: implement */
176 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
177}
178/*----------------------------------------------------------------------------*/
179void batch_bulk_out(usb_transfer_batch_t *instance)
180{
181 assert(instance);
182 instance->direction = USB_DIRECTION_IN;
183 instance->next_step = batch_call_in_and_dispose;
184 /* TODO: implement */
185 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
186}
187/*----------------------------------------------------------------------------*/
188ed_t * batch_ed(usb_transfer_batch_t *instance)
189{
190 assert(instance);
191 ohci_batch_t *data = instance->private_data;
192 assert(data);
193 return data->ed;
194}
195/*----------------------------------------------------------------------------*/
196static void batch_control(usb_transfer_batch_t *instance)
197{
198 assert(instance);
199 ohci_batch_t *data = instance->private_data;
200 assert(data);
201 ed_init(data->ed, instance->ep);
202}
203/*----------------------------------------------------------------------------*/
204/** Helper function calls callback and correctly disposes of batch structure.
205 *
206 * @param[in] instance Batch structure to use.
207 */
208void batch_call_in_and_dispose(usb_transfer_batch_t *instance)
209{
210 assert(instance);
211 usb_transfer_batch_call_in(instance);
212 batch_dispose(instance);
213}
214/*----------------------------------------------------------------------------*/
215/** Helper function calls callback and correctly disposes of batch structure.
216 *
217 * @param[in] instance Batch structure to use.
218 */
219void batch_call_out_and_dispose(usb_transfer_batch_t *instance)
220{
221 assert(instance);
222 usb_transfer_batch_call_out(instance);
223 batch_dispose(instance);
224}
225/**
226 * @}
227 */
Note: See TracBrowser for help on using the repository browser.