struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
int bus, struct pci_ops *ops, void *sysdata)
{
struct pci_bus *b;
b = pci_create_bus(parent, bus, ops, sysdata);
if (b)
b->subordinate = pci_scan_child_bus(b);
return b;
}
在pci_create_bus()中,为对应总线号构建pci_bus,然后将其挂入到pci_root_buses链表.该函数代码比较简
单,请自行分析.然后,调用然后pci_scan_child_bus枚举该总线下的所有设备.pci_bus->subordinate表示下流
总线的最大总线号.pci_sacn_child_bus()代码如下:
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
{
unsigned int devfn, pass, max = bus->secondary;
struct pci_dev *dev;
pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
/* Go find them, Rover! */
//按功能号扫描设备号对应的pci 设备
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
/*
* After performing arch-dependent fixup of the bus, look behind
* all PCI-to-PCI bridges on this bus.
*/
pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
pcibios_fixup_bus(bus);
for (pass=0; pass < 2; pass++)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
max = pci_scan_bridge(bus, dev, max, pass);
}
/*
* We've scanned the bus and so we know all about what's on
* the other side of any bridges that may be on this bus plus
* any devices.
*
* Return how far we've got finding sub-buses.
*/
pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n",
pci_domain_nr(bus), bus->number, max);
return max;
}
这节的难点就是在这个地方了,从我们之前分析的pci设备配置空间的读写方式可得知.对特定总线.下面最多个32个设备号.每个设备号又对应8
个功能号.我们可以将设备号和功能号放到一起,即占8~15位.在这面的代码中.对每个设备号调用pci_scan_slot()去扫描它下面的8个功能
号对应的设备.总而言之,把该总线下面的所有设备都要枚举完.
pci_scan_slot()代码如下:
nt pci_scan_slot(struct pci_bus *bus, int devfn)
{
int func, nr = 0;
int scan_all_fns;
scan_all_fns = pcibios_scan_all_fns(bus, devfn);
for (func = 0; func < 8; func++, devfn++) {
struct pci_dev *dev;
dev = pci_scan_single_device(bus, devfn);
if (dev) {
nr++;
/*
* If this is a single function device,
* don't scan past the first function.
*/
if (!dev->multifunction) {
if (func > 0) {
dev->multifunction = 1;
} else {
break;
}
}
} else {
if (func == 0 && !scan_all_fns)
break;
}
}
return nr;
}
对其它的每个设备都会调用pci_scan_single_device().如果是单功能设备(dev->multifunction == 0).则只要判断它的第一个功能号可以了,不需要判断之后功能号对应的设备.
Pci_scan_single_device()代码如下:
struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
dev = pci_scan_device(bus, devfn);
if (!dev)
return NULL;
//将pci_dev加至pci_bus->devices
pci_device_add(dev, bus);
return dev;
}
对每个设备,都会调用pci_scan_device()执行扫描的过程,如果该设备存在,就会将该设备加入到所属总线的devices链表
上.这是在pci_device_add()函数中完成的,这个函数比较简单.这里不做详细分析.我们把注意力集中到
pci_scan_device(),这函数有点长,分段分析如下:
static struct pci_dev * __devinit
pci_scan_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
u32 l;
u8 hdr_type;
int delay = 1;
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
return NULL;
/* some broken boards return 0 or ~0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000 ||
l == 0x0000ffff || l == 0xffff0000)
return NULL;
/* Configuration request Retry Status */
while (l == 0xffff0001) {
msleep(delay);
delay *= 2;
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
return NULL;
/* Card hasn't responded in 60 seconds? Must be stuck. */
if (delay > 60 * 1000) {
printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
"responding\n", pci_domain_nr(bus),
bus->number, PCI_SLOT(devfn),
PCI_FUNC(devfn));
return NULL;
}
}
从配置空间中读取该设备对应的vendor id和device id.如果读出来的值,有一个是空的,则说明该功能号对应的设备不存在,或者是配置非法.
如果读出来的是0xffff0001.则需要重新读一次,如果重读次数过多,也会退出
if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
return NULL;
dev = alloc_pci_dev();
if (!dev)
return NULL;
dev->bus = bus;
dev->sysdata = bus->sysdata;
dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type;
dev->devfn = devfn;
dev->hdr_type = hdr_type & 0x7f;
dev->multifunction = !!(hdr_type & 0x80);
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
dev->cfg_size = pci_cfg_space_size(dev);
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
dev->dma_mask = 0xffffffff;
接着,将不同类型设备的共同头部配置读出来,然后赋值给pci_dev的相应成员.这里有个特别要值得注意的地方:
dev->dev.bus =
&pci_bus_type.即将pci_dev里面封装的device结构的bus设置为了pci_bus_type.这个是很核心的一个步
骤.我们先将它放到这里,之后的再来详细分析
特别的, HEADER_TYPE的最高位为0,表示该设备是一个单功能设备
if (pci_setup_device(dev) < 0) {
kfree(dev);
return NULL;
}
return dev;
}
最后,流程就会转入到pci_setup_deivce()对特定类型的设备配置都行读取操作了.代码如下:
static int pci_setup_device(struct pci_dev * dev)
{
u32 class;
sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
dev->revision = class & 0xff;
class >>= 8; /* upper 3 bytes */
dev->class = class;
class >>= 8;
pr_debug("PCI: Found %s [%04x/%04x] %06x %02x\n", pci_name(dev),
dev->vendor, dev->device, class, dev->hdr_type);
/* "Unknown power state" */
dev->current_state = PCI_UNKNOWN;
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
class = dev->class >> 8;
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
goto bad;
pci_read_irq(dev);
pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
/*
* Do the ugly legacy mode stuff here rather than broken chip
* quirk code. Legacy mode ATA controllers have fixed
* addresses. These are not always echoed in BAR0-3, and
* BAR0-3 in a few cases contain junk!
*/
if (class == PCI_CLASS_STORAGE_IDE) {
u8 progif;
pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
if ((progif & 1) == 0) {
dev->resource[0].start = 0x1F0;
dev->resource[0].end = 0x1F7;
dev->resource[0].flags = LEGACY_IO_RESOURCE;
dev->resource[1].start = 0x3F6;
dev->resource[1].end = 0x3F6;
dev->resource[1].flags = LEGACY_IO_RESOURCE;
}
if ((progif & 4) == 0) {
dev->resource[2].start = 0x170;
dev->resource[2].end = 0x177;
dev->resource[2].flags = LEGACY_IO_RESOURCE;
dev->resource[3].start = 0x376;
dev->resource[3].end = 0x376;
dev->resource[3].flags = LEGACY_IO_RESOURCE;
}
}
break;
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
/* The PCI-to-PCI bridge spec requires that subtractive
decoding (i.e. transparent) bridge must have programming
interface code of 0x01. */
pci_read_irq(dev);
dev->transparent = ((dev->class & 0xff) == 1);
pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
break;
case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
if (class != PCI_CLASS_BRIDGE_CARDBUS)
goto bad;
pci_read_irq(dev);
pci_read_bases(dev, 1, 0);
pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
break;
default: /* unknown header */
printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
pci_name(dev), dev->hdr_type);
return -1;
bad:
printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
pci_name(dev), class, dev->hdr_type);
dev->class = PCI_CLASS_NOT_DEFINED;
}
/* We found a fine healthy device, go go go... */
return 0;
}
总共有三种类型的设备,分别为常规设备(PCI_HEADER_TYPE_NORMAL)
,pci-pci桥设备(PCI_HEADER_TYPE_BRIDGE),笔记本电脑上使用的
cardbus(PCI_HEADER_TYPE_CARDBUS).这里的操作不外乎是IRQ的确定,设备存储区间映射等.先将这几个操作分析如下:
1: IRQ号的确定
该操作接口为pci_read_irq():
static void pci_read_irq(struct pci_dev *dev)
{
unsigned char irq;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
dev->pin = irq;
if (irq)
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
dev->irq = irq;
}
在PCI_INTERRUPT_PIN中存放的是将INTA~INTD的哪一个引脚连接到了中断控制器,如果该值为零.说明并末将引脚连接至中断控制器.自然也就不能产生中断信号.
其实,在PCI_INTERRUPT_LINE存放的是该设备的中断线连接在中断控制器的哪一个IRQ线上.也就是对应设备的IRQ.
注意这里的寄存器只读有意义,并不是更改寄存器的值就更改该设备的IRQ
2:内部存储区间的确定
从之前的pci设备配置寄存器图中可以看到.有从0x10~0x27的6个base address寄存器.里面存放的就是内部存储器的地起地址和长度,及其类型.
首先将对应寄存器的值取出.如果最低位为1.则说明该区域是I/O端口,高29位是端口地址的高29位,低3位为零.否则是存储映射区间.前28位是存储区的高28位,低四位为零.
然后,将该寄存器全部置1.再读,取得的是长度信息. 如果是I/O端口,屏弊其低三位,如果是存储区间,屏弊其低四位.最后取第1个位为1对应的大小,即为相应区间的长度.
例如,取出来的值是0xC107.假设是I/O端口
屏蔽掉低三位,为0xC100.第一个为1的值对应的值为0x0100.即0x100
另上,ROM的操作也跟此类似.
在上面的代码中,内部存储区间的确定是由pci_read_bases()完成的.这个函数代码比较长.涉及到的东西又不多,因此不做详细分析.结构上面的分析,应该很容易看懂代码了.
从上面的代码可以看出,对于常规设备,有6个存储区间和一个ROM。Pci briage只有2个存储区间和一个ROM。Cardbus只有一个存储区间没有ROM。
好了,再这里,每一类设备的信息都已经完全读取出来了,并存放在pci_dev的相关字段。此后在驱动中就可以直接找到pci_dev.取得相应的信息,而不需要再次去枚举了.
再这里,万里长征只是迈出了一小步。我们知道,pci总线可以通过pci bridge再连一层pci总线。这个问题显然是一个递归过程。我们接下来看pci桥的处理。
返回到pci_scan_child_bus()中。我们将下面要分析的代码列出来:
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
{
……
……
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
pcibios_fixup_bus(bus);
for (pass=0; pass < 2; pass++)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
max = pci_scan_bridge(bus, dev, max, pass);
}
……
}
Pcibios_fixup_bus()这个函数看名字是用来修正总线的。芯片厂商在发布产品后,又检测到上次发布的产品有问题。回厂升级是不
可能的了。只能提供软件修改的手段,发布一些修正包。Linux将很多厂商的修改正集合在一起。这也就是pcibios_fixup_bus()要进行的
操作。具体设备的修正功能,我们就不再研究了。这个函数里还有一个重要的操作。列出代码如下:
void __devinit pcibios_fixup_bus(struct pci_bus *b)
{
struct pci_dev *dev;
pcibios_fixup_ghosts(b);
pci_read_bridge_bases(b);
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
}
我们所在讨论的重要的操作就是在pci_read_bridge_bases()中完成的。除了之上分析的配置字段外,其实pci桥还有一个很重要的配置项。即:过滤窗口。
过滤窗口决定了访问的方向。例如:如果cpu一侧要经过pci bridge访问pci总线,则它的地址必须要落在这个pci桥的过滤窗口内才可以通过。另外,pci bridge下游的pci bus要访问cpu侧。则地址必须要落在过滤窗口外才可以。
此外,pci bridge还提供了一个命令寄存器来控制“memory access enable“和“I/O access
enable”两个位来控制两个功能。如果全为0.则两个方向都会关闭。在pci初始化前,为了防止对cpu侧造成干扰, 这两个功能都关闭的,
Pci bridge有三个这样的窗口,分别如下:
1:起始地址在PCI_IO_BASE中,长度在PCI_IO_LIMIT中。如果是32位,还要通过PCI_IO_BASE_UPPER16和PCI_IO_LIMIT_UPPER16提供高16位。
2:起始地址在PCI_MEMORY_BASE,长度在PCI_MEMORY_LIMIT中。这个是一个16位的窗口。
3:起始地址在PCI_PREF_MEMORY_BASE,长度在PCI_PREF_MEMORY_LIMIT.默认是32位。如果是64,则需要PCI_PREF_BASE_UPPER32和PCI_PREF_LIMIT_UPPER32提供高32位.
存储区间在这里看起来有点繁杂。以图的形式总结如下: