PCI, x86: Add for_each_res and addon resource support
Subsystems (5)
cover PCI, x86: Add for_each_res and addon resource support
Make device resource loop easier and readable. Also add addon_resource support about non-stanard resources.
The patches need to apply to pci/for-linus and pci/linux-next
[PATCH -v3] PCI: pci_host_bridge related cleanup
[PATCH -v11] PCI: allocate pci bus num range for unassigned bridge busn [PATCH -v3] PCI, x86: pci root bus hotplug support
could get from
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-for-each-res-addon
-v2: Split to small patches.
Thanks
Yinghai
Yinghai Lu (26):
PCI: Add pci_dev_resource_n()
PCI: Add for_each_resource helpers to make resource loop easier.
PCI: Add pci_dev_resource_idx()
PCI: Update pci_resource_start to use pci_dev_resource_n() x86, PCI: Use for_each_res with pci_allocate_bridge_resources x86, PCI: Use for_each_res with pci_allocate_dev_resources
PCI: Use for_each_res with IOV releated funcs
PCI, acpiphp: Use for_each_pci_dev_resource helper PCI, pciehp: Use for_each_pci_dev_resource helper
PCI: Use for_each_pci_dev_resource pci_enable_dev
PCI: Use for_each_pci_dev_resource pci_reassigndev
PCI: Use for_each_res with pci bar reassign funcs
PCI: Use for_each_res pci_assign_resource
PCI: Use for_each_res with noassign_bars
PCI: Use for_each_res pci bases pci_dev_driver()
PCI: Use for_each_res pci release release
PCI: Use for_each_res pci bases reading
PCI: Use for_each_res with mrs
PCI: Use for_each_res with xen pci
PCI: Add addon_resource support for pci_dev
PCI: Add helpers for add addon_resource
PCI: Update pci_resource_bar() to support addon_resource
PCI: Make assign/update resource to support addon_res
PCI: Make piix4 quirk to use addon_resource support
PCI: Make quirk_io_region to use addon_resource support
PCI: Use addon_fixed_resource with ati fixed resource
arch/x86/pci/common.c | 3 +- arch/x86/pci/i386.c | 57 +++----- arch/x86/pci/mrst.c | 7 +- drivers/pci/hotplug/acpiphp_glue.c | 4 +- drivers/pci/hotplug/pciehp_hpc.c | 5 +- drivers/pci/iov.c | 31 ++--- drivers/pci/pci-driver.c | 6 +- drivers/pci/pci.c | 28 +++-- drivers/pci/probe.c | 114 ++++++++++++++++- drivers/pci/quirks.c | 256 +++++++++++++++++++++--------------- drivers/pci/remove.c | 5 +- drivers/pci/setup-bus.c | 28 ++--- drivers/pci/setup-res.c | 38 ++++-- drivers/pci/xen-pcifront.c | 4 +- include/linux/pci.h | 79 +++++++++++- 15 files changed, 446 insertions(+), 219 deletions(-)
Signature · 1 line
1.7.7
PATCH 1/26 PCI: Add pci_dev_resource_n()
Prepare to use it with addon_resource and for_each_resource macro.
--- drivers/pci/probe.c | 10 ++++++++++ include/linux/pci.h | 2 ++ 2 files changed, 12 insertions(+), 0 deletions(-)
drivers/pci/probe.c +10 -0
@@ -75,6 +75,16 @@ static int __init pcibus_class_init(void) }postcore_initcall (pcibus_class_init); +struct resource *pci_dev_resource_n (struct pci_dev *dev,int n) +{ +struct pci_dev_addon_resource *addon_res; + +if (n <PCI_NUM_RESOURCES ) +return &dev->resource[n]; + +return NULL ; +} +static u64 pci_size (u64 base,u64 maxbase,u64 mask) {u64 size = mask & maxbase;/* Find the significant bits */
include/linux/pci.h +2 -0
@@ -347,6 +347,8 @@ struct pci_dev {#endif }; +struct resource *pci_dev_resource_n (struct pci_dev *dev,int n); +static inline struct pci_dev *pci_physfn (struct pci_dev *dev) {#ifdef CONFIG_PCI_IOV
Signature · 1 line
1.7.7
PATCH 2/26 PCI: Add for_each_resource helpers to make resource loop easier.
In reply to Yinghai Lu--- include/linux/pci.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-)
include/linux/pci.h +49 -0
@@ -349,6 +349,55 @@ struct pci_dev {struct resource *pci_dev_resource_n (struct pci_dev *dev,int n); +#define resno_is_for_bridge (n) \ + ((n) >= PCI_BRIDGE_RESOURCES && (n) <= PCI_BRIDGE_RESOURCE_END) + +/* all (include bridge) resources */ +#define for_each_pci_dev_all_resource (dev, res, i) \ + for (i = 0; \ + (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \ + i++) +/* exclude bridge resources */ +#define for_each_pci_dev_nobridge_resource (dev, res, i) \ + for (i = 0; \ + (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \ + i = (i != (PCI_BRIDGE_RESOURCES - 1)) ? (i+1) : PCI_NUM_RESOURCES) +/* exclude bridge and IOV resources */ +#define for_each_pci_dev_base_resource (dev, res, i) \ + for (i = 0; \ + (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \ + i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_NUM_RESOURCES) +/* exclude ROM and bridge and IOV resources */ +#define for_each_pci_dev_base_norom_resource (dev, res, i) \ + for (i = 0; \ + (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \ + i = (i != (PCI_ROM_RESOURCE-1)) ? (i+1) : PCI_NUM_RESOURCES) +/* exclude IOV resources */ +#define for_each_pci_dev_noiov_resource (dev, res, i) \ + for (i = 0; \ + (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \ + i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_BRIDGE_RESOURCES) +/* only std resources */ +#define for_each_pci_dev_std_resource (dev, res, i) \ + for (i = PCI_STD_RESOURCES; \ + (res = pci_dev_resource_n(dev, i)) && i < (PCI_STD_RESOURCE_END+1); \ + i++) +/* only IOV resources */ +#define for_each_pci_dev_iov_resource (dev, res, i) \ + for (i = PCI_IOV_RESOURCES; \ + (res = pci_dev_resource_n(dev, i)) && i < (PCI_IOV_RESOURCE_END+1); \ + i++) +/* only bridge resources */ +#define for_each_pci_dev_bridge_resource (dev, res, i) \ + for (i = PCI_BRIDGE_RESOURCES; \ + (res = pci_dev_resource_n(dev, i)) && i < (PCI_BRIDGE_RESOURCE_END+1); \ + i++) +/* only addon resources */ +#define for_each_pci_dev_addon_resource (dev, res, i) \ + for (i = PCI_NUM_RESOURCES; \ + (res = pci_dev_resource_n(dev, i)); \ + i++) +static inline struct pci_dev *pci_physfn (struct pci_dev *dev) {#ifdef CONFIG_PCI_IOV
Signature · 1 line
1.7.7
PATCH 3/26 PCI: Add pci_dev_resource_idx()
In reply to Yinghai Lu--- drivers/pci/probe.c | 12 ++++++++++++ include/linux/pci.h | 1 + 2 files changed, 13 insertions(+), 0 deletions(-)
drivers/pci/probe.c +12 -0
@@ -85,6 +85,18 @@ struct resource *pci_dev_resource_n(struct pci_dev *dev, int n)return NULL ; } +int pci_dev_resource_idx (struct pci_dev *dev,struct resource *res) +{ +int i; +struct resource *r; + +for_each_pci_dev_all_resource (dev, r, i) +if (r == res) +return i; + +return -1 ; +} +static u64 pci_size (u64 base,u64 maxbase,u64 mask) {u64 size = mask & maxbase;/* Find the significant bits */
include/linux/pci.h +1 -0
@@ -348,6 +348,7 @@ struct pci_dev { };struct resource *pci_dev_resource_n (struct pci_dev *dev,int n); +int pci_dev_resource_idx (struct pci_dev *dev,struct resource *res);#define resno_is_for_bridge (n) \ ((n) >= PCI_BRIDGE_RESOURCES && (n) <= PCI_BRIDGE_RESOURCE_END)
Signature · 1 line
1.7.7
PATCH 4/26 PCI: Update pci_resource_start to use pci_dev_resource_n()
In reply to Yinghai Luinstead of use resource[bar], to prepare for addon resource usages.
--- include/linux/pci.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
include/linux/pci.h +3 -3
@@ -1400,9 +1400,9 @@ static inline int pci_domain_nr(struct pci_bus *bus)/* these helpers provide future and backwards compatibility * for accessing popular PCI BAR info */ -#define pci_resource_start (dev, bar) ((dev)->resource[(bar)].start) -#define pci_resource_end (dev, bar) ((dev)->resource[(bar)].end) -#define pci_resource_flags (dev, bar) ((dev)->resource[(bar)].flags) +#define pci_resource_start (dev, bar) (pci_dev_resource_n(dev, (bar))->start) +#define pci_resource_end (dev, bar) (pci_dev_resource_n(dev, (bar))->end) +#define pci_resource_flags (dev, bar) (pci_dev_resource_n(dev, (bar))->flags)#define pci_resource_len (dev,bar) \ ((pci_resource_start((dev), (bar)) == 0 && \ pci_resource_end((dev), (bar)) == \
Signature · 1 line
1.7.7
PATCH 5/26 x86, PCI: Use for_each_res with pci_allocate_bridge_resources
In reply to Yinghai Lu--- arch/x86/pci/i386.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/pci/i386.c +1 -1
@@ -198,7 +198,7 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)int idx;struct resource *r; -for (idx =PCI_BRIDGE_RESOURCES ; idx <PCI_NUM_RESOURCES ; idx++) { +for_each_pci_dev_bridge_resource (dev, r, idx) { r = &dev->resource[idx];if (r->parent)/* Already allocated */ continue ;
Signature · 1 line
1.7.7
PATCH 6/26 x86, PCI: Use for_each_res with pci_allocate_dev_resources
In reply to Yinghai Lu--- arch/x86/pci/i386.c | 55 ++++++++++++++++++-------------------------------- 1 files changed, 20 insertions(+), 35 deletions(-)
arch/x86/pci/i386.c +20 -35
@@ -228,49 +228,34 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)pcibios_allocate_bus_resources (child); } -struct pci_check_idx_range { -int start; -int end; -}; -static void pcibios_allocate_dev_resources (struct pci_dev *dev,int pass) { -int idx, disabled, i; +int idx, disabled;u16 command;struct resource *r; -struct pci_check_idx_range idx_range[] = { - {PCI_STD_RESOURCES ,PCI_STD_RESOURCE_END }, -#ifdef CONFIG_PCI_IOV - {PCI_IOV_RESOURCES ,PCI_IOV_RESOURCE_END }, -#endif - }; -pci_read_config_word (dev,PCI_COMMAND , &command); -for (i =0 ; i <ARRAY_SIZE (idx_range); i++) -for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) { - r = &dev->resource[idx]; -if (r->parent)/* Already allocated */ -continue ; -if (!r->start)/* Address not assigned at all */ -continue ; -if (r->flags &IORESOURCE_IO ) - disabled = !(command &PCI_COMMAND_IO ); -else - disabled = !(command &PCI_COMMAND_MEMORY ); -if (pass == disabled) { -dev_dbg (&dev->dev, -"BAR %d: reserving %pr (d=%d, p=%d)\n" , - idx, r, disabled, pass); -if (pci_claim_resource (dev, idx) <0 ) { -/* We'll assign a new address later */ -pcibios_save_fw_addr (dev, - idx, r->start); - r->end -= r->start; - r->start =0 ; - } +for_each_pci_dev_base_norom_resource (dev, r, idx) { +if (r->parent)/* Already allocated */ +continue ; +if (!r->start)/* Address not assigned at all */ +continue ; +if (r->flags &IORESOURCE_IO ) + disabled = !(command &PCI_COMMAND_IO ); +else + disabled = !(command &PCI_COMMAND_MEMORY ); +if (pass == disabled) { +dev_dbg (&dev->dev, +"BAR %d: reserving %pr (d=%d, p=%d)\n" , + idx, r, disabled, pass); +if (pci_claim_resource (dev, idx) <0 ) { +/* We'll assign a new address later */ +pcibios_save_fw_addr (dev, idx, r->start); + r->end -= r->start; + r->start =0 ; } } + }if (!pass) { r = &dev->resource[PCI_ROM_RESOURCE ];if (r->flags &IORESOURCE_ROM_ENABLE ) {
Signature · 1 line
1.7.7
PATCH 7/26 PCI: Use for_each_res with IOV releated funcs
In reply to Yinghai Lu--- drivers/pci/iov.c | 31 +++++++++++++++---------------- 1 files changed, 15 insertions(+), 16 deletions(-)
drivers/pci/iov.c +15 -16
@@ -99,17 +99,20 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)pci_setup_device (virtfn); virtfn->dev.parent = dev->dev.parent; -for (i =0 ; i <PCI_SRIOV_NUM_BARS ; i++) { - res = dev->resource +PCI_IOV_RESOURCES + i; +for_each_pci_dev_iov_resource (dev, res, i) { +struct resource *virtfn_res; +if (!res->parent)continue ; - virtfn->resource[i].name =pci_name (virtfn); - virtfn->resource[i].flags = res->flags; + + virtfn_res =pci_dev_resource_n (virtfn, i -PCI_IOV_RESOURCES ); + virtfn_res->name =pci_name (virtfn); + virtfn_res->flags = res->flags; size =resource_size (res);do_div (size, iov->total); - virtfn->resource[i].start = res->start + size * id; - virtfn->resource[i].end = virtfn->resource[i].start + size -1 ; - rc =request_resource (res, &virtfn->resource[i]); + virtfn_res->start = res->start + size * id; + virtfn_res->end = virtfn_res->start + size -1 ; + rc =request_resource (res, virtfn_res);BUG_ON (rc); }
@@ -313,9 +316,8 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)return -EIO ; nres =0 ; -for (i =0 ; i <PCI_SRIOV_NUM_BARS ; i++) { - bars |= (1 << (i +PCI_IOV_RESOURCES )); - res = dev->resource +PCI_IOV_RESOURCES + i; +for_each_pci_dev_iov_resource (dev, res, i) { + bars |=1 << i;if (res->parent) nres++; }
@@ -473,10 +475,9 @@ found:pci_write_config_dword (dev, pos +PCI_SRIOV_SYS_PGSIZE , pgsz); nres =0 ; -for (i =0 ; i <PCI_SRIOV_NUM_BARS ; i++) { - res = dev->resource +PCI_IOV_RESOURCES + i; +for_each_pci_dev_iov_resource (dev, res, i) { i +=__pci_read_base (dev, pci_bar_unknown, res, - pos +PCI_SRIOV_BAR + i *4 ); + pos +PCI_SRIOV_BAR + (i -PCI_IOV_RESOURCES ) *4 );if (!res->flags)continue ;if (resource_size (res) & (PAGE_SIZE -1 )) {
@@ -519,10 +520,8 @@ found:return 0 ; failed: -for (i =0 ; i <PCI_SRIOV_NUM_BARS ; i++) { - res = dev->resource +PCI_IOV_RESOURCES + i; +for_each_pci_dev_iov_resource (dev, res, i) res->flags =0 ; - }return rc; }
Signature · 1 line
1.7.7
PATCH 8/26 PCI, acpiphp: Use for_each_pci_dev_resource helper
In reply to Yinghai Lu--- drivers/pci/hotplug/acpiphp_glue.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/pci/hotplug/acpiphp_glue.c +2 -2
@@ -1025,10 +1025,10 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)struct pci_dev *dev;int i;unsigned long type_mask =IORESOURCE_IO |IORESOURCE_MEM ; +struct resource *res;list_for_each_entry (dev, &bus->devices, bus_list) { -for (i=0 ; i<PCI_BRIDGE_RESOURCES ; i++) { -struct resource *res = &dev->resource[i]; +for_each_pci_dev_nobridge_resource (dev, res, i) {if ((res->flags & type_mask) && !res->start && res->end) {/* Could not assign a required resources
Signature · 1 line
1.7.7
PATCH 9/26 PCI, pciehp: Use for_each_pci_dev_resource helper
In reply to Yinghai Lu--- drivers/pci/hotplug/pciehp_hpc.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/pci/hotplug/pciehp_hpc.c +3 -2
@@ -899,6 +899,7 @@ static inline void dbg_ctrl(struct controller *ctrl)int i;u16 reg16;struct pci_dev *pdev = ctrl->pcie->port; +struct resource *res;if (!pciehp_debug)return ;
@@ -914,11 +915,11 @@ static inline void dbg_ctrl(struct controller *ctrl) pdev->subsystem_vendor);ctrl_info (ctrl," PCIe Cap offset : 0x%02x\n" ,pci_pcie_cap (pdev)); -for (i =0 ; i <DEVICE_COUNT_RESOURCE ; i++) { +for_each_pci_dev_all_resource (pdev, res, i) {if (!pci_resource_len (pdev, i))continue ;ctrl_info (ctrl," PCI resource [%d] : %pR\n" , - i, &pdev->resource[i]); + i, res); }ctrl_info (ctrl,"Slot Capabilities : 0x%08x\n" , ctrl->slot_cap);ctrl_info (ctrl," Physical Slot Number : %d\n" ,PSN (ctrl));
Signature · 1 line
1.7.7
PATCH 10/26 PCI: Use for_each_pci_dev_resource pci_enable_dev
In reply to Yinghai Lu--- drivers/pci/pci.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-)
drivers/pci/pci.c +8 -7
@@ -486,8 +486,9 @@ static void pci_restore_bars(struct pci_dev *dev) {int i; +struct resource *res; -for (i =0 ; i <PCI_BRIDGE_RESOURCES ; i++) +for_each_pci_dev_nobridge_resource (dev, res, i)pci_update_resource (dev, i); }
@@ -1141,6 +1142,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, {int err;int i, bars =0 ; +struct resource *res;/* * Power state could be unknown at this point, either due to a fresh
@@ -1158,12 +1160,11 @@ static int __pci_enable_device_flags(struct pci_dev *dev,return 0 ;/* already enabled */ /* only skip sriov related */ -for (i =0 ; i <=PCI_ROM_RESOURCE ; i++) -if (dev->resource[i].flags & flags) - bars |= (1 << i); -for (i =PCI_BRIDGE_RESOURCES ; i <DEVICE_COUNT_RESOURCE ; i++) -if (dev->resource[i].flags & flags) +for_each_pci_dev_noiov_resource (dev, res, i) { +/* TODO: check i with bits of bars */ +if (res->flags & flags) bars |= (1 << i); + } err =do_pci_enable_device (dev, bars);if (err <0 )
@@ -2465,7 +2466,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n err_out:dev_warn (&pdev->dev,"BAR %d: can't reserve %pR\n" , bar, - &pdev->resource[bar]); +pci_dev_resource_n (pdev, bar));return -EBUSY ; }
Signature · 1 line
1.7.7
PATCH 11/26 PCI: Use for_each_pci_dev_resource pci_reassigndev
In reply to Yinghai Lu--- drivers/pci/pci.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-)
drivers/pci/pci.c +2 -4
@@ -3718,8 +3718,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) command &= ~PCI_COMMAND_MEMORY ;pci_write_config_word (dev,PCI_COMMAND , command); -for (i =0 ; i <PCI_BRIDGE_RESOURCES ; i++) { - r = &dev->resource[i]; +for_each_pci_dev_nobridge_resource (dev, r, i) {if (!(r->flags &IORESOURCE_MEM ))continue ; size =resource_size (r);
@@ -3738,8 +3737,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)*/ if (dev->hdr_type ==PCI_HEADER_TYPE_BRIDGE && (dev->class >>8 ) ==PCI_CLASS_BRIDGE_PCI ) { -for (i =PCI_BRIDGE_RESOURCES ; i <PCI_NUM_RESOURCES ; i++) { - r = &dev->resource[i]; +for_each_pci_dev_bridge_resource (dev, r, i) {if (!(r->flags &IORESOURCE_MEM ))continue ; r->end =resource_size (r) -1 ;
Signature · 1 line
1.7.7
PATCH 12/26 PCI: Use for_each_res with pci bar reassign funcs
In reply to Yinghai LuReplace those open code, and make code more readable.
--- drivers/pci/setup-bus.c | 28 ++++++++++++---------------- 1 files changed, 12 insertions(+), 16 deletions(-)
drivers/pci/setup-bus.c +12 -16
@@ -106,7 +106,7 @@ static resource_size_t get_res_add_size(struct list_head *head,list_for_each_entry (dev_res, head, list) {if (dev_res->res == res) { -int idx = res - &dev_res->dev->resource[0 ]; +int idx =pci_dev_resource_idx (dev_res->dev, res); dev_printk(KERN_DEBUG, &dev_res->dev->dev, "res[%d]=%pR get_res_add_size add_size %llx\n",
@@ -124,15 +124,13 @@ static resource_size_t get_res_add_size(struct list_head *head,static void pdev_sort_resources (struct pci_dev *dev,struct list_head *head) {int i; +struct resource *r; -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { -struct resource *r; +for_each_pci_dev_all_resource (dev, r, i) {struct pci_dev_resource *dev_res, *tmp;resource_size_t r_align;struct list_head *n; - r = &dev->resource[i]; -if (r->flags &IORESOURCE_PCI_FIXED )continue ;
@@ -237,7 +235,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,if (!found_match)/* just skip */ continue ; - idx = res - &add_res->dev->resource[0 ]; + idx =pci_dev_resource_idx (add_res->dev, res); add_size = add_res->add_size;if (!resource_size (res)) { res->start = add_res->start;
@@ -280,7 +278,7 @@ static void assign_requested_resources_sorted(struct list_head *head,list_for_each_entry (dev_res, head, list) { res = dev_res->res; - idx = res - &dev_res->dev->resource[0 ]; + idx =pci_dev_resource_idx (dev_res->dev, res);if (resource_size (res) &&pci_assign_resource (dev_res->dev, idx)) {if (fail_head && !pci_is_root_bus (dev_res->dev->bus)) {
@@ -716,9 +714,9 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,list_for_each_entry (dev, &bus->devices, bus_list) {int i; +struct resource *r; -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { -struct resource *r = &dev->resource[i]; +for_each_pci_dev_all_resource (dev, r, i) {unsigned long r_size;if (r->parent || !(r->flags &IORESOURCE_IO ))
@@ -798,9 +796,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,list_for_each_entry (dev, &bus->devices, bus_list) {int i; +struct resource *r; -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { -struct resource *r = &dev->resource[i]; +for_each_pci_dev_all_resource (dev, r, i) {resource_size_t r_size;if (r->parent || (r->flags & mask) != type)
@@ -1140,9 +1138,7 @@ static void pci_bridge_release_resources(struct pci_bus *bus,IORESOURCE_PREFETCH ; dev = bus->self; -for (idx =PCI_BRIDGE_RESOURCES ; idx <=PCI_BRIDGE_RESOURCE_END ; - idx++) { - r = &dev->resource[idx]; +for_each_pci_dev_bridge_resource (dev, r, idx) {if ((r->flags & type_mask) != type)continue ;if (!r->parent)
@@ -1313,9 +1309,9 @@ static void __init pci_realloc_detect(void)for_each_pci_dev (dev) {int i; +struct resource *r; -for (i =PCI_IOV_RESOURCES ; i <=PCI_IOV_RESOURCE_END ; i++) { -struct resource *r = &dev->resource[i]; +for_each_pci_dev_iov_resource (dev, r, i) {/* Not assigned, or rejected by kernel ? */ if (r->flags && !r->start) {
Signature · 1 line
1.7.7
PATCH 13/26 PCI: Use for_each_res pci_assign_resource
In reply to Yinghai Lu--- drivers/pci/setup-res.c | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-)
drivers/pci/setup-res.c +6 -8
@@ -92,7 +92,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)int pci_claim_resource (struct pci_dev *dev,int resource) { -struct resource *res = &dev->resource[resource]; +struct resource *res =pci_dev_resource_n (dev, resource);struct resource *root, *conflict; root =pci_find_parent_resource (dev, res);
@@ -130,7 +130,7 @@ void pci_disable_bridge_window(struct pci_dev *dev)static int __pci_assign_resource (struct pci_bus *bus,struct pci_dev *dev,int resno,resource_size_t size,resource_size_t align) { -struct resource *res = dev->resource + resno; +struct resource *res =pci_dev_resource_n (dev, resno);resource_size_t min;int ret;
@@ -208,7 +208,7 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,static int _pci_assign_resource (struct pci_dev *dev,int resno,int size,resource_size_t min_align) { -struct resource *res = dev->resource + resno; +struct resource *res =pci_dev_resource_n (dev, resno);struct pci_bus *bus;int ret;char *type;
@@ -241,7 +241,7 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resourint pci_reassign_resource (struct pci_dev *dev,int resno,resource_size_t addsize,resource_size_t min_align) { -struct resource *res = dev->resource + resno; +struct resource *res =pci_dev_resource_n (dev, resno);resource_size_t new_size;int ret;
@@ -265,7 +265,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsizint pci_assign_resource (struct pci_dev *dev,int resno) { -struct resource *res = dev->resource + resno; +struct resource *res =pci_dev_resource_n (dev, resno);resource_size_t align, size;struct pci_bus *bus;int ret;
@@ -307,12 +307,10 @@ int pci_enable_resources(struct pci_dev *dev, int mask)pci_read_config_word (dev,PCI_COMMAND , &cmd); old_cmd = cmd; -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { +for_each_pci_dev_all_resource (dev, r, i) {if (!(mask & (1 << i)))continue ; - r = &dev->resource[i]; -if (!(r->flags & (IORESOURCE_IO |IORESOURCE_MEM )))continue ; if ((i == PCI_ROM_RESOURCE) &&
Signature · 1 line
1.7.7
PATCH 14/26 PCI: Use for_each_res with noassign_bars
In reply to Yinghai LuReplace those open code, and make code more readable.
--- arch/x86/pci/common.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
arch/x86/pci/common.c +1 -2
@@ -136,8 +136,7 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)* resource so the kernel doesn't attmept to assign * it later on in pci_assign_unassigned_resources */ -for (bar =0 ; bar <=PCI_STD_RESOURCE_END ; bar++) { - bar_r = &dev->resource[bar]; +for_each_pci_dev_base_norom_resource (dev, bar_r, bar) {if (bar_r->start ==0 && bar_r->end !=0 ) { bar_r->flags =0 ; bar_r->end =0 ;
Signature · 1 line
1.7.7
PATCH 15/26 PCI: Use for_each_res pci bases pci_dev_driver()
In reply to Yinghai LuReplace those open code, and make code more readable.
--- drivers/pci/pci-driver.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/pci/pci-driver.c +4 -2
@@ -1201,9 +1201,11 @@ pci_dev_driver(const struct pci_dev *dev)if (dev->driver)return dev->driver;else { +struct resource *res;int i; -for (i=0 ; i<=PCI_ROM_RESOURCE ; i++) -if (dev->resource[i].flags &IORESOURCE_BUSY ) + +for_each_pci_dev_base_resource ((struct pci_dev *)dev, res, i) +if (res->flags &IORESOURCE_BUSY )return &pci_compat_driver; }return NULL ;
Signature · 1 line
1.7.7
PATCH 16/26 PCI: Use for_each_res pci release release
In reply to Yinghai LuReplace those open code, and make code more readable.
--- drivers/pci/remove.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/pci/remove.c +2 -3
@@ -6,15 +6,14 @@static void pci_free_resources (struct pci_dev *dev) {int i; +struct resource *res;msi_remove_pci_irq_vectors (dev);pci_cleanup_rom (dev); -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { -struct resource *res = dev->resource + i; +for_each_pci_dev_all_resource (dev, res, i)if (res->parent)release_resource (res); - } }static void pci_stop_dev (struct pci_dev *dev)
Signature · 1 line
1.7.7
PATCH 17/26 PCI: Use for_each_res pci bases reading
In reply to Yinghai LuReplace those open code, and make code more readable.
--- drivers/pci/probe.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/pci/probe.c +4 -2
@@ -277,9 +277,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,static void pci_read_bases (struct pci_dev *dev,unsigned int howmany,int rom) {unsigned int pos, reg; +struct resource *res; -for (pos =0 ; pos < howmany; pos++) { -struct resource *res = &dev->resource[pos]; +for_each_pci_dev_std_resource (dev, res, pos) { +if (pos >= howmany) +break ; reg =PCI_BASE_ADDRESS_0 + (pos <<2 ); pos +=__pci_read_base (dev, pci_bar_unknown, res, reg); }
Signature · 1 line
1.7.7
PATCH 18/26 PCI: Use for_each_res with mrs
In reply to Yinghai Lu--- arch/x86/pci/mrst.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
arch/x86/pci/mrst.c +4 -3
@@ -280,6 +280,7 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)unsigned long offset;u32 size;int i; +struct resource *res;if (!pci_soc_mode)return ;
@@ -294,10 +295,10 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev) PCI_DEVFN(2, 2) == dev->devfn)return ; -for (i =0 ; i <PCI_ROM_RESOURCE ; i++) { +for_each_pci_dev_std_resource (dev, res, i) {pci_read_config_dword (dev, offset +8 + (i *4 ), &size); - dev->resource[i].end = dev->resource[i].start + size -1 ; - dev->resource[i].flags |=IORESOURCE_PCI_FIXED ; + res->end = res->start + size -1 ; + res->flags |=IORESOURCE_PCI_FIXED ; } }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,PCI_ANY_ID , pci_fixed_bar_fixup);
Signature · 1 line
1.7.7
PATCH 19/26 PCI: Use for_each_res with xen pci
In reply to Yinghai Lu--- drivers/pci/xen-pcifront.c | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-)
drivers/pci/xen-pcifront.c +1 -3
@@ -393,9 +393,7 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data)int i;struct resource *r; -for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { - r = &dev->resource[i]; - +for_each_pci_dev_all_resource (dev, r, i) {if (!r->parent && r->start && r->flags) {dev_info (&pdev->xdev->dev,"claiming resource %s/%d\n" ,pci_name (dev), i);
Signature · 1 line
1.7.7
PATCH 20/26 PCI: Add addon_resource support for pci_dev
In reply to Yinghai LuWill add addon_resources list in pci_dev, it will be used for resources other than standard, rom, sriov, bridges.
Some could be same as std reg, but using different register. Some could have own way to read/write to them.
Kernel using different way to hack those resources like abusing pci bridge resource spot on non bridge pci device.
With this patch, will treat addon-resource like standard resource with special ops.
--- drivers/pci/probe.c | 18 ++++++++++++++++++ include/linux/pci.h | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 0 deletions(-)
drivers/pci/probe.c +18 -0
@@ -82,6 +82,12 @@ struct resource *pci_dev_resource_n(struct pci_dev *dev, int n)if (n <PCI_NUM_RESOURCES )return &dev->resource[n]; + n -=PCI_NUM_RESOURCES ; +list_for_each_entry (addon_res, &dev->addon_resources, list) { +if (n-- ==0 ) +return &addon_res->res; + } +return NULL ; }
@@ -97,6 +103,16 @@ int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res)return -1 ; } +static void pci_release_dev_addon_res (struct pci_dev *dev) +{ +struct pci_dev_addon_resource *addon_res, *tmp; + +list_for_each_entry_safe (addon_res, tmp, &dev->addon_resources, list) { +list_del (&addon_res->list); +kfree (addon_res); + } +} +static u64 pci_size (u64 base,u64 maxbase,u64 mask) {u64 size = mask & maxbase;/* Find the significant bits */
@@ -1288,6 +1304,7 @@ static void pci_release_dev(struct device *dev) pci_dev =to_pci_dev (dev);pci_release_capabilities (pci_dev);pci_release_of_node (pci_dev); +pci_release_dev_addon_res (pci_dev);kfree (pci_dev); }
@@ -1367,6 +1384,7 @@ struct pci_dev *alloc_pci_dev(void)return NULL ;INIT_LIST_HEAD (&dev->bus_list); +INIT_LIST_HEAD (&dev->addon_resources);return dev; }
include/linux/pci.h +16 -0
@@ -299,6 +299,7 @@ struct pci_dev {*/ unsigned int irq;struct resource resource[DEVICE_COUNT_RESOURCE ];/* I/O and memory regions + expansion ROMs */ +struct list_head addon_resources;/* addon I/O and memory resource */ /* These fields are used by common fixups */ unsigned int transparent:1; /* Transparent PCI bridge */
@@ -347,6 +348,21 @@ struct pci_dev {#endif }; +struct resource_ops { +int (*read)(struct pci_dev *dev,struct resource *res,int addr); +int (*write)(struct pci_dev *dev,struct resource *res,int addr); +}; + +struct pci_dev_addon_resource { +struct list_head list; +int reg_addr; +int size; +struct resource res; +struct resource_ops *ops; +}; +#define to_pci_dev_addon_resource (n) \ + container_of(n, struct pci_dev_addon_resource, res) +struct resource *pci_dev_resource_n (struct pci_dev *dev,int n);int pci_dev_resource_idx (struct pci_dev *dev,struct resource *res);
Signature · 1 line
1.7.7
PATCH 21/26 PCI: Add helpers for add addon_resource
In reply to Yinghai Lu--- drivers/pci/probe.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 5 +++ 2 files changed, 73 insertions(+), 0 deletions(-)
drivers/pci/probe.c +68 -0
@@ -103,6 +103,74 @@ int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res)return -1 ; } +struct pci_dev_addon_resource *__add_pci_dev_addon_resource ( +struct pci_dev *dev,int addr,char *name) +{ +struct pci_dev_addon_resource *addon_res; + + addon_res =kzalloc (sizeof (*addon_res),GFP_KERNEL ); + +if (!addon_res) +return NULL ; + + addon_res->reg_addr = addr; + +if (name) + addon_res->res.name = name; +else + addon_res->res.name =pci_name (dev); + +list_add_tail (&addon_res->list, &dev->addon_resources); + +return addon_res; +} + +struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource ( +struct pci_dev *dev,int start,int size,int flags, +int addr,char *name) +{ +struct pci_dev_addon_resource *addon_res; +struct resource *res; + + addon_res =__add_pci_dev_addon_resource (dev, addr, name); +if (addon_res) +return NULL ; + + res = &addon_res->res; + res->start = start; + res->end = start + size -1 ; + res->flags = flags |IORESOURCE_PCI_FIXED ; + +dev_printk (KERN_DEBUG , &dev->dev, +"addon fixed resource %s %pR added\n" , res->name, res); + +return addon_res; +} + +struct pci_dev_addon_resource *add_pci_dev_addon_resource (struct pci_dev *dev, +int addr,int size,struct resource_ops *ops,char *name) +{ +struct pci_dev_addon_resource *addon_res; +struct resource *res; + + addon_res =__add_pci_dev_addon_resource (dev, addr, name); +if (!addon_res) +return NULL ; + + res = &addon_res->res; +if (ops) { + addon_res->ops = ops; + addon_res->size = size; + ops->read (dev, res, addr); + }else +__pci_read_base (dev, pci_bar_unknown, res, addr); + +dev_printk (KERN_DEBUG , &dev->dev, +"addon resource %s %pR added\n" , res->name, res); + +return addon_res; +} +static void pci_release_dev_addon_res (struct pci_dev *dev) {struct pci_dev_addon_resource *addon_res, *tmp;
include/linux/pci.h +5 -0
@@ -365,6 +365,11 @@ struct pci_dev_addon_resource {struct resource *pci_dev_resource_n (struct pci_dev *dev,int n);int pci_dev_resource_idx (struct pci_dev *dev,struct resource *res); +struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource ( +struct pci_dev *dev,int start,int size,int flags, +int addr,char *name); +struct pci_dev_addon_resource *add_pci_dev_addon_resource (struct pci_dev *dev, +int addr,int size,struct resource_ops *ops,char *name);#define resno_is_for_bridge (n) \ ((n) >= PCI_BRIDGE_RESOURCES && (n) <= PCI_BRIDGE_RESOURCE_END)
Signature · 1 line
1.7.7
PATCH 22/26 PCI: Update pci_resource_bar() to support addon_resource
In reply to Yinghai Luneed to loop addon resource list to retrieve reg_addr in it.
--- drivers/pci/pci.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/pci/pci.c +7 -0
@@ -3549,6 +3549,13 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) reg =pci_iov_resource_bar (dev, resno, type);if (reg)return reg; + }else if (resno >=PCI_NUM_RESOURCES ) { +struct resource *res =pci_dev_resource_n (dev, resno); + +if (res) { + *type = pci_bar_unknown; +return to_pci_dev_addon_resource (res)->reg_addr; + } }dev_err (&dev->dev,"BAR %d: invalid resource\n" , resno);
Signature · 1 line
1.7.7
PATCH 23/26 PCI: Make assign/update resource to support addon_res
In reply to Yinghai Lu--- drivers/pci/setup-res.c | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-)
drivers/pci/setup-res.c +18 -6
@@ -33,7 +33,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)u32 new, check, mask;int reg;enum pci_bar_type type; -struct resource *res = dev->resource + resno; +struct resource *res =pci_dev_resource_n (dev, resno);/* * Ignore resources for unimplemented BARs and unused resource slots
@@ -50,6 +50,21 @@ void pci_update_resource(struct pci_dev *dev, int resno)if (res->flags &IORESOURCE_PCI_FIXED )return ; +if (resno >=PCI_NUM_RESOURCES ) { +struct pci_dev_addon_resource *addon_res; + + addon_res =to_pci_dev_addon_resource (res); + reg = addon_res->reg_addr; +if (addon_res->ops) { + addon_res->ops->write (dev, res, reg); +return ; + } + }else + reg =pci_resource_bar (dev, resno, &type); + +if (!reg) +return ; +pcibios_resource_to_bus (dev, ®ion, res); new = region.start | (res->flags &PCI_REGION_FLAG_MASK );
@@ -58,9 +73,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)else mask = (u32 )PCI_BASE_ADDRESS_MEM_MASK ; - reg =pci_resource_bar (dev, resno, &type); -if (!reg) -return ;if (type != pci_bar_unknown) {if (!(res->flags &IORESOURCE_ROM_ENABLE ))return ;
@@ -257,7 +269,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsizif (!ret) { res->flags &= ~IORESOURCE_STARTALIGN ;dev_info (&dev->dev,"BAR %d: reassigned %pR\n" , resno, res); -if (resno <PCI_BRIDGE_RESOURCES ) +if (!resno_is_for_bridge (resno))pci_update_resource (dev, resno); }return ret;
@@ -292,7 +304,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)if (!ret) { res->flags &= ~IORESOURCE_STARTALIGN ;dev_info (&dev->dev,"BAR %d: assigned %pR\n" , resno, res); -if (resno <PCI_BRIDGE_RESOURCES ) +if (!resno_is_for_bridge (resno))pci_update_resource (dev, resno); }return ret;
Signature · 1 line
1.7.7
PATCH 24/26 PCI: Make piix4 quirk to use addon_resource support
In reply to Yinghai Luafter they are put in add-on resources, they will be safely claimed later.
--- drivers/pci/quirks.c | 93 +++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 77 insertions(+), 16 deletions(-)
drivers/pci/quirks.c +77 -16
@@ -383,14 +383,14 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_AL ,PCI_DEVICE_ID_AL_M7101 , quirk_ali7101_acpi); -static void piix4_io_quirk (struct pci_dev *dev,const char *name,unsigned int port,unsigned int enable) +static int piix4_read_io (struct pci_dev *dev,struct resource *res,int port) {u32 devres;u32 mask, size, base; +struct pci_bus_region bus_region;pci_read_config_dword (dev, port, &devres); -if ((devres & enable) != enable) -return ; + mask = (devres >>16 ) &15 ; base = devres &0xffff ; size =16 ;
@@ -400,23 +400,53 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int pbreak ; size = bit; } -/* -* For now we only print it out. Eventually we'll want to -* reserve it (at least if it's in the 0x1000+ range), but -* let's get enough confirmation reports first. -*/ base &= -size; -dev_info (&dev->dev,"%s PIO at %04x-%04x\n" , name, base, base + size -1 ); + + bus_region.start = base; + bus_region.end = base + size -1 ; + res->flags |=IORESOURCE_IO ; +pcibios_bus_to_resource (dev, res, &bus_region); +dev_info (&dev->dev,"PIO at %pR\n" , res); + +return 0 ; } +static int piix4_write_io (struct pci_dev *dev,struct resource *res,int port) +{ +u32 devres; +struct pci_bus_region bus_region; + +pcibios_resource_to_bus (dev, &bus_region, res); -static void piix4_mem_quirk (struct pci_dev *dev,const char *name,unsigned int port,unsigned int enable) +pci_read_config_dword (dev, port, &devres); + devres &=0xffff0000 ; + devres |= bus_region.start &0xffff ; +pci_write_config_dword (dev, port, devres); + +return 0 ; +} +static struct resource_ops piix4_io_ops = { + .read = piix4_read_io, + .write = piix4_write_io, +}; +static void piix4_io_quirk (struct pci_dev *dev,char *name,unsigned int port, +unsigned int enable) {u32 devres; -u32 mask, size, base;pci_read_config_dword (dev, port, &devres);if ((devres & enable) != enable)return ; + +add_pci_dev_addon_resource (dev, port,0 , &piix4_io_ops, name); +} + +static int piix4_read_mem (struct pci_dev *dev,struct resource *res,int port) +{ +u32 devres; +u32 mask, size, base; +struct pci_bus_region bus_region; + +pci_read_config_dword (dev, port, &devres); base = devres &0xffff0000 ; mask = (devres &0x3f ) <<16 ; size =128 <<16 ;
@@ -426,12 +456,43 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned intbreak ; size = bit; } -/* -* For now we only print it out. Eventually we'll want to -* reserve it, but let's get enough confirmation reports first. -*/ base &= -size; -dev_info (&dev->dev,"%s MMIO at %04x-%04x\n" , name, base, base + size -1 ); + bus_region.start = base; + bus_region.end = base + size -1 ; + res->flags |=IORESOURCE_MEM ; +pcibios_bus_to_resource (dev, res, &bus_region); +dev_info (&dev->dev,"MMIO at %pR\n" , res); + +return 0 ; +} +static int piix4_write_mem (struct pci_dev *dev,struct resource *res,int port) +{ +u32 devres; +struct pci_bus_region bus_region; + +pcibios_resource_to_bus (dev, &bus_region, res); + +pci_read_config_dword (dev, port, &devres); + devres &=0x0000ffff ; + devres |= bus_region.start &0xffff0000 ; +pci_write_config_dword (dev, port, devres); + +return 0 ; +} +static struct resource_ops piix4_mem_ops = { + .read = piix4_read_mem, + .write = piix4_write_mem, +}; +static void piix4_mem_quirk (struct pci_dev *dev,char *name,unsigned int port, +unsigned int enable) +{ +u32 devres; + +pci_read_config_dword (dev, port, &devres); +if ((devres & enable) != enable) +return ; + +add_pci_dev_addon_resource (dev, port,0 , &piix4_mem_ops, name); }/*
Signature · 1 line
1.7.7
PATCH 25/26 PCI: Make quirk_io_region to use addon_resource support
In reply to Yinghai Luafter they are put in add-on resources, they will be safely claimed later.
--- drivers/pci/quirks.c | 155 ++++++++++++++++++++++--------------------------- 1 files changed, 70 insertions(+), 85 deletions(-)
drivers/pci/quirks.c +70 -85
@@ -324,29 +324,61 @@ static void __devinit quirk_cs5536_vsa(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_AMD ,PCI_DEVICE_ID_AMD_CS5536_ISA , quirk_cs5536_vsa); -static void __devinit quirk_io_region (struct pci_dev *dev,unsigned region, -unsigned size,int nr,const char *name) +static int quirk_read_io (struct pci_dev *dev,struct resource *res,int port) { - region &= ~(size-1 ); -if (region) { -struct pci_bus_region bus_region; -struct resource *res = dev->resource + nr; +struct pci_bus_region bus_region; +u16 region; +unsigned size =to_pci_dev_addon_resource (res)->size; - res->name =pci_name (dev); - res->start = region; - res->end = region + size -1 ; - res->flags =IORESOURCE_IO ; +pci_read_config_word (dev, port, ®ion); + region &= ~(size -1 ); -/* Convert from PCI bus to resource space. */ - bus_region.start = res->start; - bus_region.end = res->end; -pcibios_bus_to_resource (dev, res, &bus_region); +/* Convert from PCI bus to resource space. */ + bus_region.start = region; + bus_region.end = region + size -1 ; -if (pci_claim_resource (dev, nr) ==0 ) -dev_info (&dev->dev,"quirk: %pR claimed by %s\n" , - res, name); - } -} +pcibios_bus_to_resource (dev, res, &bus_region); + + res->flags |=IORESOURCE_IO ; +dev_info (&dev->dev,"PIO at %pR\n" , res); + +return 0 ; +} +static int quirk_write_io (struct pci_dev *dev,struct resource *res,int port) +{ +struct pci_bus_region bus_region; +u16 region; +unsigned size =to_pci_dev_addon_resource (res)->size; + +pci_read_config_word (dev, port, ®ion); + region &= size -1 ; + +/* Convert to PCI bus space. */ +pcibios_resource_to_bus (dev, &bus_region, res); + region |= bus_region.start & (~(size -1 )); + +pci_write_config_word (dev, port, region); + +return 0 ; +} +static struct resource_ops quirk_io_ops = { + .read = quirk_read_io, + .write = quirk_write_io, +}; + +static void __devinit quirk_io_region (struct pci_dev *dev,int port, +unsigned size,char *name) +{ +u16 region; + +pci_read_config_word (dev, port, ®ion); + region &= size -1 ; + +if (!region) +return ; + +add_pci_dev_addon_resource (dev, port, size, &quirk_io_ops, name); +}/* * ATI Northbridge setups MCE the processor if you even
@@ -374,12 +406,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_*/ static void __devinit quirk_ali7101_acpi (struct pci_dev *dev) { -u16 region; - -pci_read_config_word (dev,0xE0 , ®ion); -quirk_io_region (dev, region,64 ,PCI_BRIDGE_RESOURCES ,"ali7101 ACPI" ); -pci_read_config_word (dev,0xE2 , ®ion); -quirk_io_region (dev, region,32 ,PCI_BRIDGE_RESOURCES +1 ,"ali7101 SMB" ); +quirk_io_region (dev,0xE0 ,64 ,"ali7101 ACPI" ); +quirk_io_region (dev,0xE2 ,32 ,"ali7101 SMB" ); }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_AL ,PCI_DEVICE_ID_AL_M7101 , quirk_ali7101_acpi);
@@ -503,12 +531,10 @@ static void piix4_mem_quirk(struct pci_dev *dev, char *name, unsigned int port,*/ static void __devinit quirk_piix4_acpi (struct pci_dev *dev) { -u32 region, res_a; +u32 res_a; -pci_read_config_dword (dev,0x40 , ®ion); -quirk_io_region (dev, region,64 ,PCI_BRIDGE_RESOURCES ,"PIIX4 ACPI" ); -pci_read_config_dword (dev,0x90 , ®ion); -quirk_io_region (dev, region,16 ,PCI_BRIDGE_RESOURCES +1 ,"PIIX4 SMB" ); +quirk_io_region (dev,0x40 ,64 ,"PIIX4 ACPI" ); +quirk_io_region (dev,0x90 ,16 ,"PIIX4 SMB" );/* Device resource A has enables for some of the other ones */ pci_read_config_dword (dev,0x5c , &res_a);
@@ -552,7 +578,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui*/ static void __devinit quirk_ich4_lpc_acpi (struct pci_dev *dev) { -u32 region;u8 enable;/*
@@ -564,22 +589,12 @@ static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)*/ pci_read_config_byte (dev,ICH_ACPI_CNTL , &enable); -if (enable &ICH4_ACPI_EN ) { -pci_read_config_dword (dev,ICH_PMBASE , ®ion); - region &=PCI_BASE_ADDRESS_IO_MASK ; -if (region >=PCIBIOS_MIN_IO ) -quirk_io_region (dev, region,128 ,PCI_BRIDGE_RESOURCES , -"ICH4 ACPI/GPIO/TCO" ); - } +if (enable &ICH4_ACPI_EN ) +quirk_io_region (dev,ICH_PMBASE ,128 ,"ICH4 ACPI/GPIO/TCO" );pci_read_config_byte (dev,ICH4_GPIO_CNTL , &enable); -if (enable &ICH4_GPIO_EN ) { -pci_read_config_dword (dev,ICH4_GPIOBASE , ®ion); - region &=PCI_BASE_ADDRESS_IO_MASK ; -if (region >=PCIBIOS_MIN_IO ) -quirk_io_region (dev, region,64 , -PCI_BRIDGE_RESOURCES +1 ,"ICH4 GPIO" ); - } +if (enable &ICH4_GPIO_EN ) +quirk_io_region (dev,ICH4_GPIOBASE ,64 ,"ICH4 GPIO" ); }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_82801AA_0 , quirk_ich4_lpc_acpi);DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_82801AB_0 , quirk_ich4_lpc_acpi);
@@ -594,26 +609,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, quistatic void __devinit ich6_lpc_acpi_gpio (struct pci_dev *dev) { -u32 region;u8 enable;pci_read_config_byte (dev,ICH_ACPI_CNTL , &enable); -if (enable &ICH6_ACPI_EN ) { -pci_read_config_dword (dev,ICH_PMBASE , ®ion); - region &=PCI_BASE_ADDRESS_IO_MASK ; -if (region >=PCIBIOS_MIN_IO ) -quirk_io_region (dev, region,128 ,PCI_BRIDGE_RESOURCES , -"ICH6 ACPI/GPIO/TCO" ); - } +if (enable &ICH6_ACPI_EN ) +quirk_io_region (dev,ICH_PMBASE ,128 ,"ICH6 ACPI/GPIO/TCO" );pci_read_config_byte (dev,ICH6_GPIO_CNTL , &enable); -if (enable &ICH6_GPIO_EN ) { -pci_read_config_dword (dev,ICH6_GPIOBASE , ®ion); - region &=PCI_BASE_ADDRESS_IO_MASK ; -if (region >=PCIBIOS_MIN_IO ) -quirk_io_region (dev, region,64 , -PCI_BRIDGE_RESOURCES +1 ,"ICH6 GPIO" ); - } +if (enable &ICH6_GPIO_EN ) +quirk_io_region (dev,ICH6_GPIOBASE ,64 ,"ICH6 GPIO" ); }static void __devinit ich6_lpc_generic_decode (struct pci_dev *dev,unsigned reg,const char *name,int dynsize)
@@ -711,13 +715,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui*/ static void __devinit quirk_vt82c586_acpi (struct pci_dev *dev) { -u32 region; - -if (dev->revision &0x10 ) { -pci_read_config_dword (dev,0x48 , ®ion); - region &=PCI_BASE_ADDRESS_IO_MASK ; -quirk_io_region (dev, region,256 ,PCI_BRIDGE_RESOURCES ,"vt82c586 ACPI" ); - } +if (dev->revision &0x10 ) +quirk_io_region (dev,0x48 ,256 ,"vt82c586 ACPI" ); }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_VIA ,PCI_DEVICE_ID_VIA_82C586_3 , quirk_vt82c586_acpi);
@@ -729,18 +728,11 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt*/ static void __devinit quirk_vt82c686_acpi (struct pci_dev *dev) { -u16 hm; -u32 smb; -quirk_vt82c586_acpi (dev); -pci_read_config_word (dev,0x70 , &hm); - hm &=PCI_BASE_ADDRESS_IO_MASK ; -quirk_io_region (dev, hm,128 ,PCI_BRIDGE_RESOURCES +1 ,"vt82c686 HW-mon" ); +quirk_io_region (dev,0x70 ,128 ,"vt82c686 HW-mon" ); -pci_read_config_dword (dev,0x90 , &smb); - smb &=PCI_BASE_ADDRESS_IO_MASK ; -quirk_io_region (dev, smb,16 ,PCI_BRIDGE_RESOURCES +2 ,"vt82c686 SMB" ); +quirk_io_region (dev,0x90 ,16 ,"vt82c686 SMB" ); }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_VIA ,PCI_DEVICE_ID_VIA_82C686_4 , quirk_vt82c686_acpi);
@@ -751,15 +743,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt*/ static void __devinit quirk_vt8235_acpi (struct pci_dev *dev) { -u16 pm, smb; - -pci_read_config_word (dev,0x88 , &pm); - pm &=PCI_BASE_ADDRESS_IO_MASK ; -quirk_io_region (dev, pm,128 ,PCI_BRIDGE_RESOURCES ,"vt8235 PM" ); - -pci_read_config_word (dev,0xd0 , &smb); - smb &=PCI_BASE_ADDRESS_IO_MASK ; -quirk_io_region (dev, smb,16 ,PCI_BRIDGE_RESOURCES +1 ,"vt8235 SMB" ); +quirk_io_region (dev,0x88 ,128 ,"vt8235 PM" ); +quirk_io_region (dev,0xd0 ,16 ,"vt8235 SMB" ); }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_VIA ,PCI_DEVICE_ID_VIA_8235 , quirk_vt8235_acpi);
Signature · 1 line
1.7.7
PATCH 26/26 PCI: Use addon_fixed_resource with ati fixed resource
In reply to Yinghai Luafter they are put in add-on resources, they will be safely claimed later.
--- drivers/pci/quirks.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
drivers/pci/quirks.c +5 -3
@@ -386,10 +386,12 @@ static void __devinit quirk_io_region(struct pci_dev *dev, int port,*/ static void __devinit quirk_ati_exploding_mce (struct pci_dev *dev) { -dev_info (&dev->dev,"ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n" ); +dev_info (&dev->dev,"ATI Northbridge, will reserve I/O ports 0x3b0 to 0x3bb\n" );/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */ -request_region (0x3b0 ,0x0C ,"RadeonIGP" ); -request_region (0x3d3 ,0x01 ,"RadeonIGP" ); +add_pci_dev_addon_fixed_resource (dev,0x3B0 ,0x0C ,IORESOURCE_IO ,0 , +"RadeonIGP" ); +add_pci_dev_addon_fixed_resource (dev,0x3d3 ,0x01 ,IORESOURCE_IO ,0 , +"RadeonIGP" ); }DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_ATI ,PCI_DEVICE_ID_ATI_RS100 , quirk_ati_exploding_mce);
Signature · 1 line
1.7.7