1 /* This file contains the table with device <-> driver mappings. It also
2 * contains some routines to dynamically add and/ or remove device drivers
12 #include <minix/com.h>
16 /* Some devices may or may not be there in the next table. */
17 #define DT(enable, opcl, io, driver, flags, label) \
18 { (enable?(opcl):no_dev), (enable?(io):0), \
19 (enable?(driver):0), (flags), label, FALSE },
20 #define NC(x) (NR_CTRLRS >= (x))
22 /* The order of the entries here determines the mapping between major device
23 * numbers and tasks. The first entry (major device 0) is not used. The
24 * next entry is major device 1, etc. Character and block devices can be
25 * intermixed at random. The ordering determines the device numbers in /dev/.
26 * Note that FS knows the device number of /dev/ram/ to load the RAM disk.
27 * Also note that the major device numbers used in /dev/ are NOT the same as
28 * the process numbers of the device drivers.
31 Driver enabled Open/Cls I/O Driver # Flags Device File
32 -------------- -------- ------ ----------- ----- ------ ----
34 struct dmap dmap
[NR_DEVICES
]; /* actual map */
35 PRIVATE
struct dmap init_dmap
[] = {
36 DT(1, no_dev
, 0, 0, 0, "") /* 0 = not used */
37 DT(1, gen_opcl
, gen_io
, MEM_PROC_NR
, 0, "memory") /* 1 = /dev/mem */
38 DT(0, no_dev
, 0, 0, DMAP_MUTABLE
, "") /* 2 = /dev/fd0 */
39 DT(0, no_dev
, 0, 0, DMAP_MUTABLE
, "") /* 3 = /dev/c0 */
40 DT(1, tty_opcl
, gen_io
, TTY_PROC_NR
, 0, "") /* 4 = /dev/tty00 */
41 DT(1, ctty_opcl
,ctty_io
, TTY_PROC_NR
, 0, "") /* 5 = /dev/tty */
42 DT(0, no_dev
, 0, NONE
, DMAP_MUTABLE
, "") /* 6 = /dev/lp */
44 #if (MACHINE == IBM_PC)
45 DT(1, no_dev
, 0, 0, DMAP_MUTABLE
, "") /* 7 = /dev/ip */
46 DT(0, no_dev
, 0, NONE
, DMAP_MUTABLE
, "") /* 8 = /dev/c1 */
47 DT(0, 0, 0, 0, DMAP_MUTABLE
, "") /* 9 = not used */
48 DT(0, no_dev
, 0, 0, DMAP_MUTABLE
, "") /*10 = /dev/c2 */
49 DT(0, no_dev
, 0, 0, DMAP_MUTABLE
, "") /*11 = /dev/filter*/
50 DT(0, no_dev
, 0, NONE
, DMAP_MUTABLE
, "") /*12 = /dev/c3 */
51 DT(0, no_dev
, 0, NONE
, DMAP_MUTABLE
, "") /*13 = /dev/audio */
52 DT(0, 0, 0, 0, DMAP_MUTABLE
, "") /*14 = not used */
53 DT(1, gen_opcl
, gen_io
, LOG_PROC_NR
, 0, "") /*15 = /dev/klog */
54 DT(0, no_dev
, 0, NONE
, DMAP_MUTABLE
, "") /*16 = /dev/random*/
55 DT(0, no_dev
, 0, 0, DMAP_MUTABLE
, "") /*17 = /dev/hello */
56 DT(0, 0, 0, 0, DMAP_MUTABLE
, "") /*18 = not used */
60 /*===========================================================================*
62 *===========================================================================*/
63 PUBLIC
int do_mapdriver()
65 int r
, force
, major
, proc_nr_n
;
69 char label
[LABEL_MAX
];
73 printf("FS: unauthorized call of do_mapdriver by proc %d\n",
75 return(EPERM
); /* only su (should be only RS or some drivers)
76 * may call do_mapdriver.
81 label_vir
= (vir_bytes
)m_in
.md_label
;
82 label_len
= m_in
.md_label_len
;
84 if (label_len
+1 > sizeof(label
))
86 printf("vfs:do_mapdriver: label too long\n");
90 r
= sys_vircopy(who_e
, D
, label_vir
, SELF
, D
, (vir_bytes
)label
,
94 printf("vfs:do_mapdriver: sys_vircopy failed: %d\n", r
);
98 label
[label_len
]= '\0';
100 r
= ds_retrieve_label_num(label
, &tasknr
);
103 printf("vfs:do_mapdriver: ds doesn't know '%s'\n", label
);
107 if (isokendpt(tasknr
, &proc_nr_n
) != OK
)
109 printf("vfs:do_mapdriver: bad endpoint %d\n", tasknr
);
113 /* Try to update device mapping. */
114 major
= m_in
.md_major
;
115 force
= m_in
.md_force
;
116 r
= map_driver(label
, major
, tasknr
, m_in
.md_style
, force
);
119 /* If a driver has completed its exec(), it can be announced
122 if(force
|| fproc
[proc_nr_n
].fp_execced
) {
125 dmap
[major
].dmap_flags
|= DMAP_BABY
;
132 /*===========================================================================*
134 *===========================================================================*/
135 PUBLIC
int map_driver(label
, major
, proc_nr_e
, style
, force
)
136 char *label
; /* name of the driver */
137 int major
; /* major number of the device */
138 endpoint_t proc_nr_e
; /* process number of the driver */
139 int style
; /* style of the device */
142 /* Set a new device driver mapping in the dmap table. Given that correct
143 * arguments are given, this only works if the entry is mutable and the
144 * current driver is not busy. If the proc_nr is set to NONE, we're supposed
147 * Normal error codes are returned so that this function can be used from
148 * a system call that tries to dynamically install a new driver.
154 /* Get pointer to device entry in the dmap table. */
155 if (major
< 0 || major
>= NR_DEVICES
) return(ENODEV
);
158 /* Check if we're supposed to unmap it. If so, do it even
159 * if busy or unmutable, as unmap is called when driver has
162 if(proc_nr_e
== NONE
) {
163 dp
->dmap_opcl
= no_dev
;
164 dp
->dmap_io
= no_dev_io
;
165 dp
->dmap_driver
= NONE
;
166 dp
->dmap_flags
= DMAP_MUTABLE
; /* When gone, not busy or reserved. */
170 /* See if updating the entry is allowed. */
171 if (! (dp
->dmap_flags
& DMAP_MUTABLE
)) return(EPERM
);
172 if (dp
->dmap_flags
& DMAP_BUSY
) return(EBUSY
);
176 /* Check process number of new driver. */
177 if (isokendpt(proc_nr_e
, &proc_nr_n
) != OK
)
183 if (len
+1 > sizeof(dp
->dmap_label
))
184 panic("map_driver: label too long: %d", len
);
185 strcpy(dp
->dmap_label
, label
);
188 /* Try to update the entry. */
190 case STYLE_DEV
: dp
->dmap_opcl
= gen_opcl
; break;
191 case STYLE_TTY
: dp
->dmap_opcl
= tty_opcl
; break;
192 case STYLE_CLONE
: dp
->dmap_opcl
= clone_opcl
; break;
193 default: return(EINVAL
);
195 dp
->dmap_io
= gen_io
;
196 dp
->dmap_driver
= proc_nr_e
;
198 if (dp
->dmap_async_driver
)
199 dp
->dmap_io
= asyn_io
;
204 /*===========================================================================*
205 * dmap_unmap_by_endpt *
206 *===========================================================================*/
207 PUBLIC
void dmap_unmap_by_endpt(int proc_nr_e
)
210 for (i
=0; i
<NR_DEVICES
; i
++)
211 if(dmap
[i
].dmap_driver
&& dmap
[i
].dmap_driver
== proc_nr_e
)
212 if((r
=map_driver(NULL
, i
, NONE
, 0, 0)) != OK
)
213 printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr_e
,i
,r
);
219 /*===========================================================================*
221 *===========================================================================*/
222 PUBLIC
void build_dmap()
224 /* Initialize the table with all device <-> driver mappings. Then, map
225 * the boot driver to a controller and update the dmap table to that
226 * selection. The boot driver and the controller it handles are set at
232 /* Build table with device <-> driver mappings. */
233 for (i
=0; i
<NR_DEVICES
; i
++) {
235 if (i
< sizeof(init_dmap
)/sizeof(struct dmap
) &&
236 init_dmap
[i
].dmap_opcl
!= no_dev
) { /* a preset driver */
237 dp
->dmap_opcl
= init_dmap
[i
].dmap_opcl
;
238 dp
->dmap_io
= init_dmap
[i
].dmap_io
;
239 dp
->dmap_driver
= init_dmap
[i
].dmap_driver
;
240 dp
->dmap_flags
= init_dmap
[i
].dmap_flags
;
241 strcpy(dp
->dmap_label
, init_dmap
[i
].dmap_label
);
242 dp
->dmap_async_driver
= FALSE
;
243 } else { /* no default */
244 dp
->dmap_opcl
= no_dev
;
245 dp
->dmap_io
= no_dev_io
;
246 dp
->dmap_driver
= NONE
;
247 dp
->dmap_flags
= DMAP_MUTABLE
;
251 dmap
[13].dmap_async_driver
= TRUE
; /* Audio */
252 dmap
[15].dmap_async_driver
= TRUE
; /* Log */
253 dmap
[15].dmap_io
= asyn_io
;
254 dmap
[16].dmap_async_driver
= TRUE
; /* Random */
258 /*===========================================================================*
259 * dmap_driver_match *
260 *===========================================================================*/
261 PUBLIC
int dmap_driver_match(endpoint_t proc
, int major
)
263 if (major
< 0 || major
>= NR_DEVICES
) return(0);
264 if(dmap
[major
].dmap_driver
!= NONE
&& dmap
[major
].dmap_driver
== proc
)
269 /*===========================================================================*
271 *===========================================================================*/
272 PUBLIC
void dmap_endpt_up(int proc_e
)
275 for (i
=0; i
<NR_DEVICES
; i
++) {
276 if(dmap
[i
].dmap_driver
!= NONE
277 && dmap
[i
].dmap_driver
== proc_e
278 && (dmap
[i
].dmap_flags
& DMAP_BABY
)) {
279 dmap
[i
].dmap_flags
&= ~DMAP_BABY
;