File: diskio.c

package info (click to toggle)
syslinux 3%3A6.03%2Bdfsg-5%2Bdeb8u2
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 41,276 kB
  • sloc: ansic: 358,748; asm: 9,608; pascal: 4,809; perl: 3,894; makefile: 2,488; sh: 324; python: 266; xml: 39
file content (92 lines) | stat: -rw-r--r-- 2,462 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * 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;
}