home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
lxapi32.zip
/
PCI
/
pci-nc.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-26
|
9KB
|
410 lines
/* $Id: pci-nc.c,v 1.2 2002/04/26 23:09:35 smilcke Exp $ */
/*
* pci-nc.c
* Autor: Stefan Milcke
* Erstellt am: 25.10.2001
* Letzte Aenderung am: 10.04.2002
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/init.h>
#define INCL_NOPMAPI
#include <os2.h>
#include <kee.h>
#include <mmintrin.h>
#include <ldefos2.h>
#include <stacktoflat.h>
#ifdef CONFIG_PCI_NAMES
struct pci_subsys_info
{
unsigned short vendor;
unsigned short device;
const char *name;
struct pci_subsys_info *next;
};
struct pci_device_info
{
unsigned short device;
unsigned short seen;
const char *name;
struct pci_subsys_info *subsyses;
struct pci_device_info *next;
};
struct pci_vendor_info
{
unsigned short vendor;
unsigned short nr;
const char *name;
struct pci_device_info *devices;
struct pci_vendor_info *next;
};
static struct pci_vendor_info *vendors=0;
static struct pci_vendor_info *plvi=0;
static struct pci_device_info *pldi=0;
static struct pci_subsys_info *plsi=0;
#define MAX_LINE_LENGTH 1024
static char* line=(char*)NULL;
struct KEEfileptr
{
HFILE hFile;
KEEhfile khFile;
QWORD off;
KEEfilesize sz;
char *contents;
};
//------------------------- get_next_line_from_keefile -------------------------
static char* get_next_line_from_keefile(struct KEEfileptr *fp
,ULONG maxLen,PULONG pBytesRead)
{
line[0]='#';
do
{
ULONG c;
char *s=(fp->contents+fp->off.ulLo);
if(maxLen>MAX_LINE_LENGTH)
maxLen=MAX_LINE_LENGTH;
if(maxLen>(fp->sz.ulLo - fp->off.ulLo))
maxLen=fp->sz.ulLo - fp->off.ulLo;
*pBytesRead=0;
for(c=0;c<maxLen;c++)
{
fp->off.ulLo++;
if(0==fp->off.ulLo)
fp->off.ulHi++;
if(s[c]==0x0a)
{
c++;
break;
}
}
if(c>maxLen)
c=maxLen;
if(0==c)
return (char *)NULL;
if(c!=maxLen)
line[c]=(char)0;
memcpy(line,s,c);
*pBytesRead=c;
if((char)0!=line[0])
line[strlen(line)-1]=(char)0;
}while(line[0]=='#' || line[0]==' ' || line[0]==0x0a || line[0]==(char)0);
return line;
}
//---------------------------------- get_hex -----------------------------------
static int get_hex(char **p)
{
register int c;
register int v=0;
while(**p)
{
c=**p;
if((c)>='0' && (c)<='9')
v=v*16+(int)(c-'0');
else if((c)>='A' && (c)<='F')
v=v*16+(int)(c-('A'-10));
else if((c)>='a' && (c)<='f')
v=v*16+(int)(c-('a'-10));
else
break;
(*p)++;
}
return v;
}
//--------------------------------- get_entry ----------------------------------
static char* get_entry(char *p,int *pId,int *pType,int *pId2)
{
char *n;
*pType=0;
while(p && *p=='\t')
{
(*pType)++;
p++;
}
*pId=get_hex(&p);
while(*p==' ' || *p=='\t')
p++;
if(*pType==2)
{
*pId2=get_hex(&p);
while(*p==' ' || *p=='\t')
p++;
}
n=(char *)kmalloc(strlen(p)+1,0);
memcpy(n,p,strlen(p)+1);
return n;
}
//----------------------------- pci_generate_infos -----------------------------
static void pci_generate_infos(struct KEEfileptr *fp)
{
register char f='f';
ULONG sz;
char *s=(char *)1;
static int vnr=0;
char *name;
int id,id2;
int type;
struct pci_vendor_info *vinfo;
struct pci_device_info *dinfo;
struct pci_subsys_info *sinfo;
while(s)
{
s=get_next_line_from_keefile(fp,MAX_LINE_LENGTH,&sz);
if(s)
{
if('f'==s[0])
if('f'==s[1])
if('f'==s[2])
if('f'==s[3])
break;
{
name=get_entry(s,&id,&type,&id2);
switch(type)
{
case 0:
{
vinfo=(struct pci_vendor_info*)kmalloc(sizeof(struct pci_vendor_info),0);
vinfo->vendor=id;
vinfo->nr=vnr;
vinfo->name=name;
vinfo->next=0;
vinfo->devices=0;
if(0==vendors)
vendors=vinfo;
else
plvi->next=vinfo;
plvi=vinfo;
pldi=0;
plsi=0;
}
break;
case 1:
{
dinfo=(struct pci_device_info*)kmalloc(sizeof(struct pci_device_info),0);
dinfo->device=id;
dinfo->seen=0;
dinfo->name=name;
dinfo->next=0;
dinfo->subsyses=0;
if(plvi)
{
if(0==plvi->devices)
plvi->devices=dinfo;
else
pldi->next=dinfo;
pldi=dinfo;
plsi=0;
}
}
break;
case 2:
{
sinfo=(struct pci_subsys_info*)kmalloc(sizeof(struct pci_subsys_info),0);
sinfo->vendor=id;
sinfo->device=id2;
sinfo->name=name;
sinfo->next=0;
if(pldi)
{
if(0==pldi->subsyses)
pldi->subsyses=sinfo;
else
plsi->next=sinfo;
plsi=sinfo;
}
}
break;
default:
kfree(name);
break;
}
}
}
}
}
extern unsigned long PHPCIID;
//------------------------------- close_kee_file -------------------------------
static unsigned long close_kee_file(struct KEEfileptr *fp)
{
unsigned long rc=1;
if(fp->khFile)
{
if(fp->contents)
{
kfree(fp->contents);
fp->contents=(char *)NULL;
}
if(fp->khFile)
{
rc=KernUnLockFile(fp->khFile);
if(0==rc)
fp->khFile=(unsigned long)NULL;
}
fp->off.ulLo=0;
fp->off.ulHi=0;
fp->sz.ulLo=0;
fp->sz.ulHi=0;
}
return rc;
}
//------------------------------- open_kee_file --------------------------------
static unsigned long open_kee_file(struct KEEfileptr *fp)
{
unsigned long rc=1;
if(fp->hFile && !(fp->khFile))
{
rc=KernLockFile(fp->hFile,&(fp->khFile));
if(0==rc)
{
rc=KernGetFileSize(fp->khFile,&(fp->sz));
if(0==rc)
{
fp->contents=(char *)kmalloc(fp->sz.ulLo+10,0);
if(fp->contents)
{
unsigned long br=0;
fp->off.ulLo=0;
fp->off.ulHi=0;
rc=KernReadFileAt(fp->khFile,(PVOID)fp->contents,fp->off,fp->sz.ulLo,&br);
}
if(!fp->contents)
rc=1;
}
else
rc=1;
}
if(0!=rc)
close_kee_file(fp);
}
return rc;
}
//---------------------------- pci_name_device_init ----------------------------
void pci_name_device_init(void)
{
unsigned long rc;
unsigned short __far *phFile=(unsigned short __far *)__Make48Pointer(PHPCIID);
HFILE hf=(HFILE)*phFile;
struct KEEfileptr fp={0};
fp.hFile=hf;
rc=open_kee_file(&fp);
if(0==rc)
{
line=(char *)kmalloc(MAX_LINE_LENGTH,0);
if(line)
{
pci_generate_infos(&fp);
kfree(line);
}
rc=close_kee_file(&fp);
}
}
//---------------------------- pci_name_device_free ----------------------------
void pci_name_device_free()
{
struct pci_vendor_info *pven=vendors;
struct pci_device_info *pdev=0;
struct pci_subsys_info *psub;
while(pven)
{
struct pci_vendor_info *pv=pven;
pdev=pven->devices;
while(pdev)
{
struct pci_device_info *pd=pdev;
psub=pdev->subsyses;
while(psub)
{
struct pci_subsys_info *ps=psub;
psub=psub->next;
kfree(ps->name);
kfree(ps);
}
pdev=pdev->next;
kfree(pd->name);
kfree(pd);
}
pven=pven->next;
kfree(pv->name);
kfree(pv);
}
vendors=0;
}
unsigned long OS2_pci_name_device(struct pci_dev *dev,char *vname,char *dname,char *sname);
//------------------------------ pci_name_device -------------------------------
void pci_name_device(struct pci_dev *dev)
{
struct pci_vendor_info *pven=vendors;
struct pci_device_info *pdev=0;
struct pci_subsys_info *psub=0;
char vname[80]={0};
char dname[80]={0};
char sname[80]={0};
while(pven && pven->vendor!=dev->vendor)
pven=pven->next;
if(0==pven)
{
sprintf(dev->name,"PCI device %04x:%04x",dev->vendor,dev->device);
sprintf(vname,"%04x",dev->vendor);
}
else
{
sprintf(vname,"%s",pven->name);
pdev=pven->devices;
while(pdev && pdev->device!=dev->device)
pdev=pdev->next;
if(0==pdev)
{
sprintf(dev->name,"PCI device %04x:%04x (%s)",dev->vendor,dev->device,pven->name);
sprintf(dname,"%04x",dev->device);
}
else
{
sprintf(dev->name,"%s %s",pven->name,pdev->name);
sprintf(dname,"%s",pdev->name);
pdev->seen=pdev->seen+1;
psub=pdev->subsyses;
while(psub && (psub->vendor!=dev->subsystem_vendor || psub->device!=dev->subsystem_device))
psub=psub->next;
if(psub)
sprintf(sname,"%s",psub->name);
else
sprintf(sname,"SUB %04x:%04x",dev->subsystem_vendor,dev->subsystem_device);
}
}
{
char tmp[85];
sprintf(tmp,"%s",dev->name);
sprintf(dev->name,"B:%02x DFN:%04x (%s)"
,dev->bus->number
,dev->devfn
,tmp);
}
OS2_pci_name_device(dev,vname,dname,sname);
}
#endif // CONFIG_PCI_NAMES