Changes in / [4317827:36c410e] in mainline


Ignore:
Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/utils.c

    r4317827 r36c410e  
    109109//*********************************************
    110110
    111 static void set_hub_address(device_t *dev, usb_address_t address);
    112 
    113111usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
    114112        usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
     
    124122int usb_add_hub_device(device_t *dev) {
    125123        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    126         set_hub_address(dev, 5);
    127124
    128125        check_hub_changes();
     
    142139}
    143140
    144 /** Sample usage of usb_hc_async functions.
    145  * This function sets hub address using standard SET_ADDRESS request.
    146  *
    147  * @warning This function shall be removed once you are familiar with
    148  * the usb_hc_ API.
    149  *
    150  * @param hc Host controller the hub belongs to.
    151  * @param address New hub address.
    152  */
    153 static void set_hub_address(device_t *dev, usb_address_t address) {
    154         printf(NAME ": setting hub address to %d\n", address);
    155         usb_target_t target = {0, 0};
    156         usb_handle_t handle;
    157         int rc;
    158 
    159         usb_device_request_setup_packet_t setup_packet = {
    160                 .request_type = 0,
    161                 .request = USB_DEVREQ_SET_ADDRESS,
    162                 .index = 0,
    163                 .length = 0,
    164         };
    165         setup_packet.value = address;
    166 
    167         int hc = usb_drv_hc_connect(dev, 0);
    168 
    169         rc = usb_drv_async_control_write_setup(hc, target,
    170                         &setup_packet, sizeof (setup_packet), &handle);
    171         if (rc != EOK) {
    172                 return;
    173         }
    174 
    175         rc = usb_drv_async_wait_for(handle);
    176         if (rc != EOK) {
    177                 return;
    178         }
    179 
    180         rc = usb_drv_async_control_write_status(hc, target, &handle);
    181         if (rc != EOK) {
    182                 return;
    183         }
    184 
    185         rc = usb_drv_async_wait_for(handle);
    186         if (rc != EOK) {
    187                 return;
    188         }
    189 
    190         printf(NAME ": hub address changed\n");
    191 }
    192141
    193142/** Check changes on all known hubs.
  • uspace/lib/usb/include/usb/hcdhubd.h

    r4317827 r36c410e  
    116116} usb_hcd_transfer_ops_t;
    117117
     118/**
     119 * @brief structure holding information about free and used addresses
     120 *
     121 * This structure should not be used outside usb hcd driver.
     122 * You better consider it to be 'private'.
     123 */
     124typedef struct {
     125        /** lower bound included in the interval */
     126        usb_address_t lower_bound;
     127
     128        /** upper bound, excluded from the interval */
     129        usb_address_t upper_bound;
     130
     131        /** */
     132        link_t link;
     133}usb_address_list_t;
     134
    118135struct usb_hc_device {
    119136        /** Transfer operations. */
     
    131148        /** List of hubs operating from this HC. */
    132149        link_t hubs;
     150
     151        /** Structure with free and used addresses */
     152        link_t addresses;
    133153
    134154        /** Link to other driven HCs. */
     
    148168int usb_hcd_add_root_hub(device_t *dev);
    149169
     170/**
     171 * find first not yet used address on this host controller and use it
     172 * @param this_hcd
     173 * @return number in the range of allowed usb addresses or
     174 *     a negative number if not succesful
     175 */
     176usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd);
     177
     178/**
     179 * @brief free the address in the address space of this hcd.
     180 *
     181 * if address is not used, nothing happens
     182 * @param this_hcd
     183 * @param addr
     184 */
     185void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr );
     186
    150187
    151188/*
  • 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 * @}
  • uspace/lib/usb/src/hcdhubd_private.h

    r4317827 r36c410e  
    4747int usb_add_hc_device(device_t *);
    4848
     49/** lowest allowed usb address */
     50extern int usb_lowest_address;
     51
     52/** highest allowed usb address */
     53extern int usb_highest_address;
     54
     55/**
     56 * @brief initialize address list of given hcd
     57 *
     58 * This function should be used only for hcd initialization.
     59 * It creates interval list of free addresses, thus it is initialized as
     60 * list with one interval with whole address space. Using an address shrinks
     61 * the interval, freeing an address extends an interval or creates a
     62 * new one.
     63 *
     64 * @param hcd
     65 * @return
     66 */
     67void  usb_create_address_list(usb_hc_device_t * hcd);
     68
     69
     70
     71
     72
     73
    4974#endif
    5075/**
  • uspace/lib/usb/src/hcdrv.c

    r4317827 r36c410e  
    5555usb_hc_driver_t *hc_driver = &hc_driver_fake;
    5656
     57int usb_lowest_address = 1;
     58
     59int usb_highest_address = 255;
     60
    5761static device_ops_t usb_device_ops = {
    5862        .interfaces[USBHC_DEV_IFACE] = &usbhc_interface
    5963};
     64
     65
     66void usb_create_address_list(usb_hc_device_t * hcd){
     67        list_initialize(&hcd->addresses);
     68        usb_address_list_t * range =
     69                        (usb_address_list_t*)malloc(sizeof(usb_address_list_t));
     70        range->lower_bound = usb_lowest_address;
     71        range->upper_bound = usb_highest_address + 1;
     72        list_append(&range->link, &hcd->addresses);
     73}
    6074
    6175static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
     
    6478        list_initialize(&hc_dev->link);
    6579        list_initialize(&hc_dev->hubs);
     80        usb_create_address_list(hc_dev);
    6681        list_initialize(&hc_dev->attached_devices);
    6782        hc_dev->transfer_ops = NULL;
Note: See TracChangeset for help on using the changeset viewer.