]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Disk/Partition/Dxe/Partition.c
added PPI and Protocol definitions needed by porting modules
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / Partition / Dxe / Partition.c
CommitLineData
b9575d60 1/** @file\r
79840ee1 2 Partition driver that produces logical BlockIo devices from a physical\r
3 BlockIo device. The logical BlockIo devices are based on the format\r
4 of the raw block devices media. Currently "El Torito CD-ROM", Legacy\r
5 MBR, and GPT partition schemes are supported.\r
6\r
b9575d60
A
7 Copyright (c) 2006 - 2007, Intel Corporation \r
8 All rights reserved. This program and the accompanying materials \r
9 are licensed and made available under the terms and conditions of the BSD License \r
10 which accompanies this distribution. The full text of the license may be found at \r
11 http://opensource.org/licenses/bsd-license.php \r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
15\r
16**/\r
79840ee1 17\r
79840ee1 18\r
d8a43975 19//\r
20// Include common header file for this module.\r
21//\r
22#include "CommonHeader.h"\r
23\r
79840ee1 24#include "Partition.h"\r
25\r
26//\r
27// Partition Driver Global Variables\r
28//\r
29EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {\r
30 PartitionDriverBindingSupported,\r
31 PartitionDriverBindingStart,\r
32 PartitionDriverBindingStop,\r
33 0xa,\r
34 NULL,\r
35 NULL\r
36};\r
37\r
38STATIC \r
39PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {\r
40 PartitionInstallGptChildHandles,\r
41 PartitionInstallElToritoChildHandles,\r
42 PartitionInstallMbrChildHandles,\r
43 NULL\r
44};\r
45\r
46\r
b9575d60
A
47\r
48/**\r
49 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
50 than contains a BlockIo and DiskIo protocol can be supported.\r
51\r
52 @param This Protocol instance pointer.\r
53 @param ControllerHandle Handle of device to test\r
54 @param RemainingDevicePath Optional parameter use to pick a specific child\r
55 device to start.\r
56\r
57 @retval EFI_SUCCESS This driver supports this device\r
58 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
59 @retval other This driver does not support this device\r
60\r
61**/\r
79840ee1 62EFI_STATUS\r
63EFIAPI\r
64PartitionDriverBindingSupported (\r
65 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
66 IN EFI_HANDLE ControllerHandle,\r
67 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
68 )\r
79840ee1 69{\r
70 EFI_STATUS Status;\r
71 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
72 EFI_DISK_IO_PROTOCOL *DiskIo;\r
73 EFI_DEV_PATH *Node;\r
74\r
75 if (RemainingDevicePath != NULL) {\r
76 Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
77 if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||\r
78 Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||\r
79 DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)\r
80 ) {\r
81 return EFI_UNSUPPORTED;\r
82 }\r
83 }\r
84 //\r
85 // Open the IO Abstraction(s) needed to perform the supported test\r
86 //\r
87 Status = gBS->OpenProtocol (\r
88 ControllerHandle,\r
89 &gEfiDevicePathProtocolGuid,\r
90 (VOID **) &ParentDevicePath,\r
91 This->DriverBindingHandle,\r
92 ControllerHandle,\r
93 EFI_OPEN_PROTOCOL_BY_DRIVER\r
94 );\r
95 if (Status == EFI_ALREADY_STARTED) {\r
96 return EFI_SUCCESS;\r
97 }\r
98\r
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
102 //\r
103 // Close the I/O Abstraction(s) used to perform the supported test\r
104 //\r
105 gBS->CloseProtocol (\r
106 ControllerHandle,\r
107 &gEfiDevicePathProtocolGuid,\r
108 This->DriverBindingHandle,\r
109 ControllerHandle\r
110 );\r
111\r
112 //\r
113 // Open the IO Abstraction(s) needed to perform the supported test\r
114 //\r
115 Status = gBS->OpenProtocol (\r
116 ControllerHandle,\r
117 &gEfiDiskIoProtocolGuid,\r
118 (VOID **) &DiskIo,\r
119 This->DriverBindingHandle,\r
120 ControllerHandle,\r
121 EFI_OPEN_PROTOCOL_BY_DRIVER\r
122 );\r
123 if (Status == EFI_ALREADY_STARTED) {\r
124 return EFI_SUCCESS;\r
125 }\r
126\r
127 if (EFI_ERROR (Status)) {\r
128 return Status;\r
129 }\r
130 //\r
131 // Close the I/O Abstraction(s) used to perform the supported test\r
132 //\r
133 gBS->CloseProtocol (\r
134 ControllerHandle,\r
135 &gEfiDiskIoProtocolGuid,\r
136 This->DriverBindingHandle,\r
137 ControllerHandle\r
138 );\r
139\r
140 //\r
141 // Open the IO Abstraction(s) needed to perform the supported test\r
142 //\r
143 Status = gBS->OpenProtocol (\r
144 ControllerHandle,\r
145 &gEfiBlockIoProtocolGuid,\r
146 NULL,\r
147 This->DriverBindingHandle,\r
148 ControllerHandle,\r
149 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
150 );\r
151\r
152 return Status;\r
153}\r
154\r
b9575d60
A
155\r
156/**\r
157 Start this driver on ControllerHandle by opening a Block IO and Disk IO\r
158 protocol, reading Device Path, and creating a child handle with a\r
159 Disk IO and device path protocol.\r
160\r
161 @param This Protocol instance pointer.\r
162 @param ControllerHandle Handle of device to bind driver to\r
163 @param RemainingDevicePath Optional parameter use to pick a specific child\r
164 device to start.\r
165\r
166 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
167 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
168 @retval other This driver does not support this device\r
169\r
170**/\r
79840ee1 171EFI_STATUS\r
172EFIAPI\r
173PartitionDriverBindingStart (\r
174 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
175 IN EFI_HANDLE ControllerHandle,\r
176 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
177 )\r
79840ee1 178{\r
179 EFI_STATUS Status;\r
180 EFI_STATUS OpenStatus;\r
181 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
182 EFI_DISK_IO_PROTOCOL *DiskIo;\r
183 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
184 PARTITION_DETECT_ROUTINE *Routine;\r
185\r
186 Status = gBS->OpenProtocol (\r
187 ControllerHandle,\r
188 &gEfiBlockIoProtocolGuid,\r
189 (VOID **) &BlockIo,\r
190 This->DriverBindingHandle,\r
191 ControllerHandle,\r
192 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
193 );\r
194 if (EFI_ERROR (Status)) {\r
195 return Status;\r
196 }\r
197 //\r
198 // Get the Device Path Protocol on ControllerHandle's handle\r
199 //\r
200 Status = gBS->OpenProtocol (\r
201 ControllerHandle,\r
202 &gEfiDevicePathProtocolGuid,\r
203 (VOID **) &ParentDevicePath,\r
204 This->DriverBindingHandle,\r
205 ControllerHandle,\r
206 EFI_OPEN_PROTOCOL_BY_DRIVER\r
207 );\r
208 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
209 return Status;\r
210 }\r
211\r
212 Status = gBS->OpenProtocol (\r
213 ControllerHandle,\r
214 &gEfiDiskIoProtocolGuid,\r
215 (VOID **) &DiskIo,\r
216 This->DriverBindingHandle,\r
217 ControllerHandle,\r
218 EFI_OPEN_PROTOCOL_BY_DRIVER\r
219 );\r
220 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
221 gBS->CloseProtocol (\r
222 ControllerHandle,\r
223 &gEfiDevicePathProtocolGuid,\r
224 This->DriverBindingHandle,\r
225 ControllerHandle\r
226 );\r
227 return Status;\r
228 }\r
229\r
230 OpenStatus = Status;\r
231\r
232 //\r
233 // If no media is present, do nothing here.\r
234 //\r
235 Status = EFI_UNSUPPORTED;\r
236 if (BlockIo->Media->MediaPresent) {\r
237 //\r
238 // Try for GPT, then El Torito, and then legacy MBR partition types. If the\r
239 // media supports a given partition type install child handles to represent\r
240 // the partitions described by the media.\r
241 //\r
242 Routine = &mPartitionDetectRoutineTable[0];\r
243 while (*Routine != NULL) {\r
244 Status = (*Routine) (\r
245 This,\r
246 ControllerHandle,\r
247 DiskIo,\r
248 BlockIo,\r
249 ParentDevicePath\r
250 );\r
251 if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED) {\r
252 break;\r
253 }\r
254 Routine++;\r
255 }\r
256 }\r
257 //\r
258 // In the case that the driver is already started (OpenStatus == EFI_ALREADY_STARTED),\r
259 // the DevicePathProtocol and the DiskIoProtocol are not actually opened by the\r
260 // driver. So don't try to close them. Otherwise, we will break the dependency\r
261 // between the controller and the driver set up before.\r
262 //\r
263 if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus) && Status != EFI_MEDIA_CHANGED) {\r
264 gBS->CloseProtocol (\r
265 ControllerHandle,\r
266 &gEfiDiskIoProtocolGuid,\r
267 This->DriverBindingHandle,\r
268 ControllerHandle\r
269 );\r
270\r
271 gBS->CloseProtocol (\r
272 ControllerHandle,\r
273 &gEfiDevicePathProtocolGuid,\r
274 This->DriverBindingHandle,\r
275 ControllerHandle\r
276 );\r
277 }\r
278\r
279 return Status;\r
280}\r
281\r
b9575d60
A
282\r
283/**\r
284 Stop this driver on ControllerHandle. Support stoping any child handles\r
285 created by this driver.\r
286\r
287 @param This Protocol instance pointer.\r
288 @param ControllerHandle Handle of device to stop driver on\r
289 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
290 children is zero stop the entire bus driver.\r
291 @param ChildHandleBuffer List of Child Handles to Stop.\r
292\r
293 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
294 @retval other This driver was not removed from this device\r
295\r
296**/\r
79840ee1 297EFI_STATUS\r
298EFIAPI\r
299PartitionDriverBindingStop (\r
300 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
301 IN EFI_HANDLE ControllerHandle,\r
302 IN UINTN NumberOfChildren,\r
303 IN EFI_HANDLE *ChildHandleBuffer\r
304 )\r
79840ee1 305{\r
306 EFI_STATUS Status;\r
307 UINTN Index;\r
308 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
309 BOOLEAN AllChildrenStopped;\r
310 PARTITION_PRIVATE_DATA *Private;\r
311 EFI_DISK_IO_PROTOCOL *DiskIo;\r
312\r
313 if (NumberOfChildren == 0) {\r
314 //\r
315 // Close the bus driver\r
316 //\r
317 gBS->CloseProtocol (\r
318 ControllerHandle,\r
319 &gEfiDiskIoProtocolGuid,\r
320 This->DriverBindingHandle,\r
321 ControllerHandle\r
322 );\r
323\r
324 gBS->CloseProtocol (\r
325 ControllerHandle,\r
326 &gEfiDevicePathProtocolGuid,\r
327 This->DriverBindingHandle,\r
328 ControllerHandle\r
329 );\r
330\r
331 return EFI_SUCCESS;\r
332 }\r
333\r
334 AllChildrenStopped = TRUE;\r
335 for (Index = 0; Index < NumberOfChildren; Index++) {\r
336 Status = gBS->OpenProtocol (\r
337 ChildHandleBuffer[Index],\r
338 &gEfiBlockIoProtocolGuid,\r
339 (VOID **) &BlockIo,\r
340 This->DriverBindingHandle,\r
341 ControllerHandle,\r
342 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
343 );\r
344 if (!EFI_ERROR (Status)) {\r
345\r
346 Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (BlockIo);\r
347\r
348 //\r
349 // All Software protocols have be freed from the handle so remove it.\r
350 //\r
351 BlockIo->FlushBlocks (BlockIo);\r
352\r
353 Status = gBS->CloseProtocol (\r
354 ControllerHandle,\r
355 &gEfiDiskIoProtocolGuid,\r
356 This->DriverBindingHandle,\r
357 ChildHandleBuffer[Index]\r
358 );\r
359\r
360 Status = gBS->UninstallMultipleProtocolInterfaces (\r
361 ChildHandleBuffer[Index],\r
362 &gEfiDevicePathProtocolGuid,\r
363 Private->DevicePath,\r
364 &gEfiBlockIoProtocolGuid,\r
365 &Private->BlockIo,\r
366 Private->EspGuid,\r
367 NULL,\r
368 NULL\r
369 );\r
370 if (EFI_ERROR (Status)) {\r
371 gBS->OpenProtocol (\r
372 ControllerHandle,\r
373 &gEfiDiskIoProtocolGuid,\r
374 (VOID **) &DiskIo,\r
375 This->DriverBindingHandle,\r
376 ChildHandleBuffer[Index],\r
377 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
378 );\r
379 } else {\r
380 FreePool (Private->DevicePath);\r
381 FreePool (Private);\r
382 }\r
383\r
384 }\r
385\r
386 if (EFI_ERROR (Status)) {\r
387 AllChildrenStopped = FALSE;\r
388 }\r
389 }\r
390\r
391 if (!AllChildrenStopped) {\r
392 return EFI_DEVICE_ERROR;\r
393 }\r
394\r
395 return EFI_SUCCESS;\r
396}\r
397\r
b9575d60
A
398\r
399/**\r
400 Reset the Block Device.\r
401\r
402 @param This Protocol instance pointer.\r
403 @param ExtendedVerification Driver may perform diagnostics on reset.\r
404\r
405 @retval EFI_SUCCESS The device was reset.\r
406 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
407 not be reset.\r
408\r
409**/\r
79840ee1 410STATIC\r
411EFI_STATUS\r
412EFIAPI\r
413PartitionReset (\r
414 IN EFI_BLOCK_IO_PROTOCOL *This,\r
415 IN BOOLEAN ExtendedVerification\r
416 )\r
79840ee1 417{\r
418 PARTITION_PRIVATE_DATA *Private;\r
419\r
420 Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
421\r
422 return Private->ParentBlockIo->Reset (\r
423 Private->ParentBlockIo,\r
424 ExtendedVerification\r
425 );\r
426}\r
427\r
b9575d60
A
428\r
429/**\r
430 Read by using the Disk IO protocol on the parent device. Lba addresses\r
431 must be converted to byte offsets.\r
432\r
433 @param This Protocol instance pointer.\r
434 @param MediaId Id of the media, changes every time the media is replaced.\r
435 @param Lba The starting Logical Block Address to read from\r
436 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
437 @param Buffer Buffer containing read data\r
438\r
439 @retval EFI_SUCCESS The data was read correctly from the device.\r
440 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.\r
441 @retval EFI_NO_MEDIA There is no media in the device.\r
442 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.\r
443 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
444 @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not\r
445 valid for the device.\r
446\r
447**/\r
79840ee1 448STATIC\r
449EFI_STATUS\r
450EFIAPI\r
451PartitionReadBlocks (\r
452 IN EFI_BLOCK_IO_PROTOCOL *This,\r
453 IN UINT32 MediaId,\r
454 IN EFI_LBA Lba,\r
455 IN UINTN BufferSize,\r
456 OUT VOID *Buffer\r
457 )\r
79840ee1 458{\r
459 PARTITION_PRIVATE_DATA *Private;\r
460 UINT64 Offset;\r
461\r
462 Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
463\r
464 if (BufferSize % Private->BlockSize != 0) {\r
465 return EFI_BAD_BUFFER_SIZE;\r
466 }\r
467\r
468 Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;\r
469 if (Offset + BufferSize > Private->End) {\r
470 return EFI_INVALID_PARAMETER;\r
471 }\r
472 //\r
473 // Because some kinds of partition have different block size from their parent\r
474 // device, we call the Disk IO protocol on the parent device, not the Block IO\r
475 // protocol\r
476 //\r
477 return Private->DiskIo->ReadDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);\r
478}\r
479\r
b9575d60
A
480/**\r
481 Write by using the Disk IO protocol on the parent device. Lba addresses\r
482 must be converted to byte offsets.\r
483\r
484 @param This Protocol instance pointer.\r
485 @param MediaId Id of the media, changes every time the media is replaced.\r
486 @param Lba The starting Logical Block Address to read from\r
487 @param BufferSize Size of Buffer, must be a multiple of device block size.\r
488 @param Buffer Buffer containing read data\r
489\r
490 @retval EFI_SUCCESS The data was written correctly to the device.\r
491 @retval EFI_WRITE_PROTECTED The device can not be written to.\r
492 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.\r
493 @retval EFI_NO_MEDIA There is no media in the device.\r
494 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.\r
495 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.\r
496 @retval EFI_INVALID_PARAMETER The write request contains a LBA that is not\r
497 valid for the device.\r
498\r
499**/\r
79840ee1 500STATIC\r
501EFI_STATUS\r
502EFIAPI\r
503PartitionWriteBlocks (\r
504 IN EFI_BLOCK_IO_PROTOCOL *This,\r
505 IN UINT32 MediaId,\r
506 IN EFI_LBA Lba,\r
507 IN UINTN BufferSize,\r
508 OUT VOID *Buffer\r
509 )\r
79840ee1 510{\r
511 PARTITION_PRIVATE_DATA *Private;\r
512 UINT64 Offset;\r
513\r
514 Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
515\r
516 if (BufferSize % Private->BlockSize != 0) {\r
517 return EFI_BAD_BUFFER_SIZE;\r
518 }\r
519\r
520 Offset = MultU64x32 (Lba, Private->BlockSize) + Private->Start;\r
521 if (Offset + BufferSize > Private->End) {\r
522 return EFI_INVALID_PARAMETER;\r
523 }\r
524 //\r
525 // Because some kinds of partition have different block size from their parent\r
526 // device, we call the Disk IO protocol on the parent device, not the Block IO\r
527 // protocol\r
528 //\r
529 return Private->DiskIo->WriteDisk (Private->DiskIo, MediaId, Offset, BufferSize, Buffer);\r
530}\r
531\r
b9575d60
A
532\r
533/**\r
534 Flush the parent Block Device.\r
535\r
536 @param This Protocol instance pointer.\r
537\r
538 @retval EFI_SUCCESS All outstanding data was written to the device\r
539 @retval EFI_DEVICE_ERROR The device reported an error while writting back the data\r
540 @retval EFI_NO_MEDIA There is no media in the device.\r
541\r
542**/\r
79840ee1 543STATIC\r
544EFI_STATUS\r
545EFIAPI\r
546PartitionFlushBlocks (\r
547 IN EFI_BLOCK_IO_PROTOCOL *This\r
548 )\r
79840ee1 549{\r
550 PARTITION_PRIVATE_DATA *Private;\r
551\r
552 Private = PARTITION_DEVICE_FROM_BLOCK_IO_THIS (This);\r
553\r
554 return Private->ParentBlockIo->FlushBlocks (Private->ParentBlockIo);\r
555}\r
556\r
b9575d60
A
557\r
558\r
559/**\r
560 Create a child handle for a logical block device that represents the\r
561 bytes Start to End of the Parent Block IO device.\r
562\r
563 @param[in] This Protocol instance pointer.\r
564 @param[in] This Calling context.\r
565 @param[in] ParentHandle Parent Handle for new child\r
566 @param[in] ParentDiskIo Parent DiskIo interface\r
567 @param[in] ParentBlockIo Parent BlockIo interface\r
568 @param[in] ParentDevicePath Parent Device Path\r
569 @param[in] DevicePathNode Child Device Path node\r
570 @param[in] Start Start Block\r
571 @param[in] End End Block\r
572 @param[in] BlockSize Child block size\r
573 @param[in] InstallEspGuid Flag to install EFI System Partition GUID on handle\r
574\r
575 @retval EFI_SUCCESS A child handle was added\r
576 @retval other A child handle was not added\r
577\r
578**/\r
79840ee1 579EFI_STATUS\r
580PartitionInstallChildHandle (\r
581 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
582 IN EFI_HANDLE ParentHandle,\r
583 IN EFI_DISK_IO_PROTOCOL *ParentDiskIo,\r
584 IN EFI_BLOCK_IO_PROTOCOL *ParentBlockIo,\r
585 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
586 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
587 IN EFI_LBA Start,\r
588 IN EFI_LBA End,\r
589 IN UINT32 BlockSize,\r
590 IN BOOLEAN InstallEspGuid\r
591 )\r
79840ee1 592{\r
593 EFI_STATUS Status;\r
594 PARTITION_PRIVATE_DATA *Private;\r
595\r
596 Private = AllocateZeroPool (sizeof (PARTITION_PRIVATE_DATA));\r
597 if (Private == NULL) {\r
598 return EFI_OUT_OF_RESOURCES;\r
599 }\r
600\r
601 Private->Signature = PARTITION_PRIVATE_DATA_SIGNATURE;\r
602\r
603 Private->Start = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);\r
604 Private->End = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);\r
605\r
606 Private->BlockSize = BlockSize;\r
607 Private->ParentBlockIo = ParentBlockIo;\r
608 Private->DiskIo = ParentDiskIo;\r
609\r
610 Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;\r
611\r
612 Private->BlockIo.Media = &Private->Media;\r
613 CopyMem (Private->BlockIo.Media, ParentBlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));\r
614 Private->Media.LogicalPartition = TRUE;\r
615 Private->Media.LastBlock = DivU64x32 (\r
616 MultU64x32 (\r
617 End - Start + 1,\r
618 ParentBlockIo->Media->BlockSize\r
619 ),\r
620 BlockSize\r
621 ) - 1;\r
622\r
623 Private->Media.BlockSize = (UINT32) BlockSize;\r
624\r
625 Private->BlockIo.Reset = PartitionReset;\r
626 Private->BlockIo.ReadBlocks = PartitionReadBlocks;\r
627 Private->BlockIo.WriteBlocks = PartitionWriteBlocks;\r
628 Private->BlockIo.FlushBlocks = PartitionFlushBlocks;\r
629\r
630 Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);\r
631\r
632 if (Private->DevicePath == NULL) {\r
633 FreePool (Private);\r
634 return EFI_OUT_OF_RESOURCES;\r
635 }\r
636\r
637 if (InstallEspGuid) {\r
638 Private->EspGuid = &gEfiPartTypeSystemPartGuid;\r
639 } else {\r
640 //\r
641 // If NULL InstallMultipleProtocolInterfaces will ignore it.\r
642 //\r
643 Private->EspGuid = NULL;\r
644 }\r
645 //\r
646 // Create the new handle\r
647 //\r
648 Private->Handle = NULL;\r
649 Status = gBS->InstallMultipleProtocolInterfaces (\r
650 &Private->Handle,\r
651 &gEfiDevicePathProtocolGuid,\r
652 Private->DevicePath,\r
653 &gEfiBlockIoProtocolGuid,\r
654 &Private->BlockIo,\r
655 Private->EspGuid,\r
656 NULL,\r
657 NULL\r
658 );\r
659\r
660 if (!EFI_ERROR (Status)) {\r
661 //\r
662 // Open the Parent Handle for the child\r
663 //\r
664 Status = gBS->OpenProtocol (\r
665 ParentHandle,\r
666 &gEfiDiskIoProtocolGuid,\r
667 (VOID **) &ParentDiskIo,\r
668 This->DriverBindingHandle,\r
669 Private->Handle,\r
670 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
671 );\r
672 } else {\r
673 FreePool (Private->DevicePath);\r
674 FreePool (Private);\r
675 }\r
676\r
677 return Status;\r
678}\r
b9575d60
A
679\r
680\r
681/**\r
682 The user Entry Point for module Partition. The user code starts with this function.\r
683\r
684 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
685 @param[in] SystemTable A pointer to the EFI System Table.\r
686 \r
687 @retval EFI_SUCCESS The entry point is executed successfully.\r
688 @retval other Some error occurs when executing this entry point.\r
689\r
690**/\r
691EFI_STATUS\r
692EFIAPI\r
693InitializePartition (\r
694 IN EFI_HANDLE ImageHandle,\r
695 IN EFI_SYSTEM_TABLE *SystemTable\r
696 )\r
697{\r
698 EFI_STATUS Status;\r
699\r
700 //\r
701 // Install driver model protocol(s).\r
702 //\r
703 Status = EfiLibInstallAllDriverProtocols (\r
704 ImageHandle,\r
705 SystemTable,\r
706 &gPartitionDriverBinding,\r
707 ImageHandle,\r
708 &gPartitionComponentName,\r
709 NULL,\r
710 NULL\r
711 );\r
712 ASSERT_EFI_ERROR (Status);\r
713\r
714\r
715 return Status;\r
716}\r
717\r