xref: /haiku/src/add-ons/kernel/busses/usb/uhci_hardware.h (revision e5d65858f2361fe0552495b61620c84dcee6bc00)
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)
87  typedef 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  
143  static inline size_t
144  uhci_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  
153  static inline size_t
154  uhci_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)
164  typedef 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