#ifndef UHCI_HARDWARE_H
#define UHCI_HARDWARE_H
#define PCI_LEGSUP 0xC0
#define PCI_LEGSUP_USBPIRQDEN 0x2000
#define PCI_LEGSUP_CLEAR_SMI 0x8f00
#define UHCI_USBCMD 0x00
#define UHCI_USBSTS 0x02
#define UHCI_USBINTR 0x04
#define UHCI_FRNUM 0x06
#define UHCI_FRBASEADD 0x08
#define UHCI_SOFMOD 0x0c
#define UHCI_PORTSC1 0x10
#define UHCI_PORTSC2 0x12
#define UHCI_USBCMD_RS 0x01
#define UHCI_USBCMD_HCRESET 0x02
#define UHCI_USBCMD_GRESET 0x04
#define UHCI_USBCMD_EGSM 0x08
#define UHCI_USBCMD_FGR 0x10
#define UHCI_USBCMD_SWDBG 0x20
#define UHCI_USBCMD_CF 0x40
#define UHCI_USBCMD_MAXP 0x80
#define UHCI_USBSTS_USBINT 0x01
#define UHCI_USBSTS_ERRINT 0x02
#define UHCI_USBSTS_RESDET 0x04
#define UHCI_USBSTS_HOSTERR 0x08
#define UHCI_USBSTS_HCPRERR 0x10
#define UHCI_USBSTS_HCHALT 0x20
#define UHCI_USBINTR_CRC 0x01
#define UHCI_USBINTR_RESUME 0x02
#define UHCI_USBINTR_IOC 0x04
#define UHCI_USBINTR_SHORT 0x08
#define UHCI_PORTSC_CURSTAT 0x0001
#define UHCI_PORTSC_STATCHA 0x0002
#define UHCI_PORTSC_ENABLED 0x0004
#define UHCI_PORTSC_ENABCHA 0x0008
#define UHCI_PORTSC_LINE_0 0x0010
#define UHCI_PORTSC_LINE_1 0x0020
#define UHCI_PORTSC_RESUME 0x0040
#define UHCI_PORTSC_LOWSPEED 0x0100
#define UHCI_PORTSC_RESET 0x0200
#define UHCI_PORTSC_SUSPEND 0x1000
#define UHCI_PORTSC_DATAMASK 0x13f5
#define FRAMELIST_TERMINATE 0x1
#define FRAMELIST_NEXT_IS_QH 0x2
#define NUMBER_OF_FRAMES 1024
#define MAX_AVAILABLE_BANDWIDTH 900
typedef struct
{
uint32 link_phy;
uint32 status;
uint32 token;
uint32 buffer_phy;
uint32 this_phy;
void *link_log;
void *buffer_log;
size_t buffer_size;
} uhci_td;
#define TD_NEXT_IS_QH 0x02
#define TD_CONTROL_SPD (1 << 29)
#define TD_CONTROL_3_ERRORS (3 << 27)
#define TD_CONTROL_LOWSPEED (1 << 26)
#define TD_CONTROL_ISOCHRONOUS (1 << 25)
#define TD_CONTROL_IOC (1 << 24)
#define TD_STATUS_ACTIVE (1 << 23)
#define TD_STATUS_ERROR_STALLED (1 << 22)
#define TD_STATUS_ERROR_BUFFER (1 << 21)
#define TD_STATUS_ERROR_BABBLE (1 << 20)
#define TD_STATUS_ERROR_NAK (1 << 19)
#define TD_STATUS_ERROR_CRC (1 << 18)
#define TD_STATUS_ERROR_TIMEOUT (1 << 18)
#define TD_STATUS_ERROR_BITSTUFF (1 << 17)
#define TD_STATUS_ACTLEN_MASK 0x07ff
#define TD_STATUS_ACTLEN_NULL 0x07ff
#define TD_TOKEN_MAXLEN_SHIFT 21
#define TD_TOKEN_NULL_DATA (0x07ff << TD_TOKEN_MAXLEN_SHIFT)
#define TD_TOKEN_DATA_TOGGLE_SHIFT 19
#define TD_TOKEN_DATA1 (1 << TD_TOKEN_DATA_TOGGLE_SHIFT)
#define TD_TOKEN_SETUP 0x2d
#define TD_TOKEN_IN 0x69
#define TD_TOKEN_OUT 0xe1
#define TD_TOKEN_ENDPTADDR_SHIFT 15
#define TD_TOKEN_DEVADDR_SHIFT 8
#define TD_DEPTH_FIRST 0x04
#define TD_TERMINATE 0x01
#define TD_ERROR_MASK 0x440000
#define TD_ERROR_COUNT_SHIFT 27
#define TD_ERROR_COUNT_MASK 0x03
#define TD_LINK_MASK 0xfffffff0
static inline size_t
uhci_td_maximum_length(uhci_td *descriptor)
{
size_t length = (descriptor->token >> TD_TOKEN_MAXLEN_SHIFT) + 1;
if (length == TD_STATUS_ACTLEN_NULL + 1)
return 0;
return length;
}
static inline size_t
uhci_td_actual_length(uhci_td *descriptor)
{
size_t length = (descriptor->status & TD_STATUS_ACTLEN_MASK) + 1;
if (length == TD_STATUS_ACTLEN_NULL + 1)
return 0;
return length;
}
typedef struct
{
uint32 link_phy;
uint32 element_phy;
uint32 this_phy;
void *link_log;
} uhci_qh;
#define QH_TERMINATE 0x01
#define QH_NEXT_IS_QH 0x02
#define QH_LINK_MASK 0xfffffff0
#endif