- if(fp == NULL)
- return;
- if (fp->f_count > 1) {
- fp->f_count--;
- return;
- }
- flag = fp->f_flag;
-#ifdef BBNNET
- if (flag&FNET) {
- netclose(fp);
- return;
- }
-#endif
- if (flag & FPORT) {
- ptclose(fp);
- fp->f_count = 0;
- return;
- }
- ip = fp->f_inode;
- dev = (dev_t)ip->i_un.i_rdev;
- mode = ip->i_mode & IFMT;
- plock(ip);
- iput(ip);
- fp->f_count = 0;
-
- switch (mode) {
-
- case IFCHR:
- cfunc = cdevsw[major(dev)].d_close;
- break;
-
- case IFBLK:
- /*
- * We don't want to really close the device if it is mounted
- */
- for (mp = mount; mp < &mount[NMOUNT]; mp++)
- if (mp->m_bufp != NULL && mp->m_dev == dev)
- return;
- cfunc = bdevsw[major(dev)].d_close;
- break;
- default:
- return;
- }
-
- for(fp=file; fp < fileNFILE; fp++) {
-#ifdef BBNNET
- if (fp->f_flag & FNET)
- continue;
-#endif
- if (fp->f_count && (ip = fp->f_inode) &&
- ip->i_un.i_rdev == dev &&
- (ip->i_mode&IFMT) == mode)
- return;
- }
- if (mode == IFBLK) {
- /*
- * on last close of a block device (that isn't mounted)
- * we must invalidate any in core blocks
- */
- bflush(dev);
- binval(dev);
- }
- (*cfunc)(dev, flag, fp);
-}
-
-/*
- * openi called to allow handler
- * of special files to initialize and
- * validate before actual IO.
- */
-openi(ip, rw)
-register struct inode *ip;
-{
- dev_t dev;
- register unsigned int maj;
-
- dev = (dev_t)ip->i_un.i_rdev;
- maj = major(dev);
- switch(ip->i_mode&IFMT) {
-
- case IFCHR:
- if(maj >= nchrdev)
- goto bad;
- (*cdevsw[maj].d_open)(dev, rw);
- break;
-
- case IFBLK:
- if(maj >= nblkdev)
- goto bad;
- (*bdevsw[maj].d_open)(dev, rw);
- }
- return;
-
-bad:
- u.u_error = ENXIO;
-}