Changes in uspace/drv/usbhub/utils.c [9ca0013:10096231] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/utils.c
r9ca0013 r10096231 43 43 #include <usb/classes/hub.h> 44 44 #include "usbhub.h" 45 #include "usbhub_private.h" 46 #include "port_status.h" 47 #include <usb/devreq.h> 45 48 46 49 static void check_hub_changes(void); … … 53 56 // 54 57 //********************************************* 58 59 //hub descriptor utils 55 60 56 61 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) { … … 84 89 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) { 85 90 uint8_t * sdescriptor = (uint8_t*) serialized_descriptor; 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]; 91 92 if (sdescriptor[1] != USB_DESCTYPE_HUB) { 93 printf("[usb_hub] wrong descriptor %x\n",sdescriptor[1]); 94 return NULL; 95 } 96 97 usb_hub_descriptor_t * result = usb_new(usb_hub_descriptor_t); 98 99 89 100 result->ports_count = sdescriptor[2]; 90 101 /// @fixme handling of endianness?? … … 94 105 size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0); 95 106 result->devices_removable = (uint8_t*) malloc(var_size); 96 107 //printf("[usb_hub] getting removable devices data \n"); 97 108 size_t i; 98 109 for (i = 0; i < var_size; ++i) { … … 102 113 } 103 114 115 //control transactions 116 117 int usb_drv_sync_control_read( 118 int phone, usb_target_t target, 119 usb_device_request_setup_packet_t * request, 120 void * rcvd_buffer, size_t rcvd_size, size_t * actual_size 121 ) { 122 usb_handle_t handle; 123 int opResult; 124 //setup 125 opResult = usb_drv_async_control_read_setup(phone, target, 126 request, sizeof (usb_device_request_setup_packet_t), 127 &handle); 128 if (opResult != EOK) { 129 return opResult; 130 } 131 opResult = usb_drv_async_wait_for(handle); 132 if (opResult != EOK) { 133 return opResult; 134 } 135 //read 136 opResult = usb_drv_async_control_read_data(phone, target, 137 rcvd_buffer, rcvd_size, actual_size, 138 &handle); 139 if (opResult != EOK) { 140 return opResult; 141 } 142 opResult = usb_drv_async_wait_for(handle); 143 if (opResult != EOK) { 144 return opResult; 145 } 146 //finalize 147 opResult = usb_drv_async_control_read_status(phone, target, 148 &handle); 149 if (opResult != EOK) { 150 return opResult; 151 } 152 opResult = usb_drv_async_wait_for(handle); 153 if (opResult != EOK) { 154 return opResult; 155 } 156 return EOK; 157 } 158 159 int usb_drv_sync_control_write( 160 int phone, usb_target_t target, 161 usb_device_request_setup_packet_t * request, 162 void * sent_buffer, size_t sent_size 163 ) { 164 usb_handle_t handle; 165 int opResult; 166 //setup 167 opResult = usb_drv_async_control_write_setup(phone, target, 168 request, sizeof (usb_device_request_setup_packet_t), 169 &handle); 170 if (opResult != EOK) { 171 return opResult; 172 } 173 opResult = usb_drv_async_wait_for(handle); 174 if (opResult != EOK) { 175 return opResult; 176 } 177 //write 178 opResult = usb_drv_async_control_write_data(phone, target, 179 sent_buffer, sent_size, 180 &handle); 181 if (opResult != EOK) { 182 return opResult; 183 } 184 opResult = usb_drv_async_wait_for(handle); 185 if (opResult != EOK) { 186 return opResult; 187 } 188 //finalize 189 opResult = usb_drv_async_control_write_status(phone, target, 190 &handle); 191 if (opResult != EOK) { 192 return opResult; 193 } 194 opResult = usb_drv_async_wait_for(handle); 195 if (opResult != EOK) { 196 return opResult; 197 } 198 return EOK; 199 } 200 201 //list implementation 202 203 usb_general_list_t * usb_lst_create(void) { 204 usb_general_list_t* result = usb_new(usb_general_list_t); 205 usb_lst_init(result); 206 return result; 207 } 208 209 void usb_lst_init(usb_general_list_t * lst) { 210 lst->prev = lst; 211 lst->next = lst; 212 lst->data = NULL; 213 } 214 215 void usb_lst_prepend(usb_general_list_t* item, void* data) { 216 usb_general_list_t* appended = usb_new(usb_general_list_t); 217 appended->data = data; 218 appended->next = item; 219 appended->prev = item->prev; 220 item->prev->next = appended; 221 item->prev = appended; 222 } 223 224 void usb_lst_append(usb_general_list_t* item, void* data) { 225 usb_general_list_t* appended = usb_new(usb_general_list_t); 226 appended->data = data; 227 appended->next = item->next; 228 appended->prev = item; 229 item->next->prev = appended; 230 item->next = appended; 231 } 232 233 void usb_lst_remove(usb_general_list_t* item) { 234 item->next->prev = item->prev; 235 item->prev->next = item->next; 236 } 237 238 static void usb_hub_test_port_status(void) { 239 printf("[usb_hub] -------------port status test---------\n"); 240 usb_port_status_t status = 0; 241 242 //printf("original status %d (should be 0)\n",(uint32_t)status); 243 usb_port_set_bit(&status, 1, 1); 244 //printf("%d =?= 2\n",(uint32_t)status); 245 if (status != 2) { 246 printf("[usb_port_status] test failed: wrong set of bit 1\n"); 247 return; 248 } 249 usb_port_set_bit(&status, 3, 1); 250 if (status != 10) { 251 printf("[usb_port_status] test failed: wrong set of bit 3\n"); 252 return; 253 } 254 255 usb_port_set_bit(&status, 15, 1); 256 if (status != 10 + (1 << 15)) { 257 printf("[usb_port_status] test failed: wrong set of bit 15\n"); 258 return; 259 } 260 usb_port_set_bit(&status, 1, 0); 261 if (status != 8 + (1 << 15)) { 262 printf("[usb_port_status] test failed: wrong unset of bit 1\n"); 263 return; 264 } 265 int i; 266 for (i = 0; i < 32; ++i) { 267 if (i == 3 || i == 15) { 268 if (!usb_port_get_bit(&status, i)) { 269 printf("[usb_port_status] test failed: wrong bit at %d\n", i); 270 } 271 } else { 272 if (usb_port_get_bit(&status, i)) { 273 printf("[usb_port_status] test failed: wrong bit at %d\n", i); 274 } 275 } 276 } 277 278 printf("test ok\n"); 279 280 281 //printf("%d =?= 10\n",(uint32_t)status); 282 283 //printf("this should be 0: %d \n",usb_port_get_bit(&status,0)); 284 //printf("this should be 1: %d \n",usb_port_get_bit(&status,1)); 285 //printf("this should be 0: %d \n",usb_port_get_bit(&status,2)); 286 //printf("this should be 1: %d \n",usb_port_get_bit(&status,3)); 287 //printf("this should be 0: %d \n",usb_port_get_bit(&status,4)); 288 289 290 291 292 } 104 293 105 294 //********************************************* 106 295 // 107 // hub driver code 296 // hub driver code, initialization 108 297 // 109 298 //********************************************* 110 299 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)); 300 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) { 301 usb_hub_info_t* result = usb_new(usb_hub_info_t); 302 //result->device = device; 303 result->port_count = -1; 304 305 306 //printf("[usb_hub] phone to hc = %d\n", hc); 307 if (hc < 0) { 308 return result; 309 } 310 //get some hub info 311 usb_address_t addr = usb_drv_get_my_address(hc, device); 312 addr = 7; 313 printf("[usb_hub] addres of newly created hub = %d\n", addr); 314 /*if(addr<0){ 315 //return result; 316 317 }*/ 318 319 result->device = usb_new(usb_hcd_attached_device_info_t); 320 result->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 //printf("[usb_hub] freeing data\n"); 354 free(serialized_descriptor); 355 free(descriptor->devices_removable); 356 free(descriptor); 357 358 //finish 359 360 printf("[usb_hub] hub info created\n"); 113 361 114 362 return result; … … 122 370 int usb_add_hub_device(device_t *dev) { 123 371 printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle); 124 125 check_hub_changes(); 372 printf("[usb_hub] hub device\n"); 126 373 127 374 /* … … 132 379 133 380 //create the hub structure 134 usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev); 135 (void)hub_info; 381 //get hc connection 382 /// \TODO correct params 383 int hc = usb_drv_hc_connect(dev, 0); 384 385 usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc); 386 int port; 387 int opResult; 388 usb_device_request_setup_packet_t request; 389 usb_target_t target; 390 target.address = hub_info->device->address; 391 target.endpoint = 0; 392 for (port = 0; port < hub_info->port_count; ++port) { 393 usb_hub_set_power_port_request(&request, port); 394 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0); 395 if (opResult != EOK) { 396 printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port); 397 } 398 } 399 //ports powered, hub seems to be enabled 400 401 ipc_hangup(hc); 402 403 //add the hub to list 404 usb_lst_append(&usb_hub_list, hub_info); 405 printf("[usb_hub] hub info added to list\n"); 406 //(void)hub_info; 407 check_hub_changes(); 408 409 /// \TODO start the check loop, if not already started... 410 411 //this is just a test for port status bitmap type 412 usb_hub_test_port_status(); 413 414 printf("[usb_hub] hub dev added\n"); 136 415 137 416 return EOK; … … 139 418 } 140 419 420 //********************************************* 421 // 422 // hub driver code, main loop 423 // 424 //********************************************* 425 426 /** 427 * reset the port with new device and reserve the default address 428 * @param hc 429 * @param port 430 * @param target 431 */ 432 433 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) { 434 usb_device_request_setup_packet_t request; 435 int opResult; 436 printf("[usb_hub] some connection changed\n"); 437 438 opResult = usb_drv_reserve_default_address(hc); 439 if (opResult != EOK) { 440 printf("[usb_hub] cannot assign default address, it is probably used\n"); 441 return; 442 } 443 //reset port 444 usb_hub_set_reset_port_request(&request, port); 445 opResult = usb_drv_sync_control_write( 446 hc, target, 447 &request, 448 NULL, 0 449 ); 450 if (opResult != EOK) { 451 //continue; 452 printf("[usb_hub] something went wrong when reseting a port\n"); 453 } 454 } 455 456 /** 457 * finalize adding new device after port reset 458 * @param hc 459 * @param port 460 * @param target 461 */ 462 static void usb_hub_finalize_add_device( 463 int hc, uint16_t port, usb_target_t target) { 464 465 usb_device_request_setup_packet_t request; 466 int opResult; 467 printf("[usb_hub] finalizing add device\n"); 468 usb_address_t new_device_address = 469 usb_drv_request_address(hc); 470 usb_hub_set_set_address_request 471 (&request, new_device_address); 472 opResult = usb_drv_sync_control_write( 473 hc, target, 474 &request, 475 NULL, 0 476 ); 477 if (opResult != EOK) { 478 printf("[usb_hub] could not set address for new device\n"); 479 //will retry later... 480 return; 481 } 482 usb_drv_release_default_address(hc); 483 484 485 /// \TODO driver work 486 //add_child_device..... 487 } 488 489 /** 490 * unregister device address in hc, close the port 491 * @param hc 492 * @param port 493 * @param target 494 */ 495 static void usb_hub_removed_device(int hc, uint16_t port, usb_target_t target) { 496 usb_device_request_setup_packet_t request; 497 int opResult; 498 //disable port 499 usb_hub_set_disable_port_request(&request, port); 500 opResult = usb_drv_sync_control_write( 501 hc, target, 502 &request, 503 NULL, 0 504 ); 505 if (opResult != EOK) { 506 //continue; 507 printf("[usb_hub] something went wrong when disabling a port\n"); 508 } 509 //remove device 510 //close address 511 // 512 513 ///\TODO this code is not complete 514 } 515 516 /** 517 * process interrupts on given hub port 518 * @param hc 519 * @param port 520 * @param target 521 */ 522 static void usb_hub_process_interrupt(int hc, uint16_t port, usb_target_t target) { 523 printf("[usb_hub] interrupt at port %d\n", port); 524 //determine type of change 525 usb_port_status_t status; 526 size_t rcvd_size; 527 usb_device_request_setup_packet_t request; 528 int opResult; 529 usb_hub_set_port_status_request(&request, port); 530 531 opResult = usb_drv_sync_control_read( 532 hc, target, 533 &request, 534 &status, 4, &rcvd_size 535 ); 536 if (opResult != EOK) { 537 printf("[usb_hub] ERROR: could not get port status\n"); 538 return; 539 } 540 if (rcvd_size != sizeof (usb_port_status_t)) { 541 printf("[usb_hub] ERROR: received status has incorrect size\n"); 542 return; 543 } 544 //something connected/disconnected 545 if (usb_port_connect_change(&status)) { 546 if (usb_port_dev_connected(&status)) { 547 printf("[usb_hub] some connection changed\n"); 548 usb_hub_init_add_device(hc, port, target); 549 } else { 550 usb_hub_removed_device(hc, port, target); 551 } 552 } 553 //port reset 554 if (usb_port_reset_completed(&status)) { 555 printf("[usb_hub] finalizing add device\n"); 556 if (usb_port_enabled(&status)) { 557 usb_hub_finalize_add_device(hc, port, target); 558 } else { 559 printf("[usb_hub] ERROR: port reset, but port still not enabled\n"); 560 } 561 } 562 563 usb_port_set_connect_change(&status, false); 564 usb_port_set_reset(&status, false); 565 usb_port_set_reset_completed(&status, false); 566 usb_port_set_dev_connected(&status, false); 567 if (status) { 568 printf("[usb_hub]there was some unsupported change on port\n"); 569 } 570 /// \TODO handle other changes 571 /// \TODO debug log for various situations 572 573 574 575 /* 576 //configure device 577 usb_drv_reserve_default_address(hc); 578 579 usb_address_t new_device_address = usb_drv_request_address(hc); 580 581 582 usb_drv_release_default_address(hc); 583 * */ 584 } 141 585 142 586 /** Check changes on all known hubs. … … 146 590 * Iterate through all hubs. 147 591 */ 148 for (; false; ) { 592 usb_general_list_t * lst_item; 593 for (lst_item = usb_hub_list.next; 594 lst_item != &usb_hub_list; 595 lst_item = lst_item->next) { 596 printf("[usb_hub] checking hub changes\n"); 149 597 /* 150 598 * Check status change pipe of this hub. 151 599 */ 600 152 601 usb_target_t target = { 153 602 .address = 5, 154 603 .endpoint = 1 155 604 }; 605 /// \TODO uncomment once it works correctly 606 //target.address = usb_create_hub_info(lst_item)->device->address; 156 607 157 608 size_t port_count = 7; … … 160 611 * Connect to respective HC. 161 612 */ 613 /// \FIXME this is incorrect code: here 614 /// must be used particular device instead of NULL 615 //which one? 162 616 int hc = usb_drv_hc_connect(NULL, 0); 163 617 if (hc < 0) { … … 174 628 /* 175 629 * Send the request. 176 * FIXME: check returned value for possible errors 177 */ 178 usb_drv_async_interrupt_in(hc, target, 630 */ 631 int opResult = usb_drv_async_interrupt_in(hc, target, 179 632 change_bitmap, byte_length, &actual_size, 180 633 &handle); 181 634 182 635 usb_drv_async_wait_for(handle); 636 637 if (opResult != EOK) { 638 printf("[usb_hub] something went wrong while getting status of hub\n"); 639 continue; 640 } 641 unsigned int port; 642 for (port = 0; port < port_count; ++port) { 643 bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 644 if (interrupt) { 645 usb_hub_process_interrupt(hc, port, target); 646 } 647 } 648 183 649 184 650 /*
Note:
See TracChangeset
for help on using the changeset viewer.