open-src/xserver/xorg/driver-autoconfig.patch
changeset 606 068c11b419c9
parent 412 ac5d422c36fa
equal deleted inserted replaced
605:e5259db5befc 606:068c11b419c9
     1 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     1 From 5e847c1d4fc30a0d263a861a76982660f11998cd Mon Sep 17 00:00:00 2001
     2 # Use subject to license terms.
     2 From: Alan Coopersmith <[email protected]>
     3 #
     3 Date: Mon, 7 Jul 2008 17:08:01 -0700
     4 # Permission is hereby granted, free of charge, to any person obtaining a
     4 Subject: [PATCH] Improved driver selection when autoconfiguring driver without xorg.conf
     5 # copy of this software and associated documentation files (the
       
     6 # "Software"), to deal in the Software without restriction, including
       
     7 # without limitation the rights to use, copy, modify, merge, publish,
       
     8 # distribute, and/or sell copies of the Software, and to permit persons
       
     9 # to whom the Software is furnished to do so, provided that the above
       
    10 # copyright notice(s) and this permission notice appear in all copies of
       
    11 # the Software and that both the above copyright notice(s) and this
       
    12 # permission notice appear in supporting documentation.
       
    13 # 
       
    14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       
    15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    16 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
       
    17 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
       
    18 # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
       
    19 # INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
       
    20 # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
       
    21 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
       
    22 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
       
    23 # 
       
    24 # Except as contained in this notice, the name of a copyright holder
       
    25 # shall not be used in advertising or otherwise to promote the sale, use
       
    26 # or other dealings in this Software without prior written authorization
       
    27 # of the copyright holder.
       
    28 
     5 
    29 diff -urp -x '*~' -x '*.orig' hw/xfree86/common/xf86AutoConfig.c hw/xfree86/common/xf86AutoConfig.c
     6 - Allow returning multiple drivers to try for a given PCI id (for instance,
    30 --- hw/xfree86/common/xf86AutoConfig.c	2008-05-07 18:53:54.780461000 -0700
     7   try "geode" then "amd" for AMD Geode hardware)
    31 +++ hw/xfree86/common/xf86AutoConfig.c	2008-05-07 18:54:39.872308000 -0700
     8 - On Solaris, use VIS_GETIDENTIFIER ioctl as well as PCI id to choose drivers
    32 @@ -40,6 +40,11 @@
     9 - Use wsfb instead of fbdev as a fallback on non-Linux SPARC platforms
    33  #include "xf86Priv.h"
    10 ---
       
    11  hw/xfree86/common/xf86AutoConfig.c |  223 +++++++++++++++++++++++-------------
       
    12  1 files changed, 142 insertions(+), 81 deletions(-)
       
    13 
       
    14 diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
       
    15 index a786eed..45c42e1 100644
       
    16 --- a/hw/xfree86/common/xf86AutoConfig.c
       
    17 +++ b/hw/xfree86/common/xf86AutoConfig.c
       
    18 @@ -41,6 +41,11 @@ #include "xf86Priv.h"
    34  #include "xf86_OSlib.h"
    19  #include "xf86_OSlib.h"
       
    20  #include "dirent.h"
    35  
    21  
    36 +#ifdef sun
    22 +#ifdef sun
    37 +# include <sys/visual_io.h>
    23 +# include <sys/visual_io.h>
    38 +# include <ctype.h>
    24 +# include <ctype.h>
    39 +#endif
    25 +#endif
    40 +
    26 +
    41  /* Sections for the default built-in configuration. */
    27  /* Sections for the default built-in configuration. */
    42  
    28  
    43  #define BUILTIN_MODULE_SECTION \
    29  #define BUILTIN_DEVICE_NAME \
    44 @@ -99,7 +104,7 @@
    30 @@ -79,11 +84,8 @@ #define BUILTIN_LAYOUT_SECTION_POST \
    45  
    31  
    46  static const char **builtinConfig = NULL;
    32  static const char **builtinConfig = NULL;
    47  static int builtinLines = 0;
    33  static int builtinLines = 0;
    48 -static const char *deviceList[] = {
    34 -static const char *deviceList[] = {
    49 +static const char *fallbackDeviceList[] = {
    35 -	"fbdev",
    50  #if defined(sun) && defined(__sparc)
    36 -	"vesa",
    51  	"wsfb",
    37 -	NULL
    52  #else	
    38 -};
    53 @@ -160,70 +165,123 @@ AppendToConfig(const char *s)
    39 +
       
    40 +static void listPossibleVideoDrivers(char *matches[], int nmatches);
       
    41  
       
    42  /*
       
    43   * A built-in config file is stored as an array of strings, with each string
       
    44 @@ -135,87 +137,91 @@ AppendToConfig(const char *s)
    54      AppendToList(s, &builtinConfig, &builtinLines);
    45      AppendToList(s, &builtinConfig, &builtinLines);
    55  }
    46  }
    56  
    47  
    57 -static const char *
    48 -static const char *
    58 -videoPtrToDriverName(pciVideoPtr info)
    49 -videoPtrToDriverName(struct pci_device *dev)
    59 +static void
    50 +static int
    60 +videoPtrToDriverName(pciVideoPtr info, const char *driverList[])
    51 +videoPtrToDriverList(struct pci_device *dev,
       
    52 +		     char *returnList[], int returnListMax)
    61  {
    53  {
    62      /*
    54      /*
    63       * things not handled yet:
    55       * things not handled yet:
    64       * amd/cyrix/nsc
    56       * cyrix/nsc.  should be merged into geode anyway.
    65       * xgi
    57       * xgi.
    66       */
    58       */
    67 -
    59 +    int i;
    68      switch (info->vendor)
    60 +    /* Add more entries here if we ever return more than 4 drivers for
       
    61 +       any device */
       
    62 +    char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
       
    63  
       
    64      switch (dev->vendor_id)
    69      {
    65      {
       
    66  	case 0x1022:
       
    67 -		if (dev->device_id == 0x2081)
       
    68 -			return "geode";
       
    69 -		else
       
    70 -			return NULL;
    70 -	case 0x1142:		    return "apm";
    71 -	case 0x1142:		    return "apm";
    71 -	case 0xedd8:		    return "ark";
    72 -	case 0xedd8:		    return "ark";
    72 -	case 0x1a03:		    return "ast";
    73 -	case 0x1a03:		    return "ast";
    73 -	case 0x1002:		    return "ati";
    74 -	case 0x1002:		    return "ati";
    74 -	case 0x102c:		    return "chips";
    75 -	case 0x102c:		    return "chips";
    75 -	case 0x1013:		    return "cirrus";
    76 -	case 0x1013:		    return "cirrus";
    76 +	case 0x1142:		    driverList[0] = "apm";	break;
    77 +	    if (dev->device_id == 0x2081) {
    77 +	case 0xedd8:		    driverList[0] = "ark";	break;
    78 +		driverList[0] = "geode";
    78 +	case 0x1a03:		    driverList[0] = "ast";	break;
    79 +		driverList[1] = "amd";
    79 +	case 0x1002:
    80 +	    }
    80 +	    driverList[0] = "ati";
       
    81 +	    driverList[1] = "radeonhd";
       
    82 +	    break;
    81 +	    break;
    83 +	case 0x102c:		    driverList[0] = "chips";	break;
    82 +	case 0x1142:		    driverList[0] = "apm"; break;
    84 +	case 0x1013:		    driverList[0] = "cirrus";	break;
    83 +	case 0xedd8:		    driverList[0] = "ark"; break;
       
    84 +	case 0x1a03:		    driverList[0] = "ast"; break;
       
    85 +	case 0x1002:		    driverList[0] = "ati"; break;
       
    86 +	case 0x102c:		    driverList[0] = "chips"; break;
       
    87 +	case 0x1013:		    driverList[0] = "cirrus"; break;
    85  	case 0x8086:
    88  	case 0x8086:
    86 -	    if ((info->chipType == 0x00d1) || (info->chipType == 0x7800))
    89 -	    if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800))
    87 -		return "i740";
    90 -		return "i740";
    88 -	    else return "i810";
    91 -	    else return "intel";
    89 -	case 0x102b:		    return "mga";
    92 -	case 0x102b:		    return "mga";
    90 -	case 0x10c8:		    return "neomagic";
    93 -	case 0x10c8:		    return "neomagic";
    91 -	case 0x105d:		    return "i128";
    94 -	case 0x105d:		    return "i128";
    92 -	case 0x10de: case 0x12d2:   return "nv";
    95 -	case 0x10de: case 0x12d2:   return "nv";
    93 -	case 0x1163:		    return "rendition";
    96 -	case 0x1163:		    return "rendition";
    94 +	    if ((info->chipType == 0x00d1) || (info->chipType == 0x7800)) {
    97 +	    if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
    95 +		driverList[0] = "i740";
    98 +		driverList[0] = "i740";
    96 +	    } else {
    99 +	    } else {
    97 +		driverList[0] = "intel";
   100 +		driverList[0] = "intel";
    98 +		driverList[1] = "i810";
   101 +		driverList[1] = "i810";
    99 +	    }
   102 +	    }
   100 +	    break;
   103 +	    break;
   101 +	case 0x102b:		    driverList[0] = "mga";	break;
   104 +	case 0x102b:		    driverList[0] = "mga";	break;
   102 +	case 0x10c8:		    driverList[0] = "neomagic";	break;
   105 +	case 0x10c8:		    driverList[0] = "neomagic"; break;
   103 +	case 0x105d:		    driverList[0] = "i128";	break;
   106 +	case 0x105d:		    driverList[0] = "i128";	break;
   104 +	case 0x10de: case 0x12d2:   driverList[0] = "nv";	break;
   107 +	case 0x10de: case 0x12d2:   driverList[0] = "nv";	break;
   105 +	case 0x1163:		    driverList[0] = "rendition";break;
   108 +	case 0x1163:		    driverList[0] = "rendition"; break;
   106  	case 0x5333:
   109  	case 0x5333:
   107  	    switch (info->chipType)
   110  	    switch (dev->device_id)
   108  	    {
   111  	    {
   109  		case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
   112  		case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
   110  		case 0x8812: case 0x8814: case 0x8901:
   113  		case 0x8812: case 0x8814: case 0x8901:
   111 -		    return "s3";
   114 -		    return "s3";
   112 +		    driverList[0] = "s3";
   115 +		    driverList[0] = "s3"; break;
   113 +		    break;
       
   114  		case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
   116  		case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
   115  		case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
   117  		case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
   116 -		    return "s3virge";
   118 -		    return "s3virge";
   117 +		    driverList[0] = "s3virge";
   119 +		    driverList[0] = "s3virge"; break;
   118 +		    break;
       
   119  		default:
   120  		default:
   120 -		    return "savage";
   121 -		    return "savage";
   121 +		    driverList[0] = "savage";
   122 +		    driverList[0] = "savage"; break;
   122 +		    break;
       
   123  	    }
   123  	    }
   124 -	case 0x1039:		    return "sis";
   124 -	case 0x1039:		    return "sis";
   125 -	case 0x126f:		    return "siliconmotion";
   125 -	case 0x126f:		    return "siliconmotion";
   126 +	    break;
   126 +	    break;
   127 +	case 0x1039:		    driverList[0] = "sis";	break;
   127 +	case 0x1039:		    driverList[0] = "sis";	break;
   128 +	case 0x126f:		    driverList[0] = "siliconmotion"; break;
   128 +	case 0x126f:		    driverList[0] = "siliconmotion"; break;
   129  	case 0x121a:
   129  	case 0x121a:
   130  	    if (info->chipType < 0x0003)
   130  	    if (dev->device_id < 0x0003)
   131 -	        return "voodoo";
   131 -	        return "voodoo";
   132 +	        driverList[0] = "voodoo";
   132 +	        driverList[0] = "voodoo";
   133  	    else
   133  	    else
   134 -	        return "tdfx";
   134 -	        return "tdfx";
   135 -	case 0x3d3d:		    return "glint";
   135 -	case 0x3d3d:		    return "glint";
   136 -	case 0x1023:		    return "trident";
   136 -	case 0x1023:		    return "trident";
   137 -	case 0x100c:		    return "tseng";
   137 -	case 0x100c:		    return "tseng";
   138 -	case 0x1106:		    return "via";
   138 -	case 0x1106:		    return "openchrome";
   139 -	case 0x15ad:		    return "vmware";
   139 -	case 0x15ad:		    return "vmware";
   140 +	        driverList[0] = "tdfx";
   140 +	        driverList[0] = "tdfx";
   141 +	    break;
   141 +	    break;
   142 +	case 0x3d3d:		    driverList[0] = "glint";	break;
   142 +	case 0x3d3d:		    driverList[0] = "glint";	break;
   143 +	case 0x1023:		    driverList[0] = "trident";	break;
   143 +	case 0x1023:		    driverList[0] = "trident"; break;
   144 +	case 0x100c:		    driverList[0] = "tseng";	break;
   144 +	case 0x100c:		    driverList[0] = "tseng";	break;
   145 +	case 0x1106:
   145 +	case 0x1106:		    driverList[0] = "openchrome"; break;
   146 +	    driverList[0] = "openchrome";
       
   147 +	    driverList[1] = "via";
       
   148 +	    break;
       
   149 +	case 0x15ad:		    driverList[0] = "vmware";	break;
   146 +	case 0x15ad:		    driverList[0] = "vmware";	break;
   150  	default: break;
   147  	default: break;
   151      }
   148      }
   152 -    return NULL;
   149 -    return NULL;
       
   150 +    for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) {
       
   151 +	returnList[i] = xnfstrdup(driverList[i]);
       
   152 +    }
       
   153 +    return i;	/* Number of entries added */
   153  }
   154  }
   154  
   155  
   155  Bool
   156  Bool
   156  xf86AutoConfig(void)
   157  xf86AutoConfig(void)
   157  {
   158  {
   158 -    const char **p;
   159 -    const char **p;
   159 +    const char *detectedDeviceList[8] = { NULL, NULL, NULL, NULL,
   160 +    char *deviceList[20];
   160 +    					  NULL, NULL, NULL, NULL };
   161 +    char **p;
   161 +    const char **deviceLists[3]
   162 +    const char **cp;
   162 +	= { detectedDeviceList, fallbackDeviceList, NULL };
       
   163 +    const char **p = detectedDeviceList;
       
   164 +    const char ***d;
       
   165      char buf[1024];
   163      char buf[1024];
   166      pciVideoPtr *pciptr, info = NULL;
   164 -    const char *driver = NULL;
   167 -    char *driver = NULL;
       
   168      ConfigStatus ret;
   165      ConfigStatus ret;
   169 +#ifdef sun
   166  
   170 +    char *vendorName = NULL, *driverName = NULL;
   167 -    driver = chooseVideoDriver();
   171  
       
   172 +    /* Check for driver type based on /dev/fb type and if valid, replace
       
   173 +       detectedDeviceList */
       
   174 +    if (xf86Info.consoleFd  >= 0) {
       
   175 +	struct vis_identifier   visid;
       
   176 +	const char *cp;
       
   177 +	int ddi = 0;
       
   178 +
       
   179 +	if (ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid) >= 0) {
       
   180 +	    xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
       
   181 +
       
   182 +	    /* Special case from before the general case was set */
       
   183 +	    if (strcmp(visid.name, "NVDAnvda") == 0) {
       
   184 +		detectedDeviceList[ddi++] = "nvidia";
       
   185 +	    }
       
   186 +
       
   187 +	    /* General case - split into vendor name & driver name */
       
   188 +	    if (strcmp(visid.name, "SUNWtext") != 0) {
       
   189 +		for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
       
   190 +		    /* find end of all uppercase vendor section */
       
   191 +		}
       
   192 +		if ((cp != visid.name) && (*cp != '\0')) {
       
   193 +		    vendorName = xnfstrdup(visid.name);
       
   194 +		    vendorName[cp - visid.name] = '\0';
       
   195 +		    driverName = xnfstrdup(cp);
       
   196 +
       
   197 +		    detectedDeviceList[ddi++] = vendorName;
       
   198 +		    detectedDeviceList[ddi++] = driverName;
       
   199 +		}
       
   200 +	    }
       
   201 +	    p = &detectedDeviceList[ddi];
       
   202 +	}
       
   203 +    }
       
   204 +#endif
       
   205 +    
       
   206      /* Find the primary device, and get some information about it. */
       
   207      if (xf86PciVideoInfo) {
       
   208  	for (pciptr = xf86PciVideoInfo; (info = *pciptr); pciptr++) {
       
   209 @@ -239,38 +297,29 @@ xf86AutoConfig(void)
       
   210      }
       
   211  
       
   212      if (info)
       
   213 -	driver = videoPtrToDriverName(info);
       
   214 -
       
   215 +	videoPtrToDriverName(info, p);
       
   216 +    
       
   217      AppendToConfig(BUILTIN_MODULE_SECTION);
       
   218      AppendToConfig(BUILTIN_MONITOR_SECTION);
       
   219 -
   168 -
   220 -    if (driver) {
   169 -    if (driver) {
   221 -	snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION_PRE,
   170 -	snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION_PRE,
   222 -		 driver, 0, driver);
   171 -		 driver, 0, driver);
   223 -	AppendToConfig(buf);
   172 -	AppendToConfig(buf);
   226 -	AppendToConfig(BUILTIN_DEVICE_SECTION_POST);
   175 -	AppendToConfig(BUILTIN_DEVICE_SECTION_POST);
   227 -	snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION,
   176 -	snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION,
   228 -		 driver, 0, driver, 0);
   177 -		 driver, 0, driver, 0);
   229 -	AppendToConfig(buf);
   178 -	AppendToConfig(buf);
   230 -    }
   179 -    }
   231 -
   180 +    listPossibleVideoDrivers(deviceList, 20);
   232 -    for (p = deviceList; *p; p++) {
   181  
   233 -	snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
   182      for (p = deviceList; *p; p++) {
   234 -	AppendToConfig(buf);
   183  	snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
   235 -	snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
   184 @@ -225,23 +231,23 @@ xf86AutoConfig(void)
   236 -	AppendToConfig(buf);
   185      }
   237 +    
       
   238 +    ErrorF("Drivers to try are:");
       
   239 +    for (d = deviceLists; *d ; d++) {
       
   240 +	for (p = *d; *p; p++) {
       
   241 +	    ErrorF(" \"%s\"", *p);
       
   242 +	    snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
       
   243 +	    AppendToConfig(buf);
       
   244 +	    snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
       
   245 +	    AppendToConfig(buf);
       
   246 +	}
       
   247      }
       
   248 +    ErrorF("\n");
       
   249  
   186  
   250      AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
   187      AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
   251 -    if (driver) {
   188 -    if (driver) {
   252 -	snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, driver, 0);
   189 -	snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, driver, 0);
   253 -	AppendToConfig(buf);
   190 -	AppendToConfig(buf);
   254 -    }
   191 -    }
   255 -    for (p = deviceList; *p; p++) {
   192      for (p = deviceList; *p; p++) {
   256 -	snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
   193  	snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
   257 -	AppendToConfig(buf);
   194  	AppendToConfig(buf);
   258 +    for (d = deviceLists; *d ; d++) {
   195      }
   259 +	for (p = *d; *p; p++) {
   196      AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
   260 +	    snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
   197  
   261 +	    AppendToConfig(buf);
   198 +    for (p = deviceList; *p; p++) {
       
   199 +	xfree(*p);
       
   200 +    }
       
   201 +
       
   202      xf86MsgVerb(X_DEFAULT, 0,
       
   203  		"Using default built-in configuration (%d lines)\n",
       
   204  		builtinLines);
       
   205  
       
   206      xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
       
   207 -    for (p = builtinConfig; *p; p++)
       
   208 -	xf86ErrorFVerb(3, "\t%s", *p);
       
   209 +    for (cp = builtinConfig; *cp; cp++)
       
   210 +	xf86ErrorFVerb(3, "\t%s", *cp);
       
   211      xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
       
   212      
       
   213      xf86setBuiltinConfig(builtinConfig);
       
   214 @@ -416,17 +422,51 @@ #endif /* __GLIBC __ */
       
   215  }
       
   216  #endif /* __linux__ */
       
   217  
       
   218 -char*
       
   219 -chooseVideoDriver(void)
       
   220 +static void
       
   221 +listPossibleVideoDrivers(char *matches[], int nmatches)
       
   222  {
       
   223      struct pci_device * info = NULL;
       
   224      struct pci_device_iterator *iter;
       
   225 -    char *chosen_driver = NULL;
       
   226      int i;
       
   227 -    char *matches[20]; /* If we have more than 20 drivers we're in trouble */
       
   228      
       
   229 -    for (i=0 ; i<20 ; i++)
       
   230 +    for (i = 0 ; i < nmatches ; i++) {
       
   231          matches[i] = NULL;
       
   232 +    }
       
   233 +    i = 0;
       
   234 +
       
   235 +#ifdef sun
       
   236 +    /* Check for driver type based on /dev/fb type and if valid, use
       
   237 +       it instead of PCI bus probe results */
       
   238 +    if (xf86Info.consoleFd >= 0) {
       
   239 +	struct vis_identifier   visid;
       
   240 +	const char *cp;
       
   241 +
       
   242 +	if (ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid) >= 0) {
       
   243 +	    xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
       
   244 +
       
   245 +	    /* Special case from before the general case was set */
       
   246 +	    if (strcmp(visid.name, "NVDAnvda") == 0) {
       
   247 +		matches[i++] = xnfstrdup("nvidia");
       
   248 +	    }
       
   249 +
       
   250 +	    /* General case - split into vendor name (initial all-caps
       
   251 +	       prefix) & driver name (rest of the string). */
       
   252 +	    if (strcmp(visid.name, "SUNWtext") != 0) {
       
   253 +		for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
       
   254 +		    /* find end of all uppercase vendor section */
       
   255 +		}
       
   256 +		if ((cp != visid.name) && (*cp != '\0')) {
       
   257 +		    char *driverName = xnfstrdup(cp);
       
   258 +		    char *vendorName = xnfstrdup(visid.name);
       
   259 +		    vendorName[cp - visid.name] = '\0';
       
   260 +
       
   261 +		    matches[i++] = vendorName;
       
   262 +		    matches[i++] = driverName;
       
   263 +		}
       
   264 +	    }
   262 +	}
   265 +	}
   263      }
   266 +    }
   264      AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
       
   265  
       
   266 @@ -287,6 +336,11 @@ xf86AutoConfig(void)
       
   267      ret = xf86HandleConfigFile(TRUE);
       
   268      FreeConfig();
       
   269  
       
   270 +#ifdef sun
       
   271 +    xfree(driverName);
       
   272 +    xfree(vendorName);
       
   273 +#endif
   267 +#endif
   274 +    
   268  
   275      if (ret != CONFIG_OK)
   269      /* Find the primary device, and get some information about it. */
   276  	xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
   270      iter = pci_slot_match_iterator_create(NULL);
   277  
   271 @@ -447,31 +487,52 @@ #ifdef __linux__
       
   272      }
       
   273  #endif /* __linux__ */
       
   274  
       
   275 -    /* TODO Handle multiple drivers claiming to support the same PCI ID */
       
   276 -    if (matches[0]) {
       
   277 -        chosen_driver = matches[0];
       
   278 -    } else {
       
   279 -	if (info != NULL)
       
   280 -	    chosen_driver = videoPtrToDriverName(info);
       
   281 -	if (chosen_driver == NULL) {
       
   282 -#if defined  __i386__ || defined __amd64__ || defined __hurd__
       
   283 -	    chosen_driver = "vesa";
       
   284 -#elif defined __sparc__
       
   285 -	    chosen_driver = "sunffb";
       
   286 +    for (i = 0; (i < nmatches) && (matches[i]); i++) {
       
   287 +	/* find end of matches list */
       
   288 +    }
       
   289 +
       
   290 +    if ((info != NULL) && (i < nmatches)) {
       
   291 +	i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
       
   292 +    }
       
   293 +
       
   294 +    /* Fallback to platform default hardware */
       
   295 +    if (i < (nmatches - 1)) {
       
   296 +#if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
       
   297 +	matches[i++] = xnfstrdup("vesa");
       
   298 +#elif defined(__sparc__) && !defined(sun)
       
   299 +	matches[i++] = xnfstrdup("sunffb");
       
   300 +#endif
       
   301 +    }
       
   302 +
       
   303 +    /* Fallback to platform default frame buffer driver */
       
   304 +    if (i < (nmatches - 1)) {
       
   305 +#if !defined(__linux__) && defined(__sparc__)
       
   306 +	matches[i++] = xnfstrdup("wsfb");
       
   307  #else
       
   308 -	    chosen_driver = "fbdev";
       
   309 +	matches[i++] = xnfstrdup("fbdev");
       
   310  #endif
       
   311 -	}
       
   312      }
       
   313 +}
       
   314 +
       
   315 +char*
       
   316 +chooseVideoDriver(void)
       
   317 +{
       
   318 +    char *chosen_driver = NULL;
       
   319 +    int i;
       
   320 +    char *matches[20]; /* If we have more than 20 drivers we're in trouble */
       
   321  
       
   322 -    xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
       
   323 +    listPossibleVideoDrivers(matches, 20);
       
   324  
       
   325 -    i = 0;
       
   326 -    while (matches[i]) {
       
   327 +    /* TODO Handle multiple drivers claiming to support the same PCI ID */
       
   328 +    chosen_driver = matches[0];
       
   329 +
       
   330 +    xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n",
       
   331 +	    chosen_driver);
       
   332 +
       
   333 +    for (i = 0; matches[i] ; i++) {
       
   334          if (matches[i] != chosen_driver) {
       
   335              xfree(matches[i]);
       
   336          }
       
   337 -        i++;
       
   338      }
       
   339  
       
   340      return chosen_driver;
       
   341 -- 
       
   342 1.4.1
       
   343