Ignore:
File:
1 edited

Legend:

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

    rbdc8ab1 reae83aa  
    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);
     
    8384        }
    8485
    85         instance->tds = malloc32(sizeof(transfer_descriptor_t) * instance->packets);
     86        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    8687        if (instance->tds == NULL) {
    8788                usb_log_error("Failed to allocate transfer descriptors.\n");
     
    9091                return NULL;
    9192        }
    92         bzero(instance->tds, sizeof(transfer_descriptor_t) * instance->packets);
     93        bzero(instance->tds, sizeof(td_t) * instance->packets);
    9394
    9495        const size_t transport_size = max_packet_size * instance->packets;
     
    151152        size_t i = 0;
    152153        for (;i < instance->packets; ++i) {
    153                 if (transfer_descriptor_is_active(&instance->tds[i])) {
     154                if (td_is_active(&instance->tds[i])) {
    154155                        return false;
    155156                }
    156                 instance->error = transfer_descriptor_status(&instance->tds[i]);
     157
     158                instance->error = td_status(&instance->tds[i]);
    157159                if (instance->error != EOK) {
     160                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
     161                            instance, i, instance->tds[i].status);
    158162                        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);
     163                                goto substract_ret;
    162164                        return true;
    163165                }
    164                 instance->transfered_size +=
    165                     transfer_descriptor_actual_size(&instance->tds[i]);
    166         }
     166
     167                instance->transfered_size += td_act_size(&instance->tds[i]);
     168                if (td_is_short(&instance->tds[i]))
     169                        goto substract_ret;
     170        }
     171substract_ret:
    167172        instance->transfered_size -= instance->setup_size;
    168173        return true;
     
    192197{
    193198        assert(instance);
    194 
     199        batch_data(instance, USB_PID_IN);
     200        instance->next_step = batch_call_in_and_dispose;
     201        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
     202        batch_schedule(instance);
     203}
     204/*----------------------------------------------------------------------------*/
     205void batch_interrupt_out(batch_t *instance)
     206{
     207        assert(instance);
     208        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     209        batch_data(instance, USB_PID_OUT);
     210        instance->next_step = batch_call_out_and_dispose;
     211        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
     212        batch_schedule(instance);
     213}
     214/*----------------------------------------------------------------------------*/
     215void batch_bulk_in(batch_t *instance)
     216{
     217        assert(instance);
     218        batch_data(instance, USB_PID_IN);
     219        instance->next_step = batch_call_in_and_dispose;
     220        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
     221        batch_schedule(instance);
     222}
     223/*----------------------------------------------------------------------------*/
     224void batch_bulk_out(batch_t *instance)
     225{
     226        assert(instance);
     227        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     228        batch_data(instance, USB_PID_OUT);
     229        instance->next_step = batch_call_out_and_dispose;
     230        usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance);
     231        batch_schedule(instance);
     232}
     233/*----------------------------------------------------------------------------*/
     234static void batch_data(batch_t *instance, usb_packet_id pid)
     235{
     236        assert(instance);
    195237        const bool low_speed = instance->speed == USB_SPEED_LOW;
    196238        int toggle = 1;
    197         size_t i = 0;
    198         for (;i < instance->packets; ++i) {
     239
     240        size_t packet = 0;
     241        size_t remain_size = instance->buffer_size;
     242        while (remain_size > 0) {
    199243                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;
     244                    instance->transport_buffer + instance->buffer_size
     245                    - remain_size;
     246
    203247                toggle = 1 - toggle;
    204248
    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 
    212         instance->next_step = batch_call_in_and_dispose;
    213         usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    214         batch_schedule(instance);
    215 }
    216 /*----------------------------------------------------------------------------*/
    217 void batch_interrupt_out(batch_t *instance)
    218 {
    219         assert(instance);
    220         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 
    239         instance->next_step = batch_call_out_and_dispose;
    240         usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    241         batch_schedule(instance);
    242 }
    243 /*----------------------------------------------------------------------------*/
    244 static void batch_control(
    245     batch_t *instance, int data_stage, int status_stage)
     249                const size_t packet_size =
     250                    (instance->max_packet_size > remain_size) ?
     251                    remain_size : instance->max_packet_size;
     252
     253                td_init(&instance->tds[packet],
     254                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
     255                    instance->target, pid, data,
     256                    &instance->tds[packet + 1]);
     257
     258                ++packet;
     259                assert(packet <= instance->packets);
     260                assert(packet_size <= remain_size);
     261                remain_size -= packet_size;
     262        }
     263
     264        instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     265        instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG;
     266}
     267/*----------------------------------------------------------------------------*/
     268static void batch_control(batch_t *instance,
     269   usb_packet_id data_stage, usb_packet_id status_stage)
    246270{
    247271        assert(instance);
     
    250274        int toggle = 0;
    251275        /* setup stage */
    252         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
     276        td_init(instance->tds, DEFAULT_ERROR_COUNT,
    253277            instance->setup_size, toggle, false, low_speed, instance->target,
    254278            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
     
    268292                    remain_size : instance->max_packet_size;
    269293
    270                 transfer_descriptor_init(&instance->tds[packet],
     294                td_init(&instance->tds[packet],
    271295                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
    272296                    instance->target, data_stage, data,
     
    281305        /* status stage */
    282306        assert(packet == instance->packets - 1);
    283         transfer_descriptor_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
     307        td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
    284308            0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
    285309
Note: See TracChangeset for help on using the changeset viewer.