3 Copyright (c) 2004 - 2007, Intel Corporation
4 All rights reserved. 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
778 (Private
->Filename
, Private
->Mode
, 0644);
780 if (Private
->fd
< 0) {
781 DEBUG ((EFI_D_INFO
, "PlOpenBlock: Could not open %s\n",
783 BlockIo
->Media
->MediaPresent
= FALSE
;
784 Status
= EFI_NO_MEDIA
;
788 if (!BlockIo
->Media
->MediaPresent
) {
790 // BugBug: try to emulate if a CD appears - notify drivers to check it out
792 BlockIo
->Media
->MediaPresent
= TRUE
;
793 EfiReleaseLock (&Private
->Lock
);
794 EfiAcquireLock (&Private
->Lock
);
798 // get the size of the file
800 Status
= SetFilePointer64 (Private
, 0, &FileSize
, SEEK_END
);
802 if (EFI_ERROR (Status
)) {
803 FileSize
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
804 DEBUG ((EFI_D_ERROR
, "PlOpenBlock: Could not get filesize of %s\n", Private
->Filename
));
805 Status
= EFI_UNSUPPORTED
;
809 if (Private
->NumberOfBlocks
== 0) {
810 Private
->NumberOfBlocks
= DivU64x32 (FileSize
, Private
->BlockSize
);
813 EndOfFile
= MultU64x32 (Private
->NumberOfBlocks
, Private
->BlockSize
);
815 if (FileSize
!= EndOfFile
) {
817 // file is not the proper size, change it
819 DEBUG ((EFI_D_INIT
, "PlOpenBlock: Initializing block device: %a\n", Private
->Filename
));
824 Private
->UnixThunk
->FTruncate (Private
->fd
, 0);
827 // then set it to the needed file size (OS will zero fill it)
829 Private
->UnixThunk
->FTruncate (Private
->fd
, EndOfFile
);
832 DEBUG ((EFI_D_INIT
, "%HPlOpenBlock: opened %s%N\n", Private
->Filename
));
833 Status
= EFI_SUCCESS
;
836 if (EFI_ERROR (Status
)) {
837 if (Private
->fd
>= 0) {
838 BlockIo
->Reset (BlockIo
, FALSE
);
842 EfiReleaseLock (&Private
->Lock
);
848 IN UNIX_BLOCK_IO_PRIVATE
*Private
854 TODO: Add function description
858 Private - TODO: add argument description
862 TODO: add return values
866 return EFI_DEVICE_ERROR
;
869 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
871 BOOLEAN ReinstallBlockIoFlag
;
874 BlockIo
= &Private
->BlockIo
;
876 switch (Private
->UnixThunk
->GetLastError ()) {
878 case ERROR_NOT_READY
:
879 Status
= EFI_NO_MEDIA
;
880 BlockIo
->Media
->ReadOnly
= FALSE
;
881 BlockIo
->Media
->MediaPresent
= FALSE
;
882 ReinstallBlockIoFlag
= FALSE
;
885 case ERROR_WRONG_DISK
:
886 BlockIo
->Media
->ReadOnly
= FALSE
;
887 BlockIo
->Media
->MediaPresent
= TRUE
;
888 BlockIo
->Media
->MediaId
+= 1;
889 ReinstallBlockIoFlag
= TRUE
;
890 Status
= EFI_MEDIA_CHANGED
;
893 case ERROR_WRITE_PROTECT
:
894 BlockIo
->Media
->ReadOnly
= TRUE
;
895 ReinstallBlockIoFlag
= FALSE
;
896 Status
= EFI_WRITE_PROTECTED
;
900 ReinstallBlockIoFlag
= FALSE
;
901 Status
= EFI_DEVICE_ERROR
;
905 if (ReinstallBlockIoFlag
) {
906 BlockIo
->Reset (BlockIo
, FALSE
);
908 gBS
->ReinstallProtocolInterface (
910 &gEfiBlockIoProtocolGuid
,
921 UnixBlockIoReadWriteCommon (
922 IN UNIX_BLOCK_IO_PRIVATE
*Private
,
933 TODO: Add function description
937 Private - TODO: add argument description
938 MediaId - TODO: add argument description
939 Lba - TODO: add argument description
940 BufferSize - TODO: add argument description
941 Buffer - TODO: add argument description
942 CallerName - TODO: add argument description
946 EFI_NO_MEDIA - TODO: Add description for return value
947 EFI_MEDIA_CHANGED - TODO: Add description for return value
948 EFI_INVALID_PARAMETER - TODO: Add description for return value
949 EFI_SUCCESS - TODO: Add description for return value
950 EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
951 EFI_INVALID_PARAMETER - TODO: Add description for return value
952 EFI_SUCCESS - TODO: Add description for return value
959 INT64 DistanceToMove
;
960 UINT64 DistanceMoved
;
962 if (Private
->fd
< 0) {
963 Status
= UnixBlockIoOpenDevice (Private
);
964 if (EFI_ERROR (Status
)) {
969 if (!Private
->Media
.MediaPresent
) {
970 DEBUG ((EFI_D_INIT
, "%s: No Media\n", CallerName
));
974 if (Private
->Media
.MediaId
!= MediaId
) {
975 return EFI_MEDIA_CHANGED
;
978 if ((UINT32
) Buffer
% Private
->Media
.IoAlign
!= 0) {
979 return EFI_INVALID_PARAMETER
;
983 // Verify buffer size
985 BlockSize
= Private
->BlockSize
;
986 if (BufferSize
== 0) {
987 DEBUG ((EFI_D_INIT
, "%s: Zero length read\n", CallerName
));
991 if ((BufferSize
% BlockSize
) != 0) {
992 DEBUG ((EFI_D_INIT
, "%s: Invalid read size\n", CallerName
));
993 return EFI_BAD_BUFFER_SIZE
;
996 LastBlock
= Lba
+ (BufferSize
/ BlockSize
) - 1;
997 if (LastBlock
> Private
->LastBlock
) {
998 DEBUG ((EFI_D_INIT
, "ReadBlocks: Attempted to read off end of device\n"));
999 return EFI_INVALID_PARAMETER
;
1002 // Seek to End of File
1004 DistanceToMove
= MultU64x32 (Lba
, BlockSize
);
1005 Status
= SetFilePointer64 (Private
, DistanceToMove
, &DistanceMoved
, SEEK_SET
);
1007 if (EFI_ERROR (Status
)) {
1008 DEBUG ((EFI_D_INIT
, "WriteBlocks: SetFilePointer failed\n"));
1009 return UnixBlockIoError (Private
);
1017 UnixBlockIoReadBlocks (
1018 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1021 IN UINTN BufferSize
,
1026 Routine Description:
1027 Read BufferSize bytes from Lba into Buffer.
1030 This - Protocol instance pointer.
1031 MediaId - Id of the media, changes every time the media is replaced.
1032 Lba - The starting Logical Block Address to read from
1033 BufferSize - Size of Buffer, must be a multiple of device block size.
1034 Buffer - Buffer containing read data
1037 EFI_SUCCESS - The data was read correctly from the device.
1038 EFI_DEVICE_ERROR - The device reported an error while performing the read.
1039 EFI_NO_MEDIA - There is no media in the device.
1040 EFI_MEDIA_CHANGED - The MediaId does not matched the current device.
1041 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
1043 EFI_INVALID_PARAMETER - The read request contains device addresses that are not
1044 valid for the device.
1048 UNIX_BLOCK_IO_PRIVATE
*Private
;
1053 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1055 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1057 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixReadBlocks");
1058 if (EFI_ERROR (Status
)) {
1062 len
= Private
->UnixThunk
->Read (Private
->fd
, Buffer
, BufferSize
);
1063 if (len
!= BufferSize
) {
1064 DEBUG ((EFI_D_INIT
, "ReadBlocks: ReadFile failed.\n"));
1065 Status
= UnixBlockIoError (Private
);
1070 // If we wrote then media is present.
1072 This
->Media
->MediaPresent
= TRUE
;
1073 Status
= EFI_SUCCESS
;
1076 gBS
->RestoreTPL (OldTpl
);
1082 UnixBlockIoWriteBlocks (
1083 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1086 IN UINTN BufferSize
,
1091 Routine Description:
1092 Write BufferSize bytes from Lba into Buffer.
1095 This - Protocol instance pointer.
1096 MediaId - Id of the media, changes every time the media is replaced.
1097 Lba - The starting Logical Block Address to read from
1098 BufferSize - Size of Buffer, must be a multiple of device block size.
1099 Buffer - Buffer containing read data
1102 EFI_SUCCESS - The data was written correctly to the device.
1103 EFI_WRITE_PROTECTED - The device can not be written to.
1104 EFI_DEVICE_ERROR - The device reported an error while performing the write.
1105 EFI_NO_MEDIA - There is no media in the device.
1106 EFI_MEDIA_CHNAGED - The MediaId does not matched the current device.
1107 EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
1109 EFI_INVALID_PARAMETER - The write request contains a LBA that is not
1110 valid for the device.
1114 UNIX_BLOCK_IO_PRIVATE
*Private
;
1119 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1121 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1123 Status
= UnixBlockIoReadWriteCommon (Private
, MediaId
, Lba
, BufferSize
, Buffer
, "UnixWriteBlocks");
1124 if (EFI_ERROR (Status
)) {
1128 len
= Private
->UnixThunk
->Write (Private
->fd
, Buffer
, BufferSize
);
1129 if (len
!= BufferSize
) {
1130 DEBUG ((EFI_D_INIT
, "ReadBlocks: WriteFile failed.\n"));
1131 Status
= UnixBlockIoError (Private
);
1136 // If the write succeeded, we are not write protected and media is present.
1138 This
->Media
->MediaPresent
= TRUE
;
1139 This
->Media
->ReadOnly
= FALSE
;
1140 Status
= EFI_SUCCESS
;
1143 gBS
->RestoreTPL (OldTpl
);
1149 UnixBlockIoFlushBlocks (
1150 IN EFI_BLOCK_IO_PROTOCOL
*This
1154 Routine Description:
1155 Flush the Block Device.
1158 This - Protocol instance pointer.
1161 EFI_SUCCESS - All outstanding data was written to the device
1162 EFI_DEVICE_ERROR - The device reported an error while writting back the data
1163 EFI_NO_MEDIA - There is no media in the device.
1172 UnixBlockIoResetBlock (
1173 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1174 IN BOOLEAN ExtendedVerification
1178 Routine Description:
1179 Reset the Block Device.
1182 This - Protocol instance pointer.
1183 ExtendedVerification - Driver may perform diagnostics on reset.
1186 EFI_SUCCESS - The device was reset.
1187 EFI_DEVICE_ERROR - The device is not functioning properly and could
1192 UNIX_BLOCK_IO_PRIVATE
*Private
;
1195 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
1197 Private
= UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This
);
1199 if (Private
->fd
>= 0) {
1200 Private
->UnixThunk
->Close (Private
->fd
);
1204 gBS
->RestoreTPL (OldTpl
);
1215 Routine Description:
1217 Convert a unicode string to a UINTN
1221 String - Unicode string.
1225 UINTN of the number represented by String.
1233 // skip preceeding white space
1236 while ((*Str
) && (*Str
== ' ')) {
1240 // Convert ot a Number
1243 while (*Str
!= '\0') {
1244 if ((*Str
>= '0') && (*Str
<= '9')) {
1245 Number
= (Number
* 10) +*Str
- '0';
1258 IN UNIX_BLOCK_IO_PRIVATE
*Private
,
1259 IN INT64 DistanceToMove
,
1260 OUT UINT64
*NewFilePointer
,
1265 This function extends the capability of SetFilePointer to accept 64 bit parameters
1268 // TODO: function comment is missing 'Routine Description:'
1269 // TODO: function comment is missing 'Arguments:'
1270 // TODO: function comment is missing 'Returns:'
1271 // TODO: Private - add argument and description to function comment
1272 // TODO: DistanceToMove - add argument and description to function comment
1273 // TODO: NewFilePointer - add argument and description to function comment
1274 // TODO: MoveMethod - add argument and description to function comment
1279 res
= Private
->UnixThunk
->Lseek(Private
->fd
, DistanceToMove
, MoveMethod
);
1281 Status
= EFI_INVALID_PARAMETER
;
1284 if (NewFilePointer
!= NULL
) {
1285 *NewFilePointer
= res
;