Beispiel #1
0
/*
 * Do local shutdown processing..
 * All our links and the name have already been removed.
 * If we are a persistant device, we might refuse to go away.
 * In the case of a persistant node we signal the framework that we
 * are still in business by clearing the NGF_INVALID bit. However
 * If we find the NGF_REALLY_DIE bit set, this means that
 * we REALLY need to die (e.g. hardware removed).
 * This would have been set using the NG_NODE_REALLY_DIE(node)
 * macro in some device dependent function (not shown here) before
 * calling ng_rmnode_self().
 */
static int
ng_xxx_shutdown(node_p node)
{
	const xxx_p privdata = NG_NODE_PRIVATE(node);

#ifndef PERSISTANT_NODE
	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(node);
	free(privdata, M_NETGRAPH);
#else
	if (node->nd_flags & NGF_REALLY_DIE) {
		/*
		 * WE came here because the widget card is being unloaded,
		 * so stop being persistant.
		 * Actually undo all the things we did on creation.
		 */
		NG_NODE_SET_PRIVATE(node, NULL);
		NG_NODE_UNREF(privdata->node);
		free(privdata, M_NETGRAPH);
		return (0);
	}
	NG_NODE_REVIVE(node);		/* tell ng_rmnode() we will persist */
#endif /* PERSISTANT_NODE */
	return (0);
}
static int
ng_btsocket_hci_raw_node_shutdown(node_p node)
{
	int	error = 0;

	NG_NODE_UNREF(node);

	error = ng_make_node_common(&typestruct, &ng_btsocket_hci_raw_node);
	if (error  != 0) {
		NG_BTSOCKET_HCI_RAW_ALERT(
"%s: Could not create Netgraph node, error=%d\n", __func__, error);

		ng_btsocket_hci_raw_node = NULL;

		return (ENOMEM);
        }

	error = ng_name_node(ng_btsocket_hci_raw_node,
				NG_BTSOCKET_HCI_RAW_NODE_TYPE);
	if (error != 0) {
		NG_BTSOCKET_HCI_RAW_ALERT(
"%s: Could not name Netgraph node, error=%d\n", __func__, error);

		NG_NODE_UNREF(ng_btsocket_hci_raw_node);
		ng_btsocket_hci_raw_node = NULL;

		return (EINVAL);
	}

	return (0);
} /* ng_btsocket_hci_raw_node_shutdown */
Beispiel #3
0
static int
ng_bt3c_shutdown(node_p node)
{
	bt3c_softc_p	sc = (bt3c_softc_p) NG_NODE_PRIVATE(node);

	/* Let old node go */
	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(node);

	/* Create new fresh one if we are not going down */
	if (sc == NULL)
		goto out;

	/* Create new Netgraph node */
	if (ng_make_node_common(&typestruct, &sc->node) != 0) {
		device_printf(sc->dev, "Could not create Netgraph node\n");
		sc->node = NULL;
		goto out;
	}

	/* Name new Netgraph node */
	if (ng_name_node(sc->node,  device_get_nameunit(sc->dev)) != 0) {
		device_printf(sc->dev, "Could not name Netgraph node\n");
		NG_NODE_UNREF(sc->node);
		sc->node = NULL;
		goto out;
	}

	NG_NODE_SET_PRIVATE(sc->node, sc);
out:
	return (0);
} /* ng_bt3c_shutdown */
Beispiel #4
0
/*
 * Destroy node
 */
static int
ng_ksocket_shutdown(node_p node)
{
	const priv_p priv = NG_NODE_PRIVATE(node);
	priv_p embryo;

	/* Close our socket (if any) */
	if (priv->so != NULL) {
		atomic_clear_int(&priv->so->so_rcv.ssb_flags, SSB_UPCALL);
		atomic_clear_int(&priv->so->so_snd.ssb_flags, SSB_UPCALL);
		priv->so->so_upcall = NULL;
		soclose(priv->so, FNONBLOCK);
		priv->so = NULL;
	}

	/* If we are an embryo, take ourselves out of the parent's list */
	if (priv->flags & KSF_EMBRYONIC) {
		LIST_REMOVE(priv, siblings);
		priv->flags &= ~KSF_EMBRYONIC;
	}

	/* Remove any embryonic children we have */
	while (!LIST_EMPTY(&priv->embryos)) {
		embryo = LIST_FIRST(&priv->embryos);
		ng_rmnode_self(embryo->node);
	}

	/* Take down netgraph node */
	bzero(priv, sizeof(*priv));
	kfree(priv, M_NETGRAPH);
	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(node);		/* let the node escape */
	return (0);
}
Beispiel #5
0
/*
 * Shutdown node
 */
static int
ngfrm_shutdown(node_p node)
{
	const sc_p sc = NG_NODE_PRIVATE(node);

	NG_NODE_SET_PRIVATE(node, NULL);
	FREE(sc, M_NETGRAPH);
	NG_NODE_UNREF(node);
	return (0);
}
Beispiel #6
0
/*
 * Do local shutdown processing..
 * Cut any remaining links and free our local resources.
 */
static int
nglmi_shutdown(node_p node)
{
	const sc_p sc = NG_NODE_PRIVATE(node);

	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(sc->node);
	free(sc, M_NETGRAPH);
	return (0);
}
static int ng_vboxnetflt_shutdown(node_p node)
{
    PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
    bool fActive;

    /* Prevent node shutdown if we're active */
    if (pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE)
        return (EBUSY);
    NG_NODE_UNREF(node);
    return (0);
}
static int
ng_split_shutdown(node_p node)
{
	const priv_p	priv = NG_NODE_PRIVATE(node);

	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(node);
	free(priv, M_NETGRAPH);

	return (0);
}
Beispiel #9
0
/*
 * Do local shutdown processing..
 * We are a persistant device, we refuse to go away, and
 * only remove our links and reset ourself.
 */
Static int
ng_udbp_rmnode(node_p node)
{
	const udbp_p sc = NG_NODE_PRIVATE(node);
	int err;

	if (sc->flags & DISCONNECTED) {
		/* 
		 * WE are really going away.. hardware must have gone.
		 * Assume that the hardware drive part will clear up the 
		 * sc, in fact it may already have done so..
		 * In which case we may have just segfaulted..XXX
		 */
		return (0);
	}

	/* stolen from attach routine */
	/* Drain the queues */
	IF_DRAIN(&sc->xmitq_hipri);
	IF_DRAIN(&sc->xmitq);

	sc->packets_in = 0;		/* reset stats */
	sc->packets_out = 0;
	NG_NODE_UNREF(node);			/* forget it ever existed */

	if ((err = ng_make_node_common(&ng_udbp_typestruct, &sc->node)) == 0) {
		char	nodename[128];
		sprintf(nodename, "%s", USBDEVNAME(sc->sc_dev));
		if ((err = ng_name_node(sc->node, nodename))) {
			NG_NODE_UNREF(sc->node); /* out damned spot! */
			sc->flags &= ~NETGRAPH_INITIALISED;
			sc->node = NULL;
		} else {
			NG_NODE_SET_PRIVATE(sc->node, sc);
		}
	}
	return (err);
}
Beispiel #10
0
static int
ng_sscop_shutdown(node_p node)
{
	struct priv *priv = NG_NODE_PRIVATE(node);

	sscop_destroy(priv->sscop);

	free(priv, M_NG_SSCOP);
	NG_NODE_SET_PRIVATE(node, NULL);

	NG_NODE_UNREF(node);

	return (0);
}
Beispiel #11
0
/*
 * Shutdown processing
 *
 * This is tricky. If we have both a left and right hook, then we
 * probably want to extricate ourselves and leave the two peers
 * still linked to each other. Otherwise we should just shut down as
 * a normal node would.
 *
 * To keep the scope of info correct the routine to "extract" a node
 * from two links is in ng_base.c.
 */
static int
ngt_shutdown(node_p node)
{
	const sc_p privdata = NG_NODE_PRIVATE(node);

#if 0 /* can never happen as cutlinks is already called */
	if (privdata->left.hook && privdata->right.hook)
		ng_bypass(privdata->left.hook, privdata->right.hook);
#endif
	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(privdata->node);
	FREE(privdata, M_NETGRAPH);
	return (0);
}
Beispiel #12
0
static int
ng_ubt_shutdown(node_p node)
{
	if (node->nd_flags & NGF_REALLY_DIE) {
		/*
                 * We came here because the USB device is being
		 * detached, so stop being persistent.
                 */
		NG_NODE_SET_PRIVATE(node, NULL);
		NG_NODE_UNREF(node);
	} else
		NG_NODE_REVIVE(node); /* tell ng_rmnode we are persisant */

	return (0);
} /* ng_ubt_shutdown */
Beispiel #13
0
/*
 * Do local shutdown processing.
 * In this case, that involves making sure the socket
 * knows we should be shutting down.
 */
static int
ngs_shutdown(node_p node)
{
	struct ngsock *const priv = NG_NODE_PRIVATE(node);
	struct ngpcb *const dpcbp = priv->datasock;
	struct ngpcb *const pcbp = priv->ctlsock;

	if (dpcbp != NULL)
		soisdisconnected(dpcbp->ng_socket);

	if (pcbp != NULL)
		soisdisconnected(pcbp->ng_socket);

	mtx_lock(&priv->mtx);
	priv->node = NULL;
	NG_NODE_SET_PRIVATE(node, NULL);
	ng_socket_free_priv(priv);

	NG_NODE_UNREF(node);
	return (0);
}
Beispiel #14
0
/*
 * Remove a reference from node private data.
 */
static void
ng_socket_free_priv(struct ngsock *priv)
{
	mtx_assert(&priv->mtx, MA_OWNED);

	priv->refs--;

	if (priv->refs == 0) {
		mtx_destroy(&priv->mtx);
		kfree(priv, M_NETGRAPH_SOCK);
		return;
	}

	if ((priv->refs == 1) && (priv->node != NULL)) {
		node_p node = priv->node;

		priv->node = NULL;
		mtx_unlock(&priv->mtx);
		NG_NODE_UNREF(node);
		ng_rmnode_self(node);
	} else
		mtx_unlock(&priv->mtx);
}
Beispiel #15
0
/*
 * Remove a reference from node private data.
 */
static void
ng_socket_free_priv(struct ngsock *priv)
{
	KKASSERT(mtx_owned(&priv->mtx));

	priv->refs--;

	if (priv->refs == 0) {
		mtx_uninit(&priv->mtx);
		kfree(priv, M_NETGRAPH_SOCK);
		return;
	}

	if ((priv->refs == 1) && (priv->node != NULL)) {
		node_p node = priv->node;

		priv->node = NULL;
		mtx_unlock(&priv->mtx);
		NG_NODE_UNREF(node);
		ng_rmnode_self(node);
	} else
		mtx_unlock(&priv->mtx);
}
Beispiel #16
0
/*
 * Destroy node
 */
static int
ng_ksocket_shutdown(node_p node)
{
	const priv_p priv = NG_NODE_PRIVATE(node);
	priv_p embryo;

	/* Close our socket (if any) */
	if (priv->so != NULL) {
		SOCKBUF_LOCK(&priv->so->so_rcv);
		soupcall_clear(priv->so, SO_RCV);
		SOCKBUF_UNLOCK(&priv->so->so_rcv);
		SOCKBUF_LOCK(&priv->so->so_snd);
		soupcall_clear(priv->so, SO_SND);
		SOCKBUF_UNLOCK(&priv->so->so_snd);
		soclose(priv->so);
		priv->so = NULL;
	}

	/* If we are an embryo, take ourselves out of the parent's list */
	if (priv->flags & KSF_EMBRYONIC) {
		LIST_REMOVE(priv, siblings);
		priv->flags &= ~KSF_EMBRYONIC;
	}

	/* Remove any embryonic children we have */
	while (!LIST_EMPTY(&priv->embryos)) {
		embryo = LIST_FIRST(&priv->embryos);
		ng_rmnode_self(embryo->node);
	}

	/* Take down netgraph node */
	bzero(priv, sizeof(*priv));
	free(priv, M_NETGRAPH_KSOCKET);
	NG_NODE_SET_PRIVATE(node, NULL);
	NG_NODE_UNREF(node);		/* let the node escape */
	return (0);
}
Beispiel #17
0
/*
 * Handle the first completed incoming connection, assumed to be already
 * on the socket's so_comp queue.
 */
static void
ng_ksocket_finish_accept(priv_p priv)
{
	struct socket *const head = priv->so;
	struct socket *so;
	struct sockaddr *sa = NULL;
	struct ng_mesg *resp;
	struct ng_ksocket_accept *resp_data;
	node_p node;
	priv_p priv2;
	int len;
	int error;

	ACCEPT_LOCK();
	so = TAILQ_FIRST(&head->so_comp);
	if (so == NULL) {	/* Should never happen */
		ACCEPT_UNLOCK();
		return;
	}
	TAILQ_REMOVE(&head->so_comp, so, so_list);
	head->so_qlen--;
	so->so_qstate &= ~SQ_COMP;
	so->so_head = NULL;
	SOCK_LOCK(so);
	soref(so);
	sosetstate(so, SS_NBIO);
	SOCK_UNLOCK(so);
	ACCEPT_UNLOCK();

	/* XXX KNOTE(&head->so_rcv.sb_sel.si_note, 0); */

	soaccept(so, &sa);

	len = OFFSETOF(struct ng_ksocket_accept, addr);
	if (sa != NULL)
		len += sa->sa_len;

	NG_MKMESSAGE(resp, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, len,
	    M_WAITOK | M_NULLOK);
	if (resp == NULL) {
		soclose(so);
		goto out;
	}
	resp->header.flags |= NGF_RESP;
	resp->header.token = priv->response_token;

	/* Clone a ksocket node to wrap the new socket */
        error = ng_make_node_common(&ng_ksocket_typestruct, &node);
        if (error) {
		kfree(resp, M_NETGRAPH);
		soclose(so);
		goto out;
	}

	if (ng_ksocket_constructor(node) != 0) {
		NG_NODE_UNREF(node);
		kfree(resp, M_NETGRAPH);
		soclose(so);
		goto out;
	}

	priv2 = NG_NODE_PRIVATE(node);
	priv2->so = so;
	priv2->flags |= KSF_CLONED | KSF_EMBRYONIC;

	/*
	 * Insert the cloned node into a list of embryonic children
	 * on the parent node.  When a hook is created on the cloned
	 * node it will be removed from this list.  When the parent
	 * is destroyed it will destroy any embryonic children it has.
	 */
	LIST_INSERT_HEAD(&priv->embryos, priv2, siblings);

	so->so_upcallarg = (caddr_t)node;
	so->so_upcall = ng_ksocket_incoming;
	SOCKBUF_LOCK(&so->so_rcv);
	so->so_rcv.sb_flags |= SB_UPCALL;
	SOCKBUF_UNLOCK(&so->so_rcv);
	SOCKBUF_LOCK(&so->so_snd);
	so->so_snd.sb_flags |= SB_UPCALL;
	SOCKBUF_UNLOCK(&so->so_snd);

	/* Fill in the response data and send it or return it to the caller */
	resp_data = (struct ng_ksocket_accept *)resp->data;
	resp_data->nodeid = NG_NODE_ID(node);
	if (sa != NULL)
		bcopy(sa, &resp_data->addr, sa->sa_len);
	NG_SEND_MSG_ID(error, node, resp, priv->response_addr, 0);

out:
	if (sa != NULL)
		kfree(sa, M_SONAME);
}
Beispiel #18
0
static int
bt3c_pccard_attach(device_t dev)
{
	bt3c_softc_p	sc = (bt3c_softc_p) device_get_softc(dev);

	/* Allocate I/O ports */
	sc->iobase_rid = 0;
	sc->iobase = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
			&sc->iobase_rid, 8, RF_ACTIVE);
	if (sc->iobase == NULL) {
		device_printf(dev, "Could not allocate I/O ports\n");
		goto bad;
	}
	sc->iot = rman_get_bustag(sc->iobase);
	sc->ioh = rman_get_bushandle(sc->iobase);

	/* Allocate IRQ */
	sc->irq_rid = 0;
	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
			RF_ACTIVE);
	if (sc->irq == NULL) {
		device_printf(dev, "Could not allocate IRQ\n");
		goto bad;
	}

	sc->irq_cookie = NULL;
	if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, NULL, bt3c_intr, sc,
			&sc->irq_cookie) != 0) {
		device_printf(dev, "Could not setup ISR\n");
		goto bad;
	}

	/* Attach handler to TTY SWI thread */
	sc->ith = NULL;
	if (swi_add(&tty_intr_event, device_get_nameunit(dev),
			bt3c_swi_intr, sc, SWI_TTY, 0, &sc->ith) < 0) {
		device_printf(dev, "Could not setup SWI ISR\n");
		goto bad;
	}

	/* Create Netgraph node */
	if (ng_make_node_common(&typestruct, &sc->node) != 0) {
		device_printf(dev, "Could not create Netgraph node\n");
		sc->node = NULL;
		goto bad;
	}

	/* Name Netgraph node */
	if (ng_name_node(sc->node, device_get_nameunit(dev)) != 0) {
		device_printf(dev, "Could not name Netgraph node\n");
		NG_NODE_UNREF(sc->node);
		sc->node = NULL;
		goto bad;
	}

	sc->dev = dev;
	sc->debug = NG_BT3C_WARN_LEVEL;

	sc->inq.ifq_maxlen = sc->outq.ifq_maxlen = BT3C_DEFAULTQLEN;
	mtx_init(&sc->inq.ifq_mtx, "BT3C inq", NULL, MTX_DEF);
	mtx_init(&sc->outq.ifq_mtx, "BT3C outq", NULL, MTX_DEF);

	sc->state = NG_BT3C_W4_PKT_IND;
	sc->want = 1;

	NG_NODE_SET_PRIVATE(sc->node, sc);

	return (0);
bad:
	if (sc->ith != NULL) {
		swi_remove(sc->ith);
		sc->ith = NULL;
	}

	if (sc->irq != NULL) {
		if (sc->irq_cookie != NULL)
			bus_teardown_intr(dev, sc->irq, sc->irq_cookie);

		bus_release_resource(dev, SYS_RES_IRQ,
			sc->irq_rid, sc->irq);

		sc->irq = NULL;
		sc->irq_rid = 0;
	}

	if (sc->iobase != NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT,
			sc->iobase_rid, sc->iobase);

		sc->iobase = NULL;
		sc->iobase_rid = 0;
	}

	return (ENXIO);
} /* bt3c_pccacd_attach */
Beispiel #19
0
static int
ubt_attach(device_t dev)
{
	struct usb_attach_arg		*uaa = device_get_ivars(dev);
	struct ubt_softc		*sc = device_get_softc(dev);
	struct usb_endpoint_descriptor	*ed;
	struct usb_interface_descriptor *id;
	struct usb_interface		*iface;
	uint16_t			wMaxPacketSize;
	uint8_t				alt_index, i, j;
	uint8_t				iface_index[2] = { 0, 1 };

	device_set_usb_desc(dev);

	sc->sc_dev = dev;
	sc->sc_debug = NG_UBT_WARN_LEVEL;

	/* 
	 * Create Netgraph node
	 */

	if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
		UBT_ALERT(sc, "could not create Netgraph node\n");
		return (ENXIO);
	}

	/* Name Netgraph node */
	if (ng_name_node(sc->sc_node, device_get_nameunit(dev)) != 0) {
		UBT_ALERT(sc, "could not name Netgraph node\n");
		NG_NODE_UNREF(sc->sc_node);
		return (ENXIO);
	}
	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
	NG_NODE_FORCE_WRITER(sc->sc_node);

	/*
	 * Initialize device softc structure
	 */

	/* initialize locks */
	mtx_init(&sc->sc_ng_mtx, "ubt ng", NULL, MTX_DEF);
	mtx_init(&sc->sc_if_mtx, "ubt if", NULL, MTX_DEF | MTX_RECURSE);

	/* initialize packet queues */
	NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN);
	NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN);
	NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN);

	/* initialize glue task */
	TASK_INIT(&sc->sc_task, 0, ubt_task, sc);

	/*
	 * Configure Bluetooth USB device. Discover all required USB
	 * interfaces and endpoints.
	 *
	 * USB device must present two interfaces:
	 * 1) Interface 0 that has 3 endpoints
	 *	1) Interrupt endpoint to receive HCI events
	 *	2) Bulk IN endpoint to receive ACL data
	 *	3) Bulk OUT endpoint to send ACL data
	 *
	 * 2) Interface 1 then has 2 endpoints
	 *	1) Isochronous IN endpoint to receive SCO data
 	 *	2) Isochronous OUT endpoint to send SCO data
	 *
	 * Interface 1 (with isochronous endpoints) has several alternate
	 * configurations with different packet size.
	 */

	/*
	 * For interface #1 search alternate settings, and find
	 * the descriptor with the largest wMaxPacketSize
	 */

	wMaxPacketSize = 0;
	alt_index = 0;
	i = 0;
	j = 0;
	ed = NULL;

	/* 
	 * Search through all the descriptors looking for the largest
	 * packet size:
	 */
	while ((ed = (struct usb_endpoint_descriptor *)usb_desc_foreach(
	    usbd_get_config_descriptor(uaa->device), 
	    (struct usb_descriptor *)ed))) {

		if ((ed->bDescriptorType == UDESC_INTERFACE) &&
		    (ed->bLength >= sizeof(*id))) {
			id = (struct usb_interface_descriptor *)ed;
			i = id->bInterfaceNumber;
			j = id->bAlternateSetting;
		}

		if ((ed->bDescriptorType == UDESC_ENDPOINT) &&
		    (ed->bLength >= sizeof(*ed)) &&
		    (i == 1)) {
			uint16_t temp;

			temp = UGETW(ed->wMaxPacketSize);
			if (temp > wMaxPacketSize) {
				wMaxPacketSize = temp;
				alt_index = j;
			}
		}
	}

	/* Set alt configuration on interface #1 only if we found it */
	if (wMaxPacketSize > 0 &&
	    usbd_set_alt_interface_index(uaa->device, 1, alt_index)) {
		UBT_ALERT(sc, "could not set alternate setting %d " \
			"for interface 1!\n", alt_index);
		goto detach;
	}

	/* Setup transfers for both interfaces */
	if (usbd_transfer_setup(uaa->device, iface_index, sc->sc_xfer,
			ubt_config, UBT_N_TRANSFER, sc, &sc->sc_if_mtx)) {
		UBT_ALERT(sc, "could not allocate transfers\n");
		goto detach;
	}

	/* Claim all interfaces belonging to the Bluetooth part */
	for (i = 1;; i++) {
		iface = usbd_get_iface(uaa->device, i);
		if (iface == NULL)
			break;
		id = usbd_get_interface_descriptor(iface);

		if ((id != NULL) &&
		    (id->bInterfaceClass == UICLASS_WIRELESS) &&
		    (id->bInterfaceSubClass == UISUBCLASS_RF) &&
		    (id->bInterfaceProtocol == UIPROTO_BLUETOOTH)) {
			usbd_set_parent_iface(uaa->device, i,
			    uaa->info.bIfaceIndex);
		}
	}
	return (0); /* success */

detach:
	ubt_detach(dev);

	return (ENXIO);
} /* ubt_attach */