Fri Aug 24 23:19:42 2018 UTC ()
If the boot device could not be determined, use the first one found as
the default. While here, remove unnecessary calls to LibFileSystemInfo().


(jmcneill)
diff -r1.1 -r1.2 src/sys/stand/efiboot/efifile.c

cvs diff -r1.1 -r1.2 src/sys/stand/efiboot/efifile.c (switch to unified diff)

--- src/sys/stand/efiboot/efifile.c 2018/08/24 02:01:06 1.1
+++ src/sys/stand/efiboot/efifile.c 2018/08/24 23:19:42 1.2
@@ -1,163 +1,160 @@ @@ -1,163 +1,160 @@
1/* $NetBSD: efifile.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */ 1/* $NetBSD: efifile.c,v 1.2 2018/08/24 23:19:42 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/param.h> 29#include <sys/param.h>
30 30
31#include "efiboot.h" 31#include "efiboot.h"
32#include "efifile.h" 32#include "efifile.h"
33 33
34static EFI_HANDLE *efi_vol; 34static EFI_HANDLE *efi_vol;
35static UINTN efi_nvol; 35static UINTN efi_nvol;
36static int efi_bootvol = -1; 36static int efi_bootvol = -1;
37 37
38static int 38static int
39efi_file_parse(const char *fname, UINTN *pvol, const char **pfile) 39efi_file_parse(const char *fname, UINTN *pvol, const char **pfile)
40{ 40{
41 intmax_t vol; 41 intmax_t vol;
42 char *ep = NULL; 42 char *ep = NULL;
43 43
44 if (strchr(fname, ':') != NULL) { 44 if (strchr(fname, ':') != NULL) {
45 if (strncasecmp(fname, "fs", 2) != 0) 45 if (strncasecmp(fname, "fs", 2) != 0)
46 return EINVAL; 46 return EINVAL;
47 vol = strtoimax(fname + 2, &ep, 10); 47 vol = strtoimax(fname + 2, &ep, 10);
48 if (vol < 0 || vol >= efi_nvol || *ep != ':') 48 if (vol < 0 || vol >= efi_nvol || *ep != ':')
49 return ENXIO; 49 return ENXIO;
50 *pvol = vol; 50 *pvol = vol;
51 *pfile = ep + 1; 51 *pfile = ep + 1;
52 } else if (efi_bootvol != -1) { 52 } else if (efi_bootvol != -1) {
53 *pvol = efi_bootvol; 53 *pvol = efi_bootvol;
54 *pfile = fname; 54 *pfile = fname;
55 } else { 55 } else {
56 return EINVAL; 56 return EINVAL;
57 } 57 }
58 58
59 return 0; 59 return 0;
60} 60}
61 61
62void 62void
63efi_file_system_probe(void) 63efi_file_system_probe(void)
64{ 64{
65 EFI_FILE_SYSTEM_INFO *fsi; 
66 EFI_FILE_HANDLE fh; 65 EFI_FILE_HANDLE fh;
67 EFI_STATUS status; 66 EFI_STATUS status;
68 int n; 67 int n;
69 68
70 status = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &efi_nvol, &efi_vol); 69 status = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &efi_nvol, &efi_vol);
71 if (EFI_ERROR(status)) 70 if (EFI_ERROR(status))
72 return; 71 return;
73 72
74 for (n = 0; n < efi_nvol; n++) { 73 for (n = 0; n < efi_nvol; n++) {
75 fh = LibOpenRoot(efi_vol[n]); 74 fh = LibOpenRoot(efi_vol[n]);
76 if (!fh) 75 if (!fh)
77 continue; 76 continue;
78 77
79 fsi = LibFileSystemInfo(fh); 
80 if (!fsi) 
81 continue; 
82 
83 if (efi_bootdp && LibMatchDevicePaths(DevicePathFromHandle(efi_vol[n]), efi_bootdp) == TRUE) 78 if (efi_bootdp && LibMatchDevicePaths(DevicePathFromHandle(efi_vol[n]), efi_bootdp) == TRUE)
84 efi_bootvol = n; 79 efi_bootvol = n;
 80 else if (efi_bootdp == NULL && efi_bootvol == -1)
 81 efi_bootvol = n;
85 } 82 }
86} 83}
87 84
88int 85int
89efi_file_open(struct open_file *f, ...) 86efi_file_open(struct open_file *f, ...)
90{ 87{
91 EFI_DEVICE_PATH *dp; 88 EFI_DEVICE_PATH *dp;
92 SIMPLE_READ_FILE srf; 89 SIMPLE_READ_FILE srf;
93 EFI_HANDLE device, file; 90 EFI_HANDLE device, file;
94 EFI_STATUS status; 91 EFI_STATUS status;
95 UINTN vol; 92 UINTN vol;
96 const char *fname, *path; 93 const char *fname, *path;
97 CHAR16 *upath; 94 CHAR16 *upath;
98 va_list ap; 95 va_list ap;
99 size_t len; 96 size_t len;
100 int rv; 97 int rv;
101 98
102 va_start(ap, f); 99 va_start(ap, f);
103 fname = va_arg(ap, const char *); 100 fname = va_arg(ap, const char *);
104 va_end(ap); 101 va_end(ap);
105 102
106 rv = efi_file_parse(fname, &vol, &path); 103 rv = efi_file_parse(fname, &vol, &path);
107 if (rv != 0) 104 if (rv != 0)
108 return rv; 105 return rv;
109 106
110 device = efi_vol[vol]; 107 device = efi_vol[vol];
111 108
112 upath = NULL; 109 upath = NULL;
113 rv = utf8_to_ucs2(path, &upath, &len); 110 rv = utf8_to_ucs2(path, &upath, &len);
114 if (rv != 0) 111 if (rv != 0)
115 return rv; 112 return rv;
116 113
117 dp = FileDevicePath(device, upath); 114 dp = FileDevicePath(device, upath);
118 FreePool(upath); 115 FreePool(upath);
119 if (dp == NULL) 116 if (dp == NULL)
120 return EINVAL; 117 return EINVAL;
121 118
122 status = OpenSimpleReadFile(TRUE, NULL, 0, &dp, &file, &srf); 119 status = OpenSimpleReadFile(TRUE, NULL, 0, &dp, &file, &srf);
123 FreePool(dp); 120 FreePool(dp);
124 if (EFI_ERROR(status)) 121 if (EFI_ERROR(status))
125 return status == EFI_NOT_FOUND ? ENOENT : EIO; 122 return status == EFI_NOT_FOUND ? ENOENT : EIO;
126 123
127 f->f_dev = &devsw[0]; 124 f->f_dev = &devsw[0];
128 f->f_devdata = f; 125 f->f_devdata = f;
129 f->f_fsdata = srf; 126 f->f_fsdata = srf;
130 f->f_flags = F_NODEV | F_READ; 127 f->f_flags = F_NODEV | F_READ;
131 128
132 return 0; 129 return 0;
133} 130}
134 131
135int 132int
136efi_file_close(struct open_file *f) 133efi_file_close(struct open_file *f)
137{ 134{
138 SIMPLE_READ_FILE srf = f->f_fsdata; 135 SIMPLE_READ_FILE srf = f->f_fsdata;
139 136
140 CloseSimpleReadFile(srf); 137 CloseSimpleReadFile(srf);
141 138
142 return 0; 139 return 0;
143} 140}
144 141
145int 142int
146efi_file_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize) 143efi_file_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
147{ 144{
148 struct open_file *f = devdata; 145 struct open_file *f = devdata;
149 SIMPLE_READ_FILE srf = f->f_fsdata; 146 SIMPLE_READ_FILE srf = f->f_fsdata;
150 EFI_STATUS status; 147 EFI_STATUS status;
151 UINTN len; 148 UINTN len;
152 149
153 if (rw != F_READ) 150 if (rw != F_READ)
154 return EROFS; 151 return EROFS;
155 152
156 len = size; 153 len = size;
157 status = ReadSimpleReadFile(srf, f->f_offset, &len, buf); 154 status = ReadSimpleReadFile(srf, f->f_offset, &len, buf);
158 if (EFI_ERROR(status)) 155 if (EFI_ERROR(status))
159 return EIO; 156 return EIO;
160 *rsize = len; 157 *rsize = len;
161 158
162 return 0; 159 return 0;
163} 160}