Changeset 960bee9 in mainline for uspace/drv/uhci-hcd/batch.c


Ignore:
Timestamp:
2011-03-07T16:51:59Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
97ff14d
Parents:
a6add7a (diff), d4beec3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/batch.c

    ra6add7a r960bee9  
    4747static int batch_schedule(batch_t *instance);
    4848
    49 static void batch_control(
    50     batch_t *instance, int data_stage, int status_stage);
     49static void batch_control(batch_t *instance,
     50    usb_packet_id data_stage, usb_packet_id status_stage);
     51static void batch_data(batch_t *instance, usb_packet_id pid);
    5152static void batch_call_in(batch_t *instance);
    5253static void batch_call_out(batch_t *instance);
    5354static void batch_call_in_and_dispose(batch_t *instance);
    5455static void batch_call_out_and_dispose(batch_t *instance);
     56static void batch_dispose(batch_t *instance);
    5557
    5658
     
    6062    char* setup_buffer, size_t setup_size,
    6163    usbhc_iface_transfer_in_callback_t func_in,
    62     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     64    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     65    device_keeper_t *manager
     66    )
    6367{
    6468        assert(func_in == NULL || func_out == NULL);
     
    8387        }
    8488
    85         instance->tds = malloc32(sizeof(transfer_descriptor_t) * instance->packets);
     89        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    8690        if (instance->tds == NULL) {
    8791                usb_log_error("Failed to allocate transfer descriptors.\n");
     
    9094                return NULL;
    9195        }
    92         bzero(instance->tds, sizeof(transfer_descriptor_t) * instance->packets);
     96        bzero(instance->tds, sizeof(td_t) * instance->packets);
    9397
    9498        const size_t transport_size = max_packet_size * instance->packets;
     
    136140        instance->arg = arg;
    137141        instance->speed = speed;
     142        instance->manager = manager;
    138143
    139144        queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
     
    151156        size_t i = 0;
    152157        for (;i < instance->packets; ++i) {
    153                 if (transfer_descriptor_is_active(&instance->tds[i])) {
     158                if (td_is_active(&instance->tds[i])) {
    154159                        return false;
    155160                }
    156                 instance->error = transfer_descriptor_status(&instance->tds[i]);
     161
     162                instance->error = td_status(&instance->tds[i]);
    157163                if (instance->error != EOK) {
     164                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
     165                            instance, i, instance->tds[i].status);
     166
     167                        device_keeper_set_toggle(instance->manager, instance->target,
     168                            td_toggle(&instance->tds[i]));
    158169                        if (i > 0)
    159                                 instance->transfered_size -= instance->setup_size;
    160                         usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    161                           instance, i, instance->tds[i].status);
     170                                goto substract_ret;
    162171                        return true;
    163172                }
    164                 instance->transfered_size +=
    165                     transfer_descriptor_actual_size(&instance->tds[i]);
    166         }
     173
     174                instance->transfered_size += td_act_size(&instance->tds[i]);
     175                if (td_is_short(&instance->tds[i]))
     176                        goto substract_ret;
     177        }
     178substract_ret:
    167179        instance->transfered_size -= instance->setup_size;
    168180        return true;
     
    192204{
    193205        assert(instance);
    194 
    195         const bool low_speed = instance->speed == USB_SPEED_LOW;
    196         int toggle = 1;
    197         size_t i = 0;
    198         for (;i < instance->packets; ++i) {
    199                 char *data =
    200                     instance->transport_buffer + (i  * instance->max_packet_size);
    201                 transfer_descriptor_t *next = (i + 1) < instance->packets ?
    202                     &instance->tds[i + 1] : NULL;
    203                 toggle = 1 - toggle;
    204 
    205                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    206                     instance->max_packet_size, toggle, false, low_speed,
    207                     instance->target, USB_PID_IN, data, next);
    208         }
    209 
    210         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    211 
     206        batch_data(instance, USB_PID_IN);
    212207        instance->next_step = batch_call_in_and_dispose;
    213208        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     
    219214        assert(instance);
    220215        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    221 
    222         const bool low_speed = instance->speed == USB_SPEED_LOW;
    223         int toggle = 1;
    224         size_t i = 0;
    225         for (;i < instance->packets; ++i) {
    226                 char *data =
    227                     instance->transport_buffer + (i  * instance->max_packet_size);
    228                 transfer_descriptor_t *next = (i + 1) < instance->packets ?
    229                     &instance->tds[i + 1] : NULL;
    230                 toggle = 1 - toggle;
    231 
    232                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    233                     instance->max_packet_size, toggle++, false, low_speed,
    234                     instance->target, USB_PID_OUT, data, next);
    235         }
    236 
    237         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    238 
     216        batch_data(instance, USB_PID_OUT);
    239217        instance->next_step = batch_call_out_and_dispose;
    240218        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     
    242220}
    243221/*----------------------------------------------------------------------------*/
    244 static void batch_control(
    245     batch_t *instance, int data_stage, int status_stage)
     222void batch_bulk_in(batch_t *instance)
     223{
     224        assert(instance);
     225        batch_data(instance, USB_PID_IN);
     226        instance->next_step = batch_call_in_and_dispose;
     227        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     228        batch_schedule(instance);
     229}
     230/*----------------------------------------------------------------------------*/
     231void batch_bulk_out(batch_t *instance)
     232{
     233        assert(instance);
     234        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     235        batch_data(instance, USB_PID_OUT);
     236        instance->next_step = batch_call_out_and_dispose;
     237        usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
     238        batch_schedule(instance);
     239}
     240/*----------------------------------------------------------------------------*/
     241void batch_data(batch_t *instance, usb_packet_id pid)
     242{
     243        assert(instance);
     244        const bool low_speed = instance->speed == USB_SPEED_LOW;
     245        int toggle = device_keeper_get_toggle(instance->manager, instance->target);
     246        assert(toggle == 0 || toggle == 1);
     247
     248        size_t packet = 0;
     249        size_t remain_size = instance->buffer_size;
     250        while (remain_size > 0) {
     251                char *data =
     252                    instance->transport_buffer + instance->buffer_size
     253                    - remain_size;
     254
     255
     256                const size_t packet_size =
     257                    (instance->max_packet_size > remain_size) ?
     258                    remain_size : instance->max_packet_size;
     259
     260                td_init(&instance->tds[packet],
     261                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
     262                    instance->target, pid, data,
     263                    &instance->tds[packet + 1]);
     264
     265                toggle = 1 - toggle;
     266                ++packet;
     267                assert(packet <= instance->packets);
     268                assert(packet_size <= remain_size);
     269                remain_size -= packet_size;
     270        }
     271        device_keeper_set_toggle(instance->manager, instance->target, toggle);
     272
     273        instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     274        instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG;
     275}
     276/*----------------------------------------------------------------------------*/
     277void batch_control(batch_t *instance,
     278   usb_packet_id data_stage, usb_packet_id status_stage)
    246279{
    247280        assert(instance);
     
    250283        int toggle = 0;
    251284        /* setup stage */
    252         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
     285        td_init(instance->tds, DEFAULT_ERROR_COUNT,
    253286            instance->setup_size, toggle, false, low_speed, instance->target,
    254287            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
     
    268301                    remain_size : instance->max_packet_size;
    269302
    270                 transfer_descriptor_init(&instance->tds[packet],
     303                td_init(&instance->tds[packet],
    271304                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
    272305                    instance->target, data_stage, data,
     
    281314        /* status stage */
    282315        assert(packet == instance->packets - 1);
    283         transfer_descriptor_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
     316        td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
    284317            0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
    285318
     
    323356        assert(instance);
    324357        batch_call_in(instance);
     358        batch_dispose(instance);
     359}
     360/*----------------------------------------------------------------------------*/
     361void batch_call_out_and_dispose(batch_t *instance)
     362{
     363        assert(instance);
     364        batch_call_out(instance);
     365        batch_dispose(instance);
     366}
     367/*----------------------------------------------------------------------------*/
     368void batch_dispose(batch_t *instance)
     369{
     370        assert(instance);
    325371        usb_log_debug("Batch(%p) disposing.\n", instance);
    326372        free32(instance->tds);
     
    331377}
    332378/*----------------------------------------------------------------------------*/
    333 void batch_call_out_and_dispose(batch_t *instance)
    334 {
    335         assert(instance);
    336         batch_call_out(instance);
    337         usb_log_debug("Batch(%p) disposing.\n", instance);
    338         free32(instance->tds);
    339         free32(instance->qh);
    340         free32(instance->setup_buffer);
    341         free32(instance->transport_buffer);
    342         free(instance);
    343 }
    344 /*----------------------------------------------------------------------------*/
    345379int batch_schedule(batch_t *instance)
    346380{
Note: See TracChangeset for help on using the changeset viewer.