devpath.h revision 1.1 1 /* $NetBSD: devpath.h,v 1.1 2025/02/24 13:47:56 christos Exp $ */
2
3 /*
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
14 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #ifndef _DEVPATH_H_
27 #define _DEVPATH_H_
28
29 #ifndef lint
30 __RCSID("$NetBSD: devpath.h,v 1.1 2025/02/24 13:47:56 christos Exp $");
31 #endif /* not lint */
32
33 #include <stdlib.h>
34 #include <util.h>
35
36 typedef struct EFI_DEVICE_PATH_PROTOCOL {
37 uint8_t Type;
38 uint8_t SubType;
39 // uint8_t Length[2];
40 uint16_t Length;
41 uint8_t Data[];
42 } EFI_DEVICE_PATH_PROTOCOL;
43
44 typedef EFI_DEVICE_PATH_PROTOCOL devpath_t;
45
46 typedef struct devpath_elm {
47 size_t sz;
48 char *cp;
49 } devpath_elm_t;
50
51 enum {
52 DEVPATH_TYPE_HW = 1,
53 DEVPATH_TYPE_ACPI = 2,
54 DEVPATH_TYPE_MSG = 3,
55 DEVPATH_TYPE_MEDIA = 4,
56 DEVPATH_TYPE_BIOS = 5,
57 DEVPATH_TYPE_END = 0x7f,
58 };
59
60 #define DEVPATH_END_ALL \
61 ((EFI_DEVICE_PATH_PROTOCOL){.Type = 0x7f, .SubType = 0xff, .Length = 0x04})
62 #define DEVPATH_END_SEG \
63 ((EFI_DEVICE_PATH_PROTOCOL){.Type = 0x7f, .SubType = 0x01, .Length = 0x04})
64
65 /*
66 * For debugging
67 */
68 #define DEVPATH_FMT_HDR " DevPath_Hdr: Type %u, SubType: %u, Length: %u\n"
69 #define DEVPATH_FMT_PFX " "
70 #define DEVPATH_FMT(s) DEVPATH_FMT_PFX #s
71 #define DEVPATH_DAT_HDR(dp) (dp)->Type, (dp)->SubType, (dp)->Length
72
73 static inline char *
74 aconcat(char *bp1, const char *sep, char *bp2)
75 {
76 char *bp;
77
78 easprintf(&bp, "%s%s%s", bp1, sep, bp2);
79 free(bp1);
80 free(bp2);
81 return bp;
82 }
83
84 static inline const char *
85 devpath_type_name(size_t type)
86 {
87 static const char *type_tbl[] = {
88 [DEVPATH_TYPE_HW] = "HW",
89 [DEVPATH_TYPE_ACPI] = "ACPI",
90 [DEVPATH_TYPE_MSG] = "MSG",
91 [DEVPATH_TYPE_MEDIA] = "MEDIA",
92 [DEVPATH_TYPE_BIOS] = "BIOS",
93 };
94
95 if (type == DEVPATH_TYPE_END)
96 return "END";
97
98 if (type > __arraycount(type_tbl) || type == 0)
99 return "UNKNOWN";
100
101 return type_tbl[type];
102
103 }
104
105 static inline void
106 devpath_hdr(devpath_t *dp, devpath_elm_t *elm)
107 {
108
109 elm->sz = (size_t)easprintf(&elm->cp,
110 DEVPATH_FMT_HDR, DEVPATH_DAT_HDR(dp));
111 }
112
113 static inline void
114 devpath_unsupported(devpath_t *dp, devpath_elm_t *path, devpath_elm_t *dbg)
115 {
116
117 path->sz = (size_t)easprintf(&path->cp,
118 "[unsupported devpath type: %s(%u), subtype: %u]",
119 devpath_type_name(dp->Type), dp->Type, dp->SubType);
120
121 if (dbg != NULL)
122 devpath_hdr(dp, dbg);
123 }
124
125 char *devpath_parse(devpath_t *, size_t, char **);
126
127 #endif /* _DEVPATH_H_ */
128