15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
25 */
26
27 #include <regex.h>
28 #include <devfsadm.h>
29 #include <stdio.h>
30 #include <strings.h>
31 #include <stdlib.h>
32 #include <limits.h>
33 #include <sys/zone.h>
34 #include <sys/zcons.h>
35 #include <sys/cpuid_drv.h>
36
37 static int display(di_minor_t minor, di_node_t node);
38 static int parallel(di_minor_t minor, di_node_t node);
39 static int node_slash_minor(di_minor_t minor, di_node_t node);
40 static int driver_minor(di_minor_t minor, di_node_t node);
41 static int node_name(di_minor_t minor, di_node_t node);
42 static int minor_name(di_minor_t minor, di_node_t node);
43 static int wifi_minor_name(di_minor_t minor, di_node_t node);
44 static int conskbd(di_minor_t minor, di_node_t node);
45 static int consms(di_minor_t minor, di_node_t node);
46 static int power_button(di_minor_t minor, di_node_t node);
47 static int fc_port(di_minor_t minor, di_node_t node);
48 static int printer_create(di_minor_t minor, di_node_t node);
49 static int se_hdlc_create(di_minor_t minor, di_node_t node);
50 static int ppm(di_minor_t minor, di_node_t node);
51 static int gpio(di_minor_t minor, di_node_t node);
52 static int av_create(di_minor_t minor, di_node_t node);
53 static int tsalarm_create(di_minor_t minor, di_node_t node);
54 static int ntwdt_create(di_minor_t minor, di_node_t node);
55 static int zcons_create(di_minor_t minor, di_node_t node);
56 static int cpuid(di_minor_t minor, di_node_t node);
57 static int glvc(di_minor_t minor, di_node_t node);
58 static int ses_callback(di_minor_t minor, di_node_t node);
59 static int kmdrv_create(di_minor_t minor, di_node_t node);
60
61 static devfsadm_create_t misc_cbt[] = {
62 { "pseudo", "ddi_pseudo", "(^sad$)",
63 TYPE_EXACT | DRV_RE, ILEVEL_0, node_slash_minor
64 },
65 { "pseudo", "ddi_pseudo", "zsh",
66 TYPE_EXACT | DRV_EXACT, ILEVEL_0, driver_minor
67 },
68 { "network", "ddi_network", NULL,
69 TYPE_EXACT, ILEVEL_0, minor_name
70 },
71 { "wifi", "ddi_network:wifi", NULL,
72 TYPE_EXACT, ILEVEL_0, wifi_minor_name
73 },
74 { "display", "ddi_display", NULL,
75 TYPE_EXACT, ILEVEL_0, display
97 },
98 { "pseudo", "ddi_pseudo", "rsm",
99 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
100 },
101 { "pseudo", "ddi_pseudo",
102 "(^lockstat$)|(^SUNW,rtvc$)|(^vol$)|(^log$)|(^sy$)|"
103 "(^ksyms$)|(^clone$)|(^tl$)|(^tnf$)|(^kstat$)|(^mdesc$)|(^eeprom$)|"
104 "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|"
105 "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|"
106 "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|"
107 "(^sysevent$)|(^kssl$)|(^physmem$)",
108 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
109 },
110 { "pseudo", "ddi_pseudo",
111 "(^ip$)|(^tcp$)|(^udp$)|(^icmp$)|"
112 "(^ip6$)|(^tcp6$)|(^udp6$)|(^icmp6$)|"
113 "(^rts$)|(^arp$)|(^ipsecah$)|(^ipsecesp$)|(^keysock$)|(^spdsock$)|"
114 "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)",
115 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
116 },
117 { "pseudo", "ddi_pseudo", "ipd",
118 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
119 },
120 { "pseudo", "ddi_pseudo",
121 "(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|"
122 "(^ipsync$)|(^ipscan$)|(^iplookup$)",
123 TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
124 },
125 { "pseudo", "ddi_pseudo", "dld",
126 TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
127 },
128 { "pseudo", "ddi_pseudo",
129 "(^kdmouse$)|(^rootprop$)",
130 TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
131 },
132 { "pseudo", "ddi_pseudo", "timerfd",
133 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
134 },
135 { "pseudo", "ddi_pseudo", "tod",
136 TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
163 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
164 },
165 { "pseudo", "ddi_pseudo", "oplkmdrv",
166 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
167 },
168 { "av", "^ddi_av:(isoch|async)$", NULL,
169 TYPE_RE, ILEVEL_0, av_create,
170 },
171 { "pseudo", "ddi_pseudo", "tsalarm",
172 TYPE_EXACT | DRV_RE, ILEVEL_0, tsalarm_create,
173 },
174 { "pseudo", "ddi_pseudo", "ntwdt",
175 TYPE_EXACT | DRV_RE, ILEVEL_0, ntwdt_create,
176 },
177 { "pseudo", "ddi_pseudo", "daplt",
178 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
179 },
180 { "pseudo", "ddi_pseudo", "zcons",
181 TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create,
182 },
183 { "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME,
184 TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid,
185 },
186 { "pseudo", "ddi_pseudo", "glvc",
187 TYPE_EXACT | DRV_EXACT, ILEVEL_0, glvc,
188 },
189 { "pseudo", "ddi_pseudo", "dm2s",
190 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name,
191 },
192 { "pseudo", "ddi_pseudo", "nsmb",
193 TYPE_EXACT | DRV_EXACT, ILEVEL_1, minor_name,
194 },
195 { "pseudo", "ddi_pseudo", "mem_cache",
196 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
197 },
198 { "pseudo", "ddi_pseudo", "fm",
199 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
200 },
201 { "pseudo", "ddi_pseudo", "smbsrv",
202 TYPE_EXACT | DRV_EXACT, ILEVEL_1, minor_name,
211 static devfsadm_remove_t misc_remove_cbt[] = {
212 { "pseudo", "^profile$",
213 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
214 },
215 { "pseudo", "^rsm$",
216 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
217 },
218 { "printer", "^printers/[0-9]+$",
219 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
220 },
221 { "av", "^av/[0-9]+/(async|isoch)$",
222 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
223 },
224 { "pseudo", "^daplt$",
225 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
226 },
227 { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|"
228 ZCONS_SLAVE_NAME ")$",
229 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
230 },
231 { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT,
232 ILEVEL_0, devfsadm_rm_all
233 },
234 { "enclosure", "^es/ses[0-9]+$", RM_POST,
235 ILEVEL_0, devfsadm_rm_all
236 },
237 { "pseudo", "^pfil$",
238 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
239 },
240 { "pseudo", "^tpm$",
241 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
242 },
243 { "pseudo", "^sctp|sctp6$",
244 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_link
245 }
246 };
247
248 /* Rules for gpio devices */
249 static devfsadm_enumerate_t gpio_rules[1] =
250 {"^gpio([0-9]+)$", 1, MATCH_ALL};
655 }
656
657 static int
658 zcons_create(di_minor_t minor, di_node_t node)
659 {
660 char *minor_str;
661 char *zonename;
662 char path[MAXPATHLEN];
663
664 minor_str = di_minor_name(minor);
665
666 if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zonename",
667 &zonename) == -1) {
668 return (DEVFSADM_CONTINUE);
669 }
670
671 (void) snprintf(path, sizeof (path), "zcons/%s/%s", zonename,
672 minor_str);
673 (void) devfsadm_mklink(path, node, minor, 0);
674
675 return (DEVFSADM_CONTINUE);
676 }
677
678 /*
679 * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self
680 */
681 static int
682 cpuid(di_minor_t minor, di_node_t node)
683 {
684 (void) devfsadm_mklink(CPUID_SELF_NAME, node, minor, 0);
685 return (DEVFSADM_CONTINUE);
686 }
687
688 /*
689 * For device
690 * /dev/spfma -> /devices/virtual-devices/fma@5:glvc
691 */
692 static int
693 glvc(di_minor_t minor, di_node_t node)
694 {
|
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
25 */
26
27 #include <regex.h>
28 #include <devfsadm.h>
29 #include <stdio.h>
30 #include <strings.h>
31 #include <stdlib.h>
32 #include <limits.h>
33 #include <sys/zone.h>
34 #include <sys/zcons.h>
35 #include <sys/zfd.h>
36 #include <sys/cpuid_drv.h>
37
38 static int display(di_minor_t minor, di_node_t node);
39 static int parallel(di_minor_t minor, di_node_t node);
40 static int node_slash_minor(di_minor_t minor, di_node_t node);
41 static int driver_minor(di_minor_t minor, di_node_t node);
42 static int node_name(di_minor_t minor, di_node_t node);
43 static int minor_name(di_minor_t minor, di_node_t node);
44 static int wifi_minor_name(di_minor_t minor, di_node_t node);
45 static int conskbd(di_minor_t minor, di_node_t node);
46 static int consms(di_minor_t minor, di_node_t node);
47 static int power_button(di_minor_t minor, di_node_t node);
48 static int fc_port(di_minor_t minor, di_node_t node);
49 static int printer_create(di_minor_t minor, di_node_t node);
50 static int se_hdlc_create(di_minor_t minor, di_node_t node);
51 static int ppm(di_minor_t minor, di_node_t node);
52 static int gpio(di_minor_t minor, di_node_t node);
53 static int av_create(di_minor_t minor, di_node_t node);
54 static int tsalarm_create(di_minor_t minor, di_node_t node);
55 static int ntwdt_create(di_minor_t minor, di_node_t node);
56 static int zcons_create(di_minor_t minor, di_node_t node);
57 static int zfd_create(di_minor_t minor, di_node_t node);
58 static int cpuid(di_minor_t minor, di_node_t node);
59 static int glvc(di_minor_t minor, di_node_t node);
60 static int ses_callback(di_minor_t minor, di_node_t node);
61 static int kmdrv_create(di_minor_t minor, di_node_t node);
62
63 static devfsadm_create_t misc_cbt[] = {
64 { "pseudo", "ddi_pseudo", "(^sad$)",
65 TYPE_EXACT | DRV_RE, ILEVEL_0, node_slash_minor
66 },
67 { "pseudo", "ddi_pseudo", "zsh",
68 TYPE_EXACT | DRV_EXACT, ILEVEL_0, driver_minor
69 },
70 { "network", "ddi_network", NULL,
71 TYPE_EXACT, ILEVEL_0, minor_name
72 },
73 { "wifi", "ddi_network:wifi", NULL,
74 TYPE_EXACT, ILEVEL_0, wifi_minor_name
75 },
76 { "display", "ddi_display", NULL,
77 TYPE_EXACT, ILEVEL_0, display
99 },
100 { "pseudo", "ddi_pseudo", "rsm",
101 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
102 },
103 { "pseudo", "ddi_pseudo",
104 "(^lockstat$)|(^SUNW,rtvc$)|(^vol$)|(^log$)|(^sy$)|"
105 "(^ksyms$)|(^clone$)|(^tl$)|(^tnf$)|(^kstat$)|(^mdesc$)|(^eeprom$)|"
106 "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|"
107 "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|"
108 "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|"
109 "(^sysevent$)|(^kssl$)|(^physmem$)",
110 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
111 },
112 { "pseudo", "ddi_pseudo",
113 "(^ip$)|(^tcp$)|(^udp$)|(^icmp$)|"
114 "(^ip6$)|(^tcp6$)|(^udp6$)|(^icmp6$)|"
115 "(^rts$)|(^arp$)|(^ipsecah$)|(^ipsecesp$)|(^keysock$)|(^spdsock$)|"
116 "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)",
117 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
118 },
119 { "pseudo", "ddi_pseudo", "inotify",
120 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
121 },
122 { "pseudo", "ddi_pseudo", "ipd",
123 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
124 },
125 { "pseudo", "ddi_pseudo",
126 "(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|"
127 "(^ipsync$)|(^ipscan$)|(^iplookup$)",
128 TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
129 },
130 { "pseudo", "ddi_pseudo", "dld",
131 TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
132 },
133 { "pseudo", "ddi_pseudo",
134 "(^kdmouse$)|(^rootprop$)",
135 TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
136 },
137 { "pseudo", "ddi_pseudo", "timerfd",
138 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
139 },
140 { "pseudo", "ddi_pseudo", "tod",
141 TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
168 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
169 },
170 { "pseudo", "ddi_pseudo", "oplkmdrv",
171 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
172 },
173 { "av", "^ddi_av:(isoch|async)$", NULL,
174 TYPE_RE, ILEVEL_0, av_create,
175 },
176 { "pseudo", "ddi_pseudo", "tsalarm",
177 TYPE_EXACT | DRV_RE, ILEVEL_0, tsalarm_create,
178 },
179 { "pseudo", "ddi_pseudo", "ntwdt",
180 TYPE_EXACT | DRV_RE, ILEVEL_0, ntwdt_create,
181 },
182 { "pseudo", "ddi_pseudo", "daplt",
183 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
184 },
185 { "pseudo", "ddi_pseudo", "zcons",
186 TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create,
187 },
188 { "pseudo", "ddi_pseudo", "zfd",
189 TYPE_EXACT | DRV_EXACT, ILEVEL_0, zfd_create,
190 },
191 { "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME,
192 TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid,
193 },
194 { "pseudo", "ddi_pseudo", "glvc",
195 TYPE_EXACT | DRV_EXACT, ILEVEL_0, glvc,
196 },
197 { "pseudo", "ddi_pseudo", "dm2s",
198 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name,
199 },
200 { "pseudo", "ddi_pseudo", "nsmb",
201 TYPE_EXACT | DRV_EXACT, ILEVEL_1, minor_name,
202 },
203 { "pseudo", "ddi_pseudo", "mem_cache",
204 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
205 },
206 { "pseudo", "ddi_pseudo", "fm",
207 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
208 },
209 { "pseudo", "ddi_pseudo", "smbsrv",
210 TYPE_EXACT | DRV_EXACT, ILEVEL_1, minor_name,
219 static devfsadm_remove_t misc_remove_cbt[] = {
220 { "pseudo", "^profile$",
221 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
222 },
223 { "pseudo", "^rsm$",
224 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
225 },
226 { "printer", "^printers/[0-9]+$",
227 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
228 },
229 { "av", "^av/[0-9]+/(async|isoch)$",
230 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
231 },
232 { "pseudo", "^daplt$",
233 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
234 },
235 { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|"
236 ZCONS_SLAVE_NAME ")$",
237 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
238 },
239 { "pseudo", "^zfd/" ZONENAME_REGEXP "/(master|slave)/[0-9]+$",
240 RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
241 },
242 { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT,
243 ILEVEL_0, devfsadm_rm_all
244 },
245 { "enclosure", "^es/ses[0-9]+$", RM_POST,
246 ILEVEL_0, devfsadm_rm_all
247 },
248 { "pseudo", "^pfil$",
249 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
250 },
251 { "pseudo", "^tpm$",
252 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
253 },
254 { "pseudo", "^sctp|sctp6$",
255 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_link
256 }
257 };
258
259 /* Rules for gpio devices */
260 static devfsadm_enumerate_t gpio_rules[1] =
261 {"^gpio([0-9]+)$", 1, MATCH_ALL};
666 }
667
668 static int
669 zcons_create(di_minor_t minor, di_node_t node)
670 {
671 char *minor_str;
672 char *zonename;
673 char path[MAXPATHLEN];
674
675 minor_str = di_minor_name(minor);
676
677 if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zonename",
678 &zonename) == -1) {
679 return (DEVFSADM_CONTINUE);
680 }
681
682 (void) snprintf(path, sizeof (path), "zcons/%s/%s", zonename,
683 minor_str);
684 (void) devfsadm_mklink(path, node, minor, 0);
685
686 return (DEVFSADM_CONTINUE);
687 }
688
689 static int
690 zfd_create(di_minor_t minor, di_node_t node)
691 {
692 char *minor_str;
693 char *zonename;
694 int *id;
695 char path[MAXPATHLEN];
696
697 minor_str = di_minor_name(minor);
698
699 if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zfd_zname",
700 &zonename) == -1)
701 return (DEVFSADM_CONTINUE);
702
703 if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "zfd_id", &id) == -1)
704 return (DEVFSADM_CONTINUE);
705
706 if (strncmp(minor_str, "slave", 5) == 0) {
707 (void) snprintf(path, sizeof (path), "zfd/%s/slave/%d",
708 zonename, id[0]);
709 } else {
710 (void) snprintf(path, sizeof (path), "zfd/%s/master/%d",
711 zonename, id[0]);
712 }
713 (void) devfsadm_mklink(path, node, minor, 0);
714
715 return (DEVFSADM_CONTINUE);
716 }
717
718 /*
719 * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self
720 */
721 static int
722 cpuid(di_minor_t minor, di_node_t node)
723 {
724 (void) devfsadm_mklink(CPUID_SELF_NAME, node, minor, 0);
725 return (DEVFSADM_CONTINUE);
726 }
727
728 /*
729 * For device
730 * /dev/spfma -> /devices/virtual-devices/fma@5:glvc
731 */
732 static int
733 glvc(di_minor_t minor, di_node_t node)
734 {
|