Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a9d67aa in mainline


Ignore:
Timestamp:
2011-04-09T17:15:28Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial
Children:
97e7e8a
Parents:
5410c04 (diff), 77223f8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Refactoring: libusb, USBHC interface protocol

Highlights:

  • refactoring of libusb (not complete)
  • max packet size is not send during each transfer
  • reserving of default address is possible via endpoint registration
  • endpoint registration can send speed as well
Location:
uspace
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ehci-hcd/hc_iface.c

    r5410c04 ra9d67aa  
    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).
    125126 * @param[in] endpoint Endpoint number.
    126127 * @param[in] transfer_type USB transfer type.
     
    131132 */
    132133static int register_endpoint(ddf_fun_t *fun,
    133     usb_address_t address, usb_endpoint_t endpoint,
     134    usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
    134135    usb_transfer_type_t transfer_type, usb_direction_t direction,
    135136    size_t max_packet_size, unsigned int interval)
     
    165166 * @param[in] fun Device function the action was invoked on.
    166167 * @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     size_t max_packet_size, void *data, size_t size,
     176    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.
    194193 * @param[in] data Buffer where to store the data (in USB endianess,
    195194 *      allocated and deallocated by the caller).
     
    200199 */
    201200static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    202     size_t max_packet_size, void *data, size_t size,
     201    void *data, size_t size,
    203202    usbhc_iface_transfer_in_callback_t callback, void *arg)
    204203{
     
    217216 * @param[in] fun Device function the action was invoked on.
    218217 * @param[in] target Target pipe (address and endpoint number) specification.
    219  * @param[in] max_packet_size Max packet size for the transfer.
    220218 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    221219 *      by the caller).
     
    226224 */
    227225static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    228     size_t max_packet_size, void *data, size_t size,
     226    void *data, size_t size,
    229227    usbhc_iface_transfer_out_callback_t callback, void *arg)
    230228{
     
    243241 * @param[in] fun Device function the action was invoked on.
    244242 * @param[in] target Target pipe (address and endpoint number) specification.
    245  * @param[in] max_packet_size Max packet size for the transfer.
    246243 * @param[in] data Buffer where to store the data (in USB endianess,
    247244 *      allocated and deallocated by the caller).
     
    252249 */
    253250static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    254     size_t max_packet_size, void *data, size_t size,
     251    void *data, size_t size,
    255252    usbhc_iface_transfer_in_callback_t callback, void *arg)
    256253{
     
    269266 * @param[in] fun Device function the action was invoked on.
    270267 * @param[in] target Target pipe (address and endpoint number) specification.
    271  * @param[in] max_packet_size Max packet size for the transfer.
    272268 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    273269 *      and deallocated by the caller).
     
    281277 */
    282278static int control_write(ddf_fun_t *fun, usb_target_t target,
    283     size_t max_packet_size,
    284279    void *setup_packet, size_t setup_packet_size,
    285280    void *data_buffer, size_t data_buffer_size,
     
    300295 * @param[in] fun Device function the action was invoked on.
    301296 * @param[in] target Target pipe (address and endpoint number) specification.
    302  * @param[in] max_packet_size Max packet size for the transfer.
    303297 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    304298 *      and deallocated by the caller).
     
    312306 */
    313307static int control_read(ddf_fun_t *fun, usb_target_t target,
    314     size_t max_packet_size,
    315308    void *setup_packet, size_t setup_packet_size,
    316309    void *data_buffer, size_t data_buffer_size,
  • uspace/drv/ohci/iface.c

    r5410c04 ra9d67aa  
    197197}
    198198/*----------------------------------------------------------------------------*/
    199 static int register_endpoint(
    200     ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
     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 */
     211static int register_endpoint(ddf_fun_t *fun,
     212    usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint,
    201213    usb_transfer_type_t transfer_type, usb_direction_t direction,
    202214    size_t max_packet_size, unsigned int interval)
     
    204216        hc_t *hc = fun_to_hc(fun);
    205217        assert(hc);
    206         const usb_speed_t speed =
    207             usb_device_keeper_get_speed(&hc->manager, address);
     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        }
    208224        const size_t size =
    209225            (transfer_type == USB_TRANSFER_INTERRUPT
     
    243259        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    244260            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        }
    245266        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    246267            endpoint, direction);
    247268}
    248269/*----------------------------------------------------------------------------*/
    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.
     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.
    258284 * @return Error code.
    259285 */
    260286static int interrupt_out(
    261     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     287    ddf_fun_t *fun, usb_target_t target, void *data,
    262288    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    263289{
     
    276302}
    277303/*----------------------------------------------------------------------------*/
    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.
     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.
    287318 * @return Error code.
    288319 */
    289320static int interrupt_in(
    290     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     321    ddf_fun_t *fun, usb_target_t target, void *data,
    291322    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    292323{
     
    305336}
    306337/*----------------------------------------------------------------------------*/
    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.
     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.
    316352 * @return Error code.
    317353 */
    318354static int bulk_out(
    319     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     355    ddf_fun_t *fun, usb_target_t target, void *data,
    320356    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    321357{
     
    334370}
    335371/*----------------------------------------------------------------------------*/
    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.
     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.
    345386 * @return Error code.
    346387 */
    347388static int bulk_in(
    348     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     389    ddf_fun_t *fun, usb_target_t target, void *data,
    349390    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    350391{
     
    363404}
    364405/*----------------------------------------------------------------------------*/
    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.
     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.
    376423 * @return Error code.
    377424 */
    378425static int control_write(
    379     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     426    ddf_fun_t *fun, usb_target_t target,
    380427    void *setup_data, size_t setup_size, void *data, size_t size,
    381428    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    397444}
    398445/*----------------------------------------------------------------------------*/
    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.
     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.
    410463 * @return Error code.
    411464 */
    412465static int control_read(
    413     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     466    ddf_fun_t *fun, usb_target_t target,
    414467    void *setup_data, size_t setup_size, void *data, size_t size,
    415468    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/uhci-hcd/iface.c

    r5410c04 ra9d67aa  
    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_endpoint_t endpoint,
     200    ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
     201    usb_endpoint_t endpoint,
    201202    usb_transfer_type_t transfer_type, usb_direction_t direction,
    202203    size_t max_packet_size, unsigned int interval)
     
    204205        hc_t *hc = fun_to_hc(fun);
    205206        assert(hc);
    206         const usb_speed_t speed =
    207             usb_device_keeper_get_speed(&hc->manager, address);
    208         const size_t size = max_packet_size;
     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;
    209215        int ret;
    210216
     
    240246        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    241247            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        }
    242253        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
    243254            endpoint, direction);
     
    248259 * @param[in] fun DDF function that was called.
    249260 * @param[in] target USB device to write to.
    250  * @param[in] max_packet_size maximum size of data packet the device accepts
    251261 * @param[in] data Source of data.
    252262 * @param[in] size Size of data source.
     
    256266 */
    257267static int interrupt_out(
    258     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     268    ddf_fun_t *fun, usb_target_t target, void *data,
    259269    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    260270{
     
    277287 * @param[in] fun DDF function that was called.
    278288 * @param[in] target USB device to write to.
    279  * @param[in] max_packet_size maximum size of data packet the device accepts
    280289 * @param[out] data Data destination.
    281290 * @param[in] size Size of data source.
     
    285294 */
    286295static int interrupt_in(
    287     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     296    ddf_fun_t *fun, usb_target_t target, void *data,
    288297    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    289298{
     
    306315 * @param[in] fun DDF function that was called.
    307316 * @param[in] target USB device to write to.
    308  * @param[in] max_packet_size maximum size of data packet the device accepts
    309317 * @param[in] data Source of data.
    310318 * @param[in] size Size of data source.
     
    314322 */
    315323static int bulk_out(
    316     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     324    ddf_fun_t *fun, usb_target_t target, void *data,
    317325    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    318326{
     
    335343 * @param[in] fun DDF function that was called.
    336344 * @param[in] target USB device to write to.
    337  * @param[in] max_packet_size maximum size of data packet the device accepts
    338345 * @param[out] data Data destination.
    339346 * @param[in] size Size of data source.
     
    343350 */
    344351static int bulk_in(
    345     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     352    ddf_fun_t *fun, usb_target_t target, void *data,
    346353    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    347354{
     
    364371 * @param[in] fun DDF function that was called.
    365372 * @param[in] target USB device to write to.
    366  * @param[in] max_packet_size maximum size of data packet the device accepts.
    367373 * @param[in] setup_data Data to send with SETUP transfer.
    368374 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    374380 */
    375381static int control_write(
    376     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     382    ddf_fun_t *fun, usb_target_t target,
    377383    void *setup_data, size_t setup_size, void *data, size_t size,
    378384    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    398404 * @param[in] fun DDF function that was called.
    399405 * @param[in] target USB device to write to.
    400  * @param[in] max_packet_size maximum size of data packet the device accepts.
    401406 * @param[in] setup_data Data to send with SETUP packet.
    402407 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    408413 */
    409414static int control_read(
    410     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     415    ddf_fun_t *fun, usb_target_t target,
    411416    void *setup_data, size_t setup_size, void *data, size_t size,
    412417    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/vhc/connhost.c

    r5410c04 ra9d67aa  
    257257
    258258static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    259     size_t max_packet_size,
    260259    void *data, size_t size,
    261260    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    267266
    268267static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    269     size_t max_packet_size,
    270268    void *data, size_t size,
    271269    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    277275
    278276static int control_write(ddf_fun_t *fun, usb_target_t target,
    279     size_t max_packet_size,
    280277    void *setup_packet, size_t setup_packet_size,
    281278    void *data, size_t data_size,
     
    295292
    296293static int control_read(ddf_fun_t *fun, usb_target_t target,
    297     size_t max_packet_size,
    298294    void *setup_packet, size_t setup_packet_size,
    299295    void *data, size_t data_size,
  • uspace/lib/drv/generic/remote_usbhc.c

    r5410c04 ra9d67aa  
    270270        }
    271271
    272         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    273272        usb_target_t target = {
    274273                .address = DEV_IPC_GET_ARG1(*call),
     
    300299        trans->size = len;
    301300
    302         rc = transfer_func(fun, target, max_packet_size,
     301        rc = transfer_func(fun, target,
    303302            buffer, len,
    304303            callback_out, trans);
     
    326325        }
    327326
    328         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    329327        usb_target_t target = {
    330328                .address = DEV_IPC_GET_ARG1(*call),
     
    348346        trans->size = len;
    349347
    350         int rc = transfer_func(fun, target, max_packet_size,
     348        int rc = transfer_func(fun, target,
    351349            trans->buffer, len,
    352350            callback_in, trans);
     
    414412        };
    415413        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
    416         size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    417414
    418415        int rc;
     
    450447        trans->size = data_buffer_len;
    451448
    452         rc = usb_iface->control_write(fun, target, max_packet_size,
     449        rc = usb_iface->control_write(fun, target,
    453450            setup_packet, setup_packet_len,
    454451            data_buffer, data_buffer_len,
     
    477474                .endpoint = DEV_IPC_GET_ARG2(*call)
    478475        };
    479         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    480476
    481477        int rc;
     
    515511        }
    516512
    517         rc = usb_iface->control_read(fun, target, max_packet_size,
     513        rc = usb_iface->control_read(fun, target,
    518514            setup_packet, setup_packet_len,
    519515            trans->buffer, trans->size,
     
    537533        }
    538534
    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,
     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,
    556563            transfer_type, direction, max_packet_size, interval);
    557564
  • uspace/lib/drv/include/usbhc_iface.h

    r5410c04 ra9d67aa  
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
    68  *   - argument #3 is max packet size of the endpoint
    6968 * - this call is immediately followed by IPC data read (async version)
    7069 * - the call is not answered until the device returns some data (or until
     
    169168        /** Register endpoint attributes at host controller.
    170169         * 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 (ADDR * 256 + EP)
    173          * - transfer type + direction (TYPE * 256 + DIR)
    174          * - maximum packet size
    175          * - interval (in milliseconds)
     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
    176178         * Answer:
    177179         * - EOK - reservation successful
     
    202204
    203205/** Out transfer processing function prototype. */
    204 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
     206typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t,
    205207    void *, size_t,
    206208    usbhc_iface_transfer_out_callback_t, void *);
     
    210212
    211213/** In transfer processing function prototype. */
    212 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
     214typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t,
    213215    void *, size_t,
    214216    usbhc_iface_transfer_in_callback_t, void *);
     
    222224        int (*release_address)(ddf_fun_t *, usb_address_t);
    223225
    224         int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     226        int (*register_endpoint)(ddf_fun_t *,
     227            usb_address_t, usb_speed_t, usb_endpoint_t,
    225228            usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    226229        int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     
    234237
    235238        int (*control_write)(ddf_fun_t *, usb_target_t,
    236             size_t,
    237239            void *, size_t, void *, size_t,
    238240            usbhc_iface_transfer_out_callback_t, void *);
    239241
    240242        int (*control_read)(ddf_fun_t *, usb_target_t,
    241             size_t,
    242243            void *, size_t, void *, size_t,
    243244            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/include/usb/devdrv.h

    r5410c04 ra9d67aa  
    169169    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
    170170
     171int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
     172int 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 *);
     175int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
     176
     177size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
     178
    171179#endif
    172180/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r5410c04 ra9d67aa  
    7373void usb_device_keeper_add_ep(
    7474    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
     75void usb_device_keeper_del_ep(
     76    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
    7577
    7678void usb_device_keeper_reserve_default_address(
  • uspace/lib/usb/include/usb/pipes.h

    r5410c04 ra9d67aa  
    153153int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    154154    size_t, uint8_t *, size_t, usb_device_connection_t *);
     155int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
     156    unsigned int, usb_hc_connection_t *);
    155157int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
    156158int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
  • uspace/lib/usb/include/usb/usb.h

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

    r5410c04 ra9d67aa  
    7272}
    7373
    74 /** Log out of memory error on given device.
    75  *
    76  * @param dev Device causing the trouble.
    77  */
    78 static 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 
    8474/** Count number of pipes the driver expects.
    8575 *
     
    10898 */
    10999static int initialize_other_pipes(usb_endpoint_description_t **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,
     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,
    146106            dev->descriptors.configuration, dev->descriptors.configuration_size,
    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);
     107            dev->interface_no, alternate_setting,
     108            &pipes, &pipes_count);
     109
    157110        if (rc != EOK) {
    158111                usb_log_error(
    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;
     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;
    187119
    188120        return EOK;
    189 
    190 rollback:
    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;
    199121}
    200122
     
    249171        }
    250172
    251         /* Get the device descriptor. */
    252         rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
    253             &dev->descriptors.device);
    254         if (rc != EOK) {
    255                 usb_pipe_end_long_transfer(&dev->ctrl_pipe);
    256                 usb_log_error("Failed to retrieve device descriptor: %s.\n",
    257                     str_error(rc));
    258                 return rc;
    259         }
    260 
    261         /* Get the full configuration descriptor. */
    262         rc = usb_request_get_full_configuration_descriptor_alloc(
    263             &dev->ctrl_pipe, 0, (void **) &dev->descriptors.configuration,
    264             &dev->descriptors.configuration_size);
    265         if (rc != EOK) {
    266                 usb_pipe_end_long_transfer(&dev->ctrl_pipe);
    267                 usb_log_error("Failed retrieving configuration descriptor: %s. %s\n",
     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",
    268179                    dev->ddf_dev->name, str_error(rc));
    269180                return rc;
    270181        }
    271182
     183
    272184        if (driver->endpoints != NULL) {
    273                 rc = initialize_other_pipes(driver->endpoints, dev);
     185                rc = initialize_other_pipes(driver->endpoints, dev, 0);
    274186        }
    275187
     
    293205 * @return Number of alternate interfaces for @p interface_no interface.
    294206 */
    295 static size_t count_alternate_interfaces(uint8_t *config_descr,
    296     size_t config_descr_size, int interface_no)
     207size_t usb_interface_count_alternates(uint8_t *config_descr,
     208    size_t config_descr_size, uint8_t interface_no)
    297209{
    298210        assert(config_descr != NULL);
     211        assert(config_descr_size > 0);
     212
    299213        usb_dp_parser_t dp_parser = {
    300214                .nesting = usb_dp_standard_descriptor_nesting
     
    345259
    346260        alternates->alternative_count
    347             = count_alternate_interfaces(dev->descriptors.configuration,
     261            = usb_interface_count_alternates(dev->descriptors.configuration,
    348262            dev->descriptors.configuration_size, dev->interface_no);
    349263
     
    459373static int destroy_current_pipes(usb_device_t *dev)
    460374{
    461         size_t i;
    462         int rc;
    463 
    464         /* TODO: this shall be done under some device mutex. */
    465 
    466         /* First check that no session is opened. */
    467         for (i = 0; i < dev->pipes_count; i++) {
    468                 if (usb_pipe_is_session_started(dev->pipes[i].pipe)) {
    469                         return EBUSY;
    470                 }
    471         }
    472 
    473         /* Prepare connection to HC. */
    474         usb_hc_connection_t hc_conn;
    475         rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
    476         if (rc != EOK) {
    477                 return rc;
    478         }
    479         rc = usb_hc_connection_open(&hc_conn);
    480         if (rc != EOK) {
    481                 return rc;
    482         }
    483 
    484         /* Destroy the pipes. */
    485         for (i = 0; i < dev->pipes_count; i++) {
    486                 usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn);
    487                 free(dev->pipes[i].pipe);
    488         }
    489 
    490         usb_hc_connection_close(&hc_conn);
    491 
    492         free(dev->pipes);
     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
    493381        dev->pipes = NULL;
    494382        dev->pipes_count = 0;
     
    537425
    538426        /* Create new pipes. */
    539         rc = initialize_other_pipes(endpoints, dev);
     427        rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
    540428
    541429        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 */
     438int 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 */
     485int 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         */
     574rollback_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         */
     588rollback_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 */
     605int 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;
    542641}
    543642
  • uspace/lib/usb/src/host/device_keeper.c

    r5410c04 ra9d67aa  
    5656                instance->devices[i].control_used = 0;
    5757                instance->devices[i].handle = 0;
     58                instance->devices[i].speed = USB_SPEED_MAX;
    5859                list_initialize(&instance->devices[i].endpoints);
    5960        }
     61        // TODO: is this hack enough?
     62        // (it is needed to allow smooth registration at default address)
     63        instance->devices[0].occupied = true;
    6064}
    6165/*----------------------------------------------------------------------------*/
     
    6771        assert(instance->devices[address].occupied);
    6872        list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
     73        fibril_mutex_unlock(&instance->guard);
     74}
     75/*----------------------------------------------------------------------------*/
     76void 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);
    6984        fibril_mutex_unlock(&instance->guard);
    7085}
  • uspace/lib/usb/src/hub.c

    r5410c04 ra9d67aa  
    4040#include <errno.h>
    4141#include <assert.h>
     42#include <usb/debug.h>
    4243
    4344/** Check that HC connection is alright.
     
    5556
    5657/** Tell host controller to reserve default address.
     58 * @deprecated
    5759 *
    5860 * @param connection Opened connection to host controller.
     
    6567        CHECK_CONNECTION(connection);
    6668
     69        usb_log_warning("usb_hc_reserve_default_address() considered obsolete");
     70
    6771        return async_req_2_0(connection->hc_phone,
    6872            DEV_IFACE_ID(USBHC_DEV_IFACE),
     
    7175
    7276/** Tell host controller to release default address.
     77 * @deprecated
    7378 *
    7479 * @param connection Opened connection to host controller.
     
    7883{
    7984        CHECK_CONNECTION(connection);
     85
     86        usb_log_warning("usb_hc_release_default_address() considered obsolete");
    8087
    8188        return async_req_1_0(connection->hc_phone,
     
    235242        }
    236243
    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.
     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.)
    258249         */
    259250        usb_device_connection_t dev_conn;
     
    262253        if (rc != EOK) {
    263254                rc = ENOTCONN;
    264                 goto leave_release_default_address;
     255                goto leave_release_free_address;
    265256        }
    266257
     
    270261        if (rc != EOK) {
    271262                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) {
    272281                goto leave_release_default_address;
    273282        }
    274283
    275         /* Before sending any traffic, we need to register this
    276          * endpoint.
     284        rc = usb_pipe_probe_default_control(&ctrl_pipe);
     285        if (rc != EOK) {
     286                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.
     299         */
     300        unregister_control_endpoint_on_default_address(&hc_conn);
     301
     302        /*
     303         * Time to register the new endpoint.
    277304         */
    278305        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    279306        if (rc != EOK) {
    280                 rc = EREFUSED;
    281                 goto leave_release_default_address;
    282         }
    283         rc = usb_pipe_probe_default_control(&ctrl_pipe);
    284         if (rc != EOK) {
    285                 rc = ENOTCONN;
    286                 goto leave_release_default_address;
    287         }
    288 
    289         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
    290         if (rc != EOK) {
    291                 rc = ESTALL;
    292                 goto leave_stop_session;
    293         }
    294 
    295         /*
    296          * Register the control endpoint for the new device.
    297          */
    298         rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    299         if (rc != EOK) {
    300                 rc = EREFUSED;
    301                 goto leave_unregister_endpoint;
    302         }
    303 
    304         /*
    305          * Release the original endpoint.
    306          */
    307         unregister_control_endpoint_on_default_address(&hc_conn);
    308 
    309         /*
    310          * Once the address is changed, we can return the default address.
    311          */
    312         usb_hc_release_default_address(&hc_conn);
    313 
     307                goto leave_release_free_address;
     308        }
    314309
    315310        /*
     
    326321        }
    327322
    328 
    329 
    330323        /*
    331324         * And now inform the host controller about the handle.
     
    359352         * Completely ignoring errors here.
    360353         */
    361 
    362 leave_stop_session:
    363         usb_pipe_end_session(&ctrl_pipe);
    364 
    365 leave_unregister_endpoint:
     354leave_release_default_address:
    366355        usb_pipe_unregister(&ctrl_pipe, &hc_conn);
    367 
    368 leave_release_default_address:
    369         usb_hc_release_default_address(&hc_conn);
    370356
    371357leave_release_free_address:
  • uspace/lib/usb/src/pipesinit.c

    r5410c04 ra9d67aa  
    459459    usb_hc_connection_t *hc_connection)
    460460{
     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 */
     478int 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{
    461482        assert(pipe);
    462483        assert(hc_connection);
     
    466487        }
    467488
    468 #define _PACK(high, low) ((high) * 256 + (low))
    469 
    470         return async_req_5_0(hc_connection->hc_phone,
     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,
    471493            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
    472             _PACK(pipe->wire->address, pipe->endpoint_no),
    473             _PACK(pipe->transfer_type, pipe->direction),
    474             pipe->max_packet_size, interval);
    475 
    476 #undef _PACK
     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
    477500}
    478501
  • uspace/lib/usb/src/pipesio.c

    r5410c04 ra9d67aa  
    8585         * Make call identifying target USB device and type of transfer.
    8686         */
    87         aid_t opening_request = async_send_4(pipe->hc_phone,
     87        aid_t opening_request = async_send_3(pipe->hc_phone,
    8888            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    8989            pipe->wire->address, pipe->endpoint_no,
    90             pipe->max_packet_size,
    9190            NULL);
    9291        if (opening_request == 0) {
     
    232231         * Make call identifying target USB device and type of transfer.
    233232         */
    234         aid_t opening_request = async_send_4(pipe->hc_phone,
     233        aid_t opening_request = async_send_3(pipe->hc_phone,
    235234            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    236235            pipe->wire->address, pipe->endpoint_no,
    237             pipe->max_packet_size,
    238236            NULL);
    239237        if (opening_request == 0) {
     
    331329         * Make call identifying target USB device and control transfer type.
    332330         */
    333         aid_t opening_request = async_send_4(pipe->hc_phone,
     331        aid_t opening_request = async_send_3(pipe->hc_phone,
    334332            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
    335333            pipe->wire->address, pipe->endpoint_no,
    336             pipe->max_packet_size,
    337334            NULL);
    338335        if (opening_request == 0) {
     
    473470         * Make call identifying target USB device and control transfer type.
    474471         */
    475         aid_t opening_request = async_send_5(pipe->hc_phone,
     472        aid_t opening_request = async_send_4(pipe->hc_phone,
    476473            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
    477474            pipe->wire->address, pipe->endpoint_no,
    478475            data_buffer_size,
    479             pipe->max_packet_size,
    480476            NULL);
    481477        if (opening_request == 0) {
Note: See TracChangeset for help on using the changeset viewer.