1/* 2 * Copyright 2004-2006, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Niels S. Reedijk 8 */ 9 10#ifndef UHCI_HARDWARE_H 11#define UHCI_HARDWARE_H 12 13/************************************************************ 14 * The Registers * 15 ************************************************************/ 16 17// R/W -- Read/Write 18// R/WC -- Read/Write Clear 19// ** -- Only writable with words! 20 21// PCI register 22#define PCI_LEGSUP 0xC0 23#define PCI_LEGSUP_USBPIRQDEN 0x2000 24#define PCI_LEGSUP_CLEAR_SMI 0x8f00 25 26// Registers 27#define UHCI_USBCMD 0x00 // USB Command - word - R/W 28#define UHCI_USBSTS 0x02 // USB Status - word - R/WC 29#define UHCI_USBINTR 0x04 // USB Interrupt Enable - word - R/W 30#define UHCI_FRNUM 0x06 // Frame number - word - R/W** 31#define UHCI_FRBASEADD 0x08 // Frame List BAse Address - dword - R/W 32#define UHCI_SOFMOD 0x0c // Start of Frame Modify - byte - R/W 33#define UHCI_PORTSC1 0x10 // Port 1 Status/Control - word - R/WC** 34#define UHCI_PORTSC2 0x12 // Port 2 Status/Control - word - R/WC** 35 36// USBCMD 37#define UHCI_USBCMD_RS 0x01 // Run/Stop 38#define UHCI_USBCMD_HCRESET 0x02 // Host Controller Reset 39#define UHCI_USBCMD_GRESET 0x04 // Global Reset 40#define UHCI_USBCMD_EGSM 0x08 // Enter Global Suspensd mode 41#define UHCI_USBCMD_FGR 0x10 // Force Global resume 42#define UHCI_USBCMD_SWDBG 0x20 // Software Debug 43#define UHCI_USBCMD_CF 0x40 // Configure Flag 44#define UHCI_USBCMD_MAXP 0x80 // Max packet 45 46//USBSTS 47#define UHCI_USBSTS_USBINT 0x01 // USB interrupt 48#define UHCI_USBSTS_ERRINT 0x02 // USB error interrupt 49#define UHCI_USBSTS_RESDET 0x04 // Resume Detect 50#define UHCI_USBSTS_HOSTERR 0x08 // Host System Error 51#define UHCI_USBSTS_HCPRERR 0x10 // Host Controller Process error 52#define UHCI_USBSTS_HCHALT 0x20 // HCHalted 53 54//USBINTR 55#define UHCI_USBINTR_CRC 0x01 // Timeout/ CRC interrupt enable 56#define UHCI_USBINTR_RESUME 0x02 // Resume interrupt enable 57#define UHCI_USBINTR_IOC 0x04 // Interrupt on complete enable 58#define UHCI_USBINTR_SHORT 0x08 // Short packet interrupt enable 59 60//PORTSC 61#define UHCI_PORTSC_CURSTAT 0x0001 // Current connect status 62#define UHCI_PORTSC_STATCHA 0x0002 // Current connect status change 63#define UHCI_PORTSC_ENABLED 0x0004 // Port enabled/disabled 64#define UHCI_PORTSC_ENABCHA 0x0008 // Change in enabled/disabled 65#define UHCI_PORTSC_LINE_0 0x0010 // The status of D+ 66#define UHCI_PORTSC_LINE_1 0x0020 // The status of D- 67#define UHCI_PORTSC_RESUME 0x0040 // Something with the suspend state ??? 68#define UHCI_PORTSC_LOWSPEED 0x0100 // Low speed device attached? 69#define UHCI_PORTSC_RESET 0x0200 // Port is in reset 70#define UHCI_PORTSC_SUSPEND 0x1000 // Set port in suspend state 71 72#define UHCI_PORTSC_DATAMASK 0x13f5 // Mask that excludes the change bits 73 74/************************************************************ 75 * Hardware structs * 76 ************************************************************/ 77 78// Framelist flags 79#define FRAMELIST_TERMINATE 0x1 80#define FRAMELIST_NEXT_IS_QH 0x2 81 82// Number of frames 83#define NUMBER_OF_FRAMES 1024 84#define MAX_AVAILABLE_BANDWIDTH 900 // Microseconds 85 86// Represents a Transfer Descriptor (TD) 87typedef struct 88{ 89 // Hardware part 90 uint32 link_phy; // Link to the next TD/QH 91 uint32 status; // Status field 92 uint32 token; // Contains the packet header (where it needs to be sent) 93 uint32 buffer_phy; // A pointer to the buffer with the actual packet 94 // Software part 95 uint32 this_phy; // A physical pointer to this address 96 void *link_log; // Pointer to the next logical TD/QT 97 void *buffer_log; // Pointer to the logical buffer 98 size_t buffer_size; // Size of the buffer 99} uhci_td; 100 101#define TD_NEXT_IS_QH 0x02 102 103// Control and Status 104#define TD_CONTROL_SPD (1 << 29) 105#define TD_CONTROL_3_ERRORS (3 << 27) 106#define TD_CONTROL_LOWSPEED (1 << 26) 107#define TD_CONTROL_ISOCHRONOUS (1 << 25) 108#define TD_CONTROL_IOC (1 << 24) 109 110#define TD_STATUS_ACTIVE (1 << 23) 111#define TD_STATUS_ERROR_STALLED (1 << 22) 112#define TD_STATUS_ERROR_BUFFER (1 << 21) 113#define TD_STATUS_ERROR_BABBLE (1 << 20) 114#define TD_STATUS_ERROR_NAK (1 << 19) 115#define TD_STATUS_ERROR_CRC (1 << 18) 116#define TD_STATUS_ERROR_TIMEOUT (1 << 18) 117#define TD_STATUS_ERROR_BITSTUFF (1 << 17) 118 119#define TD_STATUS_ACTLEN_MASK 0x07ff 120#define TD_STATUS_ACTLEN_NULL 0x07ff 121 122// Token 123#define TD_TOKEN_MAXLEN_SHIFT 21 124#define TD_TOKEN_NULL_DATA (0x07ff << TD_TOKEN_MAXLEN_SHIFT) 125#define TD_TOKEN_DATA_TOGGLE_SHIFT 19 126#define TD_TOKEN_DATA1 (1 << TD_TOKEN_DATA_TOGGLE_SHIFT) 127 128#define TD_TOKEN_SETUP 0x2d 129#define TD_TOKEN_IN 0x69 130#define TD_TOKEN_OUT 0xe1 131 132#define TD_TOKEN_ENDPTADDR_SHIFT 15 133#define TD_TOKEN_DEVADDR_SHIFT 8 134 135#define TD_DEPTH_FIRST 0x04 136#define TD_TERMINATE 0x01 137#define TD_ERROR_MASK 0x440000 138#define TD_ERROR_COUNT_SHIFT 27 139#define TD_ERROR_COUNT_MASK 0x03 140#define TD_LINK_MASK 0xfffffff0 141 142 143static inline size_t 144uhci_td_maximum_length(uhci_td *descriptor) 145{ 146 size_t length = (descriptor->token >> TD_TOKEN_MAXLEN_SHIFT) + 1; 147 if (length == TD_STATUS_ACTLEN_NULL + 1) 148 return 0; 149 return length; 150} 151 152 153static inline size_t 154uhci_td_actual_length(uhci_td *descriptor) 155{ 156 size_t length = (descriptor->status & TD_STATUS_ACTLEN_MASK) + 1; 157 if (length == TD_STATUS_ACTLEN_NULL + 1) 158 return 0; 159 return length; 160} 161 162 163// Represents a Queue Head (QH) 164typedef struct 165{ 166 // Hardware part 167 uint32 link_phy; // Link to the next TD/QH 168 uint32 element_phy; // Pointer to the first element in the queue 169 // Software part 170 uint32 this_phy; // The physical pointer to this address 171 void *link_log; // Pointer to the next logical TD/QH 172} uhci_qh; 173 174#define QH_TERMINATE 0x01 175#define QH_NEXT_IS_QH 0x02 176#define QH_LINK_MASK 0xfffffff0 177 178#endif 179