home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
lxapi32.zip
/
Lib32
/
lxmodule.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-26
|
8KB
|
364 lines
/* $Id: lxmodule.c,v 1.2 2002/04/26 23:09:24 smilcke Exp $ */
/*
* module.c
* Autor: Stefan Milcke
* Erstellt am: 09.12.2001
* Letzte Aenderung am: 18.02.2002
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
//#include <linux/major.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/ioctl.h>
#include <linux/timer.h>
#include <linux/module.h>
#ifndef FAR
#define FAR_LDEFOS2
#endif
#include <ldefos2.h>
#ifdef FAR_LDEFOS2
#undef FAR
#undef FAR_LDEFOS2
#endif
#include <lxapilib.h>
struct os2lx_module_entry
{
int external;
struct os2lx_module_entry *next;
struct os2lx_module *module;
};
// Linked list of all available modules
struct os2lx_module_entry *root_module=NULL;
int num_modules=0;
//----------------------------- OS2_do_add_module ------------------------------
int OS2_do_add_module(struct os2lx_module *pModule,int external)
{
struct os2lx_module_entry *module_entry;
struct os2lx_module_entry *last=root_module;
module_entry=kmalloc(sizeof(struct os2lx_module_entry),GFP_KERNEL);
if(module_entry)
{
module_entry->external=external;
module_entry->next=NULL;
module_entry->module=pModule;
while(last && NULL !=last->next)
last=last->next;
if(last)
last->next=module_entry;
else
root_module=module_entry;
return 0;
}
return -ENOMEM;
}
//------------------------------- OS2_add_module -------------------------------
int OS2_add_module(struct os2lx_module *pModule)
{
return OS2_do_add_module(pModule,1);
}
// Linked list of all active modules
struct os2lx_module_entry *active_root_module=NULL;
//------------------------------- request_module -------------------------------
int request_module(char *modName)
{
int rc=0;
struct os2lx_module_entry *p=root_module;
struct os2lx_module_entry *ap=active_root_module;
struct os2lx_module *m=NULL;
// First search in the available module list for the entry
while(p)
{
if(0==strcmp(modName,p->module->name))
{
m=p->module;
break;
}
p=p->next;
}
// Found one, so check, if it is already active
if(m)
{
while(ap)
{
if(m==ap->module)
return -EBUSY;
ap=ap->next;
}
// Not active, initialize
ap=kmalloc(sizeof(struct os2lx_module_entry),GFP_KERNEL);
if(ap)
{
ap->external=p->external;
ap->next=active_root_module;
ap->module=m;
active_root_module=ap;
m->active=1;
num_modules++;
if((m->init_fn) && (rc=m->init_fn()))
{
m->active=0;
num_modules--;
active_root_module=ap->next;
kfree(ap);
}
}
}
return rc;
}
//------------------------------- release_module -------------------------------
int release_module(char *modName)
{
int rc=-ENOENT;
struct os2lx_module_entry *p=active_root_module;
struct os2lx_module_entry *pp=NULL;
struct os2lx_module *m=NULL;
while(p)
{
if(!strcmp(modName,p->module->name))
{
m=p->module;
if(p==active_root_module)
active_root_module=p->next;
else
pp->next=p->next;
kfree(p);
if(m->cleanup_fn)
m->cleanup_fn();
m->active=0;
rc=0;
break;
}
pp=p;
p=p->next;
}
return rc;
}
//---------------------- do_cleanup_all_requested_modules ----------------------
// external: 0 = internal modules
// 1 = external modules
// 2 = both
void do_cleanup_all_requested_modules(int external)
{
struct os2lx_module_entry *p=active_root_module;
while(p)
{
if((2==external) || p->external==external)
{
release_module(p->module->name);
p=active_root_module;
}
else
p=p->next;
}
}
//----------------------- cleanup_all_requested_modules ------------------------
void cleanup_all_requested_modules(void)
{
do_cleanup_all_requested_modules(1);
do_cleanup_all_requested_modules(0);
}
//---------------------------- get_value_from_str ------------------------------
char* get_value_from_str(char *parm,int *v)
{
int base=10;
*v=0;
if(*parm=='0')
{
if(*(parm+1)=='x' || *(parm+1)=='X')
{
base=16;
parm++;
parm++;
}
}
while(*parm && *parm!=' ' && *parm!=',')
{
if(16==base && (*parm>='a' && *parm<='f'))
*v=(*v)*base+((*parm)-'a'+10);
else if(16==base && (*parm>='A' && *parm<='F'))
*v=(*v)*base+((*parm)-'A'+10);
else if(*parm>='0' && *parm<='9')
*v=(*v)*base+((*parm)-'0');
else
break;
parm++;
}
return parm;
}
//---------------------------- get_minmax_from_parm ----------------------------
char* get_minmax_from_parm(char *parm,char *type,int *min,int *max,int *subscr)
{
int v;
*min=-1;
*max=-1;
*subscr=-1;
if(strlen(type)>1)
{
type=get_value_from_str(type,&v);
if(*type)
{
*min=v;
*max=v;
*subscr=0;
if(*type=='-')
{
type++;
type=get_value_from_str(type,max);
}
}
}
if(-1!=*min)
parm=get_value_from_str(parm,subscr);
while(*parm && *parm=='=') parm++;
return parm;
}
//----------------------------- OS2_apply_mod_parm -----------------------------
int OS2_apply_mod_parm(char *parm,struct os2lx_parm *parmList,int num)
{
char cp[200];
char *p;
int rc=0;
int i;
int v;
while(*parm)
{
p=cp;
while(*parm && *parm!=';')
{
*p=*parm;
p++;
parm++;
}
*p=(char)0;
rc=-EINVAL;
for(i=0;i<num;i++)
{
if(!strncmp(parmList[i].name,cp,strlen(parmList[i].name)))
{
int min=-1,max=-1,subscr=-1;
int *ip=(int *)parmList[i].adress;
p=&(cp[strlen(parmList[i].name)]);
p=get_minmax_from_parm(p,parmList[i].type,&min,&max,&subscr);
if(-1!=subscr)
{
while(subscr+1>=min && subscr+1<=max && *p)
{
p=get_value_from_str(p,&v);
ip[subscr]=v;
rc=0;
if(*p==',')
{
p++;
subscr++;
}
else
break;
}
}
else
{
p=get_value_from_str(p,&v);
*ip=v;
rc=0;
}
break;
}
}
if(rc)
return rc;
while(*parm && *parm==';') parm++;
}
return rc;
}
//---------------------------- OS2_set_module_parm -----------------------------
int OS2_set_module_parm(char *param)
{
struct os2lx_module_entry *p=root_module;
struct os2lx_module *m;
int rc=-ENOENT;
while(p)
{
if(p->module->modParms && !strncmp(p->module->name,param,strlen(p->module->name)))
return OS2_apply_mod_parm(&(param[strlen(p->module->name)+1])
,(struct os2lx_parm *)(p->module->modParms)
,*(p->module->numModParms));
p=p->next;
}
return -ENOENT;
}
//---------------------------- OS2_get_num_modules -----------------------------
int OS2_get_num_modules(void)
{
return num_modules;
}
//---------------------------- OS2_get_module_name -----------------------------
char *OS2_get_module_name(int nr)
{
struct os2lx_module_entry *p=root_module;
while(p && nr)
{
p=p->next;
nr--;
}
if(p)
return p->module->name;
else
return "";
}
//------------------------- OS2_get_total_num_modules --------------------------
int OS2_get_total_num_modules(void)
{
int n=0;
struct os2lx_module_entry *p=root_module;
while(p)
{
p=p->next;
n++;
}
return n;
}
//------------------------------ OS2_enum_modules ------------------------------
int OS2_enum_modules(void *buffer,unsigned long buffer_len)
{
int c=0,i;
struct os2_enum_module *pd=(struct os2_enum_module *)buffer;
struct os2lx_module_entry *p=root_module;
while(p && buffer_len>=sizeof(struct os2_enum_module))
{
memcpy(pd->name,p->module->name,32);
pd->active=p->module->active;
pd++;
c++;
p=p->next;
if(buffer_len>=sizeof(struct os2_enum_module))
buffer_len-=sizeof(struct os2_enum_module);
else
buffer_len=0;
}
return c;
}