summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h
blob: 9b8aa5de6227273992475d9fc0e7dab310714e5b (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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/** @file
Private Header file for Usb Host Controller PEIM

Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _EFI_EHCI_URB_H_
#define _EFI_EHCI_URB_H_

typedef struct _PEI_EHC_QTD  PEI_EHC_QTD;
typedef struct _PEI_EHC_QH   PEI_EHC_QH;
typedef struct _PEI_URB      PEI_URB;

#define EHC_CTRL_TRANSFER       0x01
#define EHC_BULK_TRANSFER       0x02
#define EHC_INT_TRANSFER_SYNC   0x04
#define EHC_INT_TRANSFER_ASYNC  0x08

#define EHC_QTD_SIG  SIGNATURE_32 ('U', 'S', 'B', 'T')
#define EHC_QH_SIG   SIGNATURE_32 ('U', 'S', 'B', 'H')
#define EHC_URB_SIG  SIGNATURE_32 ('U', 'S', 'B', 'R')

//
// Hardware related bit definitions
//
#define EHC_TYPE_ITD   0x00
#define EHC_TYPE_QH    0x02
#define EHC_TYPE_SITD  0x04
#define EHC_TYPE_FSTN  0x06

#define QH_NAK_RELOAD   3
#define QH_HSHBW_MULTI  1

#define QTD_MAX_ERR     3
#define QTD_PID_OUTPUT  0x00
#define QTD_PID_INPUT   0x01
#define QTD_PID_SETUP   0x02

#define QTD_STAT_DO_OUT      0
#define QTD_STAT_DO_SS       0
#define QTD_STAT_DO_PING     0x01
#define QTD_STAT_DO_CS       0x02
#define QTD_STAT_TRANS_ERR   0x08
#define QTD_STAT_BABBLE_ERR  0x10
#define QTD_STAT_BUFF_ERR    0x20
#define QTD_STAT_HALTED      0x40
#define QTD_STAT_ACTIVE      0x80
#define QTD_STAT_ERR_MASK    (QTD_STAT_TRANS_ERR | QTD_STAT_BABBLE_ERR | QTD_STAT_BUFF_ERR)

#define QTD_MAX_BUFFER  4
#define QTD_BUF_LEN     4096
#define QTD_BUF_MASK    0x0FFF

#define QH_MICROFRAME_0  0x01
#define QH_MICROFRAME_1  0x02
#define QH_MICROFRAME_2  0x04
#define QH_MICROFRAME_3  0x08
#define QH_MICROFRAME_4  0x10
#define QH_MICROFRAME_5  0x20
#define QH_MICROFRAME_6  0x40
#define QH_MICROFRAME_7  0x80

#define USB_ERR_SHORT_PACKET  0x200

//
// Fill in the hardware link point: pass in a EHC_QH/QH_HW
// pointer to QH_LINK; A EHC_QTD/QTD_HW pointer to QTD_LINK
//
#define QH_LINK(Addr, Type, Term) \
          ((UINT32) ((EHC_LOW_32BIT (Addr) & 0xFFFFFFE0) | (Type) | ((Term) ? 1 : 0)))

#define QTD_LINK(Addr, Term)  QH_LINK((Addr), 0, (Term))

//
// The defination of EHCI hardware used data structure for
// little endian architecture. The QTD and QH structures
// are required to be 32 bytes aligned. Don't add members
// to the head of the associated software strucuture.
//
#pragma pack(1)
typedef struct {
  UINT32    NextQtd;
  UINT32    AltNext;

  UINT32    Status     : 8;
  UINT32    Pid        : 2;
  UINT32    ErrCnt     : 2;
  UINT32    CurPage    : 3;
  UINT32    Ioc        : 1;
  UINT32    TotalBytes : 15;
  UINT32    DataToggle : 1;

  UINT32    Page[5];
  UINT32    PageHigh[5];
} QTD_HW;

typedef struct {
  UINT32    HorizonLink;
  //
  // Endpoint capabilities/Characteristics DWord 1 and DWord 2
  //
  UINT32    DeviceAddr   : 7;
  UINT32    Inactive     : 1;
  UINT32    EpNum        : 4;
  UINT32    EpSpeed      : 2;
  UINT32    DtCtrl       : 1;
  UINT32    ReclaimHead  : 1;
  UINT32    MaxPacketLen : 11;
  UINT32    CtrlEp       : 1;
  UINT32    NakReload    : 4;

  UINT32    SMask        : 8;
  UINT32    CMask        : 8;
  UINT32    HubAddr      : 7;
  UINT32    PortNum      : 7;
  UINT32    Multiplier   : 2;

  //
  // Transaction execution overlay area
  //
  UINT32    CurQtd;
  UINT32    NextQtd;
  UINT32    AltQtd;

  UINT32    Status     : 8;
  UINT32    Pid        : 2;
  UINT32    ErrCnt     : 2;
  UINT32    CurPage    : 3;
  UINT32    Ioc        : 1;
  UINT32    TotalBytes : 15;
  UINT32    DataToggle : 1;

  UINT32    Page[5];
  UINT32    PageHigh[5];
} QH_HW;
#pragma pack()

//
// Endpoint address and its capabilities
//
typedef struct _USB_ENDPOINT {
  UINT8                     DevAddr;
  UINT8                     EpAddr;   // Endpoint address, no direction encoded in
  EFI_USB_DATA_DIRECTION    Direction;
  UINT8                     DevSpeed;
  UINTN                     MaxPacket;
  UINT8                     HubAddr;
  UINT8                     HubPort;
  UINT8                     Toggle;   // Data toggle, not used for control transfer
  UINTN                     Type;
  UINTN                     PollRate; // Polling interval used by EHCI
} USB_ENDPOINT;

//
// Software QTD strcture, this is used to manage all the
// QTD generated from a URB. Don't add fields before QtdHw.
//
struct _PEI_EHC_QTD {
  QTD_HW            QtdHw;
  UINT32            Signature;
  EFI_LIST_ENTRY    QtdList;         // The list of QTDs to one end point
  UINT8             *Data;           // Buffer of the original data
  UINTN             DataLen;         // Original amount of data in this QTD
};

//
// Software QH structure. All three different transaction types
// supported by UEFI USB, that is the control/bulk/interrupt
// transfers use the queue head and queue token strcuture.
//
// Interrupt QHs are linked to periodic frame list in the reversed
// 2^N tree. Each interrupt QH is linked to the list starting at
// frame 0. There is a dummy interrupt QH linked to each frame as
// a sentinental whose polling interval is 1. Synchronous interrupt
// transfer is linked after this dummy QH.
//
// For control/bulk transfer, only synchronous (in the sense of UEFI)
// transfer is supported. A dummy QH is linked to EHCI AsyncListAddr
// as the reclamation header. New transfer is inserted after this QH.
//
struct _PEI_EHC_QH {
  QH_HW             QhHw;
  UINT32            Signature;
  PEI_EHC_QH        *NextQh;          // The queue head pointed to by horizontal link
  EFI_LIST_ENTRY    Qtds;             // The list of QTDs to this queue head
  UINTN             Interval;
};

//
// URB (Usb Request Block) contains information for all kinds of
// usb requests.
//
struct _PEI_URB {
  UINT32                             Signature;
  EFI_LIST_ENTRY                     UrbList;

  //
  // Transaction information
  //
  USB_ENDPOINT                       Ep;
  EFI_USB_DEVICE_REQUEST             *Request;    // Control transfer only
  VOID                               *RequestPhy; // Address of the mapped request
  VOID                               *RequestMap;
  VOID                               *Data;
  UINTN                              DataLen;
  VOID                               *DataPhy;  // Address of the mapped user data
  VOID                               *DataMap;
  EFI_ASYNC_USB_TRANSFER_CALLBACK    Callback;
  VOID                               *Context;

  //
  // Schedule data
  //
  PEI_EHC_QH                         *Qh;

  //
  // Transaction result
  //
  UINT32                             Result;
  UINTN                              Completed; // completed data length
  UINT8                              DataToggle;
};

/**
  Delete a single asynchronous interrupt transfer for
  the device and endpoint.

  @param  Ehc         The EHCI device.
  @param  Data        Current data not associated with a QTD.
  @param  DataLen     The length of the data.
  @param  PktId       Packet ID to use in the QTD.
  @param  Toggle      Data toggle to use in the QTD.
  @param  MaxPacket   Maximu packet length of the endpoint.

  @retval the pointer to the created QTD or NULL if failed to create one.

**/
PEI_EHC_QTD *
EhcCreateQtd (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN UINT8            *Data,
  IN UINTN            DataLen,
  IN UINT8            PktId,
  IN UINT8            Toggle,
  IN UINTN            MaxPacket
  )
;

/**
  Allocate and initialize a EHCI queue head.

  @param  Ehci      The EHCI device.
  @param  Ep        The endpoint to create queue head for.

  @retval the pointer to the created queue head or NULL if failed to create one.

**/
PEI_EHC_QH *
EhcCreateQh (
  IN PEI_USB2_HC_DEV  *Ehci,
  IN USB_ENDPOINT     *Ep
  )
;

/**
  Free an allocated URB. It is possible for it to be partially inited.

  @param  Ehc         The EHCI device.
  @param  Urb         The URB to free.

**/
VOID
EhcFreeUrb (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN PEI_URB          *Urb
  )
;

/**
  Create a new URB and its associated QTD.

  @param  Ehc               The EHCI device.
  @param  DevAddr           The device address.
  @param  EpAddr            Endpoint addrress & its direction.
  @param  DevSpeed          The device speed.
  @param  Toggle            Initial data toggle to use.
  @param  MaxPacket         The max packet length of the endpoint.
  @param  Hub               The transaction translator to use.
  @param  Type              The transaction type.
  @param  Request           The standard USB request for control transfer.
  @param  Data              The user data to transfer.
  @param  DataLen           The length of data buffer.
  @param  Callback          The function to call when data is transferred.
  @param  Context           The context to the callback.
  @param  Interval          The interval for interrupt transfer.

  @retval the pointer to the created URB or NULL.

**/
PEI_URB *
EhcCreateUrb (
  IN PEI_USB2_HC_DEV                     *Ehc,
  IN UINT8                               DevAddr,
  IN UINT8                               EpAddr,
  IN UINT8                               DevSpeed,
  IN UINT8                               Toggle,
  IN UINTN                               MaxPacket,
  IN EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Hub,
  IN UINTN                               Type,
  IN EFI_USB_DEVICE_REQUEST              *Request,
  IN VOID                                *Data,
  IN UINTN                               DataLen,
  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     Callback,
  IN VOID                                *Context,
  IN UINTN                               Interval
  )
;

#endif