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); }
/*ARGSUSED*/ int usb_register_event_cbs(dev_info_t *dip, usb_event_t *usb_evdata, usb_flags_t flags) { usba_device_t *usba_device; usba_evdata_t *evdata; if ((dip == NULL) || (usb_evdata == NULL)) { return (USB_FAILURE); } /* * The event list searches by ddi_get_eventcookie calls below, go * through hubd and so do not apply to host controllers. */ ASSERT(!usba_is_root_hub(dip)); usba_device = usba_get_usba_device(dip); evdata = usba_get_evdata(dip); if (usb_evdata->disconnect_event_handler != NULL) { if (usba_device->rm_cookie == NULL) { if (ddi_get_eventcookie(dip, DDI_DEVI_REMOVE_EVENT, &usba_device->rm_cookie) != DDI_SUCCESS) { goto fail; } } if (ddi_add_event_handler(dip, usba_device->rm_cookie, (peh_t)usb_evdata->disconnect_event_handler, NULL, &evdata->ev_rm_cb_id) != DDI_SUCCESS) { goto fail; } } if (usb_evdata->reconnect_event_handler != NULL) { if (usba_device->ins_cookie == NULL) { if (ddi_get_eventcookie(dip, DDI_DEVI_INSERT_EVENT, &usba_device->ins_cookie) != DDI_SUCCESS) { goto fail; } } if (ddi_add_event_handler(dip, usba_device->ins_cookie, (peh_t)usb_evdata->reconnect_event_handler, NULL, &evdata->ev_ins_cb_id) != DDI_SUCCESS) { goto fail; } } if (usb_evdata->post_resume_event_handler != NULL) { if (usba_device->resume_cookie == NULL) { if (ddi_get_eventcookie(dip, USBA_POST_RESUME_EVENT, &usba_device->resume_cookie) != DDI_SUCCESS) { goto fail; } } if (ddi_add_event_handler(dip, usba_device->resume_cookie, (peh_t)usb_evdata->post_resume_event_handler, NULL, &evdata->ev_resume_cb_id) != DDI_SUCCESS) { goto fail; } } if (usb_evdata->pre_suspend_event_handler != NULL) { if (usba_device->suspend_cookie == NULL) { if (ddi_get_eventcookie(dip, USBA_PRE_SUSPEND_EVENT, &usba_device->suspend_cookie) != DDI_SUCCESS) { goto fail; } } if (ddi_add_event_handler(dip, usba_device->suspend_cookie, (peh_t)usb_evdata->pre_suspend_event_handler, NULL, &evdata->ev_suspend_cb_id) != DDI_SUCCESS) { goto fail; } } mutex_enter(&usba_device->usb_mutex); usba_device->usb_client_flags[usba_get_ifno(dip)] |= USBA_CLIENT_FLAG_EV_CBS; usba_device->usb_client_ev_cb_list->dip = dip; usba_device->usb_client_ev_cb_list->ev_data = usb_evdata; mutex_exit(&usba_device->usb_mutex); return (USB_SUCCESS); fail: usb_unregister_event_cbs(dip, usb_evdata); return (USB_FAILURE); }
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); }
/*ARGSUSED*/ int usb_register_hotplug_cbs(dev_info_t *dip, int (*disconnect_event_handler)(dev_info_t *), int (*reconnect_event_handler)(dev_info_t *)) { usba_device_t *usba_device; usba_evdata_t *evdata; if ((dip == NULL) || (disconnect_event_handler == NULL) || (reconnect_event_handler == NULL)) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: Bad argument(s)"); return (USB_FAILURE); } USB_DPRINTF_L4(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: entry"); /* * The event list searches by ddi_get_eventcookie calls below, go * through hubd and so do not apply to host controllers. */ ASSERT(!usba_is_root_hub(dip)); usba_device = usba_get_usba_device(dip); evdata = usba_get_evdata(dip); if (usba_device->rm_cookie == NULL) { if (ddi_get_eventcookie(dip, DDI_DEVI_REMOVE_EVENT, &usba_device->rm_cookie) != DDI_SUCCESS) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: get rm cookie failed"); goto fail; } } if (ddi_add_event_handler(dip, usba_device->rm_cookie, (peh_t)disconnect_event_handler, NULL, &evdata->ev_rm_cb_id) != DDI_SUCCESS) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: add disconnect handler failed"); goto fail; } if (usba_device->ins_cookie == NULL) { if (ddi_get_eventcookie(dip, DDI_DEVI_INSERT_EVENT, &usba_device->ins_cookie) != DDI_SUCCESS) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: get ins cookie failed"); goto fail; } } if (ddi_add_event_handler(dip, usba_device->ins_cookie, (peh_t)reconnect_event_handler, NULL, &evdata->ev_ins_cb_id) != DDI_SUCCESS) { USB_DPRINTF_L2(DPRINT_MASK_USBAI, usbai_log_handle, "usb_register_hotplug_cbs: add reconnect handler failed"); goto fail; } mutex_enter(&usba_device->usb_mutex); usba_device->usb_client_flags[usba_get_ifno(dip)] |= USBA_CLIENT_FLAG_EV_CBS; usba_device->usb_client_ev_cb_list->dip = dip; mutex_exit(&usba_device->usb_mutex); return (USB_SUCCESS); fail: usb_unregister_hotplug_cbs(dip); return (USB_FAILURE); }
static int gen_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { int instance = ddi_get_instance(devi); struct dstate *dstatep; int rval; int n_devs; int n_minorcomps; int isclone; ddi_eventcookie_t dev_offline_cookie, dev_reset_cookie; ddi_eventcookie_t bus_reset_cookie, bus_quiesce_cookie; ddi_eventcookie_t bus_unquiesce_cookie, bus_test_post_cookie; int i_init = 0; int level_tmp; int i; char *pm_comp[] = { "NAME=leaf0", "0=D0", "1=D1", "2=D2", "3=D3", "NAME=leaf1", "0=off", "1=blank", "2=on"}; char *pm_hw_state = {"needs-suspend-resume"}; switch (cmd) { case DDI_ATTACH: if (ddi_soft_state_zalloc(dstates, instance) != DDI_SUCCESS) { cmn_err(CE_CONT, "%s%d: can't allocate state\n", ddi_get_name(devi), instance); return (DDI_FAILURE); } dstatep = ddi_get_soft_state(dstates, instance); dstatep->dip = devi; mutex_init(&dstatep->lock, NULL, MUTEX_DRIVER, NULL); 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); GEN_DEBUG((CE_CONT, "%s%d attaching: n_devs=%d n_minorcomps=%d isclone=%d", ddi_get_name(devi), ddi_get_instance(devi), n_devs, n_minorcomps, isclone)); if (isclone) { if (ddi_create_minor_node(devi, "gen", S_IFCHR, INST_TO_MINOR(instance), mnodetypes[0], isclone) != DDI_SUCCESS) { ddi_remove_minor_node(devi, NULL); ddi_soft_state_free(dstates, instance); cmn_err(CE_WARN, "%s%d: can't create minor " "node", ddi_get_name(devi), instance); return (DDI_FAILURE); } rval = DDI_SUCCESS; } else { rval = gen_create_minor_nodes(devi, dstatep); if (rval != DDI_SUCCESS) { ddi_prop_remove_all(devi); ddi_remove_minor_node(devi, NULL); ddi_soft_state_free(dstates, instance); cmn_err(CE_WARN, "%s%d: can't create minor " "nodes", ddi_get_name(devi), instance); return (DDI_FAILURE); } } if (ddi_get_eventcookie(devi, "pshot_dev_offline", &dev_offline_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, dev_offline_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[0])); } if (ddi_get_eventcookie(devi, "pshot_dev_reset", &dev_reset_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, dev_reset_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[1])); } if (ddi_get_eventcookie(devi, "pshot_bus_reset", &bus_reset_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, bus_reset_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[2])); } if (ddi_get_eventcookie(devi, "pshot_bus_quiesce", &bus_quiesce_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, bus_quiesce_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[3])); } if (ddi_get_eventcookie(devi, "pshot_bus_unquiesce", &bus_unquiesce_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, bus_unquiesce_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[4])); } if (ddi_get_eventcookie(devi, "pshot_bus_test_post", &bus_test_post_cookie) == DDI_SUCCESS) { (void) ddi_add_event_handler(devi, bus_test_post_cookie, gen_event_cb, NULL, &(dstatep->gen_cb_ids[5])); } /* * initialize the devices' pm state */ mutex_enter(&dstatep->lock); dstatep->flag &= ~OPEN_FLAG; dstatep->flag &= ~PWR_HAS_CHANGED_ON_RESUME_FLAG; dstatep->flag &= ~FAIL_SUSPEND_FLAG; dstatep->flag &= ~PUP_WITH_PWR_HAS_CHANGED_FLAG; dstatep->flag |= LOWER_POWER_FLAG; dstatep->flag &= ~NO_INVOL_FLAG; dstatep->flag |= PM_SUPPORTED_FLAG; dstatep->busy[0] = 0; dstatep->busy[1] = 0; dstatep->level[0] = -1; dstatep->level[1] = -1; mutex_exit(&dstatep->lock); /* * stash the nodename */ dstatep->nodename = ddi_node_name(devi); /* * Check if the no-involuntary-power-cycles property * was created. Set NO_INVOL_FLAG if so. */ if (ddi_prop_exists(DDI_DEV_T_ANY, dstatep->dip, (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), "no-involuntary-power-cycles") == 1) { GEN_DEBUG((CE_CONT, "%s%d: DDI_ATTACH:\n\tno-involuntary-power-cycles" " property was created", ddi_node_name(devi), ddi_get_instance(devi))); mutex_enter(&dstatep->lock); dstatep->flag |= NO_INVOL_FLAG; mutex_exit(&dstatep->lock); } /* * Check if the dependency-property property * was created. */ if (ddi_prop_exists(DDI_DEV_T_ANY, dstatep->dip, (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), "dependency-property") == 1) { GEN_DEBUG((CE_CONT, "%s%d: DDI_ATTACH:\n\tdependency-property" " property was created", ddi_node_name(devi), ddi_get_instance(devi))); } /* * create the pm-components property. two comps: * 4 levels on comp0, 3 on comp 1. * - skip for a "tape" device, clear PM_SUPPORTED_FLAG */ if (strcmp(ddi_node_name(devi), "tape") != 0) { if (ddi_prop_update_string_array(DDI_DEV_T_NONE, devi, "pm-components", pm_comp, 9) != DDI_PROP_SUCCESS) { cmn_err(CE_WARN, "%s%d: %s\n", ddi_node_name(devi), ddi_get_instance(devi), "unable to create \"pm-components\" " " property."); return (DDI_FAILURE); } } else { mutex_enter(&dstatep->lock); dstatep->flag &= ~PM_SUPPORTED_FLAG; mutex_exit(&dstatep->lock); } /* * Check if the pm-components property was created */ if (dstatep->flag & PM_SUPPORTED_FLAG) { if (ddi_prop_exists(DDI_DEV_T_ANY, dstatep->dip, (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), "pm-components") != 1) { cmn_err(CE_WARN, "%s%d: DDI_ATTACH:\n\t%s", ddi_node_name(devi), ddi_get_instance(devi), "\"pm-components\" property does" " not exist"); return (DDI_FAILURE); } else { GEN_DEBUG((CE_CONT, "%s%d: DDI_ATTACH:" " created pm-components property", ddi_node_name(devi), ddi_get_instance(devi))); } } /* * create the pm-hardware-state property. * needed to get DDI_SUSPEND and DDI_RESUME calls */ if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "pm-hardware-state", pm_hw_state) != DDI_PROP_SUCCESS) { cmn_err(CE_WARN, "%s%d: DDI_ATTACH:\n\t%s\n", ddi_node_name(devi), ddi_get_instance(devi), "unable to create \"pm-hardware-state\" " " property."); return (DDI_FAILURE); } /* * set power levels to max via pm_raise_power(), */ mutex_enter(&dstatep->lock); i_init = (dstatep->flag & PM_SUPPORTED_FLAG) ? 0 : COMPONENTS; mutex_exit(&dstatep->lock); for (i = i_init; i < COMPONENTS; i++) { GEN_DEBUG((CE_CONT, "%s%d: DDI_ATTACH: pm_raise_power comp %d " "to level %d", ddi_node_name(devi), ddi_get_instance(devi), i, maxpwr[i])); if (pm_raise_power(dstatep->dip, i, maxpwr[i]) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: DDI_ATTACH: pm_raise_power failed\n", ddi_node_name(devi), ddi_get_instance(devi)); dstatep->level[i] = -1; return (DDI_FAILURE); } } if (rval == DDI_SUCCESS) { ddi_report_dev(devi); } return (rval); case DDI_RESUME: GEN_DEBUG((CE_CONT, "%s%d: DDI_RESUME", ddi_node_name(devi), ddi_get_instance(devi))); dstatep = ddi_get_soft_state(dstates, ddi_get_instance(devi)); if (dstatep == NULL) { return (DDI_FAILURE); } /* * Call pm_power_has_changed() if flag * PWR_HAS_CHANGED_ON_RESUME_FLAG is set, * then clear the flag */ mutex_enter(&dstatep->lock); i_init = (dstatep->flag & PM_SUPPORTED_FLAG) ? 0 : COMPONENTS; mutex_exit(&dstatep->lock); if (dstatep->flag & PWR_HAS_CHANGED_ON_RESUME_FLAG) { for (i = i_init; i < COMPONENTS; i++) { GEN_DEBUG((CE_CONT, "%s%d: DDI_RESUME: pm_power_has_changed " "comp %d to level %d", ddi_node_name(devi), ddi_get_instance(devi), i, maxpwr[i])); mutex_enter(&dstatep->lock); level_tmp = dstatep->level[i]; dstatep->level[i] = maxpwr[i]; if (pm_power_has_changed(dstatep->dip, i, maxpwr[i]) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: DDI_RESUME:\n\t" " pm_power_has_changed" " failed: comp %d to level %d\n", ddi_node_name(devi), ddi_get_instance(devi), i, maxpwr[i]); dstatep->level[i] = level_tmp; } mutex_exit(&dstatep->lock); } } else { /* * Call pm_raise_power() instead */ for (i = i_init; i < COMPONENTS; i++) { GEN_DEBUG((CE_CONT, "%s%d: DDI_RESUME: pm_raise_power" " comp %d to level %d", ddi_node_name(devi), ddi_get_instance(devi), i, maxpwr[i])); if (pm_raise_power(dstatep->dip, i, maxpwr[i]) != DDI_SUCCESS) { cmn_err(CE_WARN, "%s%d: DDI_RESUME:" "\n\tpm_raise_power" "failed: comp %d to level %d\n", ddi_node_name(devi), ddi_get_instance(devi), i, maxpwr[i]); } } } return (DDI_SUCCESS); default: GEN_DEBUG((CE_WARN, "attach: default")); return (DDI_FAILURE); } }