Changeset 2cc6e97 in mainline for uspace/drv/uhci-hcd/batch.c
- Timestamp:
- 2011-04-12T14:07:02Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3d932af6
- Parents:
- 910ca3f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
r910ca3f r2cc6e97 45 45 #define DEFAULT_ERROR_COUNT 3 46 46 47 typedef struct uhci_ batch {47 typedef struct uhci_transfer_batch { 48 48 qh_t *qh; 49 49 td_t *tds; 50 void *device_buffer; 50 51 size_t td_count; 51 } uhci_batch_t; 52 } uhci_transfer_batch_t; 53 /*----------------------------------------------------------------------------*/ 54 static void uhci_transfer_batch_dispose(void *uhci_batch) 55 { 56 uhci_transfer_batch_t *instance = uhci_batch; 57 assert(instance); 58 free32(instance->device_buffer); 59 free(instance); 60 } 61 /*----------------------------------------------------------------------------*/ 52 62 53 63 static void batch_control(usb_transfer_batch_t *instance, 54 64 usb_packet_id data_stage, usb_packet_id status_stage); 55 65 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid); 56 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);57 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);58 59 66 60 67 /** Allocate memory and initialize internal data structure. … … 88 95 if (ptr == NULL) { \ 89 96 usb_log_error(message); \ 90 if ( instance) { \91 batch_dispose(instance); \97 if (uhci_data) { \ 98 uhci_transfer_batch_dispose(uhci_data); \ 92 99 } \ 93 100 return NULL; \ 94 101 } else (void)0 95 102 103 uhci_transfer_batch_t *uhci_data = 104 malloc(sizeof(uhci_transfer_batch_t)); 105 CHECK_NULL_DISPOSE_RETURN(uhci_data, 106 "Failed to allocate UHCI batch.\n"); 107 bzero(uhci_data, sizeof(uhci_transfer_batch_t)); 108 109 uhci_data->td_count = 110 (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size; 111 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 112 uhci_data->td_count += 2; 113 } 114 115 assert((sizeof(td_t) % 16) == 0); 116 const size_t total_size = (sizeof(td_t) * uhci_data->td_count) 117 + sizeof(qh_t) + setup_size + buffer_size; 118 uhci_data->device_buffer = malloc32(total_size); 119 CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer, 120 "Failed to allocate UHCI buffer.\n"); 121 bzero(uhci_data->device_buffer, total_size); 122 123 uhci_data->tds = uhci_data->device_buffer; 124 uhci_data->qh = 125 (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)); 126 127 qh_init(uhci_data->qh); 128 qh_set_element_td(uhci_data->qh, addr_to_phys(uhci_data->tds)); 129 96 130 usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t)); 97 131 CHECK_NULL_DISPOSE_RETURN(instance, 98 132 "Failed to allocate batch instance.\n"); 133 void *setup = 134 uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count) 135 + sizeof(qh_t); 136 void *data_buffer = setup + setup_size; 99 137 usb_target_t target = 100 138 { .address = ep->address, .endpoint = ep->endpoint }; 101 usb_transfer_batch_init(instance, ep, 102 buffer, NULL, buffer_size, NULL, setup_size, 103 func_in, func_out, arg, fun, NULL); 104 105 106 uhci_batch_t *data = malloc(sizeof(uhci_batch_t)); 107 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n"); 108 bzero(data, sizeof(uhci_batch_t)); 109 instance->private_data = data; 110 111 data->td_count = 112 (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size; 113 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 114 data->td_count += 2; 115 } 116 117 data->tds = malloc32(sizeof(td_t) * data->td_count); 118 CHECK_NULL_DISPOSE_RETURN( 119 data->tds, "Failed to allocate transfer descriptors.\n"); 120 bzero(data->tds, sizeof(td_t) * data->td_count); 121 122 data->qh = malloc32(sizeof(qh_t)); 123 CHECK_NULL_DISPOSE_RETURN(data->qh, 124 "Failed to allocate batch queue head.\n"); 125 qh_init(data->qh); 126 qh_set_element_td(data->qh, addr_to_phys(data->tds)); 127 128 if (buffer_size > 0) { 129 instance->data_buffer = malloc32(buffer_size); 130 CHECK_NULL_DISPOSE_RETURN(instance->data_buffer, 131 "Failed to allocate device accessible buffer.\n"); 132 } 133 134 if (setup_size > 0) { 135 instance->setup_buffer = malloc32(setup_size); 136 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer, 137 "Failed to allocate device accessible setup buffer.\n"); 138 memcpy(instance->setup_buffer, setup_buffer, setup_size); 139 } 140 139 usb_transfer_batch_init(instance, ep, buffer, data_buffer, buffer_size, 140 setup, setup_size, func_in, func_out, arg, fun, 141 uhci_data, uhci_transfer_batch_dispose); 142 143 memcpy(instance->setup_buffer, setup_buffer, setup_size); 141 144 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n", 142 145 instance, target.address, target.endpoint); … … 156 159 { 157 160 assert(instance); 158 uhci_ batch_t *data = instance->private_data;161 uhci_transfer_batch_t *data = instance->private_data; 159 162 assert(data); 160 163 … … 203 206 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 204 207 batch_control(instance, USB_PID_OUT, USB_PID_IN); 205 instance->next_step = batch_call_out_and_dispose;208 instance->next_step = usb_transfer_batch_call_out_and_dispose; 206 209 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 207 210 } … … 217 220 assert(instance); 218 221 batch_control(instance, USB_PID_IN, USB_PID_OUT); 219 instance->next_step = batch_call_in_and_dispose;222 instance->next_step = usb_transfer_batch_call_in_and_dispose; 220 223 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 221 224 } … … 231 234 assert(instance); 232 235 batch_data(instance, USB_PID_IN); 233 instance->next_step = batch_call_in_and_dispose;236 instance->next_step = usb_transfer_batch_call_in_and_dispose; 234 237 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 235 238 } … … 247 250 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 248 251 batch_data(instance, USB_PID_OUT); 249 instance->next_step = batch_call_out_and_dispose;252 instance->next_step = usb_transfer_batch_call_out_and_dispose; 250 253 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 251 254 } … … 261 264 assert(instance); 262 265 batch_data(instance, USB_PID_IN); 263 instance->next_step = batch_call_in_and_dispose;266 instance->next_step = usb_transfer_batch_call_in_and_dispose; 264 267 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 265 268 } … … 277 280 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 278 281 batch_data(instance, USB_PID_OUT); 279 instance->next_step = batch_call_out_and_dispose;282 instance->next_step = usb_transfer_batch_call_out_and_dispose; 280 283 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 281 284 } … … 292 295 { 293 296 assert(instance); 294 uhci_ batch_t *data = instance->private_data;297 uhci_transfer_batch_t *data = instance->private_data; 295 298 assert(data); 296 299 … … 344 347 { 345 348 assert(instance); 346 uhci_ batch_t *data = instance->private_data;349 uhci_transfer_batch_t *data = instance->private_data; 347 350 assert(data); 348 351 assert(data->td_count >= 2); … … 396 399 { 397 400 assert(instance); 398 uhci_ batch_t *data = instance->private_data;401 uhci_transfer_batch_t *data = instance->private_data; 399 402 assert(data); 400 403 return data->qh; 401 404 } 402 /*----------------------------------------------------------------------------*/403 /** Helper function, calls callback and correctly destroys batch structure.404 *405 * @param[in] instance Batch structure to use.406 */407 void batch_call_in_and_dispose(usb_transfer_batch_t *instance)408 {409 assert(instance);410 usb_transfer_batch_call_in(instance);411 batch_dispose(instance);412 }413 /*----------------------------------------------------------------------------*/414 /** Helper function calls callback and correctly destroys batch structure.415 *416 * @param[in] instance Batch structure to use.417 */418 void batch_call_out_and_dispose(usb_transfer_batch_t *instance)419 {420 assert(instance);421 usb_transfer_batch_call_out(instance);422 batch_dispose(instance);423 }424 /*----------------------------------------------------------------------------*/425 /** Correctly dispose all used data structures.426 *427 * @param[in] instance Batch structure to use.428 */429 void batch_dispose(usb_transfer_batch_t *instance)430 {431 assert(instance);432 uhci_batch_t *data = instance->private_data;433 assert(data);434 usb_log_debug("Batch(%p) disposing.\n", instance);435 /* free32 is NULL safe */436 free32(data->tds);437 free32(data->qh);438 free32(instance->setup_buffer);439 free32(instance->data_buffer);440 free(data);441 free(instance);442 }443 405 /** 444 406 * @}
Note:
See TracChangeset
for help on using the changeset viewer.