Ignore:
File:
1 edited

Legend:

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

    r4317827 r71ed4849  
    3636#include <usb/devreq.h>
    3737#include <usbhc_iface.h>
     38#include <usb_iface.h>
    3839#include <usb/descriptor.h>
    3940#include <driver.h>
     
    4546#include "hcdhubd_private.h"
    4647
     48
     49static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
     50{
     51        assert(dev);
     52        assert(dev->parent != NULL);
     53
     54        device_t *parent = dev->parent;
     55
     56        if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
     57                usb_iface_t *usb_iface
     58                    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
     59                assert(usb_iface != NULL);
     60                if (usb_iface->get_hc_handle) {
     61                        int rc = usb_iface->get_hc_handle(parent, handle);
     62                        return rc;
     63                }
     64        }
     65
     66        return ENOTSUP;
     67}
     68
     69static usb_iface_t usb_iface = {
     70        .get_hc_handle = usb_iface_get_hc_handle
     71};
     72
     73static device_ops_t child_ops = {
     74        .interfaces[USB_DEV_IFACE] = &usb_iface
     75};
     76
    4777/** Callback when new device is detected and must be handled by this driver.
    4878 *
     
    114144
    115145/** Adds a child device fibril worker. */
    116 static int fibril_add_child_device(void *arg)
    117 {
     146static int fibril_add_child_device(void *arg) {
    118147        struct child_device_info *child_info
    119             = (struct child_device_info *) arg;
     148                        = (struct child_device_info *) arg;
    120149        int rc;
    121150
     
    130159        }
    131160        child->name = child_info->name;
     161        child->parent = child_info->parent;
     162        child->ops = &child_ops;
    132163
    133164        match_id = create_match_id();
     
    141172
    142173        printf("%s: adding child device `%s' with match \"%s\"\n",
    143             hc_driver->name, child->name, match_id->id);
     174                        hc_driver->name, child->name, match_id->id);
    144175        rc = child_device_register(child, child_info->parent);
    145176        printf("%s: child device `%s' registration: %s\n",
    146             hc_driver->name, child->name, str_error(rc));
     177                        hc_driver->name, child->name, str_error(rc));
    147178
    148179        if (rc != EOK) {
     
    182213 */
    183214int usb_hc_add_child_device(device_t *parent, const char *name,
    184     const char *match_id, bool create_fibril)
    185 {
     215                const char *match_id, bool create_fibril) {
    186216        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    187             name, match_id);
     217                        name, match_id);
    188218
    189219        /*
     
    194224
    195225        struct child_device_info *child_info
    196             = malloc(sizeof(struct child_device_info));
     226                        = malloc(sizeof (struct child_device_info));
    197227
    198228        child_info->parent = parent;
     
    218248 * @return USB device address or error code.
    219249 */
    220 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    221 {
     250usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    222251        /* TODO: search list of attached devices. */
    223252        return ENOENT;
    224253}
    225254
     255usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
     256        //is there free address?
     257        link_t * addresses = &this_hcd->addresses;
     258        if (list_empty(addresses)) return -1;
     259        link_t * link_addr = addresses;
     260        bool found = false;
     261        usb_address_list_t * range = NULL;
     262        while (!found) {
     263                link_addr = link_addr->next;
     264                if (link_addr == addresses) return -2;
     265                range = list_get_instance(link_addr,
     266                                usb_address_list_t, link);
     267                if (range->upper_bound - range->lower_bound > 0) {
     268                        found = true;
     269                }
     270        }
     271        //now we have interval
     272        int result = range->lower_bound;
     273        ++(range->lower_bound);
     274        if (range->upper_bound - range->lower_bound == 0) {
     275                list_remove(&range->link);
     276                free(range);
     277        }
     278        return result;
     279}
     280
     281void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
     282        //check range
     283        if (addr < usb_lowest_address || addr > usb_highest_address)
     284                return;
     285        link_t * addresses = &this_hcd->addresses;
     286        link_t * link_addr = addresses;
     287        //find 'good' interval
     288        usb_address_list_t * found_range = NULL;
     289        bool found = false;
     290        while (!found) {
     291                link_addr = link_addr->next;
     292                if (link_addr == addresses) {
     293                        found = true;
     294                } else {
     295                        usb_address_list_t * range = list_get_instance(link_addr,
     296                                        usb_address_list_t, link);
     297                        if (    (range->lower_bound - 1 == addr) ||
     298                                        (range->upper_bound == addr)) {
     299                                found = true;
     300                                found_range = range;
     301                        }
     302                        if (range->lower_bound - 1 > addr) {
     303                                found = true;
     304                        }
     305
     306                }
     307        }
     308        if (found_range == NULL) {
     309                //no suitable range found
     310                usb_address_list_t * result_range =
     311                                (usb_address_list_t*) malloc(sizeof (usb_address_list_t));
     312                result_range->lower_bound = addr;
     313                result_range->upper_bound = addr + 1;
     314                list_insert_before(&result_range->link, link_addr);
     315        } else {
     316                //we have good range
     317                if (found_range->lower_bound - 1 == addr) {
     318                        --found_range->lower_bound;
     319                } else {
     320                        //only one possible case
     321                        ++found_range->upper_bound;
     322                        if (found_range->link.next != addresses) {
     323                                usb_address_list_t * next_range =
     324                                                list_get_instance( &found_range->link.next,
     325                                                usb_address_list_t, link);
     326                                //check neighbour range
     327                                if (next_range->lower_bound == addr + 1) {
     328                                        //join ranges
     329                                        found_range->upper_bound = next_range->upper_bound;
     330                                        list_remove(&next_range->link);
     331                                        free(next_range);
     332                                }
     333                        }
     334                }
     335        }
     336
     337}
     338
    226339/**
    227340 * @}
Note: See TracChangeset for help on using the changeset viewer.