Ignore:
File:
1 edited

Legend:

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

    r4125b7d r33d19a7  
    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,
    76102    char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
     
    107133        }
    108134
    109         /* we need one extra place for td that is currently assigned to hcd_ep*/
     135        /* We need an extra place for TD that is currently assigned to hcd_ep*/
    110136        data->tds = calloc(sizeof(td_t*), data->td_count + 1);
    111137        CHECK_NULL_DISPOSE_RETURN(data->tds,
    112138            "Failed to allocate transfer descriptors.\n");
    113139
     140        /* Add TD left over by the previous transfer */
    114141        data->tds[0] = hcd_ep->td;
    115142        data->leave_td = 0;
     
    123150        data->ed = hcd_ep->ed;
    124151
     152        /* NOTE: OHCI is capable of handling buffer that crosses page boundaries
     153         * it is, however, not capable of handling buffer that occupies more
     154         * than two pages (the first page is computed using start pointer, the
     155         * other using the end pointer) */
    125156        if (setup_size + buffer_size > 0) {
    126157                data->device_buffer = malloc32(setup_size + buffer_size);
     
    135166}
    136167/*----------------------------------------------------------------------------*/
     168/** Check batch TDs' status.
     169 *
     170 * @param[in] instance Batch structure to use.
     171 * @return False, if there is an active TD, true otherwise.
     172 *
     173 * Walk all TDs (usually there is just one). Stop with false if there is an
     174 * active TD. Stop with true if an error is found. Return true if the walk
     175 * completes with the last TD.
     176 */
    137177bool batch_is_complete(usb_transfer_batch_t *instance)
    138178{
     
    140180        ohci_transfer_batch_t *data = instance->private_data;
    141181        assert(data);
    142         size_t tds = data->td_count;
    143182        usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n",
    144             instance, tds);
     183            instance, data->td_count);
    145184        usb_log_debug("ED: %x:%x:%x:%x.\n",
    146185            data->ed->status, data->ed->td_head, data->ed->td_tail,
     
    148187        size_t i = 0;
    149188        instance->transfered_size = instance->buffer_size;
    150         for (; i < tds; ++i) {
     189        for (; i < data->td_count; ++i) {
    151190                assert(data->tds[i] != NULL);
    152191                usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
     
    173212        assert(hcd_ep);
    174213        hcd_ep->td = data->tds[i];
    175         if (i > 0)
    176                 instance->transfered_size -= td_remain_size(data->tds[i - 1]);
     214        assert(i > 0);
     215        for (--i;i < data->td_count; ++i)
     216                instance->transfered_size -= td_remain_size(data->tds[i]);
    177217
    178218        /* Clear possible ED HALT */
    179219        data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
    180         uint32_t pa = addr_to_phys(hcd_ep->td);
     220        const uint32_t pa = addr_to_phys(hcd_ep->td);
    181221        assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
    182222        assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
     
    185225}
    186226/*----------------------------------------------------------------------------*/
     227/** Starts execution of the TD list
     228 *
     229 * @param[in] instance Batch structure to use
     230 */
    187231void batch_commit(usb_transfer_batch_t *instance)
    188232{
     
    193237}
    194238/*----------------------------------------------------------------------------*/
     239/** Prepares control write transfer.
     240 *
     241 * @param[in] instance Batch structure to use.
     242 *
     243 * Uses generic control transfer using direction OUT(data stage) and
     244 * IN(status stage).
     245 */
    195246void batch_control_write(usb_transfer_batch_t *instance)
    196247{
     
    203254}
    204255/*----------------------------------------------------------------------------*/
     256/** Prepares control read transfer.
     257 *
     258 * @param[in] instance Batch structure to use.
     259 *
     260 * Uses generic control transfer using direction IN(data stage) and
     261 * OUT(status stage).
     262 */
    205263void batch_control_read(usb_transfer_batch_t *instance)
    206264{
     
    211269}
    212270/*----------------------------------------------------------------------------*/
     271/** Prepare interrupt in transfer.
     272 *
     273 * @param[in] instance Batch structure to use.
     274 *
     275 * Data transfer.
     276 */
    213277void batch_interrupt_in(usb_transfer_batch_t *instance)
    214278{
     
    219283}
    220284/*----------------------------------------------------------------------------*/
     285/** Prepare interrupt out transfer.
     286 *
     287 * @param[in] instance Batch structure to use.
     288 *
     289 * Data transfer.
     290 */
    221291void batch_interrupt_out(usb_transfer_batch_t *instance)
    222292{
     
    229299}
    230300/*----------------------------------------------------------------------------*/
     301/** Prepare bulk in transfer.
     302 *
     303 * @param[in] instance Batch structure to use.
     304 *
     305 * Data transfer.
     306 */
    231307void batch_bulk_in(usb_transfer_batch_t *instance)
    232308{
     
    237313}
    238314/*----------------------------------------------------------------------------*/
     315/** Prepare bulk out transfer.
     316 *
     317 * @param[in] instance Batch structure to use.
     318 *
     319 * Data transfer.
     320 */
    239321void batch_bulk_out(usb_transfer_batch_t *instance)
    240322{
     
    247329}
    248330/*----------------------------------------------------------------------------*/
    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 /*----------------------------------------------------------------------------*/
     331/** Prepare generic control transfer
     332 *
     333 * @param[in] instance Batch structure to use.
     334 * @param[in] data_dir Direction to use for data stage.
     335 * @param[in] status_dir Direction to use for status stage.
     336 *
     337 * Setup stage with toggle 0 and direction BOTH(SETUP_PID)
     338 * Data stage with alternating toggle and direction supplied by parameter.
     339 * Status stage with toggle 1 and direction supplied by parameter.
     340 */
    257341void batch_control(usb_transfer_batch_t *instance,
    258342    usb_direction_t data_dir, usb_direction_t status_dir)
     
    303387}
    304388/*----------------------------------------------------------------------------*/
     389/** Prepare generic data transfer
     390 *
     391 * @param[in] instance Batch structure to use.
     392 *
     393 * Direction is supplied by the associated ep and toggle is maintained by the
     394 * OHCI hw in ED.
     395 */
    305396void batch_data(usb_transfer_batch_t *instance)
    306397{
Note: See TracChangeset for help on using the changeset viewer.