]> code.delx.au - refind/blob - filesystems/scandisk.c
Added rudimentary debconf support for Debian package.
[refind] / filesystems / scandisk.c
1 /*
2 * scandisk.c
3 * Scanning disk for btrfs multi-devices
4 * by Samuel Liao
5 *
6 * Copyright (c) 2013 Tencent, Inc.
7 */
8 /*
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "fsw_efi.h"
24 #ifdef __MAKEWITH_GNUEFI
25 #include "edk2/DriverBinding.h"
26 #include "edk2/ComponentName.h"
27 extern EFI_GUID gEfiDiskIoProtocolGuid;
28 extern EFI_GUID gEfiBlockIoProtocolGuid;
29 #endif
30 #include "../include/refit_call_wrapper.h"
31
32 extern struct fsw_host_table fsw_efi_host_table;
33 static void dummy_volume_free(struct fsw_volume *vol) { }
34 static struct fsw_fstype_table dummy_fstype = {
35 { FSW_STRING_TYPE_UTF8, 4, 4, "dummy" },
36 sizeof(struct fsw_volume),
37 sizeof(struct fsw_dnode),
38
39 NULL, //volume_mount,
40 dummy_volume_free, //volume_free,
41 NULL, //volume_stat,
42 NULL, //dnode_fill,
43 NULL, //dnode_free,
44 NULL, //dnode_stat,
45 NULL, //get_extent,
46 NULL, //dir_lookup,
47 NULL, //dir_read,
48 NULL, //readlink,
49 };
50
51 static struct fsw_volume *create_dummy_volume(EFI_DISK_IO *diskio, UINT32 mediaid)
52 {
53 fsw_status_t err;
54 struct fsw_volume *vol;
55 FSW_VOLUME_DATA *Volume;
56
57 err = fsw_alloc_zero(sizeof(struct fsw_volume), (void **)&vol);
58 if(err)
59 return NULL;
60 err = fsw_alloc_zero(sizeof(FSW_VOLUME_DATA), (void **)&Volume);
61 if(err) {
62 fsw_free(vol);
63 return NULL;
64 }
65 /* fstype_table->volume_free for fsw_unmount */
66 vol->fstype_table = &dummy_fstype;
67 /* host_data needded to fsw_block_get()/fsw_efi_read_block() */
68 Volume->DiskIo = diskio;
69 Volume->MediaId = mediaid;
70
71 vol->host_data = Volume;
72 vol->host_table = &fsw_efi_host_table;
73 return vol;
74 }
75
76 static struct fsw_volume *clone_dummy_volume(struct fsw_volume *vol)
77 {
78 FSW_VOLUME_DATA *Volume = (FSW_VOLUME_DATA *)vol->host_data;
79 return create_dummy_volume(Volume->DiskIo, Volume->MediaId);
80 }
81
82 static void free_dummy_volume(struct fsw_volume *vol)
83 {
84 fsw_free(vol->host_data);
85 fsw_unmount(vol);
86 }
87
88 static int scan_disks(int (*hook)(struct fsw_volume *, struct fsw_volume *), struct fsw_volume *master)
89 {
90 EFI_STATUS Status;
91 EFI_HANDLE *Handles;
92 UINTN HandleCount = 0;
93 UINTN i;
94 UINTN scanned = 0;
95
96 // Driver hangs if compiled with GNU-EFI unless there's a Print() statement somewhere.
97 // I'm still trying to track that down; in the meantime, work around it....
98 #if defined(__MAKEWITH_GNUEFI)
99 Print(L" ");
100 #endif
101 DPRINT(L"Scanning disks\n");
102 Status = refit_call5_wrapper(BS->LocateHandleBuffer, ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &HandleCount, &Handles);
103 if (Status == EFI_NOT_FOUND)
104 return -1; // no filesystems. strange, but true...
105 for (i = 0; i < HandleCount; i++) {
106 EFI_DISK_IO *diskio;
107 EFI_BLOCK_IO *blockio;
108 Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiDiskIoProtocolGuid, (VOID **) &diskio);
109 if (Status != 0)
110 continue;
111 Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiBlockIoProtocolGuid, (VOID **) &blockio);
112 if (Status != 0)
113 continue;
114 struct fsw_volume *vol = create_dummy_volume(diskio, blockio->Media->MediaId);
115 if(vol) {
116 DPRINT(L"Checking disk %d\n", i);
117 if(hook(master, vol) == FSW_SUCCESS)
118 scanned++;
119 free_dummy_volume(vol);
120 }
121 }
122 return scanned;
123 }
124