Changes in uspace/drv/uhci-hcd/batch.c [910ca3f:06c552c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
r910ca3f r06c552c 30 30 */ 31 31 /** @file 32 * @brief UHCI driver USB trans ferstructure32 * @brief UHCI driver USB transaction structure 33 33 */ 34 34 #include <errno.h> … … 48 48 qh_t *qh; 49 49 td_t *tds; 50 size_t t d_count;50 size_t transfers; 51 51 } uhci_batch_t; 52 52 … … 61 61 * 62 62 * @param[in] fun DDF function to pass to callback. 63 * @param[in] ep Communication target 63 * @param[in] target Device and endpoint target of the transaction. 64 * @param[in] transfer_type Interrupt, Control or Bulk. 65 * @param[in] max_packet_size maximum allowed size of data transfers. 66 * @param[in] speed Speed of the transaction. 64 67 * @param[in] buffer Data source/destination. 65 68 * @param[in] size Size of the buffer. 66 69 * @param[in] setup_buffer Setup data source (if not NULL) 67 70 * @param[in] setup_size Size of setup_buffer (should be always 8) 68 * @param[in] func_in function to call on inbound trans fercompletion69 * @param[in] func_out function to call on outbound trans fercompletion71 * @param[in] func_in function to call on inbound transaction completion 72 * @param[in] func_out function to call on outbound transaction completion 70 73 * @param[in] arg additional parameter to func_in or func_out 74 * @param[in] ep Pointer to endpoint toggle management structure. 71 75 * @return Valid pointer if all substructures were successfully created, 72 76 * NULL otherwise. 73 77 * 74 * Determines the number of needed transfer descriptors (TDs).75 * Prepares a transport buffer (that is accessible by the hardware).76 * Initializes parameters needed for the transferand callback.78 * Determines the number of needed transfers (TDs). Prepares a transport buffer 79 * (that is accessible by the hardware). Initializes parameters needed for the 80 * transaction and callback. 77 81 */ 78 82 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, … … 99 103 usb_target_t target = 100 104 { .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);105 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 106 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 107 func_in, func_out, arg, fun, ep, NULL); 104 108 105 109 … … 109 113 instance->private_data = data; 110 114 111 data->t d_count=115 data->transfers = 112 116 (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size; 113 117 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 114 data->t d_count+= 2;115 } 116 117 data->tds = malloc32(sizeof(td_t) * data->t d_count);118 data->transfers += 2; 119 } 120 121 data->tds = malloc32(sizeof(td_t) * data->transfers); 118 122 CHECK_NULL_DISPOSE_RETURN( 119 123 data->tds, "Failed to allocate transfer descriptors.\n"); 120 bzero(data->tds, sizeof(td_t) * data->t d_count);124 bzero(data->tds, sizeof(td_t) * data->transfers); 121 125 122 126 data->qh = malloc32(sizeof(qh_t)); … … 127 131 128 132 if (buffer_size > 0) { 129 instance-> data_buffer = malloc32(buffer_size);130 CHECK_NULL_DISPOSE_RETURN(instance-> data_buffer,133 instance->transport_buffer = malloc32(buffer_size); 134 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer, 131 135 "Failed to allocate device accessible buffer.\n"); 132 136 } … … 150 154 * 151 155 * Walk all TDs. Stop with false if there is an active one (it is to be 152 * processed). Stop with true if an error is found. Return true if the last T D156 * processed). Stop with true if an error is found. Return true if the last TS 153 157 * is reached. 154 158 */ … … 160 164 161 165 usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n", 162 instance, data->t d_count);166 instance, data->transfers); 163 167 instance->transfered_size = 0; 164 168 size_t i = 0; 165 for (;i < data->t d_count; ++i) {169 for (;i < data->transfers; ++i) { 166 170 if (td_is_active(&data->tds[i])) { 167 171 return false; … … 173 177 instance, i, data->tds[i].status); 174 178 td_print_status(&data->tds[i]); 175 176 179 assert(instance->ep != NULL); 180 177 181 endpoint_toggle_set(instance->ep, 178 182 td_toggle(&data->tds[i])); … … 191 195 } 192 196 /*----------------------------------------------------------------------------*/ 193 /** Prepares control write trans fer.194 * 195 * @param[in] instance Batch structure to use. 196 * 197 * Uses gener iccontrol function with pids OUT and IN.197 /** Prepares control write transaction. 198 * 199 * @param[in] instance Batch structure to use. 200 * 201 * Uses genercir control function with pids OUT and IN. 198 202 */ 199 203 void batch_control_write(usb_transfer_batch_t *instance) … … 201 205 assert(instance); 202 206 /* We are data out, we are supposed to provide data */ 203 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 207 memcpy(instance->transport_buffer, instance->buffer, 208 instance->buffer_size); 204 209 batch_control(instance, USB_PID_OUT, USB_PID_IN); 205 210 instance->next_step = batch_call_out_and_dispose; … … 207 212 } 208 213 /*----------------------------------------------------------------------------*/ 209 /** Prepares control read trans fer.214 /** Prepares control read transaction. 210 215 * 211 216 * @param[in] instance Batch structure to use. … … 221 226 } 222 227 /*----------------------------------------------------------------------------*/ 223 /** Prepare interrupt in trans fer.224 * 225 * @param[in] instance Batch structure to use. 226 * 227 * Data trans ferwith PID_IN.228 /** Prepare interrupt in transaction. 229 * 230 * @param[in] instance Batch structure to use. 231 * 232 * Data transaction with PID_IN. 228 233 */ 229 234 void batch_interrupt_in(usb_transfer_batch_t *instance) 230 235 { 231 236 assert(instance); 237 instance->direction = USB_DIRECTION_IN; 232 238 batch_data(instance, USB_PID_IN); 233 239 instance->next_step = batch_call_in_and_dispose; … … 235 241 } 236 242 /*----------------------------------------------------------------------------*/ 237 /** Prepare interrupt out trans fer.238 * 239 * @param[in] instance Batch structure to use. 240 * 241 * Data trans ferwith PID_OUT.243 /** Prepare interrupt out transaction. 244 * 245 * @param[in] instance Batch structure to use. 246 * 247 * Data transaction with PID_OUT. 242 248 */ 243 249 void batch_interrupt_out(usb_transfer_batch_t *instance) 244 250 { 245 251 assert(instance); 252 instance->direction = USB_DIRECTION_OUT; 246 253 /* We are data out, we are supposed to provide data */ 247 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 254 memcpy(instance->transport_buffer, instance->buffer, 255 instance->buffer_size); 248 256 batch_data(instance, USB_PID_OUT); 249 257 instance->next_step = batch_call_out_and_dispose; … … 251 259 } 252 260 /*----------------------------------------------------------------------------*/ 253 /** Prepare bulk in trans fer.254 * 255 * @param[in] instance Batch structure to use. 256 * 257 * Data trans ferwith PID_IN.261 /** Prepare bulk in transaction. 262 * 263 * @param[in] instance Batch structure to use. 264 * 265 * Data transaction with PID_IN. 258 266 */ 259 267 void batch_bulk_in(usb_transfer_batch_t *instance) … … 261 269 assert(instance); 262 270 batch_data(instance, USB_PID_IN); 271 instance->direction = USB_DIRECTION_IN; 263 272 instance->next_step = batch_call_in_and_dispose; 264 273 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 265 274 } 266 275 /*----------------------------------------------------------------------------*/ 267 /** Prepare bulk out trans fer.268 * 269 * @param[in] instance Batch structure to use. 270 * 271 * Data trans ferwith PID_OUT.276 /** Prepare bulk out transaction. 277 * 278 * @param[in] instance Batch structure to use. 279 * 280 * Data transaction with PID_OUT. 272 281 */ 273 282 void batch_bulk_out(usb_transfer_batch_t *instance) 274 283 { 275 284 assert(instance); 285 instance->direction = USB_DIRECTION_OUT; 276 286 /* We are data out, we are supposed to provide data */ 277 memcpy(instance->data_buffer, instance->buffer, instance->buffer_size); 287 memcpy(instance->transport_buffer, instance->buffer, 288 instance->buffer_size); 278 289 batch_data(instance, USB_PID_OUT); 279 290 instance->next_step = batch_call_out_and_dispose; … … 281 292 } 282 293 /*----------------------------------------------------------------------------*/ 283 /** Prepare generic data trans fer284 * 285 * @param[in] instance Batch structure to use. 286 * @param[in] pid Pid to use for data trans actions.287 * 288 * Transactions with alternating toggle bit and supplied pid value.294 /** Prepare generic data transaction 295 * 296 * @param[in] instance Batch structure to use. 297 * @param[in] pid Pid to use for data transfers. 298 * 299 * Packets with alternating toggle bit and supplied pid value. 289 300 * The last transfer is marked with IOC flag. 290 301 */ … … 295 306 assert(data); 296 307 297 const bool low_speed = instance-> ep->speed == USB_SPEED_LOW;308 const bool low_speed = instance->speed == USB_SPEED_LOW; 298 309 int toggle = endpoint_toggle_get(instance->ep); 299 310 assert(toggle == 0 || toggle == 1); 300 311 301 size_t t d= 0;312 size_t transfer = 0; 302 313 size_t remain_size = instance->buffer_size; 303 char *buffer = instance->data_buffer;304 314 while (remain_size > 0) { 315 char *trans_data = 316 instance->transport_buffer + instance->buffer_size 317 - remain_size; 318 305 319 const size_t packet_size = 306 (instance->ep->max_packet_size > remain_size) ? 307 remain_size : instance->ep->max_packet_size; 308 309 td_t *next_td = (td + 1 < data->td_count) 310 ? &data->tds[td + 1] : NULL; 311 312 313 usb_target_t target = 314 { instance->ep->address, instance->ep->endpoint }; 315 316 assert(td < data->td_count); 320 (instance->max_packet_size > remain_size) ? 321 remain_size : instance->max_packet_size; 322 323 td_t *next_transfer = (transfer + 1 < data->transfers) 324 ? &data->tds[transfer + 1] : NULL; 325 326 assert(transfer < data->transfers); 327 assert(packet_size <= remain_size); 328 317 329 td_init( 318 &data->tds[td], DEFAULT_ERROR_COUNT, packet_size, 319 toggle, false, low_speed, target, pid, buffer, next_td); 320 321 ++td; 330 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size, 331 toggle, false, low_speed, instance->target, pid, trans_data, 332 next_transfer); 333 334 322 335 toggle = 1 - toggle; 323 buffer += packet_size;324 assert(packet_size <= remain_size);325 336 remain_size -= packet_size; 326 } 327 td_set_ioc(&data->tds[td - 1]); 337 ++transfer; 338 } 339 td_set_ioc(&data->tds[transfer - 1]); 328 340 endpoint_toggle_set(instance->ep, toggle); 329 341 } 330 342 /*----------------------------------------------------------------------------*/ 331 /** Prepare generic control trans fer332 * 333 * @param[in] instance Batch structure to use. 334 * @param[in] data_stage Pid to use for data t ds.335 * @param[in] status_stage Pid to use for data t ds.343 /** Prepare generic control transaction 344 * 345 * @param[in] instance Batch structure to use. 346 * @param[in] data_stage Pid to use for data transfers. 347 * @param[in] status_stage Pid to use for data transfers. 336 348 * 337 349 * Setup stage with toggle 0 and USB_PID_SETUP. … … 346 358 uhci_batch_t *data = instance->private_data; 347 359 assert(data); 348 assert(data->td_count >= 2); 349 350 const bool low_speed = instance->ep->speed == USB_SPEED_LOW; 351 const usb_target_t target = 352 { instance->ep->address, instance->ep->endpoint }; 353 360 assert(data->transfers >= 2); 361 362 const bool low_speed = instance->speed == USB_SPEED_LOW; 363 int toggle = 0; 354 364 /* setup stage */ 355 365 td_init( 356 data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,357 low_speed, target, USB_PID_SETUP, instance->setup_buffer,366 data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false, 367 low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer, 358 368 &data->tds[1]); 359 369 360 370 /* data stage */ 361 size_t td = 1; 362 unsigned toggle = 1; 371 size_t transfer = 1; 363 372 size_t remain_size = instance->buffer_size; 364 char *buffer = instance->data_buffer;365 373 while (remain_size > 0) { 374 char *control_data = 375 instance->transport_buffer + instance->buffer_size 376 - remain_size; 377 378 toggle = 1 - toggle; 379 366 380 const size_t packet_size = 367 (instance-> ep->max_packet_size > remain_size) ?368 remain_size : instance-> ep->max_packet_size;381 (instance->max_packet_size > remain_size) ? 382 remain_size : instance->max_packet_size; 369 383 370 384 td_init( 371 &data->tds[td], DEFAULT_ERROR_COUNT, packet_size, 372 toggle, false, low_speed, target, data_stage, 373 buffer, &data->tds[td + 1]); 374 375 ++td; 376 toggle = 1 - toggle; 377 buffer += packet_size; 378 assert(td < data->td_count); 385 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size, 386 toggle, false, low_speed, instance->target, data_stage, 387 control_data, &data->tds[transfer + 1]); 388 389 ++transfer; 390 assert(transfer < data->transfers); 379 391 assert(packet_size <= remain_size); 380 392 remain_size -= packet_size; … … 382 394 383 395 /* status stage */ 384 assert(t d == data->td_count- 1);396 assert(transfer == data->transfers - 1); 385 397 386 398 td_init( 387 &data->tds[t d], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,388 target, status_stage, NULL, NULL);389 td_set_ioc(&data->tds[t d]);399 &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed, 400 instance->target, status_stage, NULL, NULL); 401 td_set_ioc(&data->tds[transfer]); 390 402 391 403 usb_log_debug2("Control last TD status: %x.\n", 392 data->tds[t d].status);404 data->tds[transfer].status); 393 405 } 394 406 /*----------------------------------------------------------------------------*/ … … 401 413 } 402 414 /*----------------------------------------------------------------------------*/ 403 /** Helper function , calls callback and correctly destroysbatch structure.415 /** Helper function calls callback and correctly disposes of batch structure. 404 416 * 405 417 * @param[in] instance Batch structure to use. … … 412 424 } 413 425 /*----------------------------------------------------------------------------*/ 414 /** Helper function calls callback and correctly d estroysbatch structure.426 /** Helper function calls callback and correctly disposes of batch structure. 415 427 * 416 428 * @param[in] instance Batch structure to use. … … 437 449 free32(data->qh); 438 450 free32(instance->setup_buffer); 439 free32(instance-> data_buffer);451 free32(instance->transport_buffer); 440 452 free(data); 441 453 free(instance);
Note:
See TracChangeset
for help on using the changeset viewer.