Changeset 2cb6571 in mainline for uspace/lib/usb/src/hcdhubd.c


Ignore:
Timestamp:
2010-12-03T15:49:30Z (13 years ago)
Author:
smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
36c410e, 54b141a
Parents:
1dd264b (diff), 4144630 (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 with smekideki

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 * @}
Note: See TracChangeset for help on using the changeset viewer.