--- old/usr/src/uts/sun4u/montecarlo/io/hsc.c	Fri Aug  9 07:21:05 2019
+++ /dev/null	Fri Aug  9 00:52:51 2019
@@ -1,2170 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * MonteCarlo HotSwap Controller functionality
- */
-
-#include	<sys/types.h>
-#include	<sys/stropts.h>
-#include	<sys/stream.h>
-#include	<sys/strsun.h>
-#include	<sys/kmem.h>
-#include	<sys/cmn_err.h>
-#include	<sys/errno.h>
-#include	<sys/cpuvar.h>
-#include	<sys/open.h>
-#include	<sys/stat.h>
-#include	<sys/conf.h>
-#include	<sys/ddi.h>
-#include	<sys/sunddi.h>
-#include	<sys/modctl.h>
-#include	<sys/promif.h>
-#include	<sys/hotplug/hpcsvc.h>
-
-#include	<sys/hscimpl.h>
-#include	<sys/hsc.h>
-
-#include	<sys/mct_topology.h>
-#include	<sys/scsbioctl.h>
-#include	<sys/scsb.h>
-
-#define	HOTSWAP_MODE_PROP	"hotswap-mode"
-#define	ALARM_CARD_ON_SLOT	1
-#define	SCSB_HSC_FORCE_REMOVE	1	/* force remove enum intr handler */
-
-/* TUNABLE PARAMETERS. Some are Debug Only. Please take care when using. */
-
-/*
- * Set this flag to 1, to enable full hotswap mode at boot time.
- * Since HPS is threaded, it is not recommended that we set this flag
- * to 1 because enabling full hotswap interrupt can invoke the ENUM
- * event handler accessing the slot data structure which may have not
- * been initialized in the hotplug framework since the HPS may not yet
- * have called the slot registration function with the bus nexus.
- */
-static int	scsb_hsc_enable_fhs = 0;
-
-/*
- * Every time  a slot is registered with the hotswap framework, the
- * framework calls back. This variable keeps a count on how many
- * callbacks are done.
- */
-static int scsb_hsc_numReg = 0;
-/*
- * When this flag is set, the board is taken offline (put in reset) after
- * a unconfigure operation, in Basic Hotswap mode.
- */
-static int	scsb_hsc_bhs_slot_reset = 1;
-/*
- * When this flag is set, we take the board to reset after unconfigure
- * operation when operating in full hotswap mode.
- */
-static int	scsb_hsc_fhs_slot_reset = 1;
-/*
- * Implementation of this counter will work only on Montecarlo since
- * the ENUM# Interrupt line is not shared with other interrupts.
- * When the hardware routing changes, then there may be need to remove
- * or change this functionality.
- * This functionality is provided so that a bad or non friendly full hotswap
- * board does not hang the system in full hotswap mode. Atleast the
- * intent is that! Eventually Solaris kernel will provide similar support
- * for recovering from a stuck interrupt line. Till then, lets do this.
- */
-static int	scsb_hsc_max_intr_count = 8;
-/*
- * Since the hardware does not support enabling/disabling ENUM#, the
- * following flag can be used for imitating that behaviour.
- * Currently we can set this flag and use the remove op to remove the
- * interrupt handler from the system. Care must be taken when using this
- * function since trying to remove the interrupt handler when the interrupts
- * are pending may hang the system permanently.
- * Since the hardware does not support this functionality, we adopt this
- * approach for debugs.
- */
-static int	scsb_hsc_enum_switch = 0;
-
-/*
- * When the board loses Healthy# at runtime (with the board being configured),
- * cPCI specs states that a Reset has to be asserted immediately.
- * We dont do this currently, until satellite processor support is given
- * and the implications of such a act is fully understood.
- * To adopt the cPCI specs recommendation, set this flag to 1.
- */
-static	int	scsb_hsc_healthy_reset = 0;
-
-/*
- * According to PCI 2.2 specification, once a board comes out of PCI_RST#,
- * it may take upto 2^25 clock cycles to respond to config cycles. For
- * montecarlo using a 33MHz cPCI bus, it's around 1.024 s. The variable
- * will specify the time in ms to wait before attempting config access.
- */
-static	int scsb_connect_delay = 1025;
-
-/*
- * slot map property for MC should be
- *
- *	hsc-slot-map="/pci@1f,0/pci@1/pci@1","15","2",
- *               "/pci@1f,0/pci@1/pci@1","14","3",
- *               "/pci@1f,0/pci@1/pci@1","13","4",
- *               "/pci@1f,0/pci@1/pci@1","12","5"
- *               "/pci@1f,0/pci@1/pci@1","11","6"
- *               "/pci@1f,0/pci@1/pci@1","10","7"
- *               "/pci@1f,0/pci@1/pci@1","8","8";
- *
- * slot map property for Tonga should be
- *	hsc-slot-map="/pci@1f,0/pci@1/pci@1","8","1"
- *		"/pci@1f,0/pci@1/pci@1", "15", "2"
- *		"/pci@1f,0/pci@1/pci@1", "14", "4"
- *		"/pci@1f,0/pci@1/pci@1", "13", "5"
- *
- * Please note that the CPU slot number is 3 for Tonga.
- */
-
-/*
- * Services we require from the SCSB
- */
-extern int	scsb_get_slot_state(void *, int, int *);
-extern int	scsb_read_bhealthy(scsb_state_t *scsb);
-extern int	scsb_read_slot_health(scsb_state_t *scsb, int pslotnum);
-extern int	scsb_connect_slot(void *, int, int);
-extern int	scsb_disconnect_slot(void *, int, int);
-
-static void	*hsc_state;
-
-static uint_t	hsc_enum_intr(char *);
-static hsc_slot_t *hsc_get_slot_info(hsc_state_t *, int);
-static int	scsb_enable_enum(hsc_state_t *);
-static int	scsb_disable_enum(hsc_state_t *, int);
-static int	atoi(const char *);
-static int	isdigit(int);
-static hsc_slot_t *hsc_find_slot(int);
-static void	hsc_led_op(hsc_slot_t *, int, hpc_led_t, hpc_led_state_t);
-static int	hsc_led_state(hsc_slot_t *, int, hpc_led_info_t *);
-static int	scsb_hsc_disable_slot(hsc_slot_t *);
-static int	scsb_hsc_enable_slot(hsc_slot_t *);
-#ifndef	lint
-static int hsc_clear_all_enum(hsc_state_t *);
-#endif
-static int	hsc_slot_register(hsc_state_t *, char *, uint16_t, uint_t,
-					boolean_t);
-static int	hsc_slot_unregister(int);
-static int	scsb_hsc_init_slot_state(hsc_state_t *, hsc_slot_t *);
-static int	hsc_slot_autoconnect(hsc_slot_t *);
-
-static hpc_slot_ops_t	*hsc_slotops;
-static hsc_slot_t	*hsc_slot_list;		/* linked list of slots */
-
-/*
- * This mutex protects the following variables:
- *	hsc_slot_list
- */
-static kmutex_t		hsc_mutex;
-
-
-/* ARGSUSED */
-static int
-hsc_connect(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data, uint_t flags)
-{
-	hsc_slot_t *hsp = (hsc_slot_t *)ops_arg;
-	int rc, rstate;
-	hsc_state_t	*hsc;
-
-	DEBUG2("hsc_connect: slot %d, healthy %d", hsp->hs_slot_number,
-						hsp->hs_board_healthy);
-
-	if (!(hsp->hs_flags & (HSC_ENABLED|HSC_SLOT_ENABLED)))
-		return (HPC_ERR_FAILED);
-	/* if SCB hotswapped, do not allow connect operations */
-	if (hsp->hs_flags & HSC_SCB_HOTSWAPPED)
-		return (HPC_ERR_FAILED);
-	/*
-	 * if previous occupant stayed configured, do not allow another
-	 * occupant to be connected.
-	 * This behaviour is an indication that the slot state
-	 * is not clean.
-	 */
-	if (hsp->hs_flags & HSC_SLOT_BAD_STATE) {
-		/*
-		 * In the current implementation, we turn both fault
-		 * and active LEDs to ON state in this situation.
-		 */
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-							HPC_LED_ON);
-		return (HPC_ERR_FAILED);
-	}
-	/*
-	 * Get the actual status from the i2c bus
-	 */
-	rc = scsb_get_slot_state(hsp->hs_hpchandle, hsp->hs_slot_number,
-								&rstate);
-	if (rc != DDI_SUCCESS)
-		return (HPC_ERR_FAILED);
-
-	hsp->hs_slot_state = rstate;
-	if (hsp->hs_slot_state == HPC_SLOT_EMPTY) {
-#ifdef DEBUG
-		cmn_err(CE_CONT,
-			"?hsc_connect: slot %d is empty\n",
-			hsp->hs_slot_number);
-#endif
-		return (HPC_ERR_FAILED);
-	}
-
-	if (hsp->hs_slot_state == HPC_SLOT_CONNECTED)
-		return (HPC_SUCCESS);
-
-	rc = HPC_SUCCESS;
-	/*
-	 * call scsb to connect the slot. This also makes sure board is healthy
-	 */
-	if (scsb_connect_slot(hsp->hs_hpchandle, hsp->hs_slot_number,
-				hsp->hs_board_healthy) != DDI_SUCCESS) {
-		DEBUG1("hsc_connect: slot %d connection failed",
-				hsp->hs_slot_number);
-		rc = HPC_ERR_FAILED;
-	} else {
-		if (hsp->hs_slot_state != HPC_SLOT_CONNECTED) {
-			if (hsp->hs_board_healthy == B_FALSE) {
-				cmn_err(CE_NOTE, "HEALTHY# not asserted on "
-					" slot %d", hsp->hs_slot_number);
-				return (HPC_ERR_FAILED);
-			}
-			hsc = hsp->hsc;
-			hsc->hsp_last = hsp;
-			if (scsb_reset_slot(hsp->hs_hpchandle,
-				hsp->hs_slot_number, SCSB_UNRESET_SLOT) != 0) {
-
-				return (HPC_ERR_FAILED);
-			}
-			/*
-			 * Unresetting a board may have caused an interrupt
-			 * burst in case of non friendly boards. So it is
-			 * important to make sure that the ISR has not
-			 * put this board back to disconnect state.
-			 */
-			delay(1);
-			if (hsp->hs_flags & HSC_ENUM_FAILED) {
-				hsp->hs_flags &= ~HSC_ENUM_FAILED;
-				return (HPC_ERR_FAILED);
-			}
-			DEBUG1("hsc_connect: slot %d connected",
-						hsp->hs_slot_number);
-			rc = HPC_SUCCESS;
-			hsp->hs_slot_state = HPC_SLOT_CONNECTED;
-			(void) hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-				HPC_FAULT_LED, HPC_LED_OFF);
-		}
-	}
-
-	/*
-	 * PCI 2.2 specs recommend that the probe software wait
-	 * for upto 2^25 PCI clock cycles after deassertion of
-	 * PCI_RST# before the board is able to respond to config
-	 * cycles. So, before we return, we wait for ~1 sec.
-	 */
-	delay(drv_usectohz(scsb_connect_delay * 1000));
-	return (rc);
-}
-
-
-/* ARGSUSED */
-static int
-hsc_disconnect(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data, uint_t flags)
-{
-	hsc_slot_t		*hsp = (hsc_slot_t *)ops_arg;
-	hsc_state_t		*hsc;
-#ifdef	DEBUG
-	static const char	func[] = "hsc_disconnect";
-#endif
-
-	DEBUG1("hsc_disconnect: slot %d", hsp->hs_slot_number);
-
-	if (hsp->hs_board_configured) {
-#ifdef	DEBUG
-		cmn_err(CE_NOTE,
-			"%s: cannot disconnect configured board in slot %d",
-			func, hsp->hs_slot_number);
-#endif
-		return (HPC_ERR_FAILED);
-	}
-
-	if (hsp->hs_slot_state == HPC_SLOT_EMPTY) {
-#ifdef	DEBUG
-		cmn_err(CE_NOTE, "%s: slot %d is empty",
-			func, hsp->hs_slot_number);
-#endif
-		return (HPC_SUCCESS);
-	}
-
-	if (hsp->hs_slot_state == HPC_SLOT_DISCONNECTED) {
-		/*
-		 * if already disconnected, just return success
-		 * Duplicate disconnect messages should not be failed!
-		 */
-		return (HPC_SUCCESS);
-	}
-	/* if SCB hotswapped, do not allow disconnect operations */
-	if (hsp->hs_flags & HSC_SCB_HOTSWAPPED)
-		return (HPC_ERR_FAILED);
-
-	/* call scsb to disconnect the slot */
-	if (scsb_disconnect_slot(hsp->hs_hpchandle, B_TRUE, hsp->hs_slot_number)
-			!= DDI_SUCCESS)
-		return (HPC_ERR_FAILED);
-	hsc = hsp->hsc;
-	if (hsc->hsp_last == hsp)
-		hsc->hsp_last = NULL;
-
-	return (HPC_SUCCESS);
-}
-
-
-/*
- * In the cPCI world, this operation is not applicable.
- * However, we use this function to enable full hotswap mode in debug mode.
- */
-/* ARGSUSED */
-static int
-hsc_insert(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data, uint_t flags)
-{
-	hsc_slot_t		*hsp = (hsc_slot_t *)ops_arg;
-
-	if (scsb_hsc_enum_switch &&
-			(scsb_enable_enum(hsp->hsc) == DDI_SUCCESS)) {
-		return (HPC_SUCCESS);
-	}
-	return (HPC_ERR_NOTSUPPORTED);
-}
-
-
-/*
- * In the cPCI world, this operation is not applicable.
- * However, we use this function to disable full hotswap mode in debug mode.
- */
-/* ARGSUSED */
-static int
-hsc_remove(caddr_t ops_arg, hpc_slot_t slot_hdl, void *data, uint_t flags)
-{
-	hsc_slot_t		*hsp = (hsc_slot_t *)ops_arg;
-
-	if (scsb_hsc_enum_switch &&
-			(scsb_disable_enum(hsp->hsc, SCSB_HSC_FORCE_REMOVE)
-					== DDI_SUCCESS)) {
-		hsp->hs_flags &= ~HSC_ENUM_FAILED;
-		return (HPC_SUCCESS);
-	}
-	return (HPC_ERR_NOTSUPPORTED);
-}
-
-static void
-hsc_led_op(hsc_slot_t *hsp, int cmd, hpc_led_t led, hpc_led_state_t led_state)
-{
-	hpc_led_info_t	ledinfo;
-
-	ledinfo.led = led;
-	ledinfo.state = led_state;
-	(void) hsc_led_state(hsp, cmd, &ledinfo);
-}
-
-static int
-hsc_led_state(hsc_slot_t *hsp, int cmd, hpc_led_info_t *hlip)
-{
-	hpc_led_state_t	*hlsp;
-	scsb_uinfo_t	sunit;
-	int		res;
-
-	DEBUG3("hsc_led_state: slot %d, led %x, state %x",
-		hsp->hs_slot_number, hlip->led, hlip->state);
-
-	sunit.unit_type = SLOT;
-	sunit.unit_number = hsp->hs_slot_number;
-	/*
-	 * We ignore operations on LEDs that we don't support
-	 */
-	switch (hlip->led) {
-		case HPC_FAULT_LED:
-			sunit.led_type = NOK;
-			hlsp = &hsp->hs_fault_led_state;
-			break;
-		case HPC_ACTIVE_LED:
-			sunit.led_type = OK;
-			hlsp = &hsp->hs_active_led_state;
-			break;
-		default:
-			return (HPC_ERR_NOTSUPPORTED);
-	}
-
-	switch (hlip->state) {
-		case HPC_LED_BLINK:
-			sunit.unit_state = BLINK;
-			if (hlip->led != HPC_ACTIVE_LED)
-				return (HPC_ERR_NOTSUPPORTED);
-			break;
-		case HPC_LED_ON:
-			sunit.unit_state = ON;
-			break;
-		case HPC_LED_OFF:
-			sunit.unit_state = OFF;
-			break;
-		default:
-			break;
-	}
-
-	switch (cmd) {
-	case HPC_CTRL_SET_LED_STATE:
-		res = scsb_led_set(hsp->hs_hpchandle, &sunit, sunit.led_type);
-		if (res != 0)
-			return (HPC_ERR_FAILED);
-		*hlsp = (hpc_led_state_t)sunit.unit_state;
-		break;
-
-	case HPC_CTRL_GET_LED_STATE:
-		res = scsb_led_get(hsp->hs_hpchandle, &sunit, sunit.led_type);
-		if (res)
-			return (HPC_ERR_FAILED);
-		/* hlip->state = sunit.unit_state; */
-		break;
-
-	default:
-		return (HPC_ERR_INVALID);
-	}
-
-	return (HPC_SUCCESS);
-
-}
-
-
-static int
-hsc_get_slot_state(hsc_slot_t *hsp, hpc_slot_state_t *hssp)
-{
-	int rstate = 0;
-	int rc;
-#ifdef	DEBUG
-	int orstate;	/* original rstate */
-#endif
-
-	DEBUG1("hsc_get_slot_state: slot %d", hsp->hs_slot_number);
-	rc = scsb_get_slot_state(hsp->hs_hpchandle, hsp->hs_slot_number,
-								&rstate);
-	if (rc != DDI_SUCCESS)
-		return (HPC_ERR_FAILED);
-#ifdef	DEBUG
-	orstate = hsp->hs_slot_state;
-#endif
-	hsp->hs_slot_state = rstate;
-	switch (hsp->hs_slot_state) {
-	case HPC_SLOT_EMPTY:
-		DEBUG0("empty");
-		break;
-	case HPC_SLOT_CONNECTED:
-		DEBUG0("connected");
-		break;
-	case HPC_SLOT_DISCONNECTED:
-		DEBUG0("disconnected");
-		break;
-	}
-
-	*hssp = hsp->hs_slot_state;
-
-	/* doing get-state above may have caused a freeze operation */
-	if ((hsp->hs_flags & HSC_SCB_HOTSWAPPED) &&
-			(rstate == HPC_SLOT_DISCONNECTED)) {
-		/* freeze puts disconnected boards to connected state */
-		*hssp = HPC_SLOT_CONNECTED;
-#if 0
-		/* in FHS, deassertion of reset may have configured the board */
-		if (hsp->hs_board_configured == B_TRUE) {
-			hsp->hs_slot_state = *hssp;
-		}
-#endif
-	}
-#ifdef	DEBUG
-	/* a SCB hotswap may have forced a state change on the receptacle */
-	if (orstate != *hssp) {
-		cmn_err(CE_NOTE, "hsc_get_state: slot%d state change due"
-			" to SCB hotswap!", hsp->hs_slot_number);
-	}
-#endif
-	return (HPC_SUCCESS);
-}
-
-
-static int
-hsc_set_config_state(hsc_slot_t *hsp, int cmd)
-{
-	hsc_state_t	*hsc = hsp->hsc;
-
-	DEBUG1("hsc_set_config_state: slot %d", hsp->hs_slot_number);
-
-	switch (cmd) {
-	case HPC_CTRL_DEV_CONFIGURED:
-		/*
-		 * Closing of the Ejector switch in configured/busy state can
-		 * cause duplicate CONFIGURED messages to come down.
-		 * Make sure our LED states are fine.
-		 */
-		if (hsp->hs_board_configured == B_TRUE) {
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_ON);
-			break;
-		}
-		hsp->hs_board_configured = B_TRUE;
-		hsp->hs_board_configuring = B_FALSE;
-		if ((hsc->state & HSC_ATTACHED) == HSC_ATTACHED &&
-			hsp->hs_flags & HSC_ALARM_CARD_PRES)
-			(void) scsb_hsc_ac_op(hsp->hs_hpchandle,
-				hsp->hs_slot_number, SCSB_HSC_AC_CONFIGURED);
-		/* LED must be OFF on the occupant. */
-		(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_SLOT_BLUE_LED_OFF, 0);
-		if (hsp->hs_flags & HSC_AUTOCFG)
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_ENABLE_ENUM, 0);
-		else
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_DISABLE_ENUM, 0);
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_ON);
-		if (hsc->hsp_last == hsp)
-			hsc->hsp_last = NULL;
-		break;
-	case HPC_CTRL_DEV_UNCONFIGURED:
-		hsp->hs_board_configured = B_FALSE;
-		hsp->hs_board_unconfiguring = B_FALSE;
-		hsp->hs_flags &= ~HSC_SLOT_BAD_STATE;
-		if (hsp->hs_flags & HSC_ALARM_CARD_PRES)
-			(void) scsb_hsc_ac_op(hsp->hs_hpchandle,
-				hsp->hs_slot_number, SCSB_HSC_AC_UNCONFIGURED);
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-							HPC_LED_BLINK);
-		if (((hsc->state & HSC_ENUM_ENABLED) &&
-			scsb_hsc_fhs_slot_reset) ||
-		(((hsc->state & HSC_ENUM_ENABLED) != HSC_ENUM_ENABLED) &&
-				scsb_hsc_bhs_slot_reset) ||
-				((hsp->hs_flags & HSC_AUTOCFG) !=
-					HSC_AUTOCFG)) {
-			if (scsb_reset_slot(hsp->hs_hpchandle,
-				hsp->hs_slot_number, SCSB_RESET_SLOT) == 0) {
-
-				hsp->hs_slot_state = HPC_SLOT_DISCONNECTED;
-				hsp->hs_board_healthy = B_FALSE;
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-					HPC_FAULT_LED, HPC_LED_ON);
-			}
-		}
-		break;
-	case HPC_CTRL_DEV_CONFIG_FAILURE:
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-							HPC_LED_BLINK);
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-				HPC_FAULT_LED, HPC_LED_ON);
-		break;
-	case HPC_CTRL_DEV_UNCONFIG_FAILURE:
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-							HPC_LED_ON);
-		break;
-	case HPC_CTRL_DEV_CONFIG_START:
-	case HPC_CTRL_DEV_UNCONFIG_START:
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-					HPC_LED_OFF);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-					HPC_LED_BLINK);
-		break;
-	default:
-		return (HPC_ERR_INVALID);
-	}
-
-	if (cmd != HPC_CTRL_DEV_CONFIG_START &&
-		cmd != HPC_CTRL_DEV_UNCONFIG_START &&
-		hsc->regDone == B_FALSE &&
-			scsb_hsc_numReg < hsc->n_registered_occupants) {
-		scsb_hsc_numReg++;
-
-		/*
-		 * If the callback is invoked for all registered slots,
-		 * enable ENUM.
-		 */
-		if (((hsc->state & HSC_ATTACHED) == HSC_ATTACHED) &&
-			(scsb_hsc_numReg == hsc->n_registered_occupants)) {
-			hsc->regDone = B_TRUE;
-			if (hsc->hotswap_mode == HSC_HOTSWAP_MODE_FULL) {
-#ifdef DEBUG
-				cmn_err(CE_CONT, "%s%d: Enabling full hotswap"
-					":%d non-empty slots\n",
-					ddi_driver_name(hsc->dip),
-					ddi_get_instance(hsc->dip),
-					hsc->n_registered_occupants);
-#endif
-				if (scsb_enable_enum(hsc) != DDI_SUCCESS) {
-					cmn_err(CE_WARN, "%s#%d: Cannot enable "
-						"Full Hotswap",
-						ddi_driver_name(hsc->dip),
-						ddi_get_instance(hsc->dip));
-
-					return (HPC_ERR_FAILED);
-				}
-			}
-		}
-	}
-
-	return (HPC_SUCCESS);
-}
-
-
-/*ARGSUSED*/
-static int
-hsc_get_board_type(hsc_slot_t *hsp, hpc_board_type_t *hbtp)
-{
-	*hbtp = hsp->hs_board_type;
-	return (HPC_SUCCESS);
-}
-
-
-/* ARGSUSED */
-static int
-hsc_autoconfig(hsc_slot_t *hsp, int cmd)
-{
-	int res = HPC_SUCCESS, enum_disable = B_TRUE, i;
-	char slotautocfg_prop[18];
-	hsc_state_t *hsc;
-
-	DEBUG1("hsc_autoconfig: slot %d", hsp->hs_slot_number);
-	(void) sprintf(slotautocfg_prop, "slot%d-autoconfig",
-	    hsp->hs_slot_number);
-
-	if (cmd == HPC_CTRL_ENABLE_AUTOCFG) {
-		hsp->hs_flags |= HSC_AUTOCFG;
-		(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsp->hsc->dip,
-				slotautocfg_prop, "enabled");
-		if ((res = scsb_enable_enum(hsp->hsc)) == DDI_SUCCESS) {
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_ENABLE_ENUM, 0);
-		}
-	} else {
-		(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsp->hsc->dip,
-		    slotautocfg_prop, "disabled");
-		hsp->hs_flags &= ~HSC_AUTOCFG;
-		hsc = hsp->hsc;
-		if (hsc->state & HSC_ATTACHED) {
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-						HPC_EVENT_DISABLE_ENUM, 0);
-			for (i = 0; i < hsc->slot_table_size; i++) {
-				hsc_slot_t	*thsp;
-				int slotnum;
-
-				slotnum = hsc->slot_table_prop[i].pslotnum;
-				thsp = hsc_find_slot(slotnum);
-				if (thsp == NULL) {
-					cmn_err(CE_WARN, "%s#%d: hsc_autocfg:"
-						"No Slot Info for slot %d",
-						ddi_driver_name(hsc->dip),
-						ddi_get_instance(hsc->dip),
-						slotnum);
-					continue;
-				}
-				if (thsp->hs_flags & HSC_AUTOCFG) {
-					enum_disable = B_FALSE;
-					break;
-				}
-			}
-			if (enum_disable == B_TRUE)
-				(void) scsb_disable_enum(hsc,
-				    SCSB_HSC_FORCE_REMOVE);
-		}
-	}
-	return (res);
-}
-
-
-/*
- * This function is invoked to enable/disable a slot
- */
-/* ARGSUSED */
-#ifndef	lint
-static int
-hsc_slot_enable(hsc_slot_t *hsp, boolean_t enabled)
-{
-	scsb_uinfo_t	sunit;
-	int		res;
-
-	DEBUG1("hsc_slot_enable: slot %d", hsp->hs_slot_number);
-
-	sunit.unit_type = SLOT;
-	sunit.unit_number = hsp->hs_slot_number;
-	if (enabled)
-		sunit.unit_state = ON;
-	else
-		sunit.unit_state = OFF;
-
-	res = scsb_reset_unit(hsp->hs_hpchandle, &sunit);
-	if (res == 0)
-		return (HPC_SUCCESS);
-	else if (res == EINVAL)
-		return (HPC_ERR_INVALID);
-	else
-		return (HPC_ERR_FAILED);
-}
-#endif
-
-
-/*ARGSUSED*/
-static int
-hsc_control(caddr_t ops_arg, hpc_slot_t slot_hdl, int request, caddr_t arg)
-{
-	hsc_slot_t *hsp = (hsc_slot_t *)ops_arg;
-	int rc = HPC_SUCCESS;
-
-	DEBUG2("hsc_control: slot %d, op=%x\n", hsp->hs_slot_number, request);
-
-	switch (request) {
-	case HPC_CTRL_GET_LED_STATE:
-		return (hsc_led_state(hsp,
-			HPC_CTRL_GET_LED_STATE, (hpc_led_info_t *)arg));
-
-	case HPC_CTRL_SET_LED_STATE:
-		return (hsc_led_state(hsp,
-			HPC_CTRL_SET_LED_STATE, (hpc_led_info_t *)arg));
-
-	case HPC_CTRL_GET_SLOT_STATE:
-		return (hsc_get_slot_state(hsp, (hpc_slot_state_t *)arg));
-
-	case HPC_CTRL_DEV_CONFIGURED:
-		return (hsc_set_config_state(hsp, HPC_CTRL_DEV_CONFIGURED));
-
-	case HPC_CTRL_DEV_UNCONFIGURED:
-		return (hsc_set_config_state(hsp, HPC_CTRL_DEV_UNCONFIGURED));
-
-	case HPC_CTRL_DEV_CONFIG_FAILURE:
-		return (hsc_set_config_state(hsp, HPC_CTRL_DEV_CONFIG_FAILURE));
-
-	case HPC_CTRL_DEV_UNCONFIG_FAILURE:
-		return (hsc_set_config_state(hsp,
-				HPC_CTRL_DEV_UNCONFIG_FAILURE));
-
-	case HPC_CTRL_DEV_CONFIG_START:
-	case HPC_CTRL_DEV_UNCONFIG_START:
-		return (hsc_set_config_state(hsp, request));
-
-	case HPC_CTRL_GET_BOARD_TYPE:
-		return (hsc_get_board_type(hsp, (hpc_board_type_t *)arg));
-
-	case HPC_CTRL_DISABLE_AUTOCFG:
-		return (hsc_autoconfig(hsp, HPC_CTRL_DISABLE_AUTOCFG));
-
-	case HPC_CTRL_ENABLE_AUTOCFG:
-		return (hsc_autoconfig(hsp, HPC_CTRL_ENABLE_AUTOCFG));
-
-	case HPC_CTRL_DISABLE_SLOT:
-		/*
-		 * No hardware support for disabling the slot.
-		 * Just imitate a disable_autoconfig operation for now
-		 */
-		if (hsp->hs_board_configured == B_TRUE)
-			return (HPC_ERR_FAILED);
-		if (scsb_hsc_disable_slot(hsp) != DDI_SUCCESS)
-			rc = HPC_ERR_FAILED;
-		return (rc);
-
-	case HPC_CTRL_ENABLE_SLOT:
-		if (scsb_hsc_enable_slot(hsp) != DDI_SUCCESS)
-			rc = HPC_ERR_FAILED;
-		return (rc);
-
-	case HPC_CTRL_ENABLE_ENUM:
-		return (scsb_enable_enum(hsp->hsc));
-
-	case HPC_CTRL_DISABLE_ENUM:
-		return (scsb_disable_enum(hsp->hsc, 0));
-
-	default:
-		return (HPC_ERR_INVALID);
-	}
-}
-
-static int
-scsb_hsc_disable_slot(hsc_slot_t *hsp)
-{
-	int rc;
-	char slot_disable_prop[18];
-
-	DEBUG1("hsc_disable_slot: slot %d", hsp->hs_slot_number);
-	(void) sprintf(slot_disable_prop, "slot%d-status", hsp->hs_slot_number);
-
-	rc = scsb_reset_slot(hsp->hs_hpchandle, hsp->hs_slot_number,
-					SCSB_RESET_SLOT);
-	if (rc == DDI_SUCCESS) {
-		(void) hsc_autoconfig(hsp, HPC_CTRL_DISABLE_AUTOCFG);
-		hsp->hs_flags &= ~HSC_SLOT_ENABLED;
-		(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsp->hsc->dip,
-		    slot_disable_prop, "disabled");
-	} else
-		rc = DDI_FAILURE;
-	return (rc);
-}
-
-static int
-scsb_hsc_enable_slot(hsc_slot_t *hsp)
-{
-	int rc;
-	char slot_disable_prop[18];
-
-	DEBUG1("hsc_disable_slot: slot %d", hsp->hs_slot_number);
-	(void) sprintf(slot_disable_prop, "slot%d-status", hsp->hs_slot_number);
-
-	rc = scsb_reset_slot(hsp->hs_hpchandle, hsp->hs_slot_number,
-					SCSB_UNRESET_SLOT);
-	if (rc == DDI_SUCCESS) {
-		(void) hsc_autoconfig(hsp, HPC_CTRL_ENABLE_AUTOCFG);
-		hsp->hs_flags |= HSC_SLOT_ENABLED;
-		(void) ddi_prop_remove(DDI_DEV_T_NONE, hsp->hsc->dip,
-		    slot_disable_prop);
-	} else
-		rc = HPC_ERR_FAILED;
-	return (rc);
-}
-
-#define	NEW(type)	(type *) kmem_zalloc(sizeof (type), KM_SLEEP)
-
-static hsc_slot_t *
-hsc_alloc_slot(
-		uint16_t	device_number,
-		int		slot_number,
-		boolean_t	board_in_slot)
-{
-	hpc_slot_info_t	*hsip;
-	hsc_slot_t	*hsp = NEW(hsc_slot_t);
-
-	DEBUG2("hsc_alloc_slot: slot %d %s", slot_number,
-		board_in_slot ? "occupied" : "empty");
-
-	if (hsp == NULL) {
-		cmn_err(CE_NOTE,
-			"hsc_alloc_slot: allocation failed for slot %d",
-			slot_number);
-		return (NULL);
-	}
-
-	hsip = &hsp->hs_info;
-
-	hsip->version			= HPC_SLOT_INFO_VERSION;
-	hsip->slot_type			= HPC_SLOT_TYPE_CPCI;
-	hsip->pci_dev_num		= device_number;
-	hsip->pci_slot_capabilities	= 0;
-	hsip->slot_flags		= HPC_SLOT_CREATE_DEVLINK;
-	/*
-	 * Note: the name *must* be 'pci' so that the correct cfgadm plug-in
-	 *	 library is selected
-	 */
-	(void) sprintf(hsip->pci_slot_name, "cpci_slot%d", slot_number);
-
-	/*
-	 * We assume that the following LED settings reflect
-	 * the hardware state.
-	 * After we register the slot, we will be invoked by the nexus
-	 * if the slot is occupied, and we will turn on the LED then.
-	 */
-	hsp->hs_active_led_state	= HPC_LED_OFF;
-	hsp->hs_fault_led_state		= HPC_LED_OFF;
-
-	hsp->hs_board_configured	= B_FALSE;
-	hsp->hs_board_healthy		= B_FALSE;
-	hsp->hs_board_type		= HPC_BOARD_UNKNOWN;
-
-	hsp->hs_flags			= HSC_ENABLED | HSC_SLOT_ENABLED;
-	hsp->hs_slot_number		= slot_number;
-
-	/*
-	 * we should just set this to connected,
-	 * as MC slots are always connected.
-	 */
-	if (board_in_slot)
-		hsp->hs_slot_state = HPC_SLOT_CONNECTED;
-	else
-		hsp->hs_slot_state = HPC_SLOT_EMPTY;
-
-	return (hsp);
-}
-
-
-static void
-hsc_free_slot(hsc_slot_t *hsp)
-{
-	DEBUG0("hsc_free_slot");
-
-	kmem_free(hsp, sizeof (*hsp));
-}
-
-
-/*
- * This function is invoked to register a slot
- */
-static int
-hsc_slot_register(
-	hsc_state_t	*hsc,
-	char		*bus_path,	/* PCI nexus pathname */
-	uint16_t	device_number,	/* PCI device number */
-	uint_t		slot_number,	/* physical slot number */
-	boolean_t	board_in_slot)	/* receptacle status */
-{
-	int		rc = HPC_SUCCESS;
-	hsc_slot_t	*hsp;
-
-	DEBUG2("hsc_slot_register: slot number %d, device number %d",
-		slot_number, device_number);
-
-	hsp = hsc_alloc_slot(device_number, slot_number,
-			board_in_slot);
-
-	if (hsp == NULL) {
-#ifdef	DEBUG
-		cmn_err(CE_NOTE, "hsc_slot_register: hsc_alloc_slot failed");
-#endif
-		return (HPC_ERR_FAILED);
-	}
-
-	hsp->hs_hpchandle = hsc->scsb_handle; /* handle for call backs */
-	hsp->hsc = hsc;
-
-	rc = scsb_hsc_init_slot_state(hsc, hsp);
-	if (rc != DDI_SUCCESS)
-		return (HPC_ERR_FAILED);
-
-	/* slot autoconfiguration by default. */
-	if (hsc->hotswap_mode == HSC_HOTSWAP_MODE_FULL)
-		(void) hsc_autoconfig(hsp, HPC_CTRL_ENABLE_AUTOCFG);
-	else
-		(void) hsc_autoconfig(hsp, HPC_CTRL_DISABLE_AUTOCFG);
-
-	/*
-	 * Append to our list
-	 */
-	mutex_enter(&hsc_mutex);
-	hsp->hs_next = hsc_slot_list;
-	hsc_slot_list = hsp;
-	mutex_exit(&hsc_mutex);
-
-	rc = hpc_slot_register(hsc->dip,
-			bus_path,
-			&hsp->hs_info,
-			&hsp->hs_slot_handle,	/* return value */
-			hsc_slotops,
-			(caddr_t)hsp,
-			0);
-
-	if (rc != HPC_SUCCESS) {
-		cmn_err(CE_WARN, "%s#%d: failed to register slot %s:%d",
-			ddi_driver_name(hsc->dip), ddi_get_instance(hsc->dip),
-			bus_path, device_number);
-		hsc_free_slot(hsp);
-		return (rc);
-	}
-
-	DEBUG0("hsc_slot_register: hpc_slot_register successful");
-
-	return (rc);
-}
-
-
-static int
-hsc_slot_unregister(int slot_number)
-{
-	hsc_slot_t	*hsp, *prev;
-
-	DEBUG1("hsc_slot_unregister: slot number %d", slot_number);
-
-	mutex_enter(&hsc_mutex);
-	hsp = prev = NULL;
-	for (hsp = hsc_slot_list; hsp != NULL; hsp = hsp->hs_next) {
-		if (hsp->hs_slot_number == slot_number) {
-			if (prev == NULL) /* first entry */
-				hsc_slot_list = hsc_slot_list->hs_next;
-			else
-				prev->hs_next = hsp->hs_next;
-			hsp->hs_next = NULL;
-			break;
-		}
-		prev = hsp;
-	}
-	mutex_exit(&hsc_mutex);
-
-	if (hsp != NULL) {
-		(void) hpc_slot_unregister(&hsp->hs_slot_handle);
-		if ((hsp->hsc->state & HSC_ATTACHED) != HSC_ATTACHED &&
-				hsp->hs_slot_state != HPC_SLOT_EMPTY) {
-			hsp->hsc->n_registered_occupants--;
-		}
-		hsc_free_slot(hsp);
-		return (0);
-	}
-	return (1);
-}
-
-static int
-scsb_hsc_init_slot_state(hsc_state_t *hsc, hsc_slot_t *hsp)
-{
-	int rc, rstate;
-	int slot_number = hsp->hs_slot_number;
-	scsb_state_t	*scsb = (scsb_state_t *)hsc->scsb_handle;
-
-	rc = scsb_get_slot_state(hsc->scsb_handle, slot_number, &rstate);
-	if (rc != DDI_SUCCESS)
-		return (DDI_FAILURE);
-
-	/*
-	 * Set the healthy status for this slot
-	 */
-	hsp->hs_board_healthy = scsb_read_slot_health(scsb, slot_number);
-	hsp->hs_slot_state = rstate;
-	switch (rstate) {
-		case HPC_SLOT_EMPTY:
-			/*
-			 * this will clear any state differences between
-			 * SCB Freeze operations.
-			 */
-			hsp->hs_slot_state = HPC_SLOT_EMPTY;
-			/* slot empty. */
-			(void) scsb_reset_slot(hsc->scsb_handle, slot_number,
-			    SCSB_RESET_SLOT);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-			    HPC_LED_OFF);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-			    HPC_LED_OFF);
-			break;
-		case HPC_SLOT_DISCONNECTED:
-			/*
-			 * this will clear any state differences between
-			 * SCB Freeze operations.
-			 */
-			hsp->hs_slot_state = HPC_SLOT_DISCONNECTED;
-			/* check recovery from SCB freeze */
-			if (hsp->hs_board_configured != B_TRUE) {
-				/*
-				 * Force a disconnect just in case there are
-				 * differences between healthy and reset states.
-				 */
-				(void) scsb_reset_slot(hsc->scsb_handle,
-				    slot_number, SCSB_RESET_SLOT);
-				/*
-				 * Slot in reset. OBP has not probed this
-				 * device. Hence it is ok to remove this board.
-				 */
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-						HPC_ACTIVE_LED, HPC_LED_BLINK);
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-						HPC_FAULT_LED, HPC_LED_ON);
-				break;
-			}
-			/*FALLTHROUGH*/
-		case HPC_SLOT_CONNECTED:
-			/*
-			 * this will clear any state differences between
-			 * SCB Freeze operations.
-			 */
-			hsp->hs_slot_state = HPC_SLOT_CONNECTED;
-			/*
-			 * OBP should have probed this device, unless
-			 * it was plugged in during the boot operation
-			 * before the driver was loaded. In any case,
-			 * no assumption is made and hence we take
-			 * the conservative approach by keeping fault
-			 * led off so board removal is not allowed.
-			 */
-			if (hsp->hs_board_configured == B_TRUE)
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-					HPC_ACTIVE_LED, HPC_LED_ON);
-			else
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-					HPC_ACTIVE_LED, HPC_LED_BLINK);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-							HPC_LED_OFF);
-			/*
-			 * Netra ct alarm card hotswap support
-			 */
-			if (slot_number == scsb->ac_slotnum &&
-				scsb->scsb_hsc_state & SCSB_ALARM_CARD_PRES) {
-				hsp->hs_flags |= HSC_ALARM_CARD_PRES;
-				DEBUG0("Xscsb_hsc_init_slot_state: "
-						"set HSC_ALARM_CARD_PRES");
-			}
-			break;
-		default:
-			break;
-	}
-	return (rc);
-}
-
-static hsc_slot_t *
-hsc_get_slot_info(hsc_state_t *hsc, int pci_devno)
-{
-	int i;
-
-	for (i = 0; i < hsc->slot_table_size; i++) {
-
-		if (hsc->slot_table_prop[i].pci_devno == pci_devno)
-			return ((hsc_slot_t *)hsc_find_slot(
-				hsc->slot_table_prop[i].pslotnum));
-	}
-	return (NULL);
-}
-
-static hsc_slot_t *
-hsc_find_slot(int slot_number)
-{
-	hsc_slot_t	*hsp;
-
-	mutex_enter(&hsc_mutex);
-	for (hsp = hsc_slot_list; hsp != NULL; hsp = hsp->hs_next) {
-		if (hsp->hs_slot_number == slot_number)
-			break;
-	}
-	mutex_exit(&hsc_mutex);
-	return (hsp);
-}
-
-
-/*
- * This function is invoked by the SCSB when an interrupt
- * happens to indicate that a board has been inserted-in/removed-from
- * the specified slot.
- */
-int
-hsc_slot_occupancy(int slot_number, boolean_t occupied, int flags, int healthy)
-{
-	static const char	func[]	= "hsc_slot_occupancy";
-	hsc_slot_t		*hsp;
-	int			rc = DDI_SUCCESS;
-
-	DEBUG4("hsc_slot_occupancy: slot %d %s, ac=%d, healthy=%d",
-			slot_number, occupied ? "occupied" : "not occupied",
-			(flags == ALARM_CARD_ON_SLOT) ? 1:0, healthy);
-
-	hsp = hsc_find_slot(slot_number);
-
-	if (hsp == NULL) {
-		cmn_err(CE_NOTE,
-			"%s: cannot map slot number %d to a hsc_slot_t",
-			func, slot_number);
-		return (DDI_FAILURE);
-	}
-
-	hsp->hs_board_healthy = healthy;
-	if (occupied) {
-		/*
-		 * A board was just inserted. We are disconnected at this point.
-		 */
-		if (hsp->hs_slot_state == HPC_SLOT_EMPTY)
-			hsp->hs_board_type = HPC_BOARD_CPCI_HS;
-		hsp->hs_slot_state = HPC_SLOT_DISCONNECTED;
-		if (flags == ALARM_CARD_ON_SLOT) {
-			hsp->hs_flags |= HSC_ALARM_CARD_PRES;
-			DEBUG0("Xhsc_slot_occupancy: set HSC_ALARM_CARD_PRES");
-		}
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-						HPC_LED_ON);
-		/*
-		 * if previous occupant stayed configured, do not allow another
-		 * occupant to be connected.
-		 * So as soon as the board is plugged in, we turn both LEDs On.
-		 * This behaviour is an indication that the slot state
-		 * is not clean.
-		 */
-		if (hsp->hs_flags & HSC_SLOT_BAD_STATE) {
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_ON);
-			return (DDI_SUCCESS);
-		}
-
-		/* Do not allow connect if slot is disabled */
-		if ((hsp->hs_flags & HSC_SLOT_ENABLED) != HSC_SLOT_ENABLED)
-			return (DDI_SUCCESS);
-		/* if no healthy, we stay disconnected. */
-		if (healthy == B_FALSE) {
-			return (DDI_SUCCESS);
-		}
-		rc = hsc_slot_autoconnect(hsp);
-		hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_BLINK);
-	} else {
-		/*
-		 * A board was just removed
-		 */
-		hsp->hs_slot_state = HPC_SLOT_EMPTY;
-		hsp->hs_board_type = HPC_BOARD_UNKNOWN;
-		hsp->hs_flags &= ~HSC_ENUM_FAILED;
-		if (hsp->hs_flags & HSC_ALARM_CARD_PRES) {
-			hsp->hs_flags &= ~HSC_ALARM_CARD_PRES;
-			DEBUG0("Xhsc_slot_occupancy:clear HSC_ALARM_CARD_PRES");
-		}
-		if (hsp->hs_board_configured == B_TRUE) {
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_SLOT_NOT_HEALTHY, 0);
-			cmn_err(CE_WARN, "%s#%d: ALERT! Surprise Removal "
-				" on Slot %d, Occupant Online!!",
-					ddi_driver_name(hsp->hsc->dip),
-					ddi_get_instance(hsp->hsc->dip),
-					slot_number);
-			cmn_err(CE_WARN, "%s#%d: ALERT! System now in "
-				" Inconsistent State! Slot disabled. Halt!",
-					ddi_driver_name(hsp->hsc->dip),
-					ddi_get_instance(hsp->hsc->dip));
-			/* Slot in reset and disabled */
-			(void) scsb_hsc_disable_slot(hsp);
-			hsp->hs_flags |= HSC_SLOT_BAD_STATE;
-			/* the following works for P1.0 only. */
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-						HPC_LED_ON);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_ON);
-		} else {
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-						HPC_LED_OFF);
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_ACTIVE_LED,
-								HPC_LED_OFF);
-		}
-	}
-	return (rc);
-}
-
-
-/*
- * This function is invoked by the SCSB when the health status of
- * a board changes.
- */
-/*ARGSUSED*/
-int
-scsb_hsc_board_healthy(int slot_number, boolean_t healthy)
-{
-	hsc_slot_t		*hsp;
-	hsc_state_t		*hsc;
-
-	DEBUG2("hsc_board_healthy: slot %d = %d\n", slot_number, healthy);
-
-	hsp = hsc_find_slot(slot_number);
-	if (hsp == NULL) {
-		cmn_err(CE_NOTE, "hsc_board_healthy: No Slot Info.");
-		return (DDI_FAILURE);
-	}
-
-	hsc = hsp->hsc;
-	if (hsp->hs_slot_state == HPC_SLOT_EMPTY) {
-#ifdef	DEBUG
-		cmn_err(CE_NOTE, "%s#%d: Healthy# %s on "
-			"empty slot %d", ddi_driver_name(hsc->dip),
-			ddi_get_instance(hsc->dip),
-			healthy == B_TRUE ? "On" : "Off", slot_number);
-#endif
-		return (DDI_FAILURE);
-	}
-	if (hsp->hs_slot_state == HPC_SLOT_DISCONNECTED) {
-		DEBUG2("healthy %s on disconnected slot %d\n",
-			healthy == B_TRUE ? "On":"Off", slot_number);
-		/*
-		 * Connect the slot if board healthy and in autoconfig mode.
-		 */
-		hsp->hs_board_healthy = healthy;
-		if (healthy == B_TRUE)
-			return (hsc_slot_autoconnect(hsp));
-	}
-
-	/*
-	 * the board is connected. The result could be seviour depending
-	 * on the occupant state.
-	 */
-	if (healthy == B_TRUE) {
-		if (hsp->hs_board_healthy != B_TRUE) {
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE, HPC_FAULT_LED,
-					HPC_LED_OFF);
-			/* Regained HEALTHY# at Run Time...!!! */
-			cmn_err(CE_NOTE, "%s#%d: slot %d Occupant "
-				"%s, Regained HEALTHY#!",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip), slot_number,
-				hsp->hs_board_configured == B_TRUE ?
-						"configured" : "Unconfigured");
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-				HPC_EVENT_SLOT_HEALTHY_OK, 0);
-		}
-	} else {
-		if (hsp->hs_board_configured == B_TRUE) {
-			/* Lost HEALTHY# at Run Time...Serious Condition. */
-			cmn_err(CE_WARN, "%s#%d: ALERT! Lost HEALTHY#"
-				" on Slot %d, Occupant %s",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip), slot_number,
-					hsp->hs_board_configured == B_TRUE ?
-						"Online!!!" : "Offline");
-			(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_SLOT_NOT_HEALTHY, 0);
-		}
-		if ((hsp->hs_board_configured != B_TRUE) ||
-						scsb_hsc_healthy_reset) {
-			if (scsb_reset_slot(hsp->hs_hpchandle,
-					slot_number, SCSB_RESET_SLOT) == 0) {
-				/* signal Ok to remove board. */
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-					HPC_FAULT_LED, HPC_LED_ON);
-				cmn_err(CE_WARN, "%s#%d: Slot %d "
-					"successfully taken offline",
-					ddi_driver_name(hsc->dip),
-					ddi_get_instance(hsc->dip),
-					slot_number);
-			}
-		}
-	}
-	hsp->hs_board_healthy = healthy;
-	return (DDI_SUCCESS);
-}
-
-static int
-hsc_slot_autoconnect(hsc_slot_t *hsp)
-{
-	hsc_state_t *hsc = hsp->hsc;
-	int rc = DDI_SUCCESS;
-	/*
-	 * Keep slot in reset unless autoconfiguration is enabled
-	 * Ie. for Basic Hotswap mode, we stay disconnected at
-	 * insertion. For full hotswap mode, we automatically
-	 * go into connected state at insertion, so that occupant
-	 * autoconfiguration is possible.
-	 */
-	if (((hsc->state & HSC_ENUM_ENABLED) == HSC_ENUM_ENABLED) &&
-			(hsp->hs_flags & HSC_AUTOCFG)) {
-		/* this statement must be here before unreset. */
-		hsc->hsp_last = hsp;
-		if ((rc = scsb_reset_slot(hsp->hs_hpchandle,
-			hsp->hs_slot_number, SCSB_UNRESET_SLOT)) == 0) {
-
-			hsp->hs_slot_state = HPC_SLOT_CONNECTED;
-			hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-					HPC_FAULT_LED, HPC_LED_OFF);
-		} else {
-			hsc->hsp_last = NULL;
-			rc = DDI_FAILURE;
-		}
-	}
-	return (rc);
-}
-
-/*
- * The SCSB code should invoke this function from its _init() function.
- */
-int
-hsc_init()
-{
-	int rc;
-
-	rc = ddi_soft_state_init(&hsc_state, sizeof (hsc_state_t), 1);
-	if (rc != 0)
-		return (rc);
-
-	hsc_slotops = hpc_alloc_slot_ops(KM_SLEEP);
-
-	hsc_slotops->hpc_version	= HPC_SLOT_OPS_VERSION;
-	hsc_slotops->hpc_op_connect	= hsc_connect;
-	hsc_slotops->hpc_op_disconnect	= hsc_disconnect;
-	hsc_slotops->hpc_op_insert	= hsc_insert;
-	hsc_slotops->hpc_op_remove	= hsc_remove;
-	hsc_slotops->hpc_op_control	= hsc_control;
-
-	return (DDI_SUCCESS);
-}
-
-
-/*
- * The SCSB code should invoke this function from its _fini() function.
- */
-int
-hsc_fini()
-{
-	if (hsc_slotops != NULL) {
-		hpc_free_slot_ops(hsc_slotops);
-		hsc_slotops = NULL;
-	}
-	ddi_soft_state_fini(&hsc_state);
-	return (DDI_SUCCESS);
-}
-
-static int
-scsb_enable_enum(hsc_state_t *hsc)
-{
-	DEBUG0("hsc: Enable ENUM#\n");
-
-	if ((hsc->state & HSC_ENUM_ENABLED) == HSC_ENUM_ENABLED)
-		return (DDI_SUCCESS);
-	if ((hsc->state & HSC_ATTACHED) != HSC_ATTACHED)
-		return (DDI_FAILURE);
-
-	if (ddi_add_intr(hsc->dip, 1, NULL, NULL,
-			hsc_enum_intr, (caddr_t)hsc) != DDI_SUCCESS) {
-		cmn_err(CE_WARN, "%s#%d: failed ENUM# interrupt registration",
-			ddi_driver_name(hsc->dip), ddi_get_instance(hsc->dip));
-		return (DDI_FAILURE);
-	}
-	cmn_err(CE_CONT, "?%s%d: Successfully Upgraded to "
-			"Full Hotswap Mode\n", ddi_driver_name(hsc->dip),
-			ddi_get_instance(hsc->dip));
-	hsc->state |= HSC_ENUM_ENABLED;
-	(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsc->dip,
-	    HOTSWAP_MODE_PROP, "full");
-	return (DDI_SUCCESS);
-
-}
-
-/*ARGSUSED*/
-static int
-scsb_disable_enum(hsc_state_t *hsc, int op)
-{
-
-	DEBUG0("hsc: Disable ENUM#\n");
-	if (op == SCSB_HSC_FORCE_REMOVE) {
-		/*
-		 * Clear all pending interrupts before unregistering
-		 * the interrupt. Otherwise the system will hang.
-		 *
-		 * Due to the hang problem, we'll not turn off or disable
-		 * interrupts because if there's a non-friendly full hotswap
-		 * device out there, the ENUM# will be kept asserted and
-		 * hence hsc_clear_all_enum() can never deassert ENUM#.
-		 * So the system will hang.
-		 */
-		if ((hsc->state & HSC_ENUM_ENABLED) == HSC_ENUM_ENABLED) {
-			/* hsc_clear_all_enum(hsc); */
-			ddi_remove_intr(hsc->dip, 1, NULL);
-			hsc->state &= ~HSC_ENUM_ENABLED;
-			cmn_err(CE_CONT, "?%s%d: Successfully Downgraded to "
-				"Basic Hotswap Mode\n",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip));
-		}
-		(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsc->dip,
-		    HOTSWAP_MODE_PROP, "basic");
-		return (DDI_SUCCESS);
-	} else
-		/* No programming interface for disabling ENUM# on MC/Tonga */
-		return (HPC_ERR_NOTSUPPORTED);
-}
-
-#ifndef	lint
-static int
-hsc_clear_all_enum(hsc_state_t *hsc)
-{
-	int i, rc;
-	hsc_slot_t *hsp;
-
-	for (i = 0; i < hsc->slot_table_size; i++) {
-
-		hsp = hsc_find_slot(hsc->slot_table_prop[i].pslotnum);
-		if (hsp == NULL)
-			continue;
-		rc = hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_CLEAR_ENUM,
-						HPC_EVENT_SYNCHRONOUS);
-		if (rc == HPC_EVENT_UNCLAIMED)
-			break;	/* no pending interrupts across the bus */
-		DEBUG1("Pending Intr on slot %d\n",
-			hsc->slot_table_prop[i].pslotnum);
-	}
-	return (0);
-}
-#endif
-
-int
-scsb_hsc_attach(dev_info_t *dip, void *scsb_handle, int instance)
-{
-	int i, n, prop_len;
-	int prom_prop = 0;	/* default: OS property gives slot-table */
-	int rc;
-	char *hotswap_model;
-	hsc_state_t	*hsc;
-	scsb_state_t	*scsb = (scsb_state_t *)scsb_handle;
-	caddr_t hpc_slot_table_data, s;
-	int hpc_slot_table_size;
-	hsc_prom_slot_table_t	*hpstp;
-	int rstate;
-
-	DEBUG0("hsc_attach: enter\n");
-	/*
-	 * To get the slot information,
-	 * The OBP defines the 'slot-table' property. But the OS
-	 * can override it with 'hsc-slot-map' property
-	 * through the .conf file.
-	 * Since the formats are different, 2 different property names
-	 * are chosen.
-	 * The OBP property format is
-	 * <phandle>,<pci-devno>,<phys-slotno>,<ga-bits>
-	 * The OS property format is (ga-bits is not used however)
-	 * <busnexus-path>,<pci-devno>,<phys-slotno>,<ga-bits>
-	 */
-	rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
-		"hsc-slot-map", (caddr_t)&hpc_slot_table_data,
-		&hpc_slot_table_size);
-	if (rc != DDI_PROP_SUCCESS)  {
-		prom_prop = 1;
-		rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
-			"slot-table", (caddr_t)&hpc_slot_table_data,
-			&hpc_slot_table_size);
-		if (rc != DDI_PROP_SUCCESS) {
-			cmn_err(CE_WARN, "%s#%d: 'slot-table' property "
-				"missing!", ddi_driver_name(dip),
-						ddi_get_instance(dip));
-			return (DDI_FAILURE);
-		}
-	}
-	rc = ddi_soft_state_zalloc(hsc_state, instance);
-	if (rc != DDI_SUCCESS)
-		return (DDI_FAILURE);
-
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	hsc->scsb_handle = scsb_handle;
-	hsc->dip = dip;
-	hsc->instance = instance;
-	hsc->n_registered_occupants = 0;
-	hsc->regDone = B_FALSE;
-	/* hsc->slot_info = hsc_slot_list; */
-
-	/*
-	 * Check whether the system should be in basic or full
-	 * hotswap mode. The PROM property always says full, so
-	 * look at the .conf file property whether this is "full"
-	 */
-	if (scsb_hsc_enable_fhs) {
-		hsc->hotswap_mode = HSC_HOTSWAP_MODE_FULL;
-	} else {
-		hsc->hotswap_mode = HSC_HOTSWAP_MODE_BASIC;
-	}
-
-	rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
-		"default-hotswap-mode", (caddr_t)&hotswap_model, &prop_len);
-
-	if (rc == DDI_PROP_SUCCESS) {
-		if (strcmp(hotswap_model, "full") == 0) {
-			hsc->hotswap_mode = HSC_HOTSWAP_MODE_FULL;
-		} else if (strcmp(hotswap_model, "basic") == 0) {
-			hsc->hotswap_mode = HSC_HOTSWAP_MODE_BASIC;
-		}
-
-		kmem_free(hotswap_model, prop_len);
-	}
-
-	/*
-	 * Determine the size of the slot table from the property and
-	 * allocate the slot table arrary..Decoding is different for
-	 * OS and PROM property.
-	 */
-	if (!prom_prop) {	/* OS .conf property */
-		for (i = 0, n = 0; i < hpc_slot_table_size; i++) {
-			if (hpc_slot_table_data[i] == 0) {
-				n++;
-			}
-		}
-
-		/* There should be four elements per entry */
-		if (n % 4) {
-			cmn_err(CE_WARN, "%s#%d: bad format for "
-				"slot-table(%d)", ddi_driver_name(dip),
-						ddi_get_instance(dip), n);
-			kmem_free(hpc_slot_table_data, hpc_slot_table_size);
-			ddi_soft_state_free(hsc_state, instance);
-			return (DDI_FAILURE);
-		}
-
-		hsc->slot_table_size = n / 4;
-	} else {
-		hsc->slot_table_size = hpc_slot_table_size /
-						sizeof (hsc_prom_slot_table_t);
-		n = hpc_slot_table_size % sizeof (hsc_prom_slot_table_t);
-		if (n) {
-			cmn_err(CE_WARN, "%s#%d: bad format for "
-				"slot-table(%d)", ddi_driver_name(dip),
-				ddi_get_instance(dip), hpc_slot_table_size);
-			kmem_free(hpc_slot_table_data, hpc_slot_table_size);
-			ddi_soft_state_free(hsc_state, instance);
-			return (DDI_FAILURE);
-		}
-	}
-
-	/*
-	 * Netract800 FTC (formerly known as CFTM) workaround.
-	 * Leave Slot 2 out of the HS table if FTC is present in Slot 2
-	 */
-	if (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES) {
-		hsc->slot_table_size -= 1;
-	}
-	DEBUG1("hsc_attach: %d hotplug slots on bus\n", hsc->slot_table_size);
-	/*
-	 * Create enough space for each slot table entry
-	 * based on how many entries in the property
-	 */
-	hsc->slot_table_prop = (hsc_slot_table_t *)
-		kmem_zalloc(hsc->slot_table_size *
-			sizeof (hsc_slot_table_t), KM_SLEEP);
-
-	if (!prom_prop) {
-		s = hpc_slot_table_data;
-		for (i = 0; i < hsc->slot_table_size; i++) {
-
-			char *nexus, *pcidev, *phys_slotname, *ga;
-
-			/* Pick off pointer to nexus path or PROM handle */
-			nexus = s;
-			while (*s != NULL)
-				s++;
-			s++;
-
-			/* Pick off pointer to the pci device number */
-			pcidev = s;
-			while (*s != NULL)
-				s++;
-			s++;
-
-			/* Pick off physical slot no */
-			phys_slotname = s;
-			while (*s != NULL)
-				s++;
-			s++;
-
-			/* Pick off GA bits which we dont use for now. */
-			ga = s;
-			while (*s != NULL)
-				s++;
-			s++;
-
-			if (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES &&
-					atoi(phys_slotname) == SC_MC_CTC_SLOT) {
-				--i;
-				continue;
-			}
-			hsc->slot_table_prop[i].pslotnum = atoi(phys_slotname);
-			hsc->slot_table_prop[i].ga = atoi(ga);
-			hsc->slot_table_prop[i].pci_devno = atoi(pcidev);
-			(void) strcpy(hsc->slot_table_prop[i].nexus, nexus);
-		}
-	} else {
-		hpstp = (hsc_prom_slot_table_t *)hpc_slot_table_data;
-		for (i = 0; i < hsc->slot_table_size; i++, hpstp++) {
-			if (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES &&
-					hpstp->pslotnum == SC_MC_CTC_SLOT) {
-				--i;
-				continue;
-			}
-			hsc->slot_table_prop[i].pslotnum = hpstp->pslotnum;
-			hsc->slot_table_prop[i].ga = hpstp->ga;
-			hsc->slot_table_prop[i].pci_devno = hpstp->pci_devno;
-
-			if (prom_phandle_to_path((uint_t)hpstp->phandle,
-				hsc->slot_table_prop[i].nexus,
-				sizeof (hsc->slot_table_prop[i].nexus))
-						== -1) {
-				cmn_err(CE_WARN, "%s#%d: Cannot get phandle "
-					"to nexus path", ddi_driver_name(dip),
-					ddi_get_instance(dip));
-				kmem_free(hsc->slot_table_prop,
-					(hsc->slot_table_size *
-						sizeof (hsc_slot_table_t)));
-				kmem_free(hpc_slot_table_data,
-						hpc_slot_table_size);
-				ddi_soft_state_free(hsc_state, instance);
-				return (DDI_FAILURE);
-			}
-		}
-	}
-
-	/* keep healthy register cache uptodate before reading slot state */
-	if (scsb_read_bhealthy(scsb_handle) != 0) {
-		cmn_err(CE_WARN, "%s#%d: hsc_attach: Cannot read "
-			"Healthy Registers", ddi_driver_name(dip),
-				ddi_get_instance(dip));
-		kmem_free(hsc->slot_table_prop,
-			(hsc->slot_table_size *
-				sizeof (hsc_slot_table_t)));
-		kmem_free(hpc_slot_table_data,
-				hpc_slot_table_size);
-		ddi_soft_state_free(hsc_state, instance);
-		return (DDI_FAILURE);
-	}
-
-	/*
-	 * Before we start registering the slots, calculate how many
-	 * slots are occupied.
-	 */
-
-	for (i = 0; i < hsc->slot_table_size; i++) {
-		if (scsb_get_slot_state(scsb_handle,
-				hsc->slot_table_prop[i].pslotnum, &rstate) !=
-				DDI_SUCCESS)
-				return (rc);
-		if (rstate != HPC_SLOT_EMPTY)
-			hsc->n_registered_occupants++;
-	}
-
-	mutex_init(&hsc->hsc_mutex, NULL, MUTEX_DRIVER, NULL);
-	for (i = 0; i < hsc->slot_table_size; i++) {
-
-		DEBUG2("Registering on nexus [%s] cPCI device [%d]\n",
-			hsc->slot_table_prop[i].nexus,
-			hsc->slot_table_prop[i].pci_devno);
-
-		if (hsc_slot_register(hsc, hsc->slot_table_prop[i].nexus,
-			hsc->slot_table_prop[i].pci_devno,
-			hsc->slot_table_prop[i].pslotnum, B_FALSE) !=
-								HPC_SUCCESS) {
-
-			cmn_err(CE_WARN, "%s#%d: Slot Registration Failure",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-			while (i) {
-				i--;
-				n = hsc->slot_table_prop[i].pslotnum;
-				if (hsc_slot_unregister(n) != 0) {
-					cmn_err(CE_WARN,
-						"%s#%d: failed to unregister"
-						" slot %d",
-						ddi_driver_name(dip),
-						ddi_get_instance(dip), n);
-
-				}
-			}
-			mutex_destroy(&hsc->hsc_mutex);
-			kmem_free(hsc->slot_table_prop, (hsc->slot_table_size *
-					sizeof (hsc_slot_table_t)));
-			kmem_free(hpc_slot_table_data, hpc_slot_table_size);
-			ddi_soft_state_free(hsc_state, instance);
-			return (DDI_FAILURE);
-		}
-	}
-
-	hsc->hsp_last = NULL;
-	hsc->hsc_intr_counter = 0;
-	kmem_free(hpc_slot_table_data, hpc_slot_table_size);
-	(void) ddi_prop_update_string(DDI_DEV_T_NONE, hsc->dip,
-	    HOTSWAP_MODE_PROP, "basic");
-	hsc->state |= (HSC_ATTACHED|HSC_SCB_CONNECTED);
-
-	/*
-	 * We enable full hotswap right here if all the slots are empty.
-	 */
-	if ((hsc->regDone == B_FALSE && hsc->n_registered_occupants == 0) ||
-			scsb_hsc_numReg == hsc->n_registered_occupants) {
-		hsc->regDone = B_TRUE;
-		if (hsc->hotswap_mode == HSC_HOTSWAP_MODE_FULL) {
-			if (scsb_enable_enum(hsc) != DDI_SUCCESS) {
-				cmn_err(CE_WARN, "%s#%d: Cannot enable "
-					"Full Hotswap", ddi_driver_name(dip),
-					ddi_get_instance(dip));
-			}
-		}
-	}
-	return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-int
-scsb_hsc_detach(dev_info_t *dip, void *scsb_handle, int instance)
-{
-	int i = 0;
-	hsc_state_t	*hsc;
-	char slotautocfg_prop[18];
-
-	DEBUG0("hsc_detach: enter\n");
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	if (hsc == NULL) {
-		DEBUG2("%s#%d: hsc_detach: Soft state NULL",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-		return (DDI_FAILURE);
-	}
-
-	if ((hsc->state & HSC_ATTACHED) != HSC_ATTACHED)
-		return (DDI_FAILURE);
-	/*
-	 * let's unregister the hotpluggable slots with hotplug service.
-	 */
-	for (i = 0; i < hsc->slot_table_size; i++) {
-
-		hsc_slot_t	*hsp;
-
-		hsp = hsc_find_slot(hsc->slot_table_prop[i].pslotnum);
-		if (hsp == NULL) {
-			cmn_err(CE_WARN, "%s#%d: hsc_detach: No Slot Info",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-		} else {
-			hpc_led_info_t	aledinfo;	/* active led info. */
-			hpc_led_info_t	fledinfo;	/* fault led info. */
-
-			aledinfo.led = HPC_ACTIVE_LED;
-			aledinfo.state = HPC_LED_BLINK;
-			fledinfo.led = HPC_FAULT_LED;
-			fledinfo.state = HPC_LED_OFF;
-			(void) hsc_led_state(hsp, HPC_CTRL_SET_LED_STATE,
-							&aledinfo);
-			(void) hsc_led_state(hsp, HPC_CTRL_SET_LED_STATE,
-							&fledinfo);
-		}
-		(void) sprintf(slotautocfg_prop, "slot%d-autoconfig",
-		    hsp->hs_slot_number);
-		(void) ddi_prop_remove(DDI_DEV_T_NONE, hsc->dip,
-		    slotautocfg_prop);
-		if (hsc_slot_unregister(hsc->slot_table_prop[i].pslotnum)
-						!= 0) {
-			cmn_err(CE_NOTE, "%s#%d: failed to unregister"
-				" slot %d\n", ddi_driver_name(dip),
-				ddi_get_instance(dip),
-				hsc->slot_table_prop[i].pslotnum);
-			return (DDI_FAILURE);
-		}
-	}
-	kmem_free(hsc->slot_table_prop, (hsc->slot_table_size *
-					sizeof (hsc_slot_table_t)));
-	if ((hsc->state & HSC_ENUM_ENABLED) == HSC_ENUM_ENABLED) {
-		ddi_remove_intr(hsc->dip, 1, hsc->enum_iblock);
-		hsc->state &= ~HSC_ENUM_ENABLED;
-	}
-	mutex_destroy(&hsc->hsc_mutex);
-	(void) ddi_prop_remove(DDI_DEV_T_NONE, hsc->dip, HOTSWAP_MODE_PROP);
-	hsc->state &= ~(HSC_ATTACHED|HSC_SCB_CONNECTED);
-	ddi_soft_state_free(hsc_state, instance);
-	return (DDI_SUCCESS);
-}
-
-/*
- * The following function is called when the SCSB is hot extracted from
- * the system.
- */
-int
-scsb_hsc_freeze(dev_info_t *dip)
-{
-	hsc_state_t	*hsc;
-	int instance = ddi_get_instance(dip);
-	int i;
-	hsc_slot_t	*hsp;
-
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	if (hsc == NULL) {
-		DEBUG2("%s#%d: Soft state NULL",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-		return (DDI_SUCCESS);
-	}
-	if ((hsc->state & HSC_ATTACHED) != HSC_ATTACHED)
-		return (DDI_SUCCESS);
-	hsc->state &= ~HSC_SCB_CONNECTED;
-
-	for (i = 0; i < hsc->slot_table_size; i++) {
-		hsp = hsc_find_slot(hsc->slot_table_prop[i].pslotnum);
-
-		if (hsp == NULL) {
-			cmn_err(CE_NOTE, "hsc_freeze: "
-				" Cannot map slot number %d to a hsc_slot_t",
-					hsc->slot_table_prop[i].pslotnum);
-			continue;
-		}
-		/*
-		 * Since reset lines are pulled low, lets mark these
-		 * slots and not allow a connect operation.
-		 * Note that we still keep the slot as slot disconnected,
-		 * although it is connected from the hardware standpoint.
-		 * As soon as the SCB is plugged back in, we check these
-		 * states and put the hardware state back to its original
-		 * state.
-		 */
-		if (hsp->hs_slot_state == HPC_SLOT_DISCONNECTED) {
-			cmn_err(CE_WARN, "%s#%d: Slot %d Now out of Reset!",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip),
-				hsp->hs_slot_number);
-		}
-		hsp->hs_flags |= HSC_SCB_HOTSWAPPED;
-	}
-
-	return (DDI_SUCCESS);
-}
-
-/*
- * The following function is called when the SCSB is hot inserted from
- * the system. We must update the LED status and set the RST# registers
- * again.
- */
-int
-scsb_hsc_restore(dev_info_t *dip)
-{
-	int i;
-	hsc_state_t	*hsc;
-	hsc_slot_t	*hsp;
-	int instance = ddi_get_instance(dip);
-
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	if (hsc == NULL) {
-		DEBUG2("%s#%d: Soft state NULL",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-		return (DDI_SUCCESS);
-	}
-
-	if ((hsc->state & HSC_ATTACHED) != HSC_ATTACHED)
-		return (DDI_SUCCESS);
-	hsc->state |= HSC_SCB_CONNECTED;
-	for (i = 0; i < hsc->slot_table_size; i++) {
-		hsp = hsc_find_slot(hsc->slot_table_prop[i].pslotnum);
-
-		if (hsp == NULL) {
-			cmn_err(CE_NOTE, "%s#%d: hsc_restore: "
-				" Cannot map slot number %d to a hsc_slot_t",
-					ddi_driver_name(hsc->dip),
-					ddi_get_instance(hsc->dip),
-					hsc->slot_table_prop[i].pslotnum);
-			continue;
-		}
-		if ((hsp->hs_slot_state == HPC_SLOT_DISCONNECTED) &&
-				(hsp->hs_board_configured == B_FALSE)) {
-			if (scsb_reset_slot(hsp->hs_hpchandle,
-					hsp->hs_slot_number,
-					SCSB_RESET_SLOT) != 0) {
-				cmn_err(CE_WARN, "%s#%d: hsc_restore: "
-					" Cannot reset disconnected slot %d",
-						ddi_driver_name(hsc->dip),
-						ddi_get_instance(hsc->dip),
-						hsp->hs_slot_number);
-			}
-		}
-
-		if (scsb_hsc_init_slot_state(hsc, hsp) != DDI_SUCCESS) {
-
-			cmn_err(CE_WARN, "%s#%d: hsc_freeze: Cannot init"
-				" slot%d state",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip),
-				hsp->hs_slot_number);
-		}
-		hsp->hs_flags &= ~HSC_SCB_HOTSWAPPED;
-	}
-	return (DDI_SUCCESS);
-}
-
-#ifndef	lint
-int
-scsb_hsc_freeze_check(dev_info_t *dip)
-{
-	hsc_state_t	*hsc;
-	int instance = ddi_get_instance(dip);
-
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	if (hsc == NULL) {
-		DEBUG2("%s#%d: Soft state NULL",
-				ddi_driver_name(dip), ddi_get_instance(dip));
-		return (DDI_SUCCESS);
-	}
-	if ((hsc->state & HSC_ATTACHED) != HSC_ATTACHED)
-		return (DDI_SUCCESS);
-	return (DDI_SUCCESS);
-}
-#endif
-
-/*
- * update info about Alarm Card insert/remove mechanism.
- */
-void
-hsc_ac_op(int instance, int pslotnum, int op, void *arg)
-{
-	hsc_slot_t *hsp;
-	hsc_state_t	*hsc;
-
-	hsc = (hsc_state_t *)ddi_get_soft_state(hsc_state, instance);
-	if (hsc == NULL) {
-		cmn_err(CE_WARN, "%s#%d: hsc_ac_op: No Soft State Info",
-			ddi_driver_name(hsc->dip), ddi_get_instance(hsc->dip));
-		return;
-	}
-
-	hsp = hsc_find_slot(pslotnum);
-	if (hsp == NULL) {
-		cmn_err(CE_WARN, "%s#%d: hsc_ac_op: No Slot Info",
-			ddi_driver_name(hsc->dip), ddi_get_instance(hsc->dip));
-		return;
-	}
-
-	switch (op) {
-		case SCSB_HSC_AC_UNCONFIGURE :
-			/*
-			 * If ENUM# is enabled, then action is pending on
-			 * this slot, just send a event.
-			 */
-			if (hsc->state & HSC_ENUM_ENABLED)
-				(void) hpc_slot_event_notify(
-				    hsp->hs_slot_handle,
-				    HPC_EVENT_PROCESS_ENUM, 0);
-			break;
-		case SCSB_HSC_AC_GET_SLOT_INFO :
-			*(hsc_slot_t **)arg = hsp;
-			break;
-		default :
-			break;
-	}
-}
-
-static uint_t
-hsc_enum_intr(caddr_t iarg)
-{
-	int rc;
-	hsc_state_t *hsc = (hsc_state_t *)iarg;
-	hsc_slot_t *hsp;
-
-	DEBUG0("!E!");
-	if ((hsc->state & HSC_ATTACHED) == 0)
-		return (DDI_INTR_UNCLAIMED);
-
-	hsp = hsc_find_slot(hsc->slot_table_prop[0].pslotnum);
-	if (hsp == NULL)	/* No slots registered */
-		return (DDI_INTR_UNCLAIMED);
-
-	/*
-	 * The following must be done to clear interrupt (synchronous event).
-	 * To process the interrupt, we send an asynchronous event.
-	 */
-	rc = hpc_slot_event_notify(hsp->hs_slot_handle,
-					HPC_EVENT_CLEAR_ENUM,
-						HPC_EVENT_SYNCHRONOUS);
-	if (rc == HPC_EVENT_UNCLAIMED) {
-		/*
-		 * possible support for handling insertion of non friendly
-		 * full hotswap boards, otherwise the system hangs due
-		 * to uncleared interrupt bursts.
-		 */
-		DEBUG2("!E>counter %d, last op@slot %lx\n",
-				hsc->hsc_intr_counter, hsc->hsp_last);
-		hsc->hsc_intr_counter ++;
-		if (hsc->hsc_intr_counter == scsb_hsc_max_intr_count) {
-			if (!hsc->hsp_last) {
-				cmn_err(CE_WARN, "%s#%d: hsc_enum_intr: "
-					" No Last Board Insertion Info.",
-					ddi_driver_name(hsc->dip),
-					ddi_get_instance(hsc->dip));
-				hsc->hsc_intr_counter = 0;
-				return (DDI_INTR_UNCLAIMED);
-			}
-			hsp = hsc->hsp_last;
-			cmn_err(CE_WARN, "%s#%d: Bad (non friendly ?) Board "
-				"in Slot %d ? Taking it Offline.",
-				ddi_driver_name(hsc->dip),
-				ddi_get_instance(hsc->dip),
-				hsp->hs_slot_number);
-			/*
-			 * this should put just inserted board back in
-			 * reset, thus deasserting the ENUM# and the
-			 * system hang.
-			 */
-			if (scsb_reset_slot(hsp->hs_hpchandle,
-					hsp->hs_slot_number,
-					SCSB_RESET_SLOT) == 0) {
-				/* Enumeration failed on this board */
-				hsp->hs_flags |= HSC_ENUM_FAILED;
-				if (hsp->hs_board_configured == B_TRUE)
-					cmn_err(CE_WARN, "%s#%d: ALERT! System"
-						" now in Inconsistent State."
-						" Halt!",
-					    ddi_driver_name(hsc->dip),
-					    ddi_get_instance(hsc->dip));
-				hsc_led_op(hsp, HPC_CTRL_SET_LED_STATE,
-						HPC_FAULT_LED, HPC_LED_ON);
-			}
-			hsc->hsc_intr_counter = 0;
-		}
-		return (DDI_INTR_UNCLAIMED);
-	}
-	hsc->hsc_intr_counter = 0;
-	/*
-	 * if interrupt success, rc denotes the PCI device number which
-	 * generated the ENUM# interrupt.
-	 */
-	hsp = hsc_get_slot_info(hsc, rc);
-	if (hsp == NULL) {
-		cmn_err(CE_WARN, "%s#%d: hsc_enum_intr: no slot info for "
-			"dev %x", ddi_driver_name(hsc->dip),
-			ddi_get_instance(hsc->dip), rc);
-		return (DDI_INTR_CLAIMED);	/* interrupt already cleared */
-	}
-	/* if this is Alarm Card and if it is busy, dont process event */
-	if (hsp->hs_flags & HSC_ALARM_CARD_PRES) {
-		if (scsb_hsc_ac_op(hsp->hs_hpchandle, hsp->hs_slot_number,
-						SCSB_HSC_AC_BUSY) == B_TRUE) {
-			/*
-			 * Busy means we need to inform (envmond)alarmcard.so
-			 * that it should save the AC configuration, stop the
-			 * heartbeat, and shutdown the RSC link.
-			 */
-			(void) scsb_hsc_ac_op(hsp->hs_hpchandle,
-					hsp->hs_slot_number,
-					SCSB_HSC_AC_REMOVAL_ALERT);
-			return (DDI_INTR_CLAIMED);
-		}
-	}
-	/*
-	 * If SCB was swapped out, dont process ENUM#. We put this slot
-	 * back in reset after SCB is inserted.
-	 */
-	if ((hsp->hs_flags & HSC_SCB_HOTSWAPPED) &&
-			(hsp->hs_slot_state == HPC_SLOT_DISCONNECTED))
-		return (DDI_INTR_CLAIMED);
-
-	(void) hpc_slot_event_notify(hsp->hs_slot_handle,
-	    HPC_EVENT_PROCESS_ENUM, 0);
-	return (DDI_INTR_CLAIMED);
-}
-/*
- * A routine to convert a number (represented as a string) to
- * the integer value it represents.
- */
-
-static int
-isdigit(int ch)
-{
-	return (ch >= '0' && ch <= '9');
-}
-
-#define	isspace(c)	((c) == ' ' || (c) == '\t' || (c) == '\n')
-#define	bad(val)	(val == NULL || !isdigit(*val))
-
-static int
-atoi(const char *p)
-{
-	int n;
-	int c, neg = 0;
-
-	if (!isdigit(c = *p)) {
-		while (isspace(c))
-			c = *++p;
-		switch (c) {
-			case '-':
-				neg++;
-				/* FALLTHROUGH */
-			case '+':
-			c = *++p;
-		}
-		if (!isdigit(c))
-			return (0);
-	}
-	for (n = '0' - c; isdigit(c = *++p); ) {
-		n *= 10; /* two steps to avoid unnecessary overflow */
-		n += '0' - c; /* accum neg to avoid surprises at MAX */
-	}
-	return (neg ? n : -n);
-}
