extern struct dmap {
int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
- void _PROTOTYPE ((*dmap_io), (int, message *) );
+ int _PROTOTYPE ((*dmap_io), (int, message *) );
int dmap_driver;
int dmap_flags;
} dmap[];
/*===========================================================================*
* gen_io *
*===========================================================================*/
-PUBLIC void gen_io(task_nr, mess_ptr)
+PUBLIC int gen_io(task_nr, mess_ptr)
int task_nr; /* which task to call */
message *mess_ptr; /* pointer to message for task */
{
* request. The caller will do the revive for the process.
*/
if (mess_ptr->m_type == CANCEL && local_m.REP_ENDPT == proc_e) {
- return;
+ return OK;
}
/* Otherwise it should be a REVIVE. */
if (r != OK) {
if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
printf("fs: dead driver %d\n", task_nr);
- return;
+ dmap_unmap_by_endpt(task_nr);
+ return r;
}
if (r == ELOCKED) {
printf("fs: ELOCKED talking to %d\n", task_nr);
- return;
+ return r;
}
panic(__FILE__,"call_task: can't send/receive", r);
}
}
r = receive(task_nr, mess_ptr);
}
+
+ return OK;
}
/*===========================================================================*
* ctty_io *
*===========================================================================*/
-PUBLIC void ctty_io(task_nr, mess_ptr)
+PUBLIC int ctty_io(task_nr, mess_ptr)
int task_nr; /* not used - for compatibility with dmap_t */
message *mess_ptr; /* pointer to message for task */
{
if (dp->dmap_driver == NONE) {
printf("FS: ctty_io: no driver for dev\n");
- return;
+ return EIO;
}
if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
printf("FS: ctty_io: old driver %d\n",
dp->dmap_driver);
- return;
+ return EIO;
}
(*dp->dmap_io)(dp->dmap_driver, mess_ptr);
}
+ return OK;
}
/*===========================================================================*
/*===========================================================================*
* no_dev_io *
*===========================================================================*/
-PUBLIC void no_dev_io(int proc, message *m)
+PUBLIC int 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;
+ return EIO;
}
/*===========================================================================*
* as a new network connection) that has been allocated within a task.
*/
struct dmap *dp;
- int minor;
+ int r, minor;
message dev_mess;
/* Determine task dmap. */
}
/* Call the task. */
- (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+ r= (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+ if (r != OK)
+ return r;
if (op == DEV_OPEN && dev_mess.REP_STATUS >= 0) {
if (dev_mess.REP_STATUS != minor) {
for(fp = filp; fp < &filp[NR_FILPS]; fp++) {
struct inode *in;
int minor;
+
if(fp->filp_count < 1 || !(in=fp->filp_ino)) continue;
if(((in->i_zone[0] >> MAJOR) & BYTE) != maj) continue;
if(!(in->i_mode & (I_BLOCK_SPECIAL|I_CHAR_SPECIAL))) continue;
*===========================================================================*/
PUBLIC int do_devctl()
{
- int result;
+ int result, proc_nr_e, proc_nr_n;
switch(m_in.ctl_req) {
case DEV_MAP:
+ /* Check process number of new driver. */
+ proc_nr_e= m_in.driver_nr;
+ if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
+ return(EINVAL);
+
/* Try to update device mapping. */
- result = map_driver(m_in.dev_nr, m_in.driver_nr, m_in.dev_style);
+ result = map_driver(m_in.dev_nr, proc_nr_e, m_in.dev_style);
+ if (result == OK)
+ {
+ /* If a driver has completed its exec(), it can be announced to be
+ * up.
+ */
+ if(fproc[proc_nr_n].fp_execced) {
+ dev_up(m_in.dev_nr);
+ } else {
+ dmap[m_in.dev_nr].dmap_flags |= DMAP_BABY;
+ }
+ }
break;
case DEV_UNMAP:
result = map_driver(m_in.dev_nr, NONE, 0);
dp->dmap_io = gen_io;
dp->dmap_driver = proc_nr_e;
- /* If a driver has completed its exec(), it can be announced to be up. */
- if(fproc[proc_nr_n].fp_execced) {
- dev_up(major);
- } else {
- dp->dmap_flags |= DMAP_BABY;
- }
-
return(OK);
}
/* This child has not exec()ced yet. */
cp->fp_execced = 0;
+#if 0
+printf("do_fork: child %d, slot %d\n", m_in.child_endpt, cp-fproc);
+#endif
/* Record the fact that both root and working dir have another user. */
dup_inode(cp->fp_rootdir);
case FSSIGNON: {
/* A server in user space calls in to manage a device. */
struct fssignon device;
- int r, major;
+ int r, major, proc_nr_n;
if (fp->fp_effuid != SU_UID && fp->fp_effuid != SERVERS_UID)
return(EPERM);
(phys_bytes) sizeof(device))) != OK)
return(r);
+ if (isokendpt(who_e, &proc_nr_n) != OK)
+ return(EINVAL);
+
/* Try to update device mapping. */
major = (device.dev >> MAJOR) & BYTE;
r=map_driver(major, who_e, device.style);
+ if (r == OK)
+ {
+ /* If a driver has completed its exec(), it can be announced
+ * to be up.
+ */
+ if(fproc[proc_nr_n].fp_execced) {
+ dev_up(major);
+ } else {
+ dmap[major].dmap_flags |= DMAP_BABY;
+ }
+ }
+
return(r);
}
case FSDEVUNMAP: {
_PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf,
off_t pos, int bytes, int flags) );
_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 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 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( void ctty_io, (int task_nr, message *mess_ptr) );
+_PROTOTYPE( int ctty_io, (int task_nr, message *mess_ptr) );
_PROTOTYPE( int do_ioctl, (void) );
_PROTOTYPE( int do_setsid, (void) );
_PROTOTYPE( void dev_status, (message *) );