Home | History | Annotate | Line # | Download | only in efiboot
efidisk.c revision 1.1
      1  1.1  nonaka /*	$NetBSD: efidisk.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $	*/
      2  1.1  nonaka 
      3  1.1  nonaka /*-
      4  1.1  nonaka  * Copyright (c) 2016 Kimihiro Nonaka <nonaka (at) netbsd.org>
      5  1.1  nonaka  * All rights reserved.
      6  1.1  nonaka  *
      7  1.1  nonaka  * Redistribution and use in source and binary forms, with or without
      8  1.1  nonaka  * modification, are permitted provided that the following conditions
      9  1.1  nonaka  * are met:
     10  1.1  nonaka  * 1. Redistributions of source code must retain the above copyright
     11  1.1  nonaka  *    notice, this list of conditions and the following disclaimer.
     12  1.1  nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  nonaka  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  nonaka  *    documentation and/or other materials provided with the distribution.
     15  1.1  nonaka  *
     16  1.1  nonaka  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     17  1.1  nonaka  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1  nonaka  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1  nonaka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     20  1.1  nonaka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  1.1  nonaka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  1.1  nonaka  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  1.1  nonaka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  1.1  nonaka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.1  nonaka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.1  nonaka  * SUCH DAMAGE.
     27  1.1  nonaka  */
     28  1.1  nonaka 
     29  1.1  nonaka #include "efiboot.h"
     30  1.1  nonaka 
     31  1.1  nonaka #include "efidisk.h"
     32  1.1  nonaka 
     33  1.1  nonaka static struct efidiskinfo_lh efi_disklist;
     34  1.1  nonaka static int nefidisks;
     35  1.1  nonaka 
     36  1.1  nonaka void
     37  1.1  nonaka efi_disk_probe(void)
     38  1.1  nonaka {
     39  1.1  nonaka 	EFI_STATUS status;
     40  1.1  nonaka 	UINTN i, nhandles;
     41  1.1  nonaka 	EFI_HANDLE *handles;
     42  1.1  nonaka 	EFI_BLOCK_IO *bio;
     43  1.1  nonaka 	EFI_BLOCK_IO_MEDIA *media;
     44  1.1  nonaka 	struct efidiskinfo *edi;
     45  1.1  nonaka 	EFI_DEVICE_PATH *dp, *bdp;
     46  1.1  nonaka 	bool bootdev;
     47  1.1  nonaka 	int dev;
     48  1.1  nonaka 
     49  1.1  nonaka 	TAILQ_INIT(&efi_disklist);
     50  1.1  nonaka 
     51  1.1  nonaka 	status = LibLocateHandle(ByProtocol, &BlockIoProtocol, NULL,
     52  1.1  nonaka 	    &nhandles, &handles);
     53  1.1  nonaka 	if (EFI_ERROR(status))
     54  1.1  nonaka 		Panic(L"LocateHandle(BlockIoProtocol): %r", status);
     55  1.1  nonaka 
     56  1.1  nonaka 	for (i = 0; i < nhandles; i++) {
     57  1.1  nonaka 		status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
     58  1.1  nonaka 		    &BlockIoProtocol, (void **)&bio);
     59  1.1  nonaka 		if (EFI_ERROR(status))
     60  1.1  nonaka 			Panic(L"HandleProtocol(BlockIoProtocol): %r", status);
     61  1.1  nonaka 
     62  1.1  nonaka 		media = bio->Media;
     63  1.1  nonaka 		if (media->LogicalPartition || !media->MediaPresent)
     64  1.1  nonaka 			continue;
     65  1.1  nonaka 
     66  1.1  nonaka 		edi = alloc(sizeof(struct efidiskinfo));
     67  1.1  nonaka 		memset(edi, 0, sizeof(*edi));
     68  1.1  nonaka 		edi->bio = bio;
     69  1.1  nonaka 		edi->media_id = media->MediaId;
     70  1.1  nonaka 
     71  1.1  nonaka 		bootdev = false;
     72  1.1  nonaka 		if (efi_bootdp == NULL)
     73  1.1  nonaka 			goto next;
     74  1.1  nonaka 
     75  1.1  nonaka 		status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
     76  1.1  nonaka 		    &DevicePathProtocol, (void **)&dp);
     77  1.1  nonaka 		if (EFI_ERROR(status))
     78  1.1  nonaka 			goto next;
     79  1.1  nonaka 
     80  1.1  nonaka 		bdp = efi_bootdp;
     81  1.1  nonaka 		for (;;) {
     82  1.1  nonaka 			if (IsDevicePathEnd(dp)) {
     83  1.1  nonaka 				bootdev = true;
     84  1.1  nonaka 				break;
     85  1.1  nonaka 			}
     86  1.1  nonaka 			if (memcmp(dp, bdp, sizeof(EFI_DEVICE_PATH)) != 0 ||
     87  1.1  nonaka 			    memcmp(dp, bdp, DevicePathNodeLength(dp)) != 0)
     88  1.1  nonaka 				break;
     89  1.1  nonaka 			dp = NextDevicePathNode(dp);
     90  1.1  nonaka 			bdp = NextDevicePathNode(bdp);
     91  1.1  nonaka 		}
     92  1.1  nonaka next:
     93  1.1  nonaka 		if (bootdev)
     94  1.1  nonaka 			TAILQ_INSERT_HEAD(&efi_disklist, edi, list);
     95  1.1  nonaka 		else
     96  1.1  nonaka 			TAILQ_INSERT_TAIL(&efi_disklist, edi, list);
     97  1.1  nonaka 	}
     98  1.1  nonaka 
     99  1.1  nonaka 	FreePool(handles);
    100  1.1  nonaka 
    101  1.1  nonaka 	dev = 0x80;
    102  1.1  nonaka 	TAILQ_FOREACH(edi, &efi_disklist, list) {
    103  1.1  nonaka 		edi->dev = dev++;
    104  1.1  nonaka 		nefidisks++;
    105  1.1  nonaka 	}
    106  1.1  nonaka }
    107  1.1  nonaka 
    108  1.1  nonaka const struct efidiskinfo *
    109  1.1  nonaka efidisk_getinfo(int dev)
    110  1.1  nonaka {
    111  1.1  nonaka 	const struct efidiskinfo *edi;
    112  1.1  nonaka 
    113  1.1  nonaka 	TAILQ_FOREACH(edi, &efi_disklist, list) {
    114  1.1  nonaka 		if (dev == edi->dev)
    115  1.1  nonaka 			return edi;
    116  1.1  nonaka 	}
    117  1.1  nonaka 	return NULL;
    118  1.1  nonaka }
    119  1.1  nonaka 
    120  1.1  nonaka /*
    121  1.1  nonaka  * Return the number of hard disk drives.
    122  1.1  nonaka  */
    123  1.1  nonaka int
    124  1.1  nonaka get_harddrives(void)
    125  1.1  nonaka {
    126  1.1  nonaka 	return nefidisks;
    127  1.1  nonaka }
    128