Ignore:
File:
1 edited

Legend:

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

    r02cacce r4125b7d  
    4444#include "hw_struct/transfer_descriptor.h"
    4545
    46 /** OHCI specific data required for USB transfer */
    4746typedef struct ohci_transfer_batch {
    48         /** Endpoint descriptor of the target endpoint. */
    4947        ed_t *ed;
    50         /** List of TDs needed for the transfer */
    5148        td_t **tds;
    52         /** Number of TDs used by the transfer */
    5349        size_t td_count;
    54         /** Dummy TD to be left at the ED and used by the next transfer */
    5550        size_t leave_td;
    56         /** Data buffer, must be accessible byb the OHCI hw. */
    57         void *device_buffer;
     51        char *device_buffer;
    5852} ohci_transfer_batch_t;
    59 /*----------------------------------------------------------------------------*/
    60 static void batch_control(usb_transfer_batch_t *instance,
    61     usb_direction_t data_dir, usb_direction_t status_dir);
    62 static 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  */
     53
    6854static void ohci_transfer_batch_dispose(void *ohci_batch)
    6955{
     
    8369}
    8470/*----------------------------------------------------------------------------*/
    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  */
     71static void batch_control(usb_transfer_batch_t *instance,
     72    usb_direction_t data_dir, usb_direction_t status_dir);
     73static void batch_data(usb_transfer_batch_t *instance);
     74/*----------------------------------------------------------------------------*/
    10175usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    102     char *buffer, size_t buffer_size,
    103     const char *setup_buffer, size_t setup_size,
     76    char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
    10477    usbhc_iface_transfer_in_callback_t func_in,
    10578    usbhc_iface_transfer_out_callback_t func_out, void *arg)
     
    12194            ohci_transfer_batch_dispose);
    12295
    123         const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
     96        hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
    12497        assert(hcd_ep);
    12598
     
    130103        data->td_count =
    131104            ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
    132         /* Control transfer need Setup and Status stage */
    133105        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    134106                data->td_count += 2;
    135107        }
    136108
    137         /* We need an extra place for TD that is currently assigned to hcd_ep*/
     109        /* we need one extra place for td that is currently assigned to hcd_ep*/
    138110        data->tds = calloc(sizeof(td_t*), data->td_count + 1);
    139111        CHECK_NULL_DISPOSE_RETURN(data->tds,
    140112            "Failed to allocate transfer descriptors.\n");
    141113
    142         /* Add TD left over by the previous transfer */
    143114        data->tds[0] = hcd_ep->td;
    144115        data->leave_td = 0;
     
    152123        data->ed = hcd_ep->ed;
    153124
    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) */
    158125        if (setup_size + buffer_size > 0) {
    159126                data->device_buffer = malloc32(setup_size + buffer_size);
     
    168135}
    169136/*----------------------------------------------------------------------------*/
    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  */
    179137bool batch_is_complete(usb_transfer_batch_t *instance)
    180138{
     
    182140        ohci_transfer_batch_t *data = instance->private_data;
    183141        assert(data);
     142        size_t tds = data->td_count;
    184143        usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n",
    185             instance, data->td_count);
     144            instance, tds);
    186145        usb_log_debug("ED: %x:%x:%x:%x.\n",
    187146            data->ed->status, data->ed->td_head, data->ed->td_tail,
     
    189148        size_t i = 0;
    190149        instance->transfered_size = instance->buffer_size;
    191         for (; i < data->td_count; ++i) {
     150        for (; i < tds; ++i) {
    192151                assert(data->tds[i] != NULL);
    193152                usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
     
    214173        assert(hcd_ep);
    215174        hcd_ep->td = data->tds[i];
    216         assert(i > 0);
    217         for (--i;i < data->td_count; ++i)
    218                 instance->transfered_size -= td_remain_size(data->tds[i]);
     175        if (i > 0)
     176                instance->transfered_size -= td_remain_size(data->tds[i - 1]);
    219177
    220178        /* Clear possible ED HALT */
    221179        data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
    222         const uint32_t pa = addr_to_phys(hcd_ep->td);
     180        uint32_t pa = addr_to_phys(hcd_ep->td);
    223181        assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
    224182        assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
     
    227185}
    228186/*----------------------------------------------------------------------------*/
    229 /** Starts execution of the TD list
    230  *
    231  * @param[in] instance Batch structure to use
    232  */
    233187void batch_commit(usb_transfer_batch_t *instance)
    234188{
     
    239193}
    240194/*----------------------------------------------------------------------------*/
    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  */
    248195void batch_control_write(usb_transfer_batch_t *instance)
    249196{
     
    256203}
    257204/*----------------------------------------------------------------------------*/
    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  */
    265205void batch_control_read(usb_transfer_batch_t *instance)
    266206{
     
    271211}
    272212/*----------------------------------------------------------------------------*/
    273 /** Prepare interrupt in transfer.
    274  *
    275  * @param[in] instance Batch structure to use.
    276  *
    277  * Data transfer.
    278  */
    279213void batch_interrupt_in(usb_transfer_batch_t *instance)
    280214{
     
    285219}
    286220/*----------------------------------------------------------------------------*/
    287 /** Prepare interrupt out transfer.
    288  *
    289  * @param[in] instance Batch structure to use.
    290  *
    291  * Data transfer.
    292  */
    293221void batch_interrupt_out(usb_transfer_batch_t *instance)
    294222{
     
    301229}
    302230/*----------------------------------------------------------------------------*/
    303 /** Prepare bulk in transfer.
    304  *
    305  * @param[in] instance Batch structure to use.
    306  *
    307  * Data transfer.
    308  */
    309231void batch_bulk_in(usb_transfer_batch_t *instance)
    310232{
     
    315237}
    316238/*----------------------------------------------------------------------------*/
    317 /** Prepare bulk out transfer.
    318  *
    319  * @param[in] instance Batch structure to use.
    320  *
    321  * Data transfer.
    322  */
    323239void batch_bulk_out(usb_transfer_batch_t *instance)
    324240{
     
    331247}
    332248/*----------------------------------------------------------------------------*/
    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  */
     249ed_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/*----------------------------------------------------------------------------*/
    343257void batch_control(usb_transfer_batch_t *instance,
    344258    usb_direction_t data_dir, usb_direction_t status_dir)
     
    389303}
    390304/*----------------------------------------------------------------------------*/
    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  */
    398305void batch_data(usb_transfer_batch_t *instance)
    399306{
     
    409316        char *buffer = instance->data_buffer;
    410317        while (remain_size > 0) {
    411                 const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER
    412                     ? OHCI_TD_MAX_TRANSFER : remain_size;
     318                size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
     319                    OHCI_TD_MAX_TRANSFER : remain_size;
    413320
    414321                td_init(data->tds[td_current], instance->ep->direction,
Note: See TracChangeset for help on using the changeset viewer.