Home | History | Annotate | Download | only in efi
      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