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