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

[PATCH] PCI Hotplug: add common acpi functions to core

shpchprm_acpi.c and pciehprm_acpi.c are nearly identical. In addition,
there are functions in both these files that are also in acpiphp_glue.c.
This patch will remove duplicate functions from shpchp, pciehp, and
acpiphp and move this functionality to pci_hotplug, as it is not
hardware specific. Get rid of shpchprm* and pciehprm* files since they
are no longer needed. shpchprm_nonacpi.c and pciehprm_nonacpi.c are
identical, as well as shpchprm_legacy.c and can be replaced with a
macro.

This patch also changes acpiphp to use the common hpp code.

Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Kristen Accardi and committed by
Greg Kroah-Hartman
783c49fc f5afe806

+257 -594
+3 -14
drivers/pci/hotplug/Makefile
··· 22 22 pci_hotplug-objs += cpci_hotplug_core.o \ 23 23 cpci_hotplug_pci.o 24 24 endif 25 + ifdef CONFIG_ACPI 26 + pci_hotplug-objs += acpi_pcihp.o 27 + endif 25 28 26 29 cpqphp-objs := cpqphp_core.o \ 27 30 cpqphp_ctrl.o \ ··· 54 51 pciehp_ctrl.o \ 55 52 pciehp_pci.o \ 56 53 pciehp_hpc.o 57 - ifdef CONFIG_ACPI 58 - pciehp-objs += pciehprm_acpi.o 59 - else 60 - pciehp-objs += pciehprm_nonacpi.o 61 - endif 62 54 63 55 shpchp-objs := shpchp_core.o \ 64 56 shpchp_ctrl.o \ 65 57 shpchp_pci.o \ 66 58 shpchp_sysfs.o \ 67 59 shpchp_hpc.o 68 - ifdef CONFIG_ACPI 69 - shpchp-objs += shpchprm_acpi.o 70 - else 71 - ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY 72 - shpchp-objs += shpchprm_legacy.o 73 - else 74 - shpchp-objs += shpchprm_nonacpi.o 75 - endif 76 - endif
+1 -14
drivers/pci/hotplug/acpiphp.h
··· 64 64 struct acpiphp_slot *acpi_slot; 65 65 }; 66 66 67 - /** 68 - * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters 69 - * @cache_line_size in DWORD 70 - * @latency_timer in PCI clock 71 - * @enable_SERR 0 or 1 72 - * @enable_PERR 0 or 1 73 - */ 74 - struct hpp_param { 75 - u8 cache_line_size; 76 - u8 latency_timer; 77 - u8 enable_SERR; 78 - u8 enable_PERR; 79 - }; 80 67 81 68 82 69 /** ··· 87 100 struct pci_dev *pci_dev; 88 101 89 102 /* ACPI 2.0 _HPP parameters */ 90 - struct hpp_param hpp; 103 + struct hotplug_params hpp; 91 104 92 105 spinlock_t res_lock; 93 106 };
+13 -78
drivers/pci/hotplug/acpiphp_glue.c
··· 285 285 static void decode_hpp(struct acpiphp_bridge *bridge) 286 286 { 287 287 acpi_status status; 288 - struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, 289 - .pointer = NULL}; 290 - union acpi_object *package; 291 - int i; 292 288 293 - /* default numbers */ 294 - bridge->hpp.cache_line_size = 0x10; 295 - bridge->hpp.latency_timer = 0x40; 296 - bridge->hpp.enable_SERR = 0; 297 - bridge->hpp.enable_PERR = 0; 298 - 299 - status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer); 300 - 289 + status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp); 301 290 if (ACPI_FAILURE(status)) { 302 - dbg("_HPP evaluation failed\n"); 303 - return; 291 + /* use default numbers */ 292 + bridge->hpp.cache_line_size = 0x10; 293 + bridge->hpp.latency_timer = 0x40; 294 + bridge->hpp.enable_serr = 0; 295 + bridge->hpp.enable_perr = 0; 304 296 } 305 - 306 - package = (union acpi_object *) buffer.pointer; 307 - 308 - if (!package || package->type != ACPI_TYPE_PACKAGE || 309 - package->package.count != 4 || !package->package.elements) { 310 - err("invalid _HPP object; ignoring\n"); 311 - goto err_exit; 312 - } 313 - 314 - for (i = 0; i < 4; i++) { 315 - if (package->package.elements[i].type != ACPI_TYPE_INTEGER) { 316 - err("invalid _HPP parameter type; ignoring\n"); 317 - goto err_exit; 318 - } 319 - } 320 - 321 - bridge->hpp.cache_line_size = package->package.elements[0].integer.value; 322 - bridge->hpp.latency_timer = package->package.elements[1].integer.value; 323 - bridge->hpp.enable_SERR = package->package.elements[2].integer.value; 324 - bridge->hpp.enable_PERR = package->package.elements[3].integer.value; 325 - 326 - dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n", 327 - bridge->hpp.cache_line_size, 328 - bridge->hpp.latency_timer, 329 - bridge->hpp.enable_SERR, 330 - bridge->hpp.enable_PERR); 331 - 332 - bridge->flags |= BRIDGE_HAS_HPP; 333 - 334 - err_exit: 335 - kfree(buffer.pointer); 336 297 } 298 + 337 299 338 300 339 301 /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ ··· 1116 1154 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 1117 1155 bridge->hpp.latency_timer); 1118 1156 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); 1119 - if (bridge->hpp.enable_SERR) 1157 + if (bridge->hpp.enable_serr) 1120 1158 pci_cmd |= PCI_COMMAND_SERR; 1121 1159 else 1122 1160 pci_cmd &= ~PCI_COMMAND_SERR; 1123 - if (bridge->hpp.enable_PERR) 1161 + if (bridge->hpp.enable_perr) 1124 1162 pci_cmd |= PCI_COMMAND_PARITY; 1125 1163 else 1126 1164 pci_cmd &= ~PCI_COMMAND_PARITY; ··· 1131 1169 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 1132 1170 bridge->hpp.latency_timer); 1133 1171 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); 1134 - if (bridge->hpp.enable_SERR) 1172 + if (bridge->hpp.enable_serr) 1135 1173 pci_bctl |= PCI_BRIDGE_CTL_SERR; 1136 1174 else 1137 1175 pci_bctl &= ~PCI_BRIDGE_CTL_SERR; 1138 - if (bridge->hpp.enable_PERR) 1176 + if (bridge->hpp.enable_perr) 1139 1177 pci_bctl |= PCI_BRIDGE_CTL_PARITY; 1140 1178 else 1141 1179 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; ··· 1155 1193 1156 1194 memset(&bridge, 0, sizeof(bridge)); 1157 1195 bridge.handle = handle; 1196 + bridge.pci_dev = bus->self; 1158 1197 decode_hpp(&bridge); 1159 1198 list_for_each_entry(dev, &bus->devices, bus_list) 1160 1199 program_hpp(dev, &bridge); ··· 1372 1409 } 1373 1410 } 1374 1411 1375 - static int is_root_bridge(acpi_handle handle) 1376 - { 1377 - acpi_status status; 1378 - struct acpi_device_info *info; 1379 - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 1380 - int i; 1381 - 1382 - status = acpi_get_object_info(handle, &buffer); 1383 - if (ACPI_SUCCESS(status)) { 1384 - info = buffer.pointer; 1385 - if ((info->valid & ACPI_VALID_HID) && 1386 - !strcmp(PCI_ROOT_HID_STRING, 1387 - info->hardware_id.value)) { 1388 - acpi_os_free(buffer.pointer); 1389 - return 1; 1390 - } 1391 - if (info->valid & ACPI_VALID_CID) { 1392 - for (i=0; i < info->compatibility_id.count; i++) { 1393 - if (!strcmp(PCI_ROOT_HID_STRING, 1394 - info->compatibility_id.id[i].value)) { 1395 - acpi_os_free(buffer.pointer); 1396 - return 1; 1397 - } 1398 - } 1399 - } 1400 - } 1401 - return 0; 1402 - } 1403 1412 1404 1413 static acpi_status 1405 1414 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) 1406 1415 { 1407 1416 int *count = (int *)context; 1408 1417 1409 - if (is_root_bridge(handle)) { 1418 + if (acpi_root_bridge(handle)) { 1410 1419 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1411 1420 handle_hotplug_event_bridge, NULL); 1412 1421 (*count)++;
+17
drivers/pci/hotplug/pci_hotplug.h
··· 176 176 struct hotplug_slot_info *info); 177 177 extern struct subsystem pci_hotplug_slots_subsys; 178 178 179 + struct hotplug_params { 180 + u8 cache_line_size; 181 + u8 latency_timer; 182 + u8 enable_serr; 183 + u8 enable_perr; 184 + }; 185 + 186 + #ifdef CONFIG_ACPI 187 + #include <acpi/acpi.h> 188 + #include <acpi/acpi_bus.h> 189 + #include <acpi/actypes.h> 190 + extern acpi_status acpi_run_oshp(acpi_handle handle); 191 + extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 192 + struct hotplug_params *hpp); 193 + extern u8 * acpi_path_name(acpi_handle handle); 194 + int acpi_root_bridge(acpi_handle handle); 195 + #endif 179 196 #endif 180 197
+15 -9
drivers/pci/hotplug/pciehp.h
··· 50 50 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 51 51 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 52 52 53 - struct hotplug_params { 54 - u8 cache_line_size; 55 - u8 latency_timer; 56 - u8 enable_serr; 57 - u8 enable_perr; 58 - }; 59 53 60 54 struct slot { 61 55 struct slot *next; ··· 186 192 /* pci functions */ 187 193 extern int pciehp_configure_device (struct slot *p_slot); 188 194 extern int pciehp_unconfigure_device (struct slot *p_slot); 189 - extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev); 190 - extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 191 - struct hotplug_params *hpp); 192 195 193 196 194 197 ··· 277 286 int (*check_lnk_status) (struct controller *ctrl); 278 287 }; 279 288 289 + 290 + #ifdef CONFIG_ACPI 291 + #define pciehp_get_hp_hw_control_from_firmware(dev) \ 292 + pciehp_acpi_get_hp_hw_control_from_firmware(dev) 293 + static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 294 + struct hotplug_params *hpp) 295 + { 296 + if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) 297 + return -ENODEV; 298 + return 0; 299 + } 300 + #else 301 + #define pciehp_get_hp_hw_control_from_firmware(dev) 0 302 + #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) 303 + #endif /* CONFIG_ACPI */ 280 304 #endif /* _PCIEHP_H */
+73 -1
drivers/pci/hotplug/pciehp_hpc.c
··· 38 38 39 39 #include "../pci.h" 40 40 #include "pciehp.h" 41 - 41 + #include <acpi/acpi.h> 42 + #include <acpi/acpi_bus.h> 43 + #include <acpi/actypes.h> 44 + #include <linux/pci-acpi.h> 42 45 #ifdef DEBUG 43 46 #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ 44 47 #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ ··· 1238 1235 .release_ctlr = hpc_release_ctlr, 1239 1236 .check_lnk_status = hpc_check_lnk_status, 1240 1237 }; 1238 + 1239 + #ifdef CONFIG_ACPI 1240 + int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) 1241 + { 1242 + acpi_status status; 1243 + acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); 1244 + struct pci_dev *pdev = dev; 1245 + struct pci_bus *parent; 1246 + u8 *path_name = NULL; 1247 + 1248 + /* 1249 + * Per PCI firmware specification, we should run the ACPI _OSC 1250 + * method to get control of hotplug hardware before using it. 1251 + * If an _OSC is missing, we look for an OSHP to do the same thing. 1252 + * To handle different BIOS behavior, we look for _OSC and OSHP 1253 + * within the scope of the hotplug controller and its parents, upto 1254 + * the host bridge under which this controller exists. 1255 + */ 1256 + while (!handle) { 1257 + /* 1258 + * This hotplug controller was not listed in the ACPI name 1259 + * space at all. Try to get acpi handle of parent pci bus. 1260 + */ 1261 + if (!pdev || !pdev->bus->parent) 1262 + break; 1263 + parent = pdev->bus->parent; 1264 + dbg("Could not find %s in acpi namespace, trying parent\n", 1265 + pci_name(pdev)); 1266 + if (!parent->self) 1267 + /* Parent must be a host bridge */ 1268 + handle = acpi_get_pci_rootbridge_handle( 1269 + pci_domain_nr(parent), 1270 + parent->number); 1271 + else 1272 + handle = DEVICE_ACPI_HANDLE( 1273 + &(parent->self->dev)); 1274 + pdev = parent->self; 1275 + } 1276 + 1277 + while (handle) { 1278 + path_name = acpi_path_name(handle); 1279 + dbg("Trying to get hotplug control for %s \n", path_name); 1280 + status = pci_osc_control_set(handle, 1281 + OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); 1282 + if (status == AE_NOT_FOUND) 1283 + status = acpi_run_oshp(handle); 1284 + if (ACPI_SUCCESS(status)) { 1285 + dbg("Gained control for hotplug HW for pci %s (%s)\n", 1286 + pci_name(dev), path_name); 1287 + acpi_os_free(path_name); 1288 + return 0; 1289 + } 1290 + if (acpi_root_bridge(handle)) 1291 + break; 1292 + chandle = handle; 1293 + status = acpi_get_parent(chandle, &handle); 1294 + if (ACPI_FAILURE(status)) 1295 + break; 1296 + } 1297 + 1298 + err("Cannot get control of hotplug hardware for pci %s\n", 1299 + pci_name(dev)); 1300 + if (path_name) 1301 + acpi_os_free(path_name); 1302 + return -1; 1303 + } 1304 + #endif 1305 + 1306 + 1241 1307 1242 1308 int pcie_init(struct controller * ctrl, struct pcie_device *dev) 1243 1309 {
-257
drivers/pci/hotplug/pciehprm_acpi.c
··· 1 - /* 2 - * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform 3 - * 4 - * Copyright (C) 2003-2004 Intel Corporation 5 - * 6 - * All rights reserved. 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License as published by 10 - * the Free Software Foundation; either version 2 of the License, or (at 11 - * your option) any later version. 12 - * 13 - * This program is distributed in the hope that it will be useful, but 14 - * WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 16 - * NON INFRINGEMENT. See the GNU General Public License for more 17 - * details. 18 - * 19 - * You should have received a copy of the GNU General Public License 20 - * along with this program; if not, write to the Free Software 21 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 - * 23 - * Send feedback to <kristen.c.accardi@intel.com> 24 - * 25 - */ 26 - 27 - #include <linux/module.h> 28 - #include <linux/kernel.h> 29 - #include <linux/types.h> 30 - #include <linux/pci.h> 31 - #include <linux/acpi.h> 32 - #include <linux/pci-acpi.h> 33 - #include <acpi/acpi_bus.h> 34 - #include <acpi/actypes.h> 35 - #include "pciehp.h" 36 - 37 - #define METHOD_NAME__SUN "_SUN" 38 - #define METHOD_NAME__HPP "_HPP" 39 - #define METHOD_NAME_OSHP "OSHP" 40 - 41 - static u8 * acpi_path_name( acpi_handle handle) 42 - { 43 - acpi_status status; 44 - static u8 path_name[ACPI_PATHNAME_MAX]; 45 - struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name }; 46 - 47 - memset(path_name, 0, sizeof (path_name)); 48 - status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); 49 - 50 - if (ACPI_FAILURE(status)) 51 - return NULL; 52 - else 53 - return path_name; 54 - } 55 - 56 - static acpi_status 57 - acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 58 - { 59 - acpi_status status; 60 - u8 nui[4]; 61 - struct acpi_buffer ret_buf = { 0, NULL}; 62 - union acpi_object *ext_obj, *package; 63 - u8 *path_name = acpi_path_name(handle); 64 - int i, len = 0; 65 - 66 - /* get _hpp */ 67 - status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); 68 - switch (status) { 69 - case AE_BUFFER_OVERFLOW: 70 - ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 71 - if (!ret_buf.pointer) { 72 - err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, 73 - path_name); 74 - return AE_NO_MEMORY; 75 - } 76 - status = acpi_evaluate_object(handle, METHOD_NAME__HPP, 77 - NULL, &ret_buf); 78 - if (ACPI_SUCCESS(status)) 79 - break; 80 - default: 81 - if (ACPI_FAILURE(status)) { 82 - dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 83 - path_name, status); 84 - return status; 85 - } 86 - } 87 - 88 - ext_obj = (union acpi_object *) ret_buf.pointer; 89 - if (ext_obj->type != ACPI_TYPE_PACKAGE) { 90 - err ("%s:%s _HPP obj not a package\n", __FUNCTION__, 91 - path_name); 92 - status = AE_ERROR; 93 - goto free_and_return; 94 - } 95 - 96 - len = ext_obj->package.count; 97 - package = (union acpi_object *) ret_buf.pointer; 98 - for ( i = 0; (i < len) || (i < 4); i++) { 99 - ext_obj = (union acpi_object *) &package->package.elements[i]; 100 - switch (ext_obj->type) { 101 - case ACPI_TYPE_INTEGER: 102 - nui[i] = (u8)ext_obj->integer.value; 103 - break; 104 - default: 105 - err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, 106 - path_name); 107 - status = AE_ERROR; 108 - goto free_and_return; 109 - } 110 - } 111 - 112 - hpp->cache_line_size = nui[0]; 113 - hpp->latency_timer = nui[1]; 114 - hpp->enable_serr = nui[2]; 115 - hpp->enable_perr = nui[3]; 116 - 117 - dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 118 - dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 119 - dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 120 - dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 121 - 122 - free_and_return: 123 - kfree(ret_buf.pointer); 124 - return status; 125 - } 126 - 127 - static acpi_status acpi_run_oshp(acpi_handle handle) 128 - { 129 - acpi_status status; 130 - u8 *path_name = acpi_path_name(handle); 131 - 132 - /* run OSHP */ 133 - status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 134 - if (ACPI_FAILURE(status)) { 135 - dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, 136 - status); 137 - } else { 138 - dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); 139 - } 140 - return status; 141 - } 142 - 143 - static int is_root_bridge(acpi_handle handle) 144 - { 145 - acpi_status status; 146 - struct acpi_device_info *info; 147 - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 148 - int i; 149 - 150 - status = acpi_get_object_info(handle, &buffer); 151 - if (ACPI_SUCCESS(status)) { 152 - info = buffer.pointer; 153 - if ((info->valid & ACPI_VALID_HID) && 154 - !strcmp(PCI_ROOT_HID_STRING, 155 - info->hardware_id.value)) { 156 - acpi_os_free(buffer.pointer); 157 - return 1; 158 - } 159 - if (info->valid & ACPI_VALID_CID) { 160 - for (i=0; i < info->compatibility_id.count; i++) { 161 - if (!strcmp(PCI_ROOT_HID_STRING, 162 - info->compatibility_id.id[i].value)) { 163 - acpi_os_free(buffer.pointer); 164 - return 1; 165 - } 166 - } 167 - } 168 - } 169 - return 0; 170 - } 171 - 172 - int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) 173 - { 174 - acpi_status status; 175 - acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); 176 - struct pci_dev *pdev = dev; 177 - struct pci_bus *parent; 178 - u8 *path_name; 179 - 180 - /* 181 - * Per PCI firmware specification, we should run the ACPI _OSC 182 - * method to get control of hotplug hardware before using it. 183 - * If an _OSC is missing, we look for an OSHP to do the same thing. 184 - * To handle different BIOS behavior, we look for _OSC and OSHP 185 - * within the scope of the hotplug controller and its parents, upto 186 - * the host bridge under which this controller exists. 187 - */ 188 - while (!handle) { 189 - /* 190 - * This hotplug controller was not listed in the ACPI name 191 - * space at all. Try to get acpi handle of parent pci bus. 192 - */ 193 - if (!pdev || !pdev->bus->parent) 194 - break; 195 - parent = pdev->bus->parent; 196 - dbg("Could not find %s in acpi namespace, trying parent\n", 197 - pci_name(pdev)); 198 - if (!parent->self) 199 - /* Parent must be a host bridge */ 200 - handle = acpi_get_pci_rootbridge_handle( 201 - pci_domain_nr(parent), 202 - parent->number); 203 - else 204 - handle = DEVICE_ACPI_HANDLE( 205 - &(parent->self->dev)); 206 - pdev = parent->self; 207 - } 208 - 209 - while (handle) { 210 - path_name = acpi_path_name(handle); 211 - dbg("Trying to get hotplug control for %s \n", path_name); 212 - status = pci_osc_control_set(handle, 213 - OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); 214 - if (status == AE_NOT_FOUND) 215 - status = acpi_run_oshp(handle); 216 - if (ACPI_SUCCESS(status)) { 217 - dbg("Gained control for hotplug HW for pci %s (%s)\n", 218 - pci_name(dev), path_name); 219 - return 0; 220 - } 221 - if (is_root_bridge(handle)) 222 - break; 223 - chandle = handle; 224 - status = acpi_get_parent(chandle, &handle); 225 - if (ACPI_FAILURE(status)) 226 - break; 227 - } 228 - 229 - err("Cannot get control of hotplug hardware for pci %s\n", 230 - pci_name(dev)); 231 - return -1; 232 - } 233 - 234 - void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 235 - struct hotplug_params *hpp) 236 - { 237 - acpi_status status = AE_NOT_FOUND; 238 - struct pci_dev *pdev = dev; 239 - 240 - /* 241 - * _HPP settings apply to all child buses, until another _HPP is 242 - * encountered. If we don't find an _HPP for the input pci dev, 243 - * look for it in the parent device scope since that would apply to 244 - * this pci dev. If we don't find any _HPP, use hardcoded defaults 245 - */ 246 - while (pdev && (ACPI_FAILURE(status))) { 247 - acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); 248 - if (!handle) 249 - break; 250 - status = acpi_run_hpp(handle, hpp); 251 - if (!(pdev->bus->parent)) 252 - break; 253 - /* Check if a parent object supports _HPP */ 254 - pdev = pdev->bus->parent->self; 255 - } 256 - } 257 -
-47
drivers/pci/hotplug/pciehprm_nonacpi.c
··· 1 - /* 2 - * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform 3 - * 4 - * Copyright (C) 1995,2001 Compaq Computer Corporation 5 - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 - * Copyright (C) 2001 IBM Corp. 7 - * Copyright (C) 2003-2004 Intel Corporation 8 - * 9 - * All rights reserved. 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License as published by 13 - * the Free Software Foundation; either version 2 of the License, or (at 14 - * your option) any later version. 15 - * 16 - * This program is distributed in the hope that it will be useful, but 17 - * WITHOUT ANY WARRANTY; without even the implied warranty of 18 - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 - * NON INFRINGEMENT. See the GNU General Public License for more 20 - * details. 21 - * 22 - * You should have received a copy of the GNU General Public License 23 - * along with this program; if not, write to the Free Software 24 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 - * 26 - * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 27 - * 28 - */ 29 - 30 - #include <linux/module.h> 31 - #include <linux/kernel.h> 32 - #include <linux/types.h> 33 - #include <linux/sched.h> 34 - #include <linux/pci.h> 35 - #include <linux/slab.h> 36 - #include "pciehp.h" 37 - 38 - void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 39 - struct hotplug_params *hpp) 40 - { 41 - return; 42 - } 43 - 44 - int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) 45 - { 46 - return 0; 47 - }
+19 -11
drivers/pci/hotplug/shpchp.h
··· 106 106 volatile int cmd_busy; 107 107 }; 108 108 109 - struct hotplug_params { 110 - u8 cache_line_size; 111 - u8 latency_timer; 112 - u8 enable_serr; 113 - u8 enable_perr; 114 - }; 115 109 116 110 /* Define AMD SHPC ID */ 117 111 #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 ··· 187 193 extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); 188 194 extern int shpchp_configure_device(struct slot *p_slot); 189 195 extern int shpchp_unconfigure_device(struct slot *p_slot); 190 - extern void get_hp_hw_control_from_firmware(struct pci_dev *dev); 191 - extern void get_hp_params_from_firmware(struct pci_dev *dev, 192 - struct hotplug_params *hpp); 193 - extern int shpchprm_get_physical_slot_number(struct controller *ctrl, 194 - u32 *sun, u8 busnum, u8 devnum); 195 196 extern void shpchp_remove_ctrl_files(struct controller *ctrl); 196 197 extern void cleanup_slots(struct controller *ctrl); 197 198 extern void queue_pushbutton_work(void *data); 199 + 200 + 201 + #ifdef CONFIG_ACPI 202 + static inline int get_hp_params_from_firmware(struct pci_dev *dev, 203 + struct hotplug_params *hpp) 204 + { 205 + if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) 206 + return -ENODEV; 207 + return 0; 208 + } 209 + #define get_hp_hw_control_from_firmware(pdev) \ 210 + do { \ 211 + if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ 212 + acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \ 213 + } while (0) 214 + #else 215 + #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) 216 + #define get_hp_hw_control_from_firmware(dev) do { } while (0) 217 + #endif 198 218 199 219 struct ctrl_reg { 200 220 volatile u32 base_offset;
+17
drivers/pci/hotplug/shpchp_core.c
··· 104 104 slot->bus, slot->number); 105 105 } 106 106 107 + 108 + 109 + 110 + static int 111 + shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, 112 + u8 busnum, u8 devnum) 113 + { 114 + int offset = devnum - ctrl->slot_device_offset; 115 + 116 + dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, 117 + ctrl->slot_num_inc, offset); 118 + *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); 119 + return 0; 120 + } 121 + 122 + 123 + 107 124 static int init_slots(struct controller *ctrl) 108 125 { 109 126 struct slot *slot;
+8 -2
drivers/pci/hotplug/shpchp_pci.c
··· 38 38 { 39 39 u16 pci_cmd, pci_bctl; 40 40 struct pci_dev *cdev; 41 - struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */ 41 + struct hotplug_params hpp; 42 42 43 43 /* Program hpp values for this device */ 44 44 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || ··· 46 46 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) 47 47 return; 48 48 49 - get_hp_params_from_firmware(dev, &hpp); 49 + /* use default values if we can't get them from firmware */ 50 + if (get_hp_params_from_firmware(dev, &hpp)) { 51 + hpp.cache_line_size = 8; 52 + hpp.latency_timer = 0x40; 53 + hpp.enable_serr = 0; 54 + hpp.enable_perr = 0; 55 + } 50 56 51 57 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); 52 58 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
+91 -50
drivers/pci/hotplug/shpchprm_acpi.c drivers/pci/hotplug/acpi_pcihp.c
··· 1 1 /* 2 - * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform 2 + * Common ACPI functions for hot plug platforms 3 3 * 4 - * Copyright (C) 2003-2004 Intel Corporation 4 + * Copyright (C) 2006 Intel Corporation 5 5 * 6 6 * All rights reserved. 7 7 * ··· 31 31 #include <acpi/acpi.h> 32 32 #include <acpi/acpi_bus.h> 33 33 #include <acpi/actypes.h> 34 - #include "shpchp.h" 34 + #include "pci_hotplug.h" 35 35 36 36 #define METHOD_NAME__SUN "_SUN" 37 37 #define METHOD_NAME__HPP "_HPP" 38 38 #define METHOD_NAME_OSHP "OSHP" 39 39 40 - static u8 * acpi_path_name( acpi_handle handle) 40 + /* acpi_path_name 41 + * 42 + * @handle - the acpi_handle of the object who's name you want. 43 + * 44 + * Caller must free buffer. 45 + */ 46 + u8 * acpi_path_name(acpi_handle handle) 41 47 { 42 - acpi_status status; 43 - static u8 path_name[ACPI_PATHNAME_MAX]; 44 - struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name }; 48 + acpi_status status; 49 + struct acpi_buffer ret_buf = {ACPI_ALLOCATE_BUFFER, NULL}; 50 + union acpi_object *obj; 45 51 46 - memset(path_name, 0, sizeof (path_name)); 47 52 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); 48 - 49 - if (ACPI_FAILURE(status)) 53 + if (ACPI_FAILURE(status)) { 50 54 return NULL; 51 - else 52 - return path_name; 55 + } 56 + obj = ret_buf.pointer; 57 + return obj->string.pointer; 53 58 } 59 + EXPORT_SYMBOL_GPL(acpi_path_name); 60 + 61 + 54 62 55 63 static acpi_status 56 64 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) ··· 76 68 case AE_BUFFER_OVERFLOW: 77 69 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 78 70 if (!ret_buf.pointer) { 79 - err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, 80 - path_name); 71 + printk(KERN_ERR "%s:%s alloc for _HPP fail\n", 72 + __FUNCTION__, path_name); 73 + acpi_os_free(path_name); 81 74 return AE_NO_MEMORY; 82 75 } 83 76 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, ··· 87 78 break; 88 79 default: 89 80 if (ACPI_FAILURE(status)) { 90 - dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 81 + pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 91 82 path_name, status); 83 + acpi_os_free(path_name); 92 84 return status; 93 85 } 94 86 } 95 87 96 88 ext_obj = (union acpi_object *) ret_buf.pointer; 97 89 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 98 - err ("%s:%s _HPP obj not a package\n", __FUNCTION__, 90 + printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__, 99 91 path_name); 100 92 status = AE_ERROR; 101 93 goto free_and_return; ··· 111 101 nui[i] = (u8)ext_obj->integer.value; 112 102 break; 113 103 default: 114 - err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, 115 - path_name); 104 + printk(KERN_ERR "%s:%s _HPP obj type incorrect\n", 105 + __FUNCTION__, path_name); 116 106 status = AE_ERROR; 117 107 goto free_and_return; 118 108 } ··· 123 113 hpp->enable_serr = nui[2]; 124 114 hpp->enable_perr = nui[3]; 125 115 126 - dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 127 - dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 128 - dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 129 - dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 116 + pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 117 + pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 118 + pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 119 + pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 130 120 131 121 free_and_return: 122 + acpi_os_free(path_name); 132 123 kfree(ret_buf.pointer); 133 124 return status; 134 125 } 135 126 136 - static void acpi_run_oshp(acpi_handle handle) 127 + 128 + 129 + /* acpi_run_oshp - get control of hotplug from the firmware 130 + * 131 + * @handle - the handle of the hotplug controller. 132 + */ 133 + acpi_status acpi_run_oshp(acpi_handle handle) 137 134 { 138 135 acpi_status status; 139 136 u8 *path_name = acpi_path_name(handle); 140 137 141 138 /* run OSHP */ 142 139 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 143 - if (ACPI_FAILURE(status)) { 144 - err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, 145 - status); 146 - } else { 147 - dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); 148 - } 140 + if (ACPI_FAILURE(status)) 141 + printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__, 142 + path_name, status); 143 + else 144 + pr_debug("%s:%s OSHP passes\n", __FUNCTION__, path_name); 145 + acpi_os_free(path_name); 146 + return status; 149 147 } 148 + EXPORT_SYMBOL_GPL(acpi_run_oshp); 150 149 151 - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 152 - { 153 - int offset = devnum - ctrl->slot_device_offset; 154 150 155 - dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset); 156 - *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); 157 - return 0; 158 - } 159 151 160 - void get_hp_hw_control_from_firmware(struct pci_dev *dev) 161 - { 162 - /* 163 - * OSHP is an optional ACPI firmware control method. If present, 164 - * we need to run it to inform BIOS that we will control SHPC 165 - * hardware from now on. 166 - */ 167 - acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev)); 168 - if (!handle) 169 - return; 170 - acpi_run_oshp(handle); 171 - } 172 - 173 - void get_hp_params_from_firmware(struct pci_dev *dev, 152 + /* acpi_get_hp_params_from_firmware 153 + * 154 + * @dev - the pci_dev of the newly added device 155 + * @hpp - allocated by the caller 156 + */ 157 + acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 174 158 struct hotplug_params *hpp) 175 159 { 176 160 acpi_status status = AE_NOT_FOUND; ··· 186 182 /* Check if a parent object supports _HPP */ 187 183 pdev = pdev->bus->parent->self; 188 184 } 185 + return status; 189 186 } 187 + EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); 190 188 189 + 190 + /* acpi_root_bridge - check to see if this acpi object is a root bridge 191 + * 192 + * @handle - the acpi object in question. 193 + */ 194 + int acpi_root_bridge(acpi_handle handle) 195 + { 196 + acpi_status status; 197 + struct acpi_device_info *info; 198 + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 199 + int i; 200 + 201 + status = acpi_get_object_info(handle, &buffer); 202 + if (ACPI_SUCCESS(status)) { 203 + info = buffer.pointer; 204 + if ((info->valid & ACPI_VALID_HID) && 205 + !strcmp(PCI_ROOT_HID_STRING, 206 + info->hardware_id.value)) { 207 + acpi_os_free(buffer.pointer); 208 + return 1; 209 + } 210 + if (info->valid & ACPI_VALID_CID) { 211 + for (i=0; i < info->compatibility_id.count; i++) { 212 + if (!strcmp(PCI_ROOT_HID_STRING, 213 + info->compatibility_id.id[i].value)) { 214 + acpi_os_free(buffer.pointer); 215 + return 1; 216 + } 217 + } 218 + } 219 + acpi_os_free(buffer.pointer); 220 + } 221 + return 0; 222 + } 223 + EXPORT_SYMBOL_GPL(acpi_root_bridge);
-54
drivers/pci/hotplug/shpchprm_legacy.c
··· 1 - /* 2 - * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform 3 - * 4 - * Copyright (C) 1995,2001 Compaq Computer Corporation 5 - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 - * Copyright (C) 2001 IBM Corp. 7 - * Copyright (C) 2003-2004 Intel Corporation 8 - * 9 - * All rights reserved. 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License as published by 13 - * the Free Software Foundation; either version 2 of the License, or (at 14 - * your option) any later version. 15 - * 16 - * This program is distributed in the hope that it will be useful, but 17 - * WITHOUT ANY WARRANTY; without even the implied warranty of 18 - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 - * NON INFRINGEMENT. See the GNU General Public License for more 20 - * details. 21 - * 22 - * You should have received a copy of the GNU General Public License 23 - * along with this program; if not, write to the Free Software 24 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 - * 26 - * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com> 27 - * 28 - */ 29 - 30 - #include <linux/module.h> 31 - #include <linux/kernel.h> 32 - #include <linux/types.h> 33 - #include <linux/pci.h> 34 - #include "shpchp.h" 35 - 36 - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 37 - { 38 - int offset = devnum - ctrl->slot_device_offset; 39 - 40 - *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset); 41 - return 0; 42 - } 43 - 44 - void get_hp_params_from_firmware(struct pci_dev *dev, 45 - struct hotplug_params *hpp) 46 - { 47 - return; 48 - } 49 - 50 - void get_hp_hw_control_from_firmware(struct pci_dev *dev) 51 - { 52 - return; 53 - } 54 -
-57
drivers/pci/hotplug/shpchprm_nonacpi.c
··· 1 - /* 2 - * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform 3 - * 4 - * Copyright (C) 1995,2001 Compaq Computer Corporation 5 - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 - * Copyright (C) 2001 IBM Corp. 7 - * Copyright (C) 2003-2004 Intel Corporation 8 - * 9 - * All rights reserved. 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License as published by 13 - * the Free Software Foundation; either version 2 of the License, or (at 14 - * your option) any later version. 15 - * 16 - * This program is distributed in the hope that it will be useful, but 17 - * WITHOUT ANY WARRANTY; without even the implied warranty of 18 - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 - * NON INFRINGEMENT. See the GNU General Public License for more 20 - * details. 21 - * 22 - * You should have received a copy of the GNU General Public License 23 - * along with this program; if not, write to the Free Software 24 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 - * 26 - * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 27 - * 28 - */ 29 - 30 - #include <linux/config.h> 31 - #include <linux/module.h> 32 - #include <linux/kernel.h> 33 - #include <linux/types.h> 34 - #include <linux/pci.h> 35 - #include <linux/slab.h> 36 - 37 - #include "shpchp.h" 38 - 39 - int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 40 - { 41 - int offset = devnum - ctrl->slot_device_offset; 42 - 43 - dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset); 44 - *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset); 45 - return 0; 46 - } 47 - 48 - void get_hp_params_from_firmware(struct pci_dev *dev, 49 - struct hotplug_params *hpp) 50 - { 51 - return; 52 - } 53 - 54 - void get_hp_hw_control_from_firmware(struct pci_dev *dev) 55 - { 56 - return; 57 - }