代码稍有改动,自行阅读匹配;
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
* in a single byte as follows:
*
* 7:3 = slot
* 2:0 = function
*/
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
int pci_cfg_read(int bus,int dev,int func, int pos, unsigned char *buf, int len)
{
int bus=0;
int dev=0;
int func=0;
int addr = 0xcfc + (pos&3);
//printf(" enter conf1_read u=%d",u);
iopl(3);
if (pos >= 4096)
return 0;
//printf(" enter conf1_read bus=%d dev=%d func=%d",bus,dev,func);
//sleep(3);
outl(0x80000000 | ((bus & 0xff) << 16) | (PCI_DEVFN(dev, func) << 8) | (pos&~3), 0xcf8);
//printf(" outl to cf8\n");
switch (len)
{
case 1:
buf[0] = inb(addr);
break;
case 2:
((u16 *) buf)[0] = cpu_to_le16(inw(addr));
break;
case 4:
((u32 *) buf)[0] = cpu_to_le32(inl(addr));
//printf(" inl from cfc\n");
break;
default:
return 0;
}
return 1;
}
int conf1_read(int u, int pos, unsigned char *buf, int len)
{
int bus=0;
int dev=0;
int func=0;
int addr = 0xcfc + (pos&3);
//printf(" enter conf1_read u=%d",u);
iopl(3);
if (pos >= 4096)
return 0;
//printf(" enter conf1_read bus=%d dev=%d func=%d",bus,dev,func);
//sleep(3);
outl(0x80000000 | ((bus & 0xff) << 16) | (PCI_DEVFN(dev, func) << 8) | (pos&~3), 0xcf8);
//printf(" outl to cf8\n");
switch (len)
{
case 1:
buf[0] = inb(addr);
break;
case 2:
((u16 *) buf)[0] = cpu_to_le16(inw(addr));
break;
case 4:
((u32 *) buf)[0] = cpu_to_le32(inl(addr));
//printf(" inl from cfc\n");
break;
default:
return 0;
}
return 1;
}
int conf1_write(int u, int pos, unsigned char *buf, int len)
{
int bus=0;
int dev=0;
int func=0;
int addr = 0xcfc + (pos&3);
iopl(3);
if (pos >= 256)
return 0;
outl(0x80000000 | ((bus & 0xff) << 16) | (PCI_DEVFN(dev, func) << 8) | (pos&~3), 0xcf8);
switch (len)
{
case 1:
outb(buf[0], addr);
break;
case 2:
outw(le16_to_cpu(((u16 *) buf)[0]), addr);
break;
case 4:
outl(le32_to_cpu(((u32 *) buf)[0]), addr);
break;
default:
return 0;
}
return 1;
}