1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <regex.h>
27 #include <devfsadm.h>
28 #include <stdio.h>
29 #include <strings.h>
30 #include <stdlib.h>
31 #include <limits.h>
32 #include <sys/mkdev.h>
33 #include <bsm/devalloc.h>
34
35 extern int system_labeled;
36
37
38 static int ddi_other(di_minor_t minor, di_node_t node);
39 static int diskette(di_minor_t minor, di_node_t node);
40 static int ecpp_create(di_minor_t minor, di_node_t node);
41 static int mc_node(di_minor_t minor, di_node_t node);
42 static int starcat_sbbc_node(di_minor_t minor, di_node_t node);
43 static int lom(di_minor_t minor, di_node_t node);
44 static int ntwdt_create(di_minor_t minor, di_node_t node);
45 static int bmc(di_minor_t minor, di_node_t node);
46
47 static devfsadm_create_t misc_cbt[] = {
48 { "other", "ddi_other", NULL,
49 TYPE_EXACT, ILEVEL_0, ddi_other
50 },
51 { "memory-controller", "ddi_mem_ctrl", NULL,
52 TYPE_EXACT, ILEVEL_0, mc_node
53 },
54 { "pseudo", "ddi_pseudo", "sbbc",
55 TYPE_EXACT | DRV_EXACT, ILEVEL_1, starcat_sbbc_node
56 },
57 { "disk", "ddi_block:diskette", NULL,
58 TYPE_EXACT, ILEVEL_1, diskette
59 },
60 { "printer", "ddi_printer", NULL,
61 TYPE_EXACT, ILEVEL_1, ecpp_create
62 },
63 { "pseudo", "ddi_pseudo", "lw8",
64 TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom
65 },
66 { "pseudo", "ddi_pseudo", "ntwdt",
67 TYPE_EXACT | DRV_EXACT, ILEVEL_0, ntwdt_create
68 },
69 { "pseudo", "ddi_pseudo", "bmc",
70 TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc
71 }
72 };
73
74 DEVFSADM_CREATE_INIT_V0(misc_cbt);
75
76
77 /*
78 * Handles minor node type "ddi_other"
79 * type=ddi_other;name=SUNW,pmc pmc
80 * type=ddi_other;name=SUNW,mic mic\M0
81 */
82 static int
ddi_other(di_minor_t minor,di_node_t node)83 ddi_other(di_minor_t minor, di_node_t node)
84 {
85 char path[PATH_MAX + 1];
86 char *nn = di_node_name(node);
87 char *mn = di_minor_name(minor);
88
89 if (strcmp(nn, "SUNW,pmc") == 0) {
90 (void) devfsadm_mklink("pcm", node, minor, 0);
91 } else if (strcmp(nn, "SUNW,mic") == 0) {
92 (void) strcpy(path, "mic");
93 (void) strcat(path, mn);
94 (void) devfsadm_mklink(path, node, minor, 0);
95 }
96
97 return (DEVFSADM_CONTINUE);
98 }
99
100 /*
101 * This function is called for diskette nodes
102 */
103 static int
diskette(di_minor_t minor,di_node_t node)104 diskette(di_minor_t minor, di_node_t node)
105 {
106 int flags = 0;
107 char *mn = di_minor_name(minor);
108
109 if (system_labeled)
110 flags = DA_ADD|DA_FLOPPY;
111
112 if (strcmp(mn, "c") == 0) {
113 (void) devfsadm_mklink("diskette", node, minor, flags);
114 (void) devfsadm_mklink("diskette0", node, minor, flags);
115
116 } else if (strcmp(mn, "c,raw") == 0) {
117 (void) devfsadm_mklink("rdiskette", node, minor, flags);
118 (void) devfsadm_mklink("rdiskette0", node, minor, flags);
119
120 }
121 return (DEVFSADM_CONTINUE);
122 }
123
124 /*
125 * Handles links of the form:
126 * type=ddi_printer;name=ecpp ecpp\N0
127 */
128 static int
ecpp_create(di_minor_t minor,di_node_t node)129 ecpp_create(di_minor_t minor, di_node_t node)
130 {
131 char *buf;
132 char path[PATH_MAX + 1];
133 devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
134
135 if (strcmp(di_driver_name(node), "ecpp") != 0) {
136 return (DEVFSADM_CONTINUE);
137 }
138
139 if ((buf = di_devfs_path(node)) == NULL) {
140 return (DEVFSADM_CONTINUE);
141 }
142
143 (void) snprintf(path, sizeof (path), "%s:%s",
144 buf, di_minor_name(minor));
145
146 di_devfs_path_free(buf);
147
148 if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
149 return (DEVFSADM_CONTINUE);
150 }
151
152 (void) snprintf(path, sizeof (path), "ecpp%s", buf);
153 free(buf);
154
155 (void) devfsadm_mklink(path, node, minor, 0);
156 return (DEVFSADM_CONTINUE);
157 }
158
159 /* Rules for memory controller */
160 static devfsadm_enumerate_t mc_rules[1] =
161 {"^mc$/^mc([0-9]+)$", 1, MATCH_ALL};
162
163
164 static int
mc_node(di_minor_t minor,di_node_t node)165 mc_node(di_minor_t minor, di_node_t node)
166 {
167 char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath;
168 char *minor_nm;
169
170 minor_nm = di_minor_name(minor);
171
172 if (minor_nm == NULL) {
173 return (DEVFSADM_CONTINUE);
174 }
175
176 devfspath = di_devfs_path(node);
177
178 (void) strcpy(path, devfspath);
179 (void) strcat(path, ":");
180 (void) strcat(path, minor_nm);
181 di_devfs_path_free(devfspath);
182
183 /* build the physical path from the components */
184 if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) {
185 return (DEVFSADM_CONTINUE);
186 }
187
188 (void) strcpy(l_path, "mc/mc");
189 (void) strcat(l_path, buf);
190
191 free(buf);
192
193 (void) devfsadm_mklink(l_path, node, minor, 0);
194 return (DEVFSADM_CONTINUE);
195 }
196
197
198 /*
199 * Starcat sbbc node. We only really care about generating a /dev
200 * link for the lone sbbc on the SC (as opposed to the potentially
201 * numerous sbbcs on the domain), so only operate on instance 0.
202 */
203 static int
starcat_sbbc_node(di_minor_t minor,di_node_t node)204 starcat_sbbc_node(di_minor_t minor, di_node_t node)
205 {
206 char *mn;
207
208 if (di_instance(node) == 0) {
209 mn = di_minor_name(minor);
210 (void) devfsadm_mklink(mn, node, minor, 0);
211 }
212 return (DEVFSADM_CONTINUE);
213
214 }
215
216 /*
217 * Creates /dev/lom nodes for Platform Specific lom driver
218 */
219 static int
lom(di_minor_t minor,di_node_t node)220 lom(di_minor_t minor, di_node_t node)
221 {
222 (void) devfsadm_mklink("lom", node, minor, 0);
223 return (DEVFSADM_CONTINUE);
224 }
225
226 /*
227 * Creates /dev/ntwdt nodes for Platform Specific ntwdt driver
228 */
229 static int
ntwdt_create(di_minor_t minor,di_node_t node)230 ntwdt_create(di_minor_t minor, di_node_t node)
231 {
232 (void) devfsadm_mklink("ntwdt", node, minor, 0);
233 return (DEVFSADM_CONTINUE);
234 }
235
236 /*
237 * Creates /dev/bmc node.
238 */
239 static int
bmc(di_minor_t minor,di_node_t node)240 bmc(di_minor_t minor, di_node_t node)
241 {
242 (void) devfsadm_mklink("bmc", node, minor, 0);
243 return (DEVFSADM_CONTINUE);
244 }
245