2 BOT Transportation implementation.
4 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "UsbBotPeim.h"
19 #include "PeiUsbLib.h"
22 Reset the given usb device.
24 @param PeiServices The pointer of EFI_PEI_SERVICES.
25 @param PeiBotDev The instance to PEI_BOT_DEVICE.
27 @retval EFI_INVALID_PARAMETER Can not get usb io ppi.
28 @retval EFI_SUCCESS Failed to reset the given usb device.
33 IN EFI_PEI_SERVICES
**PeiServices
,
34 IN PEI_BOT_DEVICE
*PeiBotDev
37 EFI_USB_DEVICE_REQUEST DevReq
;
39 PEI_USB_IO_PPI
*UsbIoPpi
;
43 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
45 if (UsbIoPpi
== NULL
) {
46 return EFI_INVALID_PARAMETER
;
49 ZeroMem (&DevReq
, sizeof (EFI_USB_DEVICE_REQUEST
));
51 DevReq
.RequestType
= 0x21;
52 DevReq
.Request
= 0xFF;
59 Status
= UsbIoPpi
->UsbControlTransfer (
70 // clear bulk in endpoint stall feature
72 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
73 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
76 // clear bulk out endpoint stall feature
78 EndpointAddr
= (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
;
79 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
85 Send the command to the device using Bulk-Out endpoint.
87 This function sends the command to the device using Bulk-Out endpoint.
88 BOT transfer is composed of three phases: Command, Data, and Status.
89 This is the Command phase.
91 @param PeiServices The pointer of EFI_PEI_SERVICES.
92 @param PeiBotDev The instance to PEI_BOT_DEVICE.
93 @param Command The command to transfer to device.
94 @param CommandSize The length of the command.
95 @param DataTransferLength The expected length of the data.
96 @param Direction The direction of the data.
97 @param Timeout Indicates the maximum time, in millisecond, which the
98 transfer is allowed to complete.
100 @retval EFI_DEVICE_ERROR Successful to send the command to device.
101 @retval EFI_SUCCESS Failed to send the command to device.
106 IN EFI_PEI_SERVICES
**PeiServices
,
107 IN PEI_BOT_DEVICE
*PeiBotDev
,
109 IN UINT8 CommandSize
,
110 IN UINT32 DataTransferLength
,
111 IN EFI_USB_DATA_DIRECTION Direction
,
117 PEI_USB_IO_PPI
*UsbIoPpi
;
120 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
122 ZeroMem (&Cbw
, sizeof (CBW
));
125 // Fill the command block, detailed see BOT spec
127 Cbw
.Signature
= CBWSIG
;
129 Cbw
.DataTransferLength
= DataTransferLength
;
130 Cbw
.Flags
= (UINT8
) ((Direction
== EfiUsbDataIn
) ? 0x80 : 0);
132 Cbw
.CmdLen
= CommandSize
;
134 CopyMem (Cbw
.CmdBlock
, Command
, CommandSize
);
136 DataSize
= sizeof (CBW
);
138 Status
= UsbIoPpi
->UsbBulkTransfer (
141 (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
,
146 if (EFI_ERROR (Status
)) {
148 // Command phase fail, we need to recovery reset this device
150 BotRecoveryReset (PeiServices
, PeiBotDev
);
151 return EFI_DEVICE_ERROR
;
158 Transfer the data between the device and host.
160 This function transfers the data between the device and host.
161 BOT transfer is composed of three phases: Command, Data, and Status.
162 This is the Data phase.
164 @param PeiServices The pointer of EFI_PEI_SERVICES.
165 @param PeiBotDev The instance to PEI_BOT_DEVICE.
166 @param DataSize The length of the data.
167 @param DataBuffer The pointer to the data.
168 @param Direction The direction of the data.
169 @param Timeout Indicates the maximum time, in millisecond, which the
170 transfer is allowed to complete.
172 @retval EFI_DEVICE_ERROR Successful to send the data to device.
173 @retval EFI_SUCCESS Failed to send the data to device.
178 IN EFI_PEI_SERVICES
**PeiServices
,
179 IN PEI_BOT_DEVICE
*PeiBotDev
,
181 IN OUT VOID
*DataBuffer
,
182 IN EFI_USB_DATA_DIRECTION Direction
,
187 PEI_USB_IO_PPI
*UsbIoPpi
;
193 UINTN TransferredSize
;
195 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
198 BufferPtr
= (UINT8
*) DataBuffer
;
202 // retrieve the the max packet length of the given endpoint
204 if (Direction
== EfiUsbDataIn
) {
205 MaxPacketLen
= (PeiBotDev
->BulkInEndpoint
)->MaxPacketSize
;
206 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
208 MaxPacketLen
= (PeiBotDev
->BulkOutEndpoint
)->MaxPacketSize
;
209 EndpointAddr
= (PeiBotDev
->BulkOutEndpoint
)->EndpointAddress
;
214 // Using 15 packets to avoid Bitstuff error
216 if (Remain
> 16 * MaxPacketLen
) {
217 Increment
= 16 * MaxPacketLen
;
222 Status
= UsbIoPpi
->UsbBulkTransfer (
231 TransferredSize
+= Increment
;
233 if (EFI_ERROR (Status
)) {
234 PeiUsbClearEndpointHalt (PeiServices
, UsbIoPpi
, EndpointAddr
);
238 BufferPtr
+= Increment
;
242 *DataSize
= (UINT32
) TransferredSize
;
248 Get the command execution status from device.
250 This function gets the command execution status from device.
251 BOT transfer is composed of three phases: Command, Data, and Status.
252 This is the Status phase.
254 @param PeiServices The pointer of EFI_PEI_SERVICES.
255 @param PeiBotDev The instance to PEI_BOT_DEVICE.
256 @param TransferStatus The status of the transaction.
257 @param Timeout Indicates the maximum time, in millisecond, which the
258 transfer is allowed to complete.
260 @retval EFI_DEVICE_ERROR Successful to get the status of device.
261 @retval EFI_SUCCESS Failed to get the status of device.
266 IN EFI_PEI_SERVICES
**PeiServices
,
267 IN PEI_BOT_DEVICE
*PeiBotDev
,
268 OUT UINT8
*TransferStatus
,
274 PEI_USB_IO_PPI
*UsbIoPpi
;
278 UsbIoPpi
= PeiBotDev
->UsbIoPpi
;
280 ZeroMem (&Csw
, sizeof (CSW
));
282 EndpointAddr
= (PeiBotDev
->BulkInEndpoint
)->EndpointAddress
;
284 DataSize
= sizeof (CSW
);
287 // Get the status field from bulk transfer
289 Status
= UsbIoPpi
->UsbBulkTransfer (
297 if (EFI_ERROR (Status
)) {
301 if (Csw
.Signature
== CSWSIG
) {
302 *TransferStatus
= Csw
.Status
;
304 return EFI_DEVICE_ERROR
;
311 Send ATAPI command using BOT protocol.
313 @param PeiServices The pointer of EFI_PEI_SERVICES.
314 @param PeiBotDev The instance to PEI_BOT_DEVICE.
315 @param Command The command to be sent to ATAPI device.
316 @param CommandSize The length of the data to be sent.
317 @param DataBuffer The pointer to the data.
318 @param BufferLength The length of the data.
319 @param Direction The direction of the data.
320 @param TimeOutInMilliSeconds Indicates the maximum time, in millisecond, which the
321 transfer is allowed to complete.
323 @retval EFI_DEVICE_ERROR Successful to get the status of device.
324 @retval EFI_SUCCESS Failed to get the status of device.
329 IN EFI_PEI_SERVICES
**PeiServices
,
330 IN PEI_BOT_DEVICE
*PeiBotDev
,
332 IN UINT8 CommandSize
,
334 IN UINT32 BufferLength
,
335 IN EFI_USB_DATA_DIRECTION Direction
,
336 IN UINT16 TimeOutInMilliSeconds
340 EFI_STATUS BotDataStatus
;
341 UINT8 TransferStatus
;
344 BotDataStatus
= EFI_SUCCESS
;
346 // First send ATAPI command through Bot
348 Status
= BotCommandPhase (
355 TimeOutInMilliSeconds
358 if (EFI_ERROR (Status
)) {
359 return EFI_DEVICE_ERROR
;
362 // Send/Get Data if there is a Data Stage
367 BufferSize
= BufferLength
;
369 BotDataStatus
= BotDataPhase (
375 TimeOutInMilliSeconds
385 Status
= BotStatusPhase (
389 TimeOutInMilliSeconds
391 if (EFI_ERROR (Status
)) {
392 BotRecoveryReset (PeiServices
, PeiBotDev
);
393 return EFI_DEVICE_ERROR
;
396 if (TransferStatus
== 0x01) {
397 return EFI_DEVICE_ERROR
;
400 return BotDataStatus
;