TianoCore EDK2 master
Loading...
Searching...
No Matches
BotPeim.c
Go to the documentation of this file.
1
10#include "UsbBotPeim.h"
11#include "BotPeim.h"
12#include "PeiUsbLib.h"
13
26 IN EFI_PEI_SERVICES **PeiServices,
27 IN PEI_BOT_DEVICE *PeiBotDev
28 )
29{
31 UINT32 Timeout;
32 PEI_USB_IO_PPI *UsbIoPpi;
33 UINT8 EndpointAddr;
34 EFI_STATUS Status;
35
36 UsbIoPpi = PeiBotDev->UsbIoPpi;
37
38 if (UsbIoPpi == NULL) {
39 return EFI_INVALID_PARAMETER;
40 }
41
42 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
43
44 DevReq.RequestType = 0x21;
45 DevReq.Request = 0xFF;
46 DevReq.Value = 0;
47 DevReq.Index = 0;
48 DevReq.Length = 0;
49
50 Timeout = 3000;
51
52 Status = UsbIoPpi->UsbControlTransfer (
53 PeiServices,
54 UsbIoPpi,
55 &DevReq,
56 EfiUsbNoData,
57 Timeout,
58 NULL,
59 0
60 );
61
62 //
63 // clear bulk in endpoint stall feature
64 //
65 EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
66 PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
67
68 //
69 // clear bulk out endpoint stall feature
70 //
71 EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
72 PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
73
74 return Status;
75}
76
99 IN EFI_PEI_SERVICES **PeiServices,
100 IN PEI_BOT_DEVICE *PeiBotDev,
101 IN VOID *Command,
102 IN UINT8 CommandSize,
103 IN UINT32 DataTransferLength,
104 IN EFI_USB_DATA_DIRECTION Direction,
105 IN UINT16 Timeout
106 )
107{
108 CBW Cbw;
109 EFI_STATUS Status;
110 PEI_USB_IO_PPI *UsbIoPpi;
111 UINTN DataSize;
112
113 UsbIoPpi = PeiBotDev->UsbIoPpi;
114
115 ZeroMem (&Cbw, sizeof (CBW));
116
117 //
118 // Fill the command block, detailed see BOT spec
119 //
120 Cbw.Signature = CBWSIG;
121 Cbw.Tag = 0x01;
122 Cbw.DataTransferLength = DataTransferLength;
123 Cbw.Flags = (UINT8)((Direction == EfiUsbDataIn) ? 0x80 : 0);
124 Cbw.Lun = 0;
125 Cbw.CmdLen = CommandSize;
126
127 CopyMem (Cbw.CmdBlock, Command, CommandSize);
128
129 DataSize = sizeof (CBW);
130
131 Status = UsbIoPpi->UsbBulkTransfer (
132 PeiServices,
133 UsbIoPpi,
134 (PeiBotDev->BulkOutEndpoint)->EndpointAddress,
135 (UINT8 *)&Cbw,
136 &DataSize,
137 Timeout
138 );
139 if (EFI_ERROR (Status)) {
140 //
141 // Command phase fail, we need to recovery reset this device
142 //
143 BotRecoveryReset (PeiServices, PeiBotDev);
144 return EFI_DEVICE_ERROR;
145 }
146
147 return EFI_SUCCESS;
148}
149
171 IN EFI_PEI_SERVICES **PeiServices,
172 IN PEI_BOT_DEVICE *PeiBotDev,
173 IN UINT32 *DataSize,
174 IN OUT VOID *DataBuffer,
175 IN EFI_USB_DATA_DIRECTION Direction,
176 IN UINT16 Timeout
177 )
178{
179 EFI_STATUS Status;
180 PEI_USB_IO_PPI *UsbIoPpi;
181 UINT8 EndpointAddr;
182 UINTN Remain;
183 UINTN Increment;
184 UINT32 MaxPacketLen;
185 UINT8 *BufferPtr;
186 UINTN TransferredSize;
187
188 UsbIoPpi = PeiBotDev->UsbIoPpi;
189
190 Remain = *DataSize;
191 BufferPtr = (UINT8 *)DataBuffer;
192 TransferredSize = 0;
193
194 //
195 // retrieve the max packet length of the given endpoint
196 //
197 if (Direction == EfiUsbDataIn) {
198 MaxPacketLen = (PeiBotDev->BulkInEndpoint)->MaxPacketSize;
199 EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
200 } else {
201 MaxPacketLen = (PeiBotDev->BulkOutEndpoint)->MaxPacketSize;
202 EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
203 }
204
205 while (Remain > 0) {
206 //
207 // Using 15 packets to avoid Bitstuff error
208 //
209 if (Remain > 16 * MaxPacketLen) {
210 Increment = 16 * MaxPacketLen;
211 } else {
212 Increment = Remain;
213 }
214
215 Status = UsbIoPpi->UsbBulkTransfer (
216 PeiServices,
217 UsbIoPpi,
218 EndpointAddr,
219 BufferPtr,
220 &Increment,
221 Timeout
222 );
223
224 TransferredSize += Increment;
225
226 if (EFI_ERROR (Status)) {
227 PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
228 return Status;
229 }
230
231 BufferPtr += Increment;
232 Remain -= Increment;
233 }
234
235 *DataSize = (UINT32)TransferredSize;
236
237 return EFI_SUCCESS;
238}
239
259 IN EFI_PEI_SERVICES **PeiServices,
260 IN PEI_BOT_DEVICE *PeiBotDev,
261 OUT UINT8 *TransferStatus,
262 IN UINT16 Timeout
263 )
264{
265 CSW Csw;
266 EFI_STATUS Status;
267 PEI_USB_IO_PPI *UsbIoPpi;
268 UINT8 EndpointAddr;
269 UINTN DataSize;
270
271 UsbIoPpi = PeiBotDev->UsbIoPpi;
272
273 ZeroMem (&Csw, sizeof (CSW));
274
275 EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
276
277 DataSize = sizeof (CSW);
278
279 //
280 // Get the status field from bulk transfer
281 //
282 Status = UsbIoPpi->UsbBulkTransfer (
283 PeiServices,
284 UsbIoPpi,
285 EndpointAddr,
286 &Csw,
287 &DataSize,
288 Timeout
289 );
290 if (EFI_ERROR (Status)) {
291 return Status;
292 }
293
294 if (Csw.Signature == CSWSIG) {
295 *TransferStatus = Csw.Status;
296 } else {
297 return EFI_DEVICE_ERROR;
298 }
299
300 return EFI_SUCCESS;
301}
302
322 IN EFI_PEI_SERVICES **PeiServices,
323 IN PEI_BOT_DEVICE *PeiBotDev,
324 IN VOID *Command,
325 IN UINT8 CommandSize,
326 IN VOID *DataBuffer,
327 IN UINT32 BufferLength,
328 IN EFI_USB_DATA_DIRECTION Direction,
329 IN UINT16 TimeOutInMilliSeconds
330 )
331{
332 EFI_STATUS Status;
333 EFI_STATUS BotDataStatus;
334 UINT8 TransferStatus;
335 UINT32 BufferSize;
336
337 BotDataStatus = EFI_SUCCESS;
338 //
339 // First send ATAPI command through Bot
340 //
341 Status = BotCommandPhase (
342 PeiServices,
343 PeiBotDev,
344 Command,
345 CommandSize,
346 BufferLength,
347 Direction,
348 TimeOutInMilliSeconds
349 );
350
351 if (EFI_ERROR (Status)) {
352 return EFI_DEVICE_ERROR;
353 }
354
355 //
356 // Send/Get Data if there is a Data Stage
357 //
358 switch (Direction) {
359 case EfiUsbDataIn:
360 case EfiUsbDataOut:
361 BufferSize = BufferLength;
362
363 BotDataStatus = BotDataPhase (
364 PeiServices,
365 PeiBotDev,
366 &BufferSize,
367 DataBuffer,
368 Direction,
369 TimeOutInMilliSeconds
370 );
371 break;
372
373 case EfiUsbNoData:
374 break;
375 }
376
377 //
378 // Status Phase
379 //
380 Status = BotStatusPhase (
381 PeiServices,
382 PeiBotDev,
383 &TransferStatus,
384 TimeOutInMilliSeconds
385 );
386 if (EFI_ERROR (Status)) {
387 BotRecoveryReset (PeiServices, PeiBotDev);
388 return EFI_DEVICE_ERROR;
389 }
390
391 if (TransferStatus == 0x01) {
392 return EFI_DEVICE_ERROR;
393 }
394
395 return BotDataStatus;
396}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS BotStatusPhase(IN EFI_PEI_SERVICES **PeiServices, IN PEI_BOT_DEVICE *PeiBotDev, OUT UINT8 *TransferStatus, IN UINT16 Timeout)
Definition: BotPeim.c:258
EFI_STATUS BotCommandPhase(IN EFI_PEI_SERVICES **PeiServices, IN PEI_BOT_DEVICE *PeiBotDev, IN VOID *Command, IN UINT8 CommandSize, IN UINT32 DataTransferLength, IN EFI_USB_DATA_DIRECTION Direction, IN UINT16 Timeout)
Definition: BotPeim.c:98
EFI_STATUS BotDataPhase(IN EFI_PEI_SERVICES **PeiServices, IN PEI_BOT_DEVICE *PeiBotDev, IN UINT32 *DataSize, IN OUT VOID *DataBuffer, IN EFI_USB_DATA_DIRECTION Direction, IN UINT16 Timeout)
Definition: BotPeim.c:170
EFI_STATUS BotRecoveryReset(IN EFI_PEI_SERVICES **PeiServices, IN PEI_BOT_DEVICE *PeiBotDev)
Definition: BotPeim.c:25
EFI_STATUS PeiAtapiCommand(IN EFI_PEI_SERVICES **PeiServices, IN PEI_BOT_DEVICE *PeiBotDev, IN VOID *Command, IN UINT8 CommandSize, IN VOID *DataBuffer, IN UINT32 BufferLength, IN EFI_USB_DATA_DIRECTION Direction, IN UINT16 TimeOutInMilliSeconds)
Definition: BotPeim.c:321
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
EFI_USB_DATA_DIRECTION
Definition: UsbIo.h:44
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS PeiUsbClearEndpointHalt(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 EndpointAddress)
Definition: PeiUsbLib.c:83
Definition: BotPeim.h:30
Definition: BotPeim.h:40