changeset 4022:66494e9fa1c4

PSARC 2006/703 MPxIO extension for Serial Attached SCSI (SAS) on mpt(7D) PSARC 2007/046 stmsboot(1M) extension for mpt(7D) 6442215 mpt.conf maybe over written because the filetype within the SUNWckr package is 'f' 6443044 add mpxio support to SAS mpt driver 6502231 stmsboot needs to support SAS devices 6510425 the properties "flow_control" and "queue" in mpt.conf is useless 6525558 untagged command unlikely to be sent to HBA during heavy I/O 6545198 build should allow architecture dependent class action scripts
author jw149990
date Thu, 12 Apr 2007 18:26:33 -0700
parents 4a874a55e21a
children 2a35fc2ee7d3
files usr/src/cmd/stmsboot/mpxio-upgrade usr/src/cmd/stmsboot/stmsboot.sh usr/src/cmd/stmsboot/stmsboot_util.c usr/src/pkgdefs/SUNWckr/Makefile usr/src/pkgdefs/SUNWckr/pkginfo.tmpl usr/src/pkgdefs/SUNWckr/prototype_i386 usr/src/pkgdefs/SUNWpd/Makefile usr/src/pkgdefs/SUNWpd/pkginfo.tmpl usr/src/pkgdefs/SUNWpd/prototype_sparc usr/src/pkgdefs/bld_awk_pkginfo.ksh usr/src/pkgdefs/common_files/i.kclasses_i386 usr/src/pkgdefs/common_files/i.kclasses_sparc usr/src/pkgdefs/common_files/i.mptconf usr/src/tools/scripts/bfu.sh usr/src/uts/common/io/scsi/impl/scsi_hba.c usr/src/uts/common/io/warlock/mpt.wlcmd usr/src/uts/intel/os/driver_classes usr/src/uts/sparc/os/driver_classes
diffstat 18 files changed, 1035 insertions(+), 192 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/stmsboot/mpxio-upgrade	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/cmd/stmsboot/mpxio-upgrade	Thu Apr 12 18:26:33 2007 -0700
@@ -38,6 +38,8 @@
 METADEVADM=/usr/sbin/metadevadm
 usrmounted=0
 MACH=`/usr/bin/uname -p`
+EGREP=/usr/bin/egrep
+SED=/usr$SED
 
 # map $special and $fsckdev
 mpxio_mapdev()
@@ -169,11 +171,11 @@
 	NOINUSE_CHECK=1
 	export NOINUSE_CHECK
 
-	set -- `dumpadm -u 2>&1 | egrep 'cannot use /dev.* as dump device'`
+	set -- `dumpadm -u 2>&1 | $EGREP 'cannot use /dev.* as dump device'`
 	if [ "x$4" != x ]; then
 		newname=`$STMSBOOTUTIL -M $4`
 		if [ $? -eq 0 ]; then
-			if dumpadm -d $newname > /dev/null; then
+			if /usr/sbin/dumpadm -d $newname > /dev/msglog 2> /dev/console; then
 				cecho "stmsboot: dump configuration has been \
 updated."
 			else
@@ -189,16 +191,17 @@
 # Update bootpath for x86 here when we are enabling mpxio on root
 update_bootpath()
 {
-	cur_bootpath=`eeprom bootpath | sed 's/bootpath=[ 	]*//g' | sed 's/[ 	].*//'`
+	cur_bootpath=`/usr/sbin/eeprom bootpath | $SED 's/bootpath=[ 	]*//g' | $SED 's/[ 	].*//'`
 	# only take care of phci-based path here 
-	echo $cur_bootpath | egrep -s "/fp@.*/disk@.*"
+	PHCIOPT=`$STMSBOOTUTIL -D mpt -n`
+	echo $cur_bootpath | $EGREP -s "/fp@.*/disk|$PHCIOPT"
 
 	if [ $? -eq 0 ]; then
 		new_bootpath=`$STMSBOOTUTIL -m /devices$cur_bootpath`
 		if [ $? -eq 0 -a "x$new_bootpath" != "x" ]; then
 			# stmsboot_util -m phci-based path got mapped path back means
 			# mpxio is enabled on bootpath
-			new_bootpath=`echo $new_bootpath|sed "s/.*\/devices//"`
+			new_bootpath=`echo $new_bootpath|$SED "s/.*\/devices//"`
 			/usr/sbin/eeprom bootpath=$new_bootpath
 			cecho "stmsboot: bootpath has been updated"
 
--- a/usr/src/cmd/stmsboot/stmsboot.sh	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/cmd/stmsboot/stmsboot.sh	Thu Apr 12 18:26:33 2007 -0700
@@ -28,30 +28,45 @@
 PATH=/usr/bin:/usr/sbin:$PATH; export PATH
 STMSBOOTUTIL=/lib/mpxio/stmsboot_util
 STMSMETHODSCRIPT=/lib/svc/method/mpxio-upgrade
-FPCONF=/kernel/drv/fp.conf
-TMPFPCONF=/var/run/tmp.fp.conf.$$
-TMPFPCONF_MPXIO_ENTRY=/var/run/tmp.fp.conf.mpxioentry.$$
+KDRVCONF=
+DRVCONF=
+TMPDRVCONF=
+TMPDRVCONF_MPXIO_ENTRY=
+DRVLIST=
+GUID=
 VFSTAB=/etc/vfstab
 SAVEDIR=/etc/mpxio
 RECOVERFILE=$SAVEDIR/recover_instructions
 SVCCFG_RECOVERY=$SAVEDIR/svccfg_recover
-USAGE=`gettext "Usage: stmsboot -e | -d | -u | -L | -l controller_number"`
+SUPPORTED_DRIVERS="fp|mpt"
+USAGE=`gettext "Usage: stmsboot [-D $SUPPORTED_DRIVERS] -e | -d | -u | -L | -l controller_number"`
 TEXTDOMAIN=SUNW_OST_OSCMD
 export TEXTDOMAIN
 STMSINSTANCE=system/device/mpxio-upgrade:default
+STMSBOOT=/usr/sbin/stmsboot
+BOOTADM=/sbin/bootadm
+MOUNT=/usr/sbin/mount
+EGREP=/usr/bin/egrep
+GREP=/usr/bin/grep
+AWK=/usr/bin/awk
+SORT=/usr/bin/sort
+UNIQ=/usr/bin/uniq
+EXPR=/usr/bin/expr
 
 MACH=`/usr/bin/uname -p`
-if [ "x$MACH" = "xsparc" ]; then
-	CLIENT_TYPE_VHCI="/scsi_vhci.*/ssd@.*"
-	CLIENT_TYPE_PHCI="/fp@.*/ssd@.*"
-else
-	CLIENT_TYPE_VHCI="/scsi_vhci.*/disk@.*"
-	CLIENT_TYPE_PHCI="/fp@.*/disk@.*"
-	BOOTENV_FILE=/boot/solaris/bootenv.rc
-fi
+BOOTENV_FILE=/boot/solaris/bootenv.rc
+
+CLIENT_TYPE_VHCI="/scsi_vhci.*/ssd@|/scsi_vhci.*/disk@"
+# The phci client type egrep string will change based on the
+# drivers which we are operating on, and the cpu architecture
+# and we call stmsboot_util -n -D $drv to get that string
+CLIENT_TYPE_PHCI=
+reboot_needed=0
+
 #
-# Copy all entries (including comments) from source driver.conf to destination
-# driver.conf except those entries which contain mpxio-disable property.
+# Copy all entries (including comments) from source driver.conf
+# to destination driver.conf except those entries which contain
+# the mpxio-disable property.
 # Take into consideration entries that spawn more than one line.
 #
 # $1	source driver.conf file
@@ -119,12 +134,12 @@
 
 	if [ "x$cmd" = xupdate ]; then
 		gettext "\tUndo the modifications you made to STMS configuration.\n\tFor example undo any changes you made to " >> $RECOVERFILE
-		echo "/mnt$FPCONF." >> $RECOVERFILE
+		echo "/mnt$KDRVCONF." >> $RECOVERFILE
 	else
-		echo "\tcp /mnt${SAVEDIR}/fp.conf /mnt$FPCONF" >> $RECOVERFILE
+		echo "\tcp /mnt${SAVEDIR}/$DRVCONF /mnt$KDRVCONF" >> $RECOVERFILE
 	fi
 
-	if [ $1 -eq 1 ]; then
+	if [ $1 -ne 0 ]; then
 		echo "\tcp /mnt${SAVEDIR}/vfstab /mnt$VFSTAB" >> $RECOVERFILE
 
 		echo "repository /mnt/etc/svc/repository.db" > $SVCCFG_RECOVERY
@@ -139,7 +154,7 @@
 		fi
 	fi
 
-	rootdisk=`mount | grep "/ on " | cut -f 3 -d " "`
+	rootdisk=`$MOUNT | $GREP "/ on " | cut -f 3 -d " "`
 	echo "\tumount /mnt\n\treboot\n\n${rootdisk} \c" >> $RECOVERFILE
 	gettext "was your root device,\nbut it could be named differently after you boot net.\n" >> $RECOVERFILE
 }
@@ -147,53 +162,101 @@
 #
 # Arrange for /etc/vfstab and dump configuration to be updated
 # during the next reboot. If the cmd is "enable" or "disable", copy
-# $TMPFPCONF to $FPCONF.
+# $TMPDRVCONF to $KDRVCONF.
 #
 # Returns 0 on success, 1 on failure.
 #
 update_sysfiles()
 {
+
 	gettext "WARNING: This operation will require a reboot.\nDo you want to continue ? [y/n] (default: y) "
 	read response
 
 	if [ "x$response" != x -a "x$response" != xy -a \
 	    "x$response" != xY ]; then
-		rm -f $TMPFPCONF
-		return 0
+		for d in $DRVLIST; do
+			TMPDRVCONF=/var/run/tmp.$d.conf.$$
+			rm -f $TMPDRVCONF > /dev/null 2>&1
+		done;
+		return 0;
 	fi
 
-	need_bootscript=1
+	need_bootscript=""
+
 	if [ "x$cmd" = xenable -o "x$cmd" = xdisable ]; then
-		cp $FPCONF $SAVEDIR
-		cp $TMPFPCONF $FPCONF
-		rm -f $TMPFPCONF
+
+		for d in $DRVLIST; do
+			DRVCONF=$d.conf
+			KDRVCONF=/kernel/drv/$d.conf
+			TMPDRVCONF=/var/run/tmp.$d.conf.$$
+
+			cp $KDRVCONF $SAVEDIR
+			cp $TMPDRVCONF $KDRVCONF
+			rm -f $TMPDRVCONF  > /dev/null 2>&1
+
+			#
+			# there is no need to update the system files in the following
+			# cases:
+			# - we are enabling mpxio and the system has no configured
+			#   disks accessible by phci paths.
+			# - we are disabling mpxio and the system has no configured
+			#   disks accessible by vhci paths.
+			#
+
+			build_parent_list $d;
+			if [ "x$CLIENT_TYPE_PHCI" = "x" ]; then
+				continue;
+			fi
 
-		#
-		# there is no need to update the system files in the following
-		# cases:
-		# - we are enabling mpxio and the system has no configured
-		#   disks accessible by phci paths.
-		# - we are disabling mpxio and the system has no configured
-		#   disks accessible by vhci paths.
-		#
-		if [ "x$cmd" = xenable ]; then
-			ls -l /dev/dsk/*s2 2> /dev/null | \
-			    egrep -s $CLIENT_TYPE_PHCI
-		else
-			ls -l /dev/dsk/*s2 2> /dev/null | \
-			    egrep -s $CLIENT_TYPE_VHCI
-		fi
+			if [ "x$cmd" = "xenable" ]; then
+				ls -l /dev/dsk/*s2 2> /dev/null | \
+				    $EGREP -s "$CLIENT_TYPE_PHCI"
+			else
+				ls -l /dev/dsk/*s2 2> /dev/null | \
+				    $EGREP -s "$CLIENT_TYPE_VHCI"
+			fi
+
+			if [ $? -ne 0 ]; then
+				need_bootscript="$need_bootscript $d"
+			fi
+		done
+	fi
+
+	# if we're an x86/x64 machine and our bootpath is on fibrechannel
+	# then we cannot disable mpxio for that controller. Yet.....
+	# This code block is an ugly hack and when we either get full-time
+	# mpxio for all devices, or devfsadm gets re-written then we can
+	# remove it. For now, though, we have to see the beauty in ugly.
 
-		if [ $? -ne 0 ]; then
-			need_bootscript=0
+	if [ "x$MACH" = "xi386" ]; then
+		BOOTPATH=`/usr/sbin/eeprom bootpath | $AWK -F"=" '{print $2}'`
+		FPBOOT=`echo "$BOOTPATH" | $GREP "/fp@"`
+		if [ ! -z "$FPBOOT" ]; then
+			NEWP=`/usr/bin/dirname $BOOTPATH`
+			NNEWP=`/usr/bin/dirname $NEWP`
+
+			# check that we haven't already got this entry
+			# in /kernel/drv/fp.conf.
+
+			EXISTP=`$GREP "^name.*$NNEWP" /kernel/drv/fp.conf`
+#			if [ -z "$EXISTP" ]; then
+			if [ $? != 0 ]; then
+				cat >>/kernel/drv/fp.conf << EOF
+# This entry must be the last one in the fp.conf file
+# to ensure that the boot path mpxio setting is not
+# accidentally overridden
+name="fp" parent="$NNEWP" port=0 mpxio-disable="no";
+EOF
+			fi
 		fi
 	fi
 
-	if [ $need_bootscript -eq 1 ]; then
+	if [ -z "$need_bootscript" ]; then
+		need_bootscript=0
 		if [ "x$MACH" = "xi386" -a "x$new_bootpath" != "x" ]; then
 			#only update bootpath for x86.
 			cp $BOOTENV_FILE $SAVEDIR
-			eeprom bootpath=$new_bootpath
+			/usr/sbin/eeprom bootpath=$new_bootpath
 		fi
 		#
 		# Enable the mpxio-upgrade service, but don't run it now.
@@ -209,12 +272,16 @@
 
 	build_recover $need_bootscript
 
+	if [ "x$MACH" = "xi386" ]; then
+		$BOOTADM update-archive
+	fi
+
 	gettext "The changes will come into effect after rebooting the system.\nReboot the system now ? [y/n] (default: y) "
 	read response
 
 	if [ "x$response" = x -o "x$response" = xy -o \
 	    "x$response" = xY ]; then
-		reboot
+		/usr/sbin/reboot
 	fi
 
 	return 0
@@ -224,6 +291,11 @@
 # Enable or disable mpxio as specified by the cmd.
 # Returns 0 on success, 1 on failure.
 #
+# Args: $cmd = {enable | disable}
+#	$d = {fp | mpt}
+#
+# the global variable $DRVLIST is used
+#
 configure_mpxio()
 {
 	mpxiodisableno='mpxio-disable[ 	]*=[ 	]*"no"[ 	]*;'
@@ -232,51 +304,46 @@
 	if [ "x$cmd" = xenable ]; then
 		mpxiodisable_cur_entry=$mpxiodisableyes
 		propval=no
-		msg=`gettext "STMS already enabled."`
+		msg=`gettext "STMS already enabled"`
 	else
 		mpxiodisable_cur_entry=$mpxiodisableno
 		propval=yes
-		msg=`gettext "STMS already disabled."`
+		msg=`gettext "STMS already disabled"`
 	fi
 
-	if delete_mpxio_disable_entries $FPCONF $TMPFPCONF $TMPFPCONF_MPXIO_ENTRY; then
-		if [ -s $TMPFPCONF_MPXIO_ENTRY ]; then
-			# fp.conf does have mpxiodisable entries
-			egrep -s "$mpxiodisable_cur_entry" $TMPFPCONF_MPXIO_ENTRY
+	DRVCONF=$d.conf
+	KDRVCONF=/kernel/drv/$d.conf
+	TMPDRVCONF=/var/run/tmp.$d.conf.$$
+	TMPDRVCONF_MPXIO_ENTRY=/var/run/tmp.$d.conf.mpxioentry.$$;
+
+	echo "Checking mpxio status for driver $d"
+	if delete_mpxio_disable_entries $KDRVCONF $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY; then
+
+		if [ -s $TMPDRVCONF_MPXIO_ENTRY ]; then
+			# $DRVCONF does have mpxiodisable entries
+			$EGREP -s "$mpxiodisable_cur_entry" $TMPDRVCONF_MPXIO_ENTRY
 			if [ $? -ne 0 ]; then
 				# if all mpxiodisable entries are no/yes for
 				# enable/disable mpxio, notify the user
-				rm -f $TMPFPCONF $TMPFPCONF_MPXIO_ENTRY
-				echo "$msg"
-				return 0
+				rm -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY > /dev/null 2>&1
+				continue;
+			else
+				reboot_needed=`$EXPR $reboot_needed + 1`
 			fi
-			# If mpxiodisable entries does not exist, always continue update
+
+			# If mpxiodisable entries do not exist, always continue update
 		fi
 	else
-		rm -f $TMPFPCONF $TMPFPCONF_MPXIO_ENTRY
-		gettext "failed to update " 1>&2 
-		echo "$FPCONF." 1>&2 
+		rm -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY > /dev/null 2>&1
+		gettext "failed to update " 1>&2
+		echo "$KDRVCONF." 1>&2 
 		gettext "No changes were made to your STMS configuration.\n" 1>&2
 		return 1
 	fi
 
-	rm $TMPFPCONF_MPXIO_ENTRY
-	echo "mpxio-disable=\"${propval}\";" >> $TMPFPCONF
+	rm $TMPDRVCONF_MPXIO_ENTRY > /dev/null 2>&1
+	echo "mpxio-disable=\"${propval}\";" >> $TMPDRVCONF
 
-	#Need to update bootpath on x86 if boot system from FC disk
-	#Only update bootpath before reboot when mpxio is enabled
-	#If mpxio is disabled currently, will update bootpath in mpxio-upgrade
-	if [ "x$MACH" = "xi386" -a "x$cmd" = "xdisable" ]; then
-		get_newbootpath_for_stmsdev
-		if [ $? -ne 0 ]; then
-			rm -f $TMPFPCONF
-			gettext "failed to update bootpath.\n" 1>&2
-			gettext "No changes were made to your STMS configuration.\n" 1>&2
-			return 1
-		fi
-	fi
-	update_sysfiles
-	return $?
 }
 
 setcmd()
@@ -289,23 +356,26 @@
 	fi
 }
 
-
+#
 #Need to update bootpath on x86 if boot system from FC disk
 #Only update bootpath here when mpxio is enabled
 #If mpxio is disabled currently, will update bootpath in mpxio-upgrade
+#
+
 get_newbootpath_for_stmsdev() {
 	if [ "x$cmd" = "xenable" ]; then
 		return 0
 	fi
 
-	cur_bootpath=`eeprom bootpath | sed 's/bootpath=[ 	]*//g' | sed 's/[ 	]*$//'`
+	cur_bootpath=`eeprom bootpath | \
+	    sed 's/bootpath=[ 	]*//g' | sed 's/[ 	]*$//'`
 	if [ "x$cur_bootpath" = "x" ]; then
 		gettext "failed to get bootpath by eeprom\n" 1>&2
 		return 1
 	fi
 
 	#only update bootpath for STMS path
-	echo $cur_bootpath|grep $CLIENT_TYPE_VHCI > /dev/null 2>&1
+	echo $cur_bootpath|$EGREP $CLIENT_TYPE_VHCI > /dev/null 2>&1
 	if [ $? -eq 1 ]; then
 		return 0
 	fi
@@ -315,13 +385,80 @@
 		new_bootpath=""
 		return 1
 	fi
+
+	# we replace "sd" with "disk" if we need to work on the eeprom
+	# bootpath setting, since fibre-channel devices will report as
+	# being attached via "disk" and not "sd". One day we'll have a
+	# truly unified and architecture-independent view of the device
+	# tree, and this block will be redundant
+	fp_bootpath=`echo $new_bootpath|grep fp.*sd`
+	if [ "x$fp_bootpath" != "x" ]; then
+		new_bootpath=`echo $fp_bootpath |sed -e"s,sd,disk,g"`
+	fi
+}
+
+#
+# Emit a warning message to the user that by default we
+# operate on all multipath-capable controllers that are
+# attached to the system, and that if they want to operate
+# on only a specific controller type (fp|mpt|....) then 
+# they need to re-invoke stmsboot with "-D $driver" in
+# their argument list
+#
+
+emit_driver_warning_msg() {
+
+	# for each driver that we support, grab the list
+	# of controllers attached to the system.
+
+	echo "WARNING: stmsboot operates on each supported multipath-capable controller"
+	echo "         detected in a host. In your system, these controllers are"
+
+	for WARNDRV in fp mpt; do
+		$GREP "$WARNDRV.$" /etc/path_to_inst | $AWK -F"\"" '{print "/devices"$2}'
+	done;
+	
+	echo ""
+	echo "If you do NOT wish to operate on these controllers, please quit stmsboot"
+	echo "and re-invoke with -D { fp | mpt } to specify which controllers you wish"
+	echo "to modify your multipathing configuration for."
+
+	echo
+	gettext "Do you wish to continue? [y/n] (default: y) " 1>&2
+	read response
+
+	if [ "x$response" -ne "xY" -a "x$response" -ne "xy" ]; then
+		exit
+	fi
+
+}
+
+# Function to setup the CLIENT_TYPE_PHCI string based on
+# the list of drivers that we're operating on. The variable
+# depends upon the pathname of the parent node in the 
+# device tree, which can be different on x86/x64 and sparc.
+# Oh, if we only had OBP on x86/x64!
+build_parent_list() {
+
+	# stmsboot_util -n provides us with the name of the
+	# node containing "fp" or "sas-$d", and helpfully
+	# appends "/[ssd|sd]@" as appropriate
+
+	d=$1;
+
+	TLIST=`$STMSBOOTUTIL -D $d -n`
+	if [ "x$TLIST" != "x" ]; then
+		CLIENT_TYPE_PHCI="$TLIST|$CLIENT_TYPE_PHCI"
+	else
+		CLIENT_TYPE_PHCI="$CLIENT_TYPE_PHCI"
+	fi
 }
 
 
 cmd=none
 
 # process options
-while getopts eduLl: c
+while getopts D:geduLl: c
 do
 	case $c in
 	e)	setcmd enable;;
@@ -330,6 +467,8 @@
 	L)	setcmd listall;;
 	l)	setcmd list
 		controller=$OPTARG;;
+	D)	DRV=$OPTARG;;
+	g)	GUID="-g";;
 	\?)	echo "$USAGE" 1>&2
 		exit 2;;
 	esac
@@ -340,8 +479,16 @@
 	exit 2
 fi
 
-set `id`
-if [ "$1" != "uid=0(root)" ]; then
+if [ "x$DRV" = "x" ]; then
+	DRVLIST="fp mpt"
+else
+	DRVLIST=$DRV
+fi
+
+
+STMSPRIVS=`/usr/bin/ppriv $$ | $EGREP "E:.*all|E:.*sys_devices"`
+USERID=`id`
+if [ "$USERID" != "uid=0(root) gid=0(root)" ] -o [ "x$STMSPRIVS" == "x" ]; then
 	gettext "You must be super-user to run this script.\n" 1>&2
 	exit 1
 fi
@@ -353,11 +500,30 @@
 	exit 1
 fi
 
-svcprop -q $STMSINSTANCE
+# If the old sun4u-specific SMF method is found, remove it
+/usr/sbin/svccfg -s "platform/sun4u/mpxio-upgrade:default" < /dev/null > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+	/usr/sbin/svccfg delete "platform/sun4u/mpxio-upgrade:default" > /dev/null 2>&1
+fi
+
+# now import the new service, if necessary
+/usr/bin/svcprop -q $STMSINSTANCE < /dev/null > /dev/null 2>&1
 if [ $? -ne 0 ]; then
-	fmt=`gettext "Can't find %s service"`
-	printf "$fmt\n" "$STMSINSTANCE" 1>&2
-	exit 1
+	if [ -f /var/svc/manifest/system/device/mpxio-upgrade.xml ]; then
+		/usr/sbin/svccfg import /var/svc/manifest/system/device/mpxio-upgrade.xml
+		if [ $? -ne 0 ]; then
+			fmt=`gettext "Unable to import %s service"`
+			printf "$fmt\n" "$STMSINSTANCE" 1>&2
+			exit 1
+		else
+			fmt=`gettext "Service %s imported successfully, continuing"`
+			printf "$fmt\n" "$STMSINSTANCE" 1>&2
+		fi
+	else
+		fmt=`gettext "Service %s does not exist on this host"`
+ 		printf "$fmt\n" "$STMSINSTANCE" 1>&2
+		exit 1
+	fi
 fi
 
 if [ "x$cmd" = xenable -o "x$cmd" = xdisable -o "x$cmd" = xupdate ]; then
@@ -365,7 +531,7 @@
 	# The bootup script doesn't work on cache-only-clients as the script
 	# is executed before the plumbing for cachefs mounting of root is done.
 	#
-	if mount -v | egrep -s " on / type (nfs|cachefs) "; then
+	if $MOUNT -v | $EGREP -s " on / type (nfs|cachefs) "; then
 		gettext "This command option is not supported on systems with nfs or cachefs mounted root filesystem.\n" 1>&2
 		exit 1
 	fi
@@ -375,11 +541,18 @@
 		# keep a copy of the last saved files, useful for manual
 		# recovery in case of a problem.
 		#
-		if [ "x$MACH" = "xsparc" ]; then
-			backup_lastsaved $FPCONF $VFSTAB
-		else
-			backup_lastsaved $FPCONF $VFSTAB $BOOTENV_FILE
-		fi
+		for d in $DRVLIST; do
+			DRVCONF=$d.conf
+			KDRVCONF=/kernel/drv/$d.conf
+			TMPDRVCONF=/var/run/tmp.$d.conf.$$
+			TMPDRVCONF_MPXIO_ENTRY=/var/run/tmp.$d.conf.mpxioentry.$$;
+
+			if [ "x$MACH" = "xsparc" ]; then
+				backup_lastsaved $KDRVCONF $VFSTAB
+			else
+				backup_lastsaved $KDRVCONF $VFSTAB $BOOTENV_FILE
+			fi
+		done
 	else
 		mkdir $SAVEDIR
 	fi
@@ -387,7 +560,38 @@
 fi
 
 if [ "x$cmd" = xenable -o "x$cmd" = xdisable ]; then
-	configure_mpxio $cmd
+
+	msgneeded=`echo "$DRVLIST" |grep " "`
+	if [ -n "$msgneeded" ]; then
+		emit_driver_warning_msg
+	fi
+	for d in $DRVLIST; do
+		configure_mpxio $cmd $d
+	done
+
+	if [ $reboot_needed -ne 0 ]; then
+
+		# Need to update bootpath on x86 if our boot device is
+		# now accessed through mpxio.
+		# Only update bootpath before reboot when mpxio is enabled
+		# If mpxio is currently disabled, we will update bootpath
+		# on reboot in the mpxio-upgrade service
+		
+		if [ "x$MACH" = "xi386" -a "x$cmd" = "xdisable" ]; then
+			get_newbootpath_for_stmsdev
+			if [ $? -ne 0 ]; then
+				rm -f $TMPDRVCONF > /dev/null 2>&1
+				gettext "failed to update bootpath.\n" 1>&2
+				gettext "No changes were made to your STMS configuration.\n" 1>&2
+				return 1
+			fi
+		fi
+		update_sysfiles
+	else
+		echo "STMS is already ${cmd}d. No changes or reboots needed"
+	fi
+
+
 elif [ "x$cmd" = xupdate ]; then
 	if [ "x$MACH" = "xi386" ]; then
 	# In this case we always change the bootpath to phci-based
@@ -400,10 +604,11 @@
 		fi
 	fi
 	update_sysfiles
+
 elif [ "x$cmd" = xlist ]; then
-	$STMSBOOTUTIL -l $controller
+		$STMSBOOTUTIL $GUID -l $controller
 else
-	$STMSBOOTUTIL -L
+		$STMSBOOTUTIL $GUID -L
 fi
 
 exit $?
--- a/usr/src/cmd/stmsboot/stmsboot_util.c	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/cmd/stmsboot/stmsboot_util.c	Thu Apr 12 18:26:33 2007 -0700
@@ -58,16 +58,16 @@
 #define	DISK_NODE_NAME	"ssd"
 #define	DISK_DRV_NAME	"ssd"
 #define	SLASH_DISK_AT	"/ssd@"
-#define	DISK_AT_G	"ssd@g"
 #else	/* sparc */
 #define	DISK_NODE_NAME	"disk"
 #define	DISK_DRV_NAME	"sd"
 #define	SLASH_DISK_AT	"/disk@"
-#define	DISK_AT_G	"disk@g"
 #endif
 
+#define	DISK_AT_G	"disk@g"
 #define	SLASH_FP_AT	"/fp@"
 #define	SLASH_SCSI_VHCI	"/scsi_vhci"
+#define	SLASH_SD_AT	"/sd@"
 #define	DEV_DSK		"/dev/dsk/"
 #define	DEV_RDSK	"/dev/rdsk/"
 #define	SYS_FILENAME_LEN	256
@@ -82,6 +82,14 @@
 /* fcp driver publishes this property */
 #define	NODE_WWN_PROP	"node-wwn"
 
+/*
+ * For SAS, we look for "sas-$drivername", eg sas-mpt, but
+ * we strncat the driver name later once we've parsed the
+ * args passed in from the shell.
+ */
+#define	SASPROP	 "sas-"
+
+
 typedef enum {
 	CLIENT_TYPE_UNKNOWN,
 	CLIENT_TYPE_PHCI,
@@ -102,12 +110,20 @@
 static char *map_vhciname = "";
 static char *stmsboot = "stmsboot";
 
+char *drvname = (char *)NULL; /* "fp" or "mpt" or ... */
+/* "node-wwn" if drvname=fp, or "sas-$drivername" otherwise */
+char *drvprop = (char *)NULL;
+static int parent = 0; /* for "-n" usage */
+
 static int make_temp(char *, char *, char *, size_t);
 static void commit_change(char *, char *, char *, int);
 static int map_devname(char *, char *, size_t, int);
 static int update_vfstab(char *, char *);
 static int list_mappings(int, int);
 static int canopen(char *);
+static client_type_t client_by_props(char *path);
+static void list_nodes(char *drivername);
+
 static void logerr(char *, ...);
 static void logdmsg(char *, ...);
 static void *s_malloc(const size_t);
@@ -152,9 +168,17 @@
 	 *	if devname is vhci based name and open-able, get the first
 	 *	onlined phci based name without /devices prefix.
 	 *	Used in stmsboot to update the phci based bootpath.
+	 * -D drvname
+	 *	if supplied, indicates that we're going to operate on
+	 *	devices attached to this driver
+	 * -n
+	 *	if supplied, returns name of the node containing "fp" or
+	 *	"sas-$driver", appends "sd@" or "ssd@" or "disk@". Can only
+	 *	be used if -D drv is specified as well
 	 */
 	(void) fprintf(stderr, gettext("usage: %s -u | -m devname | "
-	    "-M devname | -l controller | -L | -p devname\n"), progname);
+	    "-M devname | -l controller | -L | \n"
+	    "\t\t-p devname | -D { fp | mpt } | -n\n"), progname);
 	exit(2);
 }
 
@@ -172,7 +196,7 @@
 		/*NOTREACHED*/
 	}
 
-	while ((opt = getopt(argc, argv, "udm:M:Ll:gp:")) != EOF) {
+	while ((opt = getopt(argc, argv, "udm:M:Ll:gp:D:n")) != EOF) {
 		switch (opt) {
 		case 'u':
 			patch_vfstab = 1;
@@ -216,8 +240,8 @@
 			 * to GUID mappings.
 			 */
 			list_guid_mappings = 1;
-			n++;
 			break;
+
 		case 'p':
 			/*
 			 * map openable vhci based name to phci base name
@@ -226,15 +250,48 @@
 			n++;
 			break;
 
+		case 'D':
+			/*
+			 * Grab the driver name we need to look for. Each
+			 * time we add support for a new SAS or FC driver
+			 * to this utility, make sure that its driver name
+			 * is checked here.
+			 */
+			drvname = s_malloc(sizeof (optarg) + 1);
+			drvname = s_strdup(optarg);
+			if (strcmp(drvname, "fp") == 0) {
+				drvprop = s_malloc(sizeof (NODE_WWN_PROP));
+				(void) snprintf(drvprop, sizeof (NODE_WWN_PROP),
+				    NODE_WWN_PROP);
+			} else if (strcmp(drvname, "mpt") == 0) {
+				drvprop = s_malloc(sizeof (SASPROP) +
+				    sizeof (drvname) + 1);
+				(void) snprintf(drvprop, sizeof (SASPROP) +
+				    sizeof (drvname), "%s%s",
+				    SASPROP, drvname);
+			} else {
+				logerr(gettext("Driver %s is not supported\n"),
+				    drvname);
+				clean_exit(1);
+			}
+
+			break;
+
+		case 'n':
+			++parent;
+			n++;
+			break;
+
 		default:
 			usage(argv[0]);
 			/*NOTREACHED*/
 		}
 	}
 
-	if (n != 1)
+	if (n != 1) {
 		usage(argv[0]);
 		/*NOTREACHED*/
+	}
 }
 
 int
@@ -286,6 +343,16 @@
 		clean_exit(1);
 	}
 
+	if (parent > 0) {
+		if (strcmp(drvname, "") == 0) {
+			usage(argv[0]);
+			clean_exit(1);
+		} else {
+			list_nodes(drvname);
+			clean_exit(0);
+		}
+	}
+
 	/* create a directory where a copy of the system files are saved */
 	if (patch_vfstab) {
 		if (mkdirp(SAVE_DIR, 0755) != 0 && errno != EEXIST) {
@@ -383,7 +450,7 @@
  *		component.
  * guid		caller supplied buffer where the GUID will be placed on return
  * guid_len	length of the caller supplied guid buffer.
- * no_dealy_flag if set open the device with O_NDELAY
+ * no_delay_flag if set open the device with O_NDELAY
  * node		di_node corresponding to physpath if already available,
  *		otherwise pass DI_NODE_NIL.
  *
@@ -436,12 +503,21 @@
 			devid_free_guid(i_guid);
 			rv = 0;
 			goto out;
-		} else
+		} else {
 			logdmsg("get_guid: devid_to_guid() failed\n");
+			logdmsg("Unable to get a GUID for device "
+			    "%s\n", physpath_raw);
+		}
+
 	} else
 		logdmsg("get_guid: devid_get() failed: %s\n", strerror(errno));
 
-	/* fallback to node name as the guid as this is what fcp driver does */
+	/*
+	 * Unless we're looking at an fp-attached device, we now
+	 * fallback to node name as the guid as this is what the
+	 * fcp driver does. A sas-attached device will have the
+	 * client-guid property set.
+	 */
 	if (node == DI_NODE_NIL) {
 		if ((node = di_init(physpath, DINFOCPYALL | DINFOFORCE))
 		    == DI_NODE_NIL) {
@@ -452,6 +528,16 @@
 		snapshot_taken = 1;
 	}
 
+	/* non-fp fallout */
+	if (strstr(physpath, "fp") == (char *)NULL) {
+		if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
+		    "client-guid", &guid) < 0) {
+			logdmsg("get_guid: non-fp-attached device, "
+			    "bailing out\n");
+			goto out;
+		}
+	}
+
 	if ((n = di_prop_lookup_bytes(DDI_DEV_T_ANY, node, NODE_WWN_PROP,
 	    &wwnp)) == -1) {
 		logdmsg("get_guid: di_prop_lookup_bytes() failed to lookup "
@@ -482,60 +568,223 @@
  * Given client_name return whether it is a phci or vhci based name.
  * client_name is /devices name of a client without the /devices prefix.
  *
- * client_name			Return value
+ * client_name				Return value
  * on sparc:
- * .../fp@xxx/ssd@yyy		CLIENT_TYPE_PHCI
- * .../scsi_vhci/ssd@yyy	CLIENT_TYPE_VHCI
- * other			CLIENT_TYPE_UNKNOWN
+ * .../fp@xxx/ssd@yyy			CLIENT_TYPE_PHCI (fc)
+ * .../LSILogic,sas@xxx/sd@yyy		CLIENT_TYPE_PHCI (sas)
+ * .../scsi_vhci/ssd@yyy		CLIENT_TYPE_VHCI (fc)
+ * .../scsi_vhci/disk@yyy		CLIENT_TYPE_VHCI (sas)
+ * other				CLIENT_TYPE_UNKNOWN
  * on x86:
- * .../fp@xxx/disk@yyy		CLIENT_TYPE_PHCI
- * .../scsi_vhci/disk@yyy	CLIENT_TYPE_VHCI
- * other			CLIENT_TYPE_UNKNOWN
+ * .../fp@xxx/disk@yyy			CLIENT_TYPE_PHCI (fc)
+ * .../pci1000,????@xxx/sd@yyy		CLIENT_TYPE_PHCI (sas)
+ * .../scsi_vhci/disk@yyy		CLIENT_TYPE_VHCI
+ * other				CLIENT_TYPE_UNKNOWN
  */
 static client_type_t
 client_name_type(char *client_name)
 {
 	client_type_t client_type = CLIENT_TYPE_UNKNOWN;
-	char *p1, *p2;
+	char *p1;
+	char *client_path;
+
+	client_path = s_strdup(client_name);
+	logdmsg("client_name_type: client is %s\n", client_path);
 
 	if (*client_name != '/')
 		return (CLIENT_TYPE_UNKNOWN);
 
 	if ((p1 = strrchr(client_name, '/')) == NULL ||
-	    strncmp(p1, SLASH_DISK_AT, sizeof (SLASH_DISK_AT) - 1) != 0)
+	    ((strncmp(p1, "/ssd@", sizeof ("/ssd@") - 1) != 0) &&
+	    (strncmp(p1, "/sd@", sizeof ("/sd@") - 1) != 0) &&
+	    (strncmp(p1, "/disk@", sizeof ("/disk@") - 1) != 0))) {
+		logdmsg("client_name_type: p1 = %s\n", p1);
 		return (CLIENT_TYPE_UNKNOWN);
+	}
 
 	*p1 = '\0';
 
-	if ((p2 = strrchr(client_name, '/')) != NULL) {
-		if (strncmp(p2, SLASH_FP_AT, sizeof (SLASH_FP_AT) - 1) == 0)
-			client_type = CLIENT_TYPE_PHCI;
-		else if (strncmp(p2, SLASH_SCSI_VHCI,
-		    sizeof (SLASH_SCSI_VHCI) - 1) == 0)
-			client_type = CLIENT_TYPE_VHCI;
-	}
+	/*
+	 * Courtesy of the if (..) block above, we know that any
+	 * device path we have now is either PHCI or VHCI
+	 */
+	client_type = client_by_props(client_path);
+
+	logdmsg("client_name_type: client_type = %d\n", client_type);
 
 	*p1 = '/';
 	return (client_type);
 }
 
 /*
+ * client_by_props() is called to determine what the client type
+ * is, based on properties in the device tree:
+ *
+ * drivername	property	type
+ * -------------------------------------
+ *  fp		node-wwn	CLIENT_TYPE_PHCI
+ *  mpt		sas-mpt		CLIENT_TYPE_PHCI
+ *  mpt		client-guid	CLIENT_TYPE_PHCI (corner case)
+ *
+ * Normally, the "client-guid" property only shows up for a node
+ * if we've enumerated that node under scsi_vhci. During testing
+ * of this function, one particular corner case was found which
+ * requires an exception handler.
+ */
+
+static client_type_t
+client_by_props(char *path) {
+
+	di_node_t clientnode = DI_NODE_NIL;
+	di_node_t parentnode = DI_NODE_NIL;
+	unsigned int rval = CLIENT_TYPE_UNKNOWN;
+	uchar_t *byteprop[32];
+	char *charprop = NULL;
+	char *physpath;
+	char *parentpath;
+
+	physpath = s_malloc(MAXPATHLEN);
+	bzero(physpath, MAXPATHLEN);
+
+	physpath = s_strdup(path);
+
+	logdmsg("client_by_props: physpath = (%s)\n", physpath);
+
+	/* easy short-circuits */
+	if (strstr(physpath, "scsi_vhci") != (char *)NULL) {
+		logdmsg("client_by_props: found "
+		    "'scsi_vhci' on path (%s)\n", physpath);
+		rval = CLIENT_TYPE_VHCI;
+		goto out;
+	} else if ((strstr(physpath, "ide") != (char *)NULL) ||
+	    (strstr(physpath, "storage") != (char *)NULL)) {
+		logdmsg("client_by_props: ignoring this device\n");
+		goto out;
+	}
+
+	parentpath = s_malloc(MAXPATHLEN);
+	bzero(parentpath, MAXPATHLEN);
+
+	(void) strncpy(parentpath, physpath, strlen(physpath) -
+	    strlen(strrchr(physpath, '/')));
+
+	if ((parentnode = di_init(parentpath, DINFOCPYALL |
+	    DINFOFORCE)) == DI_NODE_NIL) {
+		logdmsg("client_by_props: unable to di_init(%s)\n",
+		    parentpath);
+		goto out;
+	}
+
+	if (strstr(physpath, "fp") != (char *)NULL) {
+		if (drvprop == (char *)NULL) {
+			drvprop = s_malloc(strlen(NODE_WWN_PROP) + 1);
+		}
+		logdmsg("NODE_WWN_PROP\n");
+		(void) snprintf(drvprop, strlen(NODE_WWN_PROP) + 1,
+		    NODE_WWN_PROP);
+	} else {
+		if (drvname == (char *)NULL) {
+			drvname = di_driver_name(parentnode);
+			logdmsg("client_by_props: drvname = %s\n", drvname);
+		}
+
+		if (drvprop == (char *)NULL) {
+			drvprop = s_malloc(sizeof (SASPROP) +
+			    sizeof (drvname) + 1);
+		}
+		(void) snprintf(drvprop, sizeof (SASPROP) +
+		    sizeof (drvname), "%s%s", SASPROP, drvname);
+
+		logdmsg("parentpath: %s\nphyspath: %s\n"
+		    "length %d, strrchr: %d\n",
+		    parentpath, physpath, strlen(physpath),
+		    strlen(strrchr(physpath, '/')));
+	}
+
+	logdmsg("client_by_props: searching for property '%s'\n", drvprop);
+
+	if ((clientnode = di_init(physpath, DINFOCPYALL | DINFOFORCE)) ==
+	    DI_NODE_NIL) {
+		logdmsg("client_by_props: unable to di_init(%s)\n",
+		    physpath);
+
+		/*
+		 * On x86/x64 systems, we won't be able to di_init() the
+		 * node we want in the device tree, however the parent
+		 * node will still have 'mpxio-disable' set, so we can
+		 * check for that property and make our decision on type
+		 */
+
+		if (di_prop_lookup_strings(DDI_DEV_T_ANY, parentnode,
+		    "mpxio-disable", &charprop) > -1) {
+			rval = CLIENT_TYPE_PHCI;
+			di_fini(parentnode);
+			logdmsg("client_by_props: device %s is PHCI\n",
+			    physpath);
+		}
+		goto out;
+	}
+
+	if (di_prop_lookup_bytes(DDI_DEV_T_ANY,
+	    clientnode, drvprop, byteprop) > -1) {
+		logdmsg("client_by_props: found prop %s on "
+		    "path %s\n", drvprop, physpath);
+		rval = CLIENT_TYPE_PHCI;
+	} else if (di_prop_lookup_strings(DDI_DEV_T_ANY,
+	    clientnode, "client-guid", &charprop) > -1) {
+			/*
+			 * A corner case was seen during testing where
+			 * scsi_vhci was loaded, but not all applicable
+			 * devices were enumerated under it. That left
+			 * the phci mapping along with the "client-guid"
+			 * property.
+			 */
+			logdmsg("client_by_props: weird... \n");
+			rval = CLIENT_TYPE_PHCI;
+	} else {
+		logdmsg("client_by_props: unable to find "
+		    "property 'client-guid', 'mpxio-disable' "
+		    "or '%s' anywhere on path (%s)\n",
+		    drvprop, physpath);
+		logdmsg("client_by_props: this node is unknown\n");
+	}
+
+	di_fini(parentnode);
+	di_fini(clientnode);
+out:
+	free(physpath);
+	return (rval);
+}
+
+
+/*
  * Map phci based client name to vhci based client name.
  *
  * phci_name
  *	phci based client /devices name without the /devices prefix and
  *	minor name component.
  *	ex:
+ *
+ *	(FC)
  *	for sparc: /pci@8,600000/SUNW,qlc@4/fp@0,0/ssd@w2100002037cd9f72,0
  *	for x86: /pci@8,600000/SUNW,qlc@4/fp@0,0/disk@w2100002037cd9f72,0
  *
+ *	(SAS)
+ *	for sparc: /pci@0,2/LSILogic,sas@1/disk@6,0
+ *	for x86: /pci1000,3060@3/sd@0,0
+ *
  * vhci_name
  *	Caller supplied buffer where vhci /devices name will be placed on
  *	return (without the /devices prefix and minor name component).
  *	ex:
+ *
+ *	(FC)
  *	for sparc: /scsi_vhci/ssd@g2000002037cd9f72
  *	for x86: /scsi_vhci/disk@g2000002037cd9f72
  *
+ *	(SAS)
+ *	both: /scsi_vhci/disk@g600a0b8000254d3e00000284453ed8ac
+ *
  * vhci_name_len
  *	Length of the caller supplied vhci_name buffer.
  *
@@ -545,7 +794,7 @@
 phci_to_vhci(char *phci_name, char *vhci_name, size_t vhci_name_len)
 {
 	sv_iocdata_t ioc;
-	char *slash;
+	char *slash, *at;
 	char vhci_name_buf[MAXPATHLEN];
 	char phci_name_buf[MAXPATHLEN];
 	char addr_buf[MAXNAMELEN];
@@ -556,7 +805,9 @@
 
 	if (client_name_type(phci_name_buf) != CLIENT_TYPE_PHCI ||
 	    (slash = strrchr(phci_name_buf, '/')) == NULL ||
-	    strncmp(slash, SLASH_DISK_AT, sizeof (SLASH_DISK_AT) - 1) != 0) {
+	    ((strncmp(slash, "/ssd@", sizeof ("/ssd@") - 1) != 0) &&
+	    (strncmp(slash, "/sd@", sizeof ("/sd@") - 1) != 0) &&
+	    (strncmp(slash, "/disk@", sizeof ("/disk@") - 1) != 0))) {
 		logdmsg("phci_to_vhci: %s is not of CLIENT_TYPE_PHCI\n",
 		    phci_name);
 		return (-1);
@@ -568,7 +819,9 @@
 	}
 
 	*slash = '\0';
-	s_strlcpy(addr_buf, slash + sizeof (SLASH_DISK_AT) - 1, MAXNAMELEN);
+
+	at = strchr(slash + 1, '@');
+	s_strlcpy(addr_buf, at + 1, MAXNAMELEN);
 
 	bzero(&ioc, sizeof (sv_iocdata_t));
 	ioc.client = vhci_name_buf;
@@ -614,10 +867,10 @@
 static int
 vhci_to_phci(char *vhci_name, char *phci_name, size_t phci_name_len)
 {
-	di_node_t node, parent;
+	di_node_t node = DI_NODE_NIL;
 	char *vhci_guid, *devfspath;
 	char phci_guid[MAXPATHLEN];
-	char *parent_name, *node_name;
+	char *node_name;
 
 	logdmsg("vhci_to_phci: client = %s\n", vhci_name);
 
@@ -627,6 +880,7 @@
 		return (-1);
 	}
 
+
 	if ((vhci_guid = strrchr(vhci_name, '@')) == NULL ||
 	    *(++vhci_guid) != 'g') {
 		logerr(gettext("couldn't get guid from %s\n"), vhci_name);
@@ -651,14 +905,27 @@
 		logdmsg("vhci_to_phci: done taking devinfo snapshot\n");
 	}
 
-	for (node = di_drv_first_node(DISK_DRV_NAME, devinfo_root);
+
+	/*
+	 * When we finally get a unified "sd" driver for all
+	 * architectures that Solaris runs on, we can remove this
+	 * first loop around for "ssd"
+	 */
+	for (node = di_drv_first_node("ssd", devinfo_root);
 	    node != DI_NODE_NIL; node = di_drv_next_node(node)) {
-		if ((node_name = di_node_name(node)) == NULL ||
-		    strcmp(node_name, DISK_NODE_NAME) != 0 ||
-		    (parent = di_parent_node(node)) == DI_NODE_NIL ||
-		    (parent_name = di_node_name(parent)) == NULL ||
-		    strcmp(parent_name, "fp") != 0 ||
-		    (devfspath = di_devfs_path(node)) == NULL)
+
+		if ((node_name = di_node_name(node)) == NULL)
+			continue;
+
+		if ((strcmp(node_name, "disk") != 0) &&
+		    (strcmp(node_name, "sd") != 0) &&
+		    (strcmp(node_name, "ssd") != 0))
+			continue;
+
+		if (di_parent_node(node) == DI_NODE_NIL)
+			continue;
+
+		if ((devfspath = di_devfs_path(node)) == NULL)
 			continue;
 
 		/*
@@ -666,8 +933,46 @@
 		 * standby paths of T3. So we'll find the preferred paths.
 		 */
 		if (get_guid(devfspath, phci_guid,
-		    sizeof (phci_guid), 0, node) == 0 &&
-		    strcmp(phci_guid, vhci_guid) == 0) {
+		    sizeof (phci_guid), 0, node) != 0)
+			continue;
+
+		if (strcmp(phci_guid, vhci_guid) == 0) {
+			s_strlcpy(phci_name, devfspath, phci_name_len);
+			di_devfs_path_free(devfspath);
+			logdmsg("vhci_to_phci: %s maps to %s\n", vhci_name,
+			    phci_name);
+			return (0);
+		}
+
+		di_devfs_path_free(devfspath);
+	}
+
+	for (node = di_drv_first_node("sd", devinfo_root);
+	    node != DI_NODE_NIL; node = di_drv_next_node(node)) {
+
+		if ((node_name = di_node_name(node)) == NULL)
+			continue;
+
+		if ((strcmp(node_name, "disk") != 0) &&
+		    (strcmp(node_name, "sd") != 0) &&
+		    (strcmp(node_name, "ssd") != 0))
+			continue;
+
+		if (di_parent_node(node) == DI_NODE_NIL)
+			continue;
+
+		if ((devfspath = di_devfs_path(node)) == NULL)
+			continue;
+
+		/*
+		 * Don't set no_delay_flag to have get_guid() fail on
+		 * standby paths of T3. So we'll find the preferred paths.
+		 */
+		if (get_guid(devfspath, phci_guid,
+		    sizeof (phci_guid), 0, node) != 0)
+			continue;
+
+		if (strcmp(phci_guid, vhci_guid) == 0) {
 			s_strlcpy(phci_name, devfspath, phci_name_len);
 			di_devfs_path_free(devfspath);
 			logdmsg("vhci_to_phci: %s maps to %s\n", vhci_name,
@@ -764,6 +1069,15 @@
 	node_name++;
 	*at = '\0';
 
+	logdmsg("vhci_to_phci_by_ioctl: node_name is %s\n", node_name);
+#ifndef sparc
+	/*
+	 * We need to use a libdevinfo call to get this info
+	 * in an architecturally-neutral fashion. Phase-II for sure!
+	 */
+	node_name = "sd";
+#endif
+
 	/*
 	 * return the first online paths as non-online paths may
 	 * not be accessible in the target environment.
@@ -812,13 +1126,18 @@
 	int type;
 	int rv;
 
-	if ((type = client_name_type(physname)) == CLIENT_TYPE_VHCI)
+	type = client_name_type(physname);
+	logdmsg("map_physname: type (%d) physname = %s\n",
+	    type, physname);
+
+	if (type == CLIENT_TYPE_VHCI)
 		rv = vhci_to_phci(physname, new_physname, len);
 	else if (type == CLIENT_TYPE_PHCI)
 		rv = phci_to_vhci(physname, new_physname, len);
 	else
 		rv = -1;
 
+	logdmsg("map_physname: returning %d\n", rv);
 	return (rv);
 }
 
@@ -1011,10 +1330,14 @@
 	char minor[MAXNAMELEN];
 	char new_physname[MAXPATHLEN];
 
-	if (get_physname_minor(devname, physname, sizeof (physname),
-	    minor, sizeof (minor)) == 0 &&
-	    canopen(devname) == 0 &&
-	    map_physname(physname, new_physname, sizeof (new_physname)) == 0) {
+	logdmsg("map_devname: checking devname %s\n", devname);
+	if ((get_physname_minor(devname, physname, sizeof (physname),
+	    minor, sizeof (minor)) == 0) &&
+	    (canopen(devname) == 0) &&
+	    (map_physname(physname, new_physname,
+	    sizeof (new_physname)) == 0)) {
+
+		logdmsg("map_devname: now looking up devlink\n");
 
 		if (devlink_flag) {
 			if (lookup_devlink(new_physname, minor, new_devname,
@@ -1027,6 +1350,7 @@
 		}
 	}
 
+	logdmsg("map_devname: failed to find mapping for %s\n", devname);
 	return (-1);
 }
 
@@ -1261,8 +1585,10 @@
 
 		if (get_physname_minor(devname, physname, sizeof (physname),
 		    minor, sizeof (minor)) != 0 ||
-		    client_name_type(physname) != CLIENT_TYPE_PHCI)
+		    client_name_type(physname) != CLIENT_TYPE_PHCI) {
+			logdmsg("list_mappings: continuing\n");
 			continue;
+		}
 
 		/*
 		 * First try phci_to_vhci() mapping. It will work if the
@@ -1306,11 +1632,16 @@
 			(void) printf("%s\t\t%s\n", devname, new_devname);
 		} else {
 			/* extract guid part */
-			if ((p1 = strstr(new_physname, DISK_AT_G)) == NULL) {
+			/* we should be using a getguid() call instead */
+			if ((p1 = strstr(new_physname, "@"))
+			    == NULL) {
 				logdmsg("invalid vhci: %s\n", new_physname);
 				continue;
 			}
-			p1 += sizeof (DISK_AT_G) - 1;
+
+			logdmsg("\tp1 = %s\n", p1);
+
+			p1 += 2; /* "@" + [nwg] */
 			if ((p2 = strrchr(p1, ':')) != NULL)
 				*p2 = '\0';
 
@@ -1342,10 +1673,107 @@
 	if ((fd = open(filename, O_RDONLY)) == -1)
 		return (0);
 
+	logdmsg("canopen: was able to open %s\n", filename);
 	(void) close(fd);
 	return (1);
 }
 
+
+/*
+ * This function traverses the device tree looking for nodes
+ * which have "drivername" as a property. We return a list of
+ * these nodes, with SLASH_DISK_AT appended.
+ * Since there can be many different pci/pcie devices that all
+ * share the same driver but which have different pci vid/did
+ * combinations, we have to be smart about returning only those
+ * pci vid/dids which have the "sas-*" property unless the
+ * drivername is "fp", in which case we're searching for "node-wwn"
+ */
+static void
+list_nodes(char *drivername)
+{
+	char *aliaslist;
+	char *mpxprop = NULL;
+	di_node_t devroot = DI_NODE_NIL;
+	di_node_t thisnode = DI_NODE_NIL;
+	int *intprop = NULL;
+	int i = 1; /* fencepost */
+
+	/*
+	 * Since the "fp" driver enumerates with its own name,
+	 * we can special-case its handling.
+	 */
+	if (strcmp(drvname, "fp") == 0) {
+		(void) fprintf(stdout, "fp\n");
+	} else {
+
+		if ((devroot = di_init("/", DINFOCPYALL | DINFOFORCE))
+		    == DI_NODE_NIL) {
+			logerr(gettext("list_nodes: di_init failed: "
+			"%s\n"), strerror(errno));
+		}
+
+		if ((thisnode = di_drv_first_node(drivername, devroot))
+		    != NULL) {
+			logdmsg("list_nodes: searching for property "
+			    "%s\n", drvprop);
+
+			aliaslist = s_malloc(1024 * sizeof (char));
+			bzero(aliaslist, 1024);
+			while (thisnode != DI_NODE_NIL) {
+				logdmsg("devfs-name %s driver-name %s "
+				    "node-name %s\n",
+				    di_devfs_path(thisnode),
+				    di_driver_name(thisnode),
+				    di_node_name(thisnode));
+
+			/* We check the child node for drvprop */
+			if ((di_prop_lookup_ints(DDI_DEV_T_ANY,
+			    di_child_node(thisnode), drvprop,
+			    &intprop) > -1) ||
+			    (((di_prop_lookup_strings(DDI_DEV_T_ANY,
+			    thisnode, "mpxio-disable", &mpxprop) > -1) &&
+			    strcmp(di_driver_name(thisnode),
+			    drivername)) == 0)) {
+
+				if (strstr(aliaslist,
+				    di_node_name(thisnode))
+				    == (char *)NULL) {
+					char *nname;
+
+					nname = di_node_name(thisnode);
+
+					if (i) {
+					(void) snprintf(aliaslist,
+					    strlen(nname), "%s", nname);
+						--i;
+					} else {
+					if (strstr(aliaslist,
+					    di_node_name(thisnode)) ==
+					    (char *)NULL) {
+						(void) snprintf(aliaslist,
+						    strlen(nname) +
+						    strlen(aliaslist),
+						    "%s|%s", aliaslist,
+						    nname);
+						}
+					}
+				}
+			} else {
+				logdmsg("unable to lookup property %s "
+				    "for node %s. Error %d: %s\n",
+				    drvprop, di_devfs_path(thisnode),
+				    errno, strerror(errno));
+			}
+			thisnode = di_drv_next_node(thisnode);
+		}
+		(void) fprintf(stdout, "%s\n", aliaslist);
+		}
+
+		di_fini(devroot);
+	}
+}
+
 static void
 logerr(char *msg, ...)
 {
--- a/usr/src/pkgdefs/SUNWckr/Makefile	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWckr/Makefile	Thu Apr 12 18:26:33 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -28,7 +28,7 @@
 include ../Makefile.com
 
 DATAFILES +=	i.etcsystem i.kcfconfbase i.manifest i.preserve i.renameold \
-		i.scsivhciconf
+		i.scsivhciconf i.mptconf
 
 MACHDATAFILES += i.sdconf
 CLOBBERFILES += $(MACHDATAFILES)
--- a/usr/src/pkgdefs/SUNWckr/pkginfo.tmpl	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWckr/pkginfo.tmpl	Thu Apr 12 18:26:33 2007 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -44,6 +44,7 @@
 VENDOR="Sun Microsystems, Inc."
 HOTLINE="Please contact your local service provider"
 EMAIL=""
+CLASSES_i386="mptconf"
 CLASSES="none etcsystem kcfconfbase manifest preserve renameold scsivhciconf sdconf"
 BASEDIR=/
 SUNW_PKGVERS="1.0"
--- a/usr/src/pkgdefs/SUNWckr/prototype_i386	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWckr/prototype_i386	Thu Apr 12 18:26:33 2007 -0700
@@ -40,6 +40,7 @@
 # Include ISA independent files (prototype_com)
 #
 !include prototype_com
+i i.mptconf	
 #
 # List files which are i386 specific here
 #
@@ -98,7 +99,7 @@
 f none kernel/drv/log 755 root sys
 f none kernel/drv/mm 755 root sys
 f none kernel/drv/mpt 755 root sys
-f none kernel/drv/mpt.conf 644 root sys
+e mptconf kernel/drv/mpt.conf 644 root sys
 f none kernel/drv/mouse8042 755 root sys
 f none kernel/drv/openeepr 755 root sys
 f none kernel/drv/options 755 root sys
--- a/usr/src/pkgdefs/SUNWpd/Makefile	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWpd/Makefile	Thu Apr 12 18:26:33 2007 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -19,15 +18,15 @@
 #
 # CDDL HEADER END
 #
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
-#
-# Copyright (c) 1995 by Sun Microsystems, Inc.
+# ident	"%Z%%M%	%I%	%E% SMI"
 #
 
 include ../Makefile.com
 
-DATAFILES += depend
+DATAFILES += depend i.mptconf
 
 .KEEP_STATE:
 
--- a/usr/src/pkgdefs/SUNWpd/pkginfo.tmpl	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWpd/pkginfo.tmpl	Thu Apr 12 18:26:33 2007 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -44,6 +44,7 @@
 VENDOR="Sun Microsystems, Inc."
 HOTLINE="Please contact your local service provider"
 EMAIL=""
+CLASSES_sparc="mptconf"
 CLASSES="none"
 BASEDIR=/
 SUNW_PKGVERS="1.0"
--- a/usr/src/pkgdefs/SUNWpd/prototype_sparc	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/SUNWpd/prototype_sparc	Thu Apr 12 18:26:33 2007 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -19,10 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 1990-2003 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
-#
+
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
 # This required package information file contains a list of package contents.
@@ -39,6 +39,7 @@
 # Include ISA independent files (prototype_com)
 #
 !include prototype_com
+i i.mptconf
 #
 #
 #
@@ -55,5 +56,6 @@
 f none kernel/drv/sparcv9/se 0755 root sys
 f none kernel/drv/sparcv9/glm 0755 root sys
 f none kernel/drv/sparcv9/mpt 0755 root sys
+e mptconf kernel/drv/mpt.conf 0644 root sys
 f none kernel/drv/ecpp.conf 0644 root sys
 f none kernel/drv/sparcv9/ecpp 0755 root sys
--- a/usr/src/pkgdefs/bld_awk_pkginfo.ksh	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/bld_awk_pkginfo.ksh	Thu Apr 12 18:26:33 2007 -0700
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -23,8 +22,8 @@
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright (c) 1995,1997 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # Simple script which builds the awk_pkginfo awk script.  This awk script
 # is used to convert the pkginfo.tmpl files into pkginfo files
@@ -48,6 +47,8 @@
 VERSION2="VERSION=[^=]*=.*$"
 PRODVERS="^SUNW_PRODVERS="
 ARCH='ARCH=\"ISA\"'
+ARCHCLASSES="^CLASSES_"
+ALLCLASSES="^CLASSES=" 
 
 #
 # parse command line
@@ -122,5 +123,18 @@
       printf "ARCH=\"%s\"\n", "$mach"
       next
    }
+/$ARCHCLASSES/ {
+      sub(/\=/," ")
+      gsub(/\"/,"")
+      archclasses[\$1]=\$0
+      next
+   }
+/$ALLCLASSES/ {
+      tag="CLASSES_$mach"
+      sub(tag,"",archclasses[tag])
+      sub(/\"$/,archclasses[tag]"\"")
+      print
+      next
+   } 
 { print }
 EOF
--- a/usr/src/pkgdefs/common_files/i.kclasses_i386	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/common_files/i.kclasses_i386	Thu Apr 12 18:26:33 2007 -0700
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -65,6 +65,7 @@
 		    -e '/^smartii[ 	].*dada/d' \
 		    -e '/^trantor[	].*scsi/d' \
 		    -e '/^corvette[	].*scsi/d' \
+		    -e '/^mpt[	].*scsi/d' \
 		$dest > /tmp/c.$$
 		if cmp -s /tmp/c.$$ $dest  > /dev/null 2>&1
 		then
@@ -96,10 +97,6 @@
 		if [ $? != 0 ] ; then
 			echo 'i2o_scsi scsi' >> $dest
 		fi
-		grep '^mpt	scsi' $dest > /dev/null 2>&1
-		if [ $? != 0 ] ; then
-			echo 'mpt	scsi' >> $dest
-		fi
 	fi
 done
 
--- a/usr/src/pkgdefs/common_files/i.kclasses_sparc	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/pkgdefs/common_files/i.kclasses_sparc	Thu Apr 12 18:26:33 2007 -0700
@@ -3,9 +3,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -23,7 +22,7 @@
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -54,6 +53,7 @@
 		    -e '/^ncr[	]*scsi$/d' \
 		    -e '/^vme[ 	]*vme$/d' \
 		    -e '/^pci[ 	]*pci$/d' \
+		    -e '/^mpt[ 	]*scsi$/d' \
 		    $dest > /tmp/rest.$$ 2>/dev/null
 		cat /tmp/newident.$$ /tmp/rest.$$ > $dest
 		grep '^isp	scsi' $dest > /dev/null 2>&1
@@ -96,10 +96,6 @@
 		if [ $? != 0 ] ; then
 			echo 'simba	pci' >> $dest
 		fi
-		grep '^mpt	scsi' $dest > /dev/null 2>&1
-		if [ $? != 0 ] ; then
-			 echo 'mpt	scsi' >> $dest
-		fi
 	fi
 done
 rm -f /tmp/newident.$$ /tmp/rest.$$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/common_files/i.mptconf	Thu Apr 12 18:26:33 2007 -0700
@@ -0,0 +1,171 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+
+PATH=/usr/bin:/usr/sbin:$PATH; export PATH
+PREFIX=/tmp/mpt.conf.$$
+
+add_comment_for_vhci_class()
+{
+	if grep "^# The mpt driver, as a pHCI driver" $1 > /dev/null 2>&1; then
+		return
+	fi
+
+	cat >> $1 << EOF
+
+#
+# The mpt driver, as a pHCI driver, must specify the vHCI class it
+# belongs to(scsi_vhci).
+#
+EOF
+}
+
+add_comment_for_mpxio_disable()
+{
+
+	if grep "^# Global mpxio-disable property:" $1 > /dev/null 2>&1; then
+		return
+	fi
+
+	cat >> $1 << EOF
+
+#
+# I/O multipathing feature (MPxIO) can be enabled or disabled using
+# mpxio-disable property. Setting mpxio-disable="no" will activate
+# I/O multipathing; setting mpxio-disable="yes" disables the feature.
+#
+# Global mpxio-disable property:
+#
+# To globally enable MPxIO on all mpt controllers set:
+# mpxio-disable="no";
+#
+# To globally disable MPxIO on all mpt controllers set:
+# mpxio-disable="yes";
+#
+# You can also enable or disable MPxIO on a per HBA basis. 
+# Per HBA settings override the global setting for the specified HBAs.
+# To disable MPxIO on a controller whose parent is /pci@7c0/pci@0/pci@9
+# and the unit-address is "0" set:
+# name="mpt" parent="/pci@7c0/pci@0/pci@9" unit-address="0" mpxio-disable="yes";
+#
+EOF
+}
+
+add_comment_for_tape_property()
+{
+
+	if grep "^# The property tape" $1 > /dev/null 2>&1; then
+		return
+	fi
+
+	cat >> $1 << EOF
+
+#
+# The property tape is only used for X86
+#
+EOF
+}
+
+update_mptconf()
+{
+	NEWHDR1=$PREFIX.hdr1
+	NEWHDR2=$PREFIX.hdr2
+	TMPFILE=$PREFIX.tmp
+	
+	# replace old copyright with new one	
+	HEADER="^#.* Copyright.*Sun Microsystems.*$"
+	if grep "$HEADER" $1 > $NEWHDR1 2>/dev/null; then
+		# replace / by \/
+		sed "s/\\//\\\\\\//g" $NEWHDR1 > $NEWHDR2 2>/dev/null
+		if sed "s/$HEADER/`cat $NEWHDR2`/" $2 > $TMPFILE 2>/dev/null
+		then
+			cp $TMPFILE $2
+		fi
+	fi
+
+	# replace old ident with new ident
+	HEADER="^#.*ident.*SMI\"$"
+	if grep "$HEADER" $1 > $NEWHDR1 2>/dev/null; then
+		# replace / by \/
+		sed "s/\\//\\\\\\//g" $NEWHDR1 > $NEWHDR2 2>/dev/null
+		if sed "s/$HEADER/`cat $NEWHDR2`/" $2 > $TMPFILE 2>/dev/null
+		then
+			cp $TMPFILE $2
+		fi
+	fi
+
+	if [ "$ARCH" = "i386" ]; then
+    		# remove useless property flow_control and queue
+		# check the property named tape and that the property is
+		# only used on i386 platform
+		sed -e '/^# config file for x86 mpt SCSI HBA driver$/d' \
+		    -e '/^flow_control="dmult" queue="qsort" tape="sctp";$/d' \
+		    -e '/^# x86 only$/d' $2 > $TMPFILE 
+		cp $TMPFILE $2
+		grep 'tape="sctp"' $2 > /dev/null 2>&1
+		if [ $? != 0 ] ; then
+		        add_comment_for_tape_property $2
+			echo 'tape="sctp";' >> $2
+		fi
+	fi
+
+	add_comment_for_vhci_class $2
+
+	# check for property named ddi-vhci-class
+	grep '^ddi-vhci-class' $2 > /dev/null 2>&1
+	if [ $? != 0 ] ; then
+		echo 'ddi-vhci-class="scsi_vhci";' >> $2
+	fi
+
+	add_comment_for_mpxio_disable $2
+
+	# check for property named mpxio-disable
+	grep '^mpxio-disable' $2 > /dev/null 2>&1
+	if [ $? != 0 ] ; then
+		echo 'mpxio-disable="yes";' >> $2
+	fi
+
+	rm -f $NEWHDR1 $NEWHDR2 $TMPFILE
+}
+
+
+if read src dest; then
+	if [ ! -f $dest ]; then
+		cp $src $dest
+		if [ "$ARCH" = "i386" ]; then
+			# add property tape for i386 platform
+		        add_comment_for_tape_property $dest
+			echo 'tape="sctp";' >> $dest
+		fi	
+	else
+		# upgrading solaris
+		update_mptconf $src $dest
+	fi
+
+fi
+
+exit 0
--- a/usr/src/tools/scripts/bfu.sh	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/tools/scripts/bfu.sh	Thu Apr 12 18:26:33 2007 -0700
@@ -219,6 +219,7 @@
 	kernel/drv/scsa2usb.conf
 	kernel/drv/scsi_vhci.conf
 	kernel/drv/sd.conf
+	kernel/drv/mpt.conf
 	platform/*/kernel/drv/*ppm.conf
 	platform/i86pc/kernel/drv/aha.conf
 	platform/i86pc/kernel/drv/asy.conf
@@ -599,6 +600,18 @@
 	fi
 }
 
+# update x86 version mpt.conf for property tape
+mpttapeprop='[ 	]*tape[ 	]*=[ 	]*"sctp"[ 	]*;'
+update_mptconf_i386()
+{
+	conffile=$rootprefix/kernel/drv/mpt.conf
+	test -f $conffile || return
+	egrep -s "$mpttapeprop" $conffile
+	if [ $? -ne 0 ] ; then
+	    echo 'tape="sctp";' >> $conffile
+	fi
+}
+
 update_policy_conf() {
 	# update /etc/security/policy.conf with the default
 	# Solaris crypt(3c) policy.
@@ -6973,6 +6986,10 @@
 
 	update_policy_conf
 
+	if [ $target_isa = i386 ]; then
+	    update_mptconf_i386
+	fi
+
 	if [ $zone != global ]; then
 		rm -rf $global_zone_only_files $superfluous_nonglobal_zone_files
 	fi
--- a/usr/src/uts/common/io/scsi/impl/scsi_hba.c	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/uts/common/io/scsi/impl/scsi_hba.c	Thu Apr 12 18:26:33 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1978,6 +1978,16 @@
 		{"esi",			"scsa,0d.busb"},
 #endif	/* notdef */
 
+	/*
+	 * mapping nodenames for mpt based on scsi dtype
+	 * for being compatible with the original node names
+	 * under mpt controller
+	 */
+		{"sd",			"scsa,00.bmpt"},
+		{"sd",			"scsa,05.bmpt"},
+		{"sd",			"scsa,07.bmpt"},
+		{"st",			"scsa,01.bmpt"},
+		{"ses",			"scsa,0d.bmpt"},
 		{NULL,		NULL}
 	};
 	struct nodename_aliases *nap;
--- a/usr/src/uts/common/io/warlock/mpt.wlcmd	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/uts/common/io/warlock/mpt.wlcmd	Thu Apr 12 18:26:33 2007 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -25,6 +25,8 @@
 root mpt_kmem_cache_constructor mpt_kmem_cache_destructor
 root mpt_do_dma
 root mpt_handle_event
+root mpt_handle_dr
+root mpt_name_child
 
 for ptr in `funcptrs | grep '^scsi_hba_tran::'`
 do
--- a/usr/src/uts/intel/os/driver_classes	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/uts/intel/os/driver_classes	Thu Apr 12 18:26:33 2007 -0700
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -32,4 +31,3 @@
 pci_pci	pci
 pci_to_i2o i2o
 i2o_scsi scsi
-mpt	scsi
--- a/usr/src/uts/sparc/os/driver_classes	Thu Apr 12 16:44:57 2007 -0700
+++ b/usr/src/uts/sparc/os/driver_classes	Thu Apr 12 18:26:33 2007 -0700
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# 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.
@@ -36,4 +35,3 @@
 glm	scsi
 uata	dada
 uata	scsi
-mpt	scsi