2 * libefivar - library for the manipulation of EFI variables
3 * Copyright 2012-2015 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
21 #include <arpa/inet.h>
26 #include <efivar/efivar.h>
27 #include "efivar_endian.h"
31 format_ipv4_addr_helper(char *buf, size_t size,
32 const char *dp_type __attribute__((__unused__)),
33 uint8_t const *ipaddr, int32_t port)
36 format(buf, size, off, dp_type, "%hhu.%hhu.%hhu.%hhu",
37 ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
39 format(buf, size, off, dp_type, ":%hu", port);
44 format_ipv6_addr_helper(char *buf, size_t size,
45 const char *dp_type __attribute__((__unused__)),
46 uint8_t const *ipaddr, int32_t port)
48 uint16_t *ip = (uint16_t *)ipaddr;
51 format(buf, size, off, dp_type, "[");
53 // deciding how to print an ipv6 ip requires 2 passes, because
54 // RFC5952 says we have to use :: a) only once and b) to maximum effect.
55 int largest_zero_block_size = 0;
56 int largest_zero_block_offset = -1;
58 int this_zero_block_size = 0;
59 int this_zero_block_offset = -1;
61 int in_zero_block = 0;
64 for (i = 0; i < 8; i++) {
65 if (ip[i] != 0 && in_zero_block) {
66 if (this_zero_block_size > largest_zero_block_size) {
67 largest_zero_block_size = this_zero_block_size;
68 largest_zero_block_offset =
69 this_zero_block_offset;
70 this_zero_block_size = 0;
71 this_zero_block_offset = -1;
76 if (in_zero_block == 0) {
78 this_zero_block_offset = i;
80 this_zero_block_size++;
83 if (this_zero_block_size > largest_zero_block_size) {
84 largest_zero_block_size = this_zero_block_size;
85 largest_zero_block_offset = this_zero_block_offset;
86 this_zero_block_size = 0;
87 this_zero_block_offset = -1;
90 if (largest_zero_block_size == 1)
91 largest_zero_block_offset = -1;
93 for (i = 0; i < 8; i++) {
94 if (largest_zero_block_offset == i) {
95 format(buf, size, off, "IPv6", "::");
96 i += largest_zero_block_size -1;
99 format(buf, size, off, "IPv6", ":");
102 format(buf, size, off, "IPv6", "%x", ip[i]);
105 format(buf, size, off, "IPv6", "]");
107 format(buf, size, off, "Ipv6", ":%hu", port);
112 #define format_ipv4_addr(buf, size, off, addr, port) \
113 format_helper(format_ipv4_addr_helper, buf, size, off, \
116 #define format_ipv6_addr(buf, size, off, addr, port) \
117 format_helper(format_ipv6_addr_helper, buf, size, off, \
121 format_ip_addr_helper(char *buf, size_t size,
122 const char *dp_type __attribute__((__unused__)),
123 int is_ipv6, const efi_ip_addr_t *addr)
127 format_helper(format_ipv6_addr_helper, buf, size, off, "IPv6",
128 (const uint8_t *)&addr->v6, -1);
130 format_helper(format_ipv4_addr_helper, buf, size, off, "IPv4",
131 (const uint8_t *)&addr->v4, -1);
135 #define format_ip_addr(buf, size, off, dp_type, is_ipv6, addr) \
136 format_helper(format_ip_addr_helper, buf, size, off, \
137 dp_type, is_ipv6, addr)
140 format_uart(char *buf, size_t size,
141 const char *dp_type __attribute__((__unused__)),
146 char *labels[] = {"None", "Hardware", "XonXoff", ""};
148 value = dp->uart_flow_control.flow_control_map;
150 format(buf, size, off, "UartFlowControl",
151 "UartFlowControl(%d)", value);
154 format(buf, size, off, "UartFlowControl", "UartFlowControl(%s)",
160 format_sas(char *buf, size_t size,
161 const char *dp_type __attribute__((__unused__)),
165 const efidp_sas * const s = &dp->sas;
173 const char * const sassata_label[] = {"NoTopology", "SAS", "SATA"};
174 const char * const location_label[] = {"Internal", "External" };
175 const char * const connect_label[] = {"Direct", "Expanded" };
177 more_info = s->device_topology_info & EFIDP_SAS_TOPOLOGY_MASK;
180 sassata = (s->device_topology_info & EFIDP_SAS_DEVICE_MASK)
181 >> EFIDP_SAS_DEVICE_SHIFT;
182 if (sassata == EFIDP_SAS_DEVICE_SATA_EXTERNAL
183 || sassata == EFIDP_SAS_DEVICE_SAS_EXTERNAL)
186 if (sassata == EFIDP_SAS_DEVICE_SAS_INTERNAL
187 || sassata == EFIDP_SAS_DEVICE_SATA_INTERNAL)
192 connect = (s->device_topology_info & EFIDP_SAS_CONNECT_MASK)
193 >> EFIDP_SAS_CONNECT_SHIFT;
194 if (more_info == EFIDP_SAS_TOPOLOGY_NEXTBYTE)
195 drive_bay = s->drive_bay_id + 1;
198 format(buf, size, off, "SAS", "SAS(%"PRIx64",%"PRIx64",%"PRIx16",%s",
199 dp->subtype == EFIDP_MSG_SAS_EX ?
200 be64_to_cpu(s->sas_address) :
201 le64_to_cpu(s->sas_address),
202 dp->subtype == EFIDP_MSG_SAS_EX ?
203 be64_to_cpu(s->lun) :
205 s->rtp, sassata_label[sassata]);
208 format(buf, size, off, "SAS", ",%s,%s",
209 location_label[location], connect_label[connect]);
212 if (more_info == 2 && drive_bay >= 0) {
213 format(buf, size, off, "SAS", ",%d", drive_bay);
216 format(buf, size, off, "SAS", ")");
220 #define class_helper(buf, size, off, label, dp) \
221 format(buf, size, off, label, \
222 "%s(0x%"PRIx16",0x%"PRIx16",%d,%d)", \
224 dp->usb_class.vendor_id, \
225 dp->usb_class.product_id, \
226 dp->usb_class.device_subclass, \
227 dp->usb_class.device_protocol)
230 format_usb_class(char *buf, size_t size,
231 const char *dp_type __attribute__((__unused__)),
235 switch (dp->usb_class.device_class) {
236 case EFIDP_USB_CLASS_AUDIO:
237 class_helper(buf, size, off, "UsbAudio", dp);
239 case EFIDP_USB_CLASS_CDC_CONTROL:
240 class_helper(buf, size, off, "UsbCDCControl", dp);
242 case EFIDP_USB_CLASS_HID:
243 class_helper(buf, size, off, "UsbHID", dp);
245 case EFIDP_USB_CLASS_IMAGE:
246 class_helper(buf, size, off, "UsbImage", dp);
248 case EFIDP_USB_CLASS_PRINTER:
249 class_helper(buf, size, off, "UsbPrinter", dp);
251 case EFIDP_USB_CLASS_MASS_STORAGE:
252 class_helper(buf, size, off, "UsbMassStorage", dp);
254 case EFIDP_USB_CLASS_HUB:
255 class_helper(buf, size, off, "UsbHub", dp);
257 case EFIDP_USB_CLASS_CDC_DATA:
258 class_helper(buf, size, off, "UsbCDCData", dp);
260 case EFIDP_USB_CLASS_SMARTCARD:
261 class_helper(buf, size, off, "UsbSmartCard", dp);
263 case EFIDP_USB_CLASS_VIDEO:
264 class_helper(buf, size, off, "UsbVideo", dp);
266 case EFIDP_USB_CLASS_DIAGNOSTIC:
267 class_helper(buf, size, off, "UsbDiagnostic", dp);
269 case EFIDP_USB_CLASS_WIRELESS:
270 class_helper(buf, size, off, "UsbWireless", dp);
272 case EFIDP_USB_CLASS_254:
273 switch (dp->usb_class.device_subclass) {
274 case EFIDP_USB_SUBCLASS_FW_UPDATE:
275 format(buf, size, off, "UsbDeviceFirmwareUpdate",
276 "UsbDeviceFirmwareUpdate(0x%"PRIx16",0x%"PRIx16",%d)",
277 dp->usb_class.vendor_id,
278 dp->usb_class.product_id,
279 dp->usb_class.device_protocol);
281 case EFIDP_USB_SUBCLASS_IRDA_BRIDGE:
282 format(buf, size, off, "UsbIrdaBridge",
283 "UsbIrdaBridge(0x%"PRIx16",0x%"PRIx16",%d)",
284 dp->usb_class.vendor_id,
285 dp->usb_class.product_id,
286 dp->usb_class.device_protocol);
288 case EFIDP_USB_SUBCLASS_TEST_AND_MEASURE:
289 format(buf, size, off, "UsbTestAndMeasurement",
290 "UsbTestAndMeasurement(0x%"PRIx16",0x%"PRIx16",%d)",
291 dp->usb_class.vendor_id,
292 dp->usb_class.product_id,
293 dp->usb_class.device_protocol);
298 format(buf, size, off, "UsbClass",
299 "UsbClass(%"PRIx16",%"PRIx16",%d,%d)",
300 dp->usb_class.vendor_id,
301 dp->usb_class.product_id,
302 dp->usb_class.device_subclass,
303 dp->usb_class.device_protocol);
310 _format_message_dn(char *buf, size_t size, const_efidp dp)
313 switch (dp->subtype) {
314 case EFIDP_MSG_ATAPI:
315 format(buf, size, off, "Ata", "Ata(%d,%d,%d)",
316 dp->atapi.primary, dp->atapi.slave,
320 format(buf, size, off, "SCSI", "SCSI(%d,%d)",
321 dp->scsi.target, dp->scsi.lun);
323 case EFIDP_MSG_FIBRECHANNEL:
324 format(buf, size, off, "Fibre", "Fibre(%"PRIx64",%"PRIx64")",
325 le64_to_cpu(dp->fc.wwn),
326 le64_to_cpu(dp->fc.lun));
328 case EFIDP_MSG_FIBRECHANNELEX:
329 format(buf, size, off, "Fibre", "Fibre(%"PRIx64",%"PRIx64")",
330 be64_to_cpu(dp->fc.wwn),
331 be64_to_cpu(dp->fc.lun));
334 format(buf, size, off, "I1394", "I1394(0x%"PRIx64")",
338 format(buf, size, off, "USB", "USB(%d,%d)",
339 dp->usb.parent_port, dp->usb.interface);
342 format(buf, size, off, "I2O", "I2O(%d)", dp->i2o.target);
344 case EFIDP_MSG_INFINIBAND:
345 if (dp->infiniband.resource_flags &
346 EFIDP_INFINIBAND_RESOURCE_IOC_SERVICE) {
347 format(buf, size, off, "Infiniband",
348 "Infiniband(%08x,%"PRIx64"%"PRIx64",%"PRIx64",%"PRIu64",%"PRIu64")",
349 dp->infiniband.resource_flags,
350 dp->infiniband.port_gid[1],
351 dp->infiniband.port_gid[0],
352 dp->infiniband.service_id,
353 dp->infiniband.target_port_id,
354 dp->infiniband.device_id);
356 format(buf, size, off, "Infiniband",
357 "Infiniband(%08x,%"PRIx64"%"PRIx64",",
358 dp->infiniband.resource_flags,
359 dp->infiniband.port_gid[1],
360 dp->infiniband.port_gid[0]);
361 format_guid(buf, size, off, "Infiniband",
362 (efi_guid_t *)&dp->infiniband.ioc_guid);
363 format(buf, size, off, "Infiniband",
364 ",%"PRIu64",%"PRIu64")",
365 dp->infiniband.target_port_id,
366 dp->infiniband.device_id);
369 case EFIDP_MSG_MAC_ADDR:
370 format(buf, size, off, "MAC", "MAC(");
371 format_hex(buf, size, off, "MAC", dp->mac_addr.mac_addr,
372 dp->mac_addr.if_type < 2 ? 6
373 : sizeof(dp->mac_addr.mac_addr));
374 format(buf, size, off, "MAC", ",%d)", dp->mac_addr.if_type);
376 case EFIDP_MSG_IPv4: {
377 efidp_ipv4_addr const *a = &dp->ipv4_addr;
378 format(buf, size, off, "IPv4", "IPv4(");
379 format_ipv4_addr(buf, size, off,
380 a->local_ipv4_addr, a->local_port);
381 format_ipv4_addr(buf, size, off,
382 a->remote_ipv4_addr, a->remote_port);
383 format(buf, size, off, "IPv4", ",%hx,%hhx)",
384 a->protocol, a->static_ip_addr);
387 case EFIDP_MSG_VENDOR: {
391 ssize_t (*formatter)(char *buf, size_t size,
392 const char *dp_type __attribute__((__unused__)),
395 { .guid = EFIDP_PC_ANSI_GUID,
396 .label = "VenPcAnsi" },
397 { .guid = EFIDP_VT_100_GUID,
398 .label = "VenVt100" },
399 { .guid = EFIDP_VT_100_PLUS_GUID,
400 .label = "VenVt100Plus" },
401 { .guid = EFIDP_VT_UTF8_GUID,
402 .label = "VenUtf8" },
403 { .guid = EFIDP_MSG_DEBUGPORT_GUID,
404 .label = "DebugPort" },
405 { .guid = EFIDP_MSG_UART_GUID,
407 .formatter = format_uart },
408 { .guid = EFIDP_MSG_SAS_GUID,
410 .formatter = format_sas },
411 { .guid = efi_guid_empty,
415 ssize_t (*formatter)(char *buf, size_t size,
416 const char *dp_type __attribute__((__unused__)),
417 const_efidp dp) = NULL;
419 for (int i = 0; !efi_guid_is_zero(&subtypes[i].guid); i++) {
420 if (efi_guid_cmp(&subtypes[i].guid,
421 &dp->msg_vendor.vendor_guid))
424 if (subtypes[i].label[0])
425 label = subtypes[i].label;
426 formatter = subtypes[i].formatter;
430 if (!label && !formatter) {
431 format_vendor(buf, size, off, "VenMsg", dp);
433 } else if (!label && formatter) {
434 format_helper(formatter, buf, size, off, "VenMsg", dp);
438 format(buf, size, off, label, "%s(", label);
439 if (efidp_node_size(dp) >
440 (ssize_t)(sizeof (efidp_header)
441 + sizeof (efi_guid_t))) {
442 format_hex(buf, size, off, label,
443 dp->msg_vendor.vendor_data,
445 - sizeof (efidp_header)
446 - sizeof (efi_guid_t));
448 format(buf, size, off, label, ")");
451 case EFIDP_MSG_IPv6: {
452 efidp_ipv6_addr const *a = &dp->ipv6_addr;
458 sz = format_ipv6_addr(addr0, 0, tmpoff, a->local_ipv6_addr,
462 addr0 = alloca(sz+1);
464 sz = format_ipv6_addr(addr1, 0, tmpoff, a->remote_ipv6_addr,
468 addr1 = alloca(sz+1);
471 format_ipv6_addr(addr0, sz, tmpoff, a->local_ipv6_addr,
475 format_ipv6_addr(addr1, sz, tmpoff, a->remote_ipv6_addr,
478 format(buf, size, off, "IPv6", "IPv6(%s<->%s,%hx,%hhx)",
479 addr0, addr1, a->protocol, a->ip_addr_origin);
482 case EFIDP_MSG_UART: {
483 int parity = dp->uart.parity;
484 char parity_label[] = "DNEOMS";
485 int stop_bits = dp->uart.stop_bits;
486 char *sb_label[] = {"D", "1", "1.5", "2"};
488 format(buf, size, off, "Uart", "Uart(%"PRIu64",%d,",
489 dp->uart.baud_rate ? dp->uart.baud_rate : 115200,
490 dp->uart.data_bits ? dp->uart.data_bits : 8);
491 format(buf, size, off, "Uart",
492 parity > 5 ? "%d," : "%c,",
493 parity > 5 ? parity : parity_label[parity]);
495 format(buf, size, off, "Uart", "%d)", stop_bits);
497 format(buf, size, off, "Uart", "%s)",
498 sb_label[stop_bits]);
501 case EFIDP_MSG_USB_CLASS:
502 format_helper(format_usb_class, buf, size, off, "UsbClass", dp);
504 case EFIDP_MSG_USB_WWID: {
505 size_t limit = (efidp_node_size(dp)
506 - offsetof(efidp_usb_wwid, serial_number))
508 format(buf, size, off, "UsbWwid",
509 "UsbWwid(%"PRIx16",%"PRIx16",%d,",
510 dp->usb_wwid.vendor_id, dp->usb_wwid.product_id,
511 dp->usb_wwid.interface);
512 format_ucs2(buf, size, off, "UsbWwid",
513 dp->usb_wwid.serial_number, limit);
514 format(buf, size, off, "UsbWwid", ")");
518 format(buf, size, off, "Unit", "Unit(%d)", dp->lun.lun);
521 format(buf, size, off, "Sata", "Sata(%d,%d,%d)",
522 dp->sata.hba_port, dp->sata.port_multiplier_port,
525 case EFIDP_MSG_ISCSI: {
526 ssize_t sz = efidp_node_size(dp)
527 - offsetof(efidp_iscsi, target_name);
529 efi_error("bad DP node size");
533 if (sz > EFIDP_ISCSI_MAX_TARGET_NAME_LEN)
534 sz = EFIDP_ISCSI_MAX_TARGET_NAME_LEN;
536 char target_name[sz + 1];
537 memcpy(target_name, dp->iscsi.target_name, sz);
538 target_name[sz] = '\0';
541 memcpy(&lun, dp->iscsi.lun, sizeof (lun));
543 format(buf, size, off, "iSCSI",
544 "iSCSI(%s,%d,0x%"PRIx64",%s,%s,%s,%s)",
545 target_name, dp->iscsi.tpgt,
547 (dp->iscsi.options >> EFIDP_ISCSI_HEADER_DIGEST_SHIFT) & EFIDP_ISCSI_HEADER_CRC32 ? "CRC32" : "None",
548 (dp->iscsi.options >> EFIDP_ISCSI_DATA_DIGEST_SHIFT) & EFIDP_ISCSI_DATA_CRC32 ? "CRC32" : "None",
549 (dp->iscsi.options >> EFIDP_ISCSI_AUTH_SHIFT) & EFIDP_ISCSI_AUTH_NONE ? "None" : \
550 (dp->iscsi.options >> EFIDP_ISCSI_CHAP_SHIFT) & EFIDP_ISCSI_CHAP_UNI ? "CHAP_UNI" : "CHAP_BI",
551 dp->iscsi.protocol == 0 ? "TCP" : "Unknown");
555 format(buf, size, off, "Vlan", "Vlan(%d)", dp->vlan.vlan_id);
557 case EFIDP_MSG_SAS_EX:
558 format_sas(buf, size, NULL, dp);
561 format(buf, size, off, "NVMe", "NVMe(0x%"PRIx32","
562 "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X)",
563 dp->nvme.namespace_id, dp->nvme.ieee_eui_64[0],
564 dp->nvme.ieee_eui_64[1], dp->nvme.ieee_eui_64[2],
565 dp->nvme.ieee_eui_64[3], dp->nvme.ieee_eui_64[4],
566 dp->nvme.ieee_eui_64[5], dp->nvme.ieee_eui_64[6],
567 dp->nvme.ieee_eui_64[7]);
569 case EFIDP_MSG_URI: {
570 ssize_t sz = efidp_node_size(dp) - offsetof(efidp_uri, uri);
572 efi_error("bad DP node size");
577 memcpy(uri, dp->uri.uri, sz);
579 format(buf, size, off, "Uri", "Uri(%s)", uri);
583 format(buf, size, off, "UFS", "UFS(%d,0x%02x)",
584 dp->ufs.target_id, dp->ufs.lun);
587 format(buf, size, off, "SD", "SD(%d)", dp->sd.slot_number);
590 format(buf, size, off, "Bluetooth", "Bluetooth(");
591 format_hex_separated(buf, size, off, "Bluetooth", ":", 1,
592 dp->bt.addr, sizeof(dp->bt.addr));
593 format(buf, size, off, "Bluetooth", ")");
596 format(buf, size, off, "Wi-Fi", "Wi-Fi(");
597 format_hex_separated(buf, size, off, "Wi-Fi", ":", 1,
598 dp->wifi.ssid, sizeof(dp->wifi.ssid));
599 format(buf, size, off, "Wi-Fi", ")");
602 format(buf, size, off, "eMMC", "eMMC(%d)", dp->emmc.slot);
605 format(buf, size, off, "BluetoothLE", "BluetoothLE(");
606 format_hex_separated(buf, size, off, "BluetoothLE", ":", 1,
607 dp->btle.addr, sizeof(dp->btle.addr));
608 format(buf, size, off, "BluetoothLE", ",%d)",
611 case EFIDP_MSG_DNS: {
612 int end = (efidp_node_size(dp)
613 - sizeof(dp->dns.header)
614 - sizeof(dp->dns.is_ipv6)
615 ) / sizeof(efi_ip_addr_t);
616 format(buf, size, off, "Dns", "Dns(");
617 for (int i=0; i < end; i++) {
618 const efi_ip_addr_t *addr = &dp->dns.addrs[i];
620 format(buf, size, off, "Dns", ",");
621 format_ip_addr(buf, size, off, "Dns",
622 dp->dns.is_ipv6, addr);
627 format(buf, size, off, "Msg", "Msg(%d,", dp->subtype);
628 format_hex(buf, size, off, "Msg", (uint8_t *)dp+4,
629 efidp_node_size(dp)-4);
630 format(buf, size, off, "Msg", ")");
637 __attribute__((__visibility__ ("default")))
638 efidp_make_mac_addr(uint8_t *buf, ssize_t size, uint8_t if_type,
639 const uint8_t * const mac_addr, ssize_t mac_addr_size)
641 efidp_mac_addr *mac = (efidp_mac_addr *)buf;
643 ssize_t sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
644 EFIDP_MSG_MAC_ADDR, sizeof (*mac));
645 ssize_t req = sizeof (*mac);
646 if (size && sz == req) {
647 mac->if_type = if_type;
648 memcpy(mac->mac_addr, mac_addr,
649 mac_addr_size > 32 ? 32 : mac_addr_size);
653 efi_error("efidp_make_generic failed");
659 __attribute__((__visibility__ ("default")))
660 efidp_make_ipv4(uint8_t *buf, ssize_t size, uint32_t local, uint32_t remote,
661 uint32_t gateway, uint32_t netmask,
662 uint16_t local_port, uint16_t remote_port,
663 uint16_t protocol, int is_static)
665 efidp_ipv4_addr *ipv4 = (efidp_ipv4_addr *)buf;
666 ssize_t sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
667 EFIDP_MSG_IPv4, sizeof (*ipv4));
668 ssize_t req = sizeof (*ipv4);
669 if (size && sz == req) {
670 *((char *)ipv4->local_ipv4_addr) = htonl(local);
671 *((char *)ipv4->remote_ipv4_addr) = htonl(remote);
672 ipv4->local_port = htons(local_port);
673 ipv4->remote_port = htons(remote_port);
674 ipv4->protocol = htons(protocol);
675 ipv4->static_ip_addr = 0;
677 ipv4->static_ip_addr = 1;
678 *((char *)ipv4->gateway) = htonl(gateway);
679 *((char *)ipv4->netmask) = htonl(netmask);
683 efi_error("efidp_make_generic failed");
689 __attribute__((__visibility__ ("default")))
690 efidp_make_scsi(uint8_t *buf, ssize_t size, uint16_t target, uint16_t lun)
692 efidp_scsi *scsi = (efidp_scsi *)buf;
693 ssize_t req = sizeof (*scsi);
694 ssize_t sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
695 EFIDP_MSG_SCSI, sizeof (*scsi));
696 if (size && sz == req) {
697 scsi->target = target;
702 efi_error("efidp_make_generic failed");
708 __attribute__((__visibility__ ("default")))
709 efidp_make_nvme(uint8_t *buf, ssize_t size, uint32_t namespace_id,
710 uint8_t *ieee_eui_64)
712 efidp_nvme *nvme = (efidp_nvme *)buf;
713 ssize_t req = sizeof (*nvme);
716 sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
717 EFIDP_MSG_NVME, sizeof (*nvme));
718 if (size && sz == req) {
719 nvme->namespace_id = namespace_id;
721 memcpy(nvme->ieee_eui_64, ieee_eui_64,
722 sizeof (nvme->ieee_eui_64));
724 memset(nvme->ieee_eui_64, '\0',
725 sizeof (nvme->ieee_eui_64));
729 efi_error("efidp_make_generic failed");
735 __attribute__((__visibility__ ("default")))
736 efidp_make_sata(uint8_t *buf, ssize_t size, uint16_t hba_port,
737 int16_t port_multiplier_port, uint16_t lun)
739 efidp_sata *sata = (efidp_sata *)buf;
740 ssize_t req = sizeof (*sata);
743 sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
744 EFIDP_MSG_SATA, sizeof (*sata));
745 if (size && sz == req) {
746 sata->hba_port = hba_port;
747 sata->port_multiplier_port = port_multiplier_port;
752 efi_error("efidp_make_generic failed");
758 __attribute__((__visibility__ ("default")))
759 efidp_make_atapi(uint8_t *buf, ssize_t size, uint16_t primary,
760 uint16_t slave, uint16_t lun)
762 efidp_atapi *atapi = (efidp_atapi *)buf;
763 ssize_t req = sizeof (*atapi);
766 sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
767 EFIDP_MSG_ATAPI, sizeof (*atapi));
768 if (size && sz == req) {
769 atapi->primary = primary;
770 atapi->slave = slave;
775 efi_error("efidp_make_generic failed");
782 __attribute__((__visibility__ ("default")))
783 efidp_make_sas(uint8_t *buf, ssize_t size, uint64_t sas_address)
785 efidp_sas *sas = (efidp_sas *)buf;
786 ssize_t req = sizeof (*sas);
789 sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
790 EFIDP_MSG_VENDOR, sizeof (*sas));
791 if (size && sz == req) {
792 sas->vendor_guid = EFIDP_MSG_SAS_GUID;
794 sas->sas_address = sas_address;
796 sas->device_topology_info = 0;
797 sas->drive_bay_id = 0;
802 efi_error("efidp_make_generic failed");