Changeset 4144630 in mainline


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

Location:
uspace/lib/usb
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/hcdhubd.h

    rc39544a r4144630  
    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(usb_hc_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

    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 * @}
  • uspace/lib/usb/src/hcdhubd_private.h

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

    rc39544a r4144630  
    5050usb_hc_driver_t *hc_driver = NULL;
    5151
     52int usb_lowest_address = 1;
     53
     54int usb_highest_address = 255;
     55
    5256static device_ops_t usb_device_ops = {
    5357        .interfaces[USBHC_DEV_IFACE] = &usbhc_interface
    5458};
     59
     60
     61void usb_create_address_list(usb_hc_device_t * hcd){
     62        list_initialize(&hcd->addresses);
     63        usb_address_list_t * range =
     64                        (usb_address_list_t*)malloc(sizeof(usb_address_list_t));
     65        range->lower_bound = usb_lowest_address;
     66        range->upper_bound = usb_highest_address + 1;
     67        list_append(&range->link, &hcd->addresses);
     68}
    5569
    5670static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
     
    5973        list_initialize(&hc_dev->link);
    6074        list_initialize(&hc_dev->hubs);
     75        usb_create_address_list(hc_dev);
    6176        list_initialize(&hc_dev->attached_devices);
    6277        hc_dev->transfer_ops = NULL;
  • uspace/lib/usb/src/hubdrv.c

    rc39544a r4144630  
    113113        usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
    114114        //get parent device
    115         /// @TODO this code is not correct
    116115        device_t * my_hcd = device;
    117116        while (my_hcd->parent)
    118117                my_hcd = my_hcd->parent;
    119118        //dev->
    120         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     119        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    121120        //we add the hub into the first hc
    122121        //link_t *link_hc = hc_list.next;
     
    135134 */
    136135int usb_add_hub_device(device_t *dev) {
    137         usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
    138         set_hub_address(hc, 5);
     136        //usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
     137        assert(dev->parent);
     138        usb_hc_device_t *hc = (usb_hc_device_t*)dev->parent->driver_data;
     139        usb_address_t addr =usb_use_free_address(hc);
     140        if(addr<0){
     141                printf("[hcdhubd] ERROR: cannot find an address \n");
     142        }
     143        set_hub_address(hc, addr);
    139144
    140145        check_hub_changes();
     
    151156                my_hcd = my_hcd->parent;
    152157        //dev->
    153         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     158        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    154159        my_hcd = dev;
    155160        while (my_hcd->parent)
     
    157162        //dev->
    158163
    159         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
     164        printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    160165
    161166        //create the hub structure
     
    183188 */
    184189static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
    185         printf("%s: setting hub address to %d\n", hc->generic->name, address);
     190        printf("[hcdhubd]%s: setting hub address to %d\n", hc->generic->name, address);
    186191        usb_target_t target = {0, 0};
    187192        usb_handle_t handle;
     
    217222        }
    218223
    219         printf("%s: hub address changed\n", hc->generic->name);
     224        printf("[hcdhubd]%s: hub address changed successfully to %d\n",
     225                        hc->generic->name, address);
    220226}
    221227
Note: See TracChangeset for help on using the changeset viewer.