Esempio n. 1
0
static int
eibnx_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
	eibnx_t *ss = enx_global_ss;

	if (cmd == DDI_SUSPEND)
		return (DDI_SUCCESS);
	else if (cmd != DDI_DETACH)
		return (DDI_FAILURE);

	/*
	 * If there's no instance of eibnx attached, fail
	 */
	if (ss == NULL)
		return (DDI_FAILURE);

	/*
	 * Before we do anything, we need to stop the port monitors
	 * we may have started earlier.
	 */
	eibnx_terminate_monitors();

	/*
	 * If eibnx_ibt_fini() fails, it could be because one of the
	 * HCA's pd could not be freed, the hca could not be closed
	 * or the IBTF detach wasn't successful.  If this is the case,
	 * we have to return failure, but cannot do much about the
	 * port monitors we've already terminated.
	 */
	if (eibnx_ibt_fini(ss) == ENX_E_FAILURE)
		return (DDI_FAILURE);

	/*
	 * Cleanup any devctl minor node we may have created, unbind and
	 * free ndi event handle and free the instance softstate.
	 */
	(void) ddi_remove_minor_node(dip, NULL);
	(void) ndi_event_unbind_set(enx_ndi_event_hdl,
	    &enx_ndi_events, NDI_SLEEP);
	(void) ndi_event_free_hdl(enx_ndi_event_hdl);
	enx_ndi_event_hdl = NULL;
	kmem_free(enx_global_ss, sizeof (eibnx_t));
	enx_global_ss = NULL;

	return (DDI_SUCCESS);
}
Esempio n. 2
0
/*
 * nx1394_undefine_events()
 *    Unbinds event set bound to the hal and frees the event handle.
 */
void
nx1394_undefine_events(s1394_hal_t *hal)
{
	int ret;

	TNF_PROBE_0_DEBUG(nx1394_undefine_events_enter,
	    S1394_TNF_SL_NEXUS_STACK, "");

	ret = ndi_event_unbind_set(hal->hal_ndi_event_hdl, &nx1394_events,
	    NDI_SLEEP);
	if (ret != NDI_SUCCESS) {
		TNF_PROBE_1(nx1394_undefine_events_unbind_fail,
		    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
	} else {
		ret = ndi_event_free_hdl(hal->hal_ndi_event_hdl);
		if (ret != NDI_SUCCESS) {
			TNF_PROBE_1(nx1394_undefine_events_free_hdl_fail,
			    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
		}
	}

	TNF_PROBE_0_DEBUG(nx1394_undefine_events_exit,
	    S1394_TNF_SL_NEXUS_STACK, "");
}
Esempio n. 3
0
static int
eibnx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	eibnx_t *ss;
	int instance;

	if (cmd == DDI_RESUME)
		return (DDI_SUCCESS);
	else if (cmd != DDI_ATTACH)
		return (DDI_FAILURE);

	/*
	 * Don't allow more than one instance to attach
	 */
	if (enx_global_ss)
		return (DDI_FAILURE);

	/*
	 * Alloc this instance's softstate
	 */
	ss = kmem_zalloc(sizeof (eibnx_t), KM_SLEEP);
	ss->nx_dip = dip;

	enx_global_ss = ss;

	/*
	 * Allocate our NDI event handle and bind our event set
	 */
	if (ndi_event_alloc_hdl(dip, 0, &enx_ndi_event_hdl,
	    NDI_SLEEP) != NDI_SUCCESS) {
		ENX_DPRINTF_ERR("ndi_event_alloc_hdl(dip=0x%llx) "
		    "failed", dip);

		kmem_free(enx_global_ss, sizeof (eibnx_t));
		enx_global_ss = NULL;
		return (DDI_FAILURE);
	}
	if (ndi_event_bind_set(enx_ndi_event_hdl, &enx_ndi_events,
	    NDI_SLEEP) != NDI_SUCCESS) {
		ENX_DPRINTF_ERR("ndi_event_bind_set(ndi_event_hdl=0x%llx) "
		    "failed", enx_ndi_event_hdl);

		(void) ndi_event_free_hdl(enx_ndi_event_hdl);
		enx_ndi_event_hdl = NULL;
		kmem_free(enx_global_ss, sizeof (eibnx_t));
		enx_global_ss = NULL;
		return (DDI_FAILURE);
	}

	/*
	 * Create "devctl" minor node for general ioctl interface to the
	 * eoib nexus. If we cannot, it isn't fatal - we'll operate without
	 * the support for devctl (but issue a warning).
	 */
	instance = ddi_get_instance(dip);
	if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
	    DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
		ENX_DPRINTF_WARN("could not create devctl minor node "
		    "for instance %d", instance);
	}

	/*
	 * Do IBTF related initializations. If we fail, we cannot operate,
	 * so fail the attach.
	 */
	if (eibnx_ibt_init(ss) != ENX_E_SUCCESS) {
		(void) ddi_remove_minor_node(dip, NULL);
		(void) ndi_event_unbind_set(enx_ndi_event_hdl,
		    &enx_ndi_events, NDI_SLEEP);
		(void) ndi_event_free_hdl(enx_ndi_event_hdl);
		enx_ndi_event_hdl = NULL;
		kmem_free(enx_global_ss, sizeof (eibnx_t));
		enx_global_ss = NULL;
		return (DDI_FAILURE);
	}

	return (DDI_SUCCESS);
}