Example #1
0
/*
 * pti_done() releases the reference and checks to see if both sides have
 * been closed on a unix98 pty, allowing us to destroy the device and
 * release resources.
 *
 * We do not release resources on non-unix98 ptys.  Those are left
 * statically allocated.
 */
static void
pti_done(struct pt_ioctl *pti)
{
	lwkt_gettoken(&tty_token);
	if (--pti->pt_refs == 0) {
#ifdef UNIX98_PTYS
		cdev_t dev;
		int uminor_no;

		/*
		 * Only unix09 ptys are freed up
		 */
		if ((pti->pt_flags & PF_UNIX98) == 0) {
			lwkt_reltoken(&tty_token);
			return;
		}

		/*
		 * Interlock open attempts against termination by setting
		 * PF_TERMINATED.  This allows us to block while cleaning
		 * out the device infrastructure.
		 *
		 * Do not terminate the tty if it still has a session
		 * association (t_refs).
		 */
		if ((pti->pt_flags & (PF_SOPEN|PF_MOPEN)) == 0 &&
		    pti->pt_tty.t_refs == 0) {
			pti->pt_flags |= PF_TERMINATED;
			uminor_no = pti->pt_uminor;

			if ((dev = pti->devs) != NULL) {
				dev->si_drv1 = NULL;
				pti->devs = NULL;
				destroy_dev(dev);
			}
			if ((dev = pti->devc) != NULL) {
				dev->si_drv1 = NULL;
				pti->devc = NULL;
				destroy_dev(dev);
			}
			ttyunregister(&pti->pt_tty);
			devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(pty),
					       uminor_no);
			kfree(pti, M_PTY);
		}
#endif
	}
	lwkt_reltoken(&tty_token);
}
Example #2
0
static	int
vnclose(struct dev_close_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct vn_softc *vn;

	vn = dev->si_drv1;
	KKASSERT(vn != NULL);

	vn->sc_flags &= ~VNF_OPENED;

	/* The disk has been detached and can now be safely destroyed */
	if (vn->sc_flags & VNF_DESTROY) {
		KKASSERT(disk_getopencount(&vn->sc_disk) == 0);
		disk_destroy(&vn->sc_disk);
		devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(vn), dkunit(dev));
		SLIST_REMOVE(&vn_list, vn, vn_softc, sc_list);
		kfree(vn, M_VN);
	}
	return (0);
}
static int
snpclose(struct dev_close_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct snoop *snp;
	int ret;

	lwkt_gettoken(&tty_token);
	snp = dev->si_drv1;
	snp->snp_blen = 0;
	LIST_REMOVE(snp, snp_list);
	kfree(snp->snp_buf, M_SNP);
	snp->snp_flags &= ~SNOOP_OPEN;
	dev->si_drv1 = NULL;
	if (dev->si_uminor >= SNP_PREALLOCATED_UNITS) {
		devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(snp), dev->si_uminor);
		destroy_dev(dev);
	}
	ret = snp_detach(snp);
	lwkt_reltoken(&tty_token);
	return ret;
}
Example #4
0
void
uether_ifdetach(struct usb_ether *ue)
{
	struct ifnet *ifp;

	/* wait for any post attach or other command to complete */
	usb_proc_drain(&ue->ue_tq);

	/* read "ifnet" pointer after taskqueue drain */
	ifp = uether_getifp(ue);

	if (ifp != NULL) {

		/* we are not running any more */
		UE_LOCK(ue);
		ifp->if_flags &= ~IFF_RUNNING;
		UE_UNLOCK(ue);

		/* drain any callouts */
		usb_callout_drain(&ue->ue_watchdog);

		/* detach miibus */
		if (ue->ue_miibus != NULL) {
			device_delete_child(ue->ue_dev, ue->ue_miibus);
		}

		/* detach ethernet */
		ether_ifdetach(ifp);

		/* free sysctl */
		sysctl_ctx_free(&ue->ue_sysctl_ctx);

		/* free unit */
		devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(ue), ue->ue_unit);
	}

	/* free taskqueue, if any */
	usb_proc_free(&ue->ue_tq);
}
Example #5
0
static void
ue_attach_post_task(struct usb_proc_msg *_task)
{
	struct usb_ether_cfg_task *task =
	    (struct usb_ether_cfg_task *)_task;
	struct usb_ether *ue = task->ue;
	struct ifnet *ifp = uether_getifp(ue);
	int error;
	char num[14];			/* sufficient for 32 bits */

	/* first call driver's post attach routine */
	ue->ue_methods->ue_attach_post(ue);

	UE_UNLOCK(ue);

	KKASSERT(!lockowned(ue->ue_lock));
	ue->ue_unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(ue), 0);
	usb_callout_init_mtx(&ue->ue_watchdog, ue->ue_lock, 0);
	sysctl_ctx_init(&ue->ue_sysctl_ctx);

	KKASSERT(!lockowned(ue->ue_lock));
	error = 0;

	ifp->if_softc = ue;
	if_initname(ifp, "ue", ue->ue_unit);
	if (ue->ue_methods->ue_attach_post_sub != NULL) {
		error = ue->ue_methods->ue_attach_post_sub(ue);
		KKASSERT(!lockowned(ue->ue_lock));
	} else {
		ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
		if (ue->ue_methods->ue_ioctl != NULL)
			ifp->if_ioctl = ue->ue_methods->ue_ioctl;
		else
			ifp->if_ioctl = uether_ioctl;
		ifp->if_start = ue_start;
		ifp->if_init = ue_init;
		ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
		ifq_set_ready(&ifp->if_snd);

		if (ue->ue_methods->ue_mii_upd != NULL &&
		    ue->ue_methods->ue_mii_sts != NULL) {
			error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus, 
					      ue_ifmedia_upd, ue->ue_methods->ue_mii_sts);
		}
	}

	if (error) {
		device_printf(ue->ue_dev, "attaching PHYs failed\n");
		goto fail;
	}

	if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
	ether_ifattach(ifp, ue->ue_eaddr, NULL);
	/* Tell upper layer we support VLAN oversized frames. */
	if (ifp->if_capabilities & IFCAP_VLAN_MTU)
		ifp->if_hdrlen = sizeof(struct ether_vlan_header);

	ksnprintf(num, sizeof(num), "%u", ue->ue_unit);
	ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
	    &SYSCTL_NODE_CHILDREN(_net, ue),
	    OID_AUTO, num, CTLFLAG_RD, NULL, "");
	SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
	    SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO,
	    "%parent", CTLTYPE_STRING | CTLFLAG_RD, ue, 0,
	    ue_sysctl_parent, "A", "parent device");

	KKASSERT(!lockowned(ue->ue_lock));
	UE_LOCK(ue);
	return;

fail:
	devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(ue), ue->ue_unit);
	UE_LOCK(ue);
	return;
}