Changeset 5fd9c30 in mainline for uspace/drv/bus/usb/ohci/ohci_batch.c


Ignore:
Timestamp:
2017-10-21T20:52:56Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
766043c
Parents:
74b852b
Message:

usbhost refactoring: let transfer_batch be initialized by bus

Currently makes older HCs fail, work in progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    r74b852b r5fd9c30  
    4747#include "ohci_bus.h"
    4848
    49 static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t);
     49static void (*const batch_setup[])(ohci_transfer_batch_t*);
    5050
    5151/** Safely destructs ohci_transfer_batch_t structure
     
    5353 * @param[in] ohci_batch Instance to destroy.
    5454 */
    55 static void ohci_transfer_batch_dispose(ohci_transfer_batch_t *ohci_batch)
    56 {
    57         if (!ohci_batch)
    58                 return;
     55void ohci_transfer_batch_destroy(ohci_transfer_batch_t *ohci_batch)
     56{
     57        assert(ohci_batch);
    5958        if (ohci_batch->tds) {
    6059                const ohci_endpoint_t *ohci_ep =
     
    6766                free(ohci_batch->tds);
    6867        }
    69         usb_transfer_batch_destroy(ohci_batch->usb_batch);
    7068        free32(ohci_batch->device_buffer);
    7169        free(ohci_batch);
    72 }
    73 
    74 /** Finishes usb_transfer_batch and destroys the structure.
    75  *
    76  * @param[in] uhci_batch Instance to finish and destroy.
    77  */
    78 void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *ohci_batch)
    79 {
    80         assert(ohci_batch);
    81         assert(ohci_batch->usb_batch);
    82         usb_transfer_batch_finish(ohci_batch->usb_batch,
    83             ohci_batch->device_buffer + ohci_batch->usb_batch->setup_size);
    84         ohci_transfer_batch_dispose(ohci_batch);
    8570}
    8671
     
    9075 * @return Valid pointer if all structures were successfully created,
    9176 * NULL otherwise.
    92  *
    93  * Determines the number of needed transfer descriptors (TDs).
    94  * Prepares a transport buffer (that is accessible by the hardware).
    95  * Initializes parameters needed for the transfer and callback.
    96  */
    97 ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
    98 {
    99         assert(usb_batch);
     77 */
     78ohci_transfer_batch_t * ohci_transfer_batch_create(endpoint_t *ep)
     79{
     80        assert(ep);
    10081
    10182        ohci_transfer_batch_t *ohci_batch =
     
    10384        if (!ohci_batch) {
    10485                usb_log_error("Failed to allocate OHCI batch data.");
    105                 goto dispose;
    106         }
     86                return NULL;
     87        }
     88
     89        usb_transfer_batch_init(&ohci_batch->base, ep);
    10790        link_initialize(&ohci_batch->link);
    108         ohci_batch->td_count =
    109             (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
     91
     92        return ohci_batch;
     93}
     94
     95/** Prepares a batch to be sent.
     96 *
     97 * Determines the number of needed transfer descriptors (TDs).
     98 * Prepares a transport buffer (that is accessible by the hardware).
     99 * Initializes parameters needed for the transfer and callback.
     100 */
     101int ohci_transfer_batch_prepare(ohci_transfer_batch_t *ohci_batch)
     102{
     103        assert(ohci_batch);
     104
     105        const size_t setup_size = (ohci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL)
     106                ? USB_SETUP_PACKET_SIZE
     107                : 0;
     108
     109        usb_transfer_batch_t *usb_batch = &ohci_batch->base;
     110
     111        ohci_batch->td_count = (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
    110112            / OHCI_TD_MAX_TRANSFER;
    111113        /* Control transfer need Setup and Status stage */
     
    118120        if (!ohci_batch->tds) {
    119121                usb_log_error("Failed to allocate OHCI transfer descriptors.");
    120                 goto dispose;
     122                return ENOMEM;
    121123        }
    122124
     
    129131                if (!ohci_batch->tds[i]) {
    130132                        usb_log_error("Failed to allocate TD %d.", i);
    131                         goto dispose;
     133                        return ENOMEM;
    132134                }
    133135        }
    134 
    135136
    136137        /* NOTE: OHCI is capable of handling buffer that crosses page boundaries
     
    138139         * than two pages (the first page is computed using start pointer, the
    139140         * other using the end pointer) */
    140         if (usb_batch->setup_size + usb_batch->buffer_size > 0) {
     141        if (setup_size + usb_batch->buffer_size > 0) {
    141142                /* Use one buffer for setup and data stage */
    142143                ohci_batch->device_buffer =
    143                     malloc32(usb_batch->setup_size + usb_batch->buffer_size);
     144                    malloc32(setup_size + usb_batch->buffer_size);
    144145                if (!ohci_batch->device_buffer) {
    145146                        usb_log_error("Failed to allocate device buffer");
    146                         goto dispose;
     147                        return ENOMEM;
    147148                }
    148149                /* Copy setup data */
    149                 memcpy(ohci_batch->device_buffer, usb_batch->setup_buffer,
    150                     usb_batch->setup_size);
     150                memcpy(ohci_batch->device_buffer, usb_batch->setup.buffer, setup_size);
    151151                /* Copy generic data */
    152152                if (usb_batch->ep->direction != USB_DIRECTION_IN)
    153153                        memcpy(
    154                             ohci_batch->device_buffer + usb_batch->setup_size,
     154                            ohci_batch->device_buffer + setup_size,
    155155                            usb_batch->buffer, usb_batch->buffer_size);
    156156        }
    157         ohci_batch->usb_batch = usb_batch;
    158 
    159         const usb_direction_t dir = usb_transfer_batch_direction(usb_batch);
     157
    160158        assert(batch_setup[usb_batch->ep->transfer_type]);
    161         batch_setup[usb_batch->ep->transfer_type](ohci_batch, dir);
    162 
    163         return ohci_batch;
    164 dispose:
    165         ohci_transfer_batch_dispose(ohci_batch);
    166         return NULL;
     159        batch_setup[usb_batch->ep->transfer_type](ohci_batch);
     160
     161        return EOK;
    167162}
    168163
     
    176171 * completes with the last TD.
    177172 */
    178 bool ohci_transfer_batch_is_complete(const ohci_transfer_batch_t *ohci_batch)
    179 {
    180         assert(ohci_batch);
    181         assert(ohci_batch->usb_batch);
     173bool ohci_transfer_batch_check_completed(ohci_transfer_batch_t *ohci_batch)
     174{
     175        assert(ohci_batch);
    182176
    183177        usb_log_debug("Batch %p checking %zu td(s) for completion.\n",
     
    194188
    195189        /* Assume all data got through */
    196         ohci_batch->usb_batch->transfered_size =
    197             ohci_batch->usb_batch->buffer_size;
     190        ohci_batch->base.transfered_size = ohci_batch->base.buffer_size;
    198191
    199192        /* Assume we will leave the last(unused) TD behind */
     
    207200                    ohci_batch->tds[i]->next, ohci_batch->tds[i]->be);
    208201
    209                 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]);
    210                 if (ohci_batch->usb_batch->error == EOK) {
     202                ohci_batch->base.error = td_error(ohci_batch->tds[i]);
     203                if (ohci_batch->base.error == EOK) {
    211204                        /* If the TD got all its data through, it will report
    212205                         * 0 bytes remain, the sole exception is INPUT with
     
    221214                         * we leave the very last(unused) TD behind.
    222215                         */
    223                         ohci_batch->usb_batch->transfered_size
     216                        ohci_batch->base.transfered_size
    224217                            -= td_remain_size(ohci_batch->tds[i]);
    225218                } else {
     
    252245                }
    253246        }
    254         assert(ohci_batch->usb_batch->transfered_size <=
    255             ohci_batch->usb_batch->buffer_size);
     247        assert(ohci_batch->base.transfered_size <=
     248            ohci_batch->base.buffer_size);
     249
     250        if (ohci_batch->base.dir == USB_DIRECTION_IN)
     251                memcpy(ohci_batch->base.buffer, ohci_batch->device_buffer, ohci_batch->base.transfered_size);
    256252
    257253        /* Store the remaining TD */
    258         ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep);
     254        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->base.ep);
    259255        assert(ohci_ep);
    260256        ohci_ep->td = ohci_batch->tds[leave_td];
     
    286282 * Status stage with toggle 1 and direction supplied by parameter.
    287283 */
    288 static void batch_control(ohci_transfer_batch_t *ohci_batch, usb_direction_t dir)
    289 {
    290         assert(ohci_batch);
    291         assert(ohci_batch->usb_batch);
     284static void batch_control(ohci_transfer_batch_t *ohci_batch)
     285{
     286        assert(ohci_batch);
     287
     288        usb_direction_t dir = ohci_batch->base.dir;
    292289        assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
     290
    293291        usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed,
    294292            ohci_batch->ed->status, ohci_batch->ed->td_tail,
     
    307305        td_init(
    308306            ohci_batch->tds[0], ohci_batch->tds[1], USB_DIRECTION_BOTH,
    309             buffer, ohci_batch->usb_batch->setup_size, toggle);
     307            buffer, USB_SETUP_PACKET_SIZE, toggle);
    310308        usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n",
    311309            ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp,
    312310            ohci_batch->tds[0]->next, ohci_batch->tds[0]->be);
    313         buffer += ohci_batch->usb_batch->setup_size;
     311        buffer += USB_SETUP_PACKET_SIZE;
    314312
    315313        /* Data stage */
     
    361359 * OHCI hw in ED.
    362360 */
    363 static void batch_data(ohci_transfer_batch_t *ohci_batch, usb_direction_t dir)
    364 {
    365         assert(ohci_batch);
    366         assert(ohci_batch->usb_batch);
     361static void batch_data(ohci_transfer_batch_t *ohci_batch)
     362{
     363        assert(ohci_batch);
     364
     365        usb_direction_t dir = ohci_batch->base.dir;
    367366        assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
    368367        usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed,
     
    401400
    402401/** Transfer setup table. */
    403 static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t) =
     402static void (*const batch_setup[])(ohci_transfer_batch_t*) =
    404403{
    405404        [USB_TRANSFER_CONTROL] = batch_control,
Note: See TracChangeset for help on using the changeset viewer.