Changeset 36c410e in mainline for uspace/lib/usb/src/hcdhubd.c


Ignore:
Timestamp:
2010-12-04T15:52:12Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6f04905
Parents:
4317827 (diff), 2cb6571 (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 development/ changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/hcdhubd.c

    r4317827 r36c410e  
    114114
    115115/** Adds a child device fibril worker. */
    116 static int fibril_add_child_device(void *arg)
    117 {
     116static int fibril_add_child_device(void *arg) {
    118117        struct child_device_info *child_info
    119             = (struct child_device_info *) arg;
     118                        = (struct child_device_info *) arg;
    120119        int rc;
    121120
     
    141140
    142141        printf("%s: adding child device `%s' with match \"%s\"\n",
    143             hc_driver->name, child->name, match_id->id);
     142                        hc_driver->name, child->name, match_id->id);
    144143        rc = child_device_register(child, child_info->parent);
    145144        printf("%s: child device `%s' registration: %s\n",
    146             hc_driver->name, child->name, str_error(rc));
     145                        hc_driver->name, child->name, str_error(rc));
    147146
    148147        if (rc != EOK) {
     
    182181 */
    183182int usb_hc_add_child_device(device_t *parent, const char *name,
    184     const char *match_id, bool create_fibril)
    185 {
     183                const char *match_id, bool create_fibril) {
    186184        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    187             name, match_id);
     185                        name, match_id);
    188186
    189187        /*
     
    194192
    195193        struct child_device_info *child_info
    196             = malloc(sizeof(struct child_device_info));
     194                        = malloc(sizeof (struct child_device_info));
    197195
    198196        child_info->parent = parent;
     
    218216 * @return USB device address or error code.
    219217 */
    220 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    221 {
     218usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    222219        /* TODO: search list of attached devices. */
    223220        return ENOENT;
    224221}
    225222
     223usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
     224        //is there free address?
     225        link_t * addresses = &this_hcd->addresses;
     226        if (list_empty(addresses)) return -1;
     227        link_t * link_addr = addresses;
     228        bool found = false;
     229        usb_address_list_t * range = NULL;
     230        while (!found) {
     231                link_addr = link_addr->next;
     232                if (link_addr == addresses) return -2;
     233                range = list_get_instance(link_addr,
     234                                usb_address_list_t, link);
     235                if (range->upper_bound - range->lower_bound > 0) {
     236                        found = true;
     237                }
     238        }
     239        //now we have interval
     240        int result = range->lower_bound;
     241        ++(range->lower_bound);
     242        if (range->upper_bound - range->lower_bound == 0) {
     243                list_remove(&range->link);
     244                free(range);
     245        }
     246        return result;
     247}
     248
     249void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
     250        //check range
     251        if (addr < usb_lowest_address || addr > usb_highest_address)
     252                return;
     253        link_t * addresses = &this_hcd->addresses;
     254        link_t * link_addr = addresses;
     255        //find 'good' interval
     256        usb_address_list_t * found_range = NULL;
     257        bool found = false;
     258        while (!found) {
     259                link_addr = link_addr->next;
     260                if (link_addr == addresses) {
     261                        found = true;
     262                } else {
     263                        usb_address_list_t * range = list_get_instance(link_addr,
     264                                        usb_address_list_t, link);
     265                        if (    (range->lower_bound - 1 == addr) ||
     266                                        (range->upper_bound == addr)) {
     267                                found = true;
     268                                found_range = range;
     269                        }
     270                        if (range->lower_bound - 1 > addr) {
     271                                found = true;
     272                        }
     273
     274                }
     275        }
     276        if (found_range == NULL) {
     277                //no suitable range found
     278                usb_address_list_t * result_range =
     279                                (usb_address_list_t*) malloc(sizeof (usb_address_list_t));
     280                result_range->lower_bound = addr;
     281                result_range->upper_bound = addr + 1;
     282                list_insert_before(&result_range->link, link_addr);
     283        } else {
     284                //we have good range
     285                if (found_range->lower_bound - 1 == addr) {
     286                        --found_range->lower_bound;
     287                } else {
     288                        //only one possible case
     289                        ++found_range->upper_bound;
     290                        if (found_range->link.next != addresses) {
     291                                usb_address_list_t * next_range =
     292                                                list_get_instance( &found_range->link.next,
     293                                                usb_address_list_t, link);
     294                                //check neighbour range
     295                                if (next_range->lower_bound == addr + 1) {
     296                                        //join ranges
     297                                        found_range->upper_bound = next_range->upper_bound;
     298                                        list_remove(&next_range->link);
     299                                        free(next_range);
     300                                }
     301                        }
     302                }
     303        }
     304
     305}
     306
    226307/**
    227308 * @}
Note: See TracChangeset for help on using the changeset viewer.