Changeset 8365533 in mainline for uspace/drv/usbhub/utils.c


Ignore:
Timestamp:
2010-12-12T10:54:43Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8dc569a, ec6ab88
Parents:
243cb86 (diff), 5174c62 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from development

File:
1 edited

Legend:

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

    r243cb86 r8365533  
    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        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");
    113360
    114361        return result;
     
    122369int usb_add_hub_device(device_t *dev) {
    123370        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    124 
    125         check_hub_changes();
     371        printf("[usb_hub] hub device\n");
    126372
    127373        /*
     
    132378
    133379        //create the hub structure
    134         usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
    135         (void)hub_info;
     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");
    136414
    137415        return EOK;
     
    139417}
    140418
     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
     432static 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 */
     461static 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 */
     494static 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 */
     521static 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}
    141584
    142585/** Check changes on all known hubs.
     
    146589         * Iterate through all hubs.
    147590         */
    148         for (; false; ) {
     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");
    149596                /*
    150597                 * Check status change pipe of this hub.
    151598                 */
     599
    152600                usb_target_t target = {
    153601                        .address = 5,
    154602                        .endpoint = 1
    155603                };
     604                /// \TODO uncomment once it works correctly
     605                //target.address = usb_create_hub_info(lst_item)->device->address;
    156606
    157607                size_t port_count = 7;
     
    160610                 * Connect to respective HC.
    161611                 */
     612                /// \FIXME this is incorrect code: here
     613                /// must be used particular device instead of NULL
     614                //which one?
    162615                int hc = usb_drv_hc_connect(NULL, 0);
    163616                if (hc < 0) {
     
    174627                /*
    175628                 * Send the request.
    176                  * FIXME: check returned value for possible errors
    177                  */
    178                 usb_drv_async_interrupt_in(hc, target,
     629                 */
     630                int opResult = usb_drv_async_interrupt_in(hc, target,
    179631                                change_bitmap, byte_length, &actual_size,
    180632                                &handle);
    181633
    182634                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
    183648
    184649                /*
Note: See TracChangeset for help on using the changeset viewer.