1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 * Copyright 2020 Oxide Computer Company 15 */ 16 17 /* 18 * Create /devices links for various sensors. The sensor series of node types 19 * all begin with ddi_sensor. After which, there is a series of : delineated 20 * paths in the node type. Those represent the directory under /dev/sensors that 21 * the nodes should ultimately be created. 22 * 23 * For example, ddi_sensor:temperature:cpu would cause us to place the named 24 * minor under /dev/sensors/temperature/cpu/. Currently it is up to drivers to 25 * not conflict in names or if there is a fear of conflicting, make sure their 26 * minor is unique. 27 */ 28 29 #include <devfsadm.h> 30 #include <string.h> 31 32 #define SENSORS_BASE "sensors" 33 34 static int 35 sensor_link(di_minor_t minor, di_node_t node) 36 { 37 const char *t, *dir_path = NULL; 38 char *type, *name, *c; 39 char buf[PATH_MAX]; 40 size_t len; 41 42 if ((t = di_minor_nodetype(minor)) == NULL) { 43 return (DEVFSADM_CONTINUE); 44 } 45 46 if ((type = strdup(t)) == NULL) { 47 return (DEVFSADM_TERMINATE); 48 } 49 50 c = type; 51 while ((c = strchr(c, ':')) != NULL) { 52 if (dir_path == NULL) { 53 dir_path = c + 1; 54 } 55 *c = '/'; 56 } 57 58 if ((t = di_minor_name(minor)) == NULL) { 59 free(type); 60 return (DEVFSADM_CONTINUE); 61 } 62 63 if ((name = strdup(t)) == NULL) { 64 free(type); 65 return (DEVFSADM_TERMINATE); 66 } 67 68 c = name; 69 while ((c = strchr(c, ':')) != NULL) { 70 *c = '/'; 71 } 72 73 74 if (dir_path == NULL || *dir_path == '\0') { 75 len = snprintf(buf, sizeof (buf), "%s/%s", SENSORS_BASE, 76 name); 77 } else { 78 len = snprintf(buf, sizeof (buf), "%s/%s/%s", SENSORS_BASE, 79 dir_path, name); 80 } 81 82 if (len < sizeof (buf)) { 83 (void) devfsadm_mklink(buf, node, minor, 0); 84 } 85 86 free(type); 87 free(name); 88 return (DEVFSADM_CONTINUE); 89 } 90 91 static devfsadm_create_t sensor_create_cbt[] = { 92 { NULL, "ddi_sensor", NULL, TYPE_PARTIAL, ILEVEL_0, sensor_link } 93 }; 94 DEVFSADM_CREATE_INIT_V0(sensor_create_cbt); 95