Changeset 5fd9c30 in mainline for uspace/drv/bus/usb/uhci/uhci_batch.c
- Timestamp:
- 2017-10-21T20:52:56Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 766043c
- Parents:
- 74b852b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/uhci_batch.c
r74b852b r5fd9c30 50 50 #define DEFAULT_ERROR_COUNT 3 51 51 52 /** Safely destructs uhci_transfer_batch_t structure. 52 /** Transfer batch setup table. */ 53 static void (*const batch_setup[])(uhci_transfer_batch_t*); 54 55 /** Destroys uhci_transfer_batch_t structure. 53 56 * 54 57 * @param[in] uhci_batch Instance to destroy. 55 58 */ 56 static void uhci_transfer_batch_dispose(uhci_transfer_batch_t *uhci_batch) 57 { 58 if (uhci_batch) { 59 usb_transfer_batch_destroy(uhci_batch->usb_batch); 60 free32(uhci_batch->device_buffer); 61 free(uhci_batch); 62 } 63 } 64 65 /** Finishes usb_transfer_batch and destroys the structure. 66 * 67 * @param[in] uhci_batch Instance to finish and destroy. 68 */ 69 void uhci_transfer_batch_finish_dispose(uhci_transfer_batch_t *uhci_batch) 59 void uhci_transfer_batch_destroy(uhci_transfer_batch_t *uhci_batch) 70 60 { 71 61 assert(uhci_batch); 72 assert(uhci_batch->usb_batch); 73 assert(!link_in_use(&uhci_batch->link)); 74 usb_transfer_batch_finish(uhci_batch->usb_batch, 75 uhci_transfer_batch_data_buffer(uhci_batch)); 76 uhci_transfer_batch_dispose(uhci_batch); 77 } 78 79 /** Transfer batch setup table. */ 80 static void (*const batch_setup[])(uhci_transfer_batch_t*, usb_direction_t); 62 free32(uhci_batch->device_buffer); 63 free(uhci_batch); 64 } 81 65 82 66 /** Allocate memory and initialize internal data structure. … … 85 69 * @return Valid pointer if all structures were successfully created, 86 70 * NULL otherwise. 71 */ 72 uhci_transfer_batch_t * uhci_transfer_batch_create(endpoint_t *ep) 73 { 74 uhci_transfer_batch_t *uhci_batch = 75 calloc(1, sizeof(uhci_transfer_batch_t)); 76 if (!uhci_batch) { 77 usb_log_error("Failed to allocate UHCI batch.\n"); 78 return NULL; 79 } 80 81 usb_transfer_batch_init(&uhci_batch->base, ep); 82 83 link_initialize(&uhci_batch->link); 84 return uhci_batch; 85 } 86 87 /* Prepares batch for commiting. 87 88 * 88 89 * Determines the number of needed transfer descriptors (TDs). … … 90 91 * Initializes parameters needed for the transfer and callback. 91 92 */ 92 uhci_transfer_batch_t * uhci_transfer_batch_get(usb_transfer_batch_t *usb_batch)93 int uhci_transfer_batch_prepare(uhci_transfer_batch_t *uhci_batch) 93 94 { 94 95 static_assert((sizeof(td_t) % 16) == 0); 95 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ 96 if (ptr == NULL) { \ 97 usb_log_error(message); \ 98 uhci_transfer_batch_dispose(uhci_batch); \ 99 return NULL; \ 100 } else (void)0 101 102 uhci_transfer_batch_t *uhci_batch = 103 calloc(1, sizeof(uhci_transfer_batch_t)); 104 CHECK_NULL_DISPOSE_RETURN(uhci_batch, 105 "Failed to allocate UHCI batch.\n"); 106 link_initialize(&uhci_batch->link); 107 uhci_batch->td_count = 108 (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1) 109 / usb_batch->ep->max_packet_size; 96 97 usb_transfer_batch_t *usb_batch = &uhci_batch->base; 98 99 uhci_batch->td_count = (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1) 100 / usb_batch->ep->max_packet_size; 101 110 102 if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) { 111 103 uhci_batch->td_count += 2; 112 104 } 113 105 106 const size_t setup_size = (uhci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) 107 ? USB_SETUP_PACKET_SIZE 108 : 0; 109 114 110 const size_t total_size = (sizeof(td_t) * uhci_batch->td_count) 115 + sizeof(qh_t) + usb_batch->setup_size + usb_batch->buffer_size;111 + sizeof(qh_t) + setup_size + usb_batch->buffer_size; 116 112 uhci_batch->device_buffer = malloc32(total_size); 117 CHECK_NULL_DISPOSE_RETURN(uhci_batch->device_buffer, 118 "Failed to allocate UHCI buffer.\n"); 113 if (!uhci_batch->device_buffer) { 114 usb_log_error("Failed to allocate UHCI buffer.\n"); 115 return ENOMEM; 116 } 119 117 memset(uhci_batch->device_buffer, 0, total_size); 120 118 … … 130 128 + sizeof(qh_t); 131 129 /* Copy SETUP packet data to the device buffer */ 132 memcpy(dest, usb_batch->setup _buffer, usb_batch->setup_size);133 dest += usb_batch->setup_size;130 memcpy(dest, usb_batch->setup.buffer, setup_size); 131 dest += setup_size; 134 132 /* Copy generic data unless they are provided by the device */ 135 133 if (usb_batch->ep->direction != USB_DIRECTION_IN) { 136 134 memcpy(dest, usb_batch->buffer, usb_batch->buffer_size); 137 135 } 138 uhci_batch->usb_batch = usb_batch;139 136 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT 140 137 " memory structures ready.\n", usb_batch, 141 138 USB_TRANSFER_BATCH_ARGS(*usb_batch)); 142 139 143 const usb_direction_t dir = usb_transfer_batch_direction(usb_batch);144 145 140 assert(batch_setup[usb_batch->ep->transfer_type]); 146 batch_setup[usb_batch->ep->transfer_type](uhci_batch , dir);147 148 return uhci_batch;141 batch_setup[usb_batch->ep->transfer_type](uhci_batch); 142 143 return EOK; 149 144 } 150 145 … … 158 153 * is reached. 159 154 */ 160 bool uhci_transfer_batch_ is_complete(constuhci_transfer_batch_t *uhci_batch)155 bool uhci_transfer_batch_check_completed(uhci_transfer_batch_t *uhci_batch) 161 156 { 162 157 assert(uhci_batch); 163 assert(uhci_batch->usb_batch);164 158 165 159 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT … … 168 162 USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch), 169 163 uhci_batch->td_count); 170 uhci_batch-> usb_batch->transfered_size = 0;164 uhci_batch->base.transfered_size = 0; 171 165 172 166 for (size_t i = 0;i < uhci_batch->td_count; ++i) { … … 175 169 } 176 170 177 uhci_batch-> usb_batch->error = td_status(&uhci_batch->tds[i]);178 if (uhci_batch-> usb_batch->error != EOK) {179 assert(uhci_batch-> usb_batch->ep != NULL);171 uhci_batch->base.error = td_status(&uhci_batch->tds[i]); 172 if (uhci_batch->base.error != EOK) { 173 assert(uhci_batch->base.ep != NULL); 180 174 181 175 usb_log_debug("Batch %p found error TD(%zu->%p):%" … … 184 178 td_print_status(&uhci_batch->tds[i]); 185 179 186 endpoint_toggle_set(uhci_batch-> usb_batch->ep,180 endpoint_toggle_set(uhci_batch->base.ep, 187 181 td_toggle(&uhci_batch->tds[i])); 188 182 if (i > 0) … … 191 185 } 192 186 193 uhci_batch-> usb_batch->transfered_size187 uhci_batch->base.transfered_size 194 188 += td_act_size(&uhci_batch->tds[i]); 195 189 if (td_is_short(&uhci_batch->tds[i])) … … 197 191 } 198 192 substract_ret: 199 uhci_batch->usb_batch->transfered_size200 -= uhci_batch->usb_batch->setup_size;193 if (uhci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) 194 uhci_batch->base.transfered_size -= USB_SETUP_PACKET_SIZE; 201 195 return true; 202 196 } … … 216 210 * The last transfer is marked with IOC flag. 217 211 */ 218 static void batch_data(uhci_transfer_batch_t *uhci_batch , usb_direction_t dir)212 static void batch_data(uhci_transfer_batch_t *uhci_batch) 219 213 { 220 214 assert(uhci_batch); 221 assert(uhci_batch->usb_batch); 222 assert(uhci_batch->usb_batch->ep);215 216 usb_direction_t dir = uhci_batch->base.dir; 223 217 assert(dir == USB_DIRECTION_OUT || dir == USB_DIRECTION_IN); 224 218 … … 226 220 const usb_packet_id pid = direction_pids[dir]; 227 221 const bool low_speed = 228 uhci_batch-> usb_batch->ep->speed == USB_SPEED_LOW;229 const size_t mps = uhci_batch-> usb_batch->ep->max_packet_size;230 const usb_target_t target = uhci_batch-> usb_batch->ep->target;231 232 int toggle = endpoint_toggle_get(uhci_batch-> usb_batch->ep);222 uhci_batch->base.ep->speed == USB_SPEED_LOW; 223 const size_t mps = uhci_batch->base.ep->max_packet_size; 224 const usb_target_t target = uhci_batch->base.ep->target; 225 226 int toggle = endpoint_toggle_get(uhci_batch->base.ep); 233 227 assert(toggle == 0 || toggle == 1); 234 228 235 229 size_t td = 0; 236 size_t remain_size = uhci_batch-> usb_batch->buffer_size;230 size_t remain_size = uhci_batch->base.buffer_size; 237 231 char *buffer = uhci_transfer_batch_data_buffer(uhci_batch); 238 232 … … 254 248 } 255 249 td_set_ioc(&uhci_batch->tds[td - 1]); 256 endpoint_toggle_set(uhci_batch-> usb_batch->ep, toggle);250 endpoint_toggle_set(uhci_batch->base.ep, toggle); 257 251 usb_log_debug2( 258 252 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \ 259 253 uhci_batch->usb_batch, 260 usb_str_transfer_type(uhci_batch-> usb_batch->ep->transfer_type),261 usb_str_direction(uhci_batch-> usb_batch->ep->direction),254 usb_str_transfer_type(uhci_batch->base.ep->transfer_type), 255 usb_str_direction(uhci_batch->base.ep->direction), 262 256 USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch)); 263 257 } … … 274 268 * The last transfer is marked with IOC. 275 269 */ 276 static void batch_control(uhci_transfer_batch_t *uhci_batch , usb_direction_t dir)270 static void batch_control(uhci_transfer_batch_t *uhci_batch) 277 271 { 278 272 assert(uhci_batch); 279 assert(uhci_batch->usb_batch); 280 assert(uhci_batch->usb_batch->ep);273 274 usb_direction_t dir = uhci_batch->base.dir; 281 275 assert(dir == USB_DIRECTION_OUT || dir == USB_DIRECTION_IN); 282 276 assert(uhci_batch->td_count >= 2); … … 289 283 const usb_packet_id status_stage_pid = status_stage_pids[dir]; 290 284 const bool low_speed = 291 uhci_batch-> usb_batch->ep->speed == USB_SPEED_LOW;292 const size_t mps = uhci_batch-> usb_batch->ep->max_packet_size;293 const usb_target_t target = uhci_batch-> usb_batch->ep->target;285 uhci_batch->base.ep->speed == USB_SPEED_LOW; 286 const size_t mps = uhci_batch->base.ep->max_packet_size; 287 const usb_target_t target = uhci_batch->base.ep->target; 294 288 295 289 /* setup stage */ 296 290 td_init( 297 291 &uhci_batch->tds[0], DEFAULT_ERROR_COUNT, 298 uhci_batch->usb_batch->setup_size, 0, false,292 USB_SETUP_PACKET_SIZE, 0, false, 299 293 low_speed, target, USB_PID_SETUP, 300 294 uhci_transfer_batch_setup_buffer(uhci_batch), &uhci_batch->tds[1]); … … 303 297 size_t td = 1; 304 298 unsigned toggle = 1; 305 size_t remain_size = uhci_batch-> usb_batch->buffer_size;299 size_t remain_size = uhci_batch->base.buffer_size; 306 300 char *buffer = uhci_transfer_batch_data_buffer(uhci_batch); 307 301 … … 333 327 } 334 328 335 static void (*const batch_setup[])(uhci_transfer_batch_t* , usb_direction_t) =329 static void (*const batch_setup[])(uhci_transfer_batch_t*) = 336 330 { 337 331 [USB_TRANSFER_CONTROL] = batch_control,
Note:
See TracChangeset
for help on using the changeset viewer.