FreeBSD/Linux Kernel Cross Reference
sys/device/dev_name.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: dev_name.c,v $
29 * Revision 2.8 93/05/17 15:01:03 rvb
30 * We need a nomap() of type vm_offset_t
31 *
32 * Revision 2.7 92/08/03 17:33:11 jfriedl
33 * removed silly prototypes
34 * [92/08/02 jfriedl]
35 *
36 * Revision 2.6 92/05/21 17:08:55 jfriedl
37 * tried prototypes.
38 * [92/05/20 jfriedl]
39 *
40 * Revision 2.5 91/07/31 17:32:50 dbg
41 * Fixed to not modify the string passed in.
42 * [91/07/23 dbg]
43 *
44 * Revision 2.4 91/05/14 15:41:13 mrt
45 * Correcting copyright
46 *
47 * Revision 2.3 91/02/05 17:08:34 mrt
48 * Changed to new Mach copyright
49 * [91/01/31 17:27:34 mrt]
50 *
51 * Revision 2.2 89/09/08 11:23:17 dbg
52 * Moved device-name search routines here from dev_lookup.c
53 * [89/08/01 dbg]
54 *
55 */
56 /*
57 * Author: David B. Golub, Carnegie Mellon University
58 * Date: 8/89
59 */
60
61 #include <device/device_types.h>
62 #include <device/dev_hdr.h>
63 #include <device/conf.h>
64
65
66
67 /*
68 * Routines placed in empty entries in the device tables
69 */
70 int nulldev()
71 {
72 return (D_SUCCESS);
73 }
74
75 int nodev()
76 {
77 return (D_INVALID_OPERATION);
78 }
79
80 vm_offset_t
81 nomap()
82 {
83 return (D_INVALID_OPERATION);
84 }
85
86 /*
87 * Name comparison routine.
88 * Compares first 'len' characters of 'src'
89 * with 'target', which is zero-terminated.
90 * Returns TRUE if strings are equal:
91 * src and target are equal in first 'len' characters
92 * next character of target is 0 (end of string).
93 */
94 boolean_t
95 name_equal(src, len, target)
96 register char * src;
97 register int len;
98 register char * target;
99 {
100 while (--len >= 0)
101 if (*src++ != *target++)
102 return FALSE;
103 return *target == 0;
104 }
105
106 /*
107 * device name lookup
108 */
109 boolean_t dev_name_lookup(name, ops, unit)
110 char * name;
111 dev_ops_t *ops; /* out */
112 int *unit; /* out */
113 {
114 /*
115 * Assume that block device names are of the form
116 *
117 * <device_name><unit_number><partition>
118 *
119 * where
120 * <device_name> is the name in the device table
121 * <unit_number> is an integer
122 * <partition> is a letter in [a-h]
123 */
124
125 register char * cp = name;
126 int len;
127 register int j = 0;
128 register int c;
129 dev_ops_t dev;
130 register boolean_t found;
131
132 /*
133 * Find device type name (characters before digit)
134 */
135 while ((c = *cp) != '\0' &&
136 !(c >= '' && c <= '9'))
137 cp++;
138
139 len = cp - name;
140 if (c != '\0') {
141 /*
142 * Find unit number
143 */
144 while ((c = *cp) != '\0' &&
145 c >= '' && c <= '9') {
146 j = j * 10 + (c - '');
147 cp++;
148 }
149 }
150
151 found = FALSE;
152 dev_search(dev) {
153 if (name_equal(name, len, dev->d_name)) {
154 found = TRUE;
155 break;
156 }
157 }
158 if (!found) {
159 /* name not found - try indirection list */
160 register dev_indirect_t di;
161
162 dev_indirect_search(di) {
163 if (name_equal(name, len, di->d_name)) {
164 /*
165 * Return device and unit from indirect vector.
166 */
167 *ops = di->d_ops;
168 *unit = di->d_unit;
169 return (TRUE);
170 }
171 }
172 /* Not found in either list. */
173 return (FALSE);
174 }
175
176 *ops = dev;
177 *unit = j;
178
179 /*
180 * Find sub-device number
181 */
182 j = dev->d_subdev;
183 if (j > 0) {
184 if (c >= 'a' && c < 'a' + j) {
185 /*
186 * Minor number is <subdev_count>*unit + letter.
187 */
188 *unit = *unit * j + (c - 'a');
189 }
190 else {
191 /*
192 * Assume unit A.
193 */
194 *unit = *unit * j;
195 }
196 }
197 return (TRUE);
198 }
199
200 /*
201 * Change an entry in the indirection list.
202 */
203 void
204 dev_set_indirection(name, ops, unit)
205 char *name;
206 dev_ops_t ops;
207 int unit;
208 {
209 register dev_indirect_t di;
210
211 dev_indirect_search(di) {
212 if (!strcmp(di->d_name, name)) {
213 di->d_ops = ops;
214 di->d_unit = unit;
215 break;
216 }
217 }
218 }
219
220 boolean_t dev_change_indirect(iname, dname, unit)
221 char *iname,*dname;
222 int unit;
223 {
224 struct dev_ops *dp;
225 struct dev_indirect *di;
226 int found = FALSE;
227
228 dev_search(dp) {
229 if (!strcmp(dp->d_name,dname)) {
230 found = TRUE;
231 break;
232 }
233 }
234 if (!found) return FALSE;
235 dev_indirect_search(di) {
236 if (!strcmp(di->d_name,iname)) {
237 di->d_ops = dp;
238 di->d_unit = unit;
239 return TRUE;
240 }
241 }
242 return FALSE;
243 }
Cache object: 58a86e12a4952854e592aad0b2c3c5f5
|