Changes in uspace/drv/usbhub/utils.c [f9a0cef:9ca0013] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/utils.c
rf9a0cef r9ca0013 34 34 */ 35 35 #include <driver.h> 36 #include <bool.h> 37 #include <errno.h> 38 36 #include <usb/devreq.h> 39 37 #include <usbhc_iface.h> 40 38 #include <usb/usbdrv.h> 41 39 #include <usb/descriptor.h> 42 #include <usb/devreq.h> 40 #include <driver.h> 41 #include <bool.h> 42 #include <errno.h> 43 43 #include <usb/classes/hub.h> 44 45 44 #include "usbhub.h" 46 #include "usbhub_private.h" 47 #include "port_status.h" 48 45 46 static void check_hub_changes(void); 49 47 50 48 size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71; … … 55 53 // 56 54 //********************************************* 57 58 //hub descriptor utils59 55 60 56 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) { … … 88 84 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) { 89 85 uint8_t * sdescriptor = (uint8_t*) serialized_descriptor; 90 91 if (sdescriptor[1] != USB_DESCTYPE_HUB) { 92 printf("[usb_hub] wrong descriptor %x\n",sdescriptor[1]); 93 return NULL; 94 } 95 96 usb_hub_descriptor_t * result = usb_new(usb_hub_descriptor_t); 97 98 86 if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL; 87 usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t)); 88 //uint8_t size = sdescriptor[0]; 99 89 result->ports_count = sdescriptor[2]; 100 90 /// @fixme handling of endianness?? … … 104 94 size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0); 105 95 result->devices_removable = (uint8_t*) malloc(var_size); 106 //printf("[usb_hub] getting removable devices data \n"); 96 107 97 size_t i; 108 98 for (i = 0; i < var_size; ++i) { … … 112 102 } 113 103 114 //control transactions 115 116 int usb_drv_sync_control_read( 117 int phone, usb_target_t target, 118 usb_device_request_setup_packet_t * request, 119 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size 120 ) { 121 usb_handle_t handle; 122 int opResult; 123 //setup 124 opResult = usb_drv_async_control_read_setup(phone, target, 125 request, sizeof (usb_device_request_setup_packet_t), 126 &handle); 127 if (opResult != EOK) { 128 return opResult; 129 } 130 opResult = usb_drv_async_wait_for(handle); 131 if (opResult != EOK) { 132 return opResult; 133 } 134 //read 135 opResult = usb_drv_async_control_read_data(phone, target, 136 rcvd_buffer, rcvd_size, actual_size, 137 &handle); 138 if (opResult != EOK) { 139 return opResult; 140 } 141 opResult = usb_drv_async_wait_for(handle); 142 if (opResult != EOK) { 143 return opResult; 144 } 145 //finalize 146 opResult = usb_drv_async_control_read_status(phone, target, 147 &handle); 148 if (opResult != EOK) { 149 return opResult; 150 } 151 opResult = usb_drv_async_wait_for(handle); 152 if (opResult != EOK) { 153 return opResult; 154 } 155 return EOK; 156 } 157 158 int usb_drv_sync_control_write( 159 int phone, usb_target_t target, 160 usb_device_request_setup_packet_t * request, 161 void * sent_buffer, size_t sent_size 162 ) { 163 usb_handle_t handle; 164 int opResult; 165 //setup 166 opResult = usb_drv_async_control_write_setup(phone, target, 167 request, sizeof (usb_device_request_setup_packet_t), 168 &handle); 169 if (opResult != EOK) { 170 return opResult; 171 } 172 opResult = usb_drv_async_wait_for(handle); 173 if (opResult != EOK) { 174 return opResult; 175 } 176 //write 177 opResult = usb_drv_async_control_write_data(phone, target, 178 sent_buffer, sent_size, 179 &handle); 180 if (opResult != EOK) { 181 return opResult; 182 } 183 opResult = usb_drv_async_wait_for(handle); 184 if (opResult != EOK) { 185 return opResult; 186 } 187 //finalize 188 opResult = usb_drv_async_control_write_status(phone, target, 189 &handle); 190 if (opResult != EOK) { 191 return opResult; 192 } 193 opResult = usb_drv_async_wait_for(handle); 194 if (opResult != EOK) { 195 return opResult; 196 } 197 return EOK; 198 } 199 200 //list implementation 201 202 usb_general_list_t * usb_lst_create(void) { 203 usb_general_list_t* result = usb_new(usb_general_list_t); 204 usb_lst_init(result); 104 105 //********************************************* 106 // 107 // hub driver code 108 // 109 //********************************************* 110 111 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) { 112 usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t)); 113 205 114 return result; 206 115 } 207 116 208 void usb_lst_init(usb_general_list_t * lst) { 209 lst->prev = lst; 210 lst->next = lst; 211 lst->data = NULL; 212 } 213 214 void usb_lst_prepend(usb_general_list_t* item, void* data) { 215 usb_general_list_t* appended = usb_new(usb_general_list_t); 216 appended->data = data; 217 appended->next = item; 218 appended->prev = item->prev; 219 item->prev->next = appended; 220 item->prev = appended; 221 } 222 223 void usb_lst_append(usb_general_list_t* item, void* data) { 224 usb_general_list_t* appended = usb_new(usb_general_list_t); 225 appended->data = data; 226 appended->next = item->next; 227 appended->prev = item; 228 item->next->prev = appended; 229 item->next = appended; 230 } 231 232 void usb_lst_remove(usb_general_list_t* item) { 233 item->next->prev = item->prev; 234 item->prev->next = item->next; 235 } 236 237 static void usb_hub_test_port_status(void) { 238 printf("[usb_hub] -------------port status test---------\n"); 239 usb_port_status_t status = 0; 240 241 //printf("original status %d (should be 0)\n",(uint32_t)status); 242 usb_port_set_bit(&status, 1, 1); 243 //printf("%d =?= 2\n",(uint32_t)status); 244 if (status != 2) { 245 printf("[usb_port_status] test failed: wrong set of bit 1\n"); 246 return; 247 } 248 usb_port_set_bit(&status, 3, 1); 249 if (status != 10) { 250 printf("[usb_port_status] test failed: wrong set of bit 3\n"); 251 return; 252 } 253 254 usb_port_set_bit(&status, 15, 1); 255 if (status != 10 + (1 << 15)) { 256 printf("[usb_port_status] test failed: wrong set of bit 15\n"); 257 return; 258 } 259 usb_port_set_bit(&status, 1, 0); 260 if (status != 8 + (1 << 15)) { 261 printf("[usb_port_status] test failed: wrong unset of bit 1\n"); 262 return; 263 } 264 int i; 265 for (i = 0; i < 32; ++i) { 266 if (i == 3 || i == 15) { 267 if (!usb_port_get_bit(&status, i)) { 268 printf("[usb_port_status] test failed: wrong bit at %d\n", i); 269 } 270 } else { 271 if (usb_port_get_bit(&status, i)) { 272 printf("[usb_port_status] test failed: wrong bit at %d\n", i); 273 } 274 } 275 } 276 277 printf("test ok\n"); 278 279 280 //printf("%d =?= 10\n",(uint32_t)status); 281 282 //printf("this should be 0: %d \n",usb_port_get_bit(&status,0)); 283 //printf("this should be 1: %d \n",usb_port_get_bit(&status,1)); 284 //printf("this should be 0: %d \n",usb_port_get_bit(&status,2)); 285 //printf("this should be 1: %d \n",usb_port_get_bit(&status,3)); 286 //printf("this should be 0: %d \n",usb_port_get_bit(&status,4)); 287 288 289 290 291 } 292 293 //********************************************* 294 // 295 // hub driver code, initialization 296 // 297 //********************************************* 298 299 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 300 usb_hub_info_t* result = usb_new(usb_hub_info_t); 301 //result->device = device; 302 result->port_count = -1; 303 /// \TODO is this correct? is the device stored? 304 result->device = device; 305 306 307 //printf("[usb_hub] phone to hc = %d\n", hc); 308 if (hc < 0) { 309 return result; 310 } 311 //get some hub info 312 usb_address_t addr = usb_drv_get_my_address(hc, device); 313 printf("[usb_hub] addres of newly created hub = %d\n", addr); 314 /*if(addr<0){ 315 //return result; 316 317 }*/ 318 319 result->usb_device = usb_new(usb_hcd_attached_device_info_t); 320 result->usb_device->address = addr; 321 322 // get hub descriptor 323 usb_target_t target; 324 target.address = addr; 325 target.endpoint = 0; 326 usb_device_request_setup_packet_t request; 327 //printf("[usb_hub] creating descriptor request\n"); 328 usb_hub_set_descriptor_request(&request); 329 330 //printf("[usb_hub] creating serialized descriptor\n"); 331 void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE); 332 usb_hub_descriptor_t * descriptor; 333 size_t received_size; 334 int opResult; 335 //printf("[usb_hub] starting control transaction\n"); 336 opResult = usb_drv_sync_control_read( 337 hc, target, &request, serialized_descriptor, 338 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 339 if (opResult != EOK) { 340 printf("[usb_hub] failed when receiving hub descriptor, badcode = %d\n",opResult); 341 ///\TODO memory leak will occur here! 342 return result; 343 } 344 //printf("[usb_hub] deserializing descriptor\n"); 345 descriptor = usb_deserialize_hub_desriptor(serialized_descriptor); 346 if(descriptor==NULL){ 347 printf("[usb_hub] could not deserialize descriptor \n"); 348 result->port_count = 1;///\TODO this code is only for debug!!! 349 return result; 350 } 351 //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count); 352 result->port_count = descriptor->ports_count; 353 result->attached_devs = (usb_hub_attached_device_t*) 354 malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t)); 355 int i; 356 for(i=0;i<result->port_count+1;++i){ 357 result->attached_devs[i].devman_handle=0; 358 result->attached_devs[i].address=0; 359 } 360 //printf("[usb_hub] freeing data\n"); 361 free(serialized_descriptor); 362 free(descriptor->devices_removable); 363 free(descriptor); 364 365 //finish 366 367 printf("[usb_hub] hub info created\n"); 368 369 return result; 370 } 371 117 /** Callback when new hub device is detected. 118 * 119 * @param dev New device. 120 * @return Error code. 121 */ 372 122 int usb_add_hub_device(device_t *dev) { 373 123 printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle); 374 printf("[usb_hub] hub device\n"); 124 125 check_hub_changes(); 375 126 376 127 /* … … 381 132 382 133 //create the hub structure 383 //get hc connection 384 /// \TODO correct params 385 int hc = usb_drv_hc_connect(dev, 0); 386 387 usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc); 388 int port; 389 int opResult; 390 usb_device_request_setup_packet_t request; 391 usb_target_t target; 392 target.address = hub_info->usb_device->address; 393 target.endpoint = 0; 394 395 //get configuration descriptor 396 // this is not fully correct - there are more configurations 397 // and all should be checked 398 usb_standard_device_descriptor_t std_descriptor; 399 opResult = usb_drv_req_get_device_descriptor(hc, target.address, 400 &std_descriptor); 401 if(opResult!=EOK){ 402 printf("[usb_hub] could not get device descriptor, %d\n",opResult); 403 return 1;///\TODO some proper error code needed 404 } 405 printf("[usb_hub] hub has %d configurations\n",std_descriptor.configuration_count); 406 if(std_descriptor.configuration_count<1){ 407 printf("[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE\n"); 408 } 409 usb_standard_configuration_descriptor_t config_descriptor; 410 opResult = usb_drv_req_get_bare_configuration_descriptor(hc, 411 target.address, 0, 412 &config_descriptor); 413 if(opResult!=EOK){ 414 printf("[usb_hub] could not get configuration descriptor, %d\n",opResult); 415 return 1;///\TODO some proper error code needed 416 } 417 //set configuration 418 request.request_type = 0; 419 request.request = USB_DEVREQ_SET_CONFIGURATION; 420 request.index=0; 421 request.length=0; 422 request.value_high=0; 423 request.value_low = config_descriptor.configuration_number; 424 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 425 if (opResult != EOK) { 426 printf("[usb_hub]something went wrong when setting hub`s configuration, %d\n", opResult); 427 } 428 429 430 for (port = 1; port < hub_info->port_count+1; ++port) { 431 usb_hub_set_power_port_request(&request, port); 432 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 433 printf("[usb_hub] powering port %d\n",port); 434 if (opResult != EOK) { 435 printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port); 436 } 437 } 438 //ports powered, hub seems to be enabled 439 440 441 ipc_hangup(hc); 442 443 //add the hub to list 444 usb_lst_append(&usb_hub_list, hub_info); 445 printf("[usb_hub] hub info added to list\n"); 446 //(void)hub_info; 447 usb_hub_check_hub_changes(); 448 449 /// \TODO start the check loop, if not already started... 450 451 //this is just a test for port status bitmap type 452 usb_hub_test_port_status(); 453 454 printf("[usb_hub] hub dev added\n"); 455 printf("\taddress %d, has %d ports \n", 456 hub_info->usb_device->address, 457 hub_info->port_count); 458 printf("\tused configuration %d\n",config_descriptor.configuration_number); 134 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev); 135 (void)hub_info; 459 136 460 137 return EOK; … … 462 139 } 463 140 464 //*********************************************465 //466 // hub driver code, main loop467 //468 //*********************************************469 470 /**471 * reset the port with new device and reserve the default address472 * @param hc473 * @param port474 * @param target475 */476 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {477 usb_device_request_setup_packet_t request;478 int opResult;479 printf("[usb_hub] some connection changed\n");480 //get default address481 opResult = usb_drv_reserve_default_address(hc);482 if (opResult != EOK) {483 printf("[usb_hub] cannot assign default address, it is probably used\n");484 return;485 }486 //reset port487 usb_hub_set_reset_port_request(&request, port);488 opResult = usb_drv_sync_control_write(489 hc, target,490 &request,491 NULL, 0492 );493 if (opResult != EOK) {494 //continue;495 printf("[usb_hub] something went wrong when reseting a port\n");496 }497 }498 499 /**500 * finalize adding new device after port reset501 * @param hc502 * @param port503 * @param target504 */505 static void usb_hub_finalize_add_device( usb_hub_info_t * hub,506 int hc, uint16_t port, usb_target_t target) {507 508 int opResult;509 printf("[usb_hub] finalizing add device\n");510 opResult = usb_hub_clear_port_feature(hc, target.address,511 port, USB_HUB_FEATURE_C_PORT_RESET);512 if (opResult != EOK) {513 goto release;514 }515 516 /* Request address at from host controller. */517 usb_address_t new_device_address = usb_drv_request_address(hc);518 if (new_device_address < 0) {519 printf("[usb_hub] failed to get free USB address\n");520 opResult = new_device_address;521 goto release;522 }523 printf("[usb_hub] setting new address\n");524 opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,525 new_device_address);526 527 if (opResult != EOK) {528 printf("[usb_hub] could not set address for new device\n");529 goto release;530 }531 532 release:533 printf("[usb_hub] releasing default address\n");534 usb_drv_release_default_address(hc);535 if (opResult != EOK) {536 return;537 }538 539 devman_handle_t child_handle;540 opResult = usb_drv_register_child_in_devman(hc, hub->device,541 new_device_address, &child_handle);542 if (opResult != EOK) {543 printf("[usb_hub] could not start driver for new device \n");544 return;545 }546 hub->attached_devs[port].devman_handle = child_handle;547 hub->attached_devs[port].address = new_device_address;548 549 opResult = usb_drv_bind_address(hc, new_device_address, child_handle);550 if (opResult != EOK) {551 printf("[usb_hub] could not assign address of device in hcd \n");552 return;553 }554 printf("[usb_hub] new device address %d, handle %d\n",555 new_device_address, child_handle);556 557 }558 559 /**560 * unregister device address in hc, close the port561 * @param hc562 * @param port563 * @param target564 */565 static void usb_hub_removed_device(566 usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {567 //usb_device_request_setup_packet_t request;568 int opResult;569 //disable port570 /*usb_hub_set_disable_port_request(&request, port);571 opResult = usb_drv_sync_control_write(572 hc, target,573 &request,574 NULL, 0575 );576 if (opResult != EOK) {577 //continue;578 printf("[usb_hub] something went wrong when disabling a port\n");579 }*/580 /// \TODO remove device581 582 hub->attached_devs[port].devman_handle=0;583 //close address584 if(hub->attached_devs[port].address!=0){585 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);586 if(opResult != EOK) {587 printf("[usb_hub] could not release address of removed device: %d\n",opResult);588 }589 hub->attached_devs[port].address = 0;590 }else{591 printf("[usb_hub] this is strange, disconnected device had no address\n");592 //device was disconnected before it`s port was reset - return default address593 usb_drv_release_default_address(hc);594 }595 }596 597 /**598 * process interrupts on given hub port599 * @param hc600 * @param port601 * @param target602 */603 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,604 uint16_t port, usb_address_t address) {605 printf("[usb_hub] interrupt at port %d\n", port);606 //determine type of change607 usb_target_t target;608 target.address=address;609 target.endpoint=0;610 usb_port_status_t status;611 size_t rcvd_size;612 usb_device_request_setup_packet_t request;613 int opResult;614 usb_hub_set_port_status_request(&request, port);615 //endpoint 0616 617 opResult = usb_drv_sync_control_read(618 hc, target,619 &request,620 &status, 4, &rcvd_size621 );622 if (opResult != EOK) {623 printf("[usb_hub] ERROR: could not get port status\n");624 return;625 }626 if (rcvd_size != sizeof (usb_port_status_t)) {627 printf("[usb_hub] ERROR: received status has incorrect size\n");628 return;629 }630 //something connected/disconnected631 if (usb_port_connect_change(&status)) {632 opResult = usb_hub_clear_port_feature(hc, target.address,633 port, USB_HUB_FEATURE_C_PORT_CONNECTION);634 // TODO: check opResult635 if (usb_port_dev_connected(&status)) {636 printf("[usb_hub] some connection changed\n");637 usb_hub_init_add_device(hc, port, target);638 } else {639 usb_hub_removed_device(hub, hc, port, target);640 }641 }642 //port reset643 if (usb_port_reset_completed(&status)) {644 printf("[usb_hub] port reset complete\n");645 if (usb_port_enabled(&status)) {646 usb_hub_finalize_add_device(hub, hc, port, target);647 } else {648 printf("[usb_hub] ERROR: port reset, but port still not enabled\n");649 }650 }651 652 usb_port_set_connect_change(&status, false);653 usb_port_set_reset(&status, false);654 usb_port_set_reset_completed(&status, false);655 usb_port_set_dev_connected(&status, false);656 if (status) {657 printf("[usb_hub]there was some unsupported change on port %d\n",port);658 }659 /// \TODO handle other changes660 /// \TODO debug log for various situations661 662 663 664 /*665 //configure device666 usb_drv_reserve_default_address(hc);667 668 usb_address_t new_device_address = usb_drv_request_address(hc);669 670 671 usb_drv_release_default_address(hc);672 * */673 }674 141 675 142 /** Check changes on all known hubs. 676 143 */ 677 void usb_hub_check_hub_changes(void) {144 static void check_hub_changes(void) { 678 145 /* 679 146 * Iterate through all hubs. 680 147 */ 681 usb_general_list_t * lst_item; 682 for (lst_item = usb_hub_list.next; 683 lst_item != &usb_hub_list; 684 lst_item = lst_item->next) { 685 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 148 for (; false; ) { 686 149 /* 687 150 * Check status change pipe of this hub. 688 151 */ 689 690 usb_target_t target; 691 target.address = hub_info->usb_device->address; 692 target.endpoint = 1;/// \TODO get from endpoint descriptor 693 printf("[usb_hub] checking changes for hub at addr %d\n", 694 target.address); 695 696 size_t port_count = hub_info->port_count; 152 usb_target_t target = { 153 .address = 5, 154 .endpoint = 1 155 }; 156 157 size_t port_count = 7; 697 158 698 159 /* 699 160 * Connect to respective HC. 700 161 */ 701 int hc = usb_drv_hc_connect( hub_info->device, 0);162 int hc = usb_drv_hc_connect(NULL, 0); 702 163 if (hc < 0) { 703 164 continue; … … 705 166 706 167 // FIXME: count properly 707 size_t byte_length = ( (port_count+1)/ 8) + 1;168 size_t byte_length = (port_count / 8) + 1; 708 169 709 170 void *change_bitmap = malloc(byte_length); … … 713 174 /* 714 175 * Send the request. 715 */ 716 int opResult = usb_drv_async_interrupt_in(hc, target, 176 * FIXME: check returned value for possible errors 177 */ 178 usb_drv_async_interrupt_in(hc, target, 717 179 change_bitmap, byte_length, &actual_size, 718 180 &handle); 719 181 720 182 usb_drv_async_wait_for(handle); 721 722 if (opResult != EOK) {723 printf("[usb_hub] something went wrong while getting status of hub\n");724 continue;725 }726 unsigned int port;727 for (port = 1; port < port_count+1; ++port) {728 bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;729 if (interrupt) {730 usb_hub_process_interrupt(731 hub_info, hc, port, hub_info->usb_device->address);732 }733 }734 735 183 736 184 /*
Note:
See TracChangeset
for help on using the changeset viewer.