[PATCH] acpi_pcihp: Remove improper error message about OSHP
[linux-2.6.git] / drivers / pci / hotplug / acpi_pcihp.c
1 /*
2  * Common ACPI functions for hot plug platforms
3  *
4  * Copyright (C) 2006 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/moduleparam.h>
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <acpi/acpi.h>
33 #include <acpi/acpi_bus.h>
34 #include <acpi/actypes.h>
35 #include "pci_hotplug.h"
36
37 #define MY_NAME "acpi_pcihp"
38
39 #define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## 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)
43
44 #define METHOD_NAME__SUN        "_SUN"
45 #define METHOD_NAME__HPP        "_HPP"
46 #define METHOD_NAME_OSHP        "OSHP"
47
48 static int debug_acpi;
49
50
51 static acpi_status
52 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
53 {
54         acpi_status             status;
55         u8                      nui[4];
56         struct acpi_buffer      ret_buf = { 0, NULL};
57         struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
58         union acpi_object       *ext_obj, *package;
59         int                     i, len = 0;
60
61         acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
62
63         /* get _hpp */
64         status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
65         switch (status) {
66         case AE_BUFFER_OVERFLOW:
67                 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
68                 if (!ret_buf.pointer) {
69                         printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
70                                 __FUNCTION__, (char *)string.pointer);
71                         kfree(string.pointer);
72                         return AE_NO_MEMORY;
73                 }
74                 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
75                                 NULL, &ret_buf);
76                 if (ACPI_SUCCESS(status))
77                         break;
78         default:
79                 if (ACPI_FAILURE(status)) {
80                         pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
81                                 (char *)string.pointer, status);
82                         kfree(string.pointer);
83                         return status;
84                 }
85         }
86
87         ext_obj = (union acpi_object *) ret_buf.pointer;
88         if (ext_obj->type != ACPI_TYPE_PACKAGE) {
89                 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__,
90                                 (char *)string.pointer);
91                 status = AE_ERROR;
92                 goto free_and_return;
93         }
94
95         len = ext_obj->package.count;
96         package = (union acpi_object *) ret_buf.pointer;
97         for ( i = 0; (i < len) || (i < 4); i++) {
98                 ext_obj = (union acpi_object *) &package->package.elements[i];
99                 switch (ext_obj->type) {
100                 case ACPI_TYPE_INTEGER:
101                         nui[i] = (u8)ext_obj->integer.value;
102                         break;
103                 default:
104                         printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
105                                 __FUNCTION__, (char *)string.pointer);
106                         status = AE_ERROR;
107                         goto free_and_return;
108                 }
109         }
110
111         hpp->cache_line_size = nui[0];
112         hpp->latency_timer = nui[1];
113         hpp->enable_serr = nui[2];
114         hpp->enable_perr = nui[3];
115
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);
120
121 free_and_return:
122         kfree(string.pointer);
123         kfree(ret_buf.pointer);
124         return status;
125 }
126
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)
134 {
135         acpi_status             status;
136         struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
137
138         acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
139
140         /* run OSHP */
141         status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
142         if (ACPI_FAILURE(status))
143                 if (status != AE_NOT_FOUND)
144                         printk(KERN_ERR "%s:%s OSHP fails=0x%x\n",
145                                __FUNCTION__, (char *)string.pointer, status);
146                 else
147                         dbg("%s:%s OSHP not found\n",
148                             __FUNCTION__, (char *)string.pointer);
149         else
150                 pr_debug("%s:%s OSHP passes\n", __FUNCTION__,
151                         (char *)string.pointer);
152
153         kfree(string.pointer);
154         return status;
155 }
156 EXPORT_SYMBOL_GPL(acpi_run_oshp);
157
158
159
160 /* acpi_get_hp_params_from_firmware
161  *
162  * @bus - the pci_bus of the bus on which the device is newly added
163  * @hpp - allocated by the caller
164  */
165 acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
166                 struct hotplug_params *hpp)
167 {
168         acpi_status status = AE_NOT_FOUND;
169         acpi_handle handle, phandle;
170         struct pci_bus *pbus = bus;
171         struct pci_dev *pdev;
172
173         do {
174                 pdev = pbus->self;
175                 if (!pdev) {
176                         handle = acpi_get_pci_rootbridge_handle(
177                                 pci_domain_nr(pbus), pbus->number);
178                         break;
179                 }
180                 handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
181                 pbus = pbus->parent;
182         } while (!handle);
183
184         /*
185          * _HPP settings apply to all child buses, until another _HPP is
186          * encountered. If we don't find an _HPP for the input pci dev,
187          * look for it in the parent device scope since that would apply to
188          * this pci dev. If we don't find any _HPP, use hardcoded defaults
189          */
190         while (handle) {
191                 status = acpi_run_hpp(handle, hpp);
192                 if (ACPI_SUCCESS(status))
193                         break;
194                 if (acpi_root_bridge(handle))
195                         break;
196                 status = acpi_get_parent(handle, &phandle);
197                 if (ACPI_FAILURE(status))
198                         break;
199                 handle = phandle;
200         }
201         return status;
202 }
203 EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
204
205
206 /* acpi_root_bridge - check to see if this acpi object is a root bridge
207  *
208  * @handle - the acpi object in question.
209  */
210 int acpi_root_bridge(acpi_handle handle)
211 {
212         acpi_status status;
213         struct acpi_device_info *info;
214         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
215         int i;
216
217         status = acpi_get_object_info(handle, &buffer);
218         if (ACPI_SUCCESS(status)) {
219                 info = buffer.pointer;
220                 if ((info->valid & ACPI_VALID_HID) &&
221                         !strcmp(PCI_ROOT_HID_STRING,
222                                         info->hardware_id.value)) {
223                         kfree(buffer.pointer);
224                         return 1;
225                 }
226                 if (info->valid & ACPI_VALID_CID) {
227                         for (i=0; i < info->compatibility_id.count; i++) {
228                                 if (!strcmp(PCI_ROOT_HID_STRING,
229                                         info->compatibility_id.id[i].value)) {
230                                         kfree(buffer.pointer);
231                                         return 1;
232                                 }
233                         }
234                 }
235                 kfree(buffer.pointer);
236         }
237         return 0;
238 }
239 EXPORT_SYMBOL_GPL(acpi_root_bridge);
240
241 module_param(debug_acpi, bool, 0644);
242 MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not");