Changeset b991d37 in mainline for uspace/drv/bus/usb/uhci/uhci_batch.c


Ignore:
Timestamp:
2011-08-31T16:41:11Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ff6dd73
Parents:
96e2d01
Message:

uhci: use uhci sepcific structure instead of generic library

revert the way uhci_transfer_batch_t and usb_transfer_batch_t are included,
don't use usb_transfer_batch_t:

-private data and data dtor
-next_step pointer
-buffer_data pointer

File:
1 edited

Legend:

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

    r96e2d01 rb991d37  
    4444
    4545#define DEFAULT_ERROR_COUNT 3
    46 static void batch_control_write(usb_transfer_batch_t *instance);
    47 static void batch_control_read(usb_transfer_batch_t *instance);
    48 
    49 static void batch_interrupt_in(usb_transfer_batch_t *instance);
    50 static void batch_interrupt_out(usb_transfer_batch_t *instance);
    51 
    52 static void batch_bulk_in(usb_transfer_batch_t *instance);
    53 static void batch_bulk_out(usb_transfer_batch_t *instance);
    54 
    55 static void batch_setup_control(usb_transfer_batch_t *batch)
    56 {
    57         // TODO Find a better way to do this
    58         if (batch->setup_buffer[0] & (1 << 7))
    59                 batch_control_read(batch);
    60         else
    61                 batch_control_write(batch);
    62 }
    63 
    64 void (*batch_setup[4][3])(usb_transfer_batch_t*) =
    65 {
    66         { NULL, NULL, batch_setup_control },
    67         { NULL, NULL, NULL },
    68         { batch_bulk_in, batch_bulk_out, NULL },
    69         { batch_interrupt_in, batch_interrupt_out, NULL },
    70 };
    71  // */
    72 /** UHCI specific data required for USB transfer */
    73 typedef struct uhci_transfer_batch {
    74         /** Queue head
    75          * This QH is used to maintain UHCI schedule structure and the element
    76          * pointer points to the first TD of this batch.
    77          */
    78         qh_t *qh;
    79         /** List of TDs needed for the transfer */
    80         td_t *tds;
    81         /** Number of TDs used by the transfer */
    82         size_t td_count;
    83         /** Data buffer, must be accessible by the UHCI hw */
    84         void *device_buffer;
    85 } uhci_transfer_batch_t;
    86 /*----------------------------------------------------------------------------*/
    87 static void batch_control(usb_transfer_batch_t *instance,
     46
     47static void batch_control(uhci_transfer_batch_t *uhci_batch,
    8848    usb_packet_id data_stage, usb_packet_id status_stage);
    89 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid);
     49static void batch_data(uhci_transfer_batch_t *uhci_batch, usb_packet_id pid);
     50/*----------------------------------------------------------------------------*/
     51static void uhci_transfer_batch_dispose(uhci_transfer_batch_t *uhci_batch)
     52{
     53        if (uhci_batch) {
     54                usb_transfer_batch_dispose(uhci_batch->usb_batch);
     55                free32(uhci_batch->device_buffer);
     56                free(uhci_batch);
     57        }
     58}
    9059/*----------------------------------------------------------------------------*/
    9160/** Safely destructs uhci_transfer_batch_t structure
     
    9362 * @param[in] uhci_batch Instance to destroy.
    9463 */
    95 static void uhci_transfer_batch_dispose(void *uhci_batch)
    96 {
    97         uhci_transfer_batch_t *instance = uhci_batch;
    98         assert(instance);
    99         free32(instance->device_buffer);
    100         free(instance);
    101 }
     64void uhci_transfer_batch_call_dispose(uhci_transfer_batch_t *uhci_batch)
     65{
     66        assert(uhci_batch);
     67        assert(uhci_batch->usb_batch);
     68        /* Copy data unless we are sure we sent it */
     69        if (uhci_batch->usb_batch->ep->direction != USB_DIRECTION_OUT) {
     70                memcpy(uhci_batch->usb_batch->buffer,
     71                    uhci_transfer_batch_data_buffer(uhci_batch),
     72                    uhci_batch->usb_batch->buffer_size);
     73        }
     74        if (uhci_batch->usb_batch->callback_out)
     75                usb_transfer_batch_call_out(uhci_batch->usb_batch);
     76        if (uhci_batch->usb_batch->callback_in)
     77                usb_transfer_batch_call_in(uhci_batch->usb_batch);
     78        usb_transfer_batch_finish(uhci_batch->usb_batch);
     79        uhci_transfer_batch_dispose(uhci_batch);
     80}
     81/*----------------------------------------------------------------------------*/
     82static void (*batch_setup[4][3])(uhci_transfer_batch_t*);
    10283/*----------------------------------------------------------------------------*/
    10384/** Allocate memory and initialize internal data structure.
     
    119100 * Initializes parameters needed for the transfer and callback.
    120101 */
    121 int batch_init_uhci(usb_transfer_batch_t *batch)
    122 {
     102uhci_transfer_batch_t * uhci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
     103{
     104        assert((sizeof(td_t) % 16) == 0);
    123105#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
    124106        if (ptr == NULL) { \
    125107                usb_log_error(message); \
    126                 if (uhci_data) { \
    127                         uhci_transfer_batch_dispose(uhci_data); \
    128                 } \
    129                 return ENOMEM; \
     108                uhci_transfer_batch_dispose(uhci_batch); \
     109                return NULL; \
    130110        } else (void)0
    131111
    132         uhci_transfer_batch_t *uhci_data =
     112        uhci_transfer_batch_t *uhci_batch =
    133113            calloc(1, sizeof(uhci_transfer_batch_t));
    134         CHECK_NULL_DISPOSE_RETURN(uhci_data,
     114        CHECK_NULL_DISPOSE_RETURN(uhci_batch,
    135115            "Failed to allocate UHCI batch.\n");
    136116
    137         uhci_data->td_count =
    138             (batch->buffer_size + batch->ep->max_packet_size - 1)
    139             / batch->ep->max_packet_size;
    140         if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    141                 uhci_data->td_count += 2;
    142         }
    143 
    144         assert((sizeof(td_t) % 16) == 0);
    145         const size_t total_size = (sizeof(td_t) * uhci_data->td_count)
    146             + sizeof(qh_t) + batch->setup_size + batch->buffer_size;
    147         uhci_data->device_buffer = malloc32(total_size);
    148         CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer,
     117        uhci_batch->td_count =
     118            (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1)
     119            / usb_batch->ep->max_packet_size;
     120        if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     121                uhci_batch->td_count += 2;
     122        }
     123
     124        const size_t total_size = (sizeof(td_t) * uhci_batch->td_count)
     125            + sizeof(qh_t) + usb_batch->setup_size + usb_batch->buffer_size;
     126        uhci_batch->device_buffer = malloc32(total_size);
     127        CHECK_NULL_DISPOSE_RETURN(uhci_batch->device_buffer,
    149128            "Failed to allocate UHCI buffer.\n");
    150         bzero(uhci_data->device_buffer, total_size);
    151 
    152         uhci_data->tds = uhci_data->device_buffer;
    153         uhci_data->qh =
    154             (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count));
    155 
    156         qh_init(uhci_data->qh);
    157         qh_set_element_td(uhci_data->qh, uhci_data->tds);
    158 
    159         void *setup =
    160             uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)
     129        bzero(uhci_batch->device_buffer, total_size);
     130
     131        uhci_batch->tds = uhci_batch->device_buffer;
     132        uhci_batch->qh =
     133            (uhci_batch->device_buffer + (sizeof(td_t) * uhci_batch->td_count));
     134
     135        qh_init(uhci_batch->qh);
     136        qh_set_element_td(uhci_batch->qh, &uhci_batch->tds[0]);
     137
     138        void *dest =
     139            uhci_batch->device_buffer + (sizeof(td_t) * uhci_batch->td_count)
    161140            + sizeof(qh_t);
    162         /* Copy SETUP packet data to device buffer */
    163         memcpy(setup, batch->setup_buffer, batch->setup_size);
    164         /* Set generic data buffer pointer */
    165         batch->data_buffer = setup + batch->setup_size;
    166         batch->private_data_dtor = uhci_transfer_batch_dispose;
    167         batch->private_data = uhci_data;
     141        /* Copy SETUP packet data to the device buffer */
     142        memcpy(dest, usb_batch->setup_buffer, usb_batch->setup_size);
     143        dest += usb_batch->setup_size;
     144        /* Copy generic data if unless they are provided by the device */
     145        if (usb_batch->ep->direction != USB_DIRECTION_IN) {
     146                memcpy(dest, usb_batch->buffer, usb_batch->buffer_size);
     147        }
     148        uhci_batch->usb_batch = usb_batch;
    168149        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
    169             " memory structures ready.\n", batch,
    170             USB_TRANSFER_BATCH_ARGS(*batch));
    171         assert(batch_setup[batch->ep->transfer_type][batch->ep->direction]);
    172         batch_setup[batch->ep->transfer_type][batch->ep->direction](batch);
    173 
    174         return EOK;
     150            " memory structures ready.\n", usb_batch,
     151            USB_TRANSFER_BATCH_ARGS(*usb_batch));
     152        assert(
     153            batch_setup[usb_batch->ep->transfer_type][usb_batch->ep->direction]);
     154        batch_setup[usb_batch->ep->transfer_type][usb_batch->ep->direction](
     155            uhci_batch);
     156
     157        return uhci_batch;
    175158}
    176159/*----------------------------------------------------------------------------*/
     
    184167 * is reached.
    185168 */
    186 bool batch_is_complete(usb_transfer_batch_t *instance)
    187 {
    188         assert(instance);
    189         uhci_transfer_batch_t *data = instance->private_data;
    190         assert(data);
    191 
    192         usb_log_debug2("Batch(%p) checking %zu transfer(s) for completion.\n",
    193             instance, data->td_count);
    194         instance->transfered_size = 0;
     169bool uhci_transfer_batch_is_complete(uhci_transfer_batch_t *uhci_batch)
     170{
     171        assert(uhci_batch);
     172        assert(uhci_batch->usb_batch);
     173
     174        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
     175            " checking %zu transfer(s) for completion.\n",
     176            uhci_batch->usb_batch,
     177            USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch),
     178            uhci_batch->td_count);
     179        uhci_batch->usb_batch->transfered_size = 0;
    195180        size_t i = 0;
    196         for (;i < data->td_count; ++i) {
    197                 if (td_is_active(&data->tds[i])) {
     181        for (;i < uhci_batch->td_count; ++i) {
     182                if (td_is_active(&uhci_batch->tds[i])) {
    198183                        return false;
    199184                }
    200185
    201                 instance->error = td_status(&data->tds[i]);
    202                 if (instance->error != EOK) {
     186                uhci_batch->usb_batch->error = td_status(&uhci_batch->tds[i]);
     187                if (uhci_batch->usb_batch->error != EOK) {
     188                        assert(uhci_batch->usb_batch->ep != NULL);
     189
    203190                        usb_log_debug("Batch(%p) found error TD(%zu):%"
    204                             PRIx32 ".\n", instance, i, data->tds[i].status);
    205                         td_print_status(&data->tds[i]);
    206 
    207                         assert(instance->ep != NULL);
    208                         endpoint_toggle_set(instance->ep,
    209                             td_toggle(&data->tds[i]));
     191                            PRIx32 ".\n", uhci_batch->usb_batch, i,
     192                            uhci_batch->tds[i].status);
     193                        td_print_status(&uhci_batch->tds[i]);
     194
     195                        endpoint_toggle_set(uhci_batch->usb_batch->ep,
     196                            td_toggle(&uhci_batch->tds[i]));
    210197                        if (i > 0)
    211198                                goto substract_ret;
     
    213200                }
    214201
    215                 instance->transfered_size += td_act_size(&data->tds[i]);
    216                 if (td_is_short(&data->tds[i]))
     202                uhci_batch->usb_batch->transfered_size
     203                    += td_act_size(&uhci_batch->tds[i]);
     204                if (td_is_short(&uhci_batch->tds[i]))
    217205                        goto substract_ret;
    218206        }
    219207substract_ret:
    220         instance->transfered_size -= instance->setup_size;
     208        uhci_batch->usb_batch->transfered_size
     209            -= uhci_batch->usb_batch->setup_size;
    221210        return true;
    222211}
     
    233222 * Uses generic control function with pids OUT and IN.
    234223 */
    235 static void batch_control_write(usb_transfer_batch_t *instance)
    236 {
    237         assert(instance);
    238         /* We are data out, we are supposed to provide data */
    239         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    240         batch_control(instance, USB_PID_OUT, USB_PID_IN);
    241         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    242         LOG_BATCH_INITIALIZED(instance, "control write");
     224static void control_write(uhci_transfer_batch_t *uhci_batch)
     225{
     226        batch_control(uhci_batch, USB_PID_OUT, USB_PID_IN);
     227        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "control write");
    243228}
    244229/*----------------------------------------------------------------------------*/
     
    249234 * Uses generic control with pids IN and OUT.
    250235 */
    251 static void batch_control_read(usb_transfer_batch_t *instance)
    252 {
    253         assert(instance);
    254         batch_control(instance, USB_PID_IN, USB_PID_OUT);
    255         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    256         LOG_BATCH_INITIALIZED(instance, "control read");
     236static void control_read(uhci_transfer_batch_t *uhci_batch)
     237{
     238        batch_control(uhci_batch, USB_PID_IN, USB_PID_OUT);
     239        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "control read");
    257240}
    258241/*----------------------------------------------------------------------------*/
     
    263246 * Data transfer with PID_IN.
    264247 */
    265 static void batch_interrupt_in(usb_transfer_batch_t *instance)
    266 {
    267         assert(instance);
    268         batch_data(instance, USB_PID_IN);
    269         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    270         LOG_BATCH_INITIALIZED(instance, "interrupt in");
     248static void interrupt_in(uhci_transfer_batch_t *uhci_batch)
     249{
     250        batch_data(uhci_batch, USB_PID_IN);
     251        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "interrupt in");
    271252}
    272253/*----------------------------------------------------------------------------*/
     
    277258 * Data transfer with PID_OUT.
    278259 */
    279 static void batch_interrupt_out(usb_transfer_batch_t *instance)
    280 {
    281         assert(instance);
    282         /* We are data out, we are supposed to provide data */
    283         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    284         batch_data(instance, USB_PID_OUT);
    285         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    286         LOG_BATCH_INITIALIZED(instance, "interrupt out");
     260static void interrupt_out(uhci_transfer_batch_t *uhci_batch)
     261{
     262        batch_data(uhci_batch, USB_PID_OUT);
     263        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "interrupt out");
    287264}
    288265/*----------------------------------------------------------------------------*/
     
    293270 * Data transfer with PID_IN.
    294271 */
    295 static void batch_bulk_in(usb_transfer_batch_t *instance)
    296 {
    297         assert(instance);
    298         batch_data(instance, USB_PID_IN);
    299         instance->next_step = usb_transfer_batch_call_in_and_dispose;
    300         LOG_BATCH_INITIALIZED(instance, "bulk in");
     272static void bulk_in(uhci_transfer_batch_t *uhci_batch)
     273{
     274        batch_data(uhci_batch, USB_PID_IN);
     275        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "bulk in");
    301276}
    302277/*----------------------------------------------------------------------------*/
     
    307282 * Data transfer with PID_OUT.
    308283 */
    309 static void batch_bulk_out(usb_transfer_batch_t *instance)
    310 {
    311         assert(instance);
    312         /* We are data out, we are supposed to provide data */
    313         memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    314         batch_data(instance, USB_PID_OUT);
    315         instance->next_step = usb_transfer_batch_call_out_and_dispose;
    316         LOG_BATCH_INITIALIZED(instance, "bulk out");
     284static void bulk_out(uhci_transfer_batch_t *uhci_batch)
     285{
     286        batch_data(uhci_batch, USB_PID_OUT);
     287        LOG_BATCH_INITIALIZED(uhci_batch->usb_batch, "bulk out");
    317288}
    318289/*----------------------------------------------------------------------------*/
     
    325296 * The last transfer is marked with IOC flag.
    326297 */
    327 static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
    328 {
    329         assert(instance);
    330         uhci_transfer_batch_t *data = instance->private_data;
    331         assert(data);
    332 
    333         const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
    334         int toggle = endpoint_toggle_get(instance->ep);
     298static void batch_data(uhci_transfer_batch_t *uhci_batch, usb_packet_id pid)
     299{
     300        assert(uhci_batch);
     301        assert(uhci_batch->usb_batch);
     302
     303        const bool low_speed =
     304            uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
     305        const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
     306        const usb_target_t target = {
     307            uhci_batch->usb_batch->ep->address,
     308            uhci_batch->usb_batch->ep->endpoint };
     309
     310        int toggle = endpoint_toggle_get(uhci_batch->usb_batch->ep);
    335311        assert(toggle == 0 || toggle == 1);
    336312
    337313        size_t td = 0;
    338         size_t remain_size = instance->buffer_size;
    339         char *buffer = instance->data_buffer;
     314        size_t remain_size = uhci_batch->usb_batch->buffer_size;
     315        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
     316
    340317        while (remain_size > 0) {
    341318                const size_t packet_size =
    342                     (instance->ep->max_packet_size > remain_size) ?
    343                     remain_size : instance->ep->max_packet_size;
    344 
    345                 td_t *next_td = (td + 1 < data->td_count)
    346                     ? &data->tds[td + 1] : NULL;
    347 
    348 
    349                 usb_target_t target =
    350                     { instance->ep->address, instance->ep->endpoint };
    351 
    352                 assert(td < data->td_count);
     319                    (remain_size < mps) ? remain_size : mps;
     320
     321                const td_t *next_td = (td + 1 < uhci_batch->td_count)
     322                    ? &uhci_batch->tds[td + 1] : NULL;
     323
     324                assert(td < uhci_batch->td_count);
    353325                td_init(
    354                     &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
     326                    &uhci_batch->tds[td], DEFAULT_ERROR_COUNT, packet_size,
    355327                    toggle, false, low_speed, target, pid, buffer, next_td);
    356328
     
    358330                toggle = 1 - toggle;
    359331                buffer += packet_size;
    360                 assert(packet_size <= remain_size);
    361332                remain_size -= packet_size;
    362333        }
    363         td_set_ioc(&data->tds[td - 1]);
    364         endpoint_toggle_set(instance->ep, toggle);
     334        td_set_ioc(&uhci_batch->tds[td - 1]);
     335        endpoint_toggle_set(uhci_batch->usb_batch->ep, toggle);
    365336}
    366337/*----------------------------------------------------------------------------*/
     
    376347 * The last transfer is marked with IOC.
    377348 */
    378 static void batch_control(usb_transfer_batch_t *instance,
    379    usb_packet_id data_stage, usb_packet_id status_stage)
    380 {
    381         assert(instance);
    382         uhci_transfer_batch_t *data = instance->private_data;
    383         assert(data);
    384         assert(data->td_count >= 2);
    385 
    386         const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
    387         const usb_target_t target =
    388             { instance->ep->address, instance->ep->endpoint };
     349static void batch_control(uhci_transfer_batch_t *uhci_batch,
     350   usb_packet_id data_stage_pid, usb_packet_id status_stage_pid)
     351{
     352        assert(uhci_batch);
     353        assert(uhci_batch->usb_batch);
     354        assert(uhci_batch->usb_batch->ep);
     355        assert(uhci_batch->td_count >= 2);
     356
     357        const bool low_speed =
     358            uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
     359        const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
     360        const usb_target_t target = {
     361            uhci_batch->usb_batch->ep->address,
     362            uhci_batch->usb_batch->ep->endpoint };
    389363
    390364        /* setup stage */
    391365        td_init(
    392             data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,
    393             low_speed, target, USB_PID_SETUP, instance->setup_buffer,
    394             &data->tds[1]);
     366            &uhci_batch->tds[0], DEFAULT_ERROR_COUNT,
     367            uhci_batch->usb_batch->setup_size, 0, false,
     368            low_speed, target, USB_PID_SETUP,
     369            uhci_transfer_batch_setup_buffer(uhci_batch), &uhci_batch->tds[1]);
    395370
    396371        /* data stage */
    397372        size_t td = 1;
    398373        unsigned toggle = 1;
    399         size_t remain_size = instance->buffer_size;
    400         char *buffer = instance->data_buffer;
     374        size_t remain_size = uhci_batch->usb_batch->buffer_size;
     375        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
     376
    401377        while (remain_size > 0) {
    402378                const size_t packet_size =
    403                     (instance->ep->max_packet_size > remain_size) ?
    404                     remain_size : instance->ep->max_packet_size;
     379                    (remain_size < mps) ? remain_size : mps;
    405380
    406381                td_init(
    407                     &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
    408                     toggle, false, low_speed, target, data_stage,
    409                     buffer, &data->tds[td + 1]);
     382                    &uhci_batch->tds[td], DEFAULT_ERROR_COUNT, packet_size,
     383                    toggle, false, low_speed, target, data_stage_pid,
     384                    buffer, &uhci_batch->tds[td + 1]);
    410385
    411386                ++td;
    412387                toggle = 1 - toggle;
    413388                buffer += packet_size;
    414                 assert(td < data->td_count);
    415                 assert(packet_size <= remain_size);
    416389                remain_size -= packet_size;
     390                assert(td < uhci_batch->td_count);
    417391        }
    418392
    419393        /* status stage */
    420         assert(td == data->td_count - 1);
     394        assert(td == uhci_batch->td_count - 1);
    421395
    422396        td_init(
    423             &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    424             target, status_stage, NULL, NULL);
    425         td_set_ioc(&data->tds[td]);
     397            &uhci_batch->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     398            target, status_stage_pid, NULL, NULL);
     399        td_set_ioc(&uhci_batch->tds[td]);
    426400
    427401        usb_log_debug2("Control last TD status: %x.\n",
    428             data->tds[td].status);
    429 }
    430 /*----------------------------------------------------------------------------*/
    431 /** Provides access to QH data structure.
    432  *
    433  * @param[in] instance Batch pointer to use.
    434  * @return Pointer to the QH used by the batch.
    435  */
    436 qh_t * batch_qh(usb_transfer_batch_t *instance)
    437 {
    438         assert(instance);
    439         uhci_transfer_batch_t *data = instance->private_data;
    440         assert(data);
    441         return data->qh;
    442 }
     402            uhci_batch->tds[td].status);
     403}
     404/*----------------------------------------------------------------------------*/
     405static void batch_setup_control(uhci_transfer_batch_t *uhci_batch)
     406{
     407        // TODO Find a better way to do this
     408        assert(uhci_batch);
     409        assert(uhci_batch->usb_batch);
     410        if (uhci_batch->usb_batch->setup_buffer[0] & (1 << 7))
     411                control_read(uhci_batch);
     412        else
     413                control_write(uhci_batch);
     414}
     415/*----------------------------------------------------------------------------*/
     416static void (*batch_setup[4][3])(uhci_transfer_batch_t*) =
     417{
     418        { NULL, NULL, batch_setup_control },
     419        { NULL, NULL, NULL },
     420        { bulk_in, bulk_out, NULL },
     421        { interrupt_in, interrupt_out, NULL },
     422};
    443423/**
    444424 * @}
Note: See TracChangeset for help on using the changeset viewer.