Changeset db96017 in mainline for uspace/lib/usbhost/src/iface.c


Ignore:
Timestamp:
2012-04-07T17:41:44Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b6913b7
Parents:
b69e4c0 (diff), 6bb169b5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/iface.c

    rb69e4c0 rdb96017  
    3939#include <usb/host/hcd.h>
    4040
     41/** Prepare generic usb_transfer_batch and schedule it.
     42 * @param fun DDF fun
     43 * @param target address and endpoint number.
     44 * @param setup_data Data to use in setup stage (Control communication type)
     45 * @param in Callback for device to host communication.
     46 * @param out Callback for host to device communication.
     47 * @param arg Callback parameter.
     48 * @param name Communication identifier (for nicer output).
     49 * @return Error code.
     50 */
    4151static inline int send_batch(
    4252    ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
     
    4959        assert(hcd);
    5060
    51         int ret;
    52 
    53         size_t res_bw;
    54         endpoint_t *ep = usb_endpoint_manager_get_ep(&hcd->ep_manager,
    55             target.address, target.endpoint, direction, &res_bw);
     61        endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager,
     62            target.address, target.endpoint, direction);
    5663        if (ep == NULL) {
    5764                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    6572        const size_t bw = bandwidth_count_usb11(
    6673            ep->speed, ep->transfer_type, size, ep->max_packet_size);
    67         if (res_bw < bw) {
     74        /* Check if we have enough bandwidth reserved */
     75        if (ep->bandwidth < bw) {
    6876                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    6977                    "but only %zu is reserved.\n",
    70                     target.address, target.endpoint, name, bw, res_bw);
     78                    ep->address, ep->endpoint, name, bw, ep->bandwidth);
    7179                return ENOSPC;
    7280        }
     
    7886        /* No private data and no private data dtor */
    7987        usb_transfer_batch_t *batch =
    80             usb_transfer_batch_get(ep, data, size, setup_data,
     88            usb_transfer_batch_create(ep, data, size, setup_data,
    8189            in, out, arg, fun, NULL, NULL);
    8290        if (!batch) {
     
    8492        }
    8593
    86         ret = hcd->schedule(hcd, batch);
     94        const int ret = hcd->schedule(hcd, batch);
    8795        if (ret != EOK)
    88                 usb_transfer_batch_dispose(batch);
     96                usb_transfer_batch_destroy(batch);
    8997
    9098        return ret;
    9199}
    92100/*----------------------------------------------------------------------------*/
    93 /** Request address interface function
     101/** Calls ep_add_hook upon endpoint registration.
     102 * @param ep Endpoint to be registered.
     103 * @param arg hcd_t in disguise.
     104 * @return Error code.
     105 */
     106static int register_helper(endpoint_t *ep, void *arg)
     107{
     108        hcd_t *hcd = arg;
     109        assert(ep);
     110        assert(hcd);
     111        if (hcd->ep_add_hook)
     112                return hcd->ep_add_hook(hcd, ep);
     113        return EOK;
     114}
     115/*----------------------------------------------------------------------------*/
     116/** Calls ep_remove_hook upon endpoint removal.
     117 * @param ep Endpoint to be unregistered.
     118 * @param arg hcd_t in disguise.
     119 */
     120static void unregister_helper(endpoint_t *ep, void *arg)
     121{
     122        hcd_t *hcd = arg;
     123        assert(ep);
     124        assert(hcd);
     125        if (hcd->ep_remove_hook)
     126                hcd->ep_remove_hook(hcd, ep);
     127}
     128/*----------------------------------------------------------------------------*/
     129/** Calls ep_remove_hook upon endpoint removal. Prints warning.
     130 * @param ep Endpoint to be unregistered.
     131 * @param arg hcd_t in disguise.
     132 */
     133static void unregister_helper_warn(endpoint_t *ep, void *arg)
     134{
     135        hcd_t *hcd = arg;
     136        assert(ep);
     137        assert(hcd);
     138        usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
     139            ep->address, ep->endpoint, usb_str_direction(ep->direction));
     140        if (hcd->ep_remove_hook)
     141                hcd->ep_remove_hook(hcd, ep);
     142}
     143/*----------------------------------------------------------------------------*/
     144/** Request address interface function.
    94145 *
    95146 * @param[in] fun DDF function that was called.
     147 * @param[in] address Pointer to preferred USB address.
     148 * @param[out] address Place to write a new address.
     149 * @param[in] strict Fail if the preferred address is not available.
    96150 * @param[in] speed Speed to associate with the new default address.
    97  * @param[out] address Place to write a new address.
    98151 * @return Error code.
    99152 */
    100153static int request_address(
    101     ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address)
     154    ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed)
    102155{
    103156        assert(fun);
     
    106159        assert(address);
    107160
    108         usb_log_debug("Address request speed: %s.\n", usb_str_speed(speed));
    109         *address =
    110             usb_device_manager_get_free_address(&hcd->dev_manager, speed);
    111         usb_log_debug("Address request with result: %d.\n", *address);
    112         if (*address <= 0)
    113                 return *address;
    114         return EOK;
    115 }
    116 /*----------------------------------------------------------------------------*/
    117 /** Bind address interface function
     161        usb_log_debug("Address request: speed: %s, address: %d, strict: %s.\n",
     162            usb_str_speed(speed), *address, strict ? "YES" : "NO");
     163        return usb_device_manager_request_address(
     164            &hcd->dev_manager, address, strict, speed);
     165}
     166/*----------------------------------------------------------------------------*/
     167/** Bind address interface function.
    118168 *
    119169 * @param[in] fun DDF function that was called.
     
    123173 */
    124174static int bind_address(
    125   ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     175    ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    126176{
    127177        assert(fun);
     
    130180
    131181        usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
    132         usb_device_manager_bind(&hcd->dev_manager, address, handle);
    133         return EOK;
     182        return usb_device_manager_bind_address(
     183            &hcd->dev_manager, address, handle);
    134184}
    135185/*----------------------------------------------------------------------------*/
     
    147197        hcd_t *hcd = fun_to_hcd(fun);
    148198        assert(hcd);
    149         const bool found =
    150             usb_device_manager_find_by_address(&hcd->dev_manager, address, handle);
    151         return found ? EOK : ENOENT;
    152 }
    153 /*----------------------------------------------------------------------------*/
    154 /** Release address interface function
     199        return usb_device_manager_get_info_by_address(
     200            &hcd->dev_manager, address, handle, NULL);
     201}
     202/*----------------------------------------------------------------------------*/
     203/** Release address interface function.
    155204 *
    156205 * @param[in] fun DDF function that was called.
     
    164213        assert(hcd);
    165214        usb_log_debug("Address release %d.\n", address);
    166         usb_device_manager_release(&hcd->dev_manager, address);
     215        usb_device_manager_release_address(&hcd->dev_manager, address);
     216        usb_endpoint_manager_remove_address(&hcd->ep_manager, address,
     217            unregister_helper_warn, hcd);
    167218        return EOK;
    168219}
    169220/*----------------------------------------------------------------------------*/
     221/** Register endpoint interface function.
     222 * @param fun DDF function.
     223 * @param address USB address of the device.
     224 * @param endpoint USB endpoint number to be registered.
     225 * @param transfer_type Endpoint's transfer type.
     226 * @param direction USB communication direction the endpoint is capable of.
     227 * @param max_packet_size Maximu size of packets the endpoint accepts.
     228 * @param interval Preferred timeout between communication.
     229 * @return Error code.
     230 */
    170231static int register_endpoint(
    171     ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
    172     usb_endpoint_t endpoint,
     232    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    173233    usb_transfer_type_t transfer_type, usb_direction_t direction,
    174     size_t max_packet_size, unsigned int interval)
     234    size_t max_packet_size, unsigned interval)
    175235{
    176236        assert(fun);
     
    178238        assert(hcd);
    179239        const size_t size = max_packet_size;
    180         /* Default address is not bound or registered,
    181          * thus it does not provide speed info. */
    182         const usb_speed_t speed = (address == 0) ? ep_speed :
    183             usb_device_manager_get_speed(&hcd->dev_manager, address);
     240        usb_speed_t speed = USB_SPEED_MAX;
     241        const int ret = usb_device_manager_get_info_by_address(
     242            &hcd->dev_manager, address, NULL, &speed);
     243        if (ret != EOK) {
     244                return ret;
     245        }
    184246
    185247        usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n",
     
    188250            max_packet_size, interval);
    189251
    190         endpoint_t *ep = endpoint_get(
    191             address, endpoint, direction, transfer_type, speed, max_packet_size);
    192         if (!ep)
    193                 return ENOMEM;
    194         int ret = EOK;
    195 
    196         if (hcd->ep_add_hook) {
    197                 ret = hcd->ep_add_hook(hcd, ep);
    198         }
    199         if (ret != EOK) {
    200                 endpoint_destroy(ep);
    201                 return ret;
    202         }
    203 
    204         ret = usb_endpoint_manager_register_ep(&hcd->ep_manager, ep, size);
    205         if (ret != EOK) {
    206                 endpoint_destroy(ep);
    207         }
    208         return ret;
    209 }
    210 /*----------------------------------------------------------------------------*/
     252        return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint,
     253            direction, transfer_type, speed, max_packet_size, size,
     254            register_helper, hcd);
     255}
     256/*----------------------------------------------------------------------------*/
     257/** Unregister endpoint interface function.
     258 * @param fun DDF function.
     259 * @param address USB address of the endpoint.
     260 * @param endpoint USB endpoint number.
     261 * @param direction Communication direction of the enpdoint to unregister.
     262 * @return Error code.
     263 */
    211264static int unregister_endpoint(
    212265    ddf_fun_t *fun, usb_address_t address,
     
    218271        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    219272            address, endpoint, usb_str_direction(direction));
    220         return usb_endpoint_manager_unregister_ep(&hcd->ep_manager, address,
    221             endpoint, direction);
    222 }
    223 /*----------------------------------------------------------------------------*/
     273        return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address,
     274            endpoint, direction, unregister_helper, hcd);
     275}
     276/*----------------------------------------------------------------------------*/
     277/** Inbound communication interface function.
     278 * @param fun DDF function.
     279 * @param target Communication target.
     280 * @param setup_data Data to use in setup stage (control transfers).
     281 * @param data Pointer to data buffer.
     282 * @param size Size of the data buffer.
     283 * @param callback Function to call on communication end.
     284 * @param arg Argument passed to the callback function.
     285 * @return Error code.
     286 */
    224287static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data,
    225288    uint8_t *data, size_t size, usbhc_iface_transfer_in_callback_t callback,
     
    230293}
    231294/*----------------------------------------------------------------------------*/
     295/** Outbound communication interface function.
     296 * @param fun DDF function.
     297 * @param target Communication target.
     298 * @param setup_data Data to use in setup stage (control transfers).
     299 * @param data Pointer to data buffer.
     300 * @param size Size of the data buffer.
     301 * @param callback Function to call on communication end.
     302 * @param arg Argument passed to the callback function.
     303 * @return Error code.
     304 */
    232305static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data,
    233306    const uint8_t *data, size_t size,
     
    238311}
    239312/*----------------------------------------------------------------------------*/
     313/** usbhc Interface implementation using hcd_t from libusbhost library. */
    240314usbhc_iface_t hcd_iface = {
    241315        .request_address = request_address,
    242316        .bind_address = bind_address,
    243         .find_by_address = find_by_address,
     317        .get_handle = find_by_address,
    244318        .release_address = release_address,
    245319
Note: See TracChangeset for help on using the changeset viewer.