[e16e8f2] | 1 | /* |
---|
| 2 | * Copyright 2011-2014 Intel Corporation - All Rights Reserved |
---|
| 3 | */ |
---|
| 4 | |
---|
| 5 | #include <fs.h> |
---|
| 6 | #include <ilog2.h> |
---|
| 7 | #include <disk.h> |
---|
| 8 | #include <dprintf.h> |
---|
| 9 | #include "efi.h" |
---|
| 10 | |
---|
| 11 | static inline EFI_STATUS read_blocks(EFI_BLOCK_IO *bio, uint32_t id, |
---|
| 12 | sector_t lba, UINTN bytes, void *buf) |
---|
| 13 | { |
---|
| 14 | return uefi_call_wrapper(bio->ReadBlocks, 5, bio, id, lba, bytes, buf); |
---|
| 15 | } |
---|
| 16 | |
---|
| 17 | static inline EFI_STATUS write_blocks(EFI_BLOCK_IO *bio, uint32_t id, |
---|
| 18 | sector_t lba, UINTN bytes, void *buf) |
---|
| 19 | { |
---|
| 20 | return uefi_call_wrapper(bio->WriteBlocks, 5, bio, id, lba, bytes, buf); |
---|
| 21 | } |
---|
| 22 | |
---|
| 23 | static int efi_rdwr_sectors(struct disk *disk, void *buf, |
---|
| 24 | sector_t lba, size_t count, bool is_write) |
---|
| 25 | { |
---|
| 26 | struct efi_disk_private *priv = (struct efi_disk_private *)disk->private; |
---|
| 27 | EFI_BLOCK_IO *bio = priv->bio; |
---|
| 28 | EFI_STATUS status; |
---|
| 29 | UINTN bytes = count * disk->sector_size; |
---|
| 30 | |
---|
| 31 | if (is_write) |
---|
| 32 | status = write_blocks(bio, disk->disk_number, lba, bytes, buf); |
---|
| 33 | else |
---|
| 34 | status = read_blocks(bio, disk->disk_number, lba, bytes, buf); |
---|
| 35 | |
---|
| 36 | if (status != EFI_SUCCESS) |
---|
| 37 | Print(L"Failed to %s blocks: 0x%x\n", |
---|
| 38 | is_write ? L"write" : L"read", |
---|
| 39 | status); |
---|
| 40 | |
---|
| 41 | return count << disk->sector_shift; |
---|
| 42 | } |
---|
| 43 | |
---|
| 44 | struct disk *efi_disk_init(void *private) |
---|
| 45 | { |
---|
| 46 | static struct disk disk; |
---|
| 47 | struct efi_disk_private *priv = (struct efi_disk_private *)private; |
---|
| 48 | EFI_HANDLE handle = priv->dev_handle; |
---|
| 49 | EFI_BLOCK_IO *bio; |
---|
| 50 | EFI_DISK_IO *dio; |
---|
| 51 | EFI_STATUS status; |
---|
| 52 | |
---|
| 53 | status = uefi_call_wrapper(BS->HandleProtocol, 3, handle, |
---|
| 54 | &DiskIoProtocol, (void **)&dio); |
---|
| 55 | if (status != EFI_SUCCESS) |
---|
| 56 | return NULL; |
---|
| 57 | |
---|
| 58 | status = uefi_call_wrapper(BS->HandleProtocol, 3, handle, |
---|
| 59 | &BlockIoProtocol, (void **)&bio); |
---|
| 60 | if (status != EFI_SUCCESS) |
---|
| 61 | return NULL; |
---|
| 62 | |
---|
| 63 | /* |
---|
| 64 | * XXX Do we need to map this to a BIOS disk number? |
---|
| 65 | */ |
---|
| 66 | disk.disk_number = bio->Media->MediaId; |
---|
| 67 | |
---|
| 68 | disk.sector_size = bio->Media->BlockSize; |
---|
| 69 | disk.rdwr_sectors = efi_rdwr_sectors; |
---|
| 70 | disk.sector_shift = ilog2(disk.sector_size); |
---|
| 71 | |
---|
| 72 | dprintf("sector_size=%d, disk_number=%d\n", disk.sector_size, |
---|
| 73 | disk.disk_number); |
---|
| 74 | |
---|
| 75 | priv->bio = bio; |
---|
| 76 | priv->dio = dio; |
---|
| 77 | disk.private = private; |
---|
| 78 | #if 0 |
---|
| 79 | |
---|
| 80 | disk.part_start = part_start; |
---|
| 81 | disk.secpercyl = disk.h * disk.s; |
---|
| 82 | |
---|
| 83 | |
---|
| 84 | disk.maxtransfer = MaxTransfer; |
---|
| 85 | |
---|
| 86 | dprintf("disk %02x cdrom %d type %d sector %u/%u offset %llu limit %u\n", |
---|
| 87 | media_id, cdrom, ebios, sector_size, disk.sector_shift, |
---|
| 88 | part_start, disk.maxtransfer); |
---|
| 89 | #endif |
---|
| 90 | |
---|
| 91 | return &disk; |
---|
| 92 | } |
---|