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); }
/* * 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, ""); }
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); }