summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h
blob: 7cae215adb1d71764df8853464fc2c9e9657c917 (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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/** @file

    This file contains URB request, each request is warpped in a
    URB (Usb Request Block).

Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#ifndef _EFI_EHCI_URB_H_
#define _EFI_EHCI_URB_H_


typedef struct _EHC_QTD  EHC_QTD;
typedef struct _EHC_QH   EHC_QH;
typedef struct _URB      URB;

typedef enum {
  //
  // Transfer types, used in URB to identify the transfer type
  //
  EHC_CTRL_TRANSFER       = 0x01,
  EHC_BULK_TRANSFER       = 0x02,
  EHC_INT_TRANSFER_SYNC   = 0x04,
  EHC_INT_TRANSFER_ASYNC  = 0x08,

  EHC_QTD_SIG             = EFI_SIGNATURE_32 ('U', 'S', 'B', 'T'),
  EHC_QH_SIG              = EFI_SIGNATURE_32 ('U', 'S', 'B', 'H'),
  EHC_URB_SIG             = EFI_SIGNATURE_32 ('U', 'S', 'B', 'R'),

  //
  // Hardware related bit definitions
  //
  EHC_TYPE_ITD            = 0x00,
  EHC_TYPE_QH             = 0x02,
  EHC_TYPE_SITD           = 0x04,
  EHC_TYPE_FSTN           = 0x06,

  QH_NAK_RELOAD           = 3,
  QH_HSHBW_MULTI          = 1,

  QTD_MAX_ERR             = 3,
  QTD_PID_OUTPUT          = 0x00,
  QTD_PID_INPUT           = 0x01,
  QTD_PID_SETUP           = 0x02,

  QTD_STAT_DO_OUT         = 0,
  QTD_STAT_DO_SS          = 0,
  QTD_STAT_DO_PING        = 0x01,
  QTD_STAT_DO_CS          = 0x02,
  QTD_STAT_TRANS_ERR      = 0x08,
  QTD_STAT_BABBLE_ERR     = 0x10,
  QTD_STAT_BUFF_ERR       = 0x20,
  QTD_STAT_HALTED         = 0x40,
  QTD_STAT_ACTIVE         = 0x80,
  QTD_STAT_ERR_MASK       = QTD_STAT_TRANS_ERR | QTD_STAT_BABBLE_ERR | QTD_STAT_BUFF_ERR,

  QTD_MAX_BUFFER          = 4,
  QTD_BUF_LEN             = 4096,
  QTD_BUF_MASK            = 0x0FFF,

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

  USB_ERR_SHORT_PACKET    = 0x200
}EHCI_URB_FLAG_VALUE;

//
// 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 _EHC_QTD {
  QTD_HW                  QtdHw;
  UINT32                  Signature;
  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 _EHC_QH {
  QH_HW                   QhHw;
  UINT32                  Signature;
  EHC_QH                  *NextQh;    // The queue head pointed to by horizontal link
  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 _URB {
  UINT32                          Signature;
  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
  //
  EHC_QH                          *Qh;

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



/**
  Create a single QTD to hold the data.

  @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.

  @return Created QTD or NULL if failed to create one.

**/
EHC_QTD *
EhcCreateQtd (
  IN 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.

  @return Created queue head or NULL if failed to create one.

**/
EHC_QH *
EhcCreateQh (
  IN 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.

  @return None.

**/
VOID
EhcFreeUrb (
  IN USB2_HC_DEV          *Ehc,
  IN 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.

  @return Created URB or NULL.

**/
URB *
EhcCreateUrb (
  IN 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