⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
/* When a needed block is not in the cache, it must be fetched from the disk. * Special character files also require I/O.  The routines for these are here. * * The entry points in this file are: *   dev_open:   FS opens a device *   dev_close:  FS closes a device *   dev_io:	 FS does a read or write on a device *   dev_status: FS processes callback request alert *   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 *   do_ioctl:	 perform the IOCTL system call *   do_setsid:	 perform the SETSID system call (FS side) */#include "fs.h"#include <fcntl.h>#include <minix/callnr.h>#include <minix/com.h>#include "file.h"#include "fproc.h"#include "inode.h"#include "param.h"#include "super.h"#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))extern int dmap_size;/*===========================================================================* *				dev_open				     * *===========================================================================*/PUBLIC int dev_open(dev, proc, flags)dev_t dev;			/* device to open */int proc;			/* process to open for */int flags;			/* mode bits and flags */{  int major, r;  struct dmap *dp;  /* Determine the major device number call the device class specific   * open/close routine.  (This is the only routine that must check the   * device number for being in range.  All others can trust this check.)   */  major = (dev >> MAJOR) & BYTE;  if (major >= NR_DEVICES) major = 0;  dp = &dmap[major];  if (dp->dmap_driver == NONE) return ENXIO;  r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags);  if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver);  return(r);}/*===========================================================================* *				dev_close				     * *===========================================================================*/PUBLIC void dev_close(dev)dev_t dev;			/* device to close */{  /* See if driver is roughly valid. */  if (dmap[(dev >> MAJOR)].dmap_driver == NONE) {	return;  }  (void) (*dmap[(dev >> MAJOR) & BYTE].dmap_opcl)(DEV_CLOSE, dev, 0, 0);}/*===========================================================================* *				dev_status					* *===========================================================================*/PUBLIC void dev_status(message *m){	message st;	int d, get_more = 1;	for(d = 0; d < NR_DEVICES; d++)		if (dmap[d].dmap_driver != NONE &&		    dmap[d].dmap_driver == m->m_source)			break;	if (d >= NR_DEVICES)		return;	do {		int r;		st.m_type = DEV_STATUS;		if ((r=sendrec(m->m_source, &st)) != OK) {			if (r == EDEADSRCDST) return;			if (r == EDSTDIED) return;			if (r == ESRCDIED) return;			panic(__FILE__,"couldn't sendrec for DEV_STATUS", r);		}		switch(st.m_type) {			case DEV_REVIVE:				revive(st.REP_PROC_NR, st.REP_STATUS);				break;			case DEV_IO_READY:				select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS);				break;			default:				printf("FS: unrecognized reply %d to DEV_STATUS\n", st.m_type);				/* Fall through. */			case DEV_NO_STATUS:				get_more = 0;				break;		}	} while(get_more);	return;}/*===========================================================================* *				dev_io					     * *===========================================================================*/PUBLIC int dev_io(op, dev, proc, buf, pos, bytes, flags)int op;				/* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */dev_t dev;			/* major-minor device number */int proc;			/* in whose address space is buf? */void *buf;			/* virtual address of the buffer */off_t pos;			/* byte position */int bytes;			/* how many bytes to transfer */int flags;			/* special flags, like O_NONBLOCK */{/* Read or write from a device.  The parameter 'dev' tells which one. */  struct dmap *dp;  message dev_mess;  /* Determine task dmap. */  dp = &dmap[(dev >> MAJOR) & BYTE];  /* See if driver is roughly valid. */  if (dp->dmap_driver == NONE) return ENXIO;  /* Set up the message passed to task. */  dev_mess.m_type   = op;  dev_mess.DEVICE   = (dev >> MINOR) & BYTE;  dev_mess.POSITION = pos;  dev_mess.PROC_NR  = proc;  dev_mess.ADDRESS  = buf;  dev_mess.COUNT    = bytes;  dev_mess.TTY_FLAGS = flags;  /* Call the task. */  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);  /* Task has completed.  See if call completed. */  if (dev_mess.REP_STATUS == SUSPEND) {	if (flags & O_NONBLOCK) {		/* Not supposed to block. */		dev_mess.m_type = CANCEL;		dev_mess.PROC_NR = proc;		dev_mess.DEVICE = (dev >> MINOR) & BYTE;		(*dp->dmap_io)(dp->dmap_driver, &dev_mess);		if (dev_mess.REP_STATUS == EINTR) dev_mess.REP_STATUS = EAGAIN;	} else {		/* Suspend user. */		suspend(dp->dmap_driver);		return(SUSPEND);	}  }  return(dev_mess.REP_STATUS);}/*===========================================================================* *				gen_opcl				     * *===========================================================================*/PUBLIC int gen_opcl(op, dev, proc, flags)int op;				/* operation, DEV_OPEN or DEV_CLOSE */dev_t dev;			/* device to open or close */int proc;			/* process to open/close for */int flags;			/* mode bits and flags */{/* Called from the dmap struct in table.c on opens & closes of special files.*/  struct dmap *dp;  message dev_mess;  /* Determine task dmap. */  dp = &dmap[(dev >> MAJOR) & BYTE];  dev_mess.m_type   = op;  dev_mess.DEVICE   = (dev >> MINOR) & BYTE;  dev_mess.PROC_NR  = proc;  dev_mess.COUNT    = flags;  /* Call the task. */  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);  return(dev_mess.REP_STATUS);}/*===========================================================================* *				tty_opcl				     * *===========================================================================*/PUBLIC int tty_opcl(op, dev, proc, flags)int op;				/* operation, DEV_OPEN or DEV_CLOSE */dev_t dev;			/* device to open or close */int proc;			/* process to open/close for */int flags;			/* mode bits and flags */{/* This procedure is called from the dmap struct on tty open/close. */   int r;  register struct fproc *rfp;  /* Add O_NOCTTY to the flags if this process is not a session leader, or   * if it already has a controlling tty, or if it is someone elses   * controlling tty.   */  if (!fp->fp_sesldr || fp->fp_tty != 0) {	flags |= O_NOCTTY;  } else {	for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {		if (rfp->fp_tty == dev) flags |= O_NOCTTY;	}  }  r = gen_opcl(op, dev, proc, flags);  /* Did this call make the tty the controlling tty? */  if (r == 1) {	fp->fp_tty = dev;	r = OK;  }  return(r);}/*===========================================================================* *				ctty_opcl				     * *===========================================================================*/PUBLIC int ctty_opcl(op, dev, proc, flags)int op;				/* operation, DEV_OPEN or DEV_CLOSE */dev_t dev;			/* device to open or close */int proc;			/* process to open/close for */int flags;			/* mode bits and flags */{/* This procedure is called from the dmap struct in table.c on opening/closing * /dev/tty, the magic device that translates to the controlling tty. */   return(fp->fp_tty == 0 ? ENXIO : OK);}/*===========================================================================* *				do_setsid				     * *===========================================================================*/PUBLIC int do_setsid(){/* Perform the FS side of the SETSID call, i.e. get rid of the controlling * terminal of a process, and make the process a session leader. */  register struct fproc *rfp;  /* Only MM may do the SETSID call directly. */  if (who != PM_PROC_NR) return(ENOSYS);  /* Make the process a session leader with no controlling tty. */  rfp = &fproc[m_in.slot1];  rfp->fp_sesldr = TRUE;  rfp->fp_tty = 0;  return(OK);}/*===========================================================================* *				do_ioctl				     * *===========================================================================*/PUBLIC int do_ioctl(){/* Perform the ioctl(ls_fd, request, argx) system call (uses m2 fmt). */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -