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 #define NC(x) (NR_CTRLRS >= (x))
18 /* The order of the entries in the table determines the mapping between major
19 * device numbers and device drivers. Character and block devices
20 * can be intermixed at random. The ordering determines the device numbers in
21 * /dev. Note that the major device numbers used in /dev are NOT the same as
22 * the process numbers of the device drivers. See <minix/dmap.h> for mappings.
25 struct dmap dmap
[NR_DEVICES
];
27 #define DT_EMPTY { no_dev, no_dev_io, NONE, "", 0, STYLE_NDEV, NULL }
29 /*===========================================================================*
31 *===========================================================================*/
32 PUBLIC
int do_mapdriver()
38 char label
[LABEL_MAX
];
40 /* Only RS can map drivers. */
41 if (who_e
!= RS_PROC_NR
)
43 printf("vfs: unauthorized call of do_mapdriver by proc %d\n",
49 label_vir
= (vir_bytes
)m_in
.md_label
;
50 label_len
= m_in
.md_label_len
;
52 if (label_len
+1 > sizeof(label
))
54 printf("vfs:do_mapdriver: label too long\n");
58 r
= sys_vircopy(who_e
, D
, label_vir
, SELF
, D
, (vir_bytes
)label
,
62 printf("vfs:do_mapdriver: sys_vircopy failed: %d\n", r
);
66 label
[label_len
]= '\0';
68 r
= ds_retrieve_label_endpt(label
, &endpoint
);
71 printf("vfs:do_mapdriver: ds doesn't know '%s'\n", label
);
75 /* Try to update device mapping. */
78 r
= map_driver(label
, major
, endpoint
, m_in
.md_style
, flags
);
83 /*===========================================================================*
85 *===========================================================================*/
86 PUBLIC
int map_driver(label
, major
, proc_nr_e
, style
, flags
)
87 const char *label
; /* name of the driver */
88 int major
; /* major number of the device */
89 endpoint_t proc_nr_e
; /* process number of the driver */
90 int style
; /* style of the device */
91 int flags
; /* device flags */
93 /* Set a new device driver mapping in the dmap table.
94 * If the proc_nr is set to NONE, we're supposed to unmap it.
100 /* Get pointer to device entry in the dmap table. */
101 if (major
< 0 || major
>= NR_DEVICES
) return(ENODEV
);
104 /* Check if we're supposed to unmap it. */
105 if(proc_nr_e
== NONE
) {
106 dp
->dmap_opcl
= no_dev
;
107 dp
->dmap_io
= no_dev_io
;
108 dp
->dmap_driver
= NONE
;
109 dp
->dmap_flags
= flags
;
113 /* Check process number of new driver if requested. */
114 if (! (flags
& DRV_FORCED
))
116 if (isokendpt(proc_nr_e
, &proc_nr_n
) != OK
)
122 if (len
+1 > sizeof(dp
->dmap_label
))
123 panic("map_driver: label too long: %d", len
);
124 strcpy(dp
->dmap_label
, label
);
127 /* Try to update the entry. */
130 dp
->dmap_opcl
= gen_opcl
;
131 dp
->dmap_io
= gen_io
;
134 dp
->dmap_opcl
= gen_opcl
;
135 dp
->dmap_io
= asyn_io
;
138 dp
->dmap_opcl
= tty_opcl
;
139 dp
->dmap_io
= gen_io
;
142 dp
->dmap_opcl
= ctty_opcl
;
143 dp
->dmap_io
= ctty_io
;
146 dp
->dmap_opcl
= clone_opcl
;
147 dp
->dmap_io
= gen_io
;
152 dp
->dmap_driver
= proc_nr_e
;
153 dp
->dmap_flags
= flags
;
154 dp
->dmap_style
= style
;
159 /*===========================================================================*
160 * dmap_unmap_by_endpt *
161 *===========================================================================*/
162 PUBLIC
void dmap_unmap_by_endpt(int proc_nr_e
)
165 for (i
=0; i
<NR_DEVICES
; i
++)
166 if(dmap
[i
].dmap_driver
&& dmap
[i
].dmap_driver
== proc_nr_e
)
167 if((r
=map_driver(NULL
, i
, NONE
, 0, 0)) != OK
)
168 printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr_e
,i
,r
);
174 /*===========================================================================*
176 *===========================================================================*/
177 PUBLIC
int map_service(struct rprocpub
*rpub
)
179 /* Map a new service by storing its device driver properties. */
182 /* Not a driver, nothing more to do. */
188 r
= map_driver(rpub
->label
, rpub
->dev_nr
, rpub
->endpoint
,
189 rpub
->dev_style
, rpub
->dev_flags
);
194 /* If driver has two major numbers associated, also map the other one. */
195 if(rpub
->dev_style2
!= STYLE_NDEV
) {
196 r
= map_driver(rpub
->label
, rpub
->dev_nr
+1, rpub
->endpoint
,
197 rpub
->dev_style2
, rpub
->dev_flags
);
206 /*===========================================================================*
208 *===========================================================================*/
209 PUBLIC
void build_dmap()
211 /* Initialize the table with empty device <-> driver mappings. */
213 struct dmap dmap_default
= DT_EMPTY
;
215 for (i
=0; i
<NR_DEVICES
; i
++) {
216 dmap
[i
] = dmap_default
;
220 /*===========================================================================*
221 * dmap_driver_match *
222 *===========================================================================*/
223 PUBLIC
int dmap_driver_match(endpoint_t proc
, int major
)
225 if (major
< 0 || major
>= NR_DEVICES
) return(0);
226 if(dmap
[major
].dmap_driver
!= NONE
&& dmap
[major
].dmap_driver
== proc
)
231 /*===========================================================================*
233 *===========================================================================*/
234 PUBLIC
void dmap_endpt_up(int proc_e
)
237 for (i
=0; i
<NR_DEVICES
; i
++) {
238 if(dmap
[i
].dmap_driver
!= NONE
239 && dmap
[i
].dmap_driver
== proc_e
) {