3 Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Produce block IO abstractions for real devices on your PC using Posix APIs.
19 The configuration of what devices to mount or emulate comes from UNIX
20 environment variables. The variables must be visible to the Microsoft*
21 Developer Studio for them to work.
23 <F>ixed - Fixed disk like a hard drive.
24 <R>emovable - Removable media like a floppy or CD-ROM.
25 Read <O>nly - Write protected device.
26 Read <W>rite - Read write device.
27 <block count> - Decimal number of blocks a device supports.
28 <block size> - Decimal number of bytes per block.
30 UNIX envirnonment variable contents. '<' and '>' are not part of the variable,
31 they are just used to make this help more readable. There should be no
32 spaces between the ';'. Extra spaces will break the variable. A '!' is
33 used to seperate multiple devices in a variable.
35 EFI_UNIX_VIRTUAL_DISKS =
36 <F | R><O | W>;<block count>;<block size>[!...]
38 EFI_UNIX_PHYSICAL_DISKS =
39 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
41 Virtual Disks: These devices use a file to emulate a hard disk or removable
44 Thus a 20 MB emulated hard drive would look like:
45 EFI_UNIX_VIRTUAL_DISKS=FW;40960;512
47 A 1.44MB emulated floppy with a block size of 1024 would look like:
48 EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024
50 Physical Disks: These devices use UNIX to open a real device in your system
52 Thus a 120 MB floppy would look like:
53 EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512
55 Thus a standard CD-ROM floppy would look like:
56 EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048
59 * Other names and brands may be claimed as the property of others.
65 #include "UnixBlockIo.h"
68 // Block IO protocol member functions
72 UnixBlockIoReadBlocks (
73 IN EFI_BLOCK_IO_PROTOCOL
*This
,
83 TODO: Add function description
87 This - TODO: add argument description
88 MediaId - TODO: add argument description
89 Lba - TODO: add argument description
90 BufferSize - TODO: add argument description
91 Buffer - TODO: add argument description
95 TODO: add return values
102 UnixBlockIoWriteBlocks (
103 IN EFI_BLOCK_IO_PROTOCOL
*This
,
113 TODO: Add function description
117 This - TODO: add argument description
118 MediaId - TODO: add argument description
119 Lba - TODO: add argument description
120 BufferSize - TODO: add argument description
121 Buffer - TODO: add argument description
125 TODO: add return values
132 UnixBlockIoFlushBlocks (
133 IN EFI_BLOCK_IO_PROTOCOL
*This
139 TODO: Add function description
143 This - TODO: add argument description
147 TODO: add return values
154 UnixBlockIoResetBlock (
155 IN EFI_BLOCK_IO_PROTOCOL
*This
,
156 IN BOOLEAN ExtendedVerification
162 TODO: Add function description
166 This - TODO: add argument description
167 ExtendedVerification - TODO: add argument description
171 TODO: add return values
177 // Private Worker functions
180 UnixBlockIoCreateMapping (
181 IN EFI_UNIX_IO_PROTOCOL
*UnixIo
,
182 IN EFI_HANDLE EfiDeviceHandle
,
185 IN BOOLEAN RemovableMedia
,
186 IN UINTN NumberOfBlocks
,
193 TODO: Add function description
197 UnixIo - TODO: add argument description
198 EfiDeviceHandle - TODO: add argument description
199 Filename - TODO: add argument description
200 ReadOnly - TODO: add argument description
201 RemovableMedia - TODO: add argument description
202 NumberOfBlocks - TODO: add argument description
203 BlockSize - TODO: add argument description
204 DeviceType - TODO: add argument description
208 TODO: add return values
214 UnixBlockIoReadWriteCommon (
215 IN UNIX_BLOCK_IO_PRIVATE
*Private
,
226 TODO: Add function description
230 Private - TODO: add argument description
231 MediaId - TODO: add argument description
232 Lba - TODO: add argument description
233 BufferSize - TODO: add argument description
234 Buffer - TODO: add argument description
235 CallerName - TODO: add argument description
239 TODO: add return values
246 IN UNIX_BLOCK_IO_PRIVATE
*Private
252 TODO: Add function description
256 Private - TODO: add argument description
260 TODO: add return values
266 UnixBlockIoOpenDevice (
267 UNIX_BLOCK_IO_PRIVATE
*Private
273 TODO: Add function description
277 Private - TODO: add argument description
281 TODO: add return values
287 GetNextElementPastTerminator (
288 IN CHAR16
*EnvironmentVariable
,
295 TODO: Add function description
299 EnvironmentVariable - TODO: add argument description
300 Terminator - TODO: add argument description
304 TODO: add return values
308 EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding
= {
309 UnixBlockIoDriverBindingSupported
,
310 UnixBlockIoDriverBindingStart
,
311 UnixBlockIoDriverBindingStop
,
319 UnixBlockIoDriverBindingSupported (
320 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
321 IN EFI_HANDLE Handle
,
322 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
335 // TODO: This - add argument and description to function comment
336 // TODO: Handle - add argument and description to function comment
337 // TODO: RemainingDevicePath - add argument and description to function comment
340 EFI_UNIX_IO_PROTOCOL
*UnixIo
;
343 // Open the IO Abstraction(s) needed to perform the supported test
345 Status
= gBS
->OpenProtocol (
347 &gEfiUnixIoProtocolGuid
,
349 This
->DriverBindingHandle
,
351 EFI_OPEN_PROTOCOL_BY_DRIVER
353 if (EFI_ERROR (Status
)) {
358 // Make sure the UnixThunkProtocol is valid
360 Status
= EFI_UNSUPPORTED
;
361 if (UnixIo
->UnixThunk
->Signature
== EFI_UNIX_THUNK_PROTOCOL_SIGNATURE
) {
364 // Check the GUID to see if this is a handle type the driver supports
366 if (CompareGuid (UnixIo
->TypeGuid
, &gEfiUnixVirtualDisksGuid
) ) {
367 Status
= EFI_SUCCESS
;
372 // Close the I/O Abstraction(s) used to perform the supported test
376 &gEfiUnixIoProtocolGuid
,
377 This
->DriverBindingHandle
,
385 UnixBlockIoDriverBindingStart (
386 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
387 IN EFI_HANDLE Handle
,
388 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
401 // TODO: This - add argument and description to function comment
402 // TODO: Handle - add argument and description to function comment
403 // TODO: RemainingDevicePath - add argument and description to function comment
406 EFI_UNIX_IO_PROTOCOL
*UnixIo
;
407 CHAR16 Buffer
[FILENAME_BUFFER_SIZE
];
409 BOOLEAN RemovableMedia
;
410 BOOLEAN WriteProtected
;
411 UINTN NumberOfBlocks
;
416 // Grab the protocols we need
419 Status
= gBS
->OpenProtocol (
421 &gEfiUnixIoProtocolGuid
,
423 This
->DriverBindingHandle
,
425 EFI_OPEN_PROTOCOL_BY_DRIVER
427 if (EFI_ERROR (Status
)) {
433 if (!CompareGuid (UnixIo
->TypeGuid
, &gEfiUnixVirtualDisksGuid
)) {
434 Status
= EFI_UNSUPPORTED
;
438 Status
= EFI_NOT_FOUND
;
440 Str
= UnixIo
->EnvString
;
442 while (*Str
&& *Str
!= ':')
443 Buffer
[i
++] = *Str
++;
451 RemovableMedia
= FALSE
;
452 WriteProtected
= TRUE
;
456 if (*Str
== 'R' || *Str
== 'F') {
457 RemovableMedia
= (BOOLEAN
) (*Str
== 'R');
460 if (*Str
== 'O' || *Str
== 'W') {
461 WriteProtected
= (BOOLEAN
) (*Str
== 'O');
470 NumberOfBlocks
= Atoi (Str
);
471 Str
= GetNextElementPastTerminator (Str
, ';');
472 if (NumberOfBlocks
== 0)
475 BlockSize
= Atoi (Str
);
477 Str
= GetNextElementPastTerminator (Str
, ';');
481 // If we get here the variable is valid so do the work.
483 Status
= UnixBlockIoCreateMapping (
494 if (EFI_ERROR (Status
)) {
497 &gEfiUnixIoProtocolGuid
,
498 This
->DriverBindingHandle
,
508 UnixBlockIoDriverBindingStop (
509 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
510 IN EFI_HANDLE Handle
,
511 IN UINTN NumberOfChildren
,
512 IN EFI_HANDLE
*ChildHandleBuffer
518 TODO: Add function description
522 This - TODO: add argument description
523 Handle - TODO: add argument description
524 NumberOfChildren - TODO: add argument description
525 ChildHandleBuffer - TODO: add argument description
529 EFI_UNSUPPORTED - TODO: Add description for return value
533 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
535 UNIX_BLOCK_IO_PRIVATE
*Private
;
538 // Get our context back
540 Status
= gBS
->OpenProtocol (
542 &gEfiBlockIoProtocolGuid
,
544 This
->DriverBindingHandle
,
546 EFI_OPEN_PROTOCOL_GET_PROTOCOL
548 if (EFI_ERROR (Status
)) {
549 return EFI_UNSUPPORTED
;
552 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo
);
555 // BugBug: If we need to kick people off, we need to make Uninstall Close the handles.
556 // We could pass in our image handle or FLAG our open to be closed via
557 // Unistall (== to saying any CloseProtocol will close our open)
559 Status
= gBS
->UninstallMultipleProtocolInterfaces (
561 &gEfiBlockIoProtocolGuid
,
565 if (!EFI_ERROR (Status
)) {
567 Status
= gBS
->CloseProtocol (
569 &gEfiUnixIoProtocolGuid
,
570 This
->DriverBindingHandle
,
575 // Shut down our device
577 Private
->UnixThunk
->Close (Private
->fd
);
580 // Free our instance data
582 FreeUnicodeStringTable (Private
->ControllerNameTable
);
584 gBS
->FreePool (Private
);
591 GetNextElementPastTerminator (
592 IN CHAR16
*EnvironmentVariable
,
599 Worker function to parse environment variables.
602 EnvironmentVariable - Envirnment variable to parse.
604 Terminator - Terminator to parse for.
608 Pointer to next eliment past the first occurence of Terminator or the '\0'
609 at the end of the string.
615 for (Ptr
= EnvironmentVariable
; *Ptr
!= '\0'; Ptr
++) {
616 if (*Ptr
== Terminator
) {
626 UnixBlockIoCreateMapping (
627 IN EFI_UNIX_IO_PROTOCOL
*UnixIo
,
628 IN EFI_HANDLE EfiDeviceHandle
,
631 IN BOOLEAN RemovableMedia
,
632 IN UINTN NumberOfBlocks
,
639 TODO: Add function description
643 UnixIo - TODO: add argument description
644 EfiDeviceHandle - TODO: add argument description
645 Filename - TODO: add argument description
646 ReadOnly - TODO: add argument description
647 RemovableMedia - TODO: add argument description
648 NumberOfBlocks - TODO: add argument description
649 BlockSize - TODO: add argument description
650 DeviceType - TODO: add argument description
654 TODO: add return values
659 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
660 UNIX_BLOCK_IO_PRIVATE
*Private
;
663 Status
= gBS
->AllocatePool (
665 sizeof (UNIX_BLOCK_IO_PRIVATE
),
668 ASSERT_EFI_ERROR (Status
);
670 EfiInitializeLock (&Private
->Lock
, TPL_NOTIFY
);
672 Private
->UnixThunk
= UnixIo
->UnixThunk
;
674 Private
->Signature
= UNIX_BLOCK_IO_PRIVATE_SIGNATURE
;
675 Private
->LastBlock
= NumberOfBlocks
- 1;
676 Private
->BlockSize
= BlockSize
;
678 for (Index
= 0; Filename
[Index
] != 0; Index
++) {
679 Private
->Filename
[Index
] = Filename
[Index
];
682 Private
->Filename
[Index
] = 0;
684 Private
->Mode
= (ReadOnly
? O_RDONLY
: O_RDWR
);
686 Private
->NumberOfBlocks
= NumberOfBlocks
;
689 Private
->ControllerNameTable
= NULL
;
693 gUnixBlockIoComponentName
.SupportedLanguages
,
694 &Private
->ControllerNameTable
,
698 BlockIo
= &Private
->BlockIo
;
699 BlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION
;
700 BlockIo
->Media
= &Private
->Media
;
701 BlockIo
->Media
->BlockSize
= Private
->BlockSize
;
702 BlockIo
->Media
->LastBlock
= Private
->NumberOfBlocks
- 1;
703 BlockIo
->Media
->MediaId
= 0;;
705 BlockIo
->Reset
= UnixBlockIoResetBlock
;
706 BlockIo
->ReadBlocks
= UnixBlockIoReadBlocks
;
707 BlockIo
->WriteBlocks
= UnixBlockIoWriteBlocks
;
708 BlockIo
->FlushBlocks
= UnixBlockIoFlushBlocks
;
710 BlockIo
->Media
->ReadOnly
= ReadOnly
;
711 BlockIo
->Media
->RemovableMedia
= RemovableMedia
;
712 BlockIo
->Media
->LogicalPartition
= FALSE
;
713 BlockIo
->Media
->MediaPresent
= TRUE
;
714 BlockIo
->Media
->WriteCaching
= FALSE
;
716 BlockIo
->Media
->IoAlign
= 1;
718 Private
->EfiHandle
= EfiDeviceHandle
;
719 Status
= UnixBlockIoOpenDevice (Private
);
720 if (!EFI_ERROR (Status
)) {
722 Status
= gBS
->InstallMultipleProtocolInterfaces (
724 &gEfiBlockIoProtocolGuid
,
728 if (EFI_ERROR (Status
)) {
729 FreeUnicodeStringTable (Private
->ControllerNameTable
);
730 gBS
->FreePool (Private
);
733 DEBUG ((EFI_D_ERROR
, "BlockDevice added: %s\n", Filename
));
740 UnixBlockIoOpenDevice (
741 UNIX_BLOCK_IO_PRIVATE
*Private
747 TODO: Add function description
751 Private - TODO: add argument description
755 TODO: add return values
762 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
764 BlockIo
= &Private
->BlockIo
;
765 EfiAcquireLock (&Private
->Lock
);
768 // If the device is already opened, close it
770 if (Private
->fd
>= 0) {
771 BlockIo
->Reset (BlockIo
, FALSE
);
777 Private
->fd
= Private
->UnixThunk
->Open (Private
->Filename
, Private
->Mode
, 0644);
778 if (Private
->fd
< 0) {
779 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %a\n", Private
->Filename
));
780 BlockIo
->Media
->MediaPresent
= FALSE
;
781 Status
= EFI_NO_MEDIA
;
785 if (!BlockIo
->Media
->MediaPresent
) {
787 // BugBug: try to emulate if a CD appears - notify drivers to check it out
789 BlockIo
->Media
->MediaPresent
= TRUE
;
790 EfiReleaseLock (&Private
->Lock
);
791 EfiAcquireLock (&Private
->Lock
);
795 // get the size of the file
797 Status
= SetFilePointer64 (Private
, 0, &FileSize
, SEEK_END
);
798 if (EFI_ERROR (Status
)) {
799 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
800 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %a\n", Private
->Filename
));
801 Status
= EFI_UNSUPPORTED
;
805 if (Private
->NumberOfBlocks
== 0) {
806 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
807 Private
->LastBlock
= Private
->NumberOfBlocks
- 1;
808 Private
->Media
.LastBlock
= Private
->LastBlock
;
811 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
813 if (FileSize
!= EndOfFile
) {
815 // file is not the proper size, change it
817 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %a\n", Private
->Filename
));
822 Private
->UnixThunk
->FTruncate (Private
->fd
, 0);
825 // then set it to the needed file size (OS will zero fill it)
827 Private
->UnixThunk
->FTruncate (Private
->fd
, EndOfFile
);
830 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %a%N\n", Private
->Filename
));
831 Status
= EFI_SUCCESS
;
834 if (EFI_ERROR (Status
)) {
835 if (Private
->fd
>= 0) {
836 BlockIo
->Reset (BlockIo
, FALSE
);
840 EfiReleaseLock (&Private
->Lock
);
846 IN UNIX_BLOCK_IO_PRIVATE
*Private
852 TODO: Add function description
856 Private - TODO: add argument description
860 TODO: add return values
864 return EFI_DEVICE_ERROR
;
867 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
869 BOOLEAN ReinstallBlockIoFlag
;
872 BlockIo
= &Private
->BlockIo
;
874 switch (Private
->UnixThunk
->GetLastError ()) {
876 case ERROR_NOT_READY
:
877 Status
= EFI_NO_MEDIA
;
878 BlockIo
->Media
->ReadOnly
= FALSE
;
879 BlockIo
->Media
->MediaPresent
= FALSE
;
880 ReinstallBlockIoFlag
= FALSE
;
883 case ERROR_WRONG_DISK
:
884 BlockIo
->Media
->ReadOnly
= FALSE
;
885 BlockIo
->Media
->MediaPresent
= TRUE
;
886 BlockIo
->Media
->MediaId
+= 1;
887 ReinstallBlockIoFlag
= TRUE
;
888 Status
= EFI_MEDIA_CHANGED
;
891 case ERROR_WRITE_PROTECT
:
892 BlockIo
->Media
->ReadOnly
= TRUE
;
893 ReinstallBlockIoFlag
= FALSE
;
894 Status
= EFI_WRITE_PROTECTED
;
898 ReinstallBlockIoFlag
= FALSE
;
899 Status
= EFI_DEVICE_ERROR
;
903 if (ReinstallBlockIoFlag
) {
904 BlockIo
->Reset (BlockIo
, FALSE
);
906 gBS
->ReinstallProtocolInterface (
908 &gEfiBlockIoProtocolGuid
,
919 UnixBlockIoReadWriteCommon (
920 IN UNIX_BLOCK_IO_PRIVATE
*Private
,
931 TODO: Add function description
935 Private - TODO: add argument description
936 MediaId - TODO: add argument description
937 Lba - TODO: add argument description
938 BufferSize - TODO: add argument description
939 Buffer - TODO: add argument description
940 CallerName - TODO: add argument description
944 EFI_NO_MEDIA - TODO: Add description for return value
945 EFI_MEDIA_CHANGED - TODO: Add description for return value
946 EFI_INVALID_PARAMETER - TODO: Add description for return value
947 EFI_SUCCESS - TODO: Add description for return value
948 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
949 EFI_INVALID_PARAMETER - TODO: Add description for return value
950 EFI_SUCCESS - TODO: Add description for return value
957 INT64 DistanceToMove
;
958 UINT64 DistanceMoved
;
960 if (Private
->fd
< 0) {
961 Status
= UnixBlockIoOpenDevice (Private
);
962 if (EFI_ERROR (Status
)) {
967 if (!Private
->Media
.MediaPresent
) {
968 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
972 if (Private
->Media
.MediaId
!= MediaId
) {
973 return EFI_MEDIA_CHANGED
;
976 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
977 return EFI_INVALID_PARAMETER
;
981 // Verify buffer size
983 BlockSize
= Private
->BlockSize
;
984 if (BufferSize
== 0) {
985 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
989 if ((BufferSize
% BlockSize
) != 0) {
990 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
991 return EFI_BAD_BUFFER_SIZE
;
994 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
995 if (LastBlock
> Private
->LastBlock
) {
996 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
997 return EFI_INVALID_PARAMETER
;
1000 // Seek to End of File
1002 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
1003 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, SEEK_SET
);
1005 if (EFI_ERROR (Status
)) {
1006 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
1007 return UnixBlockIoError (Private
);
1015 UnixBlockIoReadBlocks (
1016 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1019 IN UINTN BufferSize
,
1024 Routine Description:
1025 Read BufferSize bytes from Lba into Buffer.
1028 This - Protocol instance pointer.
1029 MediaId - Id of the media, changes every time the media is replaced.
1030 Lba - The starting Logical Block Address to read from
1031 BufferSize - Size of Buffer, must be a multiple of device block size.
1032 Buffer - Buffer containing read data
1035 EFI_SUCCESS - The data was read correctly from the device.
1036 EFI_DEVICE_ERROR - The device reported an error while performing the read.
1037 EFI_NO_MEDIA - There is no media in the device.
1038 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
1039 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
1041 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
1042 valid for the device.
1046 UNIX_BLOCK_IO_PRIVATE
*Private
;
1051 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1053 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1055 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixReadBlocks");
1056 if (EFI_ERROR (Status
)) {
1060 len
= Private
->UnixThunk
->Read (Private
->fd
, Buffer
, BufferSize
);
1061 if (len
!= BufferSize
) {
1062 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed.\n"));
1063 Status
= UnixBlockIoError (Private
);
1068 // If we wrote then media is present.
1070 This
->Media
->MediaPresent
= TRUE
;
1071 Status
= EFI_SUCCESS
;
1074 gBS
->RestoreTPL (OldTpl
);
1080 UnixBlockIoWriteBlocks (
1081 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1084 IN UINTN BufferSize
,
1089 Routine Description:
1090 Write BufferSize bytes from Lba into Buffer.
1093 This - Protocol instance pointer.
1094 MediaId - Id of the media, changes every time the media is replaced.
1095 Lba - The starting Logical Block Address to read from
1096 BufferSize - Size of Buffer, must be a multiple of device block size.
1097 Buffer - Buffer containing read data
1100 EFI_SUCCESS - The data was written correctly to the device.
1101 EFI_WRITE_PROTECTED - The device can not be written to.
1102 EFI_DEVICE_ERROR - The device reported an error while performing the write.
1103 EFI_NO_MEDIA - There is no media in the device.
1104 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
1105 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
1107 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
1108 valid for the device.
1112 UNIX_BLOCK_IO_PRIVATE
*Private
;
1117 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1119 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1121 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixWriteBlocks");
1122 if (EFI_ERROR (Status
)) {
1126 len
= Private
->UnixThunk
->Write (Private
->fd
, Buffer
, BufferSize
);
1127 if (len
!= BufferSize
) {
1128 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed.\n"));
1129 Status
= UnixBlockIoError (Private
);
1134 // If the write succeeded, we are not write protected and media is present.
1136 This
->Media
->MediaPresent
= TRUE
;
1137 This
->Media
->ReadOnly
= FALSE
;
1138 Status
= EFI_SUCCESS
;
1141 gBS
->RestoreTPL (OldTpl
);
1147 UnixBlockIoFlushBlocks (
1148 IN EFI_BLOCK_IO_PROTOCOL
*This
1152 Routine Description:
1153 Flush the Block Device.
1156 This - Protocol instance pointer.
1159 EFI_SUCCESS - All outstanding data was written to the device
1160 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1161 EFI_NO_MEDIA - There is no media in the device.
1170 UnixBlockIoResetBlock (
1171 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1172 IN BOOLEAN ExtendedVerification
1176 Routine Description:
1177 Reset the Block Device.
1180 This - Protocol instance pointer.
1181 ExtendedVerification - Driver may perform diagnostics on reset.
1184 EFI_SUCCESS - The device was reset.
1185 EFI_DEVICE_ERROR - The device is not functioning properly and could
1190 UNIX_BLOCK_IO_PRIVATE
*Private
;
1193 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1195 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1197 if (Private
->fd
>= 0) {
1198 Private
->UnixThunk
->Close (Private
->fd
);
1202 gBS
->RestoreTPL (OldTpl
);
1213 Routine Description:
1215 Convert a unicode string to a UINTN
1219 String - Unicode string.
1223 UINTN of the number represented by String.
1231 // skip preceeding white space
1234 while ((*Str
) && (*Str
== ' ')) {
1238 // Convert ot a Number
1241 while (*Str
!= '\0') {
1242 if ((*Str
>= '0') && (*Str
<= '9')) {
1243 Number
= (Number
* 10) +*Str
- '0';
1256 IN UNIX_BLOCK_IO_PRIVATE
*Private
,
1257 IN INT64 DistanceToMove
,
1258 OUT UINT64
*NewFilePointer
,
1263 This function extends the capability of SetFilePointer to accept 64 bit parameters
1266 // TODO: function comment is missing 'Routine Description:'
1267 // TODO: function comment is missing 'Arguments:'
1268 // TODO: function comment is missing 'Returns:'
1269 // TODO: Private - add argument and description to function comment
1270 // TODO: DistanceToMove - add argument and description to function comment
1271 // TODO: NewFilePointer - add argument and description to function comment
1272 // TODO: MoveMethod - add argument and description to function comment
1277 Status
= EFI_SUCCESS
;
1278 res
= Private
->UnixThunk
->Lseek(Private
->fd
, DistanceToMove
, MoveMethod
);
1280 Status
= EFI_INVALID_PARAMETER
;
1283 if (NewFilePointer
!= NULL
) {
1284 *NewFilePointer
= res
;