mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
2005-03-14 Joel Sherrill <joel@OARcorp.com>
* pci/pci.c, pci/pci.h, pci/pcifinddevice.c: Continue PCI API unification. All use pci_find_device(). Also reformat to remove tabs.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2005-03-14 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
|
* pci/pci.c, pci/pci.h, pci/pcifinddevice.c: Continue PCI API
|
||||||
|
unification. All use pci_find_device(). Also reformat to remove tabs.
|
||||||
|
|
||||||
2005-03-04 Joel Sherrill <joel@OARcorp.com>
|
2005-03-04 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
* pci/pci.c, pci/pcifinddevice.c, startup/bspstart.c: Make PCI
|
* pci/pci.c, pci/pcifinddevice.c, startup/bspstart.c: Make PCI
|
||||||
|
|||||||
@@ -25,17 +25,17 @@
|
|||||||
|
|
||||||
/* allow for overriding these definitions */
|
/* allow for overriding these definitions */
|
||||||
#ifndef PCI_CONFIG_ADDR
|
#ifndef PCI_CONFIG_ADDR
|
||||||
#define PCI_CONFIG_ADDR 0xcf8
|
#define PCI_CONFIG_ADDR 0xcf8
|
||||||
#endif
|
#endif
|
||||||
#ifndef PCI_CONFIG_DATA
|
#ifndef PCI_CONFIG_DATA
|
||||||
#define PCI_CONFIG_DATA 0xcfc
|
#define PCI_CONFIG_DATA 0xcfc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
|
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
|
||||||
#define PCI_MULTI_FUNCTION 0x80
|
#define PCI_MULTI_FUNCTION 0x80
|
||||||
|
|
||||||
/* define a shortcut */
|
/* define a shortcut */
|
||||||
#define pci BSP_pci_configuration
|
#define pci BSP_pci_configuration
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bit encode for PCI_CONFIG_HEADER_TYPE register
|
* Bit encode for PCI_CONFIG_HEADER_TYPE register
|
||||||
@@ -43,181 +43,243 @@
|
|||||||
unsigned char ucMaxPCIBus;
|
unsigned char ucMaxPCIBus;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_read_config_byte(unsigned char bus, unsigned char slot,
|
indirect_pci_read_config_byte(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned char *val) {
|
unsigned char slot,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned char function,
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
unsigned char offset,
|
||||||
*val = in_8(pci.pci_config_data + (offset&3));
|
unsigned char *val
|
||||||
return PCIBIOS_SUCCESSFUL;
|
) {
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
||||||
|
*val = in_8(pci.pci_config_data + (offset&3));
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_read_config_word(unsigned char bus, unsigned char slot,
|
indirect_pci_read_config_word(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned short *val) {
|
unsigned char slot,
|
||||||
*val = 0xffff;
|
unsigned char function,
|
||||||
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char offset,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned short *val
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
) {
|
||||||
*val = in_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)));
|
*val = 0xffff;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
if (offset&1)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
||||||
|
*val = in_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)));
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_read_config_dword(unsigned char bus, unsigned char slot,
|
indirect_pci_read_config_dword(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned int *val) {
|
unsigned char slot,
|
||||||
*val = 0xffffffff;
|
unsigned char function,
|
||||||
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char offset,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned int *val
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
|
) {
|
||||||
*val = in_le32((volatile unsigned int *)pci.pci_config_data);
|
*val = 0xffffffff;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
if (offset&3)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
|
||||||
|
*val = in_le32((volatile unsigned int *)pci.pci_config_data);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_write_config_byte(unsigned char bus, unsigned char slot,
|
indirect_pci_write_config_byte(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned char val) {
|
unsigned char slot,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned char function,
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
unsigned char offset,
|
||||||
out_8(pci.pci_config_data + (offset&3), val);
|
unsigned char val
|
||||||
return PCIBIOS_SUCCESSFUL;
|
) {
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
||||||
|
out_8(pci.pci_config_data + (offset&3), val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_write_config_word(unsigned char bus, unsigned char slot,
|
indirect_pci_write_config_word(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned short val) {
|
unsigned char slot,
|
||||||
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char function,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned char offset,
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
unsigned short val
|
||||||
out_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)), val);
|
) {
|
||||||
return PCIBIOS_SUCCESSFUL;
|
if (offset&1)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
|
||||||
|
out_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)), val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
indirect_pci_write_config_dword(unsigned char bus, unsigned char slot,
|
indirect_pci_write_config_dword(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned int val) {
|
unsigned char slot,
|
||||||
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char function,
|
||||||
out_be32((unsigned int*) pci.pci_config_addr,
|
unsigned char offset,
|
||||||
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
|
unsigned int val
|
||||||
out_le32((volatile unsigned int *)pci.pci_config_data, val);
|
) {
|
||||||
return PCIBIOS_SUCCESSFUL;
|
if (offset&3)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
out_be32((unsigned int*) pci.pci_config_addr,
|
||||||
|
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
|
||||||
|
out_le32((volatile unsigned int *)pci.pci_config_data, val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pci_config_access_functions pci_indirect_functions = {
|
const pci_config_access_functions pci_indirect_functions = {
|
||||||
indirect_pci_read_config_byte,
|
indirect_pci_read_config_byte,
|
||||||
indirect_pci_read_config_word,
|
indirect_pci_read_config_word,
|
||||||
indirect_pci_read_config_dword,
|
indirect_pci_read_config_dword,
|
||||||
indirect_pci_write_config_byte,
|
indirect_pci_write_config_byte,
|
||||||
indirect_pci_write_config_word,
|
indirect_pci_write_config_word,
|
||||||
indirect_pci_write_config_dword
|
indirect_pci_write_config_dword
|
||||||
};
|
};
|
||||||
|
|
||||||
pci_config BSP_pci_configuration = {(volatile unsigned char*)PCI_CONFIG_ADDR,
|
pci_config BSP_pci_configuration = {
|
||||||
(volatile unsigned char*)PCI_CONFIG_DATA,
|
(volatile unsigned char*)PCI_CONFIG_ADDR,
|
||||||
&pci_indirect_functions};
|
(volatile unsigned char*)PCI_CONFIG_DATA,
|
||||||
|
&pci_indirect_functions
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_read_config_byte(unsigned char bus, unsigned char slot,
|
direct_pci_read_config_byte(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned char *val) {
|
unsigned char slot,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned char function,
|
||||||
*val=0xff;
|
unsigned char offset,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
unsigned char *val
|
||||||
}
|
) {
|
||||||
*val=in_8(pci.pci_config_data + ((1<<slot)&~1)
|
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
||||||
+ (function<<8) + offset);
|
*val=0xff;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
*val=in_8(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_read_config_word(unsigned char bus, unsigned char slot,
|
direct_pci_read_config_word(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned short *val) {
|
unsigned char slot,
|
||||||
*val = 0xffff;
|
unsigned char function,
|
||||||
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char offset,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned short *val
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
) {
|
||||||
}
|
*val = 0xffff;
|
||||||
*val=in_le16((volatile unsigned short *)
|
if (offset&1)
|
||||||
(pci.pci_config_data + ((1<<slot)&~1)
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
+ (function<<8) + offset));
|
if (bus != 0 || (1<<slot & 0xff8007fe))
|
||||||
return PCIBIOS_SUCCESSFUL;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
*val=in_le16((volatile unsigned short *)
|
||||||
|
(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset));
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_read_config_dword(unsigned char bus, unsigned char slot,
|
direct_pci_read_config_dword(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned int *val) {
|
unsigned char slot,
|
||||||
*val = 0xffffffff;
|
unsigned char function,
|
||||||
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char offset,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned int *val
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
) {
|
||||||
}
|
*val = 0xffffffff;
|
||||||
*val=in_le32((volatile unsigned int *)
|
if (offset&3)
|
||||||
(pci.pci_config_data + ((1<<slot)&~1)
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
+ (function<<8) + offset));
|
if (bus != 0 || (1<<slot & 0xff8007fe))
|
||||||
return PCIBIOS_SUCCESSFUL;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
*val=in_le32((volatile unsigned int *)
|
||||||
|
(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset));
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_write_config_byte(unsigned char bus, unsigned char slot,
|
direct_pci_write_config_byte(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned char val) {
|
unsigned char slot,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned char function,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
unsigned char offset,
|
||||||
}
|
unsigned char val
|
||||||
out_8(pci.pci_config_data + ((1<<slot)&~1)
|
) {
|
||||||
+ (function<<8) + offset,
|
if (bus != 0 || (1<<slot & 0xff8007fe))
|
||||||
val);
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
|
||||||
|
out_8(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset,
|
||||||
|
val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_write_config_word(unsigned char bus, unsigned char slot,
|
direct_pci_write_config_word(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned short val) {
|
unsigned char slot,
|
||||||
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char function,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned char offset,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
unsigned short val
|
||||||
}
|
) {
|
||||||
out_le16((volatile unsigned short *)
|
if (offset&1)
|
||||||
(pci.pci_config_data + ((1<<slot)&~1)
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
+ (function<<8) + offset),
|
if (bus != 0 || (1<<slot & 0xff8007fe))
|
||||||
val);
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
|
||||||
|
out_le16((volatile unsigned short *)
|
||||||
|
(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset),
|
||||||
|
val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
direct_pci_write_config_dword(unsigned char bus, unsigned char slot,
|
direct_pci_write_config_dword(
|
||||||
unsigned char function,
|
unsigned char bus,
|
||||||
unsigned char offset, unsigned int val) {
|
unsigned char slot,
|
||||||
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
|
unsigned char function,
|
||||||
if (bus != 0 || (1<<slot & 0xff8007fe)) {
|
unsigned char offset,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
unsigned int val
|
||||||
}
|
) {
|
||||||
out_le32((volatile unsigned int *)
|
if (offset&3)
|
||||||
(pci.pci_config_data + ((1<<slot)&~1)
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
+ (function<<8) + offset),
|
if (bus != 0 || (1<<slot & 0xff8007fe))
|
||||||
val);
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
return PCIBIOS_SUCCESSFUL;
|
|
||||||
|
out_le32((volatile unsigned int *)
|
||||||
|
(pci.pci_config_data + ((1<<slot)&~1)
|
||||||
|
+ (function<<8) + offset),
|
||||||
|
val);
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pci_config_access_functions pci_direct_functions = {
|
const pci_config_access_functions pci_direct_functions = {
|
||||||
direct_pci_read_config_byte,
|
direct_pci_read_config_byte,
|
||||||
direct_pci_read_config_word,
|
direct_pci_read_config_word,
|
||||||
direct_pci_read_config_dword,
|
direct_pci_read_config_dword,
|
||||||
direct_pci_write_config_byte,
|
direct_pci_write_config_byte,
|
||||||
direct_pci_write_config_word,
|
direct_pci_write_config_word,
|
||||||
direct_pci_write_config_dword
|
direct_pci_write_config_dword
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PRINT_MSG() \
|
#define PRINT_MSG() \
|
||||||
printk("pci : Device %d:%02x routed to interrupt_line %d\n", pbus, pslot, int_name )
|
printk("pci : Device %d:%02x routed to interrupt_line %d\n", \
|
||||||
|
pbus, pslot, int_name )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Validate a test interrupt name and print a warning if its not one of
|
** Validate a test interrupt name and print a warning if its not one of
|
||||||
@@ -229,299 +291,271 @@ static int test_intname(
|
|||||||
int pslot,
|
int pslot,
|
||||||
int int_pin,
|
int int_pin,
|
||||||
int int_name
|
int int_name
|
||||||
)
|
) {
|
||||||
{
|
int j, k;
|
||||||
int j, k;
|
int _nopin= -1, _noname= -1;
|
||||||
int _nopin= -1, _noname= -1;
|
|
||||||
|
|
||||||
for(j=0; row->pin_route[j].pin > -1; j++)
|
for (j=0; row->pin_route[j].pin > -1; j++) {
|
||||||
{
|
if ( row->pin_route[j].pin == int_pin ) {
|
||||||
if( row->pin_route[j].pin == int_pin )
|
_nopin = 0;
|
||||||
{
|
|
||||||
_nopin = 0;
|
|
||||||
|
|
||||||
for(k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ )
|
for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) {
|
||||||
{
|
if ( row->pin_route[j].int_name[k] == int_name ) {
|
||||||
if( row->pin_route[j].int_name[k] == int_name ){ _noname=0; break; }
|
_noname=0; break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( _nopin )
|
if ( _nopin ) {
|
||||||
{
|
printk("pci : Device %d:%02x supplied a bogus interrupt_pin %d\n",
|
||||||
printk("pci : Device %d:%02x supplied a bogus interrupt_pin %d\n", pbus, pslot, int_pin );
|
pbus, pslot, int_pin );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else {
|
||||||
else
|
if ( _noname )
|
||||||
{
|
printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d,"
|
||||||
if( _noname )
|
" using it anyway\n", pbus, pslot, int_name );
|
||||||
printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d, using it anyway\n", pbus, pslot, int_name );
|
}
|
||||||
}
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pcibridge
|
struct pcibridge
|
||||||
{
|
{
|
||||||
int bus,slot;
|
int bus;
|
||||||
|
int slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int FindPCIbridge( int mybus, struct pcibridge *pb )
|
static int FindPCIbridge( int mybus, struct pcibridge *pb )
|
||||||
{
|
{
|
||||||
int pbus, pslot;
|
int pbus, pslot;
|
||||||
uint8_t bussec, buspri;
|
uint8_t bussec, buspri;
|
||||||
uint16_t devid, vendorid, dclass;
|
uint16_t devid, vendorid, dclass;
|
||||||
|
|
||||||
for(pbus=0; pbus< BusCountPCI(); pbus++)
|
for(pbus=0; pbus< BusCountPCI(); pbus++) {
|
||||||
{
|
for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
|
||||||
for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++)
|
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
|
||||||
{
|
if ( devid == 0xffff ) continue;
|
||||||
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
|
|
||||||
if( devid == 0xffff ) continue;
|
|
||||||
|
|
||||||
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
|
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
|
||||||
if( vendorid == 0xffff ) continue;
|
if ( vendorid == 0xffff ) continue;
|
||||||
|
|
||||||
pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
|
pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
|
||||||
|
|
||||||
if( dclass == PCI_CLASS_BRIDGE_PCI )
|
if ( dclass == PCI_CLASS_BRIDGE_PCI ) {
|
||||||
{
|
pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS, &buspri);
|
||||||
pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS, &buspri);
|
pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS, &bussec);
|
||||||
pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS, &bussec);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d ", pbus, pslot, mybus, buspri, bussec );
|
printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d ",
|
||||||
|
pbus, pslot, mybus, buspri, bussec );
|
||||||
#endif
|
#endif
|
||||||
if( bussec == mybus )
|
if ( bussec == mybus ) {
|
||||||
{
|
|
||||||
#if 0
|
#if 0
|
||||||
printk("match\n");
|
printk("match\n");
|
||||||
#endif
|
#endif
|
||||||
/* found our nearest bridge going towards the root */
|
/* found our nearest bridge going towards the root */
|
||||||
pb->bus = pbus;
|
pb->bus = pbus;
|
||||||
pb->slot = pslot;
|
pb->slot = pslot;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
printk("no match\n");
|
printk("no match\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) )
|
void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) )
|
||||||
{
|
{
|
||||||
unsigned char cvalue;
|
unsigned char cvalue;
|
||||||
uint16_t devid;
|
uint16_t devid;
|
||||||
int ismatch, i, j, pbus, pslot, int_pin, int_name;
|
int ismatch, i, j, pbus, pslot, int_pin, int_name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
|
* If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
|
||||||
** INTERRUPT_NAME if one isn't already in place. Then, drivers can
|
* INTERRUPT_NAME if one isn't already in place. Then, drivers can
|
||||||
** trivially use INTERRUPT_NAME to hook up with devices.
|
* trivially use INTERRUPT_NAME to hook up with devices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for(pbus=0; pbus< BusCountPCI(); pbus++)
|
for (pbus=0; pbus< BusCountPCI(); pbus++) {
|
||||||
{
|
for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
|
||||||
for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++)
|
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
|
||||||
{
|
if ( devid == 0xffff ) continue;
|
||||||
pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
|
|
||||||
if( devid == 0xffff ) continue;
|
|
||||||
|
|
||||||
/* got a device */
|
/* got a device */
|
||||||
|
|
||||||
pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_PIN, &cvalue);
|
pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_PIN, &cvalue);
|
||||||
int_pin = cvalue;
|
int_pin = cvalue;
|
||||||
|
|
||||||
pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_LINE, &cvalue);
|
pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_LINE, &cvalue);
|
||||||
int_name = cvalue;
|
int_name = cvalue;
|
||||||
|
|
||||||
/* printk("pci : device %d:%02x devid %04x, intpin %d, intline %d\n", pbus, pslot, devid, int_pin, int_name ); */
|
/* printk("pci : device %d:%02x devid %04x, intpin %d, intline %d\n",
|
||||||
|
pbus, pslot, devid, int_pin, int_name ); */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
unsigned short cmd,stat;
|
unsigned short cmd,stat;
|
||||||
unsigned char lat, seclat, csize;
|
unsigned char lat, seclat, csize;
|
||||||
|
|
||||||
pci_read_config_word(pbus,pslot,0,PCI_COMMAND, &cmd );
|
pci_read_config_word(pbus,pslot,0,PCI_COMMAND, &cmd );
|
||||||
pci_read_config_word(pbus,pslot,0,PCI_STATUS, &stat );
|
pci_read_config_word(pbus,pslot,0,PCI_STATUS, &stat );
|
||||||
pci_read_config_byte(pbus,pslot,0,PCI_LATENCY_TIMER, &lat );
|
pci_read_config_byte(pbus,pslot,0,PCI_LATENCY_TIMER, &lat );
|
||||||
pci_read_config_byte(pbus,pslot,0,PCI_SEC_LATENCY_TIMER, &seclat );
|
pci_read_config_byte(pbus,pslot,0,PCI_SEC_LATENCY_TIMER, &seclat );
|
||||||
pci_read_config_byte(pbus,pslot,0,PCI_CACHE_LINE_SIZE, &csize );
|
pci_read_config_byte(pbus,pslot,0,PCI_CACHE_LINE_SIZE, &csize );
|
||||||
|
|
||||||
|
|
||||||
printk("pci : device %d:%02x cmd %04X, stat %04X, latency %d, sec_latency %d, clsize %d\n", pbus, pslot,
|
printk("pci : device %d:%02x cmd %04X, stat %04X, latency %d, "
|
||||||
cmd,
|
" sec_latency %d, clsize %d\n", pbus, pslot, cmd, stat,
|
||||||
stat,
|
lat, seclat, csize);
|
||||||
lat,
|
}
|
||||||
seclat,
|
|
||||||
csize);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( int_pin > 0 )
|
if ( int_pin > 0 ) {
|
||||||
{
|
ismatch = 0;
|
||||||
ismatch = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** first run thru the bspmap table and see if we have an explicit configuration
|
* first run thru the bspmap table and see if we have an
|
||||||
*/
|
* explicit configuration
|
||||||
for(i=0; bspmap[i].bus > -1; i++)
|
*/
|
||||||
{
|
for (i=0; bspmap[i].bus > -1; i++) {
|
||||||
if( bspmap[i].bus == pbus && bspmap[i].slot == pslot )
|
if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
|
||||||
{
|
ismatch = -1;
|
||||||
ismatch = -1;
|
/* we have a record in the table that gives specific
|
||||||
/* we have a record in the table that gives specific
|
* pins and interrupts for devices in this slot */
|
||||||
* pins and interrupts for devices in this slot */
|
if ( int_name == 255 ) {
|
||||||
if( int_name == 255 )
|
/* find the vector associated with whatever pin the
|
||||||
{
|
* device gives us
|
||||||
/* find the vector associated with whatever pin the device gives us */
|
*/
|
||||||
for( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ )
|
for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ) {
|
||||||
{
|
if ( bspmap[i].pin_route[j].pin == int_pin ) {
|
||||||
if( bspmap[i].pin_route[j].pin == int_pin )
|
int_name = bspmap[i].pin_route[j].int_name[0];
|
||||||
{
|
|
||||||
int_name = bspmap[i].pin_route[j].int_name[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( int_name == -1 )
|
|
||||||
{
|
|
||||||
printk("pci : Unable to resolve device %d:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PRINT_MSG();
|
|
||||||
pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
test_intname( &bspmap[i],pbus,pslot,int_pin,int_name);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( int_name == -1 ) {
|
||||||
|
printk("pci : Unable to resolve device %d:%d w/ swizzled int "
|
||||||
|
"pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
|
||||||
|
} else {
|
||||||
|
PRINT_MSG();
|
||||||
|
pci_write_config_byte( pbus,pslot,0,
|
||||||
|
PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
test_intname( &bspmap[i],pbus,pslot,int_pin,int_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ismatch ) {
|
||||||
|
/*
|
||||||
|
* no match, which means we're on a bus someplace. Work
|
||||||
|
* backwards from it to one of our defined busses,
|
||||||
|
* swizzling thru each bridge on the way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* keep pbus, pslot pointed to the device being
|
||||||
|
* configured while we track down the bridges using
|
||||||
|
* tbus,tslot. We keep searching the routing table because
|
||||||
|
* we may end up finding our bridge in it
|
||||||
|
*/
|
||||||
|
|
||||||
|
int tbus= pbus, tslot= pslot;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
for (i=0; bspmap[i].bus > -1; i++) {
|
||||||
|
if ( bspmap[i].bus == tbus &&
|
||||||
|
(bspmap[i].slot == tslot || bspmap[i].slot == -1) ) {
|
||||||
|
ismatch = -1;
|
||||||
|
/* found a record for this bus, so swizzle the
|
||||||
|
* int_pin which we then use to find the
|
||||||
|
* interrupt_name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( int_name == 255 ) {
|
||||||
|
/*
|
||||||
|
* FIXME. I can't believe this little hack
|
||||||
|
* is right. It does not yield an error in
|
||||||
|
* convienently simple situations.
|
||||||
|
*/
|
||||||
|
if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int_pin points to the interrupt channel
|
||||||
|
* this card ends up delivering interrupts
|
||||||
|
* on. Find the int_name servicing it.
|
||||||
|
*/
|
||||||
|
for (int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++){
|
||||||
|
if ( bspmap[i].pin_route[j].pin == int_pin ) {
|
||||||
|
int_name = bspmap[i].pin_route[j].int_name[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( int_name == -1 ) {
|
||||||
|
printk("pci : Unable to resolve device %d:%d w/ swizzled "
|
||||||
|
"int pin %i to an interrupt_line.\n",
|
||||||
|
pbus, pslot, int_pin );
|
||||||
|
} else {
|
||||||
|
PRINT_MSG();
|
||||||
|
pci_write_config_byte(pbus,pslot,0,
|
||||||
|
PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
test_intname(&bspmap[i],pbus,pslot,int_pin,int_name);
|
||||||
|
}
|
||||||
|
goto donesearch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !ismatch )
|
if ( !ismatch ) {
|
||||||
{
|
struct pcibridge pb;
|
||||||
/*
|
|
||||||
** no match, which means we're on a bus someplace. Work
|
/*
|
||||||
** backwards from it to one of our defined busses,
|
* Haven't found our bus in the int map, so work
|
||||||
** swizzling thru each bridge on the way.
|
* upwards thru the bridges till we find it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* keep pbus, pslot pointed to the device being
|
if ( FindPCIbridge( tbus, &pb )== 0 ) {
|
||||||
configured while we track down the bridges using
|
int_pin = (*swizzler)(tslot,int_pin);
|
||||||
tbus,tslot. We keep searching the routing table because
|
|
||||||
we may end up finding our bridge in it */
|
|
||||||
|
|
||||||
int tbus= pbus, tslot= pslot;
|
/* our next bridge up is on pb.bus, pb.slot- now
|
||||||
|
* instead of pointing to the device we're
|
||||||
|
* trying to configure, we move from bridge to
|
||||||
|
* bridge.
|
||||||
|
*/
|
||||||
|
|
||||||
for(;;)
|
tbus = pb.bus;
|
||||||
{
|
tslot = pb.slot;
|
||||||
|
} else {
|
||||||
for(i=0; bspmap[i].bus > -1; i++)
|
printk("pci : No bridge from bus %i towards root found\n",
|
||||||
{
|
tbus );
|
||||||
if( bspmap[i].bus == tbus && (bspmap[i].slot == tslot || bspmap[i].slot == -1) )
|
goto donesearch;
|
||||||
{
|
}
|
||||||
ismatch = -1;
|
|
||||||
/* found a record for this bus, so swizzle the
|
|
||||||
* int_pin which we then use to find the
|
|
||||||
* interrupt_name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( int_name == 255 )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
** FIXME. I can't believe this little hack
|
|
||||||
** is right. It does not yield an error in
|
|
||||||
** convienently simple situations.
|
|
||||||
*/
|
|
||||||
if( tbus ) int_pin = (*swizzler)(tslot,int_pin);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** int_pin points to the interrupt channel
|
|
||||||
** this card ends up delivering interrupts
|
|
||||||
** on. Find the int_name servicing it.
|
|
||||||
*/
|
|
||||||
for( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ )
|
|
||||||
{
|
|
||||||
if( bspmap[i].pin_route[j].pin == int_pin )
|
|
||||||
{
|
|
||||||
int_name = bspmap[i].pin_route[j].int_name[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( int_name == -1 )
|
|
||||||
{
|
|
||||||
printk("pci : Unable to resolve device %d:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PRINT_MSG();
|
|
||||||
pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
test_intname(&bspmap[i],pbus,pslot,int_pin,int_name);
|
|
||||||
}
|
|
||||||
goto donesearch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !ismatch )
|
|
||||||
{
|
|
||||||
struct pcibridge pb;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Haven't found our bus in the int map, so work
|
|
||||||
** upwards thru the bridges till we find it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( FindPCIbridge( tbus, &pb )== 0 )
|
|
||||||
{
|
|
||||||
int_pin = (*swizzler)(tslot,int_pin);
|
|
||||||
|
|
||||||
/* our next bridge up is on pb.bus, pb.slot- now
|
|
||||||
** instead of pointing to the device we're
|
|
||||||
** trying to configure, we move from bridge to
|
|
||||||
** bridge.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tbus = pb.bus;
|
|
||||||
tslot = pb.slot;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printk("pci : No bridge from bus %i towards root found\n", tbus );
|
|
||||||
goto donesearch;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
donesearch:
|
}
|
||||||
|
}
|
||||||
|
donesearch:
|
||||||
|
|
||||||
if( !ismatch && int_pin != 0 && int_name == 255 )
|
if ( !ismatch && int_pin != 0 && int_name == 255 ) {
|
||||||
{
|
printk("pci : Unable to match device %d:%d with an int "
|
||||||
printk("pci : Unable to match device %d:%d with an int routing table entry\n", pbus, pslot );
|
"routing table entry\n", pbus, pslot );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine determines the maximum bus number in the system
|
* This routine determines the maximum bus number in the system
|
||||||
*/
|
*/
|
||||||
void pci_initialize()
|
int pci_initialize()
|
||||||
{
|
{
|
||||||
extern void detect_host_bridge();
|
extern void detect_host_bridge();
|
||||||
unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs;
|
unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs;
|
||||||
@@ -534,66 +568,41 @@ void pci_initialize()
|
|||||||
/*
|
/*
|
||||||
* Scan PCI bus 0 looking for PCI-PCI bridges
|
* Scan PCI bus 0 looking for PCI-PCI bridges
|
||||||
*/
|
*/
|
||||||
for(ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++) {
|
for (ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++) {
|
||||||
(void)pci_read_config_dword(0,
|
pci_read_config_dword(0, ucSlotNumber, 0, PCI_VENDOR_ID, &ulDeviceID);
|
||||||
ucSlotNumber,
|
if (ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
|
||||||
0,
|
/* This slot is empty */
|
||||||
PCI_VENDOR_ID,
|
|
||||||
&ulDeviceID);
|
|
||||||
if(ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
|
|
||||||
/*
|
|
||||||
* This slot is empty
|
|
||||||
*/
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(void)pci_read_config_byte(0,
|
pci_read_config_byte(0, ucSlotNumber, 0, PCI_HEADER_TYPE, &ucHeader);
|
||||||
ucSlotNumber,
|
if (ucHeader&PCI_MULTI_FUNCTION) {
|
||||||
0,
|
|
||||||
PCI_HEADER_TYPE,
|
|
||||||
&ucHeader);
|
|
||||||
if(ucHeader&PCI_MULTI_FUNCTION) {
|
|
||||||
ucNumFuncs=PCI_MAX_FUNCTIONS;
|
ucNumFuncs=PCI_MAX_FUNCTIONS;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ucNumFuncs=1;
|
ucNumFuncs=1;
|
||||||
}
|
}
|
||||||
for(ucFnNumber=0;ucFnNumber<ucNumFuncs;ucFnNumber++) {
|
for (ucFnNumber=0;ucFnNumber<ucNumFuncs;ucFnNumber++) {
|
||||||
(void)pci_read_config_dword(0,
|
pci_read_config_dword(0, ucSlotNumber, ucFnNumber,
|
||||||
ucSlotNumber,
|
PCI_VENDOR_ID, &ulDeviceID);
|
||||||
ucFnNumber,
|
if (ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
|
||||||
PCI_VENDOR_ID,
|
/* This slot/function is empty */
|
||||||
&ulDeviceID);
|
continue;
|
||||||
if(ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
|
|
||||||
/*
|
|
||||||
* This slot/function is empty
|
|
||||||
*/
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* This slot/function has a device fitted. */
|
||||||
* This slot/function has a device fitted.
|
pci_read_config_dword(0, ucSlotNumber, ucFnNumber,
|
||||||
*/
|
PCI_CLASS_REVISION, &ulClass);
|
||||||
(void)pci_read_config_dword(0,
|
|
||||||
ucSlotNumber,
|
|
||||||
ucFnNumber,
|
|
||||||
PCI_CLASS_REVISION,
|
|
||||||
&ulClass);
|
|
||||||
ulClass >>= 16;
|
ulClass >>= 16;
|
||||||
if (ulClass == PCI_CLASS_BRIDGE_PCI) {
|
if (ulClass == PCI_CLASS_BRIDGE_PCI) {
|
||||||
/*
|
/* We have found a PCI-PCI bridge */
|
||||||
* We have found a PCI-PCI bridge
|
pci_read_config_byte(0, ucSlotNumber, ucFnNumber,
|
||||||
*/
|
PCI_SUBORDINATE_BUS, &ucMaxSubordinate);
|
||||||
(void)pci_read_config_byte(0,
|
if (ucMaxSubordinate>ucMaxPCIBus) {
|
||||||
ucSlotNumber,
|
ucMaxPCIBus=ucMaxSubordinate;
|
||||||
ucFnNumber,
|
}
|
||||||
PCI_SUBORDINATE_BUS,
|
}
|
||||||
&ucMaxSubordinate);
|
}
|
||||||
if(ucMaxSubordinate>ucMaxPCIBus) {
|
}
|
||||||
ucMaxPCIBus=ucMaxSubordinate;
|
return PCIB_ERR_SUCCESS;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -601,5 +610,5 @@ void pci_initialize()
|
|||||||
*/
|
*/
|
||||||
unsigned char BusCountPCI()
|
unsigned char BusCountPCI()
|
||||||
{
|
{
|
||||||
return(ucMaxPCIBus+1);
|
return (ucMaxPCIBus+1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,14 +32,4 @@ struct _int_map
|
|||||||
|
|
||||||
void FixupPCI( const struct _int_map *, int (*swizzler)(int,int) );
|
void FixupPCI( const struct _int_map *, int (*swizzler)(int,int) );
|
||||||
|
|
||||||
/* scan for a specific device */
|
|
||||||
/* find a particular PCI device
|
|
||||||
* (currently, only bus0 is scanned for device/fun0)
|
|
||||||
*
|
|
||||||
* RETURNS: zero on success, bus/dev/fun in *pbus / *pdev / *pfun
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
BSP_pciFindDevice(unsigned short vendorid, unsigned short deviceid,
|
|
||||||
int instance, int *pbus, int *pdev, int *pfun);
|
|
||||||
|
|
||||||
#endif /* BSP_POWERPC_PCI_H */
|
#endif /* BSP_POWERPC_PCI_H */
|
||||||
|
|||||||
@@ -7,51 +7,54 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
|
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
|
||||||
#define PCI_MULTI_FUNCTION 0x80
|
#define PCI_MULTI_FUNCTION 0x80
|
||||||
|
|
||||||
#include <bsp/pci.h>
|
#include <bsp/pci.h>
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
pci_find_by_devid( unsigned short vendorid, unsigned short deviceid,
|
pci_find_device(
|
||||||
int instance, int *pbus, int *pdev, int *pfun )
|
unsigned short vendorid,
|
||||||
{
|
unsigned short deviceid,
|
||||||
|
int instance,
|
||||||
|
int *pbus,
|
||||||
|
int *pdev,
|
||||||
|
int *pfun
|
||||||
|
) {
|
||||||
unsigned int d;
|
unsigned int d;
|
||||||
unsigned short s;
|
unsigned short s;
|
||||||
unsigned char bus,dev,fun,hd;
|
unsigned char bus,dev,fun,hd;
|
||||||
|
|
||||||
for (bus=0; bus<BusCountPCI(); bus++) {
|
for (bus=0; bus<BusCountPCI(); bus++) {
|
||||||
for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
|
for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
|
||||||
|
|
||||||
pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
|
pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
|
||||||
hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
|
hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
|
||||||
|
|
||||||
for (fun=0; fun<hd; fun++) {
|
for (fun=0; fun<hd; fun++) {
|
||||||
/*
|
/*
|
||||||
* The last devfn id/slot is special; must skip it
|
* The last devfn id/slot is special; must skip it
|
||||||
*/
|
*/
|
||||||
if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
|
if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
|
||||||
break;
|
break;
|
||||||
(void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
|
(void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
|
||||||
if (PCI_INVALID_VENDORDEVICEID == d)
|
if (PCI_INVALID_VENDORDEVICEID == d)
|
||||||
continue;
|
continue;
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
printk("pci_find_by_devid: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
|
printk("pci_find_by_devid: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
|
||||||
#endif
|
#endif
|
||||||
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
|
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
|
||||||
if (vendorid != s)
|
if (vendorid != s)
|
||||||
continue;
|
continue;
|
||||||
(void) pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
|
(void) pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
|
||||||
if (deviceid == s) {
|
if (deviceid == s) {
|
||||||
if (instance--) continue;
|
if (instance--) continue;
|
||||||
*pbus=bus; *pdev=dev; *pfun=fun;
|
*pbus=bus; *pdev=dev; *pfun=fun;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eof */
|
|
||||||
|
|||||||
Reference in New Issue
Block a user