/* * dm2s_attach - Module's attach routine. */ int dm2s_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int instance; dm2s_t *dm2sp; char name[20]; instance = ddi_get_instance(dip); /* Only one instance is supported. */ if (instance != 0) { cmn_err(CE_WARN, "only one instance is supported"); return (DDI_FAILURE); } if (cmd != DDI_ATTACH) { return (DDI_FAILURE); } if (ddi_soft_state_zalloc(dm2s_softstate, instance) != DDI_SUCCESS) { cmn_err(CE_WARN, "softstate allocation failure"); return (DDI_FAILURE); } dm2sp = (dm2s_t *)ddi_get_soft_state(dm2s_softstate, instance); if (dm2sp == NULL) { ddi_soft_state_free(dm2s_softstate, instance); cmn_err(CE_WARN, "softstate allocation failure."); return (DDI_FAILURE); } dm2sp->ms_dip = dip; dm2sp->ms_major = ddi_name_to_major(ddi_get_name(dip)); dm2sp->ms_ppa = instance; /* * Get an interrupt block cookie corresponding to the * interrupt priority of the event handler. * Assert that the event priority is not re-defined to * some higher priority. */ /* LINTED */ ASSERT(SCF_EVENT_PRI == DDI_SOFTINT_LOW); if (ddi_get_soft_iblock_cookie(dip, SCF_EVENT_PRI, &dm2sp->ms_ibcookie) != DDI_SUCCESS) { cmn_err(CE_WARN, "ddi_get_soft_iblock_cookie failed."); goto error; } mutex_init(&dm2sp->ms_lock, NULL, MUTEX_DRIVER, (void *)dm2sp->ms_ibcookie); dm2sp->ms_clean |= DM2S_CLEAN_LOCK; cv_init(&dm2sp->ms_wait, NULL, CV_DRIVER, NULL); dm2sp->ms_clean |= DM2S_CLEAN_CV; (void) sprintf(name, "%s%d", DM2S_MODNAME, instance); if (ddi_create_minor_node(dip, name, S_IFCHR, instance, DDI_PSEUDO, NULL) == DDI_FAILURE) { ddi_remove_minor_node(dip, NULL); cmn_err(CE_WARN, "Device node creation failed."); goto error; } dm2sp->ms_clean |= DM2S_CLEAN_NODE; ddi_set_driver_private(dip, (caddr_t)dm2sp); ddi_report_dev(dip); return (DDI_SUCCESS); error: dm2s_cleanup(dm2sp); return (DDI_FAILURE); }
static int ntwdt_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int instance; ntwdt_state_t *ntwdt_ptr = NULL; /* pointer to ntwdt_runstatep */ ntwdt_runstate_t *ntwdt_runstatep = NULL; cyc_handler_t *hdlr = NULL; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: return (DDI_SUCCESS); default: return (DDI_FAILURE); } if (ntwdt_chk_watchdog_support() != 0) { return (DDI_FAILURE); } instance = ddi_get_instance(dip); ASSERT(instance == 0); if (ddi_soft_state_zalloc(ntwdt_statep, instance) != DDI_SUCCESS) { return (DDI_FAILURE); } ntwdt_ptr = ddi_get_soft_state(ntwdt_statep, instance); ASSERT(ntwdt_ptr != NULL); ntwdt_dip = dip; ntwdt_ptr->ntwdt_dip = dip; ntwdt_ptr->ntwdt_cycl_id = CYCLIC_NONE; mutex_init(&ntwdt_ptr->ntwdt_mutex, NULL, MUTEX_DRIVER, NULL); /* * Initialize the watchdog structure */ ntwdt_ptr->ntwdt_run_state = kmem_zalloc(sizeof (ntwdt_runstate_t), KM_SLEEP); ntwdt_runstatep = ntwdt_ptr->ntwdt_run_state; if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_LOW, &ntwdt_runstatep->ntwdt_runstate_mtx_cookie) != DDI_SUCCESS) { cmn_err(CE_WARN, "init of iblock cookie failed " "for ntwdt_runstate_mutex"); goto err1; } else { mutex_init(&ntwdt_runstatep->ntwdt_runstate_mutex, NULL, MUTEX_DRIVER, (void *)ntwdt_runstatep->ntwdt_runstate_mtx_cookie); } /* Cyclic fires once per second: */ ntwdt_runstatep->ntwdt_cyclic_interval = NTWDT_CYCLIC_INTERVAL; /* init the Cyclic that drives the NTWDT */ hdlr = &ntwdt_runstatep->ntwdt_cycl_hdlr; hdlr->cyh_level = CY_LOCK_LEVEL; hdlr->cyh_func = (cyc_func_t)ntwdt_cyclic_pat; hdlr->cyh_arg = NULL; /* Softint that will be triggered by Cyclic that drives NTWDT */ if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &ntwdt_cyclic_softint_id, NULL, NULL, ntwdt_cyclic_softint, (caddr_t)ntwdt_ptr) != DDI_SUCCESS) { cmn_err(CE_WARN, "failed to add cyclic softintr"); goto err2; } /* * Create Minor Node as last activity. This prevents * application from accessing our implementation until it * is initialized. */ if (ddi_create_minor_node(dip, NTWDT_MINOR_NODE, S_IFCHR, 0, DDI_PSEUDO, NULL) == DDI_FAILURE) { cmn_err(CE_WARN, "failed to create Minor Node: %s", NTWDT_MINOR_NODE); goto err3; } /* Display our driver info in the banner */ ddi_report_dev(dip); return (DDI_SUCCESS); err3: ddi_remove_softintr(ntwdt_cyclic_softint_id); err2: mutex_destroy(&ntwdt_runstatep->ntwdt_runstate_mutex); err1: /* clean up the driver stuff here */ kmem_free(ntwdt_runstatep, sizeof (ntwdt_runstate_t)); ntwdt_ptr->ntwdt_run_state = NULL; mutex_destroy(&ntwdt_ptr->ntwdt_mutex); ddi_soft_state_free(ntwdt_statep, instance); ntwdt_dip = NULL; return (DDI_FAILURE); }
int rmc_comm_serdev_init(struct rmc_comm_state *rcs, dev_info_t *dip) { cyc_handler_t cychand; cyc_time_t cyctime; int err = DDI_SUCCESS; rcs->sd_state.cycid = CYCLIC_NONE; /* * Online the hardware ... */ err = rmc_comm_online(rcs, dip); if (err != 0) return (-1); /* * call ddi_get_soft_iblock_cookie() to retrieve the * the interrupt block cookie so that the mutexes are initialized * before adding the interrupt (to avoid a potential race condition). */ err = ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_LOW, &rcs->dp_state.dp_iblk); if (err != DDI_SUCCESS) return (-1); err = ddi_get_iblock_cookie(dip, 0, &rcs->sd_state.hw_iblk); if (err != DDI_SUCCESS) return (-1); /* * initialize mutex here before adding hw/sw interrupt handlers */ mutex_init(rcs->dp_state.dp_mutex, NULL, MUTEX_DRIVER, rcs->dp_state.dp_iblk); mutex_init(rcs->sd_state.hw_mutex, NULL, MUTEX_DRIVER, rcs->sd_state.hw_iblk); /* * Install soft and hard interrupt handler(s) * * the soft intr. handler will need the data protocol lock (dp_mutex) * So, data protocol mutex and iblock cookie are created/initialized * here */ err = ddi_add_softintr(dip, DDI_SOFTINT_LOW, &rcs->sd_state.softid, &rcs->dp_state.dp_iblk, NULL, rmc_comm_softint, (caddr_t)rcs); if (err != DDI_SUCCESS) { mutex_destroy(rcs->dp_state.dp_mutex); mutex_destroy(rcs->sd_state.hw_mutex); return (-1); } /* * hardware interrupt */ if (rcs->sd_state.sio_handle != NULL) { err = ddi_add_intr(dip, 0, &rcs->sd_state.hw_iblk, NULL, rmc_comm_hi_intr, (caddr_t)rcs); /* * did we successfully install the h/w interrupt handler? */ if (err != DDI_SUCCESS) { ddi_remove_softintr(rcs->sd_state.softid); mutex_destroy(rcs->dp_state.dp_mutex); mutex_destroy(rcs->sd_state.hw_mutex); return (-1); } } /* * Start cyclic callbacks */ cychand.cyh_func = rmc_comm_cyclic; cychand.cyh_arg = rcs; cychand.cyh_level = CY_LOW_LEVEL; cyctime.cyt_when = 0; /* from the next second */ cyctime.cyt_interval = 5*RMC_COMM_ONE_SEC; /* call at 5s intervals */ mutex_enter(&cpu_lock); rcs->sd_state.cycid = cyclic_add(&cychand, &cyctime); mutex_exit(&cpu_lock); return (0); }