2 * Common ACPI functions for hot plug platforms
4 * Copyright (C) 2006 Intel Corporation
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.
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
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.
23 * Send feedback to <kristen.c.accardi@intel.com>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <linux/pci_hotplug.h>
33 #include <linux/acpi.h>
34 #include <linux/pci-acpi.h>
35 #include <linux/slab.h>
37 #define MY_NAME "acpi_pcihp"
39 #define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __func__ , ## arg); } while (0)
40 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
41 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
42 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
44 #define METHOD_NAME__SUN "_SUN"
45 #define METHOD_NAME_OSHP "OSHP"
47 static bool debug_acpi
;
50 decode_type0_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
53 union acpi_object
*fields
= record
->package
.elements
;
54 u32 revision
= fields
[1].integer
.value
;
58 if (record
->package
.count
!= 6)
60 for (i
= 2; i
< 6; i
++)
61 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
63 hpx
->t0
= &hpx
->type0_data
;
64 hpx
->t0
->revision
= revision
;
65 hpx
->t0
->cache_line_size
= fields
[2].integer
.value
;
66 hpx
->t0
->latency_timer
= fields
[3].integer
.value
;
67 hpx
->t0
->enable_serr
= fields
[4].integer
.value
;
68 hpx
->t0
->enable_perr
= fields
[5].integer
.value
;
72 "%s: Type 0 Revision %d record not supported\n",
80 decode_type1_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
83 union acpi_object
*fields
= record
->package
.elements
;
84 u32 revision
= fields
[1].integer
.value
;
88 if (record
->package
.count
!= 5)
90 for (i
= 2; i
< 5; i
++)
91 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
93 hpx
->t1
= &hpx
->type1_data
;
94 hpx
->t1
->revision
= revision
;
95 hpx
->t1
->max_mem_read
= fields
[2].integer
.value
;
96 hpx
->t1
->avg_max_split
= fields
[3].integer
.value
;
97 hpx
->t1
->tot_max_split
= fields
[4].integer
.value
;
101 "%s: Type 1 Revision %d record not supported\n",
109 decode_type2_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
112 union acpi_object
*fields
= record
->package
.elements
;
113 u32 revision
= fields
[1].integer
.value
;
117 if (record
->package
.count
!= 18)
119 for (i
= 2; i
< 18; i
++)
120 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
122 hpx
->t2
= &hpx
->type2_data
;
123 hpx
->t2
->revision
= revision
;
124 hpx
->t2
->unc_err_mask_and
= fields
[2].integer
.value
;
125 hpx
->t2
->unc_err_mask_or
= fields
[3].integer
.value
;
126 hpx
->t2
->unc_err_sever_and
= fields
[4].integer
.value
;
127 hpx
->t2
->unc_err_sever_or
= fields
[5].integer
.value
;
128 hpx
->t2
->cor_err_mask_and
= fields
[6].integer
.value
;
129 hpx
->t2
->cor_err_mask_or
= fields
[7].integer
.value
;
130 hpx
->t2
->adv_err_cap_and
= fields
[8].integer
.value
;
131 hpx
->t2
->adv_err_cap_or
= fields
[9].integer
.value
;
132 hpx
->t2
->pci_exp_devctl_and
= fields
[10].integer
.value
;
133 hpx
->t2
->pci_exp_devctl_or
= fields
[11].integer
.value
;
134 hpx
->t2
->pci_exp_lnkctl_and
= fields
[12].integer
.value
;
135 hpx
->t2
->pci_exp_lnkctl_or
= fields
[13].integer
.value
;
136 hpx
->t2
->sec_unc_err_sever_and
= fields
[14].integer
.value
;
137 hpx
->t2
->sec_unc_err_sever_or
= fields
[15].integer
.value
;
138 hpx
->t2
->sec_unc_err_mask_and
= fields
[16].integer
.value
;
139 hpx
->t2
->sec_unc_err_mask_or
= fields
[17].integer
.value
;
143 "%s: Type 2 Revision %d record not supported\n",
151 acpi_run_hpx(acpi_handle handle
, struct hotplug_params
*hpx
)
154 struct acpi_buffer buffer
= {ACPI_ALLOCATE_BUFFER
, NULL
};
155 union acpi_object
*package
, *record
, *fields
;
159 /* Clear the return buffer with zeros */
160 memset(hpx
, 0, sizeof(struct hotplug_params
));
162 status
= acpi_evaluate_object(handle
, "_HPX", NULL
, &buffer
);
163 if (ACPI_FAILURE(status
))
166 package
= (union acpi_object
*)buffer
.pointer
;
167 if (package
->type
!= ACPI_TYPE_PACKAGE
) {
172 for (i
= 0; i
< package
->package
.count
; i
++) {
173 record
= &package
->package
.elements
[i
];
174 if (record
->type
!= ACPI_TYPE_PACKAGE
) {
179 fields
= record
->package
.elements
;
180 if (fields
[0].type
!= ACPI_TYPE_INTEGER
||
181 fields
[1].type
!= ACPI_TYPE_INTEGER
) {
186 type
= fields
[0].integer
.value
;
189 status
= decode_type0_hpx_record(record
, hpx
);
190 if (ACPI_FAILURE(status
))
194 status
= decode_type1_hpx_record(record
, hpx
);
195 if (ACPI_FAILURE(status
))
199 status
= decode_type2_hpx_record(record
, hpx
);
200 if (ACPI_FAILURE(status
))
204 printk(KERN_ERR
"%s: Type %d record not supported\n",
211 kfree(buffer
.pointer
);
216 acpi_run_hpp(acpi_handle handle
, struct hotplug_params
*hpp
)
219 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
220 union acpi_object
*package
, *fields
;
223 memset(hpp
, 0, sizeof(struct hotplug_params
));
225 status
= acpi_evaluate_object(handle
, "_HPP", NULL
, &buffer
);
226 if (ACPI_FAILURE(status
))
229 package
= (union acpi_object
*) buffer
.pointer
;
230 if (package
->type
!= ACPI_TYPE_PACKAGE
||
231 package
->package
.count
!= 4) {
236 fields
= package
->package
.elements
;
237 for (i
= 0; i
< 4; i
++) {
238 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
) {
244 hpp
->t0
= &hpp
->type0_data
;
245 hpp
->t0
->revision
= 1;
246 hpp
->t0
->cache_line_size
= fields
[0].integer
.value
;
247 hpp
->t0
->latency_timer
= fields
[1].integer
.value
;
248 hpp
->t0
->enable_serr
= fields
[2].integer
.value
;
249 hpp
->t0
->enable_perr
= fields
[3].integer
.value
;
252 kfree(buffer
.pointer
);
258 /* acpi_run_oshp - get control of hotplug from the firmware
260 * @handle - the handle of the hotplug controller.
262 static acpi_status
acpi_run_oshp(acpi_handle handle
)
265 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
267 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
270 status
= acpi_evaluate_object(handle
, METHOD_NAME_OSHP
, NULL
, NULL
);
271 if (ACPI_FAILURE(status
))
272 if (status
!= AE_NOT_FOUND
)
273 printk(KERN_ERR
"%s:%s OSHP fails=0x%x\n",
274 __func__
, (char *)string
.pointer
, status
);
276 dbg("%s:%s OSHP not found\n",
277 __func__
, (char *)string
.pointer
);
279 pr_debug("%s:%s OSHP passes\n", __func__
,
280 (char *)string
.pointer
);
282 kfree(string
.pointer
);
288 * @dev - the pci_dev for which we want parameters
289 * @hpp - allocated by the caller
291 int pci_get_hp_params(struct pci_dev
*dev
, struct hotplug_params
*hpp
)
294 acpi_handle handle
, phandle
;
295 struct pci_bus
*pbus
;
298 for (pbus
= dev
->bus
; pbus
; pbus
= pbus
->parent
) {
299 handle
= acpi_pci_get_bridge_handle(pbus
);
305 * _HPP settings apply to all child buses, until another _HPP is
306 * encountered. If we don't find an _HPP for the input pci dev,
307 * look for it in the parent device scope since that would apply to
311 status
= acpi_run_hpx(handle
, hpp
);
312 if (ACPI_SUCCESS(status
))
314 status
= acpi_run_hpp(handle
, hpp
);
315 if (ACPI_SUCCESS(status
))
317 if (acpi_is_root_bridge(handle
))
319 status
= acpi_get_parent(handle
, &phandle
);
320 if (ACPI_FAILURE(status
))
326 EXPORT_SYMBOL_GPL(pci_get_hp_params
);
329 * acpi_get_hp_hw_control_from_firmware
330 * @dev: the pci_dev of the bridge that has a hotplug controller
331 * @flags: requested control bits for _OSC
333 * Attempt to take hotplug control from firmware.
335 int acpi_get_hp_hw_control_from_firmware(struct pci_dev
*pdev
, u32 flags
)
338 acpi_handle chandle
, handle
;
339 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
341 flags
&= OSC_PCI_SHPC_NATIVE_HP_CONTROL
;
343 err("Invalid flags %u specified!\n", flags
);
348 * Per PCI firmware specification, we should run the ACPI _OSC
349 * method to get control of hotplug hardware before using it. If
350 * an _OSC is missing, we look for an OSHP to do the same thing.
351 * To handle different BIOS behavior, we look for _OSC on a root
352 * bridge preferentially (according to PCI fw spec). Later for
353 * OSHP within the scope of the hotplug controller and its parents,
354 * up to the host bridge under which this controller exists.
356 handle
= acpi_find_root_bridge_handle(pdev
);
358 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
359 dbg("Trying to get hotplug control for %s\n",
360 (char *)string
.pointer
);
361 status
= acpi_pci_osc_control_set(handle
, &flags
, flags
);
362 if (ACPI_SUCCESS(status
))
364 if (status
== AE_SUPPORT
)
366 kfree(string
.pointer
);
367 string
= (struct acpi_buffer
){ ACPI_ALLOCATE_BUFFER
, NULL
};
370 handle
= ACPI_HANDLE(&pdev
->dev
);
373 * This hotplug controller was not listed in the ACPI name
374 * space at all. Try to get acpi handle of parent pci bus.
376 struct pci_bus
*pbus
;
377 for (pbus
= pdev
->bus
; pbus
; pbus
= pbus
->parent
) {
378 handle
= acpi_pci_get_bridge_handle(pbus
);
385 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
386 dbg("Trying to get hotplug control for %s \n",
387 (char *)string
.pointer
);
388 status
= acpi_run_oshp(handle
);
389 if (ACPI_SUCCESS(status
))
391 if (acpi_is_root_bridge(handle
))
394 status
= acpi_get_parent(chandle
, &handle
);
395 if (ACPI_FAILURE(status
))
399 dbg("Cannot get control of hotplug hardware for pci %s\n",
401 kfree(string
.pointer
);
404 dbg("Gained control for hotplug HW for pci %s (%s)\n",
405 pci_name(pdev
), (char *)string
.pointer
);
406 kfree(string
.pointer
);
409 EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware
);
411 static int pcihp_is_ejectable(acpi_handle handle
)
414 unsigned long long removable
;
415 if (!acpi_has_method(handle
, "_ADR"))
417 if (acpi_has_method(handle
, "_EJ0"))
419 status
= acpi_evaluate_integer(handle
, "_RMV", NULL
, &removable
);
420 if (ACPI_SUCCESS(status
) && removable
)
426 * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot
427 * @pbus: the PCI bus of the PCI slot corresponding to 'handle'
428 * @handle: ACPI handle to check
430 * Return 1 if handle is ejectable PCI slot, 0 otherwise.
432 int acpi_pci_check_ejectable(struct pci_bus
*pbus
, acpi_handle handle
)
434 acpi_handle bridge_handle
, parent_handle
;
436 if (!(bridge_handle
= acpi_pci_get_bridge_handle(pbus
)))
438 if ((ACPI_FAILURE(acpi_get_parent(handle
, &parent_handle
))))
440 if (bridge_handle
!= parent_handle
)
442 return pcihp_is_ejectable(handle
);
444 EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable
);
447 check_hotplug(acpi_handle handle
, u32 lvl
, void *context
, void **rv
)
449 int *found
= (int *)context
;
450 if (pcihp_is_ejectable(handle
)) {
452 return AE_CTRL_TERMINATE
;
458 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
459 * @handle - handle of the PCI bus to scan
461 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
463 int acpi_pci_detect_ejectable(acpi_handle handle
)
470 acpi_walk_namespace(ACPI_TYPE_DEVICE
, handle
, 1,
471 check_hotplug
, NULL
, (void *)&found
, NULL
);
474 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable
);
476 module_param(debug_acpi
, bool, 0644);
477 MODULE_PARM_DESC(debug_acpi
, "Debugging mode for ACPI enabled or not");