コード例 #1
0
ファイル: dm2s.c プロジェクト: andreiw/polaris
/*
 * 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);
}
コード例 #2
0
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);
}
コード例 #3
0
ファイル: rmc_comm.c プロジェクト: andreiw/polaris
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);
}