1 /** @file
2 Usb BOT Peim definition.
3 
4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
5 
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
11 
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.
14 
15 **/
16 
17 #ifndef _PEI_USB_BOT_PEIM_H_
18 #define _PEI_USB_BOT_PEIM_H_
19 
20 #include <PiPei.h>
21 
22 #include <Ppi/UsbIo.h>
23 #include <Ppi/UsbHostController.h>
24 #include <Ppi/BlockIo.h>
25 #include <Ppi/BlockIo2.h>
26 
27 #include <Library/DebugLib.h>
28 
29 #include <IndustryStandard/Usb.h>
30 #include <IndustryStandard/Atapi.h>
31 
32 #define PEI_FAT_MAX_USB_IO_PPI  127
33 
34 /**
35   Gets the count of block I/O devices that one specific block driver detects.
36 
37   This function is used for getting the count of block I/O devices that one
38   specific block driver detects.  To the PEI ATAPI driver, it returns the number
39   of all the detected ATAPI devices it detects during the enumeration process.
40   To the PEI legacy floppy driver, it returns the number of all the legacy
41   devices it finds during its enumeration process. If no device is detected,
42   then the function will return zero.
43 
44   @param[in]  PeiServices          General-purpose services that are available
45                                    to every PEIM.
46   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
47                                    instance.
48   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
49 
50   @retval     EFI_SUCCESS          Operation performed successfully.
51 
52 **/
53 EFI_STATUS
54 EFIAPI
55 BotGetNumberOfBlockDevices (
56   IN  EFI_PEI_SERVICES                         **PeiServices,
57   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI            *This,
58   OUT UINTN                                    *NumberBlockDevices
59   );
60 
61 /**
62   Gets a block device's media information.
63 
64   This function will provide the caller with the specified block device's media
65   information. If the media changes, calling this function will update the media
66   information accordingly.
67 
68   @param[in]  PeiServices   General-purpose services that are available to every
69                             PEIM
70   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
71   @param[in]  DeviceIndex   Specifies the block device to which the function wants
72                             to talk. Because the driver that implements Block I/O
73                             PPIs will manage multiple block devices, the PPIs that
74                             want to talk to a single device must specify the
75                             device index that was assigned during the enumeration
76                             process. This index is a number from one to
77                             NumberBlockDevices.
78   @param[out] MediaInfo     The media information of the specified block media.
79                             The caller is responsible for the ownership of this
80                             data structure.
81 
82   @retval EFI_SUCCESS        Media information about the specified block device
83                              was obtained successfully.
84   @retval EFI_DEVICE_ERROR   Cannot get the media information due to a hardware
85                              error.
86 
87 **/
88 EFI_STATUS
89 EFIAPI
90 BotGetMediaInfo (
91   IN  EFI_PEI_SERVICES                          **PeiServices,
92   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI             *This,
93   IN  UINTN                                     DeviceIndex,
94   OUT EFI_PEI_BLOCK_IO_MEDIA                    *MediaInfo
95   );
96 
97 /**
98   Reads the requested number of blocks from the specified block device.
99 
100   The function reads the requested number of blocks from the device. All the
101   blocks are read, or an error is returned. If there is no media in the device,
102   the function returns EFI_NO_MEDIA.
103 
104   @param[in]  PeiServices   General-purpose services that are available to
105                             every PEIM.
106   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
107   @param[in]  DeviceIndex   Specifies the block device to which the function wants
108                             to talk. Because the driver that implements Block I/O
109                             PPIs will manage multiple block devices, the PPIs that
110                             want to talk to a single device must specify the device
111                             index that was assigned during the enumeration process.
112                             This index is a number from one to NumberBlockDevices.
113   @param[in]  StartLBA      The starting logical block address (LBA) to read from
114                             on the device
115   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
116                             a multiple of the intrinsic block size of the device.
117   @param[out] Buffer        A pointer to the destination buffer for the data.
118                             The caller is responsible for the ownership of the
119                             buffer.
120 
121   @retval EFI_SUCCESS             The data was read correctly from the device.
122   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
123                                   to perform the read operation.
124   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
125                                   valid, or the buffer is not properly aligned.
126   @retval EFI_NO_MEDIA            There is no media in the device.
127   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
128                                   the intrinsic block size of the device.
129 
130 **/
131 EFI_STATUS
132 EFIAPI
133 BotReadBlocks (
134   IN  EFI_PEI_SERVICES                          **PeiServices,
135   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI             *This,
136   IN  UINTN                                     DeviceIndex,
137   IN  EFI_PEI_LBA                               StartLBA,
138   IN  UINTN                                     BufferSize,
139   OUT VOID                                      *Buffer
140   );
141 
142 /**
143   Gets the count of block I/O devices that one specific block driver detects.
144 
145   This function is used for getting the count of block I/O devices that one
146   specific block driver detects.  To the PEI ATAPI driver, it returns the number
147   of all the detected ATAPI devices it detects during the enumeration process.
148   To the PEI legacy floppy driver, it returns the number of all the legacy
149   devices it finds during its enumeration process. If no device is detected,
150   then the function will return zero.
151 
152   @param[in]  PeiServices          General-purpose services that are available
153                                    to every PEIM.
154   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
155                                    instance.
156   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
157 
158   @retval     EFI_SUCCESS          Operation performed successfully.
159 
160 **/
161 EFI_STATUS
162 EFIAPI
163 BotGetNumberOfBlockDevices2 (
164   IN  EFI_PEI_SERVICES                         **PeiServices,
165   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI           *This,
166   OUT UINTN                                    *NumberBlockDevices
167   );
168 
169 /**
170   Gets a block device's media information.
171 
172   This function will provide the caller with the specified block device's media
173   information. If the media changes, calling this function will update the media
174   information accordingly.
175 
176   @param[in]  PeiServices   General-purpose services that are available to every
177                             PEIM
178   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
179   @param[in]  DeviceIndex   Specifies the block device to which the function wants
180                             to talk. Because the driver that implements Block I/O
181                             PPIs will manage multiple block devices, the PPIs that
182                             want to talk to a single device must specify the
183                             device index that was assigned during the enumeration
184                             process. This index is a number from one to
185                             NumberBlockDevices.
186   @param[out] MediaInfo     The media information of the specified block media.
187                             The caller is responsible for the ownership of this
188                             data structure.
189 
190   @retval EFI_SUCCESS        Media information about the specified block device
191                              was obtained successfully.
192   @retval EFI_DEVICE_ERROR   Cannot get the media information due to a hardware
193                              error.
194 
195 **/
196 EFI_STATUS
197 EFIAPI
198 BotGetMediaInfo2 (
199   IN  EFI_PEI_SERVICES                          **PeiServices,
200   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI            *This,
201   IN  UINTN                                     DeviceIndex,
202   OUT EFI_PEI_BLOCK_IO2_MEDIA                   *MediaInfo
203   );
204 
205 /**
206   Reads the requested number of blocks from the specified block device.
207 
208   The function reads the requested number of blocks from the device. All the
209   blocks are read, or an error is returned. If there is no media in the device,
210   the function returns EFI_NO_MEDIA.
211 
212   @param[in]  PeiServices   General-purpose services that are available to
213                             every PEIM.
214   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
215   @param[in]  DeviceIndex   Specifies the block device to which the function wants
216                             to talk. Because the driver that implements Block I/O
217                             PPIs will manage multiple block devices, the PPIs that
218                             want to talk to a single device must specify the device
219                             index that was assigned during the enumeration process.
220                             This index is a number from one to NumberBlockDevices.
221   @param[in]  StartLBA      The starting logical block address (LBA) to read from
222                             on the device
223   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
224                             a multiple of the intrinsic block size of the device.
225   @param[out] Buffer        A pointer to the destination buffer for the data.
226                             The caller is responsible for the ownership of the
227                             buffer.
228 
229   @retval EFI_SUCCESS             The data was read correctly from the device.
230   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
231                                   to perform the read operation.
232   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
233                                   valid, or the buffer is not properly aligned.
234   @retval EFI_NO_MEDIA            There is no media in the device.
235   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
236                                   the intrinsic block size of the device.
237 
238 **/
239 EFI_STATUS
240 EFIAPI
241 BotReadBlocks2 (
242   IN  EFI_PEI_SERVICES                          **PeiServices,
243   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI            *This,
244   IN  UINTN                                     DeviceIndex,
245   IN  EFI_PEI_LBA                               StartLBA,
246   IN  UINTN                                     BufferSize,
247   OUT VOID                                      *Buffer
248   );
249 
250 /**
251   UsbIo installation notification function.
252 
253   This function finds out all the current USB IO PPIs in the system and add them
254   into private data.
255 
256   @param  PeiServices      Indirect reference to the PEI Services Table.
257   @param  NotifyDesc       Address of the notification descriptor data structure.
258   @param  InvokePpi        Address of the PPI that was invoked.
259 
260   @retval EFI_SUCCESS      The function completes successfully.
261 
262 **/
263 EFI_STATUS
264 EFIAPI
265 NotifyOnUsbIoPpi (
266   IN  EFI_PEI_SERVICES                              **PeiServices,
267   IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,
268   IN  VOID                                          *InvokePpi
269   );
270 
271 /**
272   Initialize the usb bot device.
273 
274   @param[in]  PeiServices   General-purpose services that are available to every
275                             PEIM.
276   @param[in]  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
277 
278   @retval EFI_SUCCESS       The usb bot device is initialized successfully.
279   @retval Other             Failed to initialize media.
280 
281 **/
282 EFI_STATUS
283 InitUsbBot (
284   IN  EFI_PEI_SERVICES                          **PeiServices,
285   IN  PEI_USB_IO_PPI                            *UsbIoPpi
286   );
287 
288 #define USBCDROM    1 // let the device type value equal to USBCDROM, which is defined by PI spec.
289                       // Therefore the CdExpressPei module can do recovery on UsbCdrom.
290 #define USBFLOPPY   2 // for those that use ReadCapacity(0x25) command to retrieve media capacity
291 #define USBFLOPPY2  3 // for those that use ReadFormatCapacity(0x23) command to retrieve media capacity
292 
293 //
294 // Bot device structure
295 //
296 #define PEI_BOT_DEVICE_SIGNATURE  SIGNATURE_32 ('U', 'B', 'O', 'T')
297 typedef struct {
298   UINTN                           Signature;
299   EFI_PEI_RECOVERY_BLOCK_IO_PPI   BlkIoPpi;
300   EFI_PEI_RECOVERY_BLOCK_IO2_PPI  BlkIo2Ppi;
301   EFI_PEI_PPI_DESCRIPTOR          BlkIoPpiList;
302   EFI_PEI_PPI_DESCRIPTOR          BlkIo2PpiList;
303   EFI_PEI_BLOCK_IO_MEDIA          Media;
304   EFI_PEI_BLOCK_IO2_MEDIA         Media2;
305   PEI_USB_IO_PPI                  *UsbIoPpi;
306   EFI_USB_INTERFACE_DESCRIPTOR    *BotInterface;
307   EFI_USB_ENDPOINT_DESCRIPTOR     *BulkInEndpoint;
308   EFI_USB_ENDPOINT_DESCRIPTOR     *BulkOutEndpoint;
309   UINTN                           AllocateAddress;
310   UINTN                           DeviceType;
311   ATAPI_REQUEST_SENSE_DATA        *SensePtr;
312 } PEI_BOT_DEVICE;
313 
314 #define PEI_BOT_DEVICE_FROM_THIS(a) CR (a, PEI_BOT_DEVICE, BlkIoPpi, PEI_BOT_DEVICE_SIGNATURE)
315 #define PEI_BOT_DEVICE2_FROM_THIS(a) CR (a, PEI_BOT_DEVICE, BlkIo2Ppi, PEI_BOT_DEVICE_SIGNATURE)
316 
317 /**
318   Send ATAPI command using BOT protocol.
319 
320   @param  PeiServices            The pointer of EFI_PEI_SERVICES.
321   @param  PeiBotDev              The instance to PEI_BOT_DEVICE.
322   @param  Command                The command to be sent to ATAPI device.
323   @param  CommandSize            The length of the data to be sent.
324   @param  DataBuffer             The pointer to the data.
325   @param  BufferLength           The length of the data.
326   @param  Direction              The direction of the data.
327   @param  TimeOutInMilliSeconds  Indicates the maximum time, in millisecond, which the
328                                  transfer is allowed to complete.
329 
330   @retval EFI_DEVICE_ERROR       Successful to get the status of device.
331   @retval EFI_SUCCESS            Failed to get the status of device.
332 
333 **/
334 EFI_STATUS
335 PeiAtapiCommand (
336   IN  EFI_PEI_SERVICES            **PeiServices,
337   IN  PEI_BOT_DEVICE              *PeiBotDev,
338   IN  VOID                        *Command,
339   IN  UINT8                       CommandSize,
340   IN  VOID                        *DataBuffer,
341   IN  UINT32                      BufferLength,
342   IN  EFI_USB_DATA_DIRECTION      Direction,
343   IN  UINT16                      TimeOutInMilliSeconds
344   );
345 
346 #endif
347