xref: /titanic_51/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c (revision dd4eeefdb8e4583c47e28a7f315db6087931ef06)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <regex.h>
29 #include <devfsadm.h>
30 #include <stdio.h>
31 #include <strings.h>
32 #include <stdlib.h>
33 #include <limits.h>
34 #include <sys/mkdev.h>
35 #include <bsm/devalloc.h>
36 
37 extern int system_labeled;
38 
39 
40 static int ddi_other(di_minor_t minor, di_node_t node);
41 static int diskette(di_minor_t minor, di_node_t node);
42 static int ecpp_create(di_minor_t minor, di_node_t node);
43 static int mc_node(di_minor_t minor, di_node_t node);
44 static int ddi_cardreader(di_minor_t minor, di_node_t node);
45 static int starcat_sbbc_node(di_minor_t minor, di_node_t node);
46 static int lom(di_minor_t minor, di_node_t node);
47 static int ntwdt_create(di_minor_t minor, di_node_t node);
48 
49 static devfsadm_create_t misc_cbt[] = {
50 	{ "other", "ddi_other", NULL,
51 	    TYPE_EXACT, ILEVEL_0, ddi_other
52 	},
53 	{ "memory-controller", "ddi_mem_ctrl", NULL,
54 	    TYPE_EXACT, ILEVEL_0, mc_node
55 	},
56 	{ "pseudo", "ddi_pseudo", "sbbc",
57 	    TYPE_EXACT | DRV_EXACT, ILEVEL_1, starcat_sbbc_node
58 	},
59 	{ "disk",  "ddi_block:diskette", NULL,
60 	    TYPE_EXACT, ILEVEL_1, diskette
61 	},
62 	{ "printer",  "ddi_printer", NULL,
63 	    TYPE_EXACT, ILEVEL_1, ecpp_create
64 	},
65 	{ "card-reader", "ddi_smartcard_reader", NULL,
66 		TYPE_EXACT, ILEVEL_0, ddi_cardreader
67 	},
68 	{ "pseudo", "ddi_pseudo", "lw8",
69 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom
70 	},
71 	{ "pseudo", "ddi_pseudo", "ntwdt",
72 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, ntwdt_create
73 	},
74 };
75 
76 DEVFSADM_CREATE_INIT_V0(misc_cbt);
77 
78 /* Smart Card Reader device link */
79 #define	CARDREADER_LINK		"^scmi2c[0-9]+$"
80 
81 /* Rules for removing links */
82 static devfsadm_remove_t sparc_remove_cbt[] = {
83 	{ "card-reader", CARDREADER_LINK, RM_PRE | RM_ALWAYS,
84 		ILEVEL_0, devfsadm_rm_all }
85 };
86 
87 DEVFSADM_REMOVE_INIT_V0(sparc_remove_cbt);
88 
89 
90 /*
91  * Handles minor node type "ddi_other"
92  * type=ddi_other;name=SUNW,pmc    pmc
93  * type=ddi_other;name=SUNW,mic    mic\M0
94  */
95 static int
96 ddi_other(di_minor_t minor, di_node_t node)
97 {
98 	char path[PATH_MAX + 1];
99 	char *nn = di_node_name(node);
100 	char *mn = di_minor_name(minor);
101 
102 	if (strcmp(nn, "SUNW,pmc") == 0) {
103 		(void) devfsadm_mklink("pcm", node, minor, 0);
104 	} else if (strcmp(nn, "SUNW,mic") == 0) {
105 		(void) strcpy(path, "mic");
106 		(void) strcat(path, mn);
107 		(void) devfsadm_mklink(path, node, minor, 0);
108 	}
109 
110 	return (DEVFSADM_CONTINUE);
111 }
112 
113 /*
114  * This function is called for diskette nodes
115  */
116 static int
117 diskette(di_minor_t minor, di_node_t node)
118 {
119 	int	flags = 0;
120 	char	*mn = di_minor_name(minor);
121 
122 	if (system_labeled)
123 		flags = DA_ADD|DA_FLOPPY;
124 
125 	if (strcmp(mn, "c") == 0) {
126 		(void) devfsadm_mklink("diskette", node, minor, flags);
127 		(void) devfsadm_mklink("diskette0", node, minor, flags);
128 
129 	} else if (strcmp(mn, "c,raw") == 0) {
130 		(void) devfsadm_mklink("rdiskette", node, minor, flags);
131 		(void) devfsadm_mklink("rdiskette0", node, minor, flags);
132 
133 	}
134 	return (DEVFSADM_CONTINUE);
135 }
136 
137 /*
138  * Handles links of the form:
139  * type=ddi_printer;name=ecpp  ecpp\N0
140  */
141 static int
142 ecpp_create(di_minor_t minor, di_node_t node)
143 {
144 	char *buf;
145 	char path[PATH_MAX + 1];
146 	devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
147 
148 	if (strcmp(di_driver_name(node), "ecpp") != 0) {
149 		return (DEVFSADM_CONTINUE);
150 	}
151 
152 	if ((buf = di_devfs_path(node)) == NULL) {
153 		return (DEVFSADM_CONTINUE);
154 	}
155 
156 	(void) snprintf(path, sizeof (path), "%s:%s",
157 	    buf, di_minor_name(minor));
158 
159 	di_devfs_path_free(buf);
160 
161 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
162 		return (DEVFSADM_CONTINUE);
163 	}
164 
165 	(void) snprintf(path, sizeof (path), "ecpp%s", buf);
166 	free(buf);
167 
168 	(void) devfsadm_mklink(path, node, minor, 0);
169 	return (DEVFSADM_CONTINUE);
170 }
171 
172 /* Rules for memory controller */
173 static devfsadm_enumerate_t mc_rules[1] =
174 	{"^mc$/^mc([0-9]+)$", 1, MATCH_ALL};
175 
176 
177 static int
178 mc_node(di_minor_t minor, di_node_t node)
179 {
180 	char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath;
181 	char *minor_nm;
182 
183 	minor_nm = di_minor_name(minor);
184 
185 	if (minor_nm == NULL) {
186 		return (DEVFSADM_CONTINUE);
187 	}
188 
189 	devfspath = di_devfs_path(node);
190 
191 	(void) strcpy(path, devfspath);
192 	(void) strcat(path, ":");
193 	(void) strcat(path, minor_nm);
194 	di_devfs_path_free(devfspath);
195 
196 	/* build the physical path from the components */
197 	if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) {
198 		return (DEVFSADM_CONTINUE);
199 	}
200 
201 	(void) strcpy(l_path, "mc/mc");
202 	(void) strcat(l_path, buf);
203 
204 	free(buf);
205 
206 	(void) devfsadm_mklink(l_path, node, minor, 0);
207 	return (DEVFSADM_CONTINUE);
208 }
209 
210 
211 /*
212  * This function is called for Smartcard card reader nodes
213  * Handles minor node type "ddi_smartcard_reader"
214  * type=ddi_smartcard_reader;name=card-reader   scmi2c\N0
215  * Calls enumerate to assign logical card-reader id and then
216  * devfsadm_mklink to make the link.
217  */
218 static int
219 ddi_cardreader(di_minor_t minor, di_node_t node)
220 {
221 	char p_path[PATH_MAX +1], l_path[PATH_MAX +1];
222 	char *buf;
223 	char *ptr;
224 	char *nn, *mn;
225 
226 	devfsadm_enumerate_t rules[1] = {"^scmi2c([0-9]+)$", 1, MATCH_ALL};
227 
228 	nn = di_node_name(node);
229 	if (strcmp(nn, "card-reader")) {
230 		return (DEVFSADM_CONTINUE);
231 	}
232 
233 	if (NULL == (ptr = di_devfs_path(node))) {
234 		return (DEVFSADM_CONTINUE);
235 	}
236 
237 	(void) strcpy(p_path, ptr);
238 	(void) strcat(p_path, ":");
239 
240 	mn = di_minor_name(minor);
241 
242 	(void) strcat(p_path, mn);
243 	di_devfs_path_free(ptr);
244 
245 	if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) {
246 		return (DEVFSADM_CONTINUE);
247 	}
248 	(void) snprintf(l_path, sizeof (l_path), "scmi2c%s", buf);
249 	free(buf);
250 	(void) devfsadm_mklink(l_path, node, minor, 0);
251 
252 	return (DEVFSADM_CONTINUE);
253 }
254 
255 
256 
257 
258 
259 
260 
261 
262 /*
263  * Starcat sbbc node.  We only really care about generating a /dev
264  * link for the lone sbbc on the SC (as opposed to the potentially
265  * numerous sbbcs on the domain), so only operate on instance 0.
266  */
267 static int
268 starcat_sbbc_node(di_minor_t minor, di_node_t node)
269 {
270 	char *mn;
271 
272 	if (di_instance(node) == 0) {
273 		mn = di_minor_name(minor);
274 		(void) devfsadm_mklink(mn, node, minor, 0);
275 	}
276 	return (DEVFSADM_CONTINUE);
277 
278 }
279 
280 /*
281  * Creates /dev/lom nodes for Platform Specific lom driver
282  */
283 static int
284 lom(di_minor_t minor, di_node_t node)
285 {
286 	(void) devfsadm_mklink("lom", node, minor, 0);
287 	return (DEVFSADM_CONTINUE);
288 }
289 
290 /*
291  * Creates /dev/ntwdt nodes for Platform Specific ntwdt driver
292  */
293 static int
294 ntwdt_create(di_minor_t minor, di_node_t node)
295 {
296 	(void) devfsadm_mklink("ntwdt", node, minor, 0);
297 	return (DEVFSADM_CONTINUE);
298 }
299