93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
/*
|
|
* Copyright 2011-2014 Intel Corporation - All Rights Reserved
|
|
*/
|
|
|
|
#include <fs.h>
|
|
#include <ilog2.h>
|
|
#include <disk.h>
|
|
#include <dprintf.h>
|
|
#include "efi.h"
|
|
|
|
static inline EFI_STATUS read_blocks(EFI_BLOCK_IO *bio, uint32_t id,
|
|
sector_t lba, UINTN bytes, void *buf)
|
|
{
|
|
return uefi_call_wrapper(bio->ReadBlocks, 5, bio, id, lba, bytes, buf);
|
|
}
|
|
|
|
static inline EFI_STATUS write_blocks(EFI_BLOCK_IO *bio, uint32_t id,
|
|
sector_t lba, UINTN bytes, void *buf)
|
|
{
|
|
return uefi_call_wrapper(bio->WriteBlocks, 5, bio, id, lba, bytes, buf);
|
|
}
|
|
|
|
static int efi_rdwr_sectors(struct disk *disk, void *buf,
|
|
sector_t lba, size_t count, bool is_write)
|
|
{
|
|
struct efi_disk_private *priv = (struct efi_disk_private *)disk->private;
|
|
EFI_BLOCK_IO *bio = priv->bio;
|
|
EFI_STATUS status;
|
|
UINTN bytes = count * disk->sector_size;
|
|
|
|
if (is_write)
|
|
status = write_blocks(bio, disk->disk_number, lba, bytes, buf);
|
|
else
|
|
status = read_blocks(bio, disk->disk_number, lba, bytes, buf);
|
|
|
|
if (status != EFI_SUCCESS)
|
|
Print(L"Failed to %s blocks: 0x%x\n",
|
|
is_write ? L"write" : L"read",
|
|
status);
|
|
|
|
return count << disk->sector_shift;
|
|
}
|
|
|
|
struct disk *efi_disk_init(void *private)
|
|
{
|
|
static struct disk disk;
|
|
struct efi_disk_private *priv = (struct efi_disk_private *)private;
|
|
EFI_HANDLE handle = priv->dev_handle;
|
|
EFI_BLOCK_IO *bio;
|
|
EFI_DISK_IO *dio;
|
|
EFI_STATUS status;
|
|
|
|
status = uefi_call_wrapper(BS->HandleProtocol, 3, handle,
|
|
&DiskIoProtocol, (void **)&dio);
|
|
if (status != EFI_SUCCESS)
|
|
return NULL;
|
|
|
|
status = uefi_call_wrapper(BS->HandleProtocol, 3, handle,
|
|
&BlockIoProtocol, (void **)&bio);
|
|
if (status != EFI_SUCCESS)
|
|
return NULL;
|
|
|
|
/*
|
|
* XXX Do we need to map this to a BIOS disk number?
|
|
*/
|
|
disk.disk_number = bio->Media->MediaId;
|
|
|
|
disk.sector_size = bio->Media->BlockSize;
|
|
disk.rdwr_sectors = efi_rdwr_sectors;
|
|
disk.sector_shift = ilog2(disk.sector_size);
|
|
|
|
dprintf("sector_size=%d, disk_number=%d\n", disk.sector_size,
|
|
disk.disk_number);
|
|
|
|
priv->bio = bio;
|
|
priv->dio = dio;
|
|
disk.private = private;
|
|
#if 0
|
|
|
|
disk.part_start = part_start;
|
|
disk.secpercyl = disk.h * disk.s;
|
|
|
|
|
|
disk.maxtransfer = MaxTransfer;
|
|
|
|
dprintf("disk %02x cdrom %d type %d sector %u/%u offset %llu limit %u\n",
|
|
media_id, cdrom, ebios, sector_size, disk.sector_shift,
|
|
part_start, disk.maxtransfer);
|
|
#endif
|
|
|
|
return &disk;
|
|
}
|