1 /* $NetBSD: devpath.h,v 1.3 2025/03/02 00:03:41 riastradh 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.3 2025/03/02 00:03:41 riastradh 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