426 lines
11 KiB
C
426 lines
11 KiB
C
/*
|
|
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of Conectiva Linux shall
|
|
* not be used in advertising or otherwise to promote the sale, use or other
|
|
* dealings in this Software without prior written authorization from
|
|
* Conectiva Linux.
|
|
*
|
|
* Author: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
|
|
*
|
|
*/
|
|
|
|
#ifdef USE_MODULES
|
|
#include <setjmp.h>
|
|
|
|
#ifndef HAS_GLIBC_SIGSETJMP
|
|
#if defined(setjmp) && defined(__GNU_LIBRARY__) && \
|
|
(!defined(__GLIBC__) || (__GLIBC__ < 2) || \
|
|
((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3)))
|
|
#define HAS_GLIBC_SIGSETJMP 1
|
|
#endif
|
|
#endif
|
|
|
|
#define LOADER_PRIVATE
|
|
#include "loader.h"
|
|
|
|
#define True 1
|
|
#define False 0
|
|
#define XtPointer char*
|
|
#define XtMalloc malloc
|
|
#define XtCalloc calloc
|
|
#define XtRealloc realloc
|
|
#define XtFree free
|
|
#define XtNew(t) malloc(sizeof(t))
|
|
#define XtNewString(s) ((s) ? strdup(s) : NULL)
|
|
|
|
#define pointer void*
|
|
|
|
/* XXX beware (or fix it) libc functions called here are the xf86 ones */
|
|
|
|
static void AddModuleOptions(char*, const OptionInfoRec*);
|
|
#if 0
|
|
void xf86AddDriver(DriverPtr, void*, int);
|
|
Bool xf86ServerIsOnlyDetecting(void);
|
|
void xf86AddInputDriver(InputDriverPtr, pointer, int);
|
|
void xf86AddModuleInfo(ModuleInfoPtr, void*);
|
|
Bool xf86LoaderCheckSymbol(const char*);
|
|
void xf86LoaderRefSymLists(const char **, ...);
|
|
void xf86LoaderReqSymLists(const char **, ...);
|
|
void xf86Msg(int, const char*, ...);
|
|
void xf86MsgVerb(int, int, const char*, ...);
|
|
void xf86PrintChipsets(const char*, const char*, SymTabPtr);
|
|
void xf86ErrorFVerb(int verb, const char *format, ...);
|
|
int xf86MatchDevice(const char*, GDevPtr**);
|
|
int xf86MatchPciInstances(const char*, int, SymTabPtr, PciChipsets*, GDevPtr*, int, DriverPtr,int**);
|
|
int xf86MatchIsaInstances(const char*, SymTabPtr, pointer*, DriverPtr, pointer, GDevPtr*, int, int**);
|
|
void *xf86LoadDrvSubModule(DriverPtr drv, const char*);
|
|
void xf86DrvMsg(int, int, const char*, ...);
|
|
Bool xf86IsPrimaryPci(pcVideoPtr*);
|
|
Bool xf86CheckPciSlot( const struct pci_device * );
|
|
#endif
|
|
|
|
extern char *loaderPath, **loaderList, **ploaderList;
|
|
xf86cfgModuleOptions *module_options;
|
|
|
|
extern int noverify, error_level;
|
|
|
|
int xf86ShowUnresolved = 1;
|
|
|
|
LOOKUP miLookupTab[] = {{0,0}};
|
|
LOOKUP dixLookupTab[] = {{0,0}};
|
|
LOOKUP extLookupTab[] = {{0,0}};
|
|
LOOKUP xfree86LookupTab[] = {
|
|
/* Loader functions */
|
|
SYMFUNC(LoaderDefaultFunc)
|
|
SYMFUNC(LoadSubModule)
|
|
SYMFUNC(DuplicateModule)
|
|
SYMFUNC(LoaderErrorMsg)
|
|
SYMFUNC(LoaderCheckUnresolved)
|
|
SYMFUNC(LoadExtension)
|
|
SYMFUNC(LoaderReqSymbols)
|
|
SYMFUNC(LoaderReqSymLists)
|
|
SYMFUNC(LoaderRefSymbols)
|
|
SYMFUNC(LoaderRefSymLists)
|
|
SYMFUNC(UnloadSubModule)
|
|
SYMFUNC(LoaderSymbol)
|
|
SYMFUNC(LoaderListDirs)
|
|
SYMFUNC(LoaderFreeDirList)
|
|
SYMFUNC(LoaderGetOS)
|
|
|
|
SYMFUNC(xf86AddDriver)
|
|
SYMFUNC(xf86ServerIsOnlyDetecting)
|
|
SYMFUNC(xf86AddInputDriver)
|
|
SYMFUNC(xf86AddModuleInfo)
|
|
SYMFUNC(xf86LoaderCheckSymbol)
|
|
|
|
SYMFUNC(xf86LoaderRefSymLists)
|
|
SYMFUNC(xf86LoaderReqSymLists)
|
|
SYMFUNC(xf86Msg)
|
|
SYMFUNC(xf86MsgVerb)
|
|
SYMFUNC(ErrorF)
|
|
SYMFUNC(xf86PrintChipsets)
|
|
SYMFUNC(xf86ErrorFVerb)
|
|
SYMFUNC(xf86MatchDevice)
|
|
SYMFUNC(xf86MatchPciInstances)
|
|
SYMFUNC(xf86MatchIsaInstances)
|
|
SYMFUNC(Xfree)
|
|
SYMFUNC(xf86LoadDrvSubModule)
|
|
SYMFUNC(xf86DrvMsg)
|
|
SYMFUNC(xf86IsPrimaryPci)
|
|
SYMFUNC(xf86CheckPciSlot)
|
|
SYMFUNC(XNFalloc)
|
|
SYMFUNC(XNFrealloc)
|
|
SYMFUNC(XNFcalloc)
|
|
{0,0}
|
|
};
|
|
|
|
static DriverPtr driver;
|
|
static ModuleInfoPtr info;
|
|
static SymTabPtr chips;
|
|
static int vendor;
|
|
ModuleType module_type = GenericModule;
|
|
|
|
static void
|
|
AddModuleOptions(char *name, const OptionInfoRec *option)
|
|
{
|
|
xf86cfgModuleOptions *ptr;
|
|
const OptionInfoRec *tmp;
|
|
SymTabPtr ctmp;
|
|
int count;
|
|
|
|
/* XXX If the module is already in the list, then it means that
|
|
* it is now being properly loaded by xf86cfg and the "fake" entry
|
|
* added in xf86cfgLoaderInitList() isn't required anymore.
|
|
* Currently:
|
|
* ati and vmware are known to fail. */
|
|
for (ptr = module_options; ptr; ptr = ptr->next)
|
|
if (strcmp(name, ptr->name) == 0) {
|
|
fprintf(stderr, "Module %s already in list!\n", name);
|
|
return;
|
|
}
|
|
|
|
ptr = XtNew(xf86cfgModuleOptions);
|
|
ptr->name = XtNewString(name);
|
|
ptr->type = module_type;
|
|
if (option) {
|
|
for (count = 0, tmp = option; tmp->name != NULL; tmp++, count++)
|
|
;
|
|
++count;
|
|
ptr->option = XtCalloc(1, count * sizeof(OptionInfoRec));
|
|
for (count = 0, tmp = option; tmp->name != NULL; count++, tmp++) {
|
|
memcpy(&ptr->option[count], tmp, sizeof(OptionInfoRec));
|
|
ptr->option[count].name = XtNewString(tmp->name);
|
|
if (tmp->type == OPTV_STRING || tmp->type == OPTV_ANYSTR)
|
|
ptr->option[count].value.str = XtNewString(tmp->value.str);
|
|
}
|
|
}
|
|
else
|
|
ptr->option = NULL;
|
|
if (vendor != -1 && chips) {
|
|
ptr->vendor = vendor;
|
|
for (count = 0, ctmp = chips; ctmp->name; ctmp++, count++)
|
|
;
|
|
++count;
|
|
ptr->chipsets = XtCalloc(1, count * sizeof(SymTabRec));
|
|
for (count = 0, ctmp = chips; ctmp->name != NULL; count++, ctmp++) {
|
|
memcpy(&ptr->chipsets[count], ctmp, sizeof(SymTabRec));
|
|
ptr->chipsets[count].name = XtNewString(ctmp->name);
|
|
}
|
|
}
|
|
else
|
|
ptr->chipsets = NULL;
|
|
|
|
ptr->next = module_options;
|
|
module_options = ptr;
|
|
}
|
|
|
|
extern void xf86WrapperInit(void);
|
|
|
|
void
|
|
xf86cfgLoaderInit(void)
|
|
{
|
|
LoaderInit();
|
|
xf86WrapperInit();
|
|
}
|
|
|
|
void
|
|
xf86cfgLoaderInitList(int type)
|
|
{
|
|
static const char *generic[] = {
|
|
".",
|
|
NULL
|
|
};
|
|
static const char *video[] = {
|
|
"drivers",
|
|
NULL
|
|
};
|
|
static const char *input[] = {
|
|
"input",
|
|
NULL
|
|
};
|
|
const char **subdirs;
|
|
|
|
switch (type) {
|
|
case GenericModule:
|
|
subdirs = generic;
|
|
break;
|
|
case VideoModule:
|
|
subdirs = video;
|
|
break;
|
|
case InputModule:
|
|
subdirs = input;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Invalid value passed to xf86cfgLoaderInitList.\n");
|
|
subdirs = generic;
|
|
break;
|
|
}
|
|
LoaderSetPath(loaderPath);
|
|
loaderList = LoaderListDirs(subdirs, NULL);
|
|
|
|
/* XXX Xf86cfg isn't able to provide enough wrapper functions
|
|
* to these drivers. Maybe the drivers could also be changed
|
|
* to work better when being loaded "just for testing" */
|
|
if (type == VideoModule) {
|
|
module_type = VideoModule;
|
|
AddModuleOptions("vmware", NULL);
|
|
AddModuleOptions("ati", NULL);
|
|
module_type = NullModule;
|
|
}
|
|
}
|
|
|
|
void
|
|
xf86cfgLoaderFreeList(void)
|
|
{
|
|
LoaderFreeDirList(loaderList);
|
|
}
|
|
|
|
int
|
|
xf86cfgCheckModule(void)
|
|
{
|
|
int errmaj, errmin;
|
|
ModuleDescPtr module;
|
|
|
|
driver = NULL;
|
|
chips = NULL;
|
|
info = NULL;
|
|
vendor = -1;
|
|
module_type = GenericModule;
|
|
|
|
if ((module = LoadModule(*ploaderList, NULL, NULL, NULL, NULL,
|
|
NULL, &errmaj, &errmin)) == NULL) {
|
|
LoaderErrorMsg(NULL, *ploaderList, errmaj, errmin);
|
|
return (0);
|
|
}
|
|
else if (driver && driver->AvailableOptions) {
|
|
/* at least fbdev does not call xf86MatchPciInstances in Probe */
|
|
if (driver->Identify)
|
|
(*driver->Identify)(-1);
|
|
if (driver->Probe)
|
|
(*driver->Probe)(driver, PROBE_DETECT);
|
|
AddModuleOptions(*ploaderList, (*driver->AvailableOptions)(-1, -1));
|
|
}
|
|
else if (info && info->AvailableOptions)
|
|
AddModuleOptions(*ploaderList, (*info->AvailableOptions)(NULL));
|
|
|
|
if (!noverify) {
|
|
XF86ModuleData *initdata = NULL;
|
|
char *p;
|
|
|
|
p = XtMalloc(strlen(*ploaderList) + strlen("ModuleData") + 1);
|
|
strcpy(p, *ploaderList);
|
|
strcat(p, "ModuleData");
|
|
initdata = LoaderSymbol(p);
|
|
if (initdata) {
|
|
XF86ModuleVersionInfo *vers;
|
|
|
|
vers = initdata->vers;
|
|
if (vers && strcmp(*ploaderList, vers->modname)) {
|
|
/* This was a problem at some time for some video drivers */
|
|
CheckMsg(CHECKER_FILE_MODULE_NAME_MISMATCH,
|
|
"WARNING file/module name mismatch: \"%s\" \"%s\"\n",
|
|
*ploaderList, vers->modname);
|
|
++error_level;
|
|
}
|
|
}
|
|
XtFree(p);
|
|
}
|
|
|
|
UnloadModule(module);
|
|
|
|
return (1);
|
|
}
|
|
|
|
_X_EXPORT void
|
|
xf86AddDriver(DriverPtr drv, void *module, int flags)
|
|
{
|
|
driver = drv;
|
|
if (driver)
|
|
driver->module = module;
|
|
module_type = VideoModule;
|
|
}
|
|
|
|
_X_EXPORT Bool
|
|
xf86ServerIsOnlyDetecting(void)
|
|
{
|
|
return (True);
|
|
}
|
|
|
|
_X_EXPORT void
|
|
xf86AddInputDriver(InputDriverPtr inp, void *module, int flags)
|
|
{
|
|
module_type = InputModule;
|
|
}
|
|
|
|
_X_EXPORT void
|
|
xf86AddModuleInfo(ModuleInfoPtr inf, void *module)
|
|
{
|
|
info = inf;
|
|
}
|
|
|
|
_X_EXPORT Bool
|
|
xf86LoaderCheckSymbol(const char *symbol)
|
|
{
|
|
return LoaderSymbol(symbol) != NULL;
|
|
}
|
|
|
|
_X_EXPORT void
|
|
xf86LoaderRefSymLists(const char **list0, ...)
|
|
{
|
|
}
|
|
|
|
_X_EXPORT void
|
|
xf86LoaderReqSymLists(const char **list0, ...)
|
|
{
|
|
}
|
|
|
|
#if 0
|
|
void xf86Msg(int type, const char *format, ...)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
/*ARGSUSED*/
|
|
_X_EXPORT void
|
|
xf86PrintChipsets(const char *name, const char *msg, SymTabPtr chipsets)
|
|
{
|
|
vendor = 0;
|
|
chips = chipsets;
|
|
}
|
|
|
|
_X_EXPORT int
|
|
xf86MatchDevice(const char *name, GDevPtr **gdev)
|
|
{
|
|
*gdev = NULL;
|
|
|
|
return (1);
|
|
}
|
|
|
|
_X_EXPORT int
|
|
xf86MatchPciInstances(const char *name, int VendorID, SymTabPtr chipsets, PciChipsets *PCIchipsets,
|
|
GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities)
|
|
{
|
|
vendor = VendorID;
|
|
if (chips == NULL)
|
|
chips = chipsets;
|
|
*foundEntities = NULL;
|
|
|
|
return (0);
|
|
}
|
|
|
|
_X_EXPORT int
|
|
xf86MatchIsaInstances(const char *name, SymTabPtr chipsets, IsaChipsets *ISAchipsets, DriverPtr drvp,
|
|
FindIsaDevProc FindIsaDevice, GDevPtr *devList, int numDevs, int **foundEntities)
|
|
{
|
|
*foundEntities = NULL;
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
_X_EXPORT void *
|
|
xf86LoadDrvSubModule(DriverPtr drv, const char *name)
|
|
{
|
|
pointer ret;
|
|
int errmaj = 0, errmin = 0;
|
|
|
|
ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
|
|
&errmaj, &errmin);
|
|
if (!ret)
|
|
LoaderErrorMsg(NULL, name, errmaj, errmin);
|
|
return (ret);
|
|
}
|
|
|
|
_X_EXPORT Bool
|
|
xf86IsPrimaryPci(pciVideoPtr pPci)
|
|
{
|
|
return (True);
|
|
}
|
|
|
|
_X_EXPORT Bool
|
|
xf86CheckPciSlot( const struct pci_device * d )
|
|
{
|
|
(void) d;
|
|
return (False);
|
|
}
|
|
#endif
|