aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h11
-rw-r--r--drivers/pci/hotplug/pciehp_core.c20
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c4
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c838
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c107
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
8 files changed, 96 insertions, 993 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e9480ddd5abf..e9c09566f851 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -49,6 +49,13 @@ extern int pciehp_debug;
49#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 49#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
50#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 50#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
51 51
52struct hotplug_params {
53 u8 cache_line_size;
54 u8 latency_timer;
55 u8 enable_serr;
56 u8 enable_perr;
57};
58
52struct pci_func { 59struct pci_func {
53 struct pci_func *next; 60 struct pci_func *next;
54 u8 bus; 61 u8 bus;
@@ -199,6 +206,10 @@ extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num
199extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot); 206extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
200extern int pciehp_configure_device (struct slot *ctrl); 207extern int pciehp_configure_device (struct slot *ctrl);
201extern int pciehp_unconfigure_device (struct pci_func* func); 208extern int pciehp_unconfigure_device (struct pci_func* func);
209extern int get_hp_hw_control_from_firmware(struct pci_dev *dev);
210extern void get_hp_params_from_firmware(struct pci_dev *dev,
211 struct hotplug_params *hpp);
212
202 213
203 214
204/* Global variables */ 215/* Global variables */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 190664e5adf4..e20cf8e42bd9 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -39,7 +39,6 @@
39#include <linux/init.h> 39#include <linux/init.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include "pciehp.h" 41#include "pciehp.h"
42#include "pciehprm.h"
43#include <linux/interrupt.h> 42#include <linux/interrupt.h>
44 43
45/* Global variables */ 44/* Global variables */
@@ -381,6 +380,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
381 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid); 380 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
382 381
383 pdev = dev->port; 382 pdev = dev->port;
383 ctrl->pci_dev = pdev;
384 384
385 rc = pcie_init(ctrl, dev, 385 rc = pcie_init(ctrl, dev,
386 (php_intr_callback_t) pciehp_handle_attention_button, 386 (php_intr_callback_t) pciehp_handle_attention_button,
@@ -392,8 +392,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
392 goto err_out_free_ctrl; 392 goto err_out_free_ctrl;
393 } 393 }
394 394
395 ctrl->pci_dev = pdev;
396
397 pci_set_drvdata(pdev, ctrl); 395 pci_set_drvdata(pdev, ctrl);
398 396
399 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 397 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
@@ -609,18 +607,14 @@ static int __init pcied_init(void)
609 if (retval) 607 if (retval)
610 goto error_hpc_init; 608 goto error_hpc_init;
611 609
612 retval = pciehprm_init(PCI); 610 retval = pcie_port_service_register(&hpdriver_portdrv);
613 if (!retval) { 611 dbg("pcie_port_service_register = %d\n", retval);
614 retval = pcie_port_service_register(&hpdriver_portdrv); 612 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
615 dbg("pcie_port_service_register = %d\n", retval); 613 if (retval)
616 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 614 dbg("%s: Failure to register service\n", __FUNCTION__);
617 if (retval)
618 dbg("%s: Failure to register service\n", __FUNCTION__);
619 }
620 615
621error_hpc_init: 616error_hpc_init:
622 if (retval) { 617 if (retval) {
623 pciehprm_cleanup();
624 pciehp_event_stop_thread(); 618 pciehp_event_stop_thread();
625 }; 619 };
626 620
@@ -632,8 +626,6 @@ static void __exit pcied_cleanup(void)
632 dbg("unload_pciehpd()\n"); 626 dbg("unload_pciehpd()\n");
633 unload_pciehpd(); 627 unload_pciehpd();
634 628
635 pciehprm_cleanup();
636
637 dbg("pcie_port_service_unregister\n"); 629 dbg("pcie_port_service_unregister\n");
638 pcie_port_service_unregister(&hpdriver_portdrv); 630 pcie_port_service_unregister(&hpdriver_portdrv);
639 631
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 412783e0ef40..d07d4194bc29 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -40,7 +40,6 @@
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include "../pci.h" 41#include "../pci.h"
42#include "pciehp.h" 42#include "pciehp.h"
43#include "pciehprm.h"
44 43
45static void interrupt_event_handler(struct controller *ctrl); 44static void interrupt_event_handler(struct controller *ctrl);
46 45
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a0e27f0e063..ef79ca1f38da 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1470,6 +1470,10 @@ int pcie_init(struct controller * ctrl,
1470 } 1470 }
1471 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word); 1471 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
1472 1472
1473 rc = get_hp_hw_control_from_firmware(ctrl->pci_dev);
1474 if (rc)
1475 goto abort_free_ctlr;
1476
1473 /* Add this HPC instance into the HPC list */ 1477 /* Add this HPC instance into the HPC list */
1474 spin_lock(&list_lock); 1478 spin_lock(&list_lock);
1475 if (php_ctlr_list_head == 0) { 1479 if (php_ctlr_list_head == 0) {
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
deleted file mode 100644
index 05f20fbc5f50..000000000000
--- a/drivers/pci/hotplug/pciehprm.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_H_
31#define _PCIEHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
34#include "pciehprm_nonacpi.h"
35#endif
36
37int pciehprm_init(enum php_ctlr_type ct);
38void pciehprm_cleanup(void);
39int pciehprm_print_pirt(void);
40int pciehprm_find_available_resources(struct controller *ctrl);
41int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
42void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
43
44#ifdef DEBUG
45#define RES_CHECK(this, bits) \
46 { if (((this) & (bits - 1))) \
47 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
48#else
49#define RES_CHECK(this, bits)
50#endif
51
52#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 078550ba2708..c823cfa42eec 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -39,70 +39,11 @@
39#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
40#include <acpi/actypes.h> 40#include <acpi/actypes.h>
41#include "pciehp.h" 41#include "pciehp.h"
42#include "pciehprm.h"
43
44#define PCI_MAX_BUS 0x100
45#define ACPI_STA_DEVICE_PRESENT 0x01
46 42
47#define METHOD_NAME__SUN "_SUN" 43#define METHOD_NAME__SUN "_SUN"
48#define METHOD_NAME__HPP "_HPP" 44#define METHOD_NAME__HPP "_HPP"
49#define METHOD_NAME_OSHP "OSHP" 45#define METHOD_NAME_OSHP "OSHP"
50 46
51/* Status code for running acpi method to gain native control */
52#define NC_NOT_RUN 0
53#define OSC_NOT_EXIST 1
54#define OSC_RUN_FAILED 2
55#define OSHP_NOT_EXIST 3
56#define OSHP_RUN_FAILED 4
57#define NC_RUN_SUCCESS 5
58
59#define PHP_RES_BUS 0xA0
60#define PHP_RES_IO 0xA1
61#define PHP_RES_MEM 0xA2
62#define PHP_RES_PMEM 0xA3
63
64#define BRIDGE_TYPE_P2P 0x00
65#define BRIDGE_TYPE_HOST 0x01
66
67/* this should go to drivers/acpi/include/ */
68struct acpi__hpp {
69 u8 cache_line_size;
70 u8 latency_timer;
71 u8 enable_serr;
72 u8 enable_perr;
73};
74
75struct acpi_php_slot {
76 struct acpi_php_slot *next;
77 struct acpi_bridge *bridge;
78 acpi_handle handle;
79 int seg;
80 int bus;
81 int dev;
82 int fun;
83 u32 sun;
84 void *slot_ops; /* _STA, _EJx, etc */
85 struct slot *slot;
86}; /* per func */
87
88struct acpi_bridge {
89 struct acpi_bridge *parent;
90 struct acpi_bridge *next;
91 struct acpi_bridge *child;
92 acpi_handle handle;
93 int seg;
94 int pbus; /* pdev->bus->number */
95 int pdevice; /* PCI_SLOT(pdev->devfn) */
96 int pfunction; /* PCI_DEVFN(pdev->devfn) */
97 int bus; /* pdev->subordinate->number */
98 struct acpi__hpp *_hpp;
99 struct acpi_php_slot *slots;
100 int scanned;
101 int type;
102};
103
104static struct acpi_bridge *acpi_bridges_head;
105
106static u8 * acpi_path_name( acpi_handle handle) 47static u8 * acpi_path_name( acpi_handle handle)
107{ 48{
108 acpi_status status; 49 acpi_status status;
@@ -118,85 +59,43 @@ static u8 * acpi_path_name( acpi_handle handle)
118 return path_name; 59 return path_name;
119} 60}
120 61
121static void acpi_get__hpp ( struct acpi_bridge *ab); 62static acpi_status
122static int acpi_run_oshp ( struct acpi_bridge *ab); 63acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
123static int osc_run_status = NC_NOT_RUN;
124static int oshp_run_status = NC_NOT_RUN;
125
126static int acpi_add_slot_to_php_slots(
127 struct acpi_bridge *ab,
128 int bus_num,
129 acpi_handle handle,
130 u32 adr,
131 u32 sun
132 )
133{
134 struct acpi_php_slot *aps;
135 static long samesun = -1;
136
137 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
138 if (!aps) {
139 err ("acpi_pciehprm: alloc for aps fail\n");
140 return -1;
141 }
142 memset(aps, 0, sizeof(struct acpi_php_slot));
143
144 aps->handle = handle;
145 aps->bus = bus_num;
146 aps->dev = (adr >> 16) & 0xffff;
147 aps->fun = adr & 0xffff;
148 aps->sun = sun;
149
150 aps->next = ab->slots; /* cling to the bridge */
151 aps->bridge = ab;
152 ab->slots = aps;
153
154 ab->scanned += 1;
155 if (!ab->_hpp)
156 acpi_get__hpp(ab);
157
158 if (osc_run_status == OSC_NOT_EXIST)
159 oshp_run_status = acpi_run_oshp(ab);
160
161 if (sun != samesun) {
162 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
163 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
164 samesun = sun;
165 }
166 return 0;
167}
168
169static void acpi_get__hpp ( struct acpi_bridge *ab)
170{ 64{
171 acpi_status status; 65 acpi_status status;
172 u8 nui[4]; 66 u8 nui[4];
173 struct acpi_buffer ret_buf = { 0, NULL}; 67 struct acpi_buffer ret_buf = { 0, NULL};
174 union acpi_object *ext_obj, *package; 68 union acpi_object *ext_obj, *package;
175 u8 *path_name = acpi_path_name(ab->handle); 69 u8 *path_name = acpi_path_name(handle);
176 int i, len = 0; 70 int i, len = 0;
177 71
178 /* get _hpp */ 72 /* get _hpp */
179 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 73 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
180 switch (status) { 74 switch (status) {
181 case AE_BUFFER_OVERFLOW: 75 case AE_BUFFER_OVERFLOW:
182 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 76 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
183 if (!ret_buf.pointer) { 77 if (!ret_buf.pointer) {
184 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name); 78 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
185 return; 79 path_name);
80 return AE_NO_MEMORY;
186 } 81 }
187 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 82 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
83 NULL, &ret_buf);
188 if (ACPI_SUCCESS(status)) 84 if (ACPI_SUCCESS(status))
189 break; 85 break;
190 default: 86 default:
191 if (ACPI_FAILURE(status)) { 87 if (ACPI_FAILURE(status)) {
192 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status); 88 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
193 return; 89 path_name, status);
90 return status;
194 } 91 }
195 } 92 }
196 93
197 ext_obj = (union acpi_object *) ret_buf.pointer; 94 ext_obj = (union acpi_object *) ret_buf.pointer;
198 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 95 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
199 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name); 96 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
97 path_name);
98 status = AE_ERROR;
200 goto free_and_return; 99 goto free_and_return;
201 } 100 }
202 101
@@ -209,689 +108,94 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
209 nui[i] = (u8)ext_obj->integer.value; 108 nui[i] = (u8)ext_obj->integer.value;
210 break; 109 break;
211 default: 110 default:
212 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name); 111 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
112 path_name);
113 status = AE_ERROR;
213 goto free_and_return; 114 goto free_and_return;
214 } 115 }
215 } 116 }
216 117
217 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 118 hpp->cache_line_size = nui[0];
218 if (!ab->_hpp) { 119 hpp->latency_timer = nui[1];
219 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); 120 hpp->enable_serr = nui[2];
220 goto free_and_return; 121 hpp->enable_perr = nui[3];
221 }
222 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
223 122
224 ab->_hpp->cache_line_size = nui[0]; 123 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
225 ab->_hpp->latency_timer = nui[1]; 124 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
226 ab->_hpp->enable_serr = nui[2]; 125 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
227 ab->_hpp->enable_perr = nui[3]; 126 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
228
229 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
230 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
231 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
232 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
233 127
234free_and_return: 128free_and_return:
235 kfree(ret_buf.pointer); 129 kfree(ret_buf.pointer);
130 return status;
236} 131}
237 132
238static int acpi_run_oshp ( struct acpi_bridge *ab) 133static acpi_status acpi_run_oshp(acpi_handle handle)
239{ 134{
240 acpi_status status; 135 acpi_status status;
241 u8 *path_name = acpi_path_name(ab->handle); 136 u8 *path_name = acpi_path_name(handle);
242 137
243 /* run OSHP */ 138 /* run OSHP */
244 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL); 139 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
245 if (ACPI_FAILURE(status)) { 140 if (ACPI_FAILURE(status)) {
246 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); 141 err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
247 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED; 142 status);
248 } else { 143 } else {
249 oshp_run_status = NC_RUN_SUCCESS; 144 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
250 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
251 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
252 }
253 return oshp_run_status;
254}
255
256/* find acpi_bridge downword from ab. */
257static struct acpi_bridge *
258find_acpi_bridge_by_bus(
259 struct acpi_bridge *ab,
260 int seg,
261 int bus /* pdev->subordinate->number */
262 )
263{
264 struct acpi_bridge *lab = NULL;
265
266 if (!ab)
267 return NULL;
268
269 if ((ab->bus == bus) && (ab->seg == seg))
270 return ab;
271
272 if (ab->child)
273 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
274
275 if (!lab)
276 if (ab->next)
277 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
278
279 return lab;
280}
281
282/*
283 * Build a device tree of ACPI PCI Bridges
284 */
285static void pciehprm_acpi_register_a_bridge (
286 struct acpi_bridge **head,
287 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
288 struct acpi_bridge *cab /* child bridge to add */
289 )
290{
291 struct acpi_bridge *lpab;
292 struct acpi_bridge *lcab;
293
294 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
295 if (!lpab) {
296 if (!(pab->type & BRIDGE_TYPE_HOST))
297 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
298 pab->next = *head;
299 *head = pab;
300 lpab = pab;
301 } 145 }
302 146 return status;
303 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
304 return;
305
306 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
307 if (lcab) {
308 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
309 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
310 return;
311 } else
312 lcab = cab;
313
314 lcab->parent = lpab;
315 lcab->next = lpab->child;
316 lpab->child = lcab;
317} 147}
318 148
319static acpi_status pciehprm_acpi_build_php_slots_callback( 149int get_hp_hw_control_from_firmware(struct pci_dev *dev)
320 acpi_handle handle,
321 u32 Level,
322 void *context,
323 void **retval
324 )
325{ 150{
326 ulong bus_num; 151 acpi_status status;
327 ulong seg_num; 152 /*
328 ulong sun, adr; 153 * Per PCI firmware specification, we should run the ACPI _OSC
329 ulong padr = 0; 154 * method to get control of hotplug hardware before using it
330 acpi_handle phandle = NULL; 155 */
331 struct acpi_bridge *pab = (struct acpi_bridge *)context; 156 /* Fixme: run _OSC for a specific host bridge, not all of them */
332 struct acpi_bridge *lab; 157 status = pci_osc_control_set(OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
333 acpi_status status; 158
334 u8 *path_name = acpi_path_name(handle); 159 /* Fixme: fail native hotplug if _OSC does not exist for root ports */
335 160 if (status == AE_NOT_FOUND) {
336 /* get _SUN */ 161 /*
337 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun); 162 * Some older BIOS's don't support _OSC but support
338 switch(status) { 163 * OSHP to do the same thing
339 case AE_NOT_FOUND: 164 */
340 return AE_OK; 165 acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
341 default: 166 if (handle)
342 if (ACPI_FAILURE(status)) { 167 status = acpi_run_oshp(handle);
343 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
344 return status;
345 }
346 }
347
348 /* get _ADR. _ADR must exist if _SUN exists */
349 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
350 if (ACPI_FAILURE(status)) {
351 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
352 return status;
353 }
354
355 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
356
357 status = acpi_get_parent(handle, &phandle);
358 if (ACPI_FAILURE(status)) {
359 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
360 return (status);
361 }
362
363 bus_num = pab->bus;
364 seg_num = pab->seg;
365
366 if (pab->bus == bus_num) {
367 lab = pab;
368 } else {
369 dbg("WARN: pab is not parent\n");
370 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
371 if (!lab) {
372 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
373 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
374 if (!lab) {
375 err("acpi_pciehprm: alloc for ab fail\n");
376 return AE_NO_MEMORY;
377 }
378 memset(lab, 0, sizeof(struct acpi_bridge));
379
380 lab->handle = phandle;
381 lab->pbus = pab->bus;
382 lab->pdevice = (int)(padr >> 16) & 0xffff;
383 lab->pfunction = (int)(padr & 0xffff);
384 lab->bus = (int)bus_num;
385 lab->scanned = 0;
386 lab->type = BRIDGE_TYPE_P2P;
387
388 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
389 } else
390 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
391 } 168 }
392
393 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
394
395 return (status);
396}
397
398static int pciehprm_acpi_build_php_slots(
399 struct acpi_bridge *ab,
400 u32 depth
401 )
402{
403 acpi_status status;
404 u8 *path_name = acpi_path_name(ab->handle);
405
406 /* Walk down this pci bridge to get _SUNs if any behind P2P */
407 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
408 ab->handle,
409 depth,
410 pciehprm_acpi_build_php_slots_callback,
411 ab,
412 NULL );
413 if (ACPI_FAILURE(status)) { 169 if (ACPI_FAILURE(status)) {
414 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status); 170 err("Cannot get control of hotplug hardware\n");
415 return -1; 171 return -1;
416 } 172 }
417 173
174 dbg("Sucess getting control of hotplug hardware\n");
418 return 0; 175 return 0;
419} 176}
420 177
421static void build_a_bridge( 178void get_hp_params_from_firmware(struct pci_dev *dev,
422 struct acpi_bridge *pab, 179 struct hotplug_params *hpp)
423 struct acpi_bridge *ab
424 )
425{
426 u8 *path_name = acpi_path_name(ab->handle);
427
428 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
429
430 switch (ab->type) {
431 case BRIDGE_TYPE_HOST:
432 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
433 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
434 break;
435 case BRIDGE_TYPE_P2P:
436 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
437 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
438 break;
439 };
440
441 /* build any immediate PHP slots under this pci bridge */
442 pciehprm_acpi_build_php_slots(ab, 1);
443}
444
445static struct acpi_bridge * add_p2p_bridge(
446 acpi_handle handle,
447 struct acpi_bridge *pab, /* parent */
448 ulong adr
449 )
450{
451 struct acpi_bridge *ab;
452 struct pci_dev *pdev;
453 ulong devnum, funcnum;
454 u8 *path_name = acpi_path_name(handle);
455
456 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
457 if (!ab) {
458 err("acpi_pciehprm: alloc for ab fail\n");
459 return NULL;
460 }
461 memset(ab, 0, sizeof(struct acpi_bridge));
462
463 devnum = (adr >> 16) & 0xffff;
464 funcnum = adr & 0xffff;
465
466 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
467 if (!pdev || !pdev->subordinate) {
468 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
469 kfree(ab);
470 return NULL;
471 }
472
473 ab->handle = handle;
474 ab->seg = pab->seg;
475 ab->pbus = pab->bus; /* or pdev->bus->number */
476 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
477 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
478 ab->bus = pdev->subordinate->number;
479 ab->scanned = 0;
480 ab->type = BRIDGE_TYPE_P2P;
481
482 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
483 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
484 pab->bus, (u32)devnum, (u32)funcnum, path_name);
485
486 build_a_bridge(pab, ab);
487
488 return ab;
489}
490
491static acpi_status scan_p2p_bridge(
492 acpi_handle handle,
493 u32 Level,
494 void *context,
495 void **retval
496 )
497{
498 struct acpi_bridge *pab = (struct acpi_bridge *)context;
499 struct acpi_bridge *ab;
500 acpi_status status;
501 ulong adr = 0;
502 u8 *path_name = acpi_path_name(handle);
503 ulong devnum, funcnum;
504 struct pci_dev *pdev;
505
506 /* get device, function */
507 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
508 if (ACPI_FAILURE(status)) {
509 if (status != AE_NOT_FOUND)
510 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
511 return AE_OK;
512 }
513
514 devnum = (adr >> 16) & 0xffff;
515 funcnum = adr & 0xffff;
516
517 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
518 if (!pdev)
519 return AE_OK;
520 if (!pdev->subordinate)
521 return AE_OK;
522
523 ab = add_p2p_bridge(handle, pab, adr);
524 if (ab) {
525 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
526 handle,
527 (u32)1,
528 scan_p2p_bridge,
529 ab,
530 NULL);
531 if (ACPI_FAILURE(status))
532 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
533 }
534
535 return AE_OK;
536}
537
538static struct acpi_bridge * add_host_bridge(
539 acpi_handle handle,
540 ulong segnum,
541 ulong busnum
542 )
543{
544 ulong adr = 0;
545 acpi_status status;
546 struct acpi_bridge *ab;
547 u8 *path_name = acpi_path_name(handle);
548
549 /* get device, function: host br adr is always 0000 though. */
550 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
551 if (ACPI_FAILURE(status)) {
552 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
553 return NULL;
554 }
555 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
556 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
557
558 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
559 if (!ab) {
560 err("acpi_pciehprm: alloc for ab fail\n");
561 return NULL;
562 }
563 memset(ab, 0, sizeof(struct acpi_bridge));
564
565 ab->handle = handle;
566 ab->seg = (int)segnum;
567 ab->bus = ab->pbus = (int)busnum;
568 ab->pdevice = (int)(adr >> 16) & 0xffff;
569 ab->pfunction = (int)(adr & 0xffff);
570 ab->scanned = 0;
571 ab->type = BRIDGE_TYPE_HOST;
572
573 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
574 if (ACPI_FAILURE(status)) {
575 err("%s: status %x\n", __FUNCTION__, status);
576 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
577 } else {
578 osc_run_status = NC_RUN_SUCCESS;
579 }
580 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
581
582 build_a_bridge(ab, ab);
583
584 return ab;
585}
586
587static acpi_status acpi_scan_from_root_pci_callback (
588 acpi_handle handle,
589 u32 Level,
590 void *context,
591 void **retval
592 )
593{
594 ulong segnum = 0;
595 ulong busnum = 0;
596 acpi_status status;
597 struct acpi_bridge *ab;
598 u8 *path_name = acpi_path_name(handle);
599
600 /* get bus number of this pci root bridge */
601 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
602 if (ACPI_FAILURE(status)) {
603 if (status != AE_NOT_FOUND) {
604 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
605 return status;
606 }
607 segnum = 0;
608 }
609
610 /* get bus number of this pci root bridge */
611 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
612 if (ACPI_FAILURE(status)) {
613 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
614 return (status);
615 }
616
617 ab = add_host_bridge(handle, segnum, busnum);
618 if (ab) {
619 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
620 handle,
621 1,
622 scan_p2p_bridge,
623 ab,
624 NULL);
625 if (ACPI_FAILURE(status))
626 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
627 }
628
629 return AE_OK;
630}
631
632static int pciehprm_acpi_scan_pci (void)
633{ 180{
634 acpi_status status; 181 acpi_status status = AE_NOT_FOUND;
182 struct pci_dev *pdev = dev;
635 183
636 /* 184 /*
637 * TBD: traverse LDM device tree with the help of 185 * _HPP settings apply to all child buses, until another _HPP is
638 * unified ACPI augmented for php device population. 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
639 */ 189 */
640 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 190 while (pdev && (ACPI_FAILURE(status))) {
641 acpi_scan_from_root_pci_callback, 191 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
642 NULL, 192 if (!handle)
643 NULL ); 193 break;
644 if (ACPI_FAILURE(status)) { 194 status = acpi_run_hpp(handle, hpp);
645 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status); 195 if (!(pdev->bus->parent))
646 return -1; 196 break;
647 } 197 /* Check if a parent object supports _HPP */
648 198 pdev = pdev->bus->parent->self;
649 return 0;
650}
651
652int pciehprm_init(enum php_ctlr_type ctlr_type)
653{
654 int rc;
655
656 if (ctlr_type != PCI)
657 return -ENODEV;
658
659 dbg("pciehprm ACPI init <enter>\n");
660 acpi_bridges_head = NULL;
661
662 /* construct PCI bus:device tree of acpi_handles */
663 rc = pciehprm_acpi_scan_pci();
664 if (rc)
665 return rc;
666
667 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
668 err("Fails to gain control of native hot-plug\n");
669 rc = -ENODEV;
670 }
671
672 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
673 return rc;
674}
675
676static void free_a_slot(struct acpi_php_slot *aps)
677{
678 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
679
680 kfree(aps);
681}
682
683static void free_a_bridge( struct acpi_bridge *ab)
684{
685 struct acpi_php_slot *aps, *next;
686
687 switch (ab->type) {
688 case BRIDGE_TYPE_HOST:
689 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
690 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
691 break;
692 case BRIDGE_TYPE_P2P:
693 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
694 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
695 break;
696 };
697
698 /* free slots first */
699 for (aps = ab->slots; aps; aps = next) {
700 next = aps->next;
701 free_a_slot(aps);
702 }
703
704 kfree(ab);
705}
706
707static void pciehprm_free_bridges ( struct acpi_bridge *ab)
708{
709 if (!ab)
710 return;
711
712 if (ab->child)
713 pciehprm_free_bridges (ab->child);
714
715 if (ab->next)
716 pciehprm_free_bridges (ab->next);
717
718 free_a_bridge(ab);
719}
720
721void pciehprm_cleanup(void)
722{
723 pciehprm_free_bridges (acpi_bridges_head);
724}
725
726static int get_number_of_slots (
727 struct acpi_bridge *ab,
728 int selfonly
729 )
730{
731 struct acpi_php_slot *aps;
732 int prev_slot = -1;
733 int slot_num = 0;
734
735 for ( aps = ab->slots; aps; aps = aps->next)
736 if (aps->dev != prev_slot) {
737 prev_slot = aps->dev;
738 slot_num++;
739 }
740
741 if (ab->child)
742 slot_num += get_number_of_slots (ab->child, 0);
743
744 if (selfonly)
745 return slot_num;
746
747 if (ab->next)
748 slot_num += get_number_of_slots (ab->next, 0);
749
750 return slot_num;
751}
752
753static struct acpi_php_slot * get_acpi_slot (
754 struct acpi_bridge *ab,
755 u32 sun
756 )
757{
758 struct acpi_php_slot *aps = NULL;
759
760 for ( aps = ab->slots; aps; aps = aps->next)
761 if (aps->sun == sun)
762 return aps;
763
764 if (!aps && ab->child) {
765 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
766 if (aps)
767 return aps;
768 }
769
770 if (!aps && ab->next) {
771 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
772 if (aps)
773 return aps;
774 }
775
776 return aps;
777
778}
779
780#if 0
781void * pciehprm_get_slot(struct slot *slot)
782{
783 struct acpi_bridge *ab = acpi_bridges_head;
784 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
785
786 aps->slot = slot;
787
788 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
789
790 return (void *)aps;
791}
792#endif
793
794int pciehprm_set_hpp(
795 struct controller *ctrl,
796 struct pci_func *func,
797 u8 card_type
798 )
799{
800 struct acpi_bridge *ab;
801 struct pci_bus lpci_bus, *pci_bus;
802 int rc = 0;
803 unsigned int devfn;
804 u8 cls= 0x08; /* default cache line size */
805 u8 lt = 0x40; /* default latency timer */
806 u8 ep = 0;
807 u8 es = 0;
808
809 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
810 pci_bus = &lpci_bus;
811 pci_bus->number = func->bus;
812 devfn = PCI_DEVFN(func->device, func->function);
813
814 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
815
816 if (ab) {
817 if (ab->_hpp) {
818 lt = (u8)ab->_hpp->latency_timer;
819 cls = (u8)ab->_hpp->cache_line_size;
820 ep = (u8)ab->_hpp->enable_perr;
821 es = (u8)ab->_hpp->enable_serr;
822 } else
823 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
824 } else
825 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
826
827
828 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
829 /* set subordinate Latency Timer */
830 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
831 } 199 }
832
833 /* set base Latency Timer */
834 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
835 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
836
837 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
838 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
839
840 return rc;
841} 200}
842 201
843void pciehprm_enable_card(
844 struct controller *ctrl,
845 struct pci_func *func,
846 u8 card_type)
847{
848 u16 command, cmd, bcommand, bcmd;
849 struct pci_bus lpci_bus, *pci_bus;
850 struct acpi_bridge *ab;
851 unsigned int devfn;
852 int rc;
853
854 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
855 pci_bus = &lpci_bus;
856 pci_bus->number = func->bus;
857 devfn = PCI_DEVFN(func->device, func->function);
858
859 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
860
861 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
862 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
863 }
864
865 command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
866 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
867 bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
868
869 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
870 if (ab) {
871 if (ab->_hpp) {
872 if (ab->_hpp->enable_perr) {
873 command |= PCI_COMMAND_PARITY;
874 bcommand |= PCI_BRIDGE_CTL_PARITY;
875 } else {
876 command &= ~PCI_COMMAND_PARITY;
877 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
878 }
879 if (ab->_hpp->enable_serr) {
880 command |= PCI_COMMAND_SERR;
881 bcommand |= PCI_BRIDGE_CTL_SERR;
882 } else {
883 command &= ~PCI_COMMAND_SERR;
884 bcommand &= ~PCI_BRIDGE_CTL_SERR;
885 }
886 } else
887 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
888 } else
889 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
890
891 if (command != cmd) {
892 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
893 }
894 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
895 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
896 }
897}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index ed68c3dd0f08..32371cd19e34 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -37,15 +37,9 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <asm/uaccess.h> 38#include <asm/uaccess.h>
39#include "pciehp.h" 39#include "pciehp.h"
40#include "pciehprm.h"
41#include "pciehprm_nonacpi.h" 40#include "pciehprm_nonacpi.h"
42 41
43 42
44void pciehprm_cleanup(void)
45{
46 return;
47}
48
49int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 43int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
50{ 44{
51 45
@@ -53,106 +47,13 @@ int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
53 return 0; 47 return 0;
54} 48}
55 49
56int pciehprm_set_hpp( 50void get_hp_params_from_firmware(struct pci_dev *dev,
57 struct controller *ctrl, 51 struct hotplug_params *hpp)
58 struct pci_func *func,
59 u8 card_type)
60{
61 u32 rc;
62 u8 temp_byte;
63 struct pci_bus lpci_bus, *pci_bus;
64 unsigned int devfn;
65 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
66 pci_bus = &lpci_bus;
67 pci_bus->number = func->bus;
68 devfn = PCI_DEVFN(func->device, func->function);
69
70 temp_byte = 0x40; /* hard coded value for LT */
71 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
72 /* set subordinate Latency Timer */
73 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
74
75 if (rc) {
76 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
77 func->bus, func->device, func->function);
78 return rc;
79 }
80 }
81
82 /* set base Latency Timer */
83 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
84
85 if (rc) {
86 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
87 return rc;
88 }
89
90 /* set Cache Line size */
91 temp_byte = 0x08; /* hard coded value for CLS */
92
93 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
94
95 if (rc) {
96 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
97 }
98
99 /* set enable_perr */
100 /* set enable_serr */
101
102 return rc;
103}
104
105void pciehprm_enable_card(
106 struct controller *ctrl,
107 struct pci_func *func,
108 u8 card_type)
109{ 52{
110 u16 command, bcommand; 53 return;
111 struct pci_bus lpci_bus, *pci_bus;
112 unsigned int devfn;
113 int rc;
114
115 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
116 pci_bus = &lpci_bus;
117 pci_bus->number = func->bus;
118 devfn = PCI_DEVFN(func->device, func->function);
119
120 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
121
122 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
123 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
124 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
125
126 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
127
128 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
129
130 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
131
132 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
133 | PCI_BRIDGE_CTL_NO_ISA;
134
135 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
136 }
137} 54}
138 55
139static int legacy_pciehprm_init_pci(void) 56int get_hp_hw_control_from_firmware(struct pci_dev *dev)
140{ 57{
141 return 0; 58 return 0;
142} 59}
143
144int pciehprm_init(enum php_ctlr_type ctrl_type)
145{
146 int retval;
147
148 switch (ctrl_type) {
149 case PCI:
150 retval = legacy_pciehprm_init_pci();
151 break;
152 default:
153 retval = -ENODEV;
154 break;
155 }
156
157 return retval;
158}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
deleted file mode 100644
index b10603b0e958..000000000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_NONACPI_H_
31#define _PCIEHPRM_NONACPI_H_
32
33struct irq_info {
34 u8 bus, devfn; /* bus, device and function */
35 struct {
36 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
37 u16 bitmap; /* Available IRQs */
38 } __attribute__ ((packed)) irq[4];
39 u8 slot; /* slot number, 0=onboard */
40 u8 rfu;
41} __attribute__ ((packed));
42
43struct irq_routing_table {
44 u32 signature; /* PIRQ_SIGNATURE should be here */
45 u16 version; /* PIRQ_VERSION */
46 u16 size; /* Table size in bytes */
47 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
48 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
49 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
50 u32 miniport_data; /* Crap */
51 u8 rfu[11];
52 u8 checksum; /* Modulo 256 checksum must give zero */
53 struct irq_info slots[0];
54} __attribute__ ((packed));
55
56#endif /* _PCIEHPRM_NONACPI_H_ */