Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/connhost.c

    r6cb58e6 r46e078a  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky
     2 * Copyright (c) 2010 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
    33  * Host controller interface implementation.
     33 * @brief Connection handling of calls from host (implementation).
    3434 */
    3535#include <assert.h>
     
    3838#include <usb/addrkeep.h>
    3939#include <usb/ddfiface.h>
    40 #include <usb/debug.h>
    41 #include <usbhc_iface.h>
     40
    4241#include "vhcd.h"
    43 
    44 #define GET_VHC_DATA(fun) \
    45         ((vhc_data_t *)fun->dev->driver_data)
    46 #define VHC_DATA(vhc, fun) \
    47         vhc_data_t *vhc = GET_VHC_DATA(fun); assert(vhc->magic == 0xdeadbeef)
    48 
    49 #define UNSUPPORTED(methodname) \
    50         usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \
    51             methodname, __FILE__, __LINE__)
    52 
    53 /** Found free USB address.
    54  *
    55  * @param[in] fun Device function the action was invoked on.
    56  * @param[in] speed Speed of the device that will get this address.
    57  * @param[out] address Non-null pointer where to store the free address.
    58  * @return Error code.
    59  */
    60 static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    61     usb_address_t *address)
    62 {
    63         VHC_DATA(vhc, fun);
    64 
    65         usb_address_t addr = device_keeper_get_free_address(&vhc->dev_keeper,
    66             USB_SPEED_HIGH);
    67         if (addr < 0) {
    68                 return addr;
    69         }
    70 
    71         if (address != NULL) {
    72                 *address = addr;
    73         }
    74 
    75         return EOK;
    76 }
    77 
    78 /** Bind USB address with device devman handle.
    79  *
    80  * @param[in] fun Device function the action was invoked on.
    81  * @param[in] address USB address of the device.
    82  * @param[in] handle Devman handle of the device.
    83  * @return Error code.
    84  */
    85 static int bind_address(ddf_fun_t *fun,
    86     usb_address_t address, devman_handle_t handle)
    87 {
    88         VHC_DATA(vhc, fun);
    89         usb_log_debug("Binding handle %" PRIun " to address %d.\n",
    90             handle, address);
    91         usb_device_keeper_bind(&vhc->dev_keeper, address, handle);
    92 
    93         return EOK;
    94 }
    95 
    96 /** Release previously requested address.
    97  *
    98  * @param[in] fun Device function the action was invoked on.
    99  * @param[in] address USB address to be released.
    100  * @return Error code.
    101  */
    102 static int release_address(ddf_fun_t *fun, usb_address_t address)
    103 {
    104         VHC_DATA(vhc, fun);
    105         usb_log_debug("Releasing address %d...\n", address);
    106         usb_device_keeper_release(&vhc->dev_keeper, address);
    107 
    108         return ENOTSUP;
    109 }
    110 
    111 /** Register endpoint for bandwidth reservation.
    112  *
    113  * @param[in] fun Device function the action was invoked on.
    114  * @param[in] address USB address of the device.
    115  * @param[in] speed Endpoint speed (invalid means to use device one).
    116  * @param[in] endpoint Endpoint number.
    117  * @param[in] transfer_type USB transfer type.
    118  * @param[in] direction Endpoint data direction.
    119  * @param[in] max_packet_size Max packet size of the endpoint.
    120  * @param[in] interval Polling interval.
    121  * @return Error code.
    122  */
    123 static int register_endpoint(ddf_fun_t *fun,
    124     usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
    125     usb_transfer_type_t transfer_type, usb_direction_t direction,
    126     size_t max_packet_size, unsigned int interval)
    127 {
    128         VHC_DATA(vhc, fun);
    129 
    130         endpoint_t *ep = malloc(sizeof(endpoint_t));
    131         if (ep == NULL) {
    132                 return ENOMEM;
    133         }
    134 
    135         int rc = endpoint_init(ep, address, endpoint, direction, transfer_type,
    136             USB_SPEED_FULL, 1);
    137         if (rc != EOK) {
    138                 free(ep);
    139                 return rc;
    140         }
    141 
    142         rc = usb_endpoint_manager_register_ep(&vhc->ep_manager, ep, 1);
    143         if (rc != EOK) {
    144                 endpoint_destroy(ep);
    145                 return rc;
    146         }
    147 
    148         return EOK;
    149 }
    150 
    151 /** Unregister endpoint (free some bandwidth reservation).
    152  *
    153  * @param[in] fun Device function the action was invoked on.
    154  * @param[in] address USB address of the device.
    155  * @param[in] endpoint Endpoint number.
    156  * @param[in] direction Endpoint data direction.
    157  * @return Error code.
    158  */
    159 static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address,
    160     usb_endpoint_t endpoint, usb_direction_t direction)
    161 {
    162         VHC_DATA(vhc, fun);
    163 
    164         endpoint_t *ep = usb_endpoint_manager_get_ep(&vhc->ep_manager,
    165             address, endpoint, direction, NULL);
    166         if (ep == NULL) {
    167                 return ENOENT;
    168         }
    169 
    170         int rc = usb_endpoint_manager_unregister_ep(&vhc->ep_manager,
    171             address, endpoint, direction);
    172 
    173         return rc;
    174 }
    175 
    176 /** Schedule interrupt out transfer.
    177  *
    178  * The callback is supposed to be called once the transfer (on the wire) is
    179  * complete regardless of the outcome.
    180  * However, the callback could be called only when this function returns
    181  * with success status (i.e. returns EOK).
    182  *
    183  * @param[in] fun Device function the action was invoked on.
    184  * @param[in] target Target pipe (address and endpoint number) specification.
    185  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    186  *      by the caller).
    187  * @param[in] size Size of the @p data buffer in bytes.
    188  * @param[in] callback Callback to be issued once the transfer is complete.
    189  * @param[in] arg Pass-through argument to the callback.
    190  * @return Error code.
    191  */
     42#include "conn.h"
     43#include "hc.h"
     44
     45
     46typedef struct {
     47        usb_direction_t direction;
     48        usbhc_iface_transfer_out_callback_t out_callback;
     49        usbhc_iface_transfer_in_callback_t in_callback;
     50        ddf_fun_t *fun;
     51        size_t reported_size;
     52        void *arg;
     53} transfer_info_t;
     54
     55typedef struct {
     56        usb_direction_t direction;
     57        usb_target_t target;
     58        usbhc_iface_transfer_out_callback_t out_callback;
     59        usbhc_iface_transfer_in_callback_t in_callback;
     60        ddf_fun_t *fun;
     61        void *arg;
     62        void *data_buffer;
     63        size_t data_buffer_size;
     64} control_transfer_info_t;
     65
     66static void universal_callback(void *buffer, size_t size,
     67    int outcome, void *arg)
     68{
     69        transfer_info_t *transfer = (transfer_info_t *) arg;
     70
     71        if (transfer->reported_size != (size_t) -1) {
     72                size = transfer->reported_size;
     73        }
     74
     75        switch (transfer->direction) {
     76                case USB_DIRECTION_IN:
     77                        transfer->in_callback(transfer->fun,
     78                            outcome, size,
     79                            transfer->arg);
     80                        break;
     81                case USB_DIRECTION_OUT:
     82                        transfer->out_callback(transfer->fun,
     83                            outcome,
     84                            transfer->arg);
     85                        break;
     86                default:
     87                        assert(false && "unreachable");
     88                        break;
     89        }
     90
     91        free(transfer);
     92}
     93
     94static transfer_info_t *create_transfer_info(ddf_fun_t *fun,
     95    usb_direction_t direction, void *arg)
     96{
     97        transfer_info_t *transfer = malloc(sizeof(transfer_info_t));
     98
     99        transfer->direction = direction;
     100        transfer->in_callback = NULL;
     101        transfer->out_callback = NULL;
     102        transfer->arg = arg;
     103        transfer->fun = fun;
     104        transfer->reported_size = (size_t) -1;
     105
     106        return transfer;
     107}
     108
     109static void control_abort_prematurely(control_transfer_info_t *transfer,
     110    size_t size, int outcome)
     111{
     112        switch (transfer->direction) {
     113                case USB_DIRECTION_IN:
     114                        transfer->in_callback(transfer->fun,
     115                            outcome, size,
     116                            transfer->arg);
     117                        break;
     118                case USB_DIRECTION_OUT:
     119                        transfer->out_callback(transfer->fun,
     120                            outcome,
     121                            transfer->arg);
     122                        break;
     123                default:
     124                        assert(false && "unreachable");
     125                        break;
     126        }
     127}
     128
     129static void control_callback_two(void *buffer, size_t size,
     130    int outcome, void *arg)
     131{
     132        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
     133
     134        if (outcome != EOK) {
     135                control_abort_prematurely(ctrl_transfer, outcome, size);
     136                free(ctrl_transfer);
     137                return;
     138        }
     139
     140        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->fun,
     141            ctrl_transfer->direction, ctrl_transfer->arg);
     142        transfer->out_callback = ctrl_transfer->out_callback;
     143        transfer->in_callback = ctrl_transfer->in_callback;
     144        transfer->reported_size = size;
     145
     146        switch (ctrl_transfer->direction) {
     147                case USB_DIRECTION_IN:
     148                        hc_add_transaction_to_device(false, ctrl_transfer->target,
     149                            USB_TRANSFER_CONTROL,
     150                            NULL, 0,
     151                            universal_callback, transfer);
     152                        break;
     153                case USB_DIRECTION_OUT:
     154                        hc_add_transaction_from_device(ctrl_transfer->target,
     155                            USB_TRANSFER_CONTROL,
     156                            NULL, 0,
     157                            universal_callback, transfer);
     158                        break;
     159                default:
     160                        assert(false && "unreachable");
     161                        break;
     162        }
     163
     164        free(ctrl_transfer);
     165}
     166
     167static void control_callback_one(void *buffer, size_t size,
     168    int outcome, void *arg)
     169{
     170        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
     171
     172        if (outcome != EOK) {
     173                control_abort_prematurely(transfer, outcome, size);
     174                free(transfer);
     175                return;
     176        }
     177
     178        switch (transfer->direction) {
     179                case USB_DIRECTION_IN:
     180                        hc_add_transaction_from_device(transfer->target,
     181                            USB_TRANSFER_CONTROL,
     182                            transfer->data_buffer, transfer->data_buffer_size,
     183                            control_callback_two, transfer);
     184                        break;
     185                case USB_DIRECTION_OUT:
     186                        hc_add_transaction_to_device(false, transfer->target,
     187                            USB_TRANSFER_CONTROL,
     188                            transfer->data_buffer, transfer->data_buffer_size,
     189                            control_callback_two, transfer);
     190                        break;
     191                default:
     192                        assert(false && "unreachable");
     193                        break;
     194        }
     195}
     196
     197static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun,
     198    usb_direction_t direction, usb_target_t target,
     199    void *data_buffer, size_t data_buffer_size,
     200    void *arg)
     201{
     202        control_transfer_info_t *transfer
     203            = malloc(sizeof(control_transfer_info_t));
     204
     205        transfer->direction = direction;
     206        transfer->target = target;
     207        transfer->in_callback = NULL;
     208        transfer->out_callback = NULL;
     209        transfer->arg = arg;
     210        transfer->fun = fun;
     211        transfer->data_buffer = data_buffer;
     212        transfer->data_buffer_size = data_buffer_size;
     213
     214        return transfer;
     215}
     216
     217static int enqueue_transfer_out(ddf_fun_t *fun,
     218    usb_target_t target, usb_transfer_type_t transfer_type,
     219    void *buffer, size_t size,
     220    usbhc_iface_transfer_out_callback_t callback, void *arg)
     221{
     222        usb_log_debug2("Transfer OUT [%d.%d (%s); %zu].\n",
     223            target.address, target.endpoint,
     224            usb_str_transfer_type(transfer_type),
     225            size);
     226
     227        transfer_info_t *transfer
     228            = create_transfer_info(fun, USB_DIRECTION_OUT, arg);
     229        transfer->out_callback = callback;
     230
     231        hc_add_transaction_to_device(false, target, transfer_type, buffer, size,
     232            universal_callback, transfer);
     233
     234        return EOK;
     235}
     236
     237static int enqueue_transfer_in(ddf_fun_t *fun,
     238    usb_target_t target, usb_transfer_type_t transfer_type,
     239    void *buffer, size_t size,
     240    usbhc_iface_transfer_in_callback_t callback, void *arg)
     241{
     242        usb_log_debug2("Transfer IN [%d.%d (%s); %zu].\n",
     243            target.address, target.endpoint,
     244            usb_str_transfer_type(transfer_type),
     245            size);
     246
     247        transfer_info_t *transfer
     248            = create_transfer_info(fun, USB_DIRECTION_IN, arg);
     249        transfer->in_callback = callback;
     250
     251        hc_add_transaction_from_device(target, transfer_type, buffer, size,
     252            universal_callback, transfer);
     253
     254        return EOK;
     255}
     256
     257
    192258static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    193259    void *data, size_t size,
    194260    usbhc_iface_transfer_out_callback_t callback, void *arg)
    195261{
    196         VHC_DATA(vhc, fun);
    197 
    198         vhc_transfer_t *transfer = vhc_transfer_create(target.address,
    199             target.endpoint, USB_DIRECTION_OUT, USB_TRANSFER_INTERRUPT,
    200             fun, arg);
    201         if (transfer == NULL) {
    202                 return ENOMEM;
    203         }
    204 
    205         transfer->data_buffer = data;
    206         transfer->data_buffer_size = size;
    207         transfer->callback_out = callback;
    208 
    209         int rc = vhc_virtdev_add_transfer(vhc, transfer);
    210         if (rc != EOK) {
    211                 free(transfer);
    212                 return rc;
    213         }
    214 
    215         return EOK;
    216 }
    217 
    218 /** Schedule interrupt in transfer.
    219  *
    220  * The callback is supposed to be called once the transfer (on the wire) is
    221  * complete regardless of the outcome.
    222  * However, the callback could be called only when this function returns
    223  * with success status (i.e. returns EOK).
    224  *
    225  * @param[in] fun Device function the action was invoked on.
    226  * @param[in] target Target pipe (address and endpoint number) specification.
    227  * @param[in] data Buffer where to store the data (in USB endianess,
    228  *      allocated and deallocated by the caller).
    229  * @param[in] size Size of the @p data buffer in bytes.
    230  * @param[in] callback Callback to be issued once the transfer is complete.
    231  * @param[in] arg Pass-through argument to the callback.
    232  * @return Error code.
    233  */
     262        return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT,
     263            data, size,
     264            callback, arg);
     265}
     266
    234267static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    235268    void *data, size_t size,
    236269    usbhc_iface_transfer_in_callback_t callback, void *arg)
    237270{
    238         VHC_DATA(vhc, fun);
    239 
    240         vhc_transfer_t *transfer = vhc_transfer_create(target.address,
    241             target.endpoint, USB_DIRECTION_IN, USB_TRANSFER_INTERRUPT,
    242             fun, arg);
    243         if (transfer == NULL) {
    244                 return ENOMEM;
    245         }
    246 
    247         transfer->data_buffer = data;
    248         transfer->data_buffer_size = size;
    249         transfer->callback_in = callback;
    250 
    251         int rc = vhc_virtdev_add_transfer(vhc, transfer);
    252         if (rc != EOK) {
    253                 free(transfer);
    254                 return rc;
    255         }
    256 
    257         return EOK;
    258 }
    259 
    260 /** Schedule bulk out transfer.
    261  *
    262  * The callback is supposed to be called once the transfer (on the wire) is
    263  * complete regardless of the outcome.
    264  * However, the callback could be called only when this function returns
    265  * with success status (i.e. returns EOK).
    266  *
    267  * @param[in] fun Device function the action was invoked on.
    268  * @param[in] target Target pipe (address and endpoint number) specification.
    269  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    270  *      by the caller).
    271  * @param[in] size Size of the @p data buffer in bytes.
    272  * @param[in] callback Callback to be issued once the transfer is complete.
    273  * @param[in] arg Pass-through argument to the callback.
    274  * @return Error code.
    275  */
    276 static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    277     void *data, size_t size,
    278     usbhc_iface_transfer_out_callback_t callback, void *arg)
    279 {
    280         UNSUPPORTED("bulk_out");
    281 
    282         return ENOTSUP;
    283 }
    284 
    285 /** Schedule bulk in transfer.
    286  *
    287  * The callback is supposed to be called once the transfer (on the wire) is
    288  * complete regardless of the outcome.
    289  * However, the callback could be called only when this function returns
    290  * with success status (i.e. returns EOK).
    291  *
    292  * @param[in] fun Device function the action was invoked on.
    293  * @param[in] target Target pipe (address and endpoint number) specification.
    294  * @param[in] data Buffer where to store the data (in USB endianess,
    295  *      allocated and deallocated by the caller).
    296  * @param[in] size Size of the @p data buffer in bytes.
    297  * @param[in] callback Callback to be issued once the transfer is complete.
    298  * @param[in] arg Pass-through argument to the callback.
    299  * @return Error code.
    300  */
    301 static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    302     void *data, size_t size,
    303     usbhc_iface_transfer_in_callback_t callback, void *arg)
    304 {
    305         UNSUPPORTED("bulk_in");
    306 
    307         return ENOTSUP;
    308 }
    309 
    310 /** Schedule control write transfer.
    311  *
    312  * The callback is supposed to be called once the transfer (on the wire) is
    313  * complete regardless of the outcome.
    314  * However, the callback could be called only when this function returns
    315  * with success status (i.e. returns EOK).
    316  *
    317  * @param[in] fun Device function the action was invoked on.
    318  * @param[in] target Target pipe (address and endpoint number) specification.
    319  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    320  *      and deallocated by the caller).
    321  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    322  * @param[in] data_buffer Data buffer (in USB endianess, allocated and
    323  *      deallocated by the caller).
    324  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    325  * @param[in] callback Callback to be issued once the transfer is complete.
    326  * @param[in] arg Pass-through argument to the callback.
    327  * @return Error code.
    328  */
     271        return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT,
     272            data, size,
     273            callback, arg);
     274}
     275
    329276static int control_write(ddf_fun_t *fun, usb_target_t target,
    330277    void *setup_packet, size_t setup_packet_size,
    331     void *data_buffer, size_t data_buffer_size,
     278    void *data, size_t data_size,
    332279    usbhc_iface_transfer_out_callback_t callback, void *arg)
    333280{
    334         VHC_DATA(vhc, fun);
    335 
    336         vhc_transfer_t *transfer = vhc_transfer_create(target.address,
    337             target.endpoint, USB_DIRECTION_OUT, USB_TRANSFER_CONTROL,
    338             fun, arg);
    339         if (transfer == NULL) {
    340                 return ENOMEM;
    341         }
    342 
    343         transfer->setup_buffer = setup_packet;
    344         transfer->setup_buffer_size = setup_packet_size;
    345         transfer->data_buffer = data_buffer;
    346         transfer->data_buffer_size = data_buffer_size;
    347         transfer->callback_out = callback;
    348 
    349         int rc = vhc_virtdev_add_transfer(vhc, transfer);
    350         if (rc != EOK) {
    351                 free(transfer);
    352                 return rc;
    353         }
    354 
    355         return EOK;
    356 }
    357 
    358 /** Schedule control read transfer.
    359  *
    360  * The callback is supposed to be called once the transfer (on the wire) is
    361  * complete regardless of the outcome.
    362  * However, the callback could be called only when this function returns
    363  * with success status (i.e. returns EOK).
    364  *
    365  * @param[in] fun Device function the action was invoked on.
    366  * @param[in] target Target pipe (address and endpoint number) specification.
    367  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    368  *      and deallocated by the caller).
    369  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    370  * @param[in] data_buffer Buffer where to store the data (in USB endianess,
    371  *      allocated and deallocated by the caller).
    372  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    373  * @param[in] callback Callback to be issued once the transfer is complete.
    374  * @param[in] arg Pass-through argument to the callback.
    375  * @return Error code.
    376  */
     281        control_transfer_info_t *transfer
     282            = create_control_transfer_info(fun, USB_DIRECTION_OUT, target,
     283            data, data_size, arg);
     284        transfer->out_callback = callback;
     285
     286        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     287            setup_packet, setup_packet_size,
     288            control_callback_one, transfer);
     289
     290        return EOK;
     291}
     292
    377293static int control_read(ddf_fun_t *fun, usb_target_t target,
    378294    void *setup_packet, size_t setup_packet_size,
    379     void *data_buffer, size_t data_buffer_size,
     295    void *data, size_t data_size,
    380296    usbhc_iface_transfer_in_callback_t callback, void *arg)
    381297{
    382         VHC_DATA(vhc, fun);
    383 
    384         vhc_transfer_t *transfer = vhc_transfer_create(target.address,
    385             target.endpoint, USB_DIRECTION_IN, USB_TRANSFER_CONTROL,
    386             fun, arg);
    387         if (transfer == NULL) {
    388                 return ENOMEM;
    389         }
    390 
    391         transfer->setup_buffer = setup_packet;
    392         transfer->setup_buffer_size = setup_packet_size;
    393         transfer->data_buffer = data_buffer;
    394         transfer->data_buffer_size = data_buffer_size;
    395         transfer->callback_in = callback;
    396 
    397         int rc = vhc_virtdev_add_transfer(vhc, transfer);
    398         if (rc != EOK) {
    399                 free(transfer);
    400                 return rc;
    401         }
    402 
    403         return EOK;
    404 }
     298        control_transfer_info_t *transfer
     299            = create_control_transfer_info(fun, USB_DIRECTION_IN, target,
     300            data, data_size, arg);
     301        transfer->in_callback = callback;
     302
     303        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     304            setup_packet, setup_packet_size,
     305            control_callback_one, transfer);
     306
     307        return EOK;
     308}
     309
     310static usb_address_keeping_t addresses;
    405311
    406312static int tell_address(ddf_fun_t *fun, devman_handle_t handle,
    407313    usb_address_t *address)
    408314{
    409         UNSUPPORTED("tell_address");
    410 
    411         return ENOTSUP;
     315        usb_log_debug("tell_address(fun \"%s\", handle %zu)\n",
     316            fun->name, (size_t) fun->handle);
     317        usb_address_t addr = usb_address_keeping_find(&addresses, handle);
     318        if (addr < 0) {
     319                return addr;
     320        }
     321
     322        *address = addr;
     323        return EOK;
     324}
     325
     326static int request_address(ddf_fun_t *fun, usb_speed_t ignored,
     327    usb_address_t *address)
     328{
     329        usb_address_t addr = usb_address_keeping_request(&addresses);
     330        if (addr < 0) {
     331                return (int)addr;
     332        }
     333
     334        *address = addr;
     335        return EOK;
     336}
     337
     338static int release_address(ddf_fun_t *fun, usb_address_t address)
     339{
     340        return usb_address_keeping_release(&addresses, address);
     341}
     342
     343static int bind_address(ddf_fun_t *fun, usb_address_t address,
     344    devman_handle_t handle)
     345{
     346        usb_address_keeping_devman_bind(&addresses, address, handle);
     347        return EOK;
    412348}
    413349
     
    415351    devman_handle_t *handle)
    416352{
    417         VHC_DATA(vhc, root_hub_fun);
    418 
    419         *handle = vhc->hc_fun->handle;
     353        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
     354        assert(hc_fun != NULL);
     355
     356        *handle = hc_fun->handle;
     357
     358        usb_log_debug("usb_iface_get_hc_handle_rh_impl returns %zu\n", *handle);
    420359
    421360        return EOK;
     
    425364    usb_address_t *address)
    426365{
    427         VHC_DATA(vhc, root_hub_fun);
    428 
    429         if (handle == 0) {
    430                 handle = root_hub_fun->handle;
    431         }
    432 
    433         usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle);
    434         usb_address_t addr = usb_device_keeper_find(&vhc->dev_keeper, handle);
    435         if (addr < 0) {
    436                 return addr;
    437         } else {
    438                 *address = addr;
    439                 return EOK;
    440         }
     366        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
     367        assert(hc_fun != NULL);
     368
     369        return tell_address(hc_fun, root_hub_fun->handle, address);
     370}
     371
     372void address_init(void)
     373{
     374        usb_address_keeping_init(&addresses, 50);
    441375}
    442376
     
    446380        .release_address = release_address,
    447381
    448         .register_endpoint = register_endpoint,
    449         .unregister_endpoint = unregister_endpoint,
    450 
    451382        .interrupt_out = interrupt_out,
    452383        .interrupt_in = interrupt_in,
    453 
    454         .bulk_in = bulk_in,
    455         .bulk_out = bulk_out,
    456384
    457385        .control_write = control_write,
Note: See TracChangeset for help on using the changeset viewer.