Changes in / [501e5df:8790650] in mainline


Ignore:
Location:
uspace
Files:
2 deleted
32 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/dev.c

    r501e5df r8790650  
    5050
    5151        int rc;
    52         bool transfer_started = false;
    5352
    5453        rc = usb_device_connection_initialize(&dev->wire, hc_handle, dev_addr);
     
    7776        }
    7877
    79         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
     78        rc = usb_pipe_start_session(&dev->ctrl_pipe);
    8079        if (rc != EOK) {
    8180                fprintf(stderr,
    82                     NAME ": failed to start transfer on control pipe: %s.\n",
     81                    NAME ": failed to start session on control pipe: %s.\n",
    8382                    str_error(rc));
    8483                goto leave;
    8584        }
    86         transfer_started = true;
    8785
    8886        rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
     
    109107
    110108leave:
    111         if (transfer_started) {
    112                 usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     109        if (usb_pipe_is_session_started(&dev->ctrl_pipe)) {
     110                usb_pipe_end_session(&dev->ctrl_pipe);
    113111        }
    114112
     
    120118void destroy_device(usbinfo_device_t *dev)
    121119{
    122         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     120        usb_pipe_end_session(&dev->ctrl_pipe);
    123121        free(dev);
    124122}
  • uspace/doc/doxygroups.h

    r501e5df r8790650  
    269269
    270270        /**
    271          * @defgroup drvusbohci OHCI driver
    272          * @ingroup usb
    273          * @brief Driver for OHCI host controller.
    274          */
    275 
    276         /**
    277271         * @defgroup drvusbehci EHCI driver
    278272         * @ingroup usb
     
    281275
    282276        /**
    283          * @defgroup drvusbfallback USB fallback driver
     277         * @defgroup drvusbfallback USB fallback driver.
    284278         * @ingroup usb
    285279         * @brief Fallback driver for any USB device.
  • uspace/drv/ehci-hcd/hc_iface.c

    r501e5df r8790650  
    123123 * @param[in] fun Device function the action was invoked on.
    124124 * @param[in] address USB address of the device.
    125  * @param[in] speed Endpoint speed (invalid means to use device one).
    126125 * @param[in] endpoint Endpoint number.
    127126 * @param[in] transfer_type USB transfer type.
     
    132131 */
    133132static int register_endpoint(ddf_fun_t *fun,
    134     usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
     133    usb_address_t address, usb_endpoint_t endpoint,
    135134    usb_transfer_type_t transfer_type, usb_direction_t direction,
    136135    size_t max_packet_size, unsigned int interval)
     
    166165 * @param[in] fun Device function the action was invoked on.
    167166 * @param[in] target Target pipe (address and endpoint number) specification.
     167 * @param[in] max_packet_size Max packet size for the transfer.
    168168 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    169169 *      by the caller).
     
    174174 */
    175175static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    176     void *data, size_t size,
     176    size_t max_packet_size, void *data, size_t size,
    177177    usbhc_iface_transfer_out_callback_t callback, void *arg)
    178178{
     
    191191 * @param[in] fun Device function the action was invoked on.
    192192 * @param[in] target Target pipe (address and endpoint number) specification.
     193 * @param[in] max_packet_size Max packet size for the transfer.
    193194 * @param[in] data Buffer where to store the data (in USB endianess,
    194195 *      allocated and deallocated by the caller).
     
    199200 */
    200201static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    201     void *data, size_t size,
     202    size_t max_packet_size, void *data, size_t size,
    202203    usbhc_iface_transfer_in_callback_t callback, void *arg)
    203204{
     
    216217 * @param[in] fun Device function the action was invoked on.
    217218 * @param[in] target Target pipe (address and endpoint number) specification.
     219 * @param[in] max_packet_size Max packet size for the transfer.
    218220 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    219221 *      by the caller).
     
    224226 */
    225227static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    226     void *data, size_t size,
     228    size_t max_packet_size, void *data, size_t size,
    227229    usbhc_iface_transfer_out_callback_t callback, void *arg)
    228230{
     
    241243 * @param[in] fun Device function the action was invoked on.
    242244 * @param[in] target Target pipe (address and endpoint number) specification.
     245 * @param[in] max_packet_size Max packet size for the transfer.
    243246 * @param[in] data Buffer where to store the data (in USB endianess,
    244247 *      allocated and deallocated by the caller).
     
    249252 */
    250253static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    251     void *data, size_t size,
     254    size_t max_packet_size, void *data, size_t size,
    252255    usbhc_iface_transfer_in_callback_t callback, void *arg)
    253256{
     
    266269 * @param[in] fun Device function the action was invoked on.
    267270 * @param[in] target Target pipe (address and endpoint number) specification.
     271 * @param[in] max_packet_size Max packet size for the transfer.
    268272 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    269273 *      and deallocated by the caller).
     
    277281 */
    278282static int control_write(ddf_fun_t *fun, usb_target_t target,
     283    size_t max_packet_size,
    279284    void *setup_packet, size_t setup_packet_size,
    280285    void *data_buffer, size_t data_buffer_size,
     
    295300 * @param[in] fun Device function the action was invoked on.
    296301 * @param[in] target Target pipe (address and endpoint number) specification.
     302 * @param[in] max_packet_size Max packet size for the transfer.
    297303 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    298304 *      and deallocated by the caller).
     
    306312 */
    307313static int control_read(ddf_fun_t *fun, usb_target_t target,
     314    size_t max_packet_size,
    308315    void *setup_packet, size_t setup_packet_size,
    309316    void *data_buffer, size_t data_buffer_size,
  • uspace/drv/ohci/iface.c

    r501e5df r8790650  
    197197}
    198198/*----------------------------------------------------------------------------*/
    199 /** Register endpoint for bandwidth reservation.
    200  *
    201  * @param[in] fun Device function the action was invoked on.
    202  * @param[in] address USB address of the device.
    203  * @param[in] ep_speed Endpoint speed (invalid means to use device one).
    204  * @param[in] endpoint Endpoint number.
    205  * @param[in] transfer_type USB transfer type.
    206  * @param[in] direction Endpoint data direction.
    207  * @param[in] max_packet_size Max packet size of the endpoint.
    208  * @param[in] interval Polling interval.
    209  * @return Error code.
    210  */
    211 static int register_endpoint(ddf_fun_t *fun,
    212     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,
    213201    usb_transfer_type_t transfer_type, usb_direction_t direction,
    214202    size_t max_packet_size, unsigned int interval)
     
    216204        hc_t *hc = fun_to_hc(fun);
    217205        assert(hc);
    218         if (address == hc->rh.address)
    219                 return EOK;
    220         usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    221         if (speed >= USB_SPEED_MAX) {
    222                 speed = ep_speed;
    223         }
     206        const usb_speed_t speed =
     207            usb_device_keeper_get_speed(&hc->manager, address);
    224208        const size_t size =
    225209            (transfer_type == USB_TRANSFER_INTERRUPT
     
    259243        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    260244            address, endpoint, direction);
    261         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    262             address, endpoint, direction, NULL);
    263         if (ep != NULL) {
    264                 usb_device_keeper_del_ep(&hc->manager, address, ep);
    265         }
    266245        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    267246            endpoint, direction);
    268247}
    269248/*----------------------------------------------------------------------------*/
    270 /** Schedule interrupt out transfer.
    271  *
    272  * The callback is supposed to be called once the transfer (on the wire) is
    273  * complete regardless of the outcome.
    274  * However, the callback could be called only when this function returns
    275  * with success status (i.e. returns EOK).
    276  *
    277  * @param[in] fun Device function the action was invoked on.
    278  * @param[in] target Target pipe (address and endpoint number) specification.
    279  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    280  *      by the caller).
    281  * @param[in] size Size of the @p data buffer in bytes.
    282  * @param[in] callback Callback to be issued once the transfer is complete.
    283  * @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.
    284258 * @return Error code.
    285259 */
    286260static int interrupt_out(
    287     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,
    288262    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    289263{
     
    302276}
    303277/*----------------------------------------------------------------------------*/
    304 /** Schedule interrupt in transfer.
    305  *
    306  * The callback is supposed to be called once the transfer (on the wire) is
    307  * complete regardless of the outcome.
    308  * However, the callback could be called only when this function returns
    309  * with success status (i.e. returns EOK).
    310  *
    311  * @param[in] fun Device function the action was invoked on.
    312  * @param[in] target Target pipe (address and endpoint number) specification.
    313  * @param[in] data Buffer where to store the data (in USB endianess,
    314  *      allocated and deallocated by the caller).
    315  * @param[in] size Size of the @p data buffer in bytes.
    316  * @param[in] callback Callback to be issued once the transfer is complete.
    317  * @param[in] arg Pass-through argument to the callback.
     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.
    318287 * @return Error code.
    319288 */
    320289static int interrupt_in(
    321     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,
    322291    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    323292{
     
    336305}
    337306/*----------------------------------------------------------------------------*/
    338 /** Schedule bulk out transfer.
    339  *
    340  * The callback is supposed to be called once the transfer (on the wire) is
    341  * complete regardless of the outcome.
    342  * However, the callback could be called only when this function returns
    343  * with success status (i.e. returns EOK).
    344  *
    345  * @param[in] fun Device function the action was invoked on.
    346  * @param[in] target Target pipe (address and endpoint number) specification.
    347  * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    348  *      by the caller).
    349  * @param[in] size Size of the @p data buffer in bytes.
    350  * @param[in] callback Callback to be issued once the transfer is complete.
    351  * @param[in] arg Pass-through argument to the callback.
     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.
    352316 * @return Error code.
    353317 */
    354318static int bulk_out(
    355     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,
    356320    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    357321{
     
    370334}
    371335/*----------------------------------------------------------------------------*/
    372 /** Schedule bulk in transfer.
    373  *
    374  * The callback is supposed to be called once the transfer (on the wire) is
    375  * complete regardless of the outcome.
    376  * However, the callback could be called only when this function returns
    377  * with success status (i.e. returns EOK).
    378  *
    379  * @param[in] fun Device function the action was invoked on.
    380  * @param[in] target Target pipe (address and endpoint number) specification.
    381  * @param[in] data Buffer where to store the data (in USB endianess,
    382  *      allocated and deallocated by the caller).
    383  * @param[in] size Size of the @p data buffer in bytes.
    384  * @param[in] callback Callback to be issued once the transfer is complete.
    385  * @param[in] arg Pass-through argument to the callback.
     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.
    386345 * @return Error code.
    387346 */
    388347static int bulk_in(
    389     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,
    390349    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    391350{
     
    404363}
    405364/*----------------------------------------------------------------------------*/
    406 /** Schedule control write transfer.
    407  *
    408  * The callback is supposed to be called once the transfer (on the wire) is
    409  * complete regardless of the outcome.
    410  * However, the callback could be called only when this function returns
    411  * with success status (i.e. returns EOK).
    412  *
    413  * @param[in] fun Device function the action was invoked on.
    414  * @param[in] target Target pipe (address and endpoint number) specification.
    415  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    416  *      and deallocated by the caller).
    417  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    418  * @param[in] data_buffer Data buffer (in USB endianess, allocated and
    419  *      deallocated by the caller).
    420  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    421  * @param[in] callback Callback to be issued once the transfer is complete.
    422  * @param[in] arg Pass-through argument to the callback.
     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.
    423376 * @return Error code.
    424377 */
    425378static int control_write(
    426     ddf_fun_t *fun, usb_target_t target,
     379    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    427380    void *setup_data, size_t setup_size, void *data, size_t size,
    428381    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    444397}
    445398/*----------------------------------------------------------------------------*/
    446 /** Schedule control read transfer.
    447  *
    448  * The callback is supposed to be called once the transfer (on the wire) is
    449  * complete regardless of the outcome.
    450  * However, the callback could be called only when this function returns
    451  * with success status (i.e. returns EOK).
    452  *
    453  * @param[in] fun Device function the action was invoked on.
    454  * @param[in] target Target pipe (address and endpoint number) specification.
    455  * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    456  *      and deallocated by the caller).
    457  * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
    458  * @param[in] data_buffer Buffer where to store the data (in USB endianess,
    459  *      allocated and deallocated by the caller).
    460  * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
    461  * @param[in] callback Callback to be issued once the transfer is complete.
    462  * @param[in] arg Pass-through argument to the callback.
     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.
    463410 * @return Error code.
    464411 */
    465412static int control_read(
    466     ddf_fun_t *fun, usb_target_t target,
     413    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    467414    void *setup_data, size_t setup_size, void *data, size_t size,
    468415    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/ohci/root_hub.c

    r501e5df r8790650  
    115115
    116116static const uint32_t hub_set_feature_valid_mask =
    117         (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) |
    118 (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
     117        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    119118
    120119
     
    588587        if (!((1 << feature) & hub_set_feature_valid_mask))
    589588                return EINVAL;
    590         if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)
    591                 feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16;
    592589        instance->registers->rh_status =
    593590                (instance->registers->rh_status | (1 << feature))
  • uspace/drv/uhci-hcd/iface.c

    r501e5df r8790650  
    7474            name, target.address, target.endpoint, size, ep->max_packet_size);
    7575
    76 //      assert(ep->speed ==
    77 //          usb_device_keeper_get_speed(&(*hc)->manager, target.address));
     76        assert(ep->speed ==
     77            usb_device_keeper_get_speed(&(*hc)->manager, target.address));
    7878//      assert(ep->max_packet_size == max_packet_size);
    7979//      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
     
    198198/*----------------------------------------------------------------------------*/
    199199static int register_endpoint(
    200     ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
    201     usb_endpoint_t endpoint,
     200    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    202201    usb_transfer_type_t transfer_type, usb_direction_t direction,
    203202    size_t max_packet_size, unsigned int interval)
     
    205204        hc_t *hc = fun_to_hc(fun);
    206205        assert(hc);
    207         usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
    208         if (speed >= USB_SPEED_MAX) {
    209                 speed = ep_speed;
    210         }
    211         const size_t size =
    212             (transfer_type == USB_TRANSFER_INTERRUPT
    213             || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
    214             max_packet_size : 0;
     206        const usb_speed_t speed =
     207            usb_device_keeper_get_speed(&hc->manager, address);
     208        const size_t size = max_packet_size;
    215209        int ret;
    216210
     
    246240        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    247241            address, endpoint, direction);
    248         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    249             address, endpoint, direction, NULL);
    250         if (ep != NULL) {
    251                 usb_device_keeper_del_ep(&hc->manager, address, ep);
    252         }
    253242        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    254243            endpoint, direction);
     
    259248 * @param[in] fun DDF function that was called.
    260249 * @param[in] target USB device to write to.
     250 * @param[in] max_packet_size maximum size of data packet the device accepts
    261251 * @param[in] data Source of data.
    262252 * @param[in] size Size of data source.
     
    266256 */
    267257static int interrupt_out(
    268     ddf_fun_t *fun, usb_target_t target, void *data,
     258    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    269259    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    270260{
     
    287277 * @param[in] fun DDF function that was called.
    288278 * @param[in] target USB device to write to.
     279 * @param[in] max_packet_size maximum size of data packet the device accepts
    289280 * @param[out] data Data destination.
    290281 * @param[in] size Size of data source.
     
    294285 */
    295286static int interrupt_in(
    296     ddf_fun_t *fun, usb_target_t target, void *data,
     287    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    297288    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    298289{
     
    315306 * @param[in] fun DDF function that was called.
    316307 * @param[in] target USB device to write to.
     308 * @param[in] max_packet_size maximum size of data packet the device accepts
    317309 * @param[in] data Source of data.
    318310 * @param[in] size Size of data source.
     
    322314 */
    323315static int bulk_out(
    324     ddf_fun_t *fun, usb_target_t target, void *data,
     316    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    325317    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    326318{
     
    343335 * @param[in] fun DDF function that was called.
    344336 * @param[in] target USB device to write to.
     337 * @param[in] max_packet_size maximum size of data packet the device accepts
    345338 * @param[out] data Data destination.
    346339 * @param[in] size Size of data source.
     
    350343 */
    351344static int bulk_in(
    352     ddf_fun_t *fun, usb_target_t target, void *data,
     345    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    353346    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    354347{
     
    371364 * @param[in] fun DDF function that was called.
    372365 * @param[in] target USB device to write to.
     366 * @param[in] max_packet_size maximum size of data packet the device accepts.
    373367 * @param[in] setup_data Data to send with SETUP transfer.
    374368 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    380374 */
    381375static int control_write(
    382     ddf_fun_t *fun, usb_target_t target,
     376    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    383377    void *setup_data, size_t setup_size, void *data, size_t size,
    384378    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    404398 * @param[in] fun DDF function that was called.
    405399 * @param[in] target USB device to write to.
     400 * @param[in] max_packet_size maximum size of data packet the device accepts.
    406401 * @param[in] setup_data Data to send with SETUP packet.
    407402 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    413408 */
    414409static int control_read(
    415     ddf_fun_t *fun, usb_target_t target,
     410    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    416411    void *setup_data, size_t setup_size, void *data, size_t size,
    417412    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/usbhub/Makefile

    r501e5df r8790650  
    3434SOURCES = \
    3535        main.c \
     36        ports.c \
    3637        utils.c \
    37         usbhub.c \
    38         ports.c
     38        usbhub.c
    3939
    4040include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/usbhub/port_status.h

    r501e5df r8790650  
    4949
    5050/**
    51  * structure holding hub status and changes flags.
    52  * should not be accessed directly, use supplied getter/setter methods.
    53  *
    54  * For more information refer to table 11.16.2.5 in
    55  * "Universal Serial Bus Specification Revision 1.1"
    56  *
    57  */
    58 typedef uint32_t usb_hub_status_t;
    59 
    60 /**
    6151 * set values in request to be it a port status request
    6252 * @param request
     
    6454 */
    6555static inline void usb_hub_set_port_status_request(
    66         usb_device_request_setup_packet_t * request, uint16_t port
    67         ) {
     56usb_device_request_setup_packet_t * request, uint16_t port
     57){
    6858        request->index = port;
    6959        request->request_type = USB_HUB_REQ_TYPE_GET_PORT_STATUS;
     
    7363}
    7464
    75 /**
    76  * set values in request to be it a port status request
    77  * @param request
    78  * @param port
    79  */
    80 static inline void usb_hub_set_hub_status_request(
    81         usb_device_request_setup_packet_t * request
    82         ) {
    83         request->index = 0;
    84         request->request_type = USB_HUB_REQ_TYPE_GET_HUB_STATUS;
    85         request->request = USB_HUB_REQUEST_GET_STATUS;
    86         request->value = 0;
    87         request->length = 4;
    88 }
    8965
    9066/**
     
    9470 */
    9571static inline usb_device_request_setup_packet_t *
    96 usb_hub_create_port_status_request(uint16_t port) {
     72usb_hub_create_port_status_request(uint16_t port){
    9773        usb_device_request_setup_packet_t * result =
    98                 malloc(sizeof(usb_device_request_setup_packet_t));
    99         usb_hub_set_port_status_request(result, port);
     74                usb_new(usb_device_request_setup_packet_t);
     75        usb_hub_set_port_status_request(result,port);
    10076        return result;
    10177}
    10278
     79
    10380/**
    10481 * set the device request to be a port feature enable request
     
    10885 */
    10986static inline void usb_hub_set_enable_port_feature_request(
    110         usb_device_request_setup_packet_t * request, uint16_t port,
    111         uint16_t feature_selector
    112         ) {
     87usb_device_request_setup_packet_t * request, uint16_t port,
     88                uint16_t feature_selector
     89){
    11390        request->index = port;
    11491        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    125102 */
    126103static inline void usb_hub_set_disable_port_feature_request(
    127         usb_device_request_setup_packet_t * request, uint16_t port,
    128         uint16_t feature_selector
    129         ) {
     104usb_device_request_setup_packet_t * request, uint16_t port,
     105                uint16_t feature_selector
     106){
    130107        request->index = port;
    131108        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    141118 */
    142119static inline void usb_hub_set_enable_port_request(
    143         usb_device_request_setup_packet_t * request, uint16_t port
    144         ) {
     120usb_device_request_setup_packet_t * request, uint16_t port
     121){
    145122        request->index = port;
    146123        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    156133 */
    157134static inline usb_device_request_setup_packet_t *
    158 usb_hub_create_enable_port_request(uint16_t port) {
     135usb_hub_create_enable_port_request(uint16_t port){
    159136        usb_device_request_setup_packet_t * result =
    160                 malloc(sizeof(usb_device_request_setup_packet_t));
    161         usb_hub_set_enable_port_request(result, port);
     137                usb_new(usb_device_request_setup_packet_t);
     138        usb_hub_set_enable_port_request(result,port);
    162139        return result;
    163140}
     
    169146 */
    170147static inline void usb_hub_set_disable_port_request(
    171         usb_device_request_setup_packet_t * request, uint16_t port
    172         ) {
     148usb_device_request_setup_packet_t * request, uint16_t port
     149){
    173150        request->index = port;
    174151        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    184161 */
    185162static inline usb_device_request_setup_packet_t *
    186 usb_hub_create_disable_port_request(uint16_t port) {
     163usb_hub_create_disable_port_request(uint16_t port){
    187164        usb_device_request_setup_packet_t * result =
    188                 malloc(sizeof(usb_device_request_setup_packet_t));
    189         usb_hub_set_disable_port_request(result, port);
     165                usb_new(usb_device_request_setup_packet_t);
     166        usb_hub_set_disable_port_request(result,port);
    190167        return result;
    191168}
     
    197174 */
    198175static inline void usb_hub_set_reset_port_request(
    199         usb_device_request_setup_packet_t * request, uint16_t port
    200         ) {
     176usb_device_request_setup_packet_t * request, uint16_t port
     177){
    201178        request->index = port;
    202179        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    212189 */
    213190static inline usb_device_request_setup_packet_t *
    214 usb_hub_create_reset_port_request(uint16_t port) {
     191usb_hub_create_reset_port_request(uint16_t port){
    215192        usb_device_request_setup_packet_t * result =
    216                 malloc(sizeof(usb_device_request_setup_packet_t));
    217         usb_hub_set_reset_port_request(result, port);
     193                usb_new(usb_device_request_setup_packet_t);
     194        usb_hub_set_reset_port_request(result,port);
    218195        return result;
    219196}
     
    225202 */
    226203static inline void usb_hub_set_power_port_request(
    227         usb_device_request_setup_packet_t * request, uint16_t port
    228         ) {
     204usb_device_request_setup_packet_t * request, uint16_t port
     205){
    229206        request->index = port;
    230207        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    240217 */
    241218static inline void usb_hub_unset_power_port_request(
    242         usb_device_request_setup_packet_t * request, uint16_t port
    243         ) {
     219usb_device_request_setup_packet_t * request, uint16_t port
     220){
    244221        request->index = port;
    245222        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    249226}
    250227
    251 /**
    252  * get i`th bit of port status
    253  *
    254  * @param status
    255  * @param idx
    256  * @return
    257  */
    258 static inline bool usb_port_is_status(usb_port_status_t status, int idx) {
    259         return (status&(1 << idx))!=0;
    260 }
    261 
    262 /**
    263  * set i`th bit of port status
    264  *
    265  * @param status
    266  * @param idx
    267  * @param value
    268  */
    269 static inline void usb_port_status_set_bit(
    270         usb_port_status_t * status, int idx, bool value) {
    271         (*status) = value ?
    272                 ((*status) | (1 << (idx))) :
    273                 ((*status)&(~(1 << (idx))));
    274 }
    275 
    276 /**
    277  * get i`th bit of hub status
    278  *
    279  * @param status
    280  * @param idx
    281  * @return
    282  */
    283 static inline bool usb_hub_is_status(usb_hub_status_t status, int idx) {
    284         return (status&(1 << idx))!=0;
    285 }
    286 
    287 /**
    288  * set i`th bit of hub status
    289  *
    290  * @param status
    291  * @param idx
    292  * @param value
    293  */
    294 static inline void usb_hub_status_set_bit(
    295         usb_hub_status_t * status, int idx, bool value) {
    296         (*status) = value ?
    297                 ((*status) | (1 << (idx))) :
    298                 ((*status)&(~(1 << (idx))));
    299 }
    300 
    301 
    302 #if 0
    303 /**
    304  * connection status geter for port status
    305  *
    306  * @param status
    307  * @return true if there is something connected
    308  */
    309 static inline bool usb_port_dev_connected(usb_port_status_t * status) {
    310         return usb_port_get_bit(status, 0);
    311 }
    312 
    313 /**
    314  * set device connected bit in port status
    315  *
    316  * @param status
    317  * @param connected value of the bit
    318  */
    319 static inline void usb_port_set_dev_connected(usb_port_status_t * status, bool connected) {
    320         usb_port_set_bit(status, 0, connected);
     228
     229/** get i`th bit of port status */
     230static inline bool usb_port_get_bit(usb_port_status_t * status, int idx)
     231{
     232        return (((*status)>>(idx))%2);
     233}
     234
     235/** set i`th bit of port status */
     236static inline void usb_port_set_bit(
     237        usb_port_status_t * status, int idx, bool value)
     238{
     239        (*status) = value?
     240                               ((*status)|(1<<(idx))):
     241                               ((*status)&(~(1<<(idx))));
     242}
     243
     244//device connnected on port
     245static inline bool usb_port_dev_connected(usb_port_status_t * status){
     246        return usb_port_get_bit(status,0);
     247}
     248
     249static inline void usb_port_set_dev_connected(usb_port_status_t * status,bool connected){
     250        usb_port_set_bit(status,0,connected);
    321251}
    322252
    323253//port enabled
    324 
    325 /**
    326  * port enabled getter for port status
    327  *
    328  * @param status
    329  * @return true if the port is enabled
    330  */
    331 static inline bool usb_port_enabled(usb_port_status_t * status) {
    332         return usb_port_get_bit(status, 1);
    333 }
    334 
    335 /**
    336  * set port enabled bit in port status
    337  *
    338  * @param status
    339  * @param enabled value of the bit
    340  */
    341 static inline void usb_port_set_enabled(usb_port_status_t * status, bool enabled) {
    342         usb_port_set_bit(status, 1, enabled);
     254static inline bool usb_port_enabled(usb_port_status_t * status){
     255        return usb_port_get_bit(status,1);
     256}
     257
     258static inline void usb_port_set_enabled(usb_port_status_t * status,bool enabled){
     259        usb_port_set_bit(status,1,enabled);
    343260}
    344261
    345262//port suspended
    346 /**
    347  * port suspended getter for port status
    348  *
    349  * @param status
    350  * @return true if port is suspended
    351  */
    352 static inline bool usb_port_suspended(usb_port_status_t * status) {
    353         return usb_port_get_bit(status, 2);
    354 }
    355 
    356 /**
    357  * set port suspended bit in port status
    358  *
    359  * @param status
    360  * @param suspended value of the bit
    361  */
    362 static inline void usb_port_set_suspended(usb_port_status_t * status, bool suspended) {
    363         usb_port_set_bit(status, 2, suspended);
     263static inline bool usb_port_suspended(usb_port_status_t * status){
     264        return usb_port_get_bit(status,2);
     265}
     266
     267static inline void usb_port_set_suspended(usb_port_status_t * status,bool suspended){
     268        usb_port_set_bit(status,2,suspended);
    364269}
    365270
    366271//over currect
    367 /**
    368  * over current condition indicator getter for port status
    369  *
    370  * @param status
    371  * @return true if there is opver-current condition on the hub
    372  */
    373 static inline bool usb_port_over_current(usb_port_status_t * status) {
    374         return usb_port_get_bit(status, 3);
    375 }
    376 
    377 /**
    378  * set over current indicator bit in port status
    379  *
    380  * @param status
    381  * @param value value of the bit
    382  */
    383 static inline void usb_port_set_over_current(usb_port_status_t * status, bool value) {
    384         usb_port_set_bit(status, 3, value);
     272static inline bool usb_port_over_current(usb_port_status_t * status){
     273        return usb_port_get_bit(status,3);
     274}
     275
     276static inline void usb_port_set_over_current(usb_port_status_t * status,bool value){
     277        usb_port_set_bit(status,3,value);
    385278}
    386279
    387280//port reset
    388 /**
    389  * port reset indicator getter for port status
    390  *
    391  * @param status
    392  * @return true if port is reset
    393  */
    394 static inline bool usb_port_reset(usb_port_status_t * status) {
    395         return usb_port_get_bit(status, 4);
    396 }
    397 
    398 /**
    399  * set port reset bit in port status
    400  *
    401  * @param status
    402  * @param value value of the bit
    403  */
    404 static inline void usb_port_set_reset(usb_port_status_t * status, bool value) {
    405         usb_port_set_bit(status, 4, value);
     281static inline bool usb_port_reset(usb_port_status_t * status){
     282        return usb_port_get_bit(status,4);
     283}
     284
     285static inline void usb_port_set_reset(usb_port_status_t * status,bool value){
     286        usb_port_set_bit(status,4,value);
    406287}
    407288
    408289//powered
    409 /**
    410  * power state getter for port status
    411  *
    412  * @param status
    413  * @return true if port is powered
    414  */
    415 static inline bool usb_port_powered(usb_port_status_t * status) {
    416         return usb_port_get_bit(status, 8);
    417 }
    418 
    419 /**
    420  * set port powered bit in port status
    421  *
    422  * @param status
    423  * @param powered value of the bit
    424  */
    425 static inline void usb_port_set_powered(usb_port_status_t * status, bool powered) {
    426         usb_port_set_bit(status, 8, powered);
    427 }
    428 
    429 #endif
     290static inline bool usb_port_powered(usb_port_status_t * status){
     291        return usb_port_get_bit(status,8);
     292}
     293
     294static inline void usb_port_set_powered(usb_port_status_t * status,bool powered){
     295        usb_port_set_bit(status,8,powered);
     296}
    430297
    431298//low speed device attached
    432 /**
    433  * low speed device on the port indicator
    434  *
    435  * @param status
    436  * @return true if low speed device is attached
    437  */
    438 static inline bool usb_port_low_speed(usb_port_status_t status) {
    439         return usb_port_is_status(status, 9);
    440 }
    441 
    442 /**
    443  * set low speed device connected bit in port status
    444  *
    445  * @param status
    446  * @param low_speed value of the bit
    447  */
    448 static inline void usb_port_set_low_speed(usb_port_status_t * status, bool low_speed) {
    449         usb_port_status_set_bit(status, 9, low_speed);
    450 }
    451 
    452 //high speed device attached
    453 /**
    454  * high speed device on the port indicator
    455  *
    456  * @param status
    457  * @return true if high speed device is on port
    458  */
    459 static inline bool usb_port_high_speed(usb_port_status_t status) {
    460         return usb_port_is_status(status, 10);
    461 }
    462 
    463 /**
    464  * set high speed device bit in port status
    465  *
    466  * @param status
    467  * @param high_speed value of the bit
    468  */
    469 static inline void usb_port_set_high_speed(usb_port_status_t * status, bool high_speed) {
    470         usb_port_status_set_bit(status, 10, high_speed);
    471 }
    472 
    473 /**
    474  * speed getter for port status
    475  *
    476  * @param status
    477  * @return speed of usb device (for more see usb specification)
    478  */
    479 static inline usb_speed_t usb_port_speed(usb_port_status_t status) {
    480         if (usb_port_low_speed(status))
     299static inline bool usb_port_low_speed(usb_port_status_t * status){
     300        return usb_port_get_bit(status,9);
     301}
     302
     303static inline void usb_port_set_low_speed(usb_port_status_t * status,bool low_speed){
     304        usb_port_set_bit(status,9,low_speed);
     305}
     306
     307//low speed device attached
     308static inline bool usb_port_high_speed(usb_port_status_t * status){
     309        return usb_port_get_bit(status,10);
     310}
     311
     312static inline void usb_port_set_high_speed(usb_port_status_t * status,bool high_speed){
     313        usb_port_set_bit(status,10,high_speed);
     314}
     315
     316static inline usb_speed_t usb_port_speed(usb_port_status_t * status){
     317        if(usb_port_low_speed(status))
    481318                return USB_SPEED_LOW;
    482         if (usb_port_high_speed(status))
     319        if(usb_port_high_speed(status))
    483320                return USB_SPEED_HIGH;
    484321        return USB_SPEED_FULL;
    485322}
    486323
    487 #if 0
     324
    488325//connect change
    489 /**
    490  * port connect change indicator
    491  *
    492  * @param status
    493  * @return true if connection has changed
    494  */
    495 static inline bool usb_port_connect_change(usb_port_status_t * status) {
    496         return usb_port_get_bit(status, 16);
    497 }
    498 
    499 /**
    500  * set connection change bit in port status
    501  * @param status
    502  * @param change value of the bit
    503  */
    504 static inline void usb_port_set_connect_change(usb_port_status_t * status, bool change) {
    505         usb_port_set_bit(status, 16, change);
     326static inline bool usb_port_connect_change(usb_port_status_t * status){
     327        return usb_port_get_bit(status,16);
     328}
     329
     330static inline void usb_port_set_connect_change(usb_port_status_t * status,bool change){
     331        usb_port_set_bit(status,16,change);
    506332}
    507333
    508334//port enable change
    509 /**
    510  * port enable change for port status
    511  *
    512  * @param status
    513  * @return true if the port has been enabled/disabled
    514  */
    515 static inline bool usb_port_enabled_change(usb_port_status_t * status) {
    516         return usb_port_get_bit(status, 17);
    517 }
    518 
    519 /**
    520  * set port enable change bit in port status
    521  *
    522  * @param status
    523  * @param change value of the bit
    524  */
    525 static inline void usb_port_set_enabled_change(usb_port_status_t * status, bool change) {
    526         usb_port_set_bit(status, 17, change);
     335static inline bool usb_port_enabled_change(usb_port_status_t * status){
     336        return usb_port_get_bit(status,17);
     337}
     338
     339static inline void usb_port_set_enabled_change(usb_port_status_t * status,bool change){
     340        usb_port_set_bit(status,17,change);
    527341}
    528342
    529343//suspend change
    530 /**
    531  * port suspend change for port status
    532  *
    533  * @param status
    534  * @return ture if suspend status has changed
    535  */
    536 static inline bool usb_port_suspend_change(usb_port_status_t * status) {
    537         return usb_port_get_bit(status, 18);
    538 }
    539 
    540 /**
    541  * set port suspend change bit in port status
    542  *
    543  * @param status
    544  * @param change value of the bit
    545  */
    546 static inline void usb_port_set_suspend_change(usb_port_status_t * status, bool change) {
    547         usb_port_set_bit(status, 18, change);
     344static inline bool usb_port_suspend_change(usb_port_status_t * status){
     345        return usb_port_get_bit(status,18);
     346}
     347
     348static inline void usb_port_set_suspend_change(usb_port_status_t * status,bool change){
     349        usb_port_set_bit(status,18,change);
    548350}
    549351
    550352//over current change
    551 /**
    552  * over current change indicator
    553  *
    554  * @param status
    555  * @return true if over-current condition on port has changed
    556  */
    557 static inline bool usb_port_overcurrent_change(usb_port_status_t * status) {
    558         return usb_port_get_bit(status, 19);
    559 }
    560 
    561 /**
    562  * set port over current change bit in port status
    563  *
    564  * @param status
    565  * @param change value of the bit
    566  */
    567 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status, bool change) {
    568         usb_port_set_bit(status, 19, change);
     353static inline bool usb_port_overcurrent_change(usb_port_status_t * status){
     354        return usb_port_get_bit(status,19);
     355}
     356
     357static inline void usb_port_set_overcurrent_change(usb_port_status_t * status,bool change){
     358        usb_port_set_bit(status,19,change);
    569359}
    570360
    571361//reset change
    572 /**
    573  * port reset change indicator
    574  * @param status
    575  * @return true if port has been reset
    576  */
    577 static inline bool usb_port_reset_completed(usb_port_status_t * status) {
    578         return usb_port_get_bit(status, 20);
    579 }
    580 
    581 /**
    582  * set port reset completed bit in port status
    583  *
    584  * @param status
    585  * @param change value of the bit
    586  */
    587 static inline void usb_port_set_reset_completed(usb_port_status_t * status, bool completed) {
    588         usb_port_set_bit(status, 20, completed);
    589 }
    590 
    591 //local power status
    592 /**
    593  * local power lost indicator for hub status
    594  *
    595  * @param status
    596  * @return true if hub is not powered
    597  */
    598 static inline bool usb_hub_local_power_lost(usb_hub_status_t * status) {
    599         return usb_hub_get_bit(status, 0);
    600 }
    601 
    602 /**
    603  * set hub power lost bit in hub status
    604  *
    605  * @param status
    606  * @param change value of the bit
    607  */
    608 static inline void usb_hub_set_local_power_lost(usb_port_status_t * status,
    609         bool power_lost) {
    610         usb_hub_set_bit(status, 0, power_lost);
    611 }
    612 
    613 //over current ocndition
    614 /**
    615  * hub over-current indicator
    616  *
    617  * @param status
    618  * @return true if over-current condition occurred on hub
    619  */
    620 static inline bool usb_hub_over_current(usb_hub_status_t * status) {
    621         return usb_hub_get_bit(status, 1);
    622 }
    623 
    624 /**
    625  * set hub over current bit in hub status
    626  *
    627  * @param status
    628  * @param change value of the bit
    629  */
    630 static inline void usb_hub_set_over_current(usb_port_status_t * status,
    631         bool over_current) {
    632         usb_hub_set_bit(status, 1, over_current);
    633 }
    634 
    635 //local power change
    636 /**
    637  * hub power change indicator
    638  *
    639  * @param status
    640  * @return true if local power status has been changed - power has been
    641  * dropped or re-established
    642  */
    643 static inline bool usb_hub_local_power_change(usb_hub_status_t * status) {
    644         return usb_hub_get_bit(status, 16);
    645 }
    646 
    647 /**
    648  * set hub power change bit in hub status
    649  *
    650  * @param status
    651  * @param change value of the bit
    652  */
    653 static inline void usb_hub_set_local_power_change(usb_port_status_t * status,
    654         bool change) {
    655         usb_hub_set_bit(status, 16, change);
    656 }
    657 
    658 //local power status
    659 /**
    660  * hub over-current condition change indicator
    661  *
    662  * @param status
    663  * @return true if over-current condition has changed
    664  */
    665 static inline bool usb_hub_over_current_change(usb_hub_status_t * status) {
    666         return usb_hub_get_bit(status, 17);
    667 }
    668 
    669 /**
    670  * set hub over current change bit in hub status
    671  *
    672  * @param status
    673  * @param change value of the bit
    674  */
    675 static inline void usb_hub_set_over_current_change(usb_port_status_t * status,
    676         bool change) {
    677         usb_hub_set_bit(status, 17, change);
    678 }
    679 #endif
     362static inline bool usb_port_reset_completed(usb_port_status_t * status){
     363        return usb_port_get_bit(status,20);
     364}
     365
     366static inline void usb_port_set_reset_completed(usb_port_status_t * status,bool completed){
     367        usb_port_set_bit(status,20,completed);
     368}
     369
    680370
    681371
  • uspace/drv/usbhub/ports.c

    r501e5df r8790650  
    3333 * Hub ports functions.
    3434 */
    35 
    36 #include <bool.h>
     35#include "port_status.h"
     36#include <inttypes.h>
    3737#include <errno.h>
    3838#include <str_error.h>
    39 #include <inttypes.h>
    40 #include <fibril_synch.h>
    41 
     39#include <usb/request.h>
    4240#include <usb/debug.h>
    4341
    44 #include "ports.h"
    45 #include "usbhub.h"
    46 #include "usbhub_private.h"
    47 #include "port_status.h"
    48 
     42/** Retrieve port status.
     43 *
     44 * @param[in] ctrl_pipe Control pipe to use.
     45 * @param[in] port Port number (starting at 1).
     46 * @param[out] status Where to store the port status.
     47 * @return Error code.
     48 */
     49static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
     50    usb_port_status_t *status)
     51{
     52        size_t recv_size;
     53        usb_device_request_setup_packet_t request;
     54        usb_port_status_t status_tmp;
     55
     56        usb_hub_set_port_status_request(&request, port);
     57        int rc = usb_pipe_control_read(ctrl_pipe,
     58            &request, sizeof(usb_device_request_setup_packet_t),
     59            &status_tmp, sizeof(status_tmp), &recv_size);
     60        if (rc != EOK) {
     61                return rc;
     62        }
     63
     64        if (recv_size != sizeof (status_tmp)) {
     65                return ELIMIT;
     66        }
     67
     68        if (status != NULL) {
     69                *status = status_tmp;
     70        }
     71
     72        return EOK;
     73}
    4974
    5075/** Information for fibril for device discovery. */
     
    5580};
    5681
    57 static void usb_hub_removed_device(
    58         usb_hub_info_t * hub, uint16_t port);
    59 
    60 static void usb_hub_port_reset_completed(usb_hub_info_t * hub,
    61         uint16_t port, uint32_t status);
    62 
    63 static void usb_hub_port_over_current(usb_hub_info_t * hub,
    64         uint16_t port, uint32_t status);
    65 
    66 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    67     usb_port_status_t *status);
    68 
    69 static int enable_port_callback(int port_no, void *arg);
    70 
    71 static int add_device_phase1_worker_fibril(void *arg);
    72 
    73 static int create_add_device_fibril(usb_hub_info_t *hub, size_t port,
    74     usb_speed_t speed);
    75 
    76 /**
    77  * Process interrupts on given hub port
    78  *
    79  * Accepts connection, over current and port reset change.
    80  * @param hub hub representation
    81  * @param port port number, starting from 1
    82  */
    83 void usb_hub_process_interrupt(usb_hub_info_t * hub,
    84         uint16_t port) {
    85         usb_log_debug("interrupt at port %d\n", port);
    86         //determine type of change
    87         //usb_pipe_t *pipe = hub->control_pipe;
    88 
    89         int opResult;
    90 
    91         usb_port_status_t status;
    92         opResult = get_port_status(&hub->usb_device->ctrl_pipe, port, &status);
    93         if (opResult != EOK) {
    94                 usb_log_error("Failed to get port %zu status: %s.\n",
    95                     port, str_error(opResult));
    96                 return;
    97         }
    98         //connection change
    99         if (usb_port_is_status(status, USB_HUB_FEATURE_C_PORT_CONNECTION)) {
    100                 bool device_connected = usb_port_is_status(status,
    101                     USB_HUB_FEATURE_PORT_CONNECTION);
    102                 usb_log_debug("Connection change on port %zu: %s.\n", port,
    103                     device_connected ? "device attached" : "device removed");
    104 
    105                 if (device_connected) {
    106                         opResult = create_add_device_fibril(hub, port,
    107                             usb_port_speed(status));
    108                         if (opResult != EOK) {
    109                                 usb_log_error(
    110                                     "Cannot handle change on port %zu: %s.\n",
    111                                     str_error(opResult));
    112                         }
    113                 } else {
    114                         usb_hub_removed_device(hub, port);
    115                 }
    116         }
    117         //over current
    118         if (usb_port_is_status(status, USB_HUB_FEATURE_C_PORT_OVER_CURRENT)) {
    119                 //check if it was not auto-resolved
    120                 usb_log_debug("overcurrent change on port\n");
    121                 usb_hub_port_over_current(hub, port, status);
    122         }
    123         //port reset
    124         if (usb_port_is_status(status, USB_HUB_FEATURE_C_PORT_RESET)) {
    125                 usb_hub_port_reset_completed(hub, port, status);
    126         }
    127         usb_log_debug("status x%x : %d\n ", status, status);
    128 
    129         usb_port_status_set_bit(
    130             &status, USB_HUB_FEATURE_C_PORT_CONNECTION,false);
    131         usb_port_status_set_bit(
    132             &status, USB_HUB_FEATURE_PORT_RESET,false);
    133         usb_port_status_set_bit(
    134             &status, USB_HUB_FEATURE_C_PORT_RESET,false);
    135         usb_port_status_set_bit(
    136             &status, USB_HUB_FEATURE_C_PORT_OVER_CURRENT,false);
    137         /// \TODO what about port power change?
    138         if (status >> 16) {
    139                 usb_log_info("there was unsupported change on port %d: %X\n",
    140                         port, status);
    141 
    142         }
    143 }
    144 
    145 
    146 /**
    147  * routine called when a device on port has been removed
    148  *
    149  * If the device on port had default address, it releases default address.
    150  * Otherwise does not do anything, because DDF does not allow to remove device
    151  * from it`s device tree.
    152  * @param hub hub representation
    153  * @param port port number, starting from 1
    154  */
    155 static void usb_hub_removed_device(
    156         usb_hub_info_t * hub, uint16_t port) {
    157 
    158         int opResult = usb_hub_clear_port_feature(hub->control_pipe,
    159                 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    160         if (opResult != EOK) {
    161                 usb_log_warning("could not clear port-change-connection flag\n");
    162         }
    163         /** \TODO remove device from device manager - not yet implemented in
    164          * devide manager
    165          */
    166 
    167         //close address
    168         //if (hub->attached_devs[port].address != 0) {
    169         if(hub->ports[port].attached_device.address >= 0){
    170                 /*uncomment this code to use it when DDF allows device removal
    171                 opResult = usb_hc_unregister_device(
    172                         &hub->connection,
    173                         hub->attached_devs[port].address);
    174                 if(opResult != EOK) {
    175                         dprintf(USB_LOG_LEVEL_WARNING, "could not release "
    176                                 "address of "
    177                             "removed device: %d", opResult);
    178                 }
    179                 hub->attached_devs[port].address = 0;
    180                 hub->attached_devs[port].handle = 0;
    181                  */
    182         } else {
    183                 usb_log_warning("this is strange, disconnected device had "
    184                         "no address\n");
    185                 //device was disconnected before it`s port was reset -
    186                 //return default address
    187                 usb_hub_release_default_address(hub);
    188         }
    189 }
    190 
    191 
    192 /**
    193  * Process port reset change
    194  *
    195  * After this change port should be enabled, unless some problem occured.
    196  * This functions triggers second phase of enabling new device.
    197  * @param hub
    198  * @param port
    199  * @param status
    200  */
    201 static void usb_hub_port_reset_completed(usb_hub_info_t * hub,
    202         uint16_t port, uint32_t status){
    203         usb_log_debug("Port %zu reset complete.\n", port);
    204         if (usb_port_is_status(status, USB_HUB_FEATURE_PORT_ENABLE)) {
    205                 /* Finalize device adding. */
    206                 usb_hub_port_t *the_port = hub->ports + port;
    207                 fibril_mutex_lock(&the_port->reset_mutex);
    208                 the_port->reset_completed = true;
    209                 fibril_condvar_broadcast(&the_port->reset_cv);
    210                 fibril_mutex_unlock(&the_port->reset_mutex);
    211         } else {
    212                 usb_log_warning(
    213                     "Port %zu reset complete but port not enabled.\n",
    214                     port);
    215         }
    216 }
    217 
    218 /**
    219  * Process over current condition on port.
    220  *
    221  * Turn off the power on the port.
    222  *
    223  * @param hub hub representation
    224  * @param port port number, starting from 1
    225  */
    226 static void usb_hub_port_over_current(usb_hub_info_t * hub,
    227         uint16_t port, uint32_t status) {
    228         int opResult;
    229         if(usb_port_is_status(status, USB_HUB_FEATURE_PORT_OVER_CURRENT)){
    230                 opResult = usb_hub_clear_port_feature(hub->control_pipe,
    231                         port, USB_HUB_FEATURE_PORT_POWER);
    232                 if (opResult != EOK) {
    233                         usb_log_error("cannot power off port %d;  %d\n",
    234                                 port, opResult);
    235                 }
    236         }else{
    237                 opResult = usb_hub_set_port_feature(hub->control_pipe,
    238                         port, USB_HUB_FEATURE_PORT_POWER);
    239                 if (opResult != EOK) {
    240                         usb_log_error("cannot power on port %d;  %d\n",
    241                                 port, opResult);
    242                 }
    243         }
    244 }
    245 
    246 /** Retrieve port status.
    247  *
    248  * @param[in] ctrl_pipe Control pipe to use.
    249  * @param[in] port Port number (starting at 1).
    250  * @param[out] status Where to store the port status.
    251  * @return Error code.
    252  */
    253 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    254     usb_port_status_t *status)
    255 {
    256         size_t recv_size;
    257         usb_device_request_setup_packet_t request;
    258         usb_port_status_t status_tmp;
    259 
    260         usb_hub_set_port_status_request(&request, port);
    261         int rc = usb_pipe_control_read(ctrl_pipe,
    262             &request, sizeof(usb_device_request_setup_packet_t),
    263             &status_tmp, sizeof(status_tmp), &recv_size);
    264         if (rc != EOK) {
    265                 return rc;
    266         }
    267 
    268         if (recv_size != sizeof (status_tmp)) {
    269                 return ELIMIT;
    270         }
    271 
    272         if (status != NULL) {
    273                 *status = status_tmp;
    274         }
    275 
    276         return EOK;
    277 }
    278 
    27982/** Callback for enabling a specific port.
    28083 *
     
    28891static int enable_port_callback(int port_no, void *arg)
    28992{
    290         usb_hub_info_t *hub = arg;
     93        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
    29194        int rc;
    29295        usb_device_request_setup_packet_t request;
     
    353156        data->hub->ports[data->port].attached_device.address = new_address;
    354157
    355         usb_log_info("Detected new device on `%s' (port %zu), "
     158        usb_log_info("Detected new device on `%s' (port %zu), " \
    356159            "address %d (handle %" PRIun ").\n",
    357160            data->hub->usb_device->ddf_dev->name, data->port,
     
    363166        return EOK;
    364167}
    365 
    366168
    367169/** Start device adding when connection change is detected.
     
    374176 * @return Error code.
    375177 */
    376 static int create_add_device_fibril(usb_hub_info_t *hub, size_t port,
     178static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,
    377179    usb_speed_t speed)
    378180{
     
    411213}
    412214
     215/** Process change on a single port.
     216 *
     217 * @param hub Hub to which the port belongs.
     218 * @param port Port index (starting at 1).
     219 */
     220static void process_port_change(usb_hub_info_t *hub, size_t port)
     221{
     222        int rc;
     223
     224        usb_port_status_t port_status;
     225
     226        rc = get_port_status(&hub->usb_device->ctrl_pipe, port, &port_status);
     227        if (rc != EOK) {
     228                usb_log_error("Failed to get port %zu status: %s.\n",
     229                    port, str_error(rc));
     230                return;
     231        }
     232
     233        /*
     234         * Check exact nature of the change.
     235         */
     236        usb_log_debug("Port %zu change status: %x.\n", port,
     237            (unsigned int) port_status);
     238
     239        if (usb_port_connect_change(&port_status)) {
     240                bool device_connected = usb_port_dev_connected(&port_status);
     241                usb_log_debug("Connection change on port %zu: %s.\n", port,
     242                    device_connected ? "device attached" : "device removed");
     243
     244                if (device_connected) {
     245                        rc = add_device_phase1_new_fibril(hub, port,
     246                            usb_port_speed(&port_status));
     247                        if (rc != EOK) {
     248                                usb_log_error(
     249                                    "Cannot handle change on port %zu: %s.\n",
     250                                    str_error(rc));
     251                        }
     252                } else {
     253                        usb_hub_removed_device(hub, port);
     254                }
     255        }
     256
     257        if (usb_port_overcurrent_change(&port_status)) {
     258                if (usb_port_over_current(&port_status)) {
     259                        usb_log_warning("Overcurrent on port %zu.\n", port);
     260                        usb_hub_over_current(hub, port);
     261                } else {
     262                        usb_log_debug("Overcurrent on port %zu autoresolved.\n",
     263                            port);
     264                }
     265        }
     266
     267        if (usb_port_reset_completed(&port_status)) {
     268                usb_log_debug("Port %zu reset complete.\n", port);
     269                if (usb_port_enabled(&port_status)) {
     270                        /* Finalize device adding. */
     271                        usb_hub_port_t *the_port = hub->ports + port;
     272                        fibril_mutex_lock(&the_port->reset_mutex);
     273                        the_port->reset_completed = true;
     274                        fibril_condvar_broadcast(&the_port->reset_cv);
     275                        fibril_mutex_unlock(&the_port->reset_mutex);
     276                } else {
     277                        usb_log_warning(
     278                            "Port %zu reset complete but port not enabled.\n",
     279                            port);
     280                }
     281        }
     282
     283        usb_port_set_connect_change(&port_status, false);
     284        usb_port_set_reset(&port_status, false);
     285        usb_port_set_reset_completed(&port_status, false);
     286        usb_port_set_dev_connected(&port_status, false);
     287        if (port_status >> 16) {
     288                usb_log_warning("Unsupported change on port %zu: %x.\n",
     289                    port, (unsigned int) port_status);
     290        }
     291}
     292
     293
     294/** Callback for polling hub for port changes.
     295 *
     296 * @param dev Device where the change occured.
     297 * @param change_bitmap Bitmap of changed ports.
     298 * @param change_bitmap_size Size of the bitmap in bytes.
     299 * @param arg Custom argument, points to @c usb_hub_info_t.
     300 * @return Whether to continue polling.
     301 */
     302bool hub_port_changes_callback(usb_device_t *dev,
     303    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg)
     304{
     305        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
     306
     307        /* FIXME: check that we received enough bytes. */
     308        if (change_bitmap_size == 0) {
     309                goto leave;
     310        }
     311
     312        size_t port;
     313        for (port = 1; port < hub->port_count + 1; port++) {
     314                bool change = (change_bitmap[port / 8] >> (port % 8)) % 2;
     315                if (change) {
     316                        process_port_change(hub, port);
     317                }
     318        }
     319
     320
     321leave:
     322        /* FIXME: proper interval. */
     323        async_usleep(1000 * 1000 * 10 );
     324
     325        return true;
     326}
     327
     328
    413329/**
    414330 * @}
  • uspace/drv/usbhub/ports.h

    r501e5df r8790650  
    3636#define DRV_USBHUB_PORTS_H
    3737
    38 #include <usb/devdrv.h>
     38#include <ipc/devman.h>
     39#include <usb/usb.h>
     40#include <ddf/driver.h>
     41#include <fibril_synch.h>
     42
    3943#include <usb/hub.h>
    4044
    41 typedef struct usb_hub_info_t usb_hub_info_t;
     45#include <usb/pipes.h>
     46#include <usb/devdrv.h>
    4247
    4348/** Information about single port on a hub. */
     
    6772}
    6873
    69 
    70 void usb_hub_process_interrupt(usb_hub_info_t * hub,
    71         uint16_t port);
    72 
     74bool hub_port_changes_callback(usb_device_t *, uint8_t *, size_t, void *);
    7375
    7476
  • uspace/drv/usbhub/usbhub.c

    r501e5df r8790650  
    3737#include <errno.h>
    3838#include <str_error.h>
    39 #include <inttypes.h>
    4039
    4140#include <usb_iface.h>
     
    5453#include "usb/classes/classes.h"
    5554
    56 
    57 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
    58 
    59 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
    60 
    61 static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
    62 
    63 static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info);
    64 
    65 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
    66     usb_hub_status_t status);
    67 
    68 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    69     usb_hub_status_t status);
    70 
    71 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
    72 
    73 
    74 /// \TODO malloc checking
     55static int usb_hub_trigger_connecting_non_removable_devices(
     56                usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     57
    7558
    7659//*********************************************
     
    8164
    8265/**
    83  * Initialize hub device driver fibril
    84  *
    85  * Creates hub representation and fibril that periodically checks hub`s status.
    86  * Hub representation is passed to the fibril.
    87  * @param usb_dev generic usb device information
    88  * @return error code
    89  */
    90 int usb_hub_add_device(usb_device_t * usb_dev) {
    91         if (!usb_dev) return EINVAL;
    92         usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
    93         //create hc connection
    94         usb_log_debug("Initializing USB wire abstraction.\n");
    95         int opResult = usb_hc_connection_initialize_from_device(
    96             &hub_info->connection,
    97             hub_info->usb_device->ddf_dev);
    98         if (opResult != EOK) {
    99                 usb_log_error("could not initialize connection to device, "
    100                     "errno %d\n",
    101                     opResult);
    102                 free(hub_info);
    103                 return opResult;
    104         }
    105 
    106         usb_pipe_start_session(hub_info->control_pipe);
    107         //set hub configuration
    108         opResult = usb_hub_set_configuration(hub_info);
    109         if (opResult != EOK) {
    110                 usb_log_error("could not set hub configuration, errno %d\n",
    111                     opResult);
    112                 free(hub_info);
    113                 return opResult;
    114         }
    115         //get port count and create attached_devs
    116         opResult = usb_hub_process_hub_specific_info(hub_info);
    117         if (opResult != EOK) {
    118                 usb_log_error("could process hub specific info, errno %d\n",
    119                     opResult);
    120                 free(hub_info);
    121                 return opResult;
    122         }
    123         usb_pipe_end_session(hub_info->control_pipe);
    124 
    125         /// \TODO what is this?
    126         usb_log_debug("Creating `hub' function.\n");
    127         ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
    128             fun_exposed, "hub");
    129         assert(hub_fun != NULL);
    130         hub_fun->ops = NULL;
    131 
    132         opResult = ddf_fun_bind(hub_fun);
    133         assert(opResult == EOK);
    134         opResult = ddf_fun_add_to_class(hub_fun, "hub");
    135         assert(opResult == EOK);
    136 
    137         opResult = usb_hub_start_hub_fibril(hub_info);
    138         if(opResult!=EOK)
    139                 free(hub_info);
    140         return opResult;
    141 }
    142 
    143 
    144 /** Callback for polling hub for changes.
    145  *
    146  * @param dev Device where the change occured.
    147  * @param change_bitmap Bitmap of changed ports.
    148  * @param change_bitmap_size Size of the bitmap in bytes.
    149  * @param arg Custom argument, points to @c usb_hub_info_t.
    150  * @return Whether to continue polling.
    151  */
    152 bool hub_port_changes_callback(usb_device_t *dev,
    153     uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) {
    154         usb_hub_info_t *hub = (usb_hub_info_t *) arg;
    155 
    156         /* FIXME: check that we received enough bytes. */
    157         if (change_bitmap_size == 0) {
    158                 goto leave;
    159         }
    160 
    161         bool change;
    162         change = ((uint8_t*) change_bitmap)[0] & 1;
    163         if (change) {
    164                 usb_hub_process_global_interrupt(hub);
    165         }
    166 
    167         size_t port;
    168         for (port = 1; port < hub->port_count + 1; port++) {
    169                 bool change = (change_bitmap[port / 8] >> (port % 8)) % 2;
    170                 if (change) {
    171                         usb_hub_process_interrupt(hub, port);
    172                 }
    173         }
    174 leave:
    175         /* FIXME: proper interval. */
    176         async_usleep(1000 * 1000 * 10);
    177 
    178         return true;
    179 }
    180 
    181 /**
    182  * release default address used by given hub
    183  *
    184  * Also unsets hub->is_default_address_used. Convenience wrapper function.
    185  * @note hub->connection MUST be open for communication
    186  * @param hub hub representation
    187  * @return error code
    188  */
    189 int usb_hub_release_default_address(usb_hub_info_t * hub) {
    190         int opResult = usb_hc_release_default_address(&hub->connection);
    191         if (opResult != EOK) {
    192                 usb_log_error("could not release default address, errno %d\n",
    193                     opResult);
    194                 return opResult;
    195         }
    196         hub->is_default_address_used = false;
    197         return EOK;
    198 }
    199 
    200 
    201 //*********************************************
    202 //
    203 //  support functions
    204 //
    205 //*********************************************
    206 
    207 /**
    20866 * create usb_hub_info_t structure
    20967 *
     
    21371 */
    21472static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
    215         usb_hub_info_t * result = malloc(sizeof(usb_hub_info_t));
    216         if (!result) return NULL;
     73        usb_hub_info_t * result = usb_new(usb_hub_info_t);
     74        if(!result) return NULL;
    21775        result->usb_device = usb_dev;
    21876        result->status_change_pipe = usb_dev->pipes[0].pipe;
     
    23290 * @return error code
    23391 */
    234 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {
     92static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
    23593        // get hub descriptor
    23694        usb_log_debug("creating serialized descriptor\n");
    23795        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    23896        usb_hub_descriptor_t * descriptor;
    239         int opResult;
    240 
     97
     98        /* this was one fix of some bug, should not be needed anymore
     99         * these lines allow to reset hub once more, it can be used as
     100         * brute-force initialization for non-removable devices
     101        int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
     102        if(opResult!=EOK){
     103                usb_log_error("could not set default configuration, errno %d",opResult);
     104                return opResult;
     105        }
     106         */
    241107        size_t received_size;
    242         opResult = usb_request_get_descriptor(hub_info->control_pipe,
    243             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
    244             USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
    245             USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     108        int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,
     109                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     110                        USB_DESCTYPE_HUB,
     111                        0, 0, serialized_descriptor,
     112                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    246113
    247114        if (opResult != EOK) {
    248                 usb_log_error("failed when receiving hub descriptor, "
    249                     "badcode = %d\n",
    250                     opResult);
     115                usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
     116                                opResult);
    251117                free(serialized_descriptor);
    252118                return opResult;
     
    254120        usb_log_debug2("deserializing descriptor\n");
    255121        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    256         if (descriptor == NULL) {
     122        if(descriptor==NULL){
    257123                usb_log_warning("could not deserialize descriptor \n");
    258124                return opResult;
    259125        }
    260         usb_log_debug("setting port count to %d\n", descriptor->ports_count);
     126        usb_log_debug("setting port count to %d\n",descriptor->ports_count);
    261127        hub_info->port_count = descriptor->ports_count;
    262         /// \TODO this is not semantically correct
    263         hub_info->ports = malloc(
    264             sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
     128        hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
    265129        size_t port;
    266130        for (port = 0; port < hub_info->port_count + 1; port++) {
    267131                usb_hub_port_init(&hub_info->ports[port]);
    268132        }
     133        //handle non-removable devices
     134        usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
    269135        usb_log_debug2("freeing data\n");
    270136        free(serialized_descriptor);
     
    273139        return EOK;
    274140}
    275 
    276141/**
    277142 * Set configuration of hub
     
    282147 * @return error code
    283148 */
    284 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {
     149static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
    285150        //device descriptor
    286151        usb_standard_device_descriptor_t *std_descriptor
     
    288153        usb_log_debug("hub has %d configurations\n",
    289154            std_descriptor->configuration_count);
    290         if (std_descriptor->configuration_count < 1) {
     155        if(std_descriptor->configuration_count<1){
    291156                usb_log_error("there are no configurations available\n");
    292157                return EINVAL;
     
    308173        }
    309174        usb_log_debug("\tused configuration %d\n",
    310             config_descriptor->configuration_number);
     175                        config_descriptor->configuration_number);
    311176
    312177        return EOK;
     
    314179
    315180/**
    316  * create and start fibril with hub control loop
    317  *
    318  * Before the fibril is started, the control pipe and host controller
    319  * connection of the hub is open.
    320  *
    321  * @param hub_info hub representing structure
     181 * Initialize hub device driver fibril
     182 *
     183 * Creates hub representation and fibril that periodically checks hub`s status.
     184 * Hub representation is passed to the fibril.
     185 * @param usb_dev generic usb device information
    322186 * @return error code
    323187 */
    324 static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info){
     188int usb_hub_add_device(usb_device_t * usb_dev){
     189        if(!usb_dev) return EINVAL;
     190        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
     191        //create hc connection
     192        usb_log_debug("Initializing USB wire abstraction.\n");
     193        int opResult = usb_hc_connection_initialize_from_device(
     194                        &hub_info->connection,
     195                        hub_info->usb_device->ddf_dev);
     196        if(opResult != EOK){
     197                usb_log_error("could not initialize connection to device, errno %d\n",
     198                                opResult);
     199                free(hub_info);
     200                return opResult;
     201        }
     202       
     203        usb_pipe_start_session(hub_info->control_pipe);
     204        //set hub configuration
     205        opResult = usb_hub_set_configuration(hub_info);
     206        if(opResult!=EOK){
     207                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     208                free(hub_info);
     209                return opResult;
     210        }
     211        //get port count and create attached_devs
     212        opResult = usb_hub_process_hub_specific_info(hub_info);
     213        if(opResult!=EOK){
     214                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     215                free(hub_info);
     216                return opResult;
     217        }
     218        usb_pipe_end_session(hub_info->control_pipe);
     219
     220
     221        /// \TODO what is this?
     222        usb_log_debug("Creating `hub' function.\n");
     223        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
     224                        fun_exposed, "hub");
     225        assert(hub_fun != NULL);
     226        hub_fun->ops = NULL;
     227
     228        int rc = ddf_fun_bind(hub_fun);
     229        assert(rc == EOK);
     230        rc = ddf_fun_add_to_class(hub_fun, "hub");
     231        assert(rc == EOK);
     232
    325233        /*
    326234         * The processing will require opened control pipe and connection
     
    331239         * auto destruction, this could work better.
    332240         */
    333         int rc = usb_pipe_start_session(hub_info->control_pipe);
     241        rc = usb_pipe_start_session(&usb_dev->ctrl_pipe);
    334242        if (rc != EOK) {
    335243                usb_log_error("Failed to start session on control pipe: %s.\n",
    336244                    str_error(rc));
    337                 return rc;
     245                goto leave;
    338246        }
    339247        rc = usb_hc_connection_open(&hub_info->connection);
    340248        if (rc != EOK) {
    341                 usb_pipe_end_session(hub_info->control_pipe);
     249                usb_pipe_end_session(&usb_dev->ctrl_pipe);
    342250                usb_log_error("Failed to open connection to HC: %s.\n",
    343251                    str_error(rc));
    344                 return rc;
     252                goto leave;
    345253        }
    346254
    347255        rc = usb_device_auto_poll(hub_info->usb_device, 0,
    348             hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
     256            hub_port_changes_callback, ((hub_info->port_count+1) / 8) + 1,
    349257            NULL, hub_info);
    350258        if (rc != EOK) {
     
    358266            hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    359267        return EOK;
    360 }
     268
     269leave:
     270        free(hub_info);
     271
     272        return rc;
     273}
     274
    361275
    362276//*********************************************
    363277//
    364 //  change handling functions
     278//  hub driver code, main loop and port handling
    365279//
    366280//*********************************************
    367281
    368 
    369 /**
    370  * process hub over current change
    371  *
    372  * This means either to power off the hub or power it on.
    373  * @param hub_info hub instance
    374  * @param status hub status bitmask
     282/**
     283 * triggers actions to connect non0removable devices
     284 *
     285 * This will trigger operations leading to activated non-removable device.
     286 * Control pipe of the hub must be open fo communication.
     287 * @param hub hub representation
     288 * @param descriptor usb hub descriptor
    375289 * @return error code
    376290 */
    377 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
    378     usb_hub_status_t status) {
     291static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
     292                usb_hub_descriptor_t * descriptor)
     293{
     294        usb_log_info("attaching non-removable devices(if any)\n");
     295        usb_device_request_setup_packet_t request;
    379296        int opResult;
    380         if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_OVER_CURRENT)){
    381                 opResult = usb_hub_clear_feature(hub_info->control_pipe,
    382                     USB_HUB_FEATURE_HUB_LOCAL_POWER);
    383                 if (opResult != EOK) {
    384                         usb_log_error("cannot power off hub: %d\n",
    385                             opResult);
    386                 }
    387         } else {
    388                 opResult = usb_hub_set_feature(hub_info->control_pipe,
    389                     USB_HUB_FEATURE_HUB_LOCAL_POWER);
    390                 if (opResult != EOK) {
    391                         usb_log_error("cannot power on hub: %d\n",
    392                             opResult);
    393                 }
    394         }
    395         return opResult;
    396 }
    397 
    398 /**
    399  * process hub power change
    400  *
    401  * If the power has been lost, reestablish it.
    402  * If it was reestablished, re-power all ports.
    403  * @param hub_info hub instance
    404  * @param status hub status bitmask
    405  * @return error code
    406  */
    407 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    408     usb_hub_status_t status) {
    409         int opResult;
    410         if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
    411                 //restart power on hub
    412                 opResult = usb_hub_set_feature(hub_info->control_pipe,
    413                     USB_HUB_FEATURE_HUB_LOCAL_POWER);
    414                 if (opResult != EOK) {
    415                         usb_log_error("cannot power on hub: %d\n",
    416                             opResult);
    417                 }
    418         } else {//power reestablished on hub- restart ports
    419                 size_t port;
    420                 for (port = 0; port < hub_info->port_count; ++port) {
    421                         opResult = usb_hub_set_port_feature(
    422                             hub_info->control_pipe,
    423                             port, USB_HUB_FEATURE_PORT_POWER);
     297        size_t rcvd_size;
     298        usb_port_status_t status;
     299        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
     300        int port;
     301        for(port=1;port<=descriptor->ports_count;++port){
     302                bool is_non_removable =
     303                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     304                if(is_non_removable){
     305                        usb_log_debug("non-removable device on port %d\n",port);
     306                        usb_hub_set_port_status_request(&request, port);
     307                        opResult = usb_pipe_control_read(
     308                                        hub->control_pipe,
     309                                        &request, sizeof(usb_device_request_setup_packet_t),
     310                                        &status, 4, &rcvd_size
     311                                        );
    424312                        if (opResult != EOK) {
    425                                 usb_log_error("cannot power on port %d;  %d\n",
    426                                     port, opResult);
     313                                usb_log_error("could not get port status of port %d errno:%d\n",
     314                                                port, opResult);
     315                                return opResult;
     316                        }
     317                        //set the status change bit, so it will be noticed in driver loop
     318                        if(usb_port_dev_connected(&status)){
     319                                usb_hub_set_disable_port_feature_request(&request, port,
     320                                                USB_HUB_FEATURE_PORT_CONNECTION);
     321                                opResult = usb_pipe_control_read(
     322                                                hub->control_pipe,
     323                                                &request, sizeof(usb_device_request_setup_packet_t),
     324                                                &status, 4, &rcvd_size
     325                                                );
     326                                if (opResult != EOK) {
     327                                        usb_log_warning(
     328                                                        "could not clear port connection on port %d errno:%d\n",
     329                                                        port, opResult);
     330                                }
     331                                usb_log_debug("cleared port connection\n");
     332                                usb_hub_set_enable_port_feature_request(&request, port,
     333                                                USB_HUB_FEATURE_PORT_ENABLE);
     334                                opResult = usb_pipe_control_read(
     335                                                hub->control_pipe,
     336                                                &request, sizeof(usb_device_request_setup_packet_t),
     337                                                &status, 4, &rcvd_size
     338                                                );
     339                                if (opResult != EOK) {
     340                                        usb_log_warning(
     341                                                        "could not set port enabled on port %d errno:%d\n",
     342                                                        port, opResult);
     343                                }
     344                                usb_log_debug("port set to enabled - should lead to connection change\n");
    427345                        }
    428346                }
    429347        }
    430         return opResult;
    431 }
    432 
    433 /**
    434  * process hub interrupts
    435  *
    436  * The change can be either in the over-current condition or
    437  * local-power lost condition.
    438  * @param hub_info hub instance
    439  */
    440 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info) {
    441         usb_log_debug("global interrupt on a hub\n");
    442         usb_pipe_t *pipe = hub_info->control_pipe;
     348        /// \TODO this is just a debug code
     349        for(port=1;port<=descriptor->ports_count;++port){
     350                bool is_non_removable =
     351                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     352                if(is_non_removable){
     353                        usb_log_debug("port %d is non-removable\n",port);
     354                        usb_port_status_t status;
     355                        size_t rcvd_size;
     356                        usb_device_request_setup_packet_t request;
     357                        //int opResult;
     358                        usb_hub_set_port_status_request(&request, port);
     359                        //endpoint 0
     360                        opResult = usb_pipe_control_read(
     361                                        hub->control_pipe,
     362                                        &request, sizeof(usb_device_request_setup_packet_t),
     363                                        &status, 4, &rcvd_size
     364                                        );
     365                        if (opResult != EOK) {
     366                                usb_log_error("could not get port status %d\n",opResult);
     367                        }
     368                        if (rcvd_size != sizeof (usb_port_status_t)) {
     369                                usb_log_error("received status has incorrect size\n");
     370                        }
     371                        //something connected/disconnected
     372                        if (usb_port_connect_change(&status)) {
     373                                usb_log_debug("some connection changed\n");
     374                        }
     375                        usb_log_debug("status: %s\n",usb_debug_str_buffer(
     376                                        (uint8_t *)&status,4,4));
     377                }
     378        }
     379        return EOK;
     380}
     381
     382
     383/**
     384 * release default address used by given hub
     385 *
     386 * Also unsets hub->is_default_address_used. Convenience wrapper function.
     387 * @note hub->connection MUST be open for communication
     388 * @param hub hub representation
     389 * @return error code
     390 */
     391static int usb_hub_release_default_address(usb_hub_info_t * hub){
     392        int opResult = usb_hc_release_default_address(&hub->connection);
     393        if(opResult!=EOK){
     394                usb_log_error("could not release default address, errno %d\n",opResult);
     395                return opResult;
     396        }
     397        hub->is_default_address_used = false;
     398        return EOK;
     399}
     400
     401/**
     402 * routine called when a device on port has been removed
     403 *
     404 * If the device on port had default address, it releases default address.
     405 * Otherwise does not do anything, because DDF does not allow to remove device
     406 * from it`s device tree.
     407 * @param hub hub representation
     408 * @param port port number, starting from 1
     409 */
     410void usb_hub_removed_device(
     411    usb_hub_info_t * hub,uint16_t port) {
     412
     413        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
     414                                port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     415        if(opResult != EOK){
     416                usb_log_warning("could not clear port-change-connection flag\n");
     417        }
     418        /** \TODO remove device from device manager - not yet implemented in
     419         * devide manager
     420         */
     421       
     422        //close address
     423        if(hub->ports[port].attached_device.address >= 0){
     424                /*uncomment this code to use it when DDF allows device removal
     425                opResult = usb_hc_unregister_device(
     426                                &hub->connection, hub->attached_devs[port].address);
     427                if(opResult != EOK) {
     428                        dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
     429                            "removed device: %d", opResult);
     430                }
     431                hub->attached_devs[port].address = 0;
     432                hub->attached_devs[port].handle = 0;
     433                 */
     434        }else{
     435                usb_log_warning("this is strange, disconnected device had no address\n");
     436                //device was disconnected before it`s port was reset - return default address
     437                usb_hub_release_default_address(hub);
     438        }
     439}
     440
     441
     442/**
     443 * Process over current condition on port.
     444 *
     445 * Turn off the power on the port.
     446 *
     447 * @param hub hub representation
     448 * @param port port number, starting from 1
     449 */
     450void usb_hub_over_current( usb_hub_info_t * hub,
     451                uint16_t port){
    443452        int opResult;
    444 
    445         usb_port_status_t status;
    446         size_t rcvd_size;
    447         usb_device_request_setup_packet_t request;
    448         //int opResult;
    449         usb_hub_set_hub_status_request(&request);
    450         //endpoint 0
    451 
    452         opResult = usb_pipe_control_read(
    453             pipe,
    454             &request, sizeof (usb_device_request_setup_packet_t),
    455             &status, 4, &rcvd_size
    456             );
    457         if (opResult != EOK) {
    458                 usb_log_error("could not get hub status\n");
    459                 return;
    460         }
    461         if (rcvd_size != sizeof (usb_port_status_t)) {
    462                 usb_log_error("received status has incorrect size\n");
    463                 return;
    464         }
    465         //port reset
    466         if (
    467             usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_OVER_CURRENT)) {
    468                 usb_process_hub_over_current(hub_info, status);
    469         }
    470         if (
    471             usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_LOCAL_POWER)) {
    472                 usb_process_hub_power_change(hub_info, status);
    473         }
    474 }
     453        opResult = usb_hub_clear_port_feature(hub->control_pipe,
     454            port, USB_HUB_FEATURE_PORT_POWER);
     455        if(opResult!=EOK){
     456                usb_log_error("cannot power off port %d;  %d\n",
     457                                port, opResult);
     458        }
     459}
     460
    475461
    476462/**
  • uspace/drv/usbhub/usbhub.h

    r501e5df r8790650  
    3737
    3838#include <ipc/devman.h>
     39#include <usb/usb.h>
    3940#include <ddf/driver.h>
    4041
     42#define NAME "usbhub"
     43
    4144#include <usb/hub.h>
    42 #include <usb/classes/hub.h>
    4345
    4446#include <usb/pipes.h>
    4547#include <usb/devdrv.h>
    46 
    47 #include <fibril_synch.h>
    48 
    49 #define NAME "usbhub"
    5048
    5149#include "ports.h"
     
    5452
    5553/** Information about attached hub. */
    56 struct usb_hub_info_t{
     54typedef struct {
    5755        /** Number of ports. */
    5856        size_t port_count;
    5957
    60         /** attached device handles, for each port one */
     58        /** Ports. */
    6159        usb_hub_port_t *ports;
    62 
     60       
    6361        /** connection to hcd */
    6462        usb_hc_connection_t connection;
     
    8987        /** generic usb device data*/
    9088        usb_device_t * usb_device;
    91 };
     89} usb_hub_info_t;
    9290
    93 //int usb_hub_control_loop(void * hub_info_param);
     91/**
     92 * function running the hub-controlling loop.
     93 * @param hub_info_param hub info pointer
     94 */
     95int usb_hub_control_loop(void * hub_info_param);
     96
     97/**
     98 * Check changes on specified hub
     99 * @param hub_info_param pointer to usb_hub_info_t structure
     100 * @return error code if there is problem when initializing communication with
     101 * hub, EOK otherwise
     102 */
     103int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
     104
     105void usb_hub_removed_device(usb_hub_info_t *, uint16_t);
     106void usb_hub_over_current(usb_hub_info_t *, uint16_t);
    94107
    95108int usb_hub_add_device(usb_device_t * usb_dev);
    96 
    97 bool hub_port_changes_callback(usb_device_t *dev,
    98     uint8_t *change_bitmap, size_t change_bitmap_size, void *arg);
    99 
    100 int usb_hub_release_default_address(usb_hub_info_t * hub);
    101109
    102110#endif
  • uspace/drv/usbhub/usbhub_private.h

    r501e5df r8790650  
    5454//
    5555//************
     56#define usb_new(type) (type*)malloc(sizeof(type))
    5657
    5758
     59/**
     60 * Create hub structure instance
     61 *
     62 * Set the address and port count information most importantly.
     63 *
     64 * @param device
     65 * @param hc host controller phone
     66 * @return
     67 */
    5868usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device);
    5969
     
    100110
    101111/**
    102  * Clear feature on hub port.
    103  *
    104  * @param hc Host controller telephone
    105  * @param address Hub address
    106  * @param port_index Port
    107  * @param feature Feature selector
    108  * @return Operation result
    109  */
    110 static inline int usb_hub_set_port_feature(usb_pipe_t *pipe,
    111     int port_index,
    112     usb_hub_class_feature_t feature) {
    113 
    114         usb_device_request_setup_packet_t clear_request = {
    115                 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
    116                 .request = USB_DEVREQ_SET_FEATURE,
    117                 .length = 0,
    118                 .index = port_index
    119         };
    120         clear_request.value = feature;
    121         return usb_pipe_control_write(pipe, &clear_request,
    122             sizeof(clear_request), NULL, 0);
    123 }
    124 
    125 
    126 /**
    127  * Clear feature on hub port.
    128  *
    129  * @param pipe pipe to hub control endpoint
    130  * @param feature Feature selector
    131  * @return Operation result
    132  */
    133 static inline int usb_hub_clear_feature(usb_pipe_t *pipe,
    134     usb_hub_class_feature_t feature) {
    135 
    136         usb_device_request_setup_packet_t clear_request = {
    137                 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
    138                 .request = USB_DEVREQ_CLEAR_FEATURE,
    139                 .length = 0,
    140                 .index = 0
    141         };
    142         clear_request.value = feature;
    143         return usb_pipe_control_write(pipe, &clear_request,
    144             sizeof(clear_request), NULL, 0);
    145 }
    146 
    147 /**
    148  * Clear feature on hub port.
    149  *
    150  * @param pipe pipe to hub control endpoint
    151  * @param feature Feature selector
    152  * @return Operation result
    153  */
    154 static inline int usb_hub_set_feature(usb_pipe_t *pipe,
    155     usb_hub_class_feature_t feature) {
    156 
    157         usb_device_request_setup_packet_t clear_request = {
    158                 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
    159                 .request = USB_DEVREQ_SET_FEATURE,
    160                 .length = 0,
    161                 .index = 0
    162         };
    163         clear_request.value = feature;
    164         return usb_pipe_control_write(pipe, &clear_request,
    165             sizeof(clear_request), NULL, 0);
    166 }
    167 
    168 /**
    169112 * create uint8_t array with serialized descriptor
    170113 *
  • uspace/drv/usbhub/utils.c

    r501e5df r8790650  
    6060        size_t size = 7;
    6161        //variable size according to port count
    62         size_t var_size = (descriptor->ports_count+7)/8;
     62        size_t var_size = descriptor->ports_count / 8 + ((descriptor->ports_count % 8 > 0) ? 1 : 0);
    6363        size += 2 * var_size;
    64         uint8_t * result = malloc(size);
     64        uint8_t * result = (uint8_t*) malloc(size);
    6565        //size
    6666        result[0] = size;
     
    8484}
    8585
    86 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(
    87 void * serialized_descriptor) {
    88         uint8_t * sdescriptor = serialized_descriptor;
     86usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
     87        uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
    8988
    9089        if (sdescriptor[1] != USB_DESCTYPE_HUB) {
    91                 usb_log_warning("trying to deserialize wrong descriptor %x\n",
    92                     sdescriptor[1]);
     90                usb_log_warning("trying to deserialize wrong descriptor %x\n",sdescriptor[1]);
    9391                return NULL;
    9492        }
    9593
    96         usb_hub_descriptor_t * result = malloc(sizeof(usb_hub_descriptor_t));
     94        usb_hub_descriptor_t * result = usb_new(usb_hub_descriptor_t);
    9795       
    9896
     
    102100        result->pwr_on_2_good_time = sdescriptor[5];
    103101        result->current_requirement = sdescriptor[6];
    104         size_t var_size = (result->ports_count+7) / 8;
     102        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0)
     103                        ? 1 : 0);
    105104        result->devices_removable = (uint8_t*) malloc(var_size);
    106105
  • uspace/drv/usbmid/main.c

    r501e5df r8790650  
    5555        int rc;
    5656
    57         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
     57        rc = usb_pipe_start_session(&dev->ctrl_pipe);
    5858        if (rc != EOK) {
    59                 usb_log_error("Failed to start transfer on control pipe: %s.\n",
     59                usb_log_error("Failed to start session on control pipe: %s.\n",
    6060                    str_error(rc));
    6161                return rc;
     
    6464        bool accept = usbmid_explore_device(dev);
    6565
    66         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     66        rc = usb_pipe_end_session(&dev->ctrl_pipe);
     67        if (rc != EOK) {
     68                usb_log_warning("Failed to end session on control pipe: %s.\n",
     69                    str_error(rc));
     70        }
    6771
    6872        if (!accept) {
  • uspace/drv/vhc/connhost.c

    r501e5df r8790650  
    257257
    258258static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
     259    size_t max_packet_size,
    259260    void *data, size_t size,
    260261    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    266267
    267268static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
     269    size_t max_packet_size,
    268270    void *data, size_t size,
    269271    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    275277
    276278static int control_write(ddf_fun_t *fun, usb_target_t target,
     279    size_t max_packet_size,
    277280    void *setup_packet, size_t setup_packet_size,
    278281    void *data, size_t data_size,
     
    292295
    293296static int control_read(ddf_fun_t *fun, usb_target_t target,
     297    size_t max_packet_size,
    294298    void *setup_packet, size_t setup_packet_size,
    295299    void *data, size_t data_size,
  • uspace/lib/drv/generic/remote_usbhc.c

    r501e5df r8790650  
    270270        }
    271271
     272        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    272273        usb_target_t target = {
    273274                .address = DEV_IPC_GET_ARG1(*call),
     
    299300        trans->size = len;
    300301
    301         rc = transfer_func(fun, target,
     302        rc = transfer_func(fun, target, max_packet_size,
    302303            buffer, len,
    303304            callback_out, trans);
     
    325326        }
    326327
     328        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    327329        usb_target_t target = {
    328330                .address = DEV_IPC_GET_ARG1(*call),
     
    346348        trans->size = len;
    347349
    348         int rc = transfer_func(fun, target,
     350        int rc = transfer_func(fun, target, max_packet_size,
    349351            trans->buffer, len,
    350352            callback_in, trans);
     
    412414        };
    413415        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
     416        size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    414417
    415418        int rc;
     
    447450        trans->size = data_buffer_len;
    448451
    449         rc = usb_iface->control_write(fun, target,
     452        rc = usb_iface->control_write(fun, target, max_packet_size,
    450453            setup_packet, setup_packet_len,
    451454            data_buffer, data_buffer_len,
     
    474477                .endpoint = DEV_IPC_GET_ARG2(*call)
    475478        };
     479        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    476480
    477481        int rc;
     
    511515        }
    512516
    513         rc = usb_iface->control_read(fun, target,
     517        rc = usb_iface->control_read(fun, target, max_packet_size,
    514518            setup_packet, setup_packet_len,
    515519            trans->buffer, trans->size,
     
    533537        }
    534538
    535 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
    536         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
    537 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
    538         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 16)
    539 #define _INIT_FROM_HIGH_DATA3(type, var, arg_no) \
    540         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
    541 #define _INIT_FROM_MIDDLE_DATA3(type, var, arg_no) \
    542         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) / (1 << 8)) % (1 << 8)
    543 #define _INIT_FROM_LOW_DATA3(type, var, arg_no) \
    544         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 8)
    545 
    546         _INIT_FROM_HIGH_DATA2(usb_address_t, address, 1);
    547         _INIT_FROM_LOW_DATA2(usb_endpoint_t, endpoint, 1);
    548 
    549         _INIT_FROM_HIGH_DATA3(usb_speed_t, speed, 2);
    550         _INIT_FROM_MIDDLE_DATA3(usb_transfer_type_t, transfer_type, 2);
    551         _INIT_FROM_LOW_DATA3(usb_direction_t, direction, 2);
    552 
    553         _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
    554         _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
    555 
    556 #undef _INIT_FROM_HIGH_DATA2
    557 #undef _INIT_FROM_LOW_DATA2
    558 #undef _INIT_FROM_HIGH_DATA3
    559 #undef _INIT_FROM_MIDDLE_DATA3
    560 #undef _INIT_FROM_LOW_DATA3
    561 
    562         int rc = usb_iface->register_endpoint(fun, address, speed, endpoint,
     539#define INIT_FROM_HIGH_DATA(type, var, arg_no) \
     540        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256
     541#define INIT_FROM_LOW_DATA(type, var, arg_no) \
     542        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256
     543
     544        INIT_FROM_HIGH_DATA(usb_address_t, address, 1);
     545        INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1);
     546        INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2);
     547        INIT_FROM_LOW_DATA(usb_direction_t, direction, 2);
     548
     549#undef INIT_FROM_HIGH_DATA
     550#undef INIT_FROM_LOW_DATA
     551
     552        size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call);
     553        unsigned int interval  = (unsigned int) DEV_IPC_GET_ARG4(*call);
     554
     555        int rc = usb_iface->register_endpoint(fun, address, endpoint,
    563556            transfer_type, direction, max_packet_size, interval);
    564557
  • uspace/lib/drv/include/usbhc_iface.h

    r501e5df r8790650  
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
     68 *   - argument #3 is max packet size of the endpoint
    6869 * - this call is immediately followed by IPC data read (async version)
    6970 * - the call is not answered until the device returns some data (or until
     
    168169        /** Register endpoint attributes at host controller.
    169170         * This is used to reserve portion of USB bandwidth.
    170          * When speed is invalid, speed of the device is used.
    171171         * Parameters:
    172          * - USB address + endpoint number
    173          *   - packed as ADDR << 16 + EP
    174          * - speed + transfer type + direction
    175          *   - packed as ( SPEED << 8 + TYPE ) << 8 + DIR
    176          * - maximum packet size + interval (in milliseconds)
    177          *   - packed as MPS << 16 + INT
     172         * - USB address + endpoint number (ADDR * 256 + EP)
     173         * - transfer type + direction (TYPE * 256 + DIR)
     174         * - maximum packet size
     175         * - interval (in milliseconds)
    178176         * Answer:
    179177         * - EOK - reservation successful
     
    204202
    205203/** Out transfer processing function prototype. */
    206 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t,
     204typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
    207205    void *, size_t,
    208206    usbhc_iface_transfer_out_callback_t, void *);
     
    212210
    213211/** In transfer processing function prototype. */
    214 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t,
     212typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
    215213    void *, size_t,
    216214    usbhc_iface_transfer_in_callback_t, void *);
     
    224222        int (*release_address)(ddf_fun_t *, usb_address_t);
    225223
    226         int (*register_endpoint)(ddf_fun_t *,
    227             usb_address_t, usb_speed_t, usb_endpoint_t,
     224        int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
    228225            usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    229226        int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     
    237234
    238235        int (*control_write)(ddf_fun_t *, usb_target_t,
     236            size_t,
    239237            void *, size_t, void *, size_t,
    240238            usbhc_iface_transfer_out_callback_t, void *);
    241239
    242240        int (*control_read)(ddf_fun_t *, usb_target_t,
     241            size_t,
    243242            void *, size_t, void *, size_t,
    244243            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/Makefile

    r501e5df r8790650  
    4343        src/hidparser.c \
    4444        src/hub.c \
    45         src/pipepriv.c \
    4645        src/pipes.c \
    4746        src/pipesinit.c \
  • uspace/lib/usb/include/usb/classes/hub.h

    r501e5df r8790650  
    4343 */
    4444typedef enum {
    45         USB_HUB_FEATURE_HUB_LOCAL_POWER = 0,
    46         USB_HUB_FEATURE_HUB_OVER_CURRENT = 1,
    4745        USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
    4846        USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
     
    6159        /* USB_HUB_FEATURE_ = , */
    6260} usb_hub_class_feature_t;
    63 
    6461
    6562/** Header of standard hub descriptor without the "variadic" part. */
  • uspace/lib/usb/include/usb/devdrv.h

    r501e5df r8790650  
    169169    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
    170170
    171 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    172 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
    173     usb_endpoint_description_t **, uint8_t *, size_t, int, int,
    174     usb_endpoint_mapping_t **, size_t *);
    175 int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    176 
    177 size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
    178 
    179171#endif
    180172/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r501e5df r8790650  
    7373void usb_device_keeper_add_ep(
    7474    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
    75 void usb_device_keeper_del_ep(
    76     usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
    7775
    7876void usb_device_keeper_reserve_default_address(
  • uspace/lib/usb/include/usb/pipes.h

    r501e5df r8790650  
    4242#include <ipc/devman.h>
    4343#include <ddf/driver.h>
    44 #include <fibril_synch.h>
    4544
    4645/** Abstraction of a physical connection to the device.
     
    6059 * This endpoint must be bound with existing usb_device_connection_t
    6160 * (i.e. the wire to send data over).
    62  *
    63  * Locking order: if you want to lock both mutexes
    64  * (@c guard and @c hc_phone_mutex), lock @c guard first.
    65  * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex
    66  * only.
    6761 */
    6862typedef struct {
    69         /** Guard of the whole pipe. */
    70         fibril_mutex_t guard;
    71 
    7263        /** The connection used for sending the data. */
    7364        usb_device_connection_t *wire;
     
    8778        /** Phone to the host controller.
    8879         * Negative when no session is active.
    89          * It is an error to access this member without @c hc_phone_mutex
    90          * being locked.
    91          * If call over the phone is to be made, it must be preceeded by
    92          * call to pipe_add_ref() [internal libusb function].
    9380         */
    9481        int hc_phone;
    95 
    96         /** Guard for serialization of requests over the phone. */
    97         fibril_mutex_t hc_phone_mutex;
    98 
    99         /** Number of active transfers over the pipe. */
    100         int refcount;
    10182} usb_pipe_t;
    10283
     
    153134int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    154135    size_t, uint8_t *, size_t, usb_device_connection_t *);
    155 int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
    156     unsigned int, usb_hc_connection_t *);
    157136int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
    158137int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
     
    161140int usb_pipe_end_session(usb_pipe_t *);
    162141bool usb_pipe_is_session_started(usb_pipe_t *);
    163 
    164 int usb_pipe_start_long_transfer(usb_pipe_t *);
    165 void usb_pipe_end_long_transfer(usb_pipe_t *);
    166142
    167143int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *);
  • uspace/lib/usb/include/usb/usb.h

    r501e5df r8790650  
    7777        USB_SPEED_FULL,
    7878        /** USB 2.0 high speed (480Mbits/s). */
    79         USB_SPEED_HIGH,
    80         /** Psuedo-speed serving as a boundary. */
    81         USB_SPEED_MAX
     79        USB_SPEED_HIGH
    8280} usb_speed_t;
    8381
  • uspace/lib/usb/src/devdrv.c

    r501e5df r8790650  
    7272}
    7373
     74/** Log out of memory error on given device.
     75 *
     76 * @param dev Device causing the trouble.
     77 */
     78static void usb_log_oom(ddf_dev_t *dev)
     79{
     80        usb_log_error("Out of memory when adding device `%s'.\n",
     81            dev->name);
     82}
     83
    7484/** Count number of pipes the driver expects.
    7585 *
     
    98108 */
    99109static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
    100     usb_device_t *dev, int alternate_setting)
    101 {
    102         usb_endpoint_mapping_t *pipes;
    103         size_t pipes_count;
    104 
    105         int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
     110    usb_device_t *dev)
     111{
     112        int rc;
     113
     114        size_t pipe_count = count_other_pipes(endpoints);
     115        if (pipe_count == 0) {
     116                return EOK;
     117        }
     118
     119        dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
     120        if (dev->pipes == NULL) {
     121                usb_log_oom(dev->ddf_dev);
     122                return ENOMEM;
     123        }
     124
     125        size_t i;
     126
     127        /* Initialize to NULL first for rollback purposes. */
     128        for (i = 0; i < pipe_count; i++) {
     129                dev->pipes[i].pipe = NULL;
     130        }
     131
     132        for (i = 0; i < pipe_count; i++) {
     133                dev->pipes[i].pipe = malloc(sizeof(usb_pipe_t));
     134                if (dev->pipes[i].pipe == NULL) {
     135                        usb_log_oom(dev->ddf_dev);
     136                        rc = ENOMEM;
     137                        goto rollback;
     138                }
     139
     140                dev->pipes[i].description = endpoints[i];
     141                dev->pipes[i].interface_no = dev->interface_no;
     142                dev->pipes[i].interface_setting = 0;
     143        }
     144
     145        rc = usb_pipe_initialize_from_configuration(dev->pipes, pipe_count,
    106146            dev->descriptors.configuration, dev->descriptors.configuration_size,
    107             dev->interface_no, alternate_setting,
    108             &pipes, &pipes_count);
    109 
     147            &dev->wire);
     148        if (rc != EOK) {
     149                usb_log_error("Failed initializing USB endpoints: %s.\n",
     150                    str_error(rc));
     151                goto rollback;
     152        }
     153
     154        /* Register the endpoints. */
     155        usb_hc_connection_t hc_conn;
     156        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
    110157        if (rc != EOK) {
    111158                usb_log_error(
    112                     "Failed to create endpoint pipes for `%s': %s.\n",
    113                     dev->ddf_dev->name, str_error(rc));
    114                 return rc;
    115         }
    116 
    117         dev->pipes = pipes;
    118         dev->pipes_count = pipes_count;
     159                    "Failed initializing connection to host controller: %s.\n",
     160                    str_error(rc));
     161                goto rollback;
     162        }
     163        rc = usb_hc_connection_open(&hc_conn);
     164        if (rc != EOK) {
     165                usb_log_error("Failed to connect to host controller: %s.\n",
     166                    str_error(rc));
     167                goto rollback;
     168        }
     169        for (i = 0; i < pipe_count; i++) {
     170                if (dev->pipes[i].present) {
     171                        rc = usb_pipe_register(dev->pipes[i].pipe,
     172                            dev->pipes[i].descriptor->poll_interval,
     173                            &hc_conn);
     174                        /* Ignore error when operation not supported by HC. */
     175                        if ((rc != EOK) && (rc != ENOTSUP)) {
     176                                /* FIXME: what shall we do? */
     177                                dev->pipes[i].present = false;
     178                                free(dev->pipes[i].pipe);
     179                                dev->pipes[i].pipe = NULL;
     180                        }
     181                }
     182        }
     183        /* Ignoring errors here. */
     184        usb_hc_connection_close(&hc_conn);
     185
     186        dev->pipes_count = pipe_count;
    119187
    120188        return EOK;
     189
     190rollback:
     191        for (i = 0; i < pipe_count; i++) {
     192                if (dev->pipes[i].pipe != NULL) {
     193                        free(dev->pipes[i].pipe);
     194                }
     195        }
     196        free(dev->pipes);
     197
     198        return rc;
    121199}
    122200
     
    161239
    162240        /*
    163          * We will do some querying of the device, it is worth to prepare
    164          * the long transfer.
     241         * For further actions, we need open session on default control pipe.
    165242         */
    166         rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe);
    167         if (rc != EOK) {
    168                 usb_log_error("Failed to start transfer: %s.\n",
     243        rc = usb_pipe_start_session(&dev->ctrl_pipe);
     244        if (rc != EOK) {
     245                usb_log_error("Failed to start an IPC session: %s.\n",
    169246                    str_error(rc));
    170247                return rc;
    171248        }
    172249
    173         /* Retrieve the descriptors. */
    174         rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
    175             &dev->descriptors);
    176         if (rc != EOK) {
    177                 usb_log_error("Failed to retrieve standard device " \
    178                     "descriptors of %s: %s.\n",
     250        /* Get the device descriptor. */
     251        rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
     252            &dev->descriptors.device);
     253        if (rc != EOK) {
     254                usb_log_error("Failed to retrieve device descriptor: %s.\n",
     255                    str_error(rc));
     256                return rc;
     257        }
     258
     259        /* Get the full configuration descriptor. */
     260        rc = usb_request_get_full_configuration_descriptor_alloc(
     261            &dev->ctrl_pipe, 0, (void **) &dev->descriptors.configuration,
     262            &dev->descriptors.configuration_size);
     263        if (rc != EOK) {
     264                usb_log_error("Failed retrieving configuration descriptor: %s. %s\n",
    179265                    dev->ddf_dev->name, str_error(rc));
    180266                return rc;
    181267        }
    182268
    183 
    184269        if (driver->endpoints != NULL) {
    185                 rc = initialize_other_pipes(driver->endpoints, dev, 0);
    186         }
    187 
    188         usb_pipe_end_long_transfer(&dev->ctrl_pipe);
     270                rc = initialize_other_pipes(driver->endpoints, dev);
     271        }
     272
     273        /* No checking here. */
     274        usb_pipe_end_session(&dev->ctrl_pipe);
    189275
    190276        /* Rollback actions. */
     
    205291 * @return Number of alternate interfaces for @p interface_no interface.
    206292 */
    207 size_t usb_interface_count_alternates(uint8_t *config_descr,
    208     size_t config_descr_size, uint8_t interface_no)
     293static size_t count_alternate_interfaces(uint8_t *config_descr,
     294    size_t config_descr_size, int interface_no)
    209295{
    210296        assert(config_descr != NULL);
    211         assert(config_descr_size > 0);
    212 
    213297        usb_dp_parser_t dp_parser = {
    214298                .nesting = usb_dp_standard_descriptor_nesting
     
    259343
    260344        alternates->alternative_count
    261             = usb_interface_count_alternates(dev->descriptors.configuration,
     345            = count_alternate_interfaces(dev->descriptors.configuration,
    262346            dev->descriptors.configuration_size, dev->interface_no);
    263347
     
    373457static int destroy_current_pipes(usb_device_t *dev)
    374458{
    375         int rc = usb_device_destroy_pipes(dev->ddf_dev,
    376             dev->pipes, dev->pipes_count);
    377         if (rc != EOK) {
    378                 return rc;
    379         }
    380 
     459        size_t i;
     460        int rc;
     461
     462        /* TODO: this shall be done under some device mutex. */
     463
     464        /* First check that no session is opened. */
     465        for (i = 0; i < dev->pipes_count; i++) {
     466                if (usb_pipe_is_session_started(dev->pipes[i].pipe)) {
     467                        return EBUSY;
     468                }
     469        }
     470
     471        /* Prepare connection to HC. */
     472        usb_hc_connection_t hc_conn;
     473        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
     474        if (rc != EOK) {
     475                return rc;
     476        }
     477        rc = usb_hc_connection_open(&hc_conn);
     478        if (rc != EOK) {
     479                return rc;
     480        }
     481
     482        /* Destroy the pipes. */
     483        for (i = 0; i < dev->pipes_count; i++) {
     484                usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn);
     485                free(dev->pipes[i].pipe);
     486        }
     487
     488        usb_hc_connection_close(&hc_conn);
     489
     490        free(dev->pipes);
    381491        dev->pipes = NULL;
    382492        dev->pipes_count = 0;
     
    425535
    426536        /* Create new pipes. */
    427         rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
     537        rc = initialize_other_pipes(endpoints, dev);
    428538
    429539        return rc;
    430 }
    431 
    432 /** Retrieve basic descriptors from the device.
    433  *
    434  * @param[in] ctrl_pipe Control pipe with opened session.
    435  * @param[out] descriptors Where to store the descriptors.
    436  * @return Error code.
    437  */
    438 int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
    439     usb_device_descriptors_t *descriptors)
    440 {
    441         assert(descriptors != NULL);
    442         assert(usb_pipe_is_session_started(ctrl_pipe));
    443 
    444         descriptors->configuration = NULL;
    445 
    446         int rc;
    447 
    448         /* Get the device descriptor. */
    449         rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
    450         if (rc != EOK) {
    451                 return rc;
    452         }
    453 
    454         /* Get the full configuration descriptor. */
    455         rc = usb_request_get_full_configuration_descriptor_alloc(
    456             ctrl_pipe, 0, (void **) &descriptors->configuration,
    457             &descriptors->configuration_size);
    458         if (rc != EOK) {
    459                 return rc;
    460         }
    461 
    462         return EOK;
    463 }
    464 
    465 /** Create pipes for a device.
    466  *
    467  * This is more or less a wrapper that does following actions:
    468  * - allocate and initialize pipes
    469  * - map endpoints to the pipes based on the descriptions
    470  * - registers endpoints with the host controller
    471  *
    472  * @param[in] dev Generic DDF device backing the USB one.
    473  * @param[in] wire Initialized backing connection to the host controller.
    474  * @param[in] endpoints Endpoints description, NULL terminated.
    475  * @param[in] config_descr Configuration descriptor of active configuration.
    476  * @param[in] config_descr_size Size of @p config_descr in bytes.
    477  * @param[in] interface_no Interface to map from.
    478  * @param[in] interface_setting Interface setting (default is usually 0).
    479  * @param[out] pipes_ptr Where to store array of created pipes
    480  *      (not NULL terminated).
    481  * @param[out] pipes_count_ptr Where to store number of pipes
    482  *      (set to if you wish to ignore the count).
    483  * @return Error code.
    484  */
    485 int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
    486     usb_endpoint_description_t **endpoints,
    487     uint8_t *config_descr, size_t config_descr_size,
    488     int interface_no, int interface_setting,
    489     usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
    490 {
    491         assert(dev != NULL);
    492         assert(wire != NULL);
    493         assert(endpoints != NULL);
    494         assert(config_descr != NULL);
    495         assert(config_descr_size > 0);
    496         assert(pipes_ptr != NULL);
    497 
    498         size_t i;
    499         int rc;
    500 
    501         size_t pipe_count = count_other_pipes(endpoints);
    502         if (pipe_count == 0) {
    503                 *pipes_ptr = NULL;
    504                 return EOK;
    505         }
    506 
    507         usb_endpoint_mapping_t *pipes
    508             = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
    509         if (pipes == NULL) {
    510                 return ENOMEM;
    511         }
    512 
    513         /* Initialize to NULL to allow smooth rollback. */
    514         for (i = 0; i < pipe_count; i++) {
    515                 pipes[i].pipe = NULL;
    516         }
    517 
    518         /* Now allocate and fully initialize. */
    519         for (i = 0; i < pipe_count; i++) {
    520                 pipes[i].pipe = malloc(sizeof(usb_pipe_t));
    521                 if (pipes[i].pipe == NULL) {
    522                         rc = ENOMEM;
    523                         goto rollback_free_only;
    524                 }
    525                 pipes[i].description = endpoints[i];
    526                 pipes[i].interface_no = interface_no;
    527                 pipes[i].interface_setting = interface_setting;
    528         }
    529 
    530         /* Find the mapping from configuration descriptor. */
    531         rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    532             config_descr, config_descr_size, wire);
    533         if (rc != EOK) {
    534                 goto rollback_free_only;
    535         }
    536 
    537         /* Register the endpoints with HC. */
    538         usb_hc_connection_t hc_conn;
    539         rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
    540         if (rc != EOK) {
    541                 goto rollback_free_only;
    542         }
    543 
    544         rc = usb_hc_connection_open(&hc_conn);
    545         if (rc != EOK) {
    546                 goto rollback_free_only;
    547         }
    548 
    549         for (i = 0; i < pipe_count; i++) {
    550                 if (pipes[i].present) {
    551                         rc = usb_pipe_register(pipes[i].pipe,
    552                             pipes[i].descriptor->poll_interval, &hc_conn);
    553                         if (rc != EOK) {
    554                                 goto rollback_unregister_endpoints;
    555                         }
    556                 }
    557         }
    558 
    559         usb_hc_connection_close(&hc_conn);
    560 
    561         *pipes_ptr = pipes;
    562         if (pipes_count_ptr != NULL) {
    563                 *pipes_count_ptr = pipe_count;
    564         }
    565 
    566         return EOK;
    567 
    568         /*
    569          * Jump here if something went wrong after endpoints have
    570          * been registered.
    571          * This is also the target when the registration of
    572          * endpoints fails.
    573          */
    574 rollback_unregister_endpoints:
    575         for (i = 0; i < pipe_count; i++) {
    576                 if (pipes[i].present) {
    577                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    578                 }
    579         }
    580 
    581         usb_hc_connection_close(&hc_conn);
    582 
    583         /*
    584          * Jump here if something went wrong before some actual communication
    585          * with HC. Then the only thing that needs to be done is to free
    586          * allocated memory.
    587          */
    588 rollback_free_only:
    589         for (i = 0; i < pipe_count; i++) {
    590                 if (pipes[i].pipe != NULL) {
    591                         free(pipes[i].pipe);
    592                 }
    593         }
    594         free(pipes);
    595 
    596         return rc;
    597 }
    598 
    599 /** Destroy pipes previously created by usb_device_create_pipes.
    600  *
    601  * @param[in] dev Generic DDF device backing the USB one.
    602  * @param[in] pipes Endpoint mapping to be destroyed.
    603  * @param[in] pipes_count Number of endpoints.
    604  */
    605 int usb_device_destroy_pipes(ddf_dev_t *dev,
    606     usb_endpoint_mapping_t *pipes, size_t pipes_count)
    607 {
    608         assert(dev != NULL);
    609         assert(((pipes != NULL) && (pipes_count > 0))
    610             || ((pipes == NULL) && (pipes_count == 0)));
    611 
    612         if (pipes_count == 0) {
    613                 return EOK;
    614         }
    615 
    616         int rc;
    617 
    618         /* Prepare connection to HC to allow endpoint unregistering. */
    619         usb_hc_connection_t hc_conn;
    620         rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
    621         if (rc != EOK) {
    622                 return rc;
    623         }
    624         rc = usb_hc_connection_open(&hc_conn);
    625         if (rc != EOK) {
    626                 return rc;
    627         }
    628 
    629         /* Destroy the pipes. */
    630         size_t i;
    631         for (i = 0; i < pipes_count; i++) {
    632                 usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    633                 free(pipes[i].pipe);
    634         }
    635 
    636         usb_hc_connection_close(&hc_conn);
    637 
    638         free(pipes);
    639 
    640         return EOK;
    641540}
    642541
  • uspace/lib/usb/src/devpoll.c

    r501e5df r8790650  
    7777                int rc;
    7878
     79                rc = usb_pipe_start_session(pipe);
     80                if (rc != EOK) {
     81                        failed_attempts++;
     82                        continue;
     83                }
     84
    7985                size_t actual_size;
    8086                rc = usb_pipe_read(pipe, polling_data->buffer,
    8187                    polling_data->request_size, &actual_size);
    8288
     89                /* Quit the session regardless of errors. */
     90                usb_pipe_end_session(pipe);
    8391               
    8492//              if (rc == ESTALL) {
  • uspace/lib/usb/src/host/device_keeper.c

    r501e5df r8790650  
    5656                instance->devices[i].control_used = 0;
    5757                instance->devices[i].handle = 0;
    58                 instance->devices[i].speed = USB_SPEED_MAX;
    5958                list_initialize(&instance->devices[i].endpoints);
    6059        }
    61         // TODO: is this hack enough?
    62         // (it is needed to allow smooth registration at default address)
    63         instance->devices[0].occupied = true;
    6460}
    6561/*----------------------------------------------------------------------------*/
     
    7167        assert(instance->devices[address].occupied);
    7268        list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
    73         fibril_mutex_unlock(&instance->guard);
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 void usb_device_keeper_del_ep(
    77     usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
    78 {
    79         assert(instance);
    80         fibril_mutex_lock(&instance->guard);
    81         assert(instance->devices[address].occupied);
    82         list_remove(&ep->same_device_eps);
    83         list_initialize(&ep->same_device_eps);
    8469        fibril_mutex_unlock(&instance->guard);
    8570}
  • uspace/lib/usb/src/hub.c

    r501e5df r8790650  
    4040#include <errno.h>
    4141#include <assert.h>
    42 #include <usb/debug.h>
    4342
    4443/** Check that HC connection is alright.
     
    5655
    5756/** Tell host controller to reserve default address.
    58  * @deprecated
    5957 *
    6058 * @param connection Opened connection to host controller.
     
    6765        CHECK_CONNECTION(connection);
    6866
    69         usb_log_warning("usb_hc_reserve_default_address() considered obsolete");
    70 
    7167        return async_req_2_0(connection->hc_phone,
    7268            DEV_IFACE_ID(USBHC_DEV_IFACE),
     
    7571
    7672/** Tell host controller to release default address.
    77  * @deprecated
    7873 *
    7974 * @param connection Opened connection to host controller.
     
    8378{
    8479        CHECK_CONNECTION(connection);
    85 
    86         usb_log_warning("usb_hc_release_default_address() considered obsolete");
    8780
    8881        return async_req_1_0(connection->hc_phone,
     
    242235        }
    243236
    244         /*
    245          * We will not register control pipe on default address.
    246          * The registration might fail. That means that someone else already
    247          * registered that endpoint. We will simply wait and try again.
    248          * (Someone else already wants to add a new device.)
     237
     238        /*
     239         * Reserve the default address.
     240         */
     241        rc = usb_hc_reserve_default_address(&hc_conn, dev_speed);
     242        if (rc != EOK) {
     243                rc = EBUSY;
     244                goto leave_release_free_address;
     245        }
     246
     247        /*
     248         * Enable the port (i.e. allow signaling through this port).
     249         */
     250        rc = enable_port(port_no, arg);
     251        if (rc != EOK) {
     252                goto leave_release_default_address;
     253        }
     254
     255        /*
     256         * Change the address from default to the free one.
     257         * We need to create a new control pipe for that.
    249258         */
    250259        usb_device_connection_t dev_conn;
     
    253262        if (rc != EOK) {
    254263                rc = ENOTCONN;
    255                 goto leave_release_free_address;
     264                goto leave_release_default_address;
    256265        }
    257266
     
    261270        if (rc != EOK) {
    262271                rc = ENOTCONN;
    263                 goto leave_release_free_address;
    264         }
    265 
    266         do {
    267                 rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
    268                     &hc_conn);
    269                 if (rc != EOK) {
    270                         /* Do not overheat the CPU ;-). */
    271                         async_usleep(10);
    272                 }
    273         } while (rc != EOK);
    274 
    275         /*
    276          * Endpoint is registered. We can enable the port and change
    277          * device address.
    278          */
    279         rc = enable_port(port_no, arg);
    280         if (rc != EOK) {
    281                 goto leave_release_default_address;
    282         }
    283 
     272                goto leave_release_default_address;
     273        }
     274
     275        /* Before sending any traffic, we need to register this
     276         * endpoint.
     277         */
     278        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     279        if (rc != EOK) {
     280                rc = EREFUSED;
     281                goto leave_release_default_address;
     282        }
    284283        rc = usb_pipe_probe_default_control(&ctrl_pipe);
    285284        if (rc != EOK) {
     285                rc = ENOTCONN;
     286                goto leave_release_default_address;
     287        }
     288
     289        rc = usb_pipe_start_session(&ctrl_pipe);
     290        if (rc != EOK) {
     291                rc = ENOTCONN;
     292                goto leave_unregister_endpoint;
     293        }
     294
     295        rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     296        if (rc != EOK) {
    286297                rc = ESTALL;
    287                 goto leave_release_default_address;
    288         }
    289 
    290         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
    291         if (rc != EOK) {
    292                 rc = ESTALL;
    293                 goto leave_release_default_address;
    294         }
    295 
    296         /*
    297          * Address changed. We can release the original endpoint, thus
    298          * allowing other to access the default address.
     298                goto leave_stop_session;
     299        }
     300
     301        usb_pipe_end_session(&ctrl_pipe);
     302
     303        /*
     304         * Register the control endpoint for the new device.
     305         */
     306        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     307        if (rc != EOK) {
     308                rc = EREFUSED;
     309                goto leave_unregister_endpoint;
     310        }
     311
     312        /*
     313         * Release the original endpoint.
    299314         */
    300315        unregister_control_endpoint_on_default_address(&hc_conn);
    301316
    302317        /*
    303          * Time to register the new endpoint.
    304          */
    305         rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    306         if (rc != EOK) {
    307                 goto leave_release_free_address;
    308         }
     318         * Once the address is changed, we can return the default address.
     319         */
     320        usb_hc_release_default_address(&hc_conn);
     321
    309322
    310323        /*
     
    321334        }
    322335
     336
     337
    323338        /*
    324339         * And now inform the host controller about the handle.
     
    352367         * Completely ignoring errors here.
    353368         */
     369
     370leave_stop_session:
     371        usb_pipe_end_session(&ctrl_pipe);
     372
     373leave_unregister_endpoint:
     374        usb_pipe_unregister(&ctrl_pipe, &hc_conn);
     375
    354376leave_release_default_address:
    355         usb_pipe_unregister(&ctrl_pipe, &hc_conn);
     377        usb_hc_release_default_address(&hc_conn);
    356378
    357379leave_release_free_address:
  • uspace/lib/usb/src/pipes.c

    r501e5df r8790650  
    4141#include <errno.h>
    4242#include <assert.h>
    43 #include "pipepriv.h"
    4443
    4544#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
     
    242241 * necessary.
    243242 *
    244  * @deprecated
    245  * Obsoleted with introduction of usb_pipe_start_long_transfer
    246  *
    247243 * @param pipe Endpoint pipe to start the session on.
    248244 * @return Error code.
     
    250246int usb_pipe_start_session(usb_pipe_t *pipe)
    251247{
    252         usb_log_warning("usb_pipe_start_session() was deprecated.\n");
     248        assert(pipe);
     249
     250        if (usb_pipe_is_session_started(pipe)) {
     251                return EBUSY;
     252        }
     253
     254        int phone = devman_device_connect(pipe->wire->hc_handle, 0);
     255        if (phone < 0) {
     256                return phone;
     257        }
     258
     259        pipe->hc_phone = phone;
     260
    253261        return EOK;
    254262}
     
    257265/** Ends a session on the endpoint pipe.
    258266 *
    259  * @deprecated
    260  * Obsoleted with introduction of usb_pipe_end_long_transfer
    261  *
    262267 * @see usb_pipe_start_session
    263268 *
     
    267272int usb_pipe_end_session(usb_pipe_t *pipe)
    268273{
    269         usb_log_warning("usb_pipe_end_session() was deprecated.\n");
     274        assert(pipe);
     275
     276        if (!usb_pipe_is_session_started(pipe)) {
     277                return ENOENT;
     278        }
     279
     280        int rc = async_hangup(pipe->hc_phone);
     281        if (rc != EOK) {
     282                return rc;
     283        }
     284
     285        pipe->hc_phone = -1;
     286
    270287        return EOK;
    271288}
     
    281298bool usb_pipe_is_session_started(usb_pipe_t *pipe)
    282299{
    283         pipe_acquire(pipe);
    284         bool started = pipe->refcount > 0;
    285         pipe_release(pipe);
    286         return started;
    287 }
    288 
    289 /** Prepare pipe for a long transfer.
    290  *
    291  * By a long transfer is mean transfer consisting of several
    292  * requests to the HC.
    293  * Calling such function is optional and it has positive effect of
    294  * improved performance because IPC session is initiated only once.
    295  *
    296  * @param pipe Pipe over which the transfer will happen.
    297  * @return Error code.
    298  */
    299 int usb_pipe_start_long_transfer(usb_pipe_t *pipe)
    300 {
    301         return pipe_add_ref(pipe);
    302 }
    303 
    304 /** Terminate a long transfer on a pipe.
    305  *
    306  * @see usb_pipe_start_long_transfer
    307  *
    308  * @param pipe Pipe where to end the long transfer.
    309  */
    310 void usb_pipe_end_long_transfer(usb_pipe_t *pipe)
    311 {
    312         pipe_drop_ref(pipe);
     300        return (pipe->hc_phone >= 0);
    313301}
    314302
  • uspace/lib/usb/src/pipesinit.c

    r501e5df r8790650  
    356356        assert(connection);
    357357
    358         fibril_mutex_initialize(&pipe->guard);
    359358        pipe->wire = connection;
    360359        pipe->hc_phone = -1;
    361         fibril_mutex_initialize(&pipe->hc_phone_mutex);
    362360        pipe->endpoint_no = endpoint_no;
    363361        pipe->transfer_type = transfer_type;
    364362        pipe->max_packet_size = max_packet_size;
    365363        pipe->direction = direction;
    366         pipe->refcount = 0;
    367364
    368365        return EOK;
     
    416413        int rc;
    417414
    418         rc = usb_pipe_start_long_transfer(pipe);
     415        TRY_LOOP(failed_attempts) {
     416                rc = usb_pipe_start_session(pipe);
     417                if (rc == EOK) {
     418                        break;
     419                }
     420        }
    419421        if (rc != EOK) {
    420422                return rc;
     
    437439                }
    438440        }
    439         usb_pipe_end_long_transfer(pipe);
     441        usb_pipe_end_session(pipe);
    440442        if (rc != EOK) {
    441443                return rc;
     
    459461    usb_hc_connection_t *hc_connection)
    460462{
    461         return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
    462             interval, hc_connection);
    463 }
    464 
    465 /** Register endpoint with a speed at the host controller.
    466  *
    467  * You will rarely need to use this function because it is needed only
    468  * if the registered endpoint is of address 0 and there is no other way
    469  * to tell speed of the device at address 0.
    470  *
    471  * @param pipe Pipe to be registered.
    472  * @param speed Speed of the device
    473  *      (invalid speed means use previously specified one).
    474  * @param interval Polling interval.
    475  * @param hc_connection Connection to the host controller (must be opened).
    476  * @return Error code.
    477  */
    478 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
    479     unsigned int interval,
    480     usb_hc_connection_t *hc_connection)
    481 {
    482463        assert(pipe);
    483464        assert(hc_connection);
     
    487468        }
    488469
    489 #define _PACK2(high, low) (((high) << 16) + (low))
    490 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
    491 
    492         return async_req_4_0(hc_connection->hc_phone,
     470#define _PACK(high, low) ((high) * 256 + (low))
     471
     472        return async_req_5_0(hc_connection->hc_phone,
    493473            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
    494             _PACK2(pipe->wire->address, pipe->endpoint_no),
    495             _PACK3(speed, pipe->transfer_type, pipe->direction),
    496             _PACK2(pipe->max_packet_size, interval));
    497 
    498 #undef _PACK2
    499 #undef _PACK3
     474            _PACK(pipe->wire->address, pipe->endpoint_no),
     475            _PACK(pipe->transfer_type, pipe->direction),
     476            pipe->max_packet_size, interval);
     477
     478#undef _PACK
    500479}
    501480
  • uspace/lib/usb/src/pipesio.c

    r501e5df r8790650  
    4949#include <assert.h>
    5050#include <usbhc_iface.h>
    51 #include "pipepriv.h"
    5251
    5352/** Request an in transfer, no checking of input parameters.
     
    7978        }
    8079
    81         /* Ensure serialization over the phone. */
    82         pipe_start_transaction(pipe);
    83 
    8480        /*
    8581         * Make call identifying target USB device and type of transfer.
    8682         */
    87         aid_t opening_request = async_send_3(pipe->hc_phone,
     83        aid_t opening_request = async_send_4(pipe->hc_phone,
    8884            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    8985            pipe->wire->address, pipe->endpoint_no,
     86            pipe->max_packet_size,
    9087            NULL);
    9188        if (opening_request == 0) {
    92                 pipe_end_transaction(pipe);
    9389                return ENOMEM;
    9490        }
     
    10096        aid_t data_request = async_data_read(pipe->hc_phone, buffer, size,
    10197            &data_request_call);
    102 
    103         /*
    104          * Since now on, someone else might access the backing phone
    105          * without breaking the transfer IPC protocol.
    106          */
    107         pipe_end_transaction(pipe);
    10898
    10999        if (data_request == 0) {
     
    156146
    157147        if (buffer == NULL) {
    158                 return EINVAL;
     148                        return EINVAL;
    159149        }
    160150
     
    163153        }
    164154
     155        if (!usb_pipe_is_session_started(pipe)) {
     156                return EBADF;
     157        }
     158
    165159        if (pipe->direction != USB_DIRECTION_IN) {
    166160                return EBADF;
     
    171165        }
    172166
     167        size_t act_size = 0;
    173168        int rc;
    174         rc = pipe_add_ref(pipe);
    175         if (rc != EOK) {
    176                 return rc;
    177         }
    178 
    179 
    180         size_t act_size = 0;
    181169
    182170        rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size);
    183 
    184         pipe_drop_ref(pipe);
    185 
    186171        if (rc != EOK) {
    187172                return rc;
     
    225210        }
    226211
    227         /* Ensure serialization over the phone. */
    228         pipe_start_transaction(pipe);
    229 
    230212        /*
    231213         * Make call identifying target USB device and type of transfer.
    232214         */
    233         aid_t opening_request = async_send_3(pipe->hc_phone,
     215        aid_t opening_request = async_send_4(pipe->hc_phone,
    234216            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    235217            pipe->wire->address, pipe->endpoint_no,
     218            pipe->max_packet_size,
    236219            NULL);
    237220        if (opening_request == 0) {
    238                 pipe_end_transaction(pipe);
    239221                return ENOMEM;
    240222        }
     
    244226         */
    245227        int rc = async_data_write_start(pipe->hc_phone, buffer, size);
    246 
    247         /*
    248          * Since now on, someone else might access the backing phone
    249          * without breaking the transfer IPC protocol.
    250          */
    251         pipe_end_transaction(pipe);
    252 
    253228        if (rc != EOK) {
    254229                async_wait_for(opening_request, NULL);
     
    285260        }
    286261
     262        if (!usb_pipe_is_session_started(pipe)) {
     263                return EBADF;
     264        }
     265
    287266        if (pipe->direction != USB_DIRECTION_OUT) {
    288267                return EBADF;
     
    293272        }
    294273
    295         int rc;
    296 
    297         rc = pipe_add_ref(pipe);
    298         if (rc != EOK) {
    299                 return rc;
    300         }
    301 
    302         rc = usb_pipe_write_no_check(pipe, buffer, size);
    303 
    304         pipe_drop_ref(pipe);
     274        int rc = usb_pipe_write_no_check(pipe, buffer, size);
    305275
    306276        return rc;
     
    323293    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
    324294{
    325         /* Ensure serialization over the phone. */
    326         pipe_start_transaction(pipe);
    327 
    328295        /*
    329296         * Make call identifying target USB device and control transfer type.
    330297         */
    331         aid_t opening_request = async_send_3(pipe->hc_phone,
     298        aid_t opening_request = async_send_4(pipe->hc_phone,
    332299            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
    333300            pipe->wire->address, pipe->endpoint_no,
     301            pipe->max_packet_size,
    334302            NULL);
    335303        if (opening_request == 0) {
     
    343311            setup_buffer, setup_buffer_size);
    344312        if (rc != EOK) {
    345                 pipe_end_transaction(pipe);
    346313                async_wait_for(opening_request, NULL);
    347314                return rc;
     
    355322            data_buffer, data_buffer_size,
    356323            &data_request_call);
    357 
    358         /*
    359          * Since now on, someone else might access the backing phone
    360          * without breaking the transfer IPC protocol.
    361          */
    362         pipe_end_transaction(pipe);
    363 
    364 
    365324        if (data_request == 0) {
    366325                async_wait_for(opening_request, NULL);
     
    420379        }
    421380
     381        if (!usb_pipe_is_session_started(pipe)) {
     382                return EBADF;
     383        }
     384
    422385        if ((pipe->direction != USB_DIRECTION_BOTH)
    423386            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     
    425388        }
    426389
    427         int rc;
    428 
    429         rc = pipe_add_ref(pipe);
    430         if (rc != EOK) {
    431                 return rc;
    432         }
    433 
    434390        size_t act_size = 0;
    435         rc = usb_pipe_control_read_no_check(pipe,
     391        int rc = usb_pipe_control_read_no_check(pipe,
    436392            setup_buffer, setup_buffer_size,
    437393            data_buffer, data_buffer_size, &act_size);
    438 
    439         pipe_drop_ref(pipe);
    440394
    441395        if (rc != EOK) {
     
    464418    void *data_buffer, size_t data_buffer_size)
    465419{
    466         /* Ensure serialization over the phone. */
    467         pipe_start_transaction(pipe);
    468 
    469420        /*
    470421         * Make call identifying target USB device and control transfer type.
    471422         */
    472         aid_t opening_request = async_send_4(pipe->hc_phone,
     423        aid_t opening_request = async_send_5(pipe->hc_phone,
    473424            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
    474425            pipe->wire->address, pipe->endpoint_no,
    475426            data_buffer_size,
     427            pipe->max_packet_size,
    476428            NULL);
    477429        if (opening_request == 0) {
    478                 pipe_end_transaction(pipe);
    479430                return ENOMEM;
    480431        }
     
    486437            setup_buffer, setup_buffer_size);
    487438        if (rc != EOK) {
    488                 pipe_end_transaction(pipe);
    489439                async_wait_for(opening_request, NULL);
    490440                return rc;
     
    497447                rc = async_data_write_start(pipe->hc_phone,
    498448                    data_buffer, data_buffer_size);
    499 
    500                 /* All data sent, pipe can be released. */
    501                 pipe_end_transaction(pipe);
    502 
    503449                if (rc != EOK) {
    504450                        async_wait_for(opening_request, NULL);
    505451                        return rc;
    506452                }
    507         } else {
    508                 /* No data to send, we can release the pipe for others. */
    509                 pipe_end_transaction(pipe);
    510453        }
    511454
     
    548491        }
    549492
     493        if (!usb_pipe_is_session_started(pipe)) {
     494                return EBADF;
     495        }
     496
    550497        if ((pipe->direction != USB_DIRECTION_BOTH)
    551498            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     
    553500        }
    554501
    555         int rc;
    556 
    557         rc = pipe_add_ref(pipe);
    558         if (rc != EOK) {
    559                 return rc;
    560         }
    561 
    562         rc = usb_pipe_control_write_no_check(pipe,
     502        int rc = usb_pipe_control_write_no_check(pipe,
    563503            setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
    564 
    565         pipe_drop_ref(pipe);
    566504
    567505        return rc;
  • uspace/lib/usb/src/recognise.c

    r501e5df r8790650  
    404404        child->driver_data = dev_data;
    405405
     406        rc = usb_pipe_start_session(&ctrl_pipe);
     407        if (rc != EOK) {
     408                goto failure;
     409        }
     410
    406411        rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
     412        if (rc != EOK) {
     413                goto failure;
     414        }
     415
     416        rc = usb_pipe_end_session(&ctrl_pipe);
    407417        if (rc != EOK) {
    408418                goto failure;
Note: See TracChangeset for help on using the changeset viewer.