/*
* Copyright (c) 2018 Ondrej Hlavaty
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @addtogroup drvusbxhci
* @{
*/
/** @file
* @brief Data structures and functions related to isochronous transfers.
*/
#ifndef XHCI_ISOCH_H
#define XHCI_ISOCH_H
#include <usb/dma_buffer.h>
#include "trb_ring.h"
#include "transfers.h"
typedef struct xhci_endpoint xhci_endpoint_t;
typedef enum {
ISOCH_EMPTY, /* Unused yet */
ISOCH_FILLED, /* The data buffer is valid */
ISOCH_FED, /* The data buffer is in possession of xHC */
ISOCH_COMPLETE, /* The error code is valid */
} xhci_isoch_transfer_state_t;
typedef struct {
/** Buffer with data */
dma_buffer_t data;
/** Used buffer size */
size_t size;
/** Current state */
xhci_isoch_transfer_state_t state;
/** Microframe to which to schedule */
uint64_t mfindex;
/** Physical address of enqueued TRB */
uintptr_t interrupt_trb_phys;
/** Result of the transfer. Valid only if status == ISOCH_COMPLETE. */
errno_t error;
} xhci_isoch_transfer_t;
typedef struct {
/** Protects common buffers. */
fibril_mutex_t guard;
/** Signals filled buffer. */
fibril_condvar_t avail;
/** Defers handing buffers to the HC. */
fibril_timer_t *feeding_timer;
/** Resets endpoint if there is no traffic. */
fibril_timer_t *reset_timer;
/**
* The maximum size of an isochronous transfer
* and therefore the size of buffers
*/
size_t max_size;
/** The microframe at which the last TRB was scheduled. */
uint64_t last_mf;
/** The number of transfer buffers allocated */
size_t buffer_count;
/** Isochronous scheduled transfers with respective buffers */
xhci_isoch_transfer_t *transfers;
/**
* Out: Next buffer that will be handed to HW.
* In: Invalid. Hidden inside HC.
*/
size_t hw_enqueue;
/**
* Out: Next buffer that will be used for writing.
* In: Next buffer that will be enqueued to be written by the HC
*/
size_t enqueue;
/**
* Out: First buffer that will be checked for completion
* In: Next buffer to be read from, when valid.
*/
size_t dequeue;
} xhci_isoch_t;
typedef struct usb_endpoint_descriptors usb_endpoint_descriptors_t;
extern void isoch_init(xhci_endpoint_t *, const usb_endpoint_descriptors_t *);
extern void isoch_fini(xhci_endpoint_t *);
extern errno_t isoch_alloc_transfers(xhci_endpoint_t *);
extern errno_t isoch_schedule_out(xhci_transfer_t *);
extern errno_t isoch_schedule_in(xhci_transfer_t *);
extern void isoch_handle_transfer_event(xhci_hc_t *, xhci_endpoint_t *,
xhci_trb_t *);
#endif
/**
* @}
*/