Example #1
0
/*
 * Create properties of various data types for testing devfs events.
 */
static int
gen_create_properties(dev_info_t *devi)
{
	int int_val = 3023;
	int int_array[] = { 3, 10, 304, 230, 4};
	int64_t int64_val = 20;
	int64_t int64_array[] = { 12, 24, 36, 48};
	char *string_val = "Dev_node_prop";
	char *string_array[] = {"Dev_node_prop:0",
	    "Dev_node_prop:1", "Dev_node_prop:2", "Dev_node_prop:3"};
	uchar_t byte_array[] = { (uchar_t)0xaa, (uchar_t)0x55,
	    (uchar_t)0x12, (uchar_t)0xcd };
	char bytes[] = { (char)0x00, (char)0xef, (char)0xff };

	if (ddi_prop_update_int(DDI_DEV_T_NONE, devi, "int", int_val)
	    != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_int_array(DDI_DEV_T_NONE, devi, "int-array",
	    int_array, sizeof (int_array) / sizeof (int)) != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_int64(DDI_DEV_T_NONE, devi, "int64", int64_val)
	    != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_int64_array(DDI_DEV_T_NONE, devi, "int64-array",
	    int64_array, sizeof (int64_array) / sizeof (int64_t))
	    != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "string", string_val)
	    != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, devi, "string-array",
	    string_array, sizeof (string_array) / sizeof (char *))
	    != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_create(DDI_DEV_T_NONE, devi, DDI_PROP_CANSLEEP,
	    "boolean", NULL, 0) != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	if (ddi_prop_update_byte_array(DDI_DEV_T_NONE, devi, "byte-array",
	    byte_array, sizeof (byte_array)) != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	/* untyped property */
	if (ddi_prop_create(DDI_DEV_T_NONE, devi, DDI_PROP_CANSLEEP, "untyped",
	    (caddr_t)bytes, sizeof (bytes)) != DDI_PROP_SUCCESS)
		return (DDI_FAILURE);

	return (DDI_SUCCESS);
}
Example #2
0
/*ARGSUSED*/
static int
px_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	px_t		*px_p;	/* per bus state pointer */
	int		instance = DIP_TO_INST(dip);
	int		ret = DDI_SUCCESS;
	devhandle_t	dev_hdl = NULL;
	pcie_hp_regops_t regops;
	pcie_bus_t	*bus_p;

	switch (cmd) {
	case DDI_ATTACH:
		DBG(DBG_ATTACH, dip, "DDI_ATTACH\n");

		/* See pci_cfgacc.c */
		pci_cfgacc_acc_p = pci_cfgacc_acc;

		/*
		 * Allocate and get the per-px soft state structure.
		 */
		if (ddi_soft_state_zalloc(px_state_p, instance)
		    != DDI_SUCCESS) {
			cmn_err(CE_WARN, "%s%d: can't allocate px state",
			    ddi_driver_name(dip), instance);
			goto err_bad_px_softstate;
		}
		px_p = INST_TO_STATE(instance);
		px_p->px_dip = dip;
		mutex_init(&px_p->px_mutex, NULL, MUTEX_DRIVER, NULL);
		px_p->px_soft_state = PCI_SOFT_STATE_CLOSED;

		(void) ddi_prop_update_string(DDI_DEV_T_NONE, dip,
		    "device_type", "pciex");

		/* Initialize px_dbg for high pil printing */
		px_dbg_attach(dip, &px_p->px_dbg_hdl);
		pcie_rc_init_bus(dip);

		/*
		 * Get key properties of the pci bridge node and
		 * determine it's type (psycho, schizo, etc ...).
		 */
		if (px_get_props(px_p, dip) == DDI_FAILURE)
			goto err_bad_px_prop;

		if (px_lib_dev_init(dip, &dev_hdl) != DDI_SUCCESS)
			goto err_bad_dev_init;

		/* Initialize device handle */
		px_p->px_dev_hdl = dev_hdl;

		/* Cache the BDF of the root port nexus */
		px_p->px_bdf = px_lib_get_bdf(px_p);

		/*
		 * Initialize interrupt block.  Note that this
		 * initialize error handling for the PEC as well.
		 */
		if ((ret = px_ib_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_ib;

		if (px_cb_attach(px_p) != DDI_SUCCESS)
			goto err_bad_cb;

		/*
		 * Start creating the modules.
		 * Note that attach() routines should
		 * register and enable their own interrupts.
		 */

		if ((px_mmu_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_mmu;

		if ((px_msiq_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_msiq;

		if ((px_msi_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_msi;

		if ((px_pec_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_pec;

		if ((px_dma_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_dma; /* nothing to uninitialize on DMA */

		if ((px_fm_attach(px_p)) != DDI_SUCCESS)
			goto err_bad_dma;

		/*
		 * All of the error handlers have been registered
		 * by now so it's time to activate all the interrupt.
		 */
		if ((px_enable_err_intr(px_p)) != DDI_SUCCESS)
			goto err_bad_intr;

		if (px_lib_hotplug_init(dip, (void *)&regops) == DDI_SUCCESS) {
			pcie_bus_t	*bus_p = PCIE_DIP2BUS(dip);

			bus_p->bus_hp_sup_modes |= PCIE_NATIVE_HP_MODE;
		}

		(void) px_set_mps(px_p);

		if (pcie_init(dip, (caddr_t)&regops) != DDI_SUCCESS)
			goto err_bad_hotplug;

		(void) pcie_hpintr_enable(dip);

		if (pxtool_init(dip) != DDI_SUCCESS)
			goto err_bad_pcitool_node;

		/*
		 * power management setup. Even if it fails, attach will
		 * succeed as this is a optional feature. Since we are
		 * always at full power, this is not critical.
		 */
		if (pwr_common_setup(dip) != DDI_SUCCESS) {
			DBG(DBG_PWR, dip, "pwr_common_setup failed\n");
		} else if (px_pwr_setup(dip) != DDI_SUCCESS) {
			DBG(DBG_PWR, dip, "px_pwr_setup failed \n");
			pwr_common_teardown(dip);
		}

		/*
		 * add cpr callback
		 */
		px_cpr_add_callb(px_p);

		/*
		 * do fabric sync in case we don't need to wait for
		 * any bridge driver to be ready
		 */
		(void) px_lib_fabric_sync(dip);

		ddi_report_dev(dip);

		px_p->px_state = PX_ATTACHED;

		/*
		 * save base addr in bus_t for pci_cfgacc_xxx(), this
		 * depends of px structure being properly initialized.
		 */
		bus_p = PCIE_DIP2BUS(dip);
		bus_p->bus_cfgacc_base = px_lib_get_cfgacc_base(dip);

		/*
		 * Partially populate bus_t for all devices in this fabric
		 * for device type macros to work.
		 */
		/*
		 * Populate bus_t for all devices in this fabric, after FMA
		 * is initializated, so that config access errors could
		 * trigger panic.
		 */
		pcie_fab_init_bus(dip, PCIE_BUS_ALL);

		DBG(DBG_ATTACH, dip, "attach success\n");
		break;

err_bad_pcitool_node:
		(void) pcie_hpintr_disable(dip);
		(void) pcie_uninit(dip);
err_bad_hotplug:
		(void) px_lib_hotplug_uninit(dip);
		px_disable_err_intr(px_p);
err_bad_intr:
		px_fm_detach(px_p);
err_bad_dma:
		px_pec_detach(px_p);
err_bad_pec:
		px_msi_detach(px_p);
err_bad_msi:
		px_msiq_detach(px_p);
err_bad_msiq:
		px_mmu_detach(px_p);
err_bad_mmu:
err_bad_cb:
		px_ib_detach(px_p);
err_bad_ib:
		if (px_lib_dev_fini(dip) != DDI_SUCCESS) {
			DBG(DBG_ATTACH, dip, "px_lib_dev_fini failed\n");
		}
err_bad_dev_init:
		px_free_props(px_p);
err_bad_px_prop:
		pcie_rc_fini_bus(dip);
		px_dbg_detach(dip, &px_p->px_dbg_hdl);
		mutex_destroy(&px_p->px_mutex);
		ddi_soft_state_free(px_state_p, instance);
err_bad_px_softstate:
		ret = DDI_FAILURE;
		break;

	case DDI_RESUME:
		DBG(DBG_ATTACH, dip, "DDI_RESUME\n");

		px_p = INST_TO_STATE(instance);

		mutex_enter(&px_p->px_mutex);

		/* suspend might have not succeeded */
		if (px_p->px_state != PX_SUSPENDED) {
			DBG(DBG_ATTACH, px_p->px_dip,
			    "instance NOT suspended\n");
			ret = DDI_FAILURE;
			break;
		}

		px_msiq_resume(px_p);
		px_lib_resume(dip);
		(void) pcie_pwr_resume(dip);
		px_p->px_state = PX_ATTACHED;

		mutex_exit(&px_p->px_mutex);

		break;
	default:
		DBG(DBG_ATTACH, dip, "unsupported attach op\n");
		ret = DDI_FAILURE;
		break;
	}

	return (ret);
}
Example #3
0
/*
 * attach the module
 */
static int
tvhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	char *vclass;
	int instance, vhci_regis = 0;
	struct tvhci_state *vhci = NULL;
	dev_info_t *pdip;

	instance = ddi_get_instance(dip);

	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
	case DDI_PM_RESUME:
		return (0);	/* nothing to do */

	default:
		return (DDI_FAILURE);
	}

	/*
	 * Allocate vhci data structure.
	 */
	if (ddi_soft_state_zalloc(tvhci_state, instance) != DDI_SUCCESS) {
		return (DDI_FAILURE);
	}

	vhci = ddi_get_soft_state(tvhci_state, instance);
	ASSERT(vhci != NULL);
	vhci->dip = dip;

	/* parent must be /pshot */
	pdip = ddi_get_parent(dip);
	if (strcmp(ddi_driver_name(pdip), "pshot") != 0 ||
	    ddi_get_parent(pdip) != ddi_root_node()) {
		cmn_err(CE_NOTE, "tvhci must be under /pshot/");
		goto attach_fail;
	}

	/*
	 * XXX add mpxio-disable property. need to remove the check
	 *	from the framework
	 */
	(void) ddi_prop_update_string(DDI_DEV_T_NONE, dip,
	    "mpxio-disable", "no");

	/* bus_addr is the <vhci_class> */
	vclass = ddi_get_name_addr(dip);
	if (vclass == NULL || vclass[1] == '\0') {
		cmn_err(CE_NOTE, "tvhci invalid vhci class");
		goto attach_fail;
	}

	/*
	 * Attach this instance with the mpxio framework
	 */
	if (mdi_vhci_register(vclass, dip, &tvhci_opinfo, 0) != MDI_SUCCESS) {
		cmn_err(CE_WARN, "%s mdi_vhci_register failed",
		    ddi_node_name(dip));
		goto attach_fail;
	}
	vhci_regis++;

	if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
	    instance, DDI_NT_SCSI_NEXUS, 0) != DDI_SUCCESS) {
		cmn_err(CE_NOTE, "%s ddi_create_minor_node failed",
		    ddi_node_name(dip));
		goto attach_fail;
	}

	(void) ddi_prop_update_int(DDI_DEV_T_NONE, dip, DDI_NO_AUTODETACH, 1);
	ddi_report_dev(dip);
	return (DDI_SUCCESS);

attach_fail:
	if (vhci_regis)
		(void) mdi_vhci_unregister(dip, 0);

	ddi_soft_state_free(tvhci_state, instance);
	return (DDI_FAILURE);
}
Example #4
0
/*
 * Create a minor node for the specified volume.
 */
int
zvol_create_minor(zfs_cmd_t *zc)
{
	char *name = zc->zc_name;
	dev_t dev = zc->zc_dev;
	zvol_state_t *zv;
	objset_t *os;
	uint64_t volsize;
	minor_t minor = 0;
	struct pathname linkpath;
	int ds_mode = DS_MODE_PRIMARY;
	vnode_t *vp = NULL;
	char *devpath;
	size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + 1 + strlen(name) + 1;
	char chrbuf[30], blkbuf[30];
	int error;

	mutex_enter(&zvol_state_lock);

	if ((zv = zvol_minor_lookup(name)) != NULL) {
		mutex_exit(&zvol_state_lock);
		return (EEXIST);
	}

	if (strchr(name, '@') != 0)
		ds_mode |= DS_MODE_READONLY;

	error = dmu_objset_open(name, DMU_OST_ZVOL, ds_mode, &os);

	if (error) {
		mutex_exit(&zvol_state_lock);
		return (error);
	}

	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);

	if (error) {
		dmu_objset_close(os);
		mutex_exit(&zvol_state_lock);
		return (error);
	}

	/*
	 * If there's an existing /dev/zvol symlink, try to use the
	 * same minor number we used last time.
	 */
	devpath = kmem_alloc(devpathlen, KM_SLEEP);

	(void) sprintf(devpath, "%s/%s", ZVOL_FULL_DEV_DIR, name);

	error = lookupname(devpath, UIO_SYSSPACE, NO_FOLLOW, NULL, &vp);

	kmem_free(devpath, devpathlen);

	if (error == 0 && vp->v_type != VLNK)
		error = EINVAL;

	if (error == 0) {
		pn_alloc(&linkpath);
		error = pn_getsymlink(vp, &linkpath, kcred);
		if (error == 0) {
			char *ms = strstr(linkpath.pn_path, ZVOL_PSEUDO_DEV);
			if (ms != NULL) {
				ms += strlen(ZVOL_PSEUDO_DEV);
				minor = stoi(&ms);
			}
		}
		pn_free(&linkpath);
	}

	if (vp != NULL)
		VN_RELE(vp);

	/*
	 * If we found a minor but it's already in use, we must pick a new one.
	 */
	if (minor != 0 && ddi_get_soft_state(zvol_state, minor) != NULL)
		minor = 0;

	if (minor == 0)
		minor = zvol_minor_alloc();

	if (minor == 0) {
		dmu_objset_close(os);
		mutex_exit(&zvol_state_lock);
		return (ENXIO);
	}

	if (ddi_soft_state_zalloc(zvol_state, minor) != DDI_SUCCESS) {
		dmu_objset_close(os);
		mutex_exit(&zvol_state_lock);
		return (EAGAIN);
	}

	(void) ddi_prop_update_string(minor, zfs_dip, ZVOL_PROP_NAME, name);

	(void) sprintf(chrbuf, "%uc,raw", minor);

	if (ddi_create_minor_node(zfs_dip, chrbuf, S_IFCHR,
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
		ddi_soft_state_free(zvol_state, minor);
		dmu_objset_close(os);
		mutex_exit(&zvol_state_lock);
		return (EAGAIN);
	}

	(void) sprintf(blkbuf, "%uc", minor);

	if (ddi_create_minor_node(zfs_dip, blkbuf, S_IFBLK,
	    minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
		ddi_remove_minor_node(zfs_dip, chrbuf);
		ddi_soft_state_free(zvol_state, minor);
		dmu_objset_close(os);
		mutex_exit(&zvol_state_lock);
		return (EAGAIN);
	}

	zv = ddi_get_soft_state(zvol_state, minor);

	(void) strcpy(zv->zv_name, name);
	zv->zv_min_bs = DEV_BSHIFT;
	zv->zv_minor = minor;
	zv->zv_volsize = volsize;
	zv->zv_objset = os;
	zv->zv_mode = ds_mode;
	zv->zv_zilog = zil_open(os, NULL);

	rw_init(&zv->zv_dslock, NULL, RW_DEFAULT, NULL);

	zil_replay(os, zv, &zv->zv_txg_assign, zvol_replay_vector, NULL);

	zvol_size_changed(zv, dev);

	/* XXX this should handle the possible i/o error */
	VERIFY(dsl_prop_register(dmu_objset_ds(zv->zv_objset),
	    "readonly", zvol_readonly_changed_cb, zv) == 0);

	zvol_minors++;

	mutex_exit(&zvol_state_lock);

	return (0);
}
Example #5
0
int
pcn_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
	pcn_t			*pcnp;
	mac_register_t		*macp;
	const pcn_type_t	*pcn_type;
	int			instance = ddi_get_instance(dip);
	int			rc;
	ddi_acc_handle_t	pci;
	uint16_t		venid;
	uint16_t		devid;
	uint16_t		svid;
	uint16_t		ssid;

	switch (cmd) {
	case DDI_RESUME:
		return (pcn_ddi_resume(dip));

	case DDI_ATTACH:
		break;

	default:
		return (DDI_FAILURE);
	}

	if (ddi_slaveonly(dip) == DDI_SUCCESS) {
		pcn_error(dip, "slot does not support PCI bus-master");
		return (DDI_FAILURE);
	}

	if (ddi_intr_hilevel(dip, 0) != 0) {
		pcn_error(dip, "hilevel interrupts not supported");
		return (DDI_FAILURE);
	}

	if (pci_config_setup(dip, &pci) != DDI_SUCCESS) {
		pcn_error(dip, "unable to setup PCI config handle");
		return (DDI_FAILURE);
	}

	venid = pci_config_get16(pci, PCI_CONF_VENID);
	devid = pci_config_get16(pci, PCI_CONF_DEVID);
	svid = pci_config_get16(pci, PCI_CONF_SUBVENID);
	ssid = pci_config_get16(pci, PCI_CONF_SUBSYSID);

	if ((pcn_type = pcn_match(venid, devid)) == NULL) {
		pci_config_teardown(&pci);
		pcn_error(dip, "Unable to identify PCI card");
		return (DDI_FAILURE);
	}

	if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
	    pcn_type->pcn_name) != DDI_PROP_SUCCESS) {
		pci_config_teardown(&pci);
		pcn_error(dip, "Unable to create model property");
		return (DDI_FAILURE);
	}

	if (ddi_soft_state_zalloc(pcn_ssp, instance) != DDI_SUCCESS) {
		pcn_error(dip, "Unable to allocate soft state");
		pci_config_teardown(&pci);
		return (DDI_FAILURE);
	}

	pcnp = ddi_get_soft_state(pcn_ssp, instance);
	pcnp->pcn_dip = dip;
	pcnp->pcn_instance = instance;
	pcnp->pcn_extphyaddr = -1;

	if (ddi_get_iblock_cookie(dip, 0, &pcnp->pcn_icookie) != DDI_SUCCESS) {
		pcn_error(pcnp->pcn_dip, "ddi_get_iblock_cookie failed");
		ddi_soft_state_free(pcn_ssp, instance);
		pci_config_teardown(&pci);
		return (DDI_FAILURE);
	}


	mutex_init(&pcnp->pcn_xmtlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);
	mutex_init(&pcnp->pcn_intrlock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);
	mutex_init(&pcnp->pcn_reglock, NULL, MUTEX_DRIVER, pcnp->pcn_icookie);

	/*
	 * Enable bus master, IO space, and memory space accesses
	 */
	pci_config_put16(pci, PCI_CONF_COMM,
	    pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_ME | PCI_COMM_MAE);

	pci_config_teardown(&pci);

	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&pcnp->pcn_regs, 0, 0,
	    &pcn_devattr, &pcnp->pcn_regshandle)) {
		pcn_error(dip, "ddi_regs_map_setup failed");
		goto fail;
	}

	if (pcn_set_chipid(pcnp, (uint32_t)ssid << 16 | (uint32_t)svid) !=
	    DDI_SUCCESS) {
		goto fail;
	}

	if ((pcnp->pcn_mii = mii_alloc(pcnp, dip, &pcn_mii_ops)) == NULL)
		goto fail;

	/* XXX: need to set based on device */
	mii_set_pauseable(pcnp->pcn_mii, B_FALSE, B_FALSE);

	if ((pcn_allocrxring(pcnp) != DDI_SUCCESS) ||
	    (pcn_alloctxring(pcnp) != DDI_SUCCESS)) {
		pcn_error(dip, "unable to allocate DMA resources");
		goto fail;
	}

	pcnp->pcn_promisc = B_FALSE;

	mutex_enter(&pcnp->pcn_intrlock);
	mutex_enter(&pcnp->pcn_xmtlock);
	rc = pcn_initialize(pcnp, B_TRUE);
	mutex_exit(&pcnp->pcn_xmtlock);
	mutex_exit(&pcnp->pcn_intrlock);
	if (rc != DDI_SUCCESS)
		goto fail;

	if (ddi_add_intr(dip, 0, NULL, NULL, pcn_intr, (caddr_t)pcnp) !=
	    DDI_SUCCESS) {
		pcn_error(dip, "unable to add interrupt");
		goto fail;
	}

	pcnp->pcn_flags |= PCN_INTR_ENABLED;

	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
		pcn_error(pcnp->pcn_dip, "mac_alloc failed");
		goto fail;
	}

	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
	macp->m_driver = pcnp;
	macp->m_dip = dip;
	macp->m_src_addr = pcnp->pcn_addr;
	macp->m_callbacks = &pcn_m_callbacks;
	macp->m_min_sdu = 0;
	macp->m_max_sdu = ETHERMTU;
	macp->m_margin = VLAN_TAGSZ;

	if (mac_register(macp, &pcnp->pcn_mh) == DDI_SUCCESS) {
		mac_free(macp);
		return (DDI_SUCCESS);
	}

	mac_free(macp);

	return (DDI_SUCCESS);

fail:
	pcn_teardown(pcnp);
	return (DDI_FAILURE);
}
Example #6
0
static int
pcn_set_chipid(pcn_t *pcnp, uint32_t conf_id)
{
	char *name = NULL;
	uint32_t chipid;

	/*
	 * Note: we can *NOT* put the chip into 32-bit mode yet. If a
	 * lance ethernet device is present and pcn tries to attach, it can
	 * hang the device (requiring a hardware reset), since they only work
	 * in 16-bit mode.
	 *
	 * The solution is check using 16-bit operations first, and determine
	 * if 32-bit mode operations are supported.
	 *
	 * The safest way to do this is to read the PCI subsystem ID from
	 * BCR23/24 and compare that with the value read from PCI config
	 * space.
	 */
	chipid = pcn_bcr_read16(pcnp, PCN_BCR_PCISUBSYSID);
	chipid <<= 16;
	chipid |= pcn_bcr_read16(pcnp, PCN_BCR_PCISUBVENID);

	/*
	 * The test for 0x10001000 is a hack to pacify VMware, who's
	 * pseudo-PCnet interface is broken. Reading the subsystem register
	 * from PCI config space yields 0x00000000 while reading the same value
	 * from I/O space yields 0x10001000. It's not supposed to be that way.
	 */
	if (chipid == conf_id || chipid == 0x10001000) {
		/* We're in 16-bit mode. */
		chipid = pcn_csr_read16(pcnp, PCN_CSR_CHIPID1);
		chipid <<= 16;
		chipid |= pcn_csr_read16(pcnp, PCN_CSR_CHIPID0);
	} else {
		chipid = pcn_csr_read(pcnp, PCN_CSR_CHIPID1);
		chipid <<= 16;
		chipid |= pcn_csr_read(pcnp, PCN_CSR_CHIPID0);
	}

	chipid = CHIPID_PARTID(chipid);

	/* Set default value and override as needed */
	switch (chipid) {
	case Am79C970:
		name = "Am79C970 PCnet-PCI";
		pcn_error(pcnp->pcn_dip, "Unsupported chip: %s", name);
		return (DDI_FAILURE);
	case Am79C970A:
		name = "Am79C970A PCnet-PCI II";
		pcn_error(pcnp->pcn_dip, "Unsupported chip: %s", name);
		return (DDI_FAILURE);
	case Am79C971:
		name = "Am79C971 PCnet-FAST";
		break;
	case Am79C972:
		name = "Am79C972 PCnet-FAST+";
		break;
	case Am79C973:
		name = "Am79C973 PCnet-FAST III";
		break;
	case Am79C975:
		name = "Am79C975 PCnet-FAST III";
		break;
	case Am79C976:
		name = "Am79C976";
		break;
	case Am79C978:
		name = "Am79C978";
		break;
	default:
		name = "Unknown";
		pcn_error(pcnp->pcn_dip, "Unknown chip id 0x%x", chipid);
	}

	if (ddi_prop_update_string(DDI_DEV_T_NONE, pcnp->pcn_dip, "chipid",
	    name) != DDI_SUCCESS) {
		pcn_error(pcnp->pcn_dip, "Unable to set chipid property");
		return (DDI_FAILURE);
	}

	return (DDI_SUCCESS);
}
Example #7
0
/*ARGSUSED*/
static int
ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	dev_info_t *root = ddi_root_node();
	int instance;
	ppb_devstate_t *ppb;
	dev_info_t *pdip;
	ddi_acc_handle_t config_handle;
	char *bus;

	switch (cmd) {
	case DDI_ATTACH:

		/*
		 * Make sure the "device_type" property exists.
		 */
		(void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
		    "device_type", "pci");

		/*
		 * Allocate and get soft state structure.
		 */
		instance = ddi_get_instance(devi);
		if (ddi_soft_state_zalloc(ppb_state, instance) != DDI_SUCCESS)
			return (DDI_FAILURE);
		ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state, instance);
		ppb->dip = devi;
		mutex_init(&ppb->ppb_mutex, NULL, MUTEX_DRIVER, NULL);
		ppb->ppb_soft_state = PCI_SOFT_STATE_CLOSED;
		if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
			mutex_destroy(&ppb->ppb_mutex);
			ddi_soft_state_free(ppb_state, instance);
			return (DDI_FAILURE);
		}
		ppb_pwr_setup(ppb, devi);

		if (PM_CAPABLE(ppb->ppb_pwr_p)) {
			mutex_enter(&ppb->ppb_pwr_p->pwr_mutex);

			/*
			 * Before reading config registers, make sure power is
			 * on, and remains on.
			 */
			ppb->ppb_pwr_p->pwr_fp++;

			pci_pwr_change(ppb->ppb_pwr_p,
			    ppb->ppb_pwr_p->current_lvl,
			    pci_pwr_new_lvl(ppb->ppb_pwr_p));
		}

		ppb->ppb_cache_line_size =
		    pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
		ppb->ppb_latency_timer =
		    pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);

		/*
		 * Check whether the "ranges" property is present.
		 * Otherwise create the ranges property by reading
		 * the configuration registers
		 */
		if (ddi_prop_exists(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
		    "ranges") == 0) {
			ppb_create_ranges_prop(devi, config_handle);
		}

		pci_config_teardown(&config_handle);

		if (PM_CAPABLE(ppb->ppb_pwr_p)) {
			ppb->ppb_pwr_p->pwr_fp--;

			pci_pwr_change(ppb->ppb_pwr_p,
			    ppb->ppb_pwr_p->current_lvl,
			    pci_pwr_new_lvl(ppb->ppb_pwr_p));

			mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
		}

		ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO;
		for (pdip = ddi_get_parent(ppb->dip); pdip && (pdip != root) &&
		    (ppb->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV);
		    pdip = ddi_get_parent(pdip)) {
			if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
			    DDI_PROP_DONTPASS, "device_type", &bus) !=
			    DDI_PROP_SUCCESS)
				break;

			if (strcmp(bus, "pciex") == 0)
				ppb->parent_bus =
				    PCIE_PCIECAP_DEV_TYPE_PCIE_DEV;

			ddi_prop_free(bus);
		}

		/*
		 * Initialize hotplug support on this bus.
		 */
		if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
			if (pcie_init(devi, NULL) != DDI_SUCCESS) {
				(void) ppb_detach(devi, DDI_DETACH);
				return (DDI_FAILURE);
			}
		else
			ppb_init_hotplug(ppb);

		DEBUG1(DBG_ATTACH, devi,
		    "ppb_attach(): this nexus %s hotplug slots\n",
		    ppb->hotplug_capable == B_TRUE ? "has":"has no");

		ppb_fm_init(ppb);
		ddi_report_dev(devi);

		return (DDI_SUCCESS);

	case DDI_RESUME:
		/*
		 * Get the soft state structure for the bridge.
		 */
		ppb = (ppb_devstate_t *)
		    ddi_get_soft_state(ppb_state, ddi_get_instance(devi));

		pci_pwr_resume(devi, ppb->ppb_pwr_p);

		return (DDI_SUCCESS);
	}
	return (DDI_FAILURE);
}
Example #8
0
/*ARGSUSED*/
static int
ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	dev_info_t *root = ddi_root_node();
	int instance;
	ppb_devstate_t *ppb;
	dev_info_t *pdip;
	ddi_acc_handle_t config_handle;
	char *bus;
	int ret;

	switch (cmd) {
	case DDI_ATTACH:

		/*
		 * Make sure the "device_type" property exists.
		 */
		(void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
		    "device_type", "pci");

		/*
		 * Allocate and get soft state structure.
		 */
		instance = ddi_get_instance(devi);
		if (ddi_soft_state_zalloc(ppb_state, instance) != DDI_SUCCESS)
			return (DDI_FAILURE);
		ppb = ddi_get_soft_state(ppb_state, instance);
		ppb->dip = devi;

		/*
		 * don't enable ereports if immediate child of npe
		 */
		if (strcmp(ddi_driver_name(ddi_get_parent(devi)), "npe") == 0)
			ppb->ppb_fmcap = DDI_FM_ERRCB_CAPABLE |
			    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
		else
			ppb->ppb_fmcap = DDI_FM_EREPORT_CAPABLE |
			    DDI_FM_ERRCB_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
			    DDI_FM_DMACHK_CAPABLE;

		ddi_fm_init(devi, &ppb->ppb_fmcap, &ppb->ppb_fm_ibc);
		mutex_init(&ppb->ppb_mutex, NULL, MUTEX_DRIVER, NULL);
		mutex_init(&ppb->ppb_err_mutex, NULL, MUTEX_DRIVER,
		    (void *)ppb->ppb_fm_ibc);
		mutex_init(&ppb->ppb_peek_poke_mutex, NULL, MUTEX_DRIVER,
		    (void *)ppb->ppb_fm_ibc);

		if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
		    DDI_FM_EREPORT_CAPABLE))
			pci_ereport_setup(devi);
		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
			ddi_fm_handler_register(devi, ppb_fm_callback, NULL);

		if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
			if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
				ddi_fm_handler_unregister(devi);
			if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
			    DDI_FM_EREPORT_CAPABLE))
				pci_ereport_teardown(devi);
			ddi_fm_fini(devi);
			ddi_soft_state_free(ppb_state, instance);
			return (DDI_FAILURE);
		}

		ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO;
		for (pdip = ddi_get_parent(devi); pdip && (pdip != root) &&
		    (ppb->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV);
		    pdip = ddi_get_parent(pdip)) {
			if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
			    DDI_PROP_DONTPASS, "device_type", &bus) !=
			    DDI_PROP_SUCCESS)
				break;

			if (strcmp(bus, "pciex") == 0)
				ppb->parent_bus =
				    PCIE_PCIECAP_DEV_TYPE_PCIE_DEV;

			ddi_prop_free(bus);
		}

		if (ppb_support_ht_msimap == 1)
			(void) ppb_ht_msimap_set(config_handle,
			    HT_MSIMAP_ENABLE);
		else if (ppb_support_ht_msimap == -1)
			(void) ppb_ht_msimap_set(config_handle,
			    HT_MSIMAP_DISABLE);

		pci_config_teardown(&config_handle);

		/*
		 * Initialize hotplug support on this bus.
		 */
		if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
			ret = pcie_init(devi, NULL);
		else
			ret = pcihp_init(devi);

		if (ret != DDI_SUCCESS) {
			cmn_err(CE_WARN,
			    "pci: Failed to setup hotplug framework");
			(void) ppb_detach(devi, DDI_DETACH);
			return (ret);
		}

		ddi_report_dev(devi);
		return (DDI_SUCCESS);

	case DDI_RESUME:

		/*
		 * Get the soft state structure for the bridge.
		 */
		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
		ppb_restore_config_regs(ppb);
		return (DDI_SUCCESS);

	default:
		break;
	}
	return (DDI_FAILURE);
}
Example #9
0
/*ARGSUSED*/
static int
pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	/*
	 * Use the minor number as constructed by pcihp, as the index value to
	 * ddi_soft_state_zalloc.
	 */
	int instance = ddi_get_instance(devi);
	pci_state_t *pcip = NULL;
	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
		return (DDI_SUCCESS);

	default:
		return (DDI_FAILURE);
	}

	if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", "pci")
	    != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "pci:  'device_type' prop create failed");
	}

	if (ddi_soft_state_zalloc(pci_statep, instance) == DDI_SUCCESS) {
		pcip = ddi_get_soft_state(pci_statep, instance);
	}

	if (pcip == NULL) {
		goto bad_soft_state;
	}

	pcip->pci_dip = devi;
	pcip->pci_soft_state = PCI_SOFT_STATE_CLOSED;

	/*
	 * Initialize hotplug support on this bus. At minimum
	 * (for non hotplug bus) this would create ":devctl" minor
	 * node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls
	 * to this bus.
	 */
	if (pcihp_init(devi) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "pci: Failed to setup hotplug framework");
		goto bad_pcihp_init;
	}

	/* Second arg: initialize for pci, not pci_express */
	if (pcitool_init(devi, B_FALSE) != DDI_SUCCESS) {
		goto bad_pcitool_init;
	}

	pcip->pci_fmcap = DDI_FM_ERRCB_CAPABLE |
	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
	ddi_fm_init(devi, &pcip->pci_fmcap, &pcip->pci_fm_ibc);
	mutex_init(&pcip->pci_mutex, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&pcip->pci_err_mutex, NULL, MUTEX_DRIVER,
	    (void *)pcip->pci_fm_ibc);
	mutex_init(&pcip->pci_peek_poke_mutex, NULL, MUTEX_DRIVER,
	    (void *)pcip->pci_fm_ibc);
	if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) {
		pci_ereport_setup(devi);
		ddi_fm_handler_register(devi, pci_fm_callback, NULL);
	}

	ddi_report_dev(devi);

	return (DDI_SUCCESS);

bad_pcitool_init:
	(void) pcihp_uninit(devi);
bad_pcihp_init:
	ddi_soft_state_free(pci_statep, instance);
bad_soft_state:
	return (DDI_FAILURE);
}
Example #10
0
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);
	}
}
Example #11
0
static int
acpinex_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
	int instance;
	acpinex_softstate_t *softsp;

	switch (cmd) {
	case DDI_ATTACH:
		break;

	case DDI_RESUME:
		return (DDI_SUCCESS);

	default:
		return (DDI_FAILURE);
	}

	/* Get and check instance number. */
	instance = ddi_get_instance(devi);
	if (instance >= ACPINEX_INSTANCE_MAX) {
		cmn_err(CE_WARN, "acpinex: instance number %d is out of range "
		    "in acpinex_attach(), max %d.",
		    instance, ACPINEX_INSTANCE_MAX - 1);
		return (DDI_FAILURE);
	}

	/* Get soft state structure. */
	if (ddi_soft_state_zalloc(acpinex_softstates, instance)
	    != DDI_SUCCESS) {
		cmn_err(CE_WARN, "!acpinex: failed to allocate soft state "
		    "object in acpinex_attach().");
		return (DDI_FAILURE);
	}
	softsp = ddi_get_soft_state(acpinex_softstates, instance);

	/* Initialize soft state structure */
	softsp->ans_dip = devi;
	(void) ddi_pathname(devi, softsp->ans_path);
	if (ACPI_FAILURE(acpica_get_handle(devi, &softsp->ans_hdl))) {
		ACPINEX_DEBUG(CE_WARN,
		    "!acpinex: failed to get ACPI handle for %s.",
		    softsp->ans_path);
		ddi_soft_state_free(acpinex_softstates, instance);
		return (DDI_FAILURE);
	}
	mutex_init(&softsp->ans_lock, NULL, MUTEX_DRIVER, NULL);

	/* Install event handler for child/descendant objects. */
	if (acpinex_event_scan(softsp, B_TRUE) != DDI_SUCCESS) {
		cmn_err(CE_WARN, "!acpinex: failed to install event handler "
		    "for children of %s.", softsp->ans_path);
	}

	/* nothing to suspend/resume here */
	(void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
	    "pm-hardware-state", "no-suspend-resume");
	(void) ddi_prop_update_int(DDI_DEV_T_NONE, devi,
	    DDI_NO_AUTODETACH, 1);

	acpinex_fm_init(softsp);
	ddi_report_dev(devi);

	return (DDI_SUCCESS);
}
Example #12
0
static int
simmstat_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
    struct simmstat_soft_state *softsp;
    int instance;

    switch (cmd) {
    case DDI_ATTACH:
        break;

    case DDI_RESUME:
        return (DDI_SUCCESS);

    default:
        return (DDI_FAILURE);
    }

    instance = ddi_get_instance(devi);

    if (ddi_soft_state_zalloc(simmstatp, instance) != DDI_SUCCESS)
        return (DDI_FAILURE);

    softsp = ddi_get_soft_state(simmstatp, instance);

    /* Set the dip in the soft state */
    softsp->dip = devi;

    /* Get the board number from this nodes parent device. */
    softsp->pdip = ddi_get_parent(softsp->dip);
    if ((softsp->board = (int)ddi_getprop(DDI_DEV_T_ANY, softsp->pdip,
                                          DDI_PROP_DONTPASS, OBP_BOARDNUM, -1)) == -1) {
        cmn_err(CE_WARN, "simmstat%d: unable to retrieve %s property",
                instance, OBP_BOARDNUM);
        goto bad;
    }

    DPRINTF(SIMMSTAT_ATTACH_DEBUG, ("simmstat%d: devi= 0x%p\n, "
                                    " softsp=0x%p\n", instance, (void *)devi, (void *)softsp));

    /* map in the registers for this device. */
    if (ddi_map_regs(softsp->dip, 0,
                     (caddr_t *)&softsp->simmstat_base, 0, 0)) {
        cmn_err(CE_WARN, "simmstat%d: unable to map registers",
                instance);
        goto bad;
    }

    /* nothing to suspend/resume here */
    (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
                                  "pm-hardware-state", "no-suspend-resume");

    /* create the kstats for this device */
    simmstat_add_kstats(softsp);

    ddi_report_dev(devi);

    return (DDI_SUCCESS);

bad:
    ddi_soft_state_free(simmstatp, instance);
    return (DDI_FAILURE);
}