File: linux.h

package info (click to toggle)
efivar 37-6
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 1,648 kB
  • sloc: ansic: 10,605; makefile: 234; asm: 34
file content (359 lines) | stat: -rw-r--r-- 13,665 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/*
 * libefiboot - library for the manipulation of EFI boot variables
 * Copyright 2012-2019 Red Hat, Inc.
 * Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
 *
 */
#ifndef _EFIBOOT_LINUX_H
#define _EFIBOOT_LINUX_H

struct acpi_root_info {
        uint32_t acpi_hid;
        uint64_t acpi_uid;
        uint32_t acpi_cid;
        char *acpi_hid_str;
        char *acpi_uid_str;
        char *acpi_cid_str;
};

struct pci_root_info {
        uint16_t pci_domain;
        uint8_t pci_bus;
};

struct pci_dev_info {
        uint16_t pci_domain;
        uint8_t pci_bus;
        uint8_t pci_device;
        uint8_t pci_function;
        char *driverlink;
};

struct scsi_info {
        uint32_t scsi_bus;
        uint32_t scsi_device;
        uint32_t scsi_target;
        uint64_t scsi_lun;
};

struct sas_info {
        uint32_t scsi_bus;
        uint32_t scsi_device;
        uint32_t scsi_target;
        uint64_t scsi_lun;

        uint64_t sas_address;
};

struct sata_info {
        uint32_t scsi_bus;
        uint32_t scsi_device;
        uint32_t scsi_target;
        uint64_t scsi_lun;

        uint32_t ata_devno;
        uint32_t ata_port;
        uint32_t ata_pmp;

        uint32_t ata_print_id;
};

struct ata_info {
        uint32_t scsi_bus;
        uint32_t scsi_device;
        uint32_t scsi_target;
        uint64_t scsi_lun;

        uint32_t scsi_host;
};

struct nvme_info {
        int32_t ctrl_id;
        int32_t ns_id;
        int has_eui;
        uint8_t eui[8];
};

struct nvdimm_info {
        efi_guid_t namespace_label;
        efi_guid_t nvdimm_label;
};

struct emmc_info {
       int32_t slot_id;
};

enum interface_type {
        unknown,
	isa, acpi_root, pci_root, soc_root, virtual_root,
	pci, network,
        ata, atapi, scsi, sata, sas,
        usb, i1394, fibre, i2o,
        md, virtblk,
        nvme, nd_pmem,
        emmc,
};

struct dev_probe;

struct device {
        enum interface_type interface_type;
        uint32_t flags;
        char *link;
        char *device;
        char *driver;

        struct dev_probe **probes;
        unsigned int n_probes;

        union {
                struct {
                        struct stat stat;

                        unsigned int controllernum;
                        unsigned int disknum;
                        int part;
                        uint64_t major;
                        uint32_t minor;
                        uint32_t edd10_devicenum;

                        char *disk_name;
                        char *part_name;

                        struct acpi_root_info acpi_root;
                        struct pci_root_info pci_root;
                        unsigned int n_pci_devs;
                        struct pci_dev_info *pci_dev;

                        union {
                                struct scsi_info scsi_info;
                                struct sas_info sas_info;
                                struct sata_info sata_info;
                                struct ata_info ata_info;
                                struct nvme_info nvme_info;
                                struct emmc_info emmc_info;
                                struct nvdimm_info nvdimm_info;
                        };
                };
                char *ifname;
        };
};

extern struct device HIDDEN *device_get(int fd, int partition);
extern void HIDDEN device_free(struct device *dev);
extern int HIDDEN set_disk_and_part_name(struct device *dev);
extern int HIDDEN set_part(struct device *dev, int value);
extern int HIDDEN set_part_name(struct device *dev, const char * const fmt, ...);
extern int HIDDEN set_disk_name(struct device *dev, const char * const fmt, ...);
extern bool HIDDEN is_pata(struct device *dev);
extern int HIDDEN make_blockdev_path(uint8_t *buf, ssize_t size,
                                     struct device *dev);
extern int HIDDEN parse_acpi_hid_uid(struct device *dev, const char *fmt, ...);
extern int HIDDEN eb_nvme_ns_id(int fd, uint32_t *ns_id);

int HIDDEN get_sector_size(int filedes);

extern int HIDDEN find_parent_devpath(const char * const child,
                                      char **parent);

extern ssize_t HIDDEN make_mac_path(uint8_t *buf, ssize_t size,
                                    const char * const ifname);

#define read_sysfs_file(buf, fmt, args...)                              \
        ({                                                              \
                uint8_t *buf_ = NULL;                                   \
                ssize_t bufsize_ = -1;                                  \
                int error_;                                             \
                                                                        \
                bufsize_ = get_file(&buf_, "/sys/" fmt, ## args);       \
                if (bufsize_ > 0) {                                     \
                        uint8_t *buf2_ = alloca(bufsize_);              \
                        error_ = errno;                                 \
                        if (buf2_)                                      \
                                memcpy(buf2_, buf_, bufsize_);          \
                        free(buf_);                                     \
                        *(buf) = (__typeof__(*(buf)))buf2_;             \
                        errno = error_;                                 \
                } else if (buf_) {                                      \
                        /* covscan is _sure_ we leak buf_ if bufsize_ */\
                        /* is <= 0, which is wrong, but appease it.   */\
                        free(buf_);                                     \
                        buf_ = NULL;                                    \
                }                                                       \
                bufsize_;                                               \
        })

#define sysfs_access(mode, fmt, args...)				\
	({								\
		int rc_;						\
		char *pn_;						\
									\
		rc_ = asprintfa(&pn_, "/sys/" fmt, ## args);		\
		if (rc_ >= 0) {						\
			rc_ = access(pn_, mode);			\
			if (rc_ < 0)					\
				efi_error("could not access %s", pn_);  \
		} else {						\
			efi_error("could not allocate memory");		\
		}							\
		rc_;							\
	})

#define sysfs_readlink(linkbuf, fmt, args...)                           \
        ({                                                              \
                char *_lb = alloca(PATH_MAX+1);                         \
                char *_pn;                                              \
                int _rc;                                                \
                                                                        \
                *(linkbuf) = NULL;                                      \
                _rc = asprintfa(&_pn, "/sys/" fmt, ## args);            \
                if (_rc >= 0) {                                         \
                        ssize_t _linksz;                                \
                        _rc = _linksz = readlink(_pn, _lb, PATH_MAX);   \
                        if (_linksz >= 0)                               \
                                _lb[_linksz] = '\0';                    \
                        else                                            \
                                efi_error("readlink of %s failed", _pn);\
                        *(linkbuf) = _lb;                               \
                } else {                                                \
                        efi_error("could not allocate memory");         \
                }                                                       \
                _rc;                                                    \
        })

#define sysfs_stat(statbuf, fmt, args...)                               \
        ({                                                              \
                int rc_;                                                \
                char *pn_;                                              \
                                                                        \
                rc_ = asprintfa(&pn_, "/sys/" fmt, ## args);            \
                if (rc_ >= 0) {                                         \
                        rc_ = stat(pn_, statbuf);                       \
                        if (rc_ < 0)                                    \
                                efi_error("could not stat %s", pn_);    \
                } else {                                                \
                        efi_error("could not allocate memory");         \
                }                                                       \
                rc_;                                                    \
        })

#define sysfs_opendir(fmt, args...)                                     \
        ({                                                              \
                int rc_;                                                \
                char *pn_;                                              \
                DIR *dir_ = NULL;                                       \
                                                                        \
                rc_ = asprintfa(&pn_, "/sys/" fmt, ## args);            \
                if (rc_ >= 0) {                                         \
                        dir_ = opendir(pn_);                            \
                        if (dir_ == NULL)                               \
                                efi_error("could not open %s", pn_);    \
                } else {                                                \
                        efi_error("could not allocate memory");         \
                }                                                       \
                dir_;                                                   \
        })

/*
 * Iterate a /sys/block directory looking for device/foo, device/device/foo,
 * etc.  I'm not proud of this method.
 */
#define find_device_file(result, name, fmt, args...)				\
	({									\
		int rc_ = 0;							\
		debug("searching for %s from in %s", name, dev->disk_name);	\
		for (unsigned int try_ = 0; true; try_++) {			\
			char slashdev_[sizeof("device")				\
				       + try_ * strlen("/device")];		\
										\
			char *nul_ = stpcpy(slashdev_, "device");		\
			for (unsigned int i_ = 0; i_ < try_; i_++)		\
				nul_ = stpcpy(nul_, "/device");			\
										\
			debug("trying /sys/" fmt "/%s/%s",			\
			      ## args, slashdev_, name);			\
										\
			rc_ = sysfs_access(F_OK, fmt "/%s", ## args, slashdev_);\
			if (rc_ < 0) {						\
				if (errno == ENOENT) {				\
					break;					\
				}						\
				efi_error("cannot access /sys/"fmt"/%s: %m",	\
					  ## args, slashdev_);			\
				goto find_device_link_err_;			\
			}							\
										\
			rc_ = sysfs_access(F_OK, fmt "/%s/%s",			\
					   ## args, slashdev_, name);		\
			if (rc_ < 0) {						\
				if (errno == ENOENT) {				\
					break;					\
				}						\
				efi_error("cannot access /sys/"fmt"/%s/%s: %m",	\
					  ## args, slashdev_, name);		\
				goto find_device_link_err_;			\
			}							\
										\
			rc_ = asprintfa(result, fmt "/%s/%s",			\
					## args, slashdev_, name);		\
			if (rc_ < 0) {						\
				efi_error("cannot allocate memory: %m");	\
				goto find_device_link_err_;			\
			}							\
		}								\
find_device_link_err_:								\
		rc_;								\
	})

#define DEV_PROVIDES_ROOT       1
#define DEV_PROVIDES_HD         2
#define DEV_ABBREV_ONLY         4

struct dev_probe {
        char *name;
        enum interface_type *iftypes;
        uint32_t flags;
        ssize_t (*parse)(struct device *dev,
                         const char * const current, const char * const root);
        ssize_t (*create)(struct device *dev,
                          uint8_t *buf, ssize_t size, ssize_t off);
        char *(*make_part_name)(struct device *dev);
};

extern ssize_t parse_scsi_link(const char *current, uint32_t *host,
                               uint32_t *bus, uint32_t *device,
                               uint32_t *target, uint64_t *lun,
                               uint32_t *local_port_id, uint32_t *remote_port_id,
                               uint32_t *remote_target_id);

/* device support implementations */
extern struct dev_probe pmem_parser;
extern struct dev_probe pci_root_parser;
extern struct dev_probe acpi_root_parser;
extern struct dev_probe soc_root_parser;
extern struct dev_probe virtual_root_parser;
extern struct dev_probe pci_parser;
extern struct dev_probe sas_parser;
extern struct dev_probe sata_parser;
extern struct dev_probe nvme_parser;
extern struct dev_probe virtblk_parser;
extern struct dev_probe i2o_parser;
extern struct dev_probe scsi_parser;
extern struct dev_probe ata_parser;
extern struct dev_probe emmc_parser;

#endif /* _EFIBOOT_LINUX_H */