Changeset 243cb86 in mainline for uspace/lib/usb/src


Ignore:
Timestamp:
2010-12-12T10:50:19Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8365533
Parents:
101ef25c (diff), ebb98c5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from development + several changes to hid driver.

Changes to hid driver:

  • copied some code to usbkbd_get_descriptors() function
  • base structure for hid descriptor and report parser (files uspace/lib/usb/include/usb/classes/hidparser.h

and uspace/lib/usb/src/hidparser.c)

Location:
uspace/lib/usb/src
Files:
5 added
6 edited

Legend:

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

    r101ef25c r243cb86  
    5151 */
    5252static int add_device(device_t *dev) {
    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         }
     53        return ENOTSUP;
    6954}
    7055
     
    10590 * @return Error code.
    10691 */
    107 int usb_hcd_add_root_hub(usb_hc_device_t *dev)
     92int usb_hcd_add_root_hub(device_t *dev)
    10893{
    10994        char *id;
    110         int rc = asprintf(&id, "usb&hc=%s&hub", hc_driver->name);
     95        int rc = asprintf(&id, "usb&hub");
    11196        if (rc <= 0) {
    11297                return rc;
    11398        }
    11499
    115         rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true);
     100        rc = usb_hc_add_child_device(dev, USB_HUB_DEVICE_NAME, id, true);
    116101        if (rc != EOK) {
    117102                free(id);
     
    129114
    130115/** Adds a child device fibril worker. */
    131 static int fibril_add_child_device(void *arg)
    132 {
     116static int fibril_add_child_device(void *arg) {
    133117        struct child_device_info *child_info
    134             = (struct child_device_info *) arg;
     118                        = (struct child_device_info *) arg;
    135119        int rc;
    136120
     
    156140
    157141        printf("%s: adding child device `%s' with match \"%s\"\n",
    158             hc_driver->name, child->name, match_id->id);
     142                        hc_driver->name, child->name, match_id->id);
    159143        rc = child_device_register(child, child_info->parent);
    160144        printf("%s: child device `%s' registration: %s\n",
    161             hc_driver->name, child->name, str_error(rc));
     145                        hc_driver->name, child->name, str_error(rc));
    162146
    163147        if (rc != EOK) {
     
    197181 */
    198182int usb_hc_add_child_device(device_t *parent, const char *name,
    199     const char *match_id, bool create_fibril)
    200 {
     183                const char *match_id, bool create_fibril) {
    201184        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    202             name, match_id);
     185                        name, match_id);
    203186
    204187        /*
     
    209192
    210193        struct child_device_info *child_info
    211             = malloc(sizeof(struct child_device_info));
     194                        = malloc(sizeof (struct child_device_info));
    212195
    213196        child_info->parent = parent;
     
    233216 * @return USB device address or error code.
    234217 */
    235 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    236 {
     218usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    237219        /* TODO: search list of attached devices. */
    238220        return ENOENT;
    239221}
    240222
     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
    241307/**
    242308 * @}
  • uspace/lib/usb/src/hcdhubd_private.h

    r101ef25c r243cb86  
    4646usb_address_t usb_get_address_by_handle(devman_handle_t);
    4747int usb_add_hc_device(device_t *);
    48 int usb_add_hub_device(device_t *);
     48
     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
    4973
    5074#endif
  • uspace/lib/usb/src/hcdrv.c

    r101ef25c r243cb86  
    4747LIST_INITIALIZE(hc_list);
    4848
     49/* Fake driver to have the name item initialized. */
     50static usb_hc_driver_t hc_driver_fake = {
     51        .name = "HCD",
     52};
     53
    4954/** Our HC driver. */
    50 usb_hc_driver_t *hc_driver = NULL;
     55usb_hc_driver_t *hc_driver = &hc_driver_fake;
     56
     57int usb_lowest_address = 1;
     58
     59int usb_highest_address = 255;
    5160
    5261static device_ops_t usb_device_ops = {
    5362        .interfaces[USBHC_DEV_IFACE] = &usbhc_interface
    5463};
     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}
    5574
    5675static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
     
    5978        list_initialize(&hc_dev->link);
    6079        list_initialize(&hc_dev->hubs);
     80        usb_create_address_list(hc_dev);
    6181        list_initialize(&hc_dev->attached_devices);
    6282        hc_dev->transfer_ops = NULL;
     
    7191int usb_add_hc_device(device_t *dev)
    7292{
     93        return ENOTSUP;
    7394        usb_hc_device_t *hc_dev = usb_hc_device_create(dev);
    7495
  • uspace/lib/usb/src/localdrv.c

    r101ef25c r243cb86  
    3939#include <errno.h>
    4040
     41/** Find host controller when handled by current task.
     42 *
     43 * @param dev Device asking for connection.
     44 * @return Device structure corresponding to parent host controller.
     45 * @retval NULL Corresponding host controller not found.
     46 */
     47device_t *usb_hc_connect(device_t *dev)
     48{
     49        /*
     50         * FIXME: this will not work when some hub on the path is
     51         * not driven by the same task.
     52         */
     53        device_t *parent = dev;
     54        while (parent->parent != NULL) {
     55                parent = parent->parent;
     56        }
     57       
     58        if (dev == parent) {
     59                printf("FIXME in %s:%d encountered!\n", __FILE__, __LINE__);
     60                parent = NULL;
     61        }
     62
     63        return parent;
     64}
     65
    4166/** Information about pending transaction on HC. */
    4267typedef struct {
  • uspace/lib/usb/src/remotedrv.c

    r101ef25c r243cb86  
    300300 */
    301301static void remote_in_callback(usb_hc_device_t *hc,
    302     usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
     302    size_t actual_size, usb_transaction_outcome_t outcome, void *arg)
    303303{
    304304        transfer_info_t *transfer = (transfer_info_t *) arg;
  • uspace/lib/usb/src/usbdrv.c

    r101ef25c r243cb86  
    5555/** Connect to host controller the device is physically attached to.
    5656 *
    57  * @param handle Device handle.
     57 * @param dev Device asking for connection.
    5858 * @param flags Connection flags (blocking connection).
    5959 * @return Phone to corresponding HC or error code.
     
    7171        devman_handle_t handle;
    7272
    73         rc = devman_device_get_handle("/vhc", &handle, 0);
     73        rc = devman_device_get_handle("/virt/usbhc", &handle, 0);
    7474        if (rc != EOK) {
    7575                return rc;
     
    9898
    9999        return (usb_address_t) address;
     100}
     101
     102/** Tell HC to reserve default address.
     103 *
     104 * @param phone Open phone to host controller driver.
     105 * @return Error code.
     106 */
     107int usb_drv_reserve_default_address(int phone)
     108{
     109        return async_req_0_0(phone, IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
     110}
     111
     112/** Tell HC to release default address.
     113 *
     114 * @param phone Open phone to host controller driver.
     115 * @return Error code.
     116 */
     117int usb_drv_release_default_address(int phone)
     118{
     119        return async_req_0_0(phone, IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
     120}
     121
     122/** Ask HC for free address assignment.
     123 *
     124 * @param phone Open phone to host controller driver.
     125 * @return Assigned USB address or negative error code.
     126 */
     127usb_address_t usb_drv_request_address(int phone)
     128{
     129        ipcarg_t address;
     130        int rc = async_req_0_1(phone, IPC_M_USBHC_REQUEST_ADDRESS, &address);
     131        if (rc != EOK) {
     132                return rc;
     133        } else {
     134                return (usb_address_t) address;
     135        }
     136}
     137
     138/** Inform HC about binding address with devman handle.
     139 *
     140 * @param phone Open phone to host controller driver.
     141 * @param address Address to be binded.
     142 * @param handle Devman handle of the device.
     143 * @return Error code.
     144 */
     145int usb_drv_bind_address(int phone, usb_address_t address,
     146    devman_handle_t handle)
     147{
     148        int rc = async_req_2_0(phone, IPC_M_USBHC_BIND_ADDRESS,
     149            address, handle);
     150
     151        return rc;
     152}
     153
     154/** Inform HC about address release.
     155 *
     156 * @param phone Open phone to host controller driver.
     157 * @param address Address to be released.
     158 * @return Error code.
     159 */
     160int usb_drv_release_address(int phone, usb_address_t address)
     161{
     162        return async_req_1_0(phone, IPC_M_USBHC_RELEASE_ADDRESS, address);
    100163}
    101164
Note: See TracChangeset for help on using the changeset viewer.