Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r58563585 r5fd9c30  
    5050#define DEFAULT_ERROR_COUNT 3
    5151
    52 /** Safely destructs uhci_transfer_batch_t structure.
     52/** Transfer batch setup table. */
     53static void (*const batch_setup[])(uhci_transfer_batch_t*);
     54
     55/** Destroys uhci_transfer_batch_t structure.
    5356 *
    5457 * @param[in] uhci_batch Instance to destroy.
    5558 */
    56 static void uhci_transfer_batch_dispose(uhci_transfer_batch_t *uhci_batch)
    57 {
    58         if (uhci_batch) {
    59                 usb_transfer_batch_destroy(uhci_batch->usb_batch);
    60                 free32(uhci_batch->device_buffer);
    61                 free(uhci_batch);
    62         }
    63 }
    64 
    65 /** Finishes usb_transfer_batch and destroys the structure.
    66  *
    67  * @param[in] uhci_batch Instance to finish and destroy.
    68  */
    69 void uhci_transfer_batch_finish_dispose(uhci_transfer_batch_t *uhci_batch)
     59void uhci_transfer_batch_destroy(uhci_transfer_batch_t *uhci_batch)
    7060{
    7161        assert(uhci_batch);
    72         assert(uhci_batch->usb_batch);
    73         assert(!link_in_use(&uhci_batch->link));
    74         usb_transfer_batch_finish(uhci_batch->usb_batch,
    75             uhci_transfer_batch_data_buffer(uhci_batch));
    76         uhci_transfer_batch_dispose(uhci_batch);
    77 }
    78 
    79 /** Transfer batch setup table. */
    80 static void (*const batch_setup[])(uhci_transfer_batch_t*, usb_direction_t);
     62        free32(uhci_batch->device_buffer);
     63        free(uhci_batch);
     64}
    8165
    8266/** Allocate memory and initialize internal data structure.
     
    8569 * @return Valid pointer if all structures were successfully created,
    8670 * NULL otherwise.
     71 */
     72uhci_transfer_batch_t * uhci_transfer_batch_create(endpoint_t *ep)
     73{
     74        uhci_transfer_batch_t *uhci_batch =
     75            calloc(1, sizeof(uhci_transfer_batch_t));
     76        if (!uhci_batch) {
     77                usb_log_error("Failed to allocate UHCI batch.\n");
     78                return NULL;
     79        }
     80
     81        usb_transfer_batch_init(&uhci_batch->base, ep);
     82
     83        link_initialize(&uhci_batch->link);
     84        return uhci_batch;
     85}
     86
     87/* Prepares batch for commiting.
    8788 *
    8889 * Determines the number of needed transfer descriptors (TDs).
     
    9091 * Initializes parameters needed for the transfer and callback.
    9192 */
    92 uhci_transfer_batch_t * uhci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
     93int uhci_transfer_batch_prepare(uhci_transfer_batch_t *uhci_batch)
    9394{
    9495        static_assert((sizeof(td_t) % 16) == 0);
    95 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    96         if (ptr == NULL) { \
    97                 usb_log_error(message); \
    98                 uhci_transfer_batch_dispose(uhci_batch); \
    99                 return NULL; \
    100         } else (void)0
    101 
    102         uhci_transfer_batch_t *uhci_batch =
    103             calloc(1, sizeof(uhci_transfer_batch_t));
    104         CHECK_NULL_DISPOSE_RETURN(uhci_batch,
    105             "Failed to allocate UHCI batch.\n");
    106         link_initialize(&uhci_batch->link);
    107         uhci_batch->td_count =
    108             (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1)
    109             / usb_batch->ep->max_packet_size;
     96
     97        usb_transfer_batch_t *usb_batch = &uhci_batch->base;
     98
     99        uhci_batch->td_count = (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1)
     100                / usb_batch->ep->max_packet_size;
     101
    110102        if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    111103                uhci_batch->td_count += 2;
    112104        }
    113105
     106        const size_t setup_size = (uhci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL)
     107                ? USB_SETUP_PACKET_SIZE
     108                : 0;
     109
    114110        const size_t total_size = (sizeof(td_t) * uhci_batch->td_count)
    115             + sizeof(qh_t) + usb_batch->setup_size + usb_batch->buffer_size;
     111            + sizeof(qh_t) + setup_size + usb_batch->buffer_size;
    116112        uhci_batch->device_buffer = malloc32(total_size);
    117         CHECK_NULL_DISPOSE_RETURN(uhci_batch->device_buffer,
    118             "Failed to allocate UHCI buffer.\n");
     113        if (!uhci_batch->device_buffer) {
     114                usb_log_error("Failed to allocate UHCI buffer.\n");
     115                return ENOMEM;
     116        }
    119117        memset(uhci_batch->device_buffer, 0, total_size);
    120118
     
    130128            + sizeof(qh_t);
    131129        /* Copy SETUP packet data to the device buffer */
    132         memcpy(dest, usb_batch->setup_buffer, usb_batch->setup_size);
    133         dest += usb_batch->setup_size;
     130        memcpy(dest, usb_batch->setup.buffer, setup_size);
     131        dest += setup_size;
    134132        /* Copy generic data unless they are provided by the device */
    135133        if (usb_batch->ep->direction != USB_DIRECTION_IN) {
    136134                memcpy(dest, usb_batch->buffer, usb_batch->buffer_size);
    137135        }
    138         uhci_batch->usb_batch = usb_batch;
    139136        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
    140137            " memory structures ready.\n", usb_batch,
    141138            USB_TRANSFER_BATCH_ARGS(*usb_batch));
    142139
    143         const usb_direction_t dir = usb_transfer_batch_direction(usb_batch);
    144 
    145140        assert(batch_setup[usb_batch->ep->transfer_type]);
    146         batch_setup[usb_batch->ep->transfer_type](uhci_batch, dir);
    147 
    148         return uhci_batch;
     141        batch_setup[usb_batch->ep->transfer_type](uhci_batch);
     142
     143        return EOK;
    149144}
    150145
     
    158153 * is reached.
    159154 */
    160 bool uhci_transfer_batch_is_complete(const uhci_transfer_batch_t *uhci_batch)
     155bool uhci_transfer_batch_check_completed(uhci_transfer_batch_t *uhci_batch)
    161156{
    162157        assert(uhci_batch);
    163         assert(uhci_batch->usb_batch);
    164158
    165159        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
     
    168162            USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch),
    169163            uhci_batch->td_count);
    170         uhci_batch->usb_batch->transfered_size = 0;
     164        uhci_batch->base.transfered_size = 0;
    171165
    172166        for (size_t i = 0;i < uhci_batch->td_count; ++i) {
     
    175169                }
    176170
    177                 uhci_batch->usb_batch->error = td_status(&uhci_batch->tds[i]);
    178                 if (uhci_batch->usb_batch->error != EOK) {
    179                         assert(uhci_batch->usb_batch->ep != NULL);
     171                uhci_batch->base.error = td_status(&uhci_batch->tds[i]);
     172                if (uhci_batch->base.error != EOK) {
     173                        assert(uhci_batch->base.ep != NULL);
    180174
    181175                        usb_log_debug("Batch %p found error TD(%zu->%p):%"
     
    184178                        td_print_status(&uhci_batch->tds[i]);
    185179
    186                         endpoint_toggle_set(uhci_batch->usb_batch->ep,
     180                        endpoint_toggle_set(uhci_batch->base.ep,
    187181                            td_toggle(&uhci_batch->tds[i]));
    188182                        if (i > 0)
     
    191185                }
    192186
    193                 uhci_batch->usb_batch->transfered_size
     187                uhci_batch->base.transfered_size
    194188                    += td_act_size(&uhci_batch->tds[i]);
    195189                if (td_is_short(&uhci_batch->tds[i]))
     
    197191        }
    198192substract_ret:
    199         uhci_batch->usb_batch->transfered_size
    200             -= uhci_batch->usb_batch->setup_size;
     193        if (uhci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL)
     194                uhci_batch->base.transfered_size -= USB_SETUP_PACKET_SIZE;
    201195        return true;
    202196}
     
    216210 * The last transfer is marked with IOC flag.
    217211 */
    218 static void batch_data(uhci_transfer_batch_t *uhci_batch, usb_direction_t dir)
     212static void batch_data(uhci_transfer_batch_t *uhci_batch)
    219213{
    220214        assert(uhci_batch);
    221         assert(uhci_batch->usb_batch);
    222         assert(uhci_batch->usb_batch->ep);
     215
     216        usb_direction_t dir = uhci_batch->base.dir;
    223217        assert(dir == USB_DIRECTION_OUT || dir == USB_DIRECTION_IN);
    224218
     
    226220        const usb_packet_id pid = direction_pids[dir];
    227221        const bool low_speed =
    228             uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
    229         const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
    230         const usb_target_t target = {{
    231             uhci_batch->usb_batch->ep->address,
    232             uhci_batch->usb_batch->ep->endpoint }};
    233 
    234         int toggle = endpoint_toggle_get(uhci_batch->usb_batch->ep);
     222            uhci_batch->base.ep->speed == USB_SPEED_LOW;
     223        const size_t mps = uhci_batch->base.ep->max_packet_size;
     224        const usb_target_t target = uhci_batch->base.ep->target;
     225
     226        int toggle = endpoint_toggle_get(uhci_batch->base.ep);
    235227        assert(toggle == 0 || toggle == 1);
    236228
    237229        size_t td = 0;
    238         size_t remain_size = uhci_batch->usb_batch->buffer_size;
     230        size_t remain_size = uhci_batch->base.buffer_size;
    239231        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
    240232
     
    256248        }
    257249        td_set_ioc(&uhci_batch->tds[td - 1]);
    258         endpoint_toggle_set(uhci_batch->usb_batch->ep, toggle);
     250        endpoint_toggle_set(uhci_batch->base.ep, toggle);
    259251        usb_log_debug2(
    260252            "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
    261253            uhci_batch->usb_batch,
    262             usb_str_transfer_type(uhci_batch->usb_batch->ep->transfer_type),
    263             usb_str_direction(uhci_batch->usb_batch->ep->direction),
     254            usb_str_transfer_type(uhci_batch->base.ep->transfer_type),
     255            usb_str_direction(uhci_batch->base.ep->direction),
    264256            USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch));
    265257}
     
    276268 * The last transfer is marked with IOC.
    277269 */
    278 static void batch_control(uhci_transfer_batch_t *uhci_batch, usb_direction_t dir)
     270static void batch_control(uhci_transfer_batch_t *uhci_batch)
    279271{
    280272        assert(uhci_batch);
    281         assert(uhci_batch->usb_batch);
    282         assert(uhci_batch->usb_batch->ep);
     273
     274        usb_direction_t dir = uhci_batch->base.dir;
    283275        assert(dir == USB_DIRECTION_OUT || dir == USB_DIRECTION_IN);
    284276        assert(uhci_batch->td_count >= 2);
     
    291283        const usb_packet_id status_stage_pid = status_stage_pids[dir];
    292284        const bool low_speed =
    293             uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
    294         const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
    295         const usb_target_t target = {{
    296             uhci_batch->usb_batch->ep->address,
    297             uhci_batch->usb_batch->ep->endpoint }};
     285            uhci_batch->base.ep->speed == USB_SPEED_LOW;
     286        const size_t mps = uhci_batch->base.ep->max_packet_size;
     287        const usb_target_t target = uhci_batch->base.ep->target;
    298288
    299289        /* setup stage */
    300290        td_init(
    301291            &uhci_batch->tds[0], DEFAULT_ERROR_COUNT,
    302             uhci_batch->usb_batch->setup_size, 0, false,
     292            USB_SETUP_PACKET_SIZE, 0, false,
    303293            low_speed, target, USB_PID_SETUP,
    304294            uhci_transfer_batch_setup_buffer(uhci_batch), &uhci_batch->tds[1]);
     
    307297        size_t td = 1;
    308298        unsigned toggle = 1;
    309         size_t remain_size = uhci_batch->usb_batch->buffer_size;
     299        size_t remain_size = uhci_batch->base.buffer_size;
    310300        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
    311301
     
    337327}
    338328
    339 static void (*const batch_setup[])(uhci_transfer_batch_t*, usb_direction_t) =
     329static void (*const batch_setup[])(uhci_transfer_batch_t*) =
    340330{
    341331        [USB_TRANSFER_CONTROL] = batch_control,
Note: See TracChangeset for help on using the changeset viewer.