3 * Scanning disk for btrfs multi-devices
6 * Copyright (c) 2013 Tencent, Inc.
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.
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.
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/>.
24 #ifdef __MAKEWITH_GNUEFI
25 #include "edk2/DriverBinding.h"
26 #include "edk2/ComponentName.h"
27 extern EFI_GUID gEfiDiskIoProtocolGuid
;
28 extern EFI_GUID gEfiBlockIoProtocolGuid
;
30 #include "../include/refit_call_wrapper.h"
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
),
40 dummy_volume_free
, //volume_free,
51 static struct fsw_volume
*create_dummy_volume(EFI_DISK_IO
*diskio
, UINT32 mediaid
)
54 struct fsw_volume
*vol
;
55 FSW_VOLUME_DATA
*Volume
;
57 err
= fsw_alloc_zero(sizeof(struct fsw_volume
), (void **)&vol
);
60 err
= fsw_alloc_zero(sizeof(FSW_VOLUME_DATA
), (void **)&Volume
);
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
;
71 vol
->host_data
= Volume
;
72 vol
->host_table
= &fsw_efi_host_table
;
76 static struct fsw_volume
*clone_dummy_volume(struct fsw_volume
*vol
)
78 FSW_VOLUME_DATA
*Volume
= (FSW_VOLUME_DATA
*)vol
->host_data
;
79 return create_dummy_volume(Volume
->DiskIo
, Volume
->MediaId
);
82 static void free_dummy_volume(struct fsw_volume
*vol
)
84 fsw_free(vol
->host_data
);
88 static int scan_disks(int (*hook
)(struct fsw_volume
*, struct fsw_volume
*), struct fsw_volume
*master
)
92 UINTN HandleCount
= 0;
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)
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
++) {
107 EFI_BLOCK_IO
*blockio
;
108 Status
= refit_call3_wrapper(BS
->HandleProtocol
, Handles
[i
], &gEfiDiskIoProtocolGuid
, (VOID
**) &diskio
);
111 Status
= refit_call3_wrapper(BS
->HandleProtocol
, Handles
[i
], &gEfiBlockIoProtocolGuid
, (VOID
**) &blockio
);
114 struct fsw_volume
*vol
= create_dummy_volume(diskio
, blockio
->Media
->MediaId
);
116 DPRINT(L
"Checking disk %d\n", i
);
117 if(hook(master
, vol
) == FSW_SUCCESS
)
119 free_dummy_volume(vol
);