Changeset 4deca9b in mainline for uspace/drv/uhci-hcd/batch.c


Ignore:
Timestamp:
2011-04-12T11:43:35Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
651b352
Parents:
1324ff3 (diff), 910ca3f (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:

Extensive cleanup, preparation for OHCI rework

File:
1 edited

Legend:

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

    r1324ff3 r4deca9b  
    3030 */
    3131/** @file
    32  * @brief UHCI driver USB transaction structure
     32 * @brief UHCI driver USB transfer structure
    3333 */
    3434#include <errno.h>
     
    4848        qh_t *qh;
    4949        td_t *tds;
    50         size_t transfers;
     50        size_t td_count;
    5151} uhci_batch_t;
    5252
     
    6161 *
    6262 * @param[in] fun DDF function to pass to callback.
    63  * @param[in] target Device and endpoint target of the transaction.
    64  * @param[in] transfer_type Interrupt, Control or Bulk.
    65  * @param[in] max_packet_size maximum allowed size of data transfers.
    66  * @param[in] speed Speed of the transaction.
     63 * @param[in] ep Communication target
    6764 * @param[in] buffer Data source/destination.
    6865 * @param[in] size Size of the buffer.
    6966 * @param[in] setup_buffer Setup data source (if not NULL)
    7067 * @param[in] setup_size Size of setup_buffer (should be always 8)
    71  * @param[in] func_in function to call on inbound transaction completion
    72  * @param[in] func_out function to call on outbound transaction completion
     68 * @param[in] func_in function to call on inbound transfer completion
     69 * @param[in] func_out function to call on outbound transfer completion
    7370 * @param[in] arg additional parameter to func_in or func_out
    74  * @param[in] ep Pointer to endpoint toggle management structure.
    7571 * @return Valid pointer if all substructures were successfully created,
    7672 * NULL otherwise.
    7773 *
    78  * Determines the number of needed transfers (TDs). Prepares a transport buffer
    79  * (that is accessible by the hardware). Initializes parameters needed for the
    80  * transaction and callback.
     74 * Determines the number of needed transfer descriptors (TDs).
     75 * Prepares a transport buffer (that is accessible by the hardware).
     76 * Initializes parameters needed for the transfer and callback.
    8177 */
    8278usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
     
    10399        usb_target_t target =
    104100            { .address = ep->address, .endpoint = ep->endpoint };
    105         usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
    106             ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
    107             func_in, func_out, arg, fun, ep, NULL);
     101        usb_transfer_batch_init(instance, ep,
     102            buffer, NULL, buffer_size, NULL, setup_size,
     103            func_in, func_out, arg, fun, NULL);
    108104
    109105
     
    113109        instance->private_data = data;
    114110
    115         data->transfers =
     111        data->td_count =
    116112            (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
    117113        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    118                 data->transfers += 2;
    119         }
    120 
    121         data->tds = malloc32(sizeof(td_t) * data->transfers);
     114                data->td_count += 2;
     115        }
     116
     117        data->tds = malloc32(sizeof(td_t) * data->td_count);
    122118        CHECK_NULL_DISPOSE_RETURN(
    123119            data->tds, "Failed to allocate transfer descriptors.\n");
    124         bzero(data->tds, sizeof(td_t) * data->transfers);
     120        bzero(data->tds, sizeof(td_t) * data->td_count);
    125121
    126122        data->qh = malloc32(sizeof(qh_t));
     
    131127
    132128        if (buffer_size > 0) {
    133                 instance->transport_buffer = malloc32(buffer_size);
    134                 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
     129                instance->data_buffer = malloc32(buffer_size);
     130                CHECK_NULL_DISPOSE_RETURN(instance->data_buffer,
    135131                    "Failed to allocate device accessible buffer.\n");
    136132        }
     
    154150 *
    155151 * Walk all TDs. Stop with false if there is an active one (it is to be
    156  * processed). Stop with true if an error is found. Return true if the last TS
     152 * processed). Stop with true if an error is found. Return true if the last TD
    157153 * is reached.
    158154 */
     
    164160
    165161        usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n",
    166             instance, data->transfers);
     162            instance, data->td_count);
    167163        instance->transfered_size = 0;
    168164        size_t i = 0;
    169         for (;i < data->transfers; ++i) {
     165        for (;i < data->td_count; ++i) {
    170166                if (td_is_active(&data->tds[i])) {
    171167                        return false;
     
    177173                            instance, i, data->tds[i].status);
    178174                        td_print_status(&data->tds[i]);
     175
    179176                        assert(instance->ep != NULL);
    180 
    181177                        endpoint_toggle_set(instance->ep,
    182178                            td_toggle(&data->tds[i]));
     
    195191}
    196192/*----------------------------------------------------------------------------*/
    197 /** Prepares control write transaction.
    198  *
    199  * @param[in] instance Batch structure to use.
    200  *
    201  * Uses genercir control function with pids OUT and IN.
     193/** Prepares control write transfer.
     194 *
     195 * @param[in] instance Batch structure to use.
     196 *
     197 * Uses generic control function with pids OUT and IN.
    202198 */
    203199void batch_control_write(usb_transfer_batch_t *instance)
     
    205201        assert(instance);
    206202        /* We are data out, we are supposed to provide data */
    207         memcpy(instance->transport_buffer, instance->buffer,
    208             instance->buffer_size);
     203        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    209204        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    210205        instance->next_step = batch_call_out_and_dispose;
     
    212207}
    213208/*----------------------------------------------------------------------------*/
    214 /** Prepares control read transaction.
     209/** Prepares control read transfer.
    215210 *
    216211 * @param[in] instance Batch structure to use.
     
    226221}
    227222/*----------------------------------------------------------------------------*/
    228 /** Prepare interrupt in transaction.
    229  *
    230  * @param[in] instance Batch structure to use.
    231  *
    232  * Data transaction with PID_IN.
     223/** Prepare interrupt in transfer.
     224 *
     225 * @param[in] instance Batch structure to use.
     226 *
     227 * Data transfer with PID_IN.
    233228 */
    234229void batch_interrupt_in(usb_transfer_batch_t *instance)
    235230{
    236231        assert(instance);
    237         instance->direction = USB_DIRECTION_IN;
    238232        batch_data(instance, USB_PID_IN);
    239233        instance->next_step = batch_call_in_and_dispose;
     
    241235}
    242236/*----------------------------------------------------------------------------*/
    243 /** Prepare interrupt out transaction.
    244  *
    245  * @param[in] instance Batch structure to use.
    246  *
    247  * Data transaction with PID_OUT.
     237/** Prepare interrupt out transfer.
     238 *
     239 * @param[in] instance Batch structure to use.
     240 *
     241 * Data transfer with PID_OUT.
    248242 */
    249243void batch_interrupt_out(usb_transfer_batch_t *instance)
    250244{
    251245        assert(instance);
    252         instance->direction = USB_DIRECTION_OUT;
    253246        /* We are data out, we are supposed to provide data */
    254         memcpy(instance->transport_buffer, instance->buffer,
    255             instance->buffer_size);
     247        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    256248        batch_data(instance, USB_PID_OUT);
    257249        instance->next_step = batch_call_out_and_dispose;
     
    259251}
    260252/*----------------------------------------------------------------------------*/
    261 /** Prepare bulk in transaction.
    262  *
    263  * @param[in] instance Batch structure to use.
    264  *
    265  * Data transaction with PID_IN.
     253/** Prepare bulk in transfer.
     254 *
     255 * @param[in] instance Batch structure to use.
     256 *
     257 * Data transfer with PID_IN.
    266258 */
    267259void batch_bulk_in(usb_transfer_batch_t *instance)
     
    269261        assert(instance);
    270262        batch_data(instance, USB_PID_IN);
    271         instance->direction = USB_DIRECTION_IN;
    272263        instance->next_step = batch_call_in_and_dispose;
    273264        usb_log_debug("Batch(%p) BULK IN initialized.\n", instance);
    274265}
    275266/*----------------------------------------------------------------------------*/
    276 /** Prepare bulk out transaction.
    277  *
    278  * @param[in] instance Batch structure to use.
    279  *
    280  * Data transaction with PID_OUT.
     267/** Prepare bulk out transfer.
     268 *
     269 * @param[in] instance Batch structure to use.
     270 *
     271 * Data transfer with PID_OUT.
    281272 */
    282273void batch_bulk_out(usb_transfer_batch_t *instance)
    283274{
    284275        assert(instance);
    285         instance->direction = USB_DIRECTION_OUT;
    286276        /* We are data out, we are supposed to provide data */
    287         memcpy(instance->transport_buffer, instance->buffer,
    288             instance->buffer_size);
     277        memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
    289278        batch_data(instance, USB_PID_OUT);
    290279        instance->next_step = batch_call_out_and_dispose;
     
    292281}
    293282/*----------------------------------------------------------------------------*/
    294 /** Prepare generic data transaction
    295  *
    296  * @param[in] instance Batch structure to use.
    297  * @param[in] pid Pid to use for data transfers.
    298  *
    299  * Packets with alternating toggle bit and supplied pid value.
     283/** Prepare generic data transfer
     284 *
     285 * @param[in] instance Batch structure to use.
     286 * @param[in] pid Pid to use for data transactions.
     287 *
     288 * Transactions with alternating toggle bit and supplied pid value.
    300289 * The last transfer is marked with IOC flag.
    301290 */
     
    306295        assert(data);
    307296
    308         const bool low_speed = instance->speed == USB_SPEED_LOW;
     297        const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
    309298        int toggle = endpoint_toggle_get(instance->ep);
    310299        assert(toggle == 0 || toggle == 1);
    311300
    312         size_t transfer = 0;
     301        size_t td = 0;
    313302        size_t remain_size = instance->buffer_size;
     303        char *buffer = instance->data_buffer;
    314304        while (remain_size > 0) {
    315                 char *trans_data =
    316                     instance->transport_buffer + instance->buffer_size
    317                     - remain_size;
    318 
    319305                const size_t packet_size =
    320                     (instance->max_packet_size > remain_size) ?
    321                     remain_size : instance->max_packet_size;
    322 
    323                 td_t *next_transfer = (transfer + 1 < data->transfers)
    324                     ? &data->tds[transfer + 1] : NULL;
    325 
    326                 assert(transfer < data->transfers);
     306                    (instance->ep->max_packet_size > remain_size) ?
     307                    remain_size : instance->ep->max_packet_size;
     308
     309                td_t *next_td = (td + 1 < data->td_count)
     310                    ? &data->tds[td + 1] : NULL;
     311
     312
     313                usb_target_t target =
     314                    { instance->ep->address, instance->ep->endpoint };
     315
     316                assert(td < data->td_count);
     317                td_init(
     318                    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
     319                    toggle, false, low_speed, target, pid, buffer, next_td);
     320
     321                ++td;
     322                toggle = 1 - toggle;
     323                buffer += packet_size;
    327324                assert(packet_size <= remain_size);
    328 
    329                 td_init(
    330                     &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    331                     toggle, false, low_speed, instance->target, pid, trans_data,
    332                     next_transfer);
    333 
    334 
    335                 toggle = 1 - toggle;
    336325                remain_size -= packet_size;
    337                 ++transfer;
    338         }
    339         td_set_ioc(&data->tds[transfer - 1]);
     326        }
     327        td_set_ioc(&data->tds[td - 1]);
    340328        endpoint_toggle_set(instance->ep, toggle);
    341329}
    342330/*----------------------------------------------------------------------------*/
    343 /** Prepare generic control transaction
    344  *
    345  * @param[in] instance Batch structure to use.
    346  * @param[in] data_stage Pid to use for data transfers.
    347  * @param[in] status_stage Pid to use for data transfers.
     331/** Prepare generic control transfer
     332 *
     333 * @param[in] instance Batch structure to use.
     334 * @param[in] data_stage Pid to use for data tds.
     335 * @param[in] status_stage Pid to use for data tds.
    348336 *
    349337 * Setup stage with toggle 0 and USB_PID_SETUP.
     
    358346        uhci_batch_t *data = instance->private_data;
    359347        assert(data);
    360         assert(data->transfers >= 2);
    361 
    362         const bool low_speed = instance->speed == USB_SPEED_LOW;
    363         int toggle = 0;
     348        assert(data->td_count >= 2);
     349
     350        const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
     351        const usb_target_t target =
     352            { instance->ep->address, instance->ep->endpoint };
     353
    364354        /* setup stage */
    365355        td_init(
    366             data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, toggle, false,
    367             low_speed, instance->target, USB_PID_SETUP, instance->setup_buffer,
     356            data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,
     357            low_speed, target, USB_PID_SETUP, instance->setup_buffer,
    368358            &data->tds[1]);
    369359
    370360        /* data stage */
    371         size_t transfer = 1;
     361        size_t td = 1;
     362        unsigned toggle = 1;
    372363        size_t remain_size = instance->buffer_size;
     364        char *buffer = instance->data_buffer;
    373365        while (remain_size > 0) {
    374                 char *control_data =
    375                     instance->transport_buffer + instance->buffer_size
    376                     - remain_size;
    377 
     366                const size_t packet_size =
     367                    (instance->ep->max_packet_size > remain_size) ?
     368                    remain_size : instance->ep->max_packet_size;
     369
     370                td_init(
     371                    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
     372                    toggle, false, low_speed, target, data_stage,
     373                    buffer, &data->tds[td + 1]);
     374
     375                ++td;
    378376                toggle = 1 - toggle;
    379 
    380                 const size_t packet_size =
    381                     (instance->max_packet_size > remain_size) ?
    382                     remain_size : instance->max_packet_size;
    383 
    384                 td_init(
    385                     &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size,
    386                     toggle, false, low_speed, instance->target, data_stage,
    387                     control_data, &data->tds[transfer + 1]);
    388 
    389                 ++transfer;
    390                 assert(transfer < data->transfers);
     377                buffer += packet_size;
     378                assert(td < data->td_count);
    391379                assert(packet_size <= remain_size);
    392380                remain_size -= packet_size;
     
    394382
    395383        /* status stage */
    396         assert(transfer == data->transfers - 1);
     384        assert(td == data->td_count - 1);
    397385
    398386        td_init(
    399             &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
    400             instance->target, status_stage, NULL, NULL);
    401         td_set_ioc(&data->tds[transfer]);
     387            &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
     388            target, status_stage, NULL, NULL);
     389        td_set_ioc(&data->tds[td]);
    402390
    403391        usb_log_debug2("Control last TD status: %x.\n",
    404             data->tds[transfer].status);
     392            data->tds[td].status);
    405393}
    406394/*----------------------------------------------------------------------------*/
     
    413401}
    414402/*----------------------------------------------------------------------------*/
    415 /** Helper function calls callback and correctly disposes of batch structure.
     403/** Helper function, calls callback and correctly destroys batch structure.
    416404 *
    417405 * @param[in] instance Batch structure to use.
     
    424412}
    425413/*----------------------------------------------------------------------------*/
    426 /** Helper function calls callback and correctly disposes of batch structure.
     414/** Helper function calls callback and correctly destroys batch structure.
    427415 *
    428416 * @param[in] instance Batch structure to use.
     
    449437        free32(data->qh);
    450438        free32(instance->setup_buffer);
    451         free32(instance->transport_buffer);
     439        free32(instance->data_buffer);
    452440        free(data);
    453441        free(instance);
Note: See TracChangeset for help on using the changeset viewer.