Changeset 82122f3 in mainline for uspace/drv/usbhub/utils.c


Ignore:
Timestamp:
2010-12-17T14:51:41Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1f383dde
Parents:
692f13e4 (diff), 11658b64 (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:

Merged development into lelian/hidd

File:
1 edited

Legend:

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

    r692f13e4 r82122f3  
    3434 */
    3535#include <driver.h>
    36 #include <usb/devreq.h>
     36#include <bool.h>
     37#include <errno.h>
     38
    3739#include <usbhc_iface.h>
    3840#include <usb/usbdrv.h>
    3941#include <usb/descriptor.h>
    40 #include <driver.h>
    41 #include <bool.h>
    42 #include <errno.h>
     42#include <usb/devreq.h>
    4343#include <usb/classes/hub.h>
     44
    4445#include "usbhub.h"
    4546#include "usbhub_private.h"
    4647#include "port_status.h"
    47 #include <usb/devreq.h>
    48 
    49 static void check_hub_changes(void);
     48
    5049
    5150size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
     
    302301        //result->device = device;
    303302        result->port_count = -1;
     303        /// \TODO is this correct? is the device stored?
     304        result->device = device;
    304305
    305306
     
    316317        }*/
    317318
    318         result->device = usb_new(usb_hcd_attached_device_info_t);
    319         result->device->address = addr;
     319        result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     320        result->usb_device->address = addr;
    320321
    321322        // get hub descriptor
     
    350351        //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
    351352        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        }
    352360        //printf("[usb_hub] freeing data\n");
    353361        free(serialized_descriptor);
     
    362370}
    363371
    364 /** Callback when new hub device is detected.
    365  *
    366  * @param dev New device.
    367  * @return Error code.
    368  */
    369372int usb_add_hub_device(device_t *dev) {
    370373        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
     
    387390        usb_device_request_setup_packet_t request;
    388391        usb_target_t target;
    389         target.address = hub_info->device->address;
     392        target.address = hub_info->usb_device->address;
    390393        target.endpoint = 0;
    391         for (port = 0; port < hub_info->port_count; ++port) {
     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) {
    392431                usb_hub_set_power_port_request(&request, port);
    393432                opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     433                printf("[usb_hub] powering port %d\n",port);
    394434                if (opResult != EOK) {
    395435                        printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port);
     
    397437        }
    398438        //ports powered, hub seems to be enabled
     439       
    399440
    400441        ipc_hangup(hc);
     
    404445        printf("[usb_hub] hub info added to list\n");
    405446        //(void)hub_info;
    406         check_hub_changes();
     447        usb_hub_check_hub_changes();
    407448
    408449        /// \TODO start the check loop, if not already started...
     
    412453
    413454        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);
    414459
    415460        return EOK;
     
    429474 * @param target
    430475 */
    431 
    432476static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
    433477        usb_device_request_setup_packet_t request;
    434478        int opResult;
    435479        printf("[usb_hub] some connection changed\n");
    436 
     480        //get default address
    437481        opResult = usb_drv_reserve_default_address(hc);
    438482        if (opResult != EOK) {
     
    459503 * @param target
    460504 */
    461 static void usb_hub_finalize_add_device(
     505static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    462506                int hc, uint16_t port, usb_target_t target) {
    463507
    464         usb_device_request_setup_packet_t request;
    465508        int opResult;
    466509        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);
     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
     532release:
     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 %zu\n",
     555            new_device_address, child_handle);
     556       
     557}
     558
     559/**
     560 * unregister device address in hc, close the port
     561 * @param hc
     562 * @param port
     563 * @param target
     564 */
     565static 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 port
     570        /*usb_hub_set_disable_port_request(&request, port);
    471571        opResult = usb_drv_sync_control_write(
    472572                        hc, target,
     
    475575                        );
    476576        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) {
    505577                //continue;
    506578                printf("[usb_hub] something went wrong when disabling a port\n");
    507         }
    508         //remove device
     579        }*/
     580        /// \TODO remove device
     581
     582        hub->attached_devs[port].devman_handle=0;
    509583        //close address
    510         //
    511 
    512         ///\TODO this code is not complete
     584        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 address
     593                usb_drv_release_default_address(hc);
     594        }
    513595}
    514596
     
    519601 * @param target
    520602 */
    521 static void usb_hub_process_interrupt(int hc, uint16_t port, usb_target_t target) {
     603static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
     604        uint16_t port, usb_address_t address) {
    522605        printf("[usb_hub] interrupt at port %d\n", port);
    523606        //determine type of change
     607        usb_target_t target;
     608        target.address=address;
     609        target.endpoint=0;
    524610        usb_port_status_t status;
    525611        size_t rcvd_size;
     
    527613        int opResult;
    528614        usb_hub_set_port_status_request(&request, port);
     615        //endpoint 0
    529616
    530617        opResult = usb_drv_sync_control_read(
     
    543630        //something connected/disconnected
    544631        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 opResult
    545635                if (usb_port_dev_connected(&status)) {
    546636                        printf("[usb_hub] some connection changed\n");
    547637                        usb_hub_init_add_device(hc, port, target);
    548638                } else {
    549                         usb_hub_removed_device(hc, port, target);
     639                        usb_hub_removed_device(hub, hc, port, target);
    550640                }
    551641        }
    552642        //port reset
    553643        if (usb_port_reset_completed(&status)) {
    554                 printf("[usb_hub] finalizing add device\n");
     644                printf("[usb_hub] port reset complete\n");
    555645                if (usb_port_enabled(&status)) {
    556                         usb_hub_finalize_add_device(hc, port, target);
     646                        usb_hub_finalize_add_device(hub, hc, port, target);
    557647                } else {
    558648                        printf("[usb_hub] ERROR: port reset, but port still not enabled\n");
     
    565655        usb_port_set_dev_connected(&status, false);
    566656        if (status) {
    567                 printf("[usb_hub]there was some unsupported change on port\n");
     657                printf("[usb_hub]there was some unsupported change on port %d\n",port);
    568658        }
    569659        /// \TODO handle other changes
     
    585675/** Check changes on all known hubs.
    586676 */
    587 static void check_hub_changes(void) {
     677void usb_hub_check_hub_changes(void) {
    588678        /*
    589679         * Iterate through all hubs.
     
    593683                        lst_item != &usb_hub_list;
    594684                        lst_item = lst_item->next) {
    595                 printf("[usb_hub] checking hub changes\n");
     685                usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    596686                /*
    597687                 * Check status change pipe of this hub.
    598688                 */
    599689
    600                 usb_target_t target = {
    601                         .address = 5,
    602                         .endpoint = 1
    603                 };
    604                 /// \TODO uncomment once it works correctly
    605                 //target.address = usb_create_hub_info(lst_item)->device->address;
    606 
    607                 size_t port_count = 7;
     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;
    608697
    609698                /*
    610699                 * Connect to respective HC.
    611700                 */
    612                 /// \FIXME this is incorrect code: here
    613                 /// must be used particular device instead of NULL
    614                 //which one?
    615                 int hc = usb_drv_hc_connect(NULL, 0);
     701                int hc = usb_drv_hc_connect(hub_info->device, 0);
    616702                if (hc < 0) {
    617703                        continue;
     
    619705
    620706                // FIXME: count properly
    621                 size_t byte_length = (port_count / 8) + 1;
     707                size_t byte_length = ((port_count+1) / 8) + 1;
    622708
    623709                void *change_bitmap = malloc(byte_length);
     
    639725                }
    640726                unsigned int port;
    641                 for (port = 0; port < port_count; ++port) {
     727                for (port = 1; port < port_count+1; ++port) {
    642728                        bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
    643729                        if (interrupt) {
    644                                 usb_hub_process_interrupt(hc, port, target);
     730                                usb_hub_process_interrupt(
     731                                        hub_info, hc, port, hub_info->usb_device->address);
    645732                        }
    646733                }
Note: See TracChangeset for help on using the changeset viewer.