Exemple #1
0
/*
 * The first round search is to find:
 * 1) a VGA device.
 * 2) a PCI VGA compatible device whose IO space is enabled
 *    and the VGA Enable bit of any PCI-PCI bridge above it is set.
 * If the first round search succeeds, prune the second round search.
 *
 * The second round seach does not check the VGA Enable bit.
 *
 * Return the device path as the console fb path.
 */
char *
plat_fbpath(void)
{
	struct find_fb_dev_param param;
	static char *fbpath = NULL;
	static char fbpath_buf[MAXPATHLEN];

	/* first round search */
	param.found_dip = NULL;
	param.vga_enable = 1;
	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);

	if (param.found_dip != NULL) {
		(void) ddi_pathname(param.found_dip, fbpath_buf);
		fbpath = fbpath_buf;
		return (fbpath);
	}

	/*
	 * second round search, do not check the
	 * PCI_BCNF_BCNTRL_VGA_ENABLE bit
	 */
	param.found_dip = NULL;
	param.vga_enable = 0;
	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);

	if (param.found_dip == NULL)
		return (NULL);

	(void) ddi_pathname(param.found_dip, fbpath_buf);
	fbpath = fbpath_buf;
	return (fbpath);
}
/*
 * Recursive ascent
 *
 * This now only does half the job.  It finds the node, then the caller
 * has to search the node for the binding name
 */
static in_node_t *
in_devwalk(dev_info_t *dip, in_node_t **ap, char *addr)
{
	in_node_t *np;
	char *name;

	ASSERT(dip);
	ASSERT(e_ddi_inst_state.ins_busy);
	if (dip == ddi_root_node()) {
		*ap = NULL;
		return (e_ddi_inst_state.ins_root);
	}
	/*
	 * call up to find parent, then look through the list of kids
	 * for a match
	 */
	np = in_devwalk(ddi_get_parent(dip), ap, NULL);
	if (np == NULL)
		return (np);
	*ap = np;
	np = np->in_child;
	name = ddi_node_name(dip);
	if (addr == NULL)
		addr = ddi_get_name_addr(dip);

	while (np) {
		if (in_eqstr(np->in_node_name, name) &&
		    in_eqstr(np->in_unit_addr, addr)) {
			return (np);
		}
		np = np->in_sibling;
	}
	return (np);
}
/*
 * Routine used to setup a newly inserted CPU in preparation for starting
 * it running code.
 */
int
mp_cpu_configure(int cpuid)
{
    extern void fill_cpu_ddi(dev_info_t *);
    extern int setup_cpu_common(int);
    struct mp_find_cpu_arg target;

    ASSERT(MUTEX_HELD(&cpu_lock));

    target.dip = NULL;
    target.cpuid = cpuid;
    ddi_walk_devs(ddi_root_node(), mp_find_cpu, &target);

    if (target.dip == NULL)
        return (ENODEV);

    /*
     * Note:  uses cpu_lock to protect cpunodes and ncpunodes
     * which will be modified inside of fill_cpu_ddi().
     */
    fill_cpu_ddi(target.dip);

    /*
     * sun4v cpu setup may fail. sun4u assumes cpu setup to
     * be always successful, so the return value is ignored.
     */
    (void) setup_cpu_common(cpuid);

    return (0);
}
int
gfxp_pci_device_present(uint16_t vendor, uint16_t device)
{
	gfxp_pci_bsf_t	*pci_bsf;
	int		rv;

	/*
	 * Find a PCI device based on its device and vendor id.
	 */

	if ((pci_bsf = kmem_zalloc(sizeof (gfxp_pci_bsf_t), KM_SLEEP)) == NULL)
	    return (0);

	pci_bsf->vendor = vendor;
	pci_bsf->device = device;
	ddi_walk_devs(ddi_root_node(), gfxp_pci_find_vd, pci_bsf);

	if (pci_bsf->found) {
		rv = 1;
	} else {
		rv = 0;
	}

	kmem_free(pci_bsf, sizeof (gfxp_pci_bsf_t));

	return (rv);
}
Exemple #5
0
int
_init(void)
{
	int	err;
	char tty_irq_param[9] = "ttyX-irq";
	char *tty_irq;
	int i;

	if ((err = mod_install(&modlinkage)) != 0)
		return (err);

	/* Check if any tty irqs are overridden by eeprom config */
	for (i = 0; i < num_BIOS_serial; i++) {
		tty_irq_param[3] = 'a' + i;
		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
		    DDI_PROP_DONTPASS, tty_irq_param, &tty_irq)
		    == DDI_PROP_SUCCESS) {
			long data;

			if (ddi_strtol(tty_irq, NULL, 0, &data) == 0) {
				asy_intrs[i] = (int)data;
				asy_intr_override |= 1<<i;
			}

			ddi_prop_free(tty_irq);
		}
	}

	impl_bus_add_probe(isa_enumerate);
	return (0);
}
Exemple #6
0
/*
 * vdds_create_new_node -- A common function to create NIU nexus/NIU node.
 */
static dev_info_t *
vdds_create_new_node(vdds_cb_arg_t *cbap, dev_info_t *pdip,
    int (*new_node_func)(dev_info_t *dip, void *arg, uint_t flags))
{
	devi_branch_t br;
	int rv;

	DBG1(NULL, "Called cookie=0x%lx", cbap->cookie);

	br.arg = (void *)cbap;
	br.type = DEVI_BRANCH_SID;
	br.create.sid_branch_create = new_node_func;
	br.devi_branch_callback = NULL;

	if (pdip == NULL) {
		pdip = ddi_root_node();
	}
	DBG1(NULL, "calling e_ddi_branch_create");
	if ((rv = e_ddi_branch_create(pdip, &br, NULL,
	    DEVI_BRANCH_CHILD | DEVI_BRANCH_CONFIGURE))) {
		DERR(NULL, "e_ddi_branch_create failed=%d", rv);
		return (NULL);
	}
	DBG1(NULL, "Returning(dip=0x%p", cbap->dip);
	return (cbap->dip);
}
int
uadmin(int cmd, int fcn, uintptr_t mdep)
{
	int error = 0, rv = 0;
	size_t nbytes = 0;
	cred_t *credp = CRED();
	char *bootargs = NULL;
	int reset_status = 0;

	if (cmd == A_SHUTDOWN && fcn == AD_FASTREBOOT_DRYRUN) {
		ddi_walk_devs(ddi_root_node(), check_driver_quiesce,
		    &reset_status);
		if (reset_status != 0)
			return (EIO);
		else
			return (0);
	}

	/*
	 * The swapctl system call doesn't have its own entry point: it uses
	 * uadmin as a wrapper so we just call it directly from here.
	 */
	if (cmd == A_SWAPCTL) {
		if (get_udatamodel() == DATAMODEL_NATIVE)
			error = swapctl(fcn, (void *)mdep, &rv);
#if defined(_SYSCALL32_IMPL)
		else
			error = swapctl32(fcn, (void *)mdep, &rv);
#endif /* _SYSCALL32_IMPL */
		return (error ? set_errno(error) : rv);
	}

	/*
	 * Certain subcommands intepret a non-NULL mdep value as a pointer to
	 * a boot string.  We pull that in as bootargs, if applicable.
	 */
	if (mdep != NULL &&
	    (cmd == A_SHUTDOWN || cmd == A_REBOOT || cmd == A_DUMP ||
	    cmd == A_FREEZE || cmd == A_CONFIG)) {
		bootargs = kmem_zalloc(BOOTARGS_MAX, KM_SLEEP);
		if ((error = copyinstr((const char *)mdep, bootargs,
		    BOOTARGS_MAX, &nbytes)) != 0) {
			kmem_free(bootargs, BOOTARGS_MAX);
			return (set_errno(error));
		}
	}

	/*
	 * Invoke the appropriate kadmin() routine.
	 */
	if (getzoneid() != GLOBAL_ZONEID)
		error = zone_kadmin(cmd, fcn, bootargs, credp);
	else
		error = kadmin(cmd, fcn, bootargs, credp);

	if (bootargs != NULL)
		kmem_free(bootargs, BOOTARGS_MAX);
	return (error ? set_errno(error) : 0);
}
Exemple #8
0
/*
 * sets master_ops_debug flag from propertyu passed by the boot
 */
static void
set_master_ops_debug_flags()
{
	char *prop;
	long flags;

	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
	    DDI_PROP_DONTPASS, "master_ops_debug", &prop) == DDI_PROP_SUCCESS) {
		long data;
		if (ddi_strtol(prop, NULL, 0, &data) == 0) {
			master_ops_debug = (unsigned long)data;
			e_ddi_prop_remove(DDI_DEV_T_NONE, ddi_root_node(),
			    "master_ops_debug");
			e_ddi_prop_update_int(DDI_DEV_T_NONE, ddi_root_node(),
			    "master_ops_debug", data);
		}
		ddi_prop_free(prop);
	}
}
void
xen_resume_devices(void)
{
	int rc;

	SUSPEND_DEBUG("xen_resume_devices\n");

	if ((rc = cpr_resume_devices(ddi_root_node(), 0)) != 0)
		panic("failed to resume devices: %d", rc);
}
Exemple #10
0
char *
spa_get_bootprop(char *propname)
{
	char *value;

	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
	    DDI_PROP_DONTPASS, propname, &value) != DDI_SUCCESS)
		return (NULL);
	return (value);
}
void
xen_suspend_devices(void)
{
	int rc;

	SUSPEND_DEBUG("xen_suspend_devices\n");

	if ((rc = cpr_suspend_devices(ddi_root_node())) != 0)
		panic("failed to suspend devices: %d", rc);
}
Exemple #12
0
int
_init(void)
{
    int err = 0;

    /*
     * Create a resource map for the contigous memory allocated
     * at start-of-day in startup.c
     */
    if (ndi_ra_map_setup(ddi_root_node(), "gptwo-contigousmem")
            == NDI_FAILURE) {
        GPTWO_DEBUG0(1, CE_WARN,
                     "Can not setup resource map - gptwo-contigousmem\n");
        return (1);
    }

    /*
     * Put the allocated memory into the pool.
     */
    (void) ndi_ra_free(ddi_root_node(), (uint64_t)efcode_vaddr,
                       (uint64_t)efcode_size, "gptwo-contigousmem", 0);

    /* register devices with the configurator */
    gptwocfg_register_ops(SAFPTYPE_sPCI, gptwo_configure_pci,
                          gptwo_unconfigure_pci);
    gptwocfg_register_ops(SAFPTYPE_cPCI, gptwo_configure_pci,
                          gptwo_unconfigure_pci);
    gptwocfg_register_ops(SAFPTYPE_PCIX, gptwo_configure_pci,
                          gptwo_unconfigure_pci);

    if ((err = mod_install(&modlinkage)) != 0) {
        GPTWO_DEBUG1(1, CE_WARN, "gptwo_pci (PCI Functions) "
                     "failed to load, error=%d\n", err);
        gptwocfg_unregister_ops(SAFPTYPE_sPCI);
        gptwocfg_unregister_ops(SAFPTYPE_cPCI);
        gptwocfg_unregister_ops(SAFPTYPE_PCIX);
    } else {
        GPTWO_DEBUG0(1, CE_WARN, "gptwo_pci (PCI Functions) "
                     "has been loaded.\n");
    }
    return (err);
}
/*
 * Before suspending devices first mark all device nodes busy. This
 * avoids a deadlock situation when another thread holds a device busy
 * and accesses an already suspended device.
 */
static int
sbdp_suspend_devices(dev_info_t *dip, sbdp_sr_handle_t *srh)
{
	int	rv;

	/* assumes dip is ddi_root_node so no ndi_devi_enter required */
	ASSERT(dip == ddi_root_node());
	ddi_walk_devs(dip, sbdp_suspend_devices_enter, NULL);
	rv = sbdp_suspend_devices_(dip, srh);
	ddi_walk_devs(dip, sbdp_suspend_devices_exit, NULL);
	return (rv);
}
int
is_pseudo_device(dev_info_t *dip)
{
	dev_info_t	*pdip;

	for (pdip = ddi_get_parent(dip); pdip && pdip != ddi_root_node();
	    pdip = ddi_get_parent(pdip)) {
		if (strcmp(ddi_get_name(pdip), DEVI_PSEUDO_NEXNAME) == 0)
			return (1);
	}
	return (0);
}
Exemple #15
0
void
reset(void)
{
	extern	void acpi_reset_system();
#if !defined(__xpv)
	ushort_t *bios_memchk;

	/*
	 * Can't use psm_map_phys or acpi_reset_system before the hat is
	 * initialized.
	 */
	if (khat_running) {
		bios_memchk = (ushort_t *)psm_map_phys(0x472,
		    sizeof (ushort_t), PROT_READ | PROT_WRITE);
		if (bios_memchk)
			*bios_memchk = 0x1234;	/* bios memory check disable */

		if (options_dip != NULL &&
		    ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), 0,
		    "efi-systab")) {
			if (bootops == NULL)
				acpi_reset_system();
			efi_reset();
		}

		/*
		 * The problem with using stubs is that we can call
		 * acpi_reset_system only after the kernel is up and running.
		 *
		 * We should create a global state to keep track of how far
		 * up the kernel is but for the time being we will depend on
		 * bootops. bootops cleared in startup_end().
		 */
		if (bootops == NULL)
			acpi_reset_system();
	}

	pc_reset();
#else
	if (IN_XPV_PANIC()) {
		if (khat_running && bootops == NULL) {
			acpi_reset_system();
		}

		pc_reset();
	}

	(void) HYPERVISOR_shutdown(SHUTDOWN_reboot);
	panic("HYPERVISOR_shutdown() failed");
#endif
	/*NOTREACHED*/
}
void
gp2_fc_ops_free_handle(fco_handle_t rp)
{
	struct fc_resource *ip, *np;

	ASSERT(rp);

	if (rp->next_handle)
		fc_ops_free_handle(rp->next_handle);
	if (rp->unit_address)
		kmem_free(rp->unit_address, strlen(rp->unit_address) + 1);
	if (rp->my_args != NULL)
		kmem_free(rp->my_args, strlen(rp->my_args) + 1);

	/*
	 * Release all the resources from the resource list
	 */
	for (ip = rp->head; ip != NULL; ip = np) {
		np = ip->next;
		switch (ip->type) {
		case RT_MAP:
			FC_DEBUG1(1, CE_CONT, "gp2_fc_ops_free: "
			    " map handle - %p\n", ip->fc_map_handle);
			break;
		case RT_DMA:
			/* DMA has to be freed up at exit time */
			cmn_err(CE_CONT, "gfc_fc_ops_free: DMA seen!\n");
			break;
		case RT_CONTIGIOUS:
			FC_DEBUG2(1, CE_CONT, "gp2_fc_ops_free: "
			    "Free claim-memory resource 0x%lx size 0x%x\n",
			    ip->fc_contig_virt, ip->fc_contig_len);

			(void) ndi_ra_free(ddi_root_node(),
			    (uint64_t)ip->fc_contig_virt,
			    ip->fc_contig_len, "gptwo-contigousmem",
			    NDI_RA_PASS);

			break;
		default:
			cmn_err(CE_CONT, "gp2_fc_ops_free: "
			    "unknown resource type %d\n", ip->type);
			break;
		}
		fc_rem_resource(rp, ip);
		kmem_free(ip, sizeof (struct fc_resource));
	}
	kmem_free(rp, sizeof (struct fc_resource_list));
}
/*
 * gfc_release_memory
 *
 * release-memory ( size vaddr -- )
 */
static int
gfc_release_memory(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp)
{
	int32_t vaddr, size;
	struct fc_resource *ip;

	if (fc_cell2int(cp->nargs) != 2)
		return (fc_syntax_error(cp, "nargs must be 2"));

	if (fc_cell2int(cp->nresults) != 0)
		return (fc_syntax_error(cp, "nresults must be 0"));

	vaddr = fc_cell2int(fc_arg(cp, 1));
	size = fc_cell2int(fc_arg(cp, 0));

	FC_DEBUG2(1, CE_CONT, "gfc_release_memory: vaddr=0x%x size=0x%x\n",
	    vaddr, size);
	/*
	 * Find if this request matches a mapping resource we set up.
	 */
	fc_lock_resource_list(rp);
	for (ip = rp->head; ip != NULL; ip = ip->next) {
		if (ip->type != RT_CONTIGIOUS)
			continue;
		if (ip->fc_contig_virt != (void *)(uintptr_t)vaddr)
			continue;
		if (ip->fc_contig_len == size)
			break;
	}
	fc_unlock_resource_list(rp);

	if (ip == NULL)
		return (fc_priv_error(cp, "request doesn't match a "
		    "known mapping"));

	(void) ndi_ra_free(ddi_root_node(), vaddr, size,
	    "gptwo-contigousmem", NDI_RA_PASS);

	/*
	 * remove the resource from the list and release it.
	 */
	fc_rem_resource(rp, ip);
	kmem_free(ip, sizeof (struct fc_resource));

	cp->nresults = fc_int2cell(0);

	return (fc_success_op(ap, rp, cp));
}
Exemple #18
0
void
startup_bios_disk()
{
	uchar_t drivenum;
	int got_devparams = 0;
	int got_first_block = 0;
	uchar_t	name[20];
	dev_info_t	*devi;
	int extensions;

	if (dobiosdev == 0)
		return;

	for (drivenum = 0x80; drivenum < (0x80 + BIOSDEV_NUM); drivenum++) {

		if (!drive_present(drivenum))
			continue;

		extensions = bios_check_extension_present(drivenum);

		/*
		 * If we're booting from an Eltorito CD/DVD image, there's
		 * no need to get the device parameters or read the first block
		 * because we'll never install onto this device.
		 */
		if (extensions && is_eltorito(drivenum))
			continue;

		if (extensions && get_dev_params(drivenum))
			got_devparams = 1;
		else
			got_devparams = 0;

		if ((got_first_block = read_firstblock(drivenum)) == 0) {
			/* retry */
			got_first_block = read_firstblock(drivenum);
		}

		if (got_devparams || got_first_block) {
			(void) sprintf((char *)name, "biosdev-0x%x", drivenum);
			devi = ddi_root_node();
			(void) e_ddi_prop_update_byte_array(DDI_DEV_T_NONE,
			    devi, (char *)name,
			    (uchar_t *)&biosdev_info[drivenum - 0x80],
			    sizeof (biosdev_data_t));
		}
	}
}
Exemple #19
0
static void
create_devinfo_tree(void)
{
	major_t major;
	pnode_t nodeid;

	i_ddi_node_cache_init();
#if defined(__sparc)
	nodeid = prom_nextnode(0);
#else /* x86 */
	nodeid = DEVI_SID_NODEID;
#endif
	top_devinfo = i_ddi_alloc_node(NULL, rootname,
	    nodeid, -1, NULL, KM_SLEEP);
	ndi_hold_devi(top_devinfo);	/* never release the root */

	i_ddi_add_devimap(top_devinfo);

	/*
	 * Bind root node.
	 * This code is special because root node has no parent
	 */
	major = ddi_name_to_major("rootnex");
	ASSERT(major != DDI_MAJOR_T_NONE);
	DEVI(top_devinfo)->devi_major = major;
	devnamesp[major].dn_head = top_devinfo;
	i_ddi_set_binding_name(top_devinfo, rootname);
	i_ddi_set_node_state(top_devinfo, DS_BOUND);

	/*
	 * Record that devinfos have been made for "rootnex."
	 * di_dfs() is used to read the prom because it doesn't get the
	 * next sibling until the function returns, unlike ddi_walk_devs().
	 */
	di_dfs(ddi_root_node(), get_neighbors, 0);

#if !defined(__sparc)
	/*
	 * On x86, there is no prom. Create device tree by
	 * probing pci config space
	 */
	{
		extern void impl_setup_ddi(void);
		impl_setup_ddi();
	}
#endif /* x86 */
}
Exemple #20
0
/*
 * Call parent busop fm clean-up routine.
 *
 * Called during driver detach(1M)
 */
void
i_ndi_busop_fm_fini(dev_info_t *dip)
{
	dev_info_t *pdip = (dev_info_t *)DEVI(dip)->devi_parent;

	if (dip == ddi_root_node())
		return;

	/* Valid operation for BUSO_REV_6 and above */
	if (DEVI(pdip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_6)
		return;

	if (DEVI(pdip)->devi_ops->devo_bus_ops->bus_fm_fini == NULL)
		return;

	(*DEVI(pdip)->devi_ops->devo_bus_ops->bus_fm_fini)(pdip, dip);
}
/*
 * Look first for an ACPI PCI bus node matching busid, then for a _PRT on the
 * parent node; then drop into the bridge-chasing code (which will also
 * look for _PRTs on the way up the tree of bridges)
 *
 * Stores polarity and sensitivity in the structure pointed to by
 * intr_flagp, and irqno in the value pointed to by pci_irqp.  *
 * Returns:
 *  	ACPI_PSM_SUCCESS on success.
 *	ACPI_PSM_PARTIAL to indicate need to configure the interrupt
 *	link device.
 * 	ACPI_PSM_FAILURE  if an error prevented the system from
 *	obtaining irq information for dip.
 */
int
acpi_translate_pci_irq(dev_info_t *dip, int ipin, int *pci_irqp,
    iflag_t *intr_flagp, acpi_psm_lnk_t *acpipsmlnkp)
{
	ACPI_HANDLE pciobj;
	int status = AE_ERROR;
	dev_info_t *curdip, *parentdip;
	int curpin, curbus, curdev;


	curpin = ipin;
	curdip = dip;
	while (curdip != ddi_root_node()) {
		parentdip = ddi_get_parent(curdip);
		ASSERT(parentdip != NULL);

		if (get_bdf(curdip, &curbus, &curdev, NULL) != 0)
			break;

		status = acpica_get_handle(parentdip, &pciobj);
		if ((status == AE_OK) && psm_node_has_prt(pciobj)) {
			return (acpi_get_gsiv(curdip, pciobj, curdev, curpin,
			    pci_irqp, intr_flagp, acpipsmlnkp));
		}

		/* if we got here, we need to traverse a bridge upwards */
		if (!psm_is_pci_bridge(parentdip))
			break;

		/*
		 * This is the rotating scheme that Compaq is using
		 * and documented in the PCI-PCI spec.  Also, if the
		 * PCI-PCI bridge is behind another PCI-PCI bridge,
		 * then it needs to keep ascending until an interrupt
		 * entry is found or the top is reached
		 */
		curpin = (curdev + curpin) % PCI_INTD;
		curdip = parentdip;
	}

	/*
	 * We should never, ever get here; didn't find a _PRT
	 */
	return (ACPI_PSM_FAILURE);
}
Exemple #22
0
ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer()
{
	ACPI_PHYSICAL_ADDRESS Address;

	/*
	 * For EFI firmware, the root pointer is defined in EFI systab.
	 * The boot code process the table and put the physical address
	 * in the acpi-root-tab property.
	 */
	Address = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(),
	    DDI_PROP_DONTPASS, "acpi-root-tab", NULL);

	if ((Address == NULL) && ACPI_FAILURE(AcpiFindRootPointer(&Address)))
		Address = NULL;

	return (Address);
}
void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */
	int			simba_present = 0;
	dev_info_t		*root_child_node;


	/*
	 * Install Isa driver. This is required for the southbridge IDE
	 * workaround - to reset the IDE channel during IDE bus reset.
	 * Panic the system in case ISA driver could not be loaded or
	 * any problem in accessing its pci config space. Since the register
	 * to reset the channel for IDE is in ISA config space!.
	 */
	root_child_node = ddi_get_child(ddi_root_node());

	while (root_child_node != NULL) {
		if (strcmp(ddi_node_name(root_child_node), "pci") == 0) {
			root_child_node = ddi_get_child(root_child_node);
			if (strcmp(ddi_node_name(root_child_node), "pci") == 0)
				simba_present = 1;
			break;
		}
		root_child_node = ddi_get_next_sibling(root_child_node);
	}


	if (simba_present)
	    dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME_WITH_SIMBA, 0);
	else
	    dip = e_ddi_hold_devi_by_path(PLATFORM_ISA_PATHNAME, 0);

	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &platform_isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
Exemple #24
0
/*
 * Return success if discovery was attempted, to indicate
 * that the desired device may now be available.
 */
int
e_ddi_devid_discovery(ddi_devid_t devid)
{
	int flags;
	int rval = DDI_SUCCESS;

	mutex_enter(&devid_discovery_mutex);

	if (devid_discovery_busy) {
		DEVID_LOG_DISC((CE_CONT, "devid_discovery: busy\n"));
		while (devid_discovery_busy) {
			cv_wait(&devid_discovery_cv, &devid_discovery_mutex);
		}
	} else if (e_devid_do_discovery()) {
		devid_discovery_busy = 1;
		mutex_exit(&devid_discovery_mutex);

		if (i_ddi_io_initialized() == 0) {
			e_ddi_devid_hold_installed_driver(devid);
		} else {
			DEVID_LOG_DISC((CE_CONT,
			    "devid_discovery: ndi_devi_config\n"));
			flags = NDI_DEVI_PERSIST | NDI_CONFIG | NDI_NO_EVENT;
			if (i_ddi_io_initialized())
				flags |= NDI_DRV_CONF_REPROBE;
			(void) ndi_devi_config(ddi_root_node(), flags);
		}

		mutex_enter(&devid_discovery_mutex);
		devid_discovery_busy = 0;
		cv_broadcast(&devid_discovery_cv);
		if (devid_discovery_secs > 0)
			devid_last_discovery = ddi_get_lbolt();
		DEVID_LOG_DISC((CE_CONT, "devid_discovery: done\n"));
	} else {
		rval = DDI_FAILURE;
		DEVID_LOG_DISC((CE_CONT, "no devid discovery\n"));
	}

	mutex_exit(&devid_discovery_mutex);

	return (rval);
}
Exemple #25
0
/*
 * This function is invoked twice, first time with reprogram=0 to set up
 * the xpvd portion of the device tree. The second time it is ignored.
 */
static void
xpv_enumerate(int reprogram)
{
	dev_info_t *dip;

	if (reprogram != 0)
		return;

	ndi_devi_alloc_sleep(ddi_root_node(), "xpvd",
	    (pnode_t)DEVI_SID_NODEID, &dip);

	(void) ndi_devi_bind_driver(dip, 0);

	/*
	 * Too early to enumerate split device drivers in domU
	 * since we need to create taskq thread during enumeration.
	 * So, we only enumerate softdevs and console here.
	 */
	xendev_enum_all(dip, B_TRUE);
}
Exemple #26
0
/*
 * Call parent busop fm initialization routine.
 *
 * Called during driver attach(1M)
 */
int
i_ndi_busop_fm_init(dev_info_t *dip, int tcap, ddi_iblock_cookie_t *ibc)
{
	int pcap;
	dev_info_t *pdip = (dev_info_t *)DEVI(dip)->devi_parent;

	if (dip == ddi_root_node())
		return (ddi_system_fmcap | DDI_FM_EREPORT_CAPABLE);

	/* Valid operation for BUSO_REV_6 and above */
	if (DEVI(pdip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_6)
		return (DDI_FM_NOT_CAPABLE);

	if (DEVI(pdip)->devi_ops->devo_bus_ops->bus_fm_init == NULL)
		return (DDI_FM_NOT_CAPABLE);

	pcap = (*DEVI(pdip)->devi_ops->devo_bus_ops->bus_fm_init)
	    (pdip, dip, tcap, ibc);

	return (pcap);
}
Exemple #27
0
/*
 * vdds_match_niu_nexus -- callback function to verify a node is the
 *	NIU nexus node.
 */
static int
vdds_match_niu_nexus(dev_info_t *dip, void *arg)
{
	vdds_cb_arg_t	*warg = (vdds_cb_arg_t *)arg;
	vdds_reg_t	*reg_p;
	char		*name;
	uint64_t	hdl;
	uint_t		reglen;
	int		rv;

	if (dip == ddi_root_node()) {
		return (DDI_WALK_CONTINUE);
	}

	name = ddi_node_name(dip);
	if (strcmp(name, "niu")  != 0) {
		return (DDI_WALK_CONTINUE);
	}
	rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
	    DDI_PROP_DONTPASS, "reg", (int **)&reg_p, &reglen);
	if (rv != DDI_PROP_SUCCESS) {
		DWARN(NULL, "Failed to get reg property dip=0x%p", dip);
		return (DDI_WALK_CONTINUE);
	}

	hdl =  reg_p->addr_hi & 0x0FFFFFFF;
	ddi_prop_free(reg_p);

	DBG2(NULL, "Handle = 0x%lx dip=0x%p", hdl, dip);
	if (hdl == NIUCFGHDL(warg->cookie)) {
		/* Hold before returning */
		if (!e_ddi_branch_held(dip))
			e_ddi_branch_hold(dip);
		warg->dip = dip;
		DBG2(NULL, "Found dip = 0x%p", dip);
		return (DDI_WALK_TERMINATE);
	}
	return (DDI_WALK_CONTINUE);
}
gfxp_acc_handle_t
gfxp_pci_init_handle(uint8_t bus, uint8_t slot, uint8_t function,
	uint16_t *vendor, uint16_t *device)
{
	dev_info_t	*dip;
	gfxp_pci_bsf_t	*pci_bsf;

	/*
	 * Find a PCI device based on its address, and return a unique handle
	 * to be used in subsequent calls to read from or write to the config
	 * space of this device.
	 */

	if ((pci_bsf = kmem_zalloc(sizeof (gfxp_pci_bsf_t), KM_SLEEP))
			== NULL) {
		return (NULL);
	}

	pci_bsf->bus = bus;
	pci_bsf->slot = slot;
	pci_bsf->function = function;

	ddi_walk_devs(ddi_root_node(), gfxp_pci_find_bsf, pci_bsf);

	if (pci_bsf->found) {
		dip = pci_bsf->dip;

		if (vendor) *vendor = pci_bsf->vendor;
		if (device) *device = pci_bsf->device;
	} else {
		dip = NULL;
		if (vendor) *vendor = 0x0000;
		if (device) *device = 0x0000;
	}

	kmem_free(pci_bsf, sizeof (gfxp_pci_bsf_t));

	return ((gfxp_acc_handle_t)dip);
}
Exemple #29
0
/*
 * Get boot property value for fastreboot_onpanic.
 *
 * NOTE: If fastreboot_onpanic is set to non-zero in /etc/system,
 * new setting passed in via "-B fastreboot_onpanic" is ignored.
 * This order of precedence is to enable developers debugging panics
 * that occur early in boot to utilize Fast Reboot on panic.
 */
static void
fastboot_get_bootprop(void)
{
	int		val = 0xaa, len, ret;
	dev_info_t	*devi;
	char		*propstr = NULL;

	devi = ddi_root_node();

	ret = ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
	    FASTREBOOT_ONPANIC, &propstr);

	if (ret == DDI_PROP_SUCCESS) {
		if (FASTREBOOT_ONPANIC_NOTSET(propstr))
			val = 0;
		else if (FASTREBOOT_ONPANIC_ISSET(propstr))
			val = UA_FASTREBOOT_ONPANIC;

		/*
		 * Only set fastreboot_onpanic to the value passed in
		 * if it's not already set to non-zero, and the value
		 * has indeed been passed in via command line.
		 */
		if (!fastreboot_onpanic && val != 0xaa)
			fastreboot_onpanic = val;
		ddi_prop_free(propstr);
	} else if (ret != DDI_PROP_NOT_FOUND && ret != DDI_PROP_UNDEFINED) {
		cmn_err(CE_NOTE, "!%s value is invalid, will be ignored",
		    FASTREBOOT_ONPANIC);
	}

	len = sizeof (fastreboot_onpanic_cmdline);
	ret = ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
	    FASTREBOOT_ONPANIC_CMDLINE, fastreboot_onpanic_cmdline, &len);

	if (ret == DDI_PROP_BUF_TOO_SMALL)
		cmn_err(CE_NOTE, "!%s value is too long, will be ignored",
		    FASTREBOOT_ONPANIC_CMDLINE);
}
Exemple #30
0
static int
console_type()
{
	static int boot_console = CONS_INVALID;

	char *cons;
	dev_info_t *root;

	if (boot_console != CONS_INVALID)
		return (boot_console);

#if defined(__xpv)
	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
		boot_console = CONS_HYPERVISOR;
		return (boot_console);
	}
#endif /* __xpv */

	/*
	 * console is defined by "console" property, with
	 * fallback on the old "input-device" property.
	 * If "input-device" is not defined either, also check "output-device".
	 */
	boot_console = CONS_SCREEN;	/* default is screen/kb */
	root = ddi_root_node();
	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS) ||
	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
	    DDI_PROP_DONTPASS, "output-device", &cons) == DDI_SUCCESS)) {
		if (strcmp(cons, "ttya") == 0) {
			boot_console = CONS_TTYA;
		} else if (strcmp(cons, "ttyb") == 0) {
			boot_console = CONS_TTYB;
		} else if (strcmp(cons, "usb-serial") == 0) {
			(void) i_ddi_attach_hw_nodes("ehci");
			(void) i_ddi_attach_hw_nodes("uhci");
			(void) i_ddi_attach_hw_nodes("ohci");
			/*
			 * USB device enumerate asynchronously.
			 * Wait 2 seconds for USB serial devices to attach.
			 */
			delay(drv_usectohz(2000000));
			boot_console = CONS_USBSER;
#if defined(__xpv)
		} else if (strcmp(cons, "hypervisor") == 0) {
			boot_console = CONS_HYPERVISOR;
#endif /* __xpv */
		}
		ddi_prop_free(cons);
	}

	/*
	 * If the console is configured to use a framebuffer but none
	 * could be found, fallback to "ttya" since it's likely to exist
	 * and it matches longstanding behavior on SPARC.
	 */
	if (boot_console == CONS_SCREEN && plat_fbpath() == NULL)
		boot_console = CONS_TTYA;

	return (boot_console);
}