2 BOT Transportation implementation.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "UsbBotPeim.h"
12 #include "PeiUsbLib.h"
15 Reset the given usb device.
17 @param PeiServices The pointer of EFI_PEI_SERVICES.
18 @param PeiBotDev The instance to PEI_BOT_DEVICE.
20 @retval EFI_INVALID_PARAMETER Can not get usb io ppi.
21 @retval EFI_SUCCESS Failed to reset the given usb device.
26 IN EFI_PEI_SERVICES
**PeiServices
,
27 IN PEI_BOT_DEVICE
*PeiBotDev
30 EFI_USB_DEVICE_REQUEST DevReq
;
32 PEI_USB_IO_PPI
*UsbIoPpi
;
36 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
38 if (UsbIoPpi
== NULL
) {
39 return EFI_INVALID_PARAMETER
;
42 ZeroMem (&DevReq
, sizeof (EFI_USB_DEVICE_REQUEST
));
44 DevReq
.RequestType
= 0x21;
45 DevReq
.Request
= 0xFF;
52 Status
= UsbIoPpi
->UsbControlTransfer (
63 // clear bulk in endpoint stall feature
65 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
66 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
69 // clear bulk out endpoint stall feature
71 EndpointAddr
= (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
;
72 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
78 Send the command to the device using Bulk-Out endpoint.
80 This function sends the command to the device using Bulk-Out endpoint.
81 BOT transfer is composed of three phases: Command, Data, and Status.
82 This is the Command phase.
84 @param PeiServices The pointer of EFI_PEI_SERVICES.
85 @param PeiBotDev The instance to PEI_BOT_DEVICE.
86 @param Command The command to transfer to device.
87 @param CommandSize The length of the command.
88 @param DataTransferLength The expected length of the data.
89 @param Direction The direction of the data.
90 @param Timeout Indicates the maximum time, in millisecond, which the
91 transfer is allowed to complete.
93 @retval EFI_DEVICE_ERROR Successful to send the command to device.
94 @retval EFI_SUCCESS Failed to send the command to device.
99 IN EFI_PEI_SERVICES
**PeiServices
,
100 IN PEI_BOT_DEVICE
*PeiBotDev
,
102 IN UINT8 CommandSize
,
103 IN UINT32 DataTransferLength
,
104 IN EFI_USB_DATA_DIRECTION Direction
,
110 PEI_USB_IO_PPI
*UsbIoPpi
;
113 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
115 ZeroMem (&Cbw
, sizeof (CBW
));
118 // Fill the command block, detailed see BOT spec
120 Cbw
.Signature
= CBWSIG
;
122 Cbw
.DataTransferLength
= DataTransferLength
;
123 Cbw
.Flags
= (UINT8
) ((Direction
== EfiUsbDataIn
) ? 0x80 : 0);
125 Cbw
.CmdLen
= CommandSize
;
127 CopyMem (Cbw
.CmdBlock
, Command
, CommandSize
);
129 DataSize
= sizeof (CBW
);
131 Status
= UsbIoPpi
->UsbBulkTransfer (
134 (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
,
139 if (EFI_ERROR (Status
)) {
141 // Command phase fail, we need to recovery reset this device
143 BotRecoveryReset (PeiServices
, PeiBotDev
);
144 return EFI_DEVICE_ERROR
;
151 Transfer the data between the device and host.
153 This function transfers the data between the device and host.
154 BOT transfer is composed of three phases: Command, Data, and Status.
155 This is the Data phase.
157 @param PeiServices The pointer of EFI_PEI_SERVICES.
158 @param PeiBotDev The instance to PEI_BOT_DEVICE.
159 @param DataSize The length of the data.
160 @param DataBuffer The pointer to the data.
161 @param Direction The direction of the data.
162 @param Timeout Indicates the maximum time, in millisecond, which the
163 transfer is allowed to complete.
165 @retval EFI_DEVICE_ERROR Successful to send the data to device.
166 @retval EFI_SUCCESS Failed to send the data to device.
171 IN EFI_PEI_SERVICES
**PeiServices
,
172 IN PEI_BOT_DEVICE
*PeiBotDev
,
174 IN OUT VOID
*DataBuffer
,
175 IN EFI_USB_DATA_DIRECTION Direction
,
180 PEI_USB_IO_PPI
*UsbIoPpi
;
186 UINTN TransferredSize
;
188 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
191 BufferPtr
= (UINT8
*) DataBuffer
;
195 // retrieve the the max packet length of the given endpoint
197 if (Direction
== EfiUsbDataIn
) {
198 MaxPacketLen
= (PeiBotDev
->BulkInEndpoint
)->MaxPacketSize
;
199 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
201 MaxPacketLen
= (PeiBotDev
->BulkOutEndpoint
)->MaxPacketSize
;
202 EndpointAddr
= (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
;
207 // Using 15 packets to avoid Bitstuff error
209 if (Remain
> 16 * MaxPacketLen
) {
210 Increment
= 16 * MaxPacketLen
;
215 Status
= UsbIoPpi
->UsbBulkTransfer (
224 TransferredSize
+= Increment
;
226 if (EFI_ERROR (Status
)) {
227 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
231 BufferPtr
+= Increment
;
235 *DataSize
= (UINT32
) TransferredSize
;
241 Get the command execution status from device.
243 This function gets the command execution status from device.
244 BOT transfer is composed of three phases: Command, Data, and Status.
245 This is the Status phase.
247 @param PeiServices The pointer of EFI_PEI_SERVICES.
248 @param PeiBotDev The instance to PEI_BOT_DEVICE.
249 @param TransferStatus The status of the transaction.
250 @param Timeout Indicates the maximum time, in millisecond, which the
251 transfer is allowed to complete.
253 @retval EFI_DEVICE_ERROR Successful to get the status of device.
254 @retval EFI_SUCCESS Failed to get the status of device.
259 IN EFI_PEI_SERVICES
**PeiServices
,
260 IN PEI_BOT_DEVICE
*PeiBotDev
,
261 OUT UINT8
*TransferStatus
,
267 PEI_USB_IO_PPI
*UsbIoPpi
;
271 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
273 ZeroMem (&Csw
, sizeof (CSW
));
275 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
277 DataSize
= sizeof (CSW
);
280 // Get the status field from bulk transfer
282 Status
= UsbIoPpi
->UsbBulkTransfer (
290 if (EFI_ERROR (Status
)) {
294 if (Csw
.Signature
== CSWSIG
) {
295 *TransferStatus
= Csw
.Status
;
297 return EFI_DEVICE_ERROR
;
304 Send ATAPI command using BOT protocol.
306 @param PeiServices The pointer of EFI_PEI_SERVICES.
307 @param PeiBotDev The instance to PEI_BOT_DEVICE.
308 @param Command The command to be sent to ATAPI device.
309 @param CommandSize The length of the data to be sent.
310 @param DataBuffer The pointer to the data.
311 @param BufferLength The length of the data.
312 @param Direction The direction of the data.
313 @param TimeOutInMilliSeconds Indicates the maximum time, in millisecond, which the
314 transfer is allowed to complete.
316 @retval EFI_DEVICE_ERROR Successful to get the status of device.
317 @retval EFI_SUCCESS Failed to get the status of device.
322 IN EFI_PEI_SERVICES
**PeiServices
,
323 IN PEI_BOT_DEVICE
*PeiBotDev
,
325 IN UINT8 CommandSize
,
327 IN UINT32 BufferLength
,
328 IN EFI_USB_DATA_DIRECTION Direction
,
329 IN UINT16 TimeOutInMilliSeconds
333 EFI_STATUS BotDataStatus
;
334 UINT8 TransferStatus
;
337 BotDataStatus
= EFI_SUCCESS
;
339 // First send ATAPI command through Bot
341 Status
= BotCommandPhase (
348 TimeOutInMilliSeconds
351 if (EFI_ERROR (Status
)) {
352 return EFI_DEVICE_ERROR
;
355 // Send/Get Data if there is a Data Stage
360 BufferSize
= BufferLength
;
362 BotDataStatus
= BotDataPhase (
368 TimeOutInMilliSeconds
378 Status
= BotStatusPhase (
382 TimeOutInMilliSeconds
384 if (EFI_ERROR (Status
)) {
385 BotRecoveryReset (PeiServices
, PeiBotDev
);
386 return EFI_DEVICE_ERROR
;
389 if (TransferStatus
== 0x01) {
390 return EFI_DEVICE_ERROR
;
393 return BotDataStatus
;