Changes in / [bf58895:4fa05a32] in mainline
- Location:
- uspace/drv
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
rbf58895 r4fa05a32 153 153 } 154 154 /*----------------------------------------------------------------------------*/ 155 /** Mark batch as failed and continue with next step. 156 * 157 * @param[in] instance Batch structure to use. 158 * 159 */ 160 void batch_abort(batch_t *instance) 161 { 162 assert(instance); 163 instance->error = EIO; 164 instance->next_step(instance); 165 } 166 /*----------------------------------------------------------------------------*/ 155 167 /** Check batch TDs for activity. 156 168 * … … 251 263 assert(instance); 252 264 /* We are data out, we are supposed to provide data */ 253 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 265 memcpy(instance->transport_buffer, instance->buffer, 266 instance->buffer_size); 254 267 batch_data(instance, USB_PID_OUT); 255 268 instance->next_step = batch_call_out_and_dispose; … … 281 294 assert(instance); 282 295 /* We are data out, we are supposed to provide data */ 283 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 296 memcpy(instance->transport_buffer, instance->buffer, 297 instance->buffer_size); 284 298 batch_data(instance, USB_PID_OUT); 285 299 instance->next_step = batch_call_out_and_dispose; -
uspace/drv/uhci-hcd/batch.h
rbf58895 r4fa05a32 69 69 } batch_t; 70 70 71 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, 72 usb_transfer_type_t transfer_type, size_t max_packet_size, 73 usb_speed_t speed, char *buffer, size_t size, 74 char *setup_buffer, size_t setup_size, 71 batch_t * batch_get( 72 ddf_fun_t *fun, 73 usb_target_t target, 74 usb_transfer_type_t transfer_type, 75 size_t max_packet_size, 76 usb_speed_t speed, 77 char *buffer, 78 size_t size, 79 char *setup_buffer, 80 size_t setup_size, 75 81 usbhc_iface_transfer_in_callback_t func_in, 76 usbhc_iface_transfer_out_callback_t func_out, void *arg, 82 usbhc_iface_transfer_out_callback_t func_out, 83 void *arg, 77 84 device_keeper_t *manager 78 85 ); 79 86 80 87 void batch_dispose(batch_t *instance); 88 89 void batch_abort(batch_t *instance); 81 90 82 91 bool batch_is_complete(batch_t *instance); -
uspace/drv/uhci-hcd/transfer_list.c
rbf58895 r4fa05a32 129 129 } 130 130 /*----------------------------------------------------------------------------*/ 131 /** Check list for finished batches. 132 * 133 * @param[in] instance List to use. 134 * @return Error code 135 * 136 * Creates a local list of finished batches and calls next_step on each and 137 * every one. This is safer because next_step may theoretically access 138 * this transfer list leading to the deadlock if its done inline. 139 */ 140 void transfer_list_remove_finished(transfer_list_t *instance) 141 { 142 assert(instance); 143 144 LIST_INITIALIZE(done); 145 146 fibril_mutex_lock(&instance->guard); 147 link_t *current = instance->batch_list.next; 148 while (current != &instance->batch_list) { 149 link_t *next = current->next; 150 batch_t *batch = list_get_instance(current, batch_t, link); 151 152 if (batch_is_complete(batch)) { 153 /* Save for post-processing */ 154 transfer_list_remove_batch(instance, batch); 155 list_append(current, &done); 156 } 157 current = next; 158 } 159 fibril_mutex_unlock(&instance->guard); 160 161 while (!list_empty(&done)) { 162 link_t *item = done.next; 163 list_remove(item); 164 batch_t *batch = list_get_instance(item, batch_t, link); 165 batch->next_step(batch); 166 } 167 } 168 /*----------------------------------------------------------------------------*/ 169 /** Walk the list and abort all batches. 170 * 171 * @param[in] instance List to use. 172 */ 173 void transfer_list_abort_all(transfer_list_t *instance) 174 { 175 fibril_mutex_lock(&instance->guard); 176 while (list_empty(&instance->batch_list)) { 177 link_t *current = instance->batch_list.next; 178 batch_t *batch = list_get_instance(current, batch_t, link); 179 transfer_list_remove_batch(instance, batch); 180 batch_abort(batch); 181 } 182 fibril_mutex_unlock(&instance->guard); 183 } 184 /*----------------------------------------------------------------------------*/ 131 185 /** Remove a transfer batch from the list and queue. 132 186 * … … 163 217 batch, pos, instance->name, batch->qh->next); 164 218 } 165 /*----------------------------------------------------------------------------*/166 /** Check list for finished batches.167 *168 * @param[in] instance List to use.169 * @return Error code170 *171 * Creates a local list of finished batches and calls next_step on each and172 * every one. This is safer because next_step may theoretically access173 * this transfer list leading to the deadlock if its done inline.174 */175 void transfer_list_remove_finished(transfer_list_t *instance)176 {177 assert(instance);178 179 LIST_INITIALIZE(done);180 181 fibril_mutex_lock(&instance->guard);182 link_t *current = instance->batch_list.next;183 while (current != &instance->batch_list) {184 link_t *next = current->next;185 batch_t *batch = list_get_instance(current, batch_t, link);186 187 if (batch_is_complete(batch)) {188 /* Save for post-processing */189 transfer_list_remove_batch(instance, batch);190 list_append(current, &done);191 }192 current = next;193 }194 fibril_mutex_unlock(&instance->guard);195 196 while (!list_empty(&done)) {197 link_t *item = done.next;198 list_remove(item);199 batch_t *batch = list_get_instance(item, batch_t, link);200 batch->next_step(batch);201 }202 }203 219 /** 204 220 * @} -
uspace/drv/uhci-hcd/transfer_list.h
rbf58895 r4fa05a32 66 66 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 67 67 68 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch); 69 68 70 void transfer_list_remove_finished(transfer_list_t *instance); 69 71 70 void transfer_list_a dd_batch(transfer_list_t *instance, batch_t *batch);72 void transfer_list_abort_all(transfer_list_t *instance); 71 73 #endif 72 74 /** -
uspace/drv/uhci-hcd/uhci_hc.c
rbf58895 r4fa05a32 97 97 98 98 instance->hw_interrupts = interrupts; 99 instance->hw_failures = 0; 100 99 101 /* Setup UHCI function. */ 100 102 instance->ddf_instance = fun; … … 149 151 while ((pio_read_16(®isters->usbcmd) & UHCI_CMD_HCRESET) != 0); 150 152 151 /* Set framelist pointer */ 153 /* Set frame to exactly 1ms */ 154 pio_write_8(®isters->sofmod, 64); 155 156 /* Set frame list pointer */ 152 157 const uint32_t pa = addr_to_phys(instance->frame_list); 153 158 pio_write_32(®isters->flbaseadd, pa); … … 347 352 { 348 353 assert(instance); 349 /* TODO: Check interrupt cause here*/354 /* TODO: Resume interrupts are not supported */ 350 355 /* Lower 2 bits are transaction error and transaction complete */ 351 356 if (status & 0x3) { … … 354 359 transfer_list_remove_finished(&instance->transfers_control_full); 355 360 transfer_list_remove_finished(&instance->transfers_bulk_full); 361 } 362 /* bits 4 and 5 indicate hc error */ 363 if (status & 0x18) { 364 usb_log_error("UHCI hardware failure!.\n"); 365 ++instance->hw_failures; 366 transfer_list_abort_all(&instance->transfers_interrupt); 367 transfer_list_abort_all(&instance->transfers_control_slow); 368 transfer_list_abort_all(&instance->transfers_control_full); 369 transfer_list_abort_all(&instance->transfers_bulk_full); 370 371 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) { 372 /* reinitialize hw, this triggers virtual disconnect*/ 373 uhci_hc_init_hw(instance); 374 } else { 375 usb_log_fatal("Too many UHCI hardware failures!.\n"); 376 uhci_hc_fini(instance); 377 } 356 378 } 357 379 } -
uspace/drv/uhci-hcd/uhci_hc.h
rbf58895 r4fa05a32 80 80 #define UHCI_CLEANER_TIMEOUT 10000 81 81 #define UHCI_DEBUGER_TIMEOUT 5000000 82 #define UHCI_ALLOWED_HW_FAIL 5 82 83 83 84 typedef struct uhci_hc { … … 100 101 fid_t debug_checker; 101 102 bool hw_interrupts; 103 unsigned hw_failures; 102 104 103 105 ddf_fun_t *ddf_instance; -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
rbf58895 r4fa05a32 159 159 (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "", 160 160 (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "", 161 (s >> TD_STATUS_ACTLEN_POS) & TD_STATUS_ACTLEN_MASK161 td_act_size(instance) 162 162 ); 163 163 } -
uspace/drv/usbhub/usbhub.c
rbf58895 r4fa05a32 72 72 int usb_hub_control_loop(void * hub_info_param){ 73 73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param; 74 while(true){ 75 usb_hub_check_hub_changes(hub_info); 74 int errorCode = EOK; 75 76 while(errorCode == EOK){ 77 errorCode = usb_hub_check_hub_changes(hub_info); 76 78 async_usleep(1000 * 1000 );/// \TODO proper number once 77 79 } 80 dprintf(USB_LOG_LEVEL_ERROR, 81 "something in ctrl loop went wrong, errno %d",errorCode); 78 82 return 0; 79 83 } … … 380 384 * @param target 381 385 */ 382 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) { 386 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port, 387 bool isLowSpeed) { 383 388 usb_device_request_setup_packet_t request; 384 389 int opResult; … … 386 391 assert(hub->endpoints.control.hc_phone); 387 392 //get default address 388 //opResult = usb_drv_reserve_default_address(hc);389 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);393 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 394 opResult = usb_hc_reserve_default_address(&hub->connection, speed); 390 395 391 396 if (opResult != EOK) { … … 446 451 usb_address_t new_device_address = usb_hc_request_address( 447 452 &hub->connection, 448 speed /// \TODO fullspeed??453 speed 449 454 ); 450 455 if (new_device_address < 0) { … … 510 515 static void usb_hub_removed_device( 511 516 usb_hub_info_t * hub,uint16_t port) { 512 //usb_device_request_setup_packet_t request; 513 int opResult; 514 517 515 518 /** \TODO remove device from device manager - not yet implemented in 516 519 * devide manager … … 519 522 //close address 520 523 if(hub->attached_devs[port].address!=0){ 521 / /opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);524 /*uncomment this code to use it when DDF allows device removal 522 525 opResult = usb_hc_unregister_device( 523 526 &hub->connection, hub->attached_devs[port].address); … … 528 531 hub->attached_devs[port].address = 0; 529 532 hub->attached_devs[port].handle = 0; 533 */ 530 534 }else{ 531 535 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); … … 597 601 if (usb_port_dev_connected(&status)) { 598 602 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 599 usb_hub_init_add_device(hub, port );603 usb_hub_init_add_device(hub, port, usb_port_low_speed(&status)); 600 604 } else { 601 605 usb_hub_removed_device(hub, port); … … 635 639 /** 636 640 * Check changes on particular hub 637 * @param hub_info_param 638 */ 639 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 641 * @param hub_info_param pointer to usb_hub_info_t structure 642 * @return error code if there is problem when initializing communication with 643 * hub, EOK otherwise 644 */ 645 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 640 646 int opResult; 641 647 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); … … 643 649 dprintf(USB_LOG_LEVEL_ERROR, 644 650 "could not initialize communication for hub; %d", opResult); 645 return ;651 return opResult; 646 652 } 647 653 … … 665 671 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 666 672 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 667 return ;673 return opResult; 668 674 } 669 675 unsigned int port; … … 673 679 opResult); 674 680 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 675 return ;681 return opResult; 676 682 } 677 683 opResult = usb_hc_connection_open(&hub_info->connection); … … 681 687 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 682 688 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 683 return ;689 return opResult; 684 690 } 685 691 … … 697 703 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 698 704 free(change_bitmap); 705 return EOK; 699 706 } 700 707 -
uspace/drv/usbhub/usbhub.h
rbf58895 r4fa05a32 87 87 88 88 /** 89 * check changes on specified hub89 * Check changes on specified hub 90 90 * @param hub_info_param pointer to usb_hub_info_t structure 91 * @return error code if there is problem when initializing communication with 92 * hub, EOK otherwise 91 93 */ 92 voidusb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);94 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param); 93 95 94 96
Note:
See TracChangeset
for help on using the changeset viewer.