aboutsummaryrefslogtreecommitdiffstats
path: root/src/filo/usb/uhci.h
blob: 17370a13da1fce07f068318c604e597d72f483b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#ifndef _UHCI_H
#define _UHCI_H

/*
 * The link pointer is multi use. Some fields are valid only for some uses. 
 * In other cases, they must be 0
 *
 */

#define MAX_POLLDEV 10

#define MAX_TRANSACTIONS 10
#define MAX_QUEUEHEAD 255
#define MAX_TD 1024


typedef struct link_pointer {
        unsigned long terminate:1;
        unsigned long queue:1;
        unsigned long depth:1;
        unsigned long reserved:1;
        unsigned long link:28;
} __attribute__((packed)) link_pointer_t;

extern link_pointer_t *frame_list[];

void init_framelist(uchar dev);


#define SETUP_TOKEN 0x2d
#define IN_TOKEN 0x69
#define OUT_TOKEN 0xe1

#define CTRL_RETRIES 3
#define CONTROL_STS_RETRIES 0


// some port features
#define PORT_CONNECTION 0
#define PORT_ENABLE 1
#define PORT_SUSPEND 2
#define PORT_OVER_CURRENT 3
#define PORT_RESET 4
#define PORT_POWER 8
#define PORT_LOW_SPEED 9
#define C_PORT_CONNECTION 16
#define C_PORT_ENABLE 17
#define C_PORT_SUSPEND 18
#define C_PORT_OVER_CURRENT 19
#define C_PORT_RESET 20

// features
#define FEATURE_HALT 0

typedef struct td {
	
	link_pointer_t link;

	unsigned long actual:11;	// actual length
	unsigned long reserved2:5;

// status/error flags
	unsigned long res1:1;
	unsigned long bitstuff:1;
	unsigned long crc:1;
	unsigned long nak:1;
	unsigned long babble:1;
	unsigned long buffer_error:1;
	unsigned long stall:1;
	unsigned long active:1;

	unsigned long interrupt:1;	// interrupt on complete
	unsigned long isochronous:1;
	unsigned long lowspeed:1;
	unsigned long retrys:2;
	unsigned long detect_short:1;
	unsigned long reserved3:2;

	unsigned long packet_type:8;	// one of in (0x69), out (0xe1) or setup (0x2d)
	unsigned long device_addr:7;
	unsigned long endpoint:4;
	unsigned long data_toggle:1;
	unsigned long reserved:1;
	unsigned long max_transfer:11;	// misnamed. Desired length might be better

	void *buffer;
	unsigned long data[4];	// free use by driver
} __attribute__((packed)) td_t;

typedef struct queue_head {
	link_pointer_t bredth;	// depth must = 0
	link_pointer_t depth;	// depth may vary randomly, ignore
	unsigned long int udata[2];
} __attribute__((packed)) queue_head_t;

typedef struct transaction {
	queue_head_t	*qh;
	td_t		*td_list;
	struct transaction *next;
} transaction_t;

//#####################################################
int wait_head( queue_head_t *head, int count);

extern queue_head_t *free_qh;
extern queue_head_t *queue_heads;

queue_head_t *new_queue_head(void);
void free_queue_head( queue_head_t *qh);
void init_qh(void);

extern td_t *free_td_list;
extern td_t *tds;

void init_td(void);
td_t *new_td(void);
td_t *find_last_td(td_t *td);
void free_td( td_t *td);
link_pointer_t *queue_end( queue_head_t *queue);
void add_td( queue_head_t *head, td_t *td);

extern transaction_t transactions[MAX_TRANSACTIONS];
extern transaction_t *free_transactions;

void init_transactions(void);
void free_transaction( transaction_t *trans );
transaction_t *new_transaction(td_t *td);
transaction_t *add_transaction( transaction_t *trans, td_t *td);


#define USBCMD(x) hc_base[x]
#define USBSTS(x) (hc_base[x] + 0x02)
#define USBINTR(x) (hc_base[x] + 0x04)
#define FRNUM(x) ( hc_base[x] + 0x06)
#define FLBASE(x) ( hc_base[x] + 0x08)
#define SOFMOD(x) ( hc_base[x] + 0x0c)
#define PORTSC1(x) ( hc_base[x] + 0x10)
#define PORTSC2(x) ( hc_base[x] + 0x12)

#define USBCMDRUN 0x01
#define USBCMD_DEBUG 0x20

#define USBSTSHALTED 0x20


void hc_reset(uchar dev);
int hc_stop(void);
int hc_start(uchar dev);

extern queue_head_t *sched_queue[];

void init_sched(uchar dev);
int poll_queue_head( queue_head_t *qh);
int wait_queue_complete( queue_head_t *qh);

extern int num_polls;
extern int (*devpoll[MAX_POLLDEV])(uchar);
extern uchar parm[MAX_POLLDEV];

transaction_t *_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data);
transaction_t *ctrl_msg(uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, uchar *data);
int schedule_transaction( uchar dev, transaction_t *trans);
int wait_transaction( transaction_t *trans);
void unlink_transaction( uchar dev, transaction_t *trans);
int uhci_bulk_transfer( uchar devnum, uchar ep, unsigned int len, uchar *data);
int uhci_control_msg( uchar devnum, uchar request_type, uchar request, unsigned short wValue, unsigned short wIndex, unsigned short wLength, void *data);


// defined in uhci.c
int uhc_init(struct pci_device *dev);
void uhci_init(void);
void clear_uport_stat(unsigned short port);
int poll_u_root_hub(unsigned short port, uchar controller);

#endif