source: branches/minix3-book/servers/fs/dmap.c

Last change on this file was 4, checked in by Mattia Monga, 14 years ago

Importazione sorgenti libro

File size: 6.6 KB
Line 
1/* This file contains the table with device <-> driver mappings. It also
2 * contains some routines to dynamically add and/ or remove device drivers
3 * or change mappings.
4 */
5
6#include "fs.h"
7#include "fproc.h"
8#include <string.h>
9#include <stdlib.h>
10#include <ctype.h>
11#include <unistd.h>
12#include <minix/com.h>
13#include "param.h"
14
15/* Some devices may or may not be there in the next table. */
16#define DT(enable, opcl, io, driver, flags) \
17 { (enable?(opcl):no_dev), (enable?(io):0), \
18 (enable?(driver):0), (flags) },
19#define NC(x) (NR_CTRLRS >= (x))
20
21/* The order of the entries here determines the mapping between major device
22 * numbers and tasks. The first entry (major device 0) is not used. The
23 * next entry is major device 1, etc. Character and block devices can be
24 * intermixed at random. The ordering determines the device numbers in /dev/.
25 * Note that FS knows the device number of /dev/ram/ to load the RAM disk.
26 * Also note that the major device numbers used in /dev/ are NOT the same as
27 * the process numbers of the device drivers.
28 */
29/*
30 Driver enabled Open/Cls I/O Driver # Flags Device File
31 -------------- -------- ------ ----------- ----- ------ ----
32 */
33struct dmap dmap[NR_DEVICES]; /* actual map */
34PRIVATE struct dmap init_dmap[] = {
35 DT(1, no_dev, 0, 0, 0) /* 0 = not used */
36 DT(1, gen_opcl, gen_io, MEM_PROC_NR, 0) /* 1 = /dev/mem */
37 DT(0, no_dev, 0, 0, DMAP_MUTABLE) /* 2 = /dev/fd0 */
38 DT(0, no_dev, 0, 0, DMAP_MUTABLE) /* 3 = /dev/c0 */
39 DT(1, tty_opcl, gen_io, TTY_PROC_NR, 0) /* 4 = /dev/tty00 */
40 DT(1, ctty_opcl,ctty_io, TTY_PROC_NR, 0) /* 5 = /dev/tty */
41 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /* 6 = /dev/lp */
42 DT(1, no_dev, 0, 0, DMAP_MUTABLE) /* 7 = /dev/ip */
43 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /* 8 = /dev/c1 */
44 DT(0, 0, 0, 0, DMAP_MUTABLE) /* 9 = not used */
45 DT(0, no_dev, 0, 0, DMAP_MUTABLE) /*10 = /dev/c2 */
46 DT(0, 0, 0, 0, DMAP_MUTABLE) /*11 = not used */
47 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /*12 = /dev/c3 */
48 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /*13 = /dev/audio */
49 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /*14 = /dev/mixer */
50 DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0) /*15 = /dev/klog */
51 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /*16 = /dev/random*/
52 DT(0, no_dev, 0, NONE, DMAP_MUTABLE) /*17 = /dev/cmos */
53};
54
55/*===========================================================================*
56 * do_devctl *
57 *===========================================================================*/
58PUBLIC int do_devctl()
59{
60 int result;
61
62 switch(m_in.ctl_req) {
63 case DEV_MAP:
64 /* Try to update device mapping. */
65 result = map_driver(m_in.dev_nr, m_in.driver_nr, m_in.dev_style);
66 break;
67 case DEV_UNMAP:
68 result = ENOSYS;
69 break;
70 default:
71 result = EINVAL;
72 }
73 return(result);
74}
75
76/*===========================================================================*
77 * map_driver *
78 *===========================================================================*/
79PUBLIC int map_driver(major, proc_nr, style)
80int major; /* major number of the device */
81int proc_nr; /* process number of the driver */
82int style; /* style of the device */
83{
84/* Set a new device driver mapping in the dmap table. Given that correct
85 * arguments are given, this only works if the entry is mutable and the
86 * current driver is not busy.
87 * Normal error codes are returned so that this function can be used from
88 * a system call that tries to dynamically install a new driver.
89 */
90 struct dmap *dp;
91
92 /* Get pointer to device entry in the dmap table. */
93 if (major >= NR_DEVICES) return(ENODEV);
94 dp = &dmap[major];
95
96 /* See if updating the entry is allowed. */
97 if (! (dp->dmap_flags & DMAP_MUTABLE)) return(EPERM);
98 if (dp->dmap_flags & DMAP_BUSY) return(EBUSY);
99
100 /* Check process number of new driver. */
101 if (! isokprocnr(proc_nr)) return(EINVAL);
102
103 /* Try to update the entry. */
104 switch (style) {
105 case STYLE_DEV: dp->dmap_opcl = gen_opcl; break;
106 case STYLE_TTY: dp->dmap_opcl = tty_opcl; break;
107 case STYLE_CLONE: dp->dmap_opcl = clone_opcl; break;
108 default: return(EINVAL);
109 }
110 dp->dmap_io = gen_io;
111 dp->dmap_driver = proc_nr;
112 return(OK);
113}
114
115/*===========================================================================*
116 * build_dmap *
117 *===========================================================================*/
118PUBLIC void build_dmap()
119{
120/* Initialize the table with all device <-> driver mappings. Then, map
121 * the boot driver to a controller and update the dmap table to that
122 * selection. The boot driver and the controller it handles are set at
123 * the boot monitor.
124 */
125 char driver[16];
126 char *controller = "c##";
127 int nr, major = -1;
128 int i,s;
129 struct dmap *dp;
130
131 /* Build table with device <-> driver mappings. */
132 for (i=0; i<NR_DEVICES; i++) {
133 dp = &dmap[i];
134 if (i < sizeof(init_dmap)/sizeof(struct dmap) &&
135 init_dmap[i].dmap_opcl != no_dev) { /* a preset driver */
136 dp->dmap_opcl = init_dmap[i].dmap_opcl;
137 dp->dmap_io = init_dmap[i].dmap_io;
138 dp->dmap_driver = init_dmap[i].dmap_driver;
139 dp->dmap_flags = init_dmap[i].dmap_flags;
140 } else { /* no default */
141 dp->dmap_opcl = no_dev;
142 dp->dmap_io = 0;
143 dp->dmap_driver = 0;
144 dp->dmap_flags = DMAP_MUTABLE;
145 }
146 }
147
148 /* Get settings of 'controller' and 'driver' at the boot monitor. */
149 if ((s = env_get_param("label", driver, sizeof(driver))) != OK)
150 panic(__FILE__,"couldn't get boot monitor parameter 'driver'", s);
151 if ((s = env_get_param("controller", controller, sizeof(controller))) != OK)
152 panic(__FILE__,"couldn't get boot monitor parameter 'controller'", s);
153
154 /* Determine major number to map driver onto. */
155 if (controller[0] == 'f' && controller[1] == 'd') {
156 major = FLOPPY_MAJOR;
157 }
158 else if (controller[0] == 'c' && isdigit(controller[1])) {
159 if ((nr = (unsigned) atoi(&controller[1])) > NR_CTRLRS)
160 panic(__FILE__,"monitor 'controller' maximum 'c#' is", NR_CTRLRS);
161 major = CTRLR(nr);
162 }
163 else {
164 panic(__FILE__,"monitor 'controller' syntax is 'c#' of 'fd'", NO_NUM);
165 }
166
167 /* Now try to set the actual mapping and report to the user. */
168 if ((s=map_driver(major, DRVR_PROC_NR, STYLE_DEV)) != OK)
169 panic(__FILE__,"map_driver failed",s);
170 printf("Boot medium driver: %s driver mapped onto controller %s.\n",
171 driver, controller);
172}
173
Note: See TracBrowser for help on using the repository browser.