void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */
	pnode_t 		nodeid;

	/*
	 * 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!.
	 */

	nodeid = prom_finddevice(ONTARIO_IDE_PATHNAME);
	if (nodeid == OBP_BADNODE) {
		return;
	}
	dip = e_ddi_hold_devi_by_path(ONTARIO_ISA_PATHNAME, 0);
	if (dip == NULL) {
		cmn_err(CE_PANIC, "Could not install the isa driver\n");
		return;
	}

	if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
Beispiel #2
0
static int vboxUSBMonSolarisResetDevice(char *pszDevicePath, bool fReattach)
{
    int rc = VERR_GENERAL_FAILURE;

    LogFunc((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: pszDevicePath=%s fReattach=%d\n", pszDevicePath, fReattach));

    /*
     * Try grabbing the dev_info_t.
     */
    dev_info_t *pDeviceInfo = e_ddi_hold_devi_by_path(pszDevicePath, 0);
    if (pDeviceInfo)
    {
        ddi_release_devi(pDeviceInfo);

        /*
         * Grab the root device node from the parent hub for resetting.
         */
        dev_info_t *pTmpDeviceInfo = NULL;
        for (;;)
        {
            pTmpDeviceInfo = ddi_get_parent(pDeviceInfo);
            if (!pTmpDeviceInfo)
            {
                LogRel((DEVICE_NAME ":vboxUSBMonSolarisResetDevice: Failed to get parent device info for %s\n", pszDevicePath));
                return VERR_GENERAL_FAILURE;
            }

            if (ddi_prop_exists(DDI_DEV_T_ANY, pTmpDeviceInfo, DDI_PROP_DONTPASS, "usb-port-count"))   /* parent hub */
                break;

            pDeviceInfo = pTmpDeviceInfo;
        }

        /*
         * Try re-enumerating the device.
         */
        rc = usb_reset_device(pDeviceInfo, fReattach ? USB_RESET_LVL_REATTACH : USB_RESET_LVL_DEFAULT);
        Log((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: usb_reset_device for %s level=%s rc=%d\n", pszDevicePath,
             fReattach ? "ReAttach" : "Default", rc));

        switch (rc)
        {
            case USB_SUCCESS:         rc = VINF_SUCCESS;                break;
            case USB_INVALID_PERM:    rc = VERR_PERMISSION_DENIED;      break;
            case USB_INVALID_ARGS:    rc = VERR_INVALID_PARAMETER;      break;
            case USB_BUSY:            rc = VERR_RESOURCE_BUSY;          break;
            case USB_INVALID_CONTEXT: rc = VERR_INVALID_CONTEXT;        break;
            case USB_FAILURE:         rc = VERR_GENERAL_FAILURE;        break;

            default:                  rc = VERR_UNRESOLVED_ERROR;       break;
        }
    }
    else
    {
        rc = VERR_INVALID_HANDLE;
        LogRel((DEVICE_NAME ": vboxUSBMonSolarisResetDevice: Cannot obtain device info for %s\n", pszDevicePath));
    }

    return rc;
}
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;
	}
}
void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */

	/*
	 * Install power driver which handles the power button.
	 */
	if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"power\" driver.");
	(void) ddi_hold_driver(ddi_name_to_major("power"));

	/*
	 * It is OK to return error because 'us' driver is not available
	 * in all clusters (e.g. missing in Core cluster).
	 */
	(void) i_ddi_attach_hw_nodes("us");

	if (i_ddi_attach_hw_nodes("grbeep") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"beep\" driver.");


	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * 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!.
	 */

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

	if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
void
load_platform_drivers(void)
{
	dev_info_t 		*dip;		/* dip of the isa driver */

	/*
	 * Install 'us' driver.
	 */
	(void) i_ddi_attach_hw_nodes("us");

	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * 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!.
	 */

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

	if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) {
		cmn_err(CE_PANIC, "Could not get the config space of isa\n");
		return;
	}
}
/*
 * translate a devfs pathname to one that will be acceptable
 * by the prom.  In most cases, there is no translation needed.
 * For systems supporting generically named devices, the prom
 * may support nodes such as 'disk' that do not have any unit
 * address information (i.e. target,lun info).  If this is the
 * case, the ddi framework will reject the node as invalid and
 * populate the devinfo tree with nodes froms the .conf file
 * (e.g. sd).  In this case, the names that show up in /devices
 * are sd - since the prom only knows about 'disk' nodes, this
 * routine detects this situation and does the conversion
 * There are also cases such as pluto where the disk node in the
 * prom is named "SUNW,ssd" but in /devices the name is "ssd".
 *
 * If MPxIO is enabled, the translation involves following
 * pathinfo nodes to the "best" parent.
 *
 * return a 0 on success with the new device string in ret_buf.
 * Otherwise return the appropriate error code as we may be called
 * from the openprom driver.
 */
int
i_devname_to_promname(char *dev_name, char *ret_buf, size_t len)
{
	dev_info_t *dip, *pdip, *cdip, *alt_dip = NULL;
	mdi_pathinfo_t *pip = NULL;
	char *dev_path, *prom_path;
	char *unit_address, *minorname, *nodename;
	major_t major;
	char *rptr, *optr, *offline;
	size_t olen, rlen;
	int circ;
	int ret = 0;

	/* do some sanity checks */
	if ((dev_name == NULL) || (ret_buf == NULL) ||
	    (strlen(dev_name) > MAXPATHLEN)) {
		return (EINVAL);
	}

	/*
	 * Convert to a /devices name. Fail the translation if
	 * the name doesn't exist.
	 */
	dev_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
	if (resolve_devfs_name(dev_name, dev_path) != 0 ||
	    strncmp(dev_path, "/devices/", 9) != 0) {
		kmem_free(dev_path, MAXPATHLEN);
		return (EINVAL);
	}
	dev_name = dev_path + sizeof ("/devices") - 1;

	bzero(ret_buf, len);

	if (prom_finddevice(dev_name) != OBP_BADNODE) {
		/* we are done */
		(void) snprintf(ret_buf, len, "%s", dev_name);
		kmem_free(dev_path, MAXPATHLEN);
		return (0);
	}

	/*
	 * if we get here, then some portion of the device path is
	 * not understood by the prom.  We need to look for alternate
	 * names (e.g. replace ssd by disk) and mpxio enabled devices.
	 */
	dip = e_ddi_hold_devi_by_path(dev_name, 0);
	if (dip == NULL) {
		cmn_err(CE_NOTE, "cannot find dip for %s", dev_name);
		kmem_free(dev_path, MAXPATHLEN);
		return (EINVAL);
	}

	prom_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
	rlen = len;
	rptr = ret_buf;

	if (!MDI_CLIENT(dip)) {
		ret = i_devi_to_promname(dip, prom_path, &alt_dip);
		if (ret == 0) {
			minorname = strrchr(dev_name, ':');
			if (minorname && (minorname[1] != '\0')) {
				(void) strcat(prom_path, minorname);
			}
			(void) snprintf(rptr, rlen, "%s", prom_path);
		}
	} else {
		/*
		 * if get to here, means dip is a vhci client
		 */
		offline = kmem_zalloc(len, KM_SLEEP); /* offline paths */
		olen = len;
		optr = offline;
		/*
		 * The following code assumes that the phci client is at leaf
		 * level.
		 */
		ndi_devi_enter(dip, &circ);
		while ((pip = mdi_get_next_phci_path(dip, pip)) != NULL) {
			/*
			 * walk all paths associated to the client node
			 */
			bzero(prom_path, MAXPATHLEN);

			/*
			 * replace with mdi_hold_path() when mpxio goes into
			 * genunix
			 */
			MDI_PI_LOCK(pip);
			MDI_PI_HOLD(pip);
			MDI_PI_UNLOCK(pip);

			if (mdi_pi_pathname_obp(pip, prom_path) != NULL) {
				/*
				 * The path has different obp path
				 */
				goto minor_pathinfo;
			}

			pdip = mdi_pi_get_phci(pip);
			ndi_hold_devi(pdip);

			/*
			 * Get obp path name of the phci node firstly.
			 * NOTE: if the alternate node of pdip exists,
			 * the third argument of the i_devi_to_promname()
			 * would be set to the alternate node.
			 */
			(void) i_devi_to_promname(pdip, prom_path, &alt_dip);
			if (alt_dip != NULL) {
				ndi_rele_devi(pdip);
				pdip = alt_dip;
				ndi_hold_devi(pdip);
			}

			nodename = ddi_node_name(dip);
			unit_address = MDI_PI(pip)->pi_addr;

			major = ddi_driver_major(dip);
			cdip = find_alternate_node(pdip, major);

			if (cdip) {
				nodename = ddi_node_name(cdip);
			}
			/*
			 * node name + unitaddr to the prom_path
			 */
			(void) strcat(prom_path, "/");
			(void) strcat(prom_path, nodename);
			if (unit_address && (*unit_address)) {
				(void) strcat(prom_path, "@");
				(void) strcat(prom_path, unit_address);
			}
			if (cdip) {
				/* hold from find_alternate_node */
				ndi_rele_devi(cdip);
			}
			ndi_rele_devi(pdip);
minor_pathinfo:
			minorname = strrchr(dev_name, ':');
			if (minorname && (minorname[1] != '\0')) {
				(void) strcat(prom_path, minorname);
			}

			if (MDI_PI_IS_ONLINE(pip)) {
				(void) snprintf(rptr, rlen, "%s", prom_path);
				rlen -= strlen(rptr) + 1;
				rptr += strlen(rptr) + 1;
				if (rlen <= 0) /* drop paths we can't store */
					break;
			} else {	/* path is offline */
				(void) snprintf(optr, olen, "%s", prom_path);
				olen -= strlen(optr) + 1;
				if (olen > 0) /* drop paths we can't store */
					optr += strlen(optr) + 1;
			}
			MDI_PI_LOCK(pip);
			MDI_PI_RELE(pip);
			if (MDI_PI(pip)->pi_ref_cnt == 0)
				cv_broadcast(&MDI_PI(pip)->pi_ref_cv);
			MDI_PI_UNLOCK(pip);
		}
		ndi_devi_exit(dip, circ);
		ret = 0;
		if (rlen > 0) {
			/* now add as much of offline to ret_buf as possible */
			bcopy(offline, rptr, rlen);
		}
		kmem_free(offline, len);
	}
	/* release hold from e_ddi_hold_devi_by_path() */
	ndi_rele_devi(dip);
	ret_buf[len - 1] = '\0';
	ret_buf[len - 2] = '\0';
	kmem_free(dev_path, MAXPATHLEN);
	kmem_free(prom_path, MAXPATHLEN);

	return (ret);
}
Beispiel #7
0
void
load_platform_drivers(void)
{
	/*
	 * It is OK to return error because 'us' driver is not available
	 * in all clusters (e.g. missing in Core cluster).
	 */
	(void) i_ddi_attach_hw_nodes("us");


	/*
	 * mc-us3i must stay loaded for plat_get_mem_unum()
	 */
	if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS)
		cmn_err(CE_WARN, "mc-us3i driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("mc-us3i"));

	/*
	 * load the power button driver
	 */
	if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "power button driver failed to install");
	(void) ddi_hold_driver(ddi_name_to_major("power"));

	/*
	 * load the GPIO driver for the ALOM reset and watchdog lines
	 */
	if (i_ddi_attach_hw_nodes("pmugpio") != DDI_SUCCESS)
		cmn_err(CE_WARN, "pmugpio failed to install");
	else {
		extern int watchdog_enable, watchdog_available;
		extern int disable_watchdog_on_exit;

		/*
		 * Disable an active h/w watchdog timer upon exit to OBP.
		 */
		disable_watchdog_on_exit = 1;

		watchdog_enable = 1;
		watchdog_available = 1;
	}
	(void) ddi_hold_driver(ddi_name_to_major("pmugpio"));

	/*
	 * Figure out which mi2cv dip is shared with OBP for the nvram
	 * device, so the lock can be acquired.
	 */
	shared_mi2cv_dip = e_ddi_hold_devi_by_path(SHARED_MI2CV_PATH, 0);

	/*
	 * Load the environmentals driver (rmclomv)
	 *
	 * We need this driver to handle events from the RMC when state
	 * changes occur in the environmental data.
	 */
	if (i_ddi_attach_hw_nodes("rmc_comm") != DDI_SUCCESS) {
		cmn_err(CE_WARN, "rmc_comm failed to install");
	} else {
		(void) ddi_hold_driver(ddi_name_to_major("rmc_comm"));

		if (e_ddi_hold_devi_by_path(RMCLOMV_PATHNAME, 0) == NULL) {
			cmn_err(CE_WARN, "Could not install rmclomv driver\n");
		}
	}

	/*
	 * These two dummy functions are loaded over the original
	 * todm5823 set and clear_power_alarm functions. On Boston,
	 * these functionalities are not supported.
	 * The load_platform_drivers(void) is called from post_startup()
	 * which is after all the initialization of the tod module is
	 * finished, then we replace 2 of the tod_ops function pointers
	 * with our dummy version.
	 */
	tod_ops.tod_set_power_alarm = dummy_todm5823_set_power_alarm;
	tod_ops.tod_clear_power_alarm = dummy_todm5823_clear_power_alarm;

	/*
	 * create a handle to the rmc_comm_request_nowait() function
	 * inside the rmc_comm module.
	 *
	 * The Seattle/Boston todm5823 driver will use this handle to
	 * use the rmc_comm_request_nowait() function to send time/date
	 * updates to ALOM.
	 */
	rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
	    modgetsymvalue("rmc_comm_request_nowait", 0);
}
Beispiel #8
0
/*
 * Search the devid cache, returning dev_t list for all
 * device paths mapping to the device identified by the
 * given devid.
 *
 * Primary interface used by ddi_lyr_devid_to_devlist()
 */
int
e_devid_cache_to_devt_list(ddi_devid_t devid, char *minor_name,
	int *retndevts, dev_t **retdevts)
{
	char		*path, **paths;
	int		i, j, n;
	dev_t		*devts, *udevts;
	dev_t		tdevt;
	int		ndevts, undevts, ndevts_alloced;
	dev_info_t	*devi, **devis;
	int		ndevis, npaths, nalloced;
	ddi_devid_t	match_devid;

	DEVID_LOG_FIND(("find", devid, NULL));

	ASSERT(ddi_devid_valid(devid) == DDI_SUCCESS);
	if (ddi_devid_valid(devid) != DDI_SUCCESS) {
		DEVID_LOG_ERR(("invalid devid", devid, NULL));
		return (DDI_FAILURE);
	}

	nalloced = 128;

	for (;;) {
		paths = kmem_zalloc(nalloced * sizeof (char *), KM_SLEEP);
		devis = kmem_zalloc(nalloced * sizeof (dev_info_t *), KM_SLEEP);

		rw_enter(&dcfd->nvf_lock, RW_READER);
		n = e_devid_cache_devi_path_lists(devid, nalloced,
			&ndevis, devis, &npaths, paths);
		if (n <= nalloced)
			break;
		rw_exit(&dcfd->nvf_lock);
		for (i = 0; i < ndevis; i++)
			ndi_rele_devi(devis[i]);
		kmem_free(paths, nalloced * sizeof (char *));
		kmem_free(devis, nalloced * sizeof (dev_info_t *));
		nalloced = n + 128;
	}

	for (i = 0; i < npaths; i++) {
		path = i_ddi_strdup(paths[i], KM_SLEEP);
		paths[i] = path;
	}
	rw_exit(&dcfd->nvf_lock);

	if (ndevis == 0 && npaths == 0) {
		DEVID_LOG_ERR(("no devid found", devid, NULL));
		kmem_free(paths, nalloced * sizeof (char *));
		kmem_free(devis, nalloced * sizeof (dev_info_t *));
		return (DDI_FAILURE);
	}

	ndevts_alloced = 128;
restart:
	ndevts = 0;
	devts = kmem_alloc(ndevts_alloced * sizeof (dev_t), KM_SLEEP);
	for (i = 0; i < ndevis; i++) {
		ASSERT(!DEVI_IS_ATTACHING(devis[i]));
		ASSERT(!DEVI_IS_DETACHING(devis[i]));
		e_devid_minor_to_devlist(devis[i], minor_name,
			ndevts_alloced, &ndevts, devts);
		if (ndevts > ndevts_alloced) {
			kmem_free(devts, ndevts_alloced * sizeof (dev_t));
			ndevts_alloced += 128;
			goto restart;
		}
	}
	for (i = 0; i < npaths; i++) {
		DEVID_LOG_LOOKUP((CE_CONT, "lookup %s\n", paths[i]));
		devi = e_ddi_hold_devi_by_path(paths[i], 0);
		if (devi == NULL) {
			DEVID_LOG_STALE(("stale device reference",
			    devid, paths[i]));
			continue;
		}
		/*
		 * Verify the newly attached device registered a matching devid
		 */
		if (i_ddi_devi_get_devid(DDI_DEV_T_ANY, devi,
		    &match_devid) != DDI_SUCCESS) {
			DEVIDERR((CE_CONT,
			    "%s: no devid registered on attach\n",
			    paths[i]));
			ddi_release_devi(devi);
			continue;
		}

		if (ddi_devid_compare(devid, match_devid) != 0) {
			DEVID_LOG_STALE(("new devid registered",
			    devid, paths[i]));
			ddi_release_devi(devi);
			ddi_devid_free(match_devid);
			continue;
		}
		ddi_devid_free(match_devid);

		e_devid_minor_to_devlist(devi, minor_name,
			ndevts_alloced, &ndevts, devts);
		ddi_release_devi(devi);
		if (ndevts > ndevts_alloced) {
			kmem_free(devts,
			    ndevts_alloced * sizeof (dev_t));
			ndevts_alloced += 128;
			goto restart;
		}
	}

	/* drop hold from e_devid_cache_devi_path_lists */
	for (i = 0; i < ndevis; i++) {
		ndi_rele_devi(devis[i]);
	}
	for (i = 0; i < npaths; i++) {
		kmem_free(paths[i], strlen(paths[i]) + 1);
	}
	kmem_free(paths, nalloced * sizeof (char *));
	kmem_free(devis, nalloced * sizeof (dev_info_t *));

	if (ndevts == 0) {
		DEVID_LOG_ERR(("no devid found", devid, NULL));
		kmem_free(devts, ndevts_alloced * sizeof (dev_t));
		return (DDI_FAILURE);
	}

	/*
	 * Build the final list of sorted dev_t's with duplicates collapsed so
	 * returned results are consistent. This prevents implementation
	 * artifacts from causing unnecessary changes in SVM namespace.
	 */
	/* bubble sort */
	for (i = 0; i < (ndevts - 1); i++) {
		for (j = 0; j < ((ndevts - 1) - i); j++) {
			if (devts[j + 1] < devts[j]) {
				tdevt = devts[j];
				devts[j] = devts[j + 1];
				devts[j + 1] = tdevt;
			}
		}
	}

	/* determine number of unique values */
	for (undevts = ndevts, i = 1; i < ndevts; i++) {
		if (devts[i - 1] == devts[i])
			undevts--;
	}

	/* allocate unique */
	udevts = kmem_alloc(undevts * sizeof (dev_t), KM_SLEEP);

	/* copy unique */
	udevts[0] = devts[0];
	for (i = 1, j = 1; i < ndevts; i++) {
		if (devts[i - 1] != devts[i])
			udevts[j++] = devts[i];
	}
	ASSERT(j == undevts);

	kmem_free(devts, ndevts_alloced * sizeof (dev_t));

	*retndevts = undevts;
	*retdevts = udevts;

	return (DDI_SUCCESS);
}
Beispiel #9
0
void
load_platform_drivers(void)
{
	extern int		watchdog_available;
	extern int		watchdog_enable;
	dev_info_t 		*dip;		/* dip of the isa driver */
	int			simba_present = 0;
	dev_info_t		*root_child_node;
	major_t	major;

	if (ddi_install_driver("power") != DDI_SUCCESS)
		cmn_err(CE_WARN, "Failed to install \"power\" driver.");

	/*
	 * 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;
	}

	/*
	 * Load the blade support chip driver.
	 *
	 */

	if (((major = ddi_name_to_major(BSC_DRV)) == -1) ||
		(ddi_hold_installed_driver(major) == NULL)) {
		cmn_err(CE_WARN, "%s: failed to load", BSC_DRV);
	} else {

		bsc_drv_func_ptr = (void (*)(struct bscv_idi_info *))
		    modgetsymvalue(BSC_DRV_FUNC, 0);

		if (bsc_drv_func_ptr == NULL) {
			cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; signatures will not be updated\n",
			BSC_DRV_FUNC);
			watchdog_available = 0;
			if (watchdog_enable) {
				cmn_err(CE_WARN, "load_platform_defaults: %s()"
			" not found; BSC OS watchdog service not available\n",
				BSC_DRV_FUNC);
			}
		}
	}
}