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>
36 #define MY_NAME "acpi_pcihp"
38 #define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __func__ , ## arg); } while (0)
39 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
40 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
41 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
43 #define METHOD_NAME__SUN "_SUN"
44 #define METHOD_NAME__HPP "_HPP"
45 #define METHOD_NAME_OSHP "OSHP"
47 static int 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
)
220 struct acpi_buffer ret_buf
= { 0, NULL
};
221 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
222 union acpi_object
*ext_obj
, *package
;
225 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
227 /* Clear the return buffer with zeros */
228 memset(hpp
, 0, sizeof(struct hotplug_params
));
231 status
= acpi_evaluate_object(handle
, METHOD_NAME__HPP
, NULL
, &ret_buf
);
233 case AE_BUFFER_OVERFLOW
:
234 ret_buf
.pointer
= kmalloc (ret_buf
.length
, GFP_KERNEL
);
235 if (!ret_buf
.pointer
) {
236 printk(KERN_ERR
"%s:%s alloc for _HPP fail\n",
237 __func__
, (char *)string
.pointer
);
238 kfree(string
.pointer
);
241 status
= acpi_evaluate_object(handle
, METHOD_NAME__HPP
,
243 if (ACPI_SUCCESS(status
))
246 if (ACPI_FAILURE(status
)) {
247 pr_debug("%s:%s _HPP fail=0x%x\n", __func__
,
248 (char *)string
.pointer
, status
);
249 kfree(string
.pointer
);
254 ext_obj
= (union acpi_object
*) ret_buf
.pointer
;
255 if (ext_obj
->type
!= ACPI_TYPE_PACKAGE
) {
256 printk(KERN_ERR
"%s:%s _HPP obj not a package\n", __func__
,
257 (char *)string
.pointer
);
259 goto free_and_return
;
262 len
= ext_obj
->package
.count
;
263 package
= (union acpi_object
*) ret_buf
.pointer
;
264 for ( i
= 0; (i
< len
) || (i
< 4); i
++) {
265 ext_obj
= (union acpi_object
*) &package
->package
.elements
[i
];
266 switch (ext_obj
->type
) {
267 case ACPI_TYPE_INTEGER
:
268 nui
[i
] = (u8
)ext_obj
->integer
.value
;
271 printk(KERN_ERR
"%s:%s _HPP obj type incorrect\n",
272 __func__
, (char *)string
.pointer
);
274 goto free_and_return
;
278 hpp
->t0
= &hpp
->type0_data
;
279 hpp
->t0
->cache_line_size
= nui
[0];
280 hpp
->t0
->latency_timer
= nui
[1];
281 hpp
->t0
->enable_serr
= nui
[2];
282 hpp
->t0
->enable_perr
= nui
[3];
284 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp
->t0
->cache_line_size
);
285 pr_debug(" _HPP: latency timer =0x%x\n", hpp
->t0
->latency_timer
);
286 pr_debug(" _HPP: enable SERR =0x%x\n", hpp
->t0
->enable_serr
);
287 pr_debug(" _HPP: enable PERR =0x%x\n", hpp
->t0
->enable_perr
);
290 kfree(string
.pointer
);
291 kfree(ret_buf
.pointer
);
297 /* acpi_run_oshp - get control of hotplug from the firmware
299 * @handle - the handle of the hotplug controller.
301 static acpi_status
acpi_run_oshp(acpi_handle handle
)
304 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
306 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
309 status
= acpi_evaluate_object(handle
, METHOD_NAME_OSHP
, NULL
, NULL
);
310 if (ACPI_FAILURE(status
))
311 if (status
!= AE_NOT_FOUND
)
312 printk(KERN_ERR
"%s:%s OSHP fails=0x%x\n",
313 __func__
, (char *)string
.pointer
, status
);
315 dbg("%s:%s OSHP not found\n",
316 __func__
, (char *)string
.pointer
);
318 pr_debug("%s:%s OSHP passes\n", __func__
,
319 (char *)string
.pointer
);
321 kfree(string
.pointer
);
327 * @dev - the pci_dev for which we want parameters
328 * @hpp - allocated by the caller
330 int pci_get_hp_params(struct pci_dev
*dev
, struct hotplug_params
*hpp
)
333 acpi_handle handle
, phandle
;
334 struct pci_bus
*pbus
;
337 for (pbus
= dev
->bus
; pbus
; pbus
= pbus
->parent
) {
338 handle
= acpi_pci_get_bridge_handle(pbus
);
344 * _HPP settings apply to all child buses, until another _HPP is
345 * encountered. If we don't find an _HPP for the input pci dev,
346 * look for it in the parent device scope since that would apply to
350 status
= acpi_run_hpx(handle
, hpp
);
351 if (ACPI_SUCCESS(status
))
353 status
= acpi_run_hpp(handle
, hpp
);
354 if (ACPI_SUCCESS(status
))
356 if (acpi_is_root_bridge(handle
))
358 status
= acpi_get_parent(handle
, &phandle
);
359 if (ACPI_FAILURE(status
))
365 EXPORT_SYMBOL_GPL(pci_get_hp_params
);
368 * acpi_get_hp_hw_control_from_firmware
369 * @dev: the pci_dev of the bridge that has a hotplug controller
370 * @flags: requested control bits for _OSC
372 * Attempt to take hotplug control from firmware.
374 int acpi_get_hp_hw_control_from_firmware(struct pci_dev
*pdev
, u32 flags
)
377 acpi_handle chandle
, handle
;
378 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
380 flags
&= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
|
381 OSC_SHPC_NATIVE_HP_CONTROL
|
382 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
);
384 err("Invalid flags %u specified!\n", flags
);
389 * Per PCI firmware specification, we should run the ACPI _OSC
390 * method to get control of hotplug hardware before using it. If
391 * an _OSC is missing, we look for an OSHP to do the same thing.
392 * To handle different BIOS behavior, we look for _OSC on a root
393 * bridge preferentially (according to PCI fw spec). Later for
394 * OSHP within the scope of the hotplug controller and its parents,
395 * upto the host bridge under which this controller exists.
397 handle
= acpi_find_root_bridge_handle(pdev
);
399 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
400 dbg("Trying to get hotplug control for %s\n",
401 (char *)string
.pointer
);
402 status
= acpi_pci_osc_control_set(handle
, flags
);
403 if (ACPI_SUCCESS(status
))
405 kfree(string
.pointer
);
406 string
= (struct acpi_buffer
){ ACPI_ALLOCATE_BUFFER
, NULL
};
409 handle
= DEVICE_ACPI_HANDLE(&pdev
->dev
);
412 * This hotplug controller was not listed in the ACPI name
413 * space at all. Try to get acpi handle of parent pci bus.
415 struct pci_bus
*pbus
;
416 for (pbus
= pdev
->bus
; pbus
; pbus
= pbus
->parent
) {
417 handle
= acpi_pci_get_bridge_handle(pbus
);
424 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
425 dbg("Trying to get hotplug control for %s \n",
426 (char *)string
.pointer
);
427 status
= acpi_run_oshp(handle
);
428 if (ACPI_SUCCESS(status
))
430 if (acpi_is_root_bridge(handle
))
433 status
= acpi_get_parent(chandle
, &handle
);
434 if (ACPI_FAILURE(status
))
438 dbg("Cannot get control of hotplug hardware for pci %s\n",
441 kfree(string
.pointer
);
444 dbg("Gained control for hotplug HW for pci %s (%s)\n",
445 pci_name(pdev
), (char *)string
.pointer
);
446 kfree(string
.pointer
);
449 EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware
);
451 static int is_ejectable(acpi_handle handle
)
455 unsigned long long removable
;
456 status
= acpi_get_handle(handle
, "_ADR", &tmp
);
457 if (ACPI_FAILURE(status
))
459 status
= acpi_get_handle(handle
, "_EJ0", &tmp
);
460 if (ACPI_SUCCESS(status
))
462 status
= acpi_evaluate_integer(handle
, "_RMV", NULL
, &removable
);
463 if (ACPI_SUCCESS(status
) && removable
)
469 * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot
470 * @pbus: the PCI bus of the PCI slot corresponding to 'handle'
471 * @handle: ACPI handle to check
473 * Return 1 if handle is ejectable PCI slot, 0 otherwise.
475 int acpi_pci_check_ejectable(struct pci_bus
*pbus
, acpi_handle handle
)
477 acpi_handle bridge_handle
, parent_handle
;
479 if (!(bridge_handle
= acpi_pci_get_bridge_handle(pbus
)))
481 if ((ACPI_FAILURE(acpi_get_parent(handle
, &parent_handle
))))
483 if (bridge_handle
!= parent_handle
)
485 return is_ejectable(handle
);
487 EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable
);
490 check_hotplug(acpi_handle handle
, u32 lvl
, void *context
, void **rv
)
492 int *found
= (int *)context
;
493 if (is_ejectable(handle
)) {
495 return AE_CTRL_TERMINATE
;
501 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
502 * @handle - handle of the PCI bus to scan
504 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
506 int acpi_pci_detect_ejectable(acpi_handle handle
)
513 acpi_walk_namespace(ACPI_TYPE_DEVICE
, handle
, 1,
514 check_hotplug
, (void *)&found
, NULL
);
517 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable
);
519 module_param(debug_acpi
, bool, 0644);
520 MODULE_PARM_DESC(debug_acpi
, "Debugging mode for ACPI enabled or not");