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

Changeset 5dab9ef0 in mainline


Ignore:
Timestamp:
2018-01-17T11:37:34Z (2 years ago)
Author:
Salmelu <salmelu@…>
Branches:
master
Children:
61e27e80
Parents:
0f803831
Message:

xhci: stream dealocation after encountering errors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/streams.c

    r0f803831 r5dab9ef0  
    7070}
    7171
     72static int initialize_primary_structures(xhci_endpoint_t *xhci_ep, unsigned count)
     73{
     74        usb_log_debug2("Allocating primary stream context array of size %u for endpoint " XHCI_EP_FMT,
     75                count, XHCI_EP_ARGS(*xhci_ep));
     76
     77        if ((dma_buffer_alloc(&xhci_ep->primary_stream_ctx_dma, count * sizeof(xhci_stream_ctx_t)))) {
     78                return ENOMEM;
     79        }
     80
     81        xhci_ep->primary_stream_ctx_array = xhci_ep->primary_stream_ctx_dma.virt;
     82        xhci_ep->primary_stream_data_array = calloc(count, sizeof(xhci_stream_data_t));
     83        if (!xhci_ep->primary_stream_data_array) {
     84                dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
     85                return ENOMEM;
     86        }
     87
     88        xhci_ep->primary_stream_data_size = count;
     89
     90        return EOK;
     91}
     92
     93static void clear_primary_structures(xhci_endpoint_t *xhci_ep)
     94{
     95        usb_log_debug2("Deallocating primary stream structures for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
     96
     97        dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
     98        free(xhci_ep->primary_stream_data_array);
     99}
     100
     101static void clear_secondary_streams(xhci_endpoint_t *xhci_ep, unsigned index)
     102{
     103        xhci_stream_data_t *data = &xhci_ep->primary_stream_data_array[index];
     104        if (!data->secondary_size) {
     105                xhci_trb_ring_fini(&data->ring);
     106                return;
     107        }
     108
     109        for (size_t i = 0; i < data->secondary_size; ++i) {
     110                xhci_trb_ring_fini(&data->secondary_data[i].ring);
     111        }
     112
     113        dma_buffer_free(&data->secondary_stream_ctx_dma);
     114        free(data->secondary_data);
     115}
     116
    72117void xhci_stream_free_ds(xhci_endpoint_t *xhci_ep)
    73118{
     
    75120
    76121        for (size_t index = 0; index < xhci_ep->primary_stream_data_size; ++index) {
    77                 xhci_stream_data_t *primary_data = xhci_ep->primary_stream_data_array + index;
    78                 if (primary_data->secondary_size > 0) {
    79                         for (size_t index2 = 0; index2 < primary_data->secondary_size; ++index2) {
    80                                 xhci_stream_data_t *secondary_data = primary_data->secondary_data + index2;
    81                                 xhci_trb_ring_fini(&secondary_data->ring);
    82                         }
    83                         dma_buffer_free(&primary_data->secondary_stream_ctx_dma);
    84                 }
    85                 else {
    86                         xhci_trb_ring_fini(&primary_data->ring);
    87                 }
    88         }
    89         dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
    90 }
    91 
    92 /** Initialize secondary streams of XHCI bulk endpoint.
     122                clear_secondary_streams(xhci_ep, index);
     123        }
     124        clear_primary_structures(xhci_ep);
     125}
     126
     127/** Initialize primary stream structure with given index.
    93128 * @param[in] hc Host controller of the endpoint.
    94129 * @param[in] xhci_epi XHCI bulk endpoint to use.
    95  * @param[in] index Index to primary stream array
     130 * @param[in] index index of the initialized stream structure.
    96131 */
    97132static int initialize_primary_stream(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep, unsigned index) {
     
    116151/** Initialize primary streams of XHCI bulk endpoint.
    117152 * @param[in] hc Host controller of the endpoint.
    118  * @param[in] xhci_epi XHCI bulk endpoint to use.
     153 * @param[in] xhci_ep XHCI bulk endpoint to use.
    119154 */
    120155static int initialize_primary_streams(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep)
    121156{
    122157        int err = EOK;
    123         for (size_t index = 0; index < xhci_ep->primary_stream_data_size; ++index) {
     158        size_t index;
     159        for (index = 0; index < xhci_ep->primary_stream_data_size; ++index) {
    124160                err = initialize_primary_stream(hc, xhci_ep, index);
    125161                if (err) {
    126                         return err;
     162                        goto err_clean;
    127163                }
    128164        }
    129165
    130         // TODO: deinitialize if we got stuck in the middle
    131 
    132         return EOK;
     166        return EOK;
     167
     168err_clean:
     169        for (size_t i = 0; i < index; ++i) {
     170                xhci_trb_ring_fini(&xhci_ep->primary_stream_data_array[i].ring);
     171        }
     172        return err;
    133173}
    134174
     
    136176 * @param[in] hc Host controller of the endpoint.
    137177 * @param[in] xhci_epi XHCI bulk endpoint to use.
    138  * @param[in] index Index to primary stream array
     178 * @param[in] idx Index to primary stream array
    139179 * @param[in] count Number of secondary streams to initialize.
    140180 */
    141 static int initialize_secondary_streams(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep, unsigned index, unsigned count)
     181static int initialize_secondary_streams(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep, unsigned idx, unsigned count)
    142182{
    143183        if (count == 0) {
    144                 return initialize_primary_stream(hc, xhci_ep, index);
     184                return initialize_primary_stream(hc, xhci_ep, idx);
    145185        }
    146186
     
    150190        }
    151191
    152         xhci_stream_ctx_t *ctx = &xhci_ep->primary_stream_ctx_array[index];
    153         xhci_stream_data_t *data = &xhci_ep->primary_stream_data_array[index];
     192        xhci_stream_ctx_t *ctx = &xhci_ep->primary_stream_ctx_array[idx];
     193        xhci_stream_data_t *data = &xhci_ep->primary_stream_data_array[idx];
    154194        memset(data, 0, sizeof(xhci_stream_data_t));
    155195
     
    161201
    162202        if ((dma_buffer_alloc(&data->secondary_stream_ctx_dma, count * sizeof(xhci_stream_ctx_t)))) {
     203                free(data->secondary_data);
    163204                return ENOMEM;
    164205        }
     
    169210
    170211        int err = EOK;
    171 
    172         for (size_t i = 0; i < count; ++i) {
    173                 xhci_stream_ctx_t *secondary_ctx = &data->secondary_stream_ctx_array[i];
    174                 xhci_stream_data_t *secondary_data = &data->secondary_data[i];
     212        size_t index;
     213        for (index = 0; index < count; ++index) {
     214                xhci_stream_ctx_t *secondary_ctx = &data->secondary_stream_ctx_array[index];
     215                xhci_stream_data_t *secondary_data = &data->secondary_data[index];
    175216                /* Init and register TRB ring for every secondary stream */
    176217                if ((err = xhci_trb_ring_init(&secondary_data->ring))) {
    177                         return err;
     218                        goto err_init;
    178219                }
    179220
    180221                XHCI_STREAM_DEQ_PTR_SET(*secondary_ctx, secondary_data->ring.dequeue);
    181 
    182                 /* Set to linear stream array */
     222                /* Set to secondary stream array */
    183223                XHCI_STREAM_SCT_SET(*secondary_ctx, 0);
    184224        }
    185225
    186         // TODO: deinitialize if we got stuck in the middle
    187 
    188         return EOK;
     226        return EOK;
     227
     228err_init:
     229        for (size_t i = 0; i < index; ++i) {
     230                xhci_trb_ring_fini(&data->secondary_data[i].ring);
     231        }
     232        return err;
    189233}
    190234
     
    246290}
    247291
    248 static int initialize_primary_structures(xhci_endpoint_t *xhci_ep, unsigned count)
    249 {
    250         usb_log_debug2("Allocating primary stream context array of size %u for endpoint " XHCI_EP_FMT,
    251                 count, XHCI_EP_ARGS(*xhci_ep));
    252 
    253         if ((dma_buffer_alloc(&xhci_ep->primary_stream_ctx_dma, count * sizeof(xhci_stream_ctx_t)))) {
    254                 return ENOMEM;
    255         }
    256 
    257         xhci_ep->primary_stream_ctx_array = xhci_ep->primary_stream_ctx_dma.virt;
    258         xhci_ep->primary_stream_data_array = calloc(count, sizeof(xhci_stream_data_t));
    259         if (!xhci_ep->primary_stream_data_array) {
    260                 dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);
    261                 return ENOMEM;
    262         }
    263 
    264         xhci_ep->primary_stream_data_size = count;
    265 
    266         return EOK;
    267 }
    268 
    269292/** Initialize primary streams
    270293 */
     
    283306
    284307        memset(xhci_ep->primary_stream_ctx_array, 0, count * sizeof(xhci_stream_ctx_t));
    285         initialize_primary_streams(hc, xhci_ep);
     308        err = initialize_primary_streams(hc, xhci_ep);
     309        if (err) {
     310                clear_primary_structures(xhci_ep);
     311                return err;
     312        }
    286313
    287314        xhci_ep_ctx_t ep_ctx;
     
    340367
    341368        memset(xhci_ep->primary_stream_ctx_array, 0, count * sizeof(xhci_stream_ctx_t));
    342         for (size_t index = 0; index < count; ++index) {
    343                 initialize_secondary_streams(hc, xhci_ep, index, *(sizes + index));
     369        size_t index;
     370        for (index = 0; index < count; ++index) {
     371                err = initialize_secondary_streams(hc, xhci_ep, index, *(sizes + index));
     372                if (err) {
     373                        goto err_init;
     374                }
    344375        }
    345376
     
    350381        // FIXME: do we add endpoint? do we need to destroy previous configuration?
    351382        return hc_add_endpoint(hc, dev->slot_id, xhci_endpoint_index(xhci_ep), &ep_ctx);
    352 }
     383
     384err_init:
     385        for (size_t i = 0; i < index; ++i) {
     386                clear_secondary_streams(xhci_ep, i);
     387        }
     388        clear_primary_structures(xhci_ep);
     389        return err;
     390}
Note: See TracChangeset for help on using the changeset viewer.