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_OSHP "OSHP"
46 static int debug_acpi
;
49 decode_type0_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
52 union acpi_object
*fields
= record
->package
.elements
;
53 u32 revision
= fields
[1].integer
.value
;
57 if (record
->package
.count
!= 6)
59 for (i
= 2; i
< 6; i
++)
60 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
62 hpx
->t0
= &hpx
->type0_data
;
63 hpx
->t0
->revision
= revision
;
64 hpx
->t0
->cache_line_size
= fields
[2].integer
.value
;
65 hpx
->t0
->latency_timer
= fields
[3].integer
.value
;
66 hpx
->t0
->enable_serr
= fields
[4].integer
.value
;
67 hpx
->t0
->enable_perr
= fields
[5].integer
.value
;
71 "%s: Type 0 Revision %d record not supported\n",
79 decode_type1_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
82 union acpi_object
*fields
= record
->package
.elements
;
83 u32 revision
= fields
[1].integer
.value
;
87 if (record
->package
.count
!= 5)
89 for (i
= 2; i
< 5; i
++)
90 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
92 hpx
->t1
= &hpx
->type1_data
;
93 hpx
->t1
->revision
= revision
;
94 hpx
->t1
->max_mem_read
= fields
[2].integer
.value
;
95 hpx
->t1
->avg_max_split
= fields
[3].integer
.value
;
96 hpx
->t1
->tot_max_split
= fields
[4].integer
.value
;
100 "%s: Type 1 Revision %d record not supported\n",
108 decode_type2_hpx_record(union acpi_object
*record
, struct hotplug_params
*hpx
)
111 union acpi_object
*fields
= record
->package
.elements
;
112 u32 revision
= fields
[1].integer
.value
;
116 if (record
->package
.count
!= 18)
118 for (i
= 2; i
< 18; i
++)
119 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
)
121 hpx
->t2
= &hpx
->type2_data
;
122 hpx
->t2
->revision
= revision
;
123 hpx
->t2
->unc_err_mask_and
= fields
[2].integer
.value
;
124 hpx
->t2
->unc_err_mask_or
= fields
[3].integer
.value
;
125 hpx
->t2
->unc_err_sever_and
= fields
[4].integer
.value
;
126 hpx
->t2
->unc_err_sever_or
= fields
[5].integer
.value
;
127 hpx
->t2
->cor_err_mask_and
= fields
[6].integer
.value
;
128 hpx
->t2
->cor_err_mask_or
= fields
[7].integer
.value
;
129 hpx
->t2
->adv_err_cap_and
= fields
[8].integer
.value
;
130 hpx
->t2
->adv_err_cap_or
= fields
[9].integer
.value
;
131 hpx
->t2
->pci_exp_devctl_and
= fields
[10].integer
.value
;
132 hpx
->t2
->pci_exp_devctl_or
= fields
[11].integer
.value
;
133 hpx
->t2
->pci_exp_lnkctl_and
= fields
[12].integer
.value
;
134 hpx
->t2
->pci_exp_lnkctl_or
= fields
[13].integer
.value
;
135 hpx
->t2
->sec_unc_err_sever_and
= fields
[14].integer
.value
;
136 hpx
->t2
->sec_unc_err_sever_or
= fields
[15].integer
.value
;
137 hpx
->t2
->sec_unc_err_mask_and
= fields
[16].integer
.value
;
138 hpx
->t2
->sec_unc_err_mask_or
= fields
[17].integer
.value
;
142 "%s: Type 2 Revision %d record not supported\n",
150 acpi_run_hpx(acpi_handle handle
, struct hotplug_params
*hpx
)
153 struct acpi_buffer buffer
= {ACPI_ALLOCATE_BUFFER
, NULL
};
154 union acpi_object
*package
, *record
, *fields
;
158 /* Clear the return buffer with zeros */
159 memset(hpx
, 0, sizeof(struct hotplug_params
));
161 status
= acpi_evaluate_object(handle
, "_HPX", NULL
, &buffer
);
162 if (ACPI_FAILURE(status
))
165 package
= (union acpi_object
*)buffer
.pointer
;
166 if (package
->type
!= ACPI_TYPE_PACKAGE
) {
171 for (i
= 0; i
< package
->package
.count
; i
++) {
172 record
= &package
->package
.elements
[i
];
173 if (record
->type
!= ACPI_TYPE_PACKAGE
) {
178 fields
= record
->package
.elements
;
179 if (fields
[0].type
!= ACPI_TYPE_INTEGER
||
180 fields
[1].type
!= ACPI_TYPE_INTEGER
) {
185 type
= fields
[0].integer
.value
;
188 status
= decode_type0_hpx_record(record
, hpx
);
189 if (ACPI_FAILURE(status
))
193 status
= decode_type1_hpx_record(record
, hpx
);
194 if (ACPI_FAILURE(status
))
198 status
= decode_type2_hpx_record(record
, hpx
);
199 if (ACPI_FAILURE(status
))
203 printk(KERN_ERR
"%s: Type %d record not supported\n",
210 kfree(buffer
.pointer
);
215 acpi_run_hpp(acpi_handle handle
, struct hotplug_params
*hpp
)
218 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
219 union acpi_object
*package
, *fields
;
222 memset(hpp
, 0, sizeof(struct hotplug_params
));
224 status
= acpi_evaluate_object(handle
, "_HPP", NULL
, &buffer
);
225 if (ACPI_FAILURE(status
))
228 package
= (union acpi_object
*) buffer
.pointer
;
229 if (package
->type
!= ACPI_TYPE_PACKAGE
||
230 package
->package
.count
!= 4) {
235 fields
= package
->package
.elements
;
236 for (i
= 0; i
< 4; i
++) {
237 if (fields
[i
].type
!= ACPI_TYPE_INTEGER
) {
243 hpp
->t0
= &hpp
->type0_data
;
244 hpp
->t0
->revision
= 1;
245 hpp
->t0
->cache_line_size
= fields
[0].integer
.value
;
246 hpp
->t0
->latency_timer
= fields
[1].integer
.value
;
247 hpp
->t0
->enable_serr
= fields
[2].integer
.value
;
248 hpp
->t0
->enable_perr
= fields
[3].integer
.value
;
251 kfree(buffer
.pointer
);
257 /* acpi_run_oshp - get control of hotplug from the firmware
259 * @handle - the handle of the hotplug controller.
261 static acpi_status
acpi_run_oshp(acpi_handle handle
)
264 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
266 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
269 status
= acpi_evaluate_object(handle
, METHOD_NAME_OSHP
, NULL
, NULL
);
270 if (ACPI_FAILURE(status
))
271 if (status
!= AE_NOT_FOUND
)
272 printk(KERN_ERR
"%s:%s OSHP fails=0x%x\n",
273 __func__
, (char *)string
.pointer
, status
);
275 dbg("%s:%s OSHP not found\n",
276 __func__
, (char *)string
.pointer
);
278 pr_debug("%s:%s OSHP passes\n", __func__
,
279 (char *)string
.pointer
);
281 kfree(string
.pointer
);
287 * @dev - the pci_dev for which we want parameters
288 * @hpp - allocated by the caller
290 int pci_get_hp_params(struct pci_dev
*dev
, struct hotplug_params
*hpp
)
293 acpi_handle handle
, phandle
;
294 struct pci_bus
*pbus
;
297 for (pbus
= dev
->bus
; pbus
; pbus
= pbus
->parent
) {
298 handle
= acpi_pci_get_bridge_handle(pbus
);
304 * _HPP settings apply to all child buses, until another _HPP is
305 * encountered. If we don't find an _HPP for the input pci dev,
306 * look for it in the parent device scope since that would apply to
310 status
= acpi_run_hpx(handle
, hpp
);
311 if (ACPI_SUCCESS(status
))
313 status
= acpi_run_hpp(handle
, hpp
);
314 if (ACPI_SUCCESS(status
))
316 if (acpi_is_root_bridge(handle
))
318 status
= acpi_get_parent(handle
, &phandle
);
319 if (ACPI_FAILURE(status
))
325 EXPORT_SYMBOL_GPL(pci_get_hp_params
);
328 * acpi_get_hp_hw_control_from_firmware
329 * @dev: the pci_dev of the bridge that has a hotplug controller
330 * @flags: requested control bits for _OSC
332 * Attempt to take hotplug control from firmware.
334 int acpi_get_hp_hw_control_from_firmware(struct pci_dev
*pdev
, u32 flags
)
337 acpi_handle chandle
, handle
;
338 struct acpi_buffer string
= { ACPI_ALLOCATE_BUFFER
, NULL
};
340 flags
&= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
|
341 OSC_SHPC_NATIVE_HP_CONTROL
|
342 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
);
344 err("Invalid flags %u specified!\n", flags
);
349 * Per PCI firmware specification, we should run the ACPI _OSC
350 * method to get control of hotplug hardware before using it. If
351 * an _OSC is missing, we look for an OSHP to do the same thing.
352 * To handle different BIOS behavior, we look for _OSC on a root
353 * bridge preferentially (according to PCI fw spec). Later for
354 * OSHP within the scope of the hotplug controller and its parents,
355 * upto the host bridge under which this controller exists.
357 handle
= acpi_find_root_bridge_handle(pdev
);
359 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
360 dbg("Trying to get hotplug control for %s\n",
361 (char *)string
.pointer
);
362 status
= acpi_pci_osc_control_set(handle
, flags
);
363 if (ACPI_SUCCESS(status
))
365 kfree(string
.pointer
);
366 string
= (struct acpi_buffer
){ ACPI_ALLOCATE_BUFFER
, NULL
};
369 handle
= DEVICE_ACPI_HANDLE(&pdev
->dev
);
372 * This hotplug controller was not listed in the ACPI name
373 * space at all. Try to get acpi handle of parent pci bus.
375 struct pci_bus
*pbus
;
376 for (pbus
= pdev
->bus
; pbus
; pbus
= pbus
->parent
) {
377 handle
= acpi_pci_get_bridge_handle(pbus
);
384 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &string
);
385 dbg("Trying to get hotplug control for %s \n",
386 (char *)string
.pointer
);
387 status
= acpi_run_oshp(handle
);
388 if (ACPI_SUCCESS(status
))
390 if (acpi_is_root_bridge(handle
))
393 status
= acpi_get_parent(chandle
, &handle
);
394 if (ACPI_FAILURE(status
))
398 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 is_ejectable(acpi_handle handle
)
415 unsigned long long removable
;
416 status
= acpi_get_handle(handle
, "_ADR", &tmp
);
417 if (ACPI_FAILURE(status
))
419 status
= acpi_get_handle(handle
, "_EJ0", &tmp
);
420 if (ACPI_SUCCESS(status
))
422 status
= acpi_evaluate_integer(handle
, "_RMV", NULL
, &removable
);
423 if (ACPI_SUCCESS(status
) && removable
)
429 * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot
430 * @pbus: the PCI bus of the PCI slot corresponding to 'handle'
431 * @handle: ACPI handle to check
433 * Return 1 if handle is ejectable PCI slot, 0 otherwise.
435 int acpi_pci_check_ejectable(struct pci_bus
*pbus
, acpi_handle handle
)
437 acpi_handle bridge_handle
, parent_handle
;
439 if (!(bridge_handle
= acpi_pci_get_bridge_handle(pbus
)))
441 if ((ACPI_FAILURE(acpi_get_parent(handle
, &parent_handle
))))
443 if (bridge_handle
!= parent_handle
)
445 return is_ejectable(handle
);
447 EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable
);
450 check_hotplug(acpi_handle handle
, u32 lvl
, void *context
, void **rv
)
452 int *found
= (int *)context
;
453 if (is_ejectable(handle
)) {
455 return AE_CTRL_TERMINATE
;
461 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
462 * @handle - handle of the PCI bus to scan
464 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
466 int acpi_pci_detect_ejectable(acpi_handle handle
)
473 acpi_walk_namespace(ACPI_TYPE_DEVICE
, handle
, 1,
474 check_hotplug
, (void *)&found
, NULL
);
477 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable
);
479 module_param(debug_acpi
, bool, 0644);
480 MODULE_PARM_DESC(debug_acpi
, "Debugging mode for ACPI enabled or not");