/*ARGSUSED*/ static int logclose(struct dev_close_args *ap) { log_open = 0; callout_stop(&logsoftc.sc_callout); logsoftc.sc_state = 0; funsetown(&logsoftc.sc_sigio); return (0); }
/*ARGSUSED*/ static int logclose(struct cdev *dev, int flag, int mode, struct thread *td) { funsetown(&logsoftc.sc_sigio); mtx_lock(&msgbuf_lock); callout_stop(&logsoftc.sc_callout); logsoftc.sc_state = 0; log_open = 0; mtx_unlock(&msgbuf_lock); return (0); }
/* * tunclose - close the device - mark i/f down & delete * routing info */ static int tunclose(struct cdev *dev, int foo, int bar, struct thread *td) { struct tun_softc *tp; struct ifnet *ifp; int s; tp = dev->si_drv1; ifp = &tp->tun_if; mtx_lock(&tp->tun_mtx); tp->tun_flags &= ~TUN_OPEN; tp->tun_pid = 0; /* * junk all pending output */ s = splimp(); IFQ_PURGE(&ifp->if_snd); splx(s); mtx_unlock(&tp->tun_mtx); if (ifp->if_flags & IFF_UP) { s = splimp(); if_down(ifp); splx(s); } if (ifp->if_flags & IFF_RUNNING) { struct ifaddr *ifa; s = splimp(); /* find internet addresses and delete routes */ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if (ifa->ifa_addr->sa_family == AF_INET) /* Unlocked read. */ rtinit(ifa, (int)RTM_DELETE, tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); ifp->if_flags &= ~IFF_RUNNING; splx(s); } funsetown(&tp->tun_sigio); selwakeuppri(&tp->tun_rsel, PZERO + 1); TUNDEBUG (ifp, "closed\n"); return (0); }
/* * Close a socket on last file table reference removal. * Initiate disconnect if connected. * Free socket when disconnect complete. */ int soclose(struct socket *so, int fflag) { int error = 0; funsetown(&so->so_sigio); if (so->so_pcb == NULL) goto discard; if (so->so_state & SS_ISCONNECTED) { if ((so->so_state & SS_ISDISCONNECTING) == 0) { error = sodisconnect(so); if (error) goto drop; } if (so->so_options & SO_LINGER) { if ((so->so_state & SS_ISDISCONNECTING) && (fflag & FNONBLOCK)) goto drop; while (so->so_state & SS_ISCONNECTED) { error = tsleep(&so->so_timeo, PCATCH, "soclos", so->so_linger * hz); if (error) break; } } } drop: if (so->so_pcb) { int error2; error2 = so_pru_detach(so); if (error == 0) error = error2; } discard: lwkt_getpooltoken(so); if (so->so_options & SO_ACCEPTCONN) { struct socket *sp; while ((sp = TAILQ_FIRST(&so->so_incomp)) != NULL) { TAILQ_REMOVE(&so->so_incomp, sp, so_list); soclrstate(sp, SS_INCOMP); sp->so_head = NULL; so->so_incqlen--; soaborta(sp); } while ((sp = TAILQ_FIRST(&so->so_comp)) != NULL) { TAILQ_REMOVE(&so->so_comp, sp, so_list); soclrstate(sp, SS_COMP); sp->so_head = NULL; so->so_qlen--; soaborta(sp); } } lwkt_relpooltoken(so); if (so->so_state & SS_NOFDREF) panic("soclose: NOFDREF"); sosetstate(so, SS_NOFDREF); /* take ref */ sofree(so); /* dispose of ref */ return (error); }
/** * Release file. * * \param inode device inode * \param file_priv DRM file private. * \return zero on success or a negative number on failure. * * If the hardware lock is held then free it, and take it again for the kernel * context since it's necessary to reclaim buffers. Unlink the file private * data from its list and free it. Decreases the open count and if it reaches * zero calls drm_lastclose(). */ #if 0 /* old drm_release equivalent from DragonFly */ void drm_cdevpriv_dtor(void *cd) { struct drm_file *file_priv = cd; struct drm_device *dev = file_priv->dev; int retcode = 0; DRM_DEBUG("open_count = %d\n", dev->open_count); DRM_LOCK(dev); if (dev->driver->preclose != NULL) dev->driver->preclose(dev, file_priv); /* ======================================================== * Begin inline drm_release */ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", DRM_CURRENTPID, (long)dev->dev, dev->open_count); if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); if (dev->primary->master->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->primary->master->lock.hw_lock->lock) && dev->primary->master->lock.file_priv == file_priv) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->primary->master->lock.hw_lock->lock)); if (dev->driver->reclaim_buffers_locked != NULL) dev->driver->reclaim_buffers_locked(dev, file_priv); drm_lock_free(&dev->primary->master->lock, _DRM_LOCKING_CONTEXT(dev->primary->master->lock.hw_lock->lock)); /* FIXME: may require heavy-handed reset of hardware at this point, possibly processed via a callback to the X server. */ } else if (dev->driver->reclaim_buffers_locked != NULL && dev->primary->master->lock.hw_lock != NULL) { /* The lock is required to reclaim buffers */ for (;;) { if (!dev->primary->master->lock.hw_lock) { /* Device has been unregistered */ retcode = EINTR; break; } if (drm_lock_take(&dev->primary->master->lock, DRM_KERNEL_CONTEXT)) { dev->primary->master->lock.file_priv = file_priv; dev->primary->master->lock.lock_time = jiffies; atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); break; /* Got lock */ } /* Contention */ retcode = DRM_LOCK_SLEEP(dev, &dev->primary->master->lock.lock_queue, PCATCH, "drmlk2", 0); if (retcode) break; } if (retcode == 0) { dev->driver->reclaim_buffers_locked(dev, file_priv); drm_lock_free(&dev->primary->master->lock, DRM_KERNEL_CONTEXT); } } if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->reclaim_buffers_locked) drm_reclaim_buffers(dev, file_priv); funsetown(&dev->buf_sigio); if (dev->driver->postclose != NULL) dev->driver->postclose(dev, file_priv); list_del(&file_priv->lhead); /* ======================================================== * End inline drm_release */ atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); device_unbusy(dev->dev); if (--dev->open_count == 0) { retcode = drm_lastclose(dev); } DRM_UNLOCK(dev); }