Exemple #1
0
static int
dr_is_real_device(dev_info_t *dip)
{
	struct regspec *regbuf = NULL;
	int length = 0;
	int rc;

	if (ddi_get_driver(dip) == NULL)
		return (0);

	if (DEVI(dip)->devi_pm_flags & (PMC_NEEDS_SR|PMC_PARENTAL_SR))
		return (1);
	if (DEVI(dip)->devi_pm_flags & PMC_NO_SR)
		return (0);

	/*
	 * now the general case
	 */
	rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
		(caddr_t)&regbuf, &length);
	ASSERT(rc != DDI_PROP_NO_MEMORY);
	if (rc != DDI_PROP_SUCCESS) {
		return (0);
	} else {
		if ((length > 0) && (regbuf != NULL))
			kmem_free(regbuf, length);
		return (1);
	}
}
/*
 * Configuration-related entry points for nexus and leaf drivers
 */
int
devi_identify(dev_info_t *devi)
{
	struct dev_ops *ops;
	int (*fn)(dev_info_t *);

	if ((ops = ddi_get_driver(devi)) == NULL ||
	    (fn = ops->devo_identify) == NULL)
		return (-1);

	return ((*fn)(devi));
}
int
devi_quiesce(dev_info_t *devi)
{
	struct dev_ops *ops;
	int (*fn)(dev_info_t *);

	if (((ops = ddi_get_driver(devi)) == NULL) ||
	    (ops->devo_rev < 4) || ((fn = ops->devo_quiesce) == NULL))
		return (DDI_FAILURE);

	return ((*fn)(devi));
}
/*
 * This entry point not defined by Solaris 2.0 DDI/DKI, so
 * its inclusion here is somewhat moot.
 */
int
devi_reset(dev_info_t *devi, ddi_reset_cmd_t cmd)
{
	struct dev_ops *ops;
	int (*fn)(dev_info_t *, ddi_reset_cmd_t);

	if ((ops = ddi_get_driver(devi)) == NULL ||
	    (fn = ops->devo_reset) == NULL)
		return (DDI_FAILURE);

	return ((*fn)(devi, cmd));
}
int
devi_probe(dev_info_t *devi)
{
	int rv, probe_failed;
	pm_ppm_cookie_t ppm_cookie;
	struct dev_ops *ops;
	int (*fn)(dev_info_t *);

	ops = ddi_get_driver(devi);
	ASSERT(ops);

	pm_pre_probe(devi, &ppm_cookie);

	/*
	 * probe(9E) in 2.0 implies that you can get
	 * away with not writing one of these .. so we
	 * pretend we're 'nulldev' if we don't find one (sigh).
	 */
	if ((fn = ops->devo_probe) == NULL) {
		if (ddi_dev_is_sid(devi) == DDI_SUCCESS)
			rv = DDI_PROBE_DONTCARE;
		else
			rv = DDI_PROBE_FAILURE;
	} else
		rv = (*fn)(devi);

	switch (rv) {
	case DDI_PROBE_DONTCARE:
	case DDI_PROBE_SUCCESS:
		probe_failed = 0;
		break;
	default:
		probe_failed = 1;
		break;
	}
	pm_post_probe(&ppm_cookie, rv, probe_failed);

	return (rv);
}
/*
 * devi_attach()
 * 	attach a device instance to the system if the driver supplies an
 * 	attach(9E) entrypoint.
 */
int
devi_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	struct dev_ops *ops;
	int error;
	int (*fn)(dev_info_t *, ddi_attach_cmd_t);
	pm_ppm_cookie_t pc;

	if ((error = mdi_pre_attach(devi, cmd)) != DDI_SUCCESS) {
		return (error);
	}

	pm_pre_attach(devi, &pc, cmd);

	if ((cmd == DDI_RESUME || cmd == DDI_PM_RESUME) &&
	    e_ddi_parental_suspend_resume(devi)) {
		error = e_ddi_resume(devi, cmd);
		goto done;
	}
	ops = ddi_get_driver(devi);
	ASSERT(ops);
	if ((fn = ops->devo_attach) == NULL) {
		error = DDI_FAILURE;
		goto done;
	}

	/*
	 * Call the driver's attach(9e) entrypoint
	 */
	i_attach_ctlop(devi, cmd, DDI_PRE, 0);
	error = (*fn)(devi, cmd);
	i_attach_ctlop(devi, cmd, DDI_POST, error);

done:
	pm_post_attach(&pc, error);
	mdi_post_attach(devi, cmd, error);

	return (error);
}
/*
 * devi_detach()
 * 	detach a device instance from the system if the driver supplies a
 * 	detach(9E) entrypoint.
 */
int
devi_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
{
	struct dev_ops *ops;
	int error;
	int (*fn)(dev_info_t *, ddi_detach_cmd_t);
	pm_ppm_cookie_t pc;

	ASSERT(cmd == DDI_SUSPEND || cmd == DDI_PM_SUSPEND ||
	    cmd == DDI_DETACH);

	if ((cmd == DDI_SUSPEND || cmd == DDI_PM_SUSPEND) &&
	    e_ddi_parental_suspend_resume(devi)) {
		return (e_ddi_suspend(devi, cmd));
	}
	ops = ddi_get_driver(devi);
	ASSERT(ops);
	if ((fn = ops->devo_detach) == NULL)
		return (DDI_FAILURE);

	if ((error = mdi_pre_detach(devi, cmd)) != DDI_SUCCESS) {
		return (error);
	}
	i_detach_ctlop(devi, cmd, DDI_PRE, 0);
	pm_pre_detach(devi, cmd, &pc);

	/*
	 * Call the driver's detach routine
	 */
	error = (*fn)(devi, cmd);

	pm_post_detach(&pc, error);
	i_detach_ctlop(devi, cmd, DDI_POST, error);
	mdi_post_detach(devi, cmd, error);

	return (error);
}
Exemple #8
0
int
xen_suspend_devices(dev_info_t *dip)
{
	int error;
	char buf[XPV_BUFSIZE];

	SUSPEND_DEBUG("xen_suspend_devices\n");

	for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
		if (xen_suspend_devices(ddi_get_child(dip)))
			return (ENXIO);
		if (ddi_get_driver(dip) == NULL)
			continue;
		SUSPEND_DEBUG("Suspending device %s\n", ddi_deviname(dip, buf));
		ASSERT((DEVI(dip)->devi_cpr_flags & DCF_CPR_SUSPENDED) == 0);


		if (!i_ddi_devi_attached(dip)) {
			error = DDI_FAILURE;
		} else {
			error = devi_detach(dip, DDI_SUSPEND);
		}

		if (error == DDI_SUCCESS) {
			DEVI(dip)->devi_cpr_flags |= DCF_CPR_SUSPENDED;
		} else {
			SUSPEND_DEBUG("WARNING: Unable to suspend device %s\n",
			    ddi_deviname(dip, buf));
			cmn_err(CE_WARN, "Unable to suspend device %s.",
			    ddi_deviname(dip, buf));
			cmn_err(CE_WARN, "Device is busy or does not "
			    "support suspend/resume.");
				return (ENXIO);
		}
	}
	return (0);
}