From 07eddf3d597f2d009a37a4e8c7c32a1ffe992f3e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 29 Nov 2006 13:53:10 -0800 Subject: PCI: check szhi when sz is 0 when 64 bit iomem bigger than 4G For pci mem resource that size is bigger than 4G, the sz returned by pc_size will be 0. So that resource is skipped, and register contained hi address will be treated as another 32bit resource. We need to use sz64 and pci_sz64 for 64 bit resource for clear logical. Typical usages for this: Opteron system with co-processor and the co-processor could take more than 4G RAM as pre-fetchable mem resource. Signed-off-by: Yinghai Lu Cc: Andi Kleen Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 69 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 0e0401dd02cb..9d7788428642 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -144,6 +144,32 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask) return size; } +static u64 pci_size64(u64 base, u64 maxbase, u64 mask) +{ + u64 size = mask & maxbase; /* Find the significant bits */ + if (!size) + return 0; + + /* Get the lowest of them to find the decode size, and + from that the extent. */ + size = (size & ~(size-1)) - 1; + + /* base == maxbase can be valid only if the BAR has + already been programmed with all 1s. */ + if (base == maxbase && ((base | size) & mask) != mask) + return 0; + + return size; +} + +static inline int is_64bit_memory(u32 mask) +{ + if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == + (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) + return 1; + return 0; +} + static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { unsigned int pos, reg, next; @@ -151,6 +177,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) struct resource *res; for(pos=0; posresource[pos]; res->name = pci_name(dev); @@ -163,9 +193,16 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) continue; if (l == 0xffffffff) l = 0; - if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { + raw_sz = sz; + if ((l & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY) { sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK); - if (!sz) + /* + * For 64bit prefetchable memory sz could be 0, if the + * real size is bigger than 4G, so we need to check + * szhi for that. + */ + if (!is_64bit_memory(l) && !sz) continue; res->start = l & PCI_BASE_ADDRESS_MEM_MASK; res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK; @@ -178,30 +215,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) } res->end = res->start + (unsigned long) sz; res->flags |= pci_calc_resource_flags(l); - if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) - == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { + if (is_64bit_memory(l)) { u32 szhi, lhi; + pci_read_config_dword(dev, reg+4, &lhi); pci_write_config_dword(dev, reg+4, ~0); pci_read_config_dword(dev, reg+4, &szhi); pci_write_config_dword(dev, reg+4, lhi); - szhi = pci_size(lhi, szhi, 0xffffffff); + sz64 = ((u64)szhi << 32) | raw_sz; + l64 = ((u64)lhi << 32) | l; + sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK); next++; #if BITS_PER_LONG == 64 - res->start |= ((unsigned long) lhi) << 32; - res->end = res->start + sz; - if (szhi) { - /* This BAR needs > 4GB? Wow. */ - res->end |= (unsigned long)szhi<<32; + if (!sz64) { + res->start = 0; + res->end = 0; + res->flags = 0; + continue; } + res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK; + res->end = res->start + sz64; #else - if (szhi) { - printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev)); + if (sz64 > 0x100000000ULL) { + printk(KERN_ERR "PCI: Unable to handle 64-bit " + "BAR for device %s\n", pci_name(dev)); res->start = 0; res->flags = 0; } else if (lhi) { /* 64-bit wide address, treat as disabled */ - pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); + pci_write_config_dword(dev, reg, + l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); pci_write_config_dword(dev, reg+4, 0); res->start = 0; res->end = sz; -- cgit v1.2.3 From 924b08f3ff12eb0e8ecd9e9a9b6a5b884a495c23 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Mon, 18 Dec 2006 10:27:45 +0900 Subject: PCI : remove too specialized __pci_enable_device for default resume Original patch was posted as "PCI : Move pci_fixup_device and is_enabled". This 1 of 3 patches does: - reverts small part of Inaky's patch (remove __pci_enable_device) This change will be recovered by 3rd patch. - temporarily remove pci_fixup_device. This change will be recovered by 2nd patch. Signed-off-by: Kenji Kaneshige Signed-off-by: Hidetoshi Seto Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 2 +- drivers/pci/pci.c | 23 ----------------------- drivers/pci/pci.h | 1 - 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 92d5e8db0de7..1ec546d3d53c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -325,7 +325,7 @@ static int pci_default_resume(struct pci_dev *pci_dev) pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ if (atomic_read(&pci_dev->enable_cnt)) - retval = __pci_enable_device(pci_dev); + retval = pci_enable_device(pci_dev); /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 206c834d263a..d20d3983bbd6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -700,29 +700,6 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) return 0; } -/** - * __pci_enable_device - Initialize device before it's used by a driver. - * @dev: PCI device to be initialized - * - * Initialize device before it's used by a driver. Ask low-level code - * to enable I/O and memory. Wake up the device if it was suspended. - * Beware, this function can fail. - * - * Note this function is a backend and is not supposed to be called by - * normal code, use pci_enable_device() instead. - */ -int -__pci_enable_device(struct pci_dev *dev) -{ - int err; - - err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); - if (err) - return err; - pci_fixup_device(pci_fixup_enable, dev); - return 0; -} - /** * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 398852f526a6..6bf327db5c5e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -1,6 +1,5 @@ /* Functions internal to the PCI core code */ -extern int __must_check __pci_enable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); -- cgit v1.2.3 From 9fb625c3cc3731097a142ecae79a0369fb854c2d Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Mon, 18 Dec 2006 10:28:43 +0900 Subject: PCI : Move pci_fixup_device and is_enabled (originally intended change) Original patch was posted as "PCI : Move pci_fixup_device and is_enabled". This 2 of 3 patches does: - Move pci_fixup_device and enable_cnt (originally intended change) - relocate pci_fixup_device (recover latter change of 1st patch) Signed-off-by: Kenji Kaneshige Signed-off-by: Hidetoshi Seto Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d20d3983bbd6..212acd2e1a84 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -682,22 +682,28 @@ pci_restore_state(struct pci_dev *dev) * @bars: bitmask of BAR's that must be configured * * Initialize device before it's used by a driver. Ask low-level code - * to enable selected I/O and memory resources. Wake up the device if it + * to enable selected I/O and memory resources. Wake up the device if it * was suspended. Beware, this function can fail. */ - int pci_enable_device_bars(struct pci_dev *dev, int bars) { int err; + if (atomic_add_return(1, &dev->enable_cnt) > 1) + return 0; /* already enabled */ + err = pci_set_power_state(dev, PCI_D0); if (err < 0 && err != -EIO) - return err; + goto err_out; err = pcibios_enable_device(dev, bars); if (err < 0) - return err; - return 0; + goto err_out; + pci_fixup_device(pci_fixup_enable, dev); + +err_out: + atomic_dec(&dev->enable_cnt); + return err; } /** @@ -713,13 +719,7 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) */ int pci_enable_device(struct pci_dev *dev) { - int result; - if (atomic_add_return(1, &dev->enable_cnt) > 1) - return 0; /* already enabled */ - result = __pci_enable_device(dev); - if (result < 0) - atomic_dec(&dev->enable_cnt); - return result; + return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); } /** -- cgit v1.2.3 From 38cc13022ed3cea949722d5a6f49025da82c9fd0 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Mon, 18 Dec 2006 10:30:00 +0900 Subject: PCI : add extremely specialized __pci_reenable_device for default resume Original patch was posted as "PCI : Move pci_fixup_device and is_enabled". This 3 of 3 patches does: - add __pci_reenable_device (recover former change of 1st patch) Signed-off-by: Kenji Kaneshige Signed-off-by: Hidetoshi Seto Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 3 +-- drivers/pci/pci.c | 41 ++++++++++++++++++++++++++++++++--------- drivers/pci/pci.h | 1 + 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1ec546d3d53c..dd2da9b6b119 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -324,8 +324,7 @@ static int pci_default_resume(struct pci_dev *pci_dev) /* restore the PCI config space */ pci_restore_state(pci_dev); /* if the device was enabled before suspend, reenable */ - if (atomic_read(&pci_dev->enable_cnt)) - retval = pci_enable_device(pci_dev); + retval = __pci_reenable_device(pci_dev); /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 212acd2e1a84..287b685aaa5c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -676,6 +676,36 @@ pci_restore_state(struct pci_dev *dev) return 0; } +static int do_pci_enable_device(struct pci_dev *dev, int bars) +{ + int err; + + err = pci_set_power_state(dev, PCI_D0); + if (err < 0 && err != -EIO) + return err; + err = pcibios_enable_device(dev, bars); + if (err < 0) + return err; + pci_fixup_device(pci_fixup_enable, dev); + + return 0; +} + +/** + * __pci_reenable_device - Resume abandoned device + * @dev: PCI device to be resumed + * + * Note this function is a backend of pci_default_resume and is not supposed + * to be called by normal code, write proper resume handler and use it instead. + */ +int +__pci_reenable_device(struct pci_dev *dev) +{ + if (atomic_read(&dev->enable_cnt)) + return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); + return 0; +} + /** * pci_enable_device_bars - Initialize some of a device for use * @dev: PCI device to be initialized @@ -693,16 +723,9 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) if (atomic_add_return(1, &dev->enable_cnt) > 1) return 0; /* already enabled */ - err = pci_set_power_state(dev, PCI_D0); - if (err < 0 && err != -EIO) - goto err_out; - err = pcibios_enable_device(dev, bars); + err = do_pci_enable_device(dev, bars); if (err < 0) - goto err_out; - pci_fixup_device(pci_fixup_enable, dev); - -err_out: - atomic_dec(&dev->enable_cnt); + atomic_dec(&dev->enable_cnt); return err; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6bf327db5c5e..783e81f81f58 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -1,5 +1,6 @@ /* Functions internal to the PCI core code */ +extern int __must_check __pci_reenable_device(struct pci_dev *); extern int pci_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); -- cgit v1.2.3 From c87deff776feacd05a7411097e8c8c57e549e638 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Mon, 18 Dec 2006 10:31:06 +0900 Subject: PCI : Add selected_regions funcs This patch adds the following changes into generic PCI code especially for PCI legacy I/O port free drivers. - Added new pci_request_selected_regions() and pci_release_selected_regions() for PCI legacy I/O port free drivers in order to request/release only the selected regions. - Added helper routine pci_select_bars() which makes proper mask of BARs from the specified resource type. This would be very helpful for users of pci_enable_device_bars(). Signed-off-by: Kenji Kaneshige Signed-off-by: Hidetoshi Seto Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 80 +++++++++++++++++++++++++++++++++++++++++------------ include/linux/pci.h | 3 ++ 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 287b685aaa5c..599978631a46 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -921,6 +921,47 @@ err_out: return -EBUSY; } +/** + * pci_release_selected_regions - Release selected PCI I/O and memory resources + * @pdev: PCI device whose resources were previously reserved + * @bars: Bitmask of BARs to be released + * + * Release selected PCI I/O and memory resources previously reserved. + * Call this function only after all use of the PCI regions has ceased. + */ +void pci_release_selected_regions(struct pci_dev *pdev, int bars) +{ + int i; + + for (i = 0; i < 6; i++) + if (bars & (1 << i)) + pci_release_region(pdev, i); +} + +/** + * pci_request_selected_regions - Reserve selected PCI I/O and memory resources + * @pdev: PCI device whose resources are to be reserved + * @bars: Bitmask of BARs to be requested + * @res_name: Name to be associated with resource + */ +int pci_request_selected_regions(struct pci_dev *pdev, int bars, + const char *res_name) +{ + int i; + + for (i = 0; i < 6; i++) + if (bars & (1 << i)) + if(pci_request_region(pdev, i, res_name)) + goto err_out; + return 0; + +err_out: + while(--i >= 0) + if (bars & (1 << i)) + pci_release_region(pdev, i); + + return -EBUSY; +} /** * pci_release_regions - Release reserved PCI I/O and memory resources @@ -933,10 +974,7 @@ err_out: void pci_release_regions(struct pci_dev *pdev) { - int i; - - for (i = 0; i < 6; i++) - pci_release_region(pdev, i); + pci_release_selected_regions(pdev, (1 << 6) - 1); } /** @@ -954,18 +992,7 @@ void pci_release_regions(struct pci_dev *pdev) */ int pci_request_regions(struct pci_dev *pdev, const char *res_name) { - int i; - - for (i = 0; i < 6; i++) - if(pci_request_region(pdev, i, res_name)) - goto err_out; - return 0; - -err_out: - while(--i >= 0) - pci_release_region(pdev, i); - - return -EBUSY; + return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name); } /** @@ -1148,7 +1175,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) return 0; } #endif - + +/** + * pci_select_bars - Make BAR mask from the type of resource + * @pdev: the PCI device for which BAR mask is made + * @flags: resource type mask to be selected + * + * This helper routine makes bar mask from the type of resource. + */ +int pci_select_bars(struct pci_dev *dev, unsigned long flags) +{ + int i, bars = 0; + for (i = 0; i < PCI_NUM_RESOURCES; i++) + if (pci_resource_flags(dev, i) & flags) + bars |= (1 << i); + return bars; +} + static int __devinit pci_init(void) { struct pci_dev *dev = NULL; @@ -1197,6 +1240,8 @@ EXPORT_SYMBOL(pci_release_regions); EXPORT_SYMBOL(pci_request_regions); EXPORT_SYMBOL(pci_release_region); EXPORT_SYMBOL(pci_request_region); +EXPORT_SYMBOL(pci_release_selected_regions); +EXPORT_SYMBOL(pci_request_selected_regions); EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_clear_mwi); @@ -1205,6 +1250,7 @@ EXPORT_SYMBOL(pci_set_dma_mask); EXPORT_SYMBOL(pci_set_consistent_dma_mask); EXPORT_SYMBOL(pci_assign_resource); EXPORT_SYMBOL(pci_find_parent_resource); +EXPORT_SYMBOL(pci_select_bars); EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_save_state); diff --git a/include/linux/pci.h b/include/linux/pci.h index f3c617eabd8d..df875626b71a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -533,6 +533,7 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); void pci_restore_bars(struct pci_dev *dev); +int pci_select_bars(struct pci_dev *dev, unsigned long flags); /* ROM control related routines */ void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); @@ -561,6 +562,8 @@ int __must_check pci_request_regions(struct pci_dev *, const char *); void pci_release_regions(struct pci_dev *); int __must_check pci_request_region(struct pci_dev *, int, const char *); void pci_release_region(struct pci_dev *, int); +int pci_request_selected_regions(struct pci_dev *, int, const char *); +void pci_release_selected_regions(struct pci_dev *, int); /* drivers/pci/bus.c */ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, -- cgit v1.2.3 From a7369f1f6533b9efc3209d1df103537bbbf24b8c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Tue, 12 Dec 2006 16:55:59 -0600 Subject: PCI: define inline for test of channel error state Add very simple routine to indicate the pci channel error state. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index df875626b71a..79856b3c714a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -181,6 +181,11 @@ struct pci_dev { #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) +static inline int pci_channel_offline(struct pci_dev *pdev) +{ + return (pdev->error_state != pci_channel_io_normal); +} + static inline struct pci_cap_saved_state *pci_find_saved_cap( struct pci_dev *pci_dev,char cap) { -- cgit v1.2.3 From 81b1955eef786c1b2fe29f6783543ce13d8b0bc4 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Tue, 12 Dec 2006 18:29:15 -0600 Subject: PCI: Use newly defined PCI channel offline routine Use newly minted routine to access the PCI channel state. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c6259c7127f6..8424a8e4cbb0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3602,7 +3602,7 @@ e1000_update_stats(struct e1000_adapter *adapter) */ if (adapter->link_speed == 0) return; - if (pdev->error_state && pdev->error_state != pci_channel_io_normal) + if (pci_channel_offline(pdev)) return; spin_lock_irqsave(&adapter->stats_lock, flags); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index a083a9189230..f2742179f120 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1609,7 +1609,7 @@ ixgb_update_stats(struct ixgb_adapter *adapter) struct pci_dev *pdev = adapter->pdev; /* Prevent stats update while adapter is being reset */ - if (pdev->error_state && pdev->error_state != pci_channel_io_normal) + if (pci_channel_offline(pdev)) return; if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || -- cgit v1.2.3 From c30ca1db39cecade07143112ecfac09ec6b08e3f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Dec 2006 05:13:15 +0100 Subject: PCI: quirks.c: cleanup This patch contains the following cleanups: - move all EXPORT_SYMBOL's directly below the code they are exporting - move all DECLARE_PCI_FIXUP_*'s directly below the functions they are calling Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 4 ---- drivers/pci/quirks.c | 42 +++++++++++++++++------------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 599978631a46..caeeacc7b070 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1257,7 +1257,3 @@ EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); -/* Quirk info */ - -EXPORT_SYMBOL(isa_dma_bridge_buggy); -EXPORT_SYMBOL(pci_pci_problems); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c913ea4e545c..1d04ca02dd0f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -61,7 +61,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p This appears to be BIOS not version dependent. So presumably there is a chipset level fix */ -int isa_dma_bridge_buggy; /* Exported */ +int isa_dma_bridge_buggy; +EXPORT_SYMBOL(isa_dma_bridge_buggy); static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) { @@ -83,6 +84,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs ); int pci_pci_problems; +EXPORT_SYMBOL(pci_pci_problems); /* * Chipsets where PCI->PCI transfers vanish or hang @@ -94,6 +96,8 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev) pci_pci_problems |= PCIPCI_FAIL; } } +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci ); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci ); static void __devinit quirk_nopciamd(struct pci_dev *dev) { @@ -105,9 +109,6 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev) pci_pci_problems |= PCIAGP_FAIL; } } - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci ); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd ); /* @@ -1136,6 +1137,14 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev) pci_write_config_byte(dev, 0x77, val & ~0x10); } } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); /* * ... This is further complicated by the fact that some SiS96x south @@ -1173,6 +1182,8 @@ static void quirk_sis_503(struct pci_dev *dev) dev->device = devid; quirk_sis_96x_smbus(dev); } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); static void __init quirk_sis_96x_compatible(struct pci_dev *dev) { @@ -1185,8 +1196,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650, quirk_sis_96x_ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_compatible ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); /* * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller * and MC97 modem controller are disabled when a second PCI soundcard is @@ -1217,21 +1226,8 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); - - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); - DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); - -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); - #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) /* @@ -1276,7 +1272,6 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev) break; } } - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); @@ -1420,6 +1415,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_co int pcie_mch_quirk; +EXPORT_SYMBOL(pcie_mch_quirk); static void __devinit quirk_pcie_mch(struct pci_dev *pdev) { @@ -1646,6 +1642,7 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) } pci_do_fixups(dev, start, end); } +EXPORT_SYMBOL(pci_fixup_device); /* Enable 1k I/O space granularity on the Intel P64H2 */ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) @@ -1788,8 +1785,3 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); #endif /* CONFIG_PCI_MSI */ - -EXPORT_SYMBOL(pcie_mch_quirk); -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pci_fixup_device); -#endif -- cgit v1.2.3 From fd9b37cc4e32533214f77b34ea03ee85f6e0a4d2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 17 Nov 2006 15:21:45 +0100 Subject: PCI: remove pci_find_device_reverse() This patch removes the no longer used pci_find_device_reverse(). Signed-off-by: Adrian Bunk Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/pci/search.c | 38 -------------------------------------- include/linux/pci.h | 1 - 2 files changed, 39 deletions(-) diff --git a/drivers/pci/search.c b/drivers/pci/search.c index b2653c4afe9e..ff98eaddaa73 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -357,43 +357,6 @@ exit: return dev; } -/** - * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id - * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids - * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids - * @from: Previous PCI device found in search, or %NULL for new search. - * - * Iterates through the list of known PCI devices in the reverse order of - * pci_find_device(). - * If a PCI device is found with a matching @vendor and @device, a pointer to - * its device structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from previous device - * on the global list. - */ -struct pci_dev * -pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) -{ - struct list_head *n; - struct pci_dev *dev; - - WARN_ON(in_interrupt()); - down_read(&pci_bus_sem); - n = from ? from->global_list.prev : pci_devices.prev; - - while (n && (n != &pci_devices)) { - dev = pci_dev_g(n); - if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && - (device == PCI_ANY_ID || dev->device == device)) - goto exit; - n = n->prev; - } - dev = NULL; -exit: - up_read(&pci_bus_sem); - return dev; -} - /** * pci_get_class - begin or continue searching for a PCI device by class * @class: search for a PCI device with this class designation @@ -469,7 +432,6 @@ EXPORT_SYMBOL(pci_dev_present); EXPORT_SYMBOL(pci_find_present); EXPORT_SYMBOL(pci_find_device); -EXPORT_SYMBOL(pci_find_device_reverse); EXPORT_SYMBOL(pci_find_slot); /* For boot time work */ EXPORT_SYMBOL(pci_find_bus); diff --git a/include/linux/pci.h b/include/linux/pci.h index 79856b3c714a..23d2a37f3c9f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -469,7 +469,6 @@ extern void pci_sort_breadthfirst(void); /* Generic PCI functions exported to card drivers */ struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); -struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); -- cgit v1.2.3 From 429538ad3eeffec4199d8adddd1e9e4c80b2c08b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 18 Nov 2006 01:06:29 +0100 Subject: PCI: mark pci_find_device() as __deprecated On Fri, Nov 17, 2006 at 09:32:36AM -0500, Alan Cox wrote: > > Soon we should deprecate pci_find_device as well So let's mark it as __deprecated now, which also has the side effect that noone can later whine that removing it might break some shiny external modules. Oh, and if anything starts complaining "But this adds some warnings to my kernel build!", he should either first fix the 200 kB (sic) of warnings I'm getting in 2.6.19-rc5-mm2 starting at MODPOST or go to hell. Signed-off-by: Adrian Bunk Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index 23d2a37f3c9f..cf2c8a35a1df 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -468,7 +468,7 @@ extern void pci_sort_breadthfirst(void); /* Generic PCI functions exported to card drivers */ -struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); +struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); -- cgit v1.2.3 From a0b1725720d9a023a1dee129234f5972056038c6 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:02 -0800 Subject: pciehp: cleanup init_slot() This patch cleans up init_slots() in pciehp_core.c based on pcihp_skeleton.c. This has no functional change. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 10 +---- drivers/pci/hotplug/pciehp_core.c | 90 +++++++++++++++------------------------ 2 files changed, 37 insertions(+), 63 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4fb12fcda563..6a2f427768ca 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -50,7 +50,7 @@ extern int pciehp_force; #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) - +#define SLOT_NAME_SIZE 10 struct slot { struct slot *next; u8 bus; @@ -63,6 +63,7 @@ struct slot { struct hpc_ops *hpc_ops; struct hotplug_slot *hotplug_slot; struct list_head slot_list; + char name[SLOT_NAME_SIZE]; }; struct event_info { @@ -233,13 +234,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) return retval; } -#define SLOT_NAME_SIZE 10 - -static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) -{ - snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); -} - enum php_ctlr_type { PCI, ISA, diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index f13f31323e85..051d228e634e 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -98,101 +98,81 @@ static void release_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); kfree(slot->hotplug_slot->info); - kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); kfree(slot); } +static void make_slot_name(struct slot *slot) +{ + snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", + slot->bus, slot->number); +} + static int init_slots(struct controller *ctrl) { struct slot *slot; - struct hpc_ops *hpc_ops; struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *hotplug_slot_info; - u8 number_of_slots; - u8 slot_device; - u32 slot_number; - int result = -ENOMEM; + struct hotplug_slot_info *info; + int retval = -ENOMEM; + int i; - number_of_slots = ctrl->num_slots; - slot_device = ctrl->slot_device_offset; - slot_number = ctrl->first_slot; - - while (number_of_slots) { + for (i = 0; i < ctrl->num_slots; i++) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) goto error; - slot->hotplug_slot = - kzalloc(sizeof(*(slot->hotplug_slot)), - GFP_KERNEL); - if (!slot->hotplug_slot) + hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); + if (!hotplug_slot) goto error_slot; - hotplug_slot = slot->hotplug_slot; + slot->hotplug_slot = hotplug_slot; - hotplug_slot->info = - kzalloc(sizeof(*(hotplug_slot->info)), - GFP_KERNEL); - if (!hotplug_slot->info) + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) goto error_hpslot; - hotplug_slot_info = hotplug_slot->info; - hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); - if (!hotplug_slot->name) - goto error_info; + hotplug_slot->info = info; - slot->ctrl = ctrl; - slot->bus = ctrl->slot_bus; - slot->device = slot_device; - slot->hpc_ops = hpc_ops = ctrl->hpc_ops; + hotplug_slot->name = slot->name; + slot->hp_slot = i; + slot->ctrl = ctrl; + slot->bus = ctrl->pci_dev->subordinate->number; + slot->device = ctrl->slot_device_offset + i; + slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot; - slot->hp_slot = slot_device - ctrl->slot_device_offset; /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; hotplug_slot->release = &release_slot; - make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); + make_slot_name(slot); hotplug_slot->ops = &pciehp_hotplug_slot_ops; - hpc_ops->get_power_status(slot, - &(hotplug_slot_info->power_status)); - hpc_ops->get_attention_status(slot, - &(hotplug_slot_info->attention_status)); - hpc_ops->get_latch_status(slot, - &(hotplug_slot_info->latch_status)); - hpc_ops->get_adapter_status(slot, - &(hotplug_slot_info->adapter_status)); + get_power_status(hotplug_slot, &info->power_status); + get_attention_status(hotplug_slot, &info->attention_status); + get_latch_status(hotplug_slot, &info->latch_status); + get_adapter_status(hotplug_slot, &info->adapter_status); dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " - "slot_device_offset=%x\n", - slot->bus, slot->device, slot->hp_slot, slot->number, - ctrl->slot_device_offset); - result = pci_hp_register(hotplug_slot); - if (result) { - err ("pci_hp_register failed with error %d\n", result); - goto error_name; + "slot_device_offset=%x\n", slot->bus, slot->device, + slot->hp_slot, slot->number, ctrl->slot_device_offset); + retval = pci_hp_register(hotplug_slot); + if (retval) { + err ("pci_hp_register failed with error %d\n", retval); + goto error_info; } slot->next = ctrl->slot; ctrl->slot = slot; - - number_of_slots--; - slot_device++; - slot_number += ctrl->slot_num_inc; } return 0; - -error_name: - kfree(hotplug_slot->name); error_info: - kfree(hotplug_slot_info); + kfree(info); error_hpslot: kfree(hotplug_slot); error_slot: kfree(slot); error: - return result; + return retval; } -- cgit v1.2.3 From 2410fa4eaec4133f9fa8968f277ddb28b89b92b3 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:03 -0800 Subject: pciehp: cleanup slot list This patch cleans up slot list handling (use list_head). This has no functional change. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 19 +++++++------------ drivers/pci/hotplug/pciehp_core.c | 25 ++++++++++--------------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 6a2f427768ca..d07ac45f1272 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -52,7 +52,6 @@ extern int pciehp_force; #define SLOT_NAME_SIZE 10 struct slot { - struct slot *next; u8 bus; u8 device; u32 number; @@ -99,6 +98,7 @@ struct controller { int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; struct pci_bus *pci_bus; + struct list_head slot_list; struct event_info event_queue[MAX_EVENTS]; struct slot *slot; struct hpc_ops *hpc_ops; @@ -198,20 +198,15 @@ extern struct controller *pciehp_ctrl_list; static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) { - struct slot *p_slot, *tmp_slot = NULL; - - p_slot = ctrl->slot; + struct slot *slot; - while (p_slot && (p_slot->device != device)) { - tmp_slot = p_slot; - p_slot = p_slot->next; - } - if (p_slot == NULL) { - err("ERROR: pciehp_find_slot device=0x%x\n", device); - p_slot = tmp_slot; + list_for_each_entry(slot, &ctrl->slot_list, slot_list) { + if (slot->device == device) + return slot; } - return p_slot; + err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); + return NULL; } static inline int wait_for_ctrl_irq(struct controller *ctrl) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 051d228e634e..2ddde79e252c 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -160,8 +160,7 @@ static int init_slots(struct controller *ctrl) goto error_info; } - slot->next = ctrl->slot; - ctrl->slot = slot; + list_add(&slot->slot_list, &ctrl->slot_list); } return 0; @@ -175,22 +174,17 @@ error: return retval; } - -static int cleanup_slots (struct controller * ctrl) +static void cleanup_slots(struct controller *ctrl) { - struct slot *old_slot, *next_slot; - - old_slot = ctrl->slot; - ctrl->slot = NULL; + struct list_head *tmp; + struct list_head *next; + struct slot *slot; - while (old_slot) { - next_slot = old_slot->next; - pci_hp_deregister (old_slot->hotplug_slot); - old_slot = next_slot; + list_for_each_safe(tmp, next, &ctrl->slot_list) { + slot = list_entry(tmp, struct slot, slot_list); + list_del(&slot->slot_list); + pci_hp_deregister(slot->hotplug_slot); } - - - return(0); } static int get_ctlr_slot_config(struct controller *ctrl) @@ -368,6 +362,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ err("%s : out of memory\n", __FUNCTION__); goto err_out_none; } + INIT_LIST_HEAD(&ctrl->slot_list); pdev = dev->port; ctrl->pci_dev = pdev; -- cgit v1.2.3 From 48fe39151727db350347e1dba09d71c8ca24207a Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:04 -0800 Subject: pciehp: remove unnecessary php_ctlr The struct php_ctlr seems to be only for complicating codes. This patch removes struct php_ctlr and related codes. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 41 +-- drivers/pci/hotplug/pciehp_core.c | 44 +--- drivers/pci/hotplug/pciehp_ctrl.c | 12 +- drivers/pci/hotplug/pciehp_hpc.c | 517 ++++++++------------------------------ 4 files changed, 120 insertions(+), 494 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index d07ac45f1272..202e4967a941 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -70,30 +70,11 @@ struct event_info { u8 hp_slot; }; -typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); - -struct php_ctlr_state_s { - struct php_ctlr_state_s *pnext; - struct pci_dev *pci_dev; - unsigned int irq; - unsigned long flags; /* spinlock's */ - u32 slot_device_offset; - u32 num_slots; - struct timer_list int_poll_timer; /* Added for poll event */ - php_intr_callback_t attention_button_callback; - php_intr_callback_t switch_change_callback; - php_intr_callback_t presence_change_callback; - php_intr_callback_t power_fault_callback; - void *callback_instance_id; - struct ctrl_reg *creg; /* Ptr to controller register space */ -}; - #define MAX_EVENTS 10 struct controller { struct controller *next; struct mutex crit_sect; /* critical section mutex */ struct mutex ctrl_lock; /* controller lock */ - struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; @@ -113,6 +94,7 @@ struct controller { u8 ctrlcap; u16 vendor_id; u8 cap_base; + struct timer_list poll_timer; }; #define INT_BUTTON_IGNORE 0 @@ -179,10 +161,10 @@ extern void pciehp_event_stop_thread (void); extern int pciehp_enable_slot (struct slot *slot); extern int pciehp_disable_slot (struct slot *slot); -extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id); -extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id); -extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id); -extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); +extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); +extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); +extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); +extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); /* extern void long_delay (int delay); */ /* pci functions */ @@ -229,21 +211,8 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) return retval; } -enum php_ctlr_type { - PCI, - ISA, - ACPI -}; - int pcie_init(struct controller *ctrl, struct pcie_device *dev); -/* This has no meaning for PCI Express, as there is only 1 slot per port */ -int pcie_get_ctlr_slot_config(struct controller *ctrl, - int *num_ctlr_slots, - int *first_device_num, - int *physical_slot_num, - u8 *ctrlcap); - struct hpc_ops { int (*power_on_slot) (struct slot *slot); int (*power_off_slot) (struct slot *slot); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 2ddde79e252c..a315685b2d37 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -187,33 +187,6 @@ static void cleanup_slots(struct controller *ctrl) } } -static int get_ctlr_slot_config(struct controller *ctrl) -{ - int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/ - int first_device_num; /* Not needed */ - int physical_slot_num; - u8 ctrlcap; - int rc; - - rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap); - if (rc) { - err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); - return (-1); - } - - ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */ - ctrl->slot_device_offset = first_device_num; - ctrl->first_slot = physical_slot_num; - ctrl->ctrlcap = ctrlcap; - - dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n", - __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, - ctrl->bus, ctrl->device); - - return (0); -} - - /* * set_attention_status - Turns the Amber LED for a slot on, off or blink */ @@ -352,8 +325,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ int rc; struct controller *ctrl; struct slot *t_slot; - int first_device_num = 0 ; /* first PCI device number supported by this PCIE */ - int num_ctlr_slots; /* number of slots supported by this HPC */ u8 value; struct pci_dev *pdev; @@ -390,18 +361,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, ctrl->bus, ctrl->device, ctrl->function, pdev->irq); - /* - * Save configuration headers for this and subordinate PCI buses - */ - - rc = get_ctlr_slot_config(ctrl); - if (rc) { - err(msg_initialization_err, rc); - goto err_out_free_ctrl_bus; - } - first_device_num = ctrl->slot_device_offset; - num_ctlr_slots = ctrl->num_slots; - /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { @@ -409,7 +368,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ goto err_out_free_ctrl_slot; } - t_slot = pciehp_find_slot(ctrl, first_device_num); + t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); /* Finish setting up the hot plug ctrl device */ ctrl->next_event = 0; @@ -445,7 +404,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ err_out_free_ctrl_slot: cleanup_slots(ctrl); -err_out_free_ctrl_bus: kfree(ctrl->pci_bus); err_out_unmap_mmio_region: ctrl->hpc_ops->release_ctlr(ctrl); diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 372c63e35aa9..5bca9212f5e1 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -48,9 +48,8 @@ static inline char *slot_name(struct slot *p_slot) return p_slot->hotplug_slot->name; } -u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) +u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; u8 getstatus; @@ -101,9 +100,8 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) } -u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) +u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; u8 getstatus; @@ -143,9 +141,8 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) return rc; } -u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) +u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 presence_save, rc = 0; struct event_info *taskInfo; @@ -187,9 +184,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) return rc; } -u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) +u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 rc = 0; struct event_info *taskInfo; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 25d3aadfddbf..ed901b5c2798 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -218,72 +218,50 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct static spinlock_t hpc_event_lock; DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ -static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ static int ctlr_seq_num = 0; /* Controller sequence # */ -static spinlock_t list_lock; -static irqreturn_t pcie_isr(int IRQ, void *dev_id); - -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); +static irqreturn_t pcie_isr(int irq, void *dev_id); +static void start_int_poll_timer(struct controller *ctrl, int sec); /* This is the interrupt polling timeout function. */ -static void int_poll_timeout(unsigned long lphp_ctlr) +static void int_poll_timeout(unsigned long data) { - struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; + struct controller *ctrl = (struct controller *)data; DBG_ENTER_ROUTINE - if ( !php_ctlr ) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return; - } - /* Poll for interrupt events. regs == NULL => polling */ - pcie_isr( 0, (void *)php_ctlr ); - - init_timer(&php_ctlr->int_poll_timer); + pcie_isr(0, ctrl); + init_timer(&ctrl->poll_timer); if (!pciehp_poll_time) pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ - start_int_poll_timer(php_ctlr, pciehp_poll_time); - - return; + start_int_poll_timer(ctrl, pciehp_poll_time); } /* This function starts the interrupt polling timer. */ -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) +static void start_int_poll_timer(struct controller *ctrl, int sec) { - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return; - } - - if ( ( seconds <= 0 ) || ( seconds > 60 ) ) - seconds = 2; /* Clamp to sane value */ - - php_ctlr->int_poll_timer.function = &int_poll_timeout; - php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ - php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ; - add_timer(&php_ctlr->int_poll_timer); - - return; + /* Clamp to sane value */ + if ((sec <= 0) || (sec > 60)) + sec = 2; + + ctrl->poll_timer.function = &int_poll_timeout; + ctrl->poll_timer.data = (unsigned long)ctrl; + ctrl->poll_timer.expires = jiffies + sec * HZ; + add_timer(&ctrl->poll_timer); } static int pcie_write_cmd(struct slot *slot, u16 cmd) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; int retval = 0; u16 slot_status; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); + retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (retval) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return retval; @@ -295,7 +273,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); } - retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); + retval = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); if (retval) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return retval; @@ -307,19 +285,12 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) static int hpc_check_lnk_status(struct controller *ctrl) { - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; u16 lnk_status; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); - + retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); if (retval) { err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; @@ -340,20 +311,14 @@ static int hpc_check_lnk_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_ctrl; u8 atten_led_state; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (retval) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; @@ -385,27 +350,21 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) return 0; } -static int hpc_get_power_status(struct slot * slot, u8 *status) +static int hpc_get_power_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_ctrl; u8 pwr_state; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (retval) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } - dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); pwr_state = (slot_ctrl & PWR_CTRL) >> 10; @@ -428,19 +387,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) static int hpc_get_latch_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_status; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); - + retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (retval) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return retval; @@ -454,20 +407,14 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) static int hpc_get_adapter_status(struct slot *slot, u8 *status) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_status; u8 card_state; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); - + retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (retval) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return retval; @@ -479,22 +426,16 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) return 0; } -static int hpc_query_power_fault(struct slot * slot) +static int hpc_query_power_fault(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_status; u8 pwr_fault; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); - + retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (retval) { err("%s : Cannot check for power fault\n", __FUNCTION__); return retval; @@ -507,24 +448,14 @@ static int hpc_query_power_fault(struct slot * slot) static int hpc_set_attention_status(struct slot *slot, u8 value) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd = 0; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return rc; @@ -556,25 +487,14 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) static void hpc_set_green_led_on(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return ; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return ; - } - - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; @@ -592,25 +512,14 @@ static void hpc_set_green_led_on(struct slot *slot) static void hpc_set_green_led_off(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return ; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return ; - } - - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; @@ -629,25 +538,14 @@ static void hpc_set_green_led_off(struct slot *slot) static void hpc_set_green_led_blink(struct slot *slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 slot_ctrl; int rc = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return ; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return ; - } - - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); - + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return; @@ -664,119 +562,39 @@ static void hpc_set_green_led_blink(struct slot *slot) return; } -int pcie_get_ctlr_slot_config(struct controller *ctrl, - int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */ - int *first_device_num, /* PCI dev num of the first slot in this PCIE */ - int *physical_slot_num, /* phy slot num of the first slot in this PCIE */ - u8 *ctrlcap) -{ - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; - u32 slot_cap; - int rc = 0; - - DBG_ENTER_ROUTINE - - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - *first_device_num = 0; - *num_ctlr_slots = 1; - - rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); - - if (rc) { - err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); - return -1; - } - - *physical_slot_num = slot_cap >> 19; - dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num); - - *ctrlcap = slot_cap & 0x0000007f; - - DBG_LEAVE_ROUTINE - return 0; -} - static void hpc_release_ctlr(struct controller *ctrl) { - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; - struct php_ctlr_state_s *p, *p_prev; - DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return ; - } - - if (pciehp_poll_mode) { - del_timer(&php_ctlr->int_poll_timer); - } else { - if (php_ctlr->irq) { - free_irq(php_ctlr->irq, ctrl); - php_ctlr->irq = 0; - } - } - if (php_ctlr->pci_dev) - php_ctlr->pci_dev = NULL; - - spin_lock(&list_lock); - p = php_ctlr_list_head; - p_prev = NULL; - while (p) { - if (p == php_ctlr) { - if (p_prev) - p_prev->pnext = p->pnext; - else - php_ctlr_list_head = p->pnext; - break; - } else { - p_prev = p; - p = p->pnext; - } - } - spin_unlock(&list_lock); - - kfree(php_ctlr); + if (pciehp_poll_mode) + del_timer(&ctrl->poll_timer); + else + free_irq(ctrl->pci_dev->irq, ctrl); DBG_LEAVE_ROUTINE - } static int hpc_power_on_slot(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 slot_ctrl, slot_status; - int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } /* Clear sticky power-fault bit from previous power failures */ - hp_register_read_word(php_ctlr->pci_dev, - SLOT_STATUS(slot->ctrl->cap_base), slot_status); + hp_register_read_word(ctrl->pci_dev, + SLOT_STATUS(ctrl->cap_base), slot_status); slot_status &= PWR_FAULT_DETECTED; if (slot_status) - hp_register_write_word(php_ctlr->pci_dev, - SLOT_STATUS(slot->ctrl->cap_base), slot_status); - - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + hp_register_write_word(ctrl->pci_dev, + SLOT_STATUS(ctrl->cap_base), slot_status); + retval = hp_register_read_word(ctrl->pci_dev, + SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (retval) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; @@ -807,27 +625,16 @@ static int hpc_power_on_slot(struct slot * slot) static int hpc_power_off_slot(struct slot * slot) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 slot_ctrl; - int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); - slot->hp_slot = 0; - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (retval) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return retval; @@ -861,38 +668,15 @@ static int hpc_power_off_slot(struct slot * slot) return retval; } -static irqreturn_t pcie_isr(int IRQ, void *dev_id) +static irqreturn_t pcie_isr(int irq, void *dev_id) { - struct controller *ctrl = NULL; - struct php_ctlr_state_s *php_ctlr; - u8 schedule_flag = 0; + struct controller *ctrl = (struct controller *)dev_id; u16 slot_status, intr_detect, intr_loc; u16 temp_word; int hp_slot = 0; /* only 1 slot per PCI Express port */ int rc = 0; - if (!dev_id) - return IRQ_NONE; - - if (!pciehp_poll_mode) { - ctrl = dev_id; - php_ctlr = ctrl->hpc_ctlr_handle; - } else { - php_ctlr = dev_id; - ctrl = (struct controller *)php_ctlr->callback_instance_id; - } - - if (!ctrl) { - dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id); - return IRQ_NONE; - } - - if (!php_ctlr) { - dbg("%s: php_ctlr == NULL\n", __FUNCTION__); - return IRQ_NONE; - } - - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; @@ -910,7 +694,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); /* Mask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; @@ -919,13 +703,13 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; @@ -934,7 +718,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) /* Clear command complete interrupt caused by this write */ temp_word = 0x1f; - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; @@ -948,29 +732,28 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) wake_up_interruptible(&ctrl->queue); } - if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED)) - schedule_flag += php_ctlr->switch_change_callback( - hp_slot, php_ctlr->callback_instance_id); - if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED)) - schedule_flag += php_ctlr->attention_button_callback( - hp_slot, php_ctlr->callback_instance_id); - if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED)) - schedule_flag += php_ctlr->presence_change_callback( - hp_slot , php_ctlr->callback_instance_id); - if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED)) - schedule_flag += php_ctlr->power_fault_callback( - hp_slot, php_ctlr->callback_instance_id); + if (intr_loc & MRL_SENS_CHANGED) + pciehp_handle_switch_change(hp_slot, ctrl); + + if (intr_loc & ATTN_BUTTN_PRESSED) + pciehp_handle_attention_button(hp_slot, ctrl); + + if (intr_loc & PRSN_DETECT_CHANGED) + pciehp_handle_presence_change(hp_slot, ctrl); + + if (intr_loc & PWR_FAULT_DETECTED) + pciehp_handle_power_fault(hp_slot, ctrl); /* Clear all events after serving them */ temp_word = 0x1F; - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; } /* Unmask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; @@ -979,13 +762,13 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; @@ -993,7 +776,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) /* Clear command complete interrupt caused by this write */ temp_word = 0x1F; - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); return IRQ_NONE; @@ -1006,25 +789,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; enum pcie_link_speed lnk_speed; u32 lnk_cap; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); - + retval = hp_register_read_dword(ctrl->pci_dev, LNK_CAP(ctrl->cap_base), lnk_cap); if (retval) { err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); return retval; @@ -1047,25 +819,14 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; enum pcie_link_width lnk_wdth; u32 lnk_cap; int retval = 0; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); - + retval = hp_register_read_dword(ctrl->pci_dev, LNK_CAP(ctrl->cap_base), lnk_cap); if (retval) { err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); return retval; @@ -1109,25 +870,14 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; int retval = 0; u16 lnk_status; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); - + retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); if (retval) { err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; @@ -1150,25 +900,14 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value) { - struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; + struct controller *ctrl = slot->ctrl; enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; int retval = 0; u16 lnk_status; DBG_ENTER_ROUTINE - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; - } - - if (slot->hp_slot >= php_ctlr->num_slots) { - err("%s: Invalid HPC slot number!\n", __FUNCTION__); - return -1; - } - - retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); - + retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); if (retval) { err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); return retval; @@ -1305,8 +1044,6 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) int pcie_init(struct controller * ctrl, struct pcie_device *dev) { - struct php_ctlr_state_s *php_ctlr, *p; - void *instance_id = ctrl; int rc; static int first = 1; u16 temp_word; @@ -1319,18 +1056,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) DBG_ENTER_ROUTINE - spin_lock_init(&list_lock); - php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); - - if (!php_ctlr) { /* allocate controller state data */ - err("%s: HPC controller memory allocation error!\n", __FUNCTION__); - goto abort; - } - - memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); - pdev = dev->port; - php_ctlr->pci_dev = pdev; /* save pci_dev in context */ + ctrl->pci_dev = pdev; /* save pci_dev in context */ dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", __FUNCTION__, pdev->vendor, pdev->device); @@ -1359,7 +1086,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_free_ctlr; } - rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); + rc = hp_register_read_dword(ctrl->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); if (rc) { err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); goto abort_free_ctlr; @@ -1371,14 +1098,14 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_free_ctlr; } /* For debugging purpose */ - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); if (rc) { err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_ctlr; @@ -1405,19 +1132,11 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) /* setup wait queue */ init_waitqueue_head(&ctrl->queue); - /* find the IRQ */ - php_ctlr->irq = dev->irq; - - /* Save interrupt callback info */ - php_ctlr->attention_button_callback = pciehp_handle_attention_button; - php_ctlr->switch_change_callback = pciehp_handle_switch_change; - php_ctlr->presence_change_callback = pciehp_handle_presence_change; - php_ctlr->power_fault_callback = pciehp_handle_power_fault; - php_ctlr->callback_instance_id = instance_id; - /* return PCI Controller Info */ - php_ctlr->slot_device_offset = 0; - php_ctlr->num_slots = 1; + ctrl->slot_device_offset = 0; + ctrl->num_slots = 1; + ctrl->first_slot = slot_cap >> 19; + ctrl->ctrlcap = slot_cap & 0x0000007f; /* Mask Hot-plug Interrupt Enable */ rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); @@ -1435,33 +1154,35 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_free_ctlr; } - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } temp_word = 0x1F; /* Clear all events */ - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } - if (pciehp_poll_mode) {/* Install interrupt polling code */ - /* Install and start the interrupt polling timer */ - init_timer(&php_ctlr->int_poll_timer); - start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ + if (pciehp_poll_mode) { + /* Install interrupt polling timer. Start with 10 sec delay */ + init_timer(&ctrl->poll_timer); + start_int_poll_timer(ctrl, 10); } else { /* Installs the interrupt handler */ - rc = request_irq(php_ctlr->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); - dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); + rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, + MY_NAME, (void *)ctrl); + dbg("%s: request_irq %d for hpc%d (returns %d)\n", + __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); if (rc) { - err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); + err("Can't get irq %d for the hotplug controller\n", + ctrl->pci_dev->irq); goto abort_free_ctlr; } } - dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); @@ -1496,14 +1217,14 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); goto abort_free_irq; } - rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); if (rc) { err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_disable_intr; } temp_word = 0x1F; /* Clear all events */ - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_disable_intr; @@ -1518,24 +1239,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_disable_intr; } - /* Add this HPC instance into the HPC list */ - spin_lock(&list_lock); - if (php_ctlr_list_head == 0) { - php_ctlr_list_head = php_ctlr; - p = php_ctlr_list_head; - p->pnext = NULL; - } else { - p = php_ctlr_list_head; - - while (p->pnext) - p = p->pnext; - - p->pnext = php_ctlr; - } - spin_unlock(&list_lock); - ctlr_seq_num++; - ctrl->hpc_ctlr_handle = php_ctlr; ctrl->hpc_ops = &pciehp_hpc_ops; DBG_LEAVE_ROUTINE @@ -1553,14 +1257,13 @@ abort_disable_intr: abort_free_irq: if (pciehp_poll_mode) - del_timer_sync(&php_ctlr->int_poll_timer); + del_timer_sync(&ctrl->poll_timer); else - free_irq(php_ctlr->irq, ctrl); + free_irq(ctrl->pci_dev->irq, ctrl); abort_free_ctlr: pcie_cap_base = saved_cap_base; - kfree(php_ctlr); -abort: + DBG_LEAVE_ROUTINE return -1; } -- cgit v1.2.3 From a8c2b635979823043ea7766dea1d9371773b4d8e Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:05 -0800 Subject: pciehp: remove unused pci_bus from struct controller This patch removes unused pci_bus member from struct controller. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 1 - drivers/pci/hotplug/pciehp_core.c | 14 ++------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 202e4967a941..b505515a07ae 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -78,7 +78,6 @@ struct controller { int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; - struct pci_bus *pci_bus; struct list_head slot_list; struct event_info event_queue[MAX_EVENTS]; struct slot *slot; diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index a315685b2d37..b617613381d6 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -346,13 +346,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ pci_set_drvdata(pdev, ctrl); - ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); - if (!ctrl->pci_bus) { - err("%s: out of memory\n", __FUNCTION__); - rc = -ENOMEM; - goto err_out_unmap_mmio_region; - } - memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); ctrl->bus = pdev->bus->number; /* ctrl bus */ ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ @@ -365,7 +358,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ rc = init_slots(ctrl); if (rc) { err(msg_initialization_err, 6); - goto err_out_free_ctrl_slot; + goto err_out_release_ctlr; } t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); @@ -404,8 +397,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ err_out_free_ctrl_slot: cleanup_slots(ctrl); - kfree(ctrl->pci_bus); -err_out_unmap_mmio_region: +err_out_release_ctlr: ctrl->hpc_ops->release_ctlr(ctrl); err_out_free_ctrl: kfree(ctrl); @@ -439,8 +431,6 @@ static void __exit unload_pciehpd(void) while (ctrl) { cleanup_slots(ctrl); - kfree (ctrl->pci_bus); - ctrl->hpc_ops->release_ctlr(ctrl); tctrl = ctrl; -- cgit v1.2.3 From a0f018daa9955d123b9257b08bcac2d59e295967 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:06 -0800 Subject: pciehp: cleanup register access This patch cleans up register access functions. This has no functional change. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_hpc.c | 301 +++++++++++++++++++++------------------ 1 file changed, 164 insertions(+), 137 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index ed901b5c2798..98eee63f3ec5 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -107,32 +107,29 @@ enum ctrl_offsets { }; static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ -#define PCIE_CAP_ID(cb) ( cb + PCIECAPID ) -#define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR ) -#define CAP_REG(cb) ( cb + CAPREG ) -#define DEV_CAP(cb) ( cb + DEVCAP ) -#define DEV_CTRL(cb) ( cb + DEVCTRL ) -#define DEV_STATUS(cb) ( cb + DEVSTATUS ) -#define LNK_CAP(cb) ( cb + LNKCAP ) -#define LNK_CTRL(cb) ( cb + LNKCTRL ) -#define LNK_STATUS(cb) ( cb + LNKSTATUS ) -#define SLOT_CAP(cb) ( cb + SLOTCAP ) -#define SLOT_CTRL(cb) ( cb + SLOTCTRL ) -#define SLOT_STATUS(cb) ( cb + SLOTSTATUS ) -#define ROOT_CTRL(cb) ( cb + ROOTCTRL ) -#define ROOT_STATUS(cb) ( cb + ROOTSTATUS ) - -#define hp_register_read_word(pdev, reg , value) \ - pci_read_config_word(pdev, reg, &value) - -#define hp_register_read_dword(pdev, reg , value) \ - pci_read_config_dword(pdev, reg, &value) - -#define hp_register_write_word(pdev, reg , value) \ - pci_write_config_word(pdev, reg, value) - -#define hp_register_dwrite_word(pdev, reg , value) \ - pci_write_config_dword(pdev, reg, value) +static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) +{ + struct pci_dev *dev = ctrl->pci_dev; + return pci_read_config_word(dev, ctrl->cap_base + reg, value); +} + +static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) +{ + struct pci_dev *dev = ctrl->pci_dev; + return pci_read_config_dword(dev, ctrl->cap_base + reg, value); +} + +static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) +{ + struct pci_dev *dev = ctrl->pci_dev; + return pci_write_config_word(dev, ctrl->cap_base + reg, value); +} + +static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) +{ + struct pci_dev *dev = ctrl->pci_dev; + return pci_write_config_dword(dev, ctrl->cap_base + reg, value); +} /* Field definitions in PCI Express Capabilities Register */ #define CAP_VER 0x000F @@ -260,22 +257,22 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) u16 slot_status; DBG_ENTER_ROUTINE - - retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); - return retval; - } - + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + return retval; + } + if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue the next command according to spec. Just print out the error message */ dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); } - retval = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); + retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); if (retval) { - err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); return retval; } @@ -290,9 +287,9 @@ static int hpc_check_lnk_status(struct controller *ctrl) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); + retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); return retval; } @@ -318,13 +315,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return retval; } - dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); + dbg("%s: SLOTCTRL %x, value read %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; @@ -359,12 +357,13 @@ static int hpc_get_power_status(struct slot *slot, u8 *status) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return retval; } - dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + dbg("%s: SLOTCTRL %x value read %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); pwr_state = (slot_ctrl & PWR_CTRL) >> 10; @@ -393,9 +392,9 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); return retval; } @@ -414,9 +413,9 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); return retval; } card_state = (u8)((slot_status & PRSN_STATE) >> 6); @@ -435,9 +434,9 @@ static int hpc_query_power_fault(struct slot *slot) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : Cannot check for power fault\n", __FUNCTION__); + err("%s: Cannot check for power fault\n", __FUNCTION__); return retval; } pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); @@ -455,9 +454,9 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) DBG_ENTER_ROUTINE - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return rc; } @@ -478,7 +477,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE return rc; @@ -494,9 +494,9 @@ static void hpc_set_green_led_on(struct slot *slot) DBG_ENTER_ROUTINE - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return; } slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; @@ -505,7 +505,8 @@ static void hpc_set_green_led_on(struct slot *slot) pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE return; } @@ -519,9 +520,9 @@ static void hpc_set_green_led_off(struct slot *slot) DBG_ENTER_ROUTINE - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return; } @@ -530,7 +531,8 @@ static void hpc_set_green_led_off(struct slot *slot) if (!pciehp_poll_mode) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE return; @@ -545,9 +547,9 @@ static void hpc_set_green_led_blink(struct slot *slot) DBG_ENTER_ROUTINE - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return; } @@ -557,7 +559,8 @@ static void hpc_set_green_led_blink(struct slot *slot) slot_cmd = slot_cmd | HP_INTR_ENABLE; pcie_write_cmd(slot, slot_cmd); - dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE return; } @@ -586,17 +589,24 @@ static int hpc_power_on_slot(struct slot * slot) dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); /* Clear sticky power-fault bit from previous power failures */ - hp_register_read_word(ctrl->pci_dev, - SLOT_STATUS(ctrl->cap_base), slot_status); + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + if (retval) { + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); + return retval; + } slot_status &= PWR_FAULT_DETECTED; - if (slot_status) - hp_register_write_word(ctrl->pci_dev, - SLOT_STATUS(ctrl->cap_base), slot_status); + if (slot_status) { + retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); + if (retval) { + err("%s: Cannot write to SLOTSTATUS register\n", + __FUNCTION__); + return retval; + } + } - retval = hp_register_read_word(ctrl->pci_dev, - SLOT_CTRL(ctrl->cap_base), slot_ctrl); + retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return retval; } @@ -616,7 +626,8 @@ static int hpc_power_on_slot(struct slot * slot) err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); return -1; } - dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE @@ -634,9 +645,9 @@ static int hpc_power_off_slot(struct slot * slot) dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); - retval = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); return retval; } @@ -661,7 +672,8 @@ static int hpc_power_off_slot(struct slot * slot) err("%s: Write command failed!\n", __FUNCTION__); return -1; } - dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); + dbg("%s: SLOTCTRL %x write cmd %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); DBG_LEAVE_ROUTINE @@ -676,9 +688,9 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) int hp_slot = 0; /* only 1 slot per PCI Express port */ int rc = 0; - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); return IRQ_NONE; } @@ -694,33 +706,38 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); /* Mask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOT_CTRL register\n", + __FUNCTION__); return IRQ_NONE; } - dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); + dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n", + __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; - - rc = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTCTRL register\n", + __FUNCTION__); return IRQ_NONE; } - - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOT_STATUS register\n", + __FUNCTION__); return IRQ_NONE; } - dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); + dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n", + __FUNCTION__, slot_status); /* Clear command complete interrupt caused by this write */ temp_word = 0x1f; - rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTSTATUS register\n", + __FUNCTION__); return IRQ_NONE; } } @@ -746,42 +763,47 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) /* Clear all events after serving them */ temp_word = 0x1F; - rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); return IRQ_NONE; } /* Unmask Hot-plug Interrupt Enable */ if (!pciehp_poll_mode) { - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", + __FUNCTION__); return IRQ_NONE; } dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; - rc = hp_register_write_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTCTRL register\n", + __FUNCTION__); return IRQ_NONE; } - - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOT_STATUS register\n", + __FUNCTION__); return IRQ_NONE; } /* Clear command complete interrupt caused by this write */ temp_word = 0x1F; - rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTSTATUS failed\n", + __FUNCTION__); return IRQ_NONE; } - dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); + dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n", + __FUNCTION__, temp_word); } return IRQ_HANDLED; @@ -796,9 +818,9 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) DBG_ENTER_ROUTINE - retval = hp_register_read_dword(ctrl->pci_dev, LNK_CAP(ctrl->cap_base), lnk_cap); + retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); if (retval) { - err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); + err("%s: Cannot read LNKCAP register\n", __FUNCTION__); return retval; } @@ -826,9 +848,9 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value DBG_ENTER_ROUTINE - retval = hp_register_read_dword(ctrl->pci_dev, LNK_CAP(ctrl->cap_base), lnk_cap); + retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); if (retval) { - err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); + err("%s: Cannot read LNKCAP register\n", __FUNCTION__); return retval; } @@ -877,9 +899,9 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); + retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); return retval; } @@ -907,9 +929,9 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value DBG_ENTER_ROUTINE - retval = hp_register_read_word(ctrl->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); + retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); return retval; } @@ -1073,12 +1095,13 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); - rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg); + rc = pciehp_readw(ctrl, CAPREG, &cap_reg); if (rc) { - err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); + err("%s: Cannot read CAPREG register\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg); + dbg("%s: CAPREG offset %x cap_reg %x\n", + __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { @@ -1086,31 +1109,34 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_free_ctlr; } - rc = hp_register_read_dword(ctrl->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); + rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); if (rc) { - err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap); + dbg("%s: SLOTCAP offset %x slot_cap %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); if (!(slot_cap & HP_CAP)) { dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); goto abort_free_ctlr; } /* For debugging purpose */ - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); + dbg("%s: SLOTSTATUS offset %x slot_status %x\n", + __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); - rc = hp_register_read_word(ctrl->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); + dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); if (first) { spin_lock_init(&hpc_event_lock); @@ -1139,31 +1165,32 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ctrl->ctrlcap = slot_cap & 0x0000007f; /* Mask Hot-plug Interrupt Enable */ - rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); + dbg("%s: SLOTCTRL %x value read %x\n", + __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; - rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); goto abort_free_ctlr; } - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); goto abort_free_ctlr; } temp_word = 0x1F; /* Clear all events */ - rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); goto abort_free_ctlr; } @@ -1186,9 +1213,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); - rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { - err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); goto abort_free_irq; } @@ -1212,21 +1239,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) } /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ - rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); goto abort_free_irq; } - rc = hp_register_read_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); + rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (rc) { - err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); goto abort_disable_intr; } temp_word = 0x1F; /* Clear all events */ - rc = hp_register_write_word(ctrl->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); if (rc) { - err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); goto abort_disable_intr; } @@ -1247,10 +1274,10 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) /* We end up here for the many possible ways to fail this API. */ abort_disable_intr: - rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (!rc) { temp_word &= ~(intr_enable | HP_INTR_ENABLE); - rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); + rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); } if (rc) err("%s : disabling interrupts failed\n", __FUNCTION__); -- cgit v1.2.3 From 15232ece5566710d24c81ac3dd629f7556a92818 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:07 -0800 Subject: pciehp: cleanup pciehp.h This patch cleans up pciehp.h. This has no functional change. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 101 ++++++++++++++------------------------ drivers/pci/hotplug/pciehp_core.c | 2 +- drivers/pci/hotplug/pciehp_ctrl.c | 6 +-- 3 files changed, 42 insertions(+), 67 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index b505515a07ae..e4524cf02427 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -44,11 +44,17 @@ extern int pciehp_poll_time; extern int pciehp_debug; extern int pciehp_force; -/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ -#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) -#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) +#define dbg(format, arg...) \ + do { \ + if (pciehp_debug) \ + printk("%s: " format, MY_NAME , ## arg); \ + } while (0) +#define err(format, arg...) \ + printk(KERN_ERR "%s: " format, MY_NAME , ## arg) +#define info(format, arg...) \ + printk(KERN_INFO "%s: " format, MY_NAME , ## arg) +#define warn(format, arg...) \ + printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) #define SLOT_NAME_SIZE 10 struct slot { @@ -113,8 +119,6 @@ struct controller { #define POWERON_STATE 3 #define POWEROFF_STATE 4 -#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 - /* Error messages */ #define INTERLOCK_OPEN 0x00000002 #define ADD_NOT_SUPPORTED 0x00000003 @@ -126,10 +130,6 @@ struct controller { #define WRONG_BUS_FREQUENCY 0x0000000D #define POWER_FAILURE 0x0000000E -#define REMOVE_NOT_SUPPORTED 0x00000003 - -#define DISABLE_CARD 1 - /* Field definitions in Slot Capabilities Register */ #define ATTN_BUTTN_PRSN 0x00000001 #define PWR_CTRL_PRSN 0x00000002 @@ -145,38 +145,21 @@ struct controller { #define PWR_LED(cap) (cap & PWR_LED_PRSN) #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) -/* - * error Messages - */ -#define msg_initialization_err "Initialization failure, error=%d\n" -#define msg_button_on "PCI slot #%s - powering on due to button press.\n" -#define msg_button_off "PCI slot #%s - powering off due to button press.\n" -#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" -#define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" - -/* controller functions */ -extern int pciehp_event_start_thread (void); -extern void pciehp_event_stop_thread (void); -extern int pciehp_enable_slot (struct slot *slot); -extern int pciehp_disable_slot (struct slot *slot); - +extern int pciehp_event_start_thread(void); +extern void pciehp_event_stop_thread(void); +extern int pciehp_enable_slot(struct slot *slot); +extern int pciehp_disable_slot(struct slot *slot); extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); -/* extern void long_delay (int delay); */ - -/* pci functions */ -extern int pciehp_configure_device (struct slot *p_slot); -extern int pciehp_unconfigure_device (struct slot *p_slot); - - +extern int pciehp_configure_device(struct slot *p_slot); +extern int pciehp_unconfigure_device(struct slot *p_slot); +int pcie_init(struct controller *ctrl, struct pcie_device *dev); /* Global variables */ extern struct controller *pciehp_ctrl_list; -/* Inline functions */ - static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) { struct slot *slot; @@ -192,8 +175,6 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) static inline int wait_for_ctrl_irq(struct controller *ctrl) { - int retval = 0; - DECLARE_WAITQUEUE(wait, current); add_wait_queue(&ctrl->queue, &wait); @@ -205,44 +186,38 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) remove_wait_queue(&ctrl->queue, &wait); if (signal_pending(current)) - retval = -EINTR; + return -EINTR; - return retval; + return 0; } -int pcie_init(struct controller *ctrl, struct pcie_device *dev); - struct hpc_ops { - int (*power_on_slot) (struct slot *slot); - int (*power_off_slot) (struct slot *slot); - int (*get_power_status) (struct slot *slot, u8 *status); - int (*get_attention_status) (struct slot *slot, u8 *status); - int (*set_attention_status) (struct slot *slot, u8 status); - int (*get_latch_status) (struct slot *slot, u8 *status); - int (*get_adapter_status) (struct slot *slot, u8 *status); - - int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); - int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); - - int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value); - int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value); - - int (*query_power_fault) (struct slot *slot); - void (*green_led_on) (struct slot *slot); - void (*green_led_off) (struct slot *slot); - void (*green_led_blink) (struct slot *slot); - void (*release_ctlr) (struct controller *ctrl); - int (*check_lnk_status) (struct controller *ctrl); + int (*power_on_slot)(struct slot *slot); + int (*power_off_slot)(struct slot *slot); + int (*get_power_status)(struct slot *slot, u8 *status); + int (*get_attention_status)(struct slot *slot, u8 *status); + int (*set_attention_status)(struct slot *slot, u8 status); + int (*get_latch_status)(struct slot *slot, u8 *status); + int (*get_adapter_status)(struct slot *slot, u8 *status); + int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); + int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); + int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); + int (*get_cur_lnk_width)(struct slot *slot, enum pcie_link_width *val); + int (*query_power_fault)(struct slot *slot); + void (*green_led_on)(struct slot *slot); + void (*green_led_off)(struct slot *slot); + void (*green_led_blink)(struct slot *slot); + void (*release_ctlr)(struct controller *ctrl); + int (*check_lnk_status)(struct controller *ctrl); }; - #ifdef CONFIG_ACPI #include #include #include #include -#define pciehp_get_hp_hw_control_from_firmware(dev) \ +#define pciehp_get_hp_hw_control_from_firmware(dev) \ pciehp_acpi_get_hp_hw_control_from_firmware(dev) static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, struct hotplug_params *hpp) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index b617613381d6..e2d45662bdbf 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -357,7 +357,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { - err(msg_initialization_err, 6); + err("%s: slot initialization failed\n", PCIE_MODULE_NAME); goto err_out_release_ctlr; } diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 5bca9212f5e1..072befa345a7 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -655,7 +655,7 @@ static void interrupt_event_handler(struct controller *ctrl) warn("Not a valid state\n"); return; } - info(msg_button_cancel, slot_name(p_slot)); + info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); p_slot->state = STATIC_STATE; } /* ***********Button Pressed (No action on 1st press...) */ @@ -668,12 +668,12 @@ static void interrupt_event_handler(struct controller *ctrl) /* slot is on */ dbg("slot is on\n"); p_slot->state = BLINKINGOFF_STATE; - info(msg_button_off, slot_name(p_slot)); + info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); } else { /* slot is off */ dbg("slot is off\n"); p_slot->state = BLINKINGON_STATE; - info(msg_button_on, slot_name(p_slot)); + info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); } /* Wait for exclusive access to hardware */ -- cgit v1.2.3 From 75e13178af33e20b5802885f637af2a82c64ac2c Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:08 -0800 Subject: pciehp: remove unused pcie_cap_base This patch removes unused pcie_cap_base variable. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_hpc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 98eee63f3ec5..d8f4f1241b56 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -105,7 +105,6 @@ enum ctrl_offsets { ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl), ROOTSTATUS = offsetof(struct ctrl_reg, root_status), }; -static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) { @@ -1072,7 +1071,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) u16 cap_reg; u16 intr_enable = 0; u32 slot_cap; - int cap_base, saved_cap_base; + int cap_base; u16 slot_status, slot_ctrl; struct pci_dev *pdev; @@ -1084,8 +1083,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", __FUNCTION__, pdev->vendor, pdev->device); - saved_cap_base = pcie_cap_base; - if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); goto abort_free_ctlr; @@ -1093,7 +1090,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) ctrl->cap_base = cap_base; - dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); + dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base); rc = pciehp_readw(ctrl, CAPREG, &cap_reg); if (rc) { @@ -1289,8 +1286,6 @@ abort_free_irq: free_irq(ctrl->pci_dev->irq, ctrl); abort_free_ctlr: - pcie_cap_base = saved_cap_base; - DBG_LEAVE_ROUTINE return -1; } -- cgit v1.2.3 From 44ef4cefb0168740184ee3d7d18254339741e9d5 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:09 -0800 Subject: pciehp: cleanup wait command completion This patch cleans up the code to wait for command completion. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 18 ---- drivers/pci/hotplug/pciehp_core.c | 14 +-- drivers/pci/hotplug/pciehp_ctrl.c | 205 +++++++++----------------------------- drivers/pci/hotplug/pciehp_hpc.c | 38 ++++++- 4 files changed, 82 insertions(+), 193 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index e4524cf02427..17167d594472 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -173,24 +173,6 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) return NULL; } -static inline int wait_for_ctrl_irq(struct controller *ctrl) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&ctrl->queue, &wait); - if (!pciehp_poll_mode) - /* Sleep for up to 1 second */ - msleep_interruptible(1000); - else - msleep_interruptible(2500); - - remove_wait_queue(&ctrl->queue, &wait); - if (signal_pending(current)) - return -EINTR; - - return 0; -} - struct hpc_ops { int (*power_on_slot)(struct slot *slot); int (*power_off_slot)(struct slot *slot); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index e2d45662bdbf..f7b8e0504fec 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -374,25 +374,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ pciehp_ctrl_list = ctrl; } - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ - if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ - if (rc) { - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + if (rc) goto err_out_free_ctrl_slot; - } else - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); } - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); - return 0; err_out_free_ctrl_slot: diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 072befa345a7..4283ef56dbd9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -229,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) static void set_slot_off(struct controller *ctrl, struct slot * pslot) { - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ if (POWER_CTRL(ctrl->ctrlcap)) { if (pslot->hpc_ops->power_off_slot(pslot)) { - err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); + err("%s: Issue of Slot Power Off command failed\n", + __FUNCTION__); return; } - wait_for_ctrl_irq (ctrl); } - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) pslot->hpc_ops->green_led_off(pslot); - wait_for_ctrl_irq (ctrl); - } - if (ATTN_LED(ctrl->ctrlcap)) { - if (pslot->hpc_ops->set_attention_status(pslot, 1)) { - err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); + if (ATTN_LED(ctrl->ctrlcap)) { + if (pslot->hpc_ops->set_attention_status(pslot, 1)) { + err("%s: Issue of Set Attention Led command failed\n", + __FUNCTION__); return; } - wait_for_ctrl_irq (ctrl); } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); } /** @@ -270,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) static int board_added(struct slot *p_slot) { u8 hp_slot; - int rc = 0; + int retval = 0; struct controller *ctrl = p_slot->ctrl; hp_slot = p_slot->device - ctrl->slot_device_offset; @@ -279,53 +269,38 @@ static int board_added(struct slot *p_slot) __FUNCTION__, p_slot->device, ctrl->slot_device_offset, hp_slot); - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - if (POWER_CTRL(ctrl->ctrlcap)) { /* Power on slot */ - rc = p_slot->hpc_ops->power_on_slot(p_slot); - if (rc) { - mutex_unlock(&ctrl->ctrl_lock); - return -1; - } - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); + retval = p_slot->hpc_ops->power_on_slot(p_slot); + if (retval) + return retval; } - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_blink(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); /* Wait for ~1 second */ - wait_for_ctrl_irq (ctrl); + msleep(1000); - /* Check link training status */ - rc = p_slot->hpc_ops->check_lnk_status(ctrl); - if (rc) { + /* Check link training status */ + retval = p_slot->hpc_ops->check_lnk_status(ctrl); + if (retval) { err("%s: Failed to check link status\n", __FUNCTION__); set_slot_off(ctrl, p_slot); - return rc; + return retval; } /* Check for a power fault */ if (p_slot->hpc_ops->query_power_fault(p_slot)) { dbg("%s: power fault detected\n", __FUNCTION__); - rc = POWER_FAILURE; + retval = POWER_FAILURE; goto err_exit; } - rc = pciehp_configure_device(p_slot); - if (rc) { + retval = pciehp_configure_device(p_slot); + if (retval) { err("Cannot add device 0x%x:%x\n", p_slot->bus, - p_slot->device); + p_slot->device); goto err_exit; } @@ -334,26 +309,16 @@ static int board_added(struct slot *p_slot) */ if (pcie_mch_quirk) pci_fixup_device(pci_fixup_final, ctrl->pci_dev); - if (PWR_LED(ctrl->ctrlcap)) { - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_on(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); - } + return 0; err_exit: set_slot_off(ctrl, p_slot); - return -1; + return retval; } - /** * remove_board - Turns off slot and LED's * @@ -362,44 +327,32 @@ static int remove_board(struct slot *p_slot) { u8 device; u8 hp_slot; - int rc; + int retval = 0; struct controller *ctrl = p_slot->ctrl; - if (pciehp_unconfigure_device(p_slot)) - return 1; + retval = pciehp_unconfigure_device(p_slot); + if (retval) + return retval; device = p_slot->device; - hp_slot = p_slot->device - ctrl->slot_device_offset; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - if (POWER_CTRL(ctrl->ctrlcap)) { /* power off slot */ - rc = p_slot->hpc_ops->power_off_slot(p_slot); - if (rc) { - err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->ctrl_lock); - return rc; + retval = p_slot->hpc_ops->power_off_slot(p_slot); + if (retval) { + err("%s: Issue of Slot Disable command failed\n", + __FUNCTION__); + return retval; } - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); } - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) /* turn off Green LED */ p_slot->hpc_ops->green_led_off(p_slot); - - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); return 0; } @@ -444,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot) dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, p_slot->bus, p_slot->device); - if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { - /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->ctrl_lock); - + if (pciehp_enable_slot(p_slot) && + PWR_LED(p_slot->ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->ctrl_lock); - } p_slot->state = STATIC_STATE; } @@ -494,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot) dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, p_slot->bus, p_slot->device); - if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { - /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->ctrl_lock); - + if (pciehp_enable_slot(p_slot) && + PWR_LED(p_slot->ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (p_slot->ctrl); - - /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->ctrl_lock); - } p_slot->state = STATIC_STATE; } @@ -616,40 +553,18 @@ static void interrupt_event_handler(struct controller *ctrl) switch (p_slot->state) { case BLINKINGOFF_STATE: - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_on(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - if (ATTN_LED(ctrl->ctrlcap)) { - p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); break; case BLINKINGON_STATE: - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - if (ATTN_LED(ctrl->ctrlcap)){ - p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); break; default: warn("Not a valid state\n"); @@ -676,26 +591,13 @@ static void interrupt_event_handler(struct controller *ctrl) info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); } - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - /* blink green LED and turn off amber */ - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_blink(p_slot); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - if (ATTN_LED(ctrl->ctrlcap)) { + if (ATTN_LED(ctrl->ctrlcap)) p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Wait for the command to complete */ - wait_for_ctrl_irq (ctrl); - } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); - init_timer(&p_slot->task_event); p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; @@ -708,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl) else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { if (POWER_CTRL(ctrl->ctrlcap)) { dbg("power fault\n"); - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->ctrl_lock); - - if (ATTN_LED(ctrl->ctrlcap)) { + if (ATTN_LED(ctrl->ctrlcap)) p_slot->hpc_ops->set_attention_status(p_slot, 1); - wait_for_ctrl_irq (ctrl); - } - if (PWR_LED(ctrl->ctrlcap)) { + if (PWR_LED(ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - wait_for_ctrl_irq (ctrl); - } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->ctrl_lock); } } /***********SURPRISE REMOVAL********************/ @@ -750,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl) } } - int pciehp_enable_slot(struct slot *p_slot) { u8 getstatus = 0; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index d8f4f1241b56..9fbd9b9f9824 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -249,6 +249,24 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) add_timer(&ctrl->poll_timer); } +static inline int pcie_wait_cmd(struct controller *ctrl) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&ctrl->queue, &wait); + if (!pciehp_poll_mode) + /* Sleep for up to 1 second */ + msleep_interruptible(1000); + else + msleep_interruptible(2500); + + remove_wait_queue(&ctrl->queue, &wait); + if (signal_pending(current)) + return -EINTR; + + return 0; +} + static int pcie_write_cmd(struct slot *slot, u16 cmd) { struct controller *ctrl = slot->ctrl; @@ -257,24 +275,34 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) DBG_ENTER_ROUTINE + mutex_lock(&ctrl->ctrl_lock); + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); - return retval; + goto out; } if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { - /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue - the next command according to spec. Just print out the error message */ - dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); + /* After 1 sec and CMD_COMPLETED still not set, just + proceed forward to issue the next command according + to spec. Just print out the error message */ + dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", + __FUNCTION__); } retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); if (retval) { err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); - return retval; + goto out; } + /* + * Wait for command completion. + */ + retval = pcie_wait_cmd(ctrl); + out: + mutex_unlock(&ctrl->ctrl_lock); DBG_LEAVE_ROUTINE return retval; } -- cgit v1.2.3 From 262303fe329a51463925f3749aafc358a4201397 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Dec 2006 17:01:10 -0800 Subject: pciehp: fix wait command completion This patch fixes this problem that pciehp driver will sleep unnecessarily long when waiting for command completion. With this patch, modprobe pciehp driver becomes very faster as follows for instance. o Without this patch # time /sbin/modprobe pciehp real 0m4.976s user 0m0.000s sys 0m0.004s o With this patch # time /sbin/modprobe pciehp real 0m0.640s user 0m0.000s sys 0m0.004s Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 1 + drivers/pci/hotplug/pciehp_hpc.c | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 17167d594472..927dba9911ed 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -100,6 +100,7 @@ struct controller { u16 vendor_id; u8 cap_base; struct timer_list poll_timer; + volatile int cmd_busy; }; #define INT_BUTTON_IGNORE 0 diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9fbd9b9f9824..eb1862b50bb1 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) static inline int pcie_wait_cmd(struct controller *ctrl) { - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&ctrl->queue, &wait); - if (!pciehp_poll_mode) - /* Sleep for up to 1 second */ - msleep_interruptible(1000); - else - msleep_interruptible(2500); + int retval = 0; + unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; + unsigned long timeout = msecs_to_jiffies(msecs); + int rc; - remove_wait_queue(&ctrl->queue, &wait); - if (signal_pending(current)) - return -EINTR; + rc = wait_event_interruptible_timeout(ctrl->queue, + !ctrl->cmd_busy, timeout); + if (!rc) + dbg("Command not completed in 1000 msec\n"); + else if (rc < 0) { + retval = -EINTR; + info("Command was interrupted by a signal\n"); + } - return 0; + return retval; } static int pcie_write_cmd(struct slot *slot, u16 cmd) @@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) __FUNCTION__); } + ctrl->cmd_busy = 1; retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); if (retval) { err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); @@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) /* * Command Complete Interrupt Pending */ + ctrl->cmd_busy = 0; wake_up_interruptible(&ctrl->queue); } -- cgit v1.2.3 From 34d03419f03bcfdf70d9617a9b90b60c93482c4a Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Tue, 9 Jan 2007 13:02:36 -0800 Subject: PCIEHP: Add Electro Mechanical Interlock (EMI) support to the PCIE hotplug driver. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 5 ++ drivers/pci/hotplug/pciehp_core.c | 103 ++++++++++++++++++++++++++++++++++++++ drivers/pci/hotplug/pciehp_hpc.c | 55 ++++++++++++++++++++ 3 files changed, 163 insertions(+) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 927dba9911ed..d19fcae8a7c0 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -69,6 +69,7 @@ struct slot { struct hotplug_slot *hotplug_slot; struct list_head slot_list; char name[SLOT_NAME_SIZE]; + unsigned long last_emi_toggle; }; struct event_info { @@ -138,6 +139,7 @@ struct controller { #define ATTN_LED_PRSN 0x00000008 #define PWR_LED_PRSN 0x00000010 #define HP_SUPR_RM_SUP 0x00000020 +#define EMI_PRSN 0x00020000 #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) @@ -145,6 +147,7 @@ struct controller { #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) #define PWR_LED(cap) (cap & PWR_LED_PRSN) #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) +#define EMI(cap) (cap & EMI_PRSN) extern int pciehp_event_start_thread(void); extern void pciehp_event_stop_thread(void); @@ -182,6 +185,8 @@ struct hpc_ops { int (*set_attention_status)(struct slot *slot, u8 status); int (*get_latch_status)(struct slot *slot, u8 *status); int (*get_adapter_status)(struct slot *slot, u8 *status); + int (*get_emi_status)(struct slot *slot, u8 *status); + int (*toggle_emi)(struct slot *slot); int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index f7b8e0504fec..a92eda6e02f6 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -34,6 +34,7 @@ #include #include "pciehp.h" #include +#include /* Global variables */ int pciehp_debug; @@ -87,6 +88,95 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { .get_cur_bus_speed = get_cur_bus_speed, }; +/* + * Check the status of the Electro Mechanical Interlock (EMI) + */ +static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value) +{ + struct slot *slot = hotplug_slot->private; + return (slot->hpc_ops->get_emi_status(slot, value)); +} + +/* + * sysfs interface for the Electro Mechanical Interlock (EMI) + * 1 == locked, 0 == unlocked + */ +static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf) +{ + int retval; + u8 value; + + retval = get_lock_status(slot, &value); + if (retval) + goto lock_read_exit; + retval = sprintf (buf, "%d\n", value); + +lock_read_exit: + return retval; +} + +/* + * Change the status of the Electro Mechanical Interlock (EMI) + * This is a toggle - in addition there must be at least 1 second + * in between toggles. + */ +static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) +{ + struct slot *slot = hotplug_slot->private; + int retval; + u8 value; + + mutex_lock(&slot->ctrl->crit_sect); + + /* has it been >1 sec since our last toggle? */ + if ((get_seconds() - slot->last_emi_toggle) < 1) + return -EINVAL; + + /* see what our current state is */ + retval = get_lock_status(hotplug_slot, &value); + if (retval || (value == status)) + goto set_lock_exit; + + slot->hpc_ops->toggle_emi(slot); +set_lock_exit: + mutex_unlock(&slot->ctrl->crit_sect); + return 0; +} + +/* + * sysfs interface which allows the user to toggle the Electro Mechanical + * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock + */ +static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, + size_t count) +{ + unsigned long llock; + u8 lock; + int retval = 0; + + llock = simple_strtoul(buf, NULL, 10); + lock = (u8)(llock & 0xff); + + switch (lock) { + case 0: + case 1: + retval = set_lock_status(slot, lock); + break; + default: + err ("%d is an invalid lock value\n", lock); + retval = -EINVAL; + } + if (retval) + return retval; + return count; +} + +static struct hotplug_slot_attribute hotplug_slot_attr_lock = { + .attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = lock_read_file, + .store = lock_write_file +}; + /** * release_slot - free up the memory used by a slot * @hotplug_slot: slot to free @@ -159,6 +249,16 @@ static int init_slots(struct controller *ctrl) err ("pci_hp_register failed with error %d\n", retval); goto error_info; } + /* create additional sysfs entries */ + if (EMI(ctrl->ctrlcap)) { + retval = sysfs_create_file(&hotplug_slot->kobj, + &hotplug_slot_attr_lock.attr); + if (retval) { + pci_hp_deregister(hotplug_slot); + err("cannot create additional sysfs entries\n"); + goto error_info; + } + } list_add(&slot->slot_list, &ctrl->slot_list); } @@ -183,6 +283,9 @@ static void cleanup_slots(struct controller *ctrl) list_for_each_safe(tmp, next, &ctrl->slot_list) { slot = list_entry(tmp, struct slot, slot_list); list_del(&slot->slot_list); + if (EMI(ctrl->ctrlcap)) + sysfs_remove_file(&slot->hotplug_slot->kobj, + &hotplug_slot_attr_lock.attr); pci_hp_deregister(slot->hotplug_slot); } } diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index eb1862b50bb1..fbc64aa2dd68 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "../pci.h" #include "pciehp.h" @@ -192,6 +193,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define ATTN_LED_CTRL 0x00C0 #define PWR_LED_CTRL 0x0300 #define PWR_CTRL 0x0400 +#define EMI_CTRL 0x0800 /* Attention indicator and Power indicator states */ #define LED_ON 0x01 @@ -202,6 +204,10 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define POWER_ON 0 #define POWER_OFF 0x0400 +/* EMI Status defines */ +#define EMI_DISENGAGED 0 +#define EMI_ENGAGED 1 + /* Field definitions in Slot Status Register */ #define ATTN_BUTTN_PRESSED 0x0001 #define PWR_FAULT_DETECTED 0x0002 @@ -210,6 +216,8 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define CMD_COMPLETED 0x0010 #define MRL_STATE 0x0020 #define PRSN_STATE 0x0040 +#define EMI_STATE 0x0080 +#define EMI_STATUS_BIT 7 static spinlock_t hpc_event_lock; @@ -474,6 +482,51 @@ static int hpc_query_power_fault(struct slot *slot) return pwr_fault; } +static int hpc_get_emi_status(struct slot *slot, u8 *status) +{ + struct controller *ctrl = slot->ctrl; + u16 slot_status; + int retval = 0; + + DBG_ENTER_ROUTINE + + retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); + if (retval) { + err("%s : Cannot check EMI status\n", __FUNCTION__); + return retval; + } + *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; + + DBG_LEAVE_ROUTINE + return retval; +} + +static int hpc_toggle_emi(struct slot *slot) +{ + struct controller *ctrl = slot->ctrl; + u16 slot_cmd = 0; + u16 slot_ctrl; + int rc = 0; + + DBG_ENTER_ROUTINE + + rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); + if (rc) { + err("%s : hp_register_read_word SLOT_CTRL failed\n", + __FUNCTION__); + return rc; + } + + slot_cmd = (slot_ctrl | EMI_CTRL); + if (!pciehp_poll_mode) + slot_cmd = slot_cmd | HP_INTR_ENABLE; + + pcie_write_cmd(slot, slot_cmd); + slot->last_emi_toggle = get_seconds(); + DBG_LEAVE_ROUTINE + return rc; +} + static int hpc_set_attention_status(struct slot *slot, u8 value) { struct controller *ctrl = slot->ctrl; @@ -1009,6 +1062,8 @@ static struct hpc_ops pciehp_hpc_ops = { .get_attention_status = hpc_get_attention_status, .get_latch_status = hpc_get_latch_status, .get_adapter_status = hpc_get_adapter_status, + .get_emi_status = hpc_get_emi_status, + .toggle_emi = hpc_toggle_emi, .get_max_bus_speed = hpc_get_max_lnk_speed, .get_cur_bus_speed = hpc_get_cur_lnk_speed, -- cgit v1.2.3 From 3d9c18872fa1db5c43ab97d8cbca43775998e49c Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 9 Jan 2007 13:02:48 -0800 Subject: shpchp: remove CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE The CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE config option is not needed because polling mechanism for shpc hotplug events can be enabled through module option 'shpchp_poll_mode'. This patch removes CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/Kconfig | 9 --------- drivers/pci/hotplug/shpchp_core.c | 4 ---- 2 files changed, 13 deletions(-) diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index adce4204d87d..be92695a7833 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -145,15 +145,6 @@ config HOTPLUG_PCI_SHPC When in doubt, say N. -config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE - bool "Use polling mechanism for hot-plug events (for testing purpose)" - depends on HOTPLUG_PCI_SHPC - help - Say Y here if you want to use the polling mechanism for hot-plug - events for early platform testing. - - When in doubt, say N. - config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 590cd3cbe010..5f4bc08a633a 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -401,10 +401,6 @@ static int __init shpcd_init(void) { int retval = 0; -#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE - shpchp_poll_mode = 1; -#endif - retval = pci_register_driver(&shpc_driver); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); -- cgit v1.2.3 From 1555b33da0b27f933fbe08679935ce9d83c0e9e9 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 9 Jan 2007 13:03:01 -0800 Subject: shpchp: remove DBG_XXX_ROUTINE This patch removes DBG_ENTER_ROUTINE, DBG_LEAVE_ROUTINE and related code. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp_hpc.c | 155 +++++---------------------------------- 1 file changed, 19 insertions(+), 136 deletions(-) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index b7bede4b7c27..7e9347eea5b1 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -35,38 +35,6 @@ #include "shpchp.h" -#ifdef DEBUG -#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ -#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ -#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */ -#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */ -#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT) -#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE) -/* Redefine this flagword to set debug level */ -#define DEBUG_LEVEL DBG_K_STANDARD - -#define DEFINE_DBG_BUFFER char __dbg_str_buf[256]; - -#define DBG_PRINT( dbg_flags, args... ) \ - do { \ - if ( DEBUG_LEVEL & ( dbg_flags ) ) \ - { \ - int len; \ - len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \ - __FILE__, __LINE__, __FUNCTION__ ); \ - sprintf( __dbg_str_buf + len, args ); \ - printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \ - } \ - } while (0) - -#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]"); -#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]"); -#else -#define DEFINE_DBG_BUFFER -#define DBG_ENTER_ROUTINE -#define DBG_LEAVE_ROUTINE -#endif /* DEBUG */ - /* Slot Available Register I field definition */ #define SLOT_33MHZ 0x0000001f #define SLOT_66MHZ_PCIX 0x00001f00 @@ -211,7 +179,6 @@ #define SLOT_EVENT_LATCH 0x2 #define SLOT_SERR_INT_MASK 0x3 -DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); static irqreturn_t shpc_isr(int irq, void *dev_id); @@ -268,8 +235,6 @@ static void int_poll_timeout(unsigned long data) { struct controller *ctrl = (struct controller *)data; - DBG_ENTER_ROUTINE - /* Poll for interrupt events. regs == NULL => polling */ shpc_isr(0, ctrl); @@ -278,8 +243,6 @@ static void int_poll_timeout(unsigned long data) shpchp_poll_time = 2; /* default polling interval is 2 sec */ start_int_poll_timer(ctrl, shpchp_poll_time); - - DBG_LEAVE_ROUTINE } /* @@ -353,8 +316,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) int retval = 0; u16 temp_word; - DBG_ENTER_ROUTINE - mutex_lock(&slot->ctrl->cmd_lock); if (!shpc_poll_ctrl_busy(ctrl)) { @@ -389,19 +350,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) } out: mutex_unlock(&slot->ctrl->cmd_lock); - - DBG_LEAVE_ROUTINE return retval; } static int hpc_check_cmd_status(struct controller *ctrl) { - u16 cmd_status; int retval = 0; - - DBG_ENTER_ROUTINE - - cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; + u16 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; switch (cmd_status >> 1) { case 0: @@ -423,7 +378,6 @@ static int hpc_check_cmd_status(struct controller *ctrl) retval = cmd_status; } - DBG_LEAVE_ROUTINE return retval; } @@ -431,13 +385,8 @@ static int hpc_check_cmd_status(struct controller *ctrl) static int hpc_get_attention_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg; - u8 state; - - DBG_ENTER_ROUTINE - - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; + u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u8 state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; switch (state) { case ATN_LED_STATE_ON: @@ -454,20 +403,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) break; } - DBG_LEAVE_ROUTINE return 0; } static int hpc_get_power_status(struct slot * slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg; - u8 state; - - DBG_ENTER_ROUTINE - - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; + u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u8 state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; switch (state) { case SLOT_STATE_PWRONLY: @@ -484,7 +427,6 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) break; } - DBG_LEAVE_ROUTINE return 0; } @@ -492,30 +434,21 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) static int hpc_get_latch_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg; - - DBG_ENTER_ROUTINE + u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */ - DBG_LEAVE_ROUTINE return 0; } static int hpc_get_adapter_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; - u32 slot_reg; - u8 state; - - DBG_ENTER_ROUTINE + u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u8 state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; *status = (state != 0x3) ? 1 : 0; - DBG_LEAVE_ROUTINE return 0; } @@ -523,11 +456,8 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) { struct controller *ctrl = slot->ctrl; - DBG_ENTER_ROUTINE - *prog_int = shpc_readb(ctrl, PROG_INTERFACE); - DBG_LEAVE_ROUTINE return 0; } @@ -539,8 +469,6 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) u8 m66_cap = !!(slot_reg & MHZ66_CAP); u8 pi, pcix_cap; - DBG_ENTER_ROUTINE - if ((retval = hpc_get_prog_int(slot, &pi))) return retval; @@ -582,21 +510,15 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) } dbg("Adapter speed = %d\n", *value); - DBG_LEAVE_ROUTINE return retval; } static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) { - struct controller *ctrl = slot->ctrl; - u16 sec_bus_status; - u8 pi; int retval = 0; - - DBG_ENTER_ROUTINE - - pi = shpc_readb(ctrl, PROG_INTERFACE); - sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); + struct controller *ctrl = slot->ctrl; + u16 sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); + u8 pi = shpc_readb(ctrl, PROG_INTERFACE); if (pi == 2) { *mode = (sec_bus_status & 0x0100) >> 8; @@ -605,21 +527,14 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) } dbg("Mode 1 ECC cap = %d\n", *mode); - - DBG_LEAVE_ROUTINE return retval; } static int hpc_query_power_fault(struct slot * slot) { struct controller *ctrl = slot->ctrl; - u32 slot_reg; - - DBG_ENTER_ROUTINE - - slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); + u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); - DBG_LEAVE_ROUTINE /* Note: Logic 0 => fault */ return !(slot_reg & POWER_FAULT); } @@ -666,8 +581,6 @@ static void hpc_release_ctlr(struct controller *ctrl) int i; u32 slot_reg, serr_int; - DBG_ENTER_ROUTINE - /* * Mask event interrupts and SERRs of all slots */ @@ -708,61 +621,43 @@ static void hpc_release_ctlr(struct controller *ctrl) */ if (atomic_dec_and_test(&shpchp_num_controllers)) destroy_workqueue(shpchp_wq); - - DBG_LEAVE_ROUTINE } static int hpc_power_on_slot(struct slot * slot) { int retval; - DBG_ENTER_ROUTINE - retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR); - if (retval) { + if (retval) err("%s: Write command failed!\n", __FUNCTION__); - return retval; - } - - DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_slot_enable(struct slot * slot) { int retval; - DBG_ENTER_ROUTINE - /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF); - if (retval) { + if (retval) err("%s: Write command failed!\n", __FUNCTION__); - return retval; - } - DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_slot_disable(struct slot * slot) { int retval; - DBG_ENTER_ROUTINE - /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */ retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON); - if (retval) { + if (retval) err("%s: Write command failed!\n", __FUNCTION__); - return retval; - } - DBG_LEAVE_ROUTINE - return 0; + return retval; } static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) @@ -771,8 +666,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) struct controller *ctrl = slot->ctrl; u8 pi, cmd; - DBG_ENTER_ROUTINE - pi = shpc_readb(ctrl, PROG_INTERFACE); if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) return -EINVAL; @@ -828,7 +721,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) if (retval) err("%s: Write command failed!\n", __FUNCTION__); - DBG_LEAVE_ROUTINE return retval; } @@ -920,8 +812,6 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); - DBG_ENTER_ROUTINE - if (pi == 2) { if (slot_avail2 & SLOT_133MHZ_PCIX_533) bus_speed = PCI_SPEED_133MHz_PCIX_533; @@ -954,7 +844,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) *value = bus_speed; dbg("Max bus speed = %d\n", bus_speed); - DBG_LEAVE_ROUTINE + return retval; } @@ -967,8 +857,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) u8 pi = shpc_readb(ctrl, PROG_INTERFACE); u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); - DBG_ENTER_ROUTINE - if ((pi == 1) && (speed_mode > 4)) { *value = PCI_SPEED_UNKNOWN; return -ENODEV; @@ -1024,7 +912,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) } dbg("Current bus speed = %d\n", bus_speed); - DBG_LEAVE_ROUTINE return retval; } @@ -1061,8 +948,6 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) u32 tempdword, slot_reg, slot_config; u8 i; - DBG_ENTER_ROUTINE - ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == @@ -1235,13 +1120,11 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); } - DBG_LEAVE_ROUTINE return 0; /* We end up here for the many possible ways to fail this API. */ abort_iounmap: iounmap(ctrl->creg); abort: - DBG_LEAVE_ROUTINE return rc; } -- cgit v1.2.3 From 9f593e30b318719b0e3889c730cc3a2d0729a707 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 9 Jan 2007 13:03:10 -0800 Subject: shpchp: delete trailing whitespace This patch deletes trailing white space in SHPCHP driver. This has no functional change. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 4 ++-- drivers/pci/hotplug/shpchp_ctrl.c | 20 ++++++++++---------- drivers/pci/hotplug/shpchp_hpc.c | 32 ++++++++++++++++---------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 3ca6a4f574b3..01d31a1f697c 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -106,7 +106,7 @@ struct controller { }; /* Define AMD SHPC ID */ -#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 +#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 /* AMD PCIX bridge registers */ @@ -221,7 +221,7 @@ enum ctrl_offsets { }; static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) -{ +{ return hotplug_slot->private; } diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 6bb84734cd6c..b746bd265bc6 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) /* Attention Button Change */ dbg("shpchp: Attention button interrupt received.\n"); - + p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); @@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - /* + /* * Save the presence state */ p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); @@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) return 1; } -/* The following routines constitute the bulk of the +/* The following routines constitute the bulk of the hotplug controller logic */ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed) -{ +{ int rc = 0; dbg("%s: change to speed %d\n", __FUNCTION__, speed); @@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp) -{ +{ int rc = 0; /* @@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot) err("%s: Failed to power on slot\n", __FUNCTION__); return -1; } - + if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { if (slots_not_empty) return WRONG_BUS_FREQUENCY; - + if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); return WRONG_BUS_FREQUENCY; } - + /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); return rc; } } - + rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); if (rc) { err("%s: Can't get adapter speed or bus mode mismatch\n", @@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot) err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); return rc; } - + rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); if (rc) { err("%s: Issue of Set Attention command failed\n", __FUNCTION__); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 7e9347eea5b1..5183a45d45b5 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -329,9 +329,9 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) ++t_slot; temp_word = (t_slot << 8) | (cmd & 0xFF); dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd); - + /* To make sure the Controller Busy bit is 0 before we send out the - * command. + * command. */ shpc_writew(ctrl, CMD, temp_word); @@ -357,7 +357,7 @@ static int hpc_check_cmd_status(struct controller *ctrl) { int retval = 0; u16 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; - + switch (cmd_status >> 1) { case 0: retval = 0; @@ -544,7 +544,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) u8 slot_cmd = 0; switch (value) { - case 0 : + case 0 : slot_cmd = SET_ATTN_OFF; /* OFF */ break; case 1: @@ -735,7 +735,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) if (!intr_loc) return IRQ_NONE; - dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); + dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); if(!shpchp_poll_mode) { /* @@ -748,12 +748,12 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); intr_loc2 = shpc_readl(ctrl, INTR_LOC); - dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); } if (intr_loc & CMD_INTR_PENDING) { - /* - * Command Complete Interrupt Pending + /* + * Command Complete Interrupt Pending * RO only - clear by writing 1 to the Command Completion * Detect bit in Controller SERR-INT register */ @@ -767,7 +767,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) if (!(intr_loc & ~CMD_INTR_PENDING)) goto out; - for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { + for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { /* To find out which slot has interrupt pending */ if (!(intr_loc & SLOT_INTR_PENDING(hp_slot))) continue; @@ -799,7 +799,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK); shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); } - + return IRQ_HANDLED; } @@ -919,7 +919,7 @@ static struct hpc_ops shpchp_hpc_ops = { .power_on_slot = hpc_power_on_slot, .slot_enable = hpc_slot_enable, .slot_disable = hpc_slot_disable, - .set_bus_speed_mode = hpc_set_bus_speed_mode, + .set_bus_speed_mode = hpc_set_bus_speed_mode, .set_attention_status = hpc_set_attention_status, .get_power_status = hpc_get_power_status, .get_attention_status = hpc_get_attention_status, @@ -936,7 +936,7 @@ static struct hpc_ops shpchp_hpc_ops = { .green_led_on = hpc_set_green_led_on, .green_led_off = hpc_set_green_led_off, .green_led_blink = hpc_set_green_led_blink, - + .release_ctlr = hpc_release_ctlr, }; @@ -993,9 +993,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) ctrl->mmio_size = 0x24 + 0x4 * num_slots; } - info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, + info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); - + rc = pci_enable_device(pdev); if (rc) { err("%s: pci_enable_device failed\n", __FUNCTION__); @@ -1057,7 +1057,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) slot_reg &= ~SLOT_REG_RSVDZ_MASK; shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); } - + if (shpchp_poll_mode) { /* Install interrupt polling timer. Start with 10 sec delay */ init_timer(&ctrl->poll_timer); @@ -1069,7 +1069,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) info("Can't get msi for the hotplug controller\n"); info("Use INTx for the hotplug controller\n"); } - + rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *)ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", -- cgit v1.2.3 From 15a260d53f7ca026e45109d2c2bec8c4b087780b Mon Sep 17 00:00:00 2001 From: Daniel Yeisley Date: Thu, 21 Dec 2006 14:34:57 -0500 Subject: PCI Quirk: 1k I/O space IOBL_ADR fix on P64H2 There's an existing quirk for the kernel to use 1k IO space granularity on the Intel P64H2. It turns out however that pci_setup_bridge() in drivers/pci/setup-bus.c reads in the IO base and limit address register masks it off to the nearest 4k, and writes it back. This causes the kernel to be on 1k boundaries and the hardware to be 4k aligned. The patch below fixes the problem. Signed-off-by: Dan Yeisley Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1d04ca02dd0f..47214fdfa6c8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1670,6 +1670,31 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); +/* Fix the IOBL_ADR for 1k I/O space granularity on the Intel P64H2 + * The IOBL_ADR gets re-written to 4k boundaries in pci_setup_bridge() + * in drivers/pci/setup-bus.c + */ +static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev) +{ + u16 en1k, iobl_adr, iobl_adr_1k; + struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES; + + pci_read_config_word(dev, 0x40, &en1k); + + if (en1k & 0x200) { + pci_read_config_word(dev, PCI_IO_BASE, &iobl_adr); + + iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00); + + if (iobl_adr != iobl_adr_1k) { + printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n", + iobl_adr,iobl_adr_1k); + pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k); + } + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io_fix_iobl); + /* Under some circumstances, AER is not linked with extended capabilities. * Force it to be linked by setting the corresponding control bit in the * config space. -- cgit v1.2.3 From 2f2d39d2843570e81be6d53da6052f6752dc3c45 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Jan 2007 11:23:15 +0100 Subject: PCI: Speed up the Intel SMBus unhiding quirk Speed up the Intel SMBus PCI quirk by avoiding tests which can only fail. This also makes the compiled code significantly smaller when using gcc 3.2/3.4. gcc 4.x appears to optimize the code by itself so this change doesn't make a difference there. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 47214fdfa6c8..e5cc6a40ed46 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -977,52 +977,51 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x1626: /* L3C notebook */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) switch(dev->subsystem_device) { case 0x80b1: /* P4GE-V */ case 0x80b2: /* P4PE */ case 0x8093: /* P4B533-V */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB) switch(dev->subsystem_device) { case 0x8030: /* P4T533 */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_7205_0) + else if (dev->device == PCI_DEVICE_ID_INTEL_7205_0) switch (dev->subsystem_device) { case 0x8070: /* P4G8X Deluxe */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) + else if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) switch (dev->subsystem_device) { case 0x80c9: /* PU-DLS */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch (dev->subsystem_device) { case 0x1751: /* M2N notebook */ case 0x1821: /* M5N notebook */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch (dev->subsystem_device) { case 0x184b: /* W1N notebook */ case 0x186a: /* M6Ne notebook */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) switch (dev->subsystem_device) { case 0x80f2: /* P4P800-X */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { + else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) switch (dev->subsystem_device) { case 0x1882: /* M6V notebook */ case 0x1977: /* A6VA notebook */ asus_hides_smbus = 1; } - } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { @@ -1030,25 +1029,24 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x0890: /* HP Compaq nc6000 */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) switch (dev->subsystem_device) { case 0x12bc: /* HP D330L */ case 0x12bd: /* HP D530 */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { + else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) switch (dev->subsystem_device) { case 0x099c: /* HP Compaq nx6110 */ asus_hides_smbus = 1; } - } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch(dev->subsystem_device) { case 0x0001: /* Toshiba Satellite A40 */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) + else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { case 0x0001: /* Toshiba Tecra M2 */ asus_hides_smbus = 1; -- cgit v1.2.3 From 1863100a0244828f78e5e47b22b93ca912e80963 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 14 Jan 2007 14:46:32 +0100 Subject: PCI: remove quirk_sis_96x_compatible() Since 2.6.0-test10, all quirk_sis_96x_compatible() had any effect on was a printk(). This patch therefore removes it. Signed-off-by: Adrian Bunk Acked-by: Mark M. Hoffman Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e5cc6a40ed46..d0c359335077 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1152,8 +1152,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_ * * We can also enable the sis96x bit in the discovery register.. */ -static int __devinitdata sis_96x_compatible = 0; - #define SIS_DETECT_REGISTER 0x40 static void quirk_sis_503(struct pci_dev *dev) @@ -1169,9 +1167,6 @@ static void quirk_sis_503(struct pci_dev *dev) return; } - /* Make people aware that we changed the config.. */ - printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible); - /* * Ok, it now shows up as a 96x.. run the 96x quirk by * hand in case it has already been processed. @@ -1183,16 +1178,6 @@ static void quirk_sis_503(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); -static void __init quirk_sis_96x_compatible(struct pci_dev *dev) -{ - sis_96x_compatible = 1; -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_645, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_646, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_648, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_compatible ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); /* * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller -- cgit v1.2.3 From 8255cf35d503db7c1b26ae53b6b7f23ada82316f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 6 Jan 2007 21:48:41 +0100 Subject: PCI: make isa_bridge Alpha-only Since isa_bridge is neither assigned any value !NULL nor used on !Alpha, there's no reason for providing it. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/pci.c | 4 ++++ drivers/pci/pci.c | 6 ------ include/asm-alpha/pci.h | 2 ++ include/linux/pci.h | 6 ------ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 3c10b9a1ddf5..ab642a4f08de 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -575,3 +575,7 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); + +/* FIXME: Some boxes have multiple ISA bridges! */ +struct pci_dev *isa_bridge; +EXPORT_SYMBOL(isa_bridge); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index caeeacc7b070..e91dcc05b790 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1224,12 +1224,6 @@ early_param("pci", pci_setup); device_initcall(pci_init); -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) -/* FIXME: Some boxes have multiple ISA bridges! */ -struct pci_dev *isa_bridge; -EXPORT_SYMBOL(isa_bridge); -#endif - EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 4e115f368d5f..85aa1127c903 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -293,4 +293,6 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev); #define IOBASE_ROOT_BUS 5 #define IOBASE_FROM_HOSE 0x10000 +extern struct pci_dev *isa_bridge; + #endif /* __ALPHA_PCI_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index cf2c8a35a1df..d69dfd7d0e0b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -618,10 +618,6 @@ enum pci_dma_burst_strategy { strategy_parameter byte boundaries */ }; -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) -extern struct pci_dev *isa_bridge; -#endif - struct msix_entry { u16 vector; /* kernel uses to write allocated vector */ u16 entry; /* driver uses to specify entry, OS writes */ @@ -729,8 +725,6 @@ static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } -#define isa_bridge ((struct pci_dev *)NULL) - #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } -- cgit v1.2.3 From c54c18790700b8b2a503945d729aa425c25691fe Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Thu, 18 Jan 2007 13:50:05 +0900 Subject: PCI: cleanup MSI code Cleanup MSI code as follows: - fix some types - fix strange local variable definition - delete unnecessary blank line - add comment to #endif which is far from corresponding #ifdef Signed-off-by: Satoru Takeuchi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 9 +++++---- include/linux/msi.h | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index ed3f7e1a563c..e87e8efb9bb4 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -49,8 +49,8 @@ static void msi_set_mask_bit(unsigned int irq, int flag) switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: if (entry->msi_attrib.maskbit) { - int pos; - u32 mask_bits; + int pos; + u32 mask_bits; pos = (long)entry->mask_base; pci_read_config_dword(entry->dev, pos, &mask_bits); @@ -162,6 +162,7 @@ void unmask_msi_irq(unsigned int irq) } static int msi_free_irq(struct pci_dev* dev, int irq); + static int msi_init(void) { static int status = -ENOMEM; @@ -291,7 +292,7 @@ static int msi_lookup_irq(struct pci_dev *dev, int type) continue; spin_unlock_irqrestore(&msi_lock, flags); /* This pre-assigned MSI irq for this device - already exits. Override dev->irq with this irq */ + already exists. Override dev->irq with this irq */ dev->irq = irq; return 0; } @@ -458,7 +459,7 @@ void pci_restore_msix_state(struct pci_dev *dev) pci_write_config_word(dev, msi_control_reg(pos), save); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); } -#endif +#endif /* CONFIG_PM */ /** * msi_capability_init - configure device's MSI capability structure diff --git a/include/linux/msi.h b/include/linux/msi.h index c7ef94343673..b99976b1536e 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -7,11 +7,10 @@ struct msi_msg { u32 data; /* 16 bits of msi message data */ }; -/* Heper functions */ +/* Helper functions */ extern void mask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq); extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); - extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); struct msi_desc { -- cgit v1.2.3 From e36c455c2f5fee08fed395e94c7ab156cd159360 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 16 Jan 2007 12:17:13 +0100 Subject: PCI: power management: remove noise on non-manageable hw Return early from pci_set_power_state() if hardware does not support power management. This way, we do not generate noise in the logs. Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e91dcc05b790..7ae709024456 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) if (state > PCI_D3hot) state = PCI_D3hot; + /* + * If the device or the parent bridge can't support PCI PM, ignore + * the request if we're doing anything besides putting it into D0 + * (which would only happen on boot). + */ + if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) + return 0; + /* Validate current state: * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state @@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) } else if (dev->current_state == state) return 0; /* we're already there */ - /* - * If the device or the parent bridge can't support PCI PM, ignore - * the request if we're doing anything besides putting it into D0 - * (which would only happen on boot). - */ - if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) - return 0; /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); -- cgit v1.2.3 From b11056355ea149c37edf0ef54976a49f5258cd54 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jan 2007 16:15:24 -0800 Subject: PCI: remove duplicate device id from ata_piix As pointed out by Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ata_piix.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 47701b286f8b..267241a59080 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -191,12 +191,8 @@ static const struct pci_device_id piix_pci_tbl[] = { /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */ { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - /* Intel ICH5 */ - { 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, /* C-ICH (i810E2) */ { 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, - /* ESB (855GME/875P + 6300ESB) UDMA 100 */ - { 0x8086, 0x25A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* ICH6 (and 6) (i915) UDMA 100 */ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* ICH7/7-R (i945, i975) UDMA 100*/ -- cgit v1.2.3 From 89298c7a41e71ecb1e0c3f793655e9ce09662ce0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 25 Jan 2007 16:15:24 -0800 Subject: PCI: remove duplicate device id from ipr As pointed out by Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ipr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b318500785e5..821386c7b576 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -7558,9 +7558,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, -- cgit v1.2.3 From 88187dfa4d8bb565df762f272511d2c91e427e0d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 25 Jan 2007 19:34:07 +1100 Subject: MSI: Replace pci_msi_quirk with calls to pci_no_msi() I don't see any reason why we need pci_msi_quirk, quirk code can just call pci_no_msi() instead. Remove the check of pci_msi_quirk in msi_init(). This is safe as all calls to msi_init() are protected by calls to pci_msi_supported(), which checks pci_msi_enable, which is disabled by pci_no_msi(). The pci_disable_msi routines didn't check pci_msi_quirk, only pci_msi_enable, but as far as I can see that was a bug not a feature. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/net/bnx2.c | 3 +-- drivers/pci/msi.c | 7 ------- drivers/pci/pci.h | 6 +----- drivers/pci/quirks.c | 7 ++----- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ee7b75b976b5..0420697c4293 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -5954,8 +5954,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) * responding after a while. * * AMD believes this incompatibility is unique to the 5706, and - * prefers to locally disable MSI rather than globally disabling it - * using pci_msi_quirk. + * prefers to locally disable MSI rather than globally disabling it. */ if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { struct pci_dev *amd_8132 = NULL; diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index e87e8efb9bb4..3776531586d1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -170,13 +170,6 @@ static int msi_init(void) if (!status) return status; - if (pci_msi_quirk) { - pci_msi_enable = 0; - printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n"); - status = -EINVAL; - return status; - } - status = msi_cache_init(); if (status < 0) { pci_msi_enable = 0; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 783e81f81f58..4948db0f8100 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -43,12 +43,8 @@ extern void pci_remove_legacy_files(struct pci_bus *bus); /* Lock for read/write access to pci device and bus lists */ extern struct rw_semaphore pci_bus_sem; -#ifdef CONFIG_PCI_MSI -extern int pci_msi_quirk; -#else -#define pci_msi_quirk 0 -#endif extern unsigned int pci_pm_d3_delay; + #ifdef CONFIG_PCI_MSI void disable_msi_mode(struct pci_dev *dev, int pos, int type); void pci_no_msi(void); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d0c359335077..0d0ba2fad5fc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1700,9 +1700,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_pcie_aer_ext_cap); #ifdef CONFIG_PCI_MSI -/* To disable MSI globally */ -int pci_msi_quirk; - /* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually * some other busses controlled by the chipset even if Linux is not aware of it. @@ -1711,8 +1708,8 @@ int pci_msi_quirk; */ static void __init quirk_svw_msi(struct pci_dev *dev) { - pci_msi_quirk = 1; - printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); + pci_no_msi(); + printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi); -- cgit v1.2.3 From 0fcfdabbdbedb3bdc63f29209aeeac805df78a92 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 25 Jan 2007 19:34:08 +1100 Subject: MSI: Remove pci_scan_msi_device() pci_scan_msi_device() doesn't do anything anymore, so remove it. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/pci_64.c | 2 -- drivers/pci/msi.c | 6 ------ drivers/pci/probe.c | 1 - include/linux/pci.h | 2 -- 4 files changed, 11 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 01f18c683407..2b52b087aaa8 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -381,8 +381,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, pci_device_add(dev, bus); - /* XXX pci_scan_msi_device(dev); */ - return dev; } EXPORT_SYMBOL(of_create_pci_dev); diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 3776531586d1..6cfa6be9a6d5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -294,12 +294,6 @@ static int msi_lookup_irq(struct pci_dev *dev, int type) return -EACCES; } -void pci_scan_msi_device(struct pci_dev *dev) -{ - if (!dev) - return; -} - #ifdef CONFIG_PM int pci_save_msi_state(struct pci_dev *dev) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9d7788428642..2fe1d690eb13 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -945,7 +945,6 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) return NULL; pci_device_add(dev, bus); - pci_scan_msi_device(dev); return dev; } diff --git a/include/linux/pci.h b/include/linux/pci.h index d69dfd7d0e0b..29765e2b1e0a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -625,7 +625,6 @@ struct msix_entry { #ifndef CONFIG_PCI_MSI -static inline void pci_scan_msi_device(struct pci_dev *dev) {} static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} static inline void pci_disable_msi(struct pci_dev *dev) {} static inline int pci_enable_msix(struct pci_dev* dev, @@ -633,7 +632,6 @@ static inline int pci_enable_msix(struct pci_dev* dev, static inline void pci_disable_msix(struct pci_dev *dev) {} static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} #else -extern void pci_scan_msi_device(struct pci_dev *dev); extern int pci_enable_msi(struct pci_dev *dev); extern void pci_disable_msi(struct pci_dev *dev); extern int pci_enable_msix(struct pci_dev* dev, -- cgit v1.2.3 From 8fed4b65236c44d090bd62f2d14938ae791e0260 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 25 Jan 2007 19:34:08 +1100 Subject: MSI: Combine pci_(save|restore)_msi/msix_state The PCI save/restore code doesn't need to care about MSI vs MSI-X, all it really wants is to say "save/restore all MSI(-X) info for this device". This is borne out in the code, we call the MSI and MSI-X save routines side by side, and similarly with the restore routines. So combine the MSI/MSI-X routines into pci_save_msi_state() and pci_restore_msi_state(). It is up to those routines to decide what state needs to be saved. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 27 +++++++++++++++++++++++---- drivers/pci/pci.c | 4 +--- drivers/pci/pci.h | 6 ++---- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 6cfa6be9a6d5..067ae9917fd6 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -295,7 +295,7 @@ static int msi_lookup_irq(struct pci_dev *dev, int type) } #ifdef CONFIG_PM -int pci_save_msi_state(struct pci_dev *dev) +static int __pci_save_msi_state(struct pci_dev *dev) { int pos, i = 0; u16 control; @@ -333,7 +333,7 @@ int pci_save_msi_state(struct pci_dev *dev) return 0; } -void pci_restore_msi_state(struct pci_dev *dev) +static void __pci_restore_msi_state(struct pci_dev *dev) { int i = 0, pos; u16 control; @@ -361,7 +361,7 @@ void pci_restore_msi_state(struct pci_dev *dev) kfree(save_state); } -int pci_save_msix_state(struct pci_dev *dev) +static int __pci_save_msix_state(struct pci_dev *dev) { int pos; int temp; @@ -409,7 +409,20 @@ int pci_save_msix_state(struct pci_dev *dev) return 0; } -void pci_restore_msix_state(struct pci_dev *dev) +int pci_save_msi_state(struct pci_dev *dev) +{ + int rc; + + rc = __pci_save_msi_state(dev); + if (rc) + return rc; + + rc = __pci_save_msix_state(dev); + + return rc; +} + +static void __pci_restore_msix_state(struct pci_dev *dev) { u16 save; int pos; @@ -446,6 +459,12 @@ void pci_restore_msix_state(struct pci_dev *dev) pci_write_config_word(dev, msi_control_reg(pos), save); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); } + +void pci_restore_msi_state(struct pci_dev *dev) +{ + __pci_restore_msi_state(dev); + __pci_restore_msix_state(dev); +} #endif /* CONFIG_PM */ /** diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7ae709024456..84c757ba0664 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -634,8 +634,6 @@ pci_save_state(struct pci_dev *dev) pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); if ((i = pci_save_msi_state(dev)) != 0) return i; - if ((i = pci_save_msix_state(dev)) != 0) - return i; if ((i = pci_save_pcie_state(dev)) != 0) return i; if ((i = pci_save_pcix_state(dev)) != 0) @@ -673,7 +671,7 @@ pci_restore_state(struct pci_dev *dev) } pci_restore_pcix_state(dev); pci_restore_msi_state(dev); - pci_restore_msix_state(dev); + return 0; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 4948db0f8100..a4f2d580625e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -52,17 +52,15 @@ void pci_no_msi(void); static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } static inline void pci_no_msi(void) { } #endif + #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) int pci_save_msi_state(struct pci_dev *dev); -int pci_save_msix_state(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); -void pci_restore_msix_state(struct pci_dev *dev); #else static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } -static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } static inline void pci_restore_msi_state(struct pci_dev *dev) {} -static inline void pci_restore_msix_state(struct pci_dev *dev) {} #endif + static inline int pci_no_d1d2(struct pci_dev *dev) { unsigned int parent_dstates = 0; -- cgit v1.2.3 From ded86d8d37736df67ddeec4ae00e2ec1a5a90b3c Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:42:52 -0700 Subject: msi: Kill msi_lookup_irq The function msi_lookup_irq was horrible. As a side effect of running it changed dev->irq, and then the callers would need to change it back. In addition it does a global scan through all of the irqs, which seems to be the sole justification of the msi_lock. To remove the neede for msi_lookup_irq I added first_msi_irq to struct pci_dev. Then depending on the context I replaced msi_lookup_irq with dev->first_msi_irq, dev->msi_enabled, or dev->msix_enabled. msi_enabled and msix_enabled were already present in pci_dev for other reasons. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 149 +++++++++++++++++++++------------------------------- include/linux/pci.h | 3 ++ 2 files changed, 62 insertions(+), 90 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 067ae9917fd6..b945470bef18 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -272,28 +272,6 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) pci_intx(dev, 1); /* enable intx */ } -static int msi_lookup_irq(struct pci_dev *dev, int type) -{ - int irq; - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); - for (irq = 0; irq < NR_IRQS; irq++) { - if (!msi_desc[irq] || msi_desc[irq]->dev != dev || - msi_desc[irq]->msi_attrib.type != type || - msi_desc[irq]->msi_attrib.default_irq != dev->irq) - continue; - spin_unlock_irqrestore(&msi_lock, flags); - /* This pre-assigned MSI irq for this device - already exists. Override dev->irq with this irq */ - dev->irq = irq; - return 0; - } - spin_unlock_irqrestore(&msi_lock, flags); - - return -EACCES; -} - #ifdef CONFIG_PM static int __pci_save_msi_state(struct pci_dev *dev) { @@ -364,11 +342,13 @@ static void __pci_restore_msi_state(struct pci_dev *dev) static int __pci_save_msix_state(struct pci_dev *dev) { int pos; - int temp; int irq, head, tail = 0; u16 control; struct pci_cap_saved_state *save_state; + if (!dev->msix_enabled) + return 0; + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); if (pos <= 0 || dev->no_msi) return 0; @@ -386,13 +366,7 @@ static int __pci_save_msix_state(struct pci_dev *dev) *((u16 *)&save_state->data[0]) = control; /* save the table */ - temp = dev->irq; - if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { - kfree(save_state); - return -EINVAL; - } - - irq = head = dev->irq; + irq = head = dev->first_msi_irq; while (head != tail) { struct msi_desc *entry; @@ -402,7 +376,6 @@ static int __pci_save_msix_state(struct pci_dev *dev) tail = msi_desc[irq]->link.tail; irq = tail; } - dev->irq = temp; save_state->cap_nr = PCI_CAP_ID_MSIX; pci_add_saved_cap(dev, save_state); @@ -428,9 +401,11 @@ static void __pci_restore_msix_state(struct pci_dev *dev) int pos; int irq, head, tail = 0; struct msi_desc *entry; - int temp; struct pci_cap_saved_state *save_state; + if (!dev->msix_enabled) + return; + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); if (!save_state) return; @@ -443,10 +418,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) return; /* route the table */ - temp = dev->irq; - if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) - return; - irq = head = dev->irq; + irq = head = dev->first_msi_irq; while (head != tail) { entry = msi_desc[irq]; write_msi_msg(irq, &entry->msg_save); @@ -454,7 +426,6 @@ static void __pci_restore_msix_state(struct pci_dev *dev) tail = msi_desc[irq]->link.tail; irq = tail; } - dev->irq = temp; pci_write_config_word(dev, msi_control_reg(pos), save); enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); @@ -524,6 +495,7 @@ static int msi_capability_init(struct pci_dev *dev) return status; } + dev->first_msi_irq = irq; attach_msi_entry(entry, irq); /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -620,6 +592,7 @@ static int msix_capability_init(struct pci_dev *dev, avail = -EBUSY; return avail; } + dev->first_msi_irq = entries[0].vector; /* Set MSI-X enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); @@ -667,13 +640,11 @@ int pci_msi_supported(struct pci_dev * dev) **/ int pci_enable_msi(struct pci_dev* dev) { - int pos, temp, status; + int pos, status; if (pci_msi_supported(dev) < 0) return -EINVAL; - temp = dev->irq; - status = msi_init(); if (status < 0) return status; @@ -682,15 +653,14 @@ int pci_enable_msi(struct pci_dev* dev) if (!pos) return -EINVAL; - WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); + WARN_ON(!!dev->msi_enabled); /* Check whether driver already requested for MSI-X irqs */ pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { + if (pos > 0 && dev->msix_enabled) { printk(KERN_INFO "PCI: %s: Can't enable MSI. " - "Device already has MSI-X irq assigned\n", + "Device already has MSI-X enabled\n", pci_name(dev)); - dev->irq = temp; return -EINVAL; } status = msi_capability_init(dev); @@ -709,6 +679,9 @@ void pci_disable_msi(struct pci_dev* dev) if (!dev) return; + if (!dev->msi_enabled) + return; + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); if (!pos) return; @@ -717,28 +690,30 @@ void pci_disable_msi(struct pci_dev* dev) if (!(control & PCI_MSI_FLAGS_ENABLE)) return; + disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[dev->irq]; + entry = msi_desc[dev->first_msi_irq]; if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { spin_unlock_irqrestore(&msi_lock, flags); return; } - if (irq_has_action(dev->irq)) { + if (irq_has_action(dev->first_msi_irq)) { spin_unlock_irqrestore(&msi_lock, flags); printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " "free_irq() on MSI irq %d\n", - pci_name(dev), dev->irq); - BUG_ON(irq_has_action(dev->irq)); + pci_name(dev), dev->first_msi_irq); + BUG_ON(irq_has_action(dev->first_msi_irq)); } else { default_irq = entry->msi_attrib.default_irq; spin_unlock_irqrestore(&msi_lock, flags); - msi_free_irq(dev, dev->irq); + msi_free_irq(dev, dev->first_msi_irq); /* Restore dev->irq to its default pin-assertion irq */ dev->irq = default_irq; } + dev->first_msi_irq = 0; } static int msi_free_irq(struct pci_dev* dev, int irq) @@ -797,7 +772,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { int status, pos, nr_entries; - int i, j, temp; + int i, j; u16 control; if (!entries || pci_msi_supported(dev) < 0) @@ -825,16 +800,14 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) return -EINVAL; /* duplicate entry */ } } - temp = dev->irq; - WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)); + WARN_ON(!!dev->msix_enabled); /* Check whether driver already requested for MSI irq */ if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && - !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { + dev->msi_enabled) { printk(KERN_INFO "PCI: %s: Can't enable MSI-X. " "Device already has an MSI irq assigned\n", pci_name(dev)); - dev->irq = temp; return -EINVAL; } status = msix_capability_init(dev, entries, nvec); @@ -843,7 +816,9 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) void pci_disable_msix(struct pci_dev* dev) { - int pos, temp; + int irq, head, tail = 0, warning = 0; + unsigned long flags; + int pos; u16 control; if (!pci_msi_enable) @@ -851,6 +826,9 @@ void pci_disable_msix(struct pci_dev* dev) if (!dev) return; + if (!dev->msix_enabled) + return; + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); if (!pos) return; @@ -861,31 +839,25 @@ void pci_disable_msix(struct pci_dev* dev) disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); - temp = dev->irq; - if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { - int irq, head, tail = 0, warning = 0; - unsigned long flags; - - irq = head = dev->irq; - dev->irq = temp; /* Restore pin IRQ */ - while (head != tail) { - spin_lock_irqsave(&msi_lock, flags); - tail = msi_desc[irq]->link.tail; - spin_unlock_irqrestore(&msi_lock, flags); - if (irq_has_action(irq)) - warning = 1; - else if (irq != head) /* Release MSI-X irq */ - msi_free_irq(dev, irq); - irq = tail; - } - msi_free_irq(dev, irq); - if (warning) { - printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " - "free_irq() on all MSI-X irqs\n", - pci_name(dev)); - BUG_ON(warning > 0); - } + irq = head = dev->first_msi_irq; + while (head != tail) { + spin_lock_irqsave(&msi_lock, flags); + tail = msi_desc[irq]->link.tail; + spin_unlock_irqrestore(&msi_lock, flags); + if (irq_has_action(irq)) + warning = 1; + else if (irq != head) /* Release MSI-X irq */ + msi_free_irq(dev, irq); + irq = tail; + } + msi_free_irq(dev, irq); + if (warning) { + printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " + "free_irq() on all MSI-X irqs\n", + pci_name(dev)); + BUG_ON(warning > 0); } + dev->first_msi_irq = 0; } /** @@ -899,30 +871,28 @@ void pci_disable_msix(struct pci_dev* dev) **/ void msi_remove_pci_irq_vectors(struct pci_dev* dev) { - int pos, temp; + int pos; unsigned long flags; if (!pci_msi_enable || !dev) return; - temp = dev->irq; /* Save IOAPIC IRQ */ pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { - if (irq_has_action(dev->irq)) { + if (pos > 0 && dev->msi_enabled) { + if (irq_has_action(dev->first_msi_irq)) { printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on MSI irq %d\n", - pci_name(dev), dev->irq); - BUG_ON(irq_has_action(dev->irq)); + pci_name(dev), dev->first_msi_irq); + BUG_ON(irq_has_action(dev->first_msi_irq)); } else /* Release MSI irq assigned to this device */ - msi_free_irq(dev, dev->irq); - dev->irq = temp; /* Restore IOAPIC IRQ */ + msi_free_irq(dev, dev->first_msi_irq); } pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { + if (pos > 0 && dev->msix_enabled) { int irq, head, tail = 0, warning = 0; void __iomem *base = NULL; - irq = head = dev->irq; + irq = head = dev->first_msi_irq; while (head != tail) { spin_lock_irqsave(&msi_lock, flags); tail = msi_desc[irq]->link.tail; @@ -942,7 +912,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) pci_name(dev)); BUG_ON(warning > 0); } - dev->irq = temp; /* Restore IOAPIC IRQ */ } } diff --git a/include/linux/pci.h b/include/linux/pci.h index 29765e2b1e0a..1507f8cc45fd 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -174,6 +174,9 @@ struct pci_dev { struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ int rom_attr_enabled; /* has display of the rom attribute been enabled? */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ +#ifdef CONFIG_PCI_MSI + unsigned int first_msi_irq; +#endif }; #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) -- cgit v1.2.3 From d40f540ce6d992d4123827dbd62f68c4a39c53d0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:44:21 -0700 Subject: msi: Remove msi_lock. With the removal of msi_lookup_irq all of the functions using msi_lock operated on a single device and none of them could reasonably be called on that device at the same time. Since what little synchronization that needs to happen needs to happen outside of the msi functions, msi_lock could never be contended and as such is useless and just complicates the code. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b945470bef18..0df626cf47d8 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -24,7 +24,6 @@ #include "pci.h" #include "msi.h" -static DEFINE_SPINLOCK(msi_lock); static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static struct kmem_cache* msi_cachep; @@ -196,11 +195,7 @@ static struct msi_desc* alloc_msi_entry(void) static void attach_msi_entry(struct msi_desc *entry, int irq) { - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); msi_desc[irq] = entry; - spin_unlock_irqrestore(&msi_lock, flags); } static int create_msi_irq(void) @@ -672,7 +667,6 @@ void pci_disable_msi(struct pci_dev* dev) struct msi_desc *entry; int pos, default_irq; u16 control; - unsigned long flags; if (!pci_msi_enable) return; @@ -693,21 +687,17 @@ void pci_disable_msi(struct pci_dev* dev) disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[dev->first_msi_irq]; if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { - spin_unlock_irqrestore(&msi_lock, flags); return; } if (irq_has_action(dev->first_msi_irq)) { - spin_unlock_irqrestore(&msi_lock, flags); printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " "free_irq() on MSI irq %d\n", pci_name(dev), dev->first_msi_irq); BUG_ON(irq_has_action(dev->first_msi_irq)); } else { default_irq = entry->msi_attrib.default_irq; - spin_unlock_irqrestore(&msi_lock, flags); msi_free_irq(dev, dev->first_msi_irq); /* Restore dev->irq to its default pin-assertion irq */ @@ -721,14 +711,11 @@ static int msi_free_irq(struct pci_dev* dev, int irq) struct msi_desc *entry; int head, entry_nr, type; void __iomem *base; - unsigned long flags; arch_teardown_msi_irq(irq); - spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[irq]; if (!entry || entry->dev != dev) { - spin_unlock_irqrestore(&msi_lock, flags); return -EINVAL; } type = entry->msi_attrib.type; @@ -739,7 +726,6 @@ static int msi_free_irq(struct pci_dev* dev, int irq) msi_desc[entry->link.tail]->link.head = entry->link.head; entry->dev = NULL; msi_desc[irq] = NULL; - spin_unlock_irqrestore(&msi_lock, flags); destroy_msi_irq(irq); @@ -817,7 +803,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) void pci_disable_msix(struct pci_dev* dev) { int irq, head, tail = 0, warning = 0; - unsigned long flags; int pos; u16 control; @@ -841,9 +826,7 @@ void pci_disable_msix(struct pci_dev* dev) irq = head = dev->first_msi_irq; while (head != tail) { - spin_lock_irqsave(&msi_lock, flags); tail = msi_desc[irq]->link.tail; - spin_unlock_irqrestore(&msi_lock, flags); if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ @@ -872,7 +855,6 @@ void pci_disable_msix(struct pci_dev* dev) void msi_remove_pci_irq_vectors(struct pci_dev* dev) { int pos; - unsigned long flags; if (!pci_msi_enable || !dev) return; @@ -894,10 +876,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) irq = head = dev->first_msi_irq; while (head != tail) { - spin_lock_irqsave(&msi_lock, flags); tail = msi_desc[irq]->link.tail; base = msi_desc[irq]->mask_base; - spin_unlock_irqrestore(&msi_lock, flags); if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ -- cgit v1.2.3 From 866a8c87c4e51046602387953bbef76992107bcb Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:45:54 -0700 Subject: msi: Fix msi_remove_pci_irq_vectors. Since msi_remove_pci_irq_vectors is designed to be called during hotplug remove it is actively wrong to query the hardware and expect meaningful results back. To that end remove the pci_find_capability calls. Testing dev->msi_enabled and dev->msix_enabled gives us all of the information we need. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 0df626cf47d8..529113dc3e22 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -854,13 +854,10 @@ void pci_disable_msix(struct pci_dev* dev) **/ void msi_remove_pci_irq_vectors(struct pci_dev* dev) { - int pos; - if (!pci_msi_enable || !dev) return; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos > 0 && dev->msi_enabled) { + if (dev->msi_enabled) { if (irq_has_action(dev->first_msi_irq)) { printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " "called without free_irq() on MSI irq %d\n", @@ -869,8 +866,7 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) } else /* Release MSI irq assigned to this device */ msi_free_irq(dev, dev->first_msi_irq); } - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos > 0 && dev->msix_enabled) { + if (dev->msix_enabled) { int irq, head, tail = 0, warning = 0; void __iomem *base = NULL; -- cgit v1.2.3 From 1c659d61cfbd8dc3926688c1bbf12d80f4cfb5c2 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:47:52 -0700 Subject: msi: Remove attach_msi_entry. The attach_msi_entry has been reduced to a single simple assignment, so for simplicity remove the abstraction and directory perform the assignment. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 529113dc3e22..55fe83dfd77b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -193,11 +193,6 @@ static struct msi_desc* alloc_msi_entry(void) return entry; } -static void attach_msi_entry(struct msi_desc *entry, int irq) -{ - msi_desc[irq] = entry; -} - static int create_msi_irq(void) { struct msi_desc *entry; @@ -491,7 +486,7 @@ static int msi_capability_init(struct pci_dev *dev) } dev->first_msi_irq = irq; - attach_msi_entry(entry, irq); + msi_desc[irq] = entry; /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -570,7 +565,7 @@ static int msix_capability_init(struct pci_dev *dev, break; } - attach_msi_entry(entry, irq); + msi_desc[irq] = entry; } if (i != nvec) { int avail = i - 1; -- cgit v1.2.3 From 5b912c108c8b1fcecbfe13d6d9a183db97b682d3 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:52:03 -0700 Subject: msi: Kill the msi_desc array. We need to be able to get from an irq number to a struct msi_desc. The msi_desc array in msi.c had several short comings the big one was that it could not be used outside of msi.c. Using irq_data in struct irq_desc almost worked except on some architectures irq_data needs to be used for something else. So this patch adds a msi_desc pointer to irq_desc, adds the appropriate wrappers and changes all of the msi code to use them. The dynamic_irq_init/cleanup code was tweaked to ensure the new field is left in a well defined state. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/ia64/sn/kernel/msi_sn.c | 2 +- drivers/pci/msi.c | 44 +++++++++++++++++++++----------------------- include/linux/irq.h | 4 ++++ kernel/irq/chip.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index b3a435fd70fb..31fbb859b67e 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); - entry = get_irq_data(irq); + entry = get_irq_msi(irq); if (!entry->msi_attrib.is_64) return -EINVAL; diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 55fe83dfd77b..52c253c5ad3d 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -24,7 +24,6 @@ #include "pci.h" #include "msi.h" -static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static struct kmem_cache* msi_cachep; static int pci_msi_enable = 1; @@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) { struct msi_desc *entry; - entry = msi_desc[irq]; + entry = get_irq_msi(irq); BUG_ON(!entry || !entry->dev); switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: @@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) void read_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = get_irq_data(irq); + struct msi_desc *entry = get_irq_msi(irq); switch(entry->msi_attrib.type) { case PCI_CAP_ID_MSI: { @@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) void write_msi_msg(unsigned int irq, struct msi_msg *msg) { - struct msi_desc *entry = get_irq_data(irq); + struct msi_desc *entry = get_irq_msi(irq); switch (entry->msi_attrib.type) { case PCI_CAP_ID_MSI: { @@ -208,7 +207,7 @@ static int create_msi_irq(void) return -EBUSY; } - set_irq_data(irq, entry); + set_irq_msi(irq, entry); return irq; } @@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq) { struct msi_desc *entry; - entry = get_irq_data(irq); + entry = get_irq_msi(irq); set_irq_chip(irq, NULL); - set_irq_data(irq, NULL); + set_irq_msi(irq, NULL); destroy_irq(irq); kmem_cache_free(msi_cachep, entry); } @@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev) while (head != tail) { struct msi_desc *entry; - entry = msi_desc[irq]; + entry = get_irq_msi(irq); read_msi_msg(irq, &entry->msg_save); - tail = msi_desc[irq]->link.tail; + tail = entry->link.tail; irq = tail; } @@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev) /* route the table */ irq = head = dev->first_msi_irq; while (head != tail) { - entry = msi_desc[irq]; + entry = get_irq_msi(irq); write_msi_msg(irq, &entry->msg_save); - tail = msi_desc[irq]->link.tail; + tail = entry->link.tail; irq = tail; } @@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev) if (irq < 0) return irq; - entry = get_irq_data(irq); + entry = get_irq_msi(irq); entry->link.head = irq; entry->link.tail = irq; entry->msi_attrib.type = PCI_CAP_ID_MSI; @@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev) } dev->first_msi_irq = irq; - msi_desc[irq] = entry; + set_irq_msi(irq, entry); /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev, if (irq < 0) break; - entry = get_irq_data(irq); + entry = get_irq_msi(irq); j = entries[i].entry; entries[i].vector = irq; entry->msi_attrib.type = PCI_CAP_ID_MSIX; @@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev, break; } - msi_desc[irq] = entry; + set_irq_msi(irq, entry); } if (i != nvec) { int avail = i - 1; @@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev) disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - entry = msi_desc[dev->first_msi_irq]; + entry = get_irq_msi(dev->first_msi_irq); if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { return; } @@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) arch_teardown_msi_irq(irq); - entry = msi_desc[irq]; + entry = get_irq_msi(irq); if (!entry || entry->dev != dev) { return -EINVAL; } @@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq) entry_nr = entry->msi_attrib.entry_nr; head = entry->link.head; base = entry->mask_base; - msi_desc[entry->link.head]->link.tail = entry->link.tail; - msi_desc[entry->link.tail]->link.head = entry->link.head; + get_irq_msi(entry->link.head)->link.tail = entry->link.tail; + get_irq_msi(entry->link.tail)->link.head = entry->link.head; entry->dev = NULL; - msi_desc[irq] = NULL; destroy_msi_irq(irq); @@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev) irq = head = dev->first_msi_irq; while (head != tail) { - tail = msi_desc[irq]->link.tail; + tail = get_irq_msi(irq)->link.tail; if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ @@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) irq = head = dev->first_msi_irq; while (head != tail) { - tail = msi_desc[irq]->link.tail; - base = msi_desc[irq]->mask_base; + tail = get_irq_msi(irq)->link.tail; + base = get_irq_msi(irq)->mask_base; if (irq_has_action(irq)) warning = 1; else if (irq != head) /* Release MSI-X irq */ diff --git a/include/linux/irq.h b/include/linux/irq.h index 52fc4052a0ae..5504b671357f 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, #define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ struct proc_dir_entry; +struct msi_desc; /** * struct irq_chip - hardware interrupt chip descriptor @@ -148,6 +149,7 @@ struct irq_chip { struct irq_desc { irq_flow_handler_t handle_irq; struct irq_chip *chip; + struct msi_desc *msi_desc; void *handler_data; void *chip_data; struct irqaction *action; /* IRQ action list */ @@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_type(unsigned int irq, unsigned int type); +extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); #define get_irq_chip(irq) (irq_desc[irq].chip) #define get_irq_chip_data(irq) (irq_desc[irq].chip_data) #define get_irq_data(irq) (irq_desc[irq].handler_data) +#define get_irq_msi(irq) (irq_desc[irq].msi_desc) #endif /* CONFIG_GENERIC_HARDIRQS */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index d27b25855743..475e8a71bcdc 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq) desc->chip = &no_irq_chip; desc->handle_irq = handle_bad_irq; desc->depth = 1; + desc->msi_desc = NULL; desc->handler_data = NULL; desc->chip_data = NULL; desc->action = NULL; @@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq) WARN_ON(1); return; } + desc->msi_desc = NULL; + desc->handler_data = NULL; + desc->chip_data = NULL; desc->handle_irq = handle_bad_irq; desc->chip = &no_irq_chip; spin_unlock_irqrestore(&desc->lock, flags); @@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data) } EXPORT_SYMBOL(set_irq_data); +/** + * set_irq_data - set irq type data for an irq + * @irq: Interrupt number + * @data: Pointer to interrupt specific data + * + * Set the hardware irq controller data for an irq + */ +int set_irq_msi(unsigned int irq, struct msi_desc *entry) +{ + struct irq_desc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR + "Trying to install msi data for IRQ%d\n", irq); + return -EINVAL; + } + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock, flags); + desc->msi_desc = entry; + spin_unlock_irqrestore(&desc->lock, flags); + return 0; +} + /** * set_irq_chip_data - set irq chip data for an irq * @irq: Interrupt number -- cgit v1.2.3 From f7feaca77d6ad6bcfcc88ac54e3188970448d6fe Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 28 Jan 2007 12:56:37 -0700 Subject: msi: Make MSI useable more architectures The arch hooks arch_setup_msi_irq and arch_teardown_msi_irq are now responsible for allocating and freeing the linux irq in addition to setting up the the linux irq to work with the interrupt. arch_setup_msi_irq now takes a pci_device and a msi_desc and returns an irq. With this change in place this code should be useable by all platforms except those that won't let the OS touch the hardware like ppc RTAS. Signed-off-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/io_apic.c | 17 +++++++--- arch/ia64/kernel/msi_ia64.c | 19 +++++++---- arch/ia64/sn/kernel/msi_sn.c | 20 +++++++---- arch/x86_64/kernel/io_apic.c | 17 +++++++--- drivers/pci/msi.c | 80 ++++++++++++-------------------------------- include/asm-ia64/machvec.h | 3 +- include/linux/msi.h | 2 +- 7 files changed, 75 insertions(+), 83 deletions(-) diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 6a3875f81a0a..5592fa6e1fa1 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2606,25 +2606,32 @@ static struct irq_chip msi_chip = { .retrigger = ioapic_retrigger_irq, }; -int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) +int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) { struct msi_msg msg; - int ret; + int irq, ret; + irq = create_irq(); + if (irq < 0) + return irq; + + set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); - if (ret < 0) + if (ret < 0) { + destroy_irq(irq); return ret; + } write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return 0; + return irq; } void arch_teardown_msi_irq(unsigned int irq) { - return; + destroy_irq(irq); } #endif /* CONFIG_PCI_MSI */ diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 822e59a1b822..0d05450c91c4 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -64,12 +64,17 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) } #endif /* CONFIG_SMP */ -int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) +int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { struct msi_msg msg; unsigned long dest_phys_id; - unsigned int vector; + unsigned int irq, vector; + irq = create_irq(); + if (irq < 0) + return irq; + + set_irq_msi(irq, desc); dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); vector = irq; @@ -89,12 +94,12 @@ int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); - return 0; + return irq; } void ia64_teardown_msi_irq(unsigned int irq) { - return; /* no-op */ + destroy_irq(irq); } static void ia64_ack_msi_irq(unsigned int irq) @@ -126,12 +131,12 @@ static struct irq_chip ia64_msi_chip = { }; -int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) +int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { if (platform_setup_msi_irq) - return platform_setup_msi_irq(irq, pdev); + return platform_setup_msi_irq(pdev, desc); - return ia64_setup_msi_irq(irq, pdev); + return ia64_setup_msi_irq(pdev, desc); } void arch_teardown_msi_irq(unsigned int irq) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 31fbb859b67e..ea3dc38d73fd 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -59,13 +59,12 @@ void sn_teardown_msi_irq(unsigned int irq) sn_intr_free(nasid, widget, sn_irq_info); sn_msi_info[irq].sn_irq_info = NULL; - return; + destroy_irq(irq); } -int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) +int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) { struct msi_msg msg; - struct msi_desc *entry; int widget; int status; nasid_t nasid; @@ -73,8 +72,8 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) struct sn_irq_info *sn_irq_info; struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); + int irq; - entry = get_irq_msi(irq); if (!entry->msi_attrib.is_64) return -EINVAL; @@ -84,6 +83,11 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) if (provider == NULL || provider->dma_map_consistent == NULL) return -EINVAL; + irq = create_irq(); + if (irq < 0) + return irq; + + set_irq_msi(irq, entry); /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. @@ -95,12 +99,15 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) SWIN_WIDGETNUM(bussoft->bs_base); sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (! sn_irq_info) + if (! sn_irq_info) { + destroy_irq(irq); return -ENOMEM; + } status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); if (status) { kfree(sn_irq_info); + destroy_irq(irq); return -ENOMEM; } @@ -121,6 +128,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) if (! bus_addr) { sn_intr_free(nasid, widget, sn_irq_info); kfree(sn_irq_info); + destroy_irq(irq); return -ENOMEM; } @@ -139,7 +147,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); - return 0; + return irq; } #ifdef CONFIG_SMP diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index d7bad90a5ad8..6be6730acb5c 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1956,24 +1956,31 @@ static struct irq_chip msi_chip = { .retrigger = ioapic_retrigger_irq, }; -int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) +int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) { struct msi_msg msg; - int ret; + int irq, ret; + irq = create_irq(); + if (irq < 0) + return irq; + + set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); - if (ret < 0) + if (ret < 0) { + destroy_irq(irq); return ret; + } write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return 0; + return irq; } void arch_teardown_msi_irq(unsigned int irq) { - return; + destroy_irq(irq); } #endif /* CONFIG_PCI_MSI */ diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 52c253c5ad3d..68555c11f556 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -192,37 +192,6 @@ static struct msi_desc* alloc_msi_entry(void) return entry; } -static int create_msi_irq(void) -{ - struct msi_desc *entry; - int irq; - - entry = alloc_msi_entry(); - if (!entry) - return -ENOMEM; - - irq = create_irq(); - if (irq < 0) { - kmem_cache_free(msi_cachep, entry); - return -EBUSY; - } - - set_irq_msi(irq, entry); - - return irq; -} - -static void destroy_msi_irq(unsigned int irq) -{ - struct msi_desc *entry; - - entry = get_irq_msi(irq); - set_irq_chip(irq, NULL); - set_irq_msi(irq, NULL); - destroy_irq(irq); - kmem_cache_free(msi_cachep, entry); -} - static void enable_msi_mode(struct pci_dev *dev, int pos, int type) { u16 control; @@ -438,7 +407,6 @@ void pci_restore_msi_state(struct pci_dev *dev) **/ static int msi_capability_init(struct pci_dev *dev) { - int status; struct msi_desc *entry; int pos, irq; u16 control; @@ -446,13 +414,10 @@ static int msi_capability_init(struct pci_dev *dev) pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ - irq = create_msi_irq(); - if (irq < 0) - return irq; + entry = alloc_msi_entry(); + if (!entry) + return -ENOMEM; - entry = get_irq_msi(irq); - entry->link.head = irq; - entry->link.tail = irq; entry->msi_attrib.type = PCI_CAP_ID_MSI; entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; @@ -478,14 +443,16 @@ static int msi_capability_init(struct pci_dev *dev) maskbits); } /* Configure MSI capability structure */ - status = arch_setup_msi_irq(irq, dev); - if (status < 0) { - destroy_msi_irq(irq); - return status; + irq = arch_setup_msi_irq(dev, entry); + if (irq < 0) { + kmem_cache_free(msi_cachep, entry); + return irq; } - + entry->link.head = irq; + entry->link.tail = irq; dev->first_msi_irq = irq; set_irq_msi(irq, entry); + /* Set MSI enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); @@ -507,7 +474,6 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; - int status; int irq, pos, i, j, nr_entries, temp = 0; unsigned long phys_addr; u32 table_offset; @@ -530,13 +496,11 @@ static int msix_capability_init(struct pci_dev *dev, /* MSI-X Table Initialization */ for (i = 0; i < nvec; i++) { - irq = create_msi_irq(); - if (irq < 0) + entry = alloc_msi_entry(); + if (!entry) break; - entry = get_irq_msi(irq); j = entries[i].entry; - entries[i].vector = irq; entry->msi_attrib.type = PCI_CAP_ID_MSIX; entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = j; @@ -545,6 +509,14 @@ static int msix_capability_init(struct pci_dev *dev, entry->msi_attrib.pos = pos; entry->dev = dev; entry->mask_base = base; + + /* Configure MSI-X capability structure */ + irq = arch_setup_msi_irq(dev, entry); + if (irq < 0) { + kmem_cache_free(msi_cachep, entry); + break; + } + entries[i].vector = irq; if (!head) { entry->link.head = irq; entry->link.tail = irq; @@ -557,12 +529,6 @@ static int msix_capability_init(struct pci_dev *dev, } temp = irq; tail = entry; - /* Configure MSI-X capability structure */ - status = arch_setup_msi_irq(irq, dev); - if (status < 0) { - destroy_msi_irq(irq); - break; - } set_irq_msi(irq, entry); } @@ -706,8 +672,6 @@ static int msi_free_irq(struct pci_dev* dev, int irq) int head, entry_nr, type; void __iomem *base; - arch_teardown_msi_irq(irq); - entry = get_irq_msi(irq); if (!entry || entry->dev != dev) { return -EINVAL; @@ -718,9 +682,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq) base = entry->mask_base; get_irq_msi(entry->link.head)->link.tail = entry->link.tail; get_irq_msi(entry->link.tail)->link.head = entry->link.head; - entry->dev = NULL; - destroy_msi_irq(irq); + arch_teardown_msi_irq(irq); + kmem_cache_free(msi_cachep, entry); if (type == PCI_CAP_ID_MSIX) { writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index a3891eb3f217..3c96ac19154e 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -21,6 +21,7 @@ struct mm_struct; struct pci_bus; struct task_struct; struct pci_dev; +struct msi_desc; typedef void ia64_mv_setup_t (char **); typedef void ia64_mv_cpu_init_t (void); @@ -79,7 +80,7 @@ typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); -typedef int ia64_mv_setup_msi_irq_t (unsigned int irq, struct pci_dev *pdev); +typedef int ia64_mv_setup_msi_irq_t (struct pci_dev *pdev, struct msi_desc *); typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq); static inline void diff --git a/include/linux/msi.h b/include/linux/msi.h index b99976b1536e..74c8a2ecc9dd 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -41,7 +41,7 @@ struct msi_desc { /* * The arch hook for setup up msi irqs */ -int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev); +int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); -- cgit v1.2.3 From 14719f325e1cd4ff757587e9a221ebaf394563ee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 7 Feb 2007 16:17:27 -0800 Subject: Revert "PCI: remove duplicate device id from ata_piix" This reverts commit b11056355ea149c37edf0ef54976a49f5258cd54. It was incorrect, the proper fix is coming through the SATA tree, sorry about that. Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ata_piix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 267241a59080..47701b286f8b 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -191,8 +191,12 @@ static const struct pci_device_id piix_pci_tbl[] = { /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */ { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + /* Intel ICH5 */ + { 0x8086, 0x24DB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, /* C-ICH (i810E2) */ { 0x8086, 0x245B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + /* ESB (855GME/875P + 6300ESB) UDMA 100 */ + { 0x8086, 0x25A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* ICH6 (and 6) (i915) UDMA 100 */ { 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* ICH7/7-R (i945, i975) UDMA 100*/ -- cgit v1.2.3