PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/usr/src/cmd/devfsadm/i386/misc_link_i386.c

https://bitbucket.org/illumos/illumos-gate/
C | 656 lines | 482 code | 101 blank | 73 comment | 100 complexity | 16cfe1a71aecc8288bcc1d79c9dc062e MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, AGPL-1.0, AGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, BSD-2-Clause, MPL-2.0-no-copyleft-exception, GPL-2.0, 0BSD
  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 2010 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. * Copyright 2012 Joyent, Inc. All rights reserved.
  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 <ctype.h>
  33. #include <sys/mc_amd.h>
  34. #include <bsm/devalloc.h>
  35. extern int system_labeled;
  36. static int lp(di_minor_t minor, di_node_t node);
  37. static int serial_dialout(di_minor_t minor, di_node_t node);
  38. static int serial(di_minor_t minor, di_node_t node);
  39. static int diskette(di_minor_t minor, di_node_t node);
  40. static int vt00(di_minor_t minor, di_node_t node);
  41. static int kdmouse(di_minor_t minor, di_node_t node);
  42. static int ipmi(di_minor_t minor, di_node_t node);
  43. static int smbios(di_minor_t minor, di_node_t node);
  44. static int agp_process(di_minor_t minor, di_node_t node);
  45. static int drm_node(di_minor_t minor, di_node_t node);
  46. static int mc_node(di_minor_t minor, di_node_t node);
  47. static int xsvc(di_minor_t minor, di_node_t node);
  48. static int srn(di_minor_t minor, di_node_t node);
  49. static int ucode(di_minor_t minor, di_node_t node);
  50. static int heci(di_minor_t minor, di_node_t node);
  51. static devfsadm_create_t misc_cbt[] = {
  52. { "vt00", "ddi_display", NULL,
  53. TYPE_EXACT, ILEVEL_0, vt00
  54. },
  55. { "drm", "ddi_display:drm", NULL,
  56. TYPE_EXACT, ILEVEL_0, drm_node
  57. },
  58. { "mouse", "ddi_mouse", "mouse8042",
  59. TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse
  60. },
  61. { "pseudo", "ddi_pseudo", "ipmi",
  62. TYPE_EXACT | DRV_EXACT, ILEVEL_0, ipmi,
  63. },
  64. { "pseudo", "ddi_pseudo", "smbios",
  65. TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios,
  66. },
  67. /* floppies share the same class, but not link regex, as hard disks */
  68. { "disk", "ddi_block:diskette", NULL,
  69. TYPE_EXACT, ILEVEL_1, diskette
  70. },
  71. { "parallel", "ddi_printer", NULL,
  72. TYPE_EXACT, ILEVEL_1, lp
  73. },
  74. { "serial", "ddi_serial:mb", NULL,
  75. TYPE_EXACT, ILEVEL_1, serial
  76. },
  77. { "serial", "ddi_serial:dialout,mb", NULL,
  78. TYPE_EXACT, ILEVEL_1, serial_dialout
  79. },
  80. { "agp", "ddi_agp:pseudo", NULL,
  81. TYPE_EXACT, ILEVEL_0, agp_process
  82. },
  83. { "agp", "ddi_agp:target", NULL,
  84. TYPE_EXACT, ILEVEL_0, agp_process
  85. },
  86. { "agp", "ddi_agp:cpugart", NULL,
  87. TYPE_EXACT, ILEVEL_0, agp_process
  88. },
  89. { "agp", "ddi_agp:master", NULL,
  90. TYPE_EXACT, ILEVEL_0, agp_process
  91. },
  92. { "pseudo", "ddi_pseudo", NULL,
  93. TYPE_EXACT, ILEVEL_0, xsvc
  94. },
  95. { "pseudo", "ddi_pseudo", NULL,
  96. TYPE_EXACT, ILEVEL_0, srn
  97. },
  98. { "memory-controller", "ddi_mem_ctrl", NULL,
  99. TYPE_EXACT, ILEVEL_0, mc_node
  100. },
  101. { "pseudo", "ddi_pseudo", "ucode",
  102. TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode,
  103. },
  104. { "pseudo", "ddi_pseudo", "heci",
  105. TYPE_EXACT | DRV_EXACT, ILEVEL_0, heci,
  106. }
  107. };
  108. DEVFSADM_CREATE_INIT_V0(misc_cbt);
  109. static char *debug_mid = "misc_mid";
  110. typedef enum {
  111. DRIVER_AGPPSEUDO = 0,
  112. DRIVER_AGPTARGET,
  113. DRIVER_CPUGART,
  114. DRIVER_AGPMASTER_DRM_I915,
  115. DRIVER_AGPMASTER_DRM_RADEON,
  116. DRIVER_AGPMASTER_VGATEXT,
  117. DRIVER_UNKNOWN
  118. } driver_defs_t;
  119. typedef struct {
  120. char *driver_name;
  121. int index;
  122. } driver_name_table_entry_t;
  123. static driver_name_table_entry_t driver_name_table[] = {
  124. { "agpgart", DRIVER_AGPPSEUDO },
  125. { "agptarget", DRIVER_AGPTARGET },
  126. { "amd64_gart", DRIVER_CPUGART },
  127. /* AGP master device managed by drm driver */
  128. { "i915", DRIVER_AGPMASTER_DRM_I915 },
  129. { "radeon", DRIVER_AGPMASTER_DRM_RADEON },
  130. { "vgatext", DRIVER_AGPMASTER_VGATEXT },
  131. { NULL, DRIVER_UNKNOWN }
  132. };
  133. static devfsadm_enumerate_t agptarget_rules[1] =
  134. { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL };
  135. static devfsadm_enumerate_t cpugart_rules[1] =
  136. { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL };
  137. static devfsadm_enumerate_t agpmaster_rules[1] =
  138. { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL };
  139. static devfsadm_remove_t misc_remove_cbt[] = {
  140. { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS,
  141. ILEVEL_0, devfsadm_rm_all
  142. },
  143. { "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT,
  144. ILEVEL_0, devfsadm_rm_all
  145. },
  146. { "mouse", "^kdmouse$", RM_ALWAYS | RM_PRE,
  147. ILEVEL_0, devfsadm_rm_all
  148. },
  149. { "disk", "^(diskette|rdiskette)([0-9]*)$",
  150. RM_ALWAYS | RM_PRE, ILEVEL_1, devfsadm_rm_all
  151. },
  152. { "parallel", "^(lp|ecpp)([0-9]+)$", RM_ALWAYS | RM_PRE,
  153. ILEVEL_1, devfsadm_rm_all
  154. },
  155. { "serial", "^(tty|ttyd)([0-9]+)$", RM_ALWAYS | RM_PRE,
  156. ILEVEL_1, devfsadm_rm_all
  157. },
  158. { "serial", "^tty[a-z]$", RM_ALWAYS | RM_PRE,
  159. ILEVEL_1, devfsadm_rm_all
  160. }
  161. };
  162. DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt);
  163. /*
  164. * Handles minor node type "ddi_display", in addition to generic processing
  165. * done by display().
  166. *
  167. * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility.
  168. */
  169. /* ARGSUSED */
  170. int
  171. vt00(di_minor_t minor, di_node_t node)
  172. {
  173. (void) devfsadm_secondary_link("vt00", "fb", 0);
  174. return (DEVFSADM_CONTINUE);
  175. }
  176. /*
  177. * type=ddi_block:diskette;addr=0,0;minor=c diskette
  178. * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette
  179. * type=ddi_block:diskette;addr1=0;minor=c diskette\A2
  180. * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2
  181. */
  182. static int
  183. diskette(di_minor_t minor, di_node_t node)
  184. {
  185. int flags = 0;
  186. char *a2;
  187. char link[PATH_MAX];
  188. char *addr = di_bus_addr(node);
  189. char *mn = di_minor_name(minor);
  190. if (system_labeled)
  191. flags = DA_ADD|DA_FLOPPY;
  192. if (strcmp(addr, "0,0") == 0) {
  193. if (strcmp(mn, "c") == 0) {
  194. (void) devfsadm_mklink("diskette", node, minor, flags);
  195. } else if (strcmp(mn, "c,raw") == 0) {
  196. (void) devfsadm_mklink("rdiskette", node, minor, flags);
  197. }
  198. }
  199. if (addr[0] == '0') {
  200. if ((a2 = strchr(addr, ',')) != NULL) {
  201. a2++;
  202. if (strcmp(mn, "c") == 0) {
  203. (void) strcpy(link, "diskette");
  204. (void) strcat(link, a2);
  205. (void) devfsadm_mklink(link, node, minor,
  206. flags);
  207. } else if (strcmp(mn, "c,raw") == 0) {
  208. (void) strcpy(link, "rdiskette");
  209. (void) strcat(link, a2);
  210. (void) devfsadm_mklink(link, node, minor,
  211. flags);
  212. }
  213. }
  214. }
  215. return (DEVFSADM_CONTINUE);
  216. }
  217. /*
  218. * type=ddi_printer;name=lp;addr=1,3bc lp0
  219. * type=ddi_printer;name=lp;addr=1,378 lp1
  220. * type=ddi_printer;name=lp;addr=1,278 lp2
  221. */
  222. static int
  223. lp(di_minor_t minor, di_node_t node)
  224. {
  225. char *addr = di_bus_addr(node);
  226. char *buf;
  227. char path[PATH_MAX + 1];
  228. devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
  229. if (strcmp(addr, "1,3bc") == 0) {
  230. (void) devfsadm_mklink("lp0", node, minor, 0);
  231. } else if (strcmp(addr, "1,378") == 0) {
  232. (void) devfsadm_mklink("lp1", node, minor, 0);
  233. } else if (strcmp(addr, "1,278") == 0) {
  234. (void) devfsadm_mklink("lp2", node, minor, 0);
  235. }
  236. if (strcmp(di_driver_name(node), "ecpp") != 0) {
  237. return (DEVFSADM_CONTINUE);
  238. }
  239. if ((buf = di_devfs_path(node)) == NULL) {
  240. return (DEVFSADM_CONTINUE);
  241. }
  242. (void) snprintf(path, sizeof (path), "%s:%s",
  243. buf, di_minor_name(minor));
  244. di_devfs_path_free(buf);
  245. if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
  246. return (DEVFSADM_CONTINUE);
  247. }
  248. (void) snprintf(path, sizeof (path), "ecpp%s", buf);
  249. free(buf);
  250. (void) devfsadm_mklink(path, node, minor, 0);
  251. return (DEVFSADM_CONTINUE);
  252. }
  253. /*
  254. * type=ddi_serial:mb;minor=a tty00
  255. * type=ddi_serial:mb;minor=b tty01
  256. * type=ddi_serial:mb;minor=c tty02
  257. * type=ddi_serial:mb;minor=d tty03
  258. */
  259. static int
  260. serial(di_minor_t minor, di_node_t node)
  261. {
  262. char *mn = di_minor_name(minor);
  263. char link[PATH_MAX];
  264. (void) strcpy(link, "tty");
  265. (void) strcat(link, mn);
  266. (void) devfsadm_mklink(link, node, minor, 0);
  267. if (strcmp(mn, "a") == 0) {
  268. (void) devfsadm_mklink("tty00", node, minor, 0);
  269. } else if (strcmp(mn, "b") == 0) {
  270. (void) devfsadm_mklink("tty01", node, minor, 0);
  271. } else if (strcmp(mn, "c") == 0) {
  272. (void) devfsadm_mklink("tty02", node, minor, 0);
  273. } else if (strcmp(mn, "d") == 0) {
  274. (void) devfsadm_mklink("tty03", node, minor, 0);
  275. }
  276. return (DEVFSADM_CONTINUE);
  277. }
  278. /*
  279. * type=ddi_serial:dialout,mb;minor=a,cu ttyd0
  280. * type=ddi_serial:dialout,mb;minor=b,cu ttyd1
  281. * type=ddi_serial:dialout,mb;minor=c,cu ttyd2
  282. * type=ddi_serial:dialout,mb;minor=d,cu ttyd3
  283. */
  284. static int
  285. serial_dialout(di_minor_t minor, di_node_t node)
  286. {
  287. char *mn = di_minor_name(minor);
  288. if (strcmp(mn, "a,cu") == 0) {
  289. (void) devfsadm_mklink("ttyd0", node, minor, 0);
  290. (void) devfsadm_mklink("cua0", node, minor, 0);
  291. } else if (strcmp(mn, "b,cu") == 0) {
  292. (void) devfsadm_mklink("ttyd1", node, minor, 0);
  293. (void) devfsadm_mklink("cua1", node, minor, 0);
  294. } else if (strcmp(mn, "c,cu") == 0) {
  295. (void) devfsadm_mklink("ttyd2", node, minor, 0);
  296. (void) devfsadm_mklink("cua2", node, minor, 0);
  297. } else if (strcmp(mn, "d,cu") == 0) {
  298. (void) devfsadm_mklink("ttyd3", node, minor, 0);
  299. (void) devfsadm_mklink("cua3", node, minor, 0);
  300. }
  301. return (DEVFSADM_CONTINUE);
  302. }
  303. static int
  304. kdmouse(di_minor_t minor, di_node_t node)
  305. {
  306. (void) devfsadm_mklink("kdmouse", node, minor, 0);
  307. return (DEVFSADM_CONTINUE);
  308. }
  309. static int
  310. ipmi(di_minor_t minor, di_node_t node)
  311. {
  312. /*
  313. * Follow convention from other systems, and include an instance#,
  314. * even though there will only be one.
  315. */
  316. (void) devfsadm_mklink("ipmi0", node, minor, 0);
  317. return (DEVFSADM_CONTINUE);
  318. }
  319. static int
  320. smbios(di_minor_t minor, di_node_t node)
  321. {
  322. (void) devfsadm_mklink("smbios", node, minor, 0);
  323. return (DEVFSADM_CONTINUE);
  324. }
  325. static int
  326. agp_process(di_minor_t minor, di_node_t node)
  327. {
  328. char *minor_nm, *drv_nm;
  329. char *devfspath;
  330. char *I_path, *p_path, *buf;
  331. char *name = (char *)NULL;
  332. int i, index;
  333. devfsadm_enumerate_t rules[1];
  334. minor_nm = di_minor_name(minor);
  335. drv_nm = di_driver_name(node);
  336. if ((minor_nm == NULL) || (drv_nm == NULL)) {
  337. return (DEVFSADM_CONTINUE);
  338. }
  339. devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n",
  340. minor_nm, di_node_name(node));
  341. devfspath = di_devfs_path(node);
  342. if (devfspath == NULL) {
  343. devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n");
  344. return (DEVFSADM_CONTINUE);
  345. }
  346. I_path = (char *)malloc(PATH_MAX);
  347. if (I_path == NULL) {
  348. di_devfs_path_free(devfspath);
  349. devfsadm_print(debug_mid, "agp_process: malloc failed\n");
  350. return (DEVFSADM_CONTINUE);
  351. }
  352. p_path = (char *)malloc(PATH_MAX);
  353. if (p_path == NULL) {
  354. devfsadm_print(debug_mid, "agp_process: malloc failed\n");
  355. di_devfs_path_free(devfspath);
  356. free(I_path);
  357. return (DEVFSADM_CONTINUE);
  358. }
  359. (void) strlcpy(p_path, devfspath, PATH_MAX);
  360. (void) strlcat(p_path, ":", PATH_MAX);
  361. (void) strlcat(p_path, minor_nm, PATH_MAX);
  362. di_devfs_path_free(devfspath);
  363. devfsadm_print(debug_mid, "agp_process: path %s\n", p_path);
  364. for (i = 0; ; i++) {
  365. if ((driver_name_table[i].driver_name == NULL) ||
  366. (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) {
  367. index = driver_name_table[i].index;
  368. break;
  369. }
  370. }
  371. switch (index) {
  372. case DRIVER_AGPPSEUDO:
  373. devfsadm_print(debug_mid,
  374. "agp_process: psdeudo driver name\n");
  375. name = "agpgart";
  376. (void) snprintf(I_path, PATH_MAX, "%s", name);
  377. devfsadm_print(debug_mid,
  378. "mklink %s -> %s\n", I_path, p_path);
  379. (void) devfsadm_mklink(I_path, node, minor, 0);
  380. free(I_path);
  381. free(p_path);
  382. return (DEVFSADM_CONTINUE);
  383. case DRIVER_AGPTARGET:
  384. devfsadm_print(debug_mid,
  385. "agp_process: target driver name\n");
  386. rules[0] = agptarget_rules[0];
  387. name = "agptarget";
  388. break;
  389. case DRIVER_CPUGART:
  390. devfsadm_print(debug_mid,
  391. "agp_process: cpugart driver name\n");
  392. rules[0] = cpugart_rules[0];
  393. name = "cpugart";
  394. break;
  395. case DRIVER_AGPMASTER_DRM_I915:
  396. case DRIVER_AGPMASTER_DRM_RADEON:
  397. case DRIVER_AGPMASTER_VGATEXT:
  398. devfsadm_print(debug_mid,
  399. "agp_process: agpmaster driver name\n");
  400. rules[0] = agpmaster_rules[0];
  401. name = "agpmaster";
  402. break;
  403. case DRIVER_UNKNOWN:
  404. devfsadm_print(debug_mid,
  405. "agp_process: unknown driver name=%s\n", drv_nm);
  406. free(I_path);
  407. free(p_path);
  408. return (DEVFSADM_CONTINUE);
  409. }
  410. if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) {
  411. devfsadm_print(debug_mid, "agp_process: exit/coninue\n");
  412. free(I_path);
  413. free(p_path);
  414. return (DEVFSADM_CONTINUE);
  415. }
  416. (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf);
  417. devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n",
  418. p_path, buf);
  419. free(buf);
  420. devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path);
  421. (void) devfsadm_mklink(I_path, node, minor, 0);
  422. free(p_path);
  423. free(I_path);
  424. return (DEVFSADM_CONTINUE);
  425. }
  426. static int
  427. drm_node(di_minor_t minor, di_node_t node)
  428. {
  429. char *minor_nm, *drv_nm;
  430. char *devfspath;
  431. char *I_path, *p_path, *buf;
  432. char *name = "card";
  433. devfsadm_enumerate_t drm_rules[1] = {"^dri$/^card([0-9]+)$", 1,
  434. MATCH_ALL };
  435. minor_nm = di_minor_name(minor);
  436. drv_nm = di_driver_name(node);
  437. if ((minor_nm == NULL) || (drv_nm == NULL)) {
  438. return (DEVFSADM_CONTINUE);
  439. }
  440. devfsadm_print(debug_mid, "drm_node: minor=%s node=%s type=%s\n",
  441. minor_nm, di_node_name(node), di_minor_nodetype(minor));
  442. devfspath = di_devfs_path(node);
  443. if (devfspath == NULL) {
  444. devfsadm_print(debug_mid, "drm_node: devfspath is NULL\n");
  445. return (DEVFSADM_CONTINUE);
  446. }
  447. I_path = (char *)malloc(PATH_MAX);
  448. if (I_path == NULL) {
  449. di_devfs_path_free(devfspath);
  450. devfsadm_print(debug_mid, "drm_node: malloc failed\n");
  451. return (DEVFSADM_CONTINUE);
  452. }
  453. p_path = (char *)malloc(PATH_MAX);
  454. if (p_path == NULL) {
  455. devfsadm_print(debug_mid, "drm_node: malloc failed\n");
  456. di_devfs_path_free(devfspath);
  457. free(I_path);
  458. return (DEVFSADM_CONTINUE);
  459. }
  460. (void) strlcpy(p_path, devfspath, PATH_MAX);
  461. (void) strlcat(p_path, ":", PATH_MAX);
  462. (void) strlcat(p_path, minor_nm, PATH_MAX);
  463. di_devfs_path_free(devfspath);
  464. devfsadm_print(debug_mid, "drm_node: p_path %s\n", p_path);
  465. if (devfsadm_enumerate_int(p_path, 0, &buf, drm_rules, 1)) {
  466. free(p_path);
  467. devfsadm_print(debug_mid, "drm_node: exit/coninue\n");
  468. return (DEVFSADM_CONTINUE);
  469. }
  470. (void) snprintf(I_path, PATH_MAX, "dri/%s%s", name, buf);
  471. devfsadm_print(debug_mid, "drm_node: p_path=%s buf=%s\n",
  472. p_path, buf);
  473. free(buf);
  474. devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path);
  475. (void) devfsadm_mklink(I_path, node, minor, 0);
  476. free(p_path);
  477. free(I_path);
  478. return (0);
  479. }
  480. /*
  481. * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd
  482. */
  483. static int
  484. mc_node(di_minor_t minor, di_node_t node)
  485. {
  486. const char *minorname = di_minor_name(minor);
  487. const char *busaddr = di_bus_addr(node);
  488. char linkpath[PATH_MAX];
  489. int unitaddr;
  490. char *c;
  491. if (minorname == NULL || busaddr == NULL)
  492. return (DEVFSADM_CONTINUE);
  493. errno = 0;
  494. unitaddr = strtol(busaddr, &c, 16);
  495. if (errno != 0)
  496. return (DEVFSADM_CONTINUE);
  497. if (unitaddr == 0) {
  498. (void) snprintf(linkpath, sizeof (linkpath), "mc/mc");
  499. } else if (unitaddr >= MC_AMD_DEV_OFFSET) {
  500. (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
  501. unitaddr - MC_AMD_DEV_OFFSET);
  502. } else {
  503. (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
  504. minor->dev_minor);
  505. }
  506. (void) devfsadm_mklink(linkpath, node, minor, 0);
  507. return (DEVFSADM_CONTINUE);
  508. }
  509. /*
  510. * Creates \M0 devlink for xsvc node
  511. */
  512. static int
  513. xsvc(di_minor_t minor, di_node_t node)
  514. {
  515. char *mn;
  516. if (strcmp(di_node_name(node), "xsvc") != 0)
  517. return (DEVFSADM_CONTINUE);
  518. mn = di_minor_name(minor);
  519. if (mn == NULL)
  520. return (DEVFSADM_CONTINUE);
  521. (void) devfsadm_mklink(mn, node, minor, 0);
  522. return (DEVFSADM_CONTINUE);
  523. }
  524. /*
  525. * Creates \M0 devlink for srn device
  526. */
  527. static int
  528. srn(di_minor_t minor, di_node_t node)
  529. {
  530. char *mn;
  531. if (strcmp(di_node_name(node), "srn") != 0)
  532. return (DEVFSADM_CONTINUE);
  533. mn = di_minor_name(minor);
  534. if (mn == NULL)
  535. return (DEVFSADM_CONTINUE);
  536. (void) devfsadm_mklink(mn, node, minor, 0);
  537. return (DEVFSADM_CONTINUE);
  538. }
  539. /*
  540. * /dev/ucode -> /devices/pseudo/ucode@0:ucode
  541. */
  542. static int
  543. ucode(di_minor_t minor, di_node_t node)
  544. {
  545. (void) devfsadm_mklink("ucode", node, minor, 0);
  546. return (DEVFSADM_CONTINUE);
  547. }
  548. static int
  549. heci(di_minor_t minor, di_node_t node)
  550. {
  551. if (strcmp(di_minor_name(minor), "AMT") == 0) {
  552. (void) devfsadm_mklink("heci", node, minor, 0);
  553. }
  554. return (DEVFSADM_CONTINUE);
  555. }