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

📄 device.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
  struct filp *f;  register struct inode *rip;  dev_t dev;  if ( (f = get_filp(m_in.ls_fd)) == NIL_FILP) return(err_code);  rip = f->filp_ino;		/* get inode pointer */  if ( (rip->i_mode & I_TYPE) != I_CHAR_SPECIAL	&& (rip->i_mode & I_TYPE) != I_BLOCK_SPECIAL) return(ENOTTY);  dev = (dev_t) rip->i_zone[0];#if ENABLE_BINCOMPAT  if ((m_in.TTY_REQUEST >> 8) == 't') {	/* Obsolete sgtty ioctl, message contains more than is sane. */	struct dmap *dp;	message dev_mess;	dp = &dmap[(dev >> MAJOR) & BYTE];	dev_mess = m;	/* Copy full message with all the weird bits. */	dev_mess.m_type   = DEV_IOCTL;	dev_mess.PROC_NR  = who;	dev_mess.TTY_LINE = (dev >> MINOR) & BYTE;		/* Call the task. */	(*dp->dmap_io)(dp->dmap_driver, &dev_mess);	m_out.TTY_SPEK = dev_mess.TTY_SPEK;	/* erase and kill */	m_out.TTY_FLAGS = dev_mess.TTY_FLAGS;	/* flags */	return(dev_mess.REP_STATUS);  }#endif  return(dev_io(DEV_IOCTL, dev, who, m_in.ADDRESS, 0L,   	m_in.REQUEST, f->filp_flags));}/*===========================================================================* *				gen_io					     * *===========================================================================*/PUBLIC void gen_io(task_nr, mess_ptr)int task_nr;			/* which task to call */message *mess_ptr;		/* pointer to message for task */{/* All file system I/O ultimately comes down to I/O on major/minor device * pairs.  These lead to calls on the following routines via the dmap table. */  int r, proc_nr;  message local_m;  proc_nr = mess_ptr->PROC_NR;  if (! isokprocnr(proc_nr)) {      printf("FS: warning, got illegal process number (%d) from %d\n",          mess_ptr->PROC_NR, mess_ptr->m_source);      return;  }  while ((r = sendrec(task_nr, mess_ptr)) == ELOCKED) {	/* sendrec() failed to avoid deadlock. The task 'task_nr' is	 * trying to send a REVIVE message for an earlier request.	 * Handle it and go try again.	 */	if ((r = receive(task_nr, &local_m)) != OK) {		break;	}	/* If we're trying to send a cancel message to a task which has just	 * sent a completion reply, ignore the reply and abort the cancel	 * request. The caller will do the revive for the process.	 */	if (mess_ptr->m_type == CANCEL && local_m.REP_PROC_NR == proc_nr) {		return;	}	/* Otherwise it should be a REVIVE. */	if (local_m.m_type != REVIVE) {		printf(		"fs: strange device reply from %d, type = %d, proc = %d (1)\n",			local_m.m_source,			local_m.m_type, local_m.REP_PROC_NR);		continue;	}	revive(local_m.REP_PROC_NR, local_m.REP_STATUS);  }  /* The message received may be a reply to this call, or a REVIVE for some   * other process.   */  for (;;) {	if (r != OK) {		if (r == EDEADSRCDST) return;	/* give up */		if (r == EDSTDIED) return;		if (r == ESRCDIED) return;		if (r == ELOCKED) return;		else panic(__FILE__,"call_task: can't send/receive", r);	}  	/* Did the process we did the sendrec() for get a result? */  	if (mess_ptr->REP_PROC_NR == proc_nr) {  		break;	} else if (mess_ptr->m_type == REVIVE) {		/* Otherwise it should be a REVIVE. */		revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS);	} else {		printf(		"fs: strange device reply from %d, type = %d, proc = %d (2)\n",			mess_ptr->m_source,			mess_ptr->m_type, mess_ptr->REP_PROC_NR);		return;	}	r = receive(task_nr, mess_ptr);  }}/*===========================================================================* *				ctty_io					     * *===========================================================================*/PUBLIC void ctty_io(task_nr, mess_ptr)int task_nr;			/* not used - for compatibility with dmap_t */message *mess_ptr;		/* pointer to message for task */{/* This routine is only called for one device, namely /dev/tty.  Its job * is to change the message to use the controlling terminal, instead of the * major/minor pair for /dev/tty itself. */  struct dmap *dp;  if (fp->fp_tty == 0) {	/* No controlling tty present anymore, return an I/O error. */	mess_ptr->REP_STATUS = EIO;  } else {	/* Substitute the controlling terminal device. */	dp = &dmap[(fp->fp_tty >> MAJOR) & BYTE];	mess_ptr->DEVICE = (fp->fp_tty >> MINOR) & BYTE;	(*dp->dmap_io)(dp->dmap_driver, mess_ptr);  }}/*===========================================================================* *				no_dev					     * *===========================================================================*/PUBLIC int no_dev(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 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. */  return;}/*===========================================================================* *				clone_opcl				     * *===========================================================================*/PUBLIC int clone_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 */{/* Some devices need special processing upon open.  Such a device is "cloned", * i.e. on a succesful open it is replaced by a new device with a new unique * minor device number.  This new device number identifies a new object (such * as a new network connection) that has been allocated within a task. */  struct dmap *dp;  int minor;  message dev_mess;  /* Determine task dmap. */  dp = &dmap[(dev >> MAJOR) & BYTE];  minor = (dev >> MINOR) & BYTE;  dev_mess.m_type   = op;  dev_mess.DEVICE   = minor;  dev_mess.PROC_NR  = proc;  dev_mess.COUNT    = flags;  /* Call the task. */  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);  if (op == DEV_OPEN && dev_mess.REP_STATUS >= 0) {	if (dev_mess.REP_STATUS != minor) {		/* A new minor device number has been returned.  Create a		 * temporary device file to hold it.		 */		struct inode *ip;		/* Device number of the new device. */		dev = (dev & ~(BYTE << MINOR)) | (dev_mess.REP_STATUS << MINOR);		ip = alloc_inode(root_dev, ALL_MODES | I_CHAR_SPECIAL);		if (ip == NIL_INODE) {			/* Oops, that didn't work.  Undo open. */			(void) clone_opcl(DEV_CLOSE, dev, proc, 0);			return(err_code);		}		ip->i_zone[0] = dev;		put_inode(fp->fp_filp[m_in.fd]->filp_ino);		fp->fp_filp[m_in.fd]->filp_ino = ip;	}	dev_mess.REP_STATUS = OK;  }  return(dev_mess.REP_STATUS);}/*===========================================================================* *				dev_up					     * *===========================================================================*/PUBLIC void dev_up(int maj){	/* A new device driver has been mapped in. This function	 * checks if any filesystems are mounted on it, and if so,	 * dev_open()s them so the filesystem can be reused.	 */	struct super_block *sb;	struct filp *fp;	int r;	/* Open a device once for every filp that's opened on it,	 * and once for every filesystem mounted from it.	 */	for(sb = super_block; sb < &super_block[NR_SUPERS]; sb++) {		int minor;		if(sb->s_dev == NO_DEV)			continue;		if(((sb->s_dev >> MAJOR) & BYTE) != maj)			continue;		minor = ((sb->s_dev >> MINOR) & BYTE);		printf("FS: remounting dev %d/%d\n", maj, minor);		if((r = dev_open(sb->s_dev, FS_PROC_NR,		   sb->s_rd_only ? R_BIT : (R_BIT|W_BIT))) != OK) {			printf("FS: mounted dev %d/%d re-open failed: %d.\n",				maj, minor, r);		}	}	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;				minor = ((in->i_zone[0] >> MINOR) & BYTE);		if((r = dev_open(in->i_dev, FS_PROC_NR,		   in->i_mode & (R_BIT|W_BIT))) != OK) {			printf("FS: file on dev %d/%d re-open failed: %d.\n",				maj, minor, r);		}	}	return;}

⌨️ 快捷键说明

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