diff options
author | Yu Zhao <yu.zhao@intel.com> | 2009-03-19 23:25:14 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-20 13:48:25 -0400 |
commit | 480b93b7837fb3cf0579a42f4953ac463a5b9e1e (patch) | |
tree | 39206460a790570d293dc04a64ab3fd3fff736ef | |
parent | a28724b0fb909d247229a70761c90bb37b13366a (diff) |
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>
-rw-r--r-- | drivers/pci/pci.h | 1 | ||||
-rw-r--r-- | drivers/pci/probe.c | 78 |
2 files changed, 41 insertions, 38 deletions
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 5c29cb2b8e63..f4fc10fc5872 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -178,6 +178,7 @@ enum pci_bar_type { | |||
178 | pci_bar_mem64, /* A 64-bit memory BAR */ | 178 | pci_bar_mem64, /* A 64-bit memory BAR */ |
179 | }; | 179 | }; |
180 | 180 | ||
181 | extern int pci_setup_device(struct pci_dev *dev); | ||
181 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 182 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
182 | struct resource *res, unsigned int reg); | 183 | struct resource *res, unsigned int reg); |
183 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 184 | extern int pci_resource_bar(struct pci_dev *dev, int resno, |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0ecdaea3915f..943c49a7842c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -674,6 +674,19 @@ static void pci_read_irq(struct pci_dev *dev) | |||
674 | dev->irq = irq; | 674 | dev->irq = irq; |
675 | } | 675 | } |
676 | 676 | ||
677 | static void set_pcie_port_type(struct pci_dev *pdev) | ||
678 | { | ||
679 | int pos; | ||
680 | u16 reg16; | ||
681 | |||
682 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
683 | if (!pos) | ||
684 | return; | ||
685 | pdev->is_pcie = 1; | ||
686 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | ||
687 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | ||
688 | } | ||
689 | |||
677 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 690 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
678 | 691 | ||
679 | /** | 692 | /** |
@@ -683,12 +696,34 @@ static void pci_read_irq(struct pci_dev *dev) | |||
683 | * Initialize the device structure with information about the device's | 696 | * Initialize the device structure with information about the device's |
684 | * vendor,class,memory and IO-space addresses,IRQ lines etc. | 697 | * vendor,class,memory and IO-space addresses,IRQ lines etc. |
685 | * Called at initialisation of the PCI subsystem and by CardBus services. | 698 | * Called at initialisation of the PCI subsystem and by CardBus services. |
686 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge | 699 | * Returns 0 on success and negative if unknown type of device (not normal, |
687 | * or CardBus). | 700 | * bridge or CardBus). |
688 | */ | 701 | */ |
689 | static int pci_setup_device(struct pci_dev * dev) | 702 | int pci_setup_device(struct pci_dev *dev) |
690 | { | 703 | { |
691 | u32 class; | 704 | u32 class; |
705 | u8 hdr_type; | ||
706 | struct pci_slot *slot; | ||
707 | |||
708 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | ||
709 | return -EIO; | ||
710 | |||
711 | dev->sysdata = dev->bus->sysdata; | ||
712 | dev->dev.parent = dev->bus->bridge; | ||
713 | dev->dev.bus = &pci_bus_type; | ||
714 | dev->hdr_type = hdr_type & 0x7f; | ||
715 | dev->multifunction = !!(hdr_type & 0x80); | ||
716 | dev->cfg_size = pci_cfg_space_size(dev); | ||
717 | dev->error_state = pci_channel_io_normal; | ||
718 | set_pcie_port_type(dev); | ||
719 | |||
720 | list_for_each_entry(slot, &dev->bus->slots, list) | ||
721 | if (PCI_SLOT(dev->devfn) == slot->number) | ||
722 | dev->slot = slot; | ||
723 | |||
724 | /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) | ||
725 | set this higher, assuming the system even supports it. */ | ||
726 | dev->dma_mask = 0xffffffff; | ||
692 | 727 | ||
693 | dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), | 728 | dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), |
694 | dev->bus->number, PCI_SLOT(dev->devfn), | 729 | dev->bus->number, PCI_SLOT(dev->devfn), |
@@ -708,7 +743,6 @@ static int pci_setup_device(struct pci_dev * dev) | |||
708 | 743 | ||
709 | /* Early fixups, before probing the BARs */ | 744 | /* Early fixups, before probing the BARs */ |
710 | pci_fixup_device(pci_fixup_early, dev); | 745 | pci_fixup_device(pci_fixup_early, dev); |
711 | class = dev->class >> 8; | ||
712 | 746 | ||
713 | switch (dev->hdr_type) { /* header type */ | 747 | switch (dev->hdr_type) { /* header type */ |
714 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ | 748 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |
@@ -770,7 +804,7 @@ static int pci_setup_device(struct pci_dev * dev) | |||
770 | default: /* unknown header */ | 804 | default: /* unknown header */ |
771 | dev_err(&dev->dev, "unknown header type %02x, " | 805 | dev_err(&dev->dev, "unknown header type %02x, " |
772 | "ignoring device\n", dev->hdr_type); | 806 | "ignoring device\n", dev->hdr_type); |
773 | return -1; | 807 | return -EIO; |
774 | 808 | ||
775 | bad: | 809 | bad: |
776 | dev_err(&dev->dev, "ignoring class %02x (doesn't match header " | 810 | dev_err(&dev->dev, "ignoring class %02x (doesn't match header " |
@@ -804,19 +838,6 @@ static void pci_release_dev(struct device *dev) | |||
804 | kfree(pci_dev); | 838 | kfree(pci_dev); |
805 | } | 839 | } |
806 | 840 | ||
807 | static void set_pcie_port_type(struct pci_dev *pdev) | ||
808 | { | ||
809 | int pos; | ||
810 | u16 reg16; | ||
811 | |||
812 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
813 | if (!pos) | ||
814 | return; | ||
815 | pdev->is_pcie = 1; | ||
816 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | ||
817 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | ||
818 | } | ||
819 | |||
820 | /** | 841 | /** |
821 | * pci_cfg_space_size - get the configuration space size of the PCI device. | 842 | * pci_cfg_space_size - get the configuration space size of the PCI device. |
822 | * @dev: PCI device | 843 | * @dev: PCI device |
@@ -897,9 +918,7 @@ EXPORT_SYMBOL(alloc_pci_dev); | |||
897 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | 918 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) |
898 | { | 919 | { |
899 | struct pci_dev *dev; | 920 | struct pci_dev *dev; |
900 | struct pci_slot *slot; | ||
901 | u32 l; | 921 | u32 l; |
902 | u8 hdr_type; | ||
903 | int delay = 1; | 922 | int delay = 1; |
904 | 923 | ||
905 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) | 924 | 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) | |||
926 | } | 945 | } |
927 | } | 946 | } |
928 | 947 | ||
929 | if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) | ||
930 | return NULL; | ||
931 | |||
932 | dev = alloc_pci_dev(); | 948 | dev = alloc_pci_dev(); |
933 | if (!dev) | 949 | if (!dev) |
934 | return NULL; | 950 | return NULL; |
935 | 951 | ||
936 | dev->bus = bus; | 952 | dev->bus = bus; |
937 | dev->sysdata = bus->sysdata; | ||
938 | dev->dev.parent = bus->bridge; | ||
939 | dev->dev.bus = &pci_bus_type; | ||
940 | dev->devfn = devfn; | 953 | dev->devfn = devfn; |
941 | dev->hdr_type = hdr_type & 0x7f; | ||
942 | dev->multifunction = !!(hdr_type & 0x80); | ||
943 | dev->vendor = l & 0xffff; | 954 | dev->vendor = l & 0xffff; |
944 | dev->device = (l >> 16) & 0xffff; | 955 | dev->device = (l >> 16) & 0xffff; |
945 | dev->error_state = pci_channel_io_normal; | ||
946 | set_pcie_port_type(dev); | ||
947 | |||
948 | list_for_each_entry(slot, &bus->slots, list) | ||
949 | if (PCI_SLOT(devfn) == slot->number) | ||
950 | dev->slot = slot; | ||
951 | 956 | ||
952 | /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) | 957 | if (pci_setup_device(dev)) { |
953 | set this higher, assuming the system even supports it. */ | ||
954 | dev->dma_mask = 0xffffffff; | ||
955 | if (pci_setup_device(dev) < 0) { | ||
956 | kfree(dev); | 958 | kfree(dev); |
957 | return NULL; | 959 | return NULL; |
958 | } | 960 | } |