1 /** @file
2   Partition driver that produces logical BlockIo devices from a physical
3   BlockIo device. The logical BlockIo devices are based on the format
4   of the raw block devices media. Currently "El Torito CD-ROM", Legacy
5   MBR, and GPT partition schemes are supported.
6 
7 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution.  The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12 
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 
16 **/
17 
18 #ifndef _PARTITION_H_
19 #define _PARTITION_H_
20 
21 #include <Uefi.h>
22 #include <Protocol/BlockIo.h>
23 #include <Protocol/BlockIo2.h>
24 #include <Guid/Gpt.h>
25 #include <Protocol/ComponentName.h>
26 #include <Protocol/DevicePath.h>
27 #include <Protocol/DriverBinding.h>
28 #include <Protocol/DiskIo.h>
29 #include <Protocol/DiskIo2.h>
30 #include <Library/DebugLib.h>
31 #include <Library/UefiDriverEntryPoint.h>
32 #include <Library/BaseLib.h>
33 #include <Library/UefiLib.h>
34 #include <Library/BaseMemoryLib.h>
35 #include <Library/MemoryAllocationLib.h>
36 #include <Library/UefiBootServicesTableLib.h>
37 #include <Library/DevicePathLib.h>
38 
39 #include <IndustryStandard/Mbr.h>
40 #include <IndustryStandard/ElTorito.h>
41 
42 
43 //
44 // Partition private data
45 //
46 #define PARTITION_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('P', 'a', 'r', 't')
47 typedef struct {
48   UINT64                    Signature;
49 
50   EFI_HANDLE                Handle;
51   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
52   EFI_BLOCK_IO_PROTOCOL     BlockIo;
53   EFI_BLOCK_IO2_PROTOCOL    BlockIo2;
54   EFI_BLOCK_IO_MEDIA        Media;
55   EFI_BLOCK_IO_MEDIA        Media2;//For BlockIO2
56 
57   EFI_DISK_IO_PROTOCOL      *DiskIo;
58   EFI_DISK_IO2_PROTOCOL     *DiskIo2;
59   EFI_BLOCK_IO_PROTOCOL     *ParentBlockIo;
60   EFI_BLOCK_IO2_PROTOCOL    *ParentBlockIo2;
61   UINT64                    Start;
62   UINT64                    End;
63   UINT32                    BlockSize;
64 
65   EFI_GUID                  *EspGuid;
66 
67 } PARTITION_PRIVATE_DATA;
68 
69 typedef struct {
70   EFI_DISK_IO2_TOKEN           DiskIo2Token;
71   EFI_BLOCK_IO2_TOKEN          *BlockIo2Token;
72 } PARTITION_ACCESS_TASK;
73 
74 #define PARTITION_DEVICE_FROM_BLOCK_IO_THIS(a)  CR (a, PARTITION_PRIVATE_DATA, BlockIo, PARTITION_PRIVATE_DATA_SIGNATURE)
75 #define PARTITION_DEVICE_FROM_BLOCK_IO2_THIS(a) CR (a, PARTITION_PRIVATE_DATA, BlockIo2, PARTITION_PRIVATE_DATA_SIGNATURE)
76 
77 //
78 // Global Variables
79 //
80 extern EFI_DRIVER_BINDING_PROTOCOL   gPartitionDriverBinding;
81 extern EFI_COMPONENT_NAME_PROTOCOL   gPartitionComponentName;
82 extern EFI_COMPONENT_NAME2_PROTOCOL  gPartitionComponentName2;
83 
84 //
85 // Extract INT32 from char array
86 //
87 #define UNPACK_INT32(a) (INT32)( (((UINT8 *) a)[0] <<  0) |    \
88                                  (((UINT8 *) a)[1] <<  8) |    \
89                                  (((UINT8 *) a)[2] << 16) |    \
90                                  (((UINT8 *) a)[3] << 24) )
91 
92 //
93 // Extract UINT32 from char array
94 //
95 #define UNPACK_UINT32(a) (UINT32)( (((UINT8 *) a)[0] <<  0) |    \
96                                    (((UINT8 *) a)[1] <<  8) |    \
97                                    (((UINT8 *) a)[2] << 16) |    \
98                                    (((UINT8 *) a)[3] << 24) )
99 
100 
101 //
102 // GPT Partition Entry Status
103 //
104 typedef struct {
105   BOOLEAN OutOfRange;
106   BOOLEAN Overlap;
107   BOOLEAN OsSpecific;
108 } EFI_PARTITION_ENTRY_STATUS;
109 
110 //
111 // Function Prototypes
112 //
113 /**
114   Test to see if this driver supports ControllerHandle. Any ControllerHandle
115   than contains a BlockIo and DiskIo protocol can be supported.
116 
117   @param  This                Protocol instance pointer.
118   @param  ControllerHandle    Handle of device to test
119   @param  RemainingDevicePath Optional parameter use to pick a specific child
120                               device to start.
121 
122   @retval EFI_SUCCESS         This driver supports this device
123   @retval EFI_ALREADY_STARTED This driver is already running on this device
124   @retval other               This driver does not support this device
125 
126 **/
127 EFI_STATUS
128 EFIAPI
129 PartitionDriverBindingSupported (
130   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
131   IN EFI_HANDLE                   ControllerHandle,
132   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
133   );
134 
135 /**
136   Start this driver on ControllerHandle by opening a Block IO and Disk IO
137   protocol, reading Device Path, and creating a child handle with a
138   Disk IO and device path protocol.
139 
140   @param  This                 Protocol instance pointer.
141   @param  ControllerHandle     Handle of device to bind driver to
142   @param  RemainingDevicePath  Optional parameter use to pick a specific child
143                                device to start.
144 
145   @retval EFI_SUCCESS          This driver is added to ControllerHandle
146   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
147   @retval other                This driver does not support this device
148 
149 **/
150 EFI_STATUS
151 EFIAPI
152 PartitionDriverBindingStart (
153   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
154   IN EFI_HANDLE                   ControllerHandle,
155   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
156   );
157 
158 /**
159   Stop this driver on ControllerHandle. Support stopping any child handles
160   created by this driver.
161 
162   @param  This              Protocol instance pointer.
163   @param  ControllerHandle  Handle of device to stop driver on
164   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
165                             children is zero stop the entire bus driver.
166   @param  ChildHandleBuffer List of Child Handles to Stop.
167 
168   @retval EFI_SUCCESS       This driver is removed ControllerHandle
169   @retval other             This driver was not removed from this device
170 
171 **/
172 EFI_STATUS
173 EFIAPI
174 PartitionDriverBindingStop (
175   IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
176   IN  EFI_HANDLE                    ControllerHandle,
177   IN  UINTN                         NumberOfChildren,
178   IN  EFI_HANDLE                    *ChildHandleBuffer
179   );
180 
181 //
182 // EFI Component Name Functions
183 //
184 /**
185   Retrieves a Unicode string that is the user readable name of the driver.
186 
187   This function retrieves the user readable name of a driver in the form of a
188   Unicode string. If the driver specified by This has a user readable name in
189   the language specified by Language, then a pointer to the driver name is
190   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
191   by This does not support the language specified by Language,
192   then EFI_UNSUPPORTED is returned.
193 
194   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
195                                 EFI_COMPONENT_NAME_PROTOCOL instance.
196 
197   @param  Language[in]          A pointer to a Null-terminated ASCII string
198                                 array indicating the language. This is the
199                                 language of the driver name that the caller is
200                                 requesting, and it must match one of the
201                                 languages specified in SupportedLanguages. The
202                                 number of languages supported by a driver is up
203                                 to the driver writer. Language is specified
204                                 in RFC 4646 or ISO 639-2 language code format.
205 
206   @param  DriverName[out]       A pointer to the Unicode string to return.
207                                 This Unicode string is the name of the
208                                 driver specified by This in the language
209                                 specified by Language.
210 
211   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
212                                 This and the language specified by Language was
213                                 returned in DriverName.
214 
215   @retval EFI_INVALID_PARAMETER Language is NULL.
216 
217   @retval EFI_INVALID_PARAMETER DriverName is NULL.
218 
219   @retval EFI_UNSUPPORTED       The driver specified by This does not support
220                                 the language specified by Language.
221 
222 **/
223 EFI_STATUS
224 EFIAPI
225 PartitionComponentNameGetDriverName (
226   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
227   IN  CHAR8                        *Language,
228   OUT CHAR16                       **DriverName
229   );
230 
231 
232 /**
233   Retrieves a Unicode string that is the user readable name of the controller
234   that is being managed by a driver.
235 
236   This function retrieves the user readable name of the controller specified by
237   ControllerHandle and ChildHandle in the form of a Unicode string. If the
238   driver specified by This has a user readable name in the language specified by
239   Language, then a pointer to the controller name is returned in ControllerName,
240   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
241   managing the controller specified by ControllerHandle and ChildHandle,
242   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
243   support the language specified by Language, then EFI_UNSUPPORTED is returned.
244 
245   @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
246                                 EFI_COMPONENT_NAME_PROTOCOL instance.
247 
248   @param  ControllerHandle[in]  The handle of a controller that the driver
249                                 specified by This is managing.  This handle
250                                 specifies the controller whose name is to be
251                                 returned.
252 
253   @param  ChildHandle[in]       The handle of the child controller to retrieve
254                                 the name of.  This is an optional parameter that
255                                 may be NULL.  It will be NULL for device
256                                 drivers.  It will also be NULL for a bus drivers
257                                 that wish to retrieve the name of the bus
258                                 controller.  It will not be NULL for a bus
259                                 driver that wishes to retrieve the name of a
260                                 child controller.
261 
262   @param  Language[in]          A pointer to a Null-terminated ASCII string
263                                 array indicating the language.  This is the
264                                 language of the driver name that the caller is
265                                 requesting, and it must match one of the
266                                 languages specified in SupportedLanguages. The
267                                 number of languages supported by a driver is up
268                                 to the driver writer. Language is specified in
269                                 RFC 4646 or ISO 639-2 language code format.
270 
271   @param  ControllerName[out]   A pointer to the Unicode string to return.
272                                 This Unicode string is the name of the
273                                 controller specified by ControllerHandle and
274                                 ChildHandle in the language specified by
275                                 Language from the point of view of the driver
276                                 specified by This.
277 
278   @retval EFI_SUCCESS           The Unicode string for the user readable name in
279                                 the language specified by Language for the
280                                 driver specified by This was returned in
281                                 DriverName.
282 
283   @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
284 
285   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
286                                 EFI_HANDLE.
287 
288   @retval EFI_INVALID_PARAMETER Language is NULL.
289 
290   @retval EFI_INVALID_PARAMETER ControllerName is NULL.
291 
292   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
293                                 managing the controller specified by
294                                 ControllerHandle and ChildHandle.
295 
296   @retval EFI_UNSUPPORTED       The driver specified by This does not support
297                                 the language specified by Language.
298 
299 **/
300 EFI_STATUS
301 EFIAPI
302 PartitionComponentNameGetControllerName (
303   IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
304   IN  EFI_HANDLE                                      ControllerHandle,
305   IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
306   IN  CHAR8                                           *Language,
307   OUT CHAR16                                          **ControllerName
308   );
309 
310 
311 /**
312   Create a child handle for a logical block device that represents the
313   bytes Start to End of the Parent Block IO device.
314 
315   @param[in]  This              Protocol instance pointer.
316   @param[in]  ParentHandle      Parent Handle for new child.
317   @param[in]  ParentDiskIo      Parent DiskIo interface.
318   @param[in]  ParentDiskIo2     Parent DiskIo2 interface.
319   @param[in]  ParentBlockIo     Parent BlockIo interface.
320   @param[in]  ParentBlockIo2    Parent BlockIo2 interface.
321   @param[in]  ParentDevicePath  Parent Device Path.
322   @param[in]  DevicePathNode    Child Device Path node.
323   @param[in]  Start             Start Block.
324   @param[in]  End               End Block.
325   @param[in]  BlockSize         Child block size.
326   @param[in]  InstallEspGuid    Flag to install EFI System Partition GUID on handle.
327 
328   @retval EFI_SUCCESS       A child handle was added.
329   @retval other             A child handle was not added.
330 
331 **/
332 EFI_STATUS
333 PartitionInstallChildHandle (
334   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
335   IN  EFI_HANDLE                   ParentHandle,
336   IN  EFI_DISK_IO_PROTOCOL         *ParentDiskIo,
337   IN  EFI_DISK_IO2_PROTOCOL        *ParentDiskIo2,
338   IN  EFI_BLOCK_IO_PROTOCOL        *ParentBlockIo,
339   IN  EFI_BLOCK_IO2_PROTOCOL       *ParentBlockIo2,
340   IN  EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath,
341   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
342   IN  EFI_LBA                      Start,
343   IN  EFI_LBA                      End,
344   IN  UINT32                       BlockSize,
345   IN  BOOLEAN                      InstallEspGuid
346   );
347 
348 /**
349   Install child handles if the Handle supports GPT partition structure.
350 
351   @param[in]  This       Calling context.
352   @param[in]  Handle     Parent Handle.
353   @param[in]  DiskIo     Parent DiskIo interface.
354   @param[in]  DiskIo2    Parent DiskIo2 interface.
355   @param[in]  BlockIo    Parent BlockIo interface.
356   @param[in]  BlockIo2   Parent BlockIo2 interface.
357   @param[in]  DevicePath Parent Device Path.
358 
359   @retval EFI_SUCCESS           Valid GPT disk.
360   @retval EFI_MEDIA_CHANGED     Media changed Detected.
361   @retval EFI_INVALID_PARAMETER If both BlockIo and BlockIo2 are NULL;
362   @retval other                 Not a valid GPT disk.
363 
364 **/
365 EFI_STATUS
366 PartitionInstallGptChildHandles (
367   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
368   IN  EFI_HANDLE                   Handle,
369   IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
370   IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
371   IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
372   IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
373   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
374   );
375 
376 /**
377   Install child handles if the Handle supports El Torito format.
378 
379   @param[in]  This        Calling context.
380   @param[in]  Handle      Parent Handle.
381   @param[in]  DiskIo      Parent DiskIo interface.
382   @param[in]  DiskIo2     Parent DiskIo2 interface.
383   @param[in]  BlockIo     Parent BlockIo interface.
384   @param[in]  BlockIo2    Parent BlockIo2 interface.
385   @param[in]  DevicePath  Parent Device Path
386 
387 
388   @retval EFI_SUCCESS         Child handle(s) was added.
389   @retval EFI_MEDIA_CHANGED   Media changed Detected.
390   @retval other               no child handle was added.
391 
392 **/
393 EFI_STATUS
394 PartitionInstallElToritoChildHandles (
395   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
396   IN  EFI_HANDLE                   Handle,
397   IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
398   IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
399   IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
400   IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
401   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
402   );
403 
404 /**
405   Install child handles if the Handle supports MBR format.
406 
407   @param[in]  This              Calling context.
408   @param[in]  Handle            Parent Handle.
409   @param[in]  DiskIo            Parent DiskIo interface.
410   @param[in]  DiskIo2           Parent DiskIo2 interface.
411   @param[in]  BlockIo           Parent BlockIo interface.
412   @param[in]  BlockIo2          Parent BlockIo2 interface.
413   @param[in]  DevicePath        Parent Device Path.
414 
415   @retval EFI_SUCCESS       A child handle was added.
416   @retval EFI_MEDIA_CHANGED Media change was detected.
417   @retval Others            MBR partition was not found.
418 
419 **/
420 EFI_STATUS
421 PartitionInstallMbrChildHandles (
422   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
423   IN  EFI_HANDLE                   Handle,
424   IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
425   IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
426   IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
427   IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
428   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
429   );
430 
431 typedef
432 EFI_STATUS
433 (*PARTITION_DETECT_ROUTINE) (
434   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
435   IN  EFI_HANDLE                   Handle,
436   IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
437   IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
438   IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
439   IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
440   IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
441   );
442 
443 #endif
444