Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    r9d58539 r584aa38  
    3232 * @brief OHCI driver USB transaction structure
    3333 */
     34
     35#include <assert.h>
    3436#include <errno.h>
    35 #include <str_error.h>
    3637#include <macros.h>
     38#include <mem.h>
     39#include <stdbool.h>
    3740
    3841#include <usb/usb.h>
     
    4447
    4548static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t);
    46 /*----------------------------------------------------------------------------*/
     49
    4750/** Safely destructs ohci_transfer_batch_t structure
    4851 *
     
    6770        free(ohci_batch);
    6871}
    69 /*----------------------------------------------------------------------------*/
     72
    7073/** Finishes usb_transfer_batch and destroys the structure.
    7174 *
     
    8083        ohci_transfer_batch_dispose(ohci_batch);
    8184}
    82 /*----------------------------------------------------------------------------*/
     85
    8386/** Allocate memory and initialize internal data structure.
    8487 *
     
    9497{
    9598        assert(usb_batch);
    96 #define CHECK_NULL_DISPOSE_RET(ptr, message...) \
    97 if (ptr == NULL) { \
    98         usb_log_error(message); \
    99         ohci_transfer_batch_dispose(ohci_batch); \
    100         return NULL; \
    101 } else (void)0
    10299
    103100        ohci_transfer_batch_t *ohci_batch =
    104101            calloc(1, sizeof(ohci_transfer_batch_t));
    105         CHECK_NULL_DISPOSE_RET(ohci_batch,
    106             "Failed to allocate OHCI batch data.\n");
     102        if (!ohci_batch) {
     103                usb_log_error("Failed to allocate OHCI batch data.");
     104                goto dispose;
     105        }
    107106        link_initialize(&ohci_batch->link);
    108107        ohci_batch->td_count =
     
    116115        /* We need an extra place for TD that was left at ED */
    117116        ohci_batch->tds = calloc(ohci_batch->td_count + 1, sizeof(td_t*));
    118         CHECK_NULL_DISPOSE_RET(ohci_batch->tds,
    119             "Failed to allocate OHCI transfer descriptors.\n");
     117        if (!ohci_batch->tds) {
     118                usb_log_error("Failed to allocate OHCI transfer descriptors.");
     119                goto dispose;
     120        }
    120121
    121122        /* Add TD left over by the previous transfer */
     
    125126        for (unsigned i = 1; i <= ohci_batch->td_count; ++i) {
    126127                ohci_batch->tds[i] = malloc32(sizeof(td_t));
    127                 CHECK_NULL_DISPOSE_RET(ohci_batch->tds[i],
    128                     "Failed to allocate TD %d.\n", i );
     128                if (!ohci_batch->tds[i]) {
     129                        usb_log_error("Failed to allocate TD %d.", i);
     130                        goto dispose;
     131                }
    129132        }
    130133
     
    138141                ohci_batch->device_buffer =
    139142                    malloc32(usb_batch->setup_size + usb_batch->buffer_size);
    140                 CHECK_NULL_DISPOSE_RET(ohci_batch->device_buffer,
    141                     "Failed to allocate device accessible buffer.\n");
     143                if (!ohci_batch->device_buffer) {
     144                        usb_log_error("Failed to allocate device buffer");
     145                        goto dispose;
     146                }
    142147                /* Copy setup data */
    143148                memcpy(ohci_batch->device_buffer, usb_batch->setup_buffer,
     
    156161
    157162        return ohci_batch;
    158 #undef CHECK_NULL_DISPOSE_RET
    159 }
    160 /*----------------------------------------------------------------------------*/
     163dispose:
     164        ohci_transfer_batch_dispose(ohci_batch);
     165        return NULL;
     166}
     167
    161168/** Check batch TDs' status.
    162169 *
     
    199206                    ohci_batch->tds[i]->next, ohci_batch->tds[i]->be);
    200207
    201                 /* If the TD got all its data through, it will report 0 bytes
    202                  * remain, the sole exception is INPUT with data rounding flag
    203                  * (short), i.e. every INPUT. Nice thing is that short packets
    204                  * will correctly report remaining data, thus making
    205                  * this computation correct (short packets need to be produced
    206                  * by the last TD)
    207                  * NOTE: This also works for CONTROL transfer as
    208                  * the first TD will return 0 remain.
    209                  * NOTE: Short packets don't break the assumption that
    210                  * we leave the very last(unused) TD behind.
    211                  */
    212                 ohci_batch->usb_batch->transfered_size
    213                     -= td_remain_size(ohci_batch->tds[i]);
    214 
    215208                ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]);
    216                 if (ohci_batch->usb_batch->error != EOK) {
     209                if (ohci_batch->usb_batch->error == EOK) {
     210                        /* If the TD got all its data through, it will report
     211                         * 0 bytes remain, the sole exception is INPUT with
     212                         * data rounding flag (short), i.e. every INPUT.
     213                         * Nice thing is that short packets will correctly
     214                         * report remaining data, thus making this computation
     215                         * correct (short packets need to be produced by the
     216                         * last TD)
     217                         * NOTE: This also works for CONTROL transfer as
     218                         * the first TD will return 0 remain.
     219                         * NOTE: Short packets don't break the assumption that
     220                         * we leave the very last(unused) TD behind.
     221                         */
     222                        ohci_batch->usb_batch->transfered_size
     223                            -= td_remain_size(ohci_batch->tds[i]);
     224                } else {
    217225                        usb_log_debug("Batch %p found error TD(%zu):%08x.\n",
    218226                            ohci_batch->usb_batch, i,
     
    231239
    232240                        /* Check TD assumption */
    233                         const uint32_t pa =
    234                             addr_to_phys(ohci_batch->tds[leave_td]);
    235                         assert((ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK)
    236                             == pa);
    237 
     241                        assert(ed_head_td(ohci_batch->ed) ==
     242                            addr_to_phys(ohci_batch->tds[leave_td]));
     243
     244                        /* Set tail to the same TD */
    238245                        ed_set_tail_td(ohci_batch->ed,
    239246                            ohci_batch->tds[leave_td]);
    240247
    241248                        /* Clear possible ED HALT */
    242                         ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
     249                        ed_clear_halt(ohci_batch->ed);
    243250                        break;
    244251                }
     
    253260
    254261        /* Make sure that we are leaving the right TD behind */
    255         const uint32_t pa = addr_to_phys(ohci_ep->td);
    256         assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK));
    257         assert(pa == (ohci_batch->ed->td_tail & ED_TDTAIL_PTR_MASK));
     262        assert(addr_to_phys(ohci_ep->td) == ed_head_td(ohci_batch->ed));
     263        assert(addr_to_phys(ohci_ep->td) == ed_tail_td(ohci_batch->ed));
    258264
    259265        return true;
    260266}
    261 /*----------------------------------------------------------------------------*/
     267
    262268/** Starts execution of the TD list
    263269 *
     
    269275        ed_set_tail_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]);
    270276}
    271 /*----------------------------------------------------------------------------*/
     277
    272278/** Prepare generic control transfer
    273279 *
     
    345351            USB_TRANSFER_BATCH_ARGS(*ohci_batch->usb_batch));
    346352}
    347 /*----------------------------------------------------------------------------*/
     353
    348354/** Prepare generic data transfer
    349355 *
     
    392398            USB_TRANSFER_BATCH_ARGS(*ohci_batch->usb_batch));
    393399}
    394 /*----------------------------------------------------------------------------*/
     400
    395401/** Transfer setup table. */
    396402static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t) =
Note: See TracChangeset for help on using the changeset viewer.