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 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * Copyright 2024 Oxide Computer Company
32 */
33
34 #include "lint.h"
35 #include <sys/types.h>
36 #include <sys/mkdev.h>
37 #include <errno.h>
38
39 /*
40 * Create a formatted device number
41 */
42 dev_t
__makedev(const int version,const major_t majdev,const minor_t mindev)43 __makedev(const int version, const major_t majdev, const minor_t mindev)
44 {
45 dev_t devnum;
46 switch (version) {
47 case OLDDEV:
48 if (majdev > OMAXMAJ || mindev > OMAXMIN) {
49 errno = EINVAL;
50 return ((o_dev_t)NODEV);
51 }
52 devnum = ((majdev << ONBITSMINOR) | mindev);
53 break;
54
55 case NEWDEV:
56 #if MAXMAJ != 0xfffffffful /* assumes major_t == uint32_t */
57 if (majdev > MAXMAJ) {
58 errno = EINVAL;
59 return (NODEV);
60 }
61 #endif
62 #if MAXMIN != 0xfffffffful /* assumes minor_t == uint32_t */
63 if (mindev > MAXMIN) {
64 errno = EINVAL;
65 return (NODEV);
66 }
67 #endif
68 if ((devnum = (((dev_t)majdev << NBITSMINOR) |
69 mindev)) == NODEV) {
70 errno = EINVAL;
71 return (NODEV);
72 }
73 break;
74 case COMPATDEV:
75 if (majdev > MAXMAJ32 || mindev > MAXMIN32) {
76 errno = EINVAL;
77 return (NODEV);
78 }
79
80 if ((devnum = (((dev_t)majdev << NBITSMINOR32) |
81 mindev)) == NODEV) {
82 errno = EINVAL;
83 return (NODEV);
84 }
85 break;
86 default:
87 errno = EINVAL;
88 return (NODEV);
89 }
90
91 return (devnum);
92 }
93
94 /*
95 * Return major number part of formatted device number
96 */
97 major_t
__major(const int version,const dev_t devnum)98 __major(const int version, const dev_t devnum)
99 {
100 major_t maj;
101
102 switch (version) {
103 case OLDDEV:
104 maj = (devnum >> ONBITSMINOR);
105 if (devnum == NODEV || maj > OMAXMAJ) {
106 errno = EINVAL;
107 return ((major_t)NODEV);
108 }
109 break;
110
111 case NEWDEV:
112 maj = (devnum >> NBITSMINOR);
113 if (devnum == NODEV) {
114 errno = EINVAL;
115 return ((major_t)NODEV);
116 }
117 #if MAXMAJ != 0xfffffffful /* assumes major_t == uint32_t */
118 if (maj > MAXMAJ) {
119 errno = EINVAL;
120 return ((major_t)NODEV);
121 }
122 #endif
123 break;
124
125 case COMPATDEV:
126 maj = devnum >> NBITSMAJOR32;
127 if (devnum == NODEV || maj > MAXMAJ32) {
128 errno = EINVAL;
129 return ((major_t)NODEV);
130 }
131 break;
132
133 default:
134 errno = EINVAL;
135 return ((major_t)NODEV);
136 }
137
138 return (maj);
139 }
140
141
142 /*
143 * Return minor number part of formatted device number
144 */
145 minor_t
__minor(const int version,const dev_t devnum)146 __minor(const int version, const dev_t devnum)
147 {
148 if (devnum == NODEV) {
149 errno = EINVAL;
150 return ((minor_t)NODEV);
151 }
152
153 switch (version) {
154 case OLDDEV:
155 return (devnum & OMAXMIN);
156 case NEWDEV:
157 return (devnum & MAXMIN);
158 case COMPATDEV:
159 return (devnum & MAXMIN32);
160 default:
161 errno = EINVAL;
162 return ((minor_t)NODEV);
163 }
164 }
165