163 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			163 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);
 | |
| 	      }
 | |
| 	    }
 | |
| 	  }
 | |
| 	}
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | 
