Ignore:
File:
1 edited

Legend:

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

    r4317827 r4144630  
    5151 */
    5252static int add_device(device_t *dev) {
    53         return ENOTSUP;
     53        bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0;
     54        printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name);
     55
     56        if (is_hc) {
     57                /*
     58                 * We are the HC itself.
     59                 */
     60                return usb_add_hc_device(dev);
     61        } else {
     62                /*
     63                 * We are some (maybe deeply nested) hub.
     64                 * Thus, assign our own operations and explore already
     65                 * connected devices.
     66                 */
     67                return usb_add_hub_device(dev);
     68        }
    5469}
    5570
     
    90105 * @return Error code.
    91106 */
    92 int usb_hcd_add_root_hub(device_t *dev)
    93 {
     107int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
    94108        char *id;
    95         int rc = asprintf(&id, "usb&hub");
     109        int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name);
    96110        if (rc <= 0) {
    97111                return rc;
    98112        }
    99113
    100         rc = usb_hc_add_child_device(dev, USB_HUB_DEVICE_NAME, id, true);
     114        rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true);
    101115        if (rc != EOK) {
    102116                free(id);
     
    114128
    115129/** Adds a child device fibril worker. */
    116 static int fibril_add_child_device(void *arg)
    117 {
     130static int fibril_add_child_device(void *arg) {
    118131        struct child_device_info *child_info
    119             = (struct child_device_info *) arg;
     132                        = (struct child_device_info *) arg;
    120133        int rc;
    121 
    122         async_usleep(1000);
    123134
    124135        device_t *child = create_device();
     
    141152
    142153        printf("%s: adding child device `%s' with match \"%s\"\n",
    143             hc_driver->name, child->name, match_id->id);
     154                        hc_driver->name, child->name, match_id->id);
    144155        rc = child_device_register(child, child_info->parent);
    145156        printf("%s: child device `%s' registration: %s\n",
    146             hc_driver->name, child->name, str_error(rc));
     157                        hc_driver->name, child->name, str_error(rc));
    147158
    148159        if (rc != EOK) {
     
    182193 */
    183194int usb_hc_add_child_device(device_t *parent, const char *name,
    184     const char *match_id, bool create_fibril)
    185 {
     195                const char *match_id, bool create_fibril) {
    186196        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    187             name, match_id);
    188 
    189         /*
    190          * Seems that creating fibril which postpones the action
    191          * is the best solution.
    192          */
    193         create_fibril = true;
     197                        name, match_id);
    194198
    195199        struct child_device_info *child_info
    196             = malloc(sizeof(struct child_device_info));
     200                        = malloc(sizeof (struct child_device_info));
    197201
    198202        child_info->parent = parent;
     
    218222 * @return USB device address or error code.
    219223 */
    220 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    221 {
     224usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    222225        /* TODO: search list of attached devices. */
    223226        return ENOENT;
    224227}
    225228
     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
    226313/**
    227314 * @}
Note: See TracChangeset for help on using the changeset viewer.