Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'platform-drivers-x86-v6.7-7' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fix from Ilpo Järvinen:
"Unfortunately the P2SB deadlock fix broke some older HW and we need
some time to figure out the best way to fix the issue so reverting the
deadlock fix for now"

* tag 'platform-drivers-x86-v6.7-7' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
Revert "platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe"

+52 -142
+52 -142
drivers/platform/x86/p2sb.c
··· 26 26 {} 27 27 }; 28 28 29 - /* 30 - * Cache BAR0 of P2SB device functions 0 to 7. 31 - * TODO: The constant 8 is the number of functions that PCI specification 32 - * defines. Same definitions exist tree-wide. Unify this definition and 33 - * the other definitions then move to include/uapi/linux/pci.h. 34 - */ 35 - #define NR_P2SB_RES_CACHE 8 36 - 37 - struct p2sb_res_cache { 38 - u32 bus_dev_id; 39 - struct resource res; 40 - }; 41 - 42 - static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; 43 - 44 29 static int p2sb_get_devfn(unsigned int *devfn) 45 30 { 46 31 unsigned int fn = P2SB_DEVFN_DEFAULT; ··· 39 54 return 0; 40 55 } 41 56 42 - static bool p2sb_valid_resource(struct resource *res) 43 - { 44 - if (res->flags) 45 - return true; 46 - 47 - return false; 48 - } 49 - 50 57 /* Copy resource from the first BAR of the device in question */ 51 - static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) 58 + static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) 52 59 { 53 60 struct resource *bar0 = &pdev->resource[0]; 54 61 ··· 56 79 mem->end = bar0->end; 57 80 mem->flags = bar0->flags; 58 81 mem->desc = bar0->desc; 59 - } 60 - 61 - static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) 62 - { 63 - struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)]; 64 - struct pci_dev *pdev; 65 - 66 - pdev = pci_scan_single_device(bus, devfn); 67 - if (!pdev) 68 - return; 69 - 70 - p2sb_read_bar0(pdev, &cache->res); 71 - cache->bus_dev_id = bus->dev.id; 72 - 73 - pci_stop_and_remove_bus_device(pdev); 74 - return; 75 - } 76 - 77 - static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) 78 - { 79 - unsigned int slot, fn; 80 - 81 - if (PCI_FUNC(devfn) == 0) { 82 - /* 83 - * When function number of the P2SB device is zero, scan it and 84 - * other function numbers, and if devices are available, cache 85 - * their BAR0s. 86 - */ 87 - slot = PCI_SLOT(devfn); 88 - for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++) 89 - p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn)); 90 - } else { 91 - /* Scan the P2SB device and cache its BAR0 */ 92 - p2sb_scan_and_cache_devfn(bus, devfn); 93 - } 94 - 95 - if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res)) 96 - return -ENOENT; 97 82 98 83 return 0; 99 84 } 100 85 101 - static struct pci_bus *p2sb_get_bus(struct pci_bus *bus) 86 + static int p2sb_scan_and_read(struct pci_bus *bus, unsigned int devfn, struct resource *mem) 102 87 { 103 - static struct pci_bus *p2sb_bus; 104 - 105 - bus = bus ?: p2sb_bus; 106 - if (bus) 107 - return bus; 108 - 109 - /* Assume P2SB is on the bus 0 in domain 0 */ 110 - p2sb_bus = pci_find_bus(0, 0); 111 - return p2sb_bus; 112 - } 113 - 114 - static int p2sb_cache_resources(void) 115 - { 116 - struct pci_bus *bus; 117 - unsigned int devfn_p2sb; 118 - u32 value = P2SBC_HIDE; 88 + struct pci_dev *pdev; 119 89 int ret; 120 90 121 - /* Get devfn for P2SB device itself */ 122 - ret = p2sb_get_devfn(&devfn_p2sb); 123 - if (ret) 124 - return ret; 125 - 126 - bus = p2sb_get_bus(NULL); 127 - if (!bus) 91 + pdev = pci_scan_single_device(bus, devfn); 92 + if (!pdev) 128 93 return -ENODEV; 129 94 130 - /* 131 - * Prevent concurrent PCI bus scan from seeing the P2SB device and 132 - * removing via sysfs while it is temporarily exposed. 133 - */ 134 - pci_lock_rescan_remove(); 95 + ret = p2sb_read_bar0(pdev, mem); 135 96 136 - /* 137 - * The BIOS prevents the P2SB device from being enumerated by the PCI 138 - * subsystem, so we need to unhide and hide it back to lookup the BAR. 139 - * Unhide the P2SB device here, if needed. 140 - */ 141 - pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); 142 - if (value & P2SBC_HIDE) 143 - pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); 144 - 145 - ret = p2sb_scan_and_cache(bus, devfn_p2sb); 146 - 147 - /* Hide the P2SB device, if it was hidden */ 148 - if (value & P2SBC_HIDE) 149 - pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE); 150 - 151 - pci_unlock_rescan_remove(); 152 - 97 + pci_stop_and_remove_bus_device(pdev); 153 98 return ret; 154 99 } 155 100 ··· 81 182 * @devfn: PCI slot and function to communicate with 82 183 * @mem: memory resource to be filled in 83 184 * 84 - * If @bus is NULL, the bus 0 in domain 0 will be used. 185 + * The BIOS prevents the P2SB device from being enumerated by the PCI 186 + * subsystem, so we need to unhide and hide it back to lookup the BAR. 187 + * 188 + * if @bus is NULL, the bus 0 in domain 0 will be used. 85 189 * If @devfn is 0, it will be replaced by devfn of the P2SB device. 86 190 * 87 191 * Caller must provide a valid pointer to @mem. 192 + * 193 + * Locking is handled by pci_rescan_remove_lock mutex. 88 194 * 89 195 * Return: 90 196 * 0 on success or appropriate errno value on error. 91 197 */ 92 198 int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) 93 199 { 94 - struct p2sb_res_cache *cache; 200 + struct pci_dev *pdev_p2sb; 201 + unsigned int devfn_p2sb; 202 + u32 value = P2SBC_HIDE; 95 203 int ret; 96 204 97 - bus = p2sb_get_bus(bus); 98 - if (!bus) 205 + /* Get devfn for P2SB device itself */ 206 + ret = p2sb_get_devfn(&devfn_p2sb); 207 + if (ret) 208 + return ret; 209 + 210 + /* if @bus is NULL, use bus 0 in domain 0 */ 211 + bus = bus ?: pci_find_bus(0, 0); 212 + 213 + /* 214 + * Prevent concurrent PCI bus scan from seeing the P2SB device and 215 + * removing via sysfs while it is temporarily exposed. 216 + */ 217 + pci_lock_rescan_remove(); 218 + 219 + /* Unhide the P2SB device, if needed */ 220 + pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); 221 + if (value & P2SBC_HIDE) 222 + pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); 223 + 224 + pdev_p2sb = pci_scan_single_device(bus, devfn_p2sb); 225 + if (devfn) 226 + ret = p2sb_scan_and_read(bus, devfn, mem); 227 + else 228 + ret = p2sb_read_bar0(pdev_p2sb, mem); 229 + pci_stop_and_remove_bus_device(pdev_p2sb); 230 + 231 + /* Hide the P2SB device, if it was hidden */ 232 + if (value & P2SBC_HIDE) 233 + pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, P2SBC_HIDE); 234 + 235 + pci_unlock_rescan_remove(); 236 + 237 + if (ret) 238 + return ret; 239 + 240 + if (mem->flags == 0) 99 241 return -ENODEV; 100 242 101 - if (!devfn) { 102 - ret = p2sb_get_devfn(&devfn); 103 - if (ret) 104 - return ret; 105 - } 106 - 107 - cache = &p2sb_resources[PCI_FUNC(devfn)]; 108 - if (cache->bus_dev_id != bus->dev.id) 109 - return -ENODEV; 110 - 111 - if (!p2sb_valid_resource(&cache->res)) 112 - return -ENOENT; 113 - 114 - memcpy(mem, &cache->res, sizeof(*mem)); 115 243 return 0; 116 244 } 117 245 EXPORT_SYMBOL_GPL(p2sb_bar); 118 - 119 - static int __init p2sb_fs_init(void) 120 - { 121 - p2sb_cache_resources(); 122 - return 0; 123 - } 124 - 125 - /* 126 - * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can 127 - * not be locked in sysfs pci bus rescan path because of deadlock. To 128 - * avoid the deadlock, access to P2SB devices with the lock at an early 129 - * step in kernel initialization and cache required resources. This 130 - * should happen after subsys_initcall which initializes PCI subsystem 131 - * and before device_initcall which requires P2SB resources. 132 - */ 133 - fs_initcall(p2sb_fs_init);