|
|
1.1 root 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 [email protected]
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: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 8/89
29: */
30:
31: #include <device/device_types.h>
32: #include <device/dev_hdr.h>
33: #include <device/conf.h>
34:
35:
36:
37: /*
38: * Routines placed in empty entries in the device tables
39: */
40: int nulldev()
41: {
42: return (D_SUCCESS);
43: }
44:
45: int nodev()
46: {
47: return (D_INVALID_OPERATION);
48: }
49:
50: vm_offset_t
51: nomap()
52: {
53: return (D_INVALID_OPERATION);
54: }
55:
56: /*
57: * Name comparison routine.
58: * Compares first 'len' characters of 'src'
59: * with 'target', which is zero-terminated.
60: * Returns TRUE if strings are equal:
61: * src and target are equal in first 'len' characters
62: * next character of target is 0 (end of string).
63: */
64: boolean_t
65: name_equal(src, len, target)
66: register char * src;
67: register int len;
68: register char * target;
69: {
70: while (--len >= 0)
71: if (*src++ != *target++)
72: return FALSE;
73: return *target == 0;
74: }
75:
76: /*
77: * device name lookup
78: */
79: boolean_t dev_name_lookup(name, ops, unit)
80: char * name;
81: dev_ops_t *ops; /* out */
82: int *unit; /* out */
83: {
84: /*
85: * Assume that block device names are of the form
86: *
87: * <device_name><unit_number>[[<slice num>]<partition>]
88: *
89: * where
90: * <device_name> is the name in the device table
91: * <unit_number> is an integer
92: * <slice num> * is 's' followed by a number (disks only!)
93: * <partition> is a letter in [a-h] (disks only?)
94: */
95:
96: register char * cp = name;
97: int len;
98: register int j = 0;
99: register int c;
100: dev_ops_t dev;
101: register boolean_t found;
102:
103: int slice_num=0;
104:
105: #if 0
106: printf("lookup on name %s\n",name);
107: #endif 0
108:
109: /*
110: * Find device type name (characters before digit)
111: */
112: while ((c = *cp) != '\0' &&
113: !(c >= '0' && c <= '9'))
114: cp++;
115:
116: len = cp - name;
117: if (c != '\0') {
118: /*
119: * Find unit number
120: */
121: while ((c = *cp) != '\0' &&
122: c >= '0' && c <= '9') {
123: j = j * 10 + (c - '0');
124: cp++;
125: }
126: }
127:
128: found = FALSE;
129: dev_search(dev) {
130: if (name_equal(name, len, dev->d_name)) {
131: found = TRUE;
132: break;
133: }
134: }
135: if (!found) {
136: /* name not found - try indirection list */
137: register dev_indirect_t di;
138:
139: dev_indirect_search(di) {
140: if (name_equal(name, len, di->d_name)) {
141: /*
142: * Return device and unit from indirect vector.
143: */
144: *ops = di->d_ops;
145: *unit = di->d_unit;
146: return (TRUE);
147: }
148: }
149: /* Not found in either list. */
150: return (FALSE);
151: }
152:
153: *ops = dev;
154: *unit = j;
155:
156: /*
157: * Find sub-device number
158: */
159:
160: j = dev->d_subdev;
161: if (j > 0) {
162: /* if no slice string, slice num = 0 */
163:
164: /* <subdev_count>*unit + <slice_number>*16 -- I know it's bad */
165: *unit *= j;
166:
167: /* find slice ? */
168: if (c=='s') {
169: cp++;
170: while ((c = *cp) != '\0' &&
171: c >= '0' && c <= '9') {
172: slice_num = slice_num * 10 + (c - '0');
173: cp++;
174: }
175: }
176:
177: *unit += (slice_num <<4);
178: /* if slice==0, it is either compatability or whole device */
179:
180: if (c >= 'a' && c < 'a' + j) { /* note: w/o this -> whole slice */
181: /*
182: * Minor number is <subdev_count>*unit + letter.
183: * NOW it is slice result + letter
184: */
185: #if 0
186: *unit = *unit * j + (c - 'a' +1); /* +1 to start 'a' at 1 */
187: #endif 0
188: *unit += (c - 'a' +1);
189: }
190: }
191: return (TRUE);
192: }
193:
194: /*
195: * Change an entry in the indirection list.
196: */
197: void
198: dev_set_indirection(name, ops, unit)
199: char *name;
200: dev_ops_t ops;
201: int unit;
202: {
203: register dev_indirect_t di;
204:
205: dev_indirect_search(di) {
206: if (!strcmp(di->d_name, name)) {
207: di->d_ops = ops;
208: di->d_unit = unit;
209: break;
210: }
211: }
212: }
213:
214: boolean_t dev_change_indirect(iname, dname, unit)
215: char *iname,*dname;
216: int unit;
217: {
218: struct dev_ops *dp;
219: struct dev_indirect *di;
220: int found = FALSE;
221:
222: dev_search(dp) {
223: if (!strcmp(dp->d_name,dname)) {
224: found = TRUE;
225: break;
226: }
227: }
228: if (!found) return FALSE;
229: dev_indirect_search(di) {
230: if (!strcmp(di->d_name,iname)) {
231: di->d_ops = dp;
232: di->d_unit = unit;
233: return TRUE;
234: }
235: }
236: return FALSE;
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.