minix/servers/fs/dmap.c
2005-04-21 14:53:53 +00:00

162 lines
6.1 KiB
C

/* This file contains the table with device <-> driver mappings. It also
* contains some routines to dynamically add and/ or remove device drivers
* or change mappings.
*/
#include "fs.h"
#include "fproc.h"
#include "dmap.h"
#include <string.h>
#include <minix/com.h>
#include <minix/utils.h>
/* Some devices may or may not be there in the next table. */
#define DT(enable, opcl, io, driver, flags) \
{ (enable?(opcl):no_dev), (enable?(io):0), \
(enable?(driver):0), (flags) },
/* The order of the entries here determines the mapping between major device
* numbers and tasks. The first entry (major device 0) is not used. The
* next entry is major device 1, etc. Character and block devices can be
* intermixed at random. The ordering determines the device numbers in /dev/.
* Note that FS knows the device number of /dev/ram/ to load the RAM disk.
* Also note that the major device numbers used in /dev/ are NOT the same as
* the process numbers of the device drivers.
*/
/*
Driver enabled Open/Cls I/O Driver # Flags Device File
-------------- -------- ------ ----------- ----- ------ ----
*/
struct dmap dmap[] = {
DT(1, no_dev, 0, 0, 0) /* 0 = not used */
DT(1, gen_opcl, gen_io, MEMORY, 0) /* 1 = /dev/mem */
DT(ENABLE_FLOPPY, gen_opcl, gen_io, FLOPPY, 0) /* 2 = /dev/fd0 */
DT(NR_CTRLRS >= 1, gen_opcl, gen_io, CTRLR(0), DMAP_MUTABLE) /* 3 = /dev/c0 */
#if ENABLE_USER_TTY
DT(1, tty_opcl, gen_io, TERMINAL, 0) /* 4 = /dev/tty00 */
DT(1, ctty_opcl,ctty_io,TERMINAL, 0) /* 5 = /dev/tty */
#else
DT(1, tty_opcl, gen_io, TTY, 0) /* 4 = /dev/tty00 */
DT(1, ctty_opcl,ctty_io,TTY, 0) /* 5 = /dev/tty */
#endif
DT(ENABLE_PRINTER, gen_opcl, gen_io, PRINTER, 0) /* 6 = /dev/lp */
#if (MACHINE == IBM_PC)
DT(1, no_dev, 0, 0, DMAP_MUTABLE) /* 7 = /dev/ip */
DT(NR_CTRLRS >= 2, gen_opcl, gen_io, CTRLR(1), DMAP_MUTABLE) /* 8 = /dev/c1 */
DT(0, 0, 0, 0, DMAP_MUTABLE) /* 9 = not used */
DT(NR_CTRLRS >= 3, gen_opcl, gen_io, CTRLR(2), DMAP_MUTABLE) /*10 = /dev/c2 */
DT(0, 0, 0, 0, DMAP_MUTABLE) /*11 = not used */
DT(NR_CTRLRS >= 4, gen_opcl, gen_io, CTRLR(3), DMAP_MUTABLE) /*12 = /dev/c3 */
DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*13 = /dev/audio */
DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*14 = /dev/mixer */
#endif /* IBM_PC */
};
/* This is the maximum major number at compile time. This may change when
* devices are dynamically added or removed.
*/
int max_major = sizeof(dmap)/sizeof(struct dmap);
/*===========================================================================*
* map_driver *
*===========================================================================*/
PUBLIC int map_driver(major, proc_nr, dev_style)
int major; /* major number of the device */
int proc_nr; /* process number of the driver */
int dev_style; /* style of the device */
{
/* Set a new device driver mapping in the dmap table. Given that correct
* arguments are given, this only works if the entry is mutable and the
* current driver is not busy.
* Normal error codes are returned so that this function can be used from
* a system call that tries to dynamically install a new driver.
*/
struct dmap *dp;
/* Get pointer to device entry in the dmap table. */
if (major >= max_major) /* verify bounds */
return(ENODEV);
dp = &dmap[major];
/* See if updating the entry is allowed. */
if (! (dp->dmap_flags & DMAP_MUTABLE))
return(EPERM);
if (dp->dmap_flags & DMAP_BUSY)
return(EBUSY);
/* Check process number of new driver. */
if (! isokprocnr(proc_nr))
return(EINVAL);
/* Try to update the entry. */
switch (dev_style) {
case STYLE_DEV: dp->dmap_opcl = gen_opcl; break;
case STYLE_TTY: dp->dmap_opcl = tty_opcl; break;
case STYLE_CLONE: dp->dmap_opcl = clone_opcl; break;
default: return(EINVAL);
}
dp->dmap_io = gen_io;
dp->dmap_driver = proc_nr;
return(OK);
}
/*===========================================================================*
* map_controllers *
*===========================================================================*/
PUBLIC void map_controllers()
{
/* Map drivers to controllers and update the dmap table to that selection.
* For each controller, the environment variable set by the boot monitor is
* analyzed to see what type of Winchester disk is attached. Then, the name
* of the driver that handles the device is looked up in the local drivertab.
* Finally, the process number of the driver is looked up, and, if found, is
* installed in the dmap table.
*/
static char ctrlr_nr[] = "c0"; /* controller currently analyzed */
char ctrlr_type[8]; /* type of Winchester disk */
int i, c, s;
int proc_nr=0; /* process number of driver */
struct drivertab *dp;
struct drivertab {
char wini_type[8];
char proc_name[8];
} drivertab[] = {
{ "at", "AT_WINI" }, /* AT Winchester */
{ "bios", "..." },
{ "esdi", "..." },
{ "xt", "..." },
{ "aha1540", "..." },
{ "dosfile", "..." },
{ "fatfile", "..." },
};
for (c=0; c < NR_CTRLRS; c++) {
ctrlr_nr[1] = '0' + c;
if ((s = get_mon_param(ctrlr_nr, ctrlr_type, 8)) != OK) {
if (s != ESRCH)
printf("FS: warning, couldn't get monitor param: %d\n", s);
continue;
}
for (dp = drivertab;
dp < drivertab + sizeof(drivertab)/sizeof(drivertab[0]); dp++) {
if (strcmp(ctrlr_type, dp->wini_type) == 0) { /* found driver name */
if ((s=sys_getprocnr(&proc_nr, /* lookup proc nr */
dp->proc_name, strlen(dp->proc_name)+1)) == OK) {
for (i=0; i< max_major; i++) { /* find mapping */
if (dmap[i].dmap_driver == CTRLR(c)) {
if (map_driver(i, proc_nr, STYLE_DEV) == OK) {
printf("FS: controller %s (%s) mapped to %s driver (proc. nr %d)\n",
ctrlr_nr, dp->wini_type, dp->proc_name, dmap[i].dmap_driver);
}
}
}
}
}
}
}
}