Ignore:
File:
1 edited

Legend:

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

    r9ca0013 r10096231  
    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>
    4548
    4649static void check_hub_changes(void);
     
    5356//
    5457//*********************************************
     58
     59//hub descriptor utils
    5560
    5661void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     
    8489usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
    8590        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
    89100        result->ports_count = sdescriptor[2];
    90101        /// @fixme handling of endianness??
     
    94105        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
    95106        result->devices_removable = (uint8_t*) malloc(var_size);
    96 
     107        //printf("[usb_hub] getting removable devices data \n");
    97108        size_t i;
    98109        for (i = 0; i < var_size; ++i) {
     
    102113}
    103114
     115//control transactions
     116
     117int 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
     159int 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
     203usb_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
     209void usb_lst_init(usb_general_list_t * lst) {
     210        lst->prev = lst;
     211        lst->next = lst;
     212        lst->data = NULL;
     213}
     214
     215void 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
     224void 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
     233void usb_lst_remove(usb_general_list_t* item) {
     234        item->next->prev = item->prev;
     235        item->prev->next = item->next;
     236}
     237
     238static 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}
    104293
    105294//*********************************************
    106295//
    107 //  hub driver code
     296//  hub driver code, initialization
    108297//
    109298//*********************************************
    110299
    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));
     300usb_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");
    113361
    114362        return result;
     
    122370int usb_add_hub_device(device_t *dev) {
    123371        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    124 
    125         check_hub_changes();
     372        printf("[usb_hub] hub device\n");
    126373
    127374        /*
     
    132379
    133380        //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");
    136415
    137416        return EOK;
     
    139418}
    140419
     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
     433static 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 */
     462static 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 */
     495static 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 */
     522static 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}
    141585
    142586/** Check changes on all known hubs.
     
    146590         * Iterate through all hubs.
    147591         */
    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");
    149597                /*
    150598                 * Check status change pipe of this hub.
    151599                 */
     600
    152601                usb_target_t target = {
    153602                        .address = 5,
    154603                        .endpoint = 1
    155604                };
     605                /// \TODO uncomment once it works correctly
     606                //target.address = usb_create_hub_info(lst_item)->device->address;
    156607
    157608                size_t port_count = 7;
     
    160611                 * Connect to respective HC.
    161612                 */
     613                /// \FIXME this is incorrect code: here
     614                /// must be used particular device instead of NULL
     615                //which one?
    162616                int hc = usb_drv_hc_connect(NULL, 0);
    163617                if (hc < 0) {
     
    174628                /*
    175629                 * 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,
    179632                                change_bitmap, byte_length, &actual_size,
    180633                                &handle);
    181634
    182635                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
    183649
    184650                /*
Note: See TracChangeset for help on using the changeset viewer.