2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 * Copyright (C) 2018 Huaxintong Semiconductor Technology Co.,Ltd. All rights
17 * Author: Ge Song <ge.song@hxt-semitech.com>
26 #include <sys/ioctl.h>
30 #include "talloc/talloc.h"
32 static const char *efivarfs_path;
34 inline void set_efivarfs_path(const char *path)
39 inline const char *get_efivarfs_path(void)
45 int efi_del_variable(void *ctx, const char *guidstr,
48 int fd, flag, errno_value;
53 dir = get_efivarfs_path();
57 path = talloc_asprintf(ctx, "%s%s-%s", dir, name, guidstr);
61 fd = open(path, O_RDONLY|O_NONBLOCK);
65 rc = ioctl(fd, FS_IOC_GETFLAGS, &flag);
69 flag &= ~FS_IMMUTABLE_FL;
70 rc = ioctl(fd, FS_IOC_SETFLAGS, &flag);
86 int efi_get_variable(void *ctx, const char *guidstr, const char *name,
87 uint8_t **data, size_t *data_size, uint32_t *attributes)
92 size_t bufsize = 4096;
98 dir = get_efivarfs_path();
102 path = talloc_asprintf(ctx, "%s%s-%s", dir, name, guidstr);
106 fd = open(path, O_RDONLY|O_NONBLOCK);
110 buf = talloc_size(ctx, bufsize);
116 sz = read(fd, p, bufsize);
117 if (sz < 0 && errno == EAGAIN) {
119 } else if (sz == 0) {
125 *attributes = *(uint32_t *)buf;
126 *data = (uint8_t *)(buf + sizeof(uint32_t));
127 *data_size = strlen(buf + sizeof(uint32_t));
139 int efi_set_variable(void *ctx, const char *guidstr, const char *name,
140 uint8_t *data, size_t data_size, uint32_t attributes)
142 int rc = -1, errno_value;
151 dir = get_efivarfs_path();
155 path = talloc_asprintf(ctx, "%s%s-%s", dir, name, guidstr);
159 if (!access(path, F_OK)) {
160 rc = efi_del_variable(ctx, guidstr, name);
166 fd = open(path, O_CREAT|O_WRONLY, mask);
170 bufsize = sizeof(uint32_t) + data_size;
171 buf = talloc_size(ctx, bufsize);
175 *(uint32_t *)buf = attributes;
176 memcpy(buf + sizeof(uint32_t), data, data_size);
178 len = write(fd, buf, bufsize);
179 if ((size_t)len != bufsize)