* gen_opcl: generic call to a task to perform an open/close
* gen_io: generic call to a task to perform an I/O operation
* no_dev: open/close processing for devices that don't exist
+ * no_dev_io: i/o processing for devices that don't exist
* tty_opcl: perform tty-specific processing for open/close
* ctty_opcl: perform controlling-tty-specific processing for open/close
* ctty_io: perform controlling-tty-specific processing for I/O
dp = &dmap[major];
r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags);
if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver);
+ if (r == OK && dp->dmap_driver == NONE)
+ panic(__FILE__, "no driver for dev %d", dev);
return(r);
}
/* Determine task dmap. */
dp = &dmap[(dev >> MAJOR) & BYTE];
+ /* See if driver is roughly valid. */
+ if (dp->dmap_driver == NONE)
+ panic(__FILE__, "no driver for i/o on dev %d", dev);
+
/* Set up the message passed to task. */
dev_mess.m_type = op;
dev_mess.DEVICE = (dev >> MINOR) & BYTE;
*/
for (;;) {
if (r != OK) {
- if (r == EDEADDST) return; /* give up */
+ if (r == EDEADSRCDST) return; /* give up */
else panic(__FILE__,"call_task: can't send/receive", r);
}
int flags; /* mode bits and flags */
{
/* Called when opening a nonexistent device. */
-
return(ENODEV);
}
+/*===========================================================================*
+ * no_dev_io *
+ *===========================================================================*/
+PUBLIC void no_dev_io(int proc, message *m)
+{
+/* Called when doing i/o on a nonexistent device. */
+ printf("FS: I/O on unmapped device number\n");
+ return;
+}
+
/*===========================================================================*
* clone_opcl *
*===========================================================================*/
/* Get pointer to device entry in the dmap table. */
if (major < 0 || major >= NR_DEVICES) 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 if we're supposed to unmap it. */
+ /* Check if we're supposed to unmap it. If so, do it even
+ * if busy or unmutable, as unmap is called when driver has
+ * exited.
+ */
if(proc_nr == NONE) {
dp->dmap_opcl = no_dev;
- dp->dmap_io = 0;
- dp->dmap_driver = 0;
+ dp->dmap_io = no_dev_io;
+ dp->dmap_driver = NONE;
+ dp->dmap_flags = DMAP_MUTABLE; /* When gone, not busy or reserved. */
return(OK);
}
+
+ /* 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);
return(OK);
}
+/*===========================================================================*
+ * dmap_unmap_by_proc *
+ *===========================================================================*/
+PUBLIC void dmap_unmap_by_proc(int proc_nr)
+{
+ int i, r;
+ for (i=0; i<NR_DEVICES; i++)
+ if(dmap[i].dmap_driver && dmap[i].dmap_driver == proc_nr)
+ if((r=map_driver(i, NONE, 0)) != OK)
+ printf("FS: unmap of p %d / d %d failed: %d\n", proc_nr, i, r);
+
+ return;
+
+}
+
/*===========================================================================*
* build_dmap *
*===========================================================================*/
dp->dmap_flags = init_dmap[i].dmap_flags;
} else { /* no default */
dp->dmap_opcl = no_dev;
- dp->dmap_io = 0;
- dp->dmap_driver = 0;
+ dp->dmap_io = no_dev_io;
+ dp->dmap_driver = NONE;
dp->dmap_flags = DMAP_MUTABLE;
}
}
fp->fp_rootdir = NIL_INODE;
fp->fp_workdir = NIL_INODE;
+ /* If a driver exits, unmap its entries in the dmap table. */
+ dmap_unmap_by_proc(exitee);
+
/* If a session leader exits then revoke access to its controlling tty from
* all other processes using it.
*/
/* Mark slot as free. */
fp->fp_pid = PID_FREE;
+
return(OK);
}
_PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( void gen_io, (int task_nr, message *mess_ptr) );
_PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) );
+_PROTOTYPE( void no_dev_io, (int, message *) );
_PROTOTYPE( int tty_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int ctty_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int clone_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int do_devctl, (void) );
_PROTOTYPE( void build_dmap, (void) );
_PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style) );
+_PROTOTYPE( void dmap_unmap_by_proc, (int proc_nr) );
/* filedes.c */
_PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits) );
prev_i = i;
}
+/*===========================================================================*
+ * dmap_flags *
+ *===========================================================================*/
+PRIVATE char * dmap_flags(int flags)
+{
+ static char fl[10];
+ fl[0] = '-';
+ if(flags & DMAP_MUTABLE) fl[0] = 'M';
+ fl[1] = '\0';
+ return fl;
+}
+
/*===========================================================================*
* dtab_dmp *
*===========================================================================*/
getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap);
printf("File System (FS) device <-> driver mappings\n");
- printf("Major Proc\n");
- printf("----- ----\n");
+ printf("Major Proc Flags\n");
+ printf("----- ---- -----\n");
for (i=0; i<NR_DEVICES; i++) {
if (dmap[i].dmap_driver == 0) continue;
- printf("%5d ", i);
- printf("%4d\n", dmap[i].dmap_driver);
+ printf("%5d %4d %s\n",
+ i, dmap[i].dmap_driver, dmap_flags(dmap[i].dmap_flags));
}
}