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

ACPICA: Obsolete the acpi_os_derive_pci_id OSL interface

This function is not OS-dependent and has been replaced by
acpi_hw_derive_pci_id, which is now in the ACPICA core code. Local
implementations of acpi_os_derive_pci_id are no longer necessary and
are removed. ACPICA BZ 857.

http://www.acpica.org/bugzilla/show_bug.cgi?id=857

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Bob Moore and committed by
Len Brown
95abccb5 6087658d

+430 -80
+1 -1
drivers/acpi/acpica/Makefile
··· 21 21 excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ 22 22 exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o 23 23 24 - acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o 24 + acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o 25 25 26 26 acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o 27 27
+7
drivers/acpi/acpica/achware.h
··· 123 123 124 124 #ifdef ACPI_FUTURE_USAGE 125 125 /* 126 + * hwpci - PCI configuration support 127 + */ 128 + acpi_status 129 + acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, 130 + acpi_handle root_pci_device, acpi_handle pci_region); 131 + 132 + /* 126 133 * hwtimer - ACPI Timer prototypes 127 134 */ 128 135 acpi_status acpi_get_timer_resolution(u32 * resolution);
+10 -4
drivers/acpi/acpica/evrgnini.c
··· 289 289 } 290 290 291 291 /* 292 - * Get the PCI device and function numbers from the _ADR object contained 293 - * in the parent's scope. 292 + * Get the PCI device and function numbers from the _ADR object 293 + * contained in the parent's scope. 294 294 */ 295 295 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, 296 296 pci_device_node, &pci_value); ··· 320 320 pci_id->bus = ACPI_LOWORD(pci_value); 321 321 } 322 322 323 - /* Complete this device's pci_id */ 323 + /* Complete/update the PCI ID for this device */ 324 324 325 - acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id); 325 + status = 326 + acpi_hw_derive_pci_id(pci_id, pci_root_node, 327 + region_obj->region.node); 328 + if (ACPI_FAILURE(status)) { 329 + ACPI_FREE(pci_id); 330 + return_ACPI_STATUS(status); 331 + } 326 332 327 333 *region_context = pci_id; 328 334 return_ACPI_STATUS(AE_OK);
+412
drivers/acpi/acpica/hwpci.c
··· 1 + /******************************************************************************* 2 + * 3 + * Module Name: hwpci - Obtain PCI bus, device, and function numbers 4 + * 5 + ******************************************************************************/ 6 + 7 + /* 8 + * Copyright (C) 2000 - 2010, Intel Corp. 9 + * All rights reserved. 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 1. Redistributions of source code must retain the above copyright 15 + * notice, this list of conditions, and the following disclaimer, 16 + * without modification. 17 + * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 + * substantially similar to the "NO WARRANTY" disclaimer below 19 + * ("Disclaimer") and any redistribution must be conditioned upon 20 + * including a substantially similar Disclaimer requirement for further 21 + * binary redistribution. 22 + * 3. Neither the names of the above-listed copyright holders nor the names 23 + * of any contributors may be used to endorse or promote products derived 24 + * from this software without specific prior written permission. 25 + * 26 + * Alternatively, this software may be distributed under the terms of the 27 + * GNU General Public License ("GPL") version 2 as published by the Free 28 + * Software Foundation. 29 + * 30 + * NO WARRANTY 31 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 + * POSSIBILITY OF SUCH DAMAGES. 42 + */ 43 + 44 + #include <acpi/acpi.h> 45 + #include "accommon.h" 46 + 47 + #define _COMPONENT ACPI_NAMESPACE 48 + ACPI_MODULE_NAME("hwpci") 49 + 50 + /* PCI configuration space values */ 51 + #define PCI_CFG_HEADER_TYPE_REG 0x0E 52 + #define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18 53 + #define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19 54 + /* PCI header values */ 55 + #define PCI_HEADER_TYPE_MASK 0x7F 56 + #define PCI_TYPE_BRIDGE 0x01 57 + #define PCI_TYPE_CARDBUS_BRIDGE 0x02 58 + typedef struct acpi_pci_device { 59 + acpi_handle device; 60 + struct acpi_pci_device *next; 61 + 62 + } acpi_pci_device; 63 + 64 + /* Local prototypes */ 65 + 66 + static acpi_status 67 + acpi_hw_build_pci_list(acpi_handle root_pci_device, 68 + acpi_handle pci_region, 69 + struct acpi_pci_device **return_list_head); 70 + 71 + static acpi_status 72 + acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, 73 + struct acpi_pci_device *list_head); 74 + 75 + static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head); 76 + 77 + static acpi_status 78 + acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, 79 + acpi_handle pci_device, 80 + u16 *bus_number, u8 *is_bridge); 81 + 82 + /******************************************************************************* 83 + * 84 + * FUNCTION: acpi_hw_derive_pci_id 85 + * 86 + * PARAMETERS: pci_id - Initial values for the PCI ID. May be 87 + * modified by this function. 88 + * root_pci_device - A handle to a PCI device object. This 89 + * object must be a PCI Root Bridge having a 90 + * _HID value of either PNP0A03 or PNP0A08 91 + * pci_region - A handle to a PCI configuration space 92 + * Operation Region being initialized 93 + * 94 + * RETURN: Status 95 + * 96 + * DESCRIPTION: This function derives a full PCI ID for a PCI device, 97 + * consisting of a Segment number, Bus number, Device number, 98 + * and function code. 99 + * 100 + * The PCI hardware dynamically configures PCI bus numbers 101 + * depending on the bus topology discovered during system 102 + * initialization. This function is invoked during configuration 103 + * of a PCI_Config Operation Region in order to (possibly) update 104 + * the Bus/Device/Function numbers in the pci_id with the actual 105 + * values as determined by the hardware and operating system 106 + * configuration. 107 + * 108 + * The pci_id parameter is initially populated during the Operation 109 + * Region initialization. This function is then called, and is 110 + * will make any necessary modifications to the Bus, Device, or 111 + * Function number PCI ID subfields as appropriate for the 112 + * current hardware and OS configuration. 113 + * 114 + * NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id 115 + * interface since this feature is OS-independent. This module 116 + * specifically avoids any use of recursion by building a local 117 + * temporary device list. 118 + * 119 + ******************************************************************************/ 120 + 121 + acpi_status 122 + acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, 123 + acpi_handle root_pci_device, acpi_handle pci_region) 124 + { 125 + acpi_status status; 126 + struct acpi_pci_device *list_head = NULL; 127 + 128 + ACPI_FUNCTION_TRACE(hw_derive_pci_id); 129 + 130 + if (!pci_id) { 131 + return_ACPI_STATUS(AE_BAD_PARAMETER); 132 + } 133 + 134 + /* Build a list of PCI devices, from pci_region up to root_pci_device */ 135 + 136 + status = 137 + acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head); 138 + if (ACPI_SUCCESS(status)) { 139 + 140 + /* Walk the list, updating the PCI device/function/bus numbers */ 141 + 142 + status = acpi_hw_process_pci_list(pci_id, list_head); 143 + } 144 + 145 + /* Always delete the list */ 146 + 147 + acpi_hw_delete_pci_list(list_head); 148 + return_ACPI_STATUS(status); 149 + } 150 + 151 + /******************************************************************************* 152 + * 153 + * FUNCTION: acpi_hw_build_pci_list 154 + * 155 + * PARAMETERS: root_pci_device - A handle to a PCI device object. This 156 + * object is guaranteed to be a PCI Root 157 + * Bridge having a _HID value of either 158 + * PNP0A03 or PNP0A08 159 + * pci_region - A handle to the PCI configuration space 160 + * Operation Region 161 + * return_list_head - Where the PCI device list is returned 162 + * 163 + * RETURN: Status 164 + * 165 + * DESCRIPTION: Builds a list of devices from the input PCI region up to the 166 + * Root PCI device for this namespace subtree. 167 + * 168 + ******************************************************************************/ 169 + 170 + static acpi_status 171 + acpi_hw_build_pci_list(acpi_handle root_pci_device, 172 + acpi_handle pci_region, 173 + struct acpi_pci_device **return_list_head) 174 + { 175 + acpi_handle current_device; 176 + acpi_handle parent_device; 177 + acpi_status status; 178 + struct acpi_pci_device *list_element; 179 + struct acpi_pci_device *list_head = NULL; 180 + 181 + /* 182 + * Ascend namespace branch until the root_pci_device is reached, building 183 + * a list of device nodes. Loop will exit when either the PCI device is 184 + * found, or the root of the namespace is reached. 185 + */ 186 + current_device = pci_region; 187 + while (1) { 188 + status = acpi_get_parent(current_device, &parent_device); 189 + if (ACPI_FAILURE(status)) { 190 + return (status); 191 + } 192 + 193 + /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */ 194 + 195 + if (parent_device == root_pci_device) { 196 + *return_list_head = list_head; 197 + return (AE_OK); 198 + } 199 + 200 + list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); 201 + if (!list_element) { 202 + return (AE_NO_MEMORY); 203 + } 204 + 205 + /* Put new element at the head of the list */ 206 + 207 + list_element->next = list_head; 208 + list_element->device = parent_device; 209 + list_head = list_element; 210 + 211 + current_device = parent_device; 212 + } 213 + } 214 + 215 + /******************************************************************************* 216 + * 217 + * FUNCTION: acpi_hw_process_pci_list 218 + * 219 + * PARAMETERS: pci_id - Initial values for the PCI ID. May be 220 + * modified by this function. 221 + * list_head - Device list created by 222 + * acpi_hw_build_pci_list 223 + * 224 + * RETURN: Status 225 + * 226 + * DESCRIPTION: Walk downward through the PCI device list, getting the device 227 + * info for each, via the PCI configuration space and updating 228 + * the PCI ID as necessary. Deletes the list during traversal. 229 + * 230 + ******************************************************************************/ 231 + 232 + static acpi_status 233 + acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, 234 + struct acpi_pci_device *list_head) 235 + { 236 + acpi_status status = AE_OK; 237 + struct acpi_pci_device *info; 238 + u16 bus_number; 239 + u8 is_bridge = TRUE; 240 + 241 + ACPI_FUNCTION_NAME(hw_process_pci_list); 242 + 243 + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 244 + "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n", 245 + pci_id->segment, pci_id->bus, pci_id->device, 246 + pci_id->function)); 247 + 248 + bus_number = pci_id->bus; 249 + 250 + /* 251 + * Descend down the namespace tree, collecting PCI device, function, 252 + * and bus numbers. bus_number is only important for PCI bridges. 253 + * Algorithm: As we descend the tree, use the last valid PCI device, 254 + * function, and bus numbers that are discovered, and assign them 255 + * to the PCI ID for the target device. 256 + */ 257 + info = list_head; 258 + while (info) { 259 + status = acpi_hw_get_pci_device_info(pci_id, info->device, 260 + &bus_number, &is_bridge); 261 + if (ACPI_FAILURE(status)) { 262 + return_ACPI_STATUS(status); 263 + } 264 + 265 + info = info->next; 266 + } 267 + 268 + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 269 + "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X " 270 + "Status %X BusNumber %X IsBridge %X\n", 271 + pci_id->segment, pci_id->bus, pci_id->device, 272 + pci_id->function, status, bus_number, is_bridge)); 273 + 274 + return_ACPI_STATUS(AE_OK); 275 + } 276 + 277 + /******************************************************************************* 278 + * 279 + * FUNCTION: acpi_hw_delete_pci_list 280 + * 281 + * PARAMETERS: list_head - Device list created by 282 + * acpi_hw_build_pci_list 283 + * 284 + * RETURN: None 285 + * 286 + * DESCRIPTION: Free the entire PCI list. 287 + * 288 + ******************************************************************************/ 289 + 290 + static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head) 291 + { 292 + struct acpi_pci_device *next; 293 + struct acpi_pci_device *previous; 294 + 295 + next = list_head; 296 + while (next) { 297 + previous = next; 298 + next = previous->next; 299 + ACPI_FREE(previous); 300 + } 301 + } 302 + 303 + /******************************************************************************* 304 + * 305 + * FUNCTION: acpi_hw_get_pci_device_info 306 + * 307 + * PARAMETERS: pci_id - Initial values for the PCI ID. May be 308 + * modified by this function. 309 + * pci_device - Handle for the PCI device object 310 + * bus_number - Where a PCI bridge bus number is returned 311 + * is_bridge - Return value, indicates if this PCI 312 + * device is a PCI bridge 313 + * 314 + * RETURN: Status 315 + * 316 + * DESCRIPTION: Get the device info for a single PCI device object. Get the 317 + * _ADR (contains PCI device and function numbers), and for PCI 318 + * bridge devices, get the bus number from PCI configuration 319 + * space. 320 + * 321 + ******************************************************************************/ 322 + 323 + static acpi_status 324 + acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, 325 + acpi_handle pci_device, 326 + u16 *bus_number, u8 *is_bridge) 327 + { 328 + acpi_status status; 329 + acpi_object_type object_type; 330 + u64 return_value; 331 + u64 pci_value; 332 + 333 + /* We only care about objects of type Device */ 334 + 335 + status = acpi_get_type(pci_device, &object_type); 336 + if (ACPI_FAILURE(status)) { 337 + return (status); 338 + } 339 + 340 + if (object_type != ACPI_TYPE_DEVICE) { 341 + return (AE_OK); 342 + } 343 + 344 + /* We need an _ADR. Ignore device if not present */ 345 + 346 + status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, 347 + pci_device, &return_value); 348 + if (ACPI_FAILURE(status)) { 349 + return (AE_OK); 350 + } 351 + 352 + /* 353 + * From _ADR, get the PCI Device and Function and 354 + * update the PCI ID. 355 + */ 356 + pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value)); 357 + pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value)); 358 + 359 + /* 360 + * If the previous device was a bridge, use the previous 361 + * device bus number 362 + */ 363 + if (*is_bridge) { 364 + pci_id->bus = *bus_number; 365 + } 366 + 367 + /* 368 + * Get the bus numbers from PCI Config space: 369 + * 370 + * First, get the PCI header_type 371 + */ 372 + *is_bridge = FALSE; 373 + status = acpi_os_read_pci_configuration(pci_id, 374 + PCI_CFG_HEADER_TYPE_REG, 375 + &pci_value, 8); 376 + if (ACPI_FAILURE(status)) { 377 + return (status); 378 + } 379 + 380 + /* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */ 381 + 382 + pci_value &= PCI_HEADER_TYPE_MASK; 383 + 384 + if ((pci_value != PCI_TYPE_BRIDGE) && 385 + (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) { 386 + return (AE_OK); 387 + } 388 + 389 + /* Bridge: Get the Primary bus_number */ 390 + 391 + status = acpi_os_read_pci_configuration(pci_id, 392 + PCI_CFG_PRIMARY_BUS_NUMBER_REG, 393 + &pci_value, 8); 394 + if (ACPI_FAILURE(status)) { 395 + return (status); 396 + } 397 + 398 + *is_bridge = TRUE; 399 + pci_id->bus = (u16)pci_value; 400 + 401 + /* Bridge: Get the Secondary bus_number */ 402 + 403 + status = acpi_os_read_pci_configuration(pci_id, 404 + PCI_CFG_SECONDARY_BUS_NUMBER_REG, 405 + &pci_value, 8); 406 + if (ACPI_FAILURE(status)) { 407 + return (status); 408 + } 409 + 410 + *bus_number = (u16)pci_value; 411 + return (AE_OK); 412 + }
-68
drivers/acpi/osl.c
··· 622 622 return (result ? AE_ERROR : AE_OK); 623 623 } 624 624 625 - /* TODO: Change code to take advantage of driver model more */ 626 - static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ 627 - acpi_handle chandle, /* current node */ 628 - struct acpi_pci_id **id, 629 - int *is_bridge, u8 * bus_number) 630 - { 631 - acpi_handle handle; 632 - struct acpi_pci_id *pci_id = *id; 633 - acpi_status status; 634 - unsigned long long temp; 635 - acpi_object_type type; 636 - 637 - acpi_get_parent(chandle, &handle); 638 - if (handle != rhandle) { 639 - acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, 640 - bus_number); 641 - 642 - status = acpi_get_type(handle, &type); 643 - if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) 644 - return; 645 - 646 - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, 647 - &temp); 648 - if (ACPI_SUCCESS(status)) { 649 - u64 val; 650 - pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); 651 - pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); 652 - 653 - if (*is_bridge) 654 - pci_id->bus = *bus_number; 655 - 656 - /* any nicer way to get bus number of bridge ? */ 657 - status = 658 - acpi_os_read_pci_configuration(pci_id, 0x0e, &val, 659 - 8); 660 - if (ACPI_SUCCESS(status) 661 - && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) { 662 - status = 663 - acpi_os_read_pci_configuration(pci_id, 0x18, 664 - &val, 8); 665 - if (!ACPI_SUCCESS(status)) { 666 - /* Certainly broken... FIX ME */ 667 - return; 668 - } 669 - *is_bridge = 1; 670 - pci_id->bus = val; 671 - status = 672 - acpi_os_read_pci_configuration(pci_id, 0x19, 673 - &val, 8); 674 - if (ACPI_SUCCESS(status)) { 675 - *bus_number = val; 676 - } 677 - } else 678 - *is_bridge = 0; 679 - } 680 - } 681 - } 682 - 683 - void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ 684 - acpi_handle chandle, /* current node */ 685 - struct acpi_pci_id **id) 686 - { 687 - int is_bridge = 1; 688 - u8 bus_number = (*id)->bus; 689 - 690 - acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); 691 - } 692 - 693 625 static void acpi_os_execute_deferred(struct work_struct *work) 694 626 { 695 627 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
-7
include/acpi/acpiosxf.h
··· 230 230 u32 reg, u64 value, u32 width); 231 231 232 232 /* 233 - * Interim function needed for PCI IRQ routing 234 - */ 235 - void 236 - acpi_os_derive_pci_id(acpi_handle device, 237 - acpi_handle region, struct acpi_pci_id **pci_id); 238 - 239 - /* 240 233 * Miscellaneous 241 234 */ 242 235 acpi_status