Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/iface.c

    r6bec59b r1998bcd  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky, Jan Vesely
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    3030 */
    3131/** @file
    32  * @brief OHCI driver hc interface implementation
     32 * USB-HC interface implementation.
    3333 */
    3434#include <ddf/driver.h>
     
    3636
    3737#include <usb/debug.h>
    38 #include <usb/host/endpoint.h>
    3938
    4039#include "iface.h"
    4140#include "hc.h"
    4241
    43 static inline int setup_batch(
    44     ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
    45     void *data, size_t size, void * setup_data, size_t setup_size,
    46     usbhc_iface_transfer_in_callback_t in,
    47     usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
    48     hc_t **hc, usb_transfer_batch_t **batch)
    49 {
    50         assert(hc);
    51         assert(batch);
    52         assert(fun);
    53         *hc = fun_to_hc(fun);
    54         assert(*hc);
    55 
    56         size_t res_bw;
    57         endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
    58             target.address, target.endpoint, direction, &res_bw);
    59         if (ep == NULL) {
    60                 usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
    61                     target.address, target.endpoint, name);
    62                 return ENOENT;
    63         }
    64 
    65         const size_t bw = bandwidth_count_usb11(
    66             ep->speed, ep->transfer_type, size, ep->max_packet_size);
    67         if (res_bw < bw) {
    68                 usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    69                     "but only %zu is reserved.\n",
    70                     name, target.address, target.endpoint, bw, res_bw);
    71                 return ENOSPC;
    72         }
    73         usb_log_debug("%s %d:%d %zu(%zu).\n",
    74             name, target.address, target.endpoint, size, ep->max_packet_size);
    75 
    76         assert(ep->speed ==
    77             usb_device_keeper_get_speed(&(*hc)->manager, target.address));
    78 //      assert(ep->max_packet_size == max_packet_size);
    79 //      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
    80 
    81         *batch =
    82             batch_get(fun, ep, data, size, setup_data, setup_size,
    83                 in, out, arg);
    84         if (!batch)
    85                 return ENOMEM;
    86         return EOK;
    87 }
    88 
    89 
    90 /** Reserve default address interface function
    91  *
    92  * @param[in] fun DDF function that was called.
    93  * @param[in] speed Speed to associate with the new default address.
     42#define UNSUPPORTED(methodname) \
     43        usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \
     44            methodname, __FILE__, __LINE__)
     45
     46/** Reserve default address.
     47 *
     48 * This function may block the caller.
     49 *
     50 * @param[in] fun Device function the action was invoked on.
     51 * @param[in] speed Speed of the device for which the default address is
     52 *      reserved.
    9453 * @return Error code.
    9554 */
     
    10261        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    10362        return EOK;
    104 #if 0
    105         endpoint_t *ep = malloc(sizeof(endpoint_t));
    106         if (ep == NULL)
    107                 return ENOMEM;
    108         const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
    109         endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
    110         int ret;
    111 try_retgister:
    112         ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
    113             USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
    114         if (ret == EEXISTS) {
    115                 async_usleep(1000);
    116                 goto try_retgister;
    117         }
    118         if (ret != EOK) {
    119                 endpoint_destroy(ep);
    120         }
    121         return ret;
    122 #endif
    123 }
    124 /*----------------------------------------------------------------------------*/
    125 /** Release default address interface function
    126  *
    127  * @param[in] fun DDF function that was called.
     63}
     64/*----------------------------------------------------------------------------*/
     65/** Release default address.
     66 *
     67 * @param[in] fun Device function the action was invoked on.
    12868 * @return Error code.
    12969 */
     
    13474        assert(hc);
    13575        usb_log_debug("Default address release.\n");
    136 //      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
    137 //          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
    13876        usb_device_keeper_release_default_address(&hc->manager);
    13977        return EOK;
    14078}
    14179/*----------------------------------------------------------------------------*/
    142 /** Request address interface function
    143  *
    144  * @param[in] fun DDF function that was called.
    145  * @param[in] speed Speed to associate with the new default address.
    146  * @param[out] address Place to write a new address.
     80/** Found free USB address.
     81 *
     82 * @param[in] fun Device function the action was invoked on.
     83 * @param[in] speed Speed of the device that will get this address.
     84 * @param[out] address Non-null pointer where to store the free address.
    14785 * @return Error code.
    14886 */
     
    163101}
    164102/*----------------------------------------------------------------------------*/
    165 /** Bind address interface function
    166  *
    167  * @param[in] fun DDF function that was called.
    168  * @param[in] address Address of the device
    169  * @param[in] handle Devman handle of the device driver.
     103/** Bind USB address with device devman handle.
     104 *
     105 * @param[in] fun Device function the action was invoked on.
     106 * @param[in] address USB address of the device.
     107 * @param[in] handle Devman handle of the device.
    170108 * @return Error code.
    171109 */
    172110static int bind_address(
    173   ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     111    ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    174112{
    175113        assert(fun);
     
    181119}
    182120/*----------------------------------------------------------------------------*/
    183 /** Release address interface function
    184  *
    185  * @param[in] fun DDF function that was called.
     121/** Release previously requested address.
     122 *
     123 * @param[in] fun Device function the action was invoked on.
    186124 * @param[in] address USB address to be released.
    187125 * @return Error code.
     
    197135}
    198136/*----------------------------------------------------------------------------*/
    199 static int register_endpoint(
    200     ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
     137/** Register endpoint for bandwidth reservation.
     138 *
     139 * @param[in] fun Device function the action was invoked on.
     140 * @param[in] address USB address of the device.
     141 * @param[in] ep_speed Endpoint speed (invalid means to use device one).
     142 * @param[in] endpoint Endpoint number.
     143 * @param[in] transfer_type USB transfer type.
     144 * @param[in] direction Endpoint data direction.
     145 * @param[in] max_packet_size Max packet size of the endpoint.
     146 * @param[in] interval Polling interval.
     147 * @return Error code.
     148 */
     149static int register_endpoint(ddf_fun_t *fun,
     150    usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint,
    201151    usb_transfer_type_t transfer_type, usb_direction_t direction,
    202152    size_t max_packet_size, unsigned int interval)
    203153{
    204         hc_t *hc = fun_to_hc(fun);
    205         assert(hc);
    206         const usb_speed_t speed =
    207             usb_device_keeper_get_speed(&hc->manager, address);
    208         const size_t size =
    209             (transfer_type == USB_TRANSFER_INTERRUPT
    210             || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
    211             max_packet_size : 0;
    212         int ret;
    213 
    214         endpoint_t *ep = malloc(sizeof(endpoint_t));
    215         if (ep == NULL)
    216                 return ENOMEM;
    217         ret = endpoint_init(ep, address, endpoint, direction,
    218             transfer_type, speed, max_packet_size);
    219         if (ret != EOK) {
    220                 free(ep);
    221                 return ret;
    222         }
    223 
     154        assert(fun);
     155        hc_t *hc = fun_to_hc(fun);
     156        assert(hc);
     157        if (address == hc->rh.address)
     158                return EOK;
     159        usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
     160        if (speed >= USB_SPEED_MAX) {
     161                speed = ep_speed;
     162        }
     163        const size_t size = max_packet_size;
    224164        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    225165            address, endpoint, usb_str_transfer_type(transfer_type),
    226166            usb_str_speed(speed), direction, size, max_packet_size, interval);
    227 
    228         ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
    229         if (ret != EOK) {
    230                 endpoint_destroy(ep);
    231         } else {
    232                 usb_device_keeper_add_ep(&hc->manager, address, ep);
    233         }
    234         return ret;
    235 }
    236 /*----------------------------------------------------------------------------*/
     167        // TODO use real endpoint here!
     168        return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0);
     169}
     170/*----------------------------------------------------------------------------*/
     171/** Unregister endpoint (free some bandwidth reservation).
     172 *
     173 * @param[in] fun Device function the action was invoked on.
     174 * @param[in] address USB address of the device.
     175 * @param[in] endpoint Endpoint number.
     176 * @param[in] direction Endpoint data direction.
     177 * @return Error code.
     178 */
    237179static int unregister_endpoint(
    238180    ddf_fun_t *fun, usb_address_t address,
    239181    usb_endpoint_t endpoint, usb_direction_t direction)
    240182{
     183        assert(fun);
    241184        hc_t *hc = fun_to_hc(fun);
    242185        assert(hc);
    243186        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    244187            address, endpoint, direction);
     188        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     189            address, endpoint, direction, NULL);
     190        if (ep != NULL) {
     191                usb_device_keeper_del_ep(&hc->manager, address, ep);
     192        }
    245193        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    246194            endpoint, direction);
    247195}
    248196/*----------------------------------------------------------------------------*/
    249 /** Interrupt out transaction interface function
    250  *
    251  * @param[in] fun DDF function that was called.
    252  * @param[in] target USB device to write to.
    253  * @param[in] max_packet_size maximum size of data packet the device accepts
    254  * @param[in] data Source of data.
    255  * @param[in] size Size of data source.
    256  * @param[in] callback Function to call on transaction completion
    257  * @param[in] arg Additional for callback function.
     197/** Schedule interrupt out transfer.
     198 *
     199 * The callback is supposed to be called once the transfer (on the wire) is
     200 * complete regardless of the outcome.
     201 * However, the callback could be called only when this function returns
     202 * with success status (i.e. returns EOK).
     203 *
     204 * @param[in] fun Device function the action was invoked on.
     205 * @param[in] target Target pipe (address and endpoint number) specification.
     206 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
     207 *      by the caller).
     208 * @param[in] size Size of the @p data buffer in bytes.
     209 * @param[in] callback Callback to be issued once the transfer is complete.
     210 * @param[in] arg Pass-through argument to the callback.
    258211 * @return Error code.
    259212 */
    260213static int interrupt_out(
    261     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     214    ddf_fun_t *fun, usb_target_t target, void *data,
    262215    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    263216{
    264         usb_transfer_batch_t *batch = NULL;
    265         hc_t *hc = NULL;
    266         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    267             NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
    268         if (ret != EOK)
    269                 return ret;
     217        assert(fun);
     218
     219        // FIXME: get from endpoint manager
     220        size_t max_packet_size = 8;
     221
     222        hc_t *hc = fun_to_hc(fun);
     223        assert(hc);
     224        usb_speed_t speed =
     225            usb_device_keeper_get_speed(&hc->manager, target.address);
     226
     227        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     228            target.address, target.endpoint, size, max_packet_size);
     229
     230        usb_transfer_batch_t *batch =
     231            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     232                speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     233        if (!batch)
     234                return ENOMEM;
    270235        batch_interrupt_out(batch);
    271         ret = hc_schedule(hc, batch);
     236        const int ret = hc_schedule(hc, batch);
    272237        if (ret != EOK) {
    273238                batch_dispose(batch);
     
    276241}
    277242/*----------------------------------------------------------------------------*/
    278 /** Interrupt in transaction interface function
    279  *
    280  * @param[in] fun DDF function that was called.
    281  * @param[in] target USB device to write to.
    282  * @param[in] max_packet_size maximum size of data packet the device accepts
    283  * @param[out] data Data destination.
    284  * @param[in] size Size of data source.
    285  * @param[in] callback Function to call on transaction completion
    286  * @param[in] arg Additional for callback function.
     243/** Schedule interrupt in transfer.
     244 *
     245 * The callback is supposed to be called once the transfer (on the wire) is
     246 * complete regardless of the outcome.
     247 * However, the callback could be called only when this function returns
     248 * with success status (i.e. returns EOK).
     249 *
     250 * @param[in] fun Device function the action was invoked on.
     251 * @param[in] target Target pipe (address and endpoint number) specification.
     252 * @param[in] data Buffer where to store the data (in USB endianess,
     253 *      allocated and deallocated by the caller).
     254 * @param[in] size Size of the @p data buffer in bytes.
     255 * @param[in] callback Callback to be issued once the transfer is complete.
     256 * @param[in] arg Pass-through argument to the callback.
    287257 * @return Error code.
    288258 */
    289259static int interrupt_in(
    290     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     260    ddf_fun_t *fun, usb_target_t target, void *data,
    291261    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    292262{
    293         usb_transfer_batch_t *batch = NULL;
    294         hc_t *hc = NULL;
    295         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    296             NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
    297         if (ret != EOK)
    298                 return ret;
     263        assert(fun);
     264
     265        // FIXME: get from endpoint manager
     266        size_t max_packet_size = 8;
     267
     268        hc_t *hc = fun_to_hc(fun);
     269        assert(hc);
     270        usb_speed_t speed =
     271            usb_device_keeper_get_speed(&hc->manager, target.address);
     272        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     273            target.address, target.endpoint, size, max_packet_size);
     274
     275        usb_transfer_batch_t *batch =
     276            batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
     277                speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     278        if (!batch)
     279                return ENOMEM;
    299280        batch_interrupt_in(batch);
    300         ret = hc_schedule(hc, batch);
     281        const int ret = hc_schedule(hc, batch);
    301282        if (ret != EOK) {
    302283                batch_dispose(batch);
     
    305286}
    306287/*----------------------------------------------------------------------------*/
    307 /** Bulk out transaction interface function
    308  *
    309  * @param[in] fun DDF function that was called.
    310  * @param[in] target USB device to write to.
    311  * @param[in] max_packet_size maximum size of data packet the device accepts
    312  * @param[in] data Source of data.
    313  * @param[in] size Size of data source.
    314  * @param[in] callback Function to call on transaction completion
    315  * @param[in] arg Additional for callback function.
     288/** Schedule bulk out transfer.
     289 *
     290 * The callback is supposed to be called once the transfer (on the wire) is
     291 * complete regardless of the outcome.
     292 * However, the callback could be called only when this function returns
     293 * with success status (i.e. returns EOK).
     294 *
     295 * @param[in] fun Device function the action was invoked on.
     296 * @param[in] target Target pipe (address and endpoint number) specification.
     297 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
     298 *      by the caller).
     299 * @param[in] size Size of the @p data buffer in bytes.
     300 * @param[in] callback Callback to be issued once the transfer is complete.
     301 * @param[in] arg Pass-through argument to the callback.
    316302 * @return Error code.
    317303 */
    318304static int bulk_out(
    319     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     305    ddf_fun_t *fun, usb_target_t target, void *data,
    320306    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    321307{
    322         usb_transfer_batch_t *batch = NULL;
    323         hc_t *hc = NULL;
    324         int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
    325             NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
    326         if (ret != EOK)
    327                 return ret;
     308        assert(fun);
     309
     310        // FIXME: get from endpoint manager
     311        size_t max_packet_size = 8;
     312
     313        hc_t *hc = fun_to_hc(fun);
     314        assert(hc);
     315        usb_speed_t speed =
     316            usb_device_keeper_get_speed(&hc->manager, target.address);
     317
     318        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
     319            target.address, target.endpoint, size, max_packet_size);
     320
     321        usb_transfer_batch_t *batch =
     322            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     323                data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     324        if (!batch)
     325                return ENOMEM;
    328326        batch_bulk_out(batch);
    329         ret = hc_schedule(hc, batch);
     327        const int ret = hc_schedule(hc, batch);
    330328        if (ret != EOK) {
    331329                batch_dispose(batch);
     
    334332}
    335333/*----------------------------------------------------------------------------*/
    336 /** Bulk in transaction interface function
    337  *
    338  * @param[in] fun DDF function that was called.
    339  * @param[in] target USB device to write to.
    340  * @param[in] max_packet_size maximum size of data packet the device accepts
    341  * @param[out] data Data destination.
    342  * @param[in] size Size of data source.
    343  * @param[in] callback Function to call on transaction completion
    344  * @param[in] arg Additional for callback function.
     334/** Schedule bulk in transfer.
     335 *
     336 * The callback is supposed to be called once the transfer (on the wire) is
     337 * complete regardless of the outcome.
     338 * However, the callback could be called only when this function returns
     339 * with success status (i.e. returns EOK).
     340 *
     341 * @param[in] fun Device function the action was invoked on.
     342 * @param[in] target Target pipe (address and endpoint number) specification.
     343 * @param[in] data Buffer where to store the data (in USB endianess,
     344 *      allocated and deallocated by the caller).
     345 * @param[in] size Size of the @p data buffer in bytes.
     346 * @param[in] callback Callback to be issued once the transfer is complete.
     347 * @param[in] arg Pass-through argument to the callback.
    345348 * @return Error code.
    346349 */
    347350static int bulk_in(
    348     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     351    ddf_fun_t *fun, usb_target_t target, void *data,
    349352    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    350353{
    351         usb_transfer_batch_t *batch = NULL;
    352         hc_t *hc = NULL;
    353         int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
    354             NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
    355         if (ret != EOK)
    356                 return ret;
     354        assert(fun);
     355
     356        // FIXME: get from endpoint manager
     357        size_t max_packet_size = 8;
     358
     359        hc_t *hc = fun_to_hc(fun);
     360        assert(hc);
     361        usb_speed_t speed =
     362            usb_device_keeper_get_speed(&hc->manager, target.address);
     363        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
     364            target.address, target.endpoint, size, max_packet_size);
     365
     366        usb_transfer_batch_t *batch =
     367            batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
     368                data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     369        if (!batch)
     370                return ENOMEM;
    357371        batch_bulk_in(batch);
    358         ret = hc_schedule(hc, batch);
     372        const int ret = hc_schedule(hc, batch);
    359373        if (ret != EOK) {
    360374                batch_dispose(batch);
     
    363377}
    364378/*----------------------------------------------------------------------------*/
    365 /** Control write transaction interface function
    366  *
    367  * @param[in] fun DDF function that was called.
    368  * @param[in] target USB device to write to.
    369  * @param[in] max_packet_size maximum size of data packet the device accepts.
    370  * @param[in] setup_data Data to send with SETUP transfer.
    371  * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
    372  * @param[in] data Source of data.
    373  * @param[in] size Size of data source.
    374  * @param[in] callback Function to call on transaction completion.
    375  * @param[in] arg Additional for callback function.
     379/** Schedule control write transfer.
     380 *
     381 * The callback is supposed to be called once the transfer (on the wire) is
     382 * complete regardless of the outcome.
     383 * However, the callback could be called only when this function returns
     384 * with success status (i.e. returns EOK).
     385 *
     386 * @param[in] fun Device function the action was invoked on.
     387 * @param[in] target Target pipe (address and endpoint number) specification.
     388 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
     389 *      and deallocated by the caller).
     390 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
     391 * @param[in] data_buffer Data buffer (in USB endianess, allocated and
     392 *      deallocated by the caller).
     393 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
     394 * @param[in] callback Callback to be issued once the transfer is complete.
     395 * @param[in] arg Pass-through argument to the callback.
    376396 * @return Error code.
    377397 */
    378398static int control_write(
    379     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     399    ddf_fun_t *fun, usb_target_t target,
    380400    void *setup_data, size_t setup_size, void *data, size_t size,
    381401    usbhc_iface_transfer_out_callback_t callback, void *arg)
    382402{
    383         usb_transfer_batch_t *batch = NULL;
    384         hc_t *hc = NULL;
    385         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    386             setup_data, setup_size, NULL, callback, arg, "Control WRITE",
    387             &hc, &batch);
    388         if (ret != EOK)
    389                 return ret;
     403        assert(fun);
     404
     405        // FIXME: get from endpoint manager
     406        size_t max_packet_size = 8;
     407
     408        hc_t *hc = fun_to_hc(fun);
     409        assert(hc);
     410        usb_speed_t speed =
     411            usb_device_keeper_get_speed(&hc->manager, target.address);
     412        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
     413            speed, target.address, target.endpoint, size, max_packet_size);
     414
     415        if (setup_size != 8)
     416                return EINVAL;
     417
     418        usb_transfer_batch_t *batch =
     419            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     420                speed, data, size, setup_data, setup_size, NULL, callback, arg,
     421                &hc->manager);
     422        if (!batch)
     423                return ENOMEM;
    390424        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    391425        batch_control_write(batch);
    392         ret = hc_schedule(hc, batch);
     426        const int ret = hc_schedule(hc, batch);
    393427        if (ret != EOK) {
    394428                batch_dispose(batch);
     
    397431}
    398432/*----------------------------------------------------------------------------*/
    399 /** Control read transaction interface function
    400  *
    401  * @param[in] fun DDF function that was called.
    402  * @param[in] target USB device to write to.
    403  * @param[in] max_packet_size maximum size of data packet the device accepts.
    404  * @param[in] setup_data Data to send with SETUP packet.
    405  * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
    406  * @param[out] data Source of data.
    407  * @param[in] size Size of data source.
    408  * @param[in] callback Function to call on transaction completion.
    409  * @param[in] arg Additional for callback function.
     433/** Schedule control read transfer.
     434 *
     435 * The callback is supposed to be called once the transfer (on the wire) is
     436 * complete regardless of the outcome.
     437 * However, the callback could be called only when this function returns
     438 * with success status (i.e. returns EOK).
     439 *
     440 * @param[in] fun Device function the action was invoked on.
     441 * @param[in] target Target pipe (address and endpoint number) specification.
     442 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
     443 *      and deallocated by the caller).
     444 * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
     445 * @param[in] data_buffer Buffer where to store the data (in USB endianess,
     446 *      allocated and deallocated by the caller).
     447 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
     448 * @param[in] callback Callback to be issued once the transfer is complete.
     449 * @param[in] arg Pass-through argument to the callback.
    410450 * @return Error code.
    411451 */
    412452static int control_read(
    413     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     453    ddf_fun_t *fun, usb_target_t target,
    414454    void *setup_data, size_t setup_size, void *data, size_t size,
    415455    usbhc_iface_transfer_in_callback_t callback, void *arg)
    416456{
    417         usb_transfer_batch_t *batch = NULL;
    418         hc_t *hc = NULL;
    419         int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
    420             setup_data, setup_size, callback, NULL, arg, "Control READ",
    421             &hc, &batch);
    422         if (ret != EOK)
    423                 return ret;
     457        assert(fun);
     458
     459        // FIXME: get from endpoint manager
     460        size_t max_packet_size = 8;
     461
     462        hc_t *hc = fun_to_hc(fun);
     463        assert(hc);
     464        usb_speed_t speed =
     465            usb_device_keeper_get_speed(&hc->manager, target.address);
     466
     467        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
     468            speed, target.address, target.endpoint, size, max_packet_size);
     469        usb_transfer_batch_t *batch =
     470            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size,
     471                speed, data, size, setup_data, setup_size, callback, NULL, arg,
     472                &hc->manager);
     473        if (!batch)
     474                return ENOMEM;
    424475        batch_control_read(batch);
    425         ret = hc_schedule(hc, batch);
     476        const int ret = hc_schedule(hc, batch);
    426477        if (ret != EOK) {
    427478                batch_dispose(batch);
     
    430481}
    431482/*----------------------------------------------------------------------------*/
     483/** Host controller interface implementation for OHCI. */
    432484usbhc_iface_t hc_iface = {
    433485        .reserve_default_address = reserve_default_address,
     
    449501        .control_read = control_read,
    450502};
     503
    451504/**
    452505 * @}
Note: See TracChangeset for help on using the changeset viewer.