Commit 55ff4d61 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linuxusb.bkbits.net/pci-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 508d8728 17aa2fe5
......@@ -90,12 +90,11 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
" pci_addr=0x%p, type1=0x%p)\n",
......@@ -273,87 +272,66 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
static int
apecs_read_config_byte(struct pci_dev *dev, int where, u8 *value)
apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
u8 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
long mask;
int shift;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x00 + APECS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
apecs_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x08 + APECS_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
apecs_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x18 + APECS_CONF;
*value = conf_read(addr, type1);
switch (size) {
case 1:
mask = 0x00;
shift = (where & 3) * 8;
break;
case 2:
mask = 0x08;
shift = (where & 3) * 8;
break;
case 4:
mask = 0x18;
shift = 0;
break;
}
addr = (pci_addr << 5) + mask + APECS_CONF;
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
apecs_write_config(struct pci_dev *dev, int where, u32 value, long mask)
apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
unsigned long addr, pci_addr;
unsigned char type1;
long mask;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1:
mask = 0x00;
break;
case 2:
mask = 0x08;
break;
case 4:
mask = 0x18;
break;
}
addr = (pci_addr << 5) + mask + APECS_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
static int
apecs_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
return apecs_write_config(dev, where, value, 0x00);
}
static int
apecs_write_config_word(struct pci_dev *dev, int where, u16 value)
{
return apecs_write_config(dev, where, value, 0x08);
}
static int
apecs_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return apecs_write_config(dev, where, value, 0x18);
}
struct pci_ops apecs_pci_ops =
{
read_byte: apecs_read_config_byte,
read_word: apecs_read_config_word,
read_dword: apecs_read_config_dword,
write_byte: apecs_write_config_byte,
write_word: apecs_write_config_word,
write_dword: apecs_write_config_dword
.read = apecs_read_config,
.write = apecs_write_config,
};
void
......
......@@ -89,11 +89,10 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
*type1 = (bus != 0);
*pci_addr = (bus << 16) | (device_fn << 8) | where;
......@@ -209,87 +208,69 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
static int
cia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
cia_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
u32 *value)
{
unsigned long addr, pci_addr;
long mask;
unsigned char type1;
int shift;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x00 + CIA_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
cia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x08 + CIA_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
cia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1:
mask = 0x00;
shift = (where & 3) * 8;
break;
case 2:
mask = 0x08;
shift = (where & 3) * 8;
break;
case 4:
mase = 0x18;
shift = 0;
break;
}
addr = (pci_addr << 5) + 0x18 + CIA_CONF;
*value = conf_read(addr, type1);
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
cia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
cia_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
u32 value)
{
unsigned long addr, pci_addr;
long mask;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1:
mask = 0x00;
break;
case 2:
mask = 0x08;
break;
case 4:
mase = 0x18;
break;
}
addr = (pci_addr << 5) + mask + CIA_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
static int
cia_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
return cia_write_config(dev, where, value, 0x00);
}
static int
cia_write_config_word(struct pci_dev *dev, int where, u16 value)
{
return cia_write_config(dev, where, value, 0x08);
}
static int
cia_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return cia_write_config(dev, where, value, 0x18);
}
struct pci_ops cia_pci_ops =
{
read_byte: cia_read_config_byte,
read_word: cia_read_config_word,
read_dword: cia_read_config_dword,
write_byte: cia_write_config_byte,
write_word: cia_write_config_word,
write_dword: cia_write_config_dword
.read = cia_read_config,
.write = cia_write_config,
};
/*
......
......@@ -83,12 +83,11 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
......@@ -105,12 +104,13 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
}
static int
irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
irongate_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldbu(*(vucp)addr);
......@@ -118,38 +118,13 @@ irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
}
static int
irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
irongate_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldwu(*(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
static int
irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
static int
irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)addr);
......@@ -158,45 +133,11 @@ irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
return PCIBIOS_SUCCESSFUL;
}
static int
irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)addr);
mb();
__kernel_ldwu(*(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
static int
irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)addr = value;
mb();
*(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops irongate_pci_ops =
{
read_byte: irongate_read_config_byte,
read_word: irongate_read_config_word,
read_dword: irongate_read_config_dword,
write_byte: irongate_write_config_byte,
write_word: irongate_write_config_word,
write_dword: irongate_write_config_dword
.read = irongate_read_config,
.write = irongate_write_config,
};
#ifdef DEBUG_IRONGATE
......
......@@ -99,11 +99,11 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr)
{
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
if (bus == 0) {
int device = device_fn >> 3;
......@@ -199,83 +199,65 @@ conf_write(unsigned long addr, unsigned int value)
}
static int
lca_read_config_byte(struct pci_dev *dev, int where, u8 *value)
lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr, pci_addr;
long mask;
int shift
if (mk_conf_addr(dev, where, &pci_addr))
if (mk_conf_addr(bus, devfn, dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x00 + LCA_CONF;
*value = conf_read(addr) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
lca_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long addr, pci_addr;
if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x08 + LCA_CONF;
*value = conf_read(addr) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
lca_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr, pci_addr;
if (mk_conf_addr(dev, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x18 + LCA_CONF;
*value = conf_read(addr);
switch (size) {
case 1:
shift = (where & 3) * 8;
mask = 0x00;
break;
case 2:
shift = (where & 3) * 8;
mask = 0x08
break;
case 4:
shift = 0;
mask = 0x18
break;
}
addr = (pci_addr << 5) + mask + LCA_CONF;
*value = conf_read(addr) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
lca_write_config(struct pci_dev *dev, int where, u32 value, long mask)
lca_write_config(struct pci_bus *dev, unsigned int devfn, int where, int size,
u32 value)
{
unsigned long addr, pci_addr;
long mask;
if (mk_conf_addr(dev, where, &pci_addr))
if (mk_conf_addr(bus, devfn, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1:
mask = 0x00;
break;
case 2:
mask = 0x08
break;
case 4:
mask = 0x18
break;
}
addr = (pci_addr << 5) + mask + LCA_CONF;
conf_write(addr, value << ((where & 3) * 8));
return PCIBIOS_SUCCESSFUL;
}
static int
lca_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
return lca_write_config(dev, where, value, 0x00);
}
static int
lca_write_config_word(struct pci_dev *dev, int where, u16 value)
{
return lca_write_config(dev, where, value, 0x08);
}
static int
lca_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return lca_write_config(dev, where, value, 0x18);
}
struct pci_ops lca_pci_ops =
{
read_byte: lca_read_config_byte,
read_word: lca_read_config_word,
read_dword: lca_read_config_dword,
write_byte: lca_write_config_byte,
write_word: lca_write_config_word,
write_dword: lca_write_config_dword
.read = lca_read_config,
.write = lca_write_config,
};
void
......
......@@ -65,10 +65,10 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, u8 *type1)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr, u8 *type1)
{
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
*type1 = (bus == 0) ? 0 : 1;
*pci_addr = (bus << 16) | (device_fn << 8) | (where) |
......@@ -82,51 +82,28 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr, u8 *type1)
}
static int
polaris_read_config_byte(struct pci_dev *dev, int where, u8 *value)
polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldbu(*(vucp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
static int
polaris_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = __kernel_ldwu(*(vusp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
int
polaris_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*value = *(vuip)pci_addr;
return PCIBIOS_SUCCESSFUL;
}
static int
polaris_write_config_byte(struct pci_dev *dev, int where, u8 value)
polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)pci_addr);
......@@ -135,44 +112,10 @@ polaris_write_config_byte(struct pci_dev *dev, int where, u8 value)
return PCIBIOS_SUCCESSFUL;
}
static int
polaris_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)pci_addr);
mb();
__kernel_ldwu(*(vusp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
int
polaris_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)pci_addr = value;
mb();
*(vuip)pci_addr;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops polaris_pci_ops =
{
read_byte: polaris_read_config_byte,
read_word: polaris_read_config_word,
read_dword: polaris_read_config_dword,
write_byte: polaris_write_config_byte,
write_word: polaris_write_config_word,
write_dword: polaris_write_config_dword
.read = polaris_read_config,
.write = polaris_write_config,
};
void __init
......
......@@ -89,12 +89,11 @@
*/
static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
u8 bus = bus_dev->number;
DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
" addr=0x%lx, type1=0x%x)\n",
......@@ -238,87 +237,67 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
static int
t2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
t2_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
int shift;
long mask;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x00 + T2_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
t2_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x08 + T2_CONF;
*value = conf_read(addr, type1) >> ((where & 3) * 8);
return PCIBIOS_SUCCESSFUL;
}
static int
t2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
addr = (pci_addr << 5) + 0x18 + T2_CONF;
*value = conf_read(addr, type1);
switch (size) {
case 1:
mask = 0x00;
shift = (where & 3) * 8;
break;
case 2:
mask = 0x08;
shift = (where & 3) * 8;
break;
case 4:
mask = 0x18;
shift = 0;
break;
}
addr = (pci_addr << 5) + mask + T2_CONF;
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
t2_write_config(struct pci_dev *dev, int where, u32 value, long mask)
t2_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
u32 value)
{
unsigned long addr, pci_addr;
unsigned char type1;
long mask;
if (mk_conf_addr(dev, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
case 1:
mask = 0x00;
break;
case 2:
mask = 0x08;
break;
case 4:
mask = 0x18;
break;
}
addr = (pci_addr << 5) + mask + T2_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
}
static int
t2_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
return t2_write_config(dev, where, value, 0x00);
}
static int
t2_write_config_word(struct pci_dev *dev, int where, u16 value)
{
return t2_write_config(dev, where, value, 0x08);
}
static int
t2_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return t2_write_config(dev, where, value, 0x18);
}
struct pci_ops t2_pci_ops =
{
read_byte: t2_read_config_byte,
read_word: t2_read_config_word,
read_dword: t2_read_config_dword,
write_byte: t2_write_config_byte,
write_word: t2_write_config_word,
write_dword: t2_write_config_dword
.read = t2_read_config,
.write = t2_write_config,
};
void __init
......
......@@ -25,9 +25,6 @@ int pcibios_last_bus = -1;
struct pci_bus *pci_root_bus = NULL;
struct pci_ops *pci_root_ops = NULL;
int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
/*
* legacy, numa, and acpi all want to call pcibios_scan_root
* from their initcalls. This flag prevents that.
......
......@@ -13,7 +13,7 @@
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
......@@ -41,7 +41,7 @@ static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
......@@ -69,75 +69,23 @@ static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
#undef PCI_CONF1_ADDRESS
static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
if (!value)
return -EINVAL;
return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
return __pci_conf1_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
}
static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_conf1_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static struct pci_ops pci_direct_conf1 = {
pci_conf1_read_config_byte,
pci_conf1_read_config_word,
pci_conf1_read_config_dword,
pci_conf1_write_config_byte,
pci_conf1_write_config_word,
pci_conf1_write_config_dword
.read = pci_conf1_read,
.write = pci_conf1_write,
};
......@@ -147,7 +95,7 @@ static struct pci_ops pci_direct_conf1 = {
#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg)
static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
......@@ -181,7 +129,7 @@ static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
......@@ -217,57 +165,21 @@ static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len,
#undef PCI_CONF2_ADDRESS
static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
int result;
u32 data;
result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
int result;
u32 data;
result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
return pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
static int pci_conf2_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
return __pci_conf2_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
static int pci_conf2_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
}
static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_conf2_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static struct pci_ops pci_direct_conf2 = {
pci_conf2_read_config_byte,
pci_conf2_read_config_word,
pci_conf2_read_config_dword,
pci_conf2_write_config_byte,
pci_conf2_write_config_word,
pci_conf2_write_config_dword
.read = pci_conf2_read,
.write = pci_conf2_write,
};
......@@ -283,7 +195,7 @@ static struct pci_ops pci_direct_conf2 = {
*/
static int __devinit pci_sanity_check(struct pci_ops *o)
{
u16 x;
u32 x = 0;
struct pci_bus bus; /* Fake bus and device */
struct pci_dev dev;
......@@ -292,16 +204,16 @@ static int __devinit pci_sanity_check(struct pci_ops *o)
bus.number = 0;
dev.bus = &bus;
for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
if ((!o->read(&bus, dev.devfn, PCI_CLASS_DEVICE, 2, &x) &&
(x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
(!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
(!o->read(&bus, dev.devfn, PCI_VENDOR_ID, 2, &x) &&
(x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
return 1;
DBG("PCI: Sanity check failed\n");
return 0;
}
static struct pci_ops * __devinit pci_check_direct(void)
static int __init pci_direct_init(void)
{
unsigned int tmp;
unsigned long flags;
......@@ -321,8 +233,10 @@ static struct pci_ops * __devinit pci_check_direct(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 1\n");
if (!request_region(0xCF8, 8, "PCI conf1"))
return NULL;
return &pci_direct_conf1;
pci_root_ops = NULL;
else
pci_root_ops = &pci_direct_conf1;
return 0;
}
outl (tmp, 0xCF8);
}
......@@ -339,28 +253,15 @@ static struct pci_ops * __devinit pci_check_direct(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 2\n");
if (!request_region(0xCF8, 4, "PCI conf2"))
return NULL;
return &pci_direct_conf2;
pci_root_ops = NULL;
else
pci_root_ops = &pci_direct_conf2;
return 0;
}
}
local_irq_restore(flags);
return NULL;
}
static int __init pci_direct_init(void)
{
if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
&& (pci_root_ops = pci_check_direct())) {
if (pci_root_ops == &pci_direct_conf1) {
pci_config_read = pci_conf1_read;
pci_config_write = pci_conf1_write;
}
else {
pci_config_read = pci_conf2_read;
pci_config_write = pci_conf2_write;
}
}
pci_root_ops = NULL;
return 0;
}
......
/*
* numa.c - Low-level PCI access for NUMA-Q machines
*/
#include <linux/pci.h>
#include <linux/init.h>
#include "pci.h"
#define BUS2QUAD(global) (mp_bus_id_to_node[global])
#define BUS2LOCAL(global) (mp_bus_id_to_local[global])
#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
#define PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
......@@ -22,7 +22,7 @@ static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len,
spin_lock_irqsave(&pci_config_lock, flags);
outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
outl_quad(PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
switch (len) {
case 1:
......@@ -41,7 +41,7 @@ static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
......@@ -50,7 +50,7 @@ static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len,
spin_lock_irqsave(&pci_config_lock, flags);
outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
outl_quad(PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
switch (len) {
case 1:
......@@ -69,6 +69,25 @@ static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
#undef PCI_CONF1_MQ_ADDRESS
static int pci_conf1_mq_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return __pci_conf1_mq_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_conf1_mq_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return __pci_conf1_mq_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static struct pci_ops pci_direct_conf1_mq = {
read: pci_conf1_mq_read,
write: pci_conf1_mq_write
};
static void __devinit pci_fixup_i450nx(struct pci_dev *d)
{
......@@ -102,8 +121,7 @@ static int __init pci_numa_init(void)
{
int quad;
pci_config_read = pci_conf1_read;
pci_config_write = pci_conf1_write;
pci_root_ops = &pci_direct_conf1_mq;
if (pcibios_scanned++)
return 0;
......
......@@ -185,7 +185,7 @@ static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short
return (int) (ret & 0xff00) >> 8;
}
static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long result = 0;
unsigned long flags;
......@@ -240,7 +240,7 @@ static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u
return (int)((result & 0xff00) >> 8);
}
static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long result = 0;
unsigned long flags;
......@@ -295,63 +295,16 @@ static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len,
return (int)((result & 0xff00) >> 8);
}
static int pci_bios_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int pci_bios_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_bios_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
if (!value)
return -EINVAL;
return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_bios_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
}
static int pci_bios_write_config_word(struct pci_dev *dev, int where, u16 value)
{
return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
return __pci_bios_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_bios_write_config_dword(struct pci_dev *dev, int where, u32 value)
static int pci_bios_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_bios_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
......@@ -360,12 +313,8 @@ static int pci_bios_write_config_dword(struct pci_dev *dev, int where, u32 value
*/
static struct pci_ops pci_bios_access = {
pci_bios_read_config_byte,
pci_bios_read_config_word,
pci_bios_read_config_dword,
pci_bios_write_config_byte,
pci_bios_write_config_word,
pci_bios_write_config_dword
.read = pci_bios_read,
.write = pci_bios_write
};
/*
......@@ -551,8 +500,6 @@ static int __init pci_pcbios_init(void)
&& ((pci_root_ops = pci_find_bios()))) {
pci_probe |= PCI_BIOS_SORT;
pci_bios_present = 1;
pci_config_read = pci_bios_read;
pci_config_write = pci_bios_write;
}
return 0;
}
......
......@@ -46,9 +46,6 @@ struct pci_fixup pcibios_fixups[1];
struct pci_ops *pci_root_ops;
int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
/*
* Low-level SAL-based PCI configuration access functions. Note that SAL
......@@ -60,7 +57,7 @@ int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32
((u64)(bus << 16) | (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
static int
pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
__pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
int result = 0;
u64 data = 0;
......@@ -76,7 +73,7 @@ pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
}
static int
pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
__pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
return -EINVAL;
......@@ -86,77 +83,22 @@ pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int
pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
{
int result = 0;
u32 data = 0;
if (!value)
return -EINVAL;
result = pci_sal_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8) data;
return result;
}
static int
pci_sal_read_config_word (struct pci_dev *dev, int where, u16 *value)
{
int result = 0;
u32 data = 0;
if (!value)
return -EINVAL;
result = pci_sal_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16) data;
return result;
}
static int
pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
{
if (!value)
return -EINVAL;
return pci_sal_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int
pci_sal_write_config_byte (struct pci_dev *dev, int where, u8 value)
{
return pci_sal_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
}
static int
pci_sal_write_config_word (struct pci_dev *dev, int where, u16 value)
pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_sal_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
return __pci_sal_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int
pci_sal_write_config_dword (struct pci_dev *dev, int where, u32 value)
pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_sal_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_sal_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
struct pci_ops pci_sal_ops = {
pci_sal_read_config_byte,
pci_sal_read_config_word,
pci_sal_read_config_dword,
pci_sal_write_config_byte,
pci_sal_write_config_word,
pci_sal_write_config_dword
.read = pci_sal_read,
.write = pci_sal_write,
};
......@@ -193,8 +135,6 @@ pcibios_config_init (void)
printk("PCI: Using SAL to access configuration space\n");
pci_root_ops = &pci_sal_ops;
pci_config_read = pci_sal_read;
pci_config_write = pci_sal_write;
return;
}
......
......@@ -44,22 +44,21 @@ extern devfs_handle_t pci_bus_to_vertex(unsigned char);
extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
/*
* snia64_read_config_byte - Read a byte from the config area of the device.
* snia64_read - Read from the config area of the device.
*/
static int snia64_read_config_byte (struct pci_dev *dev,
int where, unsigned char *val)
static int snia64_read (struct pci_bus *bus, unsigned char devfn,
int where, int size, unsigned char *val)
{
unsigned long res = 0;
unsigned size = 1;
devfs_handle_t device_vertex;
if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
if ( (bus == NULL) || (val == (unsigned char *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
device_vertex = devfn_to_vertex(bus->number, devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
__FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
return(-1);
}
res = pciio_config_get(device_vertex, (unsigned) where, size);
......@@ -68,160 +67,40 @@ static int snia64_read_config_byte (struct pci_dev *dev,
}
/*
* snia64_read_config_word - Read 2 bytes from the config area of the device.
* snia64_write - Writes to the config area of the device.
*/
static int snia64_read_config_word (struct pci_dev *dev,
int where, unsigned short *val)
{
unsigned long res = 0;
unsigned size = 2; /* 2 bytes */
devfs_handle_t device_vertex;
if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
res = pciio_config_get(device_vertex, (unsigned) where, size);
*val = (unsigned short) res;
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_read_config_dword - Read 4 bytes from the config area of the device.
*/
static int snia64_read_config_dword (struct pci_dev *dev,
int where, unsigned int *val)
{
unsigned long res = 0;
unsigned size = 4; /* 4 bytes */
devfs_handle_t device_vertex;
if (where & 3) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
res = pciio_config_get(device_vertex, (unsigned) where, size);
*val = (unsigned int) res;
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_byte - Writes 1 byte to the config area of the device.
*/
static int snia64_write_config_byte (struct pci_dev *dev,
int where, unsigned char val)
static int snia64_write (struct pci_bus *bus, unsigned char devfn,
int where, int size, unsigned char val)
{
devfs_handle_t device_vertex;
if ( dev == (struct pci_dev *)0 ) {
if ( bus == NULL) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
* if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3
*/
if (dev->vendor == PCI_VENDOR_ID_SGI &&
/* Starting 2.5.32 struct pci_dev is not passed down */
/*if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3 )
return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_word - Writes 2 bytes to the config area of the device.
*/
static int snia64_write_config_word (struct pci_dev *dev,
int where, unsigned short val)
{
devfs_handle_t device_vertex = NULL;
if (where & 1) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( dev == (struct pci_dev *)0 ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
* if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3
*/
if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3)
return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_dword - Writes 4 bytes to the config area of the device.
*/
static int snia64_write_config_dword (struct pci_dev *dev,
int where, unsigned int val)
{
devfs_handle_t device_vertex;
if (where & 3) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( dev == (struct pci_dev *)0 ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
* if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3
*/
if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3)
return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
device_vertex = devfn_to_vertex(bus->number, devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
__FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
return(-1);
}
pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val);
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops snia64_pci_ops = {
snia64_read_config_byte,
snia64_read_config_word,
snia64_read_config_dword,
snia64_write_config_byte,
snia64_write_config_word,
snia64_write_config_dword
.read = snia64_read,
.write = snia64_write,
};
/*
......
......@@ -43,119 +43,102 @@ static void nile4_post_pci_access0(void)
}
static int nile4_pci_read_config_dword(struct pci_dev *dev,
int where, u32 * val)
static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 * val)
{
int slot_num, func_num;
u32 base;
int status, slot_num, func_num;
u32 result, base;
switch (size) {
case 4:
/*
* For starters let's do configuration cycle 0 only (one bus only)
* For starters let's do configuration cycle 0 only
* (one bus only)
*/
if (dev->bus->number)
if (bus->number)
return PCIBIOS_FUNC_NOT_SUPPORTED;
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
if (slot_num == 5) {
/*
* This is Nile 4 and it will crash if we access it like other
* devices
* This is Nile 4 and it will crash if we access it
* like other devices
*/
*val = nile4_in32(NILE4_PCI_BASE + where);
return PCIBIOS_SUCCESSFUL;
}
base = nile4_pre_pci_access0(slot_num);
*val =
*((volatile u32 *) (base + (func_num << 8) + (where & 0xfc)));
*val = *((volatile u32 *) (base + (func_num << 8) +
(where & 0xfc)));
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
case 2:
status = nile4_pci_read(bus, devfn, where, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
result >>= 16;
*val = (u16)(result & 0xffff);
break;
case 1:
status = nile4_pci_read(bus, devfn, where, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 1)
result >>= 8;
if (where & 2)
result >>= 16;
*val = (u8)(result & 0xff);
break;
}
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
int slot_num, func_num;
u32 base;
int status, slot_num, func_num, shift = 0;
u32 result, base;
switch (size) {
case 4:
/*
* For starters let's do configuration cycle 0 only (one bus only)
* For starters let's do configuration cycle 0 only
* (one bus only)
*/
if (dev->bus->number)
if (bus->number)
return PCIBIOS_FUNC_NOT_SUPPORTED;
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
if (slot_num == 5) {
/*
* This is Nile 4 and it will crash if we access it like other
* devices
* This is Nile 4 and it will crash if we access
* it like other devices
*/
nile4_out32(NILE4_PCI_BASE + where, val);
return PCIBIOS_SUCCESSFUL;
}
base = nile4_pre_pci_access0(slot_num);
*((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))) =
val;
*((volatile u32 *) (base + (func_num << 8) +
(where & 0xfc))) = val;
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
result >>= 16;
*val = result & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 1)
result >>= 8;
if (where & 2)
result >>= 16;
*val = result & 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_word(struct pci_dev *dev, int where,
u16 val)
{
int status, shift = 0;
u32 result;
status = nile4_pci_read_config_dword(dev, where, &result);
case 2:
status = nile4_pci_read(bus, devfn, where, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
return nile4_pci_write_config_dword(dev, where, result);
}
static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
u8 val)
{
int status, shift = 0;
u32 result;
status = nile4_pci_read_config_dword(dev, where, &result);
result |= (u16)(val << shift);
break;
case 1:
status = nile4_pci_read(bus, devfn, where, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
......@@ -163,17 +146,15 @@ static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= val << shift;
return nile4_pci_write_config_dword(dev, where, result);
result |= (u8)(val << shift);
break;
}
return nile4_pci_write(bus, devfn, where, 4, result);
}
struct pci_ops nile4_pci_ops = {
nile4_pci_read_config_byte,
nile4_pci_read_config_word,
nile4_pci_read_config_dword,
nile4_pci_write_config_byte,
nile4_pci_write_config_word,
nile4_pci_write_config_dword
.read = nile4_pci_read,
.write = nile4_pci_write,
};
struct {
......
......@@ -51,145 +51,106 @@ static void nile4_post_pci_access0(void)
nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
}
static int nile4_pci_read_config_dword(struct pci_dev *dev,
int where, u32 * val)
static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 * val)
{
int slot_num, func_num;
u32 base;
u32 addr;
int status, slot_num, func_num;
u32 result, base, addr;
/*
* Do we need to generate type 1 configure transaction?
*/
if (dev->bus->number) {
if(size == 4) {
/* Do we need to generate type 1 configure transaction? */
if (bus->number) {
/* FIXME - not working yet */
return PCIBIOS_FUNC_NOT_SUPPORTED;
/*
* the largest type 1 configuration addr is 16M, < 256M
* config space
* the largest type 1 configuration addr is 16M,
* < 256M config space
*/
slot_num = 0;
addr =
(dev->bus->number << 16) | (dev->devfn <
8) | where | 1;
addr = (bus->number << 16) | (devfn < 8) | where | 1;
} else {
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
addr = (func_num << 8) + where;
}
base = nile4_pre_pci_access0(slot_num);
*val = *(volatile u32 *) (base + addr);
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
{
int slot_num, func_num;
u32 base;
u32 addr;
/*
* Do we need to generate type 1 configure transaction?
*/
if (dev->bus->number) {
/* FIXME - not working yet */
return PCIBIOS_FUNC_NOT_SUPPORTED;
/* the largest type 1 configuration addr is 16M, < 256M config space */
slot_num = 0;
addr =
(dev->bus->number << 16) | (dev->devfn <
8) | where | 1;
} else {
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
addr = (func_num << 8) + where;
}
base = nile4_pre_pci_access0(slot_num);
*(volatile u32 *) (base + addr) = val;
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
if (where & 2)
result >>= 16;
*val = result & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
{
int status;
u32 result;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
switch (size) {
case 1:
if (where & 1)
result >>= 8;
if (where & 2)
result >>= 16;
*val = result & 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_word(struct pci_dev *dev, int where,
u16 val)
{
int status, shift = 0;
u32 result;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
*val = (u8)(result & 0xff);
break;
case 2:
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
return nile4_pci_write_config_dword(dev, where & ~3, result);
result >>= 16;
*val = (u16)(result & 0xffff);
break;
}
return PCIBIOS_SUCCESSFUL;
}
static int nile4_pci_write_config_byte(struct pci_dev *dev, int where,
u8 val)
static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
int status, shift = 0;
u32 result;
int status, slot_num, func_num, shift = 0;
u32 result, base, addr;
status = nile4_pci_read_config_dword(dev, where & ~3, &result);
status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
if (status != PCIBIOS_SUCCESSFUL)
return status;
switch (size) {
case 1:
if (where & 2)
shift += 16;
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= val << shift;
return nile4_pci_write_config_dword(dev, where & ~3, result);
break;
case 2:
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
break;
case 4:
/* Do we need to generate type 1 configure transaction? */
if (bus->number) {
/* FIXME - not working yet */
return PCIBIOS_FUNC_NOT_SUPPORTED;
/* the largest type 1 configuration addr is 16M,
* < 256M config space */
slot_num = 0;
addr = (bus->number << 16) | (devfn < 8) |
where | 1;
} else {
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
addr = (func_num << 8) + where;
}
base = nile4_pre_pci_access0(slot_num);
*(volatile u32 *) (base + addr) = val;
nile4_post_pci_access0();
return PCIBIOS_SUCCESSFUL;
}
return nile4_pci_write(bus, devfn, where & ~3, 4, result);
}
struct pci_ops nile4_pci_ops = {
nile4_pci_read_config_byte,
nile4_pci_read_config_word,
nile4_pci_read_config_dword,
nile4_pci_write_config_byte,
nile4_pci_write_config_word,
nile4_pci_write_config_dword
.read = nile4_pci_read,
.write = nile4_pci_write,
};
struct {
......@@ -274,13 +235,13 @@ static void __init ddb5476_pci_fixup(void)
pci_pmu = dev; /* for LEDs D2 and D3 */
/* Program the lines for LEDs D2 and D3 to output */
nile4_pci_read_config_byte(dev, 0x7d, &t8);
nile4_pci_read(dev->bus, dev->devfn, 0x7d, 1, &t8);
t8 |= 0xc0;
nile4_pci_write_config_byte(dev, 0x7d, t8);
nile4_pci_write(dev->bus, dev->devfn, 0x7d, 1, t8);
/* Turn LEDs D2 and D3 off */
nile4_pci_read_config_byte(dev, 0x7e, &t8);
nile4_pci_read(dev->bus, dev->devfn, 0x7e, 1, &t8);
t8 |= 0xc0;
nile4_pci_write_config_byte(dev, 0x7e, t8);
nile4_pci_write(dev->bus, dev->devfn, 0x7e, 1, t8);
} else if (dev->vendor == PCI_VENDOR_ID_AL &&
dev->device == 0x5229) {
int i;
......
......@@ -134,120 +134,102 @@ static inline void ddb_close_config_base(struct pci_config_swap *swap)
ddb_out32(swap->pmr, swap->pmr_backup);
}
static int read_config_dword(struct pci_config_swap *swap,
struct pci_dev *dev,
static int read_config(struct pci_config_swap *swap,
struct pci_bus *bus,
unsigned int devfn,
u32 where,
int size,
u32 *val)
{
u32 bus, slot_num, func_num;
u32 base;
u32 busnum, slot_num, func_num, base, result;
int status
switch (size) {
case 4:
MIPS_ASSERT((where & 3) == 0);
MIPS_ASSERT(where < (1 << 8));
/* check if the bus is top-level */
if (dev->bus->parent != NULL) {
bus = dev->bus->number;
MIPS_ASSERT(bus != 0);
if (bus->parent != NULL) {
busnum = bus->number;
MIPS_ASSERT(busnum != 0);
} else {
bus = 0;
busnum = 0;
}
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
base = ddb_access_config_base(swap, bus, slot_num);
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
base = ddb_access_config_base(swap, busnum, slot_num);
*val = *(volatile u32*) (base + (func_num << 8) + where);
ddb_close_config_base(swap);
return PCIBIOS_SUCCESSFUL;
}
static int read_config_word(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u16 *val)
{
int status;
u32 result;
case 2:
MIPS_ASSERT((where & 1) == 0);
status = read_config_dword(swap, dev, where & ~3, &result);
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (where & 2) result >>= 16;
*val = result & 0xffff;
*val = (u16)(result & 0xffff);
return status;
}
static int read_config_byte(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u8 *val)
{
int status;
u32 result;
status = read_config_dword(swap, dev, where & ~3, &result);
case 1:
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (where & 1) result >>= 8;
if (where & 2) result >>= 16;
*val = result & 0xff;
*val = (u8)(result & 0xff);
return status;
}
}
static int write_config_dword(struct pci_config_swap *swap,
struct pci_dev *dev,
static int write_config(struct pci_config_swap *swap,
struct pci_bus *bus,
unsigned int devfn,
u32 where,
int size,
u32 val)
{
u32 bus, slot_num, func_num;
u32 base;
u32 busnum, slot_num, func_num, base, results;
int status, shift = 0;
switch (size) {
case 4:
MIPS_ASSERT((where & 3) == 0);
MIPS_ASSERT(where < (1 << 8));
/* check if the bus is top-level */
if (dev->bus->parent != NULL) {
bus = dev->bus->number;
MIPS_ASSERT(bus != 0);
if (bus->parent != NULL) {
busnum = bus->number;
MIPS_ASSERT(busnum != 0);
} else {
bus = 0;
busnum = 0;
}
slot_num = PCI_SLOT(dev->devfn);
func_num = PCI_FUNC(dev->devfn);
base = ddb_access_config_base(swap, bus, slot_num);
slot_num = PCI_SLOT(devfn);
func_num = PCI_FUNC(devfn);
base = ddb_access_config_base(swap, busnum, slot_num);
*(volatile u32*) (base + (func_num << 8) + where) = val;
ddb_close_config_base(swap);
return PCIBIOS_SUCCESSFUL;
}
static int write_config_word(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u16 val)
{
int status, shift=0;
u32 result;
case 2:
MIPS_ASSERT((where & 1) == 0);
status = read_config_dword(swap, dev, where & ~3, &result);
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
shift += 16;
result &= ~(0xffff << shift);
result |= val << shift;
return write_config_dword(swap, dev, where & ~3, result);
}
static int write_config_byte(struct pci_config_swap *swap,
struct pci_dev *dev,
u32 where,
u8 val)
{
int status, shift=0;
u32 result;
result |= (u16)(val << shift);
return write_config(swap, bus, devfn, where & ~3, size,
result);
status = read_config_dword(swap, dev, where & ~3, &result);
case 1:
status = read_config(swap, bus, devfn, where & ~3, 4,
&result);
if (status != PCIBIOS_SUCCESSFUL) return status;
if (where & 2)
......@@ -255,52 +237,35 @@ static int write_config_byte(struct pci_config_swap *swap,
if (where & 1)
shift += 8;
result &= ~(0xff << shift);
result |= val << shift;
return write_config_dword(swap, dev, where & ~3, result);
result |= (u8)(val << shift);
return write_config(swap, bus, devfn, where & ~3, size,
result);
}
}
#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
#define MAKE_PCI_OPS(prefix, rw, pciswap) \
static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, \
int where, int size, u32 val) \
{ \
return rw##_config_##unitname(pciswap, \
dev, \
where, \
val); \
return rw##_config(pciswap, bus, devfn, \
where, size, val); \
}
MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
MAKE_PCI_OPS(iopci, read, byte, u8 *, &io_pci_swap)
MAKE_PCI_OPS(iopci, read, word, u16 *, &io_pci_swap)
MAKE_PCI_OPS(iopci, read, dword, u32 *, &io_pci_swap)
MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
MAKE_PCI_OPS(extpci, read, &ext_pci_swap)
MAKE_PCI_OPS(extpci, write, &ext_pci_swap)
MAKE_PCI_OPS(iopci, write, byte, u8, &io_pci_swap)
MAKE_PCI_OPS(iopci, write, word, u16, &io_pci_swap)
MAKE_PCI_OPS(iopci, write, dword, u32, &io_pci_swap)
MAKE_PCI_OPS(iopci, read, &io_pci_swap)
MAKE_PCI_OPS(iopci, write, &io_pci_swap)
struct pci_ops ddb5477_ext_pci_ops ={
extpci_read_config_byte,
extpci_read_config_word,
extpci_read_config_dword,
extpci_write_config_byte,
extpci_write_config_word,
extpci_write_config_dword
.read = extpci_read_config,
.write = extpci_write_config,
};
struct pci_ops ddb5477_io_pci_ops ={
iopci_read_config_byte,
iopci_read_config_word,
iopci_read_config_dword,
iopci_write_config_byte,
iopci_write_config_word,
iopci_write_config_dword
.read = iopci_read_config,
.write = iopci_write_config,
};
#if defined(CONFIG_LL_DEBUG)
......
This diff is collapsed.
......@@ -45,18 +45,17 @@
#undef DEBUG_CONFIG_CYCLES
static int
it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
unsigned char where, u32 *data)
it8172_pcibios_config_access(unsigned char access_type, struct pci_bus *bus, unsigned int devfn, unsigned char where, u32 *data)
{
/*
* config cycles are on 4 byte boundary only
*/
unsigned char bus = dev->bus->number;
unsigned char dev_fn = dev->devfn;
unsigned char bus = bus->number;
unsigned char dev_fn = (char)devfn;
#ifdef DEBUG_CONFIG_CYCLES
printk("it config: type %d dev %x bus %d dev_fn %x data %x\n",
access_type, dev, bus, dev_fn, *data);
printk("it config: type %d bus %d dev_fn %x data %x\n",
access_type, bus, dev_fn, *data);
#endif
......@@ -86,121 +85,63 @@ it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
* read/write a 32bit word and mask/modify the data we actually want.
*/
static int
it8172_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
it8172_pcibios_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
{
u32 data = 0;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xff;
#ifdef DEBUG
printk("cfg read byte: bus %d dev_fn %x where %x: val %x\n",
dev->bus->number, dev->devfn, where, *val);
#endif
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
{
u32 data = 0;
if (where & 1)
if ((size == 2) && (where & 1))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
else if ((size == 4) && (where & 3))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
if (size == 1)
*val = (u8)(data >> ((where & 3) << 3)) & 0xff;
else if (size == 2)
*val = (u16)(data >> ((where & 3) << 3)) & 0xffff;
else if (size == 4)
*val = data;
*val = (data >> ((where & 3) << 3)) & 0xffff;
#ifdef DEBUG
printk("cfg read word: bus %d dev_fn %x where %x: val %x\n",
dev->bus->number, dev->devfn, where, *val);
printk("cfg read: bus %d devfn %x where %x size %x: val %x\n",
bus->number, devfn, where, size, *val);
#endif
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
it8172_pcibios_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{
u32 data = 0;
if ((size == 2) && (where & 1))
return PCIBIOS_BAD_REGISTER_NUMBER;
else if (size == 4) {
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
return -1;
*val = data;
#ifdef DEBUG
printk("cfg read dword: bus %d dev_fn %x where %x: val %x\n",
dev->bus->number, dev->devfn, where, *val);
#endif
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
{
u32 data = 0;
}
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
if (it8172_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
data = (data & ~(0xff << ((where & 3) << 3))) |
if(size == 1) {
data = (u8)(data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
data = (data & ~(0xffff << ((where & 3) << 3))) |
} else if (size == 2) {
data = (u16)(data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
it8172_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
{
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
return -1;
}
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops it8172_pci_ops = {
it8172_pcibios_read_config_byte,
it8172_pcibios_read_config_word,
it8172_pcibios_read_config_dword,
it8172_pcibios_write_config_byte,
it8172_pcibios_write_config_word,
it8172_pcibios_write_config_dword
.read = it8172_pcibios_read,
.write = it8172_pcibios_write,
};
void __init pcibios_init(void)
......
......@@ -37,11 +37,9 @@
#define PCI_ACCESS_WRITE 1
static int
mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
unsigned char where, u32 *data)
mips_pcibios_config_access(unsigned char access_type, struct pci_bus *bus_dev, unsigned int dev_fn, unsigned char where, u32 *data)
{
unsigned char bus = dev->bus->number;
unsigned char dev_fn = dev->devfn;
unsigned char bus = bus_dev->number;
u32 intr;
if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0)))
......@@ -101,109 +99,56 @@ mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
* read/write a 32bit word and mask/modify the data we actually want.
*/
static int
mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
mips_pcibios_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
{
u32 data = 0;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
if((size == 2) && (where & 1))
return PCIBIOS_BAD_REGISTER_NUMBER;
else if ((size == 4) && (where & 3))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xff;
if(size == 1)
*val = (u8)(data >> ((where & 3) << 3)) & 0xff;
else if (size == 2)
*val = (u16)(data >> ((where & 3) << 3)) & 0xffff;
else if (size == 4)
*val = data;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
mips_pcibios_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{
u32 data = 0;
if (where & 1)
if((size == 2) && (where & 1))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
*val = (data >> ((where & 3) << 3)) & 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
{
u32 data = 0;
if (where & 3)
else if (size == 4) {
if(where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
if(mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &val))
return -1;
*val = data;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
{
u32 data = 0;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
}
if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
if(size == 1) {
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
{
u32 data = 0;
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
return -1;
} else if (size == 2) {
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int
mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
{
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
return -1;
}
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops mips_pci_ops = {
mips_pcibios_read_config_byte,
mips_pcibios_read_config_word,
mips_pcibios_read_config_dword,
mips_pcibios_write_config_byte,
mips_pcibios_write_config_word,
mips_pcibios_write_config_dword
.read = mips_pcibios_read,
.write = mips_pcibios_write,
};
void __init pcibios_init(void)
......
......@@ -17,13 +17,13 @@
#ifdef CONFIG_PCI
#define mkaddr(dev, where) \
#define mkaddr(bus, devfn, where) \
do { \
if ((dev)->bus->number == 0) \
if (bus->number == 0) \
return -1; \
*(volatile u32 *)PCIMT_CONFIG_ADDRESS = \
((dev->bus->number & 0xff) << 0x10) | \
((dev->devfn & 0xff) << 0x08) | \
((bus->number & 0xff) << 0x10) | \
((devfn & 0xff) << 0x08) | \
(where & 0xfc); \
} while(0)
......@@ -69,87 +69,67 @@ static void pcimt_pcibios_fixup (void)
* We can't address 8 and 16 bit words directly. Instead we have to
* read/write a 32bit word and mask/modify the data we actually want.
*/
static int pcimt_read_config_byte (struct pci_dev *dev,
int where, unsigned char *val)
static int pcimt_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
{
u32 res;
mkaddr(dev, where);
switch (size) {
case 1:
mkaddr(bus, devfn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
*val = res;
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_read_config_word (struct pci_dev *dev,
int where, unsigned short *val)
{
u32 res;
*val = (u8)res;
break;
case 2:
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
mkaddr(bus, devfn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
*val = res;
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_read_config_dword (struct pci_dev *dev,
int where, unsigned int *val)
{
u32 res;
*val = (u16)res;
break;
case 4:
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
mkaddr(bus, devfn, where);
res = *(volatile u32 *)PCIMT_CONFIG_DATA;
res = le32_to_cpu(res);
*val = res;
break;
}
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_write_config_byte (struct pci_dev *dev,
int where, unsigned char val)
{
mkaddr(dev, where);
*(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val;
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_write_config_word (struct pci_dev *dev,
int where, unsigned short val)
static int pcimt_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{
switch (size) {
case 1:
mkaddr(bus, devfn, where);
*(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) =
(u8)le32_to_cpu(val);
break;
case 2:
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
*(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val);
return PCIBIOS_SUCCESSFUL;
}
static int pcimt_write_config_dword (struct pci_dev *dev,
int where, unsigned int val)
{
mkaddr(bus, devfn, where);
*(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) =
(u16)le32_to_cpu(val);
break;
case 4:
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mkaddr(dev, where);
mkaddr(bus, devfn, where);
*(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val);
break;
}
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops sni_pci_ops = {
pcimt_read_config_byte,
pcimt_read_config_word,
pcimt_read_config_dword,
pcimt_write_config_byte,
pcimt_write_config_word,
pcimt_write_config_dword
.read = pcimt_read,
.write = pcimt_write,
};
void __init
......
......@@ -31,76 +31,57 @@ struct pci_fixup pcibios_fixups[] = {
{0, 0, 0, NULL}
};
#define BBA_SELECTED(dev) (dev->bus->number==0 && dev->devfn==0)
#define BBA_SELECTED(bus,devfn) (bus->number==0 && devfn==0)
static int gapspci_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
{
if (BBA_SELECTED(dev))
*val = inb(GAPSPCI_BBA_CONFIG+where);
switch (size) {
case 1:
if (BBA_SELECTED(bus, devfn))
*val = (u8)inb(GAPSPCI_BBA_CONFIG+where);
else
*val = 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int gapspci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
if (BBA_SELECTED(dev))
*val = inw(GAPSPCI_BBA_CONFIG+where);
*val = (u8)0xff;
break;
case 2:
if (BBA_SELECTED(bus, devfn))
*val = (u16)inw(GAPSPCI_BBA_CONFIG+where);
else
*val = 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int gapspci_read_config_dword(struct pci_dev *dev, int where,
u32 * val)
{
if (BBA_SELECTED(dev))
*val = (u16)0xffff;
break;
case 4:
if (BBA_SELECTED(bus, devfn))
*val = inl(GAPSPCI_BBA_CONFIG+where);
else
*val = 0xffffffff;
return PCIBIOS_SUCCESSFUL;
}
static int gapspci_write_config_byte(struct pci_dev *dev, int where,
u8 val)
{
if (BBA_SELECTED(dev))
outb(val, GAPSPCI_BBA_CONFIG+where);
return PCIBIOS_SUCCESSFUL;
}
static int gapspci_write_config_word(struct pci_dev *dev, int where,
u16 val)
{
if (BBA_SELECTED(dev))
outw(val, GAPSPCI_BBA_CONFIG+where);
break;
}
return PCIBIOS_SUCCESSFUL;
}
static int gapspci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
{
if (BBA_SELECTED(dev))
if (BBA_SELECTED(bus, devfn)) {
switch (size) {
case 1:
if (BBA_SELECTED(bus, devfn))
outb((u8)val, GAPSPCI_BBA_CONFIG+where);
break;
case 2:
if (BBA_SELECTED(bus, devfn))
outw((u16)val, GAPSPCI_BBA_CONFIG+where);
break;
case 4:
if (BBA_SELECTED(bus, devfn))
outl(val, GAPSPCI_BBA_CONFIG+where);
break;
}
}
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pci_config_ops = {
gapspci_read_config_byte,
gapspci_read_config_word,
gapspci_read_config_dword,
gapspci_write_config_byte,
gapspci_write_config_word,
gapspci_write_config_dword
.read = gapspci_read,
.write = gapspci_write,
};
......@@ -143,7 +124,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
dev = pci_dev_b(ln);
if (!BBA_SELECTED(dev)) continue;
if (!BBA_SELECTED(bus, dev->devfn)) continue;
printk("PCI: MMIO fixup to %s\n", dev->name);
dev->resource[1].start=0x01001700;
......
......@@ -41,14 +41,14 @@ struct pci_ops *pci_root_ops;
#ifdef CONFIG_PCI_DIRECT
#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
u32 word;
unsigned long flags;
......@@ -57,9 +57,12 @@ static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
* so we must do byte alignment by hand
*/
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
word = inl(PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
switch (size) {
case 1:
switch (where & 0x3) {
case 3:
*value = (u8)(word >> 24);
......@@ -74,27 +77,10 @@ static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
*value = (u8)word;
break;
}
PCIDBG(4,"pci_conf1_read_config_byte@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),*value);
return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
u32 word;
unsigned long flags;
/* PCIPDR may only be accessed as 32 bit words,
* so we must do word alignment by hand
*/
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
word = inl(PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
case 2:
switch (where & 0x3) {
case 3:
// This should never happen...
printk(KERN_ERR "PCI BIOS: read_config_word: Illegal u16 alignment");
case 3: /*This should never happen.*/
printk(KERN_ERR "PCI BIOS: read_config: Illegal u16 alignment");
return PCIBIOS_BAD_REGISTER_NUMBER;
case 2:
*value = (u16)(word >> 16);
......@@ -106,95 +92,53 @@ static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value
*value = (u16)word;
break;
}
PCIDBG(4,"pci_conf1_read_config_word@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),*value);
case 4:
*value = word;
break;
}
PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value);
return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
/*
* Since SH7751 only does 32bit access we'll have to do a read,mask,write operation.
* We'll allow an odd byte offset, though it should be illegal.
*/
static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
u32 word,mask;
unsigned long flags;
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
*value = inl(PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
PCIDBG(4,"pci_conf1_read_config_dword@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),*value);
return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
u32 word;
u32 shift = (where & 3) * 8;
u32 mask = ((1 << 8) - 1) << shift; // create the byte mask
unsigned long flags;
/* Since SH7751 only does 32bit access we'll have to do a
* read,mask,write operation
*/
if(size == 1) {
mask = ((1 << 8) - 1) << shift; // create the byte mask
} else if(size == 2){
if(shift == 24)
return PCIBIOS_BAD_REGISTER_NUMBER;
mask = ((1 << 16) - 1) << shift; // create the word mask
}
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
word = inl(PCI_REG(SH7751_PCIPDR)) ;
word &= ~mask;
word |= value << shift;
outl(word, PCI_REG(SH7751_PCIPDR));
outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
if(size == 4){
outl(value, PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
PCIDBG(4,"pci_conf1_write_config_byte@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),word);
PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
{
u32 word;
u32 shift = (where & 3) * 8;
u32 mask = ((1 << 16) - 1) << shift; // create the word mask
unsigned long flags;
/* Since SH7751 only does 32bit access we'll have to do a
* read,mask,write operation. We'll allow an odd byte offset,
* though it should be illegal.
*/
if (shift == 24)
return PCIBIOS_BAD_REGISTER_NUMBER;
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
}
word = inl(PCI_REG(SH7751_PCIPDR)) ;
word &= ~mask;
word |= value << shift;
outl(value, PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
PCIDBG(4,"pci_conf1_write_config_word@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),word);
return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long flags;
save_and_cli(flags);
outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
outl(value, PCI_REG(SH7751_PCIPDR));
outl(word, PCI_REG(SH7751_PCIPDR));
restore_flags(flags);
PCIDBG(4,"pci_conf1_write_config_dword@0x%08x=0x%x\n",
CONFIG_CMD(dev,where),value);
PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
return PCIBIOS_SUCCESSFUL;
}
#undef CONFIG_CMD
static struct pci_ops pci_direct_conf1 = {
pci_conf1_read_config_byte,
pci_conf1_read_config_word,
pci_conf1_read_config_dword,
pci_conf1_write_config_byte,
pci_conf1_write_config_word,
pci_conf1_write_config_dword
.read = pci_conf1_read,
.write = pci_conf1_write,
};
struct pci_ops * __init pci_check_direct(void)
......
......@@ -268,7 +268,7 @@ char * __init pcibios_setup(char *str)
#define SET_CONFIG_BITS(bus,devfn,where)\
(((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
static int CheckForMasterAbort(void)
......@@ -284,79 +284,53 @@ static int CheckForMasterAbort(void)
}
/* Write to config register */
static int st40pci_read_config_byte(struct pci_dev *dev, int where,
u8 * val)
static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
*val = ST40PCI_READ_BYTE(PDR + (where & 3));
if (CheckForMasterAbort())
*val = 0xff;
return PCIBIOS_SUCCESSFUL;
}
static int st40pci_read_config_word(struct pci_dev *dev, int where,
u16 * val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
*val = ST40PCI_READ_SHORT(PDR + (where & 2));
if (CheckForMasterAbort())
*val = 0xffff;
return PCIBIOS_SUCCESSFUL;
}
static int st40pci_read_config_dword(struct pci_dev *dev, int where,
u32 * val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
switch (size) {
case 1:
*val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
break;
case 2:
*val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
break;
case 4:
*val = ST40PCI_READ(PDR);
break;
}
if (CheckForMasterAbort())
if (CheckForMasterAbort()){
switch (size) {
case 1:
*val = (u8)0xff;
break;
case 2:
*val = (u16)0xffff;
break;
case 4:
*val = 0xffffffff;
break;
}
}
return PCIBIOS_SUCCESSFUL;
}
static int st40pci_write_config_byte(struct pci_dev *dev, int where,
u8 val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
ST40PCI_WRITE_BYTE(PDR + (where & 3), val);
CheckForMasterAbort();
return PCIBIOS_SUCCESSFUL;
}
static int st40pci_write_config_word(struct pci_dev *dev, int where,
u16 val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
ST40PCI_WRITE_SHORT(PDR + (where & 2), val);
CheckForMasterAbort();
return PCIBIOS_SUCCESSFUL;
}
static int st40pci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
static int st40pci_write(struct pci_bus *bus, unsigned int devfn; int where, int size, u32 val)
{
ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
switch (size) {
case 1:
ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
break;
case 2:
ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
break;
case 4:
ST40PCI_WRITE(PDR, val);
break;
}
CheckForMasterAbort();
......@@ -364,12 +338,8 @@ static int st40pci_write_config_dword(struct pci_dev *dev, int where,
}
static struct pci_ops pci_config_ops = {
st40pci_read_config_byte,
st40pci_read_config_word,
st40pci_read_config_dword,
st40pci_write_config_byte,
st40pci_write_config_word,
st40pci_write_config_dword
.read = st40pci_read,
.write = st40pci_write,
};
......
......@@ -13,7 +13,7 @@
#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
......@@ -41,7 +41,7 @@ static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
......@@ -69,75 +69,23 @@ static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
#undef PCI_CONF1_ADDRESS
static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
int result;
u32 data;
if (!value)
return -EINVAL;
result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
if (!value)
return -EINVAL;
return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
return __pci_conf1_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
}
static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_conf1_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static struct pci_ops pci_direct_conf1 = {
pci_conf1_read_config_byte,
pci_conf1_read_config_word,
pci_conf1_read_config_dword,
pci_conf1_write_config_byte,
pci_conf1_write_config_word,
pci_conf1_write_config_dword
.read = pci_conf1_read,
.write = pci_conf1_write,
};
......@@ -147,7 +95,7 @@ static struct pci_ops pci_direct_conf1 = {
#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg)
static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
static int __pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
{
unsigned long flags;
......@@ -181,7 +129,7 @@ static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len,
return 0;
}
static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
static int __pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
unsigned long flags;
......@@ -217,57 +165,21 @@ static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len,
#undef PCI_CONF2_ADDRESS
static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
int result;
u32 data;
result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
int result;
u32 data;
result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
return pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
static int pci_conf2_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
return __pci_conf2_read(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
static int pci_conf2_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
}
static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
return __pci_conf2_write(0, bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn), where, size, value);
}
static struct pci_ops pci_direct_conf2 = {
pci_conf2_read_config_byte,
pci_conf2_read_config_word,
pci_conf2_read_config_dword,
pci_conf2_write_config_byte,
pci_conf2_write_config_word,
pci_conf2_write_config_dword
.read = pci_conf2_read,
.write = pci_conf2_write,
};
......@@ -283,7 +195,7 @@ static struct pci_ops pci_direct_conf2 = {
*/
static int __devinit pci_sanity_check(struct pci_ops *o)
{
u16 x;
u32 x = 0;
struct pci_bus bus; /* Fake bus and device */
struct pci_dev dev;
......@@ -292,16 +204,16 @@ static int __devinit pci_sanity_check(struct pci_ops *o)
bus.number = 0;
dev.bus = &bus;
for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++)
if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) &&
if ((!o->read(&bus, dev.devfn, PCI_CLASS_DEVICE, 2, &x) &&
(x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
(!o->read_word(&dev, PCI_VENDOR_ID, &x) &&
(!o->read(&bus, dev.devfn, PCI_VENDOR_ID, 2, &x) &&
(x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
return 1;
DBG("PCI: Sanity check failed\n");
return 0;
}
static struct pci_ops * __devinit pci_check_direct(void)
static int __init pci_direct_init(void)
{
unsigned int tmp;
unsigned long flags;
......@@ -321,8 +233,10 @@ static struct pci_ops * __devinit pci_check_direct(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 1\n");
if (!request_region(0xCF8, 8, "PCI conf1"))
return NULL;
return &pci_direct_conf1;
pci_root_ops = NULL;
else
pci_root_ops = &pci_direct_conf1;
return 0;
}
outl (tmp, 0xCF8);
}
......@@ -339,28 +253,15 @@ static struct pci_ops * __devinit pci_check_direct(void)
local_irq_restore(flags);
printk(KERN_INFO "PCI: Using configuration type 2\n");
if (!request_region(0xCF8, 4, "PCI conf2"))
return NULL;
return &pci_direct_conf2;
pci_root_ops = NULL;
else
pci_root_ops = &pci_direct_conf2;
return 0;
}
}
local_irq_restore(flags);
return NULL;
}
static int __init pci_direct_init(void)
{
if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
&& (pci_root_ops = pci_check_direct())) {
if (pci_root_ops == &pci_direct_conf1) {
pci_config_read = pci_conf1_read;
pci_config_write = pci_conf1_write;
}
else {
pci_config_read = pci_conf2_read;
pci_config_write = pci_conf2_write;
}
}
pci_root_ops = NULL;
return 0;
}
......
......@@ -51,245 +51,6 @@
static int debug;
static int build_dev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, struct pci_dev **pci_dev)
{
struct pci_dev *my_dev;
struct pci_bus *my_bus;
/* Some validity checks. */
if ((function > 7) ||
(slot > 31) ||
(pci_dev == NULL) ||
(ops == NULL))
return -ENODEV;
my_dev = kmalloc (sizeof (struct pci_dev), GFP_KERNEL);
if (!my_dev)
return -ENOMEM;
my_bus = kmalloc (sizeof (struct pci_bus), GFP_KERNEL);
if (!my_bus) {
kfree (my_dev);
return -ENOMEM;
}
memset(my_dev, 0, sizeof(struct pci_dev));
memset(my_bus, 0, sizeof(struct pci_bus));
my_bus->number = bus;
my_bus->ops = ops;
my_dev->devfn = PCI_DEVFN(slot, function);
my_dev->bus = my_bus;
*pci_dev = my_dev;
return 0;
}
/**
* pci_read_config_byte_nodev - read a byte from a pci device
* @ops: pointer to a &struct pci_ops that will be used to read from the pci device
* @bus: the bus of the pci device to read from
* @slot: the pci slot number of the pci device to read from
* @function: the function of the pci device to read from
* @where: the location on the pci address space to read from
* @value: pointer to where to place the data read
*
* Like pci_read_config_byte() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_read_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u8 *value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %p\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_read_config_byte (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_read_config_byte(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/**
* pci_read_config_word_nodev - read a word from a pci device
* @ops: pointer to a &struct pci_ops that will be used to read from the pci device
* @bus: the bus of the pci device to read from
* @slot: the pci slot number of the pci device to read from
* @function: the function of the pci device to read from
* @where: the location on the pci address space to read from
* @value: pointer to where to place the data read
*
* Like pci_read_config_word() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_read_config_word_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u16 *value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %p\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_read_config_word (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_read_config_word(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/**
* pci_read_config_dword_nodev - read a dword from a pci device
* @ops: pointer to a &struct pci_ops that will be used to read from the pci
* device
* @bus: the bus of the pci device to read from
* @slot: the pci slot number of the pci device to read from
* @function: the function of the pci device to read from
* @where: the location on the pci address space to read from
* @value: pointer to where to place the data read
*
* Like pci_read_config_dword() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_read_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u32 *value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %p\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_read_config_dword (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_read_config_dword(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/**
* pci_write_config_byte_nodev - write a byte to a pci device
* @ops: pointer to a &struct pci_ops that will be used to write to the pci
* device
* @bus: the bus of the pci device to write to
* @slot: the pci slot number of the pci device to write to
* @function: the function of the pci device to write to
* @where: the location on the pci address space to write to
* @value: the value to write to the pci device
*
* Like pci_write_config_byte() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_write_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u8 value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %d\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_write_config_byte (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_write_config_byte(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/**
* pci_write_config_word_nodev - write a word to a pci device
* @ops: pointer to a &struct pci_ops that will be used to write to the pci
* device
* @bus: the bus of the pci device to write to
* @slot: the pci slot number of the pci device to write to
* @function: the function of the pci device to write to
* @where: the location on the pci address space to write to
* @value: the value to write to the pci device
*
* Like pci_write_config_word() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_write_config_word_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u16 value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %d\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_write_config_word (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_write_config_word(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/**
* pci_write_config_dword_nodev - write a dword to a pci device
* @ops: pointer to a &struct pci_ops that will be used to write to the pci
* device
* @bus: the bus of the pci device to write to
* @slot: the pci slot number of the pci device to write to
* @function: the function of the pci device to write to
* @where: the location on the pci address space to write to
* @value: the value to write to the pci device
*
* Like pci_write_config_dword() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns 0 on success.
*/
int pci_write_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 slot, u8 function, int where, u32 value)
{
struct pci_dev *dev = NULL;
int result;
dbg("%p, %d, %d, %d, %d, %d\n", ops, bus, slot, function, where, value);
dev = pci_find_slot(bus, PCI_DEVFN(slot, function));
if (dev) {
dbg("using native pci_dev\n");
return pci_write_config_dword (dev, where, value);
}
result = build_dev (ops, bus, slot, function, &dev);
if (result)
return result;
result = pci_write_config_dword(dev, where, value);
kfree (dev->bus);
kfree (dev);
return result;
}
/*
* This is code that scans the pci buses.
* Every bus and every function is presented to a custom
......@@ -394,10 +155,4 @@ int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, st
EXPORT_SYMBOL(pci_visit_dev);
EXPORT_SYMBOL(pci_read_config_byte_nodev);
EXPORT_SYMBOL(pci_read_config_word_nodev);
EXPORT_SYMBOL(pci_read_config_dword_nodev);
EXPORT_SYMBOL(pci_write_config_byte_nodev);
EXPORT_SYMBOL(pci_write_config_word_nodev);
EXPORT_SYMBOL(pci_write_config_dword_nodev);
......@@ -19,29 +19,45 @@ spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
#define PCI_word_BAD (pos & 1)
#define PCI_dword_BAD (pos & 3)
#define PCI_OP(rw,size,type) \
int pci_##rw##_config_##size (struct pci_dev *dev, int pos, type value) \
#define PCI_OP_READ(size,type,len) \
int pci_bus_read_config_##size \
(struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
{ \
int res; \
unsigned long flags; \
u32 data = 0; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
spin_lock_irqsave(&pci_lock, flags); \
res = dev->bus->ops->rw##_##size(dev, pos, value); \
res = bus->ops->read(bus, devfn, pos, len, &data); \
*value = (type)data; \
spin_unlock_irqrestore(&pci_lock, flags); \
return res; \
}
PCI_OP(read, byte, u8 *)
PCI_OP(read, word, u16 *)
PCI_OP(read, dword, u32 *)
PCI_OP(write, byte, u8)
PCI_OP(write, word, u16)
PCI_OP(write, dword, u32)
EXPORT_SYMBOL(pci_read_config_byte);
EXPORT_SYMBOL(pci_read_config_word);
EXPORT_SYMBOL(pci_read_config_dword);
EXPORT_SYMBOL(pci_write_config_byte);
EXPORT_SYMBOL(pci_write_config_word);
EXPORT_SYMBOL(pci_write_config_dword);
#define PCI_OP_WRITE(size,type,len) \
int pci_bus_write_config_##size \
(struct pci_bus *bus, unsigned int devfn, int pos, type value) \
{ \
int res; \
unsigned long flags; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
spin_lock_irqsave(&pci_lock, flags); \
res = bus->ops->write(bus, devfn, pos, len, value); \
spin_unlock_irqrestore(&pci_lock, flags); \
return res; \
}
PCI_OP_READ(byte, u8, 1)
PCI_OP_READ(word, u16, 2)
PCI_OP_READ(dword, u32, 4)
PCI_OP_WRITE(byte, u8, 1)
PCI_OP_WRITE(word, u16, 2)
PCI_OP_WRITE(dword, u32, 4)
EXPORT_SYMBOL(pci_bus_read_config_byte);
EXPORT_SYMBOL(pci_bus_read_config_word);
EXPORT_SYMBOL(pci_bus_read_config_dword);
EXPORT_SYMBOL(pci_bus_write_config_byte);
EXPORT_SYMBOL(pci_bus_write_config_word);
EXPORT_SYMBOL(pci_bus_write_config_dword);
EXPORT_SYMBOL(pci_lock);
......@@ -17,18 +17,70 @@ struct pci_pool { /* the pool */
size_t allocation;
char name [32];
wait_queue_head_t waitq;
struct list_head pools;
};
struct pci_page { /* cacheable header for 'allocation' bytes */
struct list_head page_list;
void *vaddr;
dma_addr_t dma;
unsigned in_use;
unsigned long bitmap [0];
};
#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000)
#define POOL_POISON_BYTE 0xa7
static spinlock_t pools_lock = SPIN_LOCK_UNLOCKED;
static ssize_t
show_pools (struct device *dev, char *buf, size_t count, loff_t off)
{
struct pci_dev *pdev;
unsigned long flags;
unsigned temp, size;
char *next;
struct list_head *i, *j;
if (off != 0)
return 0;
pdev = container_of (dev, struct pci_dev, dev);
next = buf;
size = count;
temp = snprintf (next, size, "poolinfo - 0.1\n");
size -= temp;
next += temp;
spin_lock_irqsave (&pools_lock, flags);
list_for_each (i, &pdev->pools) {
struct pci_pool *pool;
unsigned pages = 0, blocks = 0;
pool = list_entry (i, struct pci_pool, pools);
list_for_each (j, &pool->page_list) {
struct pci_page *page;
page = list_entry (j, struct pci_page, page_list);
pages++;
blocks += page->in_use;
}
/* per-pool info, no real statistics yet */
temp = snprintf (next, size, "%-16s %4u %4u %4u %2u\n",
pool->name,
blocks, pages * pool->blocks_per_page,
pool->size, pages);
size -= temp;
next += temp;
}
spin_unlock_irqrestore (&pools_lock, flags);
return count - size;
}
static DEVICE_ATTR (pools, S_IRUGO, show_pools, NULL);
/**
* pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
......@@ -56,6 +108,7 @@ pci_pool_create (const char *name, struct pci_dev *pdev,
size_t size, size_t align, size_t allocation, int mem_flags)
{
struct pci_pool *retval;
unsigned long flags;
if (align == 0)
align = 1;
......@@ -84,6 +137,17 @@ pci_pool_create (const char *name, struct pci_dev *pdev,
retval->name [sizeof retval->name - 1] = 0;
retval->dev = pdev;
if (pdev) {
spin_lock_irqsave (&pools_lock, flags);
/* note: not currently insisting "name" be unique */
if (list_empty (&pdev->pools))
device_create_file (&pdev->dev, &dev_attr_pools);
list_add (&retval->pools, &pdev->pools);
spin_unlock_irqrestore (&pools_lock, flags);
} else
INIT_LIST_HEAD (&retval->pools);
INIT_LIST_HEAD (&retval->page_list);
spin_lock_init (&retval->lock);
retval->size = size;
......@@ -117,6 +181,7 @@ pool_alloc_page (struct pci_pool *pool, int mem_flags)
memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
#endif
list_add (&page->page_list, &pool->page_list);
page->in_use = 0;
} else {
kfree (page);
page = 0;
......@@ -177,6 +242,13 @@ pci_pool_destroy (struct pci_pool *pool)
} else
pool_free_page (pool, page);
}
spin_lock (&pools_lock);
list_del (&pool->pools);
if (pool->dev && list_empty (&pool->dev->pools))
device_remove_file (&pool->dev->dev, &dev_attr_pools);
spin_unlock (&pools_lock);
spin_unlock_irqrestore (&pool->lock, flags);
kfree (pool);
}
......@@ -243,6 +315,7 @@ pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
clear_bit (0, &page->bitmap [0]);
offset = 0;
ready:
page->in_use++;
retval = offset + page->vaddr;
*handle = offset + page->dma;
done:
......@@ -318,6 +391,7 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
#endif
spin_lock_irqsave (&pool->lock, flags);
page->in_use--;
set_bit (block, &page->bitmap [map]);
if (waitqueue_active (&pool->waitq))
wake_up (&pool->waitq);
......
......@@ -364,6 +364,7 @@ int pci_setup_device(struct pci_dev * dev)
sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
sprintf(dev->name, "PCI device %04x:%04x", dev->vendor, dev->device);
INIT_LIST_HEAD(&dev->pools);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
......
......@@ -22,8 +22,6 @@ extern unsigned long pci_mem_start;
void pcibios_config_init(void);
struct pci_bus * pcibios_scan_root(int bus);
extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
void pcibios_set_master(struct pci_dev *dev);
void pcibios_penalize_isa_irq(int irq);
......
......@@ -22,8 +22,6 @@
void pcibios_config_init(void);
struct pci_bus * pcibios_scan_root(int bus);
extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
struct pci_dev;
......
......@@ -359,6 +359,7 @@ struct pci_dev {
0xffffffff. You only need to change
this if your device has broken DMA
or supports 64-bit transfers. */
struct list_head pools; /* pci_pools tied to this device */
u32 current_state; /* Current operating state. In ACPI-speak,
this is D0-D3, D0 being fully functional,
......@@ -456,12 +457,8 @@ extern struct bus_type pci_bus_type;
/* Low-level architecture-dependent routines */
struct pci_ops {
int (*read_byte)(struct pci_dev *, int where, u8 *val);
int (*read_word)(struct pci_dev *, int where, u16 *val);
int (*read_dword)(struct pci_dev *, int where, u32 *val);
int (*write_byte)(struct pci_dev *, int where, u8 val);
int (*write_word)(struct pci_dev *, int where, u16 val);
int (*write_dword)(struct pci_dev *, int where, u32 val);
int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
};
struct pbus_set_ranges_data
......@@ -560,12 +557,37 @@ struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val);
int pci_read_config_word(struct pci_dev *dev, int where, u16 *val);
int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val);
int pci_write_config_byte(struct pci_dev *dev, int where, u8 val);
int pci_write_config_word(struct pci_dev *dev, int where, u16 val);
int pci_write_config_dword(struct pci_dev *dev, int where, u32 val);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val);
int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val);
int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 val);
int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 val);
static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
{
return pci_bus_read_config_byte (dev->bus, dev->devfn, where, val);
}
static int inline pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
{
return pci_bus_read_config_word (dev->bus, dev->devfn, where, val);
}
static int inline pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
{
return pci_bus_read_config_dword (dev->bus, dev->devfn, where, val);
}
static int inline pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
{
return pci_bus_write_config_byte (dev->bus, dev->devfn, where, val);
}
static int inline pci_write_config_word(struct pci_dev *dev, int where, u16 val)
{
return pci_bus_write_config_word (dev->bus, dev->devfn, where, val);
}
static int inline pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
{
return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val);
}
extern spinlock_t pci_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment