BOOLEAN RemovableMedia;\r
BOOLEAN WriteProtected;\r
\r
- UINTN BlockSize;\r
UINT64 NumberOfBlocks;\r
- UINT64 LastBlock;\r
\r
EMU_BLOCK_IO_PROTOCOL EmuBlockIo;\r
EFI_BLOCK_IO_MEDIA *Media;\r
{\r
EFI_STATUS Status;\r
off_t res;\r
+ off_t offset = DistanceToMove;\r
\r
Status = EFI_SUCCESS;\r
- res = lseek (Private->fd, DistanceToMove, MoveMethod);\r
+ res = lseek (Private->fd, offset, (int)MoveMethod);\r
if (res == -1) {\r
Status = EFI_INVALID_PARAMETER;\r
- }\r
+ } \r
\r
if (NewFilePointer != NULL) {\r
*NewFilePointer = res;\r
{\r
EFI_STATUS Status;\r
UINT64 FileSize;\r
- UINT64 EndOfFile;\r
+ struct statfs buf;\r
\r
\r
//\r
//\r
Private->fd = open (Private->Filename, Private->Mode, 0644);\r
if (Private->fd < 0) {\r
- DEBUG ((EFI_D_INFO, "EmuOpenBlock: Could not open %a\n", Private->Filename));\r
+ printf ("EmuOpenBlock: Could not open %s: %s\n", Private->Filename, strerror(errno));\r
Private->Media->MediaPresent = FALSE;\r
- Status = EFI_NO_MEDIA;\r
+ Status = EFI_NO_MEDIA;\r
goto Done;\r
}\r
\r
//\r
Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END);\r
if (EFI_ERROR (Status)) {\r
- FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);\r
- DEBUG ((EFI_D_ERROR, "EmuOpenBlock: Could not get filesize of %a\n", Private->Filename));\r
+ printf ("EmuOpenBlock: Could not get filesize of %s\n", Private->Filename);\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
-\r
- if (Private->NumberOfBlocks == 0) {\r
- Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize);\r
- Private->LastBlock = Private->NumberOfBlocks - 1;\r
- Private->Media->LastBlock = Private->LastBlock;\r
- }\r
-\r
- EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize);\r
-\r
- if (FileSize != EndOfFile) {\r
- //\r
- // file is not the proper size, change it\r
- //\r
- DEBUG ((EFI_D_INIT, "EmuOpenBlock: Initializing block device: %a\n", Private->Filename));\r
-\r
- //\r
- // first set it to 0\r
- //\r
- ftruncate (Private->fd, 0);\r
-\r
+ \r
+ if (FileSize == 0) {\r
+ // lseek fails on a real device. ioctl calls are OS specific\r
+#if __APPLE__\r
+ {\r
+ UINT32 BlockSize;\r
+ \r
+ if (ioctl (Private->fd, DKIOCGETBLOCKSIZE, &BlockSize) == 0) {\r
+ Private->Media->BlockSize = BlockSize;\r
+ }\r
+ if (ioctl (Private->fd, DKIOCGETBLOCKCOUNT, &Private->NumberOfBlocks) == 0) {\r
+ if ((Private->NumberOfBlocks == 0) && (BlockSize == 0x800)) {\r
+ // A DVD is ~ 4.37 GB so make up a number\r
+ Private->Media->LastBlock = (0x100000000ULL/0x800) - 1;\r
+ } else {\r
+ Private->Media->LastBlock = Private->NumberOfBlocks - 1;\r
+ }\r
+ }\r
+ ioctl (Private->fd, DKIOCGETMAXBLOCKCOUNTWRITE, &Private->Media->OptimalTransferLengthGranularity); \r
+ }\r
+#else \r
+ {\r
+ size_t BlockSize;\r
+ UINT64 DiskSize;\r
+ \r
+ if (ioctl (Private->fd, BLKSSZGET, &BlockSize) == 0) {\r
+ Private->Media->BlockSize = BlockSize;\r
+ }\r
+ if (ioctl (Private->fd, BLKGETSIZE64, &DiskSize) == 0) {\r
+ Private->NumberOfBlocks = DivU64x32 (DiskSize, (UINT32)BlockSize);\r
+ Private->Media->LastBlock = Private->NumberOfBlocks - 1;\r
+ }\r
+ }\r
+#endif\r
+ \r
+ } else if (fstatfs (Private->fd, &buf) == 0) {\r
//\r
- // then set it to the needed file size (OS will zero fill it)\r
+ // Works for files, not devices\r
//\r
- ftruncate (Private->fd, EndOfFile);\r
- }\r
+ Private->Media->BlockSize = buf.f_bsize;\r
+ Private->Media->OptimalTransferLengthGranularity = buf.f_iosize/buf.f_bsize;\r
+ Private->NumberOfBlocks = DivU64x32 (FileSize, Private->Media->BlockSize);\r
+ Private->Media->LastBlock = Private->NumberOfBlocks - 1;\r
+ } \r
\r
DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename));\r
Status = EFI_SUCCESS;\r
Media->LogicalPartition = FALSE;\r
Media->ReadOnly = Private->WriteProtected;\r
Media->WriteCaching = FALSE;\r
- Media->BlockSize = Private->BlockSize;\r
Media->IoAlign = 1;\r
Media->LastBlock = 0; // Filled in by OpenDevice\r
\r
// EFI_BLOCK_IO_PROTOCOL_REVISION2\r
Media->LowestAlignedLba = 0;\r
Media->LogicalBlocksPerPhysicalBlock = 0; \r
- \r
+ \r
+\r
// EFI_BLOCK_IO_PROTOCOL_REVISION3\r
Media->OptimalTransferLengthGranularity = 0;\r
-\r
+ \r
Status = EmuBlockIoOpenDevice (Private);\r
\r
+ \r
return Status;\r
}\r
\r
//\r
// Verify buffer size\r
//\r
- BlockSize = Private->BlockSize;\r
+ BlockSize = Private->Media->BlockSize;\r
if (BufferSize == 0) {\r
DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));\r
return EFI_SUCCESS;\r
}\r
\r
LastBlock = Lba + (BufferSize / BlockSize) - 1;\r
- if (LastBlock > Private->LastBlock) {\r
+ if (LastBlock > Private->Media->LastBlock) {\r
DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));\r
return EFI_INVALID_PARAMETER;\r
}\r
)\r
{\r
EMU_BLOCK_IO_PRIVATE *Private;\r
+ int Res;\r
\r
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);\r
\r
if (Private->fd >= 0) {\r
- close (Private->fd);\r
- Private->fd = open (Private->Filename, Private->Mode, 0644);\r
+ Res = fcntl (Private->fd, F_FULLFSYNC);\r
}\r
\r
+ \r
if (Token != NULL) {\r
if (Token->Event != NULL) {\r
// Caller is responcible for signaling EFI Event\r
}\r
}\r
\r
- Private->BlockSize = 512;\r
- \r
This->Interface = &Private->EmuBlockIo;\r
This->Private = Private;\r
return EFI_SUCCESS;\r