HelenOS sources
This source file includes following definitions.
- ed_inactive
- ed_clear_halt
- ed_transfer_pending
- ed_set_tail_td
- ed_tail_td
- ed_head_td
- ed_set_head_td
- ed_append_ed
- ed_next
- ed_toggle_get
- ed_toggle_set
#ifndef DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H
#define DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <usb/host/endpoint.h>
#include <usb/host/utils/malloc32.h>
#include "transfer_descriptor.h"
#include "completion_codes.h"
#include "mem_access.h"
typedef struct ed {
volatile uint32_t status;
#define ED_STATUS_FA_MASK (0x7f)
#define ED_STATUS_FA_SHIFT (0)
#define ED_STATUS_EN_MASK (0xf)
#define ED_STATUS_EN_SHIFT (7)
#define ED_STATUS_D_MASK (0x3)
#define ED_STATUS_D_SHIFT (11)
#define ED_STATUS_D_OUT (0x1)
#define ED_STATUS_D_IN (0x2)
#define ED_STATUS_D_TD (0x3)
#define ED_STATUS_S_FLAG (1 << 13)
#define ED_STATUS_K_FLAG (1 << 14)
#define ED_STATUS_F_FLAG (1 << 15)
#define ED_STATUS_MPS_MASK (0x3ff)
#define ED_STATUS_MPS_SHIFT (16)
volatile uint32_t td_tail;
#define ED_TDTAIL_PTR_MASK (0xfffffff0)
#define ED_TDTAIL_PTR_SHIFT (0)
volatile uint32_t td_head;
#define ED_TDHEAD_PTR_MASK (0xfffffff0)
#define ED_TDHEAD_PTR_SHIFT (0)
#define ED_TDHEAD_ZERO_MASK (0x3)
#define ED_TDHEAD_ZERO_SHIFT (2)
#define ED_TDHEAD_TOGGLE_CARRY (0x2)
#define ED_TDHEAD_HALTED_FLAG (0x1)
volatile uint32_t next;
#define ED_NEXT_PTR_MASK (0xfffffff0)
#define ED_NEXT_PTR_SHIFT (0)
} __attribute__((packed, aligned(32))) ed_t;
void ed_init(ed_t *instance, const endpoint_t *ep, const td_t *td);
static inline bool ed_inactive(const ed_t *instance)
{
assert(instance);
return (OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_HALTED_FLAG) ||
(OHCI_MEM32_RD(instance->status) & ED_STATUS_K_FLAG);
}
static inline void ed_clear_halt(ed_t *instance)
{
assert(instance);
OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_HALTED_FLAG);
}
static inline bool ed_transfer_pending(const ed_t *instance)
{
assert(instance);
return (OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_PTR_MASK) !=
(OHCI_MEM32_RD(instance->td_tail) & ED_TDTAIL_PTR_MASK);
}
static inline void ed_set_tail_td(ed_t *instance, const td_t *td)
{
assert(instance);
const uintptr_t pa = addr_to_phys(td);
OHCI_MEM32_WR(instance->td_tail, pa & ED_TDTAIL_PTR_MASK);
}
static inline uint32_t ed_tail_td(const ed_t *instance)
{
assert(instance);
return OHCI_MEM32_RD(instance->td_tail) & ED_TDTAIL_PTR_MASK;
}
static inline uint32_t ed_head_td(const ed_t *instance)
{
assert(instance);
return OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_PTR_MASK;
}
static inline void ed_set_head_td(ed_t *instance, const td_t *td)
{
assert(instance);
const uintptr_t pa = addr_to_phys(td);
OHCI_MEM32_WR(instance->td_head, pa & ED_TDHEAD_PTR_MASK);
}
static inline void ed_append_ed(ed_t *instance, const ed_t *next)
{
assert(instance);
assert(next);
const uint32_t pa = addr_to_phys(next);
assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa);
OHCI_MEM32_WR(instance->next, pa);
}
static inline uint32_t ed_next(const ed_t *instance)
{
assert(instance);
return OHCI_MEM32_RD(instance->next) & ED_NEXT_PTR_MASK;
}
static inline int ed_toggle_get(const ed_t *instance)
{
assert(instance);
return !!(OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_TOGGLE_CARRY);
}
static inline void ed_toggle_set(ed_t *instance, bool toggle)
{
assert(instance);
if (toggle) {
OHCI_MEM32_SET(instance->td_head, ED_TDHEAD_TOGGLE_CARRY);
} else {
OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_TOGGLE_CARRY);
OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_HALTED_FLAG);
}
}
#endif
HelenOS homepage, sources at GitHub