Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/utils.c

    ree0d8a8 r9ca0013  
    4343#include <usb/classes/hub.h>
    4444#include "usbhub.h"
    45 #include "usbhub_private.h"
    46 #include "port_status.h"
    47 #include <usb/devreq.h>
    4845
    4946static void check_hub_changes(void);
     
    5653//
    5754//*********************************************
    58 
    59 //hub descriptor utils
    6055
    6156void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     
    8984usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
    9085        uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
    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 
     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];
    10089        result->ports_count = sdescriptor[2];
    10190        /// @fixme handling of endianness??
     
    10594        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
    10695        result->devices_removable = (uint8_t*) malloc(var_size);
    107         //printf("[usb_hub] getting removable devices data \n");
     96
    10897        size_t i;
    10998        for (i = 0; i < var_size; ++i) {
     
    113102}
    114103
    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 }
    293 
    294 //*********************************************
    295 //
    296 //  hub driver code, initialization
    297 //
    298 //*********************************************
    299 
    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         printf("[usb_hub] addres of newly created hub = %d\n", addr);
    313         /*if(addr<0){
    314                 //return result;
    315                
    316         }*/
    317 
    318         result->device = usb_new(usb_hcd_attached_device_info_t);
    319         result->device->address = addr;
    320 
    321         // get hub descriptor
    322         usb_target_t target;
    323         target.address = addr;
    324         target.endpoint = 0;
    325         usb_device_request_setup_packet_t request;
    326         //printf("[usb_hub] creating descriptor request\n");
    327         usb_hub_set_descriptor_request(&request);
    328 
    329         //printf("[usb_hub] creating serialized descriptor\n");
    330         void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    331         usb_hub_descriptor_t * descriptor;
    332         size_t received_size;
    333         int opResult;
    334         //printf("[usb_hub] starting control transaction\n");
    335         opResult = usb_drv_sync_control_read(
    336                         hc, target, &request, serialized_descriptor,
    337                         USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    338         if (opResult != EOK) {
    339                 printf("[usb_hub] failed when receiving hub descriptor, badcode = %d\n",opResult);
    340                 ///\TODO memory leak will occur here!
    341                 return result;
    342         }
    343         //printf("[usb_hub] deserializing descriptor\n");
    344         descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    345         if(descriptor==NULL){
    346                 printf("[usb_hub] could not deserialize descriptor \n");
    347                 result->port_count = 1;///\TODO this code is only for debug!!!
    348                 return result;
    349         }
    350         //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
    351         result->port_count = descriptor->ports_count;
    352         //printf("[usb_hub] freeing data\n");
    353         free(serialized_descriptor);
    354         free(descriptor->devices_removable);
    355         free(descriptor);
    356 
    357         //finish
    358 
    359         printf("[usb_hub] hub info created\n");
     104
     105//*********************************************
     106//
     107//  hub driver code
     108//
     109//*********************************************
     110
     111usb_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));
    360113
    361114        return result;
     
    369122int usb_add_hub_device(device_t *dev) {
    370123        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    371         printf("[usb_hub] hub device\n");
     124
     125        check_hub_changes();
    372126
    373127        /*
     
    378132
    379133        //create the hub structure
    380         //get hc connection
    381         /// \TODO correct params
    382         int hc = usb_drv_hc_connect(dev, 0);
    383 
    384         usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
    385         int port;
    386         int opResult;
    387         usb_device_request_setup_packet_t request;
    388         usb_target_t target;
    389         target.address = hub_info->device->address;
    390         target.endpoint = 0;
    391         for (port = 0; port < hub_info->port_count; ++port) {
    392                 usb_hub_set_power_port_request(&request, port);
    393                 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    394                 if (opResult != EOK) {
    395                         printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port);
    396                 }
    397         }
    398         //ports powered, hub seems to be enabled
    399 
    400         ipc_hangup(hc);
    401 
    402         //add the hub to list
    403         usb_lst_append(&usb_hub_list, hub_info);
    404         printf("[usb_hub] hub info added to list\n");
    405         //(void)hub_info;
    406         check_hub_changes();
    407 
    408         /// \TODO start the check loop, if not already started...
    409 
    410         //this is just a test for port status bitmap type
    411         usb_hub_test_port_status();
    412 
    413         printf("[usb_hub] hub dev added\n");
     134        usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
     135        (void)hub_info;
    414136
    415137        return EOK;
     
    417139}
    418140
    419 //*********************************************
    420 //
    421 //  hub driver code, main loop
    422 //
    423 //*********************************************
    424 
    425 /**
    426  * reset the port with new device and reserve the default address
    427  * @param hc
    428  * @param port
    429  * @param target
    430  */
    431 
    432 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
    433         usb_device_request_setup_packet_t request;
    434         int opResult;
    435         printf("[usb_hub] some connection changed\n");
    436 
    437         opResult = usb_drv_reserve_default_address(hc);
    438         if (opResult != EOK) {
    439                 printf("[usb_hub] cannot assign default address, it is probably used\n");
    440                 return;
    441         }
    442         //reset port
    443         usb_hub_set_reset_port_request(&request, port);
    444         opResult = usb_drv_sync_control_write(
    445                         hc, target,
    446                         &request,
    447                         NULL, 0
    448                         );
    449         if (opResult != EOK) {
    450                 //continue;
    451                 printf("[usb_hub] something went wrong when reseting a port\n");
    452         }
    453 }
    454 
    455 /**
    456  * finalize adding new device after port reset
    457  * @param hc
    458  * @param port
    459  * @param target
    460  */
    461 static void usb_hub_finalize_add_device(
    462                 int hc, uint16_t port, usb_target_t target) {
    463 
    464         usb_device_request_setup_packet_t request;
    465         int opResult;
    466         printf("[usb_hub] finalizing add device\n");
    467         usb_address_t new_device_address =
    468                         usb_drv_request_address(hc);
    469         usb_hub_set_set_address_request
    470                         (&request, new_device_address);
    471         opResult = usb_drv_sync_control_write(
    472                         hc, target,
    473                         &request,
    474                         NULL, 0
    475                         );
    476         if (opResult != EOK) {
    477                 printf("[usb_hub] could not set address for new device\n");
    478                 //will retry later...
    479                 return;
    480         }
    481         usb_drv_release_default_address(hc);
    482 
    483 
    484         /// \TODO driver work
    485         //add_child_device.....
    486 }
    487 
    488 /**
    489  * unregister device address in hc, close the port
    490  * @param hc
    491  * @param port
    492  * @param target
    493  */
    494 static void usb_hub_removed_device(int hc, uint16_t port, usb_target_t target) {
    495         usb_device_request_setup_packet_t request;
    496         int opResult;
    497         //disable port
    498         usb_hub_set_disable_port_request(&request, port);
    499         opResult = usb_drv_sync_control_write(
    500                         hc, target,
    501                         &request,
    502                         NULL, 0
    503                         );
    504         if (opResult != EOK) {
    505                 //continue;
    506                 printf("[usb_hub] something went wrong when disabling a port\n");
    507         }
    508         //remove device
    509         //close address
    510         //
    511 
    512         ///\TODO this code is not complete
    513 }
    514 
    515 /**
    516  * process interrupts on given hub port
    517  * @param hc
    518  * @param port
    519  * @param target
    520  */
    521 static void usb_hub_process_interrupt(int hc, uint16_t port, usb_target_t target) {
    522         printf("[usb_hub] interrupt at port %d\n", port);
    523         //determine type of change
    524         usb_port_status_t status;
    525         size_t rcvd_size;
    526         usb_device_request_setup_packet_t request;
    527         int opResult;
    528         usb_hub_set_port_status_request(&request, port);
    529 
    530         opResult = usb_drv_sync_control_read(
    531                         hc, target,
    532                         &request,
    533                         &status, 4, &rcvd_size
    534                         );
    535         if (opResult != EOK) {
    536                 printf("[usb_hub] ERROR: could not get port status\n");
    537                 return;
    538         }
    539         if (rcvd_size != sizeof (usb_port_status_t)) {
    540                 printf("[usb_hub] ERROR: received status has incorrect size\n");
    541                 return;
    542         }
    543         //something connected/disconnected
    544         if (usb_port_connect_change(&status)) {
    545                 if (usb_port_dev_connected(&status)) {
    546                         printf("[usb_hub] some connection changed\n");
    547                         usb_hub_init_add_device(hc, port, target);
    548                 } else {
    549                         usb_hub_removed_device(hc, port, target);
    550                 }
    551         }
    552         //port reset
    553         if (usb_port_reset_completed(&status)) {
    554                 printf("[usb_hub] finalizing add device\n");
    555                 if (usb_port_enabled(&status)) {
    556                         usb_hub_finalize_add_device(hc, port, target);
    557                 } else {
    558                         printf("[usb_hub] ERROR: port reset, but port still not enabled\n");
    559                 }
    560         }
    561 
    562         usb_port_set_connect_change(&status, false);
    563         usb_port_set_reset(&status, false);
    564         usb_port_set_reset_completed(&status, false);
    565         usb_port_set_dev_connected(&status, false);
    566         if (status) {
    567                 printf("[usb_hub]there was some unsupported change on port\n");
    568         }
    569         /// \TODO handle other changes
    570         /// \TODO debug log for various situations
    571 
    572 
    573 
    574         /*
    575         //configure device
    576         usb_drv_reserve_default_address(hc);
    577 
    578         usb_address_t new_device_address = usb_drv_request_address(hc);
    579 
    580 
    581         usb_drv_release_default_address(hc);
    582          * */
    583 }
    584141
    585142/** Check changes on all known hubs.
     
    589146         * Iterate through all hubs.
    590147         */
    591         usb_general_list_t * lst_item;
    592         for (lst_item = usb_hub_list.next;
    593                         lst_item != &usb_hub_list;
    594                         lst_item = lst_item->next) {
    595                 printf("[usb_hub] checking hub changes\n");
     148        for (; false; ) {
    596149                /*
    597150                 * Check status change pipe of this hub.
    598151                 */
    599 
    600152                usb_target_t target = {
    601153                        .address = 5,
    602154                        .endpoint = 1
    603155                };
    604                 /// \TODO uncomment once it works correctly
    605                 //target.address = usb_create_hub_info(lst_item)->device->address;
    606156
    607157                size_t port_count = 7;
     
    610160                 * Connect to respective HC.
    611161                 */
    612                 /// \FIXME this is incorrect code: here
    613                 /// must be used particular device instead of NULL
    614                 //which one?
    615162                int hc = usb_drv_hc_connect(NULL, 0);
    616163                if (hc < 0) {
     
    627174                /*
    628175                 * Send the request.
    629                  */
    630                 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,
    631179                                change_bitmap, byte_length, &actual_size,
    632180                                &handle);
    633181
    634182                usb_drv_async_wait_for(handle);
    635 
    636                 if (opResult != EOK) {
    637                         printf("[usb_hub] something went wrong while getting status of hub\n");
    638                         continue;
    639                 }
    640                 unsigned int port;
    641                 for (port = 0; port < port_count; ++port) {
    642                         bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
    643                         if (interrupt) {
    644                                 usb_hub_process_interrupt(hc, port, target);
    645                         }
    646                 }
    647 
    648183
    649184                /*
Note: See TracChangeset for help on using the changeset viewer.