PCI: centralize device setup code

Move the device setup stuff into pci_setup_device() which will be used
to setup the Virtual Function later.

Reviewed-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
Yu Zhao 2009-03-20 11:25:14 +08:00 committed by Jesse Barnes
parent a28724b0fb
commit 480b93b783
2 changed files with 41 additions and 38 deletions

View file

@ -178,6 +178,7 @@ enum pci_bar_type {
pci_bar_mem64, /* A 64-bit memory BAR */ pci_bar_mem64, /* A 64-bit memory BAR */
}; };
extern int pci_setup_device(struct pci_dev *dev);
extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct resource *res, unsigned int reg); struct resource *res, unsigned int reg);
extern int pci_resource_bar(struct pci_dev *dev, int resno, extern int pci_resource_bar(struct pci_dev *dev, int resno,

View file

@ -674,6 +674,19 @@ static void pci_read_irq(struct pci_dev *dev)
dev->irq = irq; dev->irq = irq;
} }
static void set_pcie_port_type(struct pci_dev *pdev)
{
int pos;
u16 reg16;
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!pos)
return;
pdev->is_pcie = 1;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
}
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
/** /**
@ -683,12 +696,34 @@ static void pci_read_irq(struct pci_dev *dev)
* Initialize the device structure with information about the device's * Initialize the device structure with information about the device's
* vendor,class,memory and IO-space addresses,IRQ lines etc. * vendor,class,memory and IO-space addresses,IRQ lines etc.
* Called at initialisation of the PCI subsystem and by CardBus services. * Called at initialisation of the PCI subsystem and by CardBus services.
* Returns 0 on success and -1 if unknown type of device (not normal, bridge * Returns 0 on success and negative if unknown type of device (not normal,
* or CardBus). * bridge or CardBus).
*/ */
static int pci_setup_device(struct pci_dev * dev) int pci_setup_device(struct pci_dev *dev)
{ {
u32 class; u32 class;
u8 hdr_type;
struct pci_slot *slot;
if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
return -EIO;
dev->sysdata = dev->bus->sysdata;
dev->dev.parent = dev->bus->bridge;
dev->dev.bus = &pci_bus_type;
dev->hdr_type = hdr_type & 0x7f;
dev->multifunction = !!(hdr_type & 0x80);
dev->cfg_size = pci_cfg_space_size(dev);
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
list_for_each_entry(slot, &dev->bus->slots, list)
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = slot;
/* 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;
dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn), dev->bus->number, PCI_SLOT(dev->devfn),
@ -708,7 +743,6 @@ static int pci_setup_device(struct pci_dev * dev)
/* Early fixups, before probing the BARs */ /* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev); pci_fixup_device(pci_fixup_early, dev);
class = dev->class >> 8;
switch (dev->hdr_type) { /* header type */ switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */ case PCI_HEADER_TYPE_NORMAL: /* standard header */
@ -770,7 +804,7 @@ static int pci_setup_device(struct pci_dev * dev)
default: /* unknown header */ default: /* unknown header */
dev_err(&dev->dev, "unknown header type %02x, " dev_err(&dev->dev, "unknown header type %02x, "
"ignoring device\n", dev->hdr_type); "ignoring device\n", dev->hdr_type);
return -1; return -EIO;
bad: bad:
dev_err(&dev->dev, "ignoring class %02x (doesn't match header " dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
@ -804,19 +838,6 @@ static void pci_release_dev(struct device *dev)
kfree(pci_dev); kfree(pci_dev);
} }
static void set_pcie_port_type(struct pci_dev *pdev)
{
int pos;
u16 reg16;
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!pos)
return;
pdev->is_pcie = 1;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
}
/** /**
* pci_cfg_space_size - get the configuration space size of the PCI device. * pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device * @dev: PCI device
@ -897,9 +918,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{ {
struct pci_dev *dev; struct pci_dev *dev;
struct pci_slot *slot;
u32 l; u32 l;
u8 hdr_type;
int delay = 1; int delay = 1;
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
@ -926,33 +945,16 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
} }
} }
if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
return NULL;
dev = alloc_pci_dev(); dev = alloc_pci_dev();
if (!dev) if (!dev)
return NULL; return NULL;
dev->bus = bus; dev->bus = bus;
dev->sysdata = bus->sysdata;
dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type;
dev->devfn = devfn; dev->devfn = devfn;
dev->hdr_type = hdr_type & 0x7f;
dev->multifunction = !!(hdr_type & 0x80);
dev->vendor = l & 0xffff; dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff; dev->device = (l >> 16) & 0xffff;
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
list_for_each_entry(slot, &bus->slots, list) if (pci_setup_device(dev)) {
if (PCI_SLOT(devfn) == slot->number)
dev->slot = slot;
/* 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;
if (pci_setup_device(dev) < 0) {
kfree(dev); kfree(dev);
return NULL; return NULL;
} }