Ignore:
File:
1 edited

Legend:

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

    r81dce9f ra963a68  
    4242#include "uhci_hc.h"
    4343#include "utils/malloc32.h"
    44 #include "uhci_struct/transfer_descriptor.h"
    4544
    4645#define DEFAULT_ERROR_COUNT 3
    47 
    48 typedef struct uhci_batch {
    49         qh_t *qh;
    50         td_t *tds;
    51         size_t packets;
    52         device_keeper_t *manager;
    53 } uhci_batch_t;
    5446
    5547static void batch_control(batch_t *instance,
    5648    usb_packet_id data_stage, usb_packet_id status_stage);
    5749static void batch_data(batch_t *instance, usb_packet_id pid);
     50static void batch_call_in(batch_t *instance);
     51static void batch_call_out(batch_t *instance);
    5852static void batch_call_in_and_dispose(batch_t *instance);
    5953static void batch_call_out_and_dispose(batch_t *instance);
     
    8478batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    8579    usb_transfer_type_t transfer_type, size_t max_packet_size,
    86     usb_speed_t speed, char *buffer, size_t buffer_size,
     80    usb_speed_t speed, char *buffer, size_t size,
    8781    char* setup_buffer, size_t setup_size,
    8882    usbhc_iface_transfer_in_callback_t func_in,
     
    106100        CHECK_NULL_DISPOSE_RETURN(instance,
    107101            "Failed to allocate batch instance.\n");
    108         batch_init(instance, target, transfer_type, speed, max_packet_size,
    109             buffer, NULL, buffer_size, NULL, setup_size, func_in,
    110             func_out, arg, fun, NULL);
    111 
    112 
    113         uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
    114         CHECK_NULL_DISPOSE_RETURN(instance,
    115             "Failed to allocate batch instance.\n");
    116         bzero(data, sizeof(uhci_batch_t));
    117         data->manager = manager;
    118         instance->private_data = data;
    119 
    120         data->packets = (buffer_size + max_packet_size - 1) / max_packet_size;
     102        bzero(instance, sizeof(batch_t));
     103
     104        instance->qh = malloc32(sizeof(qh_t));
     105        CHECK_NULL_DISPOSE_RETURN(instance->qh,
     106            "Failed to allocate batch queue head.\n");
     107        qh_init(instance->qh);
     108
     109        instance->packets = (size + max_packet_size - 1) / max_packet_size;
    121110        if (transfer_type == USB_TRANSFER_CONTROL) {
    122                 data->packets += 2;
    123         }
    124 
    125         data->tds = malloc32(sizeof(td_t) * data->packets);
     111                instance->packets += 2;
     112        }
     113
     114        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    126115        CHECK_NULL_DISPOSE_RETURN(
    127             data->tds, "Failed to allocate transfer descriptors.\n");
    128         bzero(data->tds, sizeof(td_t) * data->packets);
    129 
    130         data->qh = malloc32(sizeof(qh_t));
    131         CHECK_NULL_DISPOSE_RETURN(data->qh,
    132             "Failed to allocate batch queue head.\n");
    133         qh_init(data->qh);
    134         qh_set_element_td(data->qh, addr_to_phys(data->tds));
    135 
    136         if (buffer_size > 0) {
    137                 instance->transport_buffer = malloc32(buffer_size);
     116            instance->tds, "Failed to allocate transfer descriptors.\n");
     117        bzero(instance->tds, sizeof(td_t) * instance->packets);
     118
     119        if (size > 0) {
     120                instance->transport_buffer = malloc32(size);
    138121                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
    139122                    "Failed to allocate device accessible buffer.\n");
     
    147130        }
    148131
     132
     133        link_initialize(&instance->link);
     134
     135        instance->max_packet_size = max_packet_size;
     136        instance->target = target;
     137        instance->transfer_type = transfer_type;
     138        instance->buffer = buffer;
     139        instance->buffer_size = size;
     140        instance->setup_size = setup_size;
     141        instance->fun = fun;
     142        instance->arg = arg;
     143        instance->speed = speed;
     144        instance->manager = manager;
     145        instance->callback_out = func_out;
     146        instance->callback_in = func_in;
     147
     148        qh_set_element_td(instance->qh, addr_to_phys(instance->tds));
     149
    149150        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    150151            instance, target.address, target.endpoint);
     
    152153}
    153154/*----------------------------------------------------------------------------*/
     155/** Mark batch as failed and continue with next step.
     156 *
     157 * @param[in] instance Batch structure to use.
     158 *
     159 */
     160void batch_abort(batch_t *instance)
     161{
     162        assert(instance);
     163        instance->error = EIO;
     164        instance->next_step(instance);
     165}
     166/*----------------------------------------------------------------------------*/
    154167/** Check batch TDs for activity.
    155168 *
     
    164177{
    165178        assert(instance);
    166         uhci_batch_t *data = instance->private_data;
    167         assert(data);
    168 
    169179        usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    170             instance, data->packets);
     180            instance, instance->packets);
    171181        instance->transfered_size = 0;
    172182        size_t i = 0;
    173         for (;i < data->packets; ++i) {
    174                 if (td_is_active(&data->tds[i])) {
     183        for (;i < instance->packets; ++i) {
     184                if (td_is_active(&instance->tds[i])) {
    175185                        return false;
    176186                }
    177187
    178                 instance->error = td_status(&data->tds[i]);
     188                instance->error = td_status(&instance->tds[i]);
    179189                if (instance->error != EOK) {
    180190                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    181                             instance, i, data->tds[i].status);
    182                         td_print_status(&data->tds[i]);
    183 
    184                         device_keeper_set_toggle(data->manager,
    185                             instance->target, td_toggle(&data->tds[i]));
     191                            instance, i, instance->tds[i].status);
     192                        td_print_status(&instance->tds[i]);
     193
     194                        device_keeper_set_toggle(instance->manager,
     195                            instance->target, td_toggle(&instance->tds[i]));
    186196                        if (i > 0)
    187197                                goto substract_ret;
     
    189199                }
    190200
    191                 instance->transfered_size += td_act_size(&data->tds[i]);
    192                 if (td_is_short(&data->tds[i]))
     201                instance->transfered_size += td_act_size(&instance->tds[i]);
     202                if (td_is_short(&instance->tds[i]))
    193203                        goto substract_ret;
    194204        }
     
    302312{
    303313        assert(instance);
    304         uhci_batch_t *data = instance->private_data;
    305         assert(data);
    306 
    307314        const bool low_speed = instance->speed == USB_SPEED_LOW;
    308         int toggle = device_keeper_get_toggle(data->manager, instance->target);
     315        int toggle =
     316            device_keeper_get_toggle(instance->manager, instance->target);
    309317        assert(toggle == 0 || toggle == 1);
    310318
     
    312320        size_t remain_size = instance->buffer_size;
    313321        while (remain_size > 0) {
    314                 char *trans_data =
     322                char *data =
    315323                    instance->transport_buffer + instance->buffer_size
    316324                    - remain_size;
     
    320328                    remain_size : instance->max_packet_size;
    321329
    322                 td_t *next_packet = (packet + 1 < data->packets)
    323                     ? &data->tds[packet + 1] : NULL;
    324 
    325                 assert(packet < data->packets);
     330                td_t *next_packet = (packet + 1 < instance->packets)
     331                    ? &instance->tds[packet + 1] : NULL;
     332
     333                assert(packet < instance->packets);
    326334                assert(packet_size <= remain_size);
    327335
    328336                td_init(
    329                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    330                     toggle, false, low_speed, instance->target, pid, trans_data,
     337                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     338                    toggle, false, low_speed, instance->target, pid, data,
    331339                    next_packet);
    332340
     
    336344                ++packet;
    337345        }
    338         td_set_ioc(&data->tds[packet - 1]);
    339         device_keeper_set_toggle(data->manager, instance->target, toggle);
     346        td_set_ioc(&instance->tds[packet - 1]);
     347        device_keeper_set_toggle(instance->manager, instance->target, toggle);
    340348}
    341349/*----------------------------------------------------------------------------*/
     
    355363{
    356364        assert(instance);
    357         uhci_batch_t *data = instance->private_data;
    358         assert(data);
    359         assert(data->packets >= 2);
    360365
    361366        const bool low_speed = instance->speed == USB_SPEED_LOW;
    362367        int toggle = 0;
    363368        /* setup stage */
    364         td_init(
    365             data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false,
    366             low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer,
    367             &data->tds[1]);
     369        td_init(instance->tds, DEFAULT_ERROR_COUNT,
     370            instance->setup_size, toggle, false, low_speed, instance->target,
     371            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
    368372
    369373        /* data stage */
     
    371375        size_t remain_size = instance->buffer_size;
    372376        while (remain_size > 0) {
    373                 char *control_data =
     377                char *data =
    374378                    instance->transport_buffer + instance->buffer_size
    375379                    - remain_size;
     
    382386
    383387                td_init(
    384                     &data->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     388                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
    385389                    toggle, false, low_speed, instance->target, data_stage,
    386                     control_data, &data->tds[packet + 1]);
     390                    data, &instance->tds[packet + 1]);
    387391
    388392                ++packet;
    389                 assert(packet < data->packets);
     393                assert(packet < instance->packets);
    390394                assert(packet_size <= remain_size);
    391395                remain_size -= packet_size;
     
    393397
    394398        /* status stage */
    395         assert(packet == data->packets - 1);
    396 
    397         td_init(
    398             &data->tds[packet], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    399             instance->target, status_stage, NULL, NULL);
    400         td_set_ioc(&data->tds[packet]);
    401 
     399        assert(packet == instance->packets - 1);
     400        td_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
     401            0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
     402
     403        td_set_ioc(&instance->tds[packet]);
    402404        usb_log_debug2("Control last TD status: %x.\n",
    403             data->tds[packet].status);
    404 }
    405 /*----------------------------------------------------------------------------*/
    406 qh_t * batch_qh(batch_t *instance)
    407 {
    408         assert(instance);
    409         uhci_batch_t *data = instance->private_data;
    410         assert(data);
    411         return data->qh;
     405            instance->tds[packet].status);
     406}
     407/*----------------------------------------------------------------------------*/
     408/** Prepare data, get error status and call callback in.
     409 *
     410 * @param[in] instance Batch structure to use.
     411 * Copies data from transport buffer, and calls callback with appropriate
     412 * parameters.
     413 */
     414void batch_call_in(batch_t *instance)
     415{
     416        assert(instance);
     417        assert(instance->callback_in);
     418
     419        /* We are data in, we need data */
     420        memcpy(instance->buffer, instance->transport_buffer,
     421            instance->buffer_size);
     422
     423        int err = instance->error;
     424        usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
     425            instance, instance->transfer_type, str_error(err), err,
     426            instance->transfered_size);
     427
     428        instance->callback_in(
     429            instance->fun, err, instance->transfered_size, instance->arg);
     430}
     431/*----------------------------------------------------------------------------*/
     432/** Get error status and call callback out.
     433 *
     434 * @param[in] instance Batch structure to use.
     435 */
     436void batch_call_out(batch_t *instance)
     437{
     438        assert(instance);
     439        assert(instance->callback_out);
     440
     441        int err = instance->error;
     442        usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n",
     443            instance, instance->transfer_type, str_error(err), err);
     444        instance->callback_out(instance->fun,
     445            err, instance->arg);
    412446}
    413447/*----------------------------------------------------------------------------*/
     
    441475{
    442476        assert(instance);
    443         uhci_batch_t *data = instance->private_data;
    444         assert(data);
    445477        usb_log_debug("Batch(%p) disposing.\n", instance);
    446478        /* free32 is NULL safe */
    447         free32(data->tds);
    448         free32(data->qh);
     479        free32(instance->tds);
     480        free32(instance->qh);
    449481        free32(instance->setup_buffer);
    450482        free32(instance->transport_buffer);
    451         free(data);
    452483        free(instance);
    453484}
Note: See TracChangeset for help on using the changeset viewer.