Changes in / [c6cb76d:61727bf] in mainline


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

Legend:

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

    rc6cb76d r61727bf  
    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.
    167168 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    168169 *      by the caller).
     
    173174 */
    174175static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    175     void *data, size_t size,
     176    size_t max_packet_size, void *data, size_t size,
    176177    usbhc_iface_transfer_out_callback_t callback, void *arg)
    177178{
     
    190191 * @param[in] fun Device function the action was invoked on.
    191192 * @param[in] target Target pipe (address and endpoint number) specification.
     193 * @param[in] max_packet_size Max packet size for the transfer.
    192194 * @param[in] data Buffer where to store the data (in USB endianess,
    193195 *      allocated and deallocated by the caller).
     
    198200 */
    199201static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    200     void *data, size_t size,
     202    size_t max_packet_size, void *data, size_t size,
    201203    usbhc_iface_transfer_in_callback_t callback, void *arg)
    202204{
     
    215217 * @param[in] fun Device function the action was invoked on.
    216218 * @param[in] target Target pipe (address and endpoint number) specification.
     219 * @param[in] max_packet_size Max packet size for the transfer.
    217220 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    218221 *      by the caller).
     
    223226 */
    224227static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    225     void *data, size_t size,
     228    size_t max_packet_size, void *data, size_t size,
    226229    usbhc_iface_transfer_out_callback_t callback, void *arg)
    227230{
     
    240243 * @param[in] fun Device function the action was invoked on.
    241244 * @param[in] target Target pipe (address and endpoint number) specification.
     245 * @param[in] max_packet_size Max packet size for the transfer.
    242246 * @param[in] data Buffer where to store the data (in USB endianess,
    243247 *      allocated and deallocated by the caller).
     
    248252 */
    249253static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    250     void *data, size_t size,
     254    size_t max_packet_size, void *data, size_t size,
    251255    usbhc_iface_transfer_in_callback_t callback, void *arg)
    252256{
     
    265269 * @param[in] fun Device function the action was invoked on.
    266270 * @param[in] target Target pipe (address and endpoint number) specification.
     271 * @param[in] max_packet_size Max packet size for the transfer.
    267272 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    268273 *      and deallocated by the caller).
     
    276281 */
    277282static int control_write(ddf_fun_t *fun, usb_target_t target,
     283    size_t max_packet_size,
    278284    void *setup_packet, size_t setup_packet_size,
    279285    void *data_buffer, size_t data_buffer_size,
     
    294300 * @param[in] fun Device function the action was invoked on.
    295301 * @param[in] target Target pipe (address and endpoint number) specification.
     302 * @param[in] max_packet_size Max packet size for the transfer.
    296303 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    297304 *      and deallocated by the caller).
     
    305312 */
    306313static int control_read(ddf_fun_t *fun, usb_target_t target,
     314    size_t max_packet_size,
    307315    void *setup_packet, size_t setup_packet_size,
    308316    void *data_buffer, size_t data_buffer_size,
  • uspace/drv/ohci/iface.c

    rc6cb76d r61727bf  
    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.
    198199 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    199200 *      by the caller).
     
    204205 */
    205206static int interrupt_out(
    206     ddf_fun_t *fun, usb_target_t target, void *data,
     207    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    207208    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    208209{
    209210        assert(fun);
    210 
    211         // FIXME: get from endpoint manager
    212         size_t max_packet_size = 8;
    213 
    214211        hc_t *hc = fun_to_hc(fun);
    215212        assert(hc);
     
    242239 * @param[in] fun Device function the action was invoked on.
    243240 * @param[in] target Target pipe (address and endpoint number) specification.
     241 * @param[in] max_packet_size Max packet size for the transfer.
    244242 * @param[in] data Buffer where to store the data (in USB endianess,
    245243 *      allocated and deallocated by the caller).
     
    250248 */
    251249static int interrupt_in(
    252     ddf_fun_t *fun, usb_target_t target, void *data,
     250    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    253251    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    254252{
    255253        assert(fun);
    256 
    257         // FIXME: get from endpoint manager
    258         size_t max_packet_size = 8;
    259 
    260254        hc_t *hc = fun_to_hc(fun);
    261255        assert(hc);
     
    287281 * @param[in] fun Device function the action was invoked on.
    288282 * @param[in] target Target pipe (address and endpoint number) specification.
     283 * @param[in] max_packet_size Max packet size for the transfer.
    289284 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
    290285 *      by the caller).
     
    295290 */
    296291static int bulk_out(
    297     ddf_fun_t *fun, usb_target_t target, void *data,
     292    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    298293    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    299294{
    300295        assert(fun);
    301 
    302         // FIXME: get from endpoint manager
    303         size_t max_packet_size = 8;
    304 
    305296        hc_t *hc = fun_to_hc(fun);
    306297        assert(hc);
     
    333324 * @param[in] fun Device function the action was invoked on.
    334325 * @param[in] target Target pipe (address and endpoint number) specification.
     326 * @param[in] max_packet_size Max packet size for the transfer.
    335327 * @param[in] data Buffer where to store the data (in USB endianess,
    336328 *      allocated and deallocated by the caller).
     
    341333 */
    342334static int bulk_in(
    343     ddf_fun_t *fun, usb_target_t target, void *data,
     335    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    344336    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    345337{
    346338        assert(fun);
    347 
    348         // FIXME: get from endpoint manager
    349         size_t max_packet_size = 8;
    350 
    351339        hc_t *hc = fun_to_hc(fun);
    352340        assert(hc);
     
    378366 * @param[in] fun Device function the action was invoked on.
    379367 * @param[in] target Target pipe (address and endpoint number) specification.
     368 * @param[in] max_packet_size Max packet size for the transfer.
    380369 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    381370 *      and deallocated by the caller).
     
    389378 */
    390379static int control_write(
    391     ddf_fun_t *fun, usb_target_t target,
     380    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    392381    void *setup_data, size_t setup_size, void *data, size_t size,
    393382    usbhc_iface_transfer_out_callback_t callback, void *arg)
    394383{
    395384        assert(fun);
    396 
    397         // FIXME: get from endpoint manager
    398         size_t max_packet_size = 8;
    399 
    400385        hc_t *hc = fun_to_hc(fun);
    401386        assert(hc);
     
    432417 * @param[in] fun Device function the action was invoked on.
    433418 * @param[in] target Target pipe (address and endpoint number) specification.
     419 * @param[in] max_packet_size Max packet size for the transfer.
    434420 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
    435421 *      and deallocated by the caller).
     
    443429 */
    444430static int control_read(
    445     ddf_fun_t *fun, usb_target_t target,
     431    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    446432    void *setup_data, size_t setup_size, void *data, size_t size,
    447433    usbhc_iface_transfer_in_callback_t callback, void *arg)
    448434{
    449435        assert(fun);
    450 
    451         // FIXME: get from endpoint manager
    452         size_t max_packet_size = 8;
    453 
    454436        hc_t *hc = fun_to_hc(fun);
    455437        assert(hc);
  • uspace/drv/uhci-hcd/iface.c

    rc6cb76d r61727bf  
    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
    253254 * @param[in] data Source of data.
    254255 * @param[in] size Size of data source.
     
    258259 */
    259260static int interrupt_out(
    260     ddf_fun_t *fun, usb_target_t target, void *data,
     261    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    261262    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    262263{
     
    279280 * @param[in] fun DDF function that was called.
    280281 * @param[in] target USB device to write to.
     282 * @param[in] max_packet_size maximum size of data packet the device accepts
    281283 * @param[out] data Data destination.
    282284 * @param[in] size Size of data source.
     
    286288 */
    287289static int interrupt_in(
    288     ddf_fun_t *fun, usb_target_t target, void *data,
     290    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    289291    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    290292{
     
    307309 * @param[in] fun DDF function that was called.
    308310 * @param[in] target USB device to write to.
     311 * @param[in] max_packet_size maximum size of data packet the device accepts
    309312 * @param[in] data Source of data.
    310313 * @param[in] size Size of data source.
     
    314317 */
    315318static int bulk_out(
    316     ddf_fun_t *fun, usb_target_t target, void *data,
     319    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    317320    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    318321{
     
    335338 * @param[in] fun DDF function that was called.
    336339 * @param[in] target USB device to write to.
     340 * @param[in] max_packet_size maximum size of data packet the device accepts
    337341 * @param[out] data Data destination.
    338342 * @param[in] size Size of data source.
     
    342346 */
    343347static int bulk_in(
    344     ddf_fun_t *fun, usb_target_t target, void *data,
     348    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data,
    345349    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    346350{
     
    363367 * @param[in] fun DDF function that was called.
    364368 * @param[in] target USB device to write to.
     369 * @param[in] max_packet_size maximum size of data packet the device accepts.
    365370 * @param[in] setup_data Data to send with SETUP transfer.
    366371 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
     
    372377 */
    373378static int control_write(
    374     ddf_fun_t *fun, usb_target_t target,
     379    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    375380    void *setup_data, size_t setup_size, void *data, size_t size,
    376381    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    396401 * @param[in] fun DDF function that was called.
    397402 * @param[in] target USB device to write to.
     403 * @param[in] max_packet_size maximum size of data packet the device accepts.
    398404 * @param[in] setup_data Data to send with SETUP packet.
    399405 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     
    405411 */
    406412static int control_read(
    407     ddf_fun_t *fun, usb_target_t target,
     413    ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,
    408414    void *setup_data, size_t setup_size, void *data, size_t size,
    409415    usbhc_iface_transfer_in_callback_t callback, void *arg)
  • uspace/drv/vhc/connhost.c

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

    rc6cb76d r61727bf  
    270270        }
    271271
     272        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    272273        usb_target_t target = {
    273274                .address = DEV_IPC_GET_ARG1(*call),
     
    299300        trans->size = len;
    300301
    301         rc = transfer_func(fun, target,
     302        rc = transfer_func(fun, target, max_packet_size,
    302303            buffer, len,
    303304            callback_out, trans);
     
    325326        }
    326327
     328        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    327329        usb_target_t target = {
    328330                .address = DEV_IPC_GET_ARG1(*call),
     
    346348        trans->size = len;
    347349
    348         int rc = transfer_func(fun, target,
     350        int rc = transfer_func(fun, target, max_packet_size,
    349351            trans->buffer, len,
    350352            callback_in, trans);
     
    412414        };
    413415        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
     416        size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    414417
    415418        int rc;
     
    447450        trans->size = data_buffer_len;
    448451
    449         rc = usb_iface->control_write(fun, target,
     452        rc = usb_iface->control_write(fun, target, max_packet_size,
    450453            setup_packet, setup_packet_len,
    451454            data_buffer, data_buffer_len,
     
    474477                .endpoint = DEV_IPC_GET_ARG2(*call)
    475478        };
     479        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    476480
    477481        int rc;
     
    511515        }
    512516
    513         rc = usb_iface->control_read(fun, target,
     517        rc = usb_iface->control_read(fun, target, max_packet_size,
    514518            setup_packet, setup_packet_len,
    515519            trans->buffer, trans->size,
  • uspace/lib/drv/include/usbhc_iface.h

    rc6cb76d r61727bf  
    6666 *   - argument #1 is target address
    6767 *   - argument #2 is target endpoint
     68 *   - argument #3 is max packet size of the endpoint
    6869 * - this call is immediately followed by IPC data read (async version)
    6970 * - the call is not answered until the device returns some data (or until
     
    201202
    202203/** Out transfer processing function prototype. */
    203 typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t,
     204typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
    204205    void *, size_t,
    205206    usbhc_iface_transfer_out_callback_t, void *);
     
    209210
    210211/** In transfer processing function prototype. */
    211 typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t,
     212typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
    212213    void *, size_t,
    213214    usbhc_iface_transfer_in_callback_t, void *);
     
    233234
    234235        int (*control_write)(ddf_fun_t *, usb_target_t,
     236            size_t,
    235237            void *, size_t, void *, size_t,
    236238            usbhc_iface_transfer_out_callback_t, void *);
    237239
    238240        int (*control_read)(ddf_fun_t *, usb_target_t,
     241            size_t,
    239242            void *, size_t, void *, size_t,
    240243            usbhc_iface_transfer_in_callback_t, void *);
  • uspace/lib/usb/include/usb/devdrv.h

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

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