diff --git a/config/hal.c b/config/hal.c
index 9de9dfc..f069dff 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2007 Daniel Stone
  * Copyright © 2007 Red Hat, Inc.
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -39,6 +40,23 @@
 #include "config-backends.h"
 #include "os.h"
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define MAX_DEVICES	4
+
+DeviceIntPtr added_devices[MAX_DEVICES];
+int num_added_devices = 0;
+Bool abort_on_fail_over = FALSE;
+static Bool do_abort = FALSE;
+
+extern int  num_total_disp_dev;
+extern int  num_session_disp_dev;
+extern char disp_dev_path[PATH_MAX];
+extern void GiveUp(int sig);
+#endif
+
 #define LIBHAL_PROP_KEY "input.x11_options."
 #define LIBHAL_XKB_PROP_KEY "input.xkb."
 
@@ -124,6 +142,51 @@ get_prop_string_array(LibHalContext * hal_ctx, const char *udi,
 }
 
 #ifdef SUNSOFT
+#if (defined(__sparc__) || defined(__sparc))
+Bool check_inactive_session(char const *path) {
+    struct stat statbuf;
+    char linkpath[PATH_MAX];
+    ssize_t readstatus;
+    char *usbpath = NULL;
+    char *ptr;
+    char disppath[PATH_MAX];
+
+    if ((num_session_disp_dev == num_total_disp_dev) || !disp_dev_path[0])
+	return FALSE;
+
+    if (lstat(path, &statbuf) == 0 &&
+		(statbuf.st_mode & S_IFMT) == S_IFLNK) {
+	readstatus = readlink(path, linkpath, sizeof(linkpath));
+
+	if (readstatus > 0 && readstatus < sizeof(linkpath)) {
+	    linkpath[readstatus] = 0;
+	    usbpath = linkpath;
+	    if (strncmp(usbpath, "../..", sizeof("../..") - 1) == 0)
+		usbpath += sizeof("../..") - 1;
+	    if (strncmp(usbpath, "/devices", sizeof("/devices") - 1) == 0)
+		usbpath += sizeof("/devices") - 1;
+	}
+    }
+
+    if (!usbpath)
+	return FALSE;
+
+    if (ptr = strchr(usbpath + 1, '/'))
+	*ptr = 0;
+    else
+	return FALSE;
+    
+    strncpy(disppath, disp_dev_path, sizeof(disppath));
+
+    if (ptr = strchr(disppath + 1, '/'))
+	*ptr = 0;
+    else
+	return FALSE;
+
+    return (strcmp(usbpath, disppath));
+}
+#endif
+
 static void
 add_extra_device(char *driver)
 {
@@ -178,6 +241,11 @@ device_added(LibHalContext * hal_ctx, const char *udi)
     struct xkb_options xkb_opts = { 0 };
     int rc;
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
+    if (do_abort)
+	return;
+#endif
+
     LibHalPropertySet *set = NULL;
     LibHalPropertySetIterator set_iter;
     char *psi_key = NULL, *tmp_val;
@@ -264,6 +332,28 @@ device_added(LibHalContext * hal_ctx, const char *udi)
     input_options = input_option_new(input_options, "driver", driver);
     input_options = input_option_new(input_options, "name", name);
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
+    if (!strcmp(name, "keyboard") || !strcmp(name, "mouse")) {
+	if (check_inactive_session(path)) {
+	    if (abort_on_fail_over) {
+		/* M5: Input devices were removed, new input device added is to
+		   activate another session, reset it.
+		 */
+		do_abort = TRUE;
+		LogMessage(X_INFO, "config/hal: Server to abort\n");
+	    } else
+		/* M5: No removal of input devices happened, new input device 
+		   added is to activate another session, do nothing.
+		 */
+		LogMessage(X_INFO, "config/hal: Not adding input device %s\n", name);
+
+            goto unwind;
+	} else
+	    /* M5: new input device added is to activate current session. */
+	    abort_on_fail_over = FALSE;
+    }
+#endif
+
     if (asprintf(&config_info, "hal:%s", udi) == -1) {
         config_info = NULL;
         LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
@@ -428,7 +518,7 @@ device_added(LibHalContext * hal_ctx, const char *udi)
 #ifdef SUNSOFT
     InputOption *md = input_option_find(input_options, "mdriver");
     if (md) {
-	char *mdriver = input_option_get_value(md);
+	char *mdriver = (char *) input_option_get_value(md);
 	add_extra_device (mdriver);
     }
 #endif
@@ -442,6 +532,26 @@ device_added(LibHalContext * hal_ctx, const char *udi)
         goto unwind;
     }
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
+    if ((num_session_disp_dev < num_total_disp_dev) &&
+		(!strcmp(name, "keyboard") || !strcmp(name, "mouse"))) {
+	int i;
+
+	if (num_added_devices == MAX_DEVICES) {
+	    LogMessage(X_ERROR, "config/hal: Too manay devices to add\n");
+	    goto unwind;
+	}
+
+	for (i = 0; i < MAX_DEVICES; i++) {
+	    if (added_devices[i] == 0) {
+		added_devices[i] = dev;
+		num_added_devices++;
+		break;
+	    }
+	}
+    }
+#endif
+	
  unwind:
     if (set)
         libhal_free_property_set(set);
@@ -474,6 +584,12 @@ device_added(LibHalContext * hal_ctx, const char *udi)
 
     dbus_error_free(&error);
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(SUNSOFT))
+    if (do_abort) {
+	config_fini();
+	GiveUp(0);
+    }
+#endif
     return;
 }
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index bee407b..248c603 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -45,6 +45,9 @@
  * the sale, use or other dealings in this Software without prior written
  * authorization from the copyright holder(s) and author(s).
  */
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
+ */
 
 #ifdef HAVE_XORG_CONFIG_H
 #include <xorg-config.h>
@@ -103,6 +106,15 @@
 static int
  xf86InputDevicePostInit(DeviceIntPtr dev);
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined(sun))
+#define MAX_DEVICES       	4
+extern int  num_total_disp_dev;
+extern int  num_session_disp_dev;
+extern DeviceIntPtr added_devices[MAX_DEVICES];
+extern int num_added_devices;
+extern Bool abort_on_fail_over;
+#endif
+
 /**
  * Eval config and modify DeviceVelocityRec accordingly
  */
@@ -1432,6 +1444,25 @@ xf86DisableDevice(DeviceIntPtr dev, Bool panic)
         SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
         DeleteInputDeviceRequest(dev);
     }
+
+#if ((defined(__sparc__) || defined(__sparc)) && defined(sun))
+    if (num_session_disp_dev < num_total_disp_dev) {
+	int i;
+
+	for (i = 0; i < MAX_DEVICES; i++) {
+	    if (added_devices[i] == dev) {
+		added_devices[i] = 0;
+		if (--num_added_devices == 0)
+		    /* M5: will abort server when another X session
+		       is activated.
+		     */
+		    abort_on_fail_over = TRUE;
+
+		break;
+	    }
+	}
+    }
+#endif
 }
 
 /**
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 258988a..2ec07d9 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -54,6 +55,12 @@
 /* Bus-specific globals */
 int pciSlotClaimed = 0;
 
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+int  num_total_disp_dev = 0;
+int  num_session_disp_dev = 0;
+char disp_dev_path[PATH_MAX];
+#endif
+
 #define PCIINFOCLASSES(c) \
     ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
       || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
@@ -115,6 +122,11 @@ xf86PciProbe(void)
                 primaryBus.id.pci = info;
             }
             info->user_data = 0;
+
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+	    if (IS_VGA(info->device_class))
+		num_total_disp_dev++;
+#endif
         }
     }
     free(iter);
@@ -483,6 +495,15 @@ xf86PciProbeDev(DriverPtr drvp)
     const struct pci_id_match *const devices = drvp->supported_devices;
     GDevPtr *devList;
     const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+    struct sol_device_private {
+	struct pci_device  base;
+	const char * device_string;
+    };
+#define DEV_PATH(dev)    (((struct sol_device_private *) dev)->device_string)
+
+    num_session_disp_dev = numDevs;
+#endif
 
     for (i = 0; i < numDevs; i++) {
         struct pci_device_iterator *iter;
@@ -560,6 +581,11 @@ xf86PciProbeDev(DriverPtr drvp)
                     if ((*drvp->PciProbe) (drvp, entry, pPci,
                                            devices[j].match_data)) {
                         foundScreen = TRUE;
+
+#if ((defined(__sparc__) || defined(__sparc)) && defined (sun))
+			strncpy(disp_dev_path, DEV_PATH(pPci), sizeof(disp_dev_path));
+#endif
+
                     }
                     else
                         xf86UnclaimPciSlot(pPci, devList[i]);
@@ -568,6 +594,7 @@ xf86PciProbeDev(DriverPtr drvp)
                 break;
             }
         }
+
     }
     free(devList);
 
