Changeset b4b534ac in mainline for uspace/lib


Ignore:
Timestamp:
2016-07-22T08:24:47Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jan.vesely/helenos/usb

Location:
uspace/lib
Files:
7 added
8 deleted
53 edited
6 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/l18n/langs.c

    r5b18137 rb4b534ac  
    6666                case L18N_WIN_LOCALE_ZULU:
    6767                        return "Zulu";
     68                default:
     69                        break;
    6870        }
    6971
  • uspace/lib/c/include/adt/list.h

    r5b18137 rb4b534ac  
    133133
    134134/** Returns true if the link is definitely part of a list. False if not sure. */
    135 static inline bool link_in_use(link_t *link)
     135static inline bool link_in_use(const link_t *link)
    136136{
    137137        return link->prev != NULL && link->next != NULL;
     
    263263 *
    264264 */
    265 static inline link_t *list_last(list_t *list)
     265static inline link_t *list_last(const list_t *list)
    266266{
    267267        return (list->head.prev == &list->head) ? NULL : list->head.prev;
     
    276276 *
    277277 */
    278 static inline link_t *list_next(link_t *link, const list_t *list)
     278static inline link_t *list_next(const link_t *link, const list_t *list)
    279279{
    280280        return (link->next == &list->head) ? NULL : link->next;
     
    289289 *
    290290 */
    291 static inline link_t *list_prev(link_t *link, const list_t *list)
     291static inline link_t *list_prev(const link_t *link, const list_t *list)
    292292{
    293293        return (link->prev == &list->head) ? NULL : link->prev;
     
    357357 *
    358358 */
    359 static inline link_t *list_nth(list_t *list, unsigned long n)
     359static inline link_t *list_nth(const list_t *list, unsigned long n)
    360360{
    361361        unsigned long cnt = 0;
  • uspace/lib/c/include/l18n/langs.h

    r5b18137 rb4b534ac  
    5454        L18N_WIN_LOCALE_SPANISH_TRADITIONAL = 0x040A,
    5555        /* ... */
    56         L18N_WIN_LOCALE_ZULU = 0x0435
     56        L18N_WIN_LOCALE_ZULU = 0x0435,
     57        L18N_WIN_LOCALE_MAX = 0xFFFF
    5758} l18_win_locales_t;
    5859
  • uspace/lib/c/include/macros.h

    r5b18137 rb4b534ac  
    6969#define PADD8 _padd(8, __LINE__)
    7070
     71#define STATIC_ASSERT(cond) int sassert[(cond) ? 1 : -1]
     72
    7173/** @}
    7274 */
  • uspace/lib/drv/generic/driver.c

    r5b18137 rb4b534ac  
    786786        assert(fun->bound == false);
    787787        assert(fun->name != NULL);
     788        assert(fun->dev != NULL);
    788789       
    789790        add_to_functions_list(fun);
     
    890891
    891892/** Set function ops. */
    892 void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
     893void ddf_fun_set_ops(ddf_fun_t *fun, const ddf_dev_ops_t *dev_ops)
    893894{
    894895        assert(fun->conn_handler == NULL);
  • uspace/lib/drv/generic/private/driver.h

    r5b18137 rb4b534ac  
    9393       
    9494        /** Implementation of operations provided by this function */
    95         ddf_dev_ops_t *ops;
     95        const ddf_dev_ops_t *ops;
    9696       
    9797        /** Connection handler or @c NULL to use the DDF default handler. */
  • uspace/lib/drv/generic/remote_usb.c

    r5b18137 rb4b534ac  
    3535
    3636#include <async.h>
     37#include <macros.h>
    3738#include <errno.h>
    38 #include <macros.h>
     39#include <devman.h>
    3940
    4041#include "usb_iface.h"
    4142#include "ddf/driver.h"
    4243
     44
     45usb_dev_session_t *usb_dev_connect(devman_handle_t handle)
     46{
     47        return devman_device_connect(handle, IPC_FLAG_BLOCKING);
     48}
     49
     50usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *dev)
     51{
     52        return devman_parent_device_connect(ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
     53}
     54
     55void usb_dev_disconnect(usb_dev_session_t *sess)
     56{
     57        if (sess)
     58                async_hangup(sess);
     59}
     60
    4361typedef enum {
    44         IPC_M_USB_GET_MY_ADDRESS,
    4562        IPC_M_USB_GET_MY_INTERFACE,
    46         IPC_M_USB_GET_HOST_CONTROLLER_HANDLE,
     63        IPC_M_USB_GET_MY_DEVICE_HANDLE,
     64        IPC_M_USB_RESERVE_DEFAULT_ADDRESS,
     65        IPC_M_USB_RELEASE_DEFAULT_ADDRESS,
     66        IPC_M_USB_DEVICE_ENUMERATE,
     67        IPC_M_USB_DEVICE_REMOVE,
     68        IPC_M_USB_REGISTER_ENDPOINT,
     69        IPC_M_USB_UNREGISTER_ENDPOINT,
     70        IPC_M_USB_READ,
     71        IPC_M_USB_WRITE,
    4772} usb_iface_funcs_t;
    48 
    49 /** Tell USB address assigned to device.
    50  * @param exch Vaid IPC exchange
    51  * @param address Pointer to address storage place.
    52  * @return Error code.
    53  *
    54  * Exch param is an open communication to device implementing usb_iface.
    55  */
    56 int usb_get_my_address(async_exch_t *exch, usb_address_t *address)
    57 {
    58         if (!exch)
    59                 return EBADMEM;
    60         sysarg_t addr;
    61         const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    62             IPC_M_USB_GET_MY_ADDRESS, &addr);
    63 
    64         if (ret == EOK && address != NULL)
    65                 *address = (usb_address_t) addr;
    66         return ret;
    67 }
    6873
    6974/** Tell interface number given device can use.
     
    8590}
    8691
    87 /** Tell devman handle of device host controller.
     92/** Tell devman handle of the usb device function.
    8893 * @param[in] exch IPC communication exchange
    89  * @param[out] hc_handle devman handle of the HC used by the target device.
     94 * @param[out] handle devman handle of the HC used by the target device.
    9095 * @return Error code.
    9196 */
    92 int usb_get_hc_handle(async_exch_t *exch, devman_handle_t *hc_handle)
    93 {
    94         if (!exch)
    95                 return EBADMEM;
    96         devman_handle_t h;
     97int usb_get_my_device_handle(async_exch_t *exch, devman_handle_t *handle)
     98{
     99        devman_handle_t h = 0;
    97100        const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    98             IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
    99         if (ret == EOK && hc_handle)
    100                 *hc_handle = (devman_handle_t)h;
     101            IPC_M_USB_GET_MY_DEVICE_HANDLE, &h);
     102        if (ret == EOK && handle)
     103                *handle = (devman_handle_t)h;
    101104        return ret;
    102105}
    103106
    104 
    105 static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     107/** Reserve default USB address.
     108 * @param[in] exch IPC communication exchange
     109 * @param[in] speed Communication speed of the newly attached device
     110 * @return Error code.
     111 */
     112int usb_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
     113{
     114        if (!exch)
     115                return EBADMEM;
     116        return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     117            IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
     118}
     119
     120/** Release default USB address.
     121 * @param[in] exch IPC communication exchange
     122 * @return Error code.
     123 */
     124int usb_release_default_address(async_exch_t *exch)
     125{
     126        if (!exch)
     127                return EBADMEM;
     128        return async_req_1_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     129            IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
     130}
     131
     132/** Trigger USB device enumeration
     133 * @param[in] exch IPC communication exchange
     134 * @param[out] handle Identifier of the newly added device (if successful)
     135 * @return Error code.
     136 */
     137int usb_device_enumerate(async_exch_t *exch, unsigned port)
     138{
     139        if (!exch)
     140                return EBADMEM;
     141        const int ret = async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     142            IPC_M_USB_DEVICE_ENUMERATE, port);
     143        return ret;
     144}
     145
     146/** Trigger USB device enumeration
     147 * @param[in] exch IPC communication exchange
     148 * @param[in] handle Identifier of the device
     149 * @return Error code.
     150 */
     151int usb_device_remove(async_exch_t *exch, unsigned port)
     152{
     153        if (!exch)
     154                return EBADMEM;
     155        return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     156            IPC_M_USB_DEVICE_REMOVE, port);
     157}
     158
     159int static_assert[sizeof(sysarg_t) >= 4 ? 1 : -1];
     160typedef union {
     161        uint8_t arr[sizeof(sysarg_t)];
     162        sysarg_t arg;
     163} pack8_t;
     164
     165int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
     166    usb_transfer_type_t type, usb_direction_t direction,
     167    size_t mps, unsigned packets, unsigned interval)
     168{
     169        if (!exch)
     170                return EBADMEM;
     171        pack8_t pack;
     172        pack.arr[0] = type;
     173        pack.arr[1] = direction;
     174        pack.arr[2] = interval;
     175        pack.arr[3] = packets;
     176
     177        return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     178            IPC_M_USB_REGISTER_ENDPOINT, endpoint, pack.arg, mps);
     179
     180}
     181
     182int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
     183    usb_direction_t direction)
     184{
     185        if (!exch)
     186                return EBADMEM;
     187        return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     188            IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction);
     189}
     190
     191int usb_read(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
     192    void *data, size_t size, size_t *rec_size)
     193{
     194        if (!exch)
     195                return EBADMEM;
     196
     197        if (size == 0 && setup == 0)
     198                return EOK;
     199
     200        /* Make call identifying target USB device and type of transfer. */
     201        aid_t opening_request = async_send_4(exch,
     202            DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_READ, endpoint,
     203            (setup & UINT32_MAX), (setup >> 32), NULL);
     204
     205        if (opening_request == 0) {
     206                return ENOMEM;
     207        }
     208
     209        /* Retrieve the data. */
     210        ipc_call_t data_request_call;
     211        aid_t data_request =
     212            async_data_read(exch, data, size, &data_request_call);
     213
     214        if (data_request == 0) {
     215                // FIXME: How to let the other side know that we want to abort?
     216                async_forget(opening_request);
     217                return ENOMEM;
     218        }
     219
     220        /* Wait for the answer. */
     221        sysarg_t data_request_rc;
     222        sysarg_t opening_request_rc;
     223        async_wait_for(data_request, &data_request_rc);
     224        async_wait_for(opening_request, &opening_request_rc);
     225
     226        if (data_request_rc != EOK) {
     227                /* Prefer the return code of the opening request. */
     228                if (opening_request_rc != EOK) {
     229                        return (int) opening_request_rc;
     230                } else {
     231                        return (int) data_request_rc;
     232                }
     233        }
     234        if (opening_request_rc != EOK) {
     235                return (int) opening_request_rc;
     236        }
     237
     238        *rec_size = IPC_GET_ARG2(data_request_call);
     239        return EOK;
     240}
     241
     242int usb_write(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
     243    const void *data, size_t size)
     244{
     245        if (!exch)
     246                return EBADMEM;
     247
     248        if (size == 0 && setup == 0)
     249                return EOK;
     250
     251        aid_t opening_request = async_send_5(exch,
     252            DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_WRITE, endpoint, size,
     253            (setup & UINT32_MAX), (setup >> 32), NULL);
     254
     255        if (opening_request == 0) {
     256                return ENOMEM;
     257        }
     258
     259        /* Send the data if any. */
     260        if (size > 0) {
     261                const int ret = async_data_write_start(exch, data, size);
     262                if (ret != EOK) {
     263                        async_forget(opening_request);
     264                        return ret;
     265                }
     266        }
     267
     268        /* Wait for the answer. */
     269        sysarg_t opening_request_rc;
     270        async_wait_for(opening_request, &opening_request_rc);
     271
     272        return (int) opening_request_rc;
     273}
     274
    106275static void remote_usb_get_my_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    107 static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     276static void remote_usb_get_my_device_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     277static void remote_usb_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     278static void remote_usb_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     279static void remote_usb_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     280static void remote_usb_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     281static void remote_usb_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     282static void remote_usb_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     283static void remote_usb_read(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
     284static void remote_usb_write(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
    108285
    109286/** Remote USB interface operations. */
    110287static const remote_iface_func_ptr_t remote_usb_iface_ops [] = {
    111         [IPC_M_USB_GET_MY_ADDRESS] = remote_usb_get_my_address,
    112288        [IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
    113         [IPC_M_USB_GET_HOST_CONTROLLER_HANDLE] = remote_usb_get_hc_handle,
     289        [IPC_M_USB_GET_MY_DEVICE_HANDLE] = remote_usb_get_my_device_handle,
     290        [IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usb_reserve_default_address,
     291        [IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usb_release_default_address,
     292        [IPC_M_USB_DEVICE_ENUMERATE] = remote_usb_device_enumerate,
     293        [IPC_M_USB_DEVICE_REMOVE] = remote_usb_device_remove,
     294        [IPC_M_USB_REGISTER_ENDPOINT] = remote_usb_register_endpoint,
     295        [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usb_unregister_endpoint,
     296        [IPC_M_USB_READ] = remote_usb_read,
     297        [IPC_M_USB_WRITE] = remote_usb_write,
    114298};
    115299
     
    118302const remote_iface_t remote_usb_iface = {
    119303        .method_count = ARRAY_SIZE(remote_usb_iface_ops),
    120         .methods = remote_usb_iface_ops
     304        .methods = remote_usb_iface_ops,
    121305};
    122 
    123 
    124 void remote_usb_get_my_address(ddf_fun_t *fun, void *iface,
    125     ipc_callid_t callid, ipc_call_t *call)
    126 {
    127         const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    128 
    129         if (usb_iface->get_my_address == NULL) {
    130                 async_answer_0(callid, ENOTSUP);
    131                 return;
    132         }
    133 
    134         usb_address_t address;
    135         const int ret = usb_iface->get_my_address(fun, &address);
    136         if (ret != EOK) {
    137                 async_answer_0(callid, ret);
    138         } else {
    139                 async_answer_1(callid, EOK, address);
    140         }
    141 }
    142306
    143307void remote_usb_get_my_interface(ddf_fun_t *fun, void *iface,
     
    160324}
    161325
    162 void remote_usb_get_hc_handle(ddf_fun_t *fun, void *iface,
     326void remote_usb_get_my_device_handle(ddf_fun_t *fun, void *iface,
    163327    ipc_callid_t callid, ipc_call_t *call)
    164328{
    165329        const usb_iface_t *usb_iface = (usb_iface_t *) iface;
    166330
    167         if (usb_iface->get_hc_handle == NULL) {
     331        if (usb_iface->get_my_device_handle == NULL) {
    168332                async_answer_0(callid, ENOTSUP);
    169333                return;
     
    171335
    172336        devman_handle_t handle;
    173         const int ret = usb_iface->get_hc_handle(fun, &handle);
     337        const int ret = usb_iface->get_my_device_handle(fun, &handle);
    174338        if (ret != EOK) {
    175339                async_answer_0(callid, ret);
     
    178342        async_answer_1(callid, EOK, (sysarg_t) handle);
    179343}
     344
     345void remote_usb_reserve_default_address(ddf_fun_t *fun, void *iface,
     346    ipc_callid_t callid, ipc_call_t *call)
     347{
     348        const usb_iface_t *usb_iface = (usb_iface_t *) iface;
     349
     350        if (usb_iface->reserve_default_address == NULL) {
     351                async_answer_0(callid, ENOTSUP);
     352                return;
     353        }
     354
     355        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     356        const int ret = usb_iface->reserve_default_address(fun, speed);
     357        async_answer_0(callid, ret);
     358}
     359
     360void remote_usb_release_default_address(ddf_fun_t *fun, void *iface,
     361    ipc_callid_t callid, ipc_call_t *call)
     362{
     363        const usb_iface_t *usb_iface = (usb_iface_t *) iface;
     364
     365        if (usb_iface->release_default_address == NULL) {
     366                async_answer_0(callid, ENOTSUP);
     367                return;
     368        }
     369
     370        const int ret = usb_iface->release_default_address(fun);
     371        async_answer_0(callid, ret);
     372}
     373
     374static void remote_usb_device_enumerate(ddf_fun_t *fun, void *iface,
     375    ipc_callid_t callid, ipc_call_t *call)
     376{
     377        const usb_iface_t *usb_iface = (usb_iface_t *) iface;
     378
     379        if (usb_iface->device_enumerate == NULL) {
     380                async_answer_0(callid, ENOTSUP);
     381                return;
     382        }
     383
     384        const unsigned port = DEV_IPC_GET_ARG1(*call);
     385        const int ret = usb_iface->device_enumerate(fun, port);
     386        async_answer_0(callid, ret);
     387}
     388
     389static void remote_usb_device_remove(ddf_fun_t *fun, void *iface,
     390    ipc_callid_t callid, ipc_call_t *call)
     391{
     392        const usb_iface_t *usb_iface = (usb_iface_t *) iface;
     393
     394        if (usb_iface->device_remove == NULL) {
     395                async_answer_0(callid, ENOTSUP);
     396                return;
     397        }
     398
     399        const unsigned port = DEV_IPC_GET_ARG1(*call);
     400        const int ret = usb_iface->device_remove(fun, port);
     401        async_answer_0(callid, ret);
     402}
     403
     404static void remote_usb_register_endpoint(ddf_fun_t *fun, void *iface,
     405    ipc_callid_t callid, ipc_call_t *call)
     406{
     407        usb_iface_t *usb_iface = (usb_iface_t *) iface;
     408
     409        if (!usb_iface->register_endpoint) {
     410                async_answer_0(callid, ENOTSUP);
     411                return;
     412        }
     413
     414        const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call);
     415        const pack8_t pack = { .arg = DEV_IPC_GET_ARG2(*call)};
     416        const size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     417
     418        const usb_transfer_type_t transfer_type = pack.arr[0];
     419        const usb_direction_t direction = pack.arr[1];
     420        unsigned packets = pack.arr[2];
     421        unsigned interval = pack.arr[3];
     422
     423        const int ret = usb_iface->register_endpoint(fun, endpoint,
     424            transfer_type, direction, max_packet_size, packets, interval);
     425
     426        async_answer_0(callid, ret);
     427}
     428
     429static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
     430    ipc_callid_t callid, ipc_call_t *call)
     431{
     432        usb_iface_t *usb_iface = (usb_iface_t *) iface;
     433
     434        if (!usb_iface->unregister_endpoint) {
     435                async_answer_0(callid, ENOTSUP);
     436                return;
     437        }
     438
     439        usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call);
     440        usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call);
     441
     442        int rc = usb_iface->unregister_endpoint(fun, endpoint, direction);
     443
     444        async_answer_0(callid, rc);
     445}
     446
     447typedef struct {
     448        ipc_callid_t caller;
     449        ipc_callid_t data_caller;
     450        void *buffer;
     451} async_transaction_t;
     452
     453static void async_transaction_destroy(async_transaction_t *trans)
     454{
     455        if (trans == NULL) {
     456                return;
     457        }
     458        if (trans->buffer != NULL) {
     459                free(trans->buffer);
     460        }
     461
     462        free(trans);
     463}
     464
     465static async_transaction_t *async_transaction_create(ipc_callid_t caller)
     466{
     467        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     468        if (trans == NULL) {
     469                return NULL;
     470        }
     471
     472        trans->caller = caller;
     473        trans->data_caller = 0;
     474        trans->buffer = NULL;
     475
     476        return trans;
     477}
     478
     479static void callback_out(int outcome, void *arg)
     480{
     481        async_transaction_t *trans = arg;
     482
     483        async_answer_0(trans->caller, outcome);
     484
     485        async_transaction_destroy(trans);
     486}
     487
     488static void callback_in(int outcome, size_t actual_size, void *arg)
     489{
     490        async_transaction_t *trans = (async_transaction_t *)arg;
     491
     492        if (outcome != EOK) {
     493                async_answer_0(trans->caller, outcome);
     494                if (trans->data_caller) {
     495                        async_answer_0(trans->data_caller, EINTR);
     496                }
     497                async_transaction_destroy(trans);
     498                return;
     499        }
     500
     501        if (trans->data_caller) {
     502                async_data_read_finalize(trans->data_caller,
     503                    trans->buffer, actual_size);
     504        }
     505
     506        async_answer_0(trans->caller, EOK);
     507
     508        async_transaction_destroy(trans);
     509}
     510
     511void remote_usb_read(
     512    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     513{
     514        assert(fun);
     515        assert(iface);
     516        assert(call);
     517
     518        const usb_iface_t *usb_iface = iface;
     519
     520        if (!usb_iface->read) {
     521                async_answer_0(callid, ENOTSUP);
     522                return;
     523        }
     524
     525        const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
     526        const uint64_t setup =
     527            ((uint64_t)DEV_IPC_GET_ARG2(*call)) |
     528            (((uint64_t)DEV_IPC_GET_ARG3(*call)) << 32);
     529
     530        async_transaction_t *trans = async_transaction_create(callid);
     531        if (trans == NULL) {
     532                async_answer_0(callid, ENOMEM);
     533                return;
     534        }
     535
     536        size_t size = 0;
     537        if (!async_data_read_receive(&trans->data_caller, &size)) {
     538                async_answer_0(callid, EPARTY);
     539                return;
     540        }
     541
     542        trans->buffer = malloc(size);
     543        if (trans->buffer == NULL) {
     544                async_answer_0(trans->data_caller, ENOMEM);
     545                async_answer_0(callid, ENOMEM);
     546                async_transaction_destroy(trans);
     547        }
     548
     549        const int rc = usb_iface->read(
     550            fun, ep, setup, trans->buffer, size, callback_in, trans);
     551
     552        if (rc != EOK) {
     553                async_answer_0(trans->data_caller, rc);
     554                async_answer_0(callid, rc);
     555                async_transaction_destroy(trans);
     556        }
     557}
     558
     559void remote_usb_write(
     560    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     561{
     562        assert(fun);
     563        assert(iface);
     564        assert(call);
     565
     566        const usb_iface_t *usb_iface = iface;
     567
     568        if (!usb_iface->write) {
     569                async_answer_0(callid, ENOTSUP);
     570                return;
     571        }
     572
     573        const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
     574        const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call);
     575        const uint64_t setup =
     576            ((uint64_t)DEV_IPC_GET_ARG3(*call)) |
     577            (((uint64_t)DEV_IPC_GET_ARG4(*call)) << 32);
     578
     579        async_transaction_t *trans = async_transaction_create(callid);
     580        if (trans == NULL) {
     581                async_answer_0(callid, ENOMEM);
     582                return;
     583        }
     584
     585        size_t size = 0;
     586        if (data_buffer_len > 0) {
     587                const int rc = async_data_write_accept(&trans->buffer, false,
     588                    1, data_buffer_len, 0, &size);
     589
     590                if (rc != EOK) {
     591                        async_answer_0(callid, rc);
     592                        async_transaction_destroy(trans);
     593                        return;
     594                }
     595        }
     596
     597        const int rc = usb_iface->write(
     598            fun, ep, setup, trans->buffer, size, callback_out, trans);
     599
     600        if (rc != EOK) {
     601                async_answer_0(callid, rc);
     602                async_transaction_destroy(trans);
     603        }
     604}
    180605/**
    181606 * @}
  • uspace/lib/drv/generic/remote_usbhc.c

    r5b18137 rb4b534ac  
    8585 */
    8686typedef enum {
    87         /** Asks for address assignment by host controller.
    88          * Answer:
    89          * - ELIMIT - host controller run out of address
    90          * - EOK - address assigned
    91          * Answer arguments:
    92          * - assigned address
    93          *
    94          * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
    95          */
    96         IPC_M_USBHC_REQUEST_ADDRESS,
    97 
    98         /** Bind USB address with devman handle.
    99          * Parameters:
    100          * - USB address
    101          * - devman handle
    102          * Answer:
    103          * - EOK - address binded
    104          * - ENOENT - address is not in use
    105          */
    106         IPC_M_USBHC_BIND_ADDRESS,
    107 
    108         /** Get handle binded with given USB address.
    109          * Parameters
    110          * - USB address
    111          * Answer:
    112          * - EOK - address binded, first parameter is the devman handle
    113          * - ENOENT - address is not in use at the moment
    114          */
    115         IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
    116 
    117         /** Release address in use.
    118          * Arguments:
    119          * - address to be released
    120          * Answer:
    121          * - ENOENT - address not in use
    122          * - EPERM - trying to release default USB address
    123          */
    124         IPC_M_USBHC_RELEASE_ADDRESS,
    125 
    126         /** Register endpoint attributes at host controller.
    127          * This is used to reserve portion of USB bandwidth.
    128          * When speed is invalid, speed of the device is used.
    129          * Parameters:
    130          * - USB address + endpoint number
    131          *   - packed as ADDR << 16 + EP
    132          * - speed + transfer type + direction
    133          *   - packed as ( SPEED << 8 + TYPE ) << 8 + DIR
    134          * - maximum packet size + interval (in milliseconds)
    135          *   - packed as MPS << 16 + INT
    136          * Answer:
    137          * - EOK - reservation successful
    138          * - ELIMIT - not enough bandwidth to satisfy the request
    139          */
    140         IPC_M_USBHC_REGISTER_ENDPOINT,
    141 
    142         /** Revert endpoint registration.
    143          * Parameters:
    144          * - USB address
    145          * - endpoint number
    146          * - data direction
    147          * Answer:
    148          * - EOK - endpoint unregistered
    149          * - ENOENT - unknown endpoint
    150          */
    151         IPC_M_USBHC_UNREGISTER_ENDPOINT,
    152 
    15387        /** Get data from device.
    15488         * See explanation at usb_iface_funcs_t (IN transaction).
     
    16195        IPC_M_USBHC_WRITE,
    16296} usbhc_iface_funcs_t;
    163 
    164 int usbhc_request_address(async_exch_t *exch, usb_address_t *address,
    165     bool strict, usb_speed_t speed)
    166 {
    167         if (!exch || !address)
    168                 return EBADMEM;
    169         sysarg_t new_address;
    170         const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    171             IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address);
    172         if (ret == EOK)
    173                 *address = (usb_address_t)new_address;
    174         return ret;
    175 }
    176 
    177 int usbhc_bind_address(async_exch_t *exch, usb_address_t address,
    178     devman_handle_t handle)
    179 {
    180         if (!exch)
    181                 return EBADMEM;
    182         return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    183             IPC_M_USBHC_BIND_ADDRESS, address, handle);
    184 }
    185 
    186 int usbhc_get_handle(async_exch_t *exch, usb_address_t address,
    187     devman_handle_t *handle)
    188 {
    189         if (!exch)
    190                 return EBADMEM;
    191         sysarg_t h;
    192         const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    193             IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h);
    194         if (ret == EOK && handle)
    195                 *handle = (devman_handle_t)h;
    196         return ret;
    197 }
    198 
    199 int usbhc_release_address(async_exch_t *exch, usb_address_t address)
    200 {
    201         if (!exch)
    202                 return EBADMEM;
    203         return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    204             IPC_M_USBHC_RELEASE_ADDRESS, address);
    205 }
    206 
    207 int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address,
    208     usb_endpoint_t endpoint, usb_transfer_type_t type,
    209     usb_direction_t direction, size_t mps, unsigned interval)
    210 {
    211         if (!exch)
    212                 return EBADMEM;
    213         const usb_target_t target =
    214             {{ .address = address, .endpoint = endpoint }};
    215 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
    216 
    217         return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    218             IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
    219             _PACK2(type, direction), _PACK2(mps, interval));
    220 
    221 #undef _PACK2
    222 }
    223 
    224 int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address,
    225     usb_endpoint_t endpoint, usb_direction_t direction)
    226 {
    227         if (!exch)
    228                 return EBADMEM;
    229         return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    230             IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction);
    231 }
    23297
    23398int usbhc_read(async_exch_t *exch, usb_address_t address,
     
    323188}
    324189
    325 
    326 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    327 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    328 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    329 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    330 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    331 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    332190static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    333191static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    334 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    335192
    336193/** Remote USB host controller interface operations. */
    337194static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
    338         [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
    339         [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
    340         [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,
    341         [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle,
    342 
    343         [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,
    344         [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint,
    345 
    346195        [IPC_M_USBHC_READ] = remote_usbhc_read,
    347196        [IPC_M_USBHC_WRITE] = remote_usbhc_write,
     
    386235}
    387236
    388 void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
    389     ipc_callid_t callid, ipc_call_t *call)
    390 {
    391         const usbhc_iface_t *usb_iface = iface;
    392 
    393         if (!usb_iface->request_address) {
    394                 async_answer_0(callid, ENOTSUP);
    395                 return;
    396         }
    397 
    398         usb_address_t address = DEV_IPC_GET_ARG1(*call);
    399         const bool strict = DEV_IPC_GET_ARG2(*call);
    400         const usb_speed_t speed = DEV_IPC_GET_ARG3(*call);
    401 
    402         const int rc = usb_iface->request_address(fun, &address, strict, speed);
    403         if (rc != EOK) {
    404                 async_answer_0(callid, rc);
    405         } else {
    406                 async_answer_1(callid, EOK, (sysarg_t) address);
    407         }
    408 }
    409 
    410 void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
    411     ipc_callid_t callid, ipc_call_t *call)
    412 {
    413         const usbhc_iface_t *usb_iface = iface;
    414 
    415         if (!usb_iface->bind_address) {
    416                 async_answer_0(callid, ENOTSUP);
    417                 return;
    418         }
    419 
    420         const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    421         const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
    422 
    423         const int ret = usb_iface->bind_address(fun, address, handle);
    424         async_answer_0(callid, ret);
    425 }
    426 
    427 void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface,
    428     ipc_callid_t callid, ipc_call_t *call)
    429 {
    430         const usbhc_iface_t *usb_iface = iface;
    431 
    432         if (!usb_iface->get_handle) {
    433                 async_answer_0(callid, ENOTSUP);
    434                 return;
    435         }
    436 
    437         const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    438         devman_handle_t handle;
    439         const int ret = usb_iface->get_handle(fun, address, &handle);
    440 
    441         if (ret == EOK) {
    442                 async_answer_1(callid, ret, handle);
    443         } else {
    444                 async_answer_0(callid, ret);
    445         }
    446 }
    447 
    448 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
    449     ipc_callid_t callid, ipc_call_t *call)
    450 {
    451         const usbhc_iface_t *usb_iface = iface;
    452 
    453         if (!usb_iface->release_address) {
    454                 async_answer_0(callid, ENOTSUP);
    455                 return;
    456         }
    457 
    458         const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    459 
    460         const int ret = usb_iface->release_address(fun, address);
    461         async_answer_0(callid, ret);
    462 }
    463 
    464 static void callback_out(ddf_fun_t *fun,
    465     int outcome, void *arg)
     237static void callback_out(int outcome, void *arg)
    466238{
    467239        async_transaction_t *trans = arg;
     
    472244}
    473245
    474 static void callback_in(ddf_fun_t *fun,
    475     int outcome, size_t actual_size, void *arg)
     246static void callback_in(int outcome, size_t actual_size, void *arg)
    476247{
    477248        async_transaction_t *trans = (async_transaction_t *)arg;
     
    496267}
    497268
    498 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,
    499     ipc_callid_t callid, ipc_call_t *call)
    500 {
    501         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    502 
    503         if (!usb_iface->register_endpoint) {
    504                 async_answer_0(callid, ENOTSUP);
    505                 return;
    506         }
    507 
    508 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
    509         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
    510 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
    511         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
    512 
    513         const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
    514 
    515         _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
    516         _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
    517 
    518         _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
    519         _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);
    520 
    521 #undef _INIT_FROM_HIGH_DATA2
    522 #undef _INIT_FROM_LOW_DATA2
    523 
    524         int rc = usb_iface->register_endpoint(fun, target.address,
    525             target.endpoint, transfer_type, direction, max_packet_size, interval);
    526 
    527         async_answer_0(callid, rc);
    528 }
    529 
    530 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,
    531     ipc_callid_t callid, ipc_call_t *call)
    532 {
    533         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    534 
    535         if (!usb_iface->unregister_endpoint) {
    536                 async_answer_0(callid, ENOTSUP);
    537                 return;
    538         }
    539 
    540         usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    541         usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);
    542         usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);
    543 
    544         int rc = usb_iface->unregister_endpoint(fun,
    545             address, endpoint, direction);
    546 
    547         async_answer_0(callid, rc);
    548 }
    549 
    550269void remote_usbhc_read(
    551270    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
  • uspace/lib/drv/include/ddf/driver.h

    r5b18137 rb4b534ac  
    132132extern int ddf_fun_offline(ddf_fun_t *);
    133133extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    134 extern void ddf_fun_set_ops(ddf_fun_t *, ddf_dev_ops_t *);
     134extern void ddf_fun_set_ops(ddf_fun_t *, const ddf_dev_ops_t *);
    135135extern void ddf_fun_set_conn_handler(ddf_fun_t *, async_port_handler_t);
    136136extern int ddf_fun_add_to_category(ddf_fun_t *, const char *);
  • uspace/lib/drv/include/usb_iface.h

    r5b18137 rb4b534ac  
    4242#include <usb/usb.h>
    4343
    44 int usb_get_my_address(async_exch_t *, usb_address_t *);
     44typedef async_sess_t usb_dev_session_t;
     45
     46usb_dev_session_t *usb_dev_connect(devman_handle_t);
     47usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *);
     48void usb_dev_disconnect(usb_dev_session_t *);
     49
    4550int usb_get_my_interface(async_exch_t *, int *);
    46 int usb_get_hc_handle(async_exch_t *, devman_handle_t *);
     51int usb_get_my_device_handle(async_exch_t *, devman_handle_t *);
     52
     53int usb_reserve_default_address(async_exch_t *, usb_speed_t);
     54int usb_release_default_address(async_exch_t *);
     55
     56int usb_device_enumerate(async_exch_t *, unsigned port);
     57int usb_device_remove(async_exch_t *, unsigned port);
     58
     59int usb_register_endpoint(async_exch_t *, usb_endpoint_t, usb_transfer_type_t,
     60    usb_direction_t, size_t, unsigned, unsigned);
     61int usb_unregister_endpoint(async_exch_t *, usb_endpoint_t, usb_direction_t);
     62int usb_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t, size_t *);
     63int usb_write(async_exch_t *, usb_endpoint_t, uint64_t, const void *, size_t);
     64
     65/** Callback for outgoing transfer. */
     66typedef void (*usb_iface_transfer_out_callback_t)(int, void *);
     67
     68/** Callback for incoming transfer. */
     69typedef void (*usb_iface_transfer_in_callback_t)(int, size_t, void *);
    4770
    4871/** USB device communication interface. */
    4972typedef struct {
    50         int (*get_my_address)(ddf_fun_t *, usb_address_t *);
    5173        int (*get_my_interface)(ddf_fun_t *, int *);
    52         int (*get_hc_handle)(ddf_fun_t *, devman_handle_t *);
     74        int (*get_my_device_handle)(ddf_fun_t *, devman_handle_t *);
     75
     76        int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
     77        int (*release_default_address)(ddf_fun_t *);
     78
     79        int (*device_enumerate)(ddf_fun_t *, unsigned);
     80        int (*device_remove)(ddf_fun_t *, unsigned);
     81
     82        int (*register_endpoint)(ddf_fun_t *, usb_endpoint_t,
     83            usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
     84        int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_t,
     85            usb_direction_t);
     86
     87        int (*read)(ddf_fun_t *, usb_endpoint_t, uint64_t, uint8_t *, size_t,
     88            usb_iface_transfer_in_callback_t, void *);
     89        int (*write)(ddf_fun_t *, usb_endpoint_t, uint64_t, const uint8_t *,
     90            size_t, usb_iface_transfer_out_callback_t, void *);
    5391} usb_iface_t;
    5492
  • uspace/lib/drv/include/usbhc_iface.h

    r5b18137 rb4b534ac  
    4444#include <stdbool.h>
    4545
    46 int usbhc_request_address(async_exch_t *, usb_address_t *, bool, usb_speed_t);
    47 int usbhc_bind_address(async_exch_t *, usb_address_t, devman_handle_t);
    48 int usbhc_get_handle(async_exch_t *, usb_address_t, devman_handle_t *);
    49 int usbhc_release_address(async_exch_t *, usb_address_t);
    50 int usbhc_register_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t,
    51     usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    52 int usbhc_unregister_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t,
    53     usb_direction_t);
    5446int usbhc_read(async_exch_t *, usb_address_t, usb_endpoint_t,
    5547    uint64_t, void *, size_t, size_t *);
     
    5850
    5951/** Callback for outgoing transfer. */
    60 typedef void (*usbhc_iface_transfer_out_callback_t)(ddf_fun_t *, int, void *);
     52typedef void (*usbhc_iface_transfer_out_callback_t)(int, void *);
    6153
    6254/** Callback for incoming transfer. */
    63 typedef void (*usbhc_iface_transfer_in_callback_t)(ddf_fun_t *,
    64     int, size_t, void *);
     55typedef void (*usbhc_iface_transfer_in_callback_t)(int, size_t, void *);
    6556
    6657/** USB host controller communication interface. */
    6758typedef struct {
    68         int (*request_address)(ddf_fun_t *, usb_address_t *, bool, usb_speed_t);
    69         int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t);
    70         int (*get_handle)(ddf_fun_t *, usb_address_t,
    71             devman_handle_t *);
    72         int (*release_address)(ddf_fun_t *, usb_address_t);
    73 
    74         int (*register_endpoint)(ddf_fun_t *,
    75             usb_address_t, usb_endpoint_t,
    76             usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    77         int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
    78             usb_direction_t);
    79 
    8059        int (*read)(ddf_fun_t *, usb_target_t, uint64_t, uint8_t *, size_t,
    8160            usbhc_iface_transfer_in_callback_t, void *);
    82 
    8361        int (*write)(ddf_fun_t *, usb_target_t, uint64_t, const uint8_t *,
    8462            size_t, usbhc_iface_transfer_out_callback_t, void *);
  • uspace/lib/scsi/include/scsi/spc.h

    r5b18137 rb4b534ac  
    4242/** SCSI command codes defined in SCSI-SPC */
    4343enum scsi_cmd_spc {
    44         SCSI_CMD_INQUIRY        = 0x12,
    45         SCSI_CMD_REQUEST_SENSE  = 0x03
     44        SCSI_CMD_TEST_UNIT_READY = 0x00,
     45        SCSI_CMD_REQUEST_SENSE   = 0x03,
     46        SCSI_CMD_INQUIRY         = 0x12,
    4647};
    4748
     
    220221extern const char *scsi_get_sense_key_str(unsigned);
    221222
     223/** SCSI Test Unit Ready command */
     224typedef struct {
     225        /** Operation code (SCSI_CMD_TEST_UNIT_READY) */
     226        uint8_t op_code;
     227        /** Reserved */
     228        uint32_t reserved;
     229        /* Control */
     230        uint8_t control;
     231} __attribute__((packed)) scsi_cdb_test_unit_ready_t;
     232
    222233#endif
    223234
  • uspace/lib/usb/Makefile

    r5b18137 rb4b534ac  
    3636SOURCES = \
    3737        src/class.c \
    38         src/ddfiface.c \
    3938        src/dev.c \
    4039        src/debug.c \
    4140        src/dump.c \
    42         src/hc.c \
    4341        src/usb.c
    4442
  • uspace/lib/usb/include/usb/classes/hub.h

    r5b18137 rb4b534ac  
    4343 */
    4444typedef enum {
     45        USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
     46        USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
    4547        USB_HUB_FEATURE_HUB_LOCAL_POWER = 0,
    4648        USB_HUB_FEATURE_HUB_OVER_CURRENT = 1,
    47         USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
    48         USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
    4949        USB_HUB_FEATURE_PORT_CONNECTION = 0,
    5050        USB_HUB_FEATURE_PORT_ENABLE = 1,
     
    5454        USB_HUB_FEATURE_PORT_POWER = 8,
    5555        USB_HUB_FEATURE_PORT_LOW_SPEED = 9,
     56        USB_HUB_FEATURE_PORT_HIGH_SPEED = 10,
    5657        USB_HUB_FEATURE_C_PORT_CONNECTION = 16,
    5758        USB_HUB_FEATURE_C_PORT_ENABLE = 17,
     
    5960        USB_HUB_FEATURE_C_PORT_OVER_CURRENT = 19,
    6061        USB_HUB_FEATURE_C_PORT_RESET = 20,
     62        USB_HUB_FEATURE_PORT_TEST = 21,
     63        USB_HUB_FEATURE_PORT_INDICATOR = 22
    6164        /* USB_HUB_FEATURE_ = , */
    6265} usb_hub_class_feature_t;
     
    6770        /** Descriptor length. */
    6871        uint8_t length;
     72
    6973        /** Descriptor type (0x29). */
    7074        uint8_t descriptor_type;
     75
    7176        /** Number of downstream ports. */
    7277        uint8_t port_count;
    73         /** Characteristics bitmask. */
     78
     79        /** Characteristics bitmask.
     80         *
     81         *  D1..D0: Logical Power Switching Mode
     82         *  00: Ganged power switching (all ports power at
     83         *  once)
     84         *  01: Individual port power switching
     85         *  1X: Reserved. Used only on 1.0 compliant hubs
     86         *  that implement no power switching.
     87         *  D2: Identifies a Compound Device
     88         *  0: Hub is not part of a compound device
     89         *  1: Hub is part of a compound device
     90         *  D4..D3: Over-current Protection Mode
     91         *  00: Global Over-current Protection. The hub
     92         *  reports over-current as a summation of all
     93         *  ports current draw, without a breakdown of
     94         *  individual port over-current status.
     95         *  01: Individual Port Over-current Protection. The
     96         *  hub reports over-current on a per-port basis.
     97         *  Each port has an over-current indicator.
     98         *  1X: No Over-current Protection. This option is
     99         *  allowed only for bus-powered hubs that do not
     100         *  implement over-current protection.
     101         *  D6..D5: TT think time
     102         *  00: At most 8 FS bit times
     103         *  01: At most 16 FS bit times
     104         *  10: At most 24 FS bit times
     105         *  11: At most 32 FS bit times
     106         *  D7: Port indicators
     107         *  0: Not supported
     108         *  1: Supported
     109         *  D15...D8: Reserved
     110         */
    74111        uint8_t characteristics;
    75 #define HUB_CHAR_POWER_PER_PORT_FLAG  (1 << 0)
    76 #define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1)
    77         /* Unused part of characteristics field */
     112#define HUB_CHAR_POWER_PER_PORT_FLAG    (1 << 0)
     113#define HUB_CHAR_NO_POWER_SWITCH_FLAG   (1 << 1)
     114#define HUB_CHAR_COMPOUND_DEVICE        (1 << 2)
     115#define HUB_CHAR_OC_PER_PORT_FLAG       (1 << 3)
     116#define HUB_CHAR_NO_OC_FLAG             (1 << 4)
     117#define HUB_CHAR_TT_THINK_16            (1 << 5)
     118#define HUB_CHAR_TT_THINK_8             (1 << 6)
     119#define HUB_CHAR_INDICATORS_FLAG        (1 << 7)
     120
     121        /** Unused part of characteristics field */
    78122        uint8_t characteristics_reserved;
    79         /** Time from power-on to stabilization of current on the port. */
     123
     124        /** Time from power-on to stabilization of current on the port.
     125         *
     126         *  Time (in 2ms intervals) from the time the power-on
     127         *  sequence begins on a port until power is good on that
     128         *  port. The USB System Software uses this value to
     129         *  determine how long to wait before accessing a
     130         *  powered-on port.
     131         */
    80132        uint8_t power_good_time;
    81         /** Maximum current requirements in mA. */
     133        /** Maximum current requirements in mA.
     134         *
     135         *  Maximum current requirements of the Hub Controller
     136         *  electronics in mA.
     137         */
    82138        uint8_t max_current;
    83139} __attribute__ ((packed)) usb_hub_descriptor_header_t;
    84140
    85 /**
    86  * @brief usb hub descriptor
    87  *
    88  * For more information see Universal Serial Bus Specification Revision 1.1
    89  * chapter 11.16.2
    90  */
    91 typedef struct usb_hub_descriptor_type {
    92     /** Number of bytes in this descriptor, including this byte */
    93     //uint8_t bDescLength;
    94 
    95     /** Descriptor Type, value: 29H for hub descriptor */
    96     //uint8_t bDescriptorType;
    97 
    98     /** Number of downstream ports that this hub supports */
    99     uint8_t port_count;
    100 
    101     /**
    102             D1...D0: Logical Power Switching Mode
    103             00: Ganged power switching (all ports power at
    104             once)
    105             01: Individual port power switching
    106             1X: Reserved. Used only on 1.0 compliant hubs
    107             that implement no power switching.
    108             D2: Identifies a Compound Device
    109             0: Hub is not part of a compound device
    110             1: Hub is part of a compound device
    111             D4...D3: Over-current Protection Mode
    112             00: Global Over-current Protection. The hub
    113             reports over-current as a summation of all
    114             ports current draw, without a breakdown of
    115             individual port over-current status.
    116             01: Individual Port Over-current Protection. The
    117             hub reports over-current on a per-port basis.
    118             Each port has an over-current indicator.
    119             1X: No Over-current Protection. This option is
    120             allowed only for bus-powered hubs that do not
    121             implement over-current protection.
    122             D15...D5:
    123             Reserved
    124      */
    125     uint16_t hub_characteristics;
    126 
    127     /**
    128             Time (in 2ms intervals) from the time the power-on
    129             sequence begins on a port until power is good on that
    130             port. The USB System Software uses this value to
    131             determine how long to wait before accessing a
    132             powered-on port.
    133      */
    134     uint8_t pwr_on_2_good_time;
    135 
    136     /**
    137             Maximum current requirements of the Hub Controller
    138             electronics in mA.
    139      */
    140     uint8_t current_requirement;
    141 
    142     /**
    143             Indicates if a port has a removable device attached.
    144             This field is reported on byte-granularity. Within a
    145             byte, if no port exists for a given location, the field
    146             representing the port characteristics returns 0.
    147             Bit value definition:
    148             0B - Device is removable
    149             1B - Device is non-removable
    150             This is a bitmap corresponding to the individual ports
    151             on the hub:
    152             Bit 0: Reserved for future use
    153             Bit 1: Port 1
    154             Bit 2: Port 2
    155             ....
    156             Bit n: Port n (implementation-dependent, up to a
    157             maximum of 255 ports).
    158      */
    159     uint8_t devices_removable[32];
    160 
    161     /**
    162             This field exists for reasons of compatibility with
    163             software written for 1.0 compliant devices. All bits in
    164             this field should be set to 1B. This field has one bit for
    165             each port on the hub with additional pad bits, if
    166             necessary, to make the number of bits in the field an
    167             integer multiple of 8.
    168      */
    169     //uint8_t * port_pwr_ctrl_mask;
    170 } usb_hub_descriptor_t;
    171 
    172 
     141/** One bit for the device and one bit for every port */
     142#define STATUS_BYTES(ports) ((1 + ports + 7) / 8)
    173143
    174144/**     @brief usb hub specific request types.
     
    204174    /** */
    205175    USB_HUB_REQUEST_CLEAR_FEATURE = 1,
    206     /** */
     176    /** USB 1.0 only */
    207177    USB_HUB_REQUEST_GET_STATE = 2,
    208178    /** */
     
    211181    USB_HUB_REQUEST_GET_DESCRIPTOR = 6,
    212182    /** */
    213     USB_HUB_REQUEST_SET_DESCRIPTOR = 7
     183    USB_HUB_REQUEST_SET_DESCRIPTOR = 7,
     184    /** */
     185    USB_HUB_REQUEST_CLEAR_TT_BUFFER = 8,
     186    /** */
     187    USB_HUB_REQUEST_RESET_TT = 9,
     188    /** */
     189    USB_HUB_GET_TT_STATE = 10,
     190    /** */
     191    USB_HUB_STOP_TT = 11,
    214192} usb_hub_request_t;
    215193
     
    218196 */
    219197/* 7 (basic size) + 2*32 (port bitmasks) */
    220 #define USB_HUB_MAX_DESCRIPTOR_SIZE 71
     198#define USB_HUB_MAX_DESCRIPTOR_SIZE (7 + 2 * 32)
    221199
    222200#endif
  • uspace/lib/usb/include/usb/classes/massstor.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_CLASS_MASSSTOR_H_
    3737
    38 #include <sys/types.h>
    39 
    4038/** USB mass storage subclasses. */
    4139typedef enum {
  • uspace/lib/usb/include/usb/debug.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_DEBUG_H_
    3737#include <stdio.h>
    38 #include <inttypes.h>
    39 #include <usb/usb.h>
     38#include <sys/types.h>
    4039#include <io/log.h>
    41 #include <assert.h>
     40
    4241
    4342void usb_dump_standard_descriptor(FILE *, const char *, const char *,
  • uspace/lib/usb/include/usb/descriptor.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_DESCRIPTOR_H_
    3737
    38 #include <async.h>
     38#include <sys/types.h>
    3939
    4040/** Descriptor type. */
     
    4545        USB_DESCTYPE_INTERFACE = 4,
    4646        USB_DESCTYPE_ENDPOINT = 5,
     47        /* New in USB2.0 */
     48        USB_DESCTYPE_DEVICE_QUALIFIER = 6,
     49        USB_DESCTYPE_OTHER_SPEED_CONFIGURATION = 7,
     50        USB_DESCTYPE_INTERFACE_POWER = 8,
     51        /* Class specific */
    4752        USB_DESCTYPE_HID = 0x21,
    4853        USB_DESCTYPE_HID_REPORT = 0x22,
     
    8994} __attribute__ ((packed)) usb_standard_device_descriptor_t;
    9095
     96/** USB device qualifier decriptor is basically a cut down version of the device
     97 * descriptor with values that would be valid if the device operated on the
     98 * other speed (HIGH vs. FULL)
     99 */
     100typedef struct {
     101        /** Size of this descriptor in bytes */
     102        uint8_t length;
     103        /** Descriptor type (USB_DESCTYPE_DEVICE_QUALIFIER) */
     104        uint8_t descriptor_type;
     105        /** USB specification release number.
     106         * The number shall be coded as binary-coded decimal (BCD).
     107         */
     108        uint16_t usb_spec_version;
     109        /** Device class. */
     110        uint8_t device_class;
     111        /** Device sub-class. */
     112        uint8_t device_subclass;
     113        /** Device protocol. */
     114        uint8_t device_protocol;
     115        /** Maximum packet size for endpoint zero.
     116         * Valid values are only 8, 16, 32, 64).
     117         */
     118        uint8_t max_packet_size;
     119        /** Number of possible configurations. */
     120        uint8_t configuration_count;
     121        uint8_t reserved;
     122} __attribute__ ((packed)) usb_standard_device_qualifier_descriptor_t;
     123
    91124/** Standard USB configuration descriptor.
    92125 */
     
    116149} __attribute__ ((packed)) usb_standard_configuration_descriptor_t;
    117150
     151/** USB Other Speed Configuration descriptor shows values that would change
     152 * in the configuration descriptor if the device operated at its other
     153 * possible speed (HIGH vs. FULL)
     154 */
     155typedef usb_standard_configuration_descriptor_t
     156    usb_other_speed_configuration_descriptor_t;
     157
    118158/** Standard USB interface descriptor.
    119159 */
     
    157197         */
    158198        uint8_t attributes;
    159         /** Maximum packet size. */
     199        /** Maximum packet size.
     200         * Lower 10 bits represent the actuall size
     201         * Bits 11,12 specify addtional transfer opportunitities for
     202         * HS INT and ISO transfers. */
    160203        uint16_t max_packet_size;
     204#define ED_MPS_PACKET_SIZE_MASK  0x3ff
     205#define ED_MPS_PACKET_SIZE_GET(value) \
     206        ((value) & ED_MPS_PACKET_SIZE_MASK)
     207#define ED_MPS_TRANS_OPPORTUNITIES_GET(value) \
     208        ((((value) >> 10) & 0x3) + 1)
    161209        /** Polling interval in milliseconds.
    162210         * Ignored for bulk and control endpoints.
  • uspace/lib/usb/include/usb/dev.h

    r5b18137 rb4b534ac  
    3636
    3737#include <devman.h>
    38 #include <usb/usb.h>
    3938
    40 int usb_get_info_by_handle(devman_handle_t,
    41     devman_handle_t *, usb_address_t *, int *);
    42 
    43 static inline int usb_get_hc_by_handle(devman_handle_t dev, devman_handle_t *hc)
    44 {
    45         return usb_get_info_by_handle(dev, hc, NULL, NULL);
    46 }
    47 
    48 static inline int usb_get_address_by_handle(
    49     devman_handle_t dev, usb_address_t *address)
    50 {
    51         return usb_get_info_by_handle(dev, NULL, address, NULL);
    52 }
    53 
    54 static inline int usb_get_iface_by_handle(devman_handle_t dev, int *iface)
    55 {
    56         return usb_get_info_by_handle(dev, NULL, NULL, iface);
    57 }
    58 
    59 int usb_resolve_device_handle(const char *, devman_handle_t *, usb_address_t *,
    60     devman_handle_t *);
     39int usb_resolve_device_handle(const char *, devman_handle_t *);
    6140#endif
    6241/**
  • uspace/lib/usb/include/usb/usb.h

    r5b18137 rb4b534ac  
    8484} usb_speed_t;
    8585
     86static inline bool usb_speed_is_11(const usb_speed_t s)
     87{
     88        return (s == USB_SPEED_FULL) || (s == USB_SPEED_LOW);
     89}
     90
    8691const char *usb_str_speed(usb_speed_t);
    8792
     
    110115#define USB_ADDRESS_DEFAULT 0
    111116/** Maximum address number in USB 1.1. */
    112 #define USB11_ADDRESS_MAX 128
     117#define USB11_ADDRESS_MAX 127
     118#define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1)
     119
     120/** Check USB address for allowed values.
     121 *
     122 * @param ep USB address.
     123 * @return True, if value is wihtin limits, false otherwise.
     124 */
     125static inline bool usb_address_is_valid(usb_address_t a)
     126{
     127        return (a >= USB_ADDRESS_DEFAULT) && (a <= USB11_ADDRESS_MAX);
     128}
    113129
    114130/** USB endpoint number type.
     
    117133typedef int16_t usb_endpoint_t;
    118134
    119 /** Maximum endpoint number in USB 1.1.
    120  */
     135/** Default control endpoint */
     136#define USB_ENDPOINT_DEFAULT_CONTROL 0
     137/** Maximum endpoint number in USB 1.1. */
    121138#define USB11_ENDPOINT_MAX 16
     139
     140/** Check USB endpoint for allowed values.
     141 *
     142 * @param ep USB endpoint number.
     143 * @return True, if value is wihtin limits, false otherwise.
     144 */
     145static inline bool usb_endpoint_is_valid(usb_endpoint_t ep)
     146{
     147        return (ep >= USB_ENDPOINT_DEFAULT_CONTROL) &&
     148            (ep < USB11_ENDPOINT_MAX);
     149}
    122150
    123151
     
    133161} usb_target_t;
    134162
     163
    135164/** Check USB target for allowed values (address and endpoint).
    136165 *
     
    140169static inline bool usb_target_is_valid(usb_target_t target)
    141170{
    142         return !(target.endpoint > 15 || target.endpoint < 0
    143             || target.address >= USB11_ADDRESS_MAX || target.address < 0);
     171        return usb_address_is_valid(target.address) &&
     172            usb_endpoint_is_valid(target.endpoint);
    144173}
    145174
  • uspace/lib/usb/src/class.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/classes/classes.h>
    36 #include <errno.h>
    3736
    3837/** Tell string representation of USB class.
  • uspace/lib/usb/src/debug.c

    r5b18137 rb4b534ac  
    3333 * Debugging and logging support.
    3434 */
    35 #include <adt/list.h>
    3635#include <fibril_synch.h>
    37 #include <errno.h>
    38 #include <stdlib.h>
    39 #include <stdio.h>
    4036#include <ddf/log.h>
    4137#include <usb/debug.h>
  • uspace/lib/usb/src/dev.c

    r5b18137 rb4b534ac  
    2929
    3030#include <usb/dev.h>
    31 #include <usb/hc.h>
    3231#include <errno.h>
    3332#include <usb_iface.h>
    3433#include <str.h>
    3534#include <stdio.h>
    36 
    37 #define MAX_DEVICE_PATH 1024
    38 
    39 /** Find host controller handle, address and iface number for the device.
    40  *
    41  * @param[in] device_handle Device devman handle.
    42  * @param[out] hc_handle Where to store handle of host controller
    43  *      controlling device with @p device_handle handle.
    44  * @param[out] address Place to store the device's address
    45  * @param[out] iface Place to stoer the assigned USB interface number.
    46  * @return Error code.
    47  */
    48 int usb_get_info_by_handle(devman_handle_t device_handle,
    49     devman_handle_t *hc_handle, usb_address_t *address, int *iface)
    50 {
    51         async_sess_t *parent_sess =
    52             devman_parent_device_connect(device_handle, IPC_FLAG_BLOCKING);
    53         if (!parent_sess)
    54                 return ENOMEM;
    55 
    56         async_exch_t *exch = async_exchange_begin(parent_sess);
    57         if (!exch) {
    58                 async_hangup(parent_sess);
    59                 return ENOMEM;
    60         }
    61 
    62         usb_address_t tmp_address;
    63         devman_handle_t tmp_handle;
    64         int tmp_iface;
    65 
    66         if (address) {
    67                 const int ret = usb_get_my_address(exch, &tmp_address);
    68                 if (ret != EOK) {
    69                         async_exchange_end(exch);
    70                         async_hangup(parent_sess);
    71                         return ret;
    72                 }
    73         }
    74 
    75         if (hc_handle) {
    76                 const int ret = usb_get_hc_handle(exch, &tmp_handle);
    77                 if (ret != EOK) {
    78                         async_exchange_end(exch);
    79                         async_hangup(parent_sess);
    80                         return ret;
    81                 }
    82         }
    83 
    84         if (iface) {
    85                 const int ret = usb_get_my_interface(exch, &tmp_iface);
    86                 switch (ret) {
    87                 case ENOTSUP:
    88                         /* Implementing GET_MY_INTERFACE is voluntary. */
    89                         tmp_iface = -1;
    90                 case EOK:
    91                         break;
    92                 default:
    93                         async_exchange_end(exch);
    94                         async_hangup(parent_sess);
    95                         return ret;
    96                 }
    97         }
    98 
    99         if (hc_handle)
    100                 *hc_handle = tmp_handle;
    101 
    102         if (address)
    103                 *address = tmp_address;
    104 
    105         if (iface)
    106                 *iface = tmp_iface;
    107 
    108         async_exchange_end(exch);
    109         async_hangup(parent_sess);
    110 
    111         return EOK;
    112 }
    113 
    114 static bool try_parse_bus_and_address(const char *path,
    115     const char **func_start,
    116     devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    117 {
    118         uint64_t sid;
    119         size_t address;
    120         int rc;
    121         const char *ptr;
    122 
    123         rc = str_uint64_t(path, &ptr, 10, false, &sid);
    124         if (rc != EOK) {
    125                 return false;
    126         }
    127         if ((*ptr == ':') || (*ptr == '.')) {
    128                 ptr++;
    129         } else {
    130                 return false;
    131         }
    132         rc = str_size_t(ptr, func_start, 10, false, &address);
    133         if (rc != EOK) {
    134                 return false;
    135         }
    136         rc = usb_ddf_get_hc_handle_by_sid(sid, out_hc_handle);
    137         if (rc != EOK) {
    138                 return false;
    139         }
    140         if (out_device_address != NULL) {
    141                 *out_device_address = (usb_address_t) address;
    142         }
    143         return true;
    144 }
    145 
    146 static int get_device_handle_by_address(devman_handle_t hc_handle, int addr,
    147     devman_handle_t *dev_handle)
    148 {
    149         usb_hc_connection_t conn;
    150         usb_hc_connection_initialize(&conn, hc_handle);
    151 
    152         const int rc = usb_hc_get_handle_by_address(&conn, addr, dev_handle);
    153 
    154         return rc;
    155 }
    15635
    15736/** Resolve handle and address of USB device from its path.
     
    17453 * @return Error code.
    17554 */
    176 int usb_resolve_device_handle(const char *dev_path, devman_handle_t *out_hc_handle,
    177     usb_address_t *out_dev_addr, devman_handle_t *out_dev_handle)
     55int usb_resolve_device_handle(const char *dev_path, devman_handle_t *dev_handle)
    17856{
    179         if (dev_path == NULL) {
     57        if (dev_path == NULL || dev_handle == NULL) {
    18058                return EBADMEM;
    18159        }
    18260
    183         bool found_hc = false;
    184         bool found_addr = false;
    185         devman_handle_t hc_handle, dev_handle;
    186         usb_address_t dev_addr = -1;
    187         int rc;
    188         bool is_bus_addr;
    189         const char *func_start = NULL;
    190         char *path = NULL;
     61        /* First, try to get the device handle. */
     62        int rc = devman_fun_get_handle(dev_path, dev_handle, 0);
    19163
    192         /* First try the BUS.ADDR format. */
    193         is_bus_addr = try_parse_bus_and_address(dev_path, &func_start,
    194             &hc_handle, &dev_addr);
    195         if (is_bus_addr) {
    196                 found_hc = true;
    197                 found_addr = true;
    198                 /*
    199                  * Now get the handle of the device. We will need that
    200                  * in both cases. If there is only BUS.ADDR, it will
    201                  * be the handle to be returned to the caller, otherwise
    202                  * we will need it to resolve the path to which the
    203                  * suffix would be appended.
    204                  */
    205                 /* If there is nothing behind the BUS.ADDR, we will
    206                  * get the device handle from the host controller.
    207                  * Otherwise, we will
    208                  */
    209                 rc = get_device_handle_by_address(hc_handle, dev_addr,
    210                     &dev_handle);
    211                 if (rc != EOK) {
    212                         return rc;
    213                 }
    214                 if (str_length(func_start) > 0) {
    215                         char tmp_path[MAX_DEVICE_PATH];
    216                         rc = devman_fun_get_path(dev_handle,
    217                             tmp_path, MAX_DEVICE_PATH);
    218                         if (rc != EOK) {
    219                                 return rc;
    220                         }
    221                         rc = asprintf(&path, "%s%s", tmp_path, func_start);
    222                         if (rc < 0) {
    223                                 return ENOMEM;
    224                         }
    225                 } else {
    226                         /* Everything is resolved. Get out of here. */
    227                         goto copy_out;
    228                 }
    229         } else {
    230                 path = str_dup(dev_path);
    231                 if (path == NULL) {
    232                         return ENOMEM;
    233                 }
     64        /* Next, try parsing dev_handle from the provided string */
     65        if (rc != EOK) {
     66                *dev_handle = strtoul(dev_path, NULL, 10);
     67                //FIXME: check errno
     68                rc = EOK;
    23469        }
    235 
    236         /* First try to get the device handle. */
    237         rc = devman_fun_get_handle(path, &dev_handle, 0);
    238         if (rc != EOK) {
    239                 free(path);
    240                 /* Invalid path altogether. */
    241                 return rc;
    242         }
    243 
    244         /* Remove suffixes and hope that we will encounter device node. */
    245         while (str_length(path) > 0) {
    246                 /* Get device handle first. */
    247                 devman_handle_t tmp_handle;
    248                 rc = devman_fun_get_handle(path, &tmp_handle, 0);
    249                 if (rc != EOK) {
    250                         free(path);
    251                         return rc;
    252                 }
    253 
    254                 /* Try to find its host controller. */
    255                 if (!found_hc) {
    256                         rc = usb_get_hc_by_handle(tmp_handle, &hc_handle);
    257                         if (rc == EOK) {
    258                                 found_hc = true;
    259                         }
    260                 }
    261 
    262                 /* Try to get its address. */
    263                 if (!found_addr) {
    264                         rc = usb_get_address_by_handle(tmp_handle, &dev_addr);
    265                         if (rc == 0) {
    266                                 found_addr = true;
    267                         }
    268                 }
    269 
    270                 /* Speed-up. */
    271                 if (found_hc && found_addr) {
    272                         break;
    273                 }
    274 
    275                 /* Remove the last suffix. */
    276                 char *slash_pos = str_rchr(path, '/');
    277                 if (slash_pos != NULL) {
    278                         *slash_pos = 0;
    279                 }
    280         }
    281 
    282         free(path);
    283 
    284         if (!found_addr || !found_hc) {
    285                 return ENOENT;
    286         }
    287 
    288 copy_out:
    289         if (out_dev_addr != NULL) {
    290                 *out_dev_addr = dev_addr;
    291         }
    292         if (out_hc_handle != NULL) {
    293                 *out_hc_handle = hc_handle;
    294         }
    295         if (out_dev_handle != NULL) {
    296                 *out_dev_handle = dev_handle;
    297         }
    298 
    299         return EOK;
     70        return rc;
    30071}
  • uspace/lib/usb/src/dump.c

    r5b18137 rb4b534ac  
    3333 * Descriptor dumping.
    3434 */
    35 #include <adt/list.h>
    36 #include <fibril_synch.h>
    37 #include <errno.h>
    3835#include <stdlib.h>
    3936#include <stdio.h>
     
    4138#include <usb/descriptor.h>
    4239#include <usb/classes/classes.h>
     40#include <usb/classes/hub.h>
     41#include <usb/usb.h>
    4342
    4443/** Mapping between descriptor id and dumping function. */
     
    276275    const uint8_t *descriptor, size_t descriptor_length)
    277276{
    278         /* TODO */
     277        usb_hub_descriptor_header_t *d =
     278            (usb_hub_descriptor_header_t *) descriptor;
     279        if (descriptor_length < sizeof(d))
     280                return;
     281
     282        PRINTLINE("bDescLength: = %d", d->length);
     283        PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
     284        PRINTLINE("bNbrPorts = %d", d->port_count);
     285        PRINTLINE("bHubCharacteristics = 0x%02x%02x (%s;%s%s)",
     286            d->characteristics_reserved, d->characteristics,
     287            (d->characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG) ?
     288                "No Power Switching" :
     289                ((d->characteristics & HUB_CHAR_POWER_PER_PORT_FLAG) ?
     290                    "Per-Port Switching" : "Ganged Power Switching"),
     291            (d->characteristics & HUB_CHAR_COMPOUND_DEVICE) ?
     292                "Compound Device;" : "",
     293            (d->characteristics & HUB_CHAR_NO_OC_FLAG) ?
     294                "No OC Protection" :
     295                    ((d->characteristics & HUB_CHAR_OC_PER_PORT_FLAG) ?
     296                        "Individual Port OC Protection" :
     297                            "Global OC Protection")
     298        );
     299        PRINTLINE("bPwrOn2PwrGood = %d (%d ms)",
     300            d->power_good_time, d->power_good_time * 2);
     301        PRINTLINE("bHubContrCurrent = %d (%d mA)",
     302            d->max_current, d->max_current);
     303        const size_t port_bytes = (descriptor_length - sizeof(*d)) / 2;
     304        const uint8_t *removable_mask = descriptor + sizeof(*d);
     305        const uint8_t *powered_mask = descriptor + sizeof(*d) + port_bytes;
     306
     307        if (port_bytes == 0
     308            || port_bytes > (((d->port_count / (unsigned)8) + 1) * 2)) {
     309                PRINTLINE("::CORRUPTED DESCRIPTOR:: (%zu bytes remain)",
     310                    port_bytes * 2);
     311        }
     312
     313        fprintf(output, "%sDeviceRemovable = 0x",
     314            line_prefix ? line_prefix : " - ");
     315        for (unsigned i = port_bytes; i > 0; --i)
     316                fprintf(output, "%02x", removable_mask[i - 1]);
     317        fprintf(output, " (0b1 - Device non-removable)%s",
     318            line_suffix ? line_suffix : "\n");
     319
     320        fprintf(output, "%sPortPwrCtrlMask = 0x",
     321            line_prefix ? line_prefix : " - ");
     322        for (unsigned i = port_bytes; i > 0; --i)
     323                fprintf(output, "%02x", powered_mask[i - 1]);
     324        fprintf(output, " (Legacy - All should be 0b1)%s",
     325            line_suffix ? line_suffix : "\n");
    279326}
    280327
  • uspace/lib/usb/src/usb.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/usb.h>
    36 #include <errno.h>
     36#include <usb/request.h>
    3737
    38 #define ARR_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
     38#include <assert.h>
     39#include <byteorder.h>
     40#include <macros.h>
    3941
    4042static const char *str_speed[] = {
     
    7173const char *usb_str_transfer_type(usb_transfer_type_t t)
    7274{
    73         if (t >= ARR_SIZE(str_transfer_type)) {
     75        if (t >= ARRAY_SIZE(str_transfer_type)) {
    7476                return "invalid";
    7577        }
     
    8486const char *usb_str_transfer_type_short(usb_transfer_type_t t)
    8587{
    86         if (t >= ARR_SIZE(str_transfer_type_short)) {
     88        if (t >= ARRAY_SIZE(str_transfer_type_short)) {
    8789                return "invl";
    8890        }
     
    9799const char *usb_str_direction(usb_direction_t d)
    98100{
    99         if (d >= ARR_SIZE(str_direction)) {
     101        if (d >= ARRAY_SIZE(str_direction)) {
    100102                return "invalid";
    101103        }
     
    110112const char *usb_str_speed(usb_speed_t s)
    111113{
    112         if (s >= ARR_SIZE(str_speed)) {
     114        if (s >= ARRAY_SIZE(str_speed)) {
    113115                return "invalid";
    114116        }
     
    116118}
    117119
     120/** Check setup packet data for signs of toggle reset.
     121 *
     122 * @param[in] requst Setup requst data.
     123 * @retval -1 No endpoints need reset.
     124 * @retval 0 All endpoints need reset.
     125 * @retval >0 Specified endpoint needs reset.
     126 */
     127int usb_request_needs_toggle_reset(
     128    const usb_device_request_setup_packet_t *request)
     129{
     130        assert(request);
     131        switch (request->request)
     132        {
     133        /* Clear Feature ENPOINT_STALL */
     134        case USB_DEVREQ_CLEAR_FEATURE: /*resets only cleared ep */
     135                /* 0x2 ( HOST to device | STANDART | TO ENPOINT) */
     136                if ((request->request_type == 0x2) &&
     137                    (request->value == USB_FEATURE_ENDPOINT_HALT))
     138                        return uint16_usb2host(request->index);
     139                break;
     140        case USB_DEVREQ_SET_CONFIGURATION:
     141        case USB_DEVREQ_SET_INTERFACE:
     142                /* Recipient must be device, this resets all endpoints,
     143                 * In fact there should be no endpoints but EP 0 registered
     144                 * as different interfaces use different endpoints,
     145                 * unless you're changing configuration or alternative
     146                 * interface of an already setup device. */
     147                if (!(request->request_type & SETUP_REQUEST_TYPE_DEVICE_TO_HOST))
     148                        return 0;
     149                break;
     150        default:
     151                break;
     152        }
     153        return -1;
     154}
     155
    118156/**
    119157 * @}
  • uspace/lib/usbdev/Makefile

    r5b18137 rb4b534ac  
    3636SOURCES = \
    3737        src/altiface.c \
     38        src/driver.c \
    3839        src/devdrv.c \
    3940        src/devpoll.c \
    4041        src/dp.c \
    41         src/hub.c \
    4242        src/pipes.c \
    4343        src/pipesinit.c \
  • uspace/lib/usbdev/include/usb/dev/alternate_ifaces.h

    r5b18137 rb4b534ac  
    11/*
    22 * Copyright (c) 2011 Vojtech Horky
     3 * Copyright (c) 2013 Jan Vesely
    34 * All rights reserved.
    45 *
     
    3132 */
    3233/** @file
    33  * Functions needed by hub drivers.
    34  *
    35  * For class specific requests, see usb/classes/hub.h.
     34 * USB device driver framework.
    3635 */
    3736
    38 #ifndef LIBUSBDEV_HUB_H_
    39 #define LIBUSBDEV_HUB_H_
     37#ifndef LIBUSBDEV_ALTERNATE_IFACES_H_
     38#define LIBUSBDEV_ALTERNATE_IFACES_H_
    4039
    41 #include <ddf/driver.h>
     40#include <usb/descriptor.h>
    4241#include <sys/types.h>
    43 #include <errno.h>
    44 #include <usb/hc.h>
    4542
    46 extern int usb_hc_new_device_wrapper(ddf_dev_t *, ddf_fun_t *,
    47     usb_hc_connection_t *, usb_speed_t, int (*)(void *), void *,
    48     usb_address_t *, ddf_dev_ops_t *);
    49 
    50 /** Info about device attached to host controller.
    51  *
    52  * This structure exists only to keep the same signature of
    53  * usb_hc_register_device() when more properties of the device
    54  * would have to be passed to the host controller.
     43/** Wrapper for data related to alternate interface setting.
     44 * The pointers will typically point inside configuration descriptor and
     45 * thus you shall not deallocate them.
    5546 */
    5647typedef struct {
    57         /** Device address. */
    58         usb_address_t address;
    59         /** DDF function (external) of the device. */
    60         ddf_fun_t *fun;
    61 } usb_hub_attached_device_t;
     48        /** Interface descriptor. */
     49        const usb_standard_interface_descriptor_t *interface;
     50        /** Pointer to start of descriptor tree bound with this interface. */
     51        const uint8_t *nested_descriptors;
     52        /** Size of data pointed by nested_descriptors in bytes. */
     53        size_t nested_descriptors_size;
     54} usb_alternate_interface_descriptors_t;
    6255
    63 extern int usb_hub_register_device(usb_hc_connection_t *,
    64     const usb_hub_attached_device_t *);
     56/** Alternate interface settings. */
     57typedef struct {
     58        /** Array of alternate interfaces descriptions. */
     59        const usb_alternate_interface_descriptors_t *alternatives;
     60        /** Size of @c alternatives array. */
     61        size_t alternative_count;
     62        /** Index of currently selected one. */
     63        size_t current;
     64} usb_alternate_interfaces_t;
    6565
    66 static inline int usb_hub_unregister_device(usb_hc_connection_t *conn,
    67     const usb_hub_attached_device_t *attached_device)
    68 {
    69         assert(conn);
    70         if (attached_device == NULL)
    71                 return EBADMEM;
    72        
    73         return usb_hc_release_address(conn, attached_device->address);
    74 }
     66size_t usb_interface_count_alternates(const uint8_t *, size_t, uint8_t);
     67int usb_alternate_interfaces_init(usb_alternate_interfaces_t *,
     68    const uint8_t *, size_t, int);
     69void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *);
    7570
    7671#endif
    77 
    7872/**
    7973 * @}
  • uspace/lib/usbdev/include/usb/dev/dp.h

    r5b18137 rb4b534ac  
    3737
    3838#include <sys/types.h>
    39 #include <usb/usb.h>
    40 #include <usb/descriptor.h>
    4139
    4240/** USB descriptors nesting.
     
    7977    const usb_dp_parser_data_t *, const uint8_t *, const uint8_t *);
    8078
    81 void usb_dp_walk_simple(uint8_t *, size_t, const usb_dp_descriptor_nesting_t *,
    82     walk_callback_t, void *);
     79void usb_dp_walk_simple(const uint8_t *, size_t,
     80    const usb_dp_descriptor_nesting_t *, walk_callback_t, void *);
    8381
    8482#endif
  • uspace/lib/usbdev/include/usb/dev/driver.h

    r5b18137 rb4b534ac  
    3737#define LIBUSBDEV_DRIVER_H_
    3838
    39 #include <usb/hc.h>
    40 #include <usb/dev/usb_device_connection.h>
     39#include <usb/dev/device.h>
    4140#include <usb/dev/pipes.h>
    42 
    43 /** Descriptors for USB device. */
    44 typedef struct {
    45         /** Standard device descriptor. */
    46         usb_standard_device_descriptor_t device;
    47         /** Full configuration descriptor of current configuration. */
    48         const uint8_t *configuration;
    49         size_t configuration_size;
    50 } usb_device_descriptors_t;
    51 
    52 /** Wrapper for data related to alternate interface setting.
    53  * The pointers will typically point inside configuration descriptor and
    54  * thus you shall not deallocate them.
    55  */
    56 typedef struct {
    57         /** Interface descriptor. */
    58         const usb_standard_interface_descriptor_t *interface;
    59         /** Pointer to start of descriptor tree bound with this interface. */
    60         const uint8_t *nested_descriptors;
    61         /** Size of data pointed by nested_descriptors in bytes. */
    62         size_t nested_descriptors_size;
    63 } usb_alternate_interface_descriptors_t;
    64 
    65 /** Alternate interface settings. */
    66 typedef struct {
    67         /** Array of alternate interfaces descriptions. */
    68         usb_alternate_interface_descriptors_t *alternatives;
    69         /** Size of @c alternatives array. */
    70         size_t alternative_count;
    71         /** Index of currently selected one. */
    72         size_t current;
    73 } usb_alternate_interfaces_t;
    74 
    75 /** USB device structure. */
    76 typedef struct {
    77         /** Connection to USB hc, used by wire and arbitrary requests. */
    78         usb_hc_connection_t hc_conn;
    79         /** Connection backing the pipes.
    80          * Typically, you will not need to use this attribute at all.
    81          */
    82         usb_device_connection_t wire;
    83         /** The default control pipe. */
    84         usb_pipe_t ctrl_pipe;
    85         /** Other endpoint pipes.
    86          * This is an array of other endpoint pipes in the same order as
    87          * in usb_driver_t.
    88          */
    89         usb_endpoint_mapping_t *pipes;
    90         /** Number of other endpoint pipes. */
    91         size_t pipes_count;
    92         /** Current interface.
    93          * Usually, drivers operate on single interface only.
    94          * This item contains the value of the interface or -1 for any.
    95          */
    96         int interface_no;
    97 
    98         /** Alternative interfaces. */
    99         usb_alternate_interfaces_t alternate_interfaces;
    100 
    101         /** Some useful descriptors. */
    102         usb_device_descriptors_t descriptors;
    103 
    104         /** Generic DDF device backing this one. DO NOT TOUCH! */
    105         ddf_dev_t *ddf_dev;
    106         /** Custom driver data.
    107          * Do not use the entry in generic device, that is already used
    108          * by the framework.
    109          */
    110         void *driver_data;
    111 } usb_device_t;
    11241
    11342/** USB driver ops. */
     
    16493int usb_driver_main(const usb_driver_t *);
    16594
    166 int usb_device_init(usb_device_t *, ddf_dev_t *,
    167     const usb_endpoint_description_t **, const char **);
    168 void usb_device_deinit(usb_device_t *);
    169 
    170 int usb_device_select_interface(usb_device_t *, uint8_t,
    171     const usb_endpoint_description_t **);
    172 
    173 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    174 void usb_device_release_descriptors(usb_device_descriptors_t *);
    175 
    176 int usb_device_create_pipes(usb_device_connection_t *,
    177     const usb_endpoint_description_t **, const uint8_t *, size_t, int, int,
    178     usb_endpoint_mapping_t **, size_t *);
    179 void usb_device_destroy_pipes(usb_endpoint_mapping_t *, size_t);
    180 
    181 void * usb_device_data_alloc(usb_device_t *, size_t);
    182 
    183 size_t usb_interface_count_alternates(const uint8_t *, size_t, uint8_t);
    184 int usb_alternate_interfaces_init(usb_alternate_interfaces_t *,
    185     const uint8_t *, size_t, int);
    186 void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *);
    18795#endif
    18896/**
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r5b18137 rb4b534ac  
    3535#define LIBUSBDEV_PIPES_H_
    3636
    37 #include <sys/types.h>
    38 #include <ipc/devman.h>
    39 #include <ddf/driver.h>
    40 #include <fibril_synch.h>
    4137#include <usb/usb.h>
    4238#include <usb/descriptor.h>
    43 #include <usb/dev/usb_device_connection.h>
     39#include <usb_iface.h>
     40
     41#include <stdbool.h>
     42#include <sys/types.h>
    4443
    4544#define CTRL_PIPE_MIN_PACKET_SIZE 8
     
    5049 */
    5150typedef struct {
    52         /** The connection used for sending the data. */
    53         usb_device_connection_t *wire;
    54 
    5551        /** Endpoint number. */
    5652        usb_endpoint_t endpoint_no;
     
    6561        size_t max_packet_size;
    6662
     63        /** Number of packets per frame/uframe.
     64         * Only valid for HS INT and ISO transfers. All others should set to 1*/
     65        unsigned packets;
     66
    6767        /** Whether to automatically reset halt on the endpoint.
    6868         * Valid only for control endpoint zero.
    6969         */
    7070        bool auto_reset_halt;
     71
     72        /** The connection used for sending the data. */
     73        usb_dev_session_t *bus_session;
    7174} usb_pipe_t;
    7275
     
    105108} usb_endpoint_mapping_t;
    106109
    107 int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
    108     usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t);
    109 int usb_pipe_initialize_default_control(usb_pipe_t *,
    110     usb_device_connection_t *);
     110int usb_pipe_initialize(usb_pipe_t *, usb_endpoint_t, usb_transfer_type_t,
     111    size_t, usb_direction_t, unsigned, usb_dev_session_t *);
     112int usb_pipe_initialize_default_control(usb_pipe_t *, usb_dev_session_t *);
    111113
    112114int usb_pipe_probe_default_control(usb_pipe_t *);
    113115int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    114     size_t, const uint8_t *, size_t, usb_device_connection_t *);
     116    size_t, const uint8_t *, size_t, usb_dev_session_t *);
    115117
    116118int usb_pipe_register(usb_pipe_t *, unsigned);
    117119int usb_pipe_unregister(usb_pipe_t *);
    118 
    119 int usb_pipe_start_long_transfer(usb_pipe_t *);
    120 int usb_pipe_end_long_transfer(usb_pipe_t *);
    121120
    122121int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *);
  • uspace/lib/usbdev/include/usb/dev/poll.h

    r5b18137 rb4b534ac  
    3636#define LIBUSBDEV_POLL_H_
    3737
    38 #include <usb/dev/driver.h>
    39 #include <time.h>
     38#include <usb/usb.h>
     39#include <usb/dev/device.h>
     40#include <usb/dev/pipes.h>
     41
     42#include <stdbool.h>
     43#include <sys/types.h>
    4044
    4145/** Parameters and callbacks for automated polling. */
     
    8791} usb_device_auto_polling_t;
    8892
    89 int usb_device_auto_polling(usb_device_t *, size_t,
     93typedef bool (*usb_polling_callback_t)(usb_device_t *, uint8_t *, size_t, void *);
     94typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
     95
     96int usb_device_auto_polling(usb_device_t *, usb_endpoint_t,
    9097    const usb_device_auto_polling_t *, size_t);
    9198
    92 typedef bool (*usb_polling_callback_t)(usb_device_t *,
    93     uint8_t *, size_t, void *);
    94 typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
     99int usb_device_auto_poll(usb_device_t *, usb_endpoint_t,
     100    usb_polling_callback_t, size_t, int, usb_polling_terminted_callback_t, void *);
    95101
    96 int usb_device_auto_poll(usb_device_t *, size_t,
    97     usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
     102int usb_device_auto_polling_desc(usb_device_t *,
     103    const usb_endpoint_description_t *, const usb_device_auto_polling_t *,
     104    size_t);
     105
     106int usb_device_auto_poll_desc(usb_device_t *,
     107    const usb_endpoint_description_t *, usb_polling_callback_t, size_t, int,
     108    usb_polling_terminted_callback_t, void *);
    98109
    99110#endif
  • uspace/lib/usbdev/include/usb/dev/recognise.h

    r5b18137 rb4b534ac  
    3737#define LIBUSBDEV_RECOGNISE_H_
    3838
    39 #include <sys/types.h>
    40 #include <usb/usb.h>
     39#include <usb/descriptor.h>
    4140#include <usb/dev/pipes.h>
    42 #include <ipc/devman.h>
     41
     42#include <devman.h>
    4343
    4444extern int usb_device_create_match_ids_from_device_descriptor(
     
    5050
    5151extern int usb_device_create_match_ids(usb_pipe_t *, match_id_list_t *);
    52 
    53 extern int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    54     ddf_dev_t *, ddf_fun_t *, ddf_dev_ops_t *);
    55 
    5652#endif
    5753
  • uspace/lib/usbdev/include/usb/dev/request.h

    r5b18137 rb4b534ac  
    4141#include <usb/dev/pipes.h>
    4242#include <usb/descriptor.h>
    43 
    44 /** USB device status - device is self powered (opposed to bus powered). */
    45 #define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0))
    46 
    47 /** USB device status - remote wake-up signaling is enabled. */
    48 #define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1))
    49 
    50 /** USB endpoint status - endpoint is halted (stalled). */
    51 #define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
    52 
    53 /** USB feature selector - endpoint halt (stall). */
    54 #define USB_FEATURE_SELECTOR_ENDPOINT_HALT (0)
    55 
    56 /** USB feature selector - device remote wake-up. */
    57 #define USB_FEATURE_SELECTOR_REMOTE_WAKEUP (1)
    58 
    59 /** Standard device request. */
    60 typedef enum {
    61         USB_DEVREQ_GET_STATUS = 0,
    62         USB_DEVREQ_CLEAR_FEATURE = 1,
    63         USB_DEVREQ_SET_FEATURE = 3,
    64         USB_DEVREQ_SET_ADDRESS = 5,
    65         USB_DEVREQ_GET_DESCRIPTOR = 6,
    66         USB_DEVREQ_SET_DESCRIPTOR = 7,
    67         USB_DEVREQ_GET_CONFIGURATION = 8,
    68         USB_DEVREQ_SET_CONFIGURATION = 9,
    69         USB_DEVREQ_GET_INTERFACE = 10,
    70         USB_DEVREQ_SET_INTERFACE = 11,
    71         USB_DEVREQ_SYNCH_FRAME = 12,
    72         USB_DEVREQ_LAST_STD
    73 } usb_stddevreq_t;
    74 
    75 /** Device request setup packet.
    76  * The setup packet describes the request.
    77  */
    78 typedef struct {
    79         /** Request type.
    80          * The type combines transfer direction, request type and
    81          * intended recipient.
    82          */
    83         uint8_t request_type;
    84 #define SETUP_REQUEST_TYPE_DEVICE_TO_HOST (1 << 7)
    85 #define SETUP_REQUEST_TYPE_GET_TYPE(rt) ((rt >> 5) & 0x3)
    86 #define SETUP_REQUEST_TYPE_GET_RECIPIENT(rec) (rec & 0x1f)
    87 #define SETUP_REQUEST_TO_HOST(type, recipient) \
    88     (uint8_t)((1 << 7) | ((type & 0x3) << 5) | (recipient & 0x1f))
    89 #define SETUP_REQUEST_TO_DEVICE(type, recipient) \
    90     (uint8_t)(((type & 0x3) << 5) | (recipient & 0x1f))
    91 
    92         /** Request identification. */
    93         uint8_t request;
    94         /** Main parameter to the request. */
    95         union __attribute__ ((packed)) {
    96                 uint16_t value;
    97                 /* FIXME: add #ifdefs according to host endianness */
    98                 struct __attribute__ ((packed)) {
    99                         uint8_t value_low;
    100                         uint8_t value_high;
    101                 };
    102         };
    103         /** Auxiliary parameter to the request.
    104          * Typically, it is offset to something.
    105          */
    106         uint16_t index;
    107         /** Length of extra data. */
    108         uint16_t length;
    109 } __attribute__ ((packed)) usb_device_request_setup_packet_t;
     43#include <usb/request.h>
    11044
    11145int usb_control_request_set(usb_pipe_t *,
    11246    usb_request_type_t, usb_request_recipient_t, uint8_t,
    113     uint16_t, uint16_t, void *, size_t);
     47    uint16_t, uint16_t, const void *, size_t);
    11448
    11549int usb_control_request_get(usb_pipe_t *,
     
    13569    void *, size_t, size_t *);
    13670int usb_request_get_full_configuration_descriptor_alloc(usb_pipe_t *,
    137     int, void **, size_t *);
     71    int, const void **, size_t *);
    13872int usb_request_set_descriptor(usb_pipe_t *, usb_request_type_t,
    139     usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t);
     73    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, const void *, size_t);
    14074
    14175int usb_request_get_configuration(usb_pipe_t *, uint8_t *);
    14276int usb_request_set_configuration(usb_pipe_t *, uint8_t);
     77
    14378int usb_request_get_interface(usb_pipe_t *, uint8_t, uint8_t *);
    14479int usb_request_set_interface(usb_pipe_t *, uint8_t, uint8_t);
  • uspace/lib/usbdev/src/altiface.c

    r5b18137 rb4b534ac  
    3434 */
    3535
    36 #include <usb/dev/driver.h>
    37 #include <usb/dev/request.h>
    38 #include <usb/debug.h>
     36#include <usb/dev/alternate_ifaces.h>
    3937#include <usb/dev/dp.h>
     38#include <assert.h>
    4039#include <errno.h>
    41 #include <str_error.h>
    42 #include <assert.h>
     40#include <stdlib.h>
    4341
    4442/** Count number of alternate settings of a interface.
     
    105103        }
    106104
    107         alternates->alternative_count
    108             = usb_interface_count_alternates(config_descr, config_descr_size,
    109                 interface_number);
     105        const size_t alt_count = usb_interface_count_alternates(config_descr,
     106            config_descr_size, interface_number);
    110107
    111         if (alternates->alternative_count == 0) {
     108        if (alt_count == 0) {
    112109                return ENOENT;
    113110        }
    114111
    115         alternates->alternatives = calloc(alternates->alternative_count,
     112        usb_alternate_interface_descriptors_t *alts = calloc(alt_count,
    116113            sizeof(usb_alternate_interface_descriptors_t));
    117         if (alternates->alternatives == NULL) {
     114        if (alts == NULL) {
    118115                return ENOMEM;
    119116        }
     
    128125        };
    129126
    130         usb_alternate_interface_descriptors_t *iterator
    131             = &alternates->alternatives[0];
    132 
    133         const usb_alternate_interface_descriptors_t *end
    134             = &alternates->alternatives[alternates->alternative_count];
    135127
    136128        const void *iface_ptr =
    137129            usb_dp_get_nested_descriptor(&dp_parser, &dp_data, dp_data.data);
    138130
    139         while (iface_ptr != NULL && iterator < end) {
     131        usb_alternate_interface_descriptors_t *iterator = alts;
     132        for (; iface_ptr != NULL && iterator < &alts[alt_count]; ++iterator) {
    140133                const usb_standard_interface_descriptor_t *iface = iface_ptr;
    141134
     
    159152                    dp_data.data + dp_data.size : iface_ptr;
    160153
    161                 iterator->nested_descriptors_size
    162                     = next - iterator->nested_descriptors;
     154                iterator->nested_descriptors_size =
     155                    next - iterator->nested_descriptors;
     156        }
    163157
    164                 ++iterator;
    165         }
     158        alternates->alternatives = alts;
     159        alternates->alternative_count = alt_count;
    166160
    167161        return EOK;
  • uspace/lib/usbdev/src/devdrv.c

    r5b18137 rb4b534ac  
    3333 * USB device driver framework.
    3434 */
    35 #include <usb/dev/driver.h>
     35
     36#include <usb_iface.h>
     37#include <usb/dev/alternate_ifaces.h>
     38#include <usb/dev/device.h>
     39#include <usb/dev/pipes.h>
    3640#include <usb/dev/request.h>
    3741#include <usb/debug.h>
    38 #include <usb/dev.h>
     42#include <usb/descriptor.h>
     43#include <usb/usb.h>
     44
     45#include <assert.h>
     46#include <async.h>
     47#include <devman.h>
    3948#include <errno.h>
    40 #include <str_error.h>
    41 #include <assert.h>
    42 
    43 static int generic_device_add(ddf_dev_t *);
    44 static int generic_device_remove(ddf_dev_t *);
    45 static int generic_device_gone(ddf_dev_t *);
    46 
    47 static driver_ops_t generic_driver_ops = {
    48         .dev_add = generic_device_add,
    49         .dev_remove = generic_device_remove,
    50         .dev_gone = generic_device_gone,
    51 };
    52 static driver_t generic_driver = {
    53         .driver_ops = &generic_driver_ops
    54 };
    55 
    56 static const usb_driver_t *driver = NULL;
    57 
    58 /** Main routine of USB device driver.
    59  *
    60  * Under normal conditions, this function never returns.
    61  *
    62  * @param drv USB device driver structure.
    63  * @return Task exit status.
    64  */
    65 int usb_driver_main(const usb_driver_t *drv)
    66 {
    67         assert(drv != NULL);
    68 
    69         /* Prepare the generic driver. */
    70         generic_driver.name = drv->name;
    71 
    72         driver = drv;
    73 
    74         return ddf_driver_main(&generic_driver);
    75 }
     49#include <stdlib.h>
     50
     51#include <ddf/driver.h>
     52
     53/** USB device structure. */
     54typedef struct usb_device {
     55        /** Connection to device on USB bus */
     56        usb_dev_session_t *bus_session;
     57        /** devman handle */
     58        devman_handle_t handle;
     59        /** The default control pipe. */
     60        usb_pipe_t ctrl_pipe;
     61
     62        /** Other endpoint pipes.
     63         * This is an array of other endpoint pipes in the same order as
     64         * in usb_driver_t.
     65         */
     66        usb_endpoint_mapping_t *pipes;
     67        /** Number of other endpoint pipes. */
     68        size_t pipes_count;
     69        /** Current interface.
     70         * Usually, drivers operate on single interface only.
     71         * This item contains the value of the interface or -1 for any.
     72         */
     73        int interface_no;
     74        /** Alternative interfaces. */
     75        usb_alternate_interfaces_t alternate_interfaces;
     76        /** Some useful descriptors for USB device. */
     77        usb_device_descriptors_t descriptors;
     78        /** Generic DDF device backing this one. DO NOT TOUCH! */
     79        ddf_dev_t *ddf_dev;
     80        /** Custom driver data.
     81         * Do not use the entry in generic device, that is already used
     82         * by the framework.
     83         */
     84        void *driver_data;
     85
     86} usb_device_t;
    7687
    7788/** Count number of pipes the driver expects.
     
    8091 * @return Number of pipes (excluding default control pipe).
    8192 */
    82 static inline size_t count_other_pipes(
    83     const usb_endpoint_description_t **endpoints)
     93static inline size_t count_pipes(const usb_endpoint_description_t **endpoints)
    8494{
    8595        size_t count;
    8696        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    8797        return count;
    88 }
    89 
    90 /** Callback when a new device is supposed to be controlled by this driver.
    91  *
    92  * This callback is a wrapper for USB specific version of @c device_add.
    93  *
    94  * @param gen_dev Device structure as prepared by DDF.
    95  * @return Error code.
    96  */
    97 int generic_device_add(ddf_dev_t *gen_dev)
    98 {
    99         assert(driver);
    100         assert(driver->ops);
    101         assert(driver->ops->device_add);
    102 
    103         /* Get place for driver data. */
    104         usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t));
    105         if (dev == NULL) {
    106                 usb_log_error("USB device `%s' structure allocation failed.\n",
    107                     ddf_dev_get_name(gen_dev));
    108                 return ENOMEM;
    109         }
    110 
    111         /* Initialize generic USB driver data. */
    112         const char *err_msg = NULL;
    113         int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg);
    114         if (rc != EOK) {
    115                 usb_log_error("USB device `%s' init failed (%s): %s.\n",
    116                     ddf_dev_get_name(gen_dev), err_msg, str_error(rc));
    117                 return rc;
    118         }
    119 
    120         /* Start USB driver specific initialization. */
    121         rc = driver->ops->device_add(dev);
    122         if (rc != EOK)
    123                 usb_device_deinit(dev);
    124         return rc;
    125 }
    126 
    127 /** Callback when a device is supposed to be removed from the system.
    128  *
    129  * This callback is a wrapper for USB specific version of @c device_remove.
    130  *
    131  * @param gen_dev Device structure as prepared by DDF.
    132  * @return Error code.
    133  */
    134 int generic_device_remove(ddf_dev_t *gen_dev)
    135 {
    136         assert(driver);
    137         assert(driver->ops);
    138         if (driver->ops->device_rem == NULL)
    139                 return ENOTSUP;
    140         /* Just tell the driver to stop whatever it is doing */
    141         usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
    142         const int ret = driver->ops->device_rem(usb_dev);
    143         if (ret != EOK)
    144                 return ret;
    145         usb_device_deinit(usb_dev);
    146         return EOK;
    147 }
    148 
    149 /** Callback when a device was removed from the system.
    150  *
    151  * This callback is a wrapper for USB specific version of @c device_gone.
    152  *
    153  * @param gen_dev Device structure as prepared by DDF.
    154  * @return Error code.
    155  */
    156 int generic_device_gone(ddf_dev_t *gen_dev)
    157 {
    158         assert(driver);
    159         assert(driver->ops);
    160         if (driver->ops->device_gone == NULL)
    161                 return ENOTSUP;
    162         usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
    163         const int ret = driver->ops->device_gone(usb_dev);
    164         if (ret == EOK)
    165                 usb_device_deinit(usb_dev);
    166 
    167         return ret;
    168 }
    169 
    170 /** Destroy existing pipes of a USB device.
    171  *
    172  * @param dev Device where to destroy the pipes.
    173  */
    174 static void destroy_current_pipes(usb_device_t *dev)
    175 {
    176         usb_device_destroy_pipes(dev->pipes, dev->pipes_count);
    177         dev->pipes = NULL;
    178         dev->pipes_count = 0;
    17998}
    18099
     
    201120 * @return Error code.
    202121 */
    203 int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
    204     const usb_endpoint_description_t **endpoints)
    205 {
    206         if (dev->interface_no < 0) {
     122int usb_device_select_interface(usb_device_t *usb_dev,
     123    uint8_t alternate_setting, const usb_endpoint_description_t **endpoints)
     124{
     125        assert(usb_dev);
     126
     127        if (usb_dev->interface_no < 0) {
    207128                return EINVAL;
    208129        }
    209130
    210         /* Destroy existing pipes. */
    211         destroy_current_pipes(dev);
    212 
    213131        /* Change the interface itself. */
    214         int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
    215             alternate_setting);
     132        int rc = usb_request_set_interface(&usb_dev->ctrl_pipe,
     133            usb_dev->interface_no, alternate_setting);
    216134        if (rc != EOK) {
    217135                return rc;
    218136        }
    219137
     138        /* Change current alternative */
     139        usb_dev->alternate_interfaces.current = alternate_setting;
     140
     141        /* Destroy existing pipes. */
     142        usb_device_destroy_pipes(usb_dev);
     143
    220144        /* Create new pipes. */
    221         rc = usb_device_create_pipes(&dev->wire, endpoints,
    222             dev->descriptors.configuration, dev->descriptors.configuration_size,
    223             dev->interface_no, (int)alternate_setting,
    224             &dev->pipes, &dev->pipes_count);
     145        rc = usb_device_create_pipes(usb_dev, endpoints);
    225146
    226147        return rc;
     
    233154 * @return Error code.
    234155 */
    235 int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
    236     usb_device_descriptors_t *descriptors)
    237 {
    238         assert(descriptors != NULL);
    239 
    240         descriptors->configuration = NULL;
    241 
    242         int rc;
    243 
    244         /* It is worth to start a long transfer. */
    245         usb_pipe_start_long_transfer(ctrl_pipe);
     156static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
     157{
     158        assert(usb_dev);
     159        assert(usb_dev->descriptors.full_config == NULL);
    246160
    247161        /* Get the device descriptor. */
    248         rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
     162        int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
     163            &usb_dev->descriptors.device);
    249164        if (rc != EOK) {
    250                 goto leave;
     165                return rc;
    251166        }
    252167
    253168        /* Get the full configuration descriptor. */
    254169        rc = usb_request_get_full_configuration_descriptor_alloc(
    255             ctrl_pipe, 0, (void **) &descriptors->configuration,
    256             &descriptors->configuration_size);
    257 
    258 leave:
    259         usb_pipe_end_long_transfer(ctrl_pipe);
     170            &usb_dev->ctrl_pipe, 0,
     171            &usb_dev->descriptors.full_config,
     172            &usb_dev->descriptors.full_config_size);
     173
    260174
    261175        return rc;
     
    266180 * @param[in] descriptors Where to store the descriptors.
    267181 */
    268 void usb_device_release_descriptors(usb_device_descriptors_t *descriptors)
    269 {
    270         assert(descriptors);
    271         free(descriptors->configuration);
    272         descriptors->configuration = NULL;
     182static void usb_device_release_descriptors(usb_device_t *usb_dev)
     183{
     184        assert(usb_dev);
     185        free(usb_dev->descriptors.full_config);
     186        usb_dev->descriptors.full_config = NULL;
     187        usb_dev->descriptors.full_config_size = 0;
    273188}
    274189
     
    280195 * - registers endpoints with the host controller
    281196 *
    282  * @param[in] wire Initialized backing connection to the host controller.
    283197 * @param[in] endpoints Endpoints description, NULL terminated.
    284198 * @param[in] config_descr Configuration descriptor of active configuration.
     
    292206 * @return Error code.
    293207 */
    294 int usb_device_create_pipes(usb_device_connection_t *wire,
    295     const usb_endpoint_description_t **endpoints,
    296     const uint8_t *config_descr, size_t config_descr_size,
    297     int interface_no, int interface_setting,
    298     usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
    299 {
    300         assert(wire != NULL);
    301         assert(config_descr != NULL);
    302         assert(config_descr_size > 0);
    303         assert(pipes_ptr != NULL);
    304 
    305         size_t i;
    306         int rc;
    307 
    308         const size_t pipe_count = count_other_pipes(endpoints);
     208int usb_device_create_pipes(usb_device_t *usb_dev,
     209    const usb_endpoint_description_t **endpoints)
     210{
     211        assert(usb_dev);
     212        assert(usb_dev->descriptors.full_config);
     213        assert(usb_dev->pipes == NULL);
     214        assert(usb_dev->pipes_count == 0);
     215
     216        size_t pipe_count = count_pipes(endpoints);
    309217        if (pipe_count == 0) {
    310                 if (pipes_count_ptr)
    311                         *pipes_count_ptr = pipe_count;
    312                 *pipes_ptr = NULL;
    313218                return EOK;
    314219        }
    315220
    316         usb_endpoint_mapping_t *pipes
    317             = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     221        usb_endpoint_mapping_t *pipes =
     222            calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    318223        if (pipes == NULL) {
    319224                return ENOMEM;
     
    321226
    322227        /* Now initialize. */
    323         for (i = 0; i < pipe_count; i++) {
     228        for (size_t i = 0; i < pipe_count; i++) {
    324229                pipes[i].description = endpoints[i];
    325                 pipes[i].interface_no = interface_no;
    326                 pipes[i].interface_setting = interface_setting;
     230                pipes[i].interface_no = usb_dev->interface_no;
     231                pipes[i].interface_setting =
     232                    usb_dev->alternate_interfaces.current;
    327233        }
    328234
    329235        /* Find the mapping from configuration descriptor. */
    330         rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    331             config_descr, config_descr_size, wire);
     236        int rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     237            usb_dev->descriptors.full_config,
     238            usb_dev->descriptors.full_config_size,
     239            usb_dev->bus_session);
    332240        if (rc != EOK) {
    333241                free(pipes);
     
    336244
    337245        /* Register created pipes. */
    338         for (i = 0; i < pipe_count; i++) {
     246        for (size_t i = 0; i < pipe_count; i++) {
    339247                if (pipes[i].present) {
    340248                        rc = usb_pipe_register(&pipes[i].pipe,
     
    346254        }
    347255
    348         *pipes_ptr = pipes;
    349         if (pipes_count_ptr != NULL) {
    350                 *pipes_count_ptr = pipe_count;
    351         }
     256        usb_dev->pipes = pipes;
     257        usb_dev->pipes_count = pipe_count;
    352258
    353259        return EOK;
     
    360266         */
    361267rollback_unregister_endpoints:
    362         for (i = 0; i < pipe_count; i++) {
     268        for (size_t i = 0; i < pipe_count; i++) {
    363269                if (pipes[i].present) {
    364270                        usb_pipe_unregister(&pipes[i].pipe);
     
    372278/** Destroy pipes previously created by usb_device_create_pipes.
    373279 *
    374  * @param[in] pipes Endpoint mapping to be destroyed.
    375  * @param[in] pipes_count Number of endpoints.
    376  */
    377 void usb_device_destroy_pipes(usb_endpoint_mapping_t *pipes, size_t pipes_count)
    378 {
     280 * @param[in] usb_dev USB device.
     281 */
     282void usb_device_destroy_pipes(usb_device_t *usb_dev)
     283{
     284        assert(usb_dev);
     285        assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    379286        /* Destroy the pipes. */
    380         for (size_t i = 0; i < pipes_count; ++i) {
    381                 assert(pipes);
     287        for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
    382288                usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
    383                     i, pipes[i].present ? "" : "not ");
    384                 if (pipes[i].present)
    385                         usb_pipe_unregister(&pipes[i].pipe);
    386         }
    387         free(pipes);
     289                    i, usb_dev->pipes[i].present ? "" : "not ");
     290                if (usb_dev->pipes[i].present)
     291                        usb_pipe_unregister(&usb_dev->pipes[i].pipe);
     292        }
     293        free(usb_dev->pipes);
     294        usb_dev->pipes = NULL;
     295        usb_dev->pipes_count = 0;
     296}
     297
     298usb_pipe_t *usb_device_get_default_pipe(usb_device_t *usb_dev)
     299{
     300        assert(usb_dev);
     301        return &usb_dev->ctrl_pipe;
     302}
     303
     304usb_endpoint_mapping_t *usb_device_get_mapped_ep_desc(usb_device_t *usb_dev,
     305    const usb_endpoint_description_t *desc)
     306{
     307        assert(usb_dev);
     308        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     309                if (usb_dev->pipes[i].description == desc)
     310                        return &usb_dev->pipes[i];
     311        }
     312        return NULL;
     313}
     314
     315usb_endpoint_mapping_t * usb_device_get_mapped_ep(
     316    usb_device_t *usb_dev, usb_endpoint_t ep)
     317{
     318        assert(usb_dev);
     319        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     320                if (usb_dev->pipes[i].pipe.endpoint_no == ep)
     321                        return &usb_dev->pipes[i];
     322        }
     323        return NULL;
     324}
     325
     326int usb_device_get_iface_number(usb_device_t *usb_dev)
     327{
     328        assert(usb_dev);
     329        return usb_dev->interface_no;
     330}
     331
     332devman_handle_t usb_device_get_devman_handle(usb_device_t *usb_dev)
     333{
     334        assert(usb_dev);
     335        return usb_dev->handle;
     336}
     337
     338const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
     339{
     340        assert(usb_dev);
     341        return &usb_dev->descriptors;
     342}
     343
     344const usb_alternate_interfaces_t * usb_device_get_alternative_ifaces(
     345    usb_device_t *usb_dev)
     346{
     347        assert(usb_dev);
     348        return &usb_dev->alternate_interfaces;
     349}
     350
     351/** Clean instance of a USB device.
     352 *
     353 * @param dev Device to be de-initialized.
     354 *
     355 * Does not free/destroy supplied pointer.
     356 */
     357static void usb_device_fini(usb_device_t *usb_dev)
     358{
     359        if (usb_dev) {
     360                /* Destroy existing pipes. */
     361                usb_device_destroy_pipes(usb_dev);
     362                /* Ignore errors and hope for the best. */
     363                usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
     364                usb_device_release_descriptors(usb_dev);
     365                free(usb_dev->driver_data);
     366                usb_dev->driver_data = NULL;
     367                usb_dev_disconnect(usb_dev->bus_session);
     368                usb_dev->bus_session = NULL;
     369        }
    388370}
    389371
     
    397379 * @return Error code.
    398380 */
    399 int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
    400     const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
     381static int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
     382    const usb_endpoint_description_t **endpoints, const char **errstr_ptr,
     383    devman_handle_t handle, int interface_no)
    401384{
    402385        assert(usb_dev != NULL);
    403         assert(ddf_dev != NULL);
     386        assert(errstr_ptr);
    404387
    405388        *errstr_ptr = NULL;
    406389
    407390        usb_dev->ddf_dev = ddf_dev;
     391        usb_dev->handle = handle;
     392        usb_dev->interface_no = interface_no;
    408393        usb_dev->driver_data = NULL;
    409         usb_dev->descriptors.configuration = NULL;
     394        usb_dev->descriptors.full_config = NULL;
     395        usb_dev->descriptors.full_config_size = 0;
    410396        usb_dev->pipes_count = 0;
    411397        usb_dev->pipes = NULL;
    412398
    413         /* Get assigned params */
    414         devman_handle_t hc_handle;
    415         usb_address_t address;
    416 
    417         int rc = usb_get_info_by_handle(ddf_dev_get_handle(ddf_dev),
    418             &hc_handle, &address, &usb_dev->interface_no);
    419         if (rc != EOK) {
    420                 *errstr_ptr = "device parameters retrieval";
    421                 return rc;
    422         }
    423 
    424         /* Initialize hc connection. */
    425         usb_hc_connection_initialize(&usb_dev->hc_conn, hc_handle);
    426 
    427         /* Initialize backing wire and control pipe. */
    428         rc = usb_device_connection_initialize(
    429             &usb_dev->wire, &usb_dev->hc_conn, address);
    430         if (rc != EOK) {
    431                 *errstr_ptr = "device connection initialization";
    432                 return rc;
     399        usb_dev->bus_session = usb_dev_connect(handle);
     400
     401        if (!usb_dev->bus_session) {
     402                *errstr_ptr = "device bus session create";
     403                return ENOMEM;
    433404        }
    434405
    435406        /* This pipe was registered by the hub driver,
    436407         * during device initialization. */
    437         rc = usb_pipe_initialize_default_control(
    438             &usb_dev->ctrl_pipe, &usb_dev->wire);
     408        int rc = usb_pipe_initialize_default_control(
     409            &usb_dev->ctrl_pipe, usb_dev->bus_session);
    439410        if (rc != EOK) {
     411                usb_dev_disconnect(usb_dev->bus_session);
    440412                *errstr_ptr = "default control pipe initialization";
    441413                return rc;
    442414        }
    443415
    444         /* Open hc connection for pipe registration. */
    445         rc = usb_hc_connection_open(&usb_dev->hc_conn);
    446         if (rc != EOK) {
    447                 *errstr_ptr = "hc connection open";
    448                 return rc;
    449         }
    450 
    451416        /* Retrieve standard descriptors. */
    452         rc = usb_device_retrieve_descriptors(
    453             &usb_dev->ctrl_pipe, &usb_dev->descriptors);
     417        rc = usb_device_retrieve_descriptors(usb_dev);
    454418        if (rc != EOK) {
    455419                *errstr_ptr = "descriptor retrieval";
    456                 usb_hc_connection_close(&usb_dev->hc_conn);
     420                usb_dev_disconnect(usb_dev->bus_session);
    457421                return rc;
    458422        }
     
    463427         * controlling a device. */
    464428        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    465             usb_dev->descriptors.configuration,
    466             usb_dev->descriptors.configuration_size, usb_dev->interface_no);
    467         const int alternate_iface =
    468             (rc == EOK) ? usb_dev->alternate_interfaces.current : 0;
    469 
    470         /* Create and register other pipes than default control (EP 0) */
    471         rc = usb_device_create_pipes(&usb_dev->wire, endpoints,
    472             usb_dev->descriptors.configuration,
    473             usb_dev->descriptors.configuration_size,
    474             usb_dev->interface_no, (int)alternate_iface,
    475             &usb_dev->pipes, &usb_dev->pipes_count);
    476         if (rc != EOK) {
    477                 usb_hc_connection_close(&usb_dev->hc_conn);
    478                 /* Full configuration descriptor is allocated. */
    479                 usb_device_release_descriptors(&usb_dev->descriptors);
    480                 /* Alternate interfaces may be allocated */
    481                 usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
    482                 *errstr_ptr = "pipes initialization";
    483                 return rc;
    484         }
    485 
    486         usb_hc_connection_close(&usb_dev->hc_conn);
     429            usb_dev->descriptors.full_config,
     430            usb_dev->descriptors.full_config_size, usb_dev->interface_no);
     431
     432        if (endpoints) {
     433                /* Create and register other pipes than default control (EP 0)*/
     434                rc = usb_device_create_pipes(usb_dev, endpoints);
     435                if (rc != EOK) {
     436                        usb_device_fini(usb_dev);
     437                        *errstr_ptr = "pipes initialization";
     438                        return rc;
     439                }
     440        }
     441
    487442        return EOK;
    488443}
    489444
    490 /** Clean instance of a USB device.
    491  *
    492  * @param dev Device to be de-initialized.
    493  *
    494  * Does not free/destroy supplied pointer.
    495  */
    496 void usb_device_deinit(usb_device_t *dev)
    497 {
    498         if (dev) {
    499                 /* Destroy existing pipes. */
    500                 destroy_current_pipes(dev);
    501                 /* Ignore errors and hope for the best. */
    502                 usb_hc_connection_deinitialize(&dev->hc_conn);
    503                 usb_alternate_interfaces_deinit(&dev->alternate_interfaces);
    504                 usb_device_release_descriptors(&dev->descriptors);
    505                 free(dev->driver_data);
    506                 dev->driver_data = NULL;
    507         }
     445static int usb_device_get_info(async_sess_t *sess, devman_handle_t *handle,
     446        int *iface_no)
     447{
     448        assert(handle);
     449        assert(iface_no);
     450        async_exch_t *exch = async_exchange_begin(sess);
     451        if (!exch)
     452                return EPARTY;
     453        int ret = usb_get_my_device_handle(exch, handle);
     454        if (ret == EOK) {
     455                ret = usb_get_my_interface(exch, iface_no);
     456                if (ret == ENOTSUP) {
     457                        *iface_no = -1;
     458                        ret = EOK;
     459                }
     460        }
     461        async_exchange_end(exch);
     462        return ret;
     463}
     464
     465int usb_device_create_ddf(ddf_dev_t *ddf_dev,
     466    const usb_endpoint_description_t **desc, const char **err)
     467{
     468        assert(ddf_dev);
     469        assert(err);
     470
     471        devman_handle_t h = 0;
     472        int iface_no = -1;
     473
     474        async_sess_t *sess = devman_parent_device_connect(
     475            ddf_dev_get_handle(ddf_dev), IPC_FLAG_BLOCKING);
     476        const int ret = usb_device_get_info(sess, &h, &iface_no);
     477        async_hangup(sess);
     478        if (ret != EOK)
     479                return ret;
     480
     481        usb_device_t *usb_dev =
     482            ddf_dev_data_alloc(ddf_dev, sizeof(usb_device_t));
     483        if (usb_dev == NULL) {
     484                *err = "DDF data alloc";
     485                return ENOMEM;
     486        }
     487       
     488        return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
     489}
     490
     491void usb_device_destroy_ddf(ddf_dev_t *ddf_dev)
     492{
     493        assert(ddf_dev);
     494        usb_device_t *usb_dev = ddf_dev_data_get(ddf_dev);
     495        assert(usb_dev);
     496        usb_device_fini(usb_dev);
     497        return;
     498}
     499
     500usb_device_t * usb_device_create(devman_handle_t handle)
     501{
     502        devman_handle_t h = 0;
     503        int iface_no = -1;
     504
     505        async_sess_t *sess = devman_device_connect(handle, IPC_FLAG_BLOCKING);
     506        int ret = usb_device_get_info(sess, &h, &iface_no);
     507        if (sess)
     508                async_hangup(sess);
     509        if (ret != EOK)
     510                return NULL;
     511
     512        usb_device_t *usb_dev = malloc(sizeof(usb_device_t));
     513        if (!usb_dev)
     514                return NULL;
     515
     516        const char* dummy = NULL;
     517        ret = usb_device_init(usb_dev, NULL, NULL, &dummy, handle, iface_no);
     518        if (ret != EOK) {
     519                free(usb_dev);
     520                usb_dev = NULL;
     521        }
     522        return usb_dev;
     523}
     524
     525void usb_device_destroy(usb_device_t *usb_dev)
     526{
     527        if (usb_dev) {
     528                usb_device_fini(usb_dev);
     529                free(usb_dev);
     530        }
     531}
     532
     533const char *usb_device_get_name(usb_device_t *usb_dev)
     534{
     535        assert(usb_dev);
     536        if (usb_dev->ddf_dev)
     537                return ddf_dev_get_name(usb_dev->ddf_dev);
     538        return NULL;
     539}
     540
     541ddf_fun_t *usb_device_ddf_fun_create(usb_device_t *usb_dev, fun_type_t ftype,
     542    const char* name)
     543{
     544        assert(usb_dev);
     545        if (usb_dev->ddf_dev)
     546                return ddf_fun_create(usb_dev->ddf_dev, ftype, name);
     547        return NULL;
     548}
     549
     550async_exch_t * usb_device_bus_exchange_begin(usb_device_t *usb_dev)
     551{
     552        assert(usb_dev);
     553        return async_exchange_begin(usb_dev->bus_session);
     554}
     555
     556void usb_device_bus_exchange_end(async_exch_t *exch)
     557{
     558        async_exchange_end(exch);
    508559}
    509560
     
    521572}
    522573
     574void * usb_device_data_get(usb_device_t *usb_dev)
     575{
     576        assert(usb_dev);
     577        return usb_dev->driver_data;
     578}
     579
    523580/**
    524581 * @}
  • uspace/lib/usbdev/src/devpoll.c

    r5b18137 rb4b534ac  
    3333 * USB device driver framework - automatic interrupt polling.
    3434 */
     35#include <usb/dev/device.h>
     36#include <usb/dev/pipes.h>
    3537#include <usb/dev/poll.h>
    3638#include <usb/dev/request.h>
     39#include <usb/classes/classes.h>
    3740#include <usb/debug.h>
    38 #include <usb/classes/classes.h>
     41#include <usb/descriptor.h>
     42#include <usb/usb.h>
     43
     44#include <assert.h>
     45#include <async.h>
    3946#include <errno.h>
     47#include <fibril.h>
     48#include <stdbool.h>
     49#include <stdlib.h>
    4050#include <str_error.h>
    41 #include <assert.h>
     51#include <sys/types.h>
    4252
    4353/** Maximum number of failed consecutive requests before announcing failure. */
     
    5161        /** USB device to poll. */
    5262        usb_device_t *dev;
    53         /** Device pipe to use for polling. */
    54         size_t pipe_index;
     63        /** Device enpoint mapping to use for polling. */
     64        usb_endpoint_mapping_t *polling_mapping;
    5565        /** Size of the recieved data. */
    5666        size_t request_size;
     
    7282        const usb_device_auto_polling_t *params = &data->auto_polling;
    7383
    74         usb_pipe_t *pipe
    75             = &data->dev->pipes[data->pipe_index].pipe;
     84        usb_pipe_t *pipe = &data->polling_mapping->pipe;
    7685
    7786        if (params->debug > 0) {
    7887                const usb_endpoint_mapping_t *mapping
    79                     = &data->dev->pipes[data->pipe_index];
    80                 usb_log_debug("Poll%p: started polling of `%s' - " \
     88                    = data->polling_mapping;
     89                usb_log_debug("Poll (%p): started polling of `%s' - " \
    8190                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
    82                     data, ddf_dev_get_name(data->dev->ddf_dev),
     91                    data, usb_device_get_name(data->dev),
    8392                    (int) mapping->interface->interface_number,
    8493                    usb_str_class(mapping->interface->interface_class),
     
    8897        }
    8998
    90         usb_pipe_start_long_transfer(pipe);
    9199        size_t failed_attempts = 0;
    92100        while (failed_attempts <= params->max_failures) {
     
    95103                    data->request_size, &actual_size);
    96104
    97                 if (params->debug > 1) {
    98                         if (rc == EOK) {
     105                if (rc == EOK) {
     106                        if (params->debug > 1) {
    99107                                usb_log_debug(
    100108                                    "Poll%p: received: '%s' (%zuB).\n",
     
    103111                                        actual_size, 16),
    104112                                    actual_size);
    105                         } else {
     113                        }
     114                } else {
    106115                                usb_log_debug(
    107116                                    "Poll%p: polling failed: %s.\n",
    108117                                    data, str_error(rc));
    109                         }
    110118                }
    111119
     
    117125                         */
    118126                        usb_request_clear_endpoint_halt(
    119                             &data->dev->ctrl_pipe, pipe->endpoint_no);
     127                            usb_device_get_default_pipe(data->dev),
     128                            pipe->endpoint_no);
    120129                }
    121130
     
    145154
    146155                /* Take a rest before next request. */
     156                //TODO: This is broken, the time is in ms not us.
     157                // but first we need to fix drivers to actually stop using this,
     158                // since polling dealy should be implemented in HC schedule
    147159                async_usleep(params->delay);
    148160        }
    149 
    150         usb_pipe_end_long_transfer(pipe);
    151161
    152162        const bool failed = failed_attempts > 0;
     
    159169                if (failed) {
    160170                        usb_log_error("Polling of device `%s' terminated: "
    161                             "recurring failures.\n", ddf_dev_get_name(
    162                             data->dev->ddf_dev));
     171                            "recurring failures.\n",
     172                            usb_device_get_name(data->dev));
    163173                } else {
    164174                        usb_log_debug("Polling of device `%s' terminated: "
    165                             "driver request.\n", ddf_dev_get_name(
    166                             data->dev->ddf_dev));
     175                            "driver request.\n",
     176                            usb_device_get_name(data->dev));
    167177                }
    168178        }
     
    175185}
    176186
     187
    177188/** Start automatic device polling over interrupt in pipe.
    178189 *
    179  * @warning It is up to the callback to produce delays between individual
    180  * requests.
     190 * The polling settings is copied thus it is okay to destroy the structure
     191 * after this function returns.
    181192 *
    182193 * @warning There is no guarantee when the request to the device
     
    185196 *
    186197 * @param dev Device to be periodically polled.
     198 * @param epm Endpoint mapping to use.
     199 * @param polling Polling settings.
     200 * @param request_size How many bytes to ask for in each request.
     201 * @param arg Custom argument (passed as is to the callbacks).
     202 * @return Error code.
     203 * @retval EOK New fibril polling the device was already started.
     204 */
     205static int usb_device_auto_polling_internal(usb_device_t *dev,
     206    usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
     207    size_t request_size)
     208{
     209        if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
     210                return EBADMEM;
     211        }
     212
     213        if (request_size == 0)
     214                return EINVAL;
     215
     216        if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
     217            (epm->pipe.direction != USB_DIRECTION_IN))
     218                return EINVAL;
     219
     220
     221        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
     222        if (polling_data == NULL) {
     223                return ENOMEM;
     224        }
     225
     226        /* Fill-in the data. */
     227        polling_data->buffer = malloc(sizeof(request_size));
     228        if (polling_data->buffer == NULL) {
     229                free(polling_data);
     230                return ENOMEM;
     231        }
     232        polling_data->request_size = request_size;
     233        polling_data->dev = dev;
     234        polling_data->polling_mapping = epm;
     235
     236        /* Copy provided settings. */
     237        polling_data->auto_polling = *polling;
     238
     239        /* Negative value means use descriptor provided value. */
     240        if (polling->delay < 0) {
     241                polling_data->auto_polling.delay =
     242                    epm->descriptor->poll_interval;
     243        }
     244
     245        fid_t fibril = fibril_create(polling_fibril, polling_data);
     246        if (fibril == 0) {
     247                free(polling_data->buffer);
     248                free(polling_data);
     249                return ENOMEM;
     250        }
     251        fibril_add_ready(fibril);
     252
     253        /* Fibril launched. That fibril will free the allocated data. */
     254
     255        return EOK;
     256}
     257/** Start automatic device polling over interrupt in pipe.
     258 *
     259 * The polling settings is copied thus it is okay to destroy the structure
     260 * after this function returns.
     261 *
     262 * @warning There is no guarantee when the request to the device
     263 * will be sent for the first time (it is possible that this
     264 * first request would be executed prior to return from this function).
     265 *
     266 * @param dev Device to be periodically polled.
    187267 * @param pipe_index Index of the endpoint pipe used for polling.
     268 * @param polling Polling settings.
     269 * @param req_size How many bytes to ask for in each request.
     270 * @param arg Custom argument (passed as is to the callbacks).
     271 * @return Error code.
     272 * @retval EOK New fibril polling the device was already started.
     273 */
     274int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
     275    const usb_device_auto_polling_t *polling, size_t req_size)
     276{
     277        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
     278        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     279}
     280
     281/** Start automatic device polling over interrupt in pipe.
     282 *
     283 * @warning It is up to the callback to produce delays between individual
     284 * requests.
     285 *
     286 * @warning There is no guarantee when the request to the device
     287 * will be sent for the first time (it is possible that this
     288 * first request would be executed prior to return from this function).
     289 *
     290 * @param dev Device to be periodically polled.
     291 * @param ep Endpoint  used for polling.
    188292 * @param callback Callback when data are available.
    189293 * @param request_size How many bytes to ask for in each request.
     294 * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    190295 * @param terminated_callback Callback when polling is terminated.
    191296 * @param arg Custom argument (passed as is to the callbacks).
     
    193298 * @retval EOK New fibril polling the device was already started.
    194299 */
    195 int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
    196     usb_polling_callback_t callback, size_t request_size,
     300int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
     301    usb_polling_callback_t callback, size_t request_size, int delay,
    197302    usb_polling_terminted_callback_t terminated_callback, void *arg)
    198303{
     
    200305                .debug = 1,
    201306                .auto_clear_halt = true,
    202                 .delay = 0,
     307                .delay = delay,
    203308                .max_failures = MAX_FAILED_ATTEMPTS,
    204309                .on_data = callback,
     
    208313        };
    209314
    210         return usb_device_auto_polling(dev, pipe_index, &auto_polling,
    211            request_size);
    212 }
    213 
    214 /** Start automatic device polling over interrupt in pipe.
    215  *
    216  * The polling settings is copied thus it is okay to destroy the structure
    217  * after this function returns.
    218  *
    219  * @warning There is no guarantee when the request to the device
    220  * will be sent for the first time (it is possible that this
    221  * first request would be executed prior to return from this function).
    222  *
    223  * @param dev Device to be periodically polled.
    224  * @param pipe_index Index of the endpoint pipe used for polling.
    225  * @param polling Polling settings.
    226  * @param request_size How many bytes to ask for in each request.
    227  * @param arg Custom argument (passed as is to the callbacks).
    228  * @return Error code.
    229  * @retval EOK New fibril polling the device was already started.
    230  */
    231 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
    232     const usb_device_auto_polling_t *polling,
    233     size_t request_size)
    234 {
    235         if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
    236                 return EBADMEM;
    237         }
    238 
    239         if (pipe_index >= dev->pipes_count || request_size == 0) {
    240                 return EINVAL;
    241         }
    242         if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
    243             || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
    244                 return EINVAL;
    245         }
    246 
    247         polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    248         if (polling_data == NULL) {
    249                 return ENOMEM;
    250         }
    251 
    252         /* Fill-in the data. */
    253         polling_data->buffer = malloc(sizeof(request_size));
    254         if (polling_data->buffer == NULL) {
    255                 free(polling_data);
    256                 return ENOMEM;
    257         }
    258         polling_data->request_size = request_size;
    259         polling_data->dev = dev;
    260         polling_data->pipe_index = pipe_index;
    261 
    262         /* Copy provided settings. */
    263         polling_data->auto_polling = *polling;
    264 
    265         /* Negative value means use descriptor provided value. */
    266         if (polling->delay < 0) {
    267                 polling_data->auto_polling.delay =
    268                     (int) dev->pipes[pipe_index].descriptor->poll_interval;
    269         }
    270 
    271         fid_t fibril = fibril_create(polling_fibril, polling_data);
    272         if (fibril == 0) {
    273                 free(polling_data->buffer);
    274                 free(polling_data);
    275                 return ENOMEM;
    276         }
    277         fibril_add_ready(fibril);
    278 
    279         /* Fibril launched. That fibril will free the allocated data. */
    280 
    281         return EOK;
     315        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
     316        return usb_device_auto_polling_internal(
     317            dev, epm, &auto_polling, request_size);
     318}
     319
     320int usb_device_auto_polling_desc(usb_device_t *usb_dev,
     321    const usb_endpoint_description_t *desc,
     322    const usb_device_auto_polling_t *polling, size_t req_size)
     323{
     324        usb_endpoint_mapping_t *epm =
     325            usb_device_get_mapped_ep_desc(usb_dev, desc);
     326        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     327}
     328
     329int usb_device_auto_poll_desc(usb_device_t * usb_dev,
     330    const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
     331    size_t req_size, int delay,
     332    usb_polling_terminted_callback_t terminated_callback, void *arg)
     333{
     334        const usb_device_auto_polling_t auto_polling = {
     335                .debug = 1,
     336                .auto_clear_halt = true,
     337                .delay = delay,
     338                .max_failures = MAX_FAILED_ATTEMPTS,
     339                .on_data = callback,
     340                .on_polling_end = terminated_callback,
     341                .on_error = NULL,
     342                .arg = arg,
     343        };
     344
     345        usb_endpoint_mapping_t *epm =
     346            usb_device_get_mapped_ep_desc(usb_dev, desc);
     347        return usb_device_auto_polling_internal(
     348            usb_dev, epm, &auto_polling, req_size);
    282349}
    283350
  • uspace/lib/usbdev/src/dp.c

    r5b18137 rb4b534ac  
    4141 * sibling.
    4242 */
    43 #include <stdio.h>
    44 #include <str_error.h>
    45 #include <errno.h>
    46 #include <assert.h>
    47 #include <stdbool.h>
    4843#include <usb/dev/dp.h>
    4944#include <usb/descriptor.h>
     45
     46#include <assert.h>
     47#include <errno.h>
     48#include <stdlib.h>
     49#include <stdbool.h>
     50#include <sys/types.h>
    5051
    5152#define NESTING(parentname, childname) \
     
    304305 * @param arg Custom (user) argument.
    305306 */
    306 void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
     307void usb_dp_walk_simple(const uint8_t *descriptors, size_t descriptors_size,
    307308    const usb_dp_descriptor_nesting_t *descriptor_nesting,
    308309    walk_callback_t callback, void *arg)
  • uspace/lib/usbdev/src/pipes.c

    r5b18137 rb4b534ac  
    3535#include <usb/dev/pipes.h>
    3636#include <usb/dev/request.h>
     37#include <usb/usb.h>
     38#include <usb_iface.h>
     39
     40#include <assert.h>
     41#include <async.h>
    3742#include <errno.h>
    38 #include <assert.h>
    39 
    40 /** Prepare pipe for a long transfer.
    41  *
    42  * Long transfer is transfer consisting of several requests to the HC.
    43  * Calling this function is optional and it has positive effect of
    44  * improved performance because IPC session is initiated only once.
    45  *
    46  * @param pipe Pipe over which the transfer will happen.
    47  * @return Error code.
    48  */
    49 int usb_pipe_start_long_transfer(usb_pipe_t *pipe)
    50 {
    51         assert(pipe);
    52         assert(pipe->wire);
    53         assert(pipe->wire->hc_connection);
    54         return usb_hc_connection_open(pipe->wire->hc_connection);
    55 }
    56 
    57 /** Terminate a long transfer on a pipe.
    58  * @param pipe Pipe where to end the long transfer.
    59  * @return Error code.
    60  * @see usb_pipe_start_long_transfer
    61  */
    62 int usb_pipe_end_long_transfer(usb_pipe_t *pipe)
    63 {
    64         assert(pipe);
    65         assert(pipe->wire);
    66         assert(pipe->wire->hc_connection);
    67         return usb_hc_connection_close(pipe->wire->hc_connection);
    68 }
     43#include <mem.h>
    6944
    7045/** Try to clear endpoint halt of default control pipe.
     
    12196        memcpy(&setup_packet, setup_buffer, 8);
    12297
     98        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    12399        size_t act_size = 0;
    124         const int rc = usb_device_control_read(pipe->wire,
     100        const int rc = usb_read(exch,
    125101            pipe->endpoint_no, setup_packet, buffer, buffer_size, &act_size);
     102        async_exchange_end(exch);
    126103
    127104        if (rc == ESTALL) {
     
    173150        memcpy(&setup_packet, setup_buffer, 8);
    174151
    175         const int rc = usb_device_control_write(pipe->wire,
     152        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     153        const int rc = usb_write(exch,
    176154            pipe->endpoint_no, setup_packet, buffer, buffer_size);
     155        async_exchange_end(exch);
    177156
    178157        if (rc == ESTALL) {
     
    217196            return ENOTSUP;
    218197
     198        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    219199        size_t act_size = 0;
    220         const int rc = usb_device_read(pipe->wire,
    221             pipe->endpoint_no, buffer, size, &act_size);
     200        const int rc =
     201            usb_read(exch, pipe->endpoint_no, 0, buffer, size, &act_size);
     202        async_exchange_end(exch);
    222203
    223204        if (rc == EOK && size_transfered != NULL) {
     
    256237            return ENOTSUP;
    257238
    258         return usb_device_write(pipe->wire,
    259             pipe->endpoint_no, buffer, size);
     239        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     240        const int rc = usb_write(exch, pipe->endpoint_no, 0, buffer, size);
     241        async_exchange_end(exch);
     242        return rc;
    260243}
    261244
     
    263246 *
    264247 * @param pipe Endpoint pipe to be initialized.
    265  * @param connection Connection to the USB device backing this pipe (the wire).
    266248 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
    267249 * @param transfer_type Transfer type (e.g. interrupt or bulk).
     
    270252 * @return Error code.
    271253 */
    272 int usb_pipe_initialize(usb_pipe_t *pipe,
    273     usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
     254int usb_pipe_initialize(usb_pipe_t *pipe, usb_endpoint_t endpoint_no,
    274255    usb_transfer_type_t transfer_type, size_t max_packet_size,
    275     usb_direction_t direction)
    276 {
    277         assert(pipe);
    278         assert(connection);
    279 
    280         pipe->wire = connection;
     256    usb_direction_t direction, unsigned packets, usb_dev_session_t *bus_session)
     257{
     258        assert(pipe);
     259
    281260        pipe->endpoint_no = endpoint_no;
    282261        pipe->transfer_type = transfer_type;
     262        pipe->packets = packets;
    283263        pipe->max_packet_size = max_packet_size;
    284264        pipe->direction = direction;
    285265        pipe->auto_reset_halt = false;
     266        pipe->bus_session = bus_session;
    286267
    287268        return EOK;
     
    291272 *
    292273 * @param pipe Endpoint pipe to be initialized.
    293  * @param connection Connection to the USB device backing this pipe (the wire).
    294274 * @return Error code.
    295275 */
    296276int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
    297     usb_device_connection_t *connection)
    298 {
    299         assert(pipe);
    300         assert(connection);
    301 
    302         int rc = usb_pipe_initialize(pipe, connection, 0, USB_TRANSFER_CONTROL,
    303             CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH);
     277    usb_dev_session_t *bus_session)
     278{
     279        assert(pipe);
     280
     281        const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
     282            CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, bus_session);
    304283
    305284        pipe->auto_reset_halt = true;
     
    317296{
    318297        assert(pipe);
    319         assert(pipe->wire);
    320 
    321         return usb_device_register_endpoint(pipe->wire,
    322            pipe->endpoint_no, pipe->transfer_type,
    323            pipe->direction, pipe->max_packet_size, interval);
     298        assert(pipe->bus_session);
     299        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     300        if (!exch)
     301                return ENOMEM;
     302        const int ret = usb_register_endpoint(exch, pipe->endpoint_no,
     303            pipe->transfer_type, pipe->direction, pipe->max_packet_size,
     304            pipe->packets, interval);
     305        async_exchange_end(exch);
     306        return ret;
    324307}
    325308
     
    332315{
    333316        assert(pipe);
    334         assert(pipe->wire);
    335 
    336         return usb_device_unregister_endpoint(pipe->wire,
    337             pipe->endpoint_no, pipe->direction);
     317        assert(pipe->bus_session);
     318        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     319        if (!exch)
     320                return ENOMEM;
     321        const int ret = usb_unregister_endpoint(exch, pipe->endpoint_no,
     322            pipe->direction);
     323        async_exchange_end(exch);
     324        return ret;
    338325}
    339326
  • uspace/lib/usbdev/src/pipesinit.c

    r5b18137 rb4b534ac  
    3434 *
    3535 */
    36 #include <usb/usb.h>
    3736#include <usb/dev/pipes.h>
    3837#include <usb/dev/dp.h>
    3938#include <usb/dev/request.h>
     39#include <usb/usb.h>
     40#include <usb/descriptor.h>
     41
     42#include <assert.h>
    4043#include <errno.h>
    41 #include <assert.h>
    4244
    4345#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
     
    148150 * @param interface Interface descriptor under which belongs the @p endpoint.
    149151 * @param endpoint Endpoint descriptor.
    150  * @param wire Connection backing the endpoint pipes.
    151152 * @return Error code.
    152153 */
     
    155156    usb_standard_interface_descriptor_t *interface,
    156157    usb_standard_endpoint_descriptor_t *endpoint_desc,
    157     usb_device_connection_t *wire)
     158    usb_dev_session_t *bus_session)
    158159{
    159160
     
    193194        }
    194195
    195         int rc = usb_pipe_initialize(&ep_mapping->pipe, wire,
     196        int rc = usb_pipe_initialize(&ep_mapping->pipe,
    196197            ep_no, description.transfer_type,
    197             uint16_usb2host(endpoint_desc->max_packet_size),
    198             description.direction);
     198            ED_MPS_PACKET_SIZE_GET(
     199                uint16_usb2host(endpoint_desc->max_packet_size)),
     200            description.direction,
     201            ED_MPS_TRANS_OPPORTUNITIES_GET(
     202                uint16_usb2host(endpoint_desc->max_packet_size)), bus_session);
    199203        if (rc != EOK) {
    200204                return rc;
     
    220224    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    221225    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data,
    222     const uint8_t *interface_descriptor)
     226    const uint8_t *interface_descriptor, usb_dev_session_t *bus_session)
    223227{
    224228        const uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
     
    236240                            (usb_standard_endpoint_descriptor_t *)
    237241                                descriptor,
    238                             (usb_device_connection_t *) parser_data->arg);
     242                            bus_session);
    239243                }
    240244
     
    280284    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    281285    const uint8_t *config_descriptor, size_t config_descriptor_size,
    282     usb_device_connection_t *connection)
    283 {
    284         assert(connection);
     286    usb_dev_session_t *bus_session)
     287{
    285288
    286289        if (config_descriptor == NULL) {
     
    306309                .data = config_descriptor,
    307310                .size = config_descriptor_size,
    308                 .arg = connection
    309311        };
    310312
     
    319321        do {
    320322                (void) process_interface(mapping, mapping_count,
    321                     &dp_parser, &dp_data, interface);
     323                    &dp_parser, &dp_data, interface, bus_session);
    322324                interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    323325                    config_descriptor, interface);
     
    347349                return EINVAL;
    348350        }
    349 
    350 
    351         usb_pipe_start_long_transfer(pipe);
    352351
    353352        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
     
    367366                }
    368367        }
    369         usb_pipe_end_long_transfer(pipe);
    370368        if (rc != EOK) {
    371369                return rc;
  • uspace/lib/usbdev/src/recognise.c

    r5b18137 rb4b534ac  
    3434 */
    3535
    36 #include <sys/types.h>
    37 #include <fibril_synch.h>
    38 #include <usb/debug.h>
    39 #include <usb/dev/hub.h>
    4036#include <usb/dev/pipes.h>
    4137#include <usb/dev/recognise.h>
    42 #include <usb/ddfiface.h>
    4338#include <usb/dev/request.h>
    4439#include <usb/classes/classes.h>
     40
     41#include <assert.h>
     42#include <errno.h>
    4543#include <stdio.h>
    46 #include <errno.h>
    47 #include <assert.h>
    48 
    49 /** DDF operations of child devices. */
    50 static ddf_dev_ops_t child_ops = {
    51         .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    52 };
     44#include <sys/types.h>
    5345
    5446/** Get integer part from BCD coded number. */
     
    242234                    (int) device_descriptor->product_id,
    243235                    BCD_ARGS(device_descriptor->device_version));
    244                
     236
    245237                /* Next, without release number. */
    246238                ADD_MATCHID_OR_RETURN(matches, 90,
     
    248240                    (int) device_descriptor->vendor_id,
    249241                    (int) device_descriptor->product_id);
    250         }       
    251 
    252         /*
    253          * If the device class points to interface we skip adding
    254          * class directly but we add a multi interface device.
    255          */
    256         if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
    257                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
    258                     usb_str_class(device_descriptor->device_class));
    259         } else {
    260                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid");
    261         }
    262        
     242        }
     243
     244        /* Class match id */
     245        ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
     246            usb_str_class(device_descriptor->device_class));
     247
    263248        /* As a last resort, try fallback driver. */
    264249        ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
     
    302287}
    303288
    304 /** Probe for device kind and register it in devman.
    305  *
    306  * @param[in] ctrl_pipe Control pipe to the device.
    307  * @param[in] parent Parent device.
    308  * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
    309  * @param[in] dev_data Arbitrary pointer to be stored in the child
    310  *      as @c driver_data.
    311  * @param[out] child_fun Storage where pointer to allocated child function
    312  *      will be written.
    313  * @return Error code.
    314  *
    315  */
    316 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    317     ddf_dev_t *parent, ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
    318 {
    319         if (ctrl_pipe == NULL)
    320                 return EINVAL;
    321        
    322         if (!dev_ops && ddf_fun_data_get(fun) != NULL) {
    323                 usb_log_warning("Using standard fun ops with arbitrary "
    324                     "driver data. This does not have to work.\n");
    325         }
    326        
    327         /** Index to append after device name for uniqueness. */
    328         static atomic_t device_name_index = {0};
    329         const size_t this_device_name_index =
    330             (size_t) atomic_preinc(&device_name_index);
    331        
    332         int rc;
    333        
    334         /*
    335          * TODO: Once the device driver framework support persistent
    336          * naming etc., something more descriptive could be created.
    337          */
    338         char child_name[12];  /* The format is: "usbAB_aXYZ", length 11 */
    339         rc = snprintf(child_name, sizeof(child_name),
    340             "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address);
    341         if (rc < 0) {
    342                 goto failure;
    343         }
    344        
    345         rc = ddf_fun_set_name(fun, child_name);
    346         if (rc != EOK)
    347                 goto failure;
    348        
    349         if (dev_ops != NULL)
    350                 ddf_fun_set_ops(fun, dev_ops);
    351         else
    352                 ddf_fun_set_ops(fun, &child_ops);
    353        
    354         /*
    355          * Store the attached device in fun
    356          * driver data if there is no other data
    357          */
    358         if (ddf_fun_data_get(fun) == NULL) {
    359                 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
    360                     fun, sizeof(usb_hub_attached_device_t));
    361                 if (!new_device) {
    362                         rc = ENOMEM;
    363                         goto failure;
    364                 }
    365                
    366                 new_device->address = ctrl_pipe->wire->address;
    367                 new_device->fun = fun;
    368         }
    369        
    370         match_id_list_t match_ids;
    371         init_match_ids(&match_ids);
    372         rc = usb_device_create_match_ids(ctrl_pipe, &match_ids);
    373         if (rc != EOK)
    374                 goto failure;
    375        
    376         list_foreach(match_ids.ids, link, match_id_t, match_id) {
    377                 rc = ddf_fun_add_match_id(fun, match_id->id, match_id->score);
    378                 if (rc != EOK) {
    379                         clean_match_ids(&match_ids);
    380                         goto failure;
    381                 }
    382         }
    383        
    384         clean_match_ids(&match_ids);
    385        
    386         rc = ddf_fun_bind(fun);
    387         if (rc != EOK)
    388                 goto failure;
    389        
    390         return EOK;
    391        
    392 failure:
    393         return rc;
    394 }
    395 
    396289/**
    397290 * @}
  • uspace/lib/usbdev/src/request.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/dev/request.h>
     36#include <usb/request.h>
     37#include <usb/usb.h>
     38
    3639#include <errno.h>
    37 #include <assert.h>
    38 #include <usb/debug.h>
     40#include <mem.h>
     41#include <stdlib.h>
     42#include <str.h>
    3943
    4044#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
     
    5155 * @param request Actual request (e.g. GET_DESCRIPTOR).
    5256 * @param value Value of @c wValue field of setup packet
    53  *      (must be in USB endianness).
     57 *      (must be in USB endianness).
    5458 * @param index Value of @c wIndex field of setup packet
    55  *      (must be in USB endianness).
     59 *      (must be in USB endianness).
    5660 * @param data Data to be sent during DATA stage
    57  *      (expected to be in USB endianness).
     61 *      (expected to be in USB endianness).
    5862 * @param data_size Size of the @p data buffer (in native endianness).
    5963 * @return Error code.
     
    6468int usb_control_request_set(usb_pipe_t *pipe,
    6569    usb_request_type_t request_type, usb_request_recipient_t recipient,
    66     uint8_t request,
    67     uint16_t value, uint16_t index,
    68     void *data, size_t data_size)
     70    uint8_t request, uint16_t value, uint16_t index,
     71    const void *data, size_t data_size)
    6972{
    7073        if (pipe == NULL) {
     
    8588         */
    8689
    87         usb_device_request_setup_packet_t setup_packet;
    88         setup_packet.request_type = (request_type << 5) | recipient;
    89         setup_packet.request = request;
    90         setup_packet.value = value;
    91         setup_packet.index = index;
    92         setup_packet.length = (uint16_t) data_size;
    93 
    94         int rc = usb_pipe_control_write(pipe,
    95             &setup_packet, sizeof(setup_packet),
    96             data, data_size);
    97 
    98         return rc;
     90        const usb_device_request_setup_packet_t setup_packet = {
     91                .request_type = (request_type << 5) | recipient,
     92                .request = request,
     93                .value = value,
     94                .index = index,
     95                .length = (uint16_t) data_size,
     96        };
     97
     98        return usb_pipe_control_write(pipe,
     99            &setup_packet, sizeof(setup_packet), data, data_size);
    99100}
    100101
     
    108109  * @param request Actual request (e.g. GET_DESCRIPTOR).
    109110  * @param value Value of @c wValue field of setup packet
    110   *     (must be in USB endianness).
     111  *     (must be in USB endianness).
    111112  * @param index Value of @c wIndex field of setup packet
    112113  *     (must be in USB endianness).
     
    114115  *     (they will come in USB endianness).
    115116  * @param data_size Size of the @p data buffer
    116   *     (in native endianness).
     117  *     (in native endianness).
    117118  * @param actual_data_size Actual size of transfered data
    118   *        (in native endianness).
     119  *     (in native endianness).
    119120  * @return Error code.
    120121  * @retval EBADMEM @p pipe is NULL.
     
    124125int usb_control_request_get(usb_pipe_t *pipe,
    125126    usb_request_type_t request_type, usb_request_recipient_t recipient,
    126     uint8_t request,
    127     uint16_t value, uint16_t index,
     127    uint8_t request, uint16_t value, uint16_t index,
    128128    void *data, size_t data_size, size_t *actual_data_size)
    129129{
     
    209209{
    210210        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    211                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    212                     && (index != 0)) {
     211                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0))
     212                {
    213213                        return EINVAL;
    214214                }
    215215        }
    216216
    217         int rc = usb_control_request_set(pipe, request_type, recipient,
    218             USB_DEVREQ_CLEAR_FEATURE,
    219             uint16_host2usb(feature_selector), uint16_host2usb(index),
    220             NULL, 0);
    221 
    222         return rc;
     217        return usb_control_request_set(pipe,
     218            request_type, recipient, USB_DEVREQ_CLEAR_FEATURE,
     219            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    223220}
    224221
     
    237234{
    238235        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    239                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    240                     && (index != 0)) {
     236                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0))
     237                {
    241238                        return EINVAL;
    242239                }
    243240        }
    244241
    245         int rc = usb_control_request_set(pipe, request_type, recipient,
    246             USB_DEVREQ_SET_FEATURE,
    247             uint16_host2usb(feature_selector), uint16_host2usb(index),
    248             NULL, 0);
    249 
    250         return rc;
     242        return usb_control_request_set(pipe,
     243            request_type, recipient, USB_DEVREQ_SET_FEATURE,
     244            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    251245}
    252246
     
    277271        }
    278272
     273        /* The wValue field specifies the descriptor type in the high byte
     274         * and the descriptor index in the low byte. USB 1.1 spec p. 189
     275         */
    279276        const uint16_t wValue = descriptor_index | (descriptor_type << 8);
    280277
     
    313310         * Get only first byte to retrieve descriptor length.
    314311         */
    315         uint8_t tmp_buffer[1];
     312        uint8_t tmp_buffer;
    316313        size_t bytes_transfered;
    317314        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    318315            descriptor_type, descriptor_index, language,
    319             &tmp_buffer, 1, &bytes_transfered);
     316            &tmp_buffer, sizeof(tmp_buffer), &bytes_transfered);
    320317        if (rc != EOK) {
    321318                return rc;
    322319        }
    323320        if (bytes_transfered != 1) {
    324                 /* FIXME: some better error code? */
    325                 return ESTALL;
    326         }
    327 
    328         size_t size = tmp_buffer[0];
     321                return ELIMIT;
     322        }
     323
     324        const size_t size = tmp_buffer;
    329325        if (size == 0) {
    330                 /* FIXME: some better error code? */
    331                 return ESTALL;
     326                return ELIMIT;
    332327        }
    333328
     
    349344        if (bytes_transfered != size) {
    350345                free(buffer);
    351                 /* FIXME: some better error code? */
    352                 return ESTALL;
     346                return ELIMIT;
    353347        }
    354348
     
    378372        int rc = usb_request_get_descriptor(pipe,
    379373            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    380             USB_DESCTYPE_DEVICE, 0, 0,
    381             &descriptor_tmp, sizeof(descriptor_tmp),
     374            USB_DESCTYPE_DEVICE, 0, 0, &descriptor_tmp, sizeof(descriptor_tmp),
    382375            &actually_transferred);
    383376
     
    421414        size_t actually_transferred = 0;
    422415        usb_standard_configuration_descriptor_t descriptor_tmp;
    423         int rc = usb_request_get_descriptor(pipe,
     416        const int rc = usb_request_get_descriptor(pipe,
    424417            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    425418            USB_DESCTYPE_CONFIGURATION, index, 0,
     
    479472int usb_request_get_full_configuration_descriptor_alloc(
    480473    usb_pipe_t *pipe, int index,
    481     void **descriptor_ptr, size_t *descriptor_size)
     474    const void **descriptor_ptr, size_t *descriptor_size)
    482475{
    483476        int rc;
     
    546539    usb_request_type_t request_type, usb_request_recipient_t recipient,
    547540    uint8_t descriptor_type, uint8_t descriptor_index,
    548     uint16_t language,
    549     void *buffer, size_t size)
     541    uint16_t language, const void *buffer, size_t size)
    550542{
    551543        if (buffer == NULL) {
     
    560552
    561553        return usb_control_request_set(pipe,
    562             request_type, recipient,
    563             USB_DEVREQ_SET_DESCRIPTOR,
    564             wValue, language,
    565             buffer, size);
     554            request_type, recipient, USB_DEVREQ_SET_DESCRIPTOR,
     555            wValue, language, buffer, size);
    566556}
    567557
     
    578568        size_t actual_size;
    579569
    580         int rc = usb_control_request_get(pipe,
     570        const int rc = usb_control_request_get(pipe,
    581571            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    582             USB_DEVREQ_GET_CONFIGURATION,
    583             0, 0,
    584             &value, 1, &actual_size);
     572            USB_DEVREQ_GET_CONFIGURATION, 0, 0, &value, 1, &actual_size);
    585573
    586574        if (rc != EOK) {
     
    607595    uint8_t configuration_value)
    608596{
    609         uint16_t config_value
     597        const uint16_t config_value
    610598            = uint16_host2usb((uint16_t) configuration_value);
    611599
     
    629617        size_t actual_size;
    630618
    631         int rc = usb_control_request_get(pipe,
     619        const int rc = usb_control_request_get(pipe,
    632620            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    633621            USB_DEVREQ_GET_INTERFACE,
    634622            0, uint16_host2usb((uint16_t) interface_index),
    635             &value, 1, &actual_size);
     623            &value, sizeof(value), &actual_size);
    636624
    637625        if (rc != EOK) {
     
    678666    l18_win_locales_t **languages_ptr, size_t *languages_count)
    679667{
    680         int rc;
    681 
    682         if (languages_ptr == NULL) {
    683                 return EBADMEM;
    684         }
    685         if (languages_count == NULL) {
     668        if (languages_ptr == NULL || languages_count == NULL) {
    686669                return EBADMEM;
    687670        }
     
    689672        uint8_t *string_descriptor = NULL;
    690673        size_t string_descriptor_size = 0;
    691         rc = usb_request_get_descriptor_alloc(pipe,
     674        const int rc = usb_request_get_descriptor_alloc(pipe,
    692675            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    693676            USB_DESCTYPE_STRING, 0, 0,
     
    710693        }
    711694
    712         size_t langs_count = string_descriptor_size / 2;
    713         l18_win_locales_t *langs
    714             = malloc(sizeof(l18_win_locales_t) * langs_count);
     695        const size_t langs_count = string_descriptor_size / 2;
     696        l18_win_locales_t *langs =
     697            calloc(langs_count, sizeof(l18_win_locales_t));
    715698        if (langs == NULL) {
    716699                free(string_descriptor);
     
    718701        }
    719702
    720         size_t i;
    721         for (i = 0; i < langs_count; i++) {
     703        for (size_t i = 0; i < langs_count; i++) {
    722704                /* Language code from the descriptor is in USB endianness. */
    723705                /* FIXME: is this really correct? */
    724                 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     706                const uint16_t lang_code =
     707                    (string_descriptor[2 + 2 * i + 1] << 8)
    725708                    + string_descriptor[2 + 2 * i];
    726709                langs[i] = uint16_usb2host(lang_code);
     
    761744        }
    762745        /* Language is actually two byte value. */
    763         if (lang > 0xFFFF) {
     746        if (lang > L18N_WIN_LOCALE_MAX) {
    764747                return ERANGE;
    765748        }
     
    795778        }
    796779
    797         size_t string_char_count = string_size / 2;
     780        const size_t string_char_count = string_size / 2;
    798781        string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
    799782        if (string_chars == NULL) {
     
    807790         * do not have them).
    808791         */
    809         size_t i;
    810         for (i = 0; i < string_char_count; i++) {
    811                 uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
     792        for (size_t i = 0; i < string_char_count; i++) {
     793                const uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
    812794                    + string[2 + 2 * i];
    813795                string_chars[i] = uni_char;
     
    827809
    828810leave:
    829         if (string != NULL) {
    830                 free(string);
    831         }
    832         if (string_chars != NULL) {
    833                 free(string_chars);
    834         }
     811        free(string);
     812        free(string_chars);
    835813
    836814        return rc;
     
    847825        return usb_request_clear_feature(pipe,
    848826            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
    849             uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
     827            uint16_host2usb(USB_FEATURE_ENDPOINT_HALT),
    850828            uint16_host2usb(ep_index));
    851829}
  • uspace/lib/usbhid/src/hidreport.c

    r5b18137 rb4b534ac  
    6161       
    6262        usb_dp_parser_data_t parser_data = {
    63                 .data = dev->descriptors.configuration,
    64                 .size = dev->descriptors.configuration_size,
     63                .data = usb_device_descriptors(dev)->full_config,
     64                .size = usb_device_descriptors(dev)->full_config_size,
    6565                .arg = NULL
    6666        };
     
    7171        const uint8_t *d =
    7272            usb_dp_get_nested_descriptor(&parser, &parser_data,
    73             dev->descriptors.configuration);
     73                usb_device_descriptors(dev)->full_config);
    7474       
    7575        /*
     
    7777         */
    7878        int i = 0;
    79         while (d != NULL && i < dev->interface_no) {
     79        while (d != NULL && i < usb_device_get_iface_number(dev)) {
    8080                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
    81                     dev->descriptors.configuration, d);
     81                    usb_device_descriptors(dev)->full_config, d);
    8282                ++i;
    8383        }
     
    8585        if (d == NULL) {
    8686                usb_log_error("The %d. interface descriptor not found!\n",
    87                     dev->interface_no);
     87                    usb_device_get_iface_number(dev));
    8888                return ENOENT;
    8989        }
     
    135135         * Get the descriptor from the device.
    136136         */
    137         int rc = usb_request_get_descriptor(&dev->ctrl_pipe,
     137        int rc = usb_request_get_descriptor(usb_device_get_default_pipe(dev),
    138138            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    139             USB_DESCTYPE_HID_REPORT, 0, dev->interface_no,
     139            USB_DESCTYPE_HID_REPORT, 0, usb_device_get_iface_number(dev),
    140140            *report_desc, length, &actual_size);
    141141
  • uspace/lib/usbhid/src/hidreq.c

    r5b18137 rb4b534ac  
    182182        uint16_t value = duration << 8;
    183183       
    184         rc = usb_control_request_set(ctrl_pipe, 
    185             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
     184        rc = usb_control_request_set(ctrl_pipe,
     185            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    186186            USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
    187187
    188188        if (rc != EOK) {
    189                 usb_log_warning("Error sending Set Idle request to the device: "
     189                usb_log_warning("Device did not accept Set Idle request: "
    190190                    "%s.\n", str_error(rc));
    191191                return rc;
  • uspace/lib/usbhost/Makefile

    r5b18137 rb4b534ac  
    3232        -I$(LIBUSB_PREFIX)/include \
    3333        -I$(LIBDRV_PREFIX)/include \
     34        -Iinclude/usb/host \
    3435        -Iinclude
    3536
    3637SOURCES = \
     38        src/ddf_helpers.c \
    3739        src/endpoint.c \
    38         src/iface.c \
    39         src/usb_device_manager.c \
    40         src/usb_endpoint_manager.c \
     40        src/hcd.c \
     41        src/usb_bus.c \
    4142        src/usb_transfer_batch.c
    4243
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    r5b18137 rb4b534ac  
    11/*
    2  * Copyright (c) 2011 Vojtech Horky
     2 * Copyright (c) 2012 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohci
     28
     29/** @addtogroup libusbhost
    2930 * @{
    3031 */
    3132/** @file
    32  * PCI related functions needed by OHCI driver.
     33 *
    3334 */
    34 #ifndef DRV_OHCI_RES_H
    35 #define DRV_OHCI_RES_H
     35
     36#ifndef LIBUSBHOST_HOST_DDF_HELPERS_H
     37#define LIBUSBHOST_HOST_DDF_HELPERS_H
     38
     39#include <usb/host/hcd.h>
     40#include <usb/host/usb_bus.h>
     41#include <usb/usb.h>
    3642
    3743#include <ddf/driver.h>
     44#include <ddf/interrupt.h>
    3845#include <device/hw_res_parsed.h>
    3946
    40 int get_my_registers(ddf_dev_t *, addr_range_t *, int *);
    41 int enable_interrupts(ddf_dev_t *);
     47typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, bool);
     48typedef void (*driver_fini_t)(hcd_t *);
     49typedef int (*claim_t)(ddf_dev_t *);
     50typedef int (*irq_code_gen_t)(irq_code_t *, const hw_res_list_parsed_t *);
     51
     52typedef struct {
     53        hcd_ops_t ops;
     54        claim_t claim;
     55        usb_speed_t hc_speed;
     56        driver_init_t init;
     57        driver_fini_t fini;
     58        interrupt_handler_t *irq_handler;
     59        irq_code_gen_t irq_code_gen;
     60        const char *name;
     61} ddf_hc_driver_t;
     62
     63int hcd_ddf_add_hc(ddf_dev_t *device, const ddf_hc_driver_t *driver);
     64
     65int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
     66    size_t bw, bw_count_func_t bw_count);
     67void hcd_ddf_clean_hc(ddf_dev_t *device);
     68int hcd_ddf_setup_root_hub(ddf_dev_t *device);
     69
     70hcd_t *dev_to_hcd(ddf_dev_t *dev);
     71
     72int hcd_ddf_enable_interrupts(ddf_dev_t *device);
     73int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res);
     74int hcd_ddf_setup_interrupts(ddf_dev_t *device,
     75    const hw_res_list_parsed_t *hw_res,
     76    interrupt_handler_t handler,
     77    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *));
     78void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
    4279
    4380#endif
     81
    4482/**
    4583 * @}
    4684 */
    47 
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r5b18137 rb4b534ac  
    5757        /** Maximum size of data packets. */
    5858        size_t max_packet_size;
     59        /** Additional opportunities per uframe */
     60        unsigned packets;
    5961        /** Necessary bandwidth. */
    6062        size_t bandwidth;
     
    6769        /** Signals change of active status. */
    6870        fibril_condvar_t avail;
     71        /** High speed TT data */
     72        struct {
     73                usb_address_t address;
     74                unsigned port;
     75        } tt;
    6976        /** Optional device specific data. */
    7077        struct {
     
    8087endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    8188    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    82     size_t max_packet_size, size_t bw);
     89    size_t max_packet_size, unsigned packets, size_t bw,
     90    usb_address_t tt_address, unsigned tt_port);
    8391void endpoint_destroy(endpoint_t *instance);
    8492
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r5b18137 rb4b534ac  
    3737#define LIBUSBHOST_HOST_HCD_H
    3838
     39#include <usb/host/endpoint.h>
     40#include <usb/host/usb_bus.h>
     41#include <usb/host/usb_transfer_batch.h>
     42#include <usb/usb.h>
     43
    3944#include <assert.h>
    4045#include <usbhc_iface.h>
    41 
    42 #include <usb/host/usb_device_manager.h>
    43 #include <usb/host/usb_endpoint_manager.h>
    44 #include <usb/host/usb_transfer_batch.h>
     46#include <sys/types.h>
    4547
    4648typedef struct hcd hcd_t;
    4749
     50typedef int (*schedule_hook_t)(hcd_t *, usb_transfer_batch_t *);
     51typedef int (*ep_add_hook_t)(hcd_t *, endpoint_t *);
     52typedef void (*ep_remove_hook_t)(hcd_t *, endpoint_t *);
     53typedef void (*interrupt_hook_t)(hcd_t *, uint32_t);
     54typedef int (*status_hook_t)(hcd_t *, uint32_t *);
     55
     56typedef struct {
     57        /** Transfer scheduling, implement in device driver. */
     58        schedule_hook_t schedule;
     59        /** Hook called upon registering new endpoint. */
     60        ep_add_hook_t ep_add_hook;
     61        /** Hook called upon removing of an endpoint. */
     62        ep_remove_hook_t ep_remove_hook;
     63        /** Hook to be called on device interrupt, passes ARG1 */
     64        interrupt_hook_t irq_hook;
     65        /** Periodic polling hook */
     66        status_hook_t status_hook;
     67} hcd_ops_t;
     68
    4869/** Generic host controller driver structure. */
    4970struct hcd {
    50         /** Device manager storing handles and addresses. */
    51         usb_device_manager_t dev_manager;
    5271        /** Endpoint manager. */
    53         usb_endpoint_manager_t ep_manager;
     72        usb_bus_t bus;
    5473
     74        /** Interrupt replacement fibril */
     75        fid_t polling_fibril;
     76
     77        /** Driver implementation */
     78        hcd_ops_t ops;
    5579        /** Device specific driver data. */
    56         void *private_data;
    57         /** Transfer scheduling, implement in device driver. */
    58         int (*schedule)(hcd_t *, usb_transfer_batch_t *);
    59         /** Hook called upon registering new endpoint. */
    60         int (*ep_add_hook)(hcd_t *, endpoint_t *);
    61         /** Hook called upon removing of an endpoint. */
    62         void (*ep_remove_hook)(hcd_t *, endpoint_t *);
     80        void * driver_data;
    6381};
    6482
    65 /** Initialize hcd_t structure.
    66  * Initializes device and endpoint managers. Sets data and hook pointer to NULL.
    67  * @param hcd hcd_t structure to initialize, non-null.
    68  * @param bandwidth Available bandwidth, passed to endpoint manager.
    69  * @param bw_count Bandwidth compute function, passed to endpoint manager.
    70  */
    71 static inline void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth,
    72     size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
     83void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth,
     84    bw_count_func_t bw_count);
     85
     86static inline void hcd_set_implementation(hcd_t *hcd, void *data,
     87    const hcd_ops_t *ops)
    7388{
    7489        assert(hcd);
    75         usb_device_manager_init(&hcd->dev_manager, max_speed);
    76         usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count);
    77         hcd->private_data = NULL;
    78         hcd->schedule = NULL;
    79         hcd->ep_add_hook = NULL;
    80         hcd->ep_remove_hook = NULL;
     90        if (ops) {
     91                hcd->driver_data = data;
     92                hcd->ops = *ops;
     93        } else {
     94                memset(&hcd->ops, 0, sizeof(hcd->ops));
     95        }
    8196}
    8297
    83 /** Check registered endpoints and reset toggle bit if necessary.
    84  * @param hcd hcd_t structure, non-null.
    85  * @param target Control communication target.
    86  * @param setup_data Setup packet of the control communication.
    87  */
    88 static inline void reset_ep_if_need(hcd_t *hcd, usb_target_t target,
    89     const char setup_data[8])
     98static inline void * hcd_get_driver_data(hcd_t *hcd)
    9099{
    91100        assert(hcd);
    92         usb_endpoint_manager_reset_eps_if_need(
    93             &hcd->ep_manager, target, (const uint8_t *)setup_data);
     101        return hcd->driver_data;
    94102}
    95103
    96 /** Data retrieve wrapper.
    97  * @param fun ddf function, non-null.
    98  * @return pointer cast to hcd_t*.
    99  */
    100 static inline hcd_t *fun_to_hcd(ddf_fun_t *fun)
     104usb_address_t hcd_request_address(hcd_t *hcd, usb_speed_t speed);
     105
     106int hcd_release_address(hcd_t *hcd, usb_address_t address);
     107
     108int hcd_reserve_default_address(hcd_t *hcd, usb_speed_t speed);
     109
     110static inline int hcd_release_default_address(hcd_t *hcd)
    101111{
    102         return ddf_fun_data_get(fun);
     112        return hcd_release_address(hcd, USB_ADDRESS_DEFAULT);
    103113}
    104114
    105 extern usbhc_iface_t hcd_iface;
     115int hcd_add_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir,
     116    usb_transfer_type_t type, size_t max_packet_size, unsigned packets,
     117    size_t size, usb_address_t tt_address, unsigned tt_port);
     118
     119int hcd_remove_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir);
     120
     121int hcd_send_batch(hcd_t *hcd, usb_target_t target, usb_direction_t direction,
     122    void *data, size_t size, uint64_t setup_data,
     123    usbhc_iface_transfer_in_callback_t in,
     124    usbhc_iface_transfer_out_callback_t out, void *arg, const char* name);
     125
     126ssize_t hcd_send_batch_sync(hcd_t *hcd, usb_target_t target,
     127    usb_direction_t dir, void *data, size_t size, uint64_t setup_data,
     128    const char* name);
    106129
    107130#endif
    108 
    109131/**
    110132 * @}
  • uspace/lib/usbhost/include/usb/host/usb_bus.h

    r5b18137 rb4b534ac  
    4040#define LIBUSBHOST_HOST_USB_ENDPOINT_MANAGER_H
    4141
     42#include <usb/host/endpoint.h>
     43#include <usb/usb.h>
     44
    4245#include <adt/list.h>
    4346#include <fibril_synch.h>
    44 #include <usb/usb.h>
     47#include <stdbool.h>
    4548
    46 #include <usb/host/endpoint.h>
    4749
    4850/** Bytes per second in FULL SPEED */
     
    5052/** 90% of total bandwidth is available for periodic transfers */
    5153#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
    52 /** 16 addresses per list */
    53 #define ENDPOINT_LIST_COUNT 8
     54
     55//TODO: Implement
     56#define BANDWIDTH_AVAILABLE_USB20  1
     57
     58typedef size_t (*bw_count_func_t)(usb_speed_t, usb_transfer_type_t, size_t, size_t);
     59typedef void (*ep_remove_callback_t)(endpoint_t *, void *);
     60typedef int (*ep_add_callback_t)(endpoint_t *, void *);
    5461
    5562/** Endpoint management structure */
    56 typedef struct usb_endpoint_manager {
    57         /** Store endpoint_t instances */
    58         list_t endpoint_lists[ENDPOINT_LIST_COUNT];
     63typedef struct usb_bus {
     64        struct {
     65                usb_speed_t speed;      /**< Device speed */
     66                bool occupied;          /**< The address is in use. */
     67                list_t endpoint_list;   /**< Store endpoint_t instances */
     68        } devices[USB_ADDRESS_COUNT];
    5969        /** Prevents races accessing lists */
    6070        fibril_mutex_t guard;
     
    6272        size_t free_bw;
    6373        /** Use this function to count bw required by EP */
    64         size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t);
    65 } usb_endpoint_manager_t;
     74        bw_count_func_t bw_count;
     75        /** Maximum speed allowed. */
     76        usb_speed_t max_speed;
     77        /** The last reserved address */
     78        usb_address_t last_address;
     79} usb_bus_t;
     80
    6681
    6782size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
    6883    size_t size, size_t max_packet_size);
     84size_t bandwidth_count_usb20(usb_speed_t speed, usb_transfer_type_t type,
     85    size_t size, size_t max_packet_size);
    6986
    70 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
    71     size_t available_bandwidth,
    72     size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t));
     87int usb_bus_init(usb_bus_t *instance,
     88    size_t available_bandwidth, bw_count_func_t bw_count, usb_speed_t max_speed);
    7389
    74 void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance,
    75     usb_target_t target, const uint8_t data[8]);
     90int usb_bus_register_ep(usb_bus_t *instance, endpoint_t *ep, size_t data_size);
    7691
    77 int usb_endpoint_manager_register_ep(
    78     usb_endpoint_manager_t *instance, endpoint_t *ep, size_t data_size);
    79 int usb_endpoint_manager_unregister_ep(
    80     usb_endpoint_manager_t *instance, endpoint_t *ep);
    81 endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
     92int usb_bus_unregister_ep(usb_bus_t *instance, endpoint_t *ep);
     93
     94endpoint_t * usb_bus_find_ep(usb_bus_t *instance,
    8295    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
    8396
    84 int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
     97int usb_bus_add_ep(usb_bus_t *instance,
    8598    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    86     usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
    87     size_t data_size, int (*callback)(endpoint_t *, void *), void *arg);
     99    usb_transfer_type_t type, size_t max_packet_size, unsigned packets,
     100    size_t data_size, ep_add_callback_t callback, void *arg,
     101    usb_address_t tt_address, unsigned tt_port);
    88102
    89 int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
     103int usb_bus_remove_ep(usb_bus_t *instance,
    90104    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    91     void (*callback)(endpoint_t *, void *), void *arg);
     105    ep_remove_callback_t callback, void *arg);
    92106
    93 void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance,
    94     usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg);
     107int usb_bus_reset_toggle(usb_bus_t *instance, usb_target_t target, bool all);
     108
     109int usb_bus_remove_address(usb_bus_t *instance,
     110    usb_address_t address, ep_remove_callback_t callback, void *arg);
     111
     112int usb_bus_request_address(usb_bus_t *instance,
     113    usb_address_t *address, bool strict, usb_speed_t speed);
     114
     115int usb_bus_get_speed(usb_bus_t *instance,
     116    usb_address_t address, usb_speed_t *speed);
    95117#endif
    96118/**
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r5b18137 rb4b534ac  
    3737#define LIBUSBHOST_HOST_USB_TRANSFER_BATCH_H
    3838
    39 #include <adt/list.h>
     39#include <usb/host/endpoint.h>
     40#include <usb/usb.h>
    4041
     42#include <assert.h>
     43#include <stdbool.h>
     44#include <sys/types.h>
    4145#include <usbhc_iface.h>
    42 #include <usb/usb.h>
    43 #include <usb/host/endpoint.h>
    4446
    4547#define USB_SETUP_PACKET_SIZE 8
     
    6769         */
    6870        size_t setup_size;
    69         /** Host controller function, passed to callback function */
    70         ddf_fun_t *fun;
    7171
    7272        /** Actually used portion of the buffer
     
    8080         */
    8181        int error;
    82 
    83         /** Driver specific data */
    84         void *private_data;
    85         /** Callback to properly remove driver data during destruction */
    86         void (*private_data_dtor)(void *p_data);
    8782} usb_transfer_batch_t;
    8883
     
    108103    usbhc_iface_transfer_in_callback_t func_in,
    109104    usbhc_iface_transfer_out_callback_t func_out,
    110     void *arg,
    111     ddf_fun_t *fun,
    112     void *private_data,
    113     void (*private_data_dtor)(void *p_data)
     105    void *arg
    114106);
    115107void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance);
  • uspace/lib/usbhost/include/usb/host/utils/malloc32.h

    r5b18137 rb4b534ac  
    11/*
    2  * Copyright (c) 2010 Jan Vesely
     2 * Copyright (c) 2013 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbohci
     28/** @addtogroup drvusbehci
    2929 * @{
    3030 */
    3131/** @file
    32  * @brief OHCI driver
     32 * @brief EHCI driver
    3333 */
    34 #ifndef DRV_OHCI_UTILS_MALLOC32_H
    35 #define DRV_OHCI_UTILS_MALLOC32_H
     34#ifndef DRV_EHCI_UTILS_MALLOC32_H
     35#define DRV_EHCI_UTILS_MALLOC32_H
    3636
    37 #include <assert.h>
    38 #include <malloc.h>
    39 #include <unistd.h>
     37#include <align.h>
     38#include <as.h>
     39#include <ddi.h>
    4040#include <errno.h>
    41 #include <mem.h>
    42 #include <as.h>
     41#include <stdlib.h>
     42#include <sys/types.h>
    4343
    4444/* Generic TDs and EDs require 16byte alignment,
     
    4646 * buffers do not have to be aligned.
    4747 */
    48 #define OHCI_ALIGN 32
     48#define EHCI_ALIGN   32
     49
     50#define EHCI_REQUIRED_PAGE_SIZE   4096
    4951
    5052/** Get physical address translation
     
    7072 */
    7173static inline void * malloc32(size_t size)
    72         { return memalign(OHCI_ALIGN, size); }
     74{
     75        uintptr_t phys;
     76        void *address = AS_AREA_ANY;
     77        size_t real_size = ALIGN_UP(size, PAGE_SIZE);
     78
     79        const int ret = dmamem_map_anonymous(real_size,
     80            DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
     81            &address);
     82
     83        if (ret == EOK) {
     84                /* Poison, accessing it should be enough to make sure
     85                 * the location is mapped, but poison works better */
     86                memset(address, 0x5, real_size);
     87                return address;
     88        }
     89        return NULL;
     90}
    7391
    7492/** Physical mallocator simulator
     
    7795 */
    7896static inline void free32(void *addr)
    79         { free(addr); }
     97{
     98        dmamem_unmap_anonymous(addr);
     99}
     100
     101/** Create 4KB page mapping
     102 *
     103 * @return Address of the mapped page, NULL on failure.
     104 */
     105static inline void *get_page()
     106{
     107        return malloc32(PAGE_SIZE);
     108}
     109
     110static inline void return_page(void *page)
     111{
     112        free32(page);
     113}
     114
     115
    80116#endif
    81117/**
  • uspace/lib/usbhost/src/endpoint.c

    r5b18137 rb4b534ac  
    3333 */
    3434
     35#include <usb/host/endpoint.h>
     36
    3537#include <assert.h>
    3638#include <stdlib.h>
    37 #include <errno.h>
    38 #include <usb/host/endpoint.h>
    3939
    4040/** Allocate ad initialize endpoint_t structure.
     
    5050endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    5151    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    52     size_t max_packet_size, size_t bw)
     52    size_t max_packet_size, unsigned packets, size_t bw,
     53    usb_address_t tt_address, unsigned tt_p)
    5354{
    5455        endpoint_t *instance = malloc(sizeof(endpoint_t));
     
    6061                instance->speed = speed;
    6162                instance->max_packet_size = max_packet_size;
     63                instance->packets = packets;
    6264                instance->bandwidth = bw;
    6365                instance->toggle = 0;
    6466                instance->active = false;
     67                instance->tt.address = tt_address;
     68                instance->tt.port = tt_p;
    6569                instance->hc_data.data = NULL;
    6670                instance->hc_data.toggle_get = NULL;
     
    109113{
    110114        assert(instance);
    111         fibril_mutex_lock(&instance->guard);
    112         instance->hc_data.data = NULL;
    113         instance->hc_data.toggle_get = NULL;
    114         instance->hc_data.toggle_set = NULL;
    115         fibril_mutex_unlock(&instance->guard);
     115        endpoint_set_hc_data(instance, NULL, NULL, NULL);
    116116}
    117117
  • uspace/lib/usbhost/src/usb_bus.c

    r5b18137 rb4b534ac  
    3333 */
    3434
    35 #include <stdbool.h>
     35#include <usb/host/usb_bus.h>
     36#include <usb/debug.h>
     37
    3638#include <assert.h>
    3739#include <errno.h>
    38 
    39 #include <usb/debug.h>
    40 #include <usb/host/usb_endpoint_manager.h>
     40#include <macros.h>
     41#include <stdbool.h>
     42
    4143
    4244/** Endpoint compare helper function.
     
    6365
    6466/** Get list that holds endpoints for given address.
    65  * @param instance usb_endpoint_manager structure, non-null.
     67 * @param instance usb_bus structure, non-null.
    6668 * @param addr USB address, must be >= 0.
    6769 * @return Pointer to the appropriate list.
    6870 */
    69 static list_t * get_list(usb_endpoint_manager_t *instance, usb_address_t addr)
     71static list_t * get_list(usb_bus_t *instance, usb_address_t addr)
    7072{
    7173        assert(instance);
    7274        assert(addr >= 0);
    73         return &instance->endpoint_lists[addr % ENDPOINT_LIST_COUNT];
     75        return &instance->devices[addr % ARRAY_SIZE(instance->devices)].endpoint_list;
    7476}
    7577
    7678/** Internal search function, works on locked structure.
    77  * @param instance usb_endpoint_manager structure, non-null.
     79 * @param instance usb_bus structure, non-null.
    7880 * @param address USB address, must be valid.
    7981 * @param endpoint USB endpoint number.
     
    8385 * @note Assumes that the internal mutex is locked.
    8486 */
    85 static endpoint_t * find_locked(usb_endpoint_manager_t *instance,
     87static endpoint_t * find_locked(usb_bus_t *instance,
    8688    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
    8789{
     
    9597        }
    9698        return NULL;
     99}
     100
     101/** Get a free USB address
     102 *
     103 * @param[in] instance Device manager structure to use.
     104 * @return Free address, or error code.
     105 */
     106static usb_address_t usb_bus_get_free_address(usb_bus_t *instance)
     107{
     108
     109        usb_address_t new_address = instance->last_address;
     110        do {
     111                new_address = (new_address + 1) % USB_ADDRESS_COUNT;
     112                if (new_address == USB_ADDRESS_DEFAULT)
     113                        new_address = 1;
     114                if (new_address == instance->last_address)
     115                        return ENOSPC;
     116        } while (instance->devices[new_address].occupied);
     117
     118        assert(new_address != USB_ADDRESS_DEFAULT);
     119        instance->last_address = new_address;
     120
     121        return new_address;
    97122}
    98123
     
    145170}
    146171
     172/** Calculate bandwidth that needs to be reserved for communication with EP.
     173 * Calculation follows USB 2.0 specification.
     174 * @param speed Device's speed.
     175 * @param type Type of the transfer.
     176 * @param size Number of byte to transfer.
     177 * @param max_packet_size Maximum bytes in one packet.
     178 */
     179size_t bandwidth_count_usb20(usb_speed_t speed, usb_transfer_type_t type,
     180    size_t size, size_t max_packet_size)
     181{
     182        /* We care about bandwidth only for interrupt and isochronous. */
     183        if ((type != USB_TRANSFER_INTERRUPT)
     184            && (type != USB_TRANSFER_ISOCHRONOUS)) {
     185                return 0;
     186        }
     187        //TODO Implement
     188        return 0;
     189}
     190
    147191/** Initialize to default state.
    148192 * You need to provide valid bw_count function if you plan to use
    149193 * add_endpoint/remove_endpoint pair.
    150194 *
    151  * @param instance usb_endpoint_manager structure, non-null.
     195 * @param instance usb_bus structure, non-null.
    152196 * @param available_bandwidth Size of the bandwidth pool.
    153197 * @param bw_count function to use to calculate endpoint bw requirements.
    154198 * @return Error code.
    155199 */
    156 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
    157     size_t available_bandwidth,
    158     size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
     200int usb_bus_init(usb_bus_t *instance,
     201    size_t available_bandwidth, bw_count_func_t bw_count, usb_speed_t max_speed)
    159202{
    160203        assert(instance);
     
    162205        instance->free_bw = available_bandwidth;
    163206        instance->bw_count = bw_count;
    164         for (unsigned i = 0; i < ENDPOINT_LIST_COUNT; ++i) {
    165                 list_initialize(&instance->endpoint_lists[i]);
     207        instance->last_address = 0;
     208        instance->max_speed = max_speed;
     209        for (unsigned i = 0; i < ARRAY_SIZE(instance->devices); ++i) {
     210                list_initialize(&instance->devices[i].endpoint_list);
     211                instance->devices[i].speed = USB_SPEED_MAX;
     212                instance->devices[i].occupied = false;
    166213        }
    167214        return EOK;
    168 }
    169 
    170 /** Check setup packet data for signs of toggle reset.
    171  *
    172  * @param[in] instance usb_endpoint_manager structure, non-null.
    173  * @param[in] target Device to receive setup packet.
    174  * @param[in] data Setup packet data.
    175  *
    176  * Really ugly one. Resets toggle bit on all endpoints that need it.
    177  * @TODO Use tools from libusbdev requests.h
    178  */
    179 void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance,
    180     usb_target_t target, const uint8_t data[8])
    181 {
    182         assert(instance);
    183         if (!usb_target_is_valid(target)) {
    184                 usb_log_error("Invalid data when checking for toggle reset.\n");
    185                 return;
    186         }
    187 
    188         assert(data);
    189         switch (data[1])
    190         {
    191         case 0x01: /* Clear Feature -- resets only cleared ep */
    192                 /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */
    193                 // TODO Use macros in libusbdev requests.h
    194                 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    195                         fibril_mutex_lock(&instance->guard);
    196                         /* endpoint number is < 16, thus first byte is enough */
    197                         list_foreach(*get_list(instance, target.address),
    198                             link, endpoint_t, ep) {
    199                                 if ((ep->address == target.address)
    200                                     && (ep->endpoint = data[4])) {
    201                                         endpoint_toggle_set(ep,0);
    202                                 }
    203                         }
    204                         fibril_mutex_unlock(&instance->guard);
    205                 }
    206         break;
    207 
    208         case 0x9: /* Set Configuration */
    209         case 0x11: /* Set Interface */
    210                 /* Recipient must be device, this resets all endpoints,
    211                  * In fact there should be no endpoints but EP 0 registered
    212                  * as different interfaces use different endpoints,
    213                  * unless you're changing configuration or alternative
    214                  * interface of an already setup device. */
    215                 if ((data[0] & 0xf) == 0) {
    216                         fibril_mutex_lock(&instance->guard);
    217                         list_foreach(*get_list(instance, target.address),
    218                             link, endpoint_t, ep) {
    219                                 if (ep->address == target.address) {
    220                                         endpoint_toggle_set(ep,0);
    221                                 }
    222                         }
    223                         fibril_mutex_unlock(&instance->guard);
    224                 }
    225         break;
    226         }
    227215}
    228216
    229217/** Register endpoint structure.
    230218 * Checks for duplicates.
    231  * @param instance usb_endpoint_manager, non-null.
     219 * @param instance usb_bus, non-null.
    232220 * @param ep endpoint_t to register.
    233221 * @param data_size Size of data to transfer.
    234222 * @return Error code.
    235223 */
    236 int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
    237     endpoint_t *ep, size_t data_size)
     224int usb_bus_register_ep(usb_bus_t *instance, endpoint_t *ep, size_t data_size)
    238225{
    239226        assert(instance);
     
    258245
    259246        instance->free_bw -= ep->bandwidth;
     247        usb_log_debug("Registered EP(%d:%d:%s:%s)\n", ep->address, ep->endpoint,
     248            usb_str_transfer_type_short(ep->transfer_type),
     249            usb_str_direction(ep->direction));
    260250        fibril_mutex_unlock(&instance->guard);
    261251        return EOK;
     
    264254/** Unregister endpoint structure.
    265255 * Checks for duplicates.
    266  * @param instance usb_endpoint_manager, non-null.
     256 * @param instance usb_bus, non-null.
    267257 * @param ep endpoint_t to unregister.
    268258 * @return Error code.
    269259 */
    270 int usb_endpoint_manager_unregister_ep(
    271     usb_endpoint_manager_t *instance, endpoint_t *ep)
     260int usb_bus_unregister_ep(usb_bus_t *instance, endpoint_t *ep)
    272261{
    273262        assert(instance);
     
    282271        list_remove(&ep->link);
    283272        instance->free_bw += ep->bandwidth;
     273        usb_log_debug("Unregistered EP(%d:%d:%s:%s)\n", ep->address,
     274            ep->endpoint, usb_str_transfer_type_short(ep->transfer_type),
     275            usb_str_direction(ep->direction));
    284276        fibril_mutex_unlock(&instance->guard);
    285277        return EOK;
     
    287279
    288280/** Find endpoint_t representing the given communication route.
    289  * @param instance usb_endpoint_manager, non-null.
     281 * @param instance usb_bus, non-null.
    290282 * @param address
    291283 */
    292 endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
     284endpoint_t * usb_bus_find_ep(usb_bus_t *instance,
    293285    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
    294286{
     
    302294
    303295/** Create and register new endpoint_t structure.
    304  * @param instance usb_endpoint_manager structure, non-null.
     296 * @param instance usb_bus structure, non-null.
    305297 * @param address USB address.
    306298 * @param endpoint USB endpoint number.
     
    314306 * @return Error code.
    315307 */
    316 int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
     308int usb_bus_add_ep(usb_bus_t *instance,
    317309    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    318     usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
    319     size_t data_size, int (*callback)(endpoint_t *, void *), void *arg)
     310    usb_transfer_type_t type, size_t max_packet_size, unsigned packets,
     311    size_t data_size, ep_add_callback_t callback, void *arg,
     312    usb_address_t tt_address, unsigned tt_port)
    320313{
    321314        assert(instance);
    322315        if (instance->bw_count == NULL)
    323316                return ENOTSUP;
    324         if (address < 0)
    325                 return EINVAL;
    326 
    327         const size_t bw =
    328             instance->bw_count(speed, type, data_size, max_packet_size);
    329 
    330         fibril_mutex_lock(&instance->guard);
    331         /* Check for available bandwidth */
    332         if (bw > instance->free_bw) {
    333                 fibril_mutex_unlock(&instance->guard);
    334                 return ENOSPC;
     317        if (!usb_address_is_valid(address))
     318                return EINVAL;
     319
     320
     321        fibril_mutex_lock(&instance->guard);
     322        /* Check for speed and address */
     323        if (!instance->devices[address].occupied) {
     324                fibril_mutex_unlock(&instance->guard);
     325                return ENOENT;
    335326        }
    336327
     
    342333        }
    343334
    344         ep = endpoint_create(
    345             address, endpoint, direction, type, speed, max_packet_size, bw);
     335        const usb_speed_t speed = instance->devices[address].speed;
     336        const size_t bw =
     337            instance->bw_count(speed, type, data_size, max_packet_size);
     338
     339        /* Check for available bandwidth */
     340        if (bw > instance->free_bw) {
     341                fibril_mutex_unlock(&instance->guard);
     342                return ENOSPC;
     343        }
     344
     345        ep = endpoint_create(address, endpoint, direction, type, speed,
     346            max_packet_size, packets, bw, tt_address, tt_port);
    346347        if (!ep) {
    347348                fibril_mutex_unlock(&instance->guard);
     
    365366
    366367/** Unregister and destroy endpoint_t structure representing given route.
    367  * @param instance usb_endpoint_manager structure, non-null.
     368 * @param instance usb_bus structure, non-null.
    368369 * @param address USB address.
    369370 * @param endpoint USB endpoint number.
     
    373374 * @return Error code.
    374375 */
    375 int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
     376int usb_bus_remove_ep(usb_bus_t *instance,
    376377    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    377     void (*callback)(endpoint_t *, void *), void *arg)
     378    ep_remove_callback_t callback, void *arg)
    378379{
    379380        assert(instance);
     
    395396}
    396397
     398int usb_bus_reset_toggle(usb_bus_t *instance, usb_target_t target, bool all)
     399{
     400        assert(instance);
     401        if (!usb_target_is_valid(target))
     402                return EINVAL;
     403
     404        int ret = ENOENT;
     405
     406        fibril_mutex_lock(&instance->guard);
     407        list_foreach(*get_list(instance, target.address), link, endpoint_t, ep) {
     408                if ((ep->address == target.address)
     409                    && (all || ep->endpoint == target.endpoint)) {
     410                        endpoint_toggle_set(ep, 0);
     411                        ret = EOK;
     412                }
     413        }
     414        fibril_mutex_unlock(&instance->guard);
     415        return ret;
     416}
     417
    397418/** Unregister and destroy all endpoints using given address.
    398  * @param instance usb_endpoint_manager structure, non-null.
     419 * @param instance usb_bus structure, non-null.
    399420 * @param address USB address.
    400421 * @param endpoint USB endpoint number.
     
    404425 * @return Error code.
    405426 */
    406 void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance,
    407     usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg)
    408 {
    409         list_t *list;
    410         link_t *link;
    411         link_t *next;
    412 
    413         assert(address >= 0);
    414         assert(instance);
    415         fibril_mutex_lock(&instance->guard);
    416 
    417         list = get_list(instance, address);
    418         link = list_first(list);
    419         while (link != NULL) {
     427int usb_bus_remove_address(usb_bus_t *instance,
     428    usb_address_t address, ep_remove_callback_t callback, void *arg)
     429{
     430        assert(instance);
     431        if (!usb_address_is_valid(address))
     432                return EINVAL;
     433
     434        fibril_mutex_lock(&instance->guard);
     435
     436        const int ret = instance->devices[address].occupied ? EOK : ENOENT;
     437        instance->devices[address].occupied = false;
     438
     439        list_t *list = get_list(instance, address);
     440        for (link_t *link = list_first(list); link != NULL; ) {
    420441                endpoint_t *ep = list_get_instance(link, endpoint_t, link);
    421                 next = list_next(link, list);
    422 
     442                link = list_next(link, list);
    423443                if (ep->address == address) {
    424444                        list_remove(&ep->link);
     
    427447                        endpoint_destroy(ep);
    428448                }
    429                 link = next;
    430         }
    431         fibril_mutex_unlock(&instance->guard);
     449        }
     450        fibril_mutex_unlock(&instance->guard);
     451        return ret;
     452}
     453
     454/** Request USB address.
     455 * @param instance usb_device_manager
     456 * @param address Pointer to requested address value, place to store new address
     457 * @parma strict Fail if the requested address is not available.
     458 * @return Error code.
     459 * @note Default address is only available in strict mode.
     460 */
     461int usb_bus_request_address(usb_bus_t *instance,
     462    usb_address_t *address, bool strict, usb_speed_t speed)
     463{
     464        assert(instance);
     465        assert(address);
     466        if (speed > instance->max_speed)
     467                return ENOTSUP;
     468
     469        if (!usb_address_is_valid(*address))
     470                return EINVAL;
     471
     472        usb_address_t addr = *address;
     473
     474        fibril_mutex_lock(&instance->guard);
     475        /* Only grant default address to strict requests */
     476        if ((addr == USB_ADDRESS_DEFAULT) && !strict) {
     477                addr = usb_bus_get_free_address(instance);
     478        }
     479
     480        if (instance->devices[addr].occupied) {
     481                if (strict) {
     482                        fibril_mutex_unlock(&instance->guard);
     483                        return ENOENT;
     484                }
     485                addr = usb_bus_get_free_address(instance);
     486        }
     487        if (usb_address_is_valid(addr)) {
     488                assert(instance->devices[addr].occupied == false);
     489                assert(addr != USB_ADDRESS_DEFAULT || strict);
     490
     491                instance->devices[addr].occupied = true;
     492                instance->devices[addr].speed = speed;
     493                *address = addr;
     494                addr = 0;
     495        }
     496
     497        fibril_mutex_unlock(&instance->guard);
     498        return addr;
     499}
     500
     501/** Get speed assigned to USB address.
     502 *
     503 * @param[in] instance Device manager structure to use.
     504 * @param[in] address Address the caller wants to find.
     505 * @param[out] speed Assigned speed.
     506 * @return Error code.
     507 */
     508int usb_bus_get_speed(usb_bus_t *instance, usb_address_t address,
     509    usb_speed_t *speed)
     510{
     511        assert(instance);
     512        if (!usb_address_is_valid(address)) {
     513                return EINVAL;
     514        }
     515
     516        fibril_mutex_lock(&instance->guard);
     517
     518        const int ret = instance->devices[address].occupied ? EOK : ENOENT;
     519        if (speed && instance->devices[address].occupied) {
     520                *speed = instance->devices[address].speed;
     521        }
     522
     523        fibril_mutex_unlock(&instance->guard);
     524        return ret;
    432525}
    433526/**
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    r5b18137 rb4b534ac  
    3232 * USB transfer transaction structures (implementation).
    3333 */
     34
     35#include <usb/host/usb_transfer_batch.h>
     36#include <usb/debug.h>
     37
     38#include <assert.h>
    3439#include <errno.h>
    3540#include <macros.h>
    36 
    37 #include <usb/usb.h>
    38 #include <usb/debug.h>
    39 
    40 #include <usb/host/usb_transfer_batch.h>
    41 #include <usb/host/hcd.h>
     41#include <mem.h>
     42#include <stdlib.h>
     43#include <usbhc_iface.h>
    4244
    4345/** Allocate and initialize usb_transfer_batch structure.
     
    6163    usbhc_iface_transfer_in_callback_t func_in,
    6264    usbhc_iface_transfer_out_callback_t func_out,
    63     void *arg,
    64     ddf_fun_t *fun,
    65     void *private_data,
    66     void (*private_data_dtor)(void *)
     65    void *arg
    6766    )
    6867{
     
    8180                instance->buffer_size = buffer_size;
    8281                instance->setup_size = 0;
    83                 instance->fun = fun;
    84                 instance->private_data = private_data;
    85                 instance->private_data_dtor = private_data_dtor;
    8682                instance->transfered_size = 0;
    8783                instance->error = EOK;
     
    110106                endpoint_release(instance->ep);
    111107        }
    112         if (instance->private_data) {
    113                 assert(instance->private_data_dtor);
    114                 instance->private_data_dtor(instance->private_data);
    115         }
    116108        free(instance);
    117109}
     
    133125        /* NOTE: Only one of these pointers should be set. */
    134126        if (instance->callback_out) {
    135                 /* Check for commands that reset toggle bit */
    136                 if (instance->ep->transfer_type == USB_TRANSFER_CONTROL
    137                     && error == EOK) {
    138                         const usb_target_t target =
    139                             {{ instance->ep->address, instance->ep->endpoint }};
    140                         reset_ep_if_need(fun_to_hcd(instance->fun), target,
    141                             instance->setup_buffer);
    142                 }
    143                 instance->callback_out(instance->fun, error, instance->arg);
     127                instance->callback_out(error, instance->arg);
    144128        }
    145129
     
    150134                        memcpy(instance->buffer, data, safe_size);
    151135                }
    152                 instance->callback_in(instance->fun, error,
    153                     safe_size, instance->arg);
     136                instance->callback_in(error, safe_size, instance->arg);
    154137        }
    155138}
  • uspace/lib/usbvirt/Makefile

    r5b18137 rb4b534ac  
    3434        -I$(LIBUSB_PREFIX)/include \
    3535        -I$(LIBUSBDEV_PREFIX)/include \
    36         -Iinclude
     36        -Iinclude \
     37        -Iinclude/usbvirt
    3738
    3839SOURCES = \
     
    4243        src/ipc_hc.c \
    4344        src/stdreq.c \
    44         src/transfer.c
     45        src/transfer.c \
     46        src/virthub_base.c \
     47        src/virthub_descriptors.c
    4548
    4649include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usbvirt/include/usbvirt/device.h

    r5b18137 rb4b534ac  
    4040#include <usb/dev/request.h>
    4141#include <async.h>
     42#include <errno.h>
     43
    4244
    4345/** Maximum number of endpoints supported by virtual USB. */
     
    5759typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *dev,
    5860    usb_endpoint_t endpoint, usb_transfer_type_t transfer_type,
    59     void *buffer, size_t buffer_size);
     61    const void *buffer, size_t buffer_size);
    6062
    6163/** Callback for data from device (IN transaction).
     
    8890    uint8_t *data, size_t *act_data_size);
    8991
     92/** Create a class request to get data from device
     93 *
     94 * @param rec Request recipient.
     95 * @param req Request code.
     96 */
     97#define CLASS_REQ_IN(rec, req) \
     98        .request_type = SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_CLASS, rec), \
     99        .request = req
     100
     101/** Create a class request to send data to device
     102 *
     103 * @param rec Request recipient.
     104 * @param req Request code.
     105 */
     106#define CLASS_REQ_OUT(rec, req) \
     107        .request_type = SETUP_REQUEST_TO_DEVICE(USB_REQUEST_TYPE_CLASS, rec), \
     108        .request = req
     109
     110/** Create a standard request to get data from device
     111 *
     112 * @param rec Request recipient.
     113 * @param req Request code.
     114 */
     115#define STD_REQ_IN(rec, req) \
     116        .request_type = SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, rec), \
     117        .request = req
     118
     119/** Create a standard request to send data to device
     120 *
     121 * @param rec Request recipient.
     122 * @param req Request code.
     123 */
     124#define STD_REQ_OUT(rec, req) \
     125        .request_type = SETUP_REQUEST_TO_DEVICE(USB_REQUEST_TYPE_STANDARD, rec), \
     126        .request = req
     127
    90128/** Callback for control request on a virtual USB device.
    91129 *
     
    94132 */
    95133typedef struct {
    96         /** Request direction (in or out). */
    97         usb_direction_t req_direction;
    98         /** Request recipient (device, interface or endpoint). */
    99         usb_request_recipient_t req_recipient;
    100         /** Request type (standard, class or vendor). */
    101         usb_request_type_t req_type;
     134        /* Request type. See usb/request.h */
     135        uint8_t request_type;
    102136        /** Actual request code. */
    103137        uint8_t request;
     
    111145typedef struct {
    112146        /** Actual data. */
    113         uint8_t *data;
     147        const uint8_t *data;
    114148        /** Data length. */
    115149        size_t length;
     
    121155        usb_standard_configuration_descriptor_t *descriptor;
    122156        /** Array of extra data. */
    123         usbvirt_device_configuration_extras_t *extra;
     157        const usbvirt_device_configuration_extras_t *extra;
    124158        /** Length of @c extra array. */
    125159        size_t extra_count;
     
    131165         * There is always only one such descriptor for the device.
    132166         */
    133         usb_standard_device_descriptor_t *device;
     167        const usb_standard_device_descriptor_t *device;
    134168
    135169        /** Configurations. */
     
    164198         * Last handler is expected to have the @c callback field set to NULL
    165199         */
    166         usbvirt_control_request_handler_t *control;
     200        const usbvirt_control_request_handler_t *control;
    167201        /** Callback when device changes state.
    168202         *
     
    180214/** Virtual USB device. */
    181215struct usbvirt_device {
     216        /** Device does not require USB bus power */
     217        bool self_powered;
     218        /** Device is allowed to signal remote wakeup */
     219        bool remote_wakeup;
    182220        /** Name for debugging purposes. */
    183221        const char *name;
     
    187225        usbvirt_device_ops_t *ops;
    188226        /** Device descriptors. */
    189         usbvirt_descriptors_t *descriptors;
     227        const usbvirt_descriptors_t *descriptors;
    190228        /** Current device address.
    191229         * You shall treat this field as read only in your code.
     
    202240};
    203241
     242
     243int req_nop(usbvirt_device_t *device,
     244    const usb_device_request_setup_packet_t *setup_packet,
     245    uint8_t *data, size_t *act_size);
     246
    204247int usbvirt_device_plug(usbvirt_device_t *, const char *);
    205248void usbvirt_device_unplug(usbvirt_device_t *);
    206249
    207250void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *,
    208     uint8_t *, size_t *, void *, size_t);
    209 
    210 int usbvirt_control_write(usbvirt_device_t *, void *, size_t, void *, size_t);
    211 int usbvirt_control_read(usbvirt_device_t *, void *, size_t, void *, size_t, size_t *);
     251    uint8_t *, size_t *, const void *, size_t);
     252
     253int usbvirt_control_write(usbvirt_device_t *, const void *, size_t, void *, size_t);
     254int usbvirt_control_read(usbvirt_device_t *, const void *, size_t, void *, size_t, size_t *);
    212255int usbvirt_data_out(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t,
    213     void *, size_t);
     256    const void *, size_t);
    214257int usbvirt_data_in(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t,
    215258    void *, size_t, size_t *);
  • uspace/lib/usbvirt/include/usbvirt/virthub_base.h

    r5b18137 rb4b534ac  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2013 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup drvusbvhc
     29/** @addtogroup libusbvirt
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief Virtual USB hub.
     33 * Virtual USB device.
    3434 */
    3535
    36 #ifndef VHCD_HUB_H_
    37 #define VHCD_HUB_H_
     36#ifndef LIBUSBVIRT_VIRTHUB_BASE_H_
     37#define LIBUSBVIRT_VIRTHUB_BASE_H_
    3838
    3939#include <usbvirt/device.h>
    40 #include <ddf/driver.h>
     40#include <usb/classes/hub.h>
    4141
    42 #include "hub/hub.h"
    43 #include "hub/virthub.h"
     42enum {
     43        VIRTHUB_EXTR_DESC = 3,
     44};
    4445
    45 extern usbvirt_device_t virtual_hub_device;
     46typedef struct {
     47        usb_standard_configuration_descriptor_t config_descriptor;
     48        usb_standard_endpoint_descriptor_t endpoint_descriptor;
     49        usbvirt_device_configuration_extras_t extra[VIRTHUB_EXTR_DESC];
     50        usbvirt_device_configuration_t configuration;
     51        usbvirt_descriptors_t descriptors;
     52        usbvirt_device_t device;
     53        void *data;
     54} virthub_base_t;
    4655
    47 void virtual_hub_device_init(ddf_fun_t *);
     56void *virthub_get_data(usbvirt_device_t *dev);
     57
     58int virthub_base_init(virthub_base_t *instance,
     59    const char *name, usbvirt_device_ops_t *ops, void *data,
     60    const usb_standard_device_descriptor_t *device_desc,
     61    const usb_hub_descriptor_header_t *hub_desc, usb_endpoint_t ep);
     62
     63usb_address_t virthub_base_get_address(virthub_base_t *instance);
     64
     65int virthub_base_request(virthub_base_t *instance, usb_target_t target,
     66    usb_direction_t dir, const usb_device_request_setup_packet_t *setup,
     67    void *buffer, size_t buffer_size, size_t *real_size);
     68
     69int virthub_base_get_hub_descriptor(usbvirt_device_t *dev,
     70    const usb_device_request_setup_packet_t *request, uint8_t *data,
     71    size_t *act_size);
     72int virthub_base_get_null_status(usbvirt_device_t *dev,
     73    const usb_device_request_setup_packet_t *request, uint8_t *data,
     74    size_t *act_size);
     75
    4876
    4977#endif
     78
    5079/**
    5180 * @}
  • uspace/lib/usbvirt/src/ctrltransfer.c

    r5b18137 rb4b534ac  
    5050 */
    5151int process_control_transfer(usbvirt_device_t *dev,
    52     usbvirt_control_request_handler_t *control_handlers,
    53     usb_device_request_setup_packet_t *setup,
     52    const usbvirt_control_request_handler_t *control_handlers,
     53    const usb_device_request_setup_packet_t *setup,
    5454    uint8_t *data, size_t *data_sent_size)
    5555{
     
    6060                return EFORWARD;
    6161        }
    62 
    63         usb_direction_t direction = setup->request_type & 128 ?
    64             USB_DIRECTION_IN : USB_DIRECTION_OUT;
    65         usb_request_recipient_t req_recipient = setup->request_type & 31;
    66         usb_request_type_t req_type = (setup->request_type >> 5) & 3;
    67 
    68         usbvirt_control_request_handler_t *handler = control_handlers;
    69         while (handler->callback != NULL) {
    70                 if (handler->req_direction != direction) {
    71                         goto next;
    72                 }
    73                 if (handler->req_recipient != req_recipient) {
    74                         goto next;
    75                 }
    76                 if (handler->req_type != req_type) {
    77                         goto next;
    78                 }
    79                 if (handler->request != setup->request) {
    80                         goto next;
     62        const usbvirt_control_request_handler_t *handler = control_handlers;
     63        for (;handler->callback != NULL; ++handler) {
     64                if (handler->request != setup->request ||
     65                    handler->request_type != setup->request_type) {
     66                        continue;
    8167                }
    8268
     
    8470                    usb_debug_str_buffer((uint8_t*) setup, sizeof(*setup), 0));
    8571                int rc = handler->callback(dev, setup, data, data_sent_size);
    86                 if (rc == EFORWARD) {
    87                         goto next;
     72                if (rc != EFORWARD) {
     73                        return rc;
    8874                }
    8975
    90                 return rc;
    91 
    92 next:
    93                 handler++;
    9476        }
    9577
  • uspace/lib/usbvirt/src/private.h

    r5b18137 rb4b534ac  
    3939
    4040int process_control_transfer(usbvirt_device_t *,
    41     usbvirt_control_request_handler_t *,
    42     usb_device_request_setup_packet_t *,
     41    const usbvirt_control_request_handler_t *,
     42    const usb_device_request_setup_packet_t *,
    4343    uint8_t *, size_t *);
    4444
  • uspace/lib/usbvirt/src/stdreq.c

    r5b18137 rb4b534ac  
    5151void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet,
    5252    uint8_t *data, size_t *act_size,
    53     void *actual_data, size_t actual_data_size)
     53    const void *actual_data, size_t actual_data_size)
    5454{
    5555        size_t expected_size = setup_packet->length;
     
    6363                *act_size = actual_data_size;
    6464        }
     65}
     66
     67/** NOP handler */
     68int req_nop(usbvirt_device_t *device,
     69    const usb_device_request_setup_packet_t *setup_packet,
     70    uint8_t *data, size_t *act_size)
     71{
     72        return EOK;
    6573}
    6674
     
    98106                }
    99107                /* Copy the data. */
    100                 usbvirt_device_configuration_t *config = &device->descriptors
    101                     ->configuration[index];
     108                const usbvirt_device_configuration_t *config =
     109                    &device->descriptors->configuration[index];
    102110                uint8_t *all_data = malloc(config->descriptor->total_length);
    103111                if (all_data == NULL) {
     
    110118                size_t i;
    111119                for (i = 0; i < config->extra_count; i++) {
    112                         usbvirt_device_configuration_extras_t *extra
     120                        const usbvirt_device_configuration_extras_t *extra
    113121                            = &config->extra[i];
    114122                        memcpy(ptr, extra->data, extra->length);
     
    189197}
    190198
     199static int req_get_dev_status(usbvirt_device_t *device,
     200    const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
     201{
     202        if (setup_packet->length != 2)
     203                return ESTALL;
     204        data[0] = (device->self_powered ? 1 : 0) | (device->remote_wakeup ? 2 : 0);
     205        data[1] = 0;
     206        *act_size = 2;
     207        return EOK;
     208}
     209static int req_get_iface_ep_status(usbvirt_device_t *device,
     210    const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
     211{
     212        if (setup_packet->length != 2)
     213                return ESTALL;
     214        data[0] = 0;
     215        data[1] = 0;
     216        *act_size = 2;
     217        return EOK;
     218}
     219
    191220/** Standard request handlers. */
    192221usbvirt_control_request_handler_t library_handlers[] = {
    193222        {
    194                 .req_direction = USB_DIRECTION_OUT,
    195                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    196                 .req_type = USB_REQUEST_TYPE_STANDARD,
    197                 .request = USB_DEVREQ_SET_ADDRESS,
     223                STD_REQ_OUT(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_SET_ADDRESS),
    198224                .name = "SetAddress",
    199225                .callback = req_set_address
    200226        },
    201227        {
    202                 .req_direction = USB_DIRECTION_IN,
    203                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    204                 .req_type = USB_REQUEST_TYPE_STANDARD,
    205                 .request = USB_DEVREQ_GET_DESCRIPTOR,
    206                 .name = "GetDescriptor",
     228                STD_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
     229                .name = "GetStdDescriptor",
    207230                .callback = req_get_descriptor
    208231        },
    209232        {
    210                 .req_direction = USB_DIRECTION_OUT,
    211                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    212                 .req_type = USB_REQUEST_TYPE_STANDARD,
    213                 .request = USB_DEVREQ_SET_CONFIGURATION,
     233                STD_REQ_OUT(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_SET_CONFIGURATION),
    214234                .name = "SetConfiguration",
    215235                .callback = req_set_configuration
    216236        },
    217 
     237        {
     238                STD_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_STATUS),
     239                .name = "GetDeviceStatus",
     240                .callback = req_get_dev_status,
     241        },
     242        {
     243                STD_REQ_IN(USB_REQUEST_RECIPIENT_INTERFACE, USB_DEVREQ_GET_STATUS),
     244                .name = "GetInterfaceStatus",
     245                .callback = req_get_iface_ep_status,
     246        },
     247        {
     248                /* virtual EPs by default cannot be stalled */
     249                STD_REQ_IN(USB_REQUEST_RECIPIENT_ENDPOINT, USB_DEVREQ_GET_STATUS),
     250                .name = "GetEndpointStatus",
     251                .callback = req_get_iface_ep_status,
     252        },
    218253        { .callback = NULL }
    219254};
  • uspace/lib/usbvirt/src/transfer.c

    r5b18137 rb4b534ac  
    5151 */
    5252static int usbvirt_control_transfer(usbvirt_device_t *dev,
    53     void *setup, size_t setup_size,
     53    const void *setup, size_t setup_size,
    5454    void *data, size_t data_size, size_t *data_size_sent)
    5555{
     
    6060                return ESTALL;
    6161        }
    62         usb_device_request_setup_packet_t *setup_packet = setup;
     62        const usb_device_request_setup_packet_t *setup_packet = setup;
    6363        if (data_size != setup_packet->length) {
    6464                return ESTALL;
     
    100100 * @return Error code.
    101101 */
    102 int usbvirt_control_write(usbvirt_device_t *dev, void *setup, size_t setup_size,
    103     void *data, size_t data_size)
     102int usbvirt_control_write(usbvirt_device_t *dev, const void *setup,
     103    size_t setup_size, void *data, size_t data_size)
    104104{
    105105        return usbvirt_control_transfer(dev, setup, setup_size,
     
    119119 * @return Error code.
    120120 */
    121 int usbvirt_control_read(usbvirt_device_t *dev, void *setup, size_t setup_size,
     121int usbvirt_control_read(usbvirt_device_t *dev, const void *setup, size_t setup_size,
    122122    void *data, size_t data_size, size_t *data_size_sent)
    123123{
     
    136136 */
    137137int usbvirt_data_out(usbvirt_device_t *dev, usb_transfer_type_t transf_type,
    138     usb_endpoint_t endpoint, void *data, size_t data_size)
     138    usb_endpoint_t endpoint, const void *data, size_t data_size)
    139139{
    140140        if ((endpoint <= 0) || (endpoint >= USBVIRT_ENDPOINT_MAX)) {
Note: See TracChangeset for help on using the changeset viewer.