Changeset 243cb86 in mainline for uspace/lib/usb


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
Files:
8 added
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/Makefile

    r101ef25c r243cb86  
    3333
    3434SOURCES = \
     35        src/addrkeep.c \
     36        src/debug.c \
     37        src/drvpsync.c \
    3538        src/hcdhubd.c \
    3639        src/hcdrv.c \
    37         src/hubdrv.c \
     40        src/hidparser.c \
    3841        src/localdrv.c \
    3942        src/remotedrv.c \
    4043        src/usb.c \
     44        src/usbdrvreq.c \
    4145        src/usbdrv.c
    4246
  • uspace/lib/usb/include/usb/classes/hid.h

    r101ef25c r243cb86  
    3838#include <usb/usb.h>
    3939#include <driver.h>
     40#include <usb/classes/hidparser.h>
    4041
    4142/** USB/HID device requests. */
     
    6667        usb_address_t address;
    6768        usb_endpoint_t default_ep;
     69        usb_hid_report_parser_t *parser;
    6870} usb_hid_dev_kbd_t;
    6971
  • uspace/lib/usb/include/usb/devreq.h

    r101ef25c r243cb86  
    3838#include <ipc/ipc.h>
    3939#include <async.h>
     40#include <usb/usb.h>
     41#include <usb/descriptor.h>
    4042
    4143/** Standard device request. */
     
    8385} __attribute__ ((packed)) usb_device_request_setup_packet_t;
    8486
     87int usb_drv_req_set_address(int, usb_address_t, usb_address_t);
     88int usb_drv_req_get_device_descriptor(int, usb_address_t,
     89    usb_standard_device_descriptor_t *);
     90int usb_drv_req_get_bare_configuration_descriptor(int, usb_address_t, int,
     91    usb_standard_configuration_descriptor_t *);
     92int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
     93    void *, size_t, size_t *);
     94
     95
    8596#endif
    8697/**
  • uspace/lib/usb/include/usb/hcdhubd.h

    r101ef25c r243cb86  
    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. */
     
    146166
    147167int usb_hcd_main(usb_hc_driver_t *);
    148 int usb_hcd_add_root_hub(usb_hc_device_t *dev);
     168int usb_hcd_add_root_hub(device_t *dev);
     169
     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 );
    149186
    150187
     
    154191 */
    155192
     193device_t *usb_hc_connect(device_t *);
    156194
    157195int usb_hc_async_interrupt_out(usb_hc_device_t *, usb_target_t,
  • uspace/lib/usb/include/usb/usb.h

    r101ef25c r243cb86  
    6969typedef int usb_address_t;
    7070
     71/** Default USB address. */
     72#define USB_ADDRESS_DEFAULT 0
     73/** Maximum address number in USB 1.1. */
     74#define USB11_ADDRESS_MAX 128
     75
    7176/** USB endpoint number type.
    7277 * Negative values could be used to indicate error.
  • uspace/lib/usb/include/usb/usbdrv.h

    r101ef25c r243cb86  
    3636#define LIBUSB_USBDRV_H_
    3737
    38 #include "usb.h"
     38#include <usb/usb.h>
    3939#include <driver.h>
     40#include <usb/devreq.h>
     41#include <usb/descriptor.h>
    4042
    4143int usb_drv_hc_connect(device_t *, unsigned int);
     44
     45int usb_drv_reserve_default_address(int);
     46int usb_drv_release_default_address(int);
     47usb_address_t usb_drv_request_address(int);
     48int usb_drv_bind_address(int, usb_address_t, devman_handle_t);
     49int usb_drv_release_address(int, usb_address_t);
    4250
    4351usb_address_t usb_drv_get_my_address(int, device_t *);
     
    4856    void *, size_t, size_t *, usb_handle_t *);
    4957
     58int usb_drv_psync_interrupt_out(int, usb_target_t, void *, size_t);
     59int usb_drv_psync_interrupt_in(int, usb_target_t, void *, size_t, size_t *);
     60
     61
     62
    5063int usb_drv_async_control_write_setup(int, usb_target_t,
    5164    void *, size_t, usb_handle_t *);
     
    5467int usb_drv_async_control_write_status(int, usb_target_t,
    5568    usb_handle_t *);
     69
     70int usb_drv_psync_control_write_setup(int, usb_target_t, void *, size_t);
     71int usb_drv_psync_control_write_data(int, usb_target_t, void *, size_t);
     72int usb_drv_psync_control_write_status(int, usb_target_t);
     73
     74int usb_drv_psync_control_write(int, usb_target_t,
     75    void *, size_t, void *, size_t);
     76
    5677
    5778int usb_drv_async_control_read_setup(int, usb_target_t,
     
    6283    usb_handle_t *);
    6384
     85int usb_drv_psync_control_read_setup(int, usb_target_t, void *, size_t);
     86int usb_drv_psync_control_read_data(int, usb_target_t, void *, size_t, size_t *);
     87int usb_drv_psync_control_read_status(int, usb_target_t);
     88
     89int usb_drv_psync_control_read(int, usb_target_t,
     90    void *, size_t, void *, size_t, size_t *);
     91
     92
     93
    6494int usb_drv_async_wait_for(usb_handle_t);
     95
    6596
    6697#endif
  • 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.