In the current version of dtc, if one has the line:
/config/ = "northbridge/amd/geodelx";

Then the file northbridge/amd/geodelx/dts is read in and processed. 
Magic(TM) appends the name "/dts" to the path. 

This hack is fine with chips that only do one thing. 
But some (all) northbridge parts play several roles: APIC cluster, PCI domain
device, and PCI device. The result is a need for more than one dts, since
there are three possible devices, with three types of IDs, and so on. 

To keep things sane, I am proposing to put three seperate dts files in the 
northbridge directory, name as follows:
domaindts
pcidts
apicdts

(of course these names can be anything, this is just an example).
This change will require a change to the dtc, since we can no longer
assume just one dts file, and hence need a way to name these different 
files. 

The proposed change is very simple. Given a config path as above, the 
dtc will at first try to open the path as a file, BEFORE trying to open the 
the path by appending "/dts" to it. 

So, 
/config/ = "northbridge/amd/geodelx/pcidts";

will open the pcidts file. But, 
/config/="southbridge/amd/cs5536";
will open the southbridge/amd/cs5536/dts file as before. 

Is this really going to far? Shouldn't we just require the users to 
name the dts file, instead of the magic? I am comfortable with that idea
too -- reduce magic, make things more clear. 

Comments are most welcome!

Once this change goes in, I can start to finish up the LX.

Changes: 
dtc: create a new function, fopenfile, that will only open a path if it 
really is a file. Modify dtc_open_file to use this function. fopenfile
assumes "-" means stdin; should it, or should I move that assumption back
to dtc_open_file?


dtc.h: add prototypes

dtc-parser.y: Given a config path, try to open the path first, then path/dts.
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>

Index: util/dtc/dtc.c
===================================================================
--- util/dtc/dtc.c	(revision 563)
+++ util/dtc/dtc.c	(working copy)
@@ -61,21 +61,47 @@
 		fill_fullpaths(child, tree->fullpath);
 }
 
-static FILE *dtc_open_file(char *fname)
+/* How stupid is POSIX? This stupid: you can fopen a directory if mode
+ * is "r", but then there is very little you can do with it except get errors. 
+ * This function now makes sure that the thing you open is a file. 
+ */
+FILE *fopenfile(char *fname)
 {
-	FILE *f;
+	FILE *f = NULL;
 
-	if (streq(fname, "-"))
+	if (streq(fname, "-")){
 		f = stdin;
-	else
+	} else {
+		struct stat buf;
+		if (stat(fname, &buf) < 0) {
+			errno = EISDIR;
+			goto no;
+		}
+
+		if (! S_ISREG(buf.st_mode)){
+			errno = EISDIR;
+			goto no;
+		}
+
 		f = fopen(fname, "r");
+	}
 
+no:
+
+	return f;
+}
+
+FILE *dtc_open_file(char *fname)
+{
+	FILE *f = fopenfile(fname);
+
 	if (! f)
 		die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
 
 	return f;
 }
 
+
 static void usage(void)
 {
 	fprintf(stderr, "Usage:\n");
Index: util/dtc/dtc.h
===================================================================
--- util/dtc/dtc.h	(revision 563)
+++ util/dtc/dtc.h	(working copy)
@@ -31,6 +31,8 @@
 #include <errno.h>
 #include <unistd.h>
 #include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 /* also covers (part of?) linux's byteswap.h functionality */
 #include "endian.h"
@@ -236,5 +238,6 @@
 
 char *join_path(char *path, char *name);
 void fill_fullpaths(struct node *tree, char *prefix);
-
+FILE *fopenfile(char *fname);
+FILE *dtc_open_file(char *fname);
 #endif /* _DTC_H */
Index: util/dtc/dtc-parser.y
===================================================================
--- util/dtc/dtc-parser.y	(revision 563)
+++ util/dtc/dtc-parser.y	(working copy)
@@ -128,13 +128,19 @@
 			/* TODO: keep track of which of these we have read in. If we have already done it, then 
 			  * don't do it twice. 
 			  */
-			sprintf(path, "%s/dts", $3.val);
-			f  = fopen(path, "r");
-			if (! f){
-				perror(path);
-				exit(1);
+			/* The need for a cast here is silly */
+			f  = fopenfile((char *)$3.val);
+			if (f)
+				switchin(f);
+			else {
+				sprintf(path, "%s/dts", $3.val);
+				f  = fopenfile(path);
+				if (! f){
+					fprintf(stderr,  "Neither %s or %s can be opened\n", $3.val, path);
+					exit(1);
+				}
+				switchin(f);
 			}
-			switchin(f);
 		}  '{' proplist '}' ';' {
 			void	switchback(void);
 			switchback();
