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


Ignore:
Timestamp:
2010-12-03T15:43:43Z (13 years ago)
Author:
smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2cb6571, 45e9cc6
Parents:
c39544a
Message:

usb adresses assigning

File:
1 edited

Legend:

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

    rc39544a r4144630  
    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", dev->generic->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
     
    154152
    155153        printf("%s: adding child device `%s' with match \"%s\"\n",
    156             hc_driver->name, child->name, match_id->id);
     154                        hc_driver->name, child->name, match_id->id);
    157155        rc = child_device_register(child, child_info->parent);
    158156        printf("%s: child device `%s' registration: %s\n",
    159             hc_driver->name, child->name, str_error(rc));
     157                        hc_driver->name, child->name, str_error(rc));
    160158
    161159        if (rc != EOK) {
     
    195193 */
    196194int usb_hc_add_child_device(device_t *parent, const char *name,
    197     const char *match_id, bool create_fibril)
    198 {
     195                const char *match_id, bool create_fibril) {
    199196        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    200             name, match_id);
     197                        name, match_id);
    201198
    202199        struct child_device_info *child_info
    203             = malloc(sizeof(struct child_device_info));
     200                        = malloc(sizeof (struct child_device_info));
    204201
    205202        child_info->parent = parent;
     
    225222 * @return USB device address or error code.
    226223 */
    227 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    228 {
     224usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    229225        /* TODO: search list of attached devices. */
    230226        return ENOENT;
    231227}
    232228
     229usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
     230        //is there free address?
     231        link_t * addresses = &this_hcd->addresses;
     232        if (list_empty(addresses)) return -1;
     233        link_t * link_addr = addresses;
     234        bool found = false;
     235        usb_address_list_t * range = NULL;
     236        while (!found) {
     237                link_addr = link_addr->next;
     238                if (link_addr == addresses) return -2;
     239                range = list_get_instance(link_addr,
     240                                usb_address_list_t, link);
     241                if (range->upper_bound - range->lower_bound > 0) {
     242                        found = true;
     243                }
     244        }
     245        //now we have interval
     246        int result = range->lower_bound;
     247        ++(range->lower_bound);
     248        if (range->upper_bound - range->lower_bound == 0) {
     249                list_remove(&range->link);
     250                free(range);
     251        }
     252        return result;
     253}
     254
     255void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
     256        //check range
     257        if (addr < usb_lowest_address || addr > usb_highest_address)
     258                return;
     259        link_t * addresses = &this_hcd->addresses;
     260        link_t * link_addr = addresses;
     261        //find 'good' interval
     262        usb_address_list_t * found_range = NULL;
     263        bool found = false;
     264        while (!found) {
     265                link_addr = link_addr->next;
     266                if (link_addr == addresses) {
     267                        found = true;
     268                } else {
     269                        usb_address_list_t * range = list_get_instance(link_addr,
     270                                        usb_address_list_t, link);
     271                        if (    (range->lower_bound - 1 == addr) ||
     272                                        (range->upper_bound == addr)) {
     273                                found = true;
     274                                found_range = range;
     275                        }
     276                        if (range->lower_bound - 1 > addr) {
     277                                found = true;
     278                        }
     279
     280                }
     281        }
     282        if (found_range == NULL) {
     283                //no suitable range found
     284                usb_address_list_t * result_range =
     285                                (usb_address_list_t*) malloc(sizeof (usb_address_list_t));
     286                result_range->lower_bound = addr;
     287                result_range->upper_bound = addr + 1;
     288                list_insert_before(&result_range->link, link_addr);
     289        } else {
     290                //we have good range
     291                if (found_range->lower_bound - 1 == addr) {
     292                        --found_range->lower_bound;
     293                } else {
     294                        //only one possible case
     295                        ++found_range->upper_bound;
     296                        if (found_range->link.next != addresses) {
     297                                usb_address_list_t * next_range =
     298                                                list_get_instance( &found_range->link.next,
     299                                                usb_address_list_t, link);
     300                                //check neighbour range
     301                                if (next_range->lower_bound == addr + 1) {
     302                                        //join ranges
     303                                        found_range->upper_bound = next_range->upper_bound;
     304                                        list_remove(&next_range->link);
     305                                        free(next_range);
     306                                }
     307                        }
     308                }
     309        }
     310
     311}
     312
    233313/**
    234314 * @}
Note: See TracChangeset for help on using the changeset viewer.