Changes in / [61727bf:c6cb76d] in mainline


Ignore:
Location:
uspace
Files:
3 added
2 deleted
8 edited

Legend:

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

    r61727bf rc6cb76d  
    165165 * @param[in] fun Device function the action was invoked on.
    166166 * @param[in] target Target pipe (address and endpoint number) specification.
    167  * @param[in] max_packet_size Max packet size for the transfer.
    168167 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    169168 *      by the caller).
     
    174173 */
    175174static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    176     size_t max_packet_size, void *data, size_t size,
     175    void *data, size_t size,
    177176    usbhc_iface_transfer_out_callback_t callback, void *arg)
    178177{
     
    191190 * @param[in] fun Device function the action was invoked on.
    192191 * @param[in] target Target pipe (address and endpoint number) specification.
    193  * @param[in] max_packet_size Max packet size for the transfer.
    194192 * @param[in] data Buffer where to store the data (in USB endianess,
    195193 *      allocated and deallocated by the caller).
     
    200198 */
    201199static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    202     size_t max_packet_size, void *data, size_t size,
     200    void *data, size_t size,
    203201    usbhc_iface_transfer_in_callback_t callback, void *arg)
    204202{
     
    217215 * @param[in] fun Device function the action was invoked on.
    218216 * @param[in] target Target pipe (address and endpoint number) specification.
    219  * @param[in] max_packet_size Max packet size for the transfer.
    220217 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    221218 *      by the caller).
     
    226223 */
    227224static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    228     size_t max_packet_size, void *data, size_t size,
     225    void *data, size_t size,
    229226    usbhc_iface_transfer_out_callback_t callback, void *arg)
    230227{
     
    243240 * @param[in] fun Device function the action was invoked on.
    244241 * @param[in] target Target pipe (address and endpoint number) specification.
    245  * @param[in] max_packet_size Max packet size for the transfer.
    246242 * @param[in] data Buffer where to store the data (in USB endianess,
    247243 *      allocated and deallocated by the caller).
     
    252248 */
    253249static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    254     size_t max_packet_size, void *data, size_t size,
     250    void *data, size_t size,
    255251    usbhc_iface_transfer_in_callback_t callback, void *arg)
    256252{
     
    269265 * @param[in] fun Device function the action was invoked on.
    270266 * @param[in] target Target pipe (address and endpoint number) specification.
    271  * @param[in] max_packet_size Max packet size for the transfer.
    272267 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    273268 *      and deallocated by the caller).
     
    281276 */
    282277static int control_write(ddf_fun_t *fun, usb_target_t target,
    283     size_t max_packet_size,
    284278    void *setup_packet, size_t setup_packet_size,
    285279    void *data_buffer, size_t data_buffer_size,
     
    300294 * @param[in] fun Device function the action was invoked on.
    301295 * @param[in] target Target pipe (address and endpoint number) specification.
    302  * @param[in] max_packet_size Max packet size for the transfer.
    303296 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    304297 *      and deallocated by the caller).
     
    312305 */
    313306static int control_read(ddf_fun_t *fun, usb_target_t target,
    314     size_t max_packet_size,
    315307    void *setup_packet, size_t setup_packet_size,
    316308    void *data_buffer, size_t data_buffer_size,
  • uspace/drv/ohci/iface.c

    r61727bf rc6cb76d  
    196196 * @param[in] fun Device function the action was invoked on.
    197197 * @param[in] target Target pipe (address and endpoint number) specification.
    198  * @param[in] max_packet_size Max packet size for the transfer.
    199198 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    200199 *      by the caller).
     
    205204 */
    206205static int interrupt_out(
    207     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     206    ddf_fun_t *fun, usb_target_t target, void *data,
    208207    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    209208{
    210209        assert(fun);
     210
     211        // FIXME: get from endpoint manager
     212        size_t max_packet_size = 8;
     213
    211214        hc_t *hc = fun_to_hc(fun);
    212215        assert(hc);
     
    239242 * @param[in] fun Device function the action was invoked on.
    240243 * @param[in] target Target pipe (address and endpoint number) specification.
    241  * @param[in] max_packet_size Max packet size for the transfer.
    242244 * @param[in] data Buffer where to store the data (in USB endianess,
    243245 *      allocated and deallocated by the caller).
     
    248250 */
    249251static int interrupt_in(
    250     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     252    ddf_fun_t *fun, usb_target_t target, void *data,
    251253    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    252254{
    253255        assert(fun);
     256
     257        // FIXME: get from endpoint manager
     258        size_t max_packet_size = 8;
     259
    254260        hc_t *hc = fun_to_hc(fun);
    255261        assert(hc);
     
    281287 * @param[in] fun Device function the action was invoked on.
    282288 * @param[in] target Target pipe (address and endpoint number) specification.
    283  * @param[in] max_packet_size Max packet size for the transfer.
    284289 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    285290 *      by the caller).
     
    290295 */
    291296static int bulk_out(
    292     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     297    ddf_fun_t *fun, usb_target_t target, void *data,
    293298    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    294299{
    295300        assert(fun);
     301
     302        // FIXME: get from endpoint manager
     303        size_t max_packet_size = 8;
     304
    296305        hc_t *hc = fun_to_hc(fun);
    297306        assert(hc);
     
    324333 * @param[in] fun Device function the action was invoked on.
    325334 * @param[in] target Target pipe (address and endpoint number) specification.
    326  * @param[in] max_packet_size Max packet size for the transfer.
    327335 * @param[in] data Buffer where to store the data (in USB endianess,
    328336 *      allocated and deallocated by the caller).
     
    333341 */
    334342static int bulk_in(
    335     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     343    ddf_fun_t *fun, usb_target_t target, void *data,
    336344    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    337345{
    338346        assert(fun);
     347
     348        // FIXME: get from endpoint manager
     349        size_t max_packet_size = 8;
     350
    339351        hc_t *hc = fun_to_hc(fun);
    340352        assert(hc);
     
    366378 * @param[in] fun Device function the action was invoked on.
    367379 * @param[in] target Target pipe (address and endpoint number) specification.
    368  * @param[in] max_packet_size Max packet size for the transfer.
    369380 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    370381 *      and deallocated by the caller).
     
    378389 */
    379390static int control_write(
    380     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     391    ddf_fun_t *fun, usb_target_t target,
    381392    void *setup_data, size_t setup_size, void *data, size_t size,
    382393    usbhc_iface_transfer_out_callback_t callback, void *arg)
    383394{
    384395        assert(fun);
     396
     397        // FIXME: get from endpoint manager
     398        size_t max_packet_size = 8;
     399
    385400        hc_t *hc = fun_to_hc(fun);
    386401        assert(hc);
     
    417432 * @param[in] fun Device function the action was invoked on.
    418433 * @param[in] target Target pipe (address and endpoint number) specification.
    419  * @param[in] max_packet_size Max packet size for the transfer.
    420434 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    421435 *      and deallocated by the caller).
     
    429443 */
    430444static int control_read(
    431     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     445    ddf_fun_t *fun, usb_target_t target,
    432446    void *setup_data, size_t setup_size, void *data, size_t size,
    433447    usbhc_iface_transfer_in_callback_t callback, void *arg)
    434448{
    435449        assert(fun);
     450
     451        // FIXME: get from endpoint manager
     452        size_t max_packet_size = 8;
     453
    436454        hc_t *hc = fun_to_hc(fun);
    437455        assert(hc);
  • uspace/drv/uhci-hcd/iface.c

    r61727bf rc6cb76d  
    251251 * @param[in] fun DDF function that was called.
    252252 * @param[in] target USB device to write to.
    253  * @param[in] max_packet_size maximum size of data packet the device accepts
    254253 * @param[in] data Source of data.
    255254 * @param[in] size Size of data source.
     
    259258 */
    260259static int interrupt_out(
    261     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     260    ddf_fun_t *fun, usb_target_t target, void *data,
    262261    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    263262{
     
    280279 * @param[in] fun DDF function that was called.
    281280 * @param[in] target USB device to write to.
    282  * @param[in] max_packet_size maximum size of data packet the device accepts
    283281 * @param[out] data Data destination.
    284282 * @param[in] size Size of data source.
     
    288286 */
    289287static int interrupt_in(
    290     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     288    ddf_fun_t *fun, usb_target_t target, void *data,
    291289    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    292290{
     
    309307 * @param[in] fun DDF function that was called.
    310308 * @param[in] target USB device to write to.
    311  * @param[in] max_packet_size maximum size of data packet the device accepts
    312309 * @param[in] data Source of data.
    313310 * @param[in] size Size of data source.
     
    317314 */
    318315static int bulk_out(
    319     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     316    ddf_fun_t *fun, usb_target_t target, void *data,
    320317    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    321318{
     
    338335 * @param[in] fun DDF function that was called.
    339336 * @param[in] target USB device to write to.
    340  * @param[in] max_packet_size maximum size of data packet the device accepts
    341337 * @param[out] data Data destination.
    342338 * @param[in] size Size of data source.
     
    346342 */
    347343static int bulk_in(
    348     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
     344    ddf_fun_t *fun, usb_target_t target, void *data,
    349345    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    350346{
     
    367363 * @param[in] fun DDF function that was called.
    368364 * @param[in] target USB device to write to.
    369  * @param[in] max_packet_size maximum size of data packet the device accepts.
    370365 * @param[in] setup_data Data to send with SETUP transfer.
    371366 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    377372 */
    378373static int control_write(
    379     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     374    ddf_fun_t *fun, usb_target_t target,
    380375    void *setup_data, size_t setup_size, void *data, size_t size,
    381376    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    401396 * @param[in] fun DDF function that was called.
    402397 * @param[in] target USB device to write to.
    403  * @param[in] max_packet_size maximum size of data packet the device accepts.
    404398 * @param[in] setup_data Data to send with SETUP packet.
    405399 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    411405 */
    412406static int control_read(
    413     ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
     407    ddf_fun_t *fun, usb_target_t target,
    414408    void *setup_data, size_t setup_size, void *data, size_t size,
    415409    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/vhc/connhost.c

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

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

    r61727bf rc6cb76d  
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
    68  *   - argument #3 is max packet size of the endpoint
    6968 * - this call is immediately followed by IPC data read (async version)
    7069 * - the call is not answered until the device returns some data (or until
     
    202201
    203202/** Out transfer processing function prototype. */
    204 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
     203typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t,
    205204    void *, size_t,
    206205    usbhc_iface_transfer_out_callback_t, void *);
     
    210209
    211210/** In transfer processing function prototype. */
    212 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
     211typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t,
    213212    void *, size_t,
    214213    usbhc_iface_transfer_in_callback_t, void *);
     
    234233
    235234        int (*control_write)(ddf_fun_t *, usb_target_t,
    236             size_t,
    237235            void *, size_t, void *, size_t,
    238236            usbhc_iface_transfer_out_callback_t, void *);
    239237
    240238        int (*control_read)(ddf_fun_t *, usb_target_t,
    241             size_t,
    242239            void *, size_t, void *, size_t,
    243240            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/include/usb/devdrv.h

    r61727bf rc6cb76d  
    169169    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
    170170
     171int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
     172int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
     173    usb_endpoint_description_t **, uint8_t *, size_t, int, int,
     174    usb_endpoint_mapping_t **, size_t *);
     175int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
     176
     177size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
     178
    171179#endif
    172180/**
  • uspace/lib/usb/src/devdrv.c

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