open-src/lib/libpciaccess/bus-range.patch
changeset 705 24ca414edbff
parent 704 f9b973ecc909
child 706 43bb5cf562a2
--- a/open-src/lib/libpciaccess/bus-range.patch	Thu May 14 20:00:54 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +0,0 @@
-From 5bf4b32c2b3844c50e720be5820f2ce657ddea12 Mon Sep 17 00:00:00 2001
-From: Alan Coopersmith <[email protected]>
-Date: Thu, 22 Jan 2009 16:14:22 -0800
-Subject: [PATCH] Solaris: Use bus-range properties to limit busses scanned on each node
-
-Based on code provided by [email protected]
----
- src/solx_devfs.c |  116 ++++++++++++++++++++++++++++++++++++++++++------------
- 1 files changed, 90 insertions(+), 26 deletions(-)
-
-diff --git a/src/solx_devfs.c b/src/solx_devfs.c
-index e184841..99ee1ac 100644
---- a/src/solx_devfs.c
-+++ b/src/solx_devfs.c
-@@ -22,7 +22,7 @@
-  * DEALINGS IN THE SOFTWARE.
-  */
- /*
-- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
-+ * Copyright 2007, 2009 Sun Microsystems, Inc.  All rights reserved.
-  *
-  * Permission is hereby granted, free of charge, to any person obtaining a
-  * copy of this software and associated documentation files (the
-@@ -68,6 +68,8 @@
- #include "pciaccess.h"
- #include "pciaccess_private.h"
- 
-+/* #define DEBUG */
-+
- #define	MAX_DEVICES	256
- #define	CELL_NUMS_1275	(sizeof(pci_regspec_t) / sizeof(uint_t))
- 
-@@ -85,12 +87,13 @@ typedef struct i_devnode {
- 
- typedef struct nexus {
-     int fd;
--    int domain;
-+    int first_bus;
-+    int last_bus;
-+    const char *path;		/* for errors/debugging; fd is all we need */
-     struct nexus *next;
- } nexus_t;
- 
- static nexus_t *nexus_list = NULL;
--static int num_domains = 0;
- static int xsvc_fd = -1;
- 
- /*
-@@ -127,9 +130,6 @@ static int xsvc_fd = -1;
- # define U45_SB_CLASS_RID	0x06040000
- #endif
- 
--#define	DEBUGON	0
--
--
- static int pci_device_solx_devfs_map_range(struct pci_device *dev,
-     struct pci_device_mapping *map);
- 
-@@ -174,12 +174,12 @@ static const struct pci_system_methods solx_devfs_methods = {
- };
- 
- static nexus_t *
--find_nexus_for_domain( int domain )
-+find_nexus_for_bus( int bus )
- {
-     nexus_t *nexus;
- 
-     for (nexus = nexus_list ; nexus != NULL ; nexus = nexus->next) {
--	if (nexus->domain == domain) {
-+	if ((bus >= nexus->first_bus) && (bus <= nexus->last_bus)) {
- 	    return nexus;
- 	}
-     }
-@@ -212,6 +212,7 @@ pci_system_solx_devfs_destroy( void )
-     for (nexus = nexus_list ; nexus != NULL ; nexus = next) {
- 	next = nexus->next;
- 	close(nexus->fd);
-+	free(nexus->path);
- 	free(nexus);
-     }
-     nexus_list = NULL;
-@@ -443,7 +444,7 @@ probe_dev(nexus_t *nexus, pcitool_reg_t *prg_p, struct pci_system *pci_sys)
- 	    /*
- 	     * Domain is peer bus??
- 	     */
--	    pci_base->domain = nexus->domain;
-+	    pci_base->domain = 0;
- 	    pci_base->bus = prg_p->bus_no;
- 	    pci_base->dev = prg_p->dev_no;
- 	    pci_base->func = func;
-@@ -466,12 +467,20 @@ probe_dev(nexus_t *nexus, pcitool_reg_t *prg_p, struct pci_system *pci_sys)
- 	    pci_sys->devices[pci_sys->num_devices].header_type
- 					= GET_CONFIG_VAL_8(PCI_CONF_HEADER);
- 
--#if DEBUGON
--	    fprintf(stderr, "busno = %x, devno = %x, funcno = %x\n",
--		    prg_p->bus_no, prg_p->dev_no, func);
-+#ifdef DEBUG
-+	    fprintf(stderr,
-+		    "nexus = %s, busno = %x, devno = %x, funcno = %x\n",
-+		    nexus->path, prg_p->bus_no, prg_p->dev_no, func);
- #endif
- 
--	    pci_sys->num_devices++;
-+	    if (pci_sys->num_devices < (MAX_DEVICES - 1)) {
-+		pci_sys->num_devices++;
-+	    } else {
-+		(void) fprintf(stderr,
-+			       "Maximum number of PCI devices found,"
-+			       " discarding additional devices\n");
-+	    }
-+
- 
- 	    /*
- 	     * Accommodate devices which state their
-@@ -495,17 +504,67 @@ static int
- probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
- {
-     struct pci_system *pci_sys = (struct pci_system *) arg;
--    char *nexus_name;
-+    const char *nexus_name;
-     nexus_t *nexus;
-     int fd;
-     char nexus_path[MAXPATHLEN];
- 
-+    di_prop_t prop;
-+    const char *strings;
-+    int *ints;
-+    int numval;
-+    int pci_node = 0;
-+    int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M);
-+
-+#ifdef DEBUG
-+    nexus_name = di_devfs_minor_path(minor);
-+    fprintf(stderr, "-- device name: %s\n", nexus_name);
-+#endif
-+
-+    for (prop = di_prop_next(di_node, NULL); prop != NULL;
-+	 prop = di_prop_next(di_node, prop)) {
-+
-+	const char *prop_name = di_prop_name(prop);
-+
-+#ifdef DEBUG
-+	fprintf(stderr, "   property: %s\n", prop_name);
-+#endif
-+
-+	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);
-+	    }
-+	    pci_node = 1;
-+	}
-+	else if (strcmp(prop_name, "class-code") == 0) {
-+	    /* not a root bus node, bail */
-+	    return (DI_WALK_CONTINUE);
-+	}
-+	else if (strcmp(prop_name, "bus-range") == 0) {
-+	    numval = di_prop_ints(prop, &ints);
-+	    if (numval == 2) {
-+		first_bus = ints[0];
-+		last_bus = ints[1];
-+	    }
-+	}
-+    }
-+
-+#ifdef __x86  /* sparc pci nodes don't have the device_type set */
-+    if (pci_node != 1)
-+	return (DI_WALK_CONTINUE);
-+#endif
-+
-+    /* we have a PCI root bus node. */
-     nexus = calloc(1, sizeof(nexus_t));
-     if (nexus == NULL) {
- 	(void) fprintf(stderr, "Error allocating memory for nexus: %s\n",
- 		       strerror(errno));
--	return DI_WALK_TERMINATE;
-+	return (DI_WALK_TERMINATE);
-     }
-+    nexus->first_bus = first_bus;
-+    nexus->last_bus = last_bus;
- 
-     nexus_name = di_devfs_minor_path(minor);
-     if (nexus_name == NULL) {
-@@ -517,14 +576,20 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
- 
-     snprintf(nexus_path, sizeof(nexus_path), "/devices%s", nexus_name);
-     di_devfs_path_free(nexus_name);
-+    nexus->path = strdup(nexus_path);
-+
-+#ifdef DEBUG
-+    fprintf(stderr, "nexus = %s, bus-range = %d - %d\n",
-+	    nexus_path, first_bus, last_bus);
-+#endif
- 
-     if ((fd = open(nexus_path, O_RDWR)) >= 0) {
- 	nexus->fd = fd;
--	nexus->domain = num_domains++;
- 	if ((do_probe(nexus, pci_sys) != 0) && (errno != ENXIO)) {
- 	    (void) fprintf(stderr, "Error probing node %s: %s\n",
- 			   nexus_path, strerror(errno));
- 	    (void) close(fd);
-+	    free(nexus->path);
- 	    free(nexus);
- 	} else {
- 	    nexus->next = nexus_list;
-@@ -533,6 +598,7 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
-     } else {
- 	(void) fprintf(stderr, "Error opening %s: %s\n",
- 		       nexus_path, strerror(errno));
-+	free(nexus->path);
- 	free(nexus);
-     }
- 
-@@ -553,9 +619,9 @@ do_probe(nexus_t *nexus, struct pci_system *pci_sys)
-     pcitool_reg_t prg;
-     uint32_t bus;
-     uint8_t dev;
--    uint32_t last_bus = PCI_REG_BUS_M >> PCI_REG_BUS_SHIFT;
-+    uint32_t last_bus = nexus->last_bus;
-     uint8_t last_dev = PCI_REG_DEV_M >> PCI_REG_DEV_SHIFT;
--    uint8_t first_bus = 0;
-+    uint8_t first_bus = nexus->first_bus;
-     uint8_t first_dev = 0;
-     int rval = 0;
- 
-@@ -593,9 +659,6 @@ do_probe(nexus_t *nexus, struct pci_system *pci_sys)
- 	    rval = 0;
- 	}
-     }
--    if (pci_sys->num_devices > MAX_DEVICES) {
--	(void) fprintf(stderr, "pci devices reach maximum number\n");
--    }
- 
-     return (rval);
- }
-@@ -634,7 +697,7 @@ find_target_node(di_node_t node, void *arg)
-     len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &regbuf);
- 
-     if (len <= 0) {
--#if DEBUGON
-+#ifdef DEBUG
- 	fprintf(stderr, "error = %x\n", errno);
- 	fprintf(stderr, "can not find assigned-address\n");
- #endif
-@@ -808,7 +871,7 @@ pci_device_solx_devfs_read_rom( struct pci_device * dev, void * buffer )
- 	.size = dev->rom_size,
- 	.flags = 0
-     };
--    
-+
-     err = pci_device_solx_devfs_map_range(dev, &prom);
-     if (err == 0) {
- 	(void) bcopy(prom.memory, buffer, dev->rom_size);
-@@ -831,7 +894,7 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data,
-     pcitool_reg_t cfg_prg;
-     int err = 0;
-     int i = 0;
--    nexus_t *nexus = find_nexus_for_domain(dev->domain);
-+    nexus_t *nexus = find_nexus_for_bus(dev->bus);
- 
-     *bytes_read = 0;
- 
-@@ -852,7 +915,8 @@ pci_device_solx_devfs_read( struct pci_device * dev, void * data,
- 	cfg_prg.offset = offset + i;
- 
- 	if ((err = ioctl(nexus->fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != 0) {
--	    fprintf(stderr, "read bdf<%x,%x,%x,%llx> config space failure\n",
-+	    fprintf(stderr, "read bdf<%s,%x,%x,%x,%llx> config space failure\n",
-+		    nexus->path,
- 		    cfg_prg.bus_no,
- 		    cfg_prg.dev_no,
- 		    cfg_prg.func_no,
-@@ -882,7 +946,7 @@ pci_device_solx_devfs_write( struct pci_device * dev, const void * data,
-     pcitool_reg_t cfg_prg;
-     int err = 0;
-     int cmd;
--    nexus_t *nexus = find_nexus_for_domain(dev->domain);
-+    nexus_t *nexus = find_nexus_for_bus(dev->bus);
- 
-     if ( bytes_written != NULL ) {
- 	*bytes_written = 0;
--- 
-1.5.6.5
-