Esempio n. 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);
}
Esempio n. 2
0
static int
acebus_update_props(ebus_devstate_t *ebus_p)
{
	dev_info_t *dip = ebus_p->dip;
	struct ebus_pci_rangespec er[2], *erp;
	pci_regspec_t *pci_rp, *prp;
	int length, rnums, imask[3], i, found = 0;

	/*
	 * If "ranges" property is found, then the device is initialized
	 * by OBP, hence simply return.
	 * Otherwise we create all the properties here.
	 */
	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "ranges", (int **)&erp, (uint_t *)&length) == DDI_PROP_SUCCESS) {
		ddi_prop_free(erp);
		return (DDI_SUCCESS);
	}

	/*
	 * interrupt-map is the only property that comes from a .conf file.
	 * Since it doesn't have the nodeid field set, it must be done here.
	 * Other properties can come from OBP or created here.
	 */
	if (acebus_set_imap(dip) != DDI_SUCCESS) {
		return (DDI_FAILURE);
	}

	/*
	 * Create the "ranges" property.
	 * Ebus has BAR0 and BAR1 allocated (both in memory space).
	 * Other BARs are 0.
	 * Hence there are 2 memory ranges it operates in. (one for each BAR).
	 * ie. there are 2 entries in its ranges property.
	 */
	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
	    DDI_PROP_DONTPASS, "assigned-addresses",
	    (int **)&pci_rp, (uint_t *)&length) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not get assigned-addresses",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		return (DDI_FAILURE);
	}
	/*
	 * Create the 1st mem range in which it operates corresponding
	 * to BAR0
	 */
	er[0].ebus_phys_hi = EBUS_CHILD_PHYS_LOW_RANGE;
	rnums = (length * sizeof (int))/sizeof (pci_regspec_t);
	for (i = 0; i < rnums; i++) {
		prp = pci_rp + i;
		if (PCI_REG_REG_G(prp->pci_phys_hi) == er[0].ebus_phys_hi) {
			found = 1;
			break;
		}
	}
	if (!found) {
		cmn_err(CE_WARN, "No assigned space for memory range 0.");
		ddi_prop_free(pci_rp);
		return (DDI_FAILURE);
	}
	found = 0;
	er[0].ebus_phys_low = 0;
	er[0].pci_phys_hi = prp->pci_phys_hi;
	er[0].pci_phys_mid = prp->pci_phys_mid;
	er[0].pci_phys_low = prp->pci_phys_low;
	er[0].rng_size = prp->pci_size_low;

	/*
	 * Create the 2nd mem range in which it operates corresponding
	 * to BAR1
	 */
	er[1].ebus_phys_hi = EBUS_CHILD_PHYS_HI_RANGE;
	for (i = 0; i < rnums; i++) {
		prp = pci_rp + i;
		if (PCI_REG_REG_G(prp->pci_phys_hi) == er[1].ebus_phys_hi) {
			found = 1;
			break;
		}
	}
	if (!found) {
		cmn_err(CE_WARN, "No assigned space for memory range 1.");
		ddi_prop_free(pci_rp);
		return (DDI_FAILURE);
	}
	er[1].ebus_phys_low = 0;
	er[1].pci_phys_hi = prp->pci_phys_hi;
	er[1].pci_phys_mid = prp->pci_phys_mid;
	er[1].pci_phys_low = prp->pci_phys_low;
	er[1].rng_size = prp->pci_size_low;

	ddi_prop_free(pci_rp);
	length = sizeof (er) / sizeof (int);
	if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
	    "ranges", (int *)er, length) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not create ranges property",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		return (DDI_FAILURE);
	}
	/* The following properties are as defined by PCI 1275 bindings. */
	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
	    "#address-cells", 2) != DDI_PROP_SUCCESS)
			return (DDI_FAILURE);
	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
	    "#size-cells", 1) != DDI_PROP_SUCCESS)
			return (DDI_FAILURE);
	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
	    "#interrupt-cells", 1) != DDI_PROP_SUCCESS)
			return (DDI_FAILURE);

	imask[0] = 0x1f;
	imask[1] = 0x00ffffff;
	imask[2] = 0x00000003;
	length = sizeof (imask) / sizeof (int);
	if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
	    "interrupt-map-mask", (int *)imask, length) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not update imap mask property",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		return (DDI_FAILURE);
	}

	return (DDI_SUCCESS);
}
Esempio n. 3
0
/*
 * This function takes in the ac-interrupt-map property from the .conf file,
 * fills in the 'nodeid' information and then creates the 'interrupt-map'
 * property.
 */
static int
acebus_set_imap(dev_info_t *dip)
{
	int *imapp, *timapp, length, num, i, default_ival = 0;
	dev_info_t *tdip = dip;
	int *port_id, imap_ok = 1;
	int ilength;
	int acebus_default_se_imap[5];

	/*
	 * interrupt-map is specified via .conf file in hotplug mode,
	 * since the child configuration is static.
	 * It could even be hardcoded in the driver.
	 */
	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
	    "ac-interrupt-map", (int **)&imapp, (uint_t *)&ilength) !=
	    DDI_PROP_SUCCESS) {
		/* assume default implementation */
		acebus_default_se_imap[0] = 0x14;
		acebus_default_se_imap[1] = 0x400000;
		acebus_default_se_imap[2] = 1;
		acebus_default_se_imap[3] = 0;
		acebus_default_se_imap[4] = 2;
		imapp = acebus_default_se_imap;
		ilength = 5;
		default_ival = 1;
	}
	num = ilength / 5;	/* there are 5 integer cells in our property */
	timapp = imapp;
	for (i = 0; i < num; i++) {
		if (*(timapp+i*5+3) == 0)
			imap_ok = 0;
	}
	if (imap_ok) {
		if (!default_ival)
			ddi_prop_free(imapp);
		return (DDI_SUCCESS);
	}

	while (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, tdip,
	    DDI_PROP_DONTPASS, "upa-portid", (int **)&port_id,
	    (uint_t *)&length) != DDI_PROP_SUCCESS) {
		tdip = ddi_get_parent(tdip);
		if (tdip == NULL) {
			cmn_err(CE_WARN, "%s%d: Could not get imap parent",
			    ddi_driver_name(dip), ddi_get_instance(dip));
			if (!default_ival)
				ddi_prop_free(imapp);
			return (DDI_FAILURE);
		}
	}
	timapp = imapp;
	for (i = 0; i < num; i++) {
		*(timapp+i*5+3) = ddi_get_nodeid(tdip);
	}

	if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
	    "interrupt-map", imapp, ilength) != DDI_PROP_SUCCESS) {
		cmn_err(CE_WARN, "%s%d: Could not update AC imap property",
		    ddi_driver_name(dip), ddi_get_instance(dip));
		if (!default_ival)
			ddi_prop_free(imapp);
		return (DDI_FAILURE);
	}
	if (!default_ival)
		ddi_prop_free(imapp);
	return (DDI_SUCCESS);
}