Ignore:
File:
1 edited

Legend:

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

    r1998bcd r6bec59b  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky, Jan Vesely
    33 * All rights reserved.
    44 *
     
    3030 */
    3131/** @file
    32  * USB-HC interface implementation.
     32 * @brief OHCI driver hc interface implementation
    3333 */
    3434#include <ddf/driver.h>
     
    3636
    3737#include <usb/debug.h>
     38#include <usb/host/endpoint.h>
    3839
    3940#include "iface.h"
    4041#include "hc.h"
    4142
    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.
     43static 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.
    5394 * @return Error code.
    5495 */
     
    61102        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    62103        return EOK;
    63 }
    64 /*----------------------------------------------------------------------------*/
    65 /** Release default address.
    66  *
    67  * @param[in] fun Device function the action was invoked on.
     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;
     111try_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.
    68128 * @return Error code.
    69129 */
     
    74134        assert(hc);
    75135        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);
    76138        usb_device_keeper_release_default_address(&hc->manager);
    77139        return EOK;
    78140}
    79141/*----------------------------------------------------------------------------*/
    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.
     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.
    85147 * @return Error code.
    86148 */
     
    101163}
    102164/*----------------------------------------------------------------------------*/
    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.
     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.
    108170 * @return Error code.
    109171 */
    110172static int bind_address(
    111     ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     173  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    112174{
    113175        assert(fun);
     
    119181}
    120182/*----------------------------------------------------------------------------*/
    121 /** Release previously requested address.
    122  *
    123  * @param[in] fun Device function the action was invoked on.
     183/** Release address interface function
     184 *
     185 * @param[in] fun DDF function that was called.
    124186 * @param[in] address USB address to be released.
    125187 * @return Error code.
     
    135197}
    136198/*----------------------------------------------------------------------------*/
    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  */
    149 static int register_endpoint(ddf_fun_t *fun,
    150     usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint,
     199static int register_endpoint(
     200    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    151201    usb_transfer_type_t transfer_type, usb_direction_t direction,
    152202    size_t max_packet_size, unsigned int interval)
    153203{
    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;
     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
    164224        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    165225            address, endpoint, usb_str_transfer_type(transfer_type),
    166226            usb_str_speed(speed), direction, size, max_packet_size, interval);
    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  */
     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/*----------------------------------------------------------------------------*/
    179237static int unregister_endpoint(
    180238    ddf_fun_t *fun, usb_address_t address,
    181239    usb_endpoint_t endpoint, usb_direction_t direction)
    182240{
    183         assert(fun);
    184241        hc_t *hc = fun_to_hc(fun);
    185242        assert(hc);
    186243        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    187244            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         }
    193245        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    194246            endpoint, direction);
    195247}
    196248/*----------------------------------------------------------------------------*/
    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.
     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.
    211258 * @return Error code.
    212259 */
    213260static int interrupt_out(
    214     ddf_fun_t *fun, usb_target_t target, void *data,
     261    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    215262    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    216263{
    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;
     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;
    235270        batch_interrupt_out(batch);
    236         const int ret = hc_schedule(hc, batch);
    237         if (ret != EOK) {
    238                 batch_dispose(batch);
    239         }
    240         return ret;
    241 }
    242 /*----------------------------------------------------------------------------*/
    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.
     271        ret = hc_schedule(hc, batch);
     272        if (ret != EOK) {
     273                batch_dispose(batch);
     274        }
     275        return ret;
     276}
     277/*----------------------------------------------------------------------------*/
     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.
    257287 * @return Error code.
    258288 */
    259289static int interrupt_in(
    260     ddf_fun_t *fun, usb_target_t target, void *data,
     290    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    261291    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    262292{
    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;
     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;
    280299        batch_interrupt_in(batch);
    281         const int ret = hc_schedule(hc, batch);
    282         if (ret != EOK) {
    283                 batch_dispose(batch);
    284         }
    285         return ret;
    286 }
    287 /*----------------------------------------------------------------------------*/
    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.
     300        ret = hc_schedule(hc, batch);
     301        if (ret != EOK) {
     302                batch_dispose(batch);
     303        }
     304        return ret;
     305}
     306/*----------------------------------------------------------------------------*/
     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.
    302316 * @return Error code.
    303317 */
    304318static int bulk_out(
    305     ddf_fun_t *fun, usb_target_t target, void *data,
     319    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    306320    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    307321{
    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;
     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;
    326328        batch_bulk_out(batch);
    327         const int ret = hc_schedule(hc, batch);
    328         if (ret != EOK) {
    329                 batch_dispose(batch);
    330         }
    331         return ret;
    332 }
    333 /*----------------------------------------------------------------------------*/
    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.
     329        ret = hc_schedule(hc, batch);
     330        if (ret != EOK) {
     331                batch_dispose(batch);
     332        }
     333        return ret;
     334}
     335/*----------------------------------------------------------------------------*/
     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.
    348345 * @return Error code.
    349346 */
    350347static int bulk_in(
    351     ddf_fun_t *fun, usb_target_t target, void *data,
     348    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    352349    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    353350{
    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;
     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;
    371357        batch_bulk_in(batch);
    372         const int ret = hc_schedule(hc, batch);
    373         if (ret != EOK) {
    374                 batch_dispose(batch);
    375         }
    376         return ret;
    377 }
    378 /*----------------------------------------------------------------------------*/
    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.
     358        ret = hc_schedule(hc, batch);
     359        if (ret != EOK) {
     360                batch_dispose(batch);
     361        }
     362        return ret;
     363}
     364/*----------------------------------------------------------------------------*/
     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.
    396376 * @return Error code.
    397377 */
    398378static int control_write(
    399     ddf_fun_t *fun, usb_target_t target,
     379    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    400380    void *setup_data, size_t setup_size, void *data, size_t size,
    401381    usbhc_iface_transfer_out_callback_t callback, void *arg)
    402382{
    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;
     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;
    424390        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    425391        batch_control_write(batch);
    426         const int ret = hc_schedule(hc, batch);
    427         if (ret != EOK) {
    428                 batch_dispose(batch);
    429         }
    430         return ret;
    431 }
    432 /*----------------------------------------------------------------------------*/
    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.
     392        ret = hc_schedule(hc, batch);
     393        if (ret != EOK) {
     394                batch_dispose(batch);
     395        }
     396        return ret;
     397}
     398/*----------------------------------------------------------------------------*/
     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.
    450410 * @return Error code.
    451411 */
    452412static int control_read(
    453     ddf_fun_t *fun, usb_target_t target,
     413    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    454414    void *setup_data, size_t setup_size, void *data, size_t size,
    455415    usbhc_iface_transfer_in_callback_t callback, void *arg)
    456416{
    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;
     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;
    475424        batch_control_read(batch);
    476         const int ret = hc_schedule(hc, batch);
    477         if (ret != EOK) {
    478                 batch_dispose(batch);
    479         }
    480         return ret;
    481 }
    482 /*----------------------------------------------------------------------------*/
    483 /** Host controller interface implementation for OHCI. */
     425        ret = hc_schedule(hc, batch);
     426        if (ret != EOK) {
     427                batch_dispose(batch);
     428        }
     429        return ret;
     430}
     431/*----------------------------------------------------------------------------*/
    484432usbhc_iface_t hc_iface = {
    485433        .reserve_default_address = reserve_default_address,
     
    501449        .control_read = control_read,
    502450};
    503 
    504451/**
    505452 * @}
Note: See TracChangeset for help on using the changeset viewer.