Example #1
0
/*ARGSUSED*/
void
usb_unregister_event_cbs(dev_info_t *dip, usb_event_t *usb_evdata)
{
	usba_evdata_t		*evdata;
	usba_device_t		*usba_device = usba_get_usba_device(dip);

	evdata = usba_get_evdata(dip);

	if (evdata->ev_rm_cb_id != NULL) {
		(void) ddi_remove_event_handler(evdata->ev_rm_cb_id);
		evdata->ev_rm_cb_id = NULL;
	}

	if (evdata->ev_ins_cb_id != NULL) {
		(void) ddi_remove_event_handler(evdata->ev_ins_cb_id);
		evdata->ev_ins_cb_id = NULL;
	}

	if (evdata->ev_suspend_cb_id != NULL) {
		(void) ddi_remove_event_handler(evdata->ev_suspend_cb_id);
		evdata->ev_suspend_cb_id = NULL;
	}

	if (evdata->ev_resume_cb_id != NULL) {
		(void) ddi_remove_event_handler(evdata->ev_resume_cb_id);
		evdata->ev_resume_cb_id = NULL;
	}

	mutex_enter(&usba_device->usb_mutex);
	usba_device->usb_client_flags[usba_get_ifno(dip)] &=
	    ~USBA_CLIENT_FLAG_EV_CBS;
	mutex_exit(&usba_device->usb_mutex);
}
Example #2
0
static void
av1394_remove_events(av1394_inst_t *avp)
{
	ddi_eventcookie_t	evc;

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_INSERT_EVENT,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_insert_cb);
	}

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_REMOVE_EVENT,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_remove_cb);
	}

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_BUS_RESET_EVENT,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_reset_cb);
	}
}
Example #3
0
static void
eib_rb_add_event_callbacks(eib_t *ss)
{
	ddi_eventcookie_t evc;

	if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_INFO_UPDATE,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(ss->ei_gw_info_cb);
		ss->ei_gw_info_cb = NULL;
	}

	if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_AVAILABLE,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
		ss->ei_gw_alive_cb = NULL;
	}

	if (ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_LOGIN_ACK,
	    &evc) == DDI_SUCCESS) {
		(void) ddi_remove_event_handler(ss->ei_login_ack_cb);
		ss->ei_login_ack_cb = NULL;
	}
}
Example #4
0
static int
av1394_add_events(av1394_inst_t *avp)
{
	ddi_eventcookie_t	br_evc, rem_evc, ins_evc;

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_BUS_RESET_EVENT,
	    &br_evc) != DDI_SUCCESS) {
		TNF_PROBE_0(av1394_add_events_error_bus_reset_cookie,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}
	if (ddi_add_event_handler(avp->av_dip, br_evc, av1394_bus_reset,
	    avp, &avp->av_reset_cb) != DDI_SUCCESS) {
		TNF_PROBE_0(av1394_add_events_error_bus_reset_event,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_REMOVE_EVENT,
	    &rem_evc) != DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_reset_cb);
		TNF_PROBE_0(av1394_add_events_error_remove_cookie,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}
	if (ddi_add_event_handler(avp->av_dip, rem_evc, av1394_disconnect,
	    avp, &avp->av_remove_cb) != DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_reset_cb);
		TNF_PROBE_0(av1394_add_events_error_remove_event,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}

	if (ddi_get_eventcookie(avp->av_dip, DDI_DEVI_INSERT_EVENT,
	    &ins_evc) != DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_remove_cb);
		(void) ddi_remove_event_handler(avp->av_reset_cb);
		TNF_PROBE_0(av1394_add_events_error_insert_cookie,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}
	if (ddi_add_event_handler(avp->av_dip, ins_evc, av1394_reconnect,
	    avp, &avp->av_insert_cb) != DDI_SUCCESS) {
		(void) ddi_remove_event_handler(avp->av_remove_cb);
		(void) ddi_remove_event_handler(avp->av_reset_cb);
		TNF_PROBE_0(av1394_add_events_error_insert_event,
		    AV1394_TNF_INST_ERROR, "");
		return (DDI_FAILURE);
	}

	return (DDI_SUCCESS);
}
Example #5
0
static int
eib_add_event_callbacks(eib_t *ss)
{
	int ret;
	ddi_eventcookie_t login_ack_evc;
	ddi_eventcookie_t gw_alive_evc;
	ddi_eventcookie_t gw_info_evc;

	/*
	 * Add callback for receiving vnic login acks from the gateway
	 */
	if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_LOGIN_ACK,
	    &login_ack_evc)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_get_eventcookie(LOGIN_ACK) failed, ret=%d", ret);
		return (EIB_E_FAILURE);
	}
	if ((ret = ddi_add_event_handler(ss->ei_dip, login_ack_evc,
	    eib_login_ack_cb, ss, &ss->ei_login_ack_cb)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_add_event_handler(LOGIN_ACK) failed, ret=%d", ret);
		return (EIB_E_FAILURE);
	}

	/*
	 * Add callback for receiving status on gateway transitioning from
	 * not-available to available
	 */
	if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_AVAILABLE,
	    &gw_alive_evc)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_get_eventcookie(GW_AVAILABLE) failed, ret=%d", ret);
		(void) ddi_remove_event_handler(ss->ei_login_ack_cb);
		return (EIB_E_FAILURE);
	}
	if ((ret = ddi_add_event_handler(ss->ei_dip, gw_alive_evc,
	    eib_gw_alive_cb, ss, &ss->ei_gw_alive_cb)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_add_event_handler(GW_AVAILABLE) failed, ret=%d", ret);
		(void) ddi_remove_event_handler(ss->ei_login_ack_cb);
		return (EIB_E_FAILURE);
	}

	/*
	 * Add callback for receiving gateway info update
	 */
	if ((ret = ddi_get_eventcookie(ss->ei_dip, EIB_NDI_EVENT_GW_INFO_UPDATE,
	    &gw_info_evc)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_get_eventcookie(GW_INFO_UPDATE) failed, ret=%d", ret);
		(void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
		(void) ddi_remove_event_handler(ss->ei_login_ack_cb);
		return (EIB_E_FAILURE);
	}
	if ((ret = ddi_add_event_handler(ss->ei_dip, gw_info_evc,
	    eib_gw_info_cb, ss, &ss->ei_gw_info_cb)) != DDI_SUCCESS) {
		EIB_DPRINTF_ERR(ss->ei_instance, "eib_add_event_callbacks: "
		    "ddi_add_event_handler(GW_INFO) failed, ret=%d", ret);
		(void) ddi_remove_event_handler(ss->ei_gw_alive_cb);
		(void) ddi_remove_event_handler(ss->ei_login_ack_cb);
		return (EIB_E_FAILURE);
	}

	return (EIB_E_SUCCESS);
}
Example #6
0
static int
gen_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
{
	struct dstate *dstatep;
	int instance;
	int i;
	int rv;
	int rm_power;
	int level_tmp;

#ifdef DEBUG
	int n_devs;
	int n_minorcomps;
	int isclone;
#endif

	switch (cmd) {
	case DDI_DETACH:
		GEN_DEBUG((CE_CONT, "%s%d: DDI_DETACH", ddi_node_name(devi),
		    ddi_get_instance(devi)));

		instance = ddi_get_instance(devi);
		dstatep = ddi_get_soft_state(dstates, instance);
		if (dstatep == NULL) {

			return (DDI_FAILURE);
}

#ifdef DEBUG
		n_devs = ddi_prop_get_int(DDI_DEV_T_ANY, devi, 0,
		    "ndevs", 1);

		isclone = ddi_prop_get_int(DDI_DEV_T_ANY, devi, 0,
		    "isclone", 0);

		n_minorcomps = ddi_prop_get_int(DDI_DEV_T_ANY, devi, 0,
		    "ncomps", 1);
#endif /* DEBUG */

		/*
		 * power off component 1.
		 */
		if (dstatep->flag & PM_SUPPORTED_FLAG) {
			GEN_DEBUG((CE_CONT,
			    "%s%d: DDI_DETACH: pm_lower_power comp 1 level %d",
			    ddi_node_name(devi), ddi_get_instance(devi),
			    MINPWR));
			if (pm_lower_power(dstatep->dip, 1, MINPWR)
			    != DDI_SUCCESS) {
				cmn_err(CE_WARN, "%s%d: DDI_DETACH:\n\t"
				    "pm_lower_power failed for comp 1 to"
				    " level %d\n", ddi_node_name(devi),
				    ddi_get_instance(devi), MINPWR);

				return (DDI_FAILURE);
			}

			/*
			 * check power level. Issue pm_power_has_changed
			 * if not at MINPWR.
			 */
			mutex_enter(&dstatep->lock);
			level_tmp = dstatep->level[1];
			dstatep->level[1] = MINPWR;
			if (dstatep->level[1] != MINPWR) {
				GEN_DEBUG((CE_NOTE, "%s%d: DDI_DETACH:"
				    " power off via pm_power_has_changed"
				    " instead", ddi_node_name(devi),
				    ddi_get_instance(devi)));
				if (pm_power_has_changed(dstatep->dip,
				    1, MINPWR) != DDI_SUCCESS) {
					GEN_DEBUG((CE_NOTE, "%s%d: DDI_DETACH:"
					    " pm_power_has_changed failed for"
					    " comp 1 to level %d",
					    ddi_node_name(devi),
					    ddi_get_instance(devi),
					    MINPWR));
					dstatep->level[1] = level_tmp;
					mutex_exit(&dstatep->lock);

					return (DDI_FAILURE);
				}
			}
			mutex_exit(&dstatep->lock);
		}

		/*
		 * If the LOWER_POWER_FLAG flag is not set,
		 * don't call pm_lowr_power() for comp 0.
		 * This should be used only for the XXXXX@XX,no_invol
		 * devices that export the
		 * no-involuntary-power-cycles property
		 */
		if (!(dstatep->flag & LOWER_POWER_FLAG) &&
		    dstatep->flag & PM_SUPPORTED_FLAG) {
			cmn_err(CE_NOTE, "%s%d: DDI_DETACH:\n\t"
			    " NOT CALLING PM_LOWER_POWER():"
			    " LOWER_POWER_FLAG NOT SET\n",
			    ddi_node_name(devi), ddi_get_instance(devi));
		} else if (dstatep->flag & PM_SUPPORTED_FLAG) {
			GEN_DEBUG((CE_CONT,
			    "%s%d: DDI_DETACH: pm_lower_power comp 0 level %d",
			    ddi_node_name(devi), ddi_get_instance(devi),
			    MINPWR));
			if (pm_lower_power(dstatep->dip, 0, MINPWR)
			    != DDI_SUCCESS) {
				cmn_err(CE_WARN, "%s%d: DDI_DETACH:\n\t"
				    "pm_lower_power failed for comp 0 to"
				    " level %d\n", ddi_node_name(devi),
				    ddi_get_instance(devi), MINPWR);

				return (DDI_FAILURE);
			}

			/*
			 * check power level. Issue pm_power_has_changed
			 * if not at MINPWR.
			 */
			mutex_enter(&dstatep->lock);
			level_tmp = dstatep->level[0];
			dstatep->level[0] = MINPWR;
			if (dstatep->level[0] != MINPWR) {
				GEN_DEBUG((CE_NOTE, "%s%d: DDI_DETACH:"
				    " power off via pm_power_has_changed"
				    " instead", ddi_node_name(devi),
				    ddi_get_instance(devi)));
				if (pm_power_has_changed(dstatep->dip,
				    0, MINPWR) != DDI_SUCCESS) {
					GEN_DEBUG((CE_NOTE, "%s%d: DDI_DETACH:"
					    " pm_power_has_changed failed for"
					    " comp 0 to level %d",
					    ddi_node_name(devi),
					    ddi_get_instance(devi),
					    MINPWR));
					dstatep->level[0] = level_tmp;
					mutex_exit(&dstatep->lock);

					return (DDI_FAILURE);
				}
			}
			mutex_exit(&dstatep->lock);
		}

		GEN_DEBUG((CE_CONT,
		    "%s%d detaching: n_devs=%d n_minorcomps=%d isclone=%d",
		    ddi_node_name(devi), ddi_get_instance(devi),
		    n_devs, n_minorcomps, isclone));

		for (i = 0; i < NUMEVENTS; i++) {
			if (dstatep->gen_cb_ids[i]) {
		(void) ddi_remove_event_handler(dstatep->gen_cb_ids[i]);
				dstatep->gen_cb_ids[i] = NULL;
			}
		}

		ddi_prop_remove_all(devi);
		ddi_remove_minor_node(devi, NULL);
		if (dstatep->node_type)
			kmem_free(dstatep->node_type,
			    strlen(dstatep->node_type) + 1);
		ddi_soft_state_free(dstates, instance);
		return (DDI_SUCCESS);

	case DDI_SUSPEND:
		GEN_DEBUG((CE_CONT, "%s%d: DDI_SUSPEND",
		    ddi_node_name(devi), ddi_get_instance(devi)));

		instance = ddi_get_instance(devi);
		dstatep = ddi_get_soft_state(dstates, instance);
		if (dstatep == NULL) {

			return (DDI_FAILURE);
		}

		/*
		 * fail the suspend if FAIL_SUSPEND_FLAG is set.
		 * clear the FAIL_SUSPEND_FLAG flag
		 */
		mutex_enter(&dstatep->lock);
		if (dstatep->flag & FAIL_SUSPEND_FLAG) {
			GEN_DEBUG((CE_CONT, "%s%d: DDI_SUSPEND:"
			    " FAIL_SUSPEND_FLAG is set,"
			    " fail suspend",
			    ddi_node_name(devi), ddi_get_instance(devi)));
			dstatep->flag &= ~FAIL_SUSPEND_FLAG;
			rv = DDI_FAILURE;
		} else {
			rv = DDI_SUCCESS;
		}
		mutex_exit(&dstatep->lock);

		/*
		 * Issue ddi_removing_power() to determine if the suspend
		 * was initiated by either CPR or DR. If CPR, the system
		 * will be powered OFF; if this driver has set the
		 * NO_INVOL_FLAG, then refuse to suspend. If DR, power
		 * will not be removed, thus allow the suspend.
		 */
		if (dstatep->flag & NO_INVOL_FLAG &&
		    dstatep->flag & PM_SUPPORTED_FLAG) {
			GEN_DEBUG((CE_CONT, "%s%d: DDI_SUSPEND:"
			    " check via ddi_removing_power()",
			    ddi_node_name(devi), ddi_get_instance(devi)));

			rm_power = ddi_removing_power(dstatep->dip);

			if (rm_power < 0) {
				cmn_err(CE_WARN, "%s%d: DDI_SUSPEND:"
				    " ddi_removing_power() failed\n",
				    ddi_node_name(devi),
				    ddi_get_instance(devi));
			} else if (rm_power == 1) {
				/*
				 * CPR: power will be removed
				 */
				GEN_DEBUG((CE_CONT, "%s%d: DDI_SUSPEND:\n\t"
				    " CPR: POWER WILL BE REMOVED, THEREFORE"
				    " REFUSE TO SUSPEND", ddi_node_name(devi),
				    ddi_get_instance(devi)));
				rv = DDI_FAILURE;
			} else if (rm_power == 0) {
				/*
				 * DR: power will not be removed
				 */
				GEN_DEBUG((CE_CONT, "%s%d: DDI_SUSPEND:\n\t"
				    " DR: POWER WILL NOT BE REMOVED, THEREFORE"
				    " ALLOW THE SUSPEND", ddi_node_name(devi),
				    ddi_get_instance(devi)));
				rv = DDI_SUCCESS;
			}
		}

		/*
		 * power OFF via pm_power_has_changed()
		 */
		mutex_enter(&dstatep->lock);
		if (dstatep->flag & PM_SUPPORTED_FLAG &&
		    !(dstatep->flag & NO_INVOL_FLAG)) {
			level_tmp = dstatep->level[0];
			dstatep->level[0] = MINPWR;
			GEN_DEBUG((CE_CONT,
			    "%s%d: DDI_SUSPEND: pm_power_has_changed comp 0"
			    " level %d", ddi_node_name(devi),
			    ddi_get_instance(devi), MINPWR));
			if (pm_power_has_changed(dstatep->dip, 0, MINPWR)
			    != DDI_SUCCESS) {
				cmn_err(CE_WARN, "%s%d: DDI_SUSPEND:\n\t"
				    "pm_power_has_changed failed for comp 0 to"
				    " level %d\n", ddi_node_name(devi),
				    ddi_get_instance(devi), MINPWR);
				dstatep->level[0] = level_tmp;
				mutex_exit(&dstatep->lock);

				return (DDI_FAILURE);
			}
		}
		mutex_exit(&dstatep->lock);

		return (rv);

	default:

		return (DDI_FAILURE);
	}
}