Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changes in / [1dd264b:2cb6571] in mainline


Ignore:
Location:
uspace/lib/usb
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/hcdhubd.h

    r1dd264b r2cb6571  
    116116} usb_hcd_transfer_ops_t;
    117117
     118/**
     119 * @brief structure holding information about free and used addresses
     120 *
     121 * This structure should not be used outside usb hcd driver.
     122 * You better consider it to be 'private'.
     123 */
     124typedef struct {
     125        /** lower bound included in the interval */
     126        usb_address_t lower_bound;
     127
     128        /** upper bound, excluded from the interval */
     129        usb_address_t upper_bound;
     130
     131        /** */
     132        link_t link;
     133}usb_address_list_t;
     134
    118135struct usb_hc_device {
    119136        /** Transfer operations. */
     
    131148        /** List of hubs operating from this HC. */
    132149        link_t hubs;
     150
     151        /** Structure with free and used addresses */
     152        link_t addresses;
    133153
    134154        /** Link to other driven HCs. */
     
    148168int usb_hcd_add_root_hub(usb_hc_device_t *dev);
    149169
     170/**
     171 * find first not yet used address on this host controller and use it
     172 * @param this_hcd
     173 * @return number in the range of allowed usb addresses or
     174 *     a negative number if not succesful
     175 */
     176usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd);
     177
     178/**
     179 * @brief free the address in the address space of this hcd.
     180 *
     181 * if address is not used, nothing happens
     182 * @param this_hcd
     183 * @param addr
     184 */
     185void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr );
     186
    150187
    151188/*
  • uspace/lib/usb/src/hcdhubd.c

    r1dd264b r2cb6571  
    105105 * @return Error code.
    106106 */
    107 int usb_hcd_add_root_hub(usb_hc_device_t *dev)
    108 {
     107int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
    109108        char *id;
    110109        int rc = asprintf(&id, "usb&hc=%s&hub", hc_driver->name);
     
    129128
    130129/** Adds a child device fibril worker. */
    131 static int fibril_add_child_device(void *arg)
    132 {
     130static int fibril_add_child_device(void *arg) {
    133131        struct child_device_info *child_info
    134             = (struct child_device_info *) arg;
     132                        = (struct child_device_info *) arg;
    135133        int rc;
    136134
     
    156154
    157155        printf("%s: adding child device `%s' with match \"%s\"\n",
    158             hc_driver->name, child->name, match_id->id);
     156                        hc_driver->name, child->name, match_id->id);
    159157        rc = child_device_register(child, child_info->parent);
    160158        printf("%s: child device `%s' registration: %s\n",
    161             hc_driver->name, child->name, str_error(rc));
     159                        hc_driver->name, child->name, str_error(rc));
    162160
    163161        if (rc != EOK) {
     
    197195 */
    198196int usb_hc_add_child_device(device_t *parent, const char *name,
    199     const char *match_id, bool create_fibril)
    200 {
     197                const char *match_id, bool create_fibril) {
    201198        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    202             name, match_id);
     199                        name, match_id);
    203200
    204201        /*
     
    209206
    210207        struct child_device_info *child_info
    211             = malloc(sizeof(struct child_device_info));
     208                        = malloc(sizeof (struct child_device_info));
    212209
    213210        child_info->parent = parent;
     
    233230 * @return USB device address or error code.
    234231 */
    235 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    236 {
     232usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    237233        /* TODO: search list of attached devices. */
    238234        return ENOENT;
    239235}
    240236
     237usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
     238        //is there free address?
     239        link_t * addresses = &this_hcd->addresses;
     240        if (list_empty(addresses)) return -1;
     241        link_t * link_addr = addresses;
     242        bool found = false;
     243        usb_address_list_t * range = NULL;
     244        while (!found) {
     245                link_addr = link_addr->next;
     246                if (link_addr == addresses) return -2;
     247                range = list_get_instance(link_addr,
     248                                usb_address_list_t, link);
     249                if (range->upper_bound - range->lower_bound > 0) {
     250                        found = true;
     251                }
     252        }
     253        //now we have interval
     254        int result = range->lower_bound;
     255        ++(range->lower_bound);
     256        if (range->upper_bound - range->lower_bound == 0) {
     257                list_remove(&range->link);
     258                free(range);
     259        }
     260        return result;
     261}
     262
     263void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
     264        //check range
     265        if (addr < usb_lowest_address || addr > usb_highest_address)
     266                return;
     267        link_t * addresses = &this_hcd->addresses;
     268        link_t * link_addr = addresses;
     269        //find 'good' interval
     270        usb_address_list_t * found_range = NULL;
     271        bool found = false;
     272        while (!found) {
     273                link_addr = link_addr->next;
     274                if (link_addr == addresses) {
     275                        found = true;
     276                } else {
     277                        usb_address_list_t * range = list_get_instance(link_addr,
     278                                        usb_address_list_t, link);
     279                        if (    (range->lower_bound - 1 == addr) ||
     280                                        (range->upper_bound == addr)) {
     281                                found = true;
     282                                found_range = range;
     283                        }
     284                        if (range->lower_bound - 1 > addr) {
     285                                found = true;
     286                        }
     287
     288                }
     289        }
     290        if (found_range == NULL) {
     291                //no suitable range found
     292                usb_address_list_t * result_range =
     293                                (usb_address_list_t*) malloc(sizeof (usb_address_list_t));
     294                result_range->lower_bound = addr;
     295                result_range->upper_bound = addr + 1;
     296                list_insert_before(&result_range->link, link_addr);
     297        } else {
     298                //we have good range
     299                if (found_range->lower_bound - 1 == addr) {
     300                        --found_range->lower_bound;
     301                } else {
     302                        //only one possible case
     303                        ++found_range->upper_bound;
     304                        if (found_range->link.next != addresses) {
     305                                usb_address_list_t * next_range =
     306                                                list_get_instance( &found_range->link.next,
     307                                                usb_address_list_t, link);
     308                                //check neighbour range
     309                                if (next_range->lower_bound == addr + 1) {
     310                                        //join ranges
     311                                        found_range->upper_bound = next_range->upper_bound;
     312                                        list_remove(&next_range->link);
     313                                        free(next_range);
     314                                }
     315                        }
     316                }
     317        }
     318
     319}
     320
    241321/**
    242322 * @}
  • uspace/lib/usb/src/hcdhubd_private.h

    r1dd264b r2cb6571  
    4848int usb_add_hub_device(device_t *);
    4949
     50/** lowest allowed usb address */
     51extern int usb_lowest_address;
     52
     53/** highest allowed usb address */
     54extern int usb_highest_address;
     55
     56/**
     57 * @brief initialize address list of given hcd
     58 *
     59 * This function should be used only for hcd initialization.
     60 * It creates interval list of free addresses, thus it is initialized as
     61 * list with one interval with whole address space. Using an address shrinks
     62 * the interval, freeing an address extends an interval or creates a
     63 * new one.
     64 *
     65 * @param hcd
     66 * @return
     67 */
     68void  usb_create_address_list(usb_hc_device_t * hcd);
     69
     70
     71
     72
     73
     74
    5075#endif
    5176/**
  • uspace/lib/usb/src/hcdrv.c

    r1dd264b r2cb6571  
    5050usb_hc_driver_t *hc_driver = NULL;
    5151
     52int usb_lowest_address = 1;
     53
     54int usb_highest_address = 255;
     55
    5256static device_ops_t usb_device_ops = {
    5357        .interfaces[USBHC_DEV_IFACE] = &usbhc_interface
    5458};
     59
     60
     61void usb_create_address_list(usb_hc_device_t * hcd){
     62        list_initialize(&hcd->addresses);
     63        usb_address_list_t * range =
     64                        (usb_address_list_t*)malloc(sizeof(usb_address_list_t));
     65        range->lower_bound = usb_lowest_address;
     66        range->upper_bound = usb_highest_address + 1;
     67        list_append(&range->link, &hcd->addresses);
     68}
    5569
    5670static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
     
    5973        list_initialize(&hc_dev->link);
    6074        list_initialize(&hc_dev->hubs);
     75        usb_create_address_list(hc_dev);
    6176        list_initialize(&hc_dev->attached_devices);
    6277        hc_dev->transfer_ops = NULL;
  • uspace/lib/usb/src/hubdrv.c

    r1dd264b r2cb6571  
    113113        usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
    114114        //get parent device
    115         /// @TODO this code is not correct
    116115        device_t * my_hcd = device;
    117116        while (my_hcd->parent)
    118117                my_hcd = my_hcd->parent;
    119118        //dev->
    120         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     119        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    121120        //we add the hub into the first hc
    122121        //link_t *link_hc = hc_list.next;
     
    135134 */
    136135int usb_add_hub_device(device_t *dev) {
    137         usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
    138         set_hub_address(hc, 5);
     136        //usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
     137        assert(dev->parent);
     138        usb_hc_device_t *hc = (usb_hc_device_t*)dev->parent->driver_data;
     139        usb_address_t addr =usb_use_free_address(hc);
     140        if(addr<0){
     141                printf("[hcdhubd] ERROR: cannot find an address \n");
     142        }
     143        set_hub_address(hc, addr);
    139144
    140145        check_hub_changes();
     
    151156                my_hcd = my_hcd->parent;
    152157        //dev->
    153         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     158        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    154159        my_hcd = dev;
    155160        while (my_hcd->parent)
     
    157162        //dev->
    158163
    159         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     164        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    160165
    161166        //create the hub structure
     
    183188 */
    184189static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
    185         printf("%s: setting hub address to %d\n", hc->generic->name, address);
     190        printf("[hcdhubd]%s: setting hub address to %d\n", hc->generic->name, address);
    186191        usb_target_t target = {0, 0};
    187192        usb_handle_t handle;
     
    217222        }
    218223
    219         printf("%s: hub address changed\n", hc->generic->name);
     224        printf("[hcdhubd]%s: hub address changed successfully to %d\n",
     225                        hc->generic->name, address);
    220226}
    221227
Note: See TracChangeset for help on using the changeset viewer.