Changeset 93fb170c in mainline for uspace/lib/usb


Ignore:
Timestamp:
2011-01-08T18:51:31Z (15 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
15be932
Parents:
8f748215 (diff), a523af4 (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 main branch

Location:
uspace/lib/usb
Files:
9 edited

Legend:

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

    r8f748215 r93fb170c  
    9292int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
    9393    void *, size_t, size_t *);
     94int usb_drv_req_get_descriptor(int, usb_address_t, usb_request_type_t,
     95    uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
    9496
    9597
  • uspace/lib/usb/include/usb/hcdhubd.h

    r8f748215 r93fb170c  
    207207int usb_hc_add_child_device(device_t *, const char *, const char *, bool);
    208208
     209
     210/**
     211 * @}
     212 */
     213
    209214#endif
  • uspace/lib/usb/include/usb/usb.h

    r8f748215 r93fb170c  
    5454        USB_DIRECTION_OUT
    5555} usb_direction_t;
     56
     57/** USB request type target. */
     58typedef enum {
     59        USB_REQUEST_TYPE_STANDARD = 0,
     60        USB_REQUEST_TYPE_CLASS = 1,
     61        USB_REQUEST_TYPE_VENDOR = 2
     62} usb_request_type_t;
    5663
    5764/** USB transaction outcome. */
  • uspace/lib/usb/include/usb/usbdrv.h

    r8f748215 r93fb170c  
    4141#include <usb/descriptor.h>
    4242
    43 int usb_drv_hc_connect(device_t *, unsigned int);
     43int usb_drv_find_hc(device_t *, devman_handle_t *);
     44int usb_drv_hc_connect(device_t *, devman_handle_t, unsigned int);
     45int usb_drv_hc_connect_auto(device_t *, unsigned int);
    4446
    4547int usb_drv_reserve_default_address(int);
     
    9496int usb_drv_async_wait_for(usb_handle_t);
    9597
     98int usb_drv_create_match_ids_from_device_descriptor(match_id_list_t *,
     99    const usb_standard_device_descriptor_t *);
     100int usb_drv_create_match_ids_from_configuration_descriptor(match_id_list_t *,
     101    const void *, size_t);
     102
    96103int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);
    97104int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,
  • uspace/lib/usb/src/addrkeep.c

    r8f748215 r93fb170c  
    187187                new_address_position = addresses->used_addresses.next;
    188188        } else {
     189                usb_address_keeping_used_t *first
     190                    = used_address_get_instance(addresses->used_addresses.next);
     191                previous_address = first->address;
     192               
    189193                for_all_used_addresses(new_address_position, addresses) {
    190194                        usb_address_keeping_used_t *info
     
    194198                                break;
    195199                        }
     200                        previous_address = info->address;
    196201                }
    197202
  • uspace/lib/usb/src/hcdhubd.c

    r8f748215 r93fb170c  
    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 *
     
    129159        }
    130160        child->name = child_info->name;
     161        child->parent = child_info->parent;
     162        child->ops = &child_ops;
    131163
    132164        match_id = create_match_id();
  • uspace/lib/usb/src/recognise.c

    r8f748215 r93fb170c  
    3333 * @brief Functions for recognising kind of attached devices.
    3434 */
     35#include <usb_iface.h>
    3536#include <usb/usbdrv.h>
    3637#include <usb/classes/classes.h>
     
    3839#include <errno.h>
    3940
     41static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
     42{
     43        assert(dev);
     44        assert(dev->parent != NULL);
     45
     46        device_t *parent = dev->parent;
     47
     48        if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
     49                usb_iface_t *usb_iface
     50                    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
     51                assert(usb_iface != NULL);
     52                if (usb_iface->get_hc_handle) {
     53                        int rc = usb_iface->get_hc_handle(parent, handle);
     54                        return rc;
     55                }
     56        }
     57
     58        return ENOTSUP;
     59}
     60
     61static usb_iface_t usb_iface = {
     62        .get_hc_handle = usb_iface_get_hc_handle
     63};
     64
     65static device_ops_t child_ops = {
     66        .interfaces[USB_DEV_IFACE] = &usb_iface
     67};
    4068
    4169#define BCD_INT(a) (((unsigned int)(a)) / 256)
     
    99127       
    100128        return rc;
     129}
     130
     131/** Create DDF match ids from USB device descriptor.
     132 *
     133 * @param matches List of match ids to extend.
     134 * @param device_descriptor Device descriptor returned by given device.
     135 * @return Error code.
     136 */
     137int usb_drv_create_match_ids_from_device_descriptor(
     138    match_id_list_t *matches,
     139    const usb_standard_device_descriptor_t *device_descriptor)
     140{
     141        int rc;
     142       
     143        /*
     144         * Unless the vendor id is 0, the pair idVendor-idProduct
     145         * quite uniquely describes the device.
     146         */
     147        if (device_descriptor->vendor_id != 0) {
     148                /* First, with release number. */
     149                rc = usb_add_match_id(matches, 100,
     150                    "usb&vendor=%d&product=%d&release=" BCD_FMT,
     151                    (int) device_descriptor->vendor_id,
     152                    (int) device_descriptor->product_id,
     153                    BCD_ARGS(device_descriptor->device_version));
     154                if (rc != EOK) {
     155                        return rc;
     156                }
     157               
     158                /* Next, without release number. */
     159                rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
     160                    (int) device_descriptor->vendor_id,
     161                    (int) device_descriptor->product_id);
     162                if (rc != EOK) {
     163                        return rc;
     164                }
     165        }       
     166
     167        /*
     168         * If the device class points to interface we skip adding
     169         * class directly.
     170         */
     171        if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
     172                rc = usb_add_match_id(matches, 50, "usb&class=%s",
     173                    usb_str_class(device_descriptor->device_class));
     174                if (rc != EOK) {
     175                        return rc;
     176                }
     177        }
     178       
     179        return EOK;
     180}
     181
     182/** Create DDF match ids from USB configuration descriptor.
     183 * The configuration descriptor is expected to be in the complete form,
     184 * i.e. including interface, endpoint etc. descriptors.
     185 *
     186 * @param matches List of match ids to extend.
     187 * @param config_descriptor Configuration descriptor returned by given device.
     188 * @param total_size Size of the @p config_descriptor.
     189 * @return Error code.
     190 */
     191int usb_drv_create_match_ids_from_configuration_descriptor(
     192    match_id_list_t *matches,
     193    const void *config_descriptor, size_t total_size)
     194{
     195        /*
     196         * Iterate through config descriptor to find the interface
     197         * descriptors.
     198         */
     199        size_t position = sizeof(usb_standard_configuration_descriptor_t);
     200        while (position + 1 < total_size) {
     201                uint8_t *current_descriptor
     202                    = ((uint8_t *) config_descriptor) + position;
     203                uint8_t cur_descr_len = current_descriptor[0];
     204                uint8_t cur_descr_type = current_descriptor[1];
     205               
     206                position += cur_descr_len;
     207               
     208                if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
     209                        continue;
     210                }
     211               
     212                /*
     213                 * Finally, we found an interface descriptor.
     214                 */
     215                usb_standard_interface_descriptor_t *interface
     216                    = (usb_standard_interface_descriptor_t *)
     217                    current_descriptor;
     218               
     219                int rc = usb_add_match_id(matches, 50,
     220                    "usb&interface&class=%s",
     221                    usb_str_class(interface->interface_class));
     222                if (rc != EOK) {
     223                        return rc;
     224                }
     225        }
     226       
     227        return EOK;
    101228}
    102229
     
    141268                        continue;
    142269                }
    143 
    144                 /*
    145                  * Iterate through config descriptor to find the interface
    146                  * descriptors.
    147                  */
    148                 size_t position = sizeof(config_descriptor);
    149                 while (position + 1 < full_config_descriptor_size) {
    150                         uint8_t *current_descriptor
    151                             = ((uint8_t *) full_config_descriptor) + position;
    152                         uint8_t cur_descr_len = current_descriptor[0];
    153                         uint8_t cur_descr_type = current_descriptor[1];
    154                        
    155                         position += cur_descr_len;
    156                        
    157                         if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
    158                                 continue;
    159                         }
    160                         /*
    161                          * Finally, we found an interface descriptor.
    162                          */
    163                         usb_standard_interface_descriptor_t *interface
    164                             = (usb_standard_interface_descriptor_t *)
    165                             current_descriptor;
    166                        
    167                         rc = usb_add_match_id(matches, 50,
    168                             "usb&interface&class=%s",
    169                             usb_str_class(interface->interface_class));
    170                         if (rc != EOK) {
    171                                 final_rc = rc;
    172                                 break;
    173                         }
    174                 }
     270               
     271                rc = usb_drv_create_match_ids_from_configuration_descriptor(
     272                    matches,
     273                    full_config_descriptor, full_config_descriptor_size);
     274                if (rc != EOK) {
     275                        final_rc = rc;
     276                        continue;
     277                }
     278               
    175279        }
    176280       
     
    192296{
    193297        int rc;
     298       
     299        /*
     300         * Retrieve device descriptor and add matches from it.
     301         */
    194302        usb_standard_device_descriptor_t device_descriptor;
    195303
     
    199307                return rc;
    200308        }
    201 
    202         /*
    203          * Unless the vendor id is 0, the pair idVendor-idProduct
    204          * quite uniquely describes the device.
    205          */
    206         if (device_descriptor.vendor_id != 0) {
    207                 /* First, with release number. */
    208                 rc = usb_add_match_id(matches, 100,
    209                     "usb&vendor=%d&product=%d&release=" BCD_FMT,
    210                     (int) device_descriptor.vendor_id,
    211                     (int) device_descriptor.product_id,
    212                     BCD_ARGS(device_descriptor.device_version));
    213                 if (rc != EOK) {
    214                         return rc;
    215                 }
    216                
    217                 /* Next, without release number. */
    218                 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
    219                     (int) device_descriptor.vendor_id,
    220                     (int) device_descriptor.product_id);
    221                 if (rc != EOK) {
    222                         return rc;
    223                 }
    224 
    225         }       
    226 
    227         /*
    228          * If the device class points to interface we skip adding
    229          * class directly.
    230          */
    231         if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
    232                 rc = usb_add_match_id(matches, 50, "usb&class=%s",
    233                     usb_str_class(device_descriptor.device_class));
    234                 if (rc != EOK) {
    235                         return rc;
    236                 }
    237         }
     309       
     310        rc = usb_drv_create_match_ids_from_device_descriptor(matches,
     311            &device_descriptor);
     312        if (rc != EOK) {
     313                return rc;
     314        }
     315       
    238316        /*
    239317         * Go through all configurations and add matches
     
    285363                goto failure;
    286364        }
     365        child->parent = parent;
    287366        child->name = child_name;
     367        child->ops = &child_ops;
    288368       
    289369        rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address);
  • uspace/lib/usb/src/usbdrv.c

    r8f748215 r93fb170c  
    3535#include <usb/usbdrv.h>
    3636#include <usbhc_iface.h>
     37#include <usb_iface.h>
    3738#include <errno.h>
    3839#include <str_error.h>
     
    5455} transfer_info_t;
    5556
     57/** Find handle of host controller the device is physically attached to.
     58 *
     59 * @param[in] dev Device looking for its host controller.
     60 * @param[out] handle Host controller devman handle.
     61 * @return Error code.
     62 */
     63int usb_drv_find_hc(device_t *dev, devman_handle_t *handle)
     64{
     65        if (dev == NULL) {
     66                return EBADMEM;
     67        }
     68        if (handle == NULL) {
     69                return EBADMEM;
     70        }
     71
     72        int parent_phone = devman_parent_device_connect(dev->handle,
     73            IPC_FLAG_BLOCKING);
     74        if (parent_phone < 0) {
     75                return parent_phone;
     76        }
     77
     78        devman_handle_t h;
     79        int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     80            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
     81
     82        ipc_hangup(parent_phone);
     83
     84        if (rc != EOK) {
     85                return rc;
     86        }
     87
     88        *handle = h;
     89
     90        return EOK;
     91}
     92
     93/** Connect to host controller the device is physically attached to.
     94 *
     95 * @param dev Device asking for connection.
     96 * @param hc_handle Devman handle of the host controller.
     97 * @param flags Connection flags (blocking connection).
     98 * @return Phone to the HC or error code.
     99 */
     100int usb_drv_hc_connect(device_t *dev, devman_handle_t hc_handle,
     101    unsigned int flags)
     102{
     103        return devman_device_connect(hc_handle, flags);
     104}
     105
    56106/** Connect to host controller the device is physically attached to.
    57107 *
     
    60110 * @return Phone to corresponding HC or error code.
    61111 */
    62 int usb_drv_hc_connect(device_t *dev, unsigned int flags)
    63 {
     112int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags)
     113{
     114        int rc;
     115        devman_handle_t hc_handle;
     116
    64117        /*
    65118         * Call parent hub to obtain device handle of respective HC.
    66119         */
    67 
    68         /*
    69          * FIXME: currently we connect always to virtual host controller.
    70          */
    71         int rc;
    72         devman_handle_t handle;
    73 
    74         rc = devman_device_get_handle("/virt/usbhc", &handle, flags);
     120        rc = usb_drv_find_hc(dev, &hc_handle);
    75121        if (rc != EOK) {
    76122                return rc;
    77123        }
    78124       
    79         int phone = devman_device_connect(handle, flags);
    80 
    81         return phone;
     125        return usb_drv_hc_connect(dev, hc_handle, flags);
    82126}
    83127
  • uspace/lib/usb/src/usbdrvreq.c

    r8f748215 r93fb170c  
    7373}
    7474
    75 /** Retrieve device descriptor of connected USB device.
    76  *
    77  * @param[in] phone Open phone to HC driver.
    78  * @param[in] address Device USB address.
    79  * @param[out] descriptor Storage for the device descriptor.
    80  * @return Error code.
    81  * @retval EBADMEM @p descriptor is NULL.
    82  */
    83 int usb_drv_req_get_device_descriptor(int phone, usb_address_t address,
    84     usb_standard_device_descriptor_t *descriptor)
    85 {
    86         if (descriptor == NULL) {
    87                 return EBADMEM;
    88         }
    89 
     75/** Retrieve USB descriptor of connected USB device.
     76 *
     77 * @param[in] hc_phone Open phone to HC driver.
     78 * @param[in] address Device USB address.
     79 * @param[in] request_type Request type (standard/class/vendor).
     80 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
     81 * @param[in] descriptor_index Descriptor index.
     82 * @param[in] langauge Language index.
     83 * @param[out] buffer Buffer where to store the retrieved descriptor.
     84 * @param[in] size Size of the @p buffer.
     85 * @param[out] actual_size Number of bytes actually transferred.
     86 * @return Error code.
     87 */
     88int usb_drv_req_get_descriptor(int hc_phone, usb_address_t address,
     89    usb_request_type_t request_type,
     90    uint8_t descriptor_type, uint8_t descriptor_index,
     91    uint16_t language,
     92    void *buffer, size_t size, size_t *actual_size)
     93{
    9094        /* Prepare the target. */
    9195        usb_target_t target = {
     
    96100        /* Prepare the setup packet. */
    97101        usb_device_request_setup_packet_t setup_packet = {
    98                 .request_type = 128,
     102                .request_type = 128 | (request_type << 5),
    99103                .request = USB_DEVREQ_GET_DESCRIPTOR,
    100                 .index = 0,
    101                 .length = sizeof(usb_standard_device_descriptor_t)
    102         };
    103         setup_packet.value_high = USB_DESCTYPE_DEVICE;
    104         setup_packet.value_low = 0;
    105 
    106         /* Prepare local descriptor. */
     104                .index = language,
     105                .length = (uint16_t) size,
     106        };
     107        setup_packet.value_high = descriptor_type;
     108        setup_packet.value_low = descriptor_index;
     109       
     110        /* Perform CONTROL READ */
     111        int rc = usb_drv_psync_control_read(hc_phone, target,
     112            &setup_packet, sizeof(setup_packet),
     113            buffer, size, actual_size);
     114       
     115        return rc;
     116}
     117
     118/** Retrieve device descriptor of connected USB device.
     119 *
     120 * @param[in] phone Open phone to HC driver.
     121 * @param[in] address Device USB address.
     122 * @param[out] descriptor Storage for the device descriptor.
     123 * @return Error code.
     124 * @retval EBADMEM @p descriptor is NULL.
     125 */
     126int usb_drv_req_get_device_descriptor(int phone, usb_address_t address,
     127    usb_standard_device_descriptor_t *descriptor)
     128{
     129        if (descriptor == NULL) {
     130                return EBADMEM;
     131        }
     132       
    107133        size_t actually_transferred = 0;
    108134        usb_standard_device_descriptor_t descriptor_tmp;
    109 
    110         /* Perform the control read transaction. */
    111         int rc = usb_drv_psync_control_read(phone, target,
    112             &setup_packet, sizeof(setup_packet),
    113             &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
     135        int rc = usb_drv_req_get_descriptor(phone, address,
     136            USB_REQUEST_TYPE_STANDARD,
     137            USB_DESCTYPE_DEVICE, 0,
     138            0,
     139            &descriptor_tmp, sizeof(descriptor_tmp),
     140            &actually_transferred);
    114141
    115142        if (rc != EOK) {
     
    150177                return EBADMEM;
    151178        }
    152 
    153         /* Prepare the target. */
    154         usb_target_t target = {
    155                 .address = address,
    156                 .endpoint = 0
    157         };
    158 
    159         /* Prepare the setup packet. */
    160         usb_device_request_setup_packet_t setup_packet = {
    161                 .request_type = 128,
    162                 .request = USB_DEVREQ_GET_DESCRIPTOR,
    163                 .index = 0,
    164                 .length = sizeof(usb_standard_configuration_descriptor_t)
    165         };
    166         setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
    167         setup_packet.value_low = index;
    168 
    169         /* Prepare local descriptor. */
     179       
    170180        size_t actually_transferred = 0;
    171181        usb_standard_configuration_descriptor_t descriptor_tmp;
    172 
    173         /* Perform the control read transaction. */
    174         int rc = usb_drv_psync_control_read(phone, target,
    175             &setup_packet, sizeof(setup_packet),
    176             &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
     182        int rc = usb_drv_req_get_descriptor(phone, address,
     183            USB_REQUEST_TYPE_STANDARD,
     184            USB_DESCTYPE_CONFIGURATION, 0,
     185            0,
     186            &descriptor_tmp, sizeof(descriptor_tmp),
     187            &actually_transferred);
    177188
    178189        if (rc != EOK) {
     
    214225        }
    215226
    216         /* Prepare the target. */
    217         usb_target_t target = {
    218                 .address = address,
    219                 .endpoint = 0
    220         };
    221 
    222         /* Prepare the setup packet. */
    223         usb_device_request_setup_packet_t setup_packet = {
    224                 .request_type = 128,
    225                 .request = USB_DEVREQ_GET_DESCRIPTOR,
    226                 .index = 0,
    227                 .length = buffer_size
    228         };
    229         setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
    230         setup_packet.value_low = index;
    231 
    232         /* Perform the control read transaction. */
    233         int rc = usb_drv_psync_control_read(phone, target,
    234             &setup_packet, sizeof(setup_packet),
    235             buffer, buffer_size, actual_buffer_size);
     227        int rc = usb_drv_req_get_descriptor(phone, address,
     228            USB_REQUEST_TYPE_STANDARD,
     229            USB_DESCTYPE_CONFIGURATION, 0,
     230            0,
     231            buffer, buffer_size,
     232            actual_buffer_size);
    236233
    237234        return rc;
Note: See TracChangeset for help on using the changeset viewer.