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 } 93