7162039 Xorg 1.12 causes server crash on startup with ast, vesa, nv drivers
authorAlan Coopersmith <Alan.Coopersmith@Oracle.COM>
Mon, 23 Apr 2012 10:37:02 -0700
changeset 1275 394f1c4996ae
parent 1274 73e31d2ed431
child 1276 52f85727ce94
7162039 Xorg 1.12 causes server crash on startup with ast, vesa, nv drivers
open-src/lib/libpciaccess/Makefile
open-src/lib/libpciaccess/legacy-io.patch
open-src/lib/libpciaccess/primary-vga.patch
open-src/lib/libpciaccess/scanpci_64bit.patch
open-src/lib/libpciaccess/sparc.patch
--- a/open-src/lib/libpciaccess/Makefile	Fri Apr 20 10:07:08 2012 -0700
+++ b/open-src/lib/libpciaccess/Makefile	Mon Apr 23 10:37:02 2012 -0700
@@ -28,15 +28,16 @@
 MODULE_NAME=libpciaccess
 
 # Version number (used in path names)
-MODULE_VERSION=0.13
+MODULE_VERSION=0.13.1
 
 # Checksums for upstream tarball
-TARBALL_MD5   = 2604307ba43c76ee8aec11ea137ae1e8
-TARBALL_SHA1  = 7ddd8e1de27326f6f4a3ac6b4d2241fe77ef5353
-TARBALL_SHA256= 24368520b0947487ec73729e3c97c95f3d9bf83704a910bb0abe1d5a63df32fd
+TARBALL_MD5   = 399a419ac6a54f0fc07c69c9bdf452dc
+TARBALL_SHA1  = ae4dcf27a1b52c6a1fd90b21165fbaecae34e8ac
+TARBALL_SHA256= 27ab68f645691a4ca258dcc9d131040586e134f9233ce079794496f6264da084
 
 # Patches to apply to source after unpacking, in order
 SOURCE_PATCHES = \
+	legacy-io.patch,-p1 \
 	scanpci.man.patch \
 	primary-vga.patch,-p1 \
 	scanpci_64bit.patch,-p1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/libpciaccess/legacy-io.patch	Mon Apr 23 10:37:02 2012 -0700
@@ -0,0 +1,183 @@
+From 1a75f838b0b0c1ec4f5b5c8200d5b9ebbded3165 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Wed, 18 Apr 2012 15:30:30 -0700
+Subject: [PATCH:libpciaccess] Solaris: Implement map_legacy & legacy_io
+ functions
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+---
+ src/solx_devfs.c |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 135 insertions(+), 2 deletions(-)
+
+diff --git a/src/solx_devfs.c b/src/solx_devfs.c
+index 2079df0..4069dc2 100644
+--- a/src/solx_devfs.c
++++ b/src/solx_devfs.c
+@@ -1,6 +1,6 @@
+ /*
+  * (C) Copyright IBM Corporation 2006
+- * Copyright (c) 2007, 2009, 2011, Oracle and/or its affiliates.
++ * Copyright (c) 2007, 2009, 2011, 2012, Oracle and/or its affiliates.
+  * All Rights Reserved.
+  *
+  * Permission is hereby granted, free of charge, to any person obtaining a
+@@ -38,6 +38,11 @@
+ #include <libdevinfo.h>
+ #include "pci_tools.h"
+ 
++#ifdef __x86
++# include <sys/sysi86.h>
++# include <sys/psw.h>
++#endif
++
+ #include "pciaccess.h"
+ #include "pciaccess_private.h"
+ 
+@@ -1122,7 +1127,125 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data,
+     return (err);
+ }
+ 
++static struct pci_io_handle *
++pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret,
++				     struct pci_device *dev,
++				     pciaddr_t base, pciaddr_t size)
++{
++#ifdef __x86
++    if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) == 0) {
++	ret->base = base;
++	ret->size = size;
++	return ret;
++    }
++#endif
++    return NULL;
++}
++
++static uint32_t
++pci_device_solx_devfs_read32(struct pci_io_handle *handle, uint32_t reg)
++{
++#ifdef __x86
++    uint16_t port = (uint16_t) (handle->base + reg);
++    uint32_t ret;
++    __asm__ __volatile__("inl %1,%0":"=a"(ret):"d"(port));
++    return ret;
++#else
++    return *(uint32_t *)((uintptr_t)handle->memory + reg);
++#endif
++}
+ 
++static uint16_t
++pci_device_solx_devfs_read16(struct pci_io_handle *handle, uint32_t reg)
++{
++#ifdef __x86
++    uint16_t port = (uint16_t) (handle->base + reg);
++    uint16_t ret;
++    __asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port));
++    return ret;
++#else
++    return *(uint16_t *)((uintptr_t)handle->memory + reg);
++#endif
++}
++
++static uint8_t
++pci_device_solx_devfs_read8(struct pci_io_handle *handle, uint32_t reg)
++{
++#ifdef __x86
++    uint16_t port = (uint16_t) (handle->base + reg);
++    uint8_t ret;
++    __asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port));
++    return ret;
++#else
++    return *(uint8_t *)((uintptr_t)handle->memory + reg);
++#endif
++}
++
++static void
++pci_device_solx_devfs_write32(struct pci_io_handle *handle, uint32_t reg,
++    uint32_t data)
++{
++#ifdef __x86
++      uint16_t port = (uint16_t) (handle->base + reg);
++      __asm__ __volatile__("outl %0,%1"::"a"(data), "d"(port));
++#else
++      *(uint16_t *)((uintptr_t)handle->memory + reg) = data;
++#endif
++}
++
++static void
++pci_device_solx_devfs_write16(struct pci_io_handle *handle, uint32_t reg,
++    uint16_t data)
++{
++#ifdef __x86
++      uint16_t port = (uint16_t) (handle->base + reg);
++      __asm__ __volatile__("outw %0,%1"::"a"(data), "d"(port));
++#else
++    *(uint8_t *)((uintptr_t)handle->memory + reg) = data;
++#endif
++}
++
++static void
++pci_device_solx_devfs_write8(struct pci_io_handle *handle, uint32_t reg,
++    uint8_t data)
++{
++#ifdef __x86
++      uint16_t port = (uint16_t) (handle->base + reg);
++      __asm__ __volatile__("outb %0,%1"::"a"(data), "d"(port));
++#else
++      *(uint32_t *)((uintptr_t)handle->memory + reg) = data;
++#endif
++}
++
++static int
++pci_device_solx_devfs_map_legacy(struct pci_device *dev, pciaddr_t base,
++				 pciaddr_t size, unsigned map_flags,
++				 void **addr)
++{
++    int err;
++    struct pci_device_mapping map = {
++	.base = base,
++	.size = size,
++	.flags = map_flags,
++    };
++
++    err = pci_device_solx_devfs_map_range(dev, &map);
++    if (err == 0)
++	*addr = map.memory;
++    return err;
++}
++
++static int
++pci_device_solx_devfs_unmap_legacy(struct pci_device *dev,
++				   void *addr, pciaddr_t size)
++{
++    struct pci_device_mapping map = {
++	.memory = addr,
++	.size = size,
++    };
++
++    return pci_device_generic_unmap_range(dev, &map);
++}
+ 
+ static const struct pci_system_methods solx_devfs_methods = {
+     .destroy = pci_system_solx_devfs_destroy,
+@@ -1135,7 +1258,17 @@ static const struct pci_system_methods solx_devfs_methods = {
+     .read = pci_device_solx_devfs_read,
+     .write = pci_device_solx_devfs_write,
+ 
+-    .fill_capabilities = pci_fill_capabilities_generic
++    .fill_capabilities = pci_fill_capabilities_generic,
++
++    .open_legacy_io = pci_device_solx_devfs_open_legacy_io,
++    .read32 = pci_device_solx_devfs_read32,
++    .read16 = pci_device_solx_devfs_read16,
++    .read8 = pci_device_solx_devfs_read8,
++    .write32 = pci_device_solx_devfs_write32,
++    .write16 = pci_device_solx_devfs_write16,
++    .write8 = pci_device_solx_devfs_write8,
++    .map_legacy = pci_device_solx_devfs_map_legacy,
++    .unmap_legacy = pci_device_solx_devfs_unmap_legacy,
+ };
+ 
+ /*
+-- 
+1.7.9.2
+
--- a/open-src/lib/libpciaccess/primary-vga.patch	Fri Apr 20 10:07:08 2012 -0700
+++ b/open-src/lib/libpciaccess/primary-vga.patch	Mon Apr 23 10:37:02 2012 -0700
@@ -1,8 +1,8 @@
 diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
-index 32f8a75..9d65a51 100644
+index fea9c9f..6996f8d 100644
 --- a/src/pciaccess_private.h
 +++ b/src/pciaccess_private.h
-@@ -133,6 +133,7 @@ struct pci_device_private {
+@@ -146,6 +146,7 @@ struct pci_device_private {
      struct pci_device_mapping *mappings;
      unsigned num_mappings;
      /*@}*/
@@ -11,10 +11,10 @@
  
  
 diff --git a/src/solx_devfs.c b/src/solx_devfs.c
-index 5e91a14..5f0db2d 100644
+index 4069dc2..504de9e 100644
 --- a/src/solx_devfs.c
 +++ b/src/solx_devfs.c
-@@ -791,6 +791,18 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
+@@ -796,6 +796,18 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
  #ifdef __sparc
  	di_minor_t minor;
  #endif
@@ -33,7 +33,7 @@
  
  #ifdef __sparc
  	if (minor = di_minor_next(args.node, DI_MINOR_NIL))
-@@ -845,22 +857,33 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
+@@ -850,22 +862,33 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
      }
  
      /*
@@ -74,7 +74,7 @@
  	/*
  	 * non relocatable resource is excluded
  	 * such like 0xa0000, 0x3b0. If it is met,
-@@ -1122,6 +1145,15 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data,
+@@ -1127,6 +1150,15 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data,
      return (err);
  }
  
@@ -87,16 +87,14 @@
 +
 +}
 +
- 
- 
- static const struct pci_system_methods solx_devfs_methods = {
-@@ -1135,7 +1167,8 @@ static const struct pci_system_methods solx_devfs_methods = {
-     .read = pci_device_solx_devfs_read,
+ static struct pci_io_handle *
+ pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret,
+ 				     struct pci_device *dev,
+@@ -1259,6 +1291,7 @@ static const struct pci_system_methods solx_devfs_methods = {
      .write = pci_device_solx_devfs_write,
  
--    .fill_capabilities = pci_fill_capabilities_generic
-+    .fill_capabilities = pci_fill_capabilities_generic,
-+    .boot_vga = pci_device_solx_devfs_boot_vga
- };
+     .fill_capabilities = pci_fill_capabilities_generic,
++    .boot_vga = pci_device_solx_devfs_boot_vga,
  
- /*
+     .open_legacy_io = pci_device_solx_devfs_open_legacy_io,
+     .read32 = pci_device_solx_devfs_read32,
--- a/open-src/lib/libpciaccess/scanpci_64bit.patch	Fri Apr 20 10:07:08 2012 -0700
+++ b/open-src/lib/libpciaccess/scanpci_64bit.patch	Mon Apr 23 10:37:02 2012 -0700
@@ -20,10 +20,10 @@
  		if ( ! dev->regions[i].is_IO ) {
  		    if ( dev->regions[i].is_prefetchable ) {
 diff --git a/src/solx_devfs.c b/src/solx_devfs.c
-index 5f0db2d..6b8db2c 100644
+index 908bb9f..6127f5d 100644
 --- a/src/solx_devfs.c
 +++ b/src/solx_devfs.c
-@@ -897,14 +897,10 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
+@@ -902,14 +902,10 @@ pci_device_solx_devfs_probe( struct pci_device * dev )
  	}
  
  
--- a/open-src/lib/libpciaccess/sparc.patch	Fri Apr 20 10:07:08 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,507 +0,0 @@
-diff -ur old/src/solx_devfs.c new/src/solx_devfs.c
---- src/solx_devfs.c	Wed Sep 21 12:43:44 2011
-+++ src/solx_devfs.c	Tue Nov 15 12:23:53 2011
-@@ -66,6 +66,11 @@
-     char *path;			/* for errors/debugging; fd is all we need */
-     char *dev_path;
-     struct nexus *next;
-+#ifdef __sparc
-+    struct pci_device **devlist;
-+    volatile size_t num_allocated_elems;
-+    volatile size_t num_devices;
-+#endif
- } nexus_t;
- 
- typedef struct probe_info {
-@@ -75,8 +80,14 @@
- } probe_info_t;
- 
- static nexus_t *nexus_list = NULL;
-+#if !defined(__sparc)
- static int xsvc_fd = -1;
-+#endif
- 
-+#ifdef __sparc
-+static di_prom_handle_t di_phdl;
-+#endif
-+
- /*
-  * Read config space in native processor endianness.  Endian-neutral
-  * processing can then take place.  On big endian machines, MSB and LSB
-@@ -91,6 +102,10 @@
- # error "ISA is neither __sparc nor __x86"
- #endif
- 
-+#ifdef __sparc
-+#define MAPPING_DEV_PATH(dev)	 (((struct pci_device_private *) dev)->device_string)
-+#endif
-+
- /*
-  * Identify problematic southbridges.  These have device id 0x5249 and
-  * vendor id 0x10b9.  Check for revision ID 0 and class code 060400 as well.
-@@ -156,7 +171,23 @@
-     .boot_vga = pci_device_solx_devfs_boot_vga
- };
- 
-+#ifdef __sparc
- static nexus_t *
-+find_nexus_for_dev(struct pci_device *dev)
-+{
-+    nexus_t *nexus;
-+    int i;
-+
-+    for (nexus = nexus_list ; nexus != NULL ; nexus = nexus->next) {
-+	for (i = 0; i < nexus->num_devices; i++) {
-+	    if (nexus->devlist[i] == dev)
-+		return nexus;
-+	}
-+    }
-+    return NULL;
-+}
-+#else
-+static nexus_t *
- find_nexus_for_bus( int domain, int bus )
- {
-     nexus_t *nexus;
-@@ -169,6 +200,7 @@
-     }
-     return NULL;
- }
-+#endif
- 
- #define GET_CONFIG_VAL_8(offset) (config_hdr.bytes[offset])
- #define GET_CONFIG_VAL_16(offset) \
-@@ -198,14 +230,32 @@
- 	close(nexus->fd);
- 	free(nexus->path);
- 	free(nexus->dev_path);
-+#ifdef __sparc
-+	{
-+	    struct pci_device *dev;
-+	    int i;
-+
-+	    for (i = 0; i < nexus->num_devices; i++) {
-+		dev = nexus->devlist[i];
-+		if (MAPPING_DEV_PATH(dev))
-+		    di_devfs_path_free((char *) MAPPING_DEV_PATH(dev));
-+	    }
-+	}
-+	free(nexus->devlist);
-+#endif
- 	free(nexus);
-     }
-     nexus_list = NULL;
- 
-+#ifdef __sparc
-+    if (di_phdl != DI_PROM_HANDLE_NIL)
-+	(void) di_prom_fini(di_phdl);
-+#else
-     if (xsvc_fd >= 0) {
- 	close(xsvc_fd);
- 	xsvc_fd = -1;
-     }
-+#endif
- }
- 
- /*
-@@ -238,10 +288,16 @@
- 	return (err);
-     }
- 
-+#ifdef __sparc
-+    if ((di_phdl = di_prom_init()) == DI_PROM_HANDLE_NIL)
-+	(void) fprintf(stderr, "di_prom_init failed: %s\n", strerror(errno));
-+#endif
-+
-     pinfo.num_allocated_elems = INITIAL_NUM_DEVICES;
-     pinfo.num_devices = 0;
--    pinfo.devices = devices; 
-+    pinfo.devices = devices;
-     (void) di_walk_minor(di_node, DDI_NT_REGACC, 0, &pinfo, probe_nexus_node);
-+
-     di_fini(di_node);
- 
-     if ((pci_sys = calloc(1, sizeof (struct pci_system))) == NULL) {
-@@ -249,6 +305,7 @@
- 	free(devices);
- 	return (err);
-     }
-+
-     pci_sys->methods = &solx_devfs_methods;
-     pci_sys->devices = pinfo.devices;
-     pci_sys->num_devices = pinfo.num_devices;
-@@ -372,6 +429,10 @@
- 	    else if (((errno != EFAULT) ||
- 		      (prg_p->status != PCITOOL_INVALID_ADDRESS)) &&
- 		     (prg_p->data != 0xffffffff)) {
-+#ifdef __sparc
-+/* on sparc, devices can be enumerated discontiguously. Do not quit */
-+		rval = 0;
-+#endif
- 		break;
- 	    }
- 
-@@ -438,6 +499,7 @@
- 	    pci_base->device_id		= GET_CONFIG_VAL_16(PCI_CONF_DEVID);
- 	    pci_base->subvendor_id 	= GET_CONFIG_VAL_16(PCI_CONF_SUBVENID);
- 	    pci_base->subdevice_id 	= GET_CONFIG_VAL_16(PCI_CONF_SUBSYSID);
-+	    pci_base->irq		= GET_CONFIG_VAL_8(PCI_CONF_ILINE);
- 
- 	    pinfo->devices[pinfo->num_devices].header_type
- 					= GET_CONFIG_VAL_8(PCI_CONF_HEADER);
-@@ -461,13 +523,32 @@
- 			           " discarding additional devices\n");
- 		    return (rval);
- 		}
--		(void) memset(&new_devs[pinfo->num_devices], 0, 
-+		(void) memset(&new_devs[pinfo->num_devices], 0,
- 			pinfo->num_allocated_elems *
- 			sizeof (struct pci_device_private));
- 		pinfo->num_allocated_elems = new_num_elems;
- 		pinfo->devices = new_devs;
--	    } 
--	
-+	    }
-+
-+#ifdef __sparc
-+	    nexus->devlist[nexus->num_devices++] = pci_base;
-+
-+	    if (nexus->num_devices == nexus->num_allocated_elems) {
-+		struct pci_device **new_devs;
-+		size_t new_num_elems = nexus->num_allocated_elems * 2;
-+
-+		new_devs = realloc(nexus->devlist,
-+			new_num_elems * sizeof (struct pci_device *));
-+		if (new_devs == NULL)
-+		    return (rval);
-+		(void) memset(&new_devs[nexus->num_devices], 0,
-+			nexus->num_allocated_elems *
-+			sizeof (struct pci_device *));
-+		nexus->num_allocated_elems = new_num_elems;
-+		nexus->devlist = new_devs;
-+	    }
-+#endif
-+
- 	    /*
- 	     * Accommodate devices which state their
- 	     * multi-functionality only in their function 0 config
-@@ -502,7 +583,13 @@
-     int pci_node = 0;
-     int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M);
-     int domain = 0;
-+#ifdef __sparc
-+    int bus_range_found = 0;
-+    int device_type_found = 0;
-+    di_prom_prop_t prom_prop;
-+#endif
- 
-+
- #ifdef DEBUG
-     nexus_name = di_devfs_minor_path(minor);
-     fprintf(stderr, "-- device name: %s\n", nexus_name);
-@@ -519,11 +606,17 @@
- 
- 	if (strcmp(prop_name, "device_type") == 0) {
- 	    numval = di_prop_strings(prop, &strings);
--	    if (numval != 1 || strncmp(strings, "pci", 3) != 0) {
--		/* not a PCI node, bail */
--		return (DI_WALK_CONTINUE);
-+   	    if (numval == 1) {
-+		if (strncmp(strings, "pci", 3) != 0)
-+		    /* not a PCI node, bail */
-+		    return (DI_WALK_CONTINUE);
-+		else {
-+		    pci_node = 1;
-+#ifdef __sparc
-+		    device_type_found =  1;
-+#endif
-+		}
- 	    }
--	    pci_node = 1;
- 	}
- 	else if (strcmp(prop_name, "class-code") == 0) {
- 	    /* not a root bus node, bail */
-@@ -534,9 +627,12 @@
- 	    if (numval == 2) {
- 		first_bus = ints[0];
- 		last_bus = ints[1];
-+#ifdef __sparc
-+		bus_range_found = 1;
-+#endif
- 	    }
- 	}
--	else if (strcmp(prop_name, "pciseg") == 0) { 
-+	else if (strcmp(prop_name, "pciseg") == 0) {
- 	    numval = di_prop_ints(prop, &ints);
- 	    if (numval == 1) {
- 		domain = ints[0];
-@@ -544,10 +640,30 @@
- 	}
-     }
- 
--#ifdef __x86  /* sparc pci nodes don't have the device_type set */
-+#ifdef __sparc
-+    if ((!device_type_found) && di_phdl) {
-+	numval = di_prom_prop_lookup_strings(di_phdl, di_node,
-+	    "device_type", &strings);
-+	if (numval == 1) {
-+	    if (strncmp(strings, "pci", 3) != 0)
-+		return (DI_WALK_CONTINUE);
-+	    else
-+		pci_node = 1;
-+	}
-+    }
-+	
-+    if ((!bus_range_found) && di_phdl) {
-+	numval = di_prom_prop_lookup_ints(di_phdl, di_node,
-+	    "bus-range", &ints);
-+	if (numval == 2) {
-+	    first_bus = ints[0];
-+	    last_bus = ints[1];
-+	}
-+    }
-+#endif
-+
-     if (pci_node != 1)
- 	return (DI_WALK_CONTINUE);
--#endif
- 
-     /* we have a PCI root bus node. */
-     nexus = calloc(1, sizeof(nexus_t));
-@@ -560,6 +676,18 @@
-     nexus->last_bus = last_bus;
-     nexus->domain = domain;
- 
-+#ifdef __sparc
-+    if ((nexus->devlist = calloc(INITIAL_NUM_DEVICES,
-+			sizeof (struct pci_device *))) == NULL) {
-+	(void) fprintf(stderr, "Error allocating memory for nexus devlist: %s\n",
-+                       strerror(errno));
-+	free (nexus);
-+	return (DI_WALK_TERMINATE);
-+    }
-+    nexus->num_allocated_elems = INITIAL_NUM_DEVICES;
-+    nexus->num_devices = 0;
-+#endif
-+
-     nexus_name = di_devfs_minor_path(minor);
-     if (nexus_name == NULL) {
- 	(void) fprintf(stderr, "Error getting nexus path: %s\n",
-@@ -692,6 +820,11 @@
- 
-     len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &regbuf);
- 
-+#ifdef __sparc
-+    if ((len <= 0) && di_phdl)
-+	len = di_prom_prop_lookup_ints(di_phdl, node, "reg", &regbuf);
-+#endif
-+
-     if (len <= 0) {
- #ifdef DEBUG
- 	fprintf(stderr, "error = %x\n", errno);
-@@ -721,8 +854,7 @@
- static int
- pci_device_solx_devfs_probe( struct pci_device * dev )
- {
--    uint8_t  config[256];
--    int err;
-+    int err = 0;
-     di_node_t rnode = DI_NODE_NIL;
-     i_devnode_t args = { 0, 0, 0, DI_NODE_NIL };
-     int *regbuf;
-@@ -735,49 +867,43 @@
- 	    (struct pci_device_private *) dev;
-     nexus_t *nexus;
- 
-+#ifdef __sparc
-+    if ( (nexus = find_nexus_for_dev(dev)) == NULL )
-+#else
-     if ( (nexus = find_nexus_for_bus(dev->domain, dev->bus)) == NULL )
-+#endif
- 	return ENODEV;
- 
--    err = pci_device_solx_devfs_read( dev, config, 0, 256, & bytes );
--
--    if ( bytes >= 64 ) {
--
--	dev->vendor_id = (uint16_t)config[0] + ((uint16_t)config[1] << 8);
--	dev->device_id = (uint16_t)config[2] + ((uint16_t)config[3] << 8);
--	dev->device_class = (uint32_t)config[9] +
--	    ((uint32_t)config[10] << 8) +
--	    ((uint16_t)config[11] << 16);
--
--	/*
--	 * device class code is already there.
--	 * see probe_dev function.
--	 */
--	dev->revision = config[8];
--	dev->subvendor_id = (uint16_t)config[44] + ((uint16_t)config[45] << 8);
--	dev->subdevice_id = (uint16_t)config[46] + ((uint16_t)config[47] << 8);
--	dev->irq = config[60];
--
--	priv->header_type = config[14];
--	/*
--	 * starting to find if it is MEM/MEM64/IO
--	 * using libdevinfo
--	 */
--	if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) {
--	    err = errno;
--	    (void) fprintf(stderr, "di_init failed: %s\n", strerror(errno));
--	} else {
--	    args.bus = dev->bus;
--	    args.dev = dev->dev;
--	    args.func = dev->func;
--	    (void) di_walk_node(rnode, DI_WALK_CLDFIRST,
--				(void *)&args, find_target_node);
--	}
-+    /*
-+     * starting to find if it is MEM/MEM64/IO
-+     * using libdevinfo
-+     */
-+    if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) {
-+	err = errno;
-+	(void) fprintf(stderr, "di_init failed: %s\n", strerror(errno));
-+    } else {
-+	args.bus = dev->bus;
-+	args.dev = dev->dev;
-+	args.func = dev->func;
-+	(void) di_walk_node(rnode, DI_WALK_CLDFIRST,
-+		(void *)&args, find_target_node);
-     }
-+ 
-     if (args.node != DI_NODE_NIL) {
- 	int *prop;
-+#ifdef __sparc
-+	di_minor_t minor;
-+#endif
- 
- 	priv->is_primary = 0;
- 
-+#ifdef __sparc
-+	if (minor = di_minor_next(args.node, DI_MINOR_NIL))
-+	    MAPPING_DEV_PATH(dev) = di_devfs_minor_path (minor);
-+	else
-+	    MAPPING_DEV_PATH(dev) = NULL;
-+#endif
-+
-     	if (di_prop_lookup_ints(DDI_DEV_T_ANY,
- 	    args.node, "primary-controller", &prop) >= 1) {
- 	        if (prop[0])
-@@ -792,6 +918,12 @@
- 				  "assigned-addresses",
- 				  &regbuf);
- 
-+#ifdef __sparc
-+	if ((len <= 0) && di_phdl) {
-+	    len = di_prom_prop_lookup_ints(di_phdl, args.node,
-+				"assigned-addresses", &regbuf);
-+	}
-+#endif
-     }
- 
- 
-@@ -927,8 +1059,14 @@
-     pcitool_reg_t cfg_prg;
-     int err = 0;
-     int i = 0;
--    nexus_t *nexus = find_nexus_for_bus(dev->domain, dev->bus);
-+    nexus_t *nexus;
- 
-+#ifdef __sparc
-+    nexus = find_nexus_for_dev(dev);
-+#else
-+    nexus = find_nexus_for_bus(dev->domain, dev->bus);
-+#endif
-+
-     *bytes_read = 0;
- 
-     if ( nexus == NULL ) {
-@@ -979,8 +1117,14 @@
-     pcitool_reg_t cfg_prg;
-     int err = 0;
-     int cmd;
--    nexus_t *nexus = find_nexus_for_bus(dev->domain, dev->bus);
-+    nexus_t *nexus;
- 
-+#ifdef __sparc
-+    nexus = find_nexus_for_dev(dev);
-+#else
-+    nexus = find_nexus_for_bus(dev->domain, dev->bus);
-+#endif
-+
-     if ( bytes_written != NULL ) {
- 	*bytes_written = 0;
-     }
-@@ -993,15 +1137,19 @@
-     switch (size) {
-         case 1:
- 	    cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_1 + NATIVE_ENDIAN;
-+    	    cfg_prg.data = *((uint8_t *)data);
- 	    break;
-         case 2:
- 	    cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_2 + NATIVE_ENDIAN;
-+    	    cfg_prg.data = *((uint16_t *)data);
- 	    break;
-         case 4:
- 	    cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN;
-+    	    cfg_prg.data = *((uint32_t *)data);
- 	    break;
-         case 8:
- 	    cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 + NATIVE_ENDIAN;
-+    	    cfg_prg.data = *((uint64_t *)data);
- 	    break;
-         default:
- 	    return EINVAL;
-@@ -1011,7 +1159,6 @@
-     cfg_prg.func_no = dev->func;
-     cfg_prg.barnum = 0;
-     cfg_prg.user_version = PCITOOL_USER_VERSION;
--    cfg_prg.data = *((uint64_t *)data);
- 
-     /*
-      * Check if this device is bridge device.
-@@ -1048,6 +1195,24 @@
- 			? (PROT_READ | PROT_WRITE) : PROT_READ;
-     int err = 0;
- 
-+#ifdef __sparc
-+    char	map_dev[128];
-+    int		map_fd;
-+
-+    if (MAPPING_DEV_PATH(dev))
-+	snprintf(map_dev, sizeof (map_dev), "%s%s", "/devices", MAPPING_DEV_PATH(dev));
-+    else
-+	strcpy (map_dev, "/dev/fb0");
-+
-+    if ((map_fd = open(map_dev, O_RDWR)) < 0) {
-+	err = errno;
-+	(void) fprintf(stderr, "can not open %s: %s\n", map_dev,
-+			   strerror(errno));
-+	return err;
-+    }
-+
-+    map->memory = mmap(NULL, map->size, prot, MAP_SHARED, map_fd, map->base);
-+#else
-     /*
-      * Still used xsvc to do the user space mapping
-      */
-@@ -1061,6 +1226,8 @@
-     }
- 
-     map->memory = mmap(NULL, map->size, prot, MAP_SHARED, xsvc_fd, map->base);
-+#endif
-+
-     if (map->memory == MAP_FAILED) {
- 	err = errno;
- 
-@@ -1068,6 +1235,10 @@
- 		       map->base, strerror(errno));
-     }
- 
-+#ifdef __sparc
-+    close (map_fd);
-+#endif
-+
-     return err;
- }
- static int pci_device_solx_devfs_boot_vga(struct pci_device *dev)