Changes in uspace/drv/ohci/batch.c [41b96b4:1387692] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r41b96b4 r1387692 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbohci hc28 /** @addtogroup drvusbohci 29 29 * @{ 30 30 */ … … 39 39 40 40 #include "batch.h" 41 #include "utils/malloc32.h" 41 42 42 static void batch_call_in(batch_t *instance); 43 static void batch_call_out(batch_t *instance); 44 static void batch_call_in_and_dispose(batch_t *instance); 45 static void batch_call_out_and_dispose(batch_t *instance); 43 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance); 44 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance); 46 45 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 */ 69 batch_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, 46 #define DEFAULT_ERROR_COUNT 3 47 usb_transfer_batch_t * batch_get( 48 ddf_fun_t *fun, 49 usb_target_t target, 50 usb_transfer_type_t transfer_type, 51 size_t max_packet_size, 52 usb_speed_t speed, 53 char *buffer, 54 size_t buffer_size, 55 char *setup_buffer, 56 size_t setup_size, 73 57 usbhc_iface_transfer_in_callback_t func_in, 74 usbhc_iface_transfer_out_callback_t func_out, void *arg 75 ) 58 usbhc_iface_transfer_out_callback_t func_out, 59 void *arg, 60 usb_device_keeper_t *manager 61 ) 76 62 { 77 assert(func_in == NULL || func_out == NULL); 78 assert(func_in != NULL || func_out != NULL); 63 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ 64 if (ptr == NULL) { \ 65 usb_log_error(message); \ 66 if (instance) { \ 67 batch_dispose(instance); \ 68 } \ 69 return NULL; \ 70 } else (void)0 79 71 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)); 72 usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t)); 90 73 CHECK_NULL_DISPOSE_RETURN(instance, 91 74 "Failed to allocate batch instance.\n"); 92 bzero(instance, sizeof(batch_t)); 75 usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size, 76 buffer, NULL, buffer_size, NULL, setup_size, func_in, 77 func_out, arg, fun, NULL); 93 78 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 } 79 if (buffer_size > 0) { 80 instance->transport_buffer = malloc32(buffer_size); 81 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer, 82 "Failed to allocate device accessible buffer.\n"); 83 } 100 84 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 } 85 if (setup_size > 0) { 86 instance->setup_buffer = malloc32(setup_size); 87 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer, 88 "Failed to allocate device accessible setup buffer.\n"); 89 memcpy(instance->setup_buffer, setup_buffer, setup_size); 90 } 108 91 109 link_initialize(&instance->link);110 92 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 93 return instance; 126 94 } 127 95 /*----------------------------------------------------------------------------*/ 128 /** Mark batch as finished and continue with next step. 129 * 130 * @param[in] instance Batch structure to use. 131 * 132 */ 133 void batch_finish(batch_t *instance, int error) 96 void batch_dispose(usb_transfer_batch_t *instance) 134 97 { 135 98 assert(instance); 136 instance->error = error; 137 instance->next_step(instance); 99 free32(instance->transport_buffer); 100 free32(instance->setup_buffer); 101 free(instance); 138 102 } 139 103 /*----------------------------------------------------------------------------*/ 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 */ 149 bool 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 */ 162 void batch_control_write(batch_t *instance) 104 void batch_control_write(usb_transfer_batch_t *instance) 163 105 { 164 106 assert(instance); … … 171 113 } 172 114 /*----------------------------------------------------------------------------*/ 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 */ 179 void batch_control_read(batch_t *instance) 115 void batch_control_read(usb_transfer_batch_t *instance) 180 116 { 181 117 assert(instance); 182 118 instance->next_step = batch_call_in_and_dispose; 183 119 /* TODO: implement */ 184 usb_log_debug("Batch(%p) CONTROL READinitialized.\n", instance);120 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 185 121 } 186 122 /*----------------------------------------------------------------------------*/ 187 /** Prepare interrupt in transaction. 188 * 189 * @param[in] instance Batch structure to use. 190 * 191 * Data transaction with PID_IN. 192 */ 193 void batch_interrupt_in(batch_t *instance) 123 void batch_interrupt_in(usb_transfer_batch_t *instance) 194 124 { 195 125 assert(instance); 126 instance->direction = USB_DIRECTION_IN; 127 instance->next_step = batch_call_in_and_dispose; 196 128 /* TODO: implement */ 197 instance->next_step = batch_call_in_and_dispose;198 129 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 199 130 } 200 131 /*----------------------------------------------------------------------------*/ 201 /** Prepare interrupt out transaction. 202 * 203 * @param[in] instance Batch structure to use. 204 * 205 * Data transaction with PID_OUT. 206 */ 207 void batch_interrupt_out(batch_t *instance) 132 void batch_interrupt_out(usb_transfer_batch_t *instance) 208 133 { 209 134 assert(instance); 135 instance->direction = USB_DIRECTION_OUT; 210 136 /* We are data out, we are supposed to provide data */ 211 137 memcpy(instance->transport_buffer, instance->buffer, … … 216 142 } 217 143 /*----------------------------------------------------------------------------*/ 218 /** Prepare bulk in transaction. 219 * 220 * @param[in] instance Batch structure to use. 221 * 222 * Data transaction with PID_IN. 223 */ 224 void batch_bulk_in(batch_t *instance) 144 void batch_bulk_in(usb_transfer_batch_t *instance) 225 145 { 226 146 assert(instance); 147 instance->direction = USB_DIRECTION_IN; 227 148 instance->next_step = batch_call_in_and_dispose; 228 149 /* TODO: implement */ … … 230 151 } 231 152 /*----------------------------------------------------------------------------*/ 232 /** Prepare bulk out transaction. 233 * 234 * @param[in] instance Batch structure to use. 235 * 236 * Data transaction with PID_OUT. 237 */ 238 void batch_bulk_out(batch_t *instance) 153 void batch_bulk_out(usb_transfer_batch_t *instance) 239 154 { 240 155 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; 156 instance->direction = USB_DIRECTION_IN; 157 instance->next_step = batch_call_in_and_dispose; 245 158 /* 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 */ 255 void 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 */ 277 void 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); 159 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 287 160 } 288 161 /*----------------------------------------------------------------------------*/ … … 291 164 * @param[in] instance Batch structure to use. 292 165 */ 293 void batch_call_in_and_dispose( batch_t *instance)166 void batch_call_in_and_dispose(usb_transfer_batch_t *instance) 294 167 { 295 168 assert(instance); 296 batch_call_in(instance);169 usb_transfer_batch_call_in(instance); 297 170 batch_dispose(instance); 298 171 } … … 302 175 * @param[in] instance Batch structure to use. 303 176 */ 304 void batch_call_out_and_dispose( batch_t *instance)177 void batch_call_out_and_dispose(usb_transfer_batch_t *instance) 305 178 { 306 179 assert(instance); 307 batch_call_out(instance);180 usb_transfer_batch_call_out(instance); 308 181 batch_dispose(instance); 309 }310 /*----------------------------------------------------------------------------*/311 /** Correctly dispose all used data structures.312 *313 * @param[in] instance Batch structure to use.314 */315 void 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 182 } 325 183 /**
Note:
See TracChangeset
for help on using the changeset viewer.