コード例 #1
0
ファイル: pci_pci.c プロジェクト: apprisi/illumos-gate
/* ARGSUSED */
static int
ppb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
	int *rvalp)
{
	int		instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
	ppb_devstate_t	*ppb_p = ddi_get_soft_state(ppb_state, instance);
	struct devctl_iocdata *dcp;
	uint_t		bus_state;
	dev_info_t	*self;
	int		rv = 0;

	if (ppb_p == NULL)
		return (ENXIO);

	/*
	 * Ioctls will be handled by SPARC PCI Express framework for all
	 * PCIe platforms
	 */
	if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
		return (pcie_ioctl(ppb_p->dip, dev, cmd, arg, mode, credp,
		    rvalp));
	else if (ppb_p->hotplug_capable == B_TRUE)
		return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, arg, mode,
		    credp, rvalp));

	self = ppb_p->dip;

	/*
	 * We can use the generic implementation for these ioctls
	 */
	switch (cmd) {
	case DEVCTL_DEVICE_GETSTATE:
	case DEVCTL_DEVICE_ONLINE:
	case DEVCTL_DEVICE_OFFLINE:
	case DEVCTL_BUS_GETSTATE:
		return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
	}

	/*
	 * read devctl ioctl data
	 */
	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
		return (EFAULT);

	switch (cmd) {

	case DEVCTL_DEVICE_RESET:
		rv = ENOTSUP;
		break;

	case DEVCTL_BUS_QUIESCE:
		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
			if (bus_state == BUS_QUIESCED)
				break;
		(void) ndi_set_bus_state(self, BUS_QUIESCED);
		break;

	case DEVCTL_BUS_UNQUIESCE:
		if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
			if (bus_state == BUS_ACTIVE)
				break;
		(void) ndi_set_bus_state(self, BUS_ACTIVE);
		break;

	case DEVCTL_BUS_RESET:
		rv = ENOTSUP;
		break;

	case DEVCTL_BUS_RESETALL:
		rv = ENOTSUP;
		break;

	default:
		rv = ENOTTY;
	}

	ndi_dc_freehdl(dcp);
	return (rv);
}
コード例 #2
0
ファイル: pci_devctl.c プロジェクト: andreiw/polaris
/* ARGSUSED */
static int
pci_devctl_ioctl(dev_info_t *dip, int cmd, intptr_t arg, int mode,
    cred_t *credp, int *rvalp)
{
	int rv = 0;
	struct devctl_iocdata *dcp;
	uint_t bus_state;

	/*
	 * We can use the generic implementation for these ioctls
	 */
	switch (cmd) {
	case DEVCTL_DEVICE_GETSTATE:
	case DEVCTL_DEVICE_ONLINE:
	case DEVCTL_DEVICE_OFFLINE:
	case DEVCTL_BUS_GETSTATE:
		return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
	}

	/*
	 * read devctl ioctl data
	 */
	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
		return (EFAULT);

	switch (cmd) {

	case DEVCTL_DEVICE_RESET:
		DEBUG0(DBG_IOCTL, dip, "DEVCTL_DEVICE_RESET\n");
		rv = ENOTSUP;
		break;


	case DEVCTL_BUS_QUIESCE:
		DEBUG0(DBG_IOCTL, dip, "DEVCTL_BUS_QUIESCE\n");
		if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS)
			if (bus_state == BUS_QUIESCED)
				break;
		(void) ndi_set_bus_state(dip, BUS_QUIESCED);
		break;

	case DEVCTL_BUS_UNQUIESCE:
		DEBUG0(DBG_IOCTL, dip, "DEVCTL_BUS_UNQUIESCE\n");
		if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS)
			if (bus_state == BUS_ACTIVE)
				break;
		(void) ndi_set_bus_state(dip, BUS_ACTIVE);
		break;

	case DEVCTL_BUS_RESET:
		DEBUG0(DBG_IOCTL, dip, "DEVCTL_BUS_RESET\n");
		rv = ENOTSUP;
		break;

	case DEVCTL_BUS_RESETALL:
		DEBUG0(DBG_IOCTL, dip, "DEVCTL_BUS_RESETALL\n");
		rv = ENOTSUP;
		break;

	default:
		rv = ENOTTY;
	}

	ndi_dc_freehdl(dcp);
	return (rv);
}
コード例 #3
0
ファイル: gen_drv.c プロジェクト: andreiw/polaris
/*ARGSUSED*/
static int
gen_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
{
	struct dstate *dstatep;
	ddi_eventcookie_t cookie;
	int instance;
	int rval = 0;
	char *nodename;
	int i;
	struct devctl_iocdata *dcp;
	uint_t state;
	int ret;
	int level_tmp;

	instance = MINOR_TO_INST(getminor(dev));
	dstatep = ddi_get_soft_state(dstates, instance);
	nodename = dstatep->nodename;

	if (dstatep == NULL)
		return (ENXIO);

	/*
	 * read devctl ioctl data
	 */
	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
		return (EFAULT);

	switch (cmd) {
	case GENDRV_IOFAULT_SIMULATE:
		if (ddi_get_eventcookie(dstatep->dip, DDI_DEVI_FAULT_EVENT,
			    &(cookie)) != NDI_SUCCESS)
			return (DDI_FAILURE);

		return (ndi_post_event(dstatep->dip, dstatep->dip, cookie,
			    NULL));

	case GENDRV_NDI_EVENT_TEST:
		if (ddi_get_eventcookie(dstatep->dip, "pshot_dev_offline",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		if (ddi_get_eventcookie(dstatep->dip, "pshot_dev_reset",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		if (ddi_get_eventcookie(dstatep->dip, "pshot_bus_reset",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		if (ddi_get_eventcookie(dstatep->dip, "pshot_bus_quiesce",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		if (ddi_get_eventcookie(dstatep->dip, "pshot_bus_unquiesce",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		if (ddi_get_eventcookie(dstatep->dip, "pshot_bus_test_post",
		    &cookie) == NDI_SUCCESS) {
			(void) ndi_post_event(dstatep->dip, dstatep->dip,
			    cookie, NULL);
		}

		break;

	case DEVCTL_PM_PWR_HAS_CHANGED_ON_RESUME:
		/*
		 * Issue pm_power_has_changed() call on DDI_RESUME
		 */
		mutex_enter(&dstatep->lock);
		dstatep->flag |= PWR_HAS_CHANGED_ON_RESUME_FLAG;
		mutex_exit(&dstatep->lock);
		GEN_DEBUG((CE_CONT, "%s%d:"
		    " DEVCTL_PM_PWR_HAS_CHANGED_ON_RESUME", nodename,
		    instance));

		break;

	case DEVCTL_PM_FAIL_SUSPEND:
		/*
		 * Fail the suspend attempt in DDI_SUSPEND
		 */
		mutex_enter(&dstatep->lock);
		dstatep->flag |= FAIL_SUSPEND_FLAG;
		mutex_exit(&dstatep->lock);
		GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_FAIL_SUSPEND",
		    nodename, instance));

		break;

	case DEVCTL_PM_PUP_WITH_PWR_HAS_CHANGED:
		/*
		 * Use pm_power_has_changed() to power up comp 0 when
		 * enforcing the comp 0 vs comp-not 0 dependency:
		 * Power up comp 0 first, if request for comp-not-0
		 * comes in.
		 * Else, default to pm_raise_power().
		 */
		mutex_enter(&dstatep->lock);
		dstatep->flag |= PUP_WITH_PWR_HAS_CHANGED_FLAG;
		mutex_exit(&dstatep->lock);
		GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_PUP_WITH_PWR_HAS_CHANGED",
		    nodename, instance));

		break;

	case DEVCTL_PM_BUSY_COMP:
		/*
		 * mark component 0 busy via a pm_busy_component() call.
		 * update the busy[] array.
		 */
		mutex_enter(&dstatep->lock);
		++dstatep->busy[0];
		GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_BUSY_COMP: comp 0:"
		    " busy=%d", nodename, instance, dstatep->busy[0]));
		mutex_exit(&dstatep->lock);
		ret = pm_busy_component(dstatep->dip, 0);
		ASSERT(ret == DDI_SUCCESS);

		break;

	case DEVCTL_PM_BUSY_COMP_TEST:
		/*
		 * test busy state on component 0
		 */
		mutex_enter(&dstatep->lock);
		state = dstatep->busy[0];
		if (copyout(&state, dcp->cpyout_buf,
		    sizeof (uint_t)) != 0) {
			cmn_err(CE_WARN, "%s%d:"
			    " DEVCTL_PM_BUSY_COMP_TEST: copyout failed\n",
			    nodename, instance);
			rval = EINVAL;
		}
		GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_BUSY_COMP_TEST:"
		    " comp 0 busy %d",
		    nodename, instance, state));
		mutex_exit(&dstatep->lock);

		break;

	case DEVCTL_PM_IDLE_COMP:
		/*
		 * mark component 0 idle via a pm_idle_component() call.
		 * NOP if dstatep->busy[0] == 0.
		 */
		mutex_enter(&dstatep->lock);
		if (dstatep->busy[0] > 0) {
			--dstatep->busy[0];
			GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_IDLE_COMP:"
			    " comp 0: busy=%d", nodename, instance,
			    dstatep->busy[0]));
			mutex_exit(&dstatep->lock);
			ret = pm_idle_component(dstatep->dip, 0);
			ASSERT(ret == DDI_SUCCESS);
		} else {
			mutex_exit(&dstatep->lock);
		}

		break;

	case DEVCTL_PM_PROM_PRINTF:
		(void) prom_printf("%s%d: PROM_PRINTF FROM GEN_DRV\n",
		    nodename, instance);

		break;

	case DEVCTL_PM_RAISE_PWR:
		/*
		 * power up both components to MAXPWR via
		 * pm_raise_power() calls. this ioctl() cmd
		 * assumes that the current level is 0
		 */
		for (i = 0; i < COMPONENTS; i++) {
			GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_RAISE_PWR:"
			    " comp %d old 0 new %d",
			    nodename, instance, i, maxpwr[i]));
			if (pm_raise_power(dstatep->dip, 0, maxpwr[i])
			    != DDI_SUCCESS) {
				rval = EINVAL;
			}
		}

		break;

	case DEVCTL_PM_CHANGE_PWR_LOW:
		/*
		 * power off both components via pm_power_has_changed() calls
		 */
		for (i = (COMPONENTS - 1); i >= 0; --i) {
			GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_CHANGE_PWR_LOW:"
			    " comp %d new 0",
			    nodename, instance, i));
			mutex_enter(&dstatep->lock);
			level_tmp = dstatep->level[i];
			dstatep->level[i] = 0;
			if (pm_power_has_changed(dstatep->dip, i, 0)
			    != DDI_SUCCESS) {
				dstatep->level[i] = level_tmp;
				rval = EINVAL;
			}
			mutex_exit(&dstatep->lock);
		}

		break;

	case DEVCTL_PM_CHANGE_PWR_HIGH:
		/*
		 * power up both components to MAXPWR via
		 * pm_power_has_changed() calls
		 */
		for (i = 0; i < COMPONENTS; i++) {
			GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_CHANGE_PWR_HIGH:"
			    " comp %d new %d",
			    nodename, instance, 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) {
				dstatep->level[i] = level_tmp;
				rval = EINVAL;
			}
			mutex_exit(&dstatep->lock);
		}

		break;

	case DEVCTL_PM_POWER:
		/*
		 * test if the gen_drv_power() routine has been called,
		 * then clear
		 */
		mutex_enter(&dstatep->lock);
		state = (dstatep->flag & POWER_FLAG) ? 1 : 0;
		if (copyout(&state, dcp->cpyout_buf,
		    sizeof (uint_t)) != 0) {
			cmn_err(CE_WARN, "%s%d: DEVCTL_PM_POWER:"
			    " copyout failed\n", nodename, instance);
			rval = EINVAL;
		}
		GEN_DEBUG((CE_CONT, "%s%d: %s POWER_FLAG: %d",
		    nodename, instance, "DEVCTL_PM_POWER", state));
		dstatep->flag &= ~POWER_FLAG;
		mutex_exit(&dstatep->lock);
		break;

	case DEVCTL_PM_NO_LOWER_POWER:
		/*
		 * issue to not invoke pm_lower_power() on detach
		 */
		mutex_enter(&dstatep->lock);
		dstatep->flag &= ~LOWER_POWER_FLAG;
		mutex_exit(&dstatep->lock);
		GEN_DEBUG((CE_CONT, "%s%d: DEVCTL_PM_NO_LOWER_POWER",
			    nodename, instance));
		break;

	default:
		return (ENOTTY);
	}

	return (rval);
}