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 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 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 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