Changeset 4fe3b6d in mainline for uspace/drv/ohci/batch.c


Ignore:
Timestamp:
2011-05-20T11:07:00Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8bb61e6
Parents:
3476be8 (diff), 7941bd6 (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 with development

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/batch.c

    r3476be8 r4fe3b6d  
    4444#include "hw_struct/transfer_descriptor.h"
    4545
     46/** OHCI specific data required for USB transfer */
    4647typedef struct ohci_transfer_batch {
     48        /** Endpoint descriptor of the target endpoint. */
    4749        ed_t *ed;
     50        /** List of TDs needed for the transfer */
    4851        td_t **tds;
     52        /** Number of TDs used by the transfer */
    4953        size_t td_count;
     54        /** Dummy TD to be left at the ED and used by the next transfer */
    5055        size_t leave_td;
    51         char *device_buffer;
     56        /** Data buffer, must be accessible byb the OHCI hw. */
     57        void *device_buffer;
    5258} ohci_transfer_batch_t;
    53 
     59/*----------------------------------------------------------------------------*/
     60static void batch_control(usb_transfer_batch_t *instance,
     61    usb_direction_t data_dir, usb_direction_t status_dir);
     62static void batch_data(usb_transfer_batch_t *instance);
     63/*----------------------------------------------------------------------------*/
     64/** Safely destructs ohci_transfer_batch_t structure
     65 *
     66 * @param[in] ohci_batch Instance to destroy.
     67 */
    5468static void ohci_transfer_batch_dispose(void *ohci_batch)
    5569{
     
    6983}
    7084/*----------------------------------------------------------------------------*/
    71 static void batch_control(usb_transfer_batch_t *instance,
    72     usb_direction_t data_dir, usb_direction_t status_dir);
    73 static void batch_data(usb_transfer_batch_t *instance);
    74 /*----------------------------------------------------------------------------*/
     85/** Allocate memory initialize internal structures
     86 *
     87 * @param[in] fun DDF function to pass to callback.
     88 * @param[in] ep Communication target
     89 * @param[in] buffer Data source/destination.
     90 * @param[in] buffer_size Size of the buffer.
     91 * @param[in] setup_buffer Setup data source (if not NULL)
     92 * @param[in] setup_size Size of setup_buffer (should be always 8)
     93 * @param[in] func_in function to call on inbound transfer completion
     94 * @param[in] func_out function to call on outbound transfer completion
     95 * @param[in] arg additional parameter to func_in or func_out
     96 * @return Valid pointer if all structures were successfully created,
     97 * NULL otherwise.
     98 *
     99 * Allocates and initializes structures needed by the OHCI hw for the transfer.
     100 */
    75101usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    76     char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
     102    char *buffer, size_t buffer_size,
     103    const char *setup_buffer, size_t setup_size,
    77104    usbhc_iface_transfer_in_callback_t func_in,
    78105    usbhc_iface_transfer_out_callback_t func_out, void *arg)
     
    94121            ohci_transfer_batch_dispose);
    95122
    96         hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
     123        const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
    97124        assert(hcd_ep);
    98125
     
    103130        data->td_count =
    104131            ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
     132        /* Control transfer need Setup and Status stage */
    105133        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    106134                data->td_count += 2;
    107135        }
    108136
    109         /* we need one extra place for td that is currently assigned to hcd_ep*/
     137        /* We need an extra place for TD that is currently assigned to hcd_ep*/
    110138        data->tds = calloc(sizeof(td_t*), data->td_count + 1);
    111139        CHECK_NULL_DISPOSE_RETURN(data->tds,
    112140            "Failed to allocate transfer descriptors.\n");
    113141
     142        /* Add TD left over by the previous transfer */
    114143        data->tds[0] = hcd_ep->td;
    115144        data->leave_td = 0;
     
    123152        data->ed = hcd_ep->ed;
    124153
     154        /* NOTE: OHCI is capable of handling buffer that crosses page boundaries
     155         * it is, however, not capable of handling buffer that occupies more
     156         * than two pages (the first page is computed using start pointer, the
     157         * other using the end pointer) */
    125158        if (setup_size + buffer_size > 0) {
    126159                data->device_buffer = malloc32(setup_size + buffer_size);
     
    135168}
    136169/*----------------------------------------------------------------------------*/
     170/** Check batch TDs' status.
     171 *
     172 * @param[in] instance Batch structure to use.
     173 * @return False, if there is an active TD, true otherwise.
     174 *
     175 * Walk all TDs (usually there is just one). Stop with false if there is an
     176 * active TD. Stop with true if an error is found. Return true if the walk
     177 * completes with the last TD.
     178 */
    137179bool batch_is_complete(usb_transfer_batch_t *instance)
    138180{
     
    140182        ohci_transfer_batch_t *data = instance->private_data;
    141183        assert(data);
    142         size_t tds = data->td_count;
    143184        usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n",
    144             instance, tds);
     185            instance, data->td_count);
    145186        usb_log_debug("ED: %x:%x:%x:%x.\n",
    146187            data->ed->status, data->ed->td_head, data->ed->td_tail,
     
    148189        size_t i = 0;
    149190        instance->transfered_size = instance->buffer_size;
    150         for (; i < tds; ++i) {
     191        for (; i < data->td_count; ++i) {
    151192                assert(data->tds[i] != NULL);
    152193                usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
     
    173214        assert(hcd_ep);
    174215        hcd_ep->td = data->tds[i];
    175         if (i > 0)
    176                 instance->transfered_size -= td_remain_size(data->tds[i - 1]);
     216        assert(i > 0);
     217        for (--i;i < data->td_count; ++i)
     218                instance->transfered_size -= td_remain_size(data->tds[i]);
    177219
    178220        /* Clear possible ED HALT */
    179221        data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
    180         uint32_t pa = addr_to_phys(hcd_ep->td);
     222        const uint32_t pa = addr_to_phys(hcd_ep->td);
    181223        assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
    182224        assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
     
    185227}
    186228/*----------------------------------------------------------------------------*/
     229/** Starts execution of the TD list
     230 *
     231 * @param[in] instance Batch structure to use
     232 */
    187233void batch_commit(usb_transfer_batch_t *instance)
    188234{
     
    193239}
    194240/*----------------------------------------------------------------------------*/
     241/** Prepares control write transfer.
     242 *
     243 * @param[in] instance Batch structure to use.
     244 *
     245 * Uses generic control transfer using direction OUT(data stage) and
     246 * IN(status stage).
     247 */
    195248void batch_control_write(usb_transfer_batch_t *instance)
    196249{
     
    203256}
    204257/*----------------------------------------------------------------------------*/
     258/** Prepares control read transfer.
     259 *
     260 * @param[in] instance Batch structure to use.
     261 *
     262 * Uses generic control transfer using direction IN(data stage) and
     263 * OUT(status stage).
     264 */
    205265void batch_control_read(usb_transfer_batch_t *instance)
    206266{
     
    211271}
    212272/*----------------------------------------------------------------------------*/
     273/** Prepare interrupt in transfer.
     274 *
     275 * @param[in] instance Batch structure to use.
     276 *
     277 * Data transfer.
     278 */
    213279void batch_interrupt_in(usb_transfer_batch_t *instance)
    214280{
     
    219285}
    220286/*----------------------------------------------------------------------------*/
     287/** Prepare interrupt out transfer.
     288 *
     289 * @param[in] instance Batch structure to use.
     290 *
     291 * Data transfer.
     292 */
    221293void batch_interrupt_out(usb_transfer_batch_t *instance)
    222294{
     
    229301}
    230302/*----------------------------------------------------------------------------*/
     303/** Prepare bulk in transfer.
     304 *
     305 * @param[in] instance Batch structure to use.
     306 *
     307 * Data transfer.
     308 */
    231309void batch_bulk_in(usb_transfer_batch_t *instance)
    232310{
     
    237315}
    238316/*----------------------------------------------------------------------------*/
     317/** Prepare bulk out transfer.
     318 *
     319 * @param[in] instance Batch structure to use.
     320 *
     321 * Data transfer.
     322 */
    239323void batch_bulk_out(usb_transfer_batch_t *instance)
    240324{
     
    247331}
    248332/*----------------------------------------------------------------------------*/
    249 ed_t * batch_ed(usb_transfer_batch_t *instance)
    250 {
    251         assert(instance);
    252         ohci_transfer_batch_t *data = instance->private_data;
    253         assert(data);
    254         return data->ed;
    255 }
    256 /*----------------------------------------------------------------------------*/
     333/** Prepare generic control transfer
     334 *
     335 * @param[in] instance Batch structure to use.
     336 * @param[in] data_dir Direction to use for data stage.
     337 * @param[in] status_dir Direction to use for status stage.
     338 *
     339 * Setup stage with toggle 0 and direction BOTH(SETUP_PID)
     340 * Data stage with alternating toggle and direction supplied by parameter.
     341 * Status stage with toggle 1 and direction supplied by parameter.
     342 */
    257343void batch_control(usb_transfer_batch_t *instance,
    258344    usb_direction_t data_dir, usb_direction_t status_dir)
     
    303389}
    304390/*----------------------------------------------------------------------------*/
     391/** Prepare generic data transfer
     392 *
     393 * @param[in] instance Batch structure to use.
     394 *
     395 * Direction is supplied by the associated ep and toggle is maintained by the
     396 * OHCI hw in ED.
     397 */
    305398void batch_data(usb_transfer_batch_t *instance)
    306399{
     
    316409        char *buffer = instance->data_buffer;
    317410        while (remain_size > 0) {
    318                 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
    319                     OHCI_TD_MAX_TRANSFER : remain_size;
     411                const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER
     412                    ? OHCI_TD_MAX_TRANSFER : remain_size;
    320413
    321414                td_init(data->tds[td_current], instance->ep->direction,
Note: See TracChangeset for help on using the changeset viewer.