aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/Kconfig197
-rw-r--r--drivers/pci/hotplug/Makefile74
-rw-r--r--drivers/pci/hotplug/acpiphp.h268
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c453
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c1344
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c499
-rw-r--r--drivers/pci/hotplug/acpiphp_pci.c449
-rw-r--r--drivers/pci/hotplug/acpiphp_res.c700
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h96
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c792
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c661
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c223
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c305
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.h79
-rw-r--r--drivers/pci/hotplug/cpqphp.h721
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c1509
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c3096
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c666
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.h57
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c1569
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c143
-rw-r--r--drivers/pci/hotplug/fakephp.c358
-rw-r--r--drivers/pci/hotplug/ibmphp.h763
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c1422
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c1275
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c1161
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c1747
-rw-r--r--drivers/pci/hotplug/ibmphp_res.c2156
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h180
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c715
-rw-r--r--drivers/pci/hotplug/pciehp.h352
-rw-r--r--drivers/pci/hotplug/pciehp_core.c662
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c2706
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c1501
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c827
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1737
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c501
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c375
-rw-r--r--drivers/pci/hotplug/rpadlpar.h24
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c503
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c151
-rw-r--r--drivers/pci/hotplug/rpaphp.h138
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c536
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c538
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c267
-rw-r--r--drivers/pci/hotplug/rpaphp_vio.c129
-rw-r--r--drivers/pci/hotplug/shpchp.h463
-rw-r--r--drivers/pci/hotplug/shpchp_core.c630
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c2848
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c1620
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c810
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c143
-rw-r--r--drivers/pci/hotplug/shpchprm.h55
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c1713
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c439
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.h113
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c434
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.h56
60 files changed, 44057 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
new file mode 100644
index 000000000000..1a4d4ca2a4dc
--- /dev/null
+++ b/drivers/pci/hotplug/Kconfig
@@ -0,0 +1,197 @@
1#
2# PCI Hotplug support
3#
4
5menu "PCI Hotplug Support"
6
7config HOTPLUG_PCI
8 tristate "Support for PCI Hotplug (EXPERIMENTAL)"
9 depends on PCI && EXPERIMENTAL
10 select HOTPLUG
11 ---help---
12 Say Y here if you have a motherboard with a PCI Hotplug controller.
13 This allows you to add and remove PCI cards while the machine is
14 powered up and running. The file system pcihpfs must be mounted
15 in order to interact with any PCI Hotplug controllers.
16
17 To compile this driver as a module, choose M here: the
18 module will be called pci_hotplug.
19
20 When in doubt, say N.
21
22config HOTPLUG_PCI_FAKE
23 tristate "Fake PCI Hotplug driver"
24 depends on HOTPLUG_PCI
25 help
26 Say Y here if you want to use the fake PCI hotplug driver. It can
27 be used to simulate PCI hotplug events if even if your system is
28 not PCI hotplug capable.
29
30 This driver will "emulate" removing PCI devices from the system.
31 If the "power" file is written to with "0" then the specified PCI
32 device will be completely removed from the kernel.
33
34 WARNING, this does NOT turn off the power to the PCI device.
35 This is a "logical" removal, not a physical or electrical
36 removal.
37
38 Use this module at your own risk. You have been warned!
39
40 To compile this driver as a module, choose M here: the
41 module will be called fakephp.
42
43 When in doubt, say N.
44
45config HOTPLUG_PCI_COMPAQ
46 tristate "Compaq PCI Hotplug driver"
47 depends on HOTPLUG_PCI && X86 && PCI_BIOS
48 help
49 Say Y here if you have a motherboard with a Compaq PCI Hotplug
50 controller.
51
52 To compile this driver as a module, choose M here: the
53 module will be called cpqphp.
54
55 When in doubt, say N.
56
57config HOTPLUG_PCI_COMPAQ_NVRAM
58 bool "Save configuration into NVRAM on Compaq servers"
59 depends on HOTPLUG_PCI_COMPAQ
60 help
61 Say Y here if you have a Compaq server that has a PCI Hotplug
62 controller. This will allow the PCI Hotplug driver to store the PCI
63 system configuration options in NVRAM.
64
65 When in doubt, say N.
66
67config HOTPLUG_PCI_IBM
68 tristate "IBM PCI Hotplug driver"
69 depends on HOTPLUG_PCI && X86_IO_APIC && X86 && PCI_BIOS
70 help
71 Say Y here if you have a motherboard with a IBM PCI Hotplug
72 controller.
73
74 To compile this driver as a module, choose M here: the
75 module will be called ibmphp.
76
77 When in doubt, say N.
78
79config HOTPLUG_PCI_ACPI
80 tristate "ACPI PCI Hotplug driver"
81 depends on ACPI_BUS && HOTPLUG_PCI
82 help
83 Say Y here if you have a system that supports PCI Hotplug using
84 ACPI.
85
86 To compile this driver as a module, choose M here: the
87 module will be called acpiphp.
88
89 When in doubt, say N.
90
91config HOTPLUG_PCI_ACPI_IBM
92 tristate "ACPI PCI Hotplug driver IBM extensions"
93 depends on HOTPLUG_PCI_ACPI
94 help
95 Say Y here if you have an IBM system that supports PCI Hotplug using
96 ACPI.
97
98 To compile this driver as a module, choose M here: the
99 module will be called acpiphp_ibm.
100
101 When in doubt, say N.
102
103config HOTPLUG_PCI_CPCI
104 bool "CompactPCI Hotplug driver"
105 depends on HOTPLUG_PCI
106 help
107 Say Y here if you have a CompactPCI system card with CompactPCI
108 hotswap support per the PICMG 2.1 specification.
109
110 When in doubt, say N.
111
112config HOTPLUG_PCI_CPCI_ZT5550
113 tristate "Ziatech ZT5550 CompactPCI Hotplug driver"
114 depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
115 help
116 Say Y here if you have an Performance Technologies (formerly Intel,
117 formerly just Ziatech) Ziatech ZT5550 CompactPCI system card.
118
119 To compile this driver as a module, choose M here: the
120 module will be called cpcihp_zt5550.
121
122 When in doubt, say N.
123
124config HOTPLUG_PCI_CPCI_GENERIC
125 tristate "Generic port I/O CompactPCI Hotplug driver"
126 depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
127 help
128 Say Y here if you have a CompactPCI system card that exposes the #ENUM
129 hotswap signal as a bit in a system register that can be read through
130 standard port I/O.
131
132 To compile this driver as a module, choose M here: the
133 module will be called cpcihp_generic.
134
135 When in doubt, say N.
136
137config HOTPLUG_PCI_SHPC
138 tristate "SHPC PCI Hotplug driver"
139 depends on HOTPLUG_PCI
140 help
141 Say Y here if you have a motherboard with a SHPC PCI Hotplug
142 controller.
143
144 To compile this driver as a module, choose M here: the
145 module will be called shpchp.
146
147 When in doubt, say N.
148
149config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
150 bool "Use polling mechanism for hot-plug events (for testing purpose)"
151 depends on HOTPLUG_PCI_SHPC
152 help
153 Say Y here if you want to use the polling mechanism for hot-plug
154 events for early platform testing.
155
156 When in doubt, say N.
157
158config HOTPLUG_PCI_SHPC_PHPRM_LEGACY
159 bool "For AMD SHPC only: Use $HRT for resource/configuration"
160 depends on HOTPLUG_PCI_SHPC && !ACPI_BUS
161 help
162 Say Y here for AMD SHPC. You have to select this option if you are
163 using this driver on platform with AMD SHPC.
164
165config HOTPLUG_PCI_RPA
166 tristate "RPA PCI Hotplug driver"
167 depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
168 help
169 Say Y here if you have a a RPA system that supports PCI Hotplug.
170
171 To compile this driver as a module, choose M here: the
172 module will be called rpaphp.
173
174 When in doubt, say N.
175
176config HOTPLUG_PCI_RPA_DLPAR
177 tristate "RPA Dynamic Logical Partitioning for I/O slots"
178 depends on HOTPLUG_PCI_RPA
179 help
180 Say Y here if your system supports Dynamic Logical Partitioning
181 for I/O slots.
182
183 To compile this driver as a module, choose M here: the
184 module will be called rpadlpar_io.
185
186 When in doubt, say N.
187
188config HOTPLUG_PCI_SGI
189 tristate "SGI PCI Hotplug Support"
190 depends on HOTPLUG_PCI && IA64_SGI_SN2
191 help
192 Say Y here if you have an SGI IA64 Altix system.
193
194 When in doubt, say N.
195
196endmenu
197
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
new file mode 100644
index 000000000000..93c120ddbd39
--- /dev/null
+++ b/drivers/pci/hotplug/Makefile
@@ -0,0 +1,74 @@
1#
2# Makefile for the Linux kernel pci hotplug controller drivers.
3#
4
5obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
6obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
7obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
8obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
9obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
10obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
11obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
12obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
13obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
14obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
15obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
16obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
17
18pci_hotplug-objs := pci_hotplug_core.o
19
20ifdef CONFIG_HOTPLUG_PCI_CPCI
21pci_hotplug-objs += cpci_hotplug_core.o \
22 cpci_hotplug_pci.o
23endif
24
25cpqphp-objs := cpqphp_core.o \
26 cpqphp_ctrl.o \
27 cpqphp_sysfs.o \
28 cpqphp_pci.o
29cpqphp-$(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM) += cpqphp_nvram.o
30cpqphp-objs += $(cpqphp-y)
31
32ibmphp-objs := ibmphp_core.o \
33 ibmphp_ebda.o \
34 ibmphp_pci.o \
35 ibmphp_res.o \
36 ibmphp_hpc.o
37
38acpiphp-objs := acpiphp_core.o \
39 acpiphp_glue.o \
40 acpiphp_pci.o \
41 acpiphp_res.o
42
43rpaphp-objs := rpaphp_core.o \
44 rpaphp_pci.o \
45 rpaphp_slot.o \
46 rpaphp_vio.o
47
48rpadlpar_io-objs := rpadlpar_core.o \
49 rpadlpar_sysfs.o
50
51pciehp-objs := pciehp_core.o \
52 pciehp_ctrl.o \
53 pciehp_pci.o \
54 pciehp_hpc.o
55ifdef CONFIG_ACPI_BUS
56 pciehp-objs += pciehprm_acpi.o
57else
58 pciehp-objs += pciehprm_nonacpi.o
59endif
60
61shpchp-objs := shpchp_core.o \
62 shpchp_ctrl.o \
63 shpchp_pci.o \
64 shpchp_sysfs.o \
65 shpchp_hpc.o
66ifdef CONFIG_ACPI_BUS
67 shpchp-objs += shpchprm_acpi.o
68else
69 ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
70 shpchp-objs += shpchprm_legacy.o
71 else
72 shpchp-objs += shpchprm_nonacpi.o
73 endif
74endif
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
new file mode 100644
index 000000000000..d9499874c8a9
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -0,0 +1,268 @@
1/*
2 * ACPI PCI Hot Plug Controller Driver
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) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>,
29 * <t-kochi@bq.jp.nec.com>
30 *
31 */
32
33#ifndef _ACPIPHP_H
34#define _ACPIPHP_H
35
36#include <linux/acpi.h>
37#include <linux/kobject.h> /* for KOBJ_NAME_LEN */
38#include "pci_hotplug.h"
39
40#define dbg(format, arg...) \
41 do { \
42 if (acpiphp_debug) \
43 printk(KERN_DEBUG "%s: " format, \
44 MY_NAME , ## arg); \
45 } while (0)
46#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
47#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
48#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
49
50/* name size which is used for entries in pcihpfs */
51#define SLOT_NAME_SIZE KOBJ_NAME_LEN /* {_SUN} */
52
53struct acpiphp_bridge;
54struct acpiphp_slot;
55struct pci_resource;
56
57/*
58 * struct slot - slot information for each *physical* slot
59 */
60struct slot {
61 u8 number;
62 struct hotplug_slot *hotplug_slot;
63 struct list_head slot_list;
64
65 struct acpiphp_slot *acpi_slot;
66};
67
68/*
69 * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
70 */
71struct pci_resource {
72 struct pci_resource * next;
73 u64 base;
74 u32 length;
75};
76
77/**
78 * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
79 * @cache_line_size in DWORD
80 * @latency_timer in PCI clock
81 * @enable_SERR 0 or 1
82 * @enable_PERR 0 or 1
83 */
84struct hpp_param {
85 u8 cache_line_size;
86 u8 latency_timer;
87 u8 enable_SERR;
88 u8 enable_PERR;
89};
90
91
92/**
93 * struct acpiphp_bridge - PCI bridge information
94 *
95 * for each bridge device in ACPI namespace
96 */
97struct acpiphp_bridge {
98 struct list_head list;
99 acpi_handle handle;
100 struct acpiphp_slot *slots;
101 int type;
102 int nr_slots;
103
104 u8 seg;
105 u8 bus;
106 u8 sub;
107
108 u32 flags;
109
110 /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
111 struct pci_bus *pci_bus;
112
113 /* PCI-to-PCI bridge device */
114 struct pci_dev *pci_dev;
115
116 /* ACPI 2.0 _HPP parameters */
117 struct hpp_param hpp;
118
119 spinlock_t res_lock;
120
121 /* available resources on this bus */
122 struct pci_resource *mem_head;
123 struct pci_resource *p_mem_head;
124 struct pci_resource *io_head;
125 struct pci_resource *bus_head;
126};
127
128
129/**
130 * struct acpiphp_slot - PCI slot information
131 *
132 * PCI slot information for each *physical* PCI slot
133 */
134struct acpiphp_slot {
135 struct acpiphp_slot *next;
136 struct acpiphp_bridge *bridge; /* parent */
137 struct list_head funcs; /* one slot may have different
138 objects (i.e. for each function) */
139 struct semaphore crit_sect;
140
141 u32 id; /* slot id (serial #) for hotplug core */
142 u8 device; /* pci device# */
143
144 u32 sun; /* ACPI _SUN (slot unique number) */
145 u32 slotno; /* slot number relative to bridge */
146 u32 flags; /* see below */
147};
148
149
150/**
151 * struct acpiphp_func - PCI function information
152 *
153 * PCI function information for each object in ACPI namespace
154 * typically 8 objects per slot (i.e. for each PCI function)
155 */
156struct acpiphp_func {
157 struct acpiphp_slot *slot; /* parent */
158
159 struct list_head sibling;
160 struct pci_dev *pci_dev;
161
162 acpi_handle handle;
163
164 u8 function; /* pci function# */
165 u32 flags; /* see below */
166
167 /* resources used for this function */
168 struct pci_resource *mem_head;
169 struct pci_resource *p_mem_head;
170 struct pci_resource *io_head;
171 struct pci_resource *bus_head;
172};
173
174/**
175 * struct acpiphp_attention_info - device specific attention registration
176 *
177 * ACPI has no generic method of setting/getting attention status
178 * this allows for device specific driver registration
179 */
180struct acpiphp_attention_info
181{
182 int (*set_attn)(struct hotplug_slot *slot, u8 status);
183 int (*get_attn)(struct hotplug_slot *slot, u8 *status);
184 struct module *owner;
185};
186
187/* PCI bus bridge HID */
188#define ACPI_PCI_HOST_HID "PNP0A03"
189
190/* PCI BRIDGE type */
191#define BRIDGE_TYPE_HOST 0
192#define BRIDGE_TYPE_P2P 1
193
194/* ACPI _STA method value (ignore bit 4; battery present) */
195#define ACPI_STA_PRESENT (0x00000001)
196#define ACPI_STA_ENABLED (0x00000002)
197#define ACPI_STA_SHOW_IN_UI (0x00000004)
198#define ACPI_STA_FUNCTIONING (0x00000008)
199#define ACPI_STA_ALL (0x0000000f)
200
201/* bridge flags */
202#define BRIDGE_HAS_STA (0x00000001)
203#define BRIDGE_HAS_EJ0 (0x00000002)
204#define BRIDGE_HAS_HPP (0x00000004)
205#define BRIDGE_HAS_PS0 (0x00000010)
206#define BRIDGE_HAS_PS1 (0x00000020)
207#define BRIDGE_HAS_PS2 (0x00000040)
208#define BRIDGE_HAS_PS3 (0x00000080)
209
210/* slot flags */
211
212#define SLOT_POWEREDON (0x00000001)
213#define SLOT_ENABLED (0x00000002)
214#define SLOT_MULTIFUNCTION (0x00000004)
215
216/* function flags */
217
218#define FUNC_HAS_STA (0x00000001)
219#define FUNC_HAS_EJ0 (0x00000002)
220#define FUNC_HAS_PS0 (0x00000010)
221#define FUNC_HAS_PS1 (0x00000020)
222#define FUNC_HAS_PS2 (0x00000040)
223#define FUNC_HAS_PS3 (0x00000080)
224
225/* function prototypes */
226
227/* acpiphp_core.c */
228extern int acpiphp_register_attention(struct acpiphp_attention_info*info);
229extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
230
231/* acpiphp_glue.c */
232extern int acpiphp_glue_init (void);
233extern void acpiphp_glue_exit (void);
234extern int acpiphp_get_num_slots (void);
235extern struct acpiphp_slot *get_slot_from_id (int id);
236typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
237
238extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
239extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
240extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
241extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
242extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
243extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
244extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
245
246/* acpiphp_pci.c */
247extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
248extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
249extern int acpiphp_configure_function (struct acpiphp_func *func);
250extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
251extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
252extern int acpiphp_init_func_resource (struct acpiphp_func *func);
253
254/* acpiphp_res.c */
255extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
256extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
257extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
258extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
259extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
260extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
261extern void acpiphp_free_resource (struct pci_resource **res);
262extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
263extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
264
265/* variables */
266extern int acpiphp_debug;
267
268#endif /* _ACPIPHP_H */
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
new file mode 100644
index 000000000000..4539e61a3dc1
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -0,0 +1,453 @@
1/*
2 * ACPI PCI Hot Plug Controller Driver
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) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>,
29 * <t-kochi@bq.jp.nec.com>
30 *
31 */
32
33#include <linux/init.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36
37#include <linux/kernel.h>
38#include <linux/pci.h>
39#include <linux/slab.h>
40#include <linux/smp.h>
41#include <linux/smp_lock.h>
42#include "pci_hotplug.h"
43#include "acpiphp.h"
44
45static LIST_HEAD(slot_list);
46
47#define MY_NAME "acpiphp"
48
49static int debug;
50int acpiphp_debug;
51
52/* local variables */
53static int num_slots;
54static struct acpiphp_attention_info *attention_info;
55
56#define DRIVER_VERSION "0.4"
57#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
58#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
59
60MODULE_AUTHOR(DRIVER_AUTHOR);
61MODULE_DESCRIPTION(DRIVER_DESC);
62MODULE_LICENSE("GPL");
63MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
64module_param(debug, bool, 0644);
65
66/* export the attention callback registration methods */
67EXPORT_SYMBOL_GPL(acpiphp_register_attention);
68EXPORT_SYMBOL_GPL(acpiphp_unregister_attention);
69
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72static int set_attention_status (struct hotplug_slot *slot, u8 value);
73static int get_power_status (struct hotplug_slot *slot, u8 *value);
74static int get_attention_status (struct hotplug_slot *slot, u8 *value);
75static int get_address (struct hotplug_slot *slot, u32 *value);
76static int get_latch_status (struct hotplug_slot *slot, u8 *value);
77static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
78
79static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
80 .owner = THIS_MODULE,
81 .enable_slot = enable_slot,
82 .disable_slot = disable_slot,
83 .set_attention_status = set_attention_status,
84 .get_power_status = get_power_status,
85 .get_attention_status = get_attention_status,
86 .get_latch_status = get_latch_status,
87 .get_adapter_status = get_adapter_status,
88 .get_address = get_address,
89};
90
91
92/**
93 * acpiphp_register_attention - set attention LED callback
94 * @info: must be completely filled with LED callbacks
95 *
96 * Description: this is used to register a hardware specific ACPI
97 * driver that manipulates the attention LED. All the fields in
98 * info must be set.
99 **/
100int acpiphp_register_attention(struct acpiphp_attention_info *info)
101{
102 int retval = -EINVAL;
103
104 if (info && info->owner && info->set_attn &&
105 info->get_attn && !attention_info) {
106 retval = 0;
107 attention_info = info;
108 }
109 return retval;
110}
111
112
113/**
114 * acpiphp_unregister_attention - unset attention LED callback
115 * @info: must match the pointer used to register
116 *
117 * Description: this is used to un-register a hardware specific acpi
118 * driver that manipulates the attention LED. The pointer to the
119 * info struct must be the same as the one used to set it.
120 **/
121int acpiphp_unregister_attention(struct acpiphp_attention_info *info)
122{
123 int retval = -EINVAL;
124
125 if (info && attention_info == info) {
126 attention_info = NULL;
127 retval = 0;
128 }
129 return retval;
130}
131
132
133/**
134 * enable_slot - power on and enable a slot
135 * @hotplug_slot: slot to enable
136 *
137 * Actual tasks are done in acpiphp_enable_slot()
138 *
139 */
140static int enable_slot(struct hotplug_slot *hotplug_slot)
141{
142 struct slot *slot = hotplug_slot->private;
143
144 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
145
146 /* enable the specified slot */
147 return acpiphp_enable_slot(slot->acpi_slot);
148}
149
150
151/**
152 * disable_slot - disable and power off a slot
153 * @hotplug_slot: slot to disable
154 *
155 * Actual tasks are done in acpiphp_disable_slot()
156 *
157 */
158static int disable_slot(struct hotplug_slot *hotplug_slot)
159{
160 struct slot *slot = hotplug_slot->private;
161
162 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
163
164 /* disable the specified slot */
165 return acpiphp_disable_slot(slot->acpi_slot);
166}
167
168
169 /**
170 * set_attention_status - set attention LED
171 * @hotplug_slot: slot to set attention LED on
172 * @status: value to set attention LED to (0 or 1)
173 *
174 * attention status LED, so we use a callback that
175 * was registered with us. This allows hardware specific
176 * ACPI implementations to blink the light for us.
177 **/
178 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
179 {
180 int retval = -ENODEV;
181
182 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
183
184 if (attention_info && try_module_get(attention_info->owner)) {
185 retval = attention_info->set_attn(hotplug_slot, status);
186 module_put(attention_info->owner);
187 } else
188 attention_info = NULL;
189 return retval;
190 }
191
192
193/**
194 * get_power_status - get power status of a slot
195 * @hotplug_slot: slot to get status
196 * @value: pointer to store status
197 *
198 * Some platforms may not implement _STA method properly.
199 * In that case, the value returned may not be reliable.
200 *
201 */
202static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
203{
204 struct slot *slot = hotplug_slot->private;
205
206 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
207
208 *value = acpiphp_get_power_status(slot->acpi_slot);
209
210 return 0;
211}
212
213
214 /**
215 * get_attention_status - get attention LED status
216 * @hotplug_slot: slot to get status from
217 * @value: returns with value of attention LED
218 *
219 * ACPI doesn't have known method to determine the state
220 * of the attention status LED, so we use a callback that
221 * was registered with us. This allows hardware specific
222 * ACPI implementations to determine its state
223 **/
224static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
225{
226 int retval = -EINVAL;
227
228 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
229
230 if (attention_info && try_module_get(attention_info->owner)) {
231 retval = attention_info->get_attn(hotplug_slot, value);
232 module_put(attention_info->owner);
233 } else
234 attention_info = NULL;
235 return retval;
236}
237
238
239/**
240 * get_latch_status - get latch status of a slot
241 * @hotplug_slot: slot to get status
242 * @value: pointer to store status
243 *
244 * ACPI doesn't provide any formal means to access latch status.
245 * Instead, we fake latch status from _STA
246 *
247 */
248static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
249{
250 struct slot *slot = hotplug_slot->private;
251
252 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
253
254 *value = acpiphp_get_latch_status(slot->acpi_slot);
255
256 return 0;
257}
258
259
260/**
261 * get_adapter_status - get adapter status of a slot
262 * @hotplug_slot: slot to get status
263 * @value: pointer to store status
264 *
265 * ACPI doesn't provide any formal means to access adapter status.
266 * Instead, we fake adapter status from _STA
267 *
268 */
269static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
270{
271 struct slot *slot = hotplug_slot->private;
272
273 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
274
275 *value = acpiphp_get_adapter_status(slot->acpi_slot);
276
277 return 0;
278}
279
280
281/**
282 * get_address - get pci address of a slot
283 * @hotplug_slot: slot to get status
284 * @busdev: pointer to struct pci_busdev (seg, bus, dev)
285 *
286 */
287static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
288{
289 struct slot *slot = hotplug_slot->private;
290
291 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
292
293 *value = acpiphp_get_address(slot->acpi_slot);
294
295 return 0;
296}
297
298static int __init init_acpi(void)
299{
300 int retval;
301
302 /* initialize internal data structure etc. */
303 retval = acpiphp_glue_init();
304
305 /* read initial number of slots */
306 if (!retval) {
307 num_slots = acpiphp_get_num_slots();
308 if (num_slots == 0)
309 retval = -ENODEV;
310 }
311
312 return retval;
313}
314
315
316/**
317 * make_slot_name - make a slot name that appears in pcihpfs
318 * @slot: slot to name
319 *
320 */
321static void make_slot_name(struct slot *slot)
322{
323 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%u",
324 slot->acpi_slot->sun);
325}
326
327/**
328 * release_slot - free up the memory used by a slot
329 * @hotplug_slot: slot to free
330 */
331static void release_slot(struct hotplug_slot *hotplug_slot)
332{
333 struct slot *slot = hotplug_slot->private;
334
335 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
336
337 kfree(slot->hotplug_slot->info);
338 kfree(slot->hotplug_slot->name);
339 kfree(slot->hotplug_slot);
340 kfree(slot);
341}
342
343/**
344 * init_slots - initialize 'struct slot' structures for each slot
345 *
346 */
347static int __init init_slots(void)
348{
349 struct slot *slot;
350 int retval = -ENOMEM;
351 int i;
352
353 for (i = 0; i < num_slots; ++i) {
354 slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
355 if (!slot)
356 goto error;
357 memset(slot, 0, sizeof(struct slot));
358
359 slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
360 if (!slot->hotplug_slot)
361 goto error_slot;
362 memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
363
364 slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
365 if (!slot->hotplug_slot->info)
366 goto error_hpslot;
367 memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
368
369 slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
370 if (!slot->hotplug_slot->name)
371 goto error_info;
372
373 slot->number = i;
374
375 slot->hotplug_slot->private = slot;
376 slot->hotplug_slot->release = &release_slot;
377 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
378
379 slot->acpi_slot = get_slot_from_id(i);
380 slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
381 slot->hotplug_slot->info->attention_status = 0;
382 slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
383 slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
384 slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
385 slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
386
387 make_slot_name(slot);
388
389 retval = pci_hp_register(slot->hotplug_slot);
390 if (retval) {
391 err("pci_hp_register failed with error %d\n", retval);
392 goto error_name;
393 }
394
395 /* add slot to our internal list */
396 list_add(&slot->slot_list, &slot_list);
397 info("Slot [%s] registered\n", slot->hotplug_slot->name);
398 }
399
400 return 0;
401error_name:
402 kfree(slot->hotplug_slot->name);
403error_info:
404 kfree(slot->hotplug_slot->info);
405error_hpslot:
406 kfree(slot->hotplug_slot);
407error_slot:
408 kfree(slot);
409error:
410 return retval;
411}
412
413
414static void __exit cleanup_slots (void)
415{
416 struct list_head *tmp, *n;
417 struct slot *slot;
418
419 list_for_each_safe (tmp, n, &slot_list) {
420 /* memory will be freed in release_slot callback */
421 slot = list_entry(tmp, struct slot, slot_list);
422 list_del(&slot->slot_list);
423 pci_hp_deregister(slot->hotplug_slot);
424 }
425}
426
427
428static int __init acpiphp_init(void)
429{
430 int retval;
431
432 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
433
434 acpiphp_debug = debug;
435
436 /* read all the ACPI info from the system */
437 retval = init_acpi();
438 if (retval)
439 return retval;
440
441 return init_slots();
442}
443
444
445static void __exit acpiphp_exit(void)
446{
447 cleanup_slots();
448 /* deallocate internal data structures etc. */
449 acpiphp_glue_exit();
450}
451
452module_init(acpiphp_init);
453module_exit(acpiphp_exit);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
new file mode 100644
index 000000000000..e7f41294f811
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -0,0 +1,1344 @@
1/*
2 * ACPI PCI HotPlug glue functions to ACPI CA subsystem
3 *
4 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
5 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
6 * Copyright (C) 2002,2003 NEC Corporation
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <t-kochi@bq.jp.nec.com>
26 *
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31
32#include <linux/kernel.h>
33#include <linux/pci.h>
34#include <linux/smp_lock.h>
35#include <asm/semaphore.h>
36
37#include "../pci.h"
38#include "pci_hotplug.h"
39#include "acpiphp.h"
40
41static LIST_HEAD(bridge_list);
42
43#define MY_NAME "acpiphp_glue"
44
45static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
46static void handle_hotplug_event_func (acpi_handle, u32, void *);
47
48/*
49 * initialization & terminatation routines
50 */
51
52/**
53 * is_ejectable - determine if a slot is ejectable
54 * @handle: handle to acpi namespace
55 *
56 * Ejectable slot should satisfy at least these conditions:
57 *
58 * 1. has _ADR method
59 * 2. has _EJ0 method
60 *
61 * optionally
62 *
63 * 1. has _STA method
64 * 2. has _PS0 method
65 * 3. has _PS3 method
66 * 4. ..
67 *
68 */
69static int is_ejectable(acpi_handle handle)
70{
71 acpi_status status;
72 acpi_handle tmp;
73
74 status = acpi_get_handle(handle, "_ADR", &tmp);
75 if (ACPI_FAILURE(status)) {
76 return 0;
77 }
78
79 status = acpi_get_handle(handle, "_EJ0", &tmp);
80 if (ACPI_FAILURE(status)) {
81 return 0;
82 }
83
84 return 1;
85}
86
87
88/* callback routine to check the existence of ejectable slots */
89static acpi_status
90is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
91{
92 int *count = (int *)context;
93
94 if (is_ejectable(handle)) {
95 (*count)++;
96 /* only one ejectable slot is enough */
97 return AE_CTRL_TERMINATE;
98 } else {
99 return AE_OK;
100 }
101}
102
103
104/* callback routine to register each ACPI PCI slot object */
105static acpi_status
106register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
107{
108 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
109 struct acpiphp_slot *slot;
110 struct acpiphp_func *newfunc;
111 acpi_handle tmp;
112 acpi_status status = AE_OK;
113 unsigned long adr, sun;
114 int device, function;
115 static int num_slots = 0; /* XXX if we support I/O node hotplug... */
116
117 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
118
119 if (ACPI_FAILURE(status))
120 return AE_OK;
121
122 status = acpi_get_handle(handle, "_EJ0", &tmp);
123
124 if (ACPI_FAILURE(status))
125 return AE_OK;
126
127 device = (adr >> 16) & 0xffff;
128 function = adr & 0xffff;
129
130 newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
131 if (!newfunc)
132 return AE_NO_MEMORY;
133 memset(newfunc, 0, sizeof(struct acpiphp_func));
134
135 INIT_LIST_HEAD(&newfunc->sibling);
136 newfunc->handle = handle;
137 newfunc->function = function;
138 newfunc->flags = FUNC_HAS_EJ0;
139
140 if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
141 newfunc->flags |= FUNC_HAS_STA;
142
143 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp)))
144 newfunc->flags |= FUNC_HAS_PS0;
145
146 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
147 newfunc->flags |= FUNC_HAS_PS3;
148
149 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
150 if (ACPI_FAILURE(status))
151 sun = -1;
152
153 /* search for objects that share the same slot */
154 for (slot = bridge->slots; slot; slot = slot->next)
155 if (slot->device == device) {
156 if (slot->sun != sun)
157 warn("sibling found, but _SUN doesn't match!\n");
158 break;
159 }
160
161 if (!slot) {
162 slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
163 if (!slot) {
164 kfree(newfunc);
165 return AE_NO_MEMORY;
166 }
167
168 memset(slot, 0, sizeof(struct acpiphp_slot));
169 slot->bridge = bridge;
170 slot->id = num_slots++;
171 slot->device = device;
172 slot->sun = sun;
173 INIT_LIST_HEAD(&slot->funcs);
174 init_MUTEX(&slot->crit_sect);
175
176 slot->next = bridge->slots;
177 bridge->slots = slot;
178
179 bridge->nr_slots++;
180
181 dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
182 slot->bridge->bus, slot->device, slot->sun);
183 }
184
185 newfunc->slot = slot;
186 list_add_tail(&newfunc->sibling, &slot->funcs);
187
188 /* associate corresponding pci_dev */
189 newfunc->pci_dev = pci_find_slot(bridge->bus,
190 PCI_DEVFN(device, function));
191 if (newfunc->pci_dev) {
192 if (acpiphp_init_func_resource(newfunc) < 0) {
193 kfree(newfunc);
194 return AE_ERROR;
195 }
196 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
197 }
198
199 /* install notify handler */
200 status = acpi_install_notify_handler(handle,
201 ACPI_SYSTEM_NOTIFY,
202 handle_hotplug_event_func,
203 newfunc);
204
205 if (ACPI_FAILURE(status)) {
206 err("failed to register interrupt notify handler\n");
207 return status;
208 }
209
210 return AE_OK;
211}
212
213
214/* see if it's worth looking at this bridge */
215static int detect_ejectable_slots(acpi_handle *bridge_handle)
216{
217 acpi_status status;
218 int count;
219
220 count = 0;
221
222 /* only check slots defined directly below bridge object */
223 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
224 is_ejectable_slot, (void *)&count, NULL);
225
226 return count;
227}
228
229
230/* decode ACPI _CRS data and convert into our internal resource list
231 * TBD: _TRA, etc.
232 */
233static acpi_status
234decode_acpi_resource(struct acpi_resource *resource, void *context)
235{
236 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
237 struct acpi_resource_address64 address;
238 struct pci_resource *res;
239
240 if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
241 resource->id != ACPI_RSTYPE_ADDRESS32 &&
242 resource->id != ACPI_RSTYPE_ADDRESS64)
243 return AE_OK;
244
245 acpi_resource_to_address64(resource, &address);
246
247 if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
248 dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
249 (unsigned long long)address.min_address_range,
250 (unsigned long long)address.max_address_range);
251 res = acpiphp_make_resource(address.min_address_range,
252 address.address_length);
253 if (!res) {
254 err("out of memory\n");
255 return AE_OK;
256 }
257
258 switch (address.resource_type) {
259 case ACPI_MEMORY_RANGE:
260 if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
261 res->next = bridge->p_mem_head;
262 bridge->p_mem_head = res;
263 } else {
264 res->next = bridge->mem_head;
265 bridge->mem_head = res;
266 }
267 break;
268 case ACPI_IO_RANGE:
269 res->next = bridge->io_head;
270 bridge->io_head = res;
271 break;
272 case ACPI_BUS_NUMBER_RANGE:
273 res->next = bridge->bus_head;
274 bridge->bus_head = res;
275 break;
276 default:
277 /* invalid type */
278 kfree(res);
279 break;
280 }
281 }
282
283 return AE_OK;
284}
285
286/* decode ACPI 2.0 _HPP hot plug parameters */
287static void decode_hpp(struct acpiphp_bridge *bridge)
288{
289 acpi_status status;
290 struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
291 .pointer = NULL};
292 union acpi_object *package;
293 int i;
294
295 /* default numbers */
296 bridge->hpp.cache_line_size = 0x10;
297 bridge->hpp.latency_timer = 0x40;
298 bridge->hpp.enable_SERR = 0;
299 bridge->hpp.enable_PERR = 0;
300
301 status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
302
303 if (ACPI_FAILURE(status)) {
304 dbg("_HPP evaluation failed\n");
305 return;
306 }
307
308 package = (union acpi_object *) buffer.pointer;
309
310 if (!package || package->type != ACPI_TYPE_PACKAGE ||
311 package->package.count != 4 || !package->package.elements) {
312 err("invalid _HPP object; ignoring\n");
313 goto err_exit;
314 }
315
316 for (i = 0; i < 4; i++) {
317 if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
318 err("invalid _HPP parameter type; ignoring\n");
319 goto err_exit;
320 }
321 }
322
323 bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
324 bridge->hpp.latency_timer = package->package.elements[1].integer.value;
325 bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
326 bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
327
328 dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
329 bridge->hpp.cache_line_size,
330 bridge->hpp.latency_timer,
331 bridge->hpp.enable_SERR,
332 bridge->hpp.enable_PERR);
333
334 bridge->flags |= BRIDGE_HAS_HPP;
335
336 err_exit:
337 kfree(buffer.pointer);
338}
339
340
341/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
342static void init_bridge_misc(struct acpiphp_bridge *bridge)
343{
344 acpi_status status;
345
346 /* decode ACPI 2.0 _HPP (hot plug parameters) */
347 decode_hpp(bridge);
348
349 /* subtract all resources already allocated */
350 acpiphp_detect_pci_resource(bridge);
351
352 /* register all slot objects under this bridge */
353 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
354 register_slot, bridge, NULL);
355
356 /* install notify handler */
357 status = acpi_install_notify_handler(bridge->handle,
358 ACPI_SYSTEM_NOTIFY,
359 handle_hotplug_event_bridge,
360 bridge);
361
362 if (ACPI_FAILURE(status)) {
363 err("failed to register interrupt notify handler\n");
364 }
365
366 list_add(&bridge->list, &bridge_list);
367
368 dbg("Bridge resource:\n");
369 acpiphp_dump_resource(bridge);
370}
371
372
373/* allocate and initialize host bridge data structure */
374static void add_host_bridge(acpi_handle *handle, int seg, int bus)
375{
376 acpi_status status;
377 struct acpiphp_bridge *bridge;
378
379 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
380 if (bridge == NULL)
381 return;
382
383 memset(bridge, 0, sizeof(struct acpiphp_bridge));
384
385 bridge->type = BRIDGE_TYPE_HOST;
386 bridge->handle = handle;
387 bridge->seg = seg;
388 bridge->bus = bus;
389
390 bridge->pci_bus = pci_find_bus(seg, bus);
391
392 spin_lock_init(&bridge->res_lock);
393
394 /* to be overridden when we decode _CRS */
395 bridge->sub = bridge->bus;
396
397 /* decode resources */
398
399 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
400 decode_acpi_resource, bridge);
401
402 if (ACPI_FAILURE(status)) {
403 err("failed to decode bridge resources\n");
404 kfree(bridge);
405 return;
406 }
407
408 acpiphp_resource_sort_and_combine(&bridge->io_head);
409 acpiphp_resource_sort_and_combine(&bridge->mem_head);
410 acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
411 acpiphp_resource_sort_and_combine(&bridge->bus_head);
412
413 dbg("ACPI _CRS resource:\n");
414 acpiphp_dump_resource(bridge);
415
416 if (bridge->bus_head) {
417 bridge->bus = bridge->bus_head->base;
418 bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
419 }
420
421 init_bridge_misc(bridge);
422}
423
424
425/* allocate and initialize PCI-to-PCI bridge data structure */
426static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
427{
428 struct acpiphp_bridge *bridge;
429 u8 tmp8;
430 u16 tmp16;
431 u64 base64, limit64;
432 u32 base, limit, base32u, limit32u;
433
434 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
435 if (bridge == NULL) {
436 err("out of memory\n");
437 return;
438 }
439
440 memset(bridge, 0, sizeof(struct acpiphp_bridge));
441
442 bridge->type = BRIDGE_TYPE_P2P;
443 bridge->handle = handle;
444 bridge->seg = seg;
445
446 bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
447 if (!bridge->pci_dev) {
448 err("Can't get pci_dev\n");
449 kfree(bridge);
450 return;
451 }
452
453 bridge->pci_bus = bridge->pci_dev->subordinate;
454 if (!bridge->pci_bus) {
455 err("This is not a PCI-to-PCI bridge!\n");
456 kfree(bridge);
457 return;
458 }
459
460 spin_lock_init(&bridge->res_lock);
461
462 bridge->bus = bridge->pci_bus->number;
463 bridge->sub = bridge->pci_bus->subordinate;
464
465 /*
466 * decode resources under this P2P bridge
467 */
468
469 /* I/O resources */
470 pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
471 base = tmp8;
472 pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
473 limit = tmp8;
474
475 switch (base & PCI_IO_RANGE_TYPE_MASK) {
476 case PCI_IO_RANGE_TYPE_16:
477 base = (base << 8) & 0xf000;
478 limit = ((limit << 8) & 0xf000) + 0xfff;
479 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
480 if (!bridge->io_head) {
481 err("out of memory\n");
482 kfree(bridge);
483 return;
484 }
485 dbg("16bit I/O range: %04x-%04x\n",
486 (u32)bridge->io_head->base,
487 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
488 break;
489 case PCI_IO_RANGE_TYPE_32:
490 pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
491 base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
492 pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
493 limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
494 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
495 if (!bridge->io_head) {
496 err("out of memory\n");
497 kfree(bridge);
498 return;
499 }
500 dbg("32bit I/O range: %08x-%08x\n",
501 (u32)bridge->io_head->base,
502 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
503 break;
504 case 0x0f:
505 dbg("I/O space unsupported\n");
506 break;
507 default:
508 warn("Unknown I/O range type\n");
509 }
510
511 /* Memory resources (mandatory for P2P bridge) */
512 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
513 base = (tmp16 & 0xfff0) << 16;
514 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
515 limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
516 bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
517 if (!bridge->mem_head) {
518 err("out of memory\n");
519 kfree(bridge);
520 return;
521 }
522 dbg("32bit Memory range: %08x-%08x\n",
523 (u32)bridge->mem_head->base,
524 (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
525
526 /* Prefetchable Memory resources (optional) */
527 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
528 base = tmp16;
529 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
530 limit = tmp16;
531
532 switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
533 case PCI_PREF_RANGE_TYPE_32:
534 base = (base & 0xfff0) << 16;
535 limit = ((limit & 0xfff0) << 16) | 0xfffff;
536 bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
537 if (!bridge->p_mem_head) {
538 err("out of memory\n");
539 kfree(bridge);
540 return;
541 }
542 dbg("32bit Prefetchable memory range: %08x-%08x\n",
543 (u32)bridge->p_mem_head->base,
544 (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
545 break;
546 case PCI_PREF_RANGE_TYPE_64:
547 pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
548 pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
549 base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
550 limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
551
552 bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
553 if (!bridge->p_mem_head) {
554 err("out of memory\n");
555 kfree(bridge);
556 return;
557 }
558 dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
559 (u32)(bridge->p_mem_head->base >> 32),
560 (u32)(bridge->p_mem_head->base & 0xffffffff),
561 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
562 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
563 break;
564 case 0x0f:
565 break;
566 default:
567 warn("Unknown prefetchale memory type\n");
568 }
569
570 init_bridge_misc(bridge);
571}
572
573
574/* callback routine to find P2P bridges */
575static acpi_status
576find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
577{
578 acpi_status status;
579 acpi_handle dummy_handle;
580 unsigned long *segbus = context;
581 unsigned long tmp;
582 int seg, bus, device, function;
583 struct pci_dev *dev;
584
585 /* get PCI address */
586 seg = (*segbus >> 8) & 0xff;
587 bus = *segbus & 0xff;
588
589 status = acpi_get_handle(handle, "_ADR", &dummy_handle);
590 if (ACPI_FAILURE(status))
591 return AE_OK; /* continue */
592
593 status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
594 if (ACPI_FAILURE(status)) {
595 dbg("%s: _ADR evaluation failure\n", __FUNCTION__);
596 return AE_OK;
597 }
598
599 device = (tmp >> 16) & 0xffff;
600 function = tmp & 0xffff;
601
602 dev = pci_find_slot(bus, PCI_DEVFN(device, function));
603
604 if (!dev)
605 return AE_OK;
606
607 if (!dev->subordinate)
608 return AE_OK;
609
610 /* check if this bridge has ejectable slots */
611 if (detect_ejectable_slots(handle) > 0) {
612 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
613 add_p2p_bridge(handle, seg, bus, device, function);
614 }
615
616 return AE_OK;
617}
618
619
620/* find hot-pluggable slots, and then find P2P bridge */
621static int add_bridge(acpi_handle handle)
622{
623 acpi_status status;
624 unsigned long tmp;
625 int seg, bus;
626 acpi_handle dummy_handle;
627
628 /* if the bridge doesn't have _STA, we assume it is always there */
629 status = acpi_get_handle(handle, "_STA", &dummy_handle);
630 if (ACPI_SUCCESS(status)) {
631 status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
632 if (ACPI_FAILURE(status)) {
633 dbg("%s: _STA evaluation failure\n", __FUNCTION__);
634 return 0;
635 }
636 if ((tmp & ACPI_STA_FUNCTIONING) == 0)
637 /* don't register this object */
638 return 0;
639 }
640
641 /* get PCI segment number */
642 status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
643
644 seg = ACPI_SUCCESS(status) ? tmp : 0;
645
646 /* get PCI bus number */
647 status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
648
649 if (ACPI_SUCCESS(status)) {
650 bus = tmp;
651 } else {
652 warn("can't get bus number, assuming 0\n");
653 bus = 0;
654 }
655
656 /* check if this bridge has ejectable slots */
657 if (detect_ejectable_slots(handle) > 0) {
658 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
659 add_host_bridge(handle, seg, bus);
660 return 0;
661 }
662
663 tmp = seg << 8 | bus;
664
665 /* search P2P bridges under this host bridge */
666 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
667 find_p2p_bridge, &tmp, NULL);
668
669 if (ACPI_FAILURE(status))
670 warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
671
672 return 0;
673}
674
675
676static void remove_bridge(acpi_handle handle)
677{
678 /* No-op for now .. */
679}
680
681
682static int power_on_slot(struct acpiphp_slot *slot)
683{
684 acpi_status status;
685 struct acpiphp_func *func;
686 struct list_head *l;
687 int retval = 0;
688
689 /* if already enabled, just skip */
690 if (slot->flags & SLOT_POWEREDON)
691 goto err_exit;
692
693 list_for_each (l, &slot->funcs) {
694 func = list_entry(l, struct acpiphp_func, sibling);
695
696 if (func->flags & FUNC_HAS_PS0) {
697 dbg("%s: executing _PS0\n", __FUNCTION__);
698 status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
699 if (ACPI_FAILURE(status)) {
700 warn("%s: _PS0 failed\n", __FUNCTION__);
701 retval = -1;
702 goto err_exit;
703 } else
704 break;
705 }
706 }
707
708 /* TBD: evaluate _STA to check if the slot is enabled */
709
710 slot->flags |= SLOT_POWEREDON;
711
712 err_exit:
713 return retval;
714}
715
716
717static int power_off_slot(struct acpiphp_slot *slot)
718{
719 acpi_status status;
720 struct acpiphp_func *func;
721 struct list_head *l;
722 struct acpi_object_list arg_list;
723 union acpi_object arg;
724
725 int retval = 0;
726
727 /* if already disabled, just skip */
728 if ((slot->flags & SLOT_POWEREDON) == 0)
729 goto err_exit;
730
731 list_for_each (l, &slot->funcs) {
732 func = list_entry(l, struct acpiphp_func, sibling);
733
734 if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
735 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
736 if (ACPI_FAILURE(status)) {
737 warn("%s: _PS3 failed\n", __FUNCTION__);
738 retval = -1;
739 goto err_exit;
740 } else
741 break;
742 }
743 }
744
745 list_for_each (l, &slot->funcs) {
746 func = list_entry(l, struct acpiphp_func, sibling);
747
748 /* We don't want to call _EJ0 on non-existing functions. */
749 if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
750 /* _EJ0 method take one argument */
751 arg_list.count = 1;
752 arg_list.pointer = &arg;
753 arg.type = ACPI_TYPE_INTEGER;
754 arg.integer.value = 1;
755
756 status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
757 if (ACPI_FAILURE(status)) {
758 warn("%s: _EJ0 failed\n", __FUNCTION__);
759 retval = -1;
760 goto err_exit;
761 } else
762 break;
763 }
764 }
765
766 /* TBD: evaluate _STA to check if the slot is disabled */
767
768 slot->flags &= (~SLOT_POWEREDON);
769
770 err_exit:
771 return retval;
772}
773
774
775/**
776 * enable_device - enable, configure a slot
777 * @slot: slot to be enabled
778 *
779 * This function should be called per *physical slot*,
780 * not per each slot object in ACPI namespace.
781 *
782 */
783static int enable_device(struct acpiphp_slot *slot)
784{
785 u8 bus;
786 struct pci_dev *dev;
787 struct pci_bus *child;
788 struct list_head *l;
789 struct acpiphp_func *func;
790 int retval = 0;
791 int num;
792
793 if (slot->flags & SLOT_ENABLED)
794 goto err_exit;
795
796 /* sanity check: dev should be NULL when hot-plugged in */
797 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
798 if (dev) {
799 /* This case shouldn't happen */
800 err("pci_dev structure already exists.\n");
801 retval = -1;
802 goto err_exit;
803 }
804
805 /* allocate resources to device */
806 retval = acpiphp_configure_slot(slot);
807 if (retval)
808 goto err_exit;
809
810 /* returned `dev' is the *first function* only! */
811 num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
812 if (num)
813 pci_bus_add_devices(slot->bridge->pci_bus);
814 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
815
816 if (!dev) {
817 err("No new device found\n");
818 retval = -1;
819 goto err_exit;
820 }
821
822 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
823 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
824 child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
825 pci_do_scan_bus(child);
826 }
827
828 /* associate pci_dev to our representation */
829 list_for_each (l, &slot->funcs) {
830 func = list_entry(l, struct acpiphp_func, sibling);
831
832 func->pci_dev = pci_find_slot(slot->bridge->bus,
833 PCI_DEVFN(slot->device,
834 func->function));
835 if (!func->pci_dev)
836 continue;
837
838 /* configure device */
839 retval = acpiphp_configure_function(func);
840 if (retval)
841 goto err_exit;
842 }
843
844 slot->flags |= SLOT_ENABLED;
845
846 dbg("Available resources:\n");
847 acpiphp_dump_resource(slot->bridge);
848
849 err_exit:
850 return retval;
851}
852
853
854/**
855 * disable_device - disable a slot
856 */
857static int disable_device(struct acpiphp_slot *slot)
858{
859 int retval = 0;
860 struct acpiphp_func *func;
861 struct list_head *l;
862
863 /* is this slot already disabled? */
864 if (!(slot->flags & SLOT_ENABLED))
865 goto err_exit;
866
867 list_for_each (l, &slot->funcs) {
868 func = list_entry(l, struct acpiphp_func, sibling);
869
870 if (func->pci_dev)
871 acpiphp_unconfigure_function(func);
872 }
873
874 slot->flags &= (~SLOT_ENABLED);
875
876 err_exit:
877 return retval;
878}
879
880
881/**
882 * get_slot_status - get ACPI slot status
883 *
884 * if a slot has _STA for each function and if any one of them
885 * returned non-zero status, return it
886 *
887 * if a slot doesn't have _STA and if any one of its functions'
888 * configuration space is configured, return 0x0f as a _STA
889 *
890 * otherwise return 0
891 */
892static unsigned int get_slot_status(struct acpiphp_slot *slot)
893{
894 acpi_status status;
895 unsigned long sta = 0;
896 u32 dvid;
897 struct list_head *l;
898 struct acpiphp_func *func;
899
900 list_for_each (l, &slot->funcs) {
901 func = list_entry(l, struct acpiphp_func, sibling);
902
903 if (func->flags & FUNC_HAS_STA) {
904 status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
905 if (ACPI_SUCCESS(status) && sta)
906 break;
907 } else {
908 pci_bus_read_config_dword(slot->bridge->pci_bus,
909 PCI_DEVFN(slot->device,
910 func->function),
911 PCI_VENDOR_ID, &dvid);
912 if (dvid != 0xffffffff) {
913 sta = ACPI_STA_ALL;
914 break;
915 }
916 }
917 }
918
919 return (unsigned int)sta;
920}
921
922/**
923 * acpiphp_check_bridge - re-enumerate devices
924 *
925 * Iterate over all slots under this bridge and make sure that if a
926 * card is present they are enabled, and if not they are disabled.
927 */
928static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
929{
930 struct acpiphp_slot *slot;
931 int retval = 0;
932 int enabled, disabled;
933
934 enabled = disabled = 0;
935
936 for (slot = bridge->slots; slot; slot = slot->next) {
937 unsigned int status = get_slot_status(slot);
938 if (slot->flags & SLOT_ENABLED) {
939 if (status == ACPI_STA_ALL)
940 continue;
941 retval = acpiphp_disable_slot(slot);
942 if (retval) {
943 err("Error occurred in disabling\n");
944 goto err_exit;
945 }
946 disabled++;
947 } else {
948 if (status != ACPI_STA_ALL)
949 continue;
950 retval = acpiphp_enable_slot(slot);
951 if (retval) {
952 err("Error occurred in enabling\n");
953 goto err_exit;
954 }
955 enabled++;
956 }
957 }
958
959 dbg("%s: %d enabled, %d disabled\n", __FUNCTION__, enabled, disabled);
960
961 err_exit:
962 return retval;
963}
964
965/*
966 * ACPI event handlers
967 */
968
969/**
970 * handle_hotplug_event_bridge - handle ACPI event on bridges
971 *
972 * @handle: Notify()'ed acpi_handle
973 * @type: Notify code
974 * @context: pointer to acpiphp_bridge structure
975 *
976 * handles ACPI event notification on {host,p2p} bridges
977 *
978 */
979static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context)
980{
981 struct acpiphp_bridge *bridge;
982 char objname[64];
983 struct acpi_buffer buffer = { .length = sizeof(objname),
984 .pointer = objname };
985
986 bridge = (struct acpiphp_bridge *)context;
987
988 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
989
990 switch (type) {
991 case ACPI_NOTIFY_BUS_CHECK:
992 /* bus re-enumerate */
993 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
994 acpiphp_check_bridge(bridge);
995 break;
996
997 case ACPI_NOTIFY_DEVICE_CHECK:
998 /* device check */
999 dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1000 acpiphp_check_bridge(bridge);
1001 break;
1002
1003 case ACPI_NOTIFY_DEVICE_WAKE:
1004 /* wake event */
1005 dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1006 break;
1007
1008 case ACPI_NOTIFY_EJECT_REQUEST:
1009 /* request device eject */
1010 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1011 break;
1012
1013 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1014 printk(KERN_ERR "Device %s cannot be configured due"
1015 " to a frequency mismatch\n", objname);
1016 break;
1017
1018 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1019 printk(KERN_ERR "Device %s cannot be configured due"
1020 " to a bus mode mismatch\n", objname);
1021 break;
1022
1023 case ACPI_NOTIFY_POWER_FAULT:
1024 printk(KERN_ERR "Device %s has suffered a power fault\n",
1025 objname);
1026 break;
1027
1028 default:
1029 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1030 break;
1031 }
1032}
1033
1034
1035/**
1036 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
1037 *
1038 * @handle: Notify()'ed acpi_handle
1039 * @type: Notify code
1040 * @context: pointer to acpiphp_func structure
1041 *
1042 * handles ACPI event notification on slots
1043 *
1044 */
1045static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
1046{
1047 struct acpiphp_func *func;
1048 char objname[64];
1049 struct acpi_buffer buffer = { .length = sizeof(objname),
1050 .pointer = objname };
1051
1052 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1053
1054 func = (struct acpiphp_func *)context;
1055
1056 switch (type) {
1057 case ACPI_NOTIFY_BUS_CHECK:
1058 /* bus re-enumerate */
1059 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
1060 acpiphp_enable_slot(func->slot);
1061 break;
1062
1063 case ACPI_NOTIFY_DEVICE_CHECK:
1064 /* device check : re-enumerate from parent bus */
1065 dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1066 acpiphp_check_bridge(func->slot->bridge);
1067 break;
1068
1069 case ACPI_NOTIFY_DEVICE_WAKE:
1070 /* wake event */
1071 dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1072 break;
1073
1074 case ACPI_NOTIFY_EJECT_REQUEST:
1075 /* request device eject */
1076 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1077 acpiphp_disable_slot(func->slot);
1078 break;
1079
1080 default:
1081 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1082 break;
1083 }
1084}
1085
1086
1087static struct acpi_pci_driver acpi_pci_hp_driver = {
1088 .add = add_bridge,
1089 .remove = remove_bridge,
1090};
1091
1092/**
1093 * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
1094 *
1095 */
1096int __init acpiphp_glue_init(void)
1097{
1098 int num;
1099
1100 if (list_empty(&pci_root_buses))
1101 return -1;
1102
1103 num = acpi_pci_register_driver(&acpi_pci_hp_driver);
1104
1105 if (num <= 0)
1106 return -1;
1107
1108 return 0;
1109}
1110
1111
1112/**
1113 * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
1114 *
1115 * This function frees all data allocated in acpiphp_glue_init()
1116 */
1117void __exit acpiphp_glue_exit(void)
1118{
1119 struct list_head *l1, *l2, *n1, *n2;
1120 struct acpiphp_bridge *bridge;
1121 struct acpiphp_slot *slot, *next;
1122 struct acpiphp_func *func;
1123 acpi_status status;
1124
1125 list_for_each_safe (l1, n1, &bridge_list) {
1126 bridge = (struct acpiphp_bridge *)l1;
1127 slot = bridge->slots;
1128 while (slot) {
1129 next = slot->next;
1130 list_for_each_safe (l2, n2, &slot->funcs) {
1131 func = list_entry(l2, struct acpiphp_func, sibling);
1132 acpiphp_free_resource(&func->io_head);
1133 acpiphp_free_resource(&func->mem_head);
1134 acpiphp_free_resource(&func->p_mem_head);
1135 acpiphp_free_resource(&func->bus_head);
1136 status = acpi_remove_notify_handler(func->handle,
1137 ACPI_SYSTEM_NOTIFY,
1138 handle_hotplug_event_func);
1139 if (ACPI_FAILURE(status))
1140 err("failed to remove notify handler\n");
1141 kfree(func);
1142 }
1143 kfree(slot);
1144 slot = next;
1145 }
1146 status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1147 handle_hotplug_event_bridge);
1148 if (ACPI_FAILURE(status))
1149 err("failed to remove notify handler\n");
1150
1151 acpiphp_free_resource(&bridge->io_head);
1152 acpiphp_free_resource(&bridge->mem_head);
1153 acpiphp_free_resource(&bridge->p_mem_head);
1154 acpiphp_free_resource(&bridge->bus_head);
1155
1156 kfree(bridge);
1157 }
1158
1159 acpi_pci_unregister_driver(&acpi_pci_hp_driver);
1160}
1161
1162
1163/**
1164 * acpiphp_get_num_slots - count number of slots in a system
1165 */
1166int __init acpiphp_get_num_slots(void)
1167{
1168 struct list_head *node;
1169 struct acpiphp_bridge *bridge;
1170 int num_slots;
1171
1172 num_slots = 0;
1173
1174 list_for_each (node, &bridge_list) {
1175 bridge = (struct acpiphp_bridge *)node;
1176 dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
1177 num_slots += bridge->nr_slots;
1178 }
1179
1180 dbg("Total %dslots\n", num_slots);
1181 return num_slots;
1182}
1183
1184
1185#if 0
1186/**
1187 * acpiphp_for_each_slot - call function for each slot
1188 * @fn: callback function
1189 * @data: context to be passed to callback function
1190 *
1191 */
1192static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
1193{
1194 struct list_head *node;
1195 struct acpiphp_bridge *bridge;
1196 struct acpiphp_slot *slot;
1197 int retval = 0;
1198
1199 list_for_each (node, &bridge_list) {
1200 bridge = (struct acpiphp_bridge *)node;
1201 for (slot = bridge->slots; slot; slot = slot->next) {
1202 retval = fn(slot, data);
1203 if (!retval)
1204 goto err_exit;
1205 }
1206 }
1207
1208 err_exit:
1209 return retval;
1210}
1211#endif
1212
1213/* search matching slot from id */
1214struct acpiphp_slot *get_slot_from_id(int id)
1215{
1216 struct list_head *node;
1217 struct acpiphp_bridge *bridge;
1218 struct acpiphp_slot *slot;
1219
1220 list_for_each (node, &bridge_list) {
1221 bridge = (struct acpiphp_bridge *)node;
1222 for (slot = bridge->slots; slot; slot = slot->next)
1223 if (slot->id == id)
1224 return slot;
1225 }
1226
1227 /* should never happen! */
1228 err("%s: no object for id %d\n", __FUNCTION__, id);
1229 WARN_ON(1);
1230 return NULL;
1231}
1232
1233
1234/**
1235 * acpiphp_enable_slot - power on slot
1236 */
1237int acpiphp_enable_slot(struct acpiphp_slot *slot)
1238{
1239 int retval;
1240
1241 down(&slot->crit_sect);
1242
1243 /* wake up all functions */
1244 retval = power_on_slot(slot);
1245 if (retval)
1246 goto err_exit;
1247
1248 if (get_slot_status(slot) == ACPI_STA_ALL)
1249 /* configure all functions */
1250 retval = enable_device(slot);
1251
1252 err_exit:
1253 up(&slot->crit_sect);
1254 return retval;
1255}
1256
1257
1258/**
1259 * acpiphp_disable_slot - power off slot
1260 */
1261int acpiphp_disable_slot(struct acpiphp_slot *slot)
1262{
1263 int retval = 0;
1264
1265 down(&slot->crit_sect);
1266
1267 /* unconfigure all functions */
1268 retval = disable_device(slot);
1269 if (retval)
1270 goto err_exit;
1271
1272 /* power off all functions */
1273 retval = power_off_slot(slot);
1274 if (retval)
1275 goto err_exit;
1276
1277 acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
1278 acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
1279 acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
1280 acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
1281 dbg("Available resources:\n");
1282 acpiphp_dump_resource(slot->bridge);
1283
1284 err_exit:
1285 up(&slot->crit_sect);
1286 return retval;
1287}
1288
1289
1290/*
1291 * slot enabled: 1
1292 * slot disabled: 0
1293 */
1294u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
1295{
1296 unsigned int sta;
1297
1298 sta = get_slot_status(slot);
1299
1300 return (sta & ACPI_STA_ENABLED) ? 1 : 0;
1301}
1302
1303
1304/*
1305 * latch closed: 1
1306 * latch open: 0
1307 */
1308u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
1309{
1310 unsigned int sta;
1311
1312 sta = get_slot_status(slot);
1313
1314 return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
1315}
1316
1317
1318/*
1319 * adapter presence : 1
1320 * absence : 0
1321 */
1322u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
1323{
1324 unsigned int sta;
1325
1326 sta = get_slot_status(slot);
1327
1328 return (sta == 0) ? 0 : 1;
1329}
1330
1331
1332/*
1333 * pci address (seg/bus/dev)
1334 */
1335u32 acpiphp_get_address(struct acpiphp_slot *slot)
1336{
1337 u32 address;
1338
1339 address = ((slot->bridge->seg) << 16) |
1340 ((slot->bridge->bus) << 8) |
1341 slot->device;
1342
1343 return address;
1344}
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
new file mode 100644
index 000000000000..7e7f913ba7b9
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -0,0 +1,499 @@
1/*
2 * ACPI PCI Hot Plug IBM Extension
3 *
4 * Copyright (C) 2004 Vernon Mauery <vernux@us.ibm.com>
5 * Copyright (C) 2004 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <vernux@us.ibm.com>
25 *
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <acpi/acpi_bus.h>
32#include <linux/sysfs.h>
33#include <linux/kobject.h>
34#include <asm/uaccess.h>
35#include <linux/moduleparam.h>
36
37#include "acpiphp.h"
38#include "pci_hotplug.h"
39
40#define DRIVER_VERSION "1.0.1"
41#define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
42#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver IBM extension"
43
44static int debug;
45
46MODULE_AUTHOR(DRIVER_AUTHOR);
47MODULE_DESCRIPTION(DRIVER_DESC);
48MODULE_LICENSE("GPL");
49MODULE_VERSION(DRIVER_VERSION);
50module_param(debug, bool, 0644);
51MODULE_PARM_DESC(debug, " Debugging mode enabled or not");
52#define MY_NAME "acpiphp_ibm"
53
54#undef dbg
55#define dbg(format, arg...) \
56do { \
57 if (debug) \
58 printk(KERN_DEBUG "%s: " format, \
59 MY_NAME , ## arg); \
60} while (0)
61
62#define FOUND_APCI 0x61504349
63/* these are the names for the IBM ACPI pseudo-device */
64#define IBM_HARDWARE_ID1 "IBM37D0"
65#define IBM_HARDWARE_ID2 "IBM37D4"
66
67#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun)
68
69/* union apci_descriptor - allows access to the
70 * various device descriptors that are embedded in the
71 * aPCI table
72 */
73union apci_descriptor {
74 struct {
75 char sig[4];
76 u8 len;
77 } header;
78 struct {
79 u8 type;
80 u8 len;
81 u16 slot_id;
82 u8 bus_id;
83 u8 dev_num;
84 u8 slot_num;
85 u8 slot_attr[2];
86 u8 attn;
87 u8 status[2];
88 u8 sun;
89 u8 res[3];
90 } slot;
91 struct {
92 u8 type;
93 u8 len;
94 } generic;
95};
96
97/* struct notification - keeps info about the device
98 * that cause the ACPI notification event
99 */
100struct notification {
101 struct acpi_device *device;
102 u8 event;
103};
104
105static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status);
106static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status);
107static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
108static int ibm_get_table_from_acpi(char **bufp);
109static ssize_t ibm_read_apci_table(struct kobject *kobj,
110 char *buffer, loff_t pos, size_t size);
111static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
112 u32 lvl, void *context, void **rv);
113static int __init ibm_acpiphp_init(void);
114static void __exit ibm_acpiphp_exit(void);
115
116static acpi_handle ibm_acpi_handle;
117static struct notification ibm_note;
118static struct bin_attribute ibm_apci_table_attr = {
119 .attr = {
120 .name = "apci_table",
121 .owner = THIS_MODULE,
122 .mode = S_IRUGO,
123 },
124 .read = ibm_read_apci_table,
125 .write = NULL,
126};
127static struct acpiphp_attention_info ibm_attention_info =
128{
129 .set_attn = ibm_set_attention_status,
130 .get_attn = ibm_get_attention_status,
131 .owner = THIS_MODULE,
132};
133
134/**
135 * ibm_slot_from_id - workaround for bad ibm hardware
136 * @id: the slot number that linux refers to the slot by
137 *
138 * Description: this method returns the aCPI slot descriptor
139 * corresponding to the Linux slot number. This descriptor
140 * has info about the aPCI slot id and attention status.
141 * This descriptor must be freed using kfree when done.
142 **/
143static union apci_descriptor *ibm_slot_from_id(int id)
144{
145 int ind = 0, size;
146 union apci_descriptor *ret = NULL, *des;
147 char *table;
148
149 size = ibm_get_table_from_acpi(&table);
150 des = (union apci_descriptor *)table;
151 if (memcmp(des->header.sig, "aPCI", 4) != 0)
152 goto ibm_slot_done;
153
154 des = (union apci_descriptor *)&table[ind += des->header.len];
155 while (ind < size && (des->generic.type != 0x82 ||
156 des->slot.slot_num != id)) {
157 des = (union apci_descriptor *)&table[ind += des->generic.len];
158 }
159
160 if (ind < size && des->slot.slot_num == id)
161 ret = des;
162
163ibm_slot_done:
164 if (ret) {
165 ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
166 memcpy(ret, des, sizeof(union apci_descriptor));
167 }
168 kfree(table);
169 return ret;
170}
171
172/**
173 * ibm_set_attention_status - callback method to set the attention LED
174 * @slot: the hotplug_slot to work with
175 * @status: what to set the LED to (0 or 1)
176 *
177 * Description: this method is registered with the acpiphp module as a
178 * callback to do the device specific task of setting the LED status
179 **/
180static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
181{
182 union acpi_object args[2];
183 struct acpi_object_list params = { .pointer = args, .count = 2 };
184 acpi_status stat;
185 unsigned long rc;
186 union apci_descriptor *ibm_slot;
187
188 ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
189
190 dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__,
191 ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
192 (status ? 1 : 0));
193
194 args[0].type = ACPI_TYPE_INTEGER;
195 args[0].integer.value = ibm_slot->slot.slot_id;
196 args[1].type = ACPI_TYPE_INTEGER;
197 args[1].integer.value = (status) ? 1 : 0;
198
199 kfree(ibm_slot);
200
201 stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", &params, &rc);
202 if (ACPI_FAILURE(stat)) {
203 err("APLS evaluation failed: 0x%08x\n", stat);
204 return -ENODEV;
205 } else if (!rc) {
206 err("APLS method failed: 0x%08lx\n", rc);
207 return -ERANGE;
208 }
209 return 0;
210}
211
212/**
213 * ibm_get_attention_status - callback method to get attention LED status
214 * @slot: the hotplug_slot to work with
215 * @status: returns what the LED is set to (0 or 1)
216 *
217 * Description: this method is registered with the acpiphp module as a
218 * callback to do the device specific task of getting the LED status
219 *
220 * Because there is no direct method of getting the LED status directly
221 * from an ACPI call, we read the aPCI table and parse out our
222 * slot descriptor to read the status from that.
223 **/
224static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
225{
226 union apci_descriptor *ibm_slot;
227
228 ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
229
230 if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
231 *status = 1;
232 else
233 *status = 0;
234
235 dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__,
236 ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
237 *status);
238
239 kfree(ibm_slot);
240 return 0;
241}
242
243/**
244 * ibm_handle_events - listens for ACPI events for the IBM37D0 device
245 * @handle: an ACPI handle to the device that caused the event
246 * @event: the event info (device specific)
247 * @context: passed context (our notification struct)
248 *
249 * Description: this method is registered as a callback with the ACPI
250 * subsystem it is called when this device has an event to notify the OS of
251 *
252 * The events actually come from the device as two events that get
253 * synthesized into one event with data by this function. The event
254 * ID comes first and then the slot number that caused it. We report
255 * this as one event to the OS.
256 *
257 * From section 5.6.2.2 of the ACPI 2.0 spec, I understand that the OSPM will
258 * only re-enable the interrupt that causes this event AFTER this method
259 * has returned, thereby enforcing serial access for the notification struct.
260 **/
261static void ibm_handle_events(acpi_handle handle, u32 event, void *context)
262{
263 u8 detail = event & 0x0f;
264 u8 subevent = event & 0xf0;
265 struct notification *note = context;
266
267 dbg("%s: Received notification %02x\n", __FUNCTION__, event);
268
269 if (subevent == 0x80) {
270 dbg("%s: generationg bus event\n", __FUNCTION__);
271 acpi_bus_generate_event(note->device, note->event, detail);
272 } else
273 note->event = event;
274}
275
276/**
277 * ibm_get_table_from_acpi - reads the APLS buffer from ACPI
278 * @bufp: address to pointer to allocate for the table
279 *
280 * Description: this method reads the APLS buffer in from ACPI and
281 * stores the "stripped" table into a single buffer
282 * it allocates and passes the address back in bufp
283 *
284 * If NULL is passed in as buffer, this method only calculates
285 * the size of the table and returns that without filling
286 * in the buffer
287 *
288 * returns < 0 on error or the size of the table on success
289 **/
290static int ibm_get_table_from_acpi(char **bufp)
291{
292 union acpi_object *package;
293 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
294 acpi_status status;
295 char *lbuf = NULL;
296 int i, size = -EIO;
297
298 status = acpi_evaluate_object(ibm_acpi_handle, "APCI", NULL, &buffer);
299 if (ACPI_FAILURE(status)) {
300 err("%s: APCI evaluation failed\n", __FUNCTION__);
301 return -ENODEV;
302 }
303
304 package = (union acpi_object *) buffer.pointer;
305 if(!(package) ||
306 (package->type != ACPI_TYPE_PACKAGE) ||
307 !(package->package.elements)) {
308 err("%s: Invalid APCI object\n", __FUNCTION__);
309 goto read_table_done;
310 }
311
312 for(size = 0, i = 0; i < package->package.count; i++) {
313 if (package->package.elements[i].type != ACPI_TYPE_BUFFER) {
314 err("%s: Invalid APCI element %d\n", __FUNCTION__, i);
315 goto read_table_done;
316 }
317 size += package->package.elements[i].buffer.length;
318 }
319
320 if (bufp == NULL)
321 goto read_table_done;
322
323 lbuf = kmalloc(size, GFP_KERNEL);
324 dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n",
325 __FUNCTION__, package->package.count, size, lbuf);
326
327 if (lbuf) {
328 *bufp = lbuf;
329 memset(lbuf, 0, size);
330 } else {
331 size = -ENOMEM;
332 goto read_table_done;
333 }
334
335 size = 0;
336 for (i=0; i<package->package.count; i++) {
337 memcpy(&lbuf[size],
338 package->package.elements[i].buffer.pointer,
339 package->package.elements[i].buffer.length);
340 size += package->package.elements[i].buffer.length;
341 }
342
343read_table_done:
344 kfree(buffer.pointer);
345 return size;
346}
347
348/**
349 * ibm_read_apci_table - callback for the sysfs apci_table file
350 * @kobj: the kobject this binary attribute is a part of
351 * @buffer: the kernel space buffer to fill
352 * @pos: the offset into the file
353 * @size: the number of bytes requested
354 *
355 * Description: gets registered with sysfs as the reader callback
356 * to be executed when /sys/bus/pci/slots/apci_table gets read
357 *
358 * Since we don't get notified on open and close for this file,
359 * things get really tricky here...
360 * our solution is to only allow reading the table in all at once
361 **/
362static ssize_t ibm_read_apci_table(struct kobject *kobj,
363 char *buffer, loff_t pos, size_t size)
364{
365 int bytes_read = -EINVAL;
366 char *table = NULL;
367
368 dbg("%s: pos = %d, size = %zd\n", __FUNCTION__, (int)pos, size);
369
370 if (pos == 0) {
371 bytes_read = ibm_get_table_from_acpi(&table);
372 if (bytes_read > 0 && bytes_read <= size)
373 memcpy(buffer, table, bytes_read);
374 kfree(table);
375 }
376 return bytes_read;
377}
378
379/**
380 * ibm_find_acpi_device - callback to find our ACPI device
381 * @handle: the ACPI handle of the device we are inspecting
382 * @lvl: depth into the namespace tree
383 * @context: a pointer to our handle to fill when we find the device
384 * @rv: a return value to fill if desired
385 *
386 * Description: used as a callback when calling acpi_walk_namespace
387 * to find our device. When this method returns non-zero
388 * acpi_walk_namespace quits its search and returns our value
389 **/
390static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
391 u32 lvl, void *context, void **rv)
392{
393 acpi_handle *phandle = (acpi_handle *)context;
394 acpi_status status;
395 struct acpi_device_info info;
396 struct acpi_buffer info_buffer = {
397 .length = sizeof(struct acpi_device_info),
398 .pointer = &info,
399 };
400
401 status = acpi_get_object_info(handle, &info_buffer);
402 if (ACPI_FAILURE(status)) {
403 err("%s: Failed to get device information", __FUNCTION__);
404 return 0;
405 }
406 info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0';
407
408 if(info.current_status && (info.valid & ACPI_VALID_HID) &&
409 (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) ||
410 !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) {
411 dbg("found hardware: %s, handle: %p\n", info.hardware_id.value,
412 handle);
413 *phandle = handle;
414 /* returning non-zero causes the search to stop
415 * and returns this value to the caller of
416 * acpi_walk_namespace, but it also causes some warnings
417 * in the acpi debug code to print...
418 */
419 return FOUND_APCI;
420 }
421 return 0;
422}
423
424static int __init ibm_acpiphp_init(void)
425{
426 int retval = 0;
427 acpi_status status;
428 struct acpi_device *device;
429 struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj;
430
431 dbg("%s\n", __FUNCTION__);
432
433 if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
434 ACPI_UINT32_MAX, ibm_find_acpi_device,
435 &ibm_acpi_handle, NULL) != FOUND_APCI) {
436 err("%s: acpi_walk_namespace failed\n", __FUNCTION__);
437 retval = -ENODEV;
438 goto init_return;
439 }
440 dbg("%s: found IBM aPCI device\n", __FUNCTION__);
441 if (acpi_bus_get_device(ibm_acpi_handle, &device)) {
442 err("%s: acpi_bus_get_device failed\n", __FUNCTION__);
443 retval = -ENODEV;
444 goto init_return;
445 }
446 if (acpiphp_register_attention(&ibm_attention_info)) {
447 retval = -ENODEV;
448 goto init_return;
449 }
450
451 ibm_note.device = device;
452 status = acpi_install_notify_handler(
453 ibm_acpi_handle,
454 ACPI_DEVICE_NOTIFY,
455 ibm_handle_events,
456 &ibm_note);
457 if (ACPI_FAILURE(status)) {
458 err("%s: Failed to register notification handler\n",
459 __FUNCTION__);
460 retval = -EBUSY;
461 goto init_cleanup;
462 }
463
464 ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL);
465 retval = sysfs_create_bin_file(sysdir, &ibm_apci_table_attr);
466
467 return retval;
468
469init_cleanup:
470 acpiphp_unregister_attention(&ibm_attention_info);
471init_return:
472 return retval;
473}
474
475static void __exit ibm_acpiphp_exit(void)
476{
477 acpi_status status;
478 struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj;
479
480 dbg("%s\n", __FUNCTION__);
481
482 if (acpiphp_unregister_attention(&ibm_attention_info))
483 err("%s: attention info deregistration failed", __FUNCTION__);
484
485 status = acpi_remove_notify_handler(
486 ibm_acpi_handle,
487 ACPI_DEVICE_NOTIFY,
488 ibm_handle_events);
489 if (ACPI_FAILURE(status))
490 err("%s: Notification handler removal failed\n",
491 __FUNCTION__);
492 // remove the /sys entries
493 if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr))
494 err("%s: removal of sysfs file apci_table failed\n",
495 __FUNCTION__);
496}
497
498module_init(ibm_acpiphp_init);
499module_exit(ibm_acpiphp_exit);
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
new file mode 100644
index 000000000000..54d97c9d1dff
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_pci.c
@@ -0,0 +1,449 @@
1/*
2 * ACPI PCI HotPlug PCI configuration space management
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001,2002 IBM Corp.
7 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
8 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/pci.h>
37#include <linux/acpi.h>
38#include "../pci.h"
39#include "pci_hotplug.h"
40#include "acpiphp.h"
41
42#define MY_NAME "acpiphp_pci"
43
44
45/* allocate mem/pmem/io resource to a new function */
46static int init_config_space (struct acpiphp_func *func)
47{
48 u32 bar, len;
49 u32 address[] = {
50 PCI_BASE_ADDRESS_0,
51 PCI_BASE_ADDRESS_1,
52 PCI_BASE_ADDRESS_2,
53 PCI_BASE_ADDRESS_3,
54 PCI_BASE_ADDRESS_4,
55 PCI_BASE_ADDRESS_5,
56 0
57 };
58 int count;
59 struct acpiphp_bridge *bridge;
60 struct pci_resource *res;
61 struct pci_bus *pbus;
62 int bus, device, function;
63 unsigned int devfn;
64 u16 tmp;
65
66 bridge = func->slot->bridge;
67 pbus = bridge->pci_bus;
68 bus = bridge->bus;
69 device = func->slot->device;
70 function = func->function;
71 devfn = PCI_DEVFN(device, function);
72
73 for (count = 0; address[count]; count++) { /* for 6 BARs */
74 pci_bus_write_config_dword(pbus, devfn,
75 address[count], 0xFFFFFFFF);
76 pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
77
78 if (!bar) /* This BAR is not implemented */
79 continue;
80
81 dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
82
83 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
84 /* This is IO */
85
86 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
87 len = len & ~(len - 1);
88
89 dbg("len in IO %x, BAR %d\n", len, count);
90
91 spin_lock(&bridge->res_lock);
92 res = acpiphp_get_io_resource(&bridge->io_head, len);
93 spin_unlock(&bridge->res_lock);
94
95 if (!res) {
96 err("cannot allocate requested io for %02x:%02x.%d len %x\n",
97 bus, device, function, len);
98 return -1;
99 }
100 pci_bus_write_config_dword(pbus, devfn,
101 address[count],
102 (u32)res->base);
103 res->next = func->io_head;
104 func->io_head = res;
105
106 } else {
107 /* This is Memory */
108 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
109 /* pfmem */
110
111 len = bar & 0xFFFFFFF0;
112 len = ~len + 1;
113
114 dbg("len in PFMEM %x, BAR %d\n", len, count);
115
116 spin_lock(&bridge->res_lock);
117 res = acpiphp_get_resource(&bridge->p_mem_head, len);
118 spin_unlock(&bridge->res_lock);
119
120 if (!res) {
121 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
122 bus, device, function, len);
123 return -1;
124 }
125
126 pci_bus_write_config_dword(pbus, devfn,
127 address[count],
128 (u32)res->base);
129
130 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
131 dbg("inside the pfmem 64 case, count %d\n", count);
132 count += 1;
133 pci_bus_write_config_dword(pbus, devfn,
134 address[count],
135 (u32)(res->base >> 32));
136 }
137
138 res->next = func->p_mem_head;
139 func->p_mem_head = res;
140
141 } else {
142 /* regular memory */
143
144 len = bar & 0xFFFFFFF0;
145 len = ~len + 1;
146
147 dbg("len in MEM %x, BAR %d\n", len, count);
148
149 spin_lock(&bridge->res_lock);
150 res = acpiphp_get_resource(&bridge->mem_head, len);
151 spin_unlock(&bridge->res_lock);
152
153 if (!res) {
154 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
155 bus, device, function, len);
156 return -1;
157 }
158
159 pci_bus_write_config_dword(pbus, devfn,
160 address[count],
161 (u32)res->base);
162
163 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
164 /* takes up another dword */
165 dbg("inside mem 64 case, reg. mem, count %d\n", count);
166 count += 1;
167 pci_bus_write_config_dword(pbus, devfn,
168 address[count],
169 (u32)(res->base >> 32));
170 }
171
172 res->next = func->mem_head;
173 func->mem_head = res;
174
175 }
176 }
177 }
178
179 /* disable expansion rom */
180 pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
181
182 /* set PCI parameters from _HPP */
183 pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
184 bridge->hpp.cache_line_size);
185 pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
186 bridge->hpp.latency_timer);
187
188 pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
189 if (bridge->hpp.enable_SERR)
190 tmp |= PCI_COMMAND_SERR;
191 if (bridge->hpp.enable_PERR)
192 tmp |= PCI_COMMAND_PARITY;
193 pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
194
195 return 0;
196}
197
198/* detect_used_resource - subtract resource under dev from bridge */
199static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
200{
201 int count;
202
203 dbg("Device %s\n", pci_name(dev));
204
205 for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
206 struct pci_resource *res;
207 struct pci_resource **head;
208 unsigned long base = dev->resource[count].start;
209 unsigned long len = dev->resource[count].end - base + 1;
210 unsigned long flags = dev->resource[count].flags;
211
212 if (!flags)
213 continue;
214
215 dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
216 base + len - 1, flags);
217
218 if (flags & IORESOURCE_IO) {
219 head = &bridge->io_head;
220 } else if (flags & IORESOURCE_PREFETCH) {
221 head = &bridge->p_mem_head;
222 } else {
223 head = &bridge->mem_head;
224 }
225
226 spin_lock(&bridge->res_lock);
227 res = acpiphp_get_resource_with_base(head, base, len);
228 spin_unlock(&bridge->res_lock);
229 if (res)
230 kfree(res);
231 }
232
233 return 0;
234}
235
236
237/**
238 * acpiphp_detect_pci_resource - detect resources under bridge
239 * @bridge: detect all resources already used under this bridge
240 *
241 * collect all resources already allocated for all devices under a bridge.
242 */
243int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
244{
245 struct list_head *l;
246 struct pci_dev *dev;
247
248 list_for_each (l, &bridge->pci_bus->devices) {
249 dev = pci_dev_b(l);
250 detect_used_resource(bridge, dev);
251 }
252
253 return 0;
254}
255
256
257/**
258 * acpiphp_init_slot_resource - gather resource usage information of a slot
259 * @slot: ACPI slot object to be checked, should have valid pci_dev member
260 *
261 * TBD: PCI-to-PCI bridge case
262 * use pci_dev->resource[]
263 */
264int acpiphp_init_func_resource (struct acpiphp_func *func)
265{
266 u64 base;
267 u32 bar, len;
268 u32 address[] = {
269 PCI_BASE_ADDRESS_0,
270 PCI_BASE_ADDRESS_1,
271 PCI_BASE_ADDRESS_2,
272 PCI_BASE_ADDRESS_3,
273 PCI_BASE_ADDRESS_4,
274 PCI_BASE_ADDRESS_5,
275 0
276 };
277 int count;
278 struct pci_resource *res;
279 struct pci_dev *dev;
280
281 dev = func->pci_dev;
282 dbg("Hot-pluggable device %s\n", pci_name(dev));
283
284 for (count = 0; address[count]; count++) { /* for 6 BARs */
285 pci_read_config_dword(dev, address[count], &bar);
286
287 if (!bar) /* This BAR is not implemented */
288 continue;
289
290 pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
291 pci_read_config_dword(dev, address[count], &len);
292
293 if (len & PCI_BASE_ADDRESS_SPACE_IO) {
294 /* This is IO */
295 base = bar & 0xFFFFFFFC;
296 len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
297 len = len & ~(len - 1);
298
299 dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
300
301 res = acpiphp_make_resource(base, len);
302 if (!res)
303 goto no_memory;
304
305 res->next = func->io_head;
306 func->io_head = res;
307
308 } else {
309 /* This is Memory */
310 base = bar & 0xFFFFFFF0;
311 if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
312 /* pfmem */
313
314 len &= 0xFFFFFFF0;
315 len = ~len + 1;
316
317 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
318 dbg("prefetch mem 64\n");
319 count += 1;
320 }
321 dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
322 res = acpiphp_make_resource(base, len);
323 if (!res)
324 goto no_memory;
325
326 res->next = func->p_mem_head;
327 func->p_mem_head = res;
328
329 } else {
330 /* regular memory */
331
332 len &= 0xFFFFFFF0;
333 len = ~len + 1;
334
335 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
336 /* takes up another dword */
337 dbg("mem 64\n");
338 count += 1;
339 }
340 dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
341 res = acpiphp_make_resource(base, len);
342 if (!res)
343 goto no_memory;
344
345 res->next = func->mem_head;
346 func->mem_head = res;
347
348 }
349 }
350
351 pci_write_config_dword(dev, address[count], bar);
352 }
353#if 1
354 acpiphp_dump_func_resource(func);
355#endif
356
357 return 0;
358
359 no_memory:
360 err("out of memory\n");
361 acpiphp_free_resource(&func->io_head);
362 acpiphp_free_resource(&func->mem_head);
363 acpiphp_free_resource(&func->p_mem_head);
364
365 return -1;
366}
367
368
369/**
370 * acpiphp_configure_slot - allocate PCI resources
371 * @slot: slot to be configured
372 *
373 * initializes a PCI functions on a device inserted
374 * into the slot
375 *
376 */
377int acpiphp_configure_slot (struct acpiphp_slot *slot)
378{
379 struct acpiphp_func *func;
380 struct list_head *l;
381 u8 hdr;
382 u32 dvid;
383 int retval = 0;
384 int is_multi = 0;
385
386 pci_bus_read_config_byte(slot->bridge->pci_bus,
387 PCI_DEVFN(slot->device, 0),
388 PCI_HEADER_TYPE, &hdr);
389
390 if (hdr & 0x80)
391 is_multi = 1;
392
393 list_for_each (l, &slot->funcs) {
394 func = list_entry(l, struct acpiphp_func, sibling);
395 if (is_multi || func->function == 0) {
396 pci_bus_read_config_dword(slot->bridge->pci_bus,
397 PCI_DEVFN(slot->device,
398 func->function),
399 PCI_VENDOR_ID, &dvid);
400 if (dvid != 0xffffffff) {
401 retval = init_config_space(func);
402 if (retval)
403 break;
404 }
405 }
406 }
407
408 return retval;
409}
410
411/**
412 * acpiphp_configure_function - configure PCI function
413 * @func: function to be configured
414 *
415 * initializes a PCI functions on a device inserted
416 * into the slot
417 *
418 */
419int acpiphp_configure_function (struct acpiphp_func *func)
420{
421 /* all handled by the pci core now */
422 return 0;
423}
424
425/**
426 * acpiphp_unconfigure_function - unconfigure PCI function
427 * @func: function to be unconfigured
428 *
429 */
430void acpiphp_unconfigure_function (struct acpiphp_func *func)
431{
432 struct acpiphp_bridge *bridge;
433
434 /* if pci_dev is NULL, ignore it */
435 if (!func->pci_dev)
436 return;
437
438 pci_remove_bus_device(func->pci_dev);
439
440 /* free all resources */
441 bridge = func->slot->bridge;
442
443 spin_lock(&bridge->res_lock);
444 acpiphp_move_resource(&func->io_head, &bridge->io_head);
445 acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
446 acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
447 acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
448 spin_unlock(&bridge->res_lock);
449}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
new file mode 100644
index 000000000000..f54b1fa7b75a
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_res.c
@@ -0,0 +1,700 @@
1/*
2 * ACPI PCI HotPlug Utility functions
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) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/sysctl.h>
39#include <linux/pci.h>
40#include <linux/smp.h>
41#include <linux/smp_lock.h>
42
43#include <linux/string.h>
44#include <linux/mm.h>
45#include <linux/errno.h>
46#include <linux/ioport.h>
47#include <linux/slab.h>
48#include <linux/interrupt.h>
49#include <linux/timer.h>
50
51#include <linux/ioctl.h>
52#include <linux/fcntl.h>
53
54#include <linux/list.h>
55
56#include "pci_hotplug.h"
57#include "acpiphp.h"
58
59#define MY_NAME "acpiphp_res"
60
61
62/*
63 * sort_by_size - sort nodes by their length, smallest first
64 */
65static int sort_by_size(struct pci_resource **head)
66{
67 struct pci_resource *current_res;
68 struct pci_resource *next_res;
69 int out_of_order = 1;
70
71 if (!(*head))
72 return 1;
73
74 if (!((*head)->next))
75 return 0;
76
77 while (out_of_order) {
78 out_of_order = 0;
79
80 /* Special case for swapping list head */
81 if (((*head)->next) &&
82 ((*head)->length > (*head)->next->length)) {
83 out_of_order++;
84 current_res = *head;
85 *head = (*head)->next;
86 current_res->next = (*head)->next;
87 (*head)->next = current_res;
88 }
89
90 current_res = *head;
91
92 while (current_res->next && current_res->next->next) {
93 if (current_res->next->length > current_res->next->next->length) {
94 out_of_order++;
95 next_res = current_res->next;
96 current_res->next = current_res->next->next;
97 current_res = current_res->next;
98 next_res->next = current_res->next;
99 current_res->next = next_res;
100 } else
101 current_res = current_res->next;
102 }
103 } /* End of out_of_order loop */
104
105 return 0;
106}
107
108#if 0
109/*
110 * sort_by_max_size - sort nodes by their length, largest first
111 */
112static int sort_by_max_size(struct pci_resource **head)
113{
114 struct pci_resource *current_res;
115 struct pci_resource *next_res;
116 int out_of_order = 1;
117
118 if (!(*head))
119 return 1;
120
121 if (!((*head)->next))
122 return 0;
123
124 while (out_of_order) {
125 out_of_order = 0;
126
127 /* Special case for swapping list head */
128 if (((*head)->next) &&
129 ((*head)->length < (*head)->next->length)) {
130 out_of_order++;
131 current_res = *head;
132 *head = (*head)->next;
133 current_res->next = (*head)->next;
134 (*head)->next = current_res;
135 }
136
137 current_res = *head;
138
139 while (current_res->next && current_res->next->next) {
140 if (current_res->next->length < current_res->next->next->length) {
141 out_of_order++;
142 next_res = current_res->next;
143 current_res->next = current_res->next->next;
144 current_res = current_res->next;
145 next_res->next = current_res->next;
146 current_res->next = next_res;
147 } else
148 current_res = current_res->next;
149 }
150 } /* End of out_of_order loop */
151
152 return 0;
153}
154#endif
155
156/**
157 * get_io_resource - get resource for I/O ports
158 *
159 * this function sorts the resource list by size and then
160 * returns the first node of "size" length that is not in the
161 * ISA aliasing window. If it finds a node larger than "size"
162 * it will split it up.
163 *
164 * size must be a power of two.
165 *
166 * difference from get_resource is handling of ISA aliasing space.
167 *
168 */
169struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
170{
171 struct pci_resource *prevnode;
172 struct pci_resource *node;
173 struct pci_resource *split_node;
174 u64 temp_qword;
175
176 if (!(*head))
177 return NULL;
178
179 if (acpiphp_resource_sort_and_combine(head))
180 return NULL;
181
182 if (sort_by_size(head))
183 return NULL;
184
185 for (node = *head; node; node = node->next) {
186 if (node->length < size)
187 continue;
188
189 if (node->base & (size - 1)) {
190 /* this one isn't base aligned properly
191 so we'll make a new entry and split it up */
192 temp_qword = (node->base | (size-1)) + 1;
193
194 /* Short circuit if adjusted size is too small */
195 if ((node->length - (temp_qword - node->base)) < size)
196 continue;
197
198 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
199
200 if (!split_node)
201 return NULL;
202
203 node->base = temp_qword;
204 node->length -= split_node->length;
205
206 /* Put it in the list */
207 split_node->next = node->next;
208 node->next = split_node;
209 } /* End of non-aligned base */
210
211 /* Don't need to check if too small since we already did */
212 if (node->length > size) {
213 /* this one is longer than we need
214 so we'll make a new entry and split it up */
215 split_node = acpiphp_make_resource(node->base + size, node->length - size);
216
217 if (!split_node)
218 return NULL;
219
220 node->length = size;
221
222 /* Put it in the list */
223 split_node->next = node->next;
224 node->next = split_node;
225 } /* End of too big on top end */
226
227 /* For IO make sure it's not in the ISA aliasing space */
228 if ((node->base & 0x300L) && !(node->base & 0xfffff000))
229 continue;
230
231 /* If we got here, then it is the right size
232 Now take it out of the list */
233 if (*head == node) {
234 *head = node->next;
235 } else {
236 prevnode = *head;
237 while (prevnode->next != node)
238 prevnode = prevnode->next;
239
240 prevnode->next = node->next;
241 }
242 node->next = NULL;
243 /* Stop looping */
244 break;
245 }
246
247 return node;
248}
249
250
251#if 0
252/**
253 * get_max_resource - get the largest resource
254 *
255 * Gets the largest node that is at least "size" big from the
256 * list pointed to by head. It aligns the node on top and bottom
257 * to "size" alignment before returning it.
258 */
259static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
260{
261 struct pci_resource *max;
262 struct pci_resource *temp;
263 struct pci_resource *split_node;
264 u64 temp_qword;
265
266 if (!(*head))
267 return NULL;
268
269 if (acpiphp_resource_sort_and_combine(head))
270 return NULL;
271
272 if (sort_by_max_size(head))
273 return NULL;
274
275 for (max = *head;max; max = max->next) {
276
277 /* If not big enough we could probably just bail,
278 instead we'll continue to the next. */
279 if (max->length < size)
280 continue;
281
282 if (max->base & (size - 1)) {
283 /* this one isn't base aligned properly
284 so we'll make a new entry and split it up */
285 temp_qword = (max->base | (size-1)) + 1;
286
287 /* Short circuit if adjusted size is too small */
288 if ((max->length - (temp_qword - max->base)) < size)
289 continue;
290
291 split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
292
293 if (!split_node)
294 return NULL;
295
296 max->base = temp_qword;
297 max->length -= split_node->length;
298
299 /* Put it next in the list */
300 split_node->next = max->next;
301 max->next = split_node;
302 }
303
304 if ((max->base + max->length) & (size - 1)) {
305 /* this one isn't end aligned properly at the top
306 so we'll make a new entry and split it up */
307 temp_qword = ((max->base + max->length) & ~(size - 1));
308
309 split_node = acpiphp_make_resource(temp_qword,
310 max->length + max->base - temp_qword);
311
312 if (!split_node)
313 return NULL;
314
315 max->length -= split_node->length;
316
317 /* Put it in the list */
318 split_node->next = max->next;
319 max->next = split_node;
320 }
321
322 /* Make sure it didn't shrink too much when we aligned it */
323 if (max->length < size)
324 continue;
325
326 /* Now take it out of the list */
327 temp = (struct pci_resource*) *head;
328 if (temp == max) {
329 *head = max->next;
330 } else {
331 while (temp && temp->next != max) {
332 temp = temp->next;
333 }
334
335 temp->next = max->next;
336 }
337
338 max->next = NULL;
339 return max;
340 }
341
342 /* If we get here, we couldn't find one */
343 return NULL;
344}
345#endif
346
347/**
348 * get_resource - get resource (mem, pfmem)
349 *
350 * this function sorts the resource list by size and then
351 * returns the first node of "size" length. If it finds a node
352 * larger than "size" it will split it up.
353 *
354 * size must be a power of two.
355 *
356 */
357struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
358{
359 struct pci_resource *prevnode;
360 struct pci_resource *node;
361 struct pci_resource *split_node;
362 u64 temp_qword;
363
364 if (!(*head))
365 return NULL;
366
367 if (acpiphp_resource_sort_and_combine(head))
368 return NULL;
369
370 if (sort_by_size(head))
371 return NULL;
372
373 for (node = *head; node; node = node->next) {
374 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
375 __FUNCTION__, size, node, (u32)node->base, node->length);
376 if (node->length < size)
377 continue;
378
379 if (node->base & (size - 1)) {
380 dbg("%s: not aligned\n", __FUNCTION__);
381 /* this one isn't base aligned properly
382 so we'll make a new entry and split it up */
383 temp_qword = (node->base | (size-1)) + 1;
384
385 /* Short circuit if adjusted size is too small */
386 if ((node->length - (temp_qword - node->base)) < size)
387 continue;
388
389 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
390
391 if (!split_node)
392 return NULL;
393
394 node->base = temp_qword;
395 node->length -= split_node->length;
396
397 /* Put it in the list */
398 split_node->next = node->next;
399 node->next = split_node;
400 } /* End of non-aligned base */
401
402 /* Don't need to check if too small since we already did */
403 if (node->length > size) {
404 dbg("%s: too big\n", __FUNCTION__);
405 /* this one is longer than we need
406 so we'll make a new entry and split it up */
407 split_node = acpiphp_make_resource(node->base + size, node->length - size);
408
409 if (!split_node)
410 return NULL;
411
412 node->length = size;
413
414 /* Put it in the list */
415 split_node->next = node->next;
416 node->next = split_node;
417 } /* End of too big on top end */
418
419 dbg("%s: got one!!!\n", __FUNCTION__);
420 /* If we got here, then it is the right size
421 Now take it out of the list */
422 if (*head == node) {
423 *head = node->next;
424 } else {
425 prevnode = *head;
426 while (prevnode->next != node)
427 prevnode = prevnode->next;
428
429 prevnode->next = node->next;
430 }
431 node->next = NULL;
432 /* Stop looping */
433 break;
434 }
435 return node;
436}
437
438/**
439 * get_resource_with_base - get resource with specific base address
440 *
441 * this function
442 * returns the first node of "size" length located at specified base address.
443 * If it finds a node larger than "size" it will split it up.
444 *
445 * size must be a power of two.
446 *
447 */
448struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
449{
450 struct pci_resource *prevnode;
451 struct pci_resource *node;
452 struct pci_resource *split_node;
453 u64 temp_qword;
454
455 if (!(*head))
456 return NULL;
457
458 if (acpiphp_resource_sort_and_combine(head))
459 return NULL;
460
461 for (node = *head; node; node = node->next) {
462 dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
463 (u32)base, size, node, (u32)node->base, node->length);
464 if (node->base > base)
465 continue;
466
467 if ((node->base + node->length) < (base + size))
468 continue;
469
470 if (node->base < base) {
471 dbg(": split 1\n");
472 /* this one isn't base aligned properly
473 so we'll make a new entry and split it up */
474 temp_qword = base;
475
476 /* Short circuit if adjusted size is too small */
477 if ((node->length - (temp_qword - node->base)) < size)
478 continue;
479
480 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
481
482 if (!split_node)
483 return NULL;
484
485 node->base = temp_qword;
486 node->length -= split_node->length;
487
488 /* Put it in the list */
489 split_node->next = node->next;
490 node->next = split_node;
491 }
492
493 dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
494 (u32)base, size, node, (u32)node->base, node->length);
495
496 /* Don't need to check if too small since we already did */
497 if (node->length > size) {
498 dbg(": split 2\n");
499 /* this one is longer than we need
500 so we'll make a new entry and split it up */
501 split_node = acpiphp_make_resource(node->base + size, node->length - size);
502
503 if (!split_node)
504 return NULL;
505
506 node->length = size;
507
508 /* Put it in the list */
509 split_node->next = node->next;
510 node->next = split_node;
511 } /* End of too big on top end */
512
513 dbg(": got one!!!\n");
514 /* If we got here, then it is the right size
515 Now take it out of the list */
516 if (*head == node) {
517 *head = node->next;
518 } else {
519 prevnode = *head;
520 while (prevnode->next != node)
521 prevnode = prevnode->next;
522
523 prevnode->next = node->next;
524 }
525 node->next = NULL;
526 /* Stop looping */
527 break;
528 }
529 return node;
530}
531
532
533/**
534 * acpiphp_resource_sort_and_combine
535 *
536 * Sorts all of the nodes in the list in ascending order by
537 * their base addresses. Also does garbage collection by
538 * combining adjacent nodes.
539 *
540 * returns 0 if success
541 */
542int acpiphp_resource_sort_and_combine (struct pci_resource **head)
543{
544 struct pci_resource *node1;
545 struct pci_resource *node2;
546 int out_of_order = 1;
547
548 if (!(*head))
549 return 1;
550
551 dbg("*head->next = %p\n",(*head)->next);
552
553 if (!(*head)->next)
554 return 0; /* only one item on the list, already sorted! */
555
556 dbg("*head->base = 0x%x\n",(u32)(*head)->base);
557 dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
558 while (out_of_order) {
559 out_of_order = 0;
560
561 /* Special case for swapping list head */
562 if (((*head)->next) &&
563 ((*head)->base > (*head)->next->base)) {
564 node1 = *head;
565 (*head) = (*head)->next;
566 node1->next = (*head)->next;
567 (*head)->next = node1;
568 out_of_order++;
569 }
570
571 node1 = (*head);
572
573 while (node1->next && node1->next->next) {
574 if (node1->next->base > node1->next->next->base) {
575 out_of_order++;
576 node2 = node1->next;
577 node1->next = node1->next->next;
578 node1 = node1->next;
579 node2->next = node1->next;
580 node1->next = node2;
581 } else
582 node1 = node1->next;
583 }
584 } /* End of out_of_order loop */
585
586 node1 = *head;
587
588 while (node1 && node1->next) {
589 if ((node1->base + node1->length) == node1->next->base) {
590 /* Combine */
591 dbg("8..\n");
592 node1->length += node1->next->length;
593 node2 = node1->next;
594 node1->next = node1->next->next;
595 kfree(node2);
596 } else
597 node1 = node1->next;
598 }
599
600 return 0;
601}
602
603
604/**
605 * acpiphp_make_resource - make resource structure
606 * @base: base address of a resource
607 * @length: length of a resource
608 */
609struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
610{
611 struct pci_resource *res;
612
613 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
614 if (res) {
615 memset(res, 0, sizeof(struct pci_resource));
616 res->base = base;
617 res->length = length;
618 }
619
620 return res;
621}
622
623
624/**
625 * acpiphp_move_resource - move linked resources from one to another
626 * @from: head of linked resource list
627 * @to: head of linked resource list
628 */
629void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
630{
631 struct pci_resource *tmp;
632
633 while (*from) {
634 tmp = (*from)->next;
635 (*from)->next = *to;
636 *to = *from;
637 *from = tmp;
638 }
639
640 /* *from = NULL is guaranteed */
641}
642
643
644/**
645 * acpiphp_free_resource - free all linked resources
646 * @res: head of linked resource list
647 */
648void acpiphp_free_resource (struct pci_resource **res)
649{
650 struct pci_resource *tmp;
651
652 while (*res) {
653 tmp = (*res)->next;
654 kfree(*res);
655 *res = tmp;
656 }
657
658 /* *res = NULL is guaranteed */
659}
660
661
662/* debug support functions; will go away sometime :) */
663static void dump_resource(struct pci_resource *head)
664{
665 struct pci_resource *p;
666 int cnt;
667
668 p = head;
669 cnt = 0;
670
671 while (p) {
672 dbg("[%02d] %08x - %08x\n",
673 cnt++, (u32)p->base, (u32)p->base + p->length - 1);
674 p = p->next;
675 }
676}
677
678void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
679{
680 dbg("I/O resource:\n");
681 dump_resource(bridge->io_head);
682 dbg("MEM resource:\n");
683 dump_resource(bridge->mem_head);
684 dbg("PMEM resource:\n");
685 dump_resource(bridge->p_mem_head);
686 dbg("BUS resource:\n");
687 dump_resource(bridge->bus_head);
688}
689
690void acpiphp_dump_func_resource(struct acpiphp_func *func)
691{
692 dbg("I/O resource:\n");
693 dump_resource(func->io_head);
694 dbg("MEM resource:\n");
695 dump_resource(func->mem_head);
696 dbg("PMEM resource:\n");
697 dump_resource(func->p_mem_head);
698 dbg("BUS resource:\n");
699 dump_resource(func->bus_head);
700}
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
new file mode 100644
index 000000000000..3ddd75937a40
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -0,0 +1,96 @@
1/*
2 * CompactPCI Hot Plug Core Functions
3 *
4 * Copyright (C) 2002 SOMA Networks, Inc.
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <scottm@somanetworks.com>
26 */
27
28#ifndef _CPCI_HOTPLUG_H
29#define _CPCI_HOTPLUG_H
30
31#include <linux/types.h>
32#include <linux/pci.h>
33
34/* PICMG 2.12 R2.0 HS CSR bits: */
35#define HS_CSR_INS 0x0080
36#define HS_CSR_EXT 0x0040
37#define HS_CSR_PI 0x0030
38#define HS_CSR_LOO 0x0008
39#define HS_CSR_PIE 0x0004
40#define HS_CSR_EIM 0x0002
41#define HS_CSR_DHA 0x0001
42
43struct slot {
44 u8 number;
45 unsigned int devfn;
46 struct pci_bus *bus;
47 struct pci_dev *dev;
48 unsigned int extracting;
49 struct hotplug_slot *hotplug_slot;
50 struct list_head slot_list;
51};
52
53struct cpci_hp_controller_ops {
54 int (*query_enum) (void);
55 int (*enable_irq) (void);
56 int (*disable_irq) (void);
57 int (*check_irq) (void *dev_id);
58 int (*hardware_test) (struct slot* slot, u32 value);
59 u8 (*get_power) (struct slot* slot);
60 int (*set_power) (struct slot* slot, int value);
61};
62
63struct cpci_hp_controller {
64 unsigned int irq;
65 unsigned long irq_flags;
66 char *devname;
67 void *dev_id;
68 char *name;
69 struct cpci_hp_controller_ops *ops;
70};
71
72extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
73extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
74extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
75extern int cpci_hp_unregister_bus(struct pci_bus *bus);
76extern int cpci_hp_start(void);
77extern int cpci_hp_stop(void);
78
79/*
80 * Internal function prototypes, these functions should not be used by
81 * board/chassis drivers.
82 */
83extern u8 cpci_get_attention_status(struct slot *slot);
84extern u8 cpci_get_latch_status(struct slot *slot);
85extern u8 cpci_get_adapter_status(struct slot *slot);
86extern u16 cpci_get_hs_csr(struct slot * slot);
87extern int cpci_set_attention_status(struct slot *slot, int status);
88extern int cpci_check_and_clear_ins(struct slot * slot);
89extern int cpci_check_ext(struct slot * slot);
90extern int cpci_clear_ext(struct slot * slot);
91extern int cpci_led_on(struct slot * slot);
92extern int cpci_led_off(struct slot * slot);
93extern int cpci_configure_slot(struct slot *slot);
94extern int cpci_unconfigure_slot(struct slot *slot);
95
96#endif /* _CPCI_HOTPLUG_H */
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
new file mode 100644
index 000000000000..ed243605dc7b
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -0,0 +1,792 @@
1/*
2 * CompactPCI Hot Plug Driver
3 *
4 * Copyright (C) 2002 SOMA Networks, Inc.
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <scottm@somanetworks.com>
26 */
27
28#include <linux/config.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/smp_lock.h>
36#include <linux/delay.h>
37#include "pci_hotplug.h"
38#include "cpci_hotplug.h"
39
40#define DRIVER_VERSION "0.2"
41#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
42#define DRIVER_DESC "CompactPCI Hot Plug Core"
43
44#define MY_NAME "cpci_hotplug"
45
46#define dbg(format, arg...) \
47 do { \
48 if(cpci_debug) \
49 printk (KERN_DEBUG "%s: " format "\n", \
50 MY_NAME , ## arg); \
51 } while(0)
52#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
53#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
54#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
55
56/* local variables */
57static spinlock_t list_lock;
58static LIST_HEAD(slot_list);
59static int slots;
60int cpci_debug;
61static struct cpci_hp_controller *controller;
62static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
63static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */
64static int thread_finished = 1;
65
66static int enable_slot(struct hotplug_slot *slot);
67static int disable_slot(struct hotplug_slot *slot);
68static int set_attention_status(struct hotplug_slot *slot, u8 value);
69static int get_power_status(struct hotplug_slot *slot, u8 * value);
70static int get_attention_status(struct hotplug_slot *slot, u8 * value);
71
72static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
73 .owner = THIS_MODULE,
74 .enable_slot = enable_slot,
75 .disable_slot = disable_slot,
76 .set_attention_status = set_attention_status,
77 .get_power_status = get_power_status,
78 .get_attention_status = get_attention_status,
79};
80
81static int
82update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
83{
84 struct hotplug_slot_info info;
85
86 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
87 info.latch_status = value;
88 return pci_hp_change_slot_info(hotplug_slot, &info);
89}
90
91static int
92update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
93{
94 struct hotplug_slot_info info;
95
96 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
97 info.adapter_status = value;
98 return pci_hp_change_slot_info(hotplug_slot, &info);
99}
100
101static int
102enable_slot(struct hotplug_slot *hotplug_slot)
103{
104 struct slot *slot = hotplug_slot->private;
105 int retval = 0;
106
107 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
108
109 if(controller->ops->set_power) {
110 retval = controller->ops->set_power(slot, 1);
111 }
112
113 return retval;
114}
115
116static int
117disable_slot(struct hotplug_slot *hotplug_slot)
118{
119 struct slot *slot = hotplug_slot->private;
120 int retval = 0;
121
122 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
123
124 /* Unconfigure device */
125 dbg("%s - unconfiguring slot %s",
126 __FUNCTION__, slot->hotplug_slot->name);
127 if((retval = cpci_unconfigure_slot(slot))) {
128 err("%s - could not unconfigure slot %s",
129 __FUNCTION__, slot->hotplug_slot->name);
130 return retval;
131 }
132 dbg("%s - finished unconfiguring slot %s",
133 __FUNCTION__, slot->hotplug_slot->name);
134
135 /* Clear EXT (by setting it) */
136 if(cpci_clear_ext(slot)) {
137 err("%s - could not clear EXT for slot %s",
138 __FUNCTION__, slot->hotplug_slot->name);
139 retval = -ENODEV;
140 }
141 cpci_led_on(slot);
142
143 if(controller->ops->set_power) {
144 retval = controller->ops->set_power(slot, 0);
145 }
146
147 if(update_adapter_status(slot->hotplug_slot, 0)) {
148 warn("failure to update adapter file");
149 }
150
151 slot->extracting = 0;
152
153 return retval;
154}
155
156static u8
157cpci_get_power_status(struct slot *slot)
158{
159 u8 power = 1;
160
161 if(controller->ops->get_power) {
162 power = controller->ops->get_power(slot);
163 }
164 return power;
165}
166
167static int
168get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
169{
170 struct slot *slot = hotplug_slot->private;
171
172 *value = cpci_get_power_status(slot);
173 return 0;
174}
175
176static int
177get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
178{
179 struct slot *slot = hotplug_slot->private;
180
181 *value = cpci_get_attention_status(slot);
182 return 0;
183}
184
185static int
186set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
187{
188 return cpci_set_attention_status(hotplug_slot->private, status);
189}
190
191static void release_slot(struct hotplug_slot *hotplug_slot)
192{
193 struct slot *slot = hotplug_slot->private;
194
195 kfree(slot->hotplug_slot->info);
196 kfree(slot->hotplug_slot->name);
197 kfree(slot->hotplug_slot);
198 kfree(slot);
199}
200
201#define SLOT_NAME_SIZE 6
202static void
203make_slot_name(struct slot *slot)
204{
205 snprintf(slot->hotplug_slot->name,
206 SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
207}
208
209int
210cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
211{
212 struct slot *slot;
213 struct hotplug_slot *hotplug_slot;
214 struct hotplug_slot_info *info;
215 char *name;
216 int status = -ENOMEM;
217 int i;
218
219 if(!(controller && bus)) {
220 return -ENODEV;
221 }
222
223 /*
224 * Create a structure for each slot, and register that slot
225 * with the pci_hotplug subsystem.
226 */
227 for (i = first; i <= last; ++i) {
228 slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
229 if (!slot)
230 goto error;
231 memset(slot, 0, sizeof (struct slot));
232
233 hotplug_slot =
234 kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
235 if (!hotplug_slot)
236 goto error_slot;
237 memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
238 slot->hotplug_slot = hotplug_slot;
239
240 info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
241 if (!info)
242 goto error_hpslot;
243 memset(info, 0, sizeof (struct hotplug_slot_info));
244 hotplug_slot->info = info;
245
246 name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
247 if (!name)
248 goto error_info;
249 hotplug_slot->name = name;
250
251 slot->bus = bus;
252 slot->number = i;
253 slot->devfn = PCI_DEVFN(i, 0);
254
255 hotplug_slot->private = slot;
256 hotplug_slot->release = &release_slot;
257 make_slot_name(slot);
258 hotplug_slot->ops = &cpci_hotplug_slot_ops;
259
260 /*
261 * Initialize the slot info structure with some known
262 * good values.
263 */
264 dbg("initializing slot %s", slot->hotplug_slot->name);
265 info->power_status = cpci_get_power_status(slot);
266 info->attention_status = cpci_get_attention_status(slot);
267
268 dbg("registering slot %s", slot->hotplug_slot->name);
269 status = pci_hp_register(slot->hotplug_slot);
270 if (status) {
271 err("pci_hp_register failed with error %d", status);
272 goto error_name;
273 }
274
275 /* Add slot to our internal list */
276 spin_lock(&list_lock);
277 list_add(&slot->slot_list, &slot_list);
278 slots++;
279 spin_unlock(&list_lock);
280 }
281 return 0;
282error_name:
283 kfree(name);
284error_info:
285 kfree(info);
286error_hpslot:
287 kfree(hotplug_slot);
288error_slot:
289 kfree(slot);
290error:
291 return status;
292}
293
294int
295cpci_hp_unregister_bus(struct pci_bus *bus)
296{
297 struct slot *slot;
298 struct list_head *tmp;
299 struct list_head *next;
300 int status;
301
302 spin_lock(&list_lock);
303 if(!slots) {
304 spin_unlock(&list_lock);
305 return -1;
306 }
307 list_for_each_safe(tmp, next, &slot_list) {
308 slot = list_entry(tmp, struct slot, slot_list);
309 if(slot->bus == bus) {
310 dbg("deregistering slot %s", slot->hotplug_slot->name);
311 status = pci_hp_deregister(slot->hotplug_slot);
312 if(status) {
313 err("pci_hp_deregister failed with error %d",
314 status);
315 return status;
316 }
317
318 list_del(&slot->slot_list);
319 slots--;
320 }
321 }
322 spin_unlock(&list_lock);
323 return 0;
324}
325
326/* This is the interrupt mode interrupt handler */
327static irqreturn_t
328cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
329{
330 dbg("entered cpci_hp_intr");
331
332 /* Check to see if it was our interrupt */
333 if((controller->irq_flags & SA_SHIRQ) &&
334 !controller->ops->check_irq(controller->dev_id)) {
335 dbg("exited cpci_hp_intr, not our interrupt");
336 return IRQ_NONE;
337 }
338
339 /* Disable ENUM interrupt */
340 controller->ops->disable_irq();
341
342 /* Trigger processing by the event thread */
343 dbg("Signal event_semaphore");
344 up(&event_semaphore);
345 dbg("exited cpci_hp_intr");
346 return IRQ_HANDLED;
347}
348
349/*
350 * According to PICMG 2.12 R2.0, section 6.3.2, upon
351 * initialization, the system driver shall clear the
352 * INS bits of the cold-inserted devices.
353 */
354static int
355init_slots(void)
356{
357 struct slot *slot;
358 struct list_head *tmp;
359 struct pci_dev* dev;
360
361 dbg("%s - enter", __FUNCTION__);
362 spin_lock(&list_lock);
363 if(!slots) {
364 spin_unlock(&list_lock);
365 return -1;
366 }
367 list_for_each(tmp, &slot_list) {
368 slot = list_entry(tmp, struct slot, slot_list);
369 dbg("%s - looking at slot %s",
370 __FUNCTION__, slot->hotplug_slot->name);
371 if(cpci_check_and_clear_ins(slot)) {
372 dbg("%s - cleared INS for slot %s",
373 __FUNCTION__, slot->hotplug_slot->name);
374 dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0));
375 if(dev) {
376 if(update_adapter_status(slot->hotplug_slot, 1)) {
377 warn("failure to update adapter file");
378 }
379 if(update_latch_status(slot->hotplug_slot, 1)) {
380 warn("failure to update latch file");
381 }
382 slot->dev = dev;
383 } else {
384 err("%s - no driver attached to device in slot %s",
385 __FUNCTION__, slot->hotplug_slot->name);
386 }
387 }
388 }
389 spin_unlock(&list_lock);
390 dbg("%s - exit", __FUNCTION__);
391 return 0;
392}
393
394static int
395check_slots(void)
396{
397 struct slot *slot;
398 struct list_head *tmp;
399 int extracted;
400 int inserted;
401
402 spin_lock(&list_lock);
403 if(!slots) {
404 spin_unlock(&list_lock);
405 err("no slots registered, shutting down");
406 return -1;
407 }
408 extracted = inserted = 0;
409 list_for_each(tmp, &slot_list) {
410 slot = list_entry(tmp, struct slot, slot_list);
411 dbg("%s - looking at slot %s",
412 __FUNCTION__, slot->hotplug_slot->name);
413 if(cpci_check_and_clear_ins(slot)) {
414 u16 hs_csr;
415
416 /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
417 if(slot->dev) {
418 warn("slot %s already inserted", slot->hotplug_slot->name);
419 inserted++;
420 continue;
421 }
422
423 /* Process insertion */
424 dbg("%s - slot %s inserted",
425 __FUNCTION__, slot->hotplug_slot->name);
426
427 /* GSM, debug */
428 hs_csr = cpci_get_hs_csr(slot);
429 dbg("%s - slot %s HS_CSR (1) = %04x",
430 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
431
432 /* Configure device */
433 dbg("%s - configuring slot %s",
434 __FUNCTION__, slot->hotplug_slot->name);
435 if(cpci_configure_slot(slot)) {
436 err("%s - could not configure slot %s",
437 __FUNCTION__, slot->hotplug_slot->name);
438 continue;
439 }
440 dbg("%s - finished configuring slot %s",
441 __FUNCTION__, slot->hotplug_slot->name);
442
443 /* GSM, debug */
444 hs_csr = cpci_get_hs_csr(slot);
445 dbg("%s - slot %s HS_CSR (2) = %04x",
446 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
447
448 if(update_latch_status(slot->hotplug_slot, 1)) {
449 warn("failure to update latch file");
450 }
451
452 if(update_adapter_status(slot->hotplug_slot, 1)) {
453 warn("failure to update adapter file");
454 }
455
456 cpci_led_off(slot);
457
458 /* GSM, debug */
459 hs_csr = cpci_get_hs_csr(slot);
460 dbg("%s - slot %s HS_CSR (3) = %04x",
461 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
462
463 inserted++;
464 } else if(cpci_check_ext(slot)) {
465 u16 hs_csr;
466
467 /* Process extraction request */
468 dbg("%s - slot %s extracted",
469 __FUNCTION__, slot->hotplug_slot->name);
470
471 /* GSM, debug */
472 hs_csr = cpci_get_hs_csr(slot);
473 dbg("%s - slot %s HS_CSR = %04x",
474 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
475
476 if(!slot->extracting) {
477 if(update_latch_status(slot->hotplug_slot, 0)) {
478 warn("failure to update latch file");
479 }
480 slot->extracting = 1;
481 }
482 extracted++;
483 }
484 }
485 spin_unlock(&list_lock);
486 if(inserted || extracted) {
487 return extracted;
488 }
489 else {
490 err("cannot find ENUM# source, shutting down");
491 return -1;
492 }
493}
494
495/* This is the interrupt mode worker thread body */
496static int
497event_thread(void *data)
498{
499 int rc;
500 struct slot *slot;
501 struct list_head *tmp;
502
503 lock_kernel();
504 daemonize("cpci_hp_eventd");
505 unlock_kernel();
506
507 dbg("%s - event thread started", __FUNCTION__);
508 while(1) {
509 dbg("event thread sleeping");
510 down_interruptible(&event_semaphore);
511 dbg("event thread woken, thread_finished = %d",
512 thread_finished);
513 if(thread_finished || signal_pending(current))
514 break;
515 while(controller->ops->query_enum()) {
516 rc = check_slots();
517 if (rc > 0)
518 /* Give userspace a chance to handle extraction */
519 msleep(500);
520 else if (rc < 0) {
521 dbg("%s - error checking slots", __FUNCTION__);
522 thread_finished = 1;
523 break;
524 }
525 }
526 /* Check for someone yanking out a board */
527 list_for_each(tmp, &slot_list) {
528 slot = list_entry(tmp, struct slot, slot_list);
529 if(slot->extracting) {
530 /*
531 * Hmmm, we're likely hosed at this point, should we
532 * bother trying to tell the driver or not?
533 */
534 err("card in slot %s was improperly removed",
535 slot->hotplug_slot->name);
536 if(update_adapter_status(slot->hotplug_slot, 0)) {
537 warn("failure to update adapter file");
538 }
539 slot->extracting = 0;
540 }
541 }
542
543 /* Re-enable ENUM# interrupt */
544 dbg("%s - re-enabling irq", __FUNCTION__);
545 controller->ops->enable_irq();
546 }
547
548 dbg("%s - event thread signals exit", __FUNCTION__);
549 up(&thread_exit);
550 return 0;
551}
552
553/* This is the polling mode worker thread body */
554static int
555poll_thread(void *data)
556{
557 int rc;
558 struct slot *slot;
559 struct list_head *tmp;
560
561 lock_kernel();
562 daemonize("cpci_hp_polld");
563 unlock_kernel();
564
565 while(1) {
566 if(thread_finished || signal_pending(current))
567 break;
568
569 while(controller->ops->query_enum()) {
570 rc = check_slots();
571 if(rc > 0)
572 /* Give userspace a chance to handle extraction */
573 msleep(500);
574 else if (rc < 0) {
575 dbg("%s - error checking slots", __FUNCTION__);
576 thread_finished = 1;
577 break;
578 }
579 }
580 /* Check for someone yanking out a board */
581 list_for_each(tmp, &slot_list) {
582 slot = list_entry(tmp, struct slot, slot_list);
583 if(slot->extracting) {
584 /*
585 * Hmmm, we're likely hosed at this point, should we
586 * bother trying to tell the driver or not?
587 */
588 err("card in slot %s was improperly removed",
589 slot->hotplug_slot->name);
590 if(update_adapter_status(slot->hotplug_slot, 0)) {
591 warn("failure to update adapter file");
592 }
593 slot->extracting = 0;
594 }
595 }
596
597 msleep(100);
598 }
599 dbg("poll thread signals exit");
600 up(&thread_exit);
601 return 0;
602}
603
604static int
605cpci_start_thread(void)
606{
607 int pid;
608
609 /* initialize our semaphores */
610 init_MUTEX_LOCKED(&event_semaphore);
611 init_MUTEX_LOCKED(&thread_exit);
612 thread_finished = 0;
613
614 if(controller->irq) {
615 pid = kernel_thread(event_thread, NULL, 0);
616 } else {
617 pid = kernel_thread(poll_thread, NULL, 0);
618 }
619 if(pid < 0) {
620 err("Can't start up our thread");
621 return -1;
622 }
623 dbg("Our thread pid = %d", pid);
624 return 0;
625}
626
627static void
628cpci_stop_thread(void)
629{
630 thread_finished = 1;
631 dbg("thread finish command given");
632 if(controller->irq) {
633 up(&event_semaphore);
634 }
635 dbg("wait for thread to exit");
636 down(&thread_exit);
637}
638
639int
640cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
641{
642 int status = 0;
643
644 if(!controller) {
645 controller = new_controller;
646 if(controller->irq) {
647 if(request_irq(controller->irq,
648 cpci_hp_intr,
649 controller->irq_flags,
650 MY_NAME, controller->dev_id)) {
651 err("Can't get irq %d for the hotplug cPCI controller", controller->irq);
652 status = -ENODEV;
653 }
654 dbg("%s - acquired controller irq %d", __FUNCTION__,
655 controller->irq);
656 }
657 } else {
658 err("cPCI hotplug controller already registered");
659 status = -1;
660 }
661 return status;
662}
663
664int
665cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
666{
667 int status = 0;
668
669 if(controller) {
670 if(!thread_finished) {
671 cpci_stop_thread();
672 }
673 if(controller->irq) {
674 free_irq(controller->irq, controller->dev_id);
675 }
676 controller = NULL;
677 } else {
678 status = -ENODEV;
679 }
680 return status;
681}
682
683int
684cpci_hp_start(void)
685{
686 static int first = 1;
687 int status;
688
689 dbg("%s - enter", __FUNCTION__);
690 if(!controller) {
691 return -ENODEV;
692 }
693
694 spin_lock(&list_lock);
695 if(!slots) {
696 spin_unlock(&list_lock);
697 return -ENODEV;
698 }
699 spin_unlock(&list_lock);
700
701 if(first) {
702 status = init_slots();
703 if(status) {
704 return status;
705 }
706 first = 0;
707 }
708
709 status = cpci_start_thread();
710 if(status) {
711 return status;
712 }
713 dbg("%s - thread started", __FUNCTION__);
714
715 if(controller->irq) {
716 /* Start enum interrupt processing */
717 dbg("%s - enabling irq", __FUNCTION__);
718 controller->ops->enable_irq();
719 }
720 dbg("%s - exit", __FUNCTION__);
721 return 0;
722}
723
724int
725cpci_hp_stop(void)
726{
727 if(!controller) {
728 return -ENODEV;
729 }
730
731 if(controller->irq) {
732 /* Stop enum interrupt processing */
733 dbg("%s - disabling irq", __FUNCTION__);
734 controller->ops->disable_irq();
735 }
736 cpci_stop_thread();
737 return 0;
738}
739
740static void __exit
741cleanup_slots(void)
742{
743 struct list_head *tmp;
744 struct slot *slot;
745
746 /*
747 * Unregister all of our slots with the pci_hotplug subsystem,
748 * and free up all memory that we had allocated.
749 */
750 spin_lock(&list_lock);
751 if(!slots) {
752 goto null_cleanup;
753 }
754 list_for_each(tmp, &slot_list) {
755 slot = list_entry(tmp, struct slot, slot_list);
756 list_del(&slot->slot_list);
757 pci_hp_deregister(slot->hotplug_slot);
758 kfree(slot->hotplug_slot->info);
759 kfree(slot->hotplug_slot->name);
760 kfree(slot->hotplug_slot);
761 kfree(slot);
762 }
763 null_cleanup:
764 spin_unlock(&list_lock);
765 return;
766}
767
768int __init
769cpci_hotplug_init(int debug)
770{
771 spin_lock_init(&list_lock);
772 cpci_debug = debug;
773
774 info(DRIVER_DESC " version: " DRIVER_VERSION);
775 return 0;
776}
777
778void __exit
779cpci_hotplug_exit(void)
780{
781 /*
782 * Clean everything up.
783 */
784 cleanup_slots();
785}
786
787EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
788EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
789EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
790EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
791EXPORT_SYMBOL_GPL(cpci_hp_start);
792EXPORT_SYMBOL_GPL(cpci_hp_stop);
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
new file mode 100644
index 000000000000..2e969616f298
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -0,0 +1,661 @@
1/*
2 * CompactPCI Hot Plug Driver PCI functions
3 *
4 * Copyright (C) 2002 by SOMA Networks, Inc.
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 <scottm@somanetworks.com>
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/pci.h>
30#include <linux/proc_fs.h>
31#include "../pci.h"
32#include "pci_hotplug.h"
33#include "cpci_hotplug.h"
34
35#if !defined(MODULE)
36#define MY_NAME "cpci_hotplug"
37#else
38#define MY_NAME THIS_MODULE->name
39#endif
40
41extern int cpci_debug;
42
43#define dbg(format, arg...) \
44 do { \
45 if(cpci_debug) \
46 printk (KERN_DEBUG "%s: " format "\n", \
47 MY_NAME , ## arg); \
48 } while(0)
49#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
50#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
51#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
52
53#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
54
55
56u8 cpci_get_attention_status(struct slot* slot)
57{
58 int hs_cap;
59 u16 hs_csr;
60
61 hs_cap = pci_bus_find_capability(slot->bus,
62 slot->devfn,
63 PCI_CAP_ID_CHSWP);
64 if(!hs_cap) {
65 return 0;
66 }
67
68 if(pci_bus_read_config_word(slot->bus,
69 slot->devfn,
70 hs_cap + 2,
71 &hs_csr)) {
72 return 0;
73 }
74 return hs_csr & 0x0008 ? 1 : 0;
75}
76
77int cpci_set_attention_status(struct slot* slot, int status)
78{
79 int hs_cap;
80 u16 hs_csr;
81
82 hs_cap = pci_bus_find_capability(slot->bus,
83 slot->devfn,
84 PCI_CAP_ID_CHSWP);
85 if(!hs_cap) {
86 return 0;
87 }
88
89 if(pci_bus_read_config_word(slot->bus,
90 slot->devfn,
91 hs_cap + 2,
92 &hs_csr)) {
93 return 0;
94 }
95 if(status) {
96 hs_csr |= HS_CSR_LOO;
97 } else {
98 hs_csr &= ~HS_CSR_LOO;
99 }
100 if(pci_bus_write_config_word(slot->bus,
101 slot->devfn,
102 hs_cap + 2,
103 hs_csr)) {
104 return 0;
105 }
106 return 1;
107}
108
109u16 cpci_get_hs_csr(struct slot* slot)
110{
111 int hs_cap;
112 u16 hs_csr;
113
114 hs_cap = pci_bus_find_capability(slot->bus,
115 slot->devfn,
116 PCI_CAP_ID_CHSWP);
117 if(!hs_cap) {
118 return 0xFFFF;
119 }
120
121 if(pci_bus_read_config_word(slot->bus,
122 slot->devfn,
123 hs_cap + 2,
124 &hs_csr)) {
125 return 0xFFFF;
126 }
127 return hs_csr;
128}
129
130#if 0
131u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
132{
133 int hs_cap;
134 u16 new_hs_csr;
135
136 hs_cap = pci_bus_find_capability(slot->bus,
137 slot->devfn,
138 PCI_CAP_ID_CHSWP);
139 if(!hs_cap) {
140 return 0xFFFF;
141 }
142
143 /* Write out the new value */
144 if(pci_bus_write_config_word(slot->bus,
145 slot->devfn,
146 hs_cap + 2,
147 hs_csr)) {
148 return 0xFFFF;
149 }
150
151 /* Read back what we just wrote out */
152 if(pci_bus_read_config_word(slot->bus,
153 slot->devfn,
154 hs_cap + 2,
155 &new_hs_csr)) {
156 return 0xFFFF;
157 }
158 return new_hs_csr;
159}
160#endif
161
162int cpci_check_and_clear_ins(struct slot* slot)
163{
164 int hs_cap;
165 u16 hs_csr;
166 int ins = 0;
167
168 hs_cap = pci_bus_find_capability(slot->bus,
169 slot->devfn,
170 PCI_CAP_ID_CHSWP);
171 if(!hs_cap) {
172 return 0;
173 }
174 if(pci_bus_read_config_word(slot->bus,
175 slot->devfn,
176 hs_cap + 2,
177 &hs_csr)) {
178 return 0;
179 }
180 if(hs_csr & HS_CSR_INS) {
181 /* Clear INS (by setting it) */
182 if(pci_bus_write_config_word(slot->bus,
183 slot->devfn,
184 hs_cap + 2,
185 hs_csr)) {
186 ins = 0;
187 }
188 ins = 1;
189 }
190 return ins;
191}
192
193int cpci_check_ext(struct slot* slot)
194{
195 int hs_cap;
196 u16 hs_csr;
197 int ext = 0;
198
199 hs_cap = pci_bus_find_capability(slot->bus,
200 slot->devfn,
201 PCI_CAP_ID_CHSWP);
202 if(!hs_cap) {
203 return 0;
204 }
205 if(pci_bus_read_config_word(slot->bus,
206 slot->devfn,
207 hs_cap + 2,
208 &hs_csr)) {
209 return 0;
210 }
211 if(hs_csr & HS_CSR_EXT) {
212 ext = 1;
213 }
214 return ext;
215}
216
217int cpci_clear_ext(struct slot* slot)
218{
219 int hs_cap;
220 u16 hs_csr;
221
222 hs_cap = pci_bus_find_capability(slot->bus,
223 slot->devfn,
224 PCI_CAP_ID_CHSWP);
225 if(!hs_cap) {
226 return -ENODEV;
227 }
228 if(pci_bus_read_config_word(slot->bus,
229 slot->devfn,
230 hs_cap + 2,
231 &hs_csr)) {
232 return -ENODEV;
233 }
234 if(hs_csr & HS_CSR_EXT) {
235 /* Clear EXT (by setting it) */
236 if(pci_bus_write_config_word(slot->bus,
237 slot->devfn,
238 hs_cap + 2,
239 hs_csr)) {
240 return -ENODEV;
241 }
242 }
243 return 0;
244}
245
246int cpci_led_on(struct slot* slot)
247{
248 int hs_cap;
249 u16 hs_csr;
250
251 hs_cap = pci_bus_find_capability(slot->bus,
252 slot->devfn,
253 PCI_CAP_ID_CHSWP);
254 if(!hs_cap) {
255 return -ENODEV;
256 }
257 if(pci_bus_read_config_word(slot->bus,
258 slot->devfn,
259 hs_cap + 2,
260 &hs_csr)) {
261 return -ENODEV;
262 }
263 if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
264 /* Set LOO */
265 hs_csr |= HS_CSR_LOO;
266 if(pci_bus_write_config_word(slot->bus,
267 slot->devfn,
268 hs_cap + 2,
269 hs_csr)) {
270 err("Could not set LOO for slot %s",
271 slot->hotplug_slot->name);
272 return -ENODEV;
273 }
274 }
275 return 0;
276}
277
278int cpci_led_off(struct slot* slot)
279{
280 int hs_cap;
281 u16 hs_csr;
282
283 hs_cap = pci_bus_find_capability(slot->bus,
284 slot->devfn,
285 PCI_CAP_ID_CHSWP);
286 if(!hs_cap) {
287 return -ENODEV;
288 }
289 if(pci_bus_read_config_word(slot->bus,
290 slot->devfn,
291 hs_cap + 2,
292 &hs_csr)) {
293 return -ENODEV;
294 }
295 if(hs_csr & HS_CSR_LOO) {
296 /* Clear LOO */
297 hs_csr &= ~HS_CSR_LOO;
298 if(pci_bus_write_config_word(slot->bus,
299 slot->devfn,
300 hs_cap + 2,
301 hs_csr)) {
302 err("Could not clear LOO for slot %s",
303 slot->hotplug_slot->name);
304 return -ENODEV;
305 }
306 }
307 return 0;
308}
309
310
311/*
312 * Device configuration functions
313 */
314
315static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
316{
317 u8 irq_pin;
318 int r;
319
320 dbg("%s - enter", __FUNCTION__);
321
322 /* NOTE: device already setup from prior scan */
323
324 /* FIXME: How would we know if we need to enable the expansion ROM? */
325 pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
326
327 /* Assign resources */
328 dbg("assigning resources for %02x:%02x.%x",
329 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
330 for (r = 0; r < 6; r++) {
331 struct resource *res = dev->resource + r;
332 if(res->flags)
333 pci_assign_resource(dev, r);
334 }
335 dbg("finished assigning resources for %02x:%02x.%x",
336 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
337
338 /* Does this function have an interrupt at all? */
339 dbg("checking for function interrupt");
340 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
341 if(irq_pin) {
342 dbg("function uses interrupt pin %d", irq_pin);
343 }
344
345 /*
346 * Need to explicitly set irq field to 0 so that it'll get assigned
347 * by the pcibios platform dependent code called by pci_enable_device.
348 */
349 dev->irq = 0;
350
351 dbg("enabling device");
352 pci_enable_device(dev); /* XXX check return */
353 dbg("now dev->irq = %d", dev->irq);
354 if(irq_pin && dev->irq) {
355 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
356 }
357
358 /* Can't use pci_insert_device at the moment, do it manually for now */
359 pci_proc_attach_device(dev);
360 dbg("notifying drivers");
361 //pci_announce_device_to_drivers(dev);
362 dbg("%s - exit", __FUNCTION__);
363 return 0;
364}
365
366static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
367{
368 int rc;
369 struct pci_bus* child;
370 struct resource* r;
371 u8 max, n;
372 u16 command;
373
374 dbg("%s - enter", __FUNCTION__);
375
376 /* Do basic bridge initialization */
377 rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
378 if(rc) {
379 printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
380 }
381 rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
382 if(rc) {
383 printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
384 }
385 rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
386 if(rc) {
387 printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
388 }
389
390 /*
391 * Set parent bridge's subordinate field so that configuration space
392 * access will work in pci_scan_bridge and friends.
393 */
394 max = pci_max_busnr();
395 bus->subordinate = max + 1;
396 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
397
398 /* Scan behind bridge */
399 n = pci_scan_bridge(bus, dev, max, 2);
400 child = pci_find_bus(0, max + 1);
401 if (!child)
402 return -ENODEV;
403 pci_proc_attach_bus(child);
404
405 /*
406 * Update parent bridge's subordinate field if there were more bridges
407 * behind the bridge that was scanned.
408 */
409 if(n > max) {
410 bus->subordinate = n;
411 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
412 }
413
414 /*
415 * Update the bridge resources of the bridge to accommodate devices
416 * behind it.
417 */
418 pci_bus_size_bridges(child);
419 pci_bus_assign_resources(child);
420
421 /* Enable resource mapping via command register */
422 command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
423 r = child->resource[0];
424 if(r && r->start) {
425 command |= PCI_COMMAND_IO;
426 }
427 r = child->resource[1];
428 if(r && r->start) {
429 command |= PCI_COMMAND_MEMORY;
430 }
431 r = child->resource[2];
432 if(r && r->start) {
433 command |= PCI_COMMAND_MEMORY;
434 }
435 rc = pci_write_config_word(dev, PCI_COMMAND, command);
436 if(rc) {
437 err("Error setting command register");
438 return rc;
439 }
440
441 /* Set bridge control register */
442 command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
443 rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
444 if(rc) {
445 err("Error setting bridge control register");
446 return rc;
447 }
448 dbg("%s - exit", __FUNCTION__);
449 return 0;
450}
451
452static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
453 struct pci_bus_wrapped *wrapped_bus)
454{
455 int rc;
456 struct pci_dev *dev = wrapped_dev->dev;
457 struct pci_bus *bus = wrapped_bus->bus;
458 struct slot* slot;
459
460 dbg("%s - enter", __FUNCTION__);
461
462 /*
463 * We need to fix up the hotplug representation with the Linux
464 * representation.
465 */
466 if(wrapped_dev->data) {
467 slot = (struct slot*) wrapped_dev->data;
468 slot->dev = dev;
469 }
470
471 /* If it's a bridge, scan behind it for devices */
472 if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
473 rc = cpci_configure_bridge(bus, dev);
474 if(rc)
475 return rc;
476 }
477
478 /* Actually configure device */
479 if(dev) {
480 rc = cpci_configure_dev(bus, dev);
481 if(rc)
482 return rc;
483 }
484 dbg("%s - exit", __FUNCTION__);
485 return 0;
486}
487
488static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
489 struct pci_bus_wrapped *wrapped_bus)
490{
491 struct pci_dev *dev = wrapped_dev->dev;
492 struct slot* slot;
493
494 dbg("%s - enter", __FUNCTION__);
495 if(!dev)
496 return -ENODEV;
497
498 /* Remove the Linux representation */
499 if(pci_remove_device_safe(dev)) {
500 err("Could not remove device\n");
501 return -1;
502 }
503
504 /*
505 * Now remove the hotplug representation.
506 */
507 if(wrapped_dev->data) {
508 slot = (struct slot*) wrapped_dev->data;
509 slot->dev = NULL;
510 } else {
511 dbg("No hotplug representation for %02x:%02x.%x",
512 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
513 }
514 dbg("%s - exit", __FUNCTION__);
515 return 0;
516}
517
518static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
519 struct pci_dev_wrapped *wrapped_dev)
520{
521 struct pci_bus *bus = wrapped_bus->bus;
522 struct pci_bus *parent = bus->self->bus;
523
524 dbg("%s - enter", __FUNCTION__);
525
526 /* The cleanup code for proc entries regarding buses should be in the kernel... */
527 if(bus->procdir)
528 dbg("detach_pci_bus %s", bus->procdir->name);
529 pci_proc_detach_bus(bus);
530
531 /* The cleanup code should live in the kernel... */
532 bus->self->subordinate = NULL;
533
534 /* unlink from parent bus */
535 list_del(&bus->node);
536
537 /* Now, remove */
538 if(bus)
539 kfree(bus);
540
541 /* Update parent's subordinate field */
542 if(parent) {
543 u8 n = pci_bus_max_busnr(parent);
544 if(n < parent->subordinate) {
545 parent->subordinate = n;
546 pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
547 }
548 }
549 dbg("%s - exit", __FUNCTION__);
550 return 0;
551}
552
553static struct pci_visit configure_functions = {
554 .visit_pci_dev = configure_visit_pci_dev,
555};
556
557static struct pci_visit unconfigure_functions_phase2 = {
558 .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
559 .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
560};
561
562
563int cpci_configure_slot(struct slot* slot)
564{
565 int rc = 0;
566
567 dbg("%s - enter", __FUNCTION__);
568
569 if(slot->dev == NULL) {
570 dbg("pci_dev null, finding %02x:%02x:%x",
571 slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
572 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
573 }
574
575 /* Still NULL? Well then scan for it! */
576 if(slot->dev == NULL) {
577 int n;
578 dbg("pci_dev still null");
579
580 /*
581 * This will generate pci_dev structures for all functions, but
582 * we will only call this case when lookup fails.
583 */
584 n = pci_scan_slot(slot->bus, slot->devfn);
585 dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
586 if(n > 0)
587 pci_bus_add_devices(slot->bus);
588 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
589 if(slot->dev == NULL) {
590 err("Could not find PCI device for slot %02x", slot->number);
591 return 0;
592 }
593 }
594 dbg("slot->dev = %p", slot->dev);
595 if(slot->dev) {
596 struct pci_dev *dev;
597 struct pci_dev_wrapped wrapped_dev;
598 struct pci_bus_wrapped wrapped_bus;
599 int i;
600
601 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
602 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
603
604 for (i = 0; i < 8; i++) {
605 dev = pci_find_slot(slot->bus->number,
606 PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
607 if(!dev)
608 continue;
609 wrapped_dev.dev = dev;
610 wrapped_bus.bus = slot->dev->bus;
611 if(i)
612 wrapped_dev.data = NULL;
613 else
614 wrapped_dev.data = (void*) slot;
615 rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
616 }
617 }
618
619 dbg("%s - exit, rc = %d", __FUNCTION__, rc);
620 return rc;
621}
622
623int cpci_unconfigure_slot(struct slot* slot)
624{
625 int rc = 0;
626 int i;
627 struct pci_dev_wrapped wrapped_dev;
628 struct pci_bus_wrapped wrapped_bus;
629 struct pci_dev *dev;
630
631 dbg("%s - enter", __FUNCTION__);
632
633 if(!slot->dev) {
634 err("No device for slot %02x\n", slot->number);
635 return -ENODEV;
636 }
637
638 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
639 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
640
641 for (i = 0; i < 8; i++) {
642 dev = pci_find_slot(slot->bus->number,
643 PCI_DEVFN(PCI_SLOT(slot->devfn), i));
644 if(dev) {
645 wrapped_dev.dev = dev;
646 wrapped_bus.bus = dev->bus;
647 if(i)
648 wrapped_dev.data = NULL;
649 else
650 wrapped_dev.data = (void*) slot;
651 dbg("%s - unconfigure phase 2", __FUNCTION__);
652 rc = pci_visit_dev(&unconfigure_functions_phase2,
653 &wrapped_dev,
654 &wrapped_bus);
655 if(rc)
656 break;
657 }
658 }
659 dbg("%s - exit, rc = %d", __FUNCTION__, rc);
660 return rc;
661}
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
new file mode 100644
index 000000000000..a62a4345b466
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -0,0 +1,223 @@
1/*
2 * cpcihp_generic.c
3 *
4 * Generic port I/O CompactPCI driver
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * This generic CompactPCI hotplug driver should allow using the PCI hotplug
31 * mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
32 * in a system register that can be read through standard port I/O.
33 *
34 * Send feedback to <scottm@somanetworks.com>
35 */
36
37#include <linux/config.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/errno.h>
41#include <linux/pci.h>
42#include "cpci_hotplug.h"
43
44#define DRIVER_VERSION "0.1"
45#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
46#define DRIVER_DESC "Generic port I/O CompactPCI Hot Plug Driver"
47
48#if !defined(MODULE)
49#define MY_NAME "cpcihp_generic"
50#else
51#define MY_NAME THIS_MODULE->name
52#endif
53
54#define dbg(format, arg...) \
55 do { \
56 if(debug) \
57 printk (KERN_DEBUG "%s: " format "\n", \
58 MY_NAME , ## arg); \
59 } while(0)
60#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
61#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
62#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
63
64/* local variables */
65static int debug;
66static char *bridge;
67static u8 bridge_busnr;
68static u8 bridge_slot;
69static struct pci_bus *bus;
70static u8 first_slot;
71static u8 last_slot;
72static u16 port;
73static unsigned int enum_bit;
74static u8 enum_mask;
75
76static struct cpci_hp_controller_ops generic_hpc_ops;
77static struct cpci_hp_controller generic_hpc;
78
79static int __init validate_parameters(void)
80{
81 char* str;
82 char* p;
83 unsigned long tmp;
84
85 if(!bridge) {
86 info("not configured, disabling.");
87 return 1;
88 }
89 str = bridge;
90 if(!*str)
91 return -EINVAL;
92
93 tmp = simple_strtoul(str, &p, 16);
94 if(p == str || tmp > 0xff) {
95 err("Invalid hotplug bus bridge device bus number");
96 return -EINVAL;
97 }
98 bridge_busnr = (u8) tmp;
99 dbg("bridge_busnr = 0x%02x", bridge_busnr);
100 if(*p != ':') {
101 err("Invalid hotplug bus bridge device");
102 return -EINVAL;
103 }
104 str = p + 1;
105 tmp = simple_strtoul(str, &p, 16);
106 if(p == str || tmp > 0x1f) {
107 err("Invalid hotplug bus bridge device slot number");
108 return -EINVAL;
109 }
110 bridge_slot = (u8) tmp;
111 dbg("bridge_slot = 0x%02x", bridge_slot);
112
113 dbg("first_slot = 0x%02x", first_slot);
114 dbg("last_slot = 0x%02x", last_slot);
115 if(!(first_slot && last_slot)) {
116 err("Need to specify first_slot and last_slot");
117 return -EINVAL;
118 }
119 if(last_slot < first_slot) {
120 err("first_slot must be less than last_slot");
121 return -EINVAL;
122 }
123
124 dbg("port = 0x%04x", port);
125 dbg("enum_bit = 0x%02x", enum_bit);
126 if(enum_bit > 7) {
127 err("Invalid #ENUM bit");
128 return -EINVAL;
129 }
130 enum_mask = 1 << enum_bit;
131 return 0;
132}
133
134static int query_enum(void)
135{
136 u8 value;
137
138 value = inb_p(port);
139 return ((value & enum_mask) == enum_mask);
140}
141
142static int __init cpcihp_generic_init(void)
143{
144 int status;
145 struct resource* r;
146 struct pci_dev* dev;
147
148 info(DRIVER_DESC " version: " DRIVER_VERSION);
149 status = validate_parameters();
150 if(status != 0)
151 return status;
152
153 r = request_region(port, 1, "#ENUM hotswap signal register");
154 if(!r)
155 return -EBUSY;
156
157 dev = pci_find_slot(bridge_busnr, PCI_DEVFN(bridge_slot, 0));
158 if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
159 err("Invalid bridge device %s", bridge);
160 return -EINVAL;
161 }
162 bus = dev->subordinate;
163
164 memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
165 generic_hpc_ops.query_enum = query_enum;
166 generic_hpc.ops = &generic_hpc_ops;
167
168 status = cpci_hp_register_controller(&generic_hpc);
169 if(status != 0) {
170 err("Could not register cPCI hotplug controller");
171 return -ENODEV;
172 }
173 dbg("registered controller");
174
175 status = cpci_hp_register_bus(bus, first_slot, last_slot);
176 if(status != 0) {
177 err("Could not register cPCI hotplug bus");
178 goto init_bus_register_error;
179 }
180 dbg("registered bus");
181
182 status = cpci_hp_start();
183 if(status != 0) {
184 err("Could not started cPCI hotplug system");
185 goto init_start_error;
186 }
187 dbg("started cpci hp system");
188 return 0;
189init_start_error:
190 cpci_hp_unregister_bus(bus);
191init_bus_register_error:
192 cpci_hp_unregister_controller(&generic_hpc);
193 err("status = %d", status);
194 return status;
195
196}
197
198static void __exit cpcihp_generic_exit(void)
199{
200 cpci_hp_stop();
201 cpci_hp_unregister_bus(bus);
202 cpci_hp_unregister_controller(&generic_hpc);
203 release_region(port, 1);
204}
205
206module_init(cpcihp_generic_init);
207module_exit(cpcihp_generic_exit);
208
209MODULE_AUTHOR(DRIVER_AUTHOR);
210MODULE_DESCRIPTION(DRIVER_DESC);
211MODULE_LICENSE("GPL");
212module_param(debug, bool, S_IRUGO | S_IWUSR);
213MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
214module_param(bridge, charp, 0);
215MODULE_PARM_DESC(bridge, "Hotswap bus bridge device, <bus>:<slot> (bus and slot are in hexadecimal)");
216module_param(first_slot, byte, 0);
217MODULE_PARM_DESC(first_slot, "Hotswap bus first slot number");
218module_param(last_slot, byte, 0);
219MODULE_PARM_DESC(last_slot, "Hotswap bus last slot number");
220module_param(port, ushort, 0);
221MODULE_PARM_DESC(port, "#ENUM signal I/O port");
222module_param(enum_bit, uint, 0);
223MODULE_PARM_DESC(enum_bit, "#ENUM signal bit (0-7)");
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
new file mode 100644
index 000000000000..e9928024be78
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -0,0 +1,305 @@
1/*
2 * cpcihp_zt5550.c
3 *
4 * Intel/Ziatech ZT5550 CompactPCI Host Controller driver
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * Send feedback to <scottm@somanetworks.com>
31 */
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/init.h>
37#include <linux/errno.h>
38#include <linux/pci.h>
39#include "cpci_hotplug.h"
40#include "cpcihp_zt5550.h"
41
42#define DRIVER_VERSION "0.2"
43#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
44#define DRIVER_DESC "ZT5550 CompactPCI Hot Plug Driver"
45
46#define MY_NAME "cpcihp_zt5550"
47
48#define dbg(format, arg...) \
49 do { \
50 if(debug) \
51 printk (KERN_DEBUG "%s: " format "\n", \
52 MY_NAME , ## arg); \
53 } while(0)
54#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
55#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
56#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
57
58/* local variables */
59static int debug;
60static int poll;
61static struct cpci_hp_controller_ops zt5550_hpc_ops;
62static struct cpci_hp_controller zt5550_hpc;
63
64/* Primary cPCI bus bridge device */
65static struct pci_dev *bus0_dev;
66static struct pci_bus *bus0;
67
68/* Host controller device */
69static struct pci_dev *hc_dev;
70
71/* Host controller register addresses */
72static void __iomem *hc_registers;
73static void __iomem *csr_hc_index;
74static void __iomem *csr_hc_data;
75static void __iomem *csr_int_status;
76static void __iomem *csr_int_mask;
77
78
79static int zt5550_hc_config(struct pci_dev *pdev)
80{
81 /* Since we know that no boards exist with two HC chips, treat it as an error */
82 if(hc_dev) {
83 err("too many host controller devices?");
84 return -EBUSY;
85 }
86 hc_dev = pdev;
87 dbg("hc_dev = %p", hc_dev);
88 dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
89 dbg("pci resource len %lx", pci_resource_len(hc_dev, 1));
90
91 if(!request_mem_region(pci_resource_start(hc_dev, 1),
92 pci_resource_len(hc_dev, 1), MY_NAME)) {
93 err("cannot reserve MMIO region");
94 return -ENOMEM;
95 }
96
97 hc_registers =
98 ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
99 if(!hc_registers) {
100 err("cannot remap MMIO region %lx @ %lx",
101 pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
102 release_mem_region(pci_resource_start(hc_dev, 1),
103 pci_resource_len(hc_dev, 1));
104 return -ENODEV;
105 }
106
107 csr_hc_index = hc_registers + CSR_HCINDEX;
108 csr_hc_data = hc_registers + CSR_HCDATA;
109 csr_int_status = hc_registers + CSR_INTSTAT;
110 csr_int_mask = hc_registers + CSR_INTMASK;
111
112 /*
113 * Disable host control, fault and serial interrupts
114 */
115 dbg("disabling host control, fault and serial interrupts");
116 writeb((u8) HC_INT_MASK_REG, csr_hc_index);
117 writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data);
118 dbg("disabled host control, fault and serial interrupts");
119
120 /*
121 * Disable timer0, timer1 and ENUM interrupts
122 */
123 dbg("disabling timer0, timer1 and ENUM interrupts");
124 writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
125 dbg("disabled timer0, timer1 and ENUM interrupts");
126 return 0;
127}
128
129static int zt5550_hc_cleanup(void)
130{
131 if(!hc_dev)
132 return -ENODEV;
133
134 iounmap(hc_registers);
135 release_mem_region(pci_resource_start(hc_dev, 1),
136 pci_resource_len(hc_dev, 1));
137 return 0;
138}
139
140static int zt5550_hc_query_enum(void)
141{
142 u8 value;
143
144 value = inb_p(ENUM_PORT);
145 return ((value & ENUM_MASK) == ENUM_MASK);
146}
147
148static int zt5550_hc_check_irq(void *dev_id)
149{
150 int ret;
151 u8 reg;
152
153 ret = 0;
154 if(dev_id == zt5550_hpc.dev_id) {
155 reg = readb(csr_int_status);
156 if(reg)
157 ret = 1;
158 }
159 return ret;
160}
161
162static int zt5550_hc_enable_irq(void)
163{
164 u8 reg;
165
166 if(hc_dev == NULL) {
167 return -ENODEV;
168 }
169 reg = readb(csr_int_mask);
170 reg = reg & ~ENUM_INT_MASK;
171 writeb(reg, csr_int_mask);
172 return 0;
173}
174
175static int zt5550_hc_disable_irq(void)
176{
177 u8 reg;
178
179 if(hc_dev == NULL) {
180 return -ENODEV;
181 }
182
183 reg = readb(csr_int_mask);
184 reg = reg | ENUM_INT_MASK;
185 writeb(reg, csr_int_mask);
186 return 0;
187}
188
189static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
190{
191 int status;
192
193 status = zt5550_hc_config(pdev);
194 if(status != 0) {
195 return status;
196 }
197 dbg("returned from zt5550_hc_config");
198
199 memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
200 zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
201 zt5550_hpc.ops = &zt5550_hpc_ops;
202 if(!poll) {
203 zt5550_hpc.irq = hc_dev->irq;
204 zt5550_hpc.irq_flags = SA_SHIRQ;
205 zt5550_hpc.dev_id = hc_dev;
206
207 zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
208 zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq;
209 zt5550_hpc_ops.check_irq = zt5550_hc_check_irq;
210 } else {
211 info("using ENUM# polling mode");
212 }
213
214 status = cpci_hp_register_controller(&zt5550_hpc);
215 if(status != 0) {
216 err("could not register cPCI hotplug controller");
217 goto init_hc_error;
218 }
219 dbg("registered controller");
220
221 /* Look for first device matching cPCI bus's bridge vendor and device IDs */
222 if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC,
223 PCI_DEVICE_ID_DEC_21154, NULL))) {
224 status = -ENODEV;
225 goto init_register_error;
226 }
227 bus0 = bus0_dev->subordinate;
228 pci_dev_put(bus0_dev);
229
230 status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
231 if(status != 0) {
232 err("could not register cPCI hotplug bus");
233 goto init_register_error;
234 }
235 dbg("registered bus");
236
237 status = cpci_hp_start();
238 if(status != 0) {
239 err("could not started cPCI hotplug system");
240 cpci_hp_unregister_bus(bus0);
241 goto init_register_error;
242 }
243 dbg("started cpci hp system");
244
245 return 0;
246init_register_error:
247 cpci_hp_unregister_controller(&zt5550_hpc);
248init_hc_error:
249 err("status = %d", status);
250 zt5550_hc_cleanup();
251 return status;
252
253}
254
255static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
256{
257 cpci_hp_stop();
258 cpci_hp_unregister_bus(bus0);
259 cpci_hp_unregister_controller(&zt5550_hpc);
260 zt5550_hc_cleanup();
261}
262
263
264static struct pci_device_id zt5550_hc_pci_tbl[] = {
265 { PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, },
266 { 0, }
267};
268MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl);
269
270static struct pci_driver zt5550_hc_driver = {
271 .name = "zt5550_hc",
272 .id_table = zt5550_hc_pci_tbl,
273 .probe = zt5550_hc_init_one,
274 .remove = __devexit_p(zt5550_hc_remove_one),
275};
276
277static int __init zt5550_init(void)
278{
279 struct resource* r;
280
281 info(DRIVER_DESC " version: " DRIVER_VERSION);
282 r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register");
283 if(!r)
284 return -EBUSY;
285
286 return pci_register_driver(&zt5550_hc_driver);
287}
288
289static void __exit
290zt5550_exit(void)
291{
292 pci_unregister_driver(&zt5550_hc_driver);
293 release_region(ENUM_PORT, 1);
294}
295
296module_init(zt5550_init);
297module_exit(zt5550_exit);
298
299MODULE_AUTHOR(DRIVER_AUTHOR);
300MODULE_DESCRIPTION(DRIVER_DESC);
301MODULE_LICENSE("GPL");
302module_param(debug, bool, 0644);
303MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
304module_param(poll, bool, 0644);
305MODULE_PARM_DESC(poll, "#ENUM polling mode enabled or not");
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.h b/drivers/pci/hotplug/cpcihp_zt5550.h
new file mode 100644
index 000000000000..bebc6060a558
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_zt5550.h
@@ -0,0 +1,79 @@
1/*
2 * cpcihp_zt5550.h
3 *
4 * Intel/Ziatech ZT5550 CompactPCI Host Controller driver definitions
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * Send feedback to <scottm@somanetworks.com>
31 */
32
33#ifndef _CPCIHP_ZT5550_H
34#define _CPCIHP_ZT5550_H
35
36/* Direct registers */
37#define CSR_HCINDEX 0x00
38#define CSR_HCDATA 0x04
39#define CSR_INTSTAT 0x08
40#define CSR_INTMASK 0x09
41#define CSR_CNT0CMD 0x0C
42#define CSR_CNT1CMD 0x0E
43#define CSR_CNT0 0x10
44#define CSR_CNT1 0x14
45
46/* Masks for interrupt bits in CSR_INTMASK direct register */
47#define CNT0_INT_MASK 0x01
48#define CNT1_INT_MASK 0x02
49#define ENUM_INT_MASK 0x04
50#define ALL_DIRECT_INTS_MASK 0x07
51
52/* Indexed registers (through CSR_INDEX, CSR_DATA) */
53#define HC_INT_MASK_REG 0x04
54#define HC_STATUS_REG 0x08
55#define HC_CMD_REG 0x0C
56#define ARB_CONFIG_GNT_REG 0x10
57#define ARB_CONFIG_CFG_REG 0x12
58#define ARB_CONFIG_REG 0x10
59#define ISOL_CONFIG_REG 0x18
60#define FAULT_STATUS_REG 0x20
61#define FAULT_CONFIG_REG 0x24
62#define WD_CONFIG_REG 0x2C
63#define HC_DIAG_REG 0x30
64#define SERIAL_COMM_REG 0x34
65#define SERIAL_OUT_REG 0x38
66#define SERIAL_IN_REG 0x3C
67
68/* Masks for interrupt bits in HC_INT_MASK_REG indexed register */
69#define SERIAL_INT_MASK 0x01
70#define FAULT_INT_MASK 0x02
71#define HCF_INT_MASK 0x04
72#define ALL_INDEXED_INTS_MASK 0x07
73
74/* Digital I/O port storing ENUM# */
75#define ENUM_PORT 0xE1
76/* Mask to get to the ENUM# bit on the bus */
77#define ENUM_MASK 0x40
78
79#endif /* _CPCIHP_ZT5550_H */
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
new file mode 100644
index 000000000000..092491e25ef2
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -0,0 +1,721 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28#ifndef _CPQPHP_H
29#define _CPQPHP_H
30
31#include "pci_hotplug.h"
32#include <linux/interrupt.h>
33#include <asm/io.h> /* for read? and write? functions */
34#include <linux/delay.h> /* for delays */
35
36#define MY_NAME "cpqphp"
37
38#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## 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)
42
43
44
45struct smbios_system_slot {
46 u8 type;
47 u8 length;
48 u16 handle;
49 u8 name_string_num;
50 u8 slot_type;
51 u8 slot_width;
52 u8 slot_current_usage;
53 u8 slot_length;
54 u16 slot_number;
55 u8 properties1;
56 u8 properties2;
57} __attribute__ ((packed));
58
59/* offsets to the smbios generic type based on the above structure layout */
60enum smbios_system_slot_offsets {
61 SMBIOS_SLOT_GENERIC_TYPE = offsetof(struct smbios_system_slot, type),
62 SMBIOS_SLOT_GENERIC_LENGTH = offsetof(struct smbios_system_slot, length),
63 SMBIOS_SLOT_GENERIC_HANDLE = offsetof(struct smbios_system_slot, handle),
64 SMBIOS_SLOT_NAME_STRING_NUM = offsetof(struct smbios_system_slot, name_string_num),
65 SMBIOS_SLOT_TYPE = offsetof(struct smbios_system_slot, slot_type),
66 SMBIOS_SLOT_WIDTH = offsetof(struct smbios_system_slot, slot_width),
67 SMBIOS_SLOT_CURRENT_USAGE = offsetof(struct smbios_system_slot, slot_current_usage),
68 SMBIOS_SLOT_LENGTH = offsetof(struct smbios_system_slot, slot_length),
69 SMBIOS_SLOT_NUMBER = offsetof(struct smbios_system_slot, slot_number),
70 SMBIOS_SLOT_PROPERTIES1 = offsetof(struct smbios_system_slot, properties1),
71 SMBIOS_SLOT_PROPERTIES2 = offsetof(struct smbios_system_slot, properties2),
72};
73
74struct smbios_generic {
75 u8 type;
76 u8 length;
77 u16 handle;
78} __attribute__ ((packed));
79
80/* offsets to the smbios generic type based on the above structure layout */
81enum smbios_generic_offsets {
82 SMBIOS_GENERIC_TYPE = offsetof(struct smbios_generic, type),
83 SMBIOS_GENERIC_LENGTH = offsetof(struct smbios_generic, length),
84 SMBIOS_GENERIC_HANDLE = offsetof(struct smbios_generic, handle),
85};
86
87struct smbios_entry_point {
88 char anchor[4];
89 u8 ep_checksum;
90 u8 ep_length;
91 u8 major_version;
92 u8 minor_version;
93 u16 max_size_entry;
94 u8 ep_rev;
95 u8 reserved[5];
96 char int_anchor[5];
97 u8 int_checksum;
98 u16 st_length;
99 u32 st_address;
100 u16 number_of_entrys;
101 u8 bcd_rev;
102} __attribute__ ((packed));
103
104/* offsets to the smbios entry point based on the above structure layout */
105enum smbios_entry_point_offsets {
106 ANCHOR = offsetof(struct smbios_entry_point, anchor[0]),
107 EP_CHECKSUM = offsetof(struct smbios_entry_point, ep_checksum),
108 EP_LENGTH = offsetof(struct smbios_entry_point, ep_length),
109 MAJOR_VERSION = offsetof(struct smbios_entry_point, major_version),
110 MINOR_VERSION = offsetof(struct smbios_entry_point, minor_version),
111 MAX_SIZE_ENTRY = offsetof(struct smbios_entry_point, max_size_entry),
112 EP_REV = offsetof(struct smbios_entry_point, ep_rev),
113 INT_ANCHOR = offsetof(struct smbios_entry_point, int_anchor[0]),
114 INT_CHECKSUM = offsetof(struct smbios_entry_point, int_checksum),
115 ST_LENGTH = offsetof(struct smbios_entry_point, st_length),
116 ST_ADDRESS = offsetof(struct smbios_entry_point, st_address),
117 NUMBER_OF_ENTRYS = offsetof(struct smbios_entry_point, number_of_entrys),
118 BCD_REV = offsetof(struct smbios_entry_point, bcd_rev),
119};
120
121struct ctrl_reg { /* offset */
122 u8 slot_RST; /* 0x00 */
123 u8 slot_enable; /* 0x01 */
124 u16 misc; /* 0x02 */
125 u32 led_control; /* 0x04 */
126 u32 int_input_clear; /* 0x08 */
127 u32 int_mask; /* 0x0a */
128 u8 reserved0; /* 0x10 */
129 u8 reserved1; /* 0x11 */
130 u8 reserved2; /* 0x12 */
131 u8 gen_output_AB; /* 0x13 */
132 u32 non_int_input; /* 0x14 */
133 u32 reserved3; /* 0x18 */
134 u32 reserved4; /* 0x1a */
135 u32 reserved5; /* 0x20 */
136 u8 reserved6; /* 0x24 */
137 u8 reserved7; /* 0x25 */
138 u16 reserved8; /* 0x26 */
139 u8 slot_mask; /* 0x28 */
140 u8 reserved9; /* 0x29 */
141 u8 reserved10; /* 0x2a */
142 u8 reserved11; /* 0x2b */
143 u8 slot_SERR; /* 0x2c */
144 u8 slot_power; /* 0x2d */
145 u8 reserved12; /* 0x2e */
146 u8 reserved13; /* 0x2f */
147 u8 next_curr_freq; /* 0x30 */
148 u8 reset_freq_mode; /* 0x31 */
149} __attribute__ ((packed));
150
151/* offsets to the controller registers based on the above structure layout */
152enum ctrl_offsets {
153 SLOT_RST = offsetof(struct ctrl_reg, slot_RST),
154 SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable),
155 MISC = offsetof(struct ctrl_reg, misc),
156 LED_CONTROL = offsetof(struct ctrl_reg, led_control),
157 INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear),
158 INT_MASK = offsetof(struct ctrl_reg, int_mask),
159 CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),
160 CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1),
161 CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1),
162 GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),
163 NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),
164 CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3),
165 CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4),
166 CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5),
167 CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6),
168 CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7),
169 CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8),
170 SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),
171 CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),
172 CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10),
173 CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),
174 SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),
175 SLOT_POWER = offsetof(struct ctrl_reg, slot_power),
176 NEXT_CURR_FREQ = offsetof(struct ctrl_reg, next_curr_freq),
177 RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode),
178};
179
180struct hrt {
181 char sig0;
182 char sig1;
183 char sig2;
184 char sig3;
185 u16 unused_IRQ;
186 u16 PCIIRQ;
187 u8 number_of_entries;
188 u8 revision;
189 u16 reserved1;
190 u32 reserved2;
191} __attribute__ ((packed));
192
193/* offsets to the hotplug resource table registers based on the above structure layout */
194enum hrt_offsets {
195 SIG0 = offsetof(struct hrt, sig0),
196 SIG1 = offsetof(struct hrt, sig1),
197 SIG2 = offsetof(struct hrt, sig2),
198 SIG3 = offsetof(struct hrt, sig3),
199 UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
200 PCIIRQ = offsetof(struct hrt, PCIIRQ),
201 NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
202 REVISION = offsetof(struct hrt, revision),
203 HRT_RESERVED1 = offsetof(struct hrt, reserved1),
204 HRT_RESERVED2 = offsetof(struct hrt, reserved2),
205};
206
207struct slot_rt {
208 u8 dev_func;
209 u8 primary_bus;
210 u8 secondary_bus;
211 u8 max_bus;
212 u16 io_base;
213 u16 io_length;
214 u16 mem_base;
215 u16 mem_length;
216 u16 pre_mem_base;
217 u16 pre_mem_length;
218} __attribute__ ((packed));
219
220/* offsets to the hotplug slot resource table registers based on the above structure layout */
221enum slot_rt_offsets {
222 DEV_FUNC = offsetof(struct slot_rt, dev_func),
223 PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
224 SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
225 MAX_BUS = offsetof(struct slot_rt, max_bus),
226 IO_BASE = offsetof(struct slot_rt, io_base),
227 IO_LENGTH = offsetof(struct slot_rt, io_length),
228 MEM_BASE = offsetof(struct slot_rt, mem_base),
229 MEM_LENGTH = offsetof(struct slot_rt, mem_length),
230 PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
231 PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
232};
233
234struct pci_func {
235 struct pci_func *next;
236 u8 bus;
237 u8 device;
238 u8 function;
239 u8 is_a_board;
240 u16 status;
241 u8 configured;
242 u8 switch_save;
243 u8 presence_save;
244 u32 base_length[0x06];
245 u8 base_type[0x06];
246 u16 reserved2;
247 u32 config_space[0x20];
248 struct pci_resource *mem_head;
249 struct pci_resource *p_mem_head;
250 struct pci_resource *io_head;
251 struct pci_resource *bus_head;
252 struct timer_list *p_task_event;
253 struct pci_dev* pci_dev;
254};
255
256struct slot {
257 struct slot *next;
258 u8 bus;
259 u8 device;
260 u8 number;
261 u8 is_a_board;
262 u8 configured;
263 u8 state;
264 u8 switch_save;
265 u8 presence_save;
266 u32 capabilities;
267 u16 reserved2;
268 struct timer_list task_event;
269 u8 hp_slot;
270 struct controller *ctrl;
271 void __iomem *p_sm_slot;
272 struct hotplug_slot *hotplug_slot;
273};
274
275struct pci_resource {
276 struct pci_resource * next;
277 u32 base;
278 u32 length;
279};
280
281struct event_info {
282 u32 event_type;
283 u8 hp_slot;
284};
285
286struct controller {
287 struct controller *next;
288 u32 ctrl_int_comp;
289 struct semaphore crit_sect; /* critical section semaphore */
290 void __iomem *hpc_reg; /* cookie for our pci controller location */
291 struct pci_resource *mem_head;
292 struct pci_resource *p_mem_head;
293 struct pci_resource *io_head;
294 struct pci_resource *bus_head;
295 struct pci_dev *pci_dev;
296 struct pci_bus *pci_bus;
297 struct event_info event_queue[10];
298 struct slot *slot;
299 u8 next_event;
300 u8 interrupt;
301 u8 cfgspc_irq;
302 u8 bus; /* bus number for the pci hotplug controller */
303 u8 rev;
304 u8 slot_device_offset;
305 u8 first_slot;
306 u8 add_support;
307 u8 push_flag;
308 enum pci_bus_speed speed;
309 enum pci_bus_speed speed_capability;
310 u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */
311 u8 slot_switch_type; /* 0 = no switch, 1 = switch present */
312 u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */
313 u8 alternate_base_address; /* 0 = not supported, 1 = supported */
314 u8 pci_config_space; /* Index/data access to working registers 0 = not supported, 1 = supported */
315 u8 pcix_speed_capability; /* PCI-X */
316 u8 pcix_support; /* PCI-X */
317 u16 vendor_id;
318 struct work_struct int_task_event;
319 wait_queue_head_t queue; /* sleep & wake process */
320};
321
322struct irq_mapping {
323 u8 barber_pole;
324 u8 valid_INT;
325 u8 interrupt[4];
326};
327
328struct resource_lists {
329 struct pci_resource *mem_head;
330 struct pci_resource *p_mem_head;
331 struct pci_resource *io_head;
332 struct pci_resource *bus_head;
333 struct irq_mapping *irqs;
334};
335
336#define ROM_PHY_ADDR 0x0F0000
337#define ROM_PHY_LEN 0x00ffff
338
339#define PCI_HPC_ID 0xA0F7
340#define PCI_SUB_HPC_ID 0xA2F7
341#define PCI_SUB_HPC_ID2 0xA2F8
342#define PCI_SUB_HPC_ID3 0xA2F9
343#define PCI_SUB_HPC_ID_INTC 0xA2FA
344#define PCI_SUB_HPC_ID4 0xA2FD
345
346#define INT_BUTTON_IGNORE 0
347#define INT_PRESENCE_ON 1
348#define INT_PRESENCE_OFF 2
349#define INT_SWITCH_CLOSE 3
350#define INT_SWITCH_OPEN 4
351#define INT_POWER_FAULT 5
352#define INT_POWER_FAULT_CLEAR 6
353#define INT_BUTTON_PRESS 7
354#define INT_BUTTON_RELEASE 8
355#define INT_BUTTON_CANCEL 9
356
357#define STATIC_STATE 0
358#define BLINKINGON_STATE 1
359#define BLINKINGOFF_STATE 2
360#define POWERON_STATE 3
361#define POWEROFF_STATE 4
362
363#define PCISLOT_INTERLOCK_CLOSED 0x00000001
364#define PCISLOT_ADAPTER_PRESENT 0x00000002
365#define PCISLOT_POWERED 0x00000004
366#define PCISLOT_66_MHZ_OPERATION 0x00000008
367#define PCISLOT_64_BIT_OPERATION 0x00000010
368#define PCISLOT_REPLACE_SUPPORTED 0x00000020
369#define PCISLOT_ADD_SUPPORTED 0x00000040
370#define PCISLOT_INTERLOCK_SUPPORTED 0x00000080
371#define PCISLOT_66_MHZ_SUPPORTED 0x00000100
372#define PCISLOT_64_BIT_SUPPORTED 0x00000200
373
374#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
375
376#define INTERLOCK_OPEN 0x00000002
377#define ADD_NOT_SUPPORTED 0x00000003
378#define CARD_FUNCTIONING 0x00000005
379#define ADAPTER_NOT_SAME 0x00000006
380#define NO_ADAPTER_PRESENT 0x00000009
381#define NOT_ENOUGH_RESOURCES 0x0000000B
382#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
383#define POWER_FAILURE 0x0000000E
384
385#define REMOVE_NOT_SUPPORTED 0x00000003
386
387
388/*
389 * error Messages
390 */
391#define msg_initialization_err "Initialization failure, error=%d\n"
392#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
393#define msg_HPC_non_compaq_or_intel "The PCI hot plug controller is not supported by this driver.\n"
394#define msg_HPC_not_supported "this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
395#define msg_unable_to_save "unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
396#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
397#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
398#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
399#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
400
401
402/* sysfs functions for the hotplug controller info */
403extern void cpqhp_create_ctrl_files (struct controller *ctrl);
404
405/* controller functions */
406extern void cpqhp_pushbutton_thread (unsigned long event_pointer);
407extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data, struct pt_regs *regs);
408extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start);
409extern int cpqhp_event_start_thread (void);
410extern void cpqhp_event_stop_thread (void);
411extern struct pci_func *cpqhp_slot_create (unsigned char busnumber);
412extern struct pci_func *cpqhp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
413extern int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func);
414extern int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func);
415extern int cpqhp_hardware_test (struct controller *ctrl, int test_num);
416
417/* resource functions */
418extern int cpqhp_resource_sort_and_combine (struct pci_resource **head);
419
420/* pci functions */
421extern int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
422extern int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
423extern int cpqhp_save_config (struct controller *ctrl, int busnumber, int is_hot_plug);
424extern int cpqhp_save_base_addr_length (struct controller *ctrl, struct pci_func * func);
425extern int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func);
426extern int cpqhp_configure_board (struct controller *ctrl, struct pci_func * func);
427extern int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
428extern int cpqhp_valid_replace (struct controller *ctrl, struct pci_func * func);
429extern void cpqhp_destroy_board_resources (struct pci_func * func);
430extern int cpqhp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
431extern void cpqhp_destroy_resource_list (struct resource_lists * resources);
432extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func);
433extern int cpqhp_unconfigure_device (struct pci_func* func);
434
435/* Global variables */
436extern int cpqhp_debug;
437extern int cpqhp_legacy_mode;
438extern struct controller *cpqhp_ctrl_list;
439extern struct pci_func *cpqhp_slot_list[256];
440
441/* these can be gotten rid of, but for debugging they are purty */
442extern u8 cpqhp_nic_irq;
443extern u8 cpqhp_disk_irq;
444
445
446/* inline functions */
447
448/*
449 * return_resource
450 *
451 * Puts node back in the resource list pointed to by head
452 *
453 */
454static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
455{
456 if (!node || !head)
457 return;
458 node->next = *head;
459 *head = node;
460}
461
462static inline void set_SOGO(struct controller *ctrl)
463{
464 u16 misc;
465
466 misc = readw(ctrl->hpc_reg + MISC);
467 misc = (misc | 0x0001) & 0xFFFB;
468 writew(misc, ctrl->hpc_reg + MISC);
469}
470
471
472static inline void amber_LED_on(struct controller *ctrl, u8 slot)
473{
474 u32 led_control;
475
476 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
477 led_control |= (0x01010000L << slot);
478 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
479}
480
481
482static inline void amber_LED_off(struct controller *ctrl, u8 slot)
483{
484 u32 led_control;
485
486 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
487 led_control &= ~(0x01010000L << slot);
488 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
489}
490
491
492static inline int read_amber_LED(struct controller *ctrl, u8 slot)
493{
494 u32 led_control;
495
496 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
497 led_control &= (0x01010000L << slot);
498
499 return led_control ? 1 : 0;
500}
501
502
503static inline void green_LED_on(struct controller *ctrl, u8 slot)
504{
505 u32 led_control;
506
507 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
508 led_control |= 0x0101L << slot;
509 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
510}
511
512static inline void green_LED_off(struct controller *ctrl, u8 slot)
513{
514 u32 led_control;
515
516 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
517 led_control &= ~(0x0101L << slot);
518 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
519}
520
521
522static inline void green_LED_blink(struct controller *ctrl, u8 slot)
523{
524 u32 led_control;
525
526 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
527 led_control &= ~(0x0101L << slot);
528 led_control |= (0x0001L << slot);
529 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
530}
531
532
533static inline void slot_disable(struct controller *ctrl, u8 slot)
534{
535 u8 slot_enable;
536
537 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
538 slot_enable &= ~(0x01 << slot);
539 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
540}
541
542
543static inline void slot_enable(struct controller *ctrl, u8 slot)
544{
545 u8 slot_enable;
546
547 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
548 slot_enable |= (0x01 << slot);
549 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
550}
551
552
553static inline u8 is_slot_enabled(struct controller *ctrl, u8 slot)
554{
555 u8 slot_enable;
556
557 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
558 slot_enable &= (0x01 << slot);
559 return slot_enable ? 1 : 0;
560}
561
562
563static inline u8 read_slot_enable(struct controller *ctrl)
564{
565 return readb(ctrl->hpc_reg + SLOT_ENABLE);
566}
567
568
569/*
570 * get_controller_speed - find the current frequency/mode of controller.
571 *
572 * @ctrl: controller to get frequency/mode for.
573 *
574 * Returns controller speed.
575 *
576 */
577static inline u8 get_controller_speed(struct controller *ctrl)
578{
579 u8 curr_freq;
580 u16 misc;
581
582 if (ctrl->pcix_support) {
583 curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
584 if ((curr_freq & 0xB0) == 0xB0)
585 return PCI_SPEED_133MHz_PCIX;
586 if ((curr_freq & 0xA0) == 0xA0)
587 return PCI_SPEED_100MHz_PCIX;
588 if ((curr_freq & 0x90) == 0x90)
589 return PCI_SPEED_66MHz_PCIX;
590 if (curr_freq & 0x10)
591 return PCI_SPEED_66MHz;
592
593 return PCI_SPEED_33MHz;
594 }
595
596 misc = readw(ctrl->hpc_reg + MISC);
597 return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
598}
599
600
601/*
602 * get_adapter_speed - find the max supported frequency/mode of adapter.
603 *
604 * @ctrl: hotplug controller.
605 * @hp_slot: hotplug slot where adapter is installed.
606 *
607 * Returns adapter speed.
608 *
609 */
610static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
611{
612 u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
613 dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
614 if (ctrl->pcix_support) {
615 if (temp_dword & (0x10000 << hp_slot))
616 return PCI_SPEED_133MHz_PCIX;
617 if (temp_dword & (0x100 << hp_slot))
618 return PCI_SPEED_66MHz_PCIX;
619 }
620
621 if (temp_dword & (0x01 << hp_slot))
622 return PCI_SPEED_66MHz;
623
624 return PCI_SPEED_33MHz;
625}
626
627static inline void enable_slot_power(struct controller *ctrl, u8 slot)
628{
629 u8 slot_power;
630
631 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
632 slot_power |= (0x01 << slot);
633 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
634}
635
636static inline void disable_slot_power(struct controller *ctrl, u8 slot)
637{
638 u8 slot_power;
639
640 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
641 slot_power &= ~(0x01 << slot);
642 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
643}
644
645
646static inline int cpq_get_attention_status(struct controller *ctrl, struct slot *slot)
647{
648 u8 hp_slot;
649
650 hp_slot = slot->device - ctrl->slot_device_offset;
651
652 return read_amber_LED(ctrl, hp_slot);
653}
654
655
656static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
657{
658 u8 hp_slot;
659
660 hp_slot = slot->device - ctrl->slot_device_offset;
661
662 return is_slot_enabled(ctrl, hp_slot);
663}
664
665
666static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slot)
667{
668 u32 status;
669 u8 hp_slot;
670
671 hp_slot = slot->device - ctrl->slot_device_offset;
672 dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
673 __FUNCTION__, slot->device, ctrl->slot_device_offset);
674
675 status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
676
677 return(status == 0) ? 1 : 0;
678}
679
680
681static inline int get_presence_status(struct controller *ctrl, struct slot *slot)
682{
683 int presence_save = 0;
684 u8 hp_slot;
685 u32 tempdword;
686
687 hp_slot = slot->device - ctrl->slot_device_offset;
688
689 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
690 presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
691
692 return presence_save;
693}
694
695#define SLOT_NAME_SIZE 10
696
697static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
698{
699 snprintf(buffer, buffer_size, "%d", slot->number);
700}
701
702
703static inline int wait_for_ctrl_irq(struct controller *ctrl)
704{
705 DECLARE_WAITQUEUE(wait, current);
706 int retval = 0;
707
708 dbg("%s - start\n", __FUNCTION__);
709 add_wait_queue(&ctrl->queue, &wait);
710 /* Sleep for up to 1 second to wait for the LED to change. */
711 msleep_interruptible(1000);
712 remove_wait_queue(&ctrl->queue, &wait);
713 if (signal_pending(current))
714 retval = -EINTR;
715
716 dbg("%s - end\n", __FUNCTION__);
717 return retval;
718}
719
720#endif
721
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
new file mode 100644
index 000000000000..afbccfa5217d
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -0,0 +1,1509 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 * Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
28 * Torben Mathiasen <torben.mathiasen@hp.com>
29 *
30 */
31
32#include <linux/config.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/slab.h>
39#include <linux/workqueue.h>
40#include <linux/pci.h>
41#include <linux/init.h>
42#include <linux/interrupt.h>
43
44#include <asm/uaccess.h>
45
46#include "cpqphp.h"
47#include "cpqphp_nvram.h"
48#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */
49
50
51/* Global variables */
52int cpqhp_debug;
53int cpqhp_legacy_mode;
54struct controller *cpqhp_ctrl_list; /* = NULL */
55struct pci_func *cpqhp_slot_list[256];
56
57/* local variables */
58static void __iomem *smbios_table;
59static void __iomem *smbios_start;
60static void __iomem *cpqhp_rom_start;
61static int power_mode;
62static int debug;
63
64#define DRIVER_VERSION "0.9.8"
65#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
66#define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver"
67
68MODULE_AUTHOR(DRIVER_AUTHOR);
69MODULE_DESCRIPTION(DRIVER_DESC);
70MODULE_LICENSE("GPL");
71
72module_param(power_mode, bool, 0644);
73MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
74
75module_param(debug, bool, 0644);
76MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
77
78#define CPQHPC_MODULE_MINOR 208
79
80static int one_time_init (void);
81static int set_attention_status (struct hotplug_slot *slot, u8 value);
82static int process_SI (struct hotplug_slot *slot);
83static int process_SS (struct hotplug_slot *slot);
84static int hardware_test (struct hotplug_slot *slot, u32 value);
85static int get_power_status (struct hotplug_slot *slot, u8 *value);
86static int get_attention_status (struct hotplug_slot *slot, u8 *value);
87static int get_latch_status (struct hotplug_slot *slot, u8 *value);
88static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
89static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
90static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
91
92static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
93 .owner = THIS_MODULE,
94 .set_attention_status = set_attention_status,
95 .enable_slot = process_SI,
96 .disable_slot = process_SS,
97 .hardware_test = hardware_test,
98 .get_power_status = get_power_status,
99 .get_attention_status = get_attention_status,
100 .get_latch_status = get_latch_status,
101 .get_adapter_status = get_adapter_status,
102 .get_max_bus_speed = get_max_bus_speed,
103 .get_cur_bus_speed = get_cur_bus_speed,
104};
105
106
107static inline int is_slot64bit(struct slot *slot)
108{
109 return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
110}
111
112static inline int is_slot66mhz(struct slot *slot)
113{
114 return (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E) ? 1 : 0;
115}
116
117/**
118 * detect_SMBIOS_pointer - find the System Management BIOS Table in mem region.
119 *
120 * @begin: begin pointer for region to be scanned.
121 * @end: end pointer for region to be scanned.
122 *
123 * Returns pointer to the head of the SMBIOS tables (or NULL)
124 *
125 */
126static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
127{
128 void __iomem *fp;
129 void __iomem *endp;
130 u8 temp1, temp2, temp3, temp4;
131 int status = 0;
132
133 endp = (end - sizeof(u32) + 1);
134
135 for (fp = begin; fp <= endp; fp += 16) {
136 temp1 = readb(fp);
137 temp2 = readb(fp+1);
138 temp3 = readb(fp+2);
139 temp4 = readb(fp+3);
140 if (temp1 == '_' &&
141 temp2 == 'S' &&
142 temp3 == 'M' &&
143 temp4 == '_') {
144 status = 1;
145 break;
146 }
147 }
148
149 if (!status)
150 fp = NULL;
151
152 dbg("Discovered SMBIOS Entry point at %p\n", fp);
153
154 return fp;
155}
156
157/**
158 * init_SERR - Initializes the per slot SERR generation.
159 *
160 * For unexpected switch opens
161 *
162 */
163static int init_SERR(struct controller * ctrl)
164{
165 u32 tempdword;
166 u32 number_of_slots;
167 u8 physical_slot;
168
169 if (!ctrl)
170 return 1;
171
172 tempdword = ctrl->first_slot;
173
174 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
175 // Loop through slots
176 while (number_of_slots) {
177 physical_slot = tempdword;
178 writeb(0, ctrl->hpc_reg + SLOT_SERR);
179 tempdword++;
180 number_of_slots--;
181 }
182
183 return 0;
184}
185
186
187/* nice debugging output */
188static int pci_print_IRQ_route (void)
189{
190 struct irq_routing_table *routing_table;
191 int len;
192 int loop;
193
194 u8 tbus, tdevice, tslot;
195
196 routing_table = pcibios_get_irq_routing_table();
197 if (routing_table == NULL) {
198 err("No BIOS Routing Table??? Not good\n");
199 return -ENOMEM;
200 }
201
202 len = (routing_table->size - sizeof(struct irq_routing_table)) /
203 sizeof(struct irq_info);
204 // Make sure I got at least one entry
205 if (len == 0) {
206 kfree(routing_table);
207 return -1;
208 }
209
210 dbg("bus dev func slot\n");
211
212 for (loop = 0; loop < len; ++loop) {
213 tbus = routing_table->slots[loop].bus;
214 tdevice = routing_table->slots[loop].devfn;
215 tslot = routing_table->slots[loop].slot;
216 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
217
218 }
219 kfree(routing_table);
220 return 0;
221}
222
223
224/**
225 * get_subsequent_smbios_entry: get the next entry from bios table.
226 *
227 * Gets the first entry if previous == NULL
228 * Otherwise, returns the next entry
229 * Uses global SMBIOS Table pointer
230 *
231 * @curr: %NULL or pointer to previously returned structure
232 *
233 * returns a pointer to an SMBIOS structure or NULL if none found
234 */
235static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
236 void __iomem *smbios_table,
237 void __iomem *curr)
238{
239 u8 bail = 0;
240 u8 previous_byte = 1;
241 void __iomem *p_temp;
242 void __iomem *p_max;
243
244 if (!smbios_table || !curr)
245 return(NULL);
246
247 // set p_max to the end of the table
248 p_max = smbios_start + readw(smbios_table + ST_LENGTH);
249
250 p_temp = curr;
251 p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
252
253 while ((p_temp < p_max) && !bail) {
254 /* Look for the double NULL terminator
255 * The first condition is the previous byte
256 * and the second is the curr */
257 if (!previous_byte && !(readb(p_temp))) {
258 bail = 1;
259 }
260
261 previous_byte = readb(p_temp);
262 p_temp++;
263 }
264
265 if (p_temp < p_max) {
266 return p_temp;
267 } else {
268 return NULL;
269 }
270}
271
272
273/**
274 * get_SMBIOS_entry
275 *
276 * @type:SMBIOS structure type to be returned
277 * @previous: %NULL or pointer to previously returned structure
278 *
279 * Gets the first entry of the specified type if previous == NULL
280 * Otherwise, returns the next entry of the given type.
281 * Uses global SMBIOS Table pointer
282 * Uses get_subsequent_smbios_entry
283 *
284 * returns a pointer to an SMBIOS structure or %NULL if none found
285 */
286static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
287 void __iomem *smbios_table,
288 u8 type,
289 void __iomem *previous)
290{
291 if (!smbios_table)
292 return NULL;
293
294 if (!previous) {
295 previous = smbios_start;
296 } else {
297 previous = get_subsequent_smbios_entry(smbios_start,
298 smbios_table, previous);
299 }
300
301 while (previous) {
302 if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
303 previous = get_subsequent_smbios_entry(smbios_start,
304 smbios_table, previous);
305 } else {
306 break;
307 }
308 }
309
310 return previous;
311}
312
313static void release_slot(struct hotplug_slot *hotplug_slot)
314{
315 struct slot *slot = hotplug_slot->private;
316
317 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
318
319 kfree(slot->hotplug_slot->info);
320 kfree(slot->hotplug_slot->name);
321 kfree(slot->hotplug_slot);
322 kfree(slot);
323}
324
325static int ctrl_slot_setup(struct controller *ctrl,
326 void __iomem *smbios_start,
327 void __iomem *smbios_table)
328{
329 struct slot *new_slot;
330 u8 number_of_slots;
331 u8 slot_device;
332 u8 slot_number;
333 u8 ctrl_slot;
334 u32 tempdword;
335 void __iomem *slot_entry= NULL;
336 int result = -ENOMEM;
337
338 dbg("%s\n", __FUNCTION__);
339
340 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
341
342 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
343 slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
344 slot_number = ctrl->first_slot;
345
346 while (number_of_slots) {
347 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
348 if (!new_slot)
349 goto error;
350
351 memset(new_slot, 0, sizeof(struct slot));
352 new_slot->hotplug_slot = kmalloc(sizeof(*(new_slot->hotplug_slot)),
353 GFP_KERNEL);
354 if (!new_slot->hotplug_slot)
355 goto error_slot;
356 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
357
358 new_slot->hotplug_slot->info =
359 kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
360 GFP_KERNEL);
361 if (!new_slot->hotplug_slot->info)
362 goto error_hpslot;
363 memset(new_slot->hotplug_slot->info, 0,
364 sizeof(struct hotplug_slot_info));
365 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
366 if (!new_slot->hotplug_slot->name)
367 goto error_info;
368
369 new_slot->ctrl = ctrl;
370 new_slot->bus = ctrl->bus;
371 new_slot->device = slot_device;
372 new_slot->number = slot_number;
373 dbg("slot->number = %d\n",new_slot->number);
374
375 slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
376 slot_entry);
377
378 while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
379 slot_entry = get_SMBIOS_entry(smbios_start,
380 smbios_table, 9, slot_entry);
381 }
382
383 new_slot->p_sm_slot = slot_entry;
384
385 init_timer(&new_slot->task_event);
386 new_slot->task_event.expires = jiffies + 5 * HZ;
387 new_slot->task_event.function = cpqhp_pushbutton_thread;
388
389 //FIXME: these capabilities aren't used but if they are
390 // they need to be correctly implemented
391 new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
392 new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
393
394 if (is_slot64bit(new_slot))
395 new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
396 if (is_slot66mhz(new_slot))
397 new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
398 if (ctrl->speed == PCI_SPEED_66MHz)
399 new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
400
401 ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
402
403 // Check presence
404 new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
405 // Check the switch state
406 new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
407 // Check the slot enable
408 new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
409
410 /* register this slot with the hotplug pci core */
411 new_slot->hotplug_slot->release = &release_slot;
412 new_slot->hotplug_slot->private = new_slot;
413 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
414 new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
415
416 new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
417 new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
418 new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
419 new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
420
421 dbg ("registering bus %d, dev %d, number %d, "
422 "ctrl->slot_device_offset %d, slot %d\n",
423 new_slot->bus, new_slot->device,
424 new_slot->number, ctrl->slot_device_offset,
425 slot_number);
426 result = pci_hp_register (new_slot->hotplug_slot);
427 if (result) {
428 err ("pci_hp_register failed with error %d\n", result);
429 goto error_name;
430 }
431
432 new_slot->next = ctrl->slot;
433 ctrl->slot = new_slot;
434
435 number_of_slots--;
436 slot_device++;
437 slot_number++;
438 }
439
440 return 0;
441
442error_name:
443 kfree(new_slot->hotplug_slot->name);
444error_info:
445 kfree(new_slot->hotplug_slot->info);
446error_hpslot:
447 kfree(new_slot->hotplug_slot);
448error_slot:
449 kfree(new_slot);
450error:
451 return result;
452}
453
454static int ctrl_slot_cleanup (struct controller * ctrl)
455{
456 struct slot *old_slot, *next_slot;
457
458 old_slot = ctrl->slot;
459 ctrl->slot = NULL;
460
461 while (old_slot) {
462 /* memory will be freed by the release_slot callback */
463 next_slot = old_slot->next;
464 pci_hp_deregister (old_slot->hotplug_slot);
465 old_slot = next_slot;
466 }
467
468 //Free IRQ associated with hot plug device
469 free_irq(ctrl->interrupt, ctrl);
470 //Unmap the memory
471 iounmap(ctrl->hpc_reg);
472 //Finally reclaim PCI mem
473 release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
474 pci_resource_len(ctrl->pci_dev, 0));
475
476 return(0);
477}
478
479
480//============================================================================
481// function: get_slot_mapping
482//
483// Description: Attempts to determine a logical slot mapping for a PCI
484// device. Won't work for more than one PCI-PCI bridge
485// in a slot.
486//
487// Input: u8 bus_num - bus number of PCI device
488// u8 dev_num - device number of PCI device
489// u8 *slot - Pointer to u8 where slot number will
490// be returned
491//
492// Output: SUCCESS or FAILURE
493//=============================================================================
494static int
495get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
496{
497 struct irq_routing_table *PCIIRQRoutingInfoLength;
498 u32 work;
499 long len;
500 long loop;
501
502 u8 tbus, tdevice, tslot, bridgeSlot;
503
504 dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
505
506 bridgeSlot = 0xFF;
507
508 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
509 if (!PCIIRQRoutingInfoLength)
510 return -1;
511
512 len = (PCIIRQRoutingInfoLength->size -
513 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
514 // Make sure I got at least one entry
515 if (len == 0) {
516 kfree(PCIIRQRoutingInfoLength);
517 return -1;
518 }
519
520 for (loop = 0; loop < len; ++loop) {
521 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
522 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
523 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
524
525 if ((tbus == bus_num) && (tdevice == dev_num)) {
526 *slot = tslot;
527 kfree(PCIIRQRoutingInfoLength);
528 return 0;
529 } else {
530 /* Did not get a match on the target PCI device. Check
531 * if the current IRQ table entry is a PCI-to-PCI bridge
532 * device. If so, and it's secondary bus matches the
533 * bus number for the target device, I need to save the
534 * bridge's slot number. If I can not find an entry for
535 * the target device, I will have to assume it's on the
536 * other side of the bridge, and assign it the bridge's
537 * slot. */
538 bus->number = tbus;
539 pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
540 PCI_REVISION_ID, &work);
541
542 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
543 pci_bus_read_config_dword(bus,
544 PCI_DEVFN(tdevice, 0),
545 PCI_PRIMARY_BUS, &work);
546 // See if bridge's secondary bus matches target bus.
547 if (((work >> 8) & 0x000000FF) == (long) bus_num) {
548 bridgeSlot = tslot;
549 }
550 }
551 }
552
553 }
554
555 // If we got here, we didn't find an entry in the IRQ mapping table
556 // for the target PCI device. If we did determine that the target
557 // device is on the other side of a PCI-to-PCI bridge, return the
558 // slot number for the bridge.
559 if (bridgeSlot != 0xFF) {
560 *slot = bridgeSlot;
561 kfree(PCIIRQRoutingInfoLength);
562 return 0;
563 }
564 kfree(PCIIRQRoutingInfoLength);
565 // Couldn't find an entry in the routing table for this PCI device
566 return -1;
567}
568
569
570/**
571 * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
572 *
573 */
574static int
575cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
576 u32 status)
577{
578 u8 hp_slot;
579
580 if (func == NULL)
581 return(1);
582
583 hp_slot = func->device - ctrl->slot_device_offset;
584
585 // Wait for exclusive access to hardware
586 down(&ctrl->crit_sect);
587
588 if (status == 1) {
589 amber_LED_on (ctrl, hp_slot);
590 } else if (status == 0) {
591 amber_LED_off (ctrl, hp_slot);
592 } else {
593 // Done with exclusive hardware access
594 up(&ctrl->crit_sect);
595 return(1);
596 }
597
598 set_SOGO(ctrl);
599
600 // Wait for SOBS to be unset
601 wait_for_ctrl_irq (ctrl);
602
603 // Done with exclusive hardware access
604 up(&ctrl->crit_sect);
605
606 return(0);
607}
608
609
610/**
611 * set_attention_status - Turns the Amber LED for a slot on or off
612 *
613 */
614static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
615{
616 struct pci_func *slot_func;
617 struct slot *slot = hotplug_slot->private;
618 struct controller *ctrl = slot->ctrl;
619 u8 bus;
620 u8 devfn;
621 u8 device;
622 u8 function;
623
624 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
625
626 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
627 return -ENODEV;
628
629 device = devfn >> 3;
630 function = devfn & 0x7;
631 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
632
633 slot_func = cpqhp_slot_find(bus, device, function);
634 if (!slot_func)
635 return -ENODEV;
636
637 return cpqhp_set_attention_status(ctrl, slot_func, status);
638}
639
640
641static int process_SI(struct hotplug_slot *hotplug_slot)
642{
643 struct pci_func *slot_func;
644 struct slot *slot = hotplug_slot->private;
645 struct controller *ctrl = slot->ctrl;
646 u8 bus;
647 u8 devfn;
648 u8 device;
649 u8 function;
650
651 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
652
653 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
654 return -ENODEV;
655
656 device = devfn >> 3;
657 function = devfn & 0x7;
658 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
659
660 slot_func = cpqhp_slot_find(bus, device, function);
661 if (!slot_func)
662 return -ENODEV;
663
664 slot_func->bus = bus;
665 slot_func->device = device;
666 slot_func->function = function;
667 slot_func->configured = 0;
668 dbg("board_added(%p, %p)\n", slot_func, ctrl);
669 return cpqhp_process_SI(ctrl, slot_func);
670}
671
672
673static int process_SS(struct hotplug_slot *hotplug_slot)
674{
675 struct pci_func *slot_func;
676 struct slot *slot = hotplug_slot->private;
677 struct controller *ctrl = slot->ctrl;
678 u8 bus;
679 u8 devfn;
680 u8 device;
681 u8 function;
682
683 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
684
685 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
686 return -ENODEV;
687
688 device = devfn >> 3;
689 function = devfn & 0x7;
690 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
691
692 slot_func = cpqhp_slot_find(bus, device, function);
693 if (!slot_func)
694 return -ENODEV;
695
696 dbg("In %s, slot_func = %p, ctrl = %p\n", __FUNCTION__, slot_func, ctrl);
697 return cpqhp_process_SS(ctrl, slot_func);
698}
699
700
701static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
702{
703 struct slot *slot = hotplug_slot->private;
704 struct controller *ctrl = slot->ctrl;
705
706 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
707
708 return cpqhp_hardware_test(ctrl, value);
709}
710
711
712static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
713{
714 struct slot *slot = hotplug_slot->private;
715 struct controller *ctrl = slot->ctrl;
716
717 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
718
719 *value = get_slot_enabled(ctrl, slot);
720 return 0;
721}
722
723static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
724{
725 struct slot *slot = hotplug_slot->private;
726 struct controller *ctrl = slot->ctrl;
727
728 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
729
730 *value = cpq_get_attention_status(ctrl, slot);
731 return 0;
732}
733
734static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
735{
736 struct slot *slot = hotplug_slot->private;
737 struct controller *ctrl = slot->ctrl;
738
739 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
740
741 *value = cpq_get_latch_status(ctrl, slot);
742
743 return 0;
744}
745
746static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
747{
748 struct slot *slot = hotplug_slot->private;
749 struct controller *ctrl = slot->ctrl;
750
751 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
752
753 *value = get_presence_status(ctrl, slot);
754
755 return 0;
756}
757
758static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
759{
760 struct slot *slot = hotplug_slot->private;
761 struct controller *ctrl = slot->ctrl;
762
763 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
764
765 *value = ctrl->speed_capability;
766
767 return 0;
768}
769
770static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
771{
772 struct slot *slot = hotplug_slot->private;
773 struct controller *ctrl = slot->ctrl;
774
775 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
776
777 *value = ctrl->speed;
778
779 return 0;
780}
781
782static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
783{
784 u8 num_of_slots = 0;
785 u8 hp_slot = 0;
786 u8 device;
787 u8 rev;
788 u8 bus_cap;
789 u16 temp_word;
790 u16 vendor_id;
791 u16 subsystem_vid;
792 u16 subsystem_deviceid;
793 u32 rc;
794 struct controller *ctrl;
795 struct pci_func *func;
796
797 // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
798 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
799 if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
800 err(msg_HPC_non_compaq_or_intel);
801 return -ENODEV;
802 }
803 dbg("Vendor ID: %x\n", vendor_id);
804
805 rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
806 dbg("revision: %d\n", rev);
807 if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
808 err(msg_HPC_rev_error);
809 return -ENODEV;
810 }
811
812 /* Check for the proper subsytem ID's
813 * Intel uses a different SSID programming model than Compaq.
814 * For Intel, each SSID bit identifies a PHP capability.
815 * Also Intel HPC's may have RID=0.
816 */
817 if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
818 // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
819 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
820 if (rc) {
821 err("%s : pci_read_config_word failed\n", __FUNCTION__);
822 return rc;
823 }
824 dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
825 if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
826 err(msg_HPC_non_compaq_or_intel);
827 return -ENODEV;
828 }
829
830 ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
831 if (!ctrl) {
832 err("%s : out of memory\n", __FUNCTION__);
833 return -ENOMEM;
834 }
835 memset(ctrl, 0, sizeof(struct controller));
836
837 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
838 if (rc) {
839 err("%s : pci_read_config_word failed\n", __FUNCTION__);
840 goto err_free_ctrl;
841 }
842
843 info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
844
845 /* Set Vendor ID, so it can be accessed later from other functions */
846 ctrl->vendor_id = vendor_id;
847
848 switch (subsystem_vid) {
849 case PCI_VENDOR_ID_COMPAQ:
850 if (rev >= 0x13) { /* CIOBX */
851 ctrl->push_flag = 1;
852 ctrl->slot_switch_type = 1;
853 ctrl->push_button = 1;
854 ctrl->pci_config_space = 1;
855 ctrl->defeature_PHP = 1;
856 ctrl->pcix_support = 1;
857 ctrl->pcix_speed_capability = 1;
858 pci_read_config_byte(pdev, 0x41, &bus_cap);
859 if (bus_cap & 0x80) {
860 dbg("bus max supports 133MHz PCI-X\n");
861 ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
862 break;
863 }
864 if (bus_cap & 0x40) {
865 dbg("bus max supports 100MHz PCI-X\n");
866 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
867 break;
868 }
869 if (bus_cap & 20) {
870 dbg("bus max supports 66MHz PCI-X\n");
871 ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
872 break;
873 }
874 if (bus_cap & 10) {
875 dbg("bus max supports 66MHz PCI\n");
876 ctrl->speed_capability = PCI_SPEED_66MHz;
877 break;
878 }
879
880 break;
881 }
882
883 switch (subsystem_deviceid) {
884 case PCI_SUB_HPC_ID:
885 /* Original 6500/7000 implementation */
886 ctrl->slot_switch_type = 1;
887 ctrl->speed_capability = PCI_SPEED_33MHz;
888 ctrl->push_button = 0;
889 ctrl->pci_config_space = 1;
890 ctrl->defeature_PHP = 1;
891 ctrl->pcix_support = 0;
892 ctrl->pcix_speed_capability = 0;
893 break;
894 case PCI_SUB_HPC_ID2:
895 /* First Pushbutton implementation */
896 ctrl->push_flag = 1;
897 ctrl->slot_switch_type = 1;
898 ctrl->speed_capability = PCI_SPEED_33MHz;
899 ctrl->push_button = 1;
900 ctrl->pci_config_space = 1;
901 ctrl->defeature_PHP = 1;
902 ctrl->pcix_support = 0;
903 ctrl->pcix_speed_capability = 0;
904 break;
905 case PCI_SUB_HPC_ID_INTC:
906 /* Third party (6500/7000) */
907 ctrl->slot_switch_type = 1;
908 ctrl->speed_capability = PCI_SPEED_33MHz;
909 ctrl->push_button = 0;
910 ctrl->pci_config_space = 1;
911 ctrl->defeature_PHP = 1;
912 ctrl->pcix_support = 0;
913 ctrl->pcix_speed_capability = 0;
914 break;
915 case PCI_SUB_HPC_ID3:
916 /* First 66 Mhz implementation */
917 ctrl->push_flag = 1;
918 ctrl->slot_switch_type = 1;
919 ctrl->speed_capability = PCI_SPEED_66MHz;
920 ctrl->push_button = 1;
921 ctrl->pci_config_space = 1;
922 ctrl->defeature_PHP = 1;
923 ctrl->pcix_support = 0;
924 ctrl->pcix_speed_capability = 0;
925 break;
926 case PCI_SUB_HPC_ID4:
927 /* First PCI-X implementation, 100MHz */
928 ctrl->push_flag = 1;
929 ctrl->slot_switch_type = 1;
930 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
931 ctrl->push_button = 1;
932 ctrl->pci_config_space = 1;
933 ctrl->defeature_PHP = 1;
934 ctrl->pcix_support = 1;
935 ctrl->pcix_speed_capability = 0;
936 break;
937 default:
938 err(msg_HPC_not_supported);
939 rc = -ENODEV;
940 goto err_free_ctrl;
941 }
942 break;
943
944 case PCI_VENDOR_ID_INTEL:
945 /* Check for speed capability (0=33, 1=66) */
946 if (subsystem_deviceid & 0x0001) {
947 ctrl->speed_capability = PCI_SPEED_66MHz;
948 } else {
949 ctrl->speed_capability = PCI_SPEED_33MHz;
950 }
951
952 /* Check for push button */
953 if (subsystem_deviceid & 0x0002) {
954 /* no push button */
955 ctrl->push_button = 0;
956 } else {
957 /* push button supported */
958 ctrl->push_button = 1;
959 }
960
961 /* Check for slot switch type (0=mechanical, 1=not mechanical) */
962 if (subsystem_deviceid & 0x0004) {
963 /* no switch */
964 ctrl->slot_switch_type = 0;
965 } else {
966 /* switch */
967 ctrl->slot_switch_type = 1;
968 }
969
970 /* PHP Status (0=De-feature PHP, 1=Normal operation) */
971 if (subsystem_deviceid & 0x0008) {
972 ctrl->defeature_PHP = 1; // PHP supported
973 } else {
974 ctrl->defeature_PHP = 0; // PHP not supported
975 }
976
977 /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
978 if (subsystem_deviceid & 0x0010) {
979 ctrl->alternate_base_address = 1; // supported
980 } else {
981 ctrl->alternate_base_address = 0; // not supported
982 }
983
984 /* PCI Config Space Index (0=not supported, 1=supported) */
985 if (subsystem_deviceid & 0x0020) {
986 ctrl->pci_config_space = 1; // supported
987 } else {
988 ctrl->pci_config_space = 0; // not supported
989 }
990
991 /* PCI-X support */
992 if (subsystem_deviceid & 0x0080) {
993 /* PCI-X capable */
994 ctrl->pcix_support = 1;
995 /* Frequency of operation in PCI-X mode */
996 if (subsystem_deviceid & 0x0040) {
997 /* 133MHz PCI-X if bit 7 is 1 */
998 ctrl->pcix_speed_capability = 1;
999 } else {
1000 /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
1001 /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
1002 ctrl->pcix_speed_capability = 0;
1003 }
1004 } else {
1005 /* Conventional PCI */
1006 ctrl->pcix_support = 0;
1007 ctrl->pcix_speed_capability = 0;
1008 }
1009 break;
1010
1011 default:
1012 err(msg_HPC_not_supported);
1013 rc = -ENODEV;
1014 goto err_free_ctrl;
1015 }
1016
1017 } else {
1018 err(msg_HPC_not_supported);
1019 return -ENODEV;
1020 }
1021
1022 // Tell the user that we found one.
1023 info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
1024 pdev->bus->number);
1025
1026 dbg("Hotplug controller capabilities:\n");
1027 dbg(" speed_capability %d\n", ctrl->speed_capability);
1028 dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ?
1029 "switch present" : "no switch");
1030 dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ?
1031 "PHP supported" : "PHP not supported");
1032 dbg(" alternate_base_address %s\n", ctrl->alternate_base_address ?
1033 "supported" : "not supported");
1034 dbg(" pci_config_space %s\n", ctrl->pci_config_space ?
1035 "supported" : "not supported");
1036 dbg(" pcix_speed_capability %s\n", ctrl->pcix_speed_capability ?
1037 "supported" : "not supported");
1038 dbg(" pcix_support %s\n", ctrl->pcix_support ?
1039 "supported" : "not supported");
1040
1041 ctrl->pci_dev = pdev;
1042 pci_set_drvdata(pdev, ctrl);
1043
1044 /* make our own copy of the pci bus structure,
1045 * as we like tweaking it a lot */
1046 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
1047 if (!ctrl->pci_bus) {
1048 err("out of memory\n");
1049 rc = -ENOMEM;
1050 goto err_free_ctrl;
1051 }
1052 memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
1053
1054 ctrl->bus = pdev->bus->number;
1055 ctrl->rev = rev;
1056 dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
1057 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
1058
1059 init_MUTEX(&ctrl->crit_sect);
1060 init_waitqueue_head(&ctrl->queue);
1061
1062 /* initialize our threads if they haven't already been started up */
1063 rc = one_time_init();
1064 if (rc) {
1065 goto err_free_bus;
1066 }
1067
1068 dbg("pdev = %p\n", pdev);
1069 dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
1070 dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
1071
1072 if (!request_mem_region(pci_resource_start(pdev, 0),
1073 pci_resource_len(pdev, 0), MY_NAME)) {
1074 err("cannot reserve MMIO region\n");
1075 rc = -ENOMEM;
1076 goto err_free_bus;
1077 }
1078
1079 ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0),
1080 pci_resource_len(pdev, 0));
1081 if (!ctrl->hpc_reg) {
1082 err("cannot remap MMIO region %lx @ %lx\n",
1083 pci_resource_len(pdev, 0),
1084 pci_resource_start(pdev, 0));
1085 rc = -ENODEV;
1086 goto err_free_mem_region;
1087 }
1088
1089 // Check for 66Mhz operation
1090 ctrl->speed = get_controller_speed(ctrl);
1091
1092
1093 /********************************************************
1094 *
1095 * Save configuration headers for this and
1096 * subordinate PCI buses
1097 *
1098 ********************************************************/
1099
1100 // find the physical slot number of the first hot plug slot
1101
1102 /* Get slot won't work for devices behind bridges, but
1103 * in this case it will always be called for the "base"
1104 * bus/dev/func of a slot.
1105 * CS: this is leveraging the PCIIRQ routing code from the kernel
1106 * (pci-pc.c: get_irq_routing_table) */
1107 rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number,
1108 (readb(ctrl->hpc_reg + SLOT_MASK) >> 4),
1109 &(ctrl->first_slot));
1110 dbg("get_slot_mapping: first_slot = %d, returned = %d\n",
1111 ctrl->first_slot, rc);
1112 if (rc) {
1113 err(msg_initialization_err, rc);
1114 goto err_iounmap;
1115 }
1116
1117 // Store PCI Config Space for all devices on this bus
1118 rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
1119 if (rc) {
1120 err("%s: unable to save PCI configuration data, error %d\n",
1121 __FUNCTION__, rc);
1122 goto err_iounmap;
1123 }
1124
1125 /*
1126 * Get IO, memory, and IRQ resources for new devices
1127 */
1128 // The next line is required for cpqhp_find_available_resources
1129 ctrl->interrupt = pdev->irq;
1130 if (ctrl->interrupt < 0x10) {
1131 cpqhp_legacy_mode = 1;
1132 dbg("System seems to be configured for Full Table Mapped MPS mode\n");
1133 }
1134
1135 ctrl->cfgspc_irq = 0;
1136 pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
1137
1138 rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
1139 ctrl->add_support = !rc;
1140 if (rc) {
1141 dbg("cpqhp_find_available_resources = 0x%x\n", rc);
1142 err("unable to locate PCI configuration resources for hot plug add.\n");
1143 goto err_iounmap;
1144 }
1145
1146 /*
1147 * Finish setting up the hot plug ctrl device
1148 */
1149 ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1150 dbg("NumSlots %d \n", ctrl->slot_device_offset);
1151
1152 ctrl->next_event = 0;
1153
1154 /* Setup the slot information structures */
1155 rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
1156 if (rc) {
1157 err(msg_initialization_err, 6);
1158 err("%s: unable to save PCI configuration data, error %d\n",
1159 __FUNCTION__, rc);
1160 goto err_iounmap;
1161 }
1162
1163 /* Mask all general input interrupts */
1164 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
1165
1166 /* set up the interrupt */
1167 dbg("HPC interrupt = %d \n", ctrl->interrupt);
1168 if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
1169 SA_SHIRQ, MY_NAME, ctrl)) {
1170 err("Can't get irq %d for the hotplug pci controller\n",
1171 ctrl->interrupt);
1172 rc = -ENODEV;
1173 goto err_iounmap;
1174 }
1175
1176 /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
1177 temp_word = readw(ctrl->hpc_reg + MISC);
1178 temp_word |= 0x4006;
1179 writew(temp_word, ctrl->hpc_reg + MISC);
1180
1181 // Changed 05/05/97 to clear all interrupts at start
1182 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
1183
1184 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
1185
1186 writel(0x0L, ctrl->hpc_reg + INT_MASK);
1187
1188 if (!cpqhp_ctrl_list) {
1189 cpqhp_ctrl_list = ctrl;
1190 ctrl->next = NULL;
1191 } else {
1192 ctrl->next = cpqhp_ctrl_list;
1193 cpqhp_ctrl_list = ctrl;
1194 }
1195
1196 // turn off empty slots here unless command line option "ON" set
1197 // Wait for exclusive access to hardware
1198 down(&ctrl->crit_sect);
1199
1200 num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
1201
1202 // find first device number for the ctrl
1203 device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1204
1205 while (num_of_slots) {
1206 dbg("num_of_slots: %d\n", num_of_slots);
1207 func = cpqhp_slot_find(ctrl->bus, device, 0);
1208 if (!func)
1209 break;
1210
1211 hp_slot = func->device - ctrl->slot_device_offset;
1212 dbg("hp_slot: %d\n", hp_slot);
1213
1214 // We have to save the presence info for these slots
1215 temp_word = ctrl->ctrl_int_comp >> 16;
1216 func->presence_save = (temp_word >> hp_slot) & 0x01;
1217 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
1218
1219 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
1220 func->switch_save = 0;
1221 } else {
1222 func->switch_save = 0x10;
1223 }
1224
1225 if (!power_mode) {
1226 if (!func->is_a_board) {
1227 green_LED_off(ctrl, hp_slot);
1228 slot_disable(ctrl, hp_slot);
1229 }
1230 }
1231
1232 device++;
1233 num_of_slots--;
1234 }
1235
1236 if (!power_mode) {
1237 set_SOGO(ctrl);
1238 // Wait for SOBS to be unset
1239 wait_for_ctrl_irq(ctrl);
1240 }
1241
1242 rc = init_SERR(ctrl);
1243 if (rc) {
1244 err("init_SERR failed\n");
1245 up(&ctrl->crit_sect);
1246 goto err_free_irq;
1247 }
1248
1249 // Done with exclusive hardware access
1250 up(&ctrl->crit_sect);
1251
1252 cpqhp_create_ctrl_files(ctrl);
1253
1254 return 0;
1255
1256err_free_irq:
1257 free_irq(ctrl->interrupt, ctrl);
1258err_iounmap:
1259 iounmap(ctrl->hpc_reg);
1260err_free_mem_region:
1261 release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1262err_free_bus:
1263 kfree(ctrl->pci_bus);
1264err_free_ctrl:
1265 kfree(ctrl);
1266 return rc;
1267}
1268
1269
1270static int one_time_init(void)
1271{
1272 int loop;
1273 int retval = 0;
1274 static int initialized = 0;
1275
1276 if (initialized)
1277 return 0;
1278
1279 power_mode = 0;
1280
1281 retval = pci_print_IRQ_route();
1282 if (retval)
1283 goto error;
1284
1285 dbg("Initialize + Start the notification mechanism \n");
1286
1287 retval = cpqhp_event_start_thread();
1288 if (retval)
1289 goto error;
1290
1291 dbg("Initialize slot lists\n");
1292 for (loop = 0; loop < 256; loop++) {
1293 cpqhp_slot_list[loop] = NULL;
1294 }
1295
1296 // FIXME: We also need to hook the NMI handler eventually.
1297 // this also needs to be worked with Christoph
1298 // register_NMI_handler();
1299
1300 // Map rom address
1301 cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
1302 if (!cpqhp_rom_start) {
1303 err ("Could not ioremap memory region for ROM\n");
1304 retval = -EIO;
1305 goto error;
1306 }
1307
1308 /* Now, map the int15 entry point if we are on compaq specific hardware */
1309 compaq_nvram_init(cpqhp_rom_start);
1310
1311 /* Map smbios table entry point structure */
1312 smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
1313 cpqhp_rom_start + ROM_PHY_LEN);
1314 if (!smbios_table) {
1315 err ("Could not find the SMBIOS pointer in memory\n");
1316 retval = -EIO;
1317 goto error_rom_start;
1318 }
1319
1320 smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
1321 readw(smbios_table + ST_LENGTH));
1322 if (!smbios_start) {
1323 err ("Could not ioremap memory region taken from SMBIOS values\n");
1324 retval = -EIO;
1325 goto error_smbios_start;
1326 }
1327
1328 initialized = 1;
1329
1330 return retval;
1331
1332error_smbios_start:
1333 iounmap(smbios_start);
1334error_rom_start:
1335 iounmap(cpqhp_rom_start);
1336error:
1337 return retval;
1338}
1339
1340
1341static void __exit unload_cpqphpd(void)
1342{
1343 struct pci_func *next;
1344 struct pci_func *TempSlot;
1345 int loop;
1346 u32 rc;
1347 struct controller *ctrl;
1348 struct controller *tctrl;
1349 struct pci_resource *res;
1350 struct pci_resource *tres;
1351
1352 rc = compaq_nvram_store(cpqhp_rom_start);
1353
1354 ctrl = cpqhp_ctrl_list;
1355
1356 while (ctrl) {
1357 if (ctrl->hpc_reg) {
1358 u16 misc;
1359 rc = read_slot_enable (ctrl);
1360
1361 writeb(0, ctrl->hpc_reg + SLOT_SERR);
1362 writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
1363
1364 misc = readw(ctrl->hpc_reg + MISC);
1365 misc &= 0xFFFD;
1366 writew(misc, ctrl->hpc_reg + MISC);
1367 }
1368
1369 ctrl_slot_cleanup(ctrl);
1370
1371 res = ctrl->io_head;
1372 while (res) {
1373 tres = res;
1374 res = res->next;
1375 kfree(tres);
1376 }
1377
1378 res = ctrl->mem_head;
1379 while (res) {
1380 tres = res;
1381 res = res->next;
1382 kfree(tres);
1383 }
1384
1385 res = ctrl->p_mem_head;
1386 while (res) {
1387 tres = res;
1388 res = res->next;
1389 kfree(tres);
1390 }
1391
1392 res = ctrl->bus_head;
1393 while (res) {
1394 tres = res;
1395 res = res->next;
1396 kfree(tres);
1397 }
1398
1399 kfree (ctrl->pci_bus);
1400
1401 tctrl = ctrl;
1402 ctrl = ctrl->next;
1403 kfree(tctrl);
1404 }
1405
1406 for (loop = 0; loop < 256; loop++) {
1407 next = cpqhp_slot_list[loop];
1408 while (next != NULL) {
1409 res = next->io_head;
1410 while (res) {
1411 tres = res;
1412 res = res->next;
1413 kfree(tres);
1414 }
1415
1416 res = next->mem_head;
1417 while (res) {
1418 tres = res;
1419 res = res->next;
1420 kfree(tres);
1421 }
1422
1423 res = next->p_mem_head;
1424 while (res) {
1425 tres = res;
1426 res = res->next;
1427 kfree(tres);
1428 }
1429
1430 res = next->bus_head;
1431 while (res) {
1432 tres = res;
1433 res = res->next;
1434 kfree(tres);
1435 }
1436
1437 TempSlot = next;
1438 next = next->next;
1439 kfree(TempSlot);
1440 }
1441 }
1442
1443 // Stop the notification mechanism
1444 cpqhp_event_stop_thread();
1445
1446 //unmap the rom address
1447 if (cpqhp_rom_start)
1448 iounmap(cpqhp_rom_start);
1449 if (smbios_start)
1450 iounmap(smbios_start);
1451}
1452
1453
1454
1455static struct pci_device_id hpcd_pci_tbl[] = {
1456 {
1457 /* handle any PCI Hotplug controller */
1458 .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1459 .class_mask = ~0,
1460
1461 /* no matter who makes it */
1462 .vendor = PCI_ANY_ID,
1463 .device = PCI_ANY_ID,
1464 .subvendor = PCI_ANY_ID,
1465 .subdevice = PCI_ANY_ID,
1466
1467 }, { /* end: all zeroes */ }
1468};
1469
1470MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
1471
1472
1473
1474static struct pci_driver cpqhpc_driver = {
1475 .name = "compaq_pci_hotplug",
1476 .id_table = hpcd_pci_tbl,
1477 .probe = cpqhpc_probe,
1478 /* remove: cpqhpc_remove_one, */
1479};
1480
1481
1482
1483static int __init cpqhpc_init(void)
1484{
1485 int result;
1486
1487 cpqhp_debug = debug;
1488
1489 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1490 result = pci_register_driver(&cpqhpc_driver);
1491 dbg("pci_register_driver = %d\n", result);
1492 return result;
1493}
1494
1495
1496static void __exit cpqhpc_cleanup(void)
1497{
1498 dbg("unload_cpqphpd()\n");
1499 unload_cpqphpd();
1500
1501 dbg("pci_unregister_driver\n");
1502 pci_unregister_driver(&cpqhpc_driver);
1503}
1504
1505
1506module_init(cpqhpc_init);
1507module_exit(cpqhpc_cleanup);
1508
1509
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
new file mode 100644
index 000000000000..10a5a7674a8a
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -0,0 +1,3096 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/slab.h>
34#include <linux/workqueue.h>
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/wait.h>
38#include <linux/smp_lock.h>
39#include <linux/pci.h>
40#include "cpqphp.h"
41
42static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,
43 u8 behind_bridge, struct resource_lists *resources);
44static int configure_new_function(struct controller* ctrl, struct pci_func *func,
45 u8 behind_bridge, struct resource_lists *resources);
46static void interrupt_event_handler(struct controller *ctrl);
47
48static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
49static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
50static int event_finished;
51static unsigned long pushbutton_pending; /* = 0 */
52
53/* things needed for the long_delay function */
54static struct semaphore delay_sem;
55static wait_queue_head_t delay_wait;
56
57/* delay is in jiffies to wait for */
58static void long_delay(int delay)
59{
60 DECLARE_WAITQUEUE(wait, current);
61
62 /* only allow 1 customer into the delay queue at once
63 * yes this makes some people wait even longer, but who really cares?
64 * this is for _huge_ delays to make the hardware happy as the
65 * signals bounce around
66 */
67 down (&delay_sem);
68
69 init_waitqueue_head(&delay_wait);
70
71 add_wait_queue(&delay_wait, &wait);
72 msleep_interruptible(jiffies_to_msecs(delay));
73 remove_wait_queue(&delay_wait, &wait);
74
75 up(&delay_sem);
76}
77
78
79/* FIXME: The following line needs to be somewhere else... */
80#define WRONG_BUS_FREQUENCY 0x07
81static u8 handle_switch_change(u8 change, struct controller * ctrl)
82{
83 int hp_slot;
84 u8 rc = 0;
85 u16 temp_word;
86 struct pci_func *func;
87 struct event_info *taskInfo;
88
89 if (!change)
90 return 0;
91
92 /* Switch Change */
93 dbg("cpqsbd: Switch interrupt received.\n");
94
95 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
96 if (change & (0x1L << hp_slot)) {
97 /**********************************
98 * this one changed.
99 **********************************/
100 func = cpqhp_slot_find(ctrl->bus,
101 (hp_slot + ctrl->slot_device_offset), 0);
102
103 /* this is the structure that tells the worker thread
104 *what to do */
105 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
106 ctrl->next_event = (ctrl->next_event + 1) % 10;
107 taskInfo->hp_slot = hp_slot;
108
109 rc++;
110
111 temp_word = ctrl->ctrl_int_comp >> 16;
112 func->presence_save = (temp_word >> hp_slot) & 0x01;
113 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
114
115 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
116 /**********************************
117 * Switch opened
118 **********************************/
119
120 func->switch_save = 0;
121
122 taskInfo->event_type = INT_SWITCH_OPEN;
123 } else {
124 /**********************************
125 * Switch closed
126 **********************************/
127
128 func->switch_save = 0x10;
129
130 taskInfo->event_type = INT_SWITCH_CLOSE;
131 }
132 }
133 }
134
135 return rc;
136}
137
138/**
139 * cpqhp_find_slot: find the struct slot of given device
140 * @ctrl: scan lots of this controller
141 * @device: the device id to find
142 */
143static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)
144{
145 struct slot *slot = ctrl->slot;
146
147 while (slot && (slot->device != device)) {
148 slot = slot->next;
149 }
150
151 return slot;
152}
153
154
155static u8 handle_presence_change(u16 change, struct controller * ctrl)
156{
157 int hp_slot;
158 u8 rc = 0;
159 u8 temp_byte;
160 u16 temp_word;
161 struct pci_func *func;
162 struct event_info *taskInfo;
163 struct slot *p_slot;
164
165 if (!change)
166 return 0;
167
168 /**********************************
169 * Presence Change
170 **********************************/
171 dbg("cpqsbd: Presence/Notify input change.\n");
172 dbg(" Changed bits are 0x%4.4x\n", change );
173
174 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
175 if (change & (0x0101 << hp_slot)) {
176 /**********************************
177 * this one changed.
178 **********************************/
179 func = cpqhp_slot_find(ctrl->bus,
180 (hp_slot + ctrl->slot_device_offset), 0);
181
182 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
183 ctrl->next_event = (ctrl->next_event + 1) % 10;
184 taskInfo->hp_slot = hp_slot;
185
186 rc++;
187
188 p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
189 if (!p_slot)
190 return 0;
191
192 /* If the switch closed, must be a button
193 * If not in button mode, nevermind */
194 if (func->switch_save && (ctrl->push_button == 1)) {
195 temp_word = ctrl->ctrl_int_comp >> 16;
196 temp_byte = (temp_word >> hp_slot) & 0x01;
197 temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
198
199 if (temp_byte != func->presence_save) {
200 /**************************************
201 * button Pressed (doesn't do anything)
202 **************************************/
203 dbg("hp_slot %d button pressed\n", hp_slot);
204 taskInfo->event_type = INT_BUTTON_PRESS;
205 } else {
206 /**********************************
207 * button Released - TAKE ACTION!!!!
208 **********************************/
209 dbg("hp_slot %d button released\n", hp_slot);
210 taskInfo->event_type = INT_BUTTON_RELEASE;
211
212 /* Cancel if we are still blinking */
213 if ((p_slot->state == BLINKINGON_STATE)
214 || (p_slot->state == BLINKINGOFF_STATE)) {
215 taskInfo->event_type = INT_BUTTON_CANCEL;
216 dbg("hp_slot %d button cancel\n", hp_slot);
217 } else if ((p_slot->state == POWERON_STATE)
218 || (p_slot->state == POWEROFF_STATE)) {
219 /* info(msg_button_ignore, p_slot->number); */
220 taskInfo->event_type = INT_BUTTON_IGNORE;
221 dbg("hp_slot %d button ignore\n", hp_slot);
222 }
223 }
224 } else {
225 /* Switch is open, assume a presence change
226 * Save the presence state */
227 temp_word = ctrl->ctrl_int_comp >> 16;
228 func->presence_save = (temp_word >> hp_slot) & 0x01;
229 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
230
231 if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
232 (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
233 /* Present */
234 taskInfo->event_type = INT_PRESENCE_ON;
235 } else {
236 /* Not Present */
237 taskInfo->event_type = INT_PRESENCE_OFF;
238 }
239 }
240 }
241 }
242
243 return rc;
244}
245
246
247static u8 handle_power_fault(u8 change, struct controller * ctrl)
248{
249 int hp_slot;
250 u8 rc = 0;
251 struct pci_func *func;
252 struct event_info *taskInfo;
253
254 if (!change)
255 return 0;
256
257 /**********************************
258 * power fault
259 **********************************/
260
261 info("power fault interrupt\n");
262
263 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
264 if (change & (0x01 << hp_slot)) {
265 /**********************************
266 * this one changed.
267 **********************************/
268 func = cpqhp_slot_find(ctrl->bus,
269 (hp_slot + ctrl->slot_device_offset), 0);
270
271 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
272 ctrl->next_event = (ctrl->next_event + 1) % 10;
273 taskInfo->hp_slot = hp_slot;
274
275 rc++;
276
277 if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
278 /**********************************
279 * power fault Cleared
280 **********************************/
281 func->status = 0x00;
282
283 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
284 } else {
285 /**********************************
286 * power fault
287 **********************************/
288 taskInfo->event_type = INT_POWER_FAULT;
289
290 if (ctrl->rev < 4) {
291 amber_LED_on (ctrl, hp_slot);
292 green_LED_off (ctrl, hp_slot);
293 set_SOGO (ctrl);
294
295 /* this is a fatal condition, we want
296 * to crash the machine to protect from
297 * data corruption. simulated_NMI
298 * shouldn't ever return */
299 /* FIXME
300 simulated_NMI(hp_slot, ctrl); */
301
302 /* The following code causes a software
303 * crash just in case simulated_NMI did
304 * return */
305 /*FIXME
306 panic(msg_power_fault); */
307 } else {
308 /* set power fault status for this board */
309 func->status = 0xFF;
310 info("power fault bit %x set\n", hp_slot);
311 }
312 }
313 }
314 }
315
316 return rc;
317}
318
319
320/**
321 * sort_by_size: sort nodes on the list by their length, smallest first.
322 * @head: list to sort
323 *
324 */
325static int sort_by_size(struct pci_resource **head)
326{
327 struct pci_resource *current_res;
328 struct pci_resource *next_res;
329 int out_of_order = 1;
330
331 if (!(*head))
332 return 1;
333
334 if (!((*head)->next))
335 return 0;
336
337 while (out_of_order) {
338 out_of_order = 0;
339
340 /* Special case for swapping list head */
341 if (((*head)->next) &&
342 ((*head)->length > (*head)->next->length)) {
343 out_of_order++;
344 current_res = *head;
345 *head = (*head)->next;
346 current_res->next = (*head)->next;
347 (*head)->next = current_res;
348 }
349
350 current_res = *head;
351
352 while (current_res->next && current_res->next->next) {
353 if (current_res->next->length > current_res->next->next->length) {
354 out_of_order++;
355 next_res = current_res->next;
356 current_res->next = current_res->next->next;
357 current_res = current_res->next;
358 next_res->next = current_res->next;
359 current_res->next = next_res;
360 } else
361 current_res = current_res->next;
362 }
363 } /* End of out_of_order loop */
364
365 return 0;
366}
367
368
369/**
370 * sort_by_max_size: sort nodes on the list by their length, largest first.
371 * @head: list to sort
372 *
373 */
374static int sort_by_max_size(struct pci_resource **head)
375{
376 struct pci_resource *current_res;
377 struct pci_resource *next_res;
378 int out_of_order = 1;
379
380 if (!(*head))
381 return 1;
382
383 if (!((*head)->next))
384 return 0;
385
386 while (out_of_order) {
387 out_of_order = 0;
388
389 /* Special case for swapping list head */
390 if (((*head)->next) &&
391 ((*head)->length < (*head)->next->length)) {
392 out_of_order++;
393 current_res = *head;
394 *head = (*head)->next;
395 current_res->next = (*head)->next;
396 (*head)->next = current_res;
397 }
398
399 current_res = *head;
400
401 while (current_res->next && current_res->next->next) {
402 if (current_res->next->length < current_res->next->next->length) {
403 out_of_order++;
404 next_res = current_res->next;
405 current_res->next = current_res->next->next;
406 current_res = current_res->next;
407 next_res->next = current_res->next;
408 current_res->next = next_res;
409 } else
410 current_res = current_res->next;
411 }
412 } /* End of out_of_order loop */
413
414 return 0;
415}
416
417
418/**
419 * do_pre_bridge_resource_split: find node of resources that are unused
420 *
421 */
422static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **head,
423 struct pci_resource **orig_head, u32 alignment)
424{
425 struct pci_resource *prevnode = NULL;
426 struct pci_resource *node;
427 struct pci_resource *split_node;
428 u32 rc;
429 u32 temp_dword;
430 dbg("do_pre_bridge_resource_split\n");
431
432 if (!(*head) || !(*orig_head))
433 return NULL;
434
435 rc = cpqhp_resource_sort_and_combine(head);
436
437 if (rc)
438 return NULL;
439
440 if ((*head)->base != (*orig_head)->base)
441 return NULL;
442
443 if ((*head)->length == (*orig_head)->length)
444 return NULL;
445
446
447 /* If we got here, there the bridge requires some of the resource, but
448 * we may be able to split some off of the front */
449
450 node = *head;
451
452 if (node->length & (alignment -1)) {
453 /* this one isn't an aligned length, so we'll make a new entry
454 * and split it up. */
455 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
456
457 if (!split_node)
458 return NULL;
459
460 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
461
462 split_node->base = node->base;
463 split_node->length = temp_dword;
464
465 node->length -= temp_dword;
466 node->base += split_node->length;
467
468 /* Put it in the list */
469 *head = split_node;
470 split_node->next = node;
471 }
472
473 if (node->length < alignment)
474 return NULL;
475
476 /* Now unlink it */
477 if (*head == node) {
478 *head = node->next;
479 } else {
480 prevnode = *head;
481 while (prevnode->next != node)
482 prevnode = prevnode->next;
483
484 prevnode->next = node->next;
485 }
486 node->next = NULL;
487
488 return node;
489}
490
491
492/**
493 * do_bridge_resource_split: find one node of resources that aren't in use
494 *
495 */
496static struct pci_resource *do_bridge_resource_split(struct pci_resource **head, u32 alignment)
497{
498 struct pci_resource *prevnode = NULL;
499 struct pci_resource *node;
500 u32 rc;
501 u32 temp_dword;
502
503 rc = cpqhp_resource_sort_and_combine(head);
504
505 if (rc)
506 return NULL;
507
508 node = *head;
509
510 while (node->next) {
511 prevnode = node;
512 node = node->next;
513 kfree(prevnode);
514 }
515
516 if (node->length < alignment)
517 goto error;
518
519 if (node->base & (alignment - 1)) {
520 /* Short circuit if adjusted size is too small */
521 temp_dword = (node->base | (alignment-1)) + 1;
522 if ((node->length - (temp_dword - node->base)) < alignment)
523 goto error;
524
525 node->length -= (temp_dword - node->base);
526 node->base = temp_dword;
527 }
528
529 if (node->length & (alignment - 1))
530 /* There's stuff in use after this node */
531 goto error;
532
533 return node;
534error:
535 kfree(node);
536 return NULL;
537}
538
539
540/**
541 * get_io_resource: find first node of given size not in ISA aliasing window.
542 * @head: list to search
543 * @size: size of node to find, must be a power of two.
544 *
545 * Description: this function sorts the resource list by size and then returns
546 * returns the first node of "size" length that is not in the ISA aliasing
547 * window. If it finds a node larger than "size" it will split it up.
548 *
549 */
550static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
551{
552 struct pci_resource *prevnode;
553 struct pci_resource *node;
554 struct pci_resource *split_node;
555 u32 temp_dword;
556
557 if (!(*head))
558 return NULL;
559
560 if ( cpqhp_resource_sort_and_combine(head) )
561 return NULL;
562
563 if ( sort_by_size(head) )
564 return NULL;
565
566 for (node = *head; node; node = node->next) {
567 if (node->length < size)
568 continue;
569
570 if (node->base & (size - 1)) {
571 /* this one isn't base aligned properly
572 * so we'll make a new entry and split it up */
573 temp_dword = (node->base | (size-1)) + 1;
574
575 /* Short circuit if adjusted size is too small */
576 if ((node->length - (temp_dword - node->base)) < size)
577 continue;
578
579 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
580
581 if (!split_node)
582 return NULL;
583
584 split_node->base = node->base;
585 split_node->length = temp_dword - node->base;
586 node->base = temp_dword;
587 node->length -= split_node->length;
588
589 /* Put it in the list */
590 split_node->next = node->next;
591 node->next = split_node;
592 } /* End of non-aligned base */
593
594 /* Don't need to check if too small since we already did */
595 if (node->length > size) {
596 /* this one is longer than we need
597 * so we'll make a new entry and split it up */
598 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
599
600 if (!split_node)
601 return NULL;
602
603 split_node->base = node->base + size;
604 split_node->length = node->length - size;
605 node->length = size;
606
607 /* Put it in the list */
608 split_node->next = node->next;
609 node->next = split_node;
610 } /* End of too big on top end */
611
612 /* For IO make sure it's not in the ISA aliasing space */
613 if (node->base & 0x300L)
614 continue;
615
616 /* If we got here, then it is the right size
617 * Now take it out of the list and break */
618 if (*head == node) {
619 *head = node->next;
620 } else {
621 prevnode = *head;
622 while (prevnode->next != node)
623 prevnode = prevnode->next;
624
625 prevnode->next = node->next;
626 }
627 node->next = NULL;
628 break;
629 }
630
631 return node;
632}
633
634
635/**
636 * get_max_resource: get largest node which has at least the given size.
637 * @head: the list to search the node in
638 * @size: the minimum size of the node to find
639 *
640 * Description: Gets the largest node that is at least "size" big from the
641 * list pointed to by head. It aligns the node on top and bottom
642 * to "size" alignment before returning it.
643 */
644static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
645{
646 struct pci_resource *max;
647 struct pci_resource *temp;
648 struct pci_resource *split_node;
649 u32 temp_dword;
650
651 if (cpqhp_resource_sort_and_combine(head))
652 return NULL;
653
654 if (sort_by_max_size(head))
655 return NULL;
656
657 for (max = *head; max; max = max->next) {
658 /* If not big enough we could probably just bail,
659 * instead we'll continue to the next. */
660 if (max->length < size)
661 continue;
662
663 if (max->base & (size - 1)) {
664 /* this one isn't base aligned properly
665 * so we'll make a new entry and split it up */
666 temp_dword = (max->base | (size-1)) + 1;
667
668 /* Short circuit if adjusted size is too small */
669 if ((max->length - (temp_dword - max->base)) < size)
670 continue;
671
672 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
673
674 if (!split_node)
675 return NULL;
676
677 split_node->base = max->base;
678 split_node->length = temp_dword - max->base;
679 max->base = temp_dword;
680 max->length -= split_node->length;
681
682 split_node->next = max->next;
683 max->next = split_node;
684 }
685
686 if ((max->base + max->length) & (size - 1)) {
687 /* this one isn't end aligned properly at the top
688 * so we'll make a new entry and split it up */
689 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
690
691 if (!split_node)
692 return NULL;
693 temp_dword = ((max->base + max->length) & ~(size - 1));
694 split_node->base = temp_dword;
695 split_node->length = max->length + max->base
696 - split_node->base;
697 max->length -= split_node->length;
698
699 split_node->next = max->next;
700 max->next = split_node;
701 }
702
703 /* Make sure it didn't shrink too much when we aligned it */
704 if (max->length < size)
705 continue;
706
707 /* Now take it out of the list */
708 temp = *head;
709 if (temp == max) {
710 *head = max->next;
711 } else {
712 while (temp && temp->next != max) {
713 temp = temp->next;
714 }
715
716 temp->next = max->next;
717 }
718
719 max->next = NULL;
720 break;
721 }
722
723 return max;
724}
725
726
727/**
728 * get_resource: find resource of given size and split up larger ones.
729 * @head: the list to search for resources
730 * @size: the size limit to use
731 *
732 * Description: This function sorts the resource list by size and then
733 * returns the first node of "size" length. If it finds a node
734 * larger than "size" it will split it up.
735 *
736 * size must be a power of two.
737 */
738static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
739{
740 struct pci_resource *prevnode;
741 struct pci_resource *node;
742 struct pci_resource *split_node;
743 u32 temp_dword;
744
745 if (cpqhp_resource_sort_and_combine(head))
746 return NULL;
747
748 if (sort_by_size(head))
749 return NULL;
750
751 for (node = *head; node; node = node->next) {
752 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
753 __FUNCTION__, size, node, node->base, node->length);
754 if (node->length < size)
755 continue;
756
757 if (node->base & (size - 1)) {
758 dbg("%s: not aligned\n", __FUNCTION__);
759 /* this one isn't base aligned properly
760 * so we'll make a new entry and split it up */
761 temp_dword = (node->base | (size-1)) + 1;
762
763 /* Short circuit if adjusted size is too small */
764 if ((node->length - (temp_dword - node->base)) < size)
765 continue;
766
767 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
768
769 if (!split_node)
770 return NULL;
771
772 split_node->base = node->base;
773 split_node->length = temp_dword - node->base;
774 node->base = temp_dword;
775 node->length -= split_node->length;
776
777 split_node->next = node->next;
778 node->next = split_node;
779 } /* End of non-aligned base */
780
781 /* Don't need to check if too small since we already did */
782 if (node->length > size) {
783 dbg("%s: too big\n", __FUNCTION__);
784 /* this one is longer than we need
785 * so we'll make a new entry and split it up */
786 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
787
788 if (!split_node)
789 return NULL;
790
791 split_node->base = node->base + size;
792 split_node->length = node->length - size;
793 node->length = size;
794
795 /* Put it in the list */
796 split_node->next = node->next;
797 node->next = split_node;
798 } /* End of too big on top end */
799
800 dbg("%s: got one!!!\n", __FUNCTION__);
801 /* If we got here, then it is the right size
802 * Now take it out of the list */
803 if (*head == node) {
804 *head = node->next;
805 } else {
806 prevnode = *head;
807 while (prevnode->next != node)
808 prevnode = prevnode->next;
809
810 prevnode->next = node->next;
811 }
812 node->next = NULL;
813 break;
814 }
815 return node;
816}
817
818
819/**
820 * cpqhp_resource_sort_and_combine: sort nodes by base addresses and clean up.
821 * @head: the list to sort and clean up
822 *
823 * Description: Sorts all of the nodes in the list in ascending order by
824 * their base addresses. Also does garbage collection by
825 * combining adjacent nodes.
826 *
827 * returns 0 if success
828 */
829int cpqhp_resource_sort_and_combine(struct pci_resource **head)
830{
831 struct pci_resource *node1;
832 struct pci_resource *node2;
833 int out_of_order = 1;
834
835 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
836
837 if (!(*head))
838 return 1;
839
840 dbg("*head->next = %p\n",(*head)->next);
841
842 if (!(*head)->next)
843 return 0; /* only one item on the list, already sorted! */
844
845 dbg("*head->base = 0x%x\n",(*head)->base);
846 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
847 while (out_of_order) {
848 out_of_order = 0;
849
850 /* Special case for swapping list head */
851 if (((*head)->next) &&
852 ((*head)->base > (*head)->next->base)) {
853 node1 = *head;
854 (*head) = (*head)->next;
855 node1->next = (*head)->next;
856 (*head)->next = node1;
857 out_of_order++;
858 }
859
860 node1 = (*head);
861
862 while (node1->next && node1->next->next) {
863 if (node1->next->base > node1->next->next->base) {
864 out_of_order++;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 node1 = node1->next;
868 node2->next = node1->next;
869 node1->next = node2;
870 } else
871 node1 = node1->next;
872 }
873 } /* End of out_of_order loop */
874
875 node1 = *head;
876
877 while (node1 && node1->next) {
878 if ((node1->base + node1->length) == node1->next->base) {
879 /* Combine */
880 dbg("8..\n");
881 node1->length += node1->next->length;
882 node2 = node1->next;
883 node1->next = node1->next->next;
884 kfree(node2);
885 } else
886 node1 = node1->next;
887 }
888
889 return 0;
890}
891
892
893irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
894{
895 struct controller *ctrl = data;
896 u8 schedule_flag = 0;
897 u8 reset;
898 u16 misc;
899 u32 Diff;
900 u32 temp_dword;
901
902
903 misc = readw(ctrl->hpc_reg + MISC);
904 /***************************************
905 * Check to see if it was our interrupt
906 ***************************************/
907 if (!(misc & 0x000C)) {
908 return IRQ_NONE;
909 }
910
911 if (misc & 0x0004) {
912 /**********************************
913 * Serial Output interrupt Pending
914 **********************************/
915
916 /* Clear the interrupt */
917 misc |= 0x0004;
918 writew(misc, ctrl->hpc_reg + MISC);
919
920 /* Read to clear posted writes */
921 misc = readw(ctrl->hpc_reg + MISC);
922
923 dbg ("%s - waking up\n", __FUNCTION__);
924 wake_up_interruptible(&ctrl->queue);
925 }
926
927 if (misc & 0x0008) {
928 /* General-interrupt-input interrupt Pending */
929 Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
930
931 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
932
933 /* Clear the interrupt */
934 writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
935
936 /* Read it back to clear any posted writes */
937 temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
938
939 if (!Diff)
940 /* Clear all interrupts */
941 writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
942
943 schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
944 schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
945 schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
946 }
947
948 reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
949 if (reset & 0x40) {
950 /* Bus reset has completed */
951 reset &= 0xCF;
952 writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
953 reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
954 wake_up_interruptible(&ctrl->queue);
955 }
956
957 if (schedule_flag) {
958 up(&event_semaphore);
959 dbg("Signal event_semaphore\n");
960 }
961 return IRQ_HANDLED;
962}
963
964
965/**
966 * cpqhp_slot_create - Creates a node and adds it to the proper bus.
967 * @busnumber - bus where new node is to be located
968 *
969 * Returns pointer to the new node or NULL if unsuccessful
970 */
971struct pci_func *cpqhp_slot_create(u8 busnumber)
972{
973 struct pci_func *new_slot;
974 struct pci_func *next;
975
976 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
977
978 if (new_slot == NULL) {
979 /* I'm not dead yet!
980 * You will be. */
981 return new_slot;
982 }
983
984 memset(new_slot, 0, sizeof(struct pci_func));
985
986 new_slot->next = NULL;
987 new_slot->configured = 1;
988
989 if (cpqhp_slot_list[busnumber] == NULL) {
990 cpqhp_slot_list[busnumber] = new_slot;
991 } else {
992 next = cpqhp_slot_list[busnumber];
993 while (next->next != NULL)
994 next = next->next;
995 next->next = new_slot;
996 }
997 return new_slot;
998}
999
1000
1001/**
1002 * slot_remove - Removes a node from the linked list of slots.
1003 * @old_slot: slot to remove
1004 *
1005 * Returns 0 if successful, !0 otherwise.
1006 */
1007static int slot_remove(struct pci_func * old_slot)
1008{
1009 struct pci_func *next;
1010
1011 if (old_slot == NULL)
1012 return 1;
1013
1014 next = cpqhp_slot_list[old_slot->bus];
1015
1016 if (next == NULL) {
1017 return 1;
1018 }
1019
1020 if (next == old_slot) {
1021 cpqhp_slot_list[old_slot->bus] = old_slot->next;
1022 cpqhp_destroy_board_resources(old_slot);
1023 kfree(old_slot);
1024 return 0;
1025 }
1026
1027 while ((next->next != old_slot) && (next->next != NULL)) {
1028 next = next->next;
1029 }
1030
1031 if (next->next == old_slot) {
1032 next->next = old_slot->next;
1033 cpqhp_destroy_board_resources(old_slot);
1034 kfree(old_slot);
1035 return 0;
1036 } else
1037 return 2;
1038}
1039
1040
1041/**
1042 * bridge_slot_remove - Removes a node from the linked list of slots.
1043 * @bridge: bridge to remove
1044 *
1045 * Returns 0 if successful, !0 otherwise.
1046 */
1047static int bridge_slot_remove(struct pci_func *bridge)
1048{
1049 u8 subordinateBus, secondaryBus;
1050 u8 tempBus;
1051 struct pci_func *next;
1052
1053 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
1054 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
1055
1056 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
1057 next = cpqhp_slot_list[tempBus];
1058
1059 while (!slot_remove(next)) {
1060 next = cpqhp_slot_list[tempBus];
1061 }
1062 }
1063
1064 next = cpqhp_slot_list[bridge->bus];
1065
1066 if (next == NULL)
1067 return 1;
1068
1069 if (next == bridge) {
1070 cpqhp_slot_list[bridge->bus] = bridge->next;
1071 goto out;
1072 }
1073
1074 while ((next->next != bridge) && (next->next != NULL))
1075 next = next->next;
1076
1077 if (next->next != bridge)
1078 return 2;
1079 next->next = bridge->next;
1080out:
1081 kfree(bridge);
1082 return 0;
1083}
1084
1085
1086/**
1087 * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1088 * @bus: bus to find
1089 * @device: device to find
1090 * @index: is 0 for first function found, 1 for the second...
1091 *
1092 * Returns pointer to the node if successful, %NULL otherwise.
1093 */
1094struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)
1095{
1096 int found = -1;
1097 struct pci_func *func;
1098
1099 func = cpqhp_slot_list[bus];
1100
1101 if ((func == NULL) || ((func->device == device) && (index == 0)))
1102 return func;
1103
1104 if (func->device == device)
1105 found++;
1106
1107 while (func->next != NULL) {
1108 func = func->next;
1109
1110 if (func->device == device)
1111 found++;
1112
1113 if (found == index)
1114 return func;
1115 }
1116
1117 return NULL;
1118}
1119
1120
1121/* DJZ: I don't think is_bridge will work as is.
1122 * FIXME */
1123static int is_bridge(struct pci_func * func)
1124{
1125 /* Check the header type */
1126 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1127 return 1;
1128 else
1129 return 0;
1130}
1131
1132
1133/**
1134 * set_controller_speed - set the frequency and/or mode of a specific
1135 * controller segment.
1136 *
1137 * @ctrl: controller to change frequency/mode for.
1138 * @adapter_speed: the speed of the adapter we want to match.
1139 * @hp_slot: the slot number where the adapter is installed.
1140 *
1141 * Returns 0 if we successfully change frequency and/or mode to match the
1142 * adapter speed.
1143 *
1144 */
1145static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
1146{
1147 struct slot *slot;
1148 u8 reg;
1149 u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
1150 u16 reg16;
1151 u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
1152
1153 if (ctrl->speed == adapter_speed)
1154 return 0;
1155
1156 /* We don't allow freq/mode changes if we find another adapter running
1157 * in another slot on this controller */
1158 for(slot = ctrl->slot; slot; slot = slot->next) {
1159 if (slot->device == (hp_slot + ctrl->slot_device_offset))
1160 continue;
1161 if (!slot->hotplug_slot && !slot->hotplug_slot->info)
1162 continue;
1163 if (slot->hotplug_slot->info->adapter_status == 0)
1164 continue;
1165 /* If another adapter is running on the same segment but at a
1166 * lower speed/mode, we allow the new adapter to function at
1167 * this rate if supported */
1168 if (ctrl->speed < adapter_speed)
1169 return 0;
1170
1171 return 1;
1172 }
1173
1174 /* If the controller doesn't support freq/mode changes and the
1175 * controller is running at a higher mode, we bail */
1176 if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
1177 return 1;
1178
1179 /* But we allow the adapter to run at a lower rate if possible */
1180 if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
1181 return 0;
1182
1183 /* We try to set the max speed supported by both the adapter and
1184 * controller */
1185 if (ctrl->speed_capability < adapter_speed) {
1186 if (ctrl->speed == ctrl->speed_capability)
1187 return 0;
1188 adapter_speed = ctrl->speed_capability;
1189 }
1190
1191 writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
1192 writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
1193
1194 set_SOGO(ctrl);
1195 wait_for_ctrl_irq(ctrl);
1196
1197 if (adapter_speed != PCI_SPEED_133MHz_PCIX)
1198 reg = 0xF5;
1199 else
1200 reg = 0xF4;
1201 pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
1202
1203 reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
1204 reg16 &= ~0x000F;
1205 switch(adapter_speed) {
1206 case(PCI_SPEED_133MHz_PCIX):
1207 reg = 0x75;
1208 reg16 |= 0xB;
1209 break;
1210 case(PCI_SPEED_100MHz_PCIX):
1211 reg = 0x74;
1212 reg16 |= 0xA;
1213 break;
1214 case(PCI_SPEED_66MHz_PCIX):
1215 reg = 0x73;
1216 reg16 |= 0x9;
1217 break;
1218 case(PCI_SPEED_66MHz):
1219 reg = 0x73;
1220 reg16 |= 0x1;
1221 break;
1222 default: /* 33MHz PCI 2.2 */
1223 reg = 0x71;
1224 break;
1225
1226 }
1227 reg16 |= 0xB << 12;
1228 writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
1229
1230 mdelay(5);
1231
1232 /* Reenable interrupts */
1233 writel(0, ctrl->hpc_reg + INT_MASK);
1234
1235 pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
1236
1237 /* Restart state machine */
1238 reg = ~0xF;
1239 pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
1240 pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
1241
1242 /* Only if mode change...*/
1243 if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
1244 ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))
1245 set_SOGO(ctrl);
1246
1247 wait_for_ctrl_irq(ctrl);
1248 mdelay(1100);
1249
1250 /* Restore LED/Slot state */
1251 writel(leds, ctrl->hpc_reg + LED_CONTROL);
1252 writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
1253
1254 set_SOGO(ctrl);
1255 wait_for_ctrl_irq(ctrl);
1256
1257 ctrl->speed = adapter_speed;
1258 slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1259
1260 info("Successfully changed frequency/mode for adapter in slot %d\n",
1261 slot->number);
1262 return 0;
1263}
1264
1265/* the following routines constitute the bulk of the
1266 hotplug controller logic
1267 */
1268
1269
1270/**
1271 * board_replaced - Called after a board has been replaced in the system.
1272 *
1273 * This is only used if we don't have resources for hot add
1274 * Turns power on for the board
1275 * Checks to see if board is the same
1276 * If board is same, reconfigures it
1277 * If board isn't same, turns it back off.
1278 *
1279 */
1280static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
1281{
1282 u8 hp_slot;
1283 u8 temp_byte;
1284 u8 adapter_speed;
1285 u32 index;
1286 u32 rc = 0;
1287 u32 src = 8;
1288
1289 hp_slot = func->device - ctrl->slot_device_offset;
1290
1291 if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
1292 /**********************************
1293 * The switch is open.
1294 **********************************/
1295 rc = INTERLOCK_OPEN;
1296 } else if (is_slot_enabled (ctrl, hp_slot)) {
1297 /**********************************
1298 * The board is already on
1299 **********************************/
1300 rc = CARD_FUNCTIONING;
1301 } else {
1302 down(&ctrl->crit_sect);
1303
1304 /* turn on board without attaching to the bus */
1305 enable_slot_power (ctrl, hp_slot);
1306
1307 set_SOGO(ctrl);
1308
1309 /* Wait for SOBS to be unset */
1310 wait_for_ctrl_irq (ctrl);
1311
1312 /* Change bits in slot power register to force another shift out
1313 * NOTE: this is to work around the timer bug */
1314 temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1315 writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1316 writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1317
1318 set_SOGO(ctrl);
1319
1320 /* Wait for SOBS to be unset */
1321 wait_for_ctrl_irq (ctrl);
1322
1323 adapter_speed = get_adapter_speed(ctrl, hp_slot);
1324 if (ctrl->speed != adapter_speed)
1325 if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1326 rc = WRONG_BUS_FREQUENCY;
1327
1328 /* turn off board without attaching to the bus */
1329 disable_slot_power (ctrl, hp_slot);
1330
1331 set_SOGO(ctrl);
1332
1333 /* Wait for SOBS to be unset */
1334 wait_for_ctrl_irq (ctrl);
1335
1336 up(&ctrl->crit_sect);
1337
1338 if (rc)
1339 return rc;
1340
1341 down(&ctrl->crit_sect);
1342
1343 slot_enable (ctrl, hp_slot);
1344 green_LED_blink (ctrl, hp_slot);
1345
1346 amber_LED_off (ctrl, hp_slot);
1347
1348 set_SOGO(ctrl);
1349
1350 /* Wait for SOBS to be unset */
1351 wait_for_ctrl_irq (ctrl);
1352
1353 up(&ctrl->crit_sect);
1354
1355 /* Wait for ~1 second because of hot plug spec */
1356 long_delay(1*HZ);
1357
1358 /* Check for a power fault */
1359 if (func->status == 0xFF) {
1360 /* power fault occurred, but it was benign */
1361 rc = POWER_FAILURE;
1362 func->status = 0;
1363 } else
1364 rc = cpqhp_valid_replace(ctrl, func);
1365
1366 if (!rc) {
1367 /* It must be the same board */
1368
1369 rc = cpqhp_configure_board(ctrl, func);
1370
1371 if (rc || src) {
1372 /* If configuration fails, turn it off
1373 * Get slot won't work for devices behind
1374 * bridges, but in this case it will always be
1375 * called for the "base" bus/dev/func of an
1376 * adapter. */
1377
1378 down(&ctrl->crit_sect);
1379
1380 amber_LED_on (ctrl, hp_slot);
1381 green_LED_off (ctrl, hp_slot);
1382 slot_disable (ctrl, hp_slot);
1383
1384 set_SOGO(ctrl);
1385
1386 /* Wait for SOBS to be unset */
1387 wait_for_ctrl_irq (ctrl);
1388
1389 up(&ctrl->crit_sect);
1390
1391 if (rc)
1392 return rc;
1393 else
1394 return 1;
1395 }
1396
1397 func->status = 0;
1398 func->switch_save = 0x10;
1399
1400 index = 1;
1401 while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
1402 rc |= cpqhp_configure_board(ctrl, func);
1403 index++;
1404 }
1405
1406 if (rc) {
1407 /* If configuration fails, turn it off
1408 * Get slot won't work for devices behind
1409 * bridges, but in this case it will always be
1410 * called for the "base" bus/dev/func of an
1411 * adapter. */
1412
1413 down(&ctrl->crit_sect);
1414
1415 amber_LED_on (ctrl, hp_slot);
1416 green_LED_off (ctrl, hp_slot);
1417 slot_disable (ctrl, hp_slot);
1418
1419 set_SOGO(ctrl);
1420
1421 /* Wait for SOBS to be unset */
1422 wait_for_ctrl_irq (ctrl);
1423
1424 up(&ctrl->crit_sect);
1425
1426 return rc;
1427 }
1428 /* Done configuring so turn LED on full time */
1429
1430 down(&ctrl->crit_sect);
1431
1432 green_LED_on (ctrl, hp_slot);
1433
1434 set_SOGO(ctrl);
1435
1436 /* Wait for SOBS to be unset */
1437 wait_for_ctrl_irq (ctrl);
1438
1439 up(&ctrl->crit_sect);
1440 rc = 0;
1441 } else {
1442 /* Something is wrong
1443
1444 * Get slot won't work for devices behind bridges, but
1445 * in this case it will always be called for the "base"
1446 * bus/dev/func of an adapter. */
1447
1448 down(&ctrl->crit_sect);
1449
1450 amber_LED_on (ctrl, hp_slot);
1451 green_LED_off (ctrl, hp_slot);
1452 slot_disable (ctrl, hp_slot);
1453
1454 set_SOGO(ctrl);
1455
1456 /* Wait for SOBS to be unset */
1457 wait_for_ctrl_irq (ctrl);
1458
1459 up(&ctrl->crit_sect);
1460 }
1461
1462 }
1463 return rc;
1464
1465}
1466
1467
1468/**
1469 * board_added - Called after a board has been added to the system.
1470 *
1471 * Turns power on for the board
1472 * Configures board
1473 *
1474 */
1475static u32 board_added(struct pci_func *func, struct controller *ctrl)
1476{
1477 u8 hp_slot;
1478 u8 temp_byte;
1479 u8 adapter_speed;
1480 int index;
1481 u32 temp_register = 0xFFFFFFFF;
1482 u32 rc = 0;
1483 struct pci_func *new_slot = NULL;
1484 struct slot *p_slot;
1485 struct resource_lists res_lists;
1486
1487 hp_slot = func->device - ctrl->slot_device_offset;
1488 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
1489 __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1490
1491 down(&ctrl->crit_sect);
1492
1493 /* turn on board without attaching to the bus */
1494 enable_slot_power(ctrl, hp_slot);
1495
1496 set_SOGO(ctrl);
1497
1498 /* Wait for SOBS to be unset */
1499 wait_for_ctrl_irq (ctrl);
1500
1501 /* Change bits in slot power register to force another shift out
1502 * NOTE: this is to work around the timer bug */
1503 temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1504 writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1505 writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1506
1507 set_SOGO(ctrl);
1508
1509 /* Wait for SOBS to be unset */
1510 wait_for_ctrl_irq (ctrl);
1511
1512 adapter_speed = get_adapter_speed(ctrl, hp_slot);
1513 if (ctrl->speed != adapter_speed)
1514 if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1515 rc = WRONG_BUS_FREQUENCY;
1516
1517 /* turn off board without attaching to the bus */
1518 disable_slot_power (ctrl, hp_slot);
1519
1520 set_SOGO(ctrl);
1521
1522 /* Wait for SOBS to be unset */
1523 wait_for_ctrl_irq(ctrl);
1524
1525 up(&ctrl->crit_sect);
1526
1527 if (rc)
1528 return rc;
1529
1530 p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1531
1532 /* turn on board and blink green LED */
1533
1534 dbg("%s: before down\n", __FUNCTION__);
1535 down(&ctrl->crit_sect);
1536 dbg("%s: after down\n", __FUNCTION__);
1537
1538 dbg("%s: before slot_enable\n", __FUNCTION__);
1539 slot_enable (ctrl, hp_slot);
1540
1541 dbg("%s: before green_LED_blink\n", __FUNCTION__);
1542 green_LED_blink (ctrl, hp_slot);
1543
1544 dbg("%s: before amber_LED_blink\n", __FUNCTION__);
1545 amber_LED_off (ctrl, hp_slot);
1546
1547 dbg("%s: before set_SOGO\n", __FUNCTION__);
1548 set_SOGO(ctrl);
1549
1550 /* Wait for SOBS to be unset */
1551 dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
1552 wait_for_ctrl_irq (ctrl);
1553 dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
1554
1555 dbg("%s: before up\n", __FUNCTION__);
1556 up(&ctrl->crit_sect);
1557 dbg("%s: after up\n", __FUNCTION__);
1558
1559 /* Wait for ~1 second because of hot plug spec */
1560 dbg("%s: before long_delay\n", __FUNCTION__);
1561 long_delay(1*HZ);
1562 dbg("%s: after long_delay\n", __FUNCTION__);
1563
1564 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1565 /* Check for a power fault */
1566 if (func->status == 0xFF) {
1567 /* power fault occurred, but it was benign */
1568 temp_register = 0xFFFFFFFF;
1569 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1570 rc = POWER_FAILURE;
1571 func->status = 0;
1572 } else {
1573 /* Get vendor/device ID u32 */
1574 ctrl->pci_bus->number = func->bus;
1575 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
1576 dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
1577 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1578
1579 if (rc != 0) {
1580 /* Something's wrong here */
1581 temp_register = 0xFFFFFFFF;
1582 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1583 }
1584 /* Preset return code. It will be changed later if things go okay. */
1585 rc = NO_ADAPTER_PRESENT;
1586 }
1587
1588 /* All F's is an empty slot or an invalid board */
1589 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1590 res_lists.io_head = ctrl->io_head;
1591 res_lists.mem_head = ctrl->mem_head;
1592 res_lists.p_mem_head = ctrl->p_mem_head;
1593 res_lists.bus_head = ctrl->bus_head;
1594 res_lists.irqs = NULL;
1595
1596 rc = configure_new_device(ctrl, func, 0, &res_lists);
1597
1598 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1599 ctrl->io_head = res_lists.io_head;
1600 ctrl->mem_head = res_lists.mem_head;
1601 ctrl->p_mem_head = res_lists.p_mem_head;
1602 ctrl->bus_head = res_lists.bus_head;
1603
1604 cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1605 cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1606 cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1607 cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1608
1609 if (rc) {
1610 down(&ctrl->crit_sect);
1611
1612 amber_LED_on (ctrl, hp_slot);
1613 green_LED_off (ctrl, hp_slot);
1614 slot_disable (ctrl, hp_slot);
1615
1616 set_SOGO(ctrl);
1617
1618 /* Wait for SOBS to be unset */
1619 wait_for_ctrl_irq (ctrl);
1620
1621 up(&ctrl->crit_sect);
1622 return rc;
1623 } else {
1624 cpqhp_save_slot_config(ctrl, func);
1625 }
1626
1627
1628 func->status = 0;
1629 func->switch_save = 0x10;
1630 func->is_a_board = 0x01;
1631
1632 /* next, we will instantiate the linux pci_dev structures (with
1633 * appropriate driver notification, if already present) */
1634 dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
1635 index = 0;
1636 do {
1637 new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
1638 if (new_slot && !new_slot->pci_dev) {
1639 cpqhp_configure_device(ctrl, new_slot);
1640 }
1641 } while (new_slot);
1642
1643 down(&ctrl->crit_sect);
1644
1645 green_LED_on (ctrl, hp_slot);
1646
1647 set_SOGO(ctrl);
1648
1649 /* Wait for SOBS to be unset */
1650 wait_for_ctrl_irq (ctrl);
1651
1652 up(&ctrl->crit_sect);
1653 } else {
1654 down(&ctrl->crit_sect);
1655
1656 amber_LED_on (ctrl, hp_slot);
1657 green_LED_off (ctrl, hp_slot);
1658 slot_disable (ctrl, hp_slot);
1659
1660 set_SOGO(ctrl);
1661
1662 /* Wait for SOBS to be unset */
1663 wait_for_ctrl_irq (ctrl);
1664
1665 up(&ctrl->crit_sect);
1666
1667 return rc;
1668 }
1669 return 0;
1670}
1671
1672
1673/**
1674 * remove_board - Turns off slot and LED's
1675 *
1676 */
1677static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
1678{
1679 int index;
1680 u8 skip = 0;
1681 u8 device;
1682 u8 hp_slot;
1683 u8 temp_byte;
1684 u32 rc;
1685 struct resource_lists res_lists;
1686 struct pci_func *temp_func;
1687
1688 if (cpqhp_unconfigure_device(func))
1689 return 1;
1690
1691 device = func->device;
1692
1693 hp_slot = func->device - ctrl->slot_device_offset;
1694 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1695
1696 /* When we get here, it is safe to change base address registers.
1697 * We will attempt to save the base address register lengths */
1698 if (replace_flag || !ctrl->add_support)
1699 rc = cpqhp_save_base_addr_length(ctrl, func);
1700 else if (!func->bus_head && !func->mem_head &&
1701 !func->p_mem_head && !func->io_head) {
1702 /* Here we check to see if we've saved any of the board's
1703 * resources already. If so, we'll skip the attempt to
1704 * determine what's being used. */
1705 index = 0;
1706 temp_func = cpqhp_slot_find(func->bus, func->device, index++);
1707 while (temp_func) {
1708 if (temp_func->bus_head || temp_func->mem_head
1709 || temp_func->p_mem_head || temp_func->io_head) {
1710 skip = 1;
1711 break;
1712 }
1713 temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
1714 }
1715
1716 if (!skip)
1717 rc = cpqhp_save_used_resources(ctrl, func);
1718 }
1719 /* Change status to shutdown */
1720 if (func->is_a_board)
1721 func->status = 0x01;
1722 func->configured = 0;
1723
1724 down(&ctrl->crit_sect);
1725
1726 green_LED_off (ctrl, hp_slot);
1727 slot_disable (ctrl, hp_slot);
1728
1729 set_SOGO(ctrl);
1730
1731 /* turn off SERR for slot */
1732 temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
1733 temp_byte &= ~(0x01 << hp_slot);
1734 writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
1735
1736 /* Wait for SOBS to be unset */
1737 wait_for_ctrl_irq (ctrl);
1738
1739 up(&ctrl->crit_sect);
1740
1741 if (!replace_flag && ctrl->add_support) {
1742 while (func) {
1743 res_lists.io_head = ctrl->io_head;
1744 res_lists.mem_head = ctrl->mem_head;
1745 res_lists.p_mem_head = ctrl->p_mem_head;
1746 res_lists.bus_head = ctrl->bus_head;
1747
1748 cpqhp_return_board_resources(func, &res_lists);
1749
1750 ctrl->io_head = res_lists.io_head;
1751 ctrl->mem_head = res_lists.mem_head;
1752 ctrl->p_mem_head = res_lists.p_mem_head;
1753 ctrl->bus_head = res_lists.bus_head;
1754
1755 cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1756 cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1757 cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1758 cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1759
1760 if (is_bridge(func)) {
1761 bridge_slot_remove(func);
1762 } else
1763 slot_remove(func);
1764
1765 func = cpqhp_slot_find(ctrl->bus, device, 0);
1766 }
1767
1768 /* Setup slot structure with entry for empty slot */
1769 func = cpqhp_slot_create(ctrl->bus);
1770
1771 if (func == NULL)
1772 return 1;
1773
1774 func->bus = ctrl->bus;
1775 func->device = device;
1776 func->function = 0;
1777 func->configured = 0;
1778 func->switch_save = 0x10;
1779 func->is_a_board = 0;
1780 func->p_task_event = NULL;
1781 }
1782
1783 return 0;
1784}
1785
1786static void pushbutton_helper_thread(unsigned long data)
1787{
1788 pushbutton_pending = data;
1789 up(&event_semaphore);
1790}
1791
1792
1793/* this is the main worker thread */
1794static int event_thread(void* data)
1795{
1796 struct controller *ctrl;
1797 lock_kernel();
1798 daemonize("phpd_event");
1799
1800 unlock_kernel();
1801
1802 while (1) {
1803 dbg("!!!!event_thread sleeping\n");
1804 down_interruptible (&event_semaphore);
1805 dbg("event_thread woken finished = %d\n", event_finished);
1806 if (event_finished) break;
1807 /* Do stuff here */
1808 if (pushbutton_pending)
1809 cpqhp_pushbutton_thread(pushbutton_pending);
1810 else
1811 for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
1812 interrupt_event_handler(ctrl);
1813 }
1814 dbg("event_thread signals exit\n");
1815 up(&event_exit);
1816 return 0;
1817}
1818
1819
1820int cpqhp_event_start_thread(void)
1821{
1822 int pid;
1823
1824 /* initialize our semaphores */
1825 init_MUTEX(&delay_sem);
1826 init_MUTEX_LOCKED(&event_semaphore);
1827 init_MUTEX_LOCKED(&event_exit);
1828 event_finished=0;
1829
1830 pid = kernel_thread(event_thread, NULL, 0);
1831 if (pid < 0) {
1832 err ("Can't start up our event thread\n");
1833 return -1;
1834 }
1835 dbg("Our event thread pid = %d\n", pid);
1836 return 0;
1837}
1838
1839
1840void cpqhp_event_stop_thread(void)
1841{
1842 event_finished = 1;
1843 dbg("event_thread finish command given\n");
1844 up(&event_semaphore);
1845 dbg("wait for event_thread to exit\n");
1846 down(&event_exit);
1847}
1848
1849
1850static int update_slot_info(struct controller *ctrl, struct slot *slot)
1851{
1852 struct hotplug_slot_info *info;
1853 int result;
1854
1855 info = kmalloc(sizeof(*info), GFP_KERNEL);
1856 if (!info)
1857 return -ENOMEM;
1858
1859 info->power_status = get_slot_enabled(ctrl, slot);
1860 info->attention_status = cpq_get_attention_status(ctrl, slot);
1861 info->latch_status = cpq_get_latch_status(ctrl, slot);
1862 info->adapter_status = get_presence_status(ctrl, slot);
1863 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1864 kfree (info);
1865 return result;
1866}
1867
1868static void interrupt_event_handler(struct controller *ctrl)
1869{
1870 int loop = 0;
1871 int change = 1;
1872 struct pci_func *func;
1873 u8 hp_slot;
1874 struct slot *p_slot;
1875
1876 while (change) {
1877 change = 0;
1878
1879 for (loop = 0; loop < 10; loop++) {
1880 /* dbg("loop %d\n", loop); */
1881 if (ctrl->event_queue[loop].event_type != 0) {
1882 hp_slot = ctrl->event_queue[loop].hp_slot;
1883
1884 func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
1885 if (!func)
1886 return;
1887
1888 p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1889 if (!p_slot)
1890 return;
1891
1892 dbg("hp_slot %d, func %p, p_slot %p\n",
1893 hp_slot, func, p_slot);
1894
1895 if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1896 dbg("button pressed\n");
1897 } else if (ctrl->event_queue[loop].event_type ==
1898 INT_BUTTON_CANCEL) {
1899 dbg("button cancel\n");
1900 del_timer(&p_slot->task_event);
1901
1902 down(&ctrl->crit_sect);
1903
1904 if (p_slot->state == BLINKINGOFF_STATE) {
1905 /* slot is on */
1906 dbg("turn on green LED\n");
1907 green_LED_on (ctrl, hp_slot);
1908 } else if (p_slot->state == BLINKINGON_STATE) {
1909 /* slot is off */
1910 dbg("turn off green LED\n");
1911 green_LED_off (ctrl, hp_slot);
1912 }
1913
1914 info(msg_button_cancel, p_slot->number);
1915
1916 p_slot->state = STATIC_STATE;
1917
1918 amber_LED_off (ctrl, hp_slot);
1919
1920 set_SOGO(ctrl);
1921
1922 /* Wait for SOBS to be unset */
1923 wait_for_ctrl_irq (ctrl);
1924
1925 up(&ctrl->crit_sect);
1926 }
1927 /*** button Released (No action on press...) */
1928 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
1929 dbg("button release\n");
1930
1931 if (is_slot_enabled (ctrl, hp_slot)) {
1932 dbg("slot is on\n");
1933 p_slot->state = BLINKINGOFF_STATE;
1934 info(msg_button_off, p_slot->number);
1935 } else {
1936 dbg("slot is off\n");
1937 p_slot->state = BLINKINGON_STATE;
1938 info(msg_button_on, p_slot->number);
1939 }
1940 down(&ctrl->crit_sect);
1941
1942 dbg("blink green LED and turn off amber\n");
1943
1944 amber_LED_off (ctrl, hp_slot);
1945 green_LED_blink (ctrl, hp_slot);
1946
1947 set_SOGO(ctrl);
1948
1949 /* Wait for SOBS to be unset */
1950 wait_for_ctrl_irq (ctrl);
1951
1952 up(&ctrl->crit_sect);
1953 init_timer(&p_slot->task_event);
1954 p_slot->hp_slot = hp_slot;
1955 p_slot->ctrl = ctrl;
1956/* p_slot->physical_slot = physical_slot; */
1957 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1958 p_slot->task_event.function = pushbutton_helper_thread;
1959 p_slot->task_event.data = (u32) p_slot;
1960
1961 dbg("add_timer p_slot = %p\n", p_slot);
1962 add_timer(&p_slot->task_event);
1963 }
1964 /***********POWER FAULT */
1965 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1966 dbg("power fault\n");
1967 } else {
1968 /* refresh notification */
1969 if (p_slot)
1970 update_slot_info(ctrl, p_slot);
1971 }
1972
1973 ctrl->event_queue[loop].event_type = 0;
1974
1975 change = 1;
1976 }
1977 } /* End of FOR loop */
1978 }
1979
1980 return;
1981}
1982
1983
1984/**
1985 * cpqhp_pushbutton_thread
1986 *
1987 * Scheduled procedure to handle blocking stuff for the pushbuttons
1988 * Handles all pending events and exits.
1989 *
1990 */
1991void cpqhp_pushbutton_thread(unsigned long slot)
1992{
1993 u8 hp_slot;
1994 u8 device;
1995 struct pci_func *func;
1996 struct slot *p_slot = (struct slot *) slot;
1997 struct controller *ctrl = (struct controller *) p_slot->ctrl;
1998
1999 pushbutton_pending = 0;
2000 hp_slot = p_slot->hp_slot;
2001
2002 device = p_slot->device;
2003
2004 if (is_slot_enabled(ctrl, hp_slot)) {
2005 p_slot->state = POWEROFF_STATE;
2006 /* power Down board */
2007 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
2008 dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
2009 if (!func) {
2010 dbg("Error! func NULL in %s\n", __FUNCTION__);
2011 return ;
2012 }
2013
2014 if (func != NULL && ctrl != NULL) {
2015 if (cpqhp_process_SS(ctrl, func) != 0) {
2016 amber_LED_on (ctrl, hp_slot);
2017 green_LED_on (ctrl, hp_slot);
2018
2019 set_SOGO(ctrl);
2020
2021 /* Wait for SOBS to be unset */
2022 wait_for_ctrl_irq (ctrl);
2023 }
2024 }
2025
2026 p_slot->state = STATIC_STATE;
2027 } else {
2028 p_slot->state = POWERON_STATE;
2029 /* slot is off */
2030
2031 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
2032 dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
2033 if (!func) {
2034 dbg("Error! func NULL in %s\n", __FUNCTION__);
2035 return ;
2036 }
2037
2038 if (func != NULL && ctrl != NULL) {
2039 if (cpqhp_process_SI(ctrl, func) != 0) {
2040 amber_LED_on(ctrl, hp_slot);
2041 green_LED_off(ctrl, hp_slot);
2042
2043 set_SOGO(ctrl);
2044
2045 /* Wait for SOBS to be unset */
2046 wait_for_ctrl_irq (ctrl);
2047 }
2048 }
2049
2050 p_slot->state = STATIC_STATE;
2051 }
2052
2053 return;
2054}
2055
2056
2057int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func)
2058{
2059 u8 device, hp_slot;
2060 u16 temp_word;
2061 u32 tempdword;
2062 int rc;
2063 struct slot* p_slot;
2064 int physical_slot = 0;
2065
2066 tempdword = 0;
2067
2068 device = func->device;
2069 hp_slot = device - ctrl->slot_device_offset;
2070 p_slot = cpqhp_find_slot(ctrl, device);
2071 if (p_slot)
2072 physical_slot = p_slot->number;
2073
2074 /* Check to see if the interlock is closed */
2075 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
2076
2077 if (tempdword & (0x01 << hp_slot)) {
2078 return 1;
2079 }
2080
2081 if (func->is_a_board) {
2082 rc = board_replaced(func, ctrl);
2083 } else {
2084 /* add board */
2085 slot_remove(func);
2086
2087 func = cpqhp_slot_create(ctrl->bus);
2088 if (func == NULL)
2089 return 1;
2090
2091 func->bus = ctrl->bus;
2092 func->device = device;
2093 func->function = 0;
2094 func->configured = 0;
2095 func->is_a_board = 1;
2096
2097 /* We have to save the presence info for these slots */
2098 temp_word = ctrl->ctrl_int_comp >> 16;
2099 func->presence_save = (temp_word >> hp_slot) & 0x01;
2100 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
2101
2102 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2103 func->switch_save = 0;
2104 } else {
2105 func->switch_save = 0x10;
2106 }
2107
2108 rc = board_added(func, ctrl);
2109 if (rc) {
2110 if (is_bridge(func)) {
2111 bridge_slot_remove(func);
2112 } else
2113 slot_remove(func);
2114
2115 /* Setup slot structure with entry for empty slot */
2116 func = cpqhp_slot_create(ctrl->bus);
2117
2118 if (func == NULL)
2119 return 1;
2120
2121 func->bus = ctrl->bus;
2122 func->device = device;
2123 func->function = 0;
2124 func->configured = 0;
2125 func->is_a_board = 0;
2126
2127 /* We have to save the presence info for these slots */
2128 temp_word = ctrl->ctrl_int_comp >> 16;
2129 func->presence_save = (temp_word >> hp_slot) & 0x01;
2130 func->presence_save |=
2131 (temp_word >> (hp_slot + 7)) & 0x02;
2132
2133 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2134 func->switch_save = 0;
2135 } else {
2136 func->switch_save = 0x10;
2137 }
2138 }
2139 }
2140
2141 if (rc) {
2142 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2143 }
2144
2145 if (p_slot)
2146 update_slot_info(ctrl, p_slot);
2147
2148 return rc;
2149}
2150
2151
2152int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
2153{
2154 u8 device, class_code, header_type, BCR;
2155 u8 index = 0;
2156 u8 replace_flag;
2157 u32 rc = 0;
2158 unsigned int devfn;
2159 struct slot* p_slot;
2160 struct pci_bus *pci_bus = ctrl->pci_bus;
2161 int physical_slot=0;
2162
2163 device = func->device;
2164 func = cpqhp_slot_find(ctrl->bus, device, index++);
2165 p_slot = cpqhp_find_slot(ctrl, device);
2166 if (p_slot) {
2167 physical_slot = p_slot->number;
2168 }
2169
2170 /* Make sure there are no video controllers here */
2171 while (func && !rc) {
2172 pci_bus->number = func->bus;
2173 devfn = PCI_DEVFN(func->device, func->function);
2174
2175 /* Check the Class Code */
2176 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2177 if (rc)
2178 return rc;
2179
2180 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2181 /* Display/Video adapter (not supported) */
2182 rc = REMOVE_NOT_SUPPORTED;
2183 } else {
2184 /* See if it's a bridge */
2185 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
2186 if (rc)
2187 return rc;
2188
2189 /* If it's a bridge, check the VGA Enable bit */
2190 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2191 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
2192 if (rc)
2193 return rc;
2194
2195 /* If the VGA Enable bit is set, remove isn't
2196 * supported */
2197 if (BCR & PCI_BRIDGE_CTL_VGA) {
2198 rc = REMOVE_NOT_SUPPORTED;
2199 }
2200 }
2201 }
2202
2203 func = cpqhp_slot_find(ctrl->bus, device, index++);
2204 }
2205
2206 func = cpqhp_slot_find(ctrl->bus, device, 0);
2207 if ((func != NULL) && !rc) {
2208 /* FIXME: Replace flag should be passed into process_SS */
2209 replace_flag = !(ctrl->add_support);
2210 rc = remove_board(func, replace_flag, ctrl);
2211 } else if (!rc) {
2212 rc = 1;
2213 }
2214
2215 if (p_slot)
2216 update_slot_info(ctrl, p_slot);
2217
2218 return rc;
2219}
2220
2221/**
2222 * switch_leds: switch the leds, go from one site to the other.
2223 * @ctrl: controller to use
2224 * @num_of_slots: number of slots to use
2225 * @direction: 1 to start from the left side, 0 to start right.
2226 */
2227static void switch_leds(struct controller *ctrl, const int num_of_slots,
2228 u32 *work_LED, const int direction)
2229{
2230 int loop;
2231
2232 for (loop = 0; loop < num_of_slots; loop++) {
2233 if (direction)
2234 *work_LED = *work_LED >> 1;
2235 else
2236 *work_LED = *work_LED << 1;
2237 writel(*work_LED, ctrl->hpc_reg + LED_CONTROL);
2238
2239 set_SOGO(ctrl);
2240
2241 /* Wait for SOGO interrupt */
2242 wait_for_ctrl_irq(ctrl);
2243
2244 /* Get ready for next iteration */
2245 long_delay((2*HZ)/10);
2246 }
2247}
2248
2249/**
2250 * hardware_test - runs hardware tests
2251 *
2252 * For hot plug ctrl folks to play with.
2253 * test_num is the number written to the "test" file in sysfs
2254 *
2255 */
2256int cpqhp_hardware_test(struct controller *ctrl, int test_num)
2257{
2258 u32 save_LED;
2259 u32 work_LED;
2260 int loop;
2261 int num_of_slots;
2262
2263 num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
2264
2265 switch (test_num) {
2266 case 1:
2267 /* Do stuff here! */
2268
2269 /* Do that funky LED thing */
2270 /* so we can restore them later */
2271 save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
2272 work_LED = 0x01010101;
2273 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2274 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2275 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2276 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2277
2278 work_LED = 0x01010000;
2279 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2280 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2281 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2282 work_LED = 0x00000101;
2283 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2284 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2285 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2286
2287 work_LED = 0x01010000;
2288 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2289 for (loop = 0; loop < num_of_slots; loop++) {
2290 set_SOGO(ctrl);
2291
2292 /* Wait for SOGO interrupt */
2293 wait_for_ctrl_irq (ctrl);
2294
2295 /* Get ready for next iteration */
2296 long_delay((3*HZ)/10);
2297 work_LED = work_LED >> 16;
2298 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2299
2300 set_SOGO(ctrl);
2301
2302 /* Wait for SOGO interrupt */
2303 wait_for_ctrl_irq (ctrl);
2304
2305 /* Get ready for next iteration */
2306 long_delay((3*HZ)/10);
2307 work_LED = work_LED << 16;
2308 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2309 work_LED = work_LED << 1;
2310 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2311 }
2312
2313 /* put it back the way it was */
2314 writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
2315
2316 set_SOGO(ctrl);
2317
2318 /* Wait for SOBS to be unset */
2319 wait_for_ctrl_irq (ctrl);
2320 break;
2321 case 2:
2322 /* Do other stuff here! */
2323 break;
2324 case 3:
2325 /* and more... */
2326 break;
2327 }
2328 return 0;
2329}
2330
2331
2332/**
2333 * configure_new_device - Configures the PCI header information of one board.
2334 *
2335 * @ctrl: pointer to controller structure
2336 * @func: pointer to function structure
2337 * @behind_bridge: 1 if this is a recursive call, 0 if not
2338 * @resources: pointer to set of resource lists
2339 *
2340 * Returns 0 if success
2341 *
2342 */
2343static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
2344 u8 behind_bridge, struct resource_lists * resources)
2345{
2346 u8 temp_byte, function, max_functions, stop_it;
2347 int rc;
2348 u32 ID;
2349 struct pci_func *new_slot;
2350 int index;
2351
2352 new_slot = func;
2353
2354 dbg("%s\n", __FUNCTION__);
2355 /* Check for Multi-function device */
2356 ctrl->pci_bus->number = func->bus;
2357 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
2358 if (rc) {
2359 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2360 return rc;
2361 }
2362
2363 if (temp_byte & 0x80) /* Multi-function device */
2364 max_functions = 8;
2365 else
2366 max_functions = 1;
2367
2368 function = 0;
2369
2370 do {
2371 rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
2372
2373 if (rc) {
2374 dbg("configure_new_function failed %d\n",rc);
2375 index = 0;
2376
2377 while (new_slot) {
2378 new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
2379
2380 if (new_slot)
2381 cpqhp_return_board_resources(new_slot, resources);
2382 }
2383
2384 return rc;
2385 }
2386
2387 function++;
2388
2389 stop_it = 0;
2390
2391 /* The following loop skips to the next present function
2392 * and creates a board structure */
2393
2394 while ((function < max_functions) && (!stop_it)) {
2395 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
2396
2397 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
2398 function++;
2399 } else { /* There's something there */
2400 /* Setup slot structure. */
2401 new_slot = cpqhp_slot_create(func->bus);
2402
2403 if (new_slot == NULL)
2404 return 1;
2405
2406 new_slot->bus = func->bus;
2407 new_slot->device = func->device;
2408 new_slot->function = function;
2409 new_slot->is_a_board = 1;
2410 new_slot->status = 0;
2411
2412 stop_it++;
2413 }
2414 }
2415
2416 } while (function < max_functions);
2417 dbg("returning from configure_new_device\n");
2418
2419 return 0;
2420}
2421
2422
2423/*
2424 Configuration logic that involves the hotplug data structures and
2425 their bookkeeping
2426 */
2427
2428
2429/**
2430 * configure_new_function - Configures the PCI header information of one device
2431 *
2432 * @ctrl: pointer to controller structure
2433 * @func: pointer to function structure
2434 * @behind_bridge: 1 if this is a recursive call, 0 if not
2435 * @resources: pointer to set of resource lists
2436 *
2437 * Calls itself recursively for bridged devices.
2438 * Returns 0 if success
2439 *
2440 */
2441static int configure_new_function(struct controller *ctrl, struct pci_func *func,
2442 u8 behind_bridge,
2443 struct resource_lists *resources)
2444{
2445 int cloop;
2446 u8 IRQ = 0;
2447 u8 temp_byte;
2448 u8 device;
2449 u8 class_code;
2450 u16 command;
2451 u16 temp_word;
2452 u32 temp_dword;
2453 u32 rc;
2454 u32 temp_register;
2455 u32 base;
2456 u32 ID;
2457 unsigned int devfn;
2458 struct pci_resource *mem_node;
2459 struct pci_resource *p_mem_node;
2460 struct pci_resource *io_node;
2461 struct pci_resource *bus_node;
2462 struct pci_resource *hold_mem_node;
2463 struct pci_resource *hold_p_mem_node;
2464 struct pci_resource *hold_IO_node;
2465 struct pci_resource *hold_bus_node;
2466 struct irq_mapping irqs;
2467 struct pci_func *new_slot;
2468 struct pci_bus *pci_bus;
2469 struct resource_lists temp_resources;
2470
2471 pci_bus = ctrl->pci_bus;
2472 pci_bus->number = func->bus;
2473 devfn = PCI_DEVFN(func->device, func->function);
2474
2475 /* Check for Bridge */
2476 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2477 if (rc)
2478 return rc;
2479
2480 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2481 /* set Primary bus */
2482 dbg("set Primary bus = %d\n", func->bus);
2483 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2484 if (rc)
2485 return rc;
2486
2487 /* find range of busses to use */
2488 dbg("find ranges of buses to use\n");
2489 bus_node = get_max_resource(&(resources->bus_head), 1);
2490
2491 /* If we don't have any busses to allocate, we can't continue */
2492 if (!bus_node)
2493 return -ENOMEM;
2494
2495 /* set Secondary bus */
2496 temp_byte = bus_node->base;
2497 dbg("set Secondary bus = %d\n", bus_node->base);
2498 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2499 if (rc)
2500 return rc;
2501
2502 /* set subordinate bus */
2503 temp_byte = bus_node->base + bus_node->length - 1;
2504 dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
2505 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2506 if (rc)
2507 return rc;
2508
2509 /* set subordinate Latency Timer and base Latency Timer */
2510 temp_byte = 0x40;
2511 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
2512 if (rc)
2513 return rc;
2514 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
2515 if (rc)
2516 return rc;
2517
2518 /* set Cache Line size */
2519 temp_byte = 0x08;
2520 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
2521 if (rc)
2522 return rc;
2523
2524 /* Setup the IO, memory, and prefetchable windows */
2525 io_node = get_max_resource(&(resources->io_head), 0x1000);
2526 if (!io_node)
2527 return -ENOMEM;
2528 mem_node = get_max_resource(&(resources->mem_head), 0x100000);
2529 if (!mem_node)
2530 return -ENOMEM;
2531 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
2532 if (!p_mem_node)
2533 return -ENOMEM;
2534 dbg("Setup the IO, memory, and prefetchable windows\n");
2535 dbg("io_node\n");
2536 dbg("(base, len, next) (%x, %x, %p)\n", io_node->base,
2537 io_node->length, io_node->next);
2538 dbg("mem_node\n");
2539 dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base,
2540 mem_node->length, mem_node->next);
2541 dbg("p_mem_node\n");
2542 dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2543 p_mem_node->length, p_mem_node->next);
2544
2545 /* set up the IRQ info */
2546 if (!resources->irqs) {
2547 irqs.barber_pole = 0;
2548 irqs.interrupt[0] = 0;
2549 irqs.interrupt[1] = 0;
2550 irqs.interrupt[2] = 0;
2551 irqs.interrupt[3] = 0;
2552 irqs.valid_INT = 0;
2553 } else {
2554 irqs.barber_pole = resources->irqs->barber_pole;
2555 irqs.interrupt[0] = resources->irqs->interrupt[0];
2556 irqs.interrupt[1] = resources->irqs->interrupt[1];
2557 irqs.interrupt[2] = resources->irqs->interrupt[2];
2558 irqs.interrupt[3] = resources->irqs->interrupt[3];
2559 irqs.valid_INT = resources->irqs->valid_INT;
2560 }
2561
2562 /* set up resource lists that are now aligned on top and bottom
2563 * for anything behind the bridge. */
2564 temp_resources.bus_head = bus_node;
2565 temp_resources.io_head = io_node;
2566 temp_resources.mem_head = mem_node;
2567 temp_resources.p_mem_head = p_mem_node;
2568 temp_resources.irqs = &irqs;
2569
2570 /* Make copies of the nodes we are going to pass down so that
2571 * if there is a problem,we can just use these to free resources */
2572 hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
2573 hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
2574 hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
2575 hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
2576
2577 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2578 kfree(hold_bus_node);
2579 kfree(hold_IO_node);
2580 kfree(hold_mem_node);
2581 kfree(hold_p_mem_node);
2582
2583 return 1;
2584 }
2585
2586 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2587
2588 bus_node->base += 1;
2589 bus_node->length -= 1;
2590 bus_node->next = NULL;
2591
2592 /* If we have IO resources copy them and fill in the bridge's
2593 * IO range registers */
2594 if (io_node) {
2595 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2596 io_node->next = NULL;
2597
2598 /* set IO base and Limit registers */
2599 temp_byte = io_node->base >> 8;
2600 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
2601
2602 temp_byte = (io_node->base + io_node->length - 1) >> 8;
2603 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2604 } else {
2605 kfree(hold_IO_node);
2606 hold_IO_node = NULL;
2607 }
2608
2609 /* If we have memory resources copy them and fill in the
2610 * bridge's memory range registers. Otherwise, fill in the
2611 * range registers with values that disable them. */
2612 if (mem_node) {
2613 memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2614 mem_node->next = NULL;
2615
2616 /* set Mem base and Limit registers */
2617 temp_word = mem_node->base >> 16;
2618 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2619
2620 temp_word = (mem_node->base + mem_node->length - 1) >> 16;
2621 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2622 } else {
2623 temp_word = 0xFFFF;
2624 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2625
2626 temp_word = 0x0000;
2627 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2628
2629 kfree(hold_mem_node);
2630 hold_mem_node = NULL;
2631 }
2632
2633 /* If we have prefetchable memory resources copy them and
2634 * fill in the bridge's memory range registers. Otherwise,
2635 * fill in the range registers with values that disable them. */
2636 if (p_mem_node) {
2637 memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2638 p_mem_node->next = NULL;
2639
2640 /* set Pre Mem base and Limit registers */
2641 temp_word = p_mem_node->base >> 16;
2642 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2643
2644 temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
2645 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2646 } else {
2647 temp_word = 0xFFFF;
2648 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2649
2650 temp_word = 0x0000;
2651 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2652
2653 kfree(hold_p_mem_node);
2654 hold_p_mem_node = NULL;
2655 }
2656
2657 /* Adjust this to compensate for extra adjustment in first loop */
2658 irqs.barber_pole--;
2659
2660 rc = 0;
2661
2662 /* Here we actually find the devices and configure them */
2663 for (device = 0; (device <= 0x1F) && !rc; device++) {
2664 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2665
2666 ID = 0xFFFFFFFF;
2667 pci_bus->number = hold_bus_node->base;
2668 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
2669 pci_bus->number = func->bus;
2670
2671 if (ID != 0xFFFFFFFF) { /* device present */
2672 /* Setup slot structure. */
2673 new_slot = cpqhp_slot_create(hold_bus_node->base);
2674
2675 if (new_slot == NULL) {
2676 rc = -ENOMEM;
2677 continue;
2678 }
2679
2680 new_slot->bus = hold_bus_node->base;
2681 new_slot->device = device;
2682 new_slot->function = 0;
2683 new_slot->is_a_board = 1;
2684 new_slot->status = 0;
2685
2686 rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
2687 dbg("configure_new_device rc=0x%x\n",rc);
2688 } /* End of IF (device in slot?) */
2689 } /* End of FOR loop */
2690
2691 if (rc)
2692 goto free_and_out;
2693 /* save the interrupt routing information */
2694 if (resources->irqs) {
2695 resources->irqs->interrupt[0] = irqs.interrupt[0];
2696 resources->irqs->interrupt[1] = irqs.interrupt[1];
2697 resources->irqs->interrupt[2] = irqs.interrupt[2];
2698 resources->irqs->interrupt[3] = irqs.interrupt[3];
2699 resources->irqs->valid_INT = irqs.valid_INT;
2700 } else if (!behind_bridge) {
2701 /* We need to hook up the interrupts here */
2702 for (cloop = 0; cloop < 4; cloop++) {
2703 if (irqs.valid_INT & (0x01 << cloop)) {
2704 rc = cpqhp_set_irq(func->bus, func->device,
2705 0x0A + cloop, irqs.interrupt[cloop]);
2706 if (rc)
2707 goto free_and_out;
2708 }
2709 } /* end of for loop */
2710 }
2711 /* Return unused bus resources
2712 * First use the temporary node to store information for
2713 * the board */
2714 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2715 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2716
2717 hold_bus_node->next = func->bus_head;
2718 func->bus_head = hold_bus_node;
2719
2720 temp_byte = temp_resources.bus_head->base - 1;
2721
2722 /* set subordinate bus */
2723 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2724
2725 if (temp_resources.bus_head->length == 0) {
2726 kfree(temp_resources.bus_head);
2727 temp_resources.bus_head = NULL;
2728 } else {
2729 return_resource(&(resources->bus_head), temp_resources.bus_head);
2730 }
2731 }
2732
2733 /* If we have IO space available and there is some left,
2734 * return the unused portion */
2735 if (hold_IO_node && temp_resources.io_head) {
2736 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2737 &hold_IO_node, 0x1000);
2738
2739 /* Check if we were able to split something off */
2740 if (io_node) {
2741 hold_IO_node->base = io_node->base + io_node->length;
2742
2743 temp_byte = (hold_IO_node->base) >> 8;
2744 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2745
2746 return_resource(&(resources->io_head), io_node);
2747 }
2748
2749 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2750
2751 /* Check if we were able to split something off */
2752 if (io_node) {
2753 /* First use the temporary node to store
2754 * information for the board */
2755 hold_IO_node->length = io_node->base - hold_IO_node->base;
2756
2757 /* If we used any, add it to the board's list */
2758 if (hold_IO_node->length) {
2759 hold_IO_node->next = func->io_head;
2760 func->io_head = hold_IO_node;
2761
2762 temp_byte = (io_node->base - 1) >> 8;
2763 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2764
2765 return_resource(&(resources->io_head), io_node);
2766 } else {
2767 /* it doesn't need any IO */
2768 temp_word = 0x0000;
2769 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
2770
2771 return_resource(&(resources->io_head), io_node);
2772 kfree(hold_IO_node);
2773 }
2774 } else {
2775 /* it used most of the range */
2776 hold_IO_node->next = func->io_head;
2777 func->io_head = hold_IO_node;
2778 }
2779 } else if (hold_IO_node) {
2780 /* it used the whole range */
2781 hold_IO_node->next = func->io_head;
2782 func->io_head = hold_IO_node;
2783 }
2784 /* If we have memory space available and there is some left,
2785 * return the unused portion */
2786 if (hold_mem_node && temp_resources.mem_head) {
2787 mem_node = do_pre_bridge_resource_split(&(temp_resources. mem_head),
2788 &hold_mem_node, 0x100000);
2789
2790 /* Check if we were able to split something off */
2791 if (mem_node) {
2792 hold_mem_node->base = mem_node->base + mem_node->length;
2793
2794 temp_word = (hold_mem_node->base) >> 16;
2795 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2796
2797 return_resource(&(resources->mem_head), mem_node);
2798 }
2799
2800 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
2801
2802 /* Check if we were able to split something off */
2803 if (mem_node) {
2804 /* First use the temporary node to store
2805 * information for the board */
2806 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2807
2808 if (hold_mem_node->length) {
2809 hold_mem_node->next = func->mem_head;
2810 func->mem_head = hold_mem_node;
2811
2812 /* configure end address */
2813 temp_word = (mem_node->base - 1) >> 16;
2814 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2815
2816 /* Return unused resources to the pool */
2817 return_resource(&(resources->mem_head), mem_node);
2818 } else {
2819 /* it doesn't need any Mem */
2820 temp_word = 0x0000;
2821 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2822
2823 return_resource(&(resources->mem_head), mem_node);
2824 kfree(hold_mem_node);
2825 }
2826 } else {
2827 /* it used most of the range */
2828 hold_mem_node->next = func->mem_head;
2829 func->mem_head = hold_mem_node;
2830 }
2831 } else if (hold_mem_node) {
2832 /* it used the whole range */
2833 hold_mem_node->next = func->mem_head;
2834 func->mem_head = hold_mem_node;
2835 }
2836 /* If we have prefetchable memory space available and there
2837 * is some left at the end, return the unused portion */
2838 if (hold_p_mem_node && temp_resources.p_mem_head) {
2839 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2840 &hold_p_mem_node, 0x100000);
2841
2842 /* Check if we were able to split something off */
2843 if (p_mem_node) {
2844 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2845
2846 temp_word = (hold_p_mem_node->base) >> 16;
2847 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2848
2849 return_resource(&(resources->p_mem_head), p_mem_node);
2850 }
2851
2852 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
2853
2854 /* Check if we were able to split something off */
2855 if (p_mem_node) {
2856 /* First use the temporary node to store
2857 * information for the board */
2858 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2859
2860 /* If we used any, add it to the board's list */
2861 if (hold_p_mem_node->length) {
2862 hold_p_mem_node->next = func->p_mem_head;
2863 func->p_mem_head = hold_p_mem_node;
2864
2865 temp_word = (p_mem_node->base - 1) >> 16;
2866 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2867
2868 return_resource(&(resources->p_mem_head), p_mem_node);
2869 } else {
2870 /* it doesn't need any PMem */
2871 temp_word = 0x0000;
2872 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2873
2874 return_resource(&(resources->p_mem_head), p_mem_node);
2875 kfree(hold_p_mem_node);
2876 }
2877 } else {
2878 /* it used the most of the range */
2879 hold_p_mem_node->next = func->p_mem_head;
2880 func->p_mem_head = hold_p_mem_node;
2881 }
2882 } else if (hold_p_mem_node) {
2883 /* it used the whole range */
2884 hold_p_mem_node->next = func->p_mem_head;
2885 func->p_mem_head = hold_p_mem_node;
2886 }
2887 /* We should be configuring an IRQ and the bridge's base address
2888 * registers if it needs them. Although we have never seen such
2889 * a device */
2890
2891 /* enable card */
2892 command = 0x0157; /* = PCI_COMMAND_IO |
2893 * PCI_COMMAND_MEMORY |
2894 * PCI_COMMAND_MASTER |
2895 * PCI_COMMAND_INVALIDATE |
2896 * PCI_COMMAND_PARITY |
2897 * PCI_COMMAND_SERR */
2898 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
2899
2900 /* set Bridge Control Register */
2901 command = 0x07; /* = PCI_BRIDGE_CTL_PARITY |
2902 * PCI_BRIDGE_CTL_SERR |
2903 * PCI_BRIDGE_CTL_NO_ISA */
2904 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
2905 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2906 /* Standard device */
2907 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2908
2909 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2910 /* Display (video) adapter (not supported) */
2911 return DEVICE_TYPE_NOT_SUPPORTED;
2912 }
2913 /* Figure out IO and memory needs */
2914 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
2915 temp_register = 0xFFFFFFFF;
2916
2917 dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
2918 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2919
2920 rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
2921 dbg("CND: base = 0x%x\n", temp_register);
2922
2923 if (temp_register) { /* If this register is implemented */
2924 if ((temp_register & 0x03L) == 0x01) {
2925 /* Map IO */
2926
2927 /* set base = amount of IO space */
2928 base = temp_register & 0xFFFFFFFC;
2929 base = ~base + 1;
2930
2931 dbg("CND: length = 0x%x\n", base);
2932 io_node = get_io_resource(&(resources->io_head), base);
2933 dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
2934 io_node->base, io_node->length, io_node->next);
2935 dbg("func (%p) io_head (%p)\n", func, func->io_head);
2936
2937 /* allocate the resource to the board */
2938 if (io_node) {
2939 base = io_node->base;
2940
2941 io_node->next = func->io_head;
2942 func->io_head = io_node;
2943 } else
2944 return -ENOMEM;
2945 } else if ((temp_register & 0x0BL) == 0x08) {
2946 /* Map prefetchable memory */
2947 base = temp_register & 0xFFFFFFF0;
2948 base = ~base + 1;
2949
2950 dbg("CND: length = 0x%x\n", base);
2951 p_mem_node = get_resource(&(resources->p_mem_head), base);
2952
2953 /* allocate the resource to the board */
2954 if (p_mem_node) {
2955 base = p_mem_node->base;
2956
2957 p_mem_node->next = func->p_mem_head;
2958 func->p_mem_head = p_mem_node;
2959 } else
2960 return -ENOMEM;
2961 } else if ((temp_register & 0x0BL) == 0x00) {
2962 /* Map memory */
2963 base = temp_register & 0xFFFFFFF0;
2964 base = ~base + 1;
2965
2966 dbg("CND: length = 0x%x\n", base);
2967 mem_node = get_resource(&(resources->mem_head), base);
2968
2969 /* allocate the resource to the board */
2970 if (mem_node) {
2971 base = mem_node->base;
2972
2973 mem_node->next = func->mem_head;
2974 func->mem_head = mem_node;
2975 } else
2976 return -ENOMEM;
2977 } else if ((temp_register & 0x0BL) == 0x04) {
2978 /* Map memory */
2979 base = temp_register & 0xFFFFFFF0;
2980 base = ~base + 1;
2981
2982 dbg("CND: length = 0x%x\n", base);
2983 mem_node = get_resource(&(resources->mem_head), base);
2984
2985 /* allocate the resource to the board */
2986 if (mem_node) {
2987 base = mem_node->base;
2988
2989 mem_node->next = func->mem_head;
2990 func->mem_head = mem_node;
2991 } else
2992 return -ENOMEM;
2993 } else if ((temp_register & 0x0BL) == 0x06) {
2994 /* Those bits are reserved, we can't handle this */
2995 return 1;
2996 } else {
2997 /* Requesting space below 1M */
2998 return NOT_ENOUGH_RESOURCES;
2999 }
3000
3001 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
3002
3003 /* Check for 64-bit base */
3004 if ((temp_register & 0x07L) == 0x04) {
3005 cloop += 4;
3006
3007 /* Upper 32 bits of address always zero
3008 * on today's systems */
3009 /* FIXME this is probably not true on
3010 * Alpha and ia64??? */
3011 base = 0;
3012 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
3013 }
3014 }
3015 } /* End of base register loop */
3016 if (cpqhp_legacy_mode) {
3017 /* Figure out which interrupt pin this function uses */
3018 rc = pci_bus_read_config_byte (pci_bus, devfn,
3019 PCI_INTERRUPT_PIN, &temp_byte);
3020
3021 /* If this function needs an interrupt and we are behind
3022 * a bridge and the pin is tied to something that's
3023 * alread mapped, set this one the same */
3024 if (temp_byte && resources->irqs &&
3025 (resources->irqs->valid_INT &
3026 (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
3027 /* We have to share with something already set up */
3028 IRQ = resources->irqs->interrupt[(temp_byte +
3029 resources->irqs->barber_pole - 1) & 0x03];
3030 } else {
3031 /* Program IRQ based on card type */
3032 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
3033
3034 if (class_code == PCI_BASE_CLASS_STORAGE) {
3035 IRQ = cpqhp_disk_irq;
3036 } else {
3037 IRQ = cpqhp_nic_irq;
3038 }
3039 }
3040
3041 /* IRQ Line */
3042 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
3043 }
3044
3045 if (!behind_bridge) {
3046 rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
3047 if (rc)
3048 return 1;
3049 } else {
3050 /* TBD - this code may also belong in the other clause
3051 * of this If statement */
3052 resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
3053 resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
3054 }
3055
3056 /* Latency Timer */
3057 temp_byte = 0x40;
3058 rc = pci_bus_write_config_byte(pci_bus, devfn,
3059 PCI_LATENCY_TIMER, temp_byte);
3060
3061 /* Cache Line size */
3062 temp_byte = 0x08;
3063 rc = pci_bus_write_config_byte(pci_bus, devfn,
3064 PCI_CACHE_LINE_SIZE, temp_byte);
3065
3066 /* disable ROM base Address */
3067 temp_dword = 0x00L;
3068 rc = pci_bus_write_config_word(pci_bus, devfn,
3069 PCI_ROM_ADDRESS, temp_dword);
3070
3071 /* enable card */
3072 temp_word = 0x0157; /* = PCI_COMMAND_IO |
3073 * PCI_COMMAND_MEMORY |
3074 * PCI_COMMAND_MASTER |
3075 * PCI_COMMAND_INVALIDATE |
3076 * PCI_COMMAND_PARITY |
3077 * PCI_COMMAND_SERR */
3078 rc = pci_bus_write_config_word (pci_bus, devfn,
3079 PCI_COMMAND, temp_word);
3080 } else { /* End of Not-A-Bridge else */
3081 /* It's some strange type of PCI adapter (Cardbus?) */
3082 return DEVICE_TYPE_NOT_SUPPORTED;
3083 }
3084
3085 func->configured = 1;
3086
3087 return 0;
3088free_and_out:
3089 cpqhp_destroy_resource_list (&temp_resources);
3090
3091 return_resource(&(resources-> bus_head), hold_bus_node);
3092 return_resource(&(resources-> io_head), hold_IO_node);
3093 return_resource(&(resources-> mem_head), hold_mem_node);
3094 return_resource(&(resources-> p_mem_head), hold_p_mem_node);
3095 return rc;
3096}
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
new file mode 100644
index 000000000000..ac98a11bd1eb
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -0,0 +1,666 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/pci.h>
37#include <linux/init.h>
38#include <asm/uaccess.h>
39#include "cpqphp.h"
40#include "cpqphp_nvram.h"
41
42
43#define ROM_INT15_PHY_ADDR 0x0FF859
44#define READ_EV 0xD8A4
45#define WRITE_EV 0xD8A5
46
47struct register_foo {
48 union {
49 unsigned long lword; /* eax */
50 unsigned short word; /* ax */
51
52 struct {
53 unsigned char low; /* al */
54 unsigned char high; /* ah */
55 } byte;
56 } data;
57
58 unsigned char opcode; /* see below */
59 unsigned long length; /* if the reg. is a pointer, how much data */
60} __attribute__ ((packed));
61
62struct all_reg {
63 struct register_foo eax_reg;
64 struct register_foo ebx_reg;
65 struct register_foo ecx_reg;
66 struct register_foo edx_reg;
67 struct register_foo edi_reg;
68 struct register_foo esi_reg;
69 struct register_foo eflags_reg;
70} __attribute__ ((packed));
71
72
73struct ev_hrt_header {
74 u8 Version;
75 u8 num_of_ctrl;
76 u8 next;
77};
78
79struct ev_hrt_ctrl {
80 u8 bus;
81 u8 device;
82 u8 function;
83 u8 mem_avail;
84 u8 p_mem_avail;
85 u8 io_avail;
86 u8 bus_avail;
87 u8 next;
88};
89
90
91static u8 evbuffer_init;
92static u8 evbuffer_length;
93static u8 evbuffer[1024];
94
95static void __iomem *compaq_int15_entry_point;
96
97static spinlock_t int15_lock; /* lock for ordering int15_bios_call() */
98
99
100/* This is a series of function that deals with
101 setting & getting the hotplug resource table in some environment variable.
102*/
103
104/*
105 * We really shouldn't be doing this unless there is a _very_ good reason to!!!
106 * greg k-h
107 */
108
109
110static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
111{
112 u8 **tByte;
113
114 if ((*used + 1) > *avail)
115 return(1);
116
117 *((u8*)*p_buffer) = value;
118 tByte = (u8**)p_buffer;
119 (*tByte)++;
120 *used+=1;
121 return(0);
122}
123
124
125static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail)
126{
127 if ((*used + 4) > *avail)
128 return(1);
129
130 **p_buffer = value;
131 (*p_buffer)++;
132 *used+=4;
133 return(0);
134}
135
136
137/*
138 * check_for_compaq_ROM
139 *
140 * this routine verifies that the ROM OEM string is 'COMPAQ'
141 *
142 * returns 0 for non-Compaq ROM, 1 for Compaq ROM
143 */
144static int check_for_compaq_ROM (void __iomem *rom_start)
145{
146 u8 temp1, temp2, temp3, temp4, temp5, temp6;
147 int result = 0;
148
149 temp1 = readb(rom_start + 0xffea + 0);
150 temp2 = readb(rom_start + 0xffea + 1);
151 temp3 = readb(rom_start + 0xffea + 2);
152 temp4 = readb(rom_start + 0xffea + 3);
153 temp5 = readb(rom_start + 0xffea + 4);
154 temp6 = readb(rom_start + 0xffea + 5);
155 if ((temp1 == 'C') &&
156 (temp2 == 'O') &&
157 (temp3 == 'M') &&
158 (temp4 == 'P') &&
159 (temp5 == 'A') &&
160 (temp6 == 'Q')) {
161 result = 1;
162 }
163 dbg ("%s - returned %d\n", __FUNCTION__, result);
164 return result;
165}
166
167
168static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
169{
170 unsigned long flags;
171 int op = operation;
172 int ret_val;
173
174 if (!compaq_int15_entry_point)
175 return -ENODEV;
176
177 spin_lock_irqsave(&int15_lock, flags);
178 __asm__ (
179 "xorl %%ebx,%%ebx\n" \
180 "xorl %%edx,%%edx\n" \
181 "pushf\n" \
182 "push %%cs\n" \
183 "cli\n" \
184 "call *%6\n"
185 : "=c" (*buf_size), "=a" (ret_val)
186 : "a" (op), "c" (*buf_size), "S" (ev_name),
187 "D" (buffer), "m" (compaq_int15_entry_point)
188 : "%ebx", "%edx");
189 spin_unlock_irqrestore(&int15_lock, flags);
190
191 return((ret_val & 0xFF00) >> 8);
192}
193
194
195/*
196 * load_HRT
197 *
198 * Read the hot plug Resource Table from NVRAM
199 */
200static int load_HRT (void __iomem *rom_start)
201{
202 u32 available;
203 u32 temp_dword;
204 u8 temp_byte = 0xFF;
205 u32 rc;
206
207 if (!check_for_compaq_ROM(rom_start)) {
208 return -ENODEV;
209 }
210
211 available = 1024;
212
213 // Now load the EV
214 temp_dword = available;
215
216 rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
217
218 evbuffer_length = temp_dword;
219
220 // We're maintaining the resource lists so write FF to invalidate old info
221 temp_dword = 1;
222
223 rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
224
225 return rc;
226}
227
228
229/*
230 * store_HRT
231 *
232 * Save the hot plug Resource Table in NVRAM
233 */
234static u32 store_HRT (void __iomem *rom_start)
235{
236 u32 *buffer;
237 u32 *pFill;
238 u32 usedbytes;
239 u32 available;
240 u32 temp_dword;
241 u32 rc;
242 u8 loop;
243 u8 numCtrl = 0;
244 struct controller *ctrl;
245 struct pci_resource *resNode;
246 struct ev_hrt_header *p_EV_header;
247 struct ev_hrt_ctrl *p_ev_ctrl;
248
249 available = 1024;
250
251 if (!check_for_compaq_ROM(rom_start)) {
252 return(1);
253 }
254
255 buffer = (u32*) evbuffer;
256
257 if (!buffer)
258 return(1);
259
260 pFill = buffer;
261 usedbytes = 0;
262
263 p_EV_header = (struct ev_hrt_header *) pFill;
264
265 ctrl = cpqhp_ctrl_list;
266
267 // The revision of this structure
268 rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
269 if (rc)
270 return(rc);
271
272 // The number of controllers
273 rc = add_byte( &pFill, 1, &usedbytes, &available);
274 if (rc)
275 return(rc);
276
277 while (ctrl) {
278 p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;
279
280 numCtrl++;
281
282 // The bus number
283 rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
284 if (rc)
285 return(rc);
286
287 // The device Number
288 rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
289 if (rc)
290 return(rc);
291
292 // The function Number
293 rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
294 if (rc)
295 return(rc);
296
297 // Skip the number of available entries
298 rc = add_dword( &pFill, 0, &usedbytes, &available);
299 if (rc)
300 return(rc);
301
302 // Figure out memory Available
303
304 resNode = ctrl->mem_head;
305
306 loop = 0;
307
308 while (resNode) {
309 loop ++;
310
311 // base
312 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
313 if (rc)
314 return(rc);
315
316 // length
317 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
318 if (rc)
319 return(rc);
320
321 resNode = resNode->next;
322 }
323
324 // Fill in the number of entries
325 p_ev_ctrl->mem_avail = loop;
326
327 // Figure out prefetchable memory Available
328
329 resNode = ctrl->p_mem_head;
330
331 loop = 0;
332
333 while (resNode) {
334 loop ++;
335
336 // base
337 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
338 if (rc)
339 return(rc);
340
341 // length
342 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
343 if (rc)
344 return(rc);
345
346 resNode = resNode->next;
347 }
348
349 // Fill in the number of entries
350 p_ev_ctrl->p_mem_avail = loop;
351
352 // Figure out IO Available
353
354 resNode = ctrl->io_head;
355
356 loop = 0;
357
358 while (resNode) {
359 loop ++;
360
361 // base
362 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
363 if (rc)
364 return(rc);
365
366 // length
367 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
368 if (rc)
369 return(rc);
370
371 resNode = resNode->next;
372 }
373
374 // Fill in the number of entries
375 p_ev_ctrl->io_avail = loop;
376
377 // Figure out bus Available
378
379 resNode = ctrl->bus_head;
380
381 loop = 0;
382
383 while (resNode) {
384 loop ++;
385
386 // base
387 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
388 if (rc)
389 return(rc);
390
391 // length
392 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
393 if (rc)
394 return(rc);
395
396 resNode = resNode->next;
397 }
398
399 // Fill in the number of entries
400 p_ev_ctrl->bus_avail = loop;
401
402 ctrl = ctrl->next;
403 }
404
405 p_EV_header->num_of_ctrl = numCtrl;
406
407 // Now store the EV
408
409 temp_dword = usedbytes;
410
411 rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
412
413 dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
414
415 evbuffer_length = temp_dword;
416
417 if (rc) {
418 err(msg_unable_to_save);
419 return(1);
420 }
421
422 return(0);
423}
424
425
426void compaq_nvram_init (void __iomem *rom_start)
427{
428 if (rom_start) {
429 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
430 }
431 dbg("int15 entry = %p\n", compaq_int15_entry_point);
432
433 /* initialize our int15 lock */
434 spin_lock_init(&int15_lock);
435}
436
437
438int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
439{
440 u8 bus, device, function;
441 u8 nummem, numpmem, numio, numbus;
442 u32 rc;
443 u8 *p_byte;
444 struct pci_resource *mem_node;
445 struct pci_resource *p_mem_node;
446 struct pci_resource *io_node;
447 struct pci_resource *bus_node;
448 struct ev_hrt_ctrl *p_ev_ctrl;
449 struct ev_hrt_header *p_EV_header;
450
451 if (!evbuffer_init) {
452 // Read the resource list information in from NVRAM
453 if (load_HRT(rom_start))
454 memset (evbuffer, 0, 1024);
455
456 evbuffer_init = 1;
457 }
458
459 // If we saved information in NVRAM, use it now
460 p_EV_header = (struct ev_hrt_header *) evbuffer;
461
462 // The following code is for systems where version 1.0 of this
463 // driver has been loaded, but doesn't support the hardware.
464 // In that case, the driver would incorrectly store something
465 // in NVRAM.
466 if ((p_EV_header->Version == 2) ||
467 ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
468 p_byte = &(p_EV_header->next);
469
470 p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);
471
472 p_byte += 3;
473
474 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
475 return 2;
476
477 bus = p_ev_ctrl->bus;
478 device = p_ev_ctrl->device;
479 function = p_ev_ctrl->function;
480
481 while ((bus != ctrl->bus) ||
482 (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
483 (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
484 nummem = p_ev_ctrl->mem_avail;
485 numpmem = p_ev_ctrl->p_mem_avail;
486 numio = p_ev_ctrl->io_avail;
487 numbus = p_ev_ctrl->bus_avail;
488
489 p_byte += 4;
490
491 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
492 return 2;
493
494 // Skip forward to the next entry
495 p_byte += (nummem + numpmem + numio + numbus) * 8;
496
497 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
498 return 2;
499
500 p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
501
502 p_byte += 3;
503
504 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
505 return 2;
506
507 bus = p_ev_ctrl->bus;
508 device = p_ev_ctrl->device;
509 function = p_ev_ctrl->function;
510 }
511
512 nummem = p_ev_ctrl->mem_avail;
513 numpmem = p_ev_ctrl->p_mem_avail;
514 numio = p_ev_ctrl->io_avail;
515 numbus = p_ev_ctrl->bus_avail;
516
517 p_byte += 4;
518
519 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
520 return 2;
521
522 while (nummem--) {
523 mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
524
525 if (!mem_node)
526 break;
527
528 mem_node->base = *(u32*)p_byte;
529 dbg("mem base = %8.8x\n",mem_node->base);
530 p_byte += 4;
531
532 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
533 kfree(mem_node);
534 return 2;
535 }
536
537 mem_node->length = *(u32*)p_byte;
538 dbg("mem length = %8.8x\n",mem_node->length);
539 p_byte += 4;
540
541 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
542 kfree(mem_node);
543 return 2;
544 }
545
546 mem_node->next = ctrl->mem_head;
547 ctrl->mem_head = mem_node;
548 }
549
550 while (numpmem--) {
551 p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
552
553 if (!p_mem_node)
554 break;
555
556 p_mem_node->base = *(u32*)p_byte;
557 dbg("pre-mem base = %8.8x\n",p_mem_node->base);
558 p_byte += 4;
559
560 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
561 kfree(p_mem_node);
562 return 2;
563 }
564
565 p_mem_node->length = *(u32*)p_byte;
566 dbg("pre-mem length = %8.8x\n",p_mem_node->length);
567 p_byte += 4;
568
569 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
570 kfree(p_mem_node);
571 return 2;
572 }
573
574 p_mem_node->next = ctrl->p_mem_head;
575 ctrl->p_mem_head = p_mem_node;
576 }
577
578 while (numio--) {
579 io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
580
581 if (!io_node)
582 break;
583
584 io_node->base = *(u32*)p_byte;
585 dbg("io base = %8.8x\n",io_node->base);
586 p_byte += 4;
587
588 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
589 kfree(io_node);
590 return 2;
591 }
592
593 io_node->length = *(u32*)p_byte;
594 dbg("io length = %8.8x\n",io_node->length);
595 p_byte += 4;
596
597 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
598 kfree(io_node);
599 return 2;
600 }
601
602 io_node->next = ctrl->io_head;
603 ctrl->io_head = io_node;
604 }
605
606 while (numbus--) {
607 bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
608
609 if (!bus_node)
610 break;
611
612 bus_node->base = *(u32*)p_byte;
613 p_byte += 4;
614
615 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
616 kfree(bus_node);
617 return 2;
618 }
619
620 bus_node->length = *(u32*)p_byte;
621 p_byte += 4;
622
623 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
624 kfree(bus_node);
625 return 2;
626 }
627
628 bus_node->next = ctrl->bus_head;
629 ctrl->bus_head = bus_node;
630 }
631
632 // If all of the following fail, we don't have any resources for
633 // hot plug add
634 rc = 1;
635 rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
636 rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
637 rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
638 rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
639
640 if (rc)
641 return(rc);
642 } else {
643 if ((evbuffer[0] != 0) && (!ctrl->push_flag))
644 return 1;
645 }
646
647 return 0;
648}
649
650
651int compaq_nvram_store (void __iomem *rom_start)
652{
653 int rc = 1;
654
655 if (rom_start == NULL)
656 return -ENODEV;
657
658 if (evbuffer_init) {
659 rc = store_HRT(rom_start);
660 if (rc) {
661 err(msg_unable_to_save);
662 }
663 }
664 return rc;
665}
666
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h
new file mode 100644
index 000000000000..e89c0702119d
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_nvram.h
@@ -0,0 +1,57 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <greg@kroah.com>
25 *
26 */
27
28#ifndef _CPQPHP_NVRAM_H
29#define _CPQPHP_NVRAM_H
30
31#ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
32
33static inline void compaq_nvram_init (void __iomem *rom_start)
34{
35 return;
36}
37
38static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
39{
40 return 0;
41}
42
43static inline int compaq_nvram_store (void __iomem *rom_start)
44{
45 return 0;
46}
47
48#else
49
50extern void compaq_nvram_init (void __iomem *rom_start);
51extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl);
52extern int compaq_nvram_store (void __iomem *rom_start);
53
54#endif
55
56#endif
57
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
new file mode 100644
index 000000000000..93e39c4096a9
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -0,0 +1,1569 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/slab.h>
34#include <linux/workqueue.h>
35#include <linux/proc_fs.h>
36#include <linux/pci.h>
37#include "../pci.h"
38#include "cpqphp.h"
39#include "cpqphp_nvram.h"
40#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */
41
42
43u8 cpqhp_nic_irq;
44u8 cpqhp_disk_irq;
45
46static u16 unused_IRQ;
47
48/*
49 * detect_HRT_floating_pointer
50 *
51 * find the Hot Plug Resource Table in the specified region of memory.
52 *
53 */
54static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
55{
56 void __iomem *fp;
57 void __iomem *endp;
58 u8 temp1, temp2, temp3, temp4;
59 int status = 0;
60
61 endp = (end - sizeof(struct hrt) + 1);
62
63 for (fp = begin; fp <= endp; fp += 16) {
64 temp1 = readb(fp + SIG0);
65 temp2 = readb(fp + SIG1);
66 temp3 = readb(fp + SIG2);
67 temp4 = readb(fp + SIG3);
68 if (temp1 == '$' &&
69 temp2 == 'H' &&
70 temp3 == 'R' &&
71 temp4 == 'T') {
72 status = 1;
73 break;
74 }
75 }
76
77 if (!status)
78 fp = NULL;
79
80 dbg("Discovered Hotplug Resource Table at %p\n", fp);
81 return fp;
82}
83
84
85int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
86{
87 unsigned char bus;
88 struct pci_bus *child;
89 int num;
90
91 if (func->pci_dev == NULL)
92 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
93
94 /* No pci device, we need to create it then */
95 if (func->pci_dev == NULL) {
96 dbg("INFO: pci_dev still null\n");
97
98 num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
99 if (num)
100 pci_bus_add_devices(ctrl->pci_dev->bus);
101
102 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
103 if (func->pci_dev == NULL) {
104 dbg("ERROR: pci_dev still null\n");
105 return 0;
106 }
107 }
108
109 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
110 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
111 child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
112 pci_do_scan_bus(child);
113 }
114
115 return 0;
116}
117
118
119int cpqhp_unconfigure_device(struct pci_func* func)
120{
121 int j;
122
123 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
124
125 for (j=0; j<8 ; j++) {
126 struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j));
127 if (temp)
128 pci_remove_bus_device(temp);
129 }
130 return 0;
131}
132
133static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
134{
135 u32 vendID = 0;
136
137 if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
138 return -1;
139 if (vendID == 0xffffffff)
140 return -1;
141 return pci_bus_read_config_dword (bus, devfn, offset, value);
142}
143
144
145/*
146 * cpqhp_set_irq
147 *
148 * @bus_num: bus number of PCI device
149 * @dev_num: device number of PCI device
150 * @slot: pointer to u8 where slot number will be returned
151 */
152int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
153{
154 int rc = 0;
155
156 if (cpqhp_legacy_mode) {
157 struct pci_dev *fakedev;
158 struct pci_bus *fakebus;
159 u16 temp_word;
160
161 fakedev = kmalloc(sizeof(*fakedev), GFP_KERNEL);
162 fakebus = kmalloc(sizeof(*fakebus), GFP_KERNEL);
163 if (!fakedev || !fakebus) {
164 kfree(fakedev);
165 kfree(fakebus);
166 return -ENOMEM;
167 }
168
169 fakedev->devfn = dev_num << 3;
170 fakedev->bus = fakebus;
171 fakebus->number = bus_num;
172 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
173 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
174 rc = pcibios_set_irq_routing(fakedev, int_pin - 0x0a, irq_num);
175 kfree(fakedev);
176 kfree(fakebus);
177 dbg("%s: rc %d\n", __FUNCTION__, rc);
178 if (!rc)
179 return !rc;
180
181 // set the Edge Level Control Register (ELCR)
182 temp_word = inb(0x4d0);
183 temp_word |= inb(0x4d1) << 8;
184
185 temp_word |= 0x01 << irq_num;
186
187 // This should only be for x86 as it sets the Edge Level Control Register
188 outb((u8) (temp_word & 0xFF), 0x4d0);
189 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
190 rc = 0;
191 }
192
193 return rc;
194}
195
196
197/*
198 * WTF??? This function isn't in the code, yet a function calls it, but the
199 * compiler optimizes it away? strange. Here as a placeholder to keep the
200 * compiler happy.
201 */
202static int PCI_ScanBusNonBridge (u8 bus, u8 device)
203{
204 return 0;
205}
206
207static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
208{
209 u16 tdevice;
210 u32 work;
211 u8 tbus;
212
213 ctrl->pci_bus->number = bus_num;
214
215 for (tdevice = 0; tdevice < 0xFF; tdevice++) {
216 //Scan for access first
217 if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
218 continue;
219 dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
220 //Yep we got one. Not a bridge ?
221 if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
222 *dev_num = tdevice;
223 dbg("found it !\n");
224 return 0;
225 }
226 }
227 for (tdevice = 0; tdevice < 0xFF; tdevice++) {
228 //Scan for access first
229 if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
230 continue;
231 dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
232 //Yep we got one. bridge ?
233 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
234 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
235 dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
236 if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
237 return 0;
238 }
239 }
240
241 return -1;
242}
243
244
245static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
246{
247 struct irq_routing_table *PCIIRQRoutingInfoLength;
248 long len;
249 long loop;
250 u32 work;
251
252 u8 tbus, tdevice, tslot;
253
254 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
255 if (!PCIIRQRoutingInfoLength)
256 return -1;
257
258 len = (PCIIRQRoutingInfoLength->size -
259 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
260 // Make sure I got at least one entry
261 if (len == 0) {
262 if (PCIIRQRoutingInfoLength != NULL)
263 kfree(PCIIRQRoutingInfoLength );
264 return -1;
265 }
266
267 for (loop = 0; loop < len; ++loop) {
268 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
269 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
270 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
271
272 if (tslot == slot) {
273 *bus_num = tbus;
274 *dev_num = tdevice;
275 ctrl->pci_bus->number = tbus;
276 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
277 if (!nobridge || (work == 0xffffffff)) {
278 if (PCIIRQRoutingInfoLength != NULL)
279 kfree(PCIIRQRoutingInfoLength );
280 return 0;
281 }
282
283 dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
284 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
285 dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
286
287 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
288 pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
289 dbg("Scan bus for Non Bridge: bus %d\n", tbus);
290 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
291 *bus_num = tbus;
292 if (PCIIRQRoutingInfoLength != NULL)
293 kfree(PCIIRQRoutingInfoLength );
294 return 0;
295 }
296 } else {
297 if (PCIIRQRoutingInfoLength != NULL)
298 kfree(PCIIRQRoutingInfoLength );
299 return 0;
300 }
301
302 }
303 }
304 if (PCIIRQRoutingInfoLength != NULL)
305 kfree(PCIIRQRoutingInfoLength );
306 return -1;
307}
308
309
310int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
311{
312 return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); //plain (bridges allowed)
313}
314
315
316/* More PCI configuration routines; this time centered around hotplug controller */
317
318
319/*
320 * cpqhp_save_config
321 *
322 * Reads configuration for all slots in a PCI bus and saves info.
323 *
324 * Note: For non-hot plug busses, the slot # saved is the device #
325 *
326 * returns 0 if success
327 */
328int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
329{
330 long rc;
331 u8 class_code;
332 u8 header_type;
333 u32 ID;
334 u8 secondary_bus;
335 struct pci_func *new_slot;
336 int sub_bus;
337 int FirstSupported;
338 int LastSupported;
339 int max_functions;
340 int function;
341 u8 DevError;
342 int device = 0;
343 int cloop = 0;
344 int stop_it;
345 int index;
346
347 // Decide which slots are supported
348
349 if (is_hot_plug) {
350 //*********************************
351 // is_hot_plug is the slot mask
352 //*********************************
353 FirstSupported = is_hot_plug >> 4;
354 LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
355 } else {
356 FirstSupported = 0;
357 LastSupported = 0x1F;
358 }
359
360 // Save PCI configuration space for all devices in supported slots
361 ctrl->pci_bus->number = busnumber;
362 for (device = FirstSupported; device <= LastSupported; device++) {
363 ID = 0xFFFFFFFF;
364 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
365
366 if (ID != 0xFFFFFFFF) { // device in slot
367 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
368 if (rc)
369 return rc;
370
371 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
372 if (rc)
373 return rc;
374
375 // If multi-function device, set max_functions to 8
376 if (header_type & 0x80)
377 max_functions = 8;
378 else
379 max_functions = 1;
380
381 function = 0;
382
383 do {
384 DevError = 0;
385
386 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge
387 // Recurse the subordinate bus
388 // get the subordinate bus number
389 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
390 if (rc) {
391 return rc;
392 } else {
393 sub_bus = (int) secondary_bus;
394
395 // Save secondary bus cfg spc
396 // with this recursive call.
397 rc = cpqhp_save_config(ctrl, sub_bus, 0);
398 if (rc)
399 return rc;
400 ctrl->pci_bus->number = busnumber;
401 }
402 }
403
404 index = 0;
405 new_slot = cpqhp_slot_find(busnumber, device, index++);
406 while (new_slot &&
407 (new_slot->function != (u8) function))
408 new_slot = cpqhp_slot_find(busnumber, device, index++);
409
410 if (!new_slot) {
411 // Setup slot structure.
412 new_slot = cpqhp_slot_create(busnumber);
413
414 if (new_slot == NULL)
415 return(1);
416 }
417
418 new_slot->bus = (u8) busnumber;
419 new_slot->device = (u8) device;
420 new_slot->function = (u8) function;
421 new_slot->is_a_board = 1;
422 new_slot->switch_save = 0x10;
423 // In case of unsupported board
424 new_slot->status = DevError;
425 new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
426
427 for (cloop = 0; cloop < 0x20; cloop++) {
428 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
429 if (rc)
430 return rc;
431 }
432
433 function++;
434
435 stop_it = 0;
436
437 // this loop skips to the next present function
438 // reading in Class Code and Header type.
439
440 while ((function < max_functions)&&(!stop_it)) {
441 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
442 if (ID == 0xFFFFFFFF) { // nothing there.
443 function++;
444 } else { // Something there
445 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
446 if (rc)
447 return rc;
448
449 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
450 if (rc)
451 return rc;
452
453 stop_it++;
454 }
455 }
456
457 } while (function < max_functions);
458 } // End of IF (device in slot?)
459 else if (is_hot_plug) {
460 // Setup slot structure with entry for empty slot
461 new_slot = cpqhp_slot_create(busnumber);
462
463 if (new_slot == NULL) {
464 return(1);
465 }
466
467 new_slot->bus = (u8) busnumber;
468 new_slot->device = (u8) device;
469 new_slot->function = 0;
470 new_slot->is_a_board = 0;
471 new_slot->presence_save = 0;
472 new_slot->switch_save = 0;
473 }
474 } // End of FOR loop
475
476 return(0);
477}
478
479
480/*
481 * cpqhp_save_slot_config
482 *
483 * Saves configuration info for all PCI devices in a given slot
484 * including subordinate busses.
485 *
486 * returns 0 if success
487 */
488int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
489{
490 long rc;
491 u8 class_code;
492 u8 header_type;
493 u32 ID;
494 u8 secondary_bus;
495 int sub_bus;
496 int max_functions;
497 int function;
498 int cloop = 0;
499 int stop_it;
500
501 ID = 0xFFFFFFFF;
502
503 ctrl->pci_bus->number = new_slot->bus;
504 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
505
506 if (ID != 0xFFFFFFFF) { // device in slot
507 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
508 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
509
510 if (header_type & 0x80) // Multi-function device
511 max_functions = 8;
512 else
513 max_functions = 1;
514
515 function = 0;
516
517 do {
518 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
519 // Recurse the subordinate bus
520 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
521
522 sub_bus = (int) secondary_bus;
523
524 // Save the config headers for the secondary bus.
525 rc = cpqhp_save_config(ctrl, sub_bus, 0);
526 if (rc)
527 return(rc);
528 ctrl->pci_bus->number = new_slot->bus;
529
530 } // End of IF
531
532 new_slot->status = 0;
533
534 for (cloop = 0; cloop < 0x20; cloop++) {
535 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
536 }
537
538 function++;
539
540 stop_it = 0;
541
542 // this loop skips to the next present function
543 // reading in the Class Code and the Header type.
544
545 while ((function < max_functions) && (!stop_it)) {
546 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
547
548 if (ID == 0xFFFFFFFF) { // nothing there.
549 function++;
550 } else { // Something there
551 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
552
553 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
554
555 stop_it++;
556 }
557 }
558
559 } while (function < max_functions);
560 } // End of IF (device in slot?)
561 else {
562 return 2;
563 }
564
565 return 0;
566}
567
568
569/*
570 * cpqhp_save_base_addr_length
571 *
572 * Saves the length of all base address registers for the
573 * specified slot. this is for hot plug REPLACE
574 *
575 * returns 0 if success
576 */
577int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
578{
579 u8 cloop;
580 u8 header_type;
581 u8 secondary_bus;
582 u8 type;
583 int sub_bus;
584 u32 temp_register;
585 u32 base;
586 u32 rc;
587 struct pci_func *next;
588 int index = 0;
589 struct pci_bus *pci_bus = ctrl->pci_bus;
590 unsigned int devfn;
591
592 func = cpqhp_slot_find(func->bus, func->device, index++);
593
594 while (func != NULL) {
595 pci_bus->number = func->bus;
596 devfn = PCI_DEVFN(func->device, func->function);
597
598 // Check for Bridge
599 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
600
601 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
602 // PCI-PCI Bridge
603 pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
604
605 sub_bus = (int) secondary_bus;
606
607 next = cpqhp_slot_list[sub_bus];
608
609 while (next != NULL) {
610 rc = cpqhp_save_base_addr_length(ctrl, next);
611 if (rc)
612 return rc;
613
614 next = next->next;
615 }
616 pci_bus->number = func->bus;
617
618 //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
619 // Figure out IO and memory base lengths
620 for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
621 temp_register = 0xFFFFFFFF;
622 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
623 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
624
625 if (base) { // If this register is implemented
626 if (base & 0x01L) {
627 // IO base
628 // set base = amount of IO space requested
629 base = base & 0xFFFFFFFE;
630 base = (~base) + 1;
631
632 type = 1;
633 } else {
634 // memory base
635 base = base & 0xFFFFFFF0;
636 base = (~base) + 1;
637
638 type = 0;
639 }
640 } else {
641 base = 0x0L;
642 type = 0;
643 }
644
645 // Save information in slot structure
646 func->base_length[(cloop - 0x10) >> 2] =
647 base;
648 func->base_type[(cloop - 0x10) >> 2] = type;
649
650 } // End of base register loop
651
652
653 } else if ((header_type & 0x7F) == 0x00) { // PCI-PCI Bridge
654 // Figure out IO and memory base lengths
655 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
656 temp_register = 0xFFFFFFFF;
657 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
658 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
659
660 if (base) { // If this register is implemented
661 if (base & 0x01L) {
662 // IO base
663 // base = amount of IO space requested
664 base = base & 0xFFFFFFFE;
665 base = (~base) + 1;
666
667 type = 1;
668 } else {
669 // memory base
670 // base = amount of memory space requested
671 base = base & 0xFFFFFFF0;
672 base = (~base) + 1;
673
674 type = 0;
675 }
676 } else {
677 base = 0x0L;
678 type = 0;
679 }
680
681 // Save information in slot structure
682 func->base_length[(cloop - 0x10) >> 2] = base;
683 func->base_type[(cloop - 0x10) >> 2] = type;
684
685 } // End of base register loop
686
687 } else { // Some other unknown header type
688 }
689
690 // find the next device in this slot
691 func = cpqhp_slot_find(func->bus, func->device, index++);
692 }
693
694 return(0);
695}
696
697
698/*
699 * cpqhp_save_used_resources
700 *
701 * Stores used resource information for existing boards. this is
702 * for boards that were in the system when this driver was loaded.
703 * this function is for hot plug ADD
704 *
705 * returns 0 if success
706 */
707int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
708{
709 u8 cloop;
710 u8 header_type;
711 u8 secondary_bus;
712 u8 temp_byte;
713 u8 b_base;
714 u8 b_length;
715 u16 command;
716 u16 save_command;
717 u16 w_base;
718 u16 w_length;
719 u32 temp_register;
720 u32 save_base;
721 u32 base;
722 int index = 0;
723 struct pci_resource *mem_node;
724 struct pci_resource *p_mem_node;
725 struct pci_resource *io_node;
726 struct pci_resource *bus_node;
727 struct pci_bus *pci_bus = ctrl->pci_bus;
728 unsigned int devfn;
729
730 func = cpqhp_slot_find(func->bus, func->device, index++);
731
732 while ((func != NULL) && func->is_a_board) {
733 pci_bus->number = func->bus;
734 devfn = PCI_DEVFN(func->device, func->function);
735
736 // Save the command register
737 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
738
739 // disable card
740 command = 0x00;
741 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
742
743 // Check for Bridge
744 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
745
746 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
747 // Clear Bridge Control Register
748 command = 0x00;
749 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
750 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
751 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
752
753 bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
754 if (!bus_node)
755 return -ENOMEM;
756
757 bus_node->base = secondary_bus;
758 bus_node->length = temp_byte - secondary_bus + 1;
759
760 bus_node->next = func->bus_head;
761 func->bus_head = bus_node;
762
763 // Save IO base and Limit registers
764 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
765 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);
766
767 if ((b_base <= b_length) && (save_command & 0x01)) {
768 io_node = kmalloc(sizeof(*io_node), GFP_KERNEL);
769 if (!io_node)
770 return -ENOMEM;
771
772 io_node->base = (b_base & 0xF0) << 8;
773 io_node->length = (b_length - b_base + 0x10) << 8;
774
775 io_node->next = func->io_head;
776 func->io_head = io_node;
777 }
778
779 // Save memory base and Limit registers
780 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
781 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
782
783 if ((w_base <= w_length) && (save_command & 0x02)) {
784 mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
785 if (!mem_node)
786 return -ENOMEM;
787
788 mem_node->base = w_base << 16;
789 mem_node->length = (w_length - w_base + 0x10) << 16;
790
791 mem_node->next = func->mem_head;
792 func->mem_head = mem_node;
793 }
794
795 // Save prefetchable memory base and Limit registers
796 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
797 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
798
799 if ((w_base <= w_length) && (save_command & 0x02)) {
800 p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
801 if (!p_mem_node)
802 return -ENOMEM;
803
804 p_mem_node->base = w_base << 16;
805 p_mem_node->length = (w_length - w_base + 0x10) << 16;
806
807 p_mem_node->next = func->p_mem_head;
808 func->p_mem_head = p_mem_node;
809 }
810 // Figure out IO and memory base lengths
811 for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
812 pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
813
814 temp_register = 0xFFFFFFFF;
815 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
816 pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
817
818 temp_register = base;
819
820 if (base) { // If this register is implemented
821 if (((base & 0x03L) == 0x01)
822 && (save_command & 0x01)) {
823 // IO base
824 // set temp_register = amount of IO space requested
825 temp_register = base & 0xFFFFFFFE;
826 temp_register = (~temp_register) + 1;
827
828 io_node = kmalloc(sizeof(*io_node),
829 GFP_KERNEL);
830 if (!io_node)
831 return -ENOMEM;
832
833 io_node->base =
834 save_base & (~0x03L);
835 io_node->length = temp_register;
836
837 io_node->next = func->io_head;
838 func->io_head = io_node;
839 } else
840 if (((base & 0x0BL) == 0x08)
841 && (save_command & 0x02)) {
842 // prefetchable memory base
843 temp_register = base & 0xFFFFFFF0;
844 temp_register = (~temp_register) + 1;
845
846 p_mem_node = kmalloc(sizeof(*p_mem_node),
847 GFP_KERNEL);
848 if (!p_mem_node)
849 return -ENOMEM;
850
851 p_mem_node->base = save_base & (~0x0FL);
852 p_mem_node->length = temp_register;
853
854 p_mem_node->next = func->p_mem_head;
855 func->p_mem_head = p_mem_node;
856 } else
857 if (((base & 0x0BL) == 0x00)
858 && (save_command & 0x02)) {
859 // prefetchable memory base
860 temp_register = base & 0xFFFFFFF0;
861 temp_register = (~temp_register) + 1;
862
863 mem_node = kmalloc(sizeof(*mem_node),
864 GFP_KERNEL);
865 if (!mem_node)
866 return -ENOMEM;
867
868 mem_node->base = save_base & (~0x0FL);
869 mem_node->length = temp_register;
870
871 mem_node->next = func->mem_head;
872 func->mem_head = mem_node;
873 } else
874 return(1);
875 }
876 } // End of base register loop
877 } else if ((header_type & 0x7F) == 0x00) { // Standard header
878 // Figure out IO and memory base lengths
879 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
880 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
881
882 temp_register = 0xFFFFFFFF;
883 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
884 pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
885
886 temp_register = base;
887
888 if (base) { // If this register is implemented
889 if (((base & 0x03L) == 0x01)
890 && (save_command & 0x01)) {
891 // IO base
892 // set temp_register = amount of IO space requested
893 temp_register = base & 0xFFFFFFFE;
894 temp_register = (~temp_register) + 1;
895
896 io_node = kmalloc(sizeof(*io_node),
897 GFP_KERNEL);
898 if (!io_node)
899 return -ENOMEM;
900
901 io_node->base = save_base & (~0x01L);
902 io_node->length = temp_register;
903
904 io_node->next = func->io_head;
905 func->io_head = io_node;
906 } else
907 if (((base & 0x0BL) == 0x08)
908 && (save_command & 0x02)) {
909 // prefetchable memory base
910 temp_register = base & 0xFFFFFFF0;
911 temp_register = (~temp_register) + 1;
912
913 p_mem_node = kmalloc(sizeof(*p_mem_node),
914 GFP_KERNEL);
915 if (!p_mem_node)
916 return -ENOMEM;
917
918 p_mem_node->base = save_base & (~0x0FL);
919 p_mem_node->length = temp_register;
920
921 p_mem_node->next = func->p_mem_head;
922 func->p_mem_head = p_mem_node;
923 } else
924 if (((base & 0x0BL) == 0x00)
925 && (save_command & 0x02)) {
926 // prefetchable memory base
927 temp_register = base & 0xFFFFFFF0;
928 temp_register = (~temp_register) + 1;
929
930 mem_node = kmalloc(sizeof(*mem_node),
931 GFP_KERNEL);
932 if (!mem_node)
933 return -ENOMEM;
934
935 mem_node->base = save_base & (~0x0FL);
936 mem_node->length = temp_register;
937
938 mem_node->next = func->mem_head;
939 func->mem_head = mem_node;
940 } else
941 return(1);
942 }
943 } // End of base register loop
944 } else { // Some other unknown header type
945 }
946
947 // find the next device in this slot
948 func = cpqhp_slot_find(func->bus, func->device, index++);
949 }
950
951 return(0);
952}
953
954
955/*
956 * cpqhp_configure_board
957 *
958 * Copies saved configuration information to one slot.
959 * this is called recursively for bridge devices.
960 * this is for hot plug REPLACE!
961 *
962 * returns 0 if success
963 */
964int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
965{
966 int cloop;
967 u8 header_type;
968 u8 secondary_bus;
969 int sub_bus;
970 struct pci_func *next;
971 u32 temp;
972 u32 rc;
973 int index = 0;
974 struct pci_bus *pci_bus = ctrl->pci_bus;
975 unsigned int devfn;
976
977 func = cpqhp_slot_find(func->bus, func->device, index++);
978
979 while (func != NULL) {
980 pci_bus->number = func->bus;
981 devfn = PCI_DEVFN(func->device, func->function);
982
983 // Start at the top of config space so that the control
984 // registers are programmed last
985 for (cloop = 0x3C; cloop > 0; cloop -= 4) {
986 pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
987 }
988
989 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
990
991 // If this is a bridge device, restore subordinate devices
992 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
993 pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
994
995 sub_bus = (int) secondary_bus;
996
997 next = cpqhp_slot_list[sub_bus];
998
999 while (next != NULL) {
1000 rc = cpqhp_configure_board(ctrl, next);
1001 if (rc)
1002 return rc;
1003
1004 next = next->next;
1005 }
1006 } else {
1007
1008 // Check all the base Address Registers to make sure
1009 // they are the same. If not, the board is different.
1010
1011 for (cloop = 16; cloop < 40; cloop += 4) {
1012 pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
1013
1014 if (temp != func->config_space[cloop >> 2]) {
1015 dbg("Config space compare failure!!! offset = %x\n", cloop);
1016 dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
1017 dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
1018 return 1;
1019 }
1020 }
1021 }
1022
1023 func->configured = 1;
1024
1025 func = cpqhp_slot_find(func->bus, func->device, index++);
1026 }
1027
1028 return 0;
1029}
1030
1031
1032/*
1033 * cpqhp_valid_replace
1034 *
1035 * this function checks to see if a board is the same as the
1036 * one it is replacing. this check will detect if the device's
1037 * vendor or device id's are the same
1038 *
1039 * returns 0 if the board is the same nonzero otherwise
1040 */
1041int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
1042{
1043 u8 cloop;
1044 u8 header_type;
1045 u8 secondary_bus;
1046 u8 type;
1047 u32 temp_register = 0;
1048 u32 base;
1049 u32 rc;
1050 struct pci_func *next;
1051 int index = 0;
1052 struct pci_bus *pci_bus = ctrl->pci_bus;
1053 unsigned int devfn;
1054
1055 if (!func->is_a_board)
1056 return(ADD_NOT_SUPPORTED);
1057
1058 func = cpqhp_slot_find(func->bus, func->device, index++);
1059
1060 while (func != NULL) {
1061 pci_bus->number = func->bus;
1062 devfn = PCI_DEVFN(func->device, func->function);
1063
1064 pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
1065
1066 // No adapter present
1067 if (temp_register == 0xFFFFFFFF)
1068 return(NO_ADAPTER_PRESENT);
1069
1070 if (temp_register != func->config_space[0])
1071 return(ADAPTER_NOT_SAME);
1072
1073 // Check for same revision number and class code
1074 pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
1075
1076 // Adapter not the same
1077 if (temp_register != func->config_space[0x08 >> 2])
1078 return(ADAPTER_NOT_SAME);
1079
1080 // Check for Bridge
1081 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1082
1083 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
1084 // In order to continue checking, we must program the
1085 // bus registers in the bridge to respond to accesses
1086 // for it's subordinate bus(es)
1087
1088 temp_register = func->config_space[0x18 >> 2];
1089 pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
1090
1091 secondary_bus = (temp_register >> 8) & 0xFF;
1092
1093 next = cpqhp_slot_list[secondary_bus];
1094
1095 while (next != NULL) {
1096 rc = cpqhp_valid_replace(ctrl, next);
1097 if (rc)
1098 return rc;
1099
1100 next = next->next;
1101 }
1102
1103 }
1104 // Check to see if it is a standard config header
1105 else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
1106 // Check subsystem vendor and ID
1107 pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
1108
1109 if (temp_register != func->config_space[0x2C >> 2]) {
1110 // If it's a SMART-2 and the register isn't filled
1111 // in, ignore the difference because
1112 // they just have an old rev of the firmware
1113
1114 if (!((func->config_space[0] == 0xAE100E11)
1115 && (temp_register == 0x00L)))
1116 return(ADAPTER_NOT_SAME);
1117 }
1118 // Figure out IO and memory base lengths
1119 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
1120 temp_register = 0xFFFFFFFF;
1121 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
1122 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
1123 if (base) { // If this register is implemented
1124 if (base & 0x01L) {
1125 // IO base
1126 // set base = amount of IO space requested
1127 base = base & 0xFFFFFFFE;
1128 base = (~base) + 1;
1129
1130 type = 1;
1131 } else {
1132 // memory base
1133 base = base & 0xFFFFFFF0;
1134 base = (~base) + 1;
1135
1136 type = 0;
1137 }
1138 } else {
1139 base = 0x0L;
1140 type = 0;
1141 }
1142
1143 // Check information in slot structure
1144 if (func->base_length[(cloop - 0x10) >> 2] != base)
1145 return(ADAPTER_NOT_SAME);
1146
1147 if (func->base_type[(cloop - 0x10) >> 2] != type)
1148 return(ADAPTER_NOT_SAME);
1149
1150 } // End of base register loop
1151
1152 } // End of (type 0 config space) else
1153 else {
1154 // this is not a type 0 or 1 config space header so
1155 // we don't know how to do it
1156 return(DEVICE_TYPE_NOT_SUPPORTED);
1157 }
1158
1159 // Get the next function
1160 func = cpqhp_slot_find(func->bus, func->device, index++);
1161 }
1162
1163
1164 return 0;
1165}
1166
1167
1168/*
1169 * cpqhp_find_available_resources
1170 *
1171 * Finds available memory, IO, and IRQ resources for programming
1172 * devices which may be added to the system
1173 * this function is for hot plug ADD!
1174 *
1175 * returns 0 if success
1176 */
1177int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
1178{
1179 u8 temp;
1180 u8 populated_slot;
1181 u8 bridged_slot;
1182 void __iomem *one_slot;
1183 void __iomem *rom_resource_table;
1184 struct pci_func *func = NULL;
1185 int i = 10, index;
1186 u32 temp_dword, rc;
1187 struct pci_resource *mem_node;
1188 struct pci_resource *p_mem_node;
1189 struct pci_resource *io_node;
1190 struct pci_resource *bus_node;
1191
1192 rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
1193 dbg("rom_resource_table = %p\n", rom_resource_table);
1194
1195 if (rom_resource_table == NULL) {
1196 return -ENODEV;
1197 }
1198 // Sum all resources and setup resource maps
1199 unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
1200 dbg("unused_IRQ = %x\n", unused_IRQ);
1201
1202 temp = 0;
1203 while (unused_IRQ) {
1204 if (unused_IRQ & 1) {
1205 cpqhp_disk_irq = temp;
1206 break;
1207 }
1208 unused_IRQ = unused_IRQ >> 1;
1209 temp++;
1210 }
1211
1212 dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
1213 unused_IRQ = unused_IRQ >> 1;
1214 temp++;
1215
1216 while (unused_IRQ) {
1217 if (unused_IRQ & 1) {
1218 cpqhp_nic_irq = temp;
1219 break;
1220 }
1221 unused_IRQ = unused_IRQ >> 1;
1222 temp++;
1223 }
1224
1225 dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
1226 unused_IRQ = readl(rom_resource_table + PCIIRQ);
1227
1228 temp = 0;
1229
1230 if (!cpqhp_nic_irq) {
1231 cpqhp_nic_irq = ctrl->cfgspc_irq;
1232 }
1233
1234 if (!cpqhp_disk_irq) {
1235 cpqhp_disk_irq = ctrl->cfgspc_irq;
1236 }
1237
1238 dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
1239
1240 rc = compaq_nvram_load(rom_start, ctrl);
1241 if (rc)
1242 return rc;
1243
1244 one_slot = rom_resource_table + sizeof (struct hrt);
1245
1246 i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
1247 dbg("number_of_entries = %d\n", i);
1248
1249 if (!readb(one_slot + SECONDARY_BUS))
1250 return 1;
1251
1252 dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");
1253
1254 while (i && readb(one_slot + SECONDARY_BUS)) {
1255 u8 dev_func = readb(one_slot + DEV_FUNC);
1256 u8 primary_bus = readb(one_slot + PRIMARY_BUS);
1257 u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
1258 u8 max_bus = readb(one_slot + MAX_BUS);
1259 u16 io_base = readw(one_slot + IO_BASE);
1260 u16 io_length = readw(one_slot + IO_LENGTH);
1261 u16 mem_base = readw(one_slot + MEM_BASE);
1262 u16 mem_length = readw(one_slot + MEM_LENGTH);
1263 u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
1264 u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
1265
1266 dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
1267 dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
1268 primary_bus, secondary_bus, max_bus);
1269
1270 // If this entry isn't for our controller's bus, ignore it
1271 if (primary_bus != ctrl->bus) {
1272 i--;
1273 one_slot += sizeof (struct slot_rt);
1274 continue;
1275 }
1276 // find out if this entry is for an occupied slot
1277 ctrl->pci_bus->number = primary_bus;
1278 pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
1279 dbg("temp_D_word = %x\n", temp_dword);
1280
1281 if (temp_dword != 0xFFFFFFFF) {
1282 index = 0;
1283 func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);
1284
1285 while (func && (func->function != (dev_func & 0x07))) {
1286 dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
1287 func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
1288 }
1289
1290 // If we can't find a match, skip this table entry
1291 if (!func) {
1292 i--;
1293 one_slot += sizeof (struct slot_rt);
1294 continue;
1295 }
1296 // this may not work and shouldn't be used
1297 if (secondary_bus != primary_bus)
1298 bridged_slot = 1;
1299 else
1300 bridged_slot = 0;
1301
1302 populated_slot = 1;
1303 } else {
1304 populated_slot = 0;
1305 bridged_slot = 0;
1306 }
1307
1308
1309 // If we've got a valid IO base, use it
1310
1311 temp_dword = io_base + io_length;
1312
1313 if ((io_base) && (temp_dword < 0x10000)) {
1314 io_node = kmalloc(sizeof(*io_node), GFP_KERNEL);
1315 if (!io_node)
1316 return -ENOMEM;
1317
1318 io_node->base = io_base;
1319 io_node->length = io_length;
1320
1321 dbg("found io_node(base, length) = %x, %x\n",
1322 io_node->base, io_node->length);
1323 dbg("populated slot =%d \n", populated_slot);
1324 if (!populated_slot) {
1325 io_node->next = ctrl->io_head;
1326 ctrl->io_head = io_node;
1327 } else {
1328 io_node->next = func->io_head;
1329 func->io_head = io_node;
1330 }
1331 }
1332
1333 // If we've got a valid memory base, use it
1334 temp_dword = mem_base + mem_length;
1335 if ((mem_base) && (temp_dword < 0x10000)) {
1336 mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
1337 if (!mem_node)
1338 return -ENOMEM;
1339
1340 mem_node->base = mem_base << 16;
1341
1342 mem_node->length = mem_length << 16;
1343
1344 dbg("found mem_node(base, length) = %x, %x\n",
1345 mem_node->base, mem_node->length);
1346 dbg("populated slot =%d \n", populated_slot);
1347 if (!populated_slot) {
1348 mem_node->next = ctrl->mem_head;
1349 ctrl->mem_head = mem_node;
1350 } else {
1351 mem_node->next = func->mem_head;
1352 func->mem_head = mem_node;
1353 }
1354 }
1355
1356 // If we've got a valid prefetchable memory base, and
1357 // the base + length isn't greater than 0xFFFF
1358 temp_dword = pre_mem_base + pre_mem_length;
1359 if ((pre_mem_base) && (temp_dword < 0x10000)) {
1360 p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
1361 if (!p_mem_node)
1362 return -ENOMEM;
1363
1364 p_mem_node->base = pre_mem_base << 16;
1365
1366 p_mem_node->length = pre_mem_length << 16;
1367 dbg("found p_mem_node(base, length) = %x, %x\n",
1368 p_mem_node->base, p_mem_node->length);
1369 dbg("populated slot =%d \n", populated_slot);
1370
1371 if (!populated_slot) {
1372 p_mem_node->next = ctrl->p_mem_head;
1373 ctrl->p_mem_head = p_mem_node;
1374 } else {
1375 p_mem_node->next = func->p_mem_head;
1376 func->p_mem_head = p_mem_node;
1377 }
1378 }
1379
1380 // If we've got a valid bus number, use it
1381 // The second condition is to ignore bus numbers on
1382 // populated slots that don't have PCI-PCI bridges
1383 if (secondary_bus && (secondary_bus != primary_bus)) {
1384 bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
1385 if (!bus_node)
1386 return -ENOMEM;
1387
1388 bus_node->base = secondary_bus;
1389 bus_node->length = max_bus - secondary_bus + 1;
1390 dbg("found bus_node(base, length) = %x, %x\n",
1391 bus_node->base, bus_node->length);
1392 dbg("populated slot =%d \n", populated_slot);
1393 if (!populated_slot) {
1394 bus_node->next = ctrl->bus_head;
1395 ctrl->bus_head = bus_node;
1396 } else {
1397 bus_node->next = func->bus_head;
1398 func->bus_head = bus_node;
1399 }
1400 }
1401
1402 i--;
1403 one_slot += sizeof (struct slot_rt);
1404 }
1405
1406 // If all of the following fail, we don't have any resources for
1407 // hot plug add
1408 rc = 1;
1409 rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1410 rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1411 rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1412 rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1413
1414 return rc;
1415}
1416
1417
1418/*
1419 * cpqhp_return_board_resources
1420 *
1421 * this routine returns all resources allocated to a board to
1422 * the available pool.
1423 *
1424 * returns 0 if success
1425 */
1426int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
1427{
1428 int rc = 0;
1429 struct pci_resource *node;
1430 struct pci_resource *t_node;
1431 dbg("%s\n", __FUNCTION__);
1432
1433 if (!func)
1434 return 1;
1435
1436 node = func->io_head;
1437 func->io_head = NULL;
1438 while (node) {
1439 t_node = node->next;
1440 return_resource(&(resources->io_head), node);
1441 node = t_node;
1442 }
1443
1444 node = func->mem_head;
1445 func->mem_head = NULL;
1446 while (node) {
1447 t_node = node->next;
1448 return_resource(&(resources->mem_head), node);
1449 node = t_node;
1450 }
1451
1452 node = func->p_mem_head;
1453 func->p_mem_head = NULL;
1454 while (node) {
1455 t_node = node->next;
1456 return_resource(&(resources->p_mem_head), node);
1457 node = t_node;
1458 }
1459
1460 node = func->bus_head;
1461 func->bus_head = NULL;
1462 while (node) {
1463 t_node = node->next;
1464 return_resource(&(resources->bus_head), node);
1465 node = t_node;
1466 }
1467
1468 rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
1469 rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
1470 rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
1471 rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));
1472
1473 return rc;
1474}
1475
1476
1477/*
1478 * cpqhp_destroy_resource_list
1479 *
1480 * Puts node back in the resource list pointed to by head
1481 */
1482void cpqhp_destroy_resource_list (struct resource_lists * resources)
1483{
1484 struct pci_resource *res, *tres;
1485
1486 res = resources->io_head;
1487 resources->io_head = NULL;
1488
1489 while (res) {
1490 tres = res;
1491 res = res->next;
1492 kfree(tres);
1493 }
1494
1495 res = resources->mem_head;
1496 resources->mem_head = NULL;
1497
1498 while (res) {
1499 tres = res;
1500 res = res->next;
1501 kfree(tres);
1502 }
1503
1504 res = resources->p_mem_head;
1505 resources->p_mem_head = NULL;
1506
1507 while (res) {
1508 tres = res;
1509 res = res->next;
1510 kfree(tres);
1511 }
1512
1513 res = resources->bus_head;
1514 resources->bus_head = NULL;
1515
1516 while (res) {
1517 tres = res;
1518 res = res->next;
1519 kfree(tres);
1520 }
1521}
1522
1523
1524/*
1525 * cpqhp_destroy_board_resources
1526 *
1527 * Puts node back in the resource list pointed to by head
1528 */
1529void cpqhp_destroy_board_resources (struct pci_func * func)
1530{
1531 struct pci_resource *res, *tres;
1532
1533 res = func->io_head;
1534 func->io_head = NULL;
1535
1536 while (res) {
1537 tres = res;
1538 res = res->next;
1539 kfree(tres);
1540 }
1541
1542 res = func->mem_head;
1543 func->mem_head = NULL;
1544
1545 while (res) {
1546 tres = res;
1547 res = res->next;
1548 kfree(tres);
1549 }
1550
1551 res = func->p_mem_head;
1552 func->p_mem_head = NULL;
1553
1554 while (res) {
1555 tres = res;
1556 res = res->next;
1557 kfree(tres);
1558 }
1559
1560 res = func->bus_head;
1561 func->bus_head = NULL;
1562
1563 while (res) {
1564 tres = res;
1565 res = res->next;
1566 kfree(tres);
1567 }
1568}
1569
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
new file mode 100644
index 000000000000..41c7971d06c5
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -0,0 +1,143 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/workqueue.h>
35#include <linux/pci.h>
36#include "cpqphp.h"
37
38
39/* A few routines that create sysfs entries for the hot plug controller */
40
41static ssize_t show_ctrl (struct device *dev, char *buf)
42{
43 struct pci_dev *pci_dev;
44 struct controller *ctrl;
45 char * out = buf;
46 int index;
47 struct pci_resource *res;
48
49 pci_dev = container_of (dev, struct pci_dev, dev);
50 ctrl = pci_get_drvdata(pci_dev);
51
52 out += sprintf(buf, "Free resources: memory\n");
53 index = 11;
54 res = ctrl->mem_head;
55 while (res && index--) {
56 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
57 res = res->next;
58 }
59 out += sprintf(out, "Free resources: prefetchable memory\n");
60 index = 11;
61 res = ctrl->p_mem_head;
62 while (res && index--) {
63 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
64 res = res->next;
65 }
66 out += sprintf(out, "Free resources: IO\n");
67 index = 11;
68 res = ctrl->io_head;
69 while (res && index--) {
70 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
71 res = res->next;
72 }
73 out += sprintf(out, "Free resources: bus numbers\n");
74 index = 11;
75 res = ctrl->bus_head;
76 while (res && index--) {
77 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
78 res = res->next;
79 }
80
81 return out - buf;
82}
83static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
84
85static ssize_t show_dev (struct device *dev, char *buf)
86{
87 struct pci_dev *pci_dev;
88 struct controller *ctrl;
89 char * out = buf;
90 int index;
91 struct pci_resource *res;
92 struct pci_func *new_slot;
93 struct slot *slot;
94
95 pci_dev = container_of (dev, struct pci_dev, dev);
96 ctrl = pci_get_drvdata(pci_dev);
97
98 slot=ctrl->slot;
99
100 while (slot) {
101 new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
102 if (!new_slot)
103 break;
104 out += sprintf(out, "assigned resources: memory\n");
105 index = 11;
106 res = new_slot->mem_head;
107 while (res && index--) {
108 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
109 res = res->next;
110 }
111 out += sprintf(out, "assigned resources: prefetchable memory\n");
112 index = 11;
113 res = new_slot->p_mem_head;
114 while (res && index--) {
115 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
116 res = res->next;
117 }
118 out += sprintf(out, "assigned resources: IO\n");
119 index = 11;
120 res = new_slot->io_head;
121 while (res && index--) {
122 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
123 res = res->next;
124 }
125 out += sprintf(out, "assigned resources: bus numbers\n");
126 index = 11;
127 res = new_slot->bus_head;
128 while (res && index--) {
129 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
130 res = res->next;
131 }
132 slot=slot->next;
133 }
134
135 return out - buf;
136}
137static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
138
139void cpqhp_create_ctrl_files (struct controller *ctrl)
140{
141 device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
142 device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
143}
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
new file mode 100644
index 000000000000..8e47fa66e25e
--- /dev/null
+++ b/drivers/pci/hotplug/fakephp.c
@@ -0,0 +1,358 @@
1/*
2 * Fake PCI Hot Plug Controller Driver
3 *
4 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
5 * Copyright (C) 2003 IBM Corp.
6 * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
7 *
8 * Based on ideas and code from:
9 * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
10 * Rolf Eike Beer <eike-kernel@sf-tec.de>
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * Send feedback to <greg@kroah.com>
19 */
20
21/*
22 *
23 * This driver will "emulate" removing PCI devices from the system. If
24 * the "power" file is written to with "0" then the specified PCI device
25 * will be completely removed from the kernel.
26 *
27 * WARNING, this does NOT turn off the power to the PCI device. This is
28 * a "logical" removal, not a physical or electrical removal.
29 *
30 * Use this module at your own risk, you have been warned!
31 *
32 * Enabling PCI devices is left as an exercise for the reader...
33 *
34 */
35#include <linux/config.h>
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include "pci_hotplug.h"
41#include "../pci.h"
42
43#if !defined(MODULE)
44 #define MY_NAME "fakephp"
45#else
46 #define MY_NAME THIS_MODULE->name
47#endif
48
49#define dbg(format, arg...) \
50 do { \
51 if (debug) \
52 printk(KERN_DEBUG "%s: " format, \
53 MY_NAME , ## arg); \
54 } while (0)
55#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
56#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
57
58#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
59#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver"
60
61struct dummy_slot {
62 struct list_head node;
63 struct hotplug_slot *slot;
64 struct pci_dev *dev;
65};
66
67static int debug;
68static LIST_HEAD(slot_list);
69
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72
73static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
74 .owner = THIS_MODULE,
75 .enable_slot = enable_slot,
76 .disable_slot = disable_slot,
77};
78
79static void dummy_release(struct hotplug_slot *slot)
80{
81 struct dummy_slot *dslot = slot->private;
82
83 list_del(&dslot->node);
84 kfree(dslot->slot->info);
85 kfree(dslot->slot);
86 pci_dev_put(dslot->dev);
87 kfree(dslot);
88}
89
90static int add_slot(struct pci_dev *dev)
91{
92 struct dummy_slot *dslot;
93 struct hotplug_slot *slot;
94 int retval = -ENOMEM;
95
96 slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
97 if (!slot)
98 goto error;
99 memset(slot, 0, sizeof(*slot));
100
101 slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
102 if (!slot->info)
103 goto error_slot;
104 memset(slot->info, 0, sizeof(struct hotplug_slot_info));
105
106 slot->info->power_status = 1;
107 slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
108 slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
109
110 slot->name = &dev->dev.bus_id[0];
111 dbg("slot->name = %s\n", slot->name);
112
113 dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
114 if (!dslot)
115 goto error_info;
116
117 slot->ops = &dummy_hotplug_slot_ops;
118 slot->release = &dummy_release;
119 slot->private = dslot;
120
121 retval = pci_hp_register(slot);
122 if (retval) {
123 err("pci_hp_register failed with error %d\n", retval);
124 goto error_dslot;
125 }
126
127 dslot->slot = slot;
128 dslot->dev = pci_dev_get(dev);
129 list_add (&dslot->node, &slot_list);
130 return retval;
131
132error_dslot:
133 kfree(dslot);
134error_info:
135 kfree(slot->info);
136error_slot:
137 kfree(slot);
138error:
139 return retval;
140}
141
142static int __init pci_scan_buses(void)
143{
144 struct pci_dev *dev = NULL;
145 int retval = 0;
146
147 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
148 retval = add_slot(dev);
149 if (retval) {
150 pci_dev_put(dev);
151 break;
152 }
153 }
154
155 return retval;
156}
157
158static void remove_slot(struct dummy_slot *dslot)
159{
160 int retval;
161
162 dbg("removing slot %s\n", dslot->slot->name);
163 retval = pci_hp_deregister(dslot->slot);
164 if (retval)
165 err("Problem unregistering a slot %s\n", dslot->slot->name);
166}
167
168/**
169 * Rescan slot.
170 * Tries hard not to re-enable already existing devices
171 * also handles scanning of subfunctions
172 *
173 * @param temp Device template. Should be set: bus and devfn.
174 */
175static void pci_rescan_slot(struct pci_dev *temp)
176{
177 struct pci_bus *bus = temp->bus;
178 struct pci_dev *dev;
179 int func;
180 u8 hdr_type;
181 if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
182 temp->hdr_type = hdr_type & 0x7f;
183 if (!pci_find_slot(bus->number, temp->devfn)) {
184 dev = pci_scan_single_device(bus, temp->devfn);
185 if (dev) {
186 dbg("New device on %s function %x:%x\n",
187 bus->name, temp->devfn >> 3,
188 temp->devfn & 7);
189 pci_bus_add_device(dev);
190 add_slot(dev);
191 }
192 }
193 /* multifunction device? */
194 if (!(hdr_type & 0x80))
195 return;
196
197 /* continue scanning for other functions */
198 for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
199 if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
200 continue;
201 temp->hdr_type = hdr_type & 0x7f;
202
203 if (!pci_find_slot(bus->number, temp->devfn)) {
204 dev = pci_scan_single_device(bus, temp->devfn);
205 if (dev) {
206 dbg("New device on %s function %x:%x\n",
207 bus->name, temp->devfn >> 3,
208 temp->devfn & 7);
209 pci_bus_add_device(dev);
210 add_slot(dev);
211 }
212 }
213 }
214 }
215}
216
217
218/**
219 * Rescan PCI bus.
220 * call pci_rescan_slot for each possible function of the bus
221 *
222 * @param bus
223 */
224static void pci_rescan_bus(const struct pci_bus *bus)
225{
226 unsigned int devfn;
227 struct pci_dev *dev;
228 dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
229 if (!dev)
230 return;
231
232 memset(dev, 0, sizeof(dev));
233 dev->bus = (struct pci_bus*)bus;
234 dev->sysdata = bus->sysdata;
235 for (devfn = 0; devfn < 0x100; devfn += 8) {
236 dev->devfn = devfn;
237 pci_rescan_slot(dev);
238 }
239 kfree(dev);
240}
241
242/* recursively scan all buses */
243static void pci_rescan_buses(const struct list_head *list)
244{
245 const struct list_head *l;
246 list_for_each(l,list) {
247 const struct pci_bus *b = pci_bus_b(l);
248 pci_rescan_bus(b);
249 pci_rescan_buses(&b->children);
250 }
251}
252
253/* initiate rescan of all pci buses */
254static inline void pci_rescan(void) {
255 pci_rescan_buses(&pci_root_buses);
256}
257
258
259static int enable_slot(struct hotplug_slot *hotplug_slot)
260{
261 /* mis-use enable_slot for rescanning of the pci bus */
262 pci_rescan();
263 return -ENODEV;
264}
265
266/* find the hotplug_slot for the pci_dev */
267static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev)
268{
269 struct dummy_slot *dslot;
270
271 list_for_each_entry(dslot, &slot_list, node) {
272 if (dslot->dev == dev)
273 return dslot->slot;
274 }
275 return NULL;
276}
277
278
279static int disable_slot(struct hotplug_slot *slot)
280{
281 struct dummy_slot *dslot;
282 struct hotplug_slot *hslot;
283 struct pci_dev *dev;
284 int func;
285
286 if (!slot)
287 return -ENODEV;
288 dslot = slot->private;
289
290 dbg("%s - physical_slot = %s\n", __FUNCTION__, slot->name);
291
292 /* don't disable bridged devices just yet, we can't handle them easily... */
293 if (dslot->dev->subordinate) {
294 err("Can't remove PCI devices with other PCI devices behind it yet.\n");
295 return -ENODEV;
296 }
297 /* search for subfunctions and disable them first */
298 if (!(dslot->dev->devfn & 7)) {
299 for (func = 1; func < 8; func++) {
300 dev = pci_find_slot(dslot->dev->bus->number,
301 dslot->dev->devfn + func);
302 if (dev) {
303 hslot = get_slot_from_dev(dev);
304 if (hslot)
305 disable_slot(hslot);
306 else {
307 err("Hotplug slot not found for subfunction of PCI device\n");
308 return -ENODEV;
309 }
310 } else
311 dbg("No device in slot found\n");
312 }
313 }
314
315 /* remove the device from the pci core */
316 pci_remove_bus_device(dslot->dev);
317
318 /* blow away this sysfs entry and other parts. */
319 remove_slot(dslot);
320
321 return 0;
322}
323
324static void cleanup_slots (void)
325{
326 struct list_head *tmp;
327 struct list_head *next;
328 struct dummy_slot *dslot;
329
330 list_for_each_safe (tmp, next, &slot_list) {
331 dslot = list_entry (tmp, struct dummy_slot, node);
332 remove_slot(dslot);
333 }
334
335}
336
337static int __init dummyphp_init(void)
338{
339 info(DRIVER_DESC "\n");
340
341 return pci_scan_buses();
342}
343
344
345static void __exit dummyphp_exit(void)
346{
347 cleanup_slots();
348}
349
350module_init(dummyphp_init);
351module_exit(dummyphp_exit);
352
353MODULE_AUTHOR(DRIVER_AUTHOR);
354MODULE_DESCRIPTION(DRIVER_DESC);
355MODULE_LICENSE("GPL");
356module_param(debug, bool, S_IRUGO | S_IWUSR);
357MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
358
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
new file mode 100644
index 000000000000..5bc039da647f
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -0,0 +1,763 @@
1#ifndef __IBMPHP_H
2#define __IBMPHP_H
3
4/*
5 * IBM Hot Plug Controller Driver
6 *
7 * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
8 *
9 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
10 * Copyright (C) 2001-2003 IBM Corp.
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
22 * NON INFRINGEMENT. See the GNU General Public License for more
23 * details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 * Send feedback to <gregkh@us.ibm.com>
30 *
31 */
32
33#include "pci_hotplug.h"
34
35extern int ibmphp_debug;
36
37#if !defined(MODULE)
38 #define MY_NAME "ibmphpd"
39#else
40 #define MY_NAME THIS_MODULE->name
41#endif
42#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
43#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
44#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
45#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
46#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
47
48
49/* EBDA stuff */
50
51/***********************************************************
52* SLOT CAPABILITY *
53***********************************************************/
54
55#define EBDA_SLOT_133_MAX 0x20
56#define EBDA_SLOT_100_MAX 0x10
57#define EBDA_SLOT_66_MAX 0x02
58#define EBDA_SLOT_PCIX_CAP 0x08
59
60
61/************************************************************
62* RESOURE TYPE *
63************************************************************/
64
65#define EBDA_RSRC_TYPE_MASK 0x03
66#define EBDA_IO_RSRC_TYPE 0x00
67#define EBDA_MEM_RSRC_TYPE 0x01
68#define EBDA_PFM_RSRC_TYPE 0x03
69#define EBDA_RES_RSRC_TYPE 0x02
70
71
72/*************************************************************
73* IO RESTRICTION TYPE *
74*************************************************************/
75
76#define EBDA_IO_RESTRI_MASK 0x0c
77#define EBDA_NO_RESTRI 0x00
78#define EBDA_AVO_VGA_ADDR 0x04
79#define EBDA_AVO_VGA_ADDR_AND_ALIA 0x08
80#define EBDA_AVO_ISA_ADDR 0x0c
81
82
83/**************************************************************
84* DEVICE TYPE DEF *
85**************************************************************/
86
87#define EBDA_DEV_TYPE_MASK 0x10
88#define EBDA_PCI_DEV 0x10
89#define EBDA_NON_PCI_DEV 0x00
90
91
92/***************************************************************
93* PRIMARY DEF DEFINITION *
94***************************************************************/
95
96#define EBDA_PRI_DEF_MASK 0x20
97#define EBDA_PRI_PCI_BUS_INFO 0x20
98#define EBDA_NORM_DEV_RSRC_INFO 0x00
99
100
101//--------------------------------------------------------------
102// RIO TABLE DATA STRUCTURE
103//--------------------------------------------------------------
104
105struct rio_table_hdr {
106 u8 ver_num;
107 u8 scal_count;
108 u8 riodev_count;
109 u16 offset;
110};
111
112//-------------------------------------------------------------
113// SCALABILITY DETAIL
114//-------------------------------------------------------------
115
116struct scal_detail {
117 u8 node_id;
118 u32 cbar;
119 u8 port0_node_connect;
120 u8 port0_port_connect;
121 u8 port1_node_connect;
122 u8 port1_port_connect;
123 u8 port2_node_connect;
124 u8 port2_port_connect;
125 u8 chassis_num;
126// struct list_head scal_detail_list;
127};
128
129//--------------------------------------------------------------
130// RIO DETAIL
131//--------------------------------------------------------------
132
133struct rio_detail {
134 u8 rio_node_id;
135 u32 bbar;
136 u8 rio_type;
137 u8 owner_id;
138 u8 port0_node_connect;
139 u8 port0_port_connect;
140 u8 port1_node_connect;
141 u8 port1_port_connect;
142 u8 first_slot_num;
143 u8 status;
144 u8 wpindex;
145 u8 chassis_num;
146 struct list_head rio_detail_list;
147};
148
149struct opt_rio {
150 u8 rio_type;
151 u8 chassis_num;
152 u8 first_slot_num;
153 u8 middle_num;
154 struct list_head opt_rio_list;
155};
156
157struct opt_rio_lo {
158 u8 rio_type;
159 u8 chassis_num;
160 u8 first_slot_num;
161 u8 middle_num;
162 u8 pack_count;
163 struct list_head opt_rio_lo_list;
164};
165
166/****************************************************************
167* HPC DESCRIPTOR NODE *
168****************************************************************/
169
170struct ebda_hpc_list {
171 u8 format;
172 u16 num_ctlrs;
173 short phys_addr;
174// struct list_head ebda_hpc_list;
175};
176/*****************************************************************
177* IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS *
178* STRUCTURE *
179*****************************************************************/
180
181struct ebda_hpc_slot {
182 u8 slot_num;
183 u32 slot_bus_num;
184 u8 ctl_index;
185 u8 slot_cap;
186};
187
188struct ebda_hpc_bus {
189 u32 bus_num;
190 u8 slots_at_33_conv;
191 u8 slots_at_66_conv;
192 u8 slots_at_66_pcix;
193 u8 slots_at_100_pcix;
194 u8 slots_at_133_pcix;
195};
196
197
198/********************************************************************
199* THREE TYPE OF HOT PLUG CONTROLER *
200********************************************************************/
201
202struct isa_ctlr_access {
203 u16 io_start;
204 u16 io_end;
205};
206
207struct pci_ctlr_access {
208 u8 bus;
209 u8 dev_fun;
210};
211
212struct wpeg_i2c_ctlr_access {
213 ulong wpegbbar;
214 u8 i2c_addr;
215};
216
217#define HPC_DEVICE_ID 0x0246
218#define HPC_SUBSYSTEM_ID 0x0247
219#define HPC_PCI_OFFSET 0x40
220/*************************************************************************
221* RSTC DESCRIPTOR NODE *
222*************************************************************************/
223
224struct ebda_rsrc_list {
225 u8 format;
226 u16 num_entries;
227 u16 phys_addr;
228 struct ebda_rsrc_list *next;
229};
230
231
232/***************************************************************************
233* PCI RSRC NODE *
234***************************************************************************/
235
236struct ebda_pci_rsrc {
237 u8 rsrc_type;
238 u8 bus_num;
239 u8 dev_fun;
240 u32 start_addr;
241 u32 end_addr;
242 u8 marked; /* for NVRAM */
243 struct list_head ebda_pci_rsrc_list;
244};
245
246
247/***********************************************************
248* BUS_INFO DATE STRUCTURE *
249***********************************************************/
250
251struct bus_info {
252 u8 slot_min;
253 u8 slot_max;
254 u8 slot_count;
255 u8 busno;
256 u8 controller_id;
257 u8 current_speed;
258 u8 current_bus_mode;
259 u8 index;
260 u8 slots_at_33_conv;
261 u8 slots_at_66_conv;
262 u8 slots_at_66_pcix;
263 u8 slots_at_100_pcix;
264 u8 slots_at_133_pcix;
265 struct list_head bus_info_list;
266};
267
268
269/***********************************************************
270* GLOBAL VARIABLES *
271***********************************************************/
272extern struct list_head ibmphp_ebda_pci_rsrc_head;
273extern struct list_head ibmphp_slot_head;
274/***********************************************************
275* FUNCTION PROTOTYPES *
276***********************************************************/
277
278extern void ibmphp_free_ebda_hpc_queue (void);
279extern int ibmphp_access_ebda (void);
280extern struct slot *ibmphp_get_slot_from_physical_num (u8);
281extern int ibmphp_get_total_hp_slots (void);
282extern void ibmphp_free_ibm_slot (struct slot *);
283extern void ibmphp_free_bus_info_queue (void);
284extern void ibmphp_free_ebda_pci_rsrc_queue (void);
285extern struct bus_info *ibmphp_find_same_bus_num (u32);
286extern int ibmphp_get_bus_index (u8);
287extern u16 ibmphp_get_total_controllers (void);
288extern int ibmphp_register_pci (void);
289
290/* passed parameters */
291#define MEM 0
292#define IO 1
293#define PFMEM 2
294
295/* bit masks */
296#define RESTYPE 0x03
297#define IOMASK 0x00 /* will need to take its complement */
298#define MMASK 0x01
299#define PFMASK 0x03
300#define PCIDEVMASK 0x10 /* we should always have PCI devices */
301#define PRIMARYBUSMASK 0x20
302
303/* pci specific defines */
304#define PCI_VENDOR_ID_NOTVALID 0xFFFF
305#define PCI_HEADER_TYPE_MULTIDEVICE 0x80
306#define PCI_HEADER_TYPE_MULTIBRIDGE 0x81
307
308#define LATENCY 0x64
309#define CACHE 64
310#define DEVICEENABLE 0x015F /* CPQ has 0x0157 */
311
312#define IOBRIDGE 0x1000 /* 4k */
313#define MEMBRIDGE 0x100000 /* 1M */
314
315/* irqs */
316#define SCSI_IRQ 0x09
317#define LAN_IRQ 0x0A
318#define OTHER_IRQ 0x0B
319
320/* Data Structures */
321
322/* type is of the form x x xx xx
323 * | | | |_ 00 - I/O, 01 - Memory, 11 - PFMemory
324 * | | - 00 - No Restrictions, 01 - Avoid VGA, 10 - Avoid
325 * | | VGA and their aliases, 11 - Avoid ISA
326 * | - 1 - PCI device, 0 - non pci device
327 * - 1 - Primary PCI Bus Information (0 if Normal device)
328 * the IO restrictions [2:3] are only for primary buses
329 */
330
331
332/* we need this struct because there could be several resource blocks
333 * allocated per primary bus in the EBDA
334 */
335struct range_node {
336 int rangeno;
337 u32 start;
338 u32 end;
339 struct range_node *next;
340};
341
342struct bus_node {
343 u8 busno;
344 int noIORanges;
345 struct range_node *rangeIO;
346 int noMemRanges;
347 struct range_node *rangeMem;
348 int noPFMemRanges;
349 struct range_node *rangePFMem;
350 int needIOUpdate;
351 int needMemUpdate;
352 int needPFMemUpdate;
353 struct resource_node *firstIO; /* first IO resource on the Bus */
354 struct resource_node *firstMem; /* first memory resource on the Bus */
355 struct resource_node *firstPFMem; /* first prefetchable memory resource on the Bus */
356 struct resource_node *firstPFMemFromMem; /* when run out of pfmem available, taking from Mem */
357 struct list_head bus_list;
358};
359
360struct resource_node {
361 int rangeno;
362 u8 busno;
363 u8 devfunc;
364 u32 start;
365 u32 end;
366 u32 len;
367 int type; /* MEM, IO, PFMEM */
368 u8 fromMem; /* this is to indicate that the range is from
369 * from the Memory bucket rather than from PFMem */
370 struct resource_node *next;
371 struct resource_node *nextRange; /* for the other mem range on bus */
372};
373
374struct res_needed {
375 u32 mem;
376 u32 pfmem;
377 u32 io;
378 u8 not_correct; /* needed for return */
379 int devices[32]; /* for device numbers behind this bridge */
380};
381
382/* functions */
383
384extern int ibmphp_rsrc_init (void);
385extern int ibmphp_add_resource (struct resource_node *);
386extern int ibmphp_remove_resource (struct resource_node *);
387extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int);
388extern int ibmphp_check_resource (struct resource_node *, u8);
389extern int ibmphp_remove_bus (struct bus_node *, u8);
390extern void ibmphp_free_resources (void);
391extern int ibmphp_add_pfmem_from_mem (struct resource_node *);
392extern struct bus_node *ibmphp_find_res_bus (u8);
393extern void ibmphp_print_test (void); /* for debugging purposes */
394
395extern void ibmphp_hpc_initvars (void);
396extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *);
397extern int ibmphp_hpc_writeslot (struct slot *, u8);
398extern void ibmphp_lock_operations (void);
399extern void ibmphp_unlock_operations (void);
400extern int ibmphp_hpc_start_poll_thread (void);
401extern void ibmphp_hpc_stop_poll_thread (void);
402
403//----------------------------------------------------------------------------
404
405
406//----------------------------------------------------------------------------
407// HPC return codes
408//----------------------------------------------------------------------------
409#define FALSE 0x00
410#define TRUE 0x01
411#define HPC_ERROR 0xFF
412
413//-----------------------------------------------------------------------------
414// BUS INFO
415//-----------------------------------------------------------------------------
416#define BUS_SPEED 0x30
417#define BUS_MODE 0x40
418#define BUS_MODE_PCIX 0x01
419#define BUS_MODE_PCI 0x00
420#define BUS_SPEED_2 0x20
421#define BUS_SPEED_1 0x10
422#define BUS_SPEED_33 0x00
423#define BUS_SPEED_66 0x01
424#define BUS_SPEED_100 0x02
425#define BUS_SPEED_133 0x03
426#define BUS_SPEED_66PCIX 0x04
427#define BUS_SPEED_66UNKNOWN 0x05
428#define BUS_STATUS_AVAILABLE 0x01
429#define BUS_CONTROL_AVAILABLE 0x02
430#define SLOT_LATCH_REGS_SUPPORTED 0x10
431
432#define PRGM_MODEL_REV_LEVEL 0xF0
433#define MAX_ADAPTER_NONE 0x09
434
435//----------------------------------------------------------------------------
436// HPC 'write' operations/commands
437//----------------------------------------------------------------------------
438// Command Code State Write to reg
439// Machine at index
440//------------------------- ---- ------- ------------
441#define HPC_CTLR_ENABLEIRQ 0x00 // N 15
442#define HPC_CTLR_DISABLEIRQ 0x01 // N 15
443#define HPC_SLOT_OFF 0x02 // Y 0-14
444#define HPC_SLOT_ON 0x03 // Y 0-14
445#define HPC_SLOT_ATTNOFF 0x04 // N 0-14
446#define HPC_SLOT_ATTNON 0x05 // N 0-14
447#define HPC_CTLR_CLEARIRQ 0x06 // N 15
448#define HPC_CTLR_RESET 0x07 // Y 15
449#define HPC_CTLR_IRQSTEER 0x08 // N 15
450#define HPC_BUS_33CONVMODE 0x09 // Y 31-34
451#define HPC_BUS_66CONVMODE 0x0A // Y 31-34
452#define HPC_BUS_66PCIXMODE 0x0B // Y 31-34
453#define HPC_BUS_100PCIXMODE 0x0C // Y 31-34
454#define HPC_BUS_133PCIXMODE 0x0D // Y 31-34
455#define HPC_ALLSLOT_OFF 0x11 // Y 15
456#define HPC_ALLSLOT_ON 0x12 // Y 15
457#define HPC_SLOT_BLINKLED 0x13 // N 0-14
458
459//----------------------------------------------------------------------------
460// read commands
461//----------------------------------------------------------------------------
462#define READ_SLOTSTATUS 0x01
463#define READ_EXTSLOTSTATUS 0x02
464#define READ_BUSSTATUS 0x03
465#define READ_CTLRSTATUS 0x04
466#define READ_ALLSTAT 0x05
467#define READ_ALLSLOT 0x06
468#define READ_SLOTLATCHLOWREG 0x07
469#define READ_REVLEVEL 0x08
470#define READ_HPCOPTIONS 0x09
471//----------------------------------------------------------------------------
472// slot status
473//----------------------------------------------------------------------------
474#define HPC_SLOT_POWER 0x01
475#define HPC_SLOT_CONNECT 0x02
476#define HPC_SLOT_ATTN 0x04
477#define HPC_SLOT_PRSNT2 0x08
478#define HPC_SLOT_PRSNT1 0x10
479#define HPC_SLOT_PWRGD 0x20
480#define HPC_SLOT_BUS_SPEED 0x40
481#define HPC_SLOT_LATCH 0x80
482
483//----------------------------------------------------------------------------
484// HPC_SLOT_POWER status return codes
485//----------------------------------------------------------------------------
486#define HPC_SLOT_POWER_OFF 0x00
487#define HPC_SLOT_POWER_ON 0x01
488
489//----------------------------------------------------------------------------
490// HPC_SLOT_CONNECT status return codes
491//----------------------------------------------------------------------------
492#define HPC_SLOT_CONNECTED 0x00
493#define HPC_SLOT_DISCONNECTED 0x01
494
495//----------------------------------------------------------------------------
496// HPC_SLOT_ATTN status return codes
497//----------------------------------------------------------------------------
498#define HPC_SLOT_ATTN_OFF 0x00
499#define HPC_SLOT_ATTN_ON 0x01
500#define HPC_SLOT_ATTN_BLINK 0x02
501
502//----------------------------------------------------------------------------
503// HPC_SLOT_PRSNT status return codes
504//----------------------------------------------------------------------------
505#define HPC_SLOT_EMPTY 0x00
506#define HPC_SLOT_PRSNT_7 0x01
507#define HPC_SLOT_PRSNT_15 0x02
508#define HPC_SLOT_PRSNT_25 0x03
509
510//----------------------------------------------------------------------------
511// HPC_SLOT_PWRGD status return codes
512//----------------------------------------------------------------------------
513#define HPC_SLOT_PWRGD_FAULT_NONE 0x00
514#define HPC_SLOT_PWRGD_GOOD 0x01
515
516//----------------------------------------------------------------------------
517// HPC_SLOT_BUS_SPEED status return codes
518//----------------------------------------------------------------------------
519#define HPC_SLOT_BUS_SPEED_OK 0x00
520#define HPC_SLOT_BUS_SPEED_MISM 0x01
521
522//----------------------------------------------------------------------------
523// HPC_SLOT_LATCH status return codes
524//----------------------------------------------------------------------------
525#define HPC_SLOT_LATCH_OPEN 0x01 // NOTE : in PCI spec bit off = open
526#define HPC_SLOT_LATCH_CLOSED 0x00 // NOTE : in PCI spec bit on = closed
527
528
529//----------------------------------------------------------------------------
530// extended slot status
531//----------------------------------------------------------------------------
532#define HPC_SLOT_PCIX 0x01
533#define HPC_SLOT_SPEED1 0x02
534#define HPC_SLOT_SPEED2 0x04
535#define HPC_SLOT_BLINK_ATTN 0x08
536#define HPC_SLOT_RSRVD1 0x10
537#define HPC_SLOT_RSRVD2 0x20
538#define HPC_SLOT_BUS_MODE 0x40
539#define HPC_SLOT_RSRVD3 0x80
540
541//----------------------------------------------------------------------------
542// HPC_XSLOT_PCIX_CAP status return codes
543//----------------------------------------------------------------------------
544#define HPC_SLOT_PCIX_NO 0x00
545#define HPC_SLOT_PCIX_YES 0x01
546
547//----------------------------------------------------------------------------
548// HPC_XSLOT_SPEED status return codes
549//----------------------------------------------------------------------------
550#define HPC_SLOT_SPEED_33 0x00
551#define HPC_SLOT_SPEED_66 0x01
552#define HPC_SLOT_SPEED_133 0x02
553
554//----------------------------------------------------------------------------
555// HPC_XSLOT_ATTN_BLINK status return codes
556//----------------------------------------------------------------------------
557#define HPC_SLOT_ATTN_BLINK_OFF 0x00
558#define HPC_SLOT_ATTN_BLINK_ON 0x01
559
560//----------------------------------------------------------------------------
561// HPC_XSLOT_BUS_MODE status return codes
562//----------------------------------------------------------------------------
563#define HPC_SLOT_BUS_MODE_OK 0x00
564#define HPC_SLOT_BUS_MODE_MISM 0x01
565
566//----------------------------------------------------------------------------
567// Controller status
568//----------------------------------------------------------------------------
569#define HPC_CTLR_WORKING 0x01
570#define HPC_CTLR_FINISHED 0x02
571#define HPC_CTLR_RESULT0 0x04
572#define HPC_CTLR_RESULT1 0x08
573#define HPC_CTLR_RESULE2 0x10
574#define HPC_CTLR_RESULT3 0x20
575#define HPC_CTLR_IRQ_ROUTG 0x40
576#define HPC_CTLR_IRQ_PENDG 0x80
577
578//----------------------------------------------------------------------------
579// HPC_CTLR_WROKING status return codes
580//----------------------------------------------------------------------------
581#define HPC_CTLR_WORKING_NO 0x00
582#define HPC_CTLR_WORKING_YES 0x01
583
584//----------------------------------------------------------------------------
585// HPC_CTLR_FINISHED status return codes
586//----------------------------------------------------------------------------
587#define HPC_CTLR_FINISHED_NO 0x00
588#define HPC_CTLR_FINISHED_YES 0x01
589
590//----------------------------------------------------------------------------
591// HPC_CTLR_RESULT status return codes
592//----------------------------------------------------------------------------
593#define HPC_CTLR_RESULT_SUCCESS 0x00
594#define HPC_CTLR_RESULT_FAILED 0x01
595#define HPC_CTLR_RESULT_RSVD 0x02
596#define HPC_CTLR_RESULT_NORESP 0x03
597
598
599//----------------------------------------------------------------------------
600// macro for slot info
601//----------------------------------------------------------------------------
602#define SLOT_POWER(s) ((u8) ((s & HPC_SLOT_POWER) \
603 ? HPC_SLOT_POWER_ON : HPC_SLOT_POWER_OFF))
604
605#define SLOT_CONNECT(s) ((u8) ((s & HPC_SLOT_CONNECT) \
606 ? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
607
608#define SLOT_ATTN(s,es) ((u8) ((es & HPC_SLOT_BLINK_ATTN) \
609 ? HPC_SLOT_ATTN_BLINK \
610 : ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
611
612#define SLOT_PRESENT(s) ((u8) ((s & HPC_SLOT_PRSNT1) \
613 ? ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_EMPTY : HPC_SLOT_PRSNT_15) \
614 : ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_PRSNT_25 : HPC_SLOT_PRSNT_7)))
615
616#define SLOT_PWRGD(s) ((u8) ((s & HPC_SLOT_PWRGD) \
617 ? HPC_SLOT_PWRGD_GOOD : HPC_SLOT_PWRGD_FAULT_NONE))
618
619#define SLOT_BUS_SPEED(s) ((u8) ((s & HPC_SLOT_BUS_SPEED) \
620 ? HPC_SLOT_BUS_SPEED_MISM : HPC_SLOT_BUS_SPEED_OK))
621
622#define SLOT_LATCH(s) ((u8) ((s & HPC_SLOT_LATCH) \
623 ? HPC_SLOT_LATCH_CLOSED : HPC_SLOT_LATCH_OPEN))
624
625#define SLOT_PCIX(es) ((u8) ((es & HPC_SLOT_PCIX) \
626 ? HPC_SLOT_PCIX_YES : HPC_SLOT_PCIX_NO))
627
628#define SLOT_SPEED(es) ((u8) ((es & HPC_SLOT_SPEED2) \
629 ? ((es & HPC_SLOT_SPEED1) ? HPC_SLOT_SPEED_133 \
630 : HPC_SLOT_SPEED_66) \
631 : HPC_SLOT_SPEED_33))
632
633#define SLOT_BUS_MODE(es) ((u8) ((es & HPC_SLOT_BUS_MODE) \
634 ? HPC_SLOT_BUS_MODE_MISM : HPC_SLOT_BUS_MODE_OK))
635
636//--------------------------------------------------------------------------
637// macro for bus info
638//---------------------------------------------------------------------------
639#define CURRENT_BUS_SPEED(s) ((u8) (s & BUS_SPEED_2) \
640 ? ((s & BUS_SPEED_1) ? BUS_SPEED_133 : BUS_SPEED_100) \
641 : ((s & BUS_SPEED_1) ? BUS_SPEED_66 : BUS_SPEED_33))
642
643#define CURRENT_BUS_MODE(s) ((u8) (s & BUS_MODE) ? BUS_MODE_PCIX : BUS_MODE_PCI)
644
645#define READ_BUS_STATUS(s) ((u8) (s->options & BUS_STATUS_AVAILABLE))
646
647#define READ_BUS_MODE(s) ((s->revision & PRGM_MODEL_REV_LEVEL) >= 0x20)
648
649#define SET_BUS_STATUS(s) ((u8) (s->options & BUS_CONTROL_AVAILABLE))
650
651#define READ_SLOT_LATCH(s) ((u8) (s->options & SLOT_LATCH_REGS_SUPPORTED))
652
653//----------------------------------------------------------------------------
654// macro for controller info
655//----------------------------------------------------------------------------
656#define CTLR_WORKING(c) ((u8) ((c & HPC_CTLR_WORKING) \
657 ? HPC_CTLR_WORKING_YES : HPC_CTLR_WORKING_NO))
658#define CTLR_FINISHED(c) ((u8) ((c & HPC_CTLR_FINISHED) \
659 ? HPC_CTLR_FINISHED_YES : HPC_CTLR_FINISHED_NO))
660#define CTLR_RESULT(c) ((u8) ((c & HPC_CTLR_RESULT1) \
661 ? ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_NORESP \
662 : HPC_CTLR_RESULT_RSVD) \
663 : ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_FAILED \
664 : HPC_CTLR_RESULT_SUCCESS)))
665
666// command that affect the state machine of HPC
667#define NEEDTOCHECK_CMDSTATUS(c) ((c == HPC_SLOT_OFF) || \
668 (c == HPC_SLOT_ON) || \
669 (c == HPC_CTLR_RESET) || \
670 (c == HPC_BUS_33CONVMODE) || \
671 (c == HPC_BUS_66CONVMODE) || \
672 (c == HPC_BUS_66PCIXMODE) || \
673 (c == HPC_BUS_100PCIXMODE) || \
674 (c == HPC_BUS_133PCIXMODE) || \
675 (c == HPC_ALLSLOT_OFF) || \
676 (c == HPC_ALLSLOT_ON))
677
678
679/* Core part of the driver */
680
681#define ENABLE 1
682#define DISABLE 0
683
684#define CARD_INFO 0x07
685#define PCIX133 0x07
686#define PCIX66 0x05
687#define PCI66 0x04
688
689extern struct pci_bus *ibmphp_pci_bus;
690
691/* Variables */
692
693struct pci_func {
694 struct pci_dev *dev; /* from the OS */
695 u8 busno;
696 u8 device;
697 u8 function;
698 struct resource_node *io[6];
699 struct resource_node *mem[6];
700 struct resource_node *pfmem[6];
701 struct pci_func *next;
702 int devices[32]; /* for bridge config */
703 u8 irq[4]; /* for interrupt config */
704 u8 bus; /* flag for unconfiguring, to say if PPB */
705};
706
707struct slot {
708 u8 bus;
709 u8 device;
710 u8 number;
711 u8 real_physical_slot_num;
712 char name[100];
713 u32 capabilities;
714 u8 supported_speed;
715 u8 supported_bus_mode;
716 struct hotplug_slot *hotplug_slot;
717 struct controller *ctrl;
718 struct pci_func *func;
719 u8 irq[4];
720 u8 flag; /* this is for disable slot and polling */
721 int bit_mode; /* 0 = 32, 1 = 64 */
722 u8 ctlr_index;
723 struct bus_info *bus_on;
724 struct list_head ibm_slot_list;
725 u8 status;
726 u8 ext_status;
727 u8 busstatus;
728};
729
730struct controller {
731 struct ebda_hpc_slot *slots;
732 struct ebda_hpc_bus *buses;
733 struct pci_dev *ctrl_dev; /* in case where controller is PCI */
734 u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/
735 u8 ending_slot_num;
736 u8 revision;
737 u8 options; /* which options HPC supports */
738 u8 status;
739 u8 ctlr_id;
740 u8 slot_count;
741 u8 bus_count;
742 u8 ctlr_relative_id;
743 u32 irq;
744 union {
745 struct isa_ctlr_access isa_ctlr;
746 struct pci_ctlr_access pci_ctlr;
747 struct wpeg_i2c_ctlr_access wpeg_ctlr;
748 } u;
749 u8 ctlr_type;
750 struct list_head ebda_hpc_list;
751};
752
753/* Functions */
754
755extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */
756extern int ibmphp_do_disable_slot (struct slot *slot_cur);
757extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */
758extern int ibmphp_configure_card (struct pci_func *, u8);
759extern int ibmphp_unconfigure_card (struct slot **, int);
760extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
761
762#endif //__IBMPHP_H
763
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
new file mode 100644
index 000000000000..0392e004258f
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -0,0 +1,1422 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
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 <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/pci.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/wait.h>
37#include <linux/smp_lock.h>
38#include "../pci.h"
39#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
40#include "ibmphp.h"
41
42#define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
43#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
44#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
45#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
46#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
47
48#define DRIVER_VERSION "0.6"
49#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
50
51int ibmphp_debug;
52
53static int debug;
54module_param(debug, bool, S_IRUGO | S_IWUSR);
55MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
56MODULE_LICENSE ("GPL");
57MODULE_DESCRIPTION (DRIVER_DESC);
58
59struct pci_bus *ibmphp_pci_bus;
60static int max_slots;
61
62static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS
63 * tables don't provide default info for empty slots */
64
65static int init_flag;
66
67/*
68static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
69
70static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
71{
72 return get_max_adapter_speed_1 (hs, value, 1);
73}
74*/
75static inline int get_cur_bus_info(struct slot **sl)
76{
77 int rc = 1;
78 struct slot * slot_cur = *sl;
79
80 debug("options = %x\n", slot_cur->ctrl->options);
81 debug("revision = %x\n", slot_cur->ctrl->revision);
82
83 if (READ_BUS_STATUS(slot_cur->ctrl))
84 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
85
86 if (rc)
87 return rc;
88
89 slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
90 if (READ_BUS_MODE(slot_cur->ctrl))
91 slot_cur->bus_on->current_bus_mode =
92 CURRENT_BUS_MODE(slot_cur->busstatus);
93 else
94 slot_cur->bus_on->current_bus_mode = 0xFF;
95
96 debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
97 slot_cur->busstatus,
98 slot_cur->bus_on->current_speed,
99 slot_cur->bus_on->current_bus_mode);
100
101 *sl = slot_cur;
102 return 0;
103}
104
105static inline int slot_update(struct slot **sl)
106{
107 int rc;
108 rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
109 if (rc)
110 return rc;
111 if (!init_flag)
112 rc = get_cur_bus_info(sl);
113 return rc;
114}
115
116static int __init get_max_slots (void)
117{
118 struct slot * slot_cur;
119 struct list_head * tmp;
120 u8 slot_count = 0;
121
122 list_for_each(tmp, &ibmphp_slot_head) {
123 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
124 /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
125 slot_count = max(slot_count, slot_cur->number);
126 }
127 return slot_count;
128}
129
130/* This routine will put the correct slot->device information per slot. It's
131 * called from initialization of the slot structures. It will also assign
132 * interrupt numbers per each slot.
133 * Parameters: struct slot
134 * Returns 0 or errors
135 */
136int ibmphp_init_devno(struct slot **cur_slot)
137{
138 struct irq_routing_table *rtable;
139 int len;
140 int loop;
141 int i;
142
143 rtable = pcibios_get_irq_routing_table();
144 if (!rtable) {
145 err("no BIOS routing table...\n");
146 return -ENOMEM;
147 }
148
149 len = (rtable->size - sizeof(struct irq_routing_table)) /
150 sizeof(struct irq_info);
151
152 if (!len)
153 return -1;
154 for (loop = 0; loop < len; loop++) {
155 if ((*cur_slot)->number == rtable->slots[loop].slot) {
156 if ((*cur_slot)->bus == rtable->slots[loop].bus) {
157 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
158 for (i = 0; i < 4; i++)
159 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
160 (int) (*cur_slot)->device, i);
161
162 debug("(*cur_slot)->irq[0] = %x\n",
163 (*cur_slot)->irq[0]);
164 debug("(*cur_slot)->irq[1] = %x\n",
165 (*cur_slot)->irq[1]);
166 debug("(*cur_slot)->irq[2] = %x\n",
167 (*cur_slot)->irq[2]);
168 debug("(*cur_slot)->irq[3] = %x\n",
169 (*cur_slot)->irq[3]);
170
171 debug("rtable->exlusive_irqs = %x\n",
172 rtable->exclusive_irqs);
173 debug("rtable->slots[loop].irq[0].bitmap = %x\n",
174 rtable->slots[loop].irq[0].bitmap);
175 debug("rtable->slots[loop].irq[1].bitmap = %x\n",
176 rtable->slots[loop].irq[1].bitmap);
177 debug("rtable->slots[loop].irq[2].bitmap = %x\n",
178 rtable->slots[loop].irq[2].bitmap);
179 debug("rtable->slots[loop].irq[3].bitmap = %x\n",
180 rtable->slots[loop].irq[3].bitmap);
181
182 debug("rtable->slots[loop].irq[0].link = %x\n",
183 rtable->slots[loop].irq[0].link);
184 debug("rtable->slots[loop].irq[1].link = %x\n",
185 rtable->slots[loop].irq[1].link);
186 debug("rtable->slots[loop].irq[2].link = %x\n",
187 rtable->slots[loop].irq[2].link);
188 debug("rtable->slots[loop].irq[3].link = %x\n",
189 rtable->slots[loop].irq[3].link);
190 debug("end of init_devno\n");
191 return 0;
192 }
193 }
194 }
195
196 return -1;
197}
198
199static inline int power_on(struct slot *slot_cur)
200{
201 u8 cmd = HPC_SLOT_ON;
202 int retval;
203
204 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
205 if (retval) {
206 err("power on failed\n");
207 return retval;
208 }
209 if (CTLR_RESULT(slot_cur->ctrl->status)) {
210 err("command not completed successfully in power_on\n");
211 return -EIO;
212 }
213 msleep(3000); /* For ServeRAID cards, and some 66 PCI */
214 return 0;
215}
216
217static inline int power_off(struct slot *slot_cur)
218{
219 u8 cmd = HPC_SLOT_OFF;
220 int retval;
221
222 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
223 if (retval) {
224 err("power off failed\n");
225 return retval;
226 }
227 if (CTLR_RESULT(slot_cur->ctrl->status)) {
228 err("command not completed successfully in power_off\n");
229 retval = -EIO;
230 }
231 return retval;
232}
233
234static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
235{
236 int rc = 0;
237 struct slot *pslot;
238 u8 cmd;
239
240 debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
241 (ulong) hotplug_slot, value);
242 ibmphp_lock_operations();
243 cmd = 0x00; // avoid compiler warning
244
245 if (hotplug_slot) {
246 switch (value) {
247 case HPC_SLOT_ATTN_OFF:
248 cmd = HPC_SLOT_ATTNOFF;
249 break;
250 case HPC_SLOT_ATTN_ON:
251 cmd = HPC_SLOT_ATTNON;
252 break;
253 case HPC_SLOT_ATTN_BLINK:
254 cmd = HPC_SLOT_BLINKLED;
255 break;
256 default:
257 rc = -ENODEV;
258 err("set_attention_status - Error : invalid input [%x]\n",
259 value);
260 break;
261 }
262 if (rc == 0) {
263 pslot = hotplug_slot->private;
264 if (pslot)
265 rc = ibmphp_hpc_writeslot(pslot, cmd);
266 else
267 rc = -ENODEV;
268 }
269 } else
270 rc = -ENODEV;
271
272 ibmphp_unlock_operations();
273
274 debug("set_attention_status - Exit rc[%d]\n", rc);
275 return rc;
276}
277
278static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
279{
280 int rc = -ENODEV;
281 struct slot *pslot;
282 struct slot myslot;
283
284 debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
285 (ulong) hotplug_slot, (ulong) value);
286
287 ibmphp_lock_operations();
288 if (hotplug_slot && value) {
289 pslot = hotplug_slot->private;
290 if (pslot) {
291 memcpy(&myslot, pslot, sizeof(struct slot));
292 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
293 &(myslot.status));
294 if (!rc)
295 rc = ibmphp_hpc_readslot(pslot,
296 READ_EXTSLOTSTATUS,
297 &(myslot.ext_status));
298 if (!rc)
299 *value = SLOT_ATTN(myslot.status,
300 myslot.ext_status);
301 }
302 }
303
304 ibmphp_unlock_operations();
305 debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
306 return rc;
307}
308
309static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
310{
311 int rc = -ENODEV;
312 struct slot *pslot;
313 struct slot myslot;
314
315 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
316 (ulong) hotplug_slot, (ulong) value);
317 ibmphp_lock_operations();
318 if (hotplug_slot && value) {
319 pslot = hotplug_slot->private;
320 if (pslot) {
321 memcpy(&myslot, pslot, sizeof(struct slot));
322 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
323 &(myslot.status));
324 if (!rc)
325 *value = SLOT_LATCH(myslot.status);
326 }
327 }
328
329 ibmphp_unlock_operations();
330 debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
331 rc, rc, *value);
332 return rc;
333}
334
335
336static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
337{
338 int rc = -ENODEV;
339 struct slot *pslot;
340 struct slot myslot;
341
342 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
343 (ulong) hotplug_slot, (ulong) value);
344 ibmphp_lock_operations();
345 if (hotplug_slot && value) {
346 pslot = hotplug_slot->private;
347 if (pslot) {
348 memcpy(&myslot, pslot, sizeof(struct slot));
349 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
350 &(myslot.status));
351 if (!rc)
352 *value = SLOT_PWRGD(myslot.status);
353 }
354 }
355
356 ibmphp_unlock_operations();
357 debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
358 rc, rc, *value);
359 return rc;
360}
361
362static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
363{
364 int rc = -ENODEV;
365 struct slot *pslot;
366 u8 present;
367 struct slot myslot;
368
369 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
370 (ulong) hotplug_slot, (ulong) value);
371 ibmphp_lock_operations();
372 if (hotplug_slot && value) {
373 pslot = hotplug_slot->private;
374 if (pslot) {
375 memcpy(&myslot, pslot, sizeof(struct slot));
376 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
377 &(myslot.status));
378 if (!rc) {
379 present = SLOT_PRESENT(myslot.status);
380 if (present == HPC_SLOT_EMPTY)
381 *value = 0;
382 else
383 *value = 1;
384 }
385 }
386 }
387
388 ibmphp_unlock_operations();
389 debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
390 return rc;
391}
392
393static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
394{
395 int rc = -ENODEV;
396 struct slot *pslot;
397 u8 mode = 0;
398
399 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
400 hotplug_slot, value);
401
402 ibmphp_lock_operations();
403
404 if (hotplug_slot && value) {
405 pslot = hotplug_slot->private;
406 if (pslot) {
407 rc = 0;
408 mode = pslot->supported_bus_mode;
409 *value = pslot->supported_speed;
410 switch (*value) {
411 case BUS_SPEED_33:
412 break;
413 case BUS_SPEED_66:
414 if (mode == BUS_MODE_PCIX)
415 *value += 0x01;
416 break;
417 case BUS_SPEED_100:
418 case BUS_SPEED_133:
419 *value = pslot->supported_speed + 0x01;
420 break;
421 default:
422 /* Note (will need to change): there would be soon 256, 512 also */
423 rc = -ENODEV;
424 }
425 }
426 }
427
428 ibmphp_unlock_operations();
429 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
430 return rc;
431}
432
433static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
434{
435 int rc = -ENODEV;
436 struct slot *pslot;
437 u8 mode = 0;
438
439 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
440 hotplug_slot, value);
441
442 ibmphp_lock_operations();
443
444 if (hotplug_slot && value) {
445 pslot = hotplug_slot->private;
446 if (pslot) {
447 rc = get_cur_bus_info(&pslot);
448 if (!rc) {
449 mode = pslot->bus_on->current_bus_mode;
450 *value = pslot->bus_on->current_speed;
451 switch (*value) {
452 case BUS_SPEED_33:
453 break;
454 case BUS_SPEED_66:
455 if (mode == BUS_MODE_PCIX)
456 *value += 0x01;
457 else if (mode == BUS_MODE_PCI)
458 ;
459 else
460 *value = PCI_SPEED_UNKNOWN;
461 break;
462 case BUS_SPEED_100:
463 case BUS_SPEED_133:
464 *value += 0x01;
465 break;
466 default:
467 /* Note of change: there would also be 256, 512 soon */
468 rc = -ENODEV;
469 }
470 }
471 }
472 }
473
474 ibmphp_unlock_operations();
475 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
476 return rc;
477}
478
479/*
480static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
481{
482 int rc = -ENODEV;
483 struct slot *pslot;
484 struct slot myslot;
485
486 debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
487 (ulong)hotplug_slot, (ulong) value);
488
489 if (flag)
490 ibmphp_lock_operations();
491
492 if (hotplug_slot && value) {
493 pslot = hotplug_slot->private;
494 if (pslot) {
495 memcpy(&myslot, pslot, sizeof(struct slot));
496 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
497 &(myslot.status));
498
499 if (!(SLOT_LATCH (myslot.status)) &&
500 (SLOT_PRESENT (myslot.status))) {
501 rc = ibmphp_hpc_readslot(pslot,
502 READ_EXTSLOTSTATUS,
503 &(myslot.ext_status));
504 if (!rc)
505 *value = SLOT_SPEED(myslot.ext_status);
506 } else
507 *value = MAX_ADAPTER_NONE;
508 }
509 }
510
511 if (flag)
512 ibmphp_unlock_operations();
513
514 debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
515 return rc;
516}
517
518static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
519{
520 int rc = -ENODEV;
521 struct slot *pslot = NULL;
522
523 debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
524
525 ibmphp_lock_operations();
526
527 if (hotplug_slot) {
528 pslot = hotplug_slot->private;
529 if (pslot) {
530 rc = 0;
531 snprintf(value, 100, "Bus %x", pslot->bus);
532 }
533 } else
534 rc = -ENODEV;
535
536 ibmphp_unlock_operations();
537 debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
538 return rc;
539}
540*/
541
542/****************************************************************************
543 * This routine will initialize the ops data structure used in the validate
544 * function. It will also power off empty slots that are powered on since BIOS
545 * leaves those on, albeit disconnected
546 ****************************************************************************/
547static int __init init_ops(void)
548{
549 struct slot *slot_cur;
550 struct list_head *tmp;
551 int retval;
552 int rc;
553
554 list_for_each(tmp, &ibmphp_slot_head) {
555 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
556
557 if (!slot_cur)
558 return -ENODEV;
559
560 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
561 slot_cur->number);
562 if (slot_cur->ctrl->revision == 0xFF)
563 if (get_ctrl_revision(slot_cur,
564 &slot_cur->ctrl->revision))
565 return -1;
566
567 if (slot_cur->bus_on->current_speed == 0xFF)
568 if (get_cur_bus_info(&slot_cur))
569 return -1;
570
571 if (slot_cur->ctrl->options == 0xFF)
572 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
573 return -1;
574
575 retval = slot_update(&slot_cur);
576 if (retval)
577 return retval;
578
579 debug("status = %x\n", slot_cur->status);
580 debug("ext_status = %x\n", slot_cur->ext_status);
581 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
582 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
583 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
584
585 if ((SLOT_PWRGD(slot_cur->status)) &&
586 !(SLOT_PRESENT(slot_cur->status)) &&
587 !(SLOT_LATCH(slot_cur->status))) {
588 debug("BEFORE POWER OFF COMMAND\n");
589 rc = power_off(slot_cur);
590 if (rc)
591 return rc;
592
593 /* retval = slot_update(&slot_cur);
594 * if (retval)
595 * return retval;
596 * ibmphp_update_slot_info(slot_cur);
597 */
598 }
599 }
600 init_flag = 0;
601 return 0;
602}
603
604/* This operation will check whether the slot is within the bounds and
605 * the operation is valid to perform on that slot
606 * Parameters: slot, operation
607 * Returns: 0 or error codes
608 */
609static int validate(struct slot *slot_cur, int opn)
610{
611 int number;
612 int retval;
613
614 if (!slot_cur)
615 return -ENODEV;
616 number = slot_cur->number;
617 if ((number > max_slots) || (number < 0))
618 return -EBADSLT;
619 debug("slot_number in validate is %d\n", slot_cur->number);
620
621 retval = slot_update(&slot_cur);
622 if (retval)
623 return retval;
624
625 switch (opn) {
626 case ENABLE:
627 if (!(SLOT_PWRGD(slot_cur->status)) &&
628 (SLOT_PRESENT(slot_cur->status)) &&
629 !(SLOT_LATCH(slot_cur->status)))
630 return 0;
631 break;
632 case DISABLE:
633 if ((SLOT_PWRGD(slot_cur->status)) &&
634 (SLOT_PRESENT(slot_cur->status)) &&
635 !(SLOT_LATCH(slot_cur->status)))
636 return 0;
637 break;
638 default:
639 break;
640 }
641 err("validate failed....\n");
642 return -EINVAL;
643}
644
645/****************************************************************************
646 * This routine is for updating the data structures in the hotplug core
647 * Parameters: struct slot
648 * Returns: 0 or error
649 ****************************************************************************/
650int ibmphp_update_slot_info(struct slot *slot_cur)
651{
652 struct hotplug_slot_info *info;
653 int rc;
654 u8 bus_speed;
655 u8 mode;
656
657 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
658 if (!info) {
659 err("out of system memory\n");
660 return -ENOMEM;
661 }
662
663 info->power_status = SLOT_PWRGD(slot_cur->status);
664 info->attention_status = SLOT_ATTN(slot_cur->status,
665 slot_cur->ext_status);
666 info->latch_status = SLOT_LATCH(slot_cur->status);
667 if (!SLOT_PRESENT(slot_cur->status)) {
668 info->adapter_status = 0;
669/* info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
670 } else {
671 info->adapter_status = 1;
672/* get_max_adapter_speed_1(slot_cur->hotplug_slot,
673 &info->max_adapter_speed_status, 0); */
674 }
675
676 bus_speed = slot_cur->bus_on->current_speed;
677 mode = slot_cur->bus_on->current_bus_mode;
678
679 switch (bus_speed) {
680 case BUS_SPEED_33:
681 break;
682 case BUS_SPEED_66:
683 if (mode == BUS_MODE_PCIX)
684 bus_speed += 0x01;
685 else if (mode == BUS_MODE_PCI)
686 ;
687 else
688 bus_speed = PCI_SPEED_UNKNOWN;
689 break;
690 case BUS_SPEED_100:
691 case BUS_SPEED_133:
692 bus_speed += 0x01;
693 break;
694 default:
695 bus_speed = PCI_SPEED_UNKNOWN;
696 }
697
698 info->cur_bus_speed = bus_speed;
699 info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
700 // To do: bus_names
701
702 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
703 kfree(info);
704 return rc;
705}
706
707
708/******************************************************************************
709 * This function will return the pci_func, given bus and devfunc, or NULL. It
710 * is called from visit routines
711 ******************************************************************************/
712
713static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
714{
715 struct pci_func *func_cur;
716 struct slot *slot_cur;
717 struct list_head * tmp;
718 list_for_each(tmp, &ibmphp_slot_head) {
719 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
720 if (slot_cur->func) {
721 func_cur = slot_cur->func;
722 while (func_cur) {
723 if ((func_cur->busno == busno) &&
724 (func_cur->device == device) &&
725 (func_cur->function == function))
726 return func_cur;
727 func_cur = func_cur->next;
728 }
729 }
730 }
731 return NULL;
732}
733
734/*************************************************************
735 * This routine frees up memory used by struct slot, including
736 * the pointers to pci_func, bus, hotplug_slot, controller,
737 * and deregistering from the hotplug core
738 *************************************************************/
739static void free_slots(void)
740{
741 struct slot *slot_cur;
742 struct list_head * tmp;
743 struct list_head * next;
744
745 debug("%s -- enter\n", __FUNCTION__);
746
747 list_for_each_safe(tmp, next, &ibmphp_slot_head) {
748 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
749 pci_hp_deregister(slot_cur->hotplug_slot);
750 }
751 debug("%s -- exit\n", __FUNCTION__);
752}
753
754static void ibm_unconfigure_device(struct pci_func *func)
755{
756 struct pci_dev *temp;
757 u8 j;
758
759 debug("inside %s\n", __FUNCTION__);
760 debug("func->device = %x, func->function = %x\n",
761 func->device, func->function);
762 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
763
764 for (j = 0; j < 0x08; j++) {
765 temp = pci_find_slot(func->busno, (func->device << 3) | j);
766 if (temp)
767 pci_remove_bus_device(temp);
768 }
769}
770
771/*
772 * The following function is to fix kernel bug regarding
773 * getting bus entries, here we manually add those primary
774 * bus entries to kernel bus structure whenever apply
775 */
776static u8 bus_structure_fixup(u8 busno)
777{
778 struct pci_bus *bus;
779 struct pci_dev *dev;
780 u16 l;
781
782 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
783 return 1;
784
785 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
786 if (!bus) {
787 err("%s - out of memory\n", __FUNCTION__);
788 return 1;
789 }
790 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
791 if (!dev) {
792 kfree(bus);
793 err("%s - out of memory\n", __FUNCTION__);
794 return 1;
795 }
796
797 bus->number = busno;
798 bus->ops = ibmphp_pci_bus->ops;
799 dev->bus = bus;
800 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
801 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
802 (l != 0x0000) && (l != 0xffff)) {
803 debug("%s - Inside bus_struture_fixup()\n",
804 __FUNCTION__);
805 pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
806 break;
807 }
808 }
809
810 kfree(dev);
811 kfree(bus);
812
813 return 0;
814}
815
816static int ibm_configure_device(struct pci_func *func)
817{
818 unsigned char bus;
819 struct pci_bus *child;
820 int num;
821 int flag = 0; /* this is to make sure we don't double scan the bus,
822 for bridged devices primarily */
823
824 if (!(bus_structure_fixup(func->busno)))
825 flag = 1;
826 if (func->dev == NULL)
827 func->dev = pci_find_slot(func->busno,
828 PCI_DEVFN(func->device, func->function));
829
830 if (func->dev == NULL) {
831 struct pci_bus *bus = pci_find_bus(0, func->busno);
832 if (!bus)
833 return 0;
834
835 num = pci_scan_slot(bus,
836 PCI_DEVFN(func->device, func->function));
837 if (num)
838 pci_bus_add_devices(bus);
839
840 func->dev = pci_find_slot(func->busno,
841 PCI_DEVFN(func->device, func->function));
842 if (func->dev == NULL) {
843 err("ERROR... : pci_dev still NULL\n");
844 return 0;
845 }
846 }
847 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
848 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
849 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
850 pci_do_scan_bus(child);
851 }
852
853 return 0;
854}
855
856/*******************************************************
857 * Returns whether the bus is empty or not
858 *******************************************************/
859static int is_bus_empty(struct slot * slot_cur)
860{
861 int rc;
862 struct slot * tmp_slot;
863 u8 i = slot_cur->bus_on->slot_min;
864
865 while (i <= slot_cur->bus_on->slot_max) {
866 if (i == slot_cur->number) {
867 i++;
868 continue;
869 }
870 tmp_slot = ibmphp_get_slot_from_physical_num(i);
871 if (!tmp_slot)
872 return 0;
873 rc = slot_update(&tmp_slot);
874 if (rc)
875 return 0;
876 if (SLOT_PRESENT(tmp_slot->status) &&
877 SLOT_PWRGD(tmp_slot->status))
878 return 0;
879 i++;
880 }
881 return 1;
882}
883
884/***********************************************************
885 * If the HPC permits and the bus currently empty, tries to set the
886 * bus speed and mode at the maximum card and bus capability
887 * Parameters: slot
888 * Returns: bus is set (0) or error code
889 ***********************************************************/
890static int set_bus(struct slot * slot_cur)
891{
892 int rc;
893 u8 speed;
894 u8 cmd = 0x0;
895 int retval;
896 static struct pci_device_id ciobx[] = {
897 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
898 { },
899 };
900
901 debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
902 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
903 rc = slot_update(&slot_cur);
904 if (rc)
905 return rc;
906 speed = SLOT_SPEED(slot_cur->ext_status);
907 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
908 switch (speed) {
909 case HPC_SLOT_SPEED_33:
910 cmd = HPC_BUS_33CONVMODE;
911 break;
912 case HPC_SLOT_SPEED_66:
913 if (SLOT_PCIX(slot_cur->ext_status)) {
914 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
915 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
916 cmd = HPC_BUS_66PCIXMODE;
917 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
918 /* if max slot/bus capability is 66 pci
919 and there's no bus mode mismatch, then
920 the adapter supports 66 pci */
921 cmd = HPC_BUS_66CONVMODE;
922 else
923 cmd = HPC_BUS_33CONVMODE;
924 } else {
925 if (slot_cur->supported_speed >= BUS_SPEED_66)
926 cmd = HPC_BUS_66CONVMODE;
927 else
928 cmd = HPC_BUS_33CONVMODE;
929 }
930 break;
931 case HPC_SLOT_SPEED_133:
932 switch (slot_cur->supported_speed) {
933 case BUS_SPEED_33:
934 cmd = HPC_BUS_33CONVMODE;
935 break;
936 case BUS_SPEED_66:
937 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
938 cmd = HPC_BUS_66PCIXMODE;
939 else
940 cmd = HPC_BUS_66CONVMODE;
941 break;
942 case BUS_SPEED_100:
943 cmd = HPC_BUS_100PCIXMODE;
944 break;
945 case BUS_SPEED_133:
946 /* This is to take care of the bug in CIOBX chip */
947 if (pci_dev_present(ciobx))
948 ibmphp_hpc_writeslot(slot_cur,
949 HPC_BUS_100PCIXMODE);
950 cmd = HPC_BUS_133PCIXMODE;
951 break;
952 default:
953 err("Wrong bus speed\n");
954 return -ENODEV;
955 }
956 break;
957 default:
958 err("wrong slot speed\n");
959 return -ENODEV;
960 }
961 debug("setting bus speed for slot %d, cmd %x\n",
962 slot_cur->number, cmd);
963 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
964 if (retval) {
965 err("setting bus speed failed\n");
966 return retval;
967 }
968 if (CTLR_RESULT(slot_cur->ctrl->status)) {
969 err("command not completed successfully in set_bus\n");
970 return -EIO;
971 }
972 }
973 /* This is for x440, once Brandon fixes the firmware,
974 will not need this delay */
975 msleep(1000);
976 debug("%s -Exit\n", __FUNCTION__);
977 return 0;
978}
979
980/* This routine checks the bus limitations that the slot is on from the BIOS.
981 * This is used in deciding whether or not to power up the slot.
982 * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
983 * same bus)
984 * Parameters: slot
985 * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
986 */
987static int check_limitations(struct slot *slot_cur)
988{
989 u8 i;
990 struct slot * tmp_slot;
991 u8 count = 0;
992 u8 limitation = 0;
993
994 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
995 tmp_slot = ibmphp_get_slot_from_physical_num(i);
996 if (!tmp_slot)
997 return -ENODEV;
998 if ((SLOT_PWRGD(tmp_slot->status)) &&
999 !(SLOT_CONNECT(tmp_slot->status)))
1000 count++;
1001 }
1002 get_cur_bus_info(&slot_cur);
1003 switch (slot_cur->bus_on->current_speed) {
1004 case BUS_SPEED_33:
1005 limitation = slot_cur->bus_on->slots_at_33_conv;
1006 break;
1007 case BUS_SPEED_66:
1008 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1009 limitation = slot_cur->bus_on->slots_at_66_pcix;
1010 else
1011 limitation = slot_cur->bus_on->slots_at_66_conv;
1012 break;
1013 case BUS_SPEED_100:
1014 limitation = slot_cur->bus_on->slots_at_100_pcix;
1015 break;
1016 case BUS_SPEED_133:
1017 limitation = slot_cur->bus_on->slots_at_133_pcix;
1018 break;
1019 }
1020
1021 if ((count + 1) > limitation)
1022 return -EINVAL;
1023 return 0;
1024}
1025
1026static inline void print_card_capability(struct slot *slot_cur)
1027{
1028 info("capability of the card is ");
1029 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1030 info(" 133 MHz PCI-X\n");
1031 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1032 info(" 66 MHz PCI-X\n");
1033 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1034 info(" 66 MHz PCI\n");
1035 else
1036 info(" 33 MHz PCI\n");
1037
1038}
1039
1040/* This routine will power on the slot, configure the device(s) and find the
1041 * drivers for them.
1042 * Parameters: hotplug_slot
1043 * Returns: 0 or failure codes
1044 */
1045static int enable_slot(struct hotplug_slot *hs)
1046{
1047 int rc, i, rcpr;
1048 struct slot *slot_cur;
1049 u8 function;
1050 struct pci_func *tmp_func;
1051
1052 ibmphp_lock_operations();
1053
1054 debug("ENABLING SLOT........\n");
1055 slot_cur = hs->private;
1056
1057 if ((rc = validate(slot_cur, ENABLE))) {
1058 err("validate function failed\n");
1059 goto error_nopower;
1060 }
1061
1062 attn_LED_blink(slot_cur);
1063
1064 rc = set_bus(slot_cur);
1065 if (rc) {
1066 err("was not able to set the bus\n");
1067 goto error_nopower;
1068 }
1069
1070 /*-----------------debugging------------------------------*/
1071 get_cur_bus_info(&slot_cur);
1072 debug("the current bus speed right after set_bus = %x\n",
1073 slot_cur->bus_on->current_speed);
1074 /*----------------------------------------------------------*/
1075
1076 rc = check_limitations(slot_cur);
1077 if (rc) {
1078 err("Adding this card exceeds the limitations of this bus.\n");
1079 err("(i.e., >1 133MHz cards running on same bus, or "
1080 ">2 66 PCI cards running on same bus\n.");
1081 err("Try hot-adding into another bus\n");
1082 rc = -EINVAL;
1083 goto error_nopower;
1084 }
1085
1086 rc = power_on(slot_cur);
1087
1088 if (rc) {
1089 err("something wrong when powering up... please see below for details\n");
1090 /* need to turn off before on, otherwise, blinking overwrites */
1091 attn_off(slot_cur);
1092 attn_on(slot_cur);
1093 if (slot_update(&slot_cur)) {
1094 attn_off(slot_cur);
1095 attn_on(slot_cur);
1096 rc = -ENODEV;
1097 goto exit;
1098 }
1099 /* Check to see the error of why it failed */
1100 if ((SLOT_POWER(slot_cur->status)) &&
1101 !(SLOT_PWRGD(slot_cur->status)))
1102 err("power fault occurred trying to power up\n");
1103 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1104 err("bus speed mismatch occurred. please check "
1105 "current bus speed and card capability\n");
1106 print_card_capability(slot_cur);
1107 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1108 err("bus mode mismatch occurred. please check "
1109 "current bus mode and card capability\n");
1110 print_card_capability(slot_cur);
1111 }
1112 ibmphp_update_slot_info(slot_cur);
1113 goto exit;
1114 }
1115 debug("after power_on\n");
1116 /*-----------------------debugging---------------------------*/
1117 get_cur_bus_info(&slot_cur);
1118 debug("the current bus speed right after power_on = %x\n",
1119 slot_cur->bus_on->current_speed);
1120 /*----------------------------------------------------------*/
1121
1122 rc = slot_update(&slot_cur);
1123 if (rc)
1124 goto error_power;
1125
1126 rc = -EINVAL;
1127 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1128 err("power fault occurred trying to power up...\n");
1129 goto error_power;
1130 }
1131 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1132 err("bus speed mismatch occurred. please check current bus "
1133 "speed and card capability\n");
1134 print_card_capability(slot_cur);
1135 goto error_power;
1136 }
1137 /* Don't think this case will happen after above checks...
1138 * but just in case, for paranoia sake */
1139 if (!(SLOT_POWER(slot_cur->status))) {
1140 err("power on failed...\n");
1141 goto error_power;
1142 }
1143
1144 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1145 if (!slot_cur->func) {
1146 /* We cannot do update_slot_info here, since no memory for
1147 * kmalloc n.e.ways, and update_slot_info allocates some */
1148 err("out of system memory\n");
1149 rc = -ENOMEM;
1150 goto error_power;
1151 }
1152 memset(slot_cur->func, 0, sizeof(struct pci_func));
1153 slot_cur->func->busno = slot_cur->bus;
1154 slot_cur->func->device = slot_cur->device;
1155 for (i = 0; i < 4; i++)
1156 slot_cur->func->irq[i] = slot_cur->irq[i];
1157
1158 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1159 slot_cur->bus, slot_cur->device);
1160
1161 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1162 err("configure_card was unsuccessful...\n");
1163 /* true because don't need to actually deallocate resources,
1164 * just remove references */
1165 ibmphp_unconfigure_card(&slot_cur, 1);
1166 debug("after unconfigure_card\n");
1167 slot_cur->func = NULL;
1168 rc = -ENOMEM;
1169 goto error_power;
1170 }
1171
1172 function = 0x00;
1173 do {
1174 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1175 function++);
1176 if (tmp_func && !(tmp_func->dev))
1177 ibm_configure_device(tmp_func);
1178 } while (tmp_func);
1179
1180 attn_off(slot_cur);
1181 if (slot_update(&slot_cur)) {
1182 rc = -EFAULT;
1183 goto exit;
1184 }
1185 ibmphp_print_test();
1186 rc = ibmphp_update_slot_info(slot_cur);
1187exit:
1188 ibmphp_unlock_operations();
1189 return rc;
1190
1191error_nopower:
1192 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1193 attn_on(slot_cur);
1194error_cont:
1195 rcpr = slot_update(&slot_cur);
1196 if (rcpr) {
1197 rc = rcpr;
1198 goto exit;
1199 }
1200 ibmphp_update_slot_info(slot_cur);
1201 goto exit;
1202
1203error_power:
1204 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1205 attn_on(slot_cur);
1206 rcpr = power_off(slot_cur);
1207 if (rcpr) {
1208 rc = rcpr;
1209 goto exit;
1210 }
1211 goto error_cont;
1212}
1213
1214/**************************************************************
1215* HOT REMOVING ADAPTER CARD *
1216* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE *
1217* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE *
1218 DISABLE POWER , *
1219**************************************************************/
1220static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1221{
1222 struct slot *slot = hotplug_slot->private;
1223 int rc;
1224
1225 ibmphp_lock_operations();
1226 rc = ibmphp_do_disable_slot(slot);
1227 ibmphp_unlock_operations();
1228 return rc;
1229}
1230
1231int ibmphp_do_disable_slot(struct slot *slot_cur)
1232{
1233 int rc;
1234 u8 flag;
1235
1236 debug("DISABLING SLOT...\n");
1237
1238 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1239 return -ENODEV;
1240 }
1241
1242 flag = slot_cur->flag;
1243 slot_cur->flag = TRUE;
1244
1245 if (flag == TRUE) {
1246 rc = validate(slot_cur, DISABLE);
1247 /* checking if powered off already & valid slot # */
1248 if (rc)
1249 goto error;
1250 }
1251 attn_LED_blink(slot_cur);
1252
1253 if (slot_cur->func == NULL) {
1254 /* We need this for fncs's that were there on bootup */
1255 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1256 if (!slot_cur->func) {
1257 err("out of system memory\n");
1258 rc = -ENOMEM;
1259 goto error;
1260 }
1261 memset(slot_cur->func, 0, sizeof(struct pci_func));
1262 slot_cur->func->busno = slot_cur->bus;
1263 slot_cur->func->device = slot_cur->device;
1264 }
1265
1266 ibm_unconfigure_device(slot_cur->func);
1267
1268 /* If we got here from latch suddenly opening on operating card or
1269 a power fault, there's no power to the card, so cannot
1270 read from it to determine what resources it occupied. This operation
1271 is forbidden anyhow. The best we can do is remove it from kernel
1272 lists at least */
1273
1274 if (!flag) {
1275 attn_off(slot_cur);
1276 return 0;
1277 }
1278
1279 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1280 slot_cur->func = NULL;
1281 debug("in disable_slot. after unconfigure_card\n");
1282 if (rc) {
1283 err("could not unconfigure card.\n");
1284 goto error;
1285 }
1286
1287 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1288 if (rc)
1289 goto error;
1290
1291 attn_off(slot_cur);
1292 rc = slot_update(&slot_cur);
1293 if (rc)
1294 goto exit;
1295
1296 rc = ibmphp_update_slot_info(slot_cur);
1297 ibmphp_print_test();
1298exit:
1299 return rc;
1300
1301error:
1302 /* Need to turn off if was blinking b4 */
1303 attn_off(slot_cur);
1304 attn_on(slot_cur);
1305 if (slot_update(&slot_cur)) {
1306 rc = -EFAULT;
1307 goto exit;
1308 }
1309 if (flag)
1310 ibmphp_update_slot_info(slot_cur);
1311 goto exit;
1312}
1313
1314struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1315 .owner = THIS_MODULE,
1316 .set_attention_status = set_attention_status,
1317 .enable_slot = enable_slot,
1318 .disable_slot = ibmphp_disable_slot,
1319 .hardware_test = NULL,
1320 .get_power_status = get_power_status,
1321 .get_attention_status = get_attention_status,
1322 .get_latch_status = get_latch_status,
1323 .get_adapter_status = get_adapter_present,
1324 .get_max_bus_speed = get_max_bus_speed,
1325 .get_cur_bus_speed = get_cur_bus_speed,
1326/* .get_max_adapter_speed = get_max_adapter_speed,
1327 .get_bus_name_status = get_bus_name,
1328*/
1329};
1330
1331static void ibmphp_unload(void)
1332{
1333 free_slots();
1334 debug("after slots\n");
1335 ibmphp_free_resources();
1336 debug("after resources\n");
1337 ibmphp_free_bus_info_queue();
1338 debug("after bus info\n");
1339 ibmphp_free_ebda_hpc_queue();
1340 debug("after ebda hpc\n");
1341 ibmphp_free_ebda_pci_rsrc_queue();
1342 debug("after ebda pci rsrc\n");
1343 kfree(ibmphp_pci_bus);
1344}
1345
1346static int __init ibmphp_init(void)
1347{
1348 struct pci_bus *bus;
1349 int i = 0;
1350 int rc = 0;
1351
1352 init_flag = 1;
1353
1354 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1355
1356 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1357 if (!ibmphp_pci_bus) {
1358 err("out of memory\n");
1359 rc = -ENOMEM;
1360 goto exit;
1361 }
1362
1363 bus = pci_find_bus(0, 0);
1364 if (!bus) {
1365 err("Can't find the root pci bus, can not continue\n");
1366 rc = -ENODEV;
1367 goto error;
1368 }
1369 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1370
1371 ibmphp_debug = debug;
1372
1373 ibmphp_hpc_initvars();
1374
1375 for (i = 0; i < 16; i++)
1376 irqs[i] = 0;
1377
1378 if ((rc = ibmphp_access_ebda()))
1379 goto error;
1380 debug("after ibmphp_access_ebda()\n");
1381
1382 if ((rc = ibmphp_rsrc_init()))
1383 goto error;
1384 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1385
1386 max_slots = get_max_slots();
1387
1388 if ((rc = ibmphp_register_pci()))
1389 goto error;
1390
1391 if (init_ops()) {
1392 rc = -ENODEV;
1393 goto error;
1394 }
1395
1396 ibmphp_print_test();
1397 if ((rc = ibmphp_hpc_start_poll_thread())) {
1398 goto error;
1399 }
1400
1401 /* lock ourselves into memory with a module
1402 * count of -1 so that no one can unload us. */
1403 module_put(THIS_MODULE);
1404
1405exit:
1406 return rc;
1407
1408error:
1409 ibmphp_unload();
1410 goto exit;
1411}
1412
1413static void __exit ibmphp_exit(void)
1414{
1415 ibmphp_hpc_stop_poll_thread();
1416 debug("after polling\n");
1417 ibmphp_unload();
1418 debug("done\n");
1419}
1420
1421module_init(ibmphp_init);
1422module_exit(ibmphp_exit);
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
new file mode 100644
index 000000000000..aea1187c73ad
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -0,0 +1,1275 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Tong Yu, IBM Corporation
5 *
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
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 <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/sched.h>
32#include <linux/errno.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <linux/pci.h>
36#include <linux/list.h>
37#include <linux/init.h>
38#include "ibmphp.h"
39
40/*
41 * POST builds data blocks(in this data block definition, a char-1
42 * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
43 * BIOS Data Area which describe the configuration of the hot-plug
44 * controllers and resources used by the PCI Hot-Plug devices.
45 *
46 * This file walks EBDA, maps data block from physical addr,
47 * reconstruct linked lists about all system resource(MEM, PFM, IO)
48 * already assigned by POST, as well as linked lists about hot plug
49 * controllers (ctlr#, slot#, bus&slot features...)
50 */
51
52/* Global lists */
53LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
54LIST_HEAD (ibmphp_slot_head);
55
56/* Local variables */
57static struct ebda_hpc_list *hpc_list_ptr;
58static struct ebda_rsrc_list *rsrc_list_ptr;
59static struct rio_table_hdr *rio_table_ptr = NULL;
60static LIST_HEAD (ebda_hpc_head);
61static LIST_HEAD (bus_info_head);
62static LIST_HEAD (rio_vg_head);
63static LIST_HEAD (rio_lo_head);
64static LIST_HEAD (opt_vg_head);
65static LIST_HEAD (opt_lo_head);
66static void __iomem *io_mem;
67
68/* Local functions */
69static int ebda_rsrc_controller (void);
70static int ebda_rsrc_rsrc (void);
71static int ebda_rio_table (void);
72
73static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
74{
75 struct ebda_hpc_list *list;
76
77 list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
78 if (!list)
79 return NULL;
80 memset (list, 0, sizeof (*list));
81 return list;
82}
83
84static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
85{
86 struct controller *controller;
87 struct ebda_hpc_slot *slots;
88 struct ebda_hpc_bus *buses;
89
90 controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
91 if (!controller)
92 goto error;
93 memset (controller, 0, sizeof (*controller));
94
95 slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
96 if (!slots)
97 goto error_contr;
98 memset (slots, 0, sizeof (*slots) * slot_count);
99 controller->slots = slots;
100
101 buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
102 if (!buses)
103 goto error_slots;
104 memset (buses, 0, sizeof (*buses) * bus_count);
105 controller->buses = buses;
106
107 return controller;
108error_slots:
109 kfree(controller->slots);
110error_contr:
111 kfree(controller);
112error:
113 return NULL;
114}
115
116static void free_ebda_hpc (struct controller *controller)
117{
118 kfree (controller->slots);
119 kfree (controller->buses);
120 kfree (controller);
121}
122
123static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
124{
125 struct ebda_rsrc_list *list;
126
127 list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
128 if (!list)
129 return NULL;
130 memset (list, 0, sizeof (*list));
131 return list;
132}
133
134static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
135{
136 struct ebda_pci_rsrc *resource;
137
138 resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
139 if (!resource)
140 return NULL;
141 memset (resource, 0, sizeof (*resource));
142 return resource;
143}
144
145static void __init print_bus_info (void)
146{
147 struct bus_info *ptr;
148 struct list_head *ptr1;
149
150 list_for_each (ptr1, &bus_info_head) {
151 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
152 debug ("%s - slot_min = %x\n", __FUNCTION__, ptr->slot_min);
153 debug ("%s - slot_max = %x\n", __FUNCTION__, ptr->slot_max);
154 debug ("%s - slot_count = %x\n", __FUNCTION__, ptr->slot_count);
155 debug ("%s - bus# = %x\n", __FUNCTION__, ptr->busno);
156 debug ("%s - current_speed = %x\n", __FUNCTION__, ptr->current_speed);
157 debug ("%s - controller_id = %x\n", __FUNCTION__, ptr->controller_id);
158
159 debug ("%s - slots_at_33_conv = %x\n", __FUNCTION__, ptr->slots_at_33_conv);
160 debug ("%s - slots_at_66_conv = %x\n", __FUNCTION__, ptr->slots_at_66_conv);
161 debug ("%s - slots_at_66_pcix = %x\n", __FUNCTION__, ptr->slots_at_66_pcix);
162 debug ("%s - slots_at_100_pcix = %x\n", __FUNCTION__, ptr->slots_at_100_pcix);
163 debug ("%s - slots_at_133_pcix = %x\n", __FUNCTION__, ptr->slots_at_133_pcix);
164
165 }
166}
167
168static void print_lo_info (void)
169{
170 struct rio_detail *ptr;
171 struct list_head *ptr1;
172 debug ("print_lo_info ----\n");
173 list_for_each (ptr1, &rio_lo_head) {
174 ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
175 debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
176 debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
177 debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
178 debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
179 debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
180 debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
181
182 }
183}
184
185static void print_vg_info (void)
186{
187 struct rio_detail *ptr;
188 struct list_head *ptr1;
189 debug ("%s ---\n", __FUNCTION__);
190 list_for_each (ptr1, &rio_vg_head) {
191 ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
192 debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
193 debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
194 debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
195 debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
196 debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
197 debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
198
199 }
200}
201
202static void __init print_ebda_pci_rsrc (void)
203{
204 struct ebda_pci_rsrc *ptr;
205 struct list_head *ptr1;
206
207 list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
208 ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
209 debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
210 __FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
211 }
212}
213
214static void __init print_ibm_slot (void)
215{
216 struct slot *ptr;
217 struct list_head *ptr1;
218
219 list_for_each (ptr1, &ibmphp_slot_head) {
220 ptr = list_entry (ptr1, struct slot, ibm_slot_list);
221 debug ("%s - slot_number: %x\n", __FUNCTION__, ptr->number);
222 }
223}
224
225static void __init print_opt_vg (void)
226{
227 struct opt_rio *ptr;
228 struct list_head *ptr1;
229 debug ("%s ---\n", __FUNCTION__);
230 list_for_each (ptr1, &opt_vg_head) {
231 ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
232 debug ("%s - rio_type %x\n", __FUNCTION__, ptr->rio_type);
233 debug ("%s - chassis_num: %x\n", __FUNCTION__, ptr->chassis_num);
234 debug ("%s - first_slot_num: %x\n", __FUNCTION__, ptr->first_slot_num);
235 debug ("%s - middle_num: %x\n", __FUNCTION__, ptr->middle_num);
236 }
237}
238
239static void __init print_ebda_hpc (void)
240{
241 struct controller *hpc_ptr;
242 struct list_head *ptr1;
243 u16 index;
244
245 list_for_each (ptr1, &ebda_hpc_head) {
246
247 hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list);
248
249 for (index = 0; index < hpc_ptr->slot_count; index++) {
250 debug ("%s - physical slot#: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_num);
251 debug ("%s - pci bus# of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_bus_num);
252 debug ("%s - index into ctlr addr: %x\n", __FUNCTION__, hpc_ptr->slots[index].ctl_index);
253 debug ("%s - cap of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_cap);
254 }
255
256 for (index = 0; index < hpc_ptr->bus_count; index++) {
257 debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __FUNCTION__, hpc_ptr->buses[index].bus_num);
258 }
259
260 debug ("%s - type of hpc: %x\n", __FUNCTION__, hpc_ptr->ctlr_type);
261 switch (hpc_ptr->ctlr_type) {
262 case 1:
263 debug ("%s - bus: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.bus);
264 debug ("%s - dev_fun: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.dev_fun);
265 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
266 break;
267
268 case 0:
269 debug ("%s - io_start: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_start);
270 debug ("%s - io_end: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_end);
271 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
272 break;
273
274 case 2:
275 case 4:
276 debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
277 debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
278 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
279 break;
280 }
281 }
282}
283
284int __init ibmphp_access_ebda (void)
285{
286 u8 format, num_ctlrs, rio_complete, hs_complete;
287 u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
288 int rc = 0;
289
290
291 rio_complete = 0;
292 hs_complete = 0;
293
294 io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
295 if (!io_mem )
296 return -ENOMEM;
297 ebda_seg = readw (io_mem);
298 iounmap (io_mem);
299 debug ("returned ebda segment: %x\n", ebda_seg);
300
301 io_mem = ioremap (ebda_seg<<4, 65000);
302 if (!io_mem )
303 return -ENOMEM;
304 next_offset = 0x180;
305
306 for (;;) {
307 offset = next_offset;
308 next_offset = readw (io_mem + offset); /* offset of next blk */
309
310 offset += 2;
311 if (next_offset == 0) /* 0 indicate it's last blk */
312 break;
313 blk_id = readw (io_mem + offset); /* this blk id */
314
315 offset += 2;
316 /* check if it is hot swap block or rio block */
317 if (blk_id != 0x4853 && blk_id != 0x4752)
318 continue;
319 /* found hs table */
320 if (blk_id == 0x4853) {
321 debug ("now enter hot swap block---\n");
322 debug ("hot blk id: %x\n", blk_id);
323 format = readb (io_mem + offset);
324
325 offset += 1;
326 if (format != 4)
327 goto error_nodev;
328 debug ("hot blk format: %x\n", format);
329 /* hot swap sub blk */
330 base = offset;
331
332 sub_addr = base;
333 re = readw (io_mem + sub_addr); /* next sub blk */
334
335 sub_addr += 2;
336 rc_id = readw (io_mem + sub_addr); /* sub blk id */
337
338 sub_addr += 2;
339 if (rc_id != 0x5243)
340 goto error_nodev;
341 /* rc sub blk signature */
342 num_ctlrs = readb (io_mem + sub_addr);
343
344 sub_addr += 1;
345 hpc_list_ptr = alloc_ebda_hpc_list ();
346 if (!hpc_list_ptr) {
347 rc = -ENOMEM;
348 goto out;
349 }
350 hpc_list_ptr->format = format;
351 hpc_list_ptr->num_ctlrs = num_ctlrs;
352 hpc_list_ptr->phys_addr = sub_addr; /* offset of RSRC_CONTROLLER blk */
353 debug ("info about hpc descriptor---\n");
354 debug ("hot blk format: %x\n", format);
355 debug ("num of controller: %x\n", num_ctlrs);
356 debug ("offset of hpc data structure enteries: %x\n ", sub_addr);
357
358 sub_addr = base + re; /* re sub blk */
359 /* FIXME: rc is never used/checked */
360 rc = readw (io_mem + sub_addr); /* next sub blk */
361
362 sub_addr += 2;
363 re_id = readw (io_mem + sub_addr); /* sub blk id */
364
365 sub_addr += 2;
366 if (re_id != 0x5245)
367 goto error_nodev;
368
369 /* signature of re */
370 num_entries = readw (io_mem + sub_addr);
371
372 sub_addr += 2; /* offset of RSRC_ENTRIES blk */
373 rsrc_list_ptr = alloc_ebda_rsrc_list ();
374 if (!rsrc_list_ptr ) {
375 rc = -ENOMEM;
376 goto out;
377 }
378 rsrc_list_ptr->format = format;
379 rsrc_list_ptr->num_entries = num_entries;
380 rsrc_list_ptr->phys_addr = sub_addr;
381
382 debug ("info about rsrc descriptor---\n");
383 debug ("format: %x\n", format);
384 debug ("num of rsrc: %x\n", num_entries);
385 debug ("offset of rsrc data structure enteries: %x\n ", sub_addr);
386
387 hs_complete = 1;
388 } else {
389 /* found rio table, blk_id == 0x4752 */
390 debug ("now enter io table ---\n");
391 debug ("rio blk id: %x\n", blk_id);
392
393 rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
394 if (!rio_table_ptr)
395 return -ENOMEM;
396 memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
397 rio_table_ptr->ver_num = readb (io_mem + offset);
398 rio_table_ptr->scal_count = readb (io_mem + offset + 1);
399 rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
400 rio_table_ptr->offset = offset +3 ;
401
402 debug("info about rio table hdr ---\n");
403 debug("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ",
404 rio_table_ptr->ver_num, rio_table_ptr->scal_count,
405 rio_table_ptr->riodev_count, rio_table_ptr->offset);
406
407 rio_complete = 1;
408 }
409 }
410
411 if (!hs_complete && !rio_complete)
412 goto error_nodev;
413
414 if (rio_table_ptr) {
415 if (rio_complete && rio_table_ptr->ver_num == 3) {
416 rc = ebda_rio_table ();
417 if (rc)
418 goto out;
419 }
420 }
421 rc = ebda_rsrc_controller ();
422 if (rc)
423 goto out;
424
425 rc = ebda_rsrc_rsrc ();
426 goto out;
427error_nodev:
428 rc = -ENODEV;
429out:
430 iounmap (io_mem);
431 return rc;
432}
433
434/*
435 * map info of scalability details and rio details from physical address
436 */
437static int __init ebda_rio_table (void)
438{
439 u16 offset;
440 u8 i;
441 struct rio_detail *rio_detail_ptr;
442
443 offset = rio_table_ptr->offset;
444 offset += 12 * rio_table_ptr->scal_count;
445
446 // we do concern about rio details
447 for (i = 0; i < rio_table_ptr->riodev_count; i++) {
448 rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
449 if (!rio_detail_ptr)
450 return -ENOMEM;
451 memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
452 rio_detail_ptr->rio_node_id = readb (io_mem + offset);
453 rio_detail_ptr->bbar = readl (io_mem + offset + 1);
454 rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
455 rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
456 rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
457 rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
458 rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
459 rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
460 rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
461 rio_detail_ptr->status = readb (io_mem + offset + 12);
462 rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
463 rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
464// debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
465 //create linked list of chassis
466 if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
467 list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
468 //create linked list of expansion box
469 else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
470 list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
471 else
472 // not in my concern
473 kfree (rio_detail_ptr);
474 offset += 15;
475 }
476 print_lo_info ();
477 print_vg_info ();
478 return 0;
479}
480
481/*
482 * reorganizing linked list of chassis
483 */
484static struct opt_rio *search_opt_vg (u8 chassis_num)
485{
486 struct opt_rio *ptr;
487 struct list_head *ptr1;
488 list_for_each (ptr1, &opt_vg_head) {
489 ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
490 if (ptr->chassis_num == chassis_num)
491 return ptr;
492 }
493 return NULL;
494}
495
496static int __init combine_wpg_for_chassis (void)
497{
498 struct opt_rio *opt_rio_ptr = NULL;
499 struct rio_detail *rio_detail_ptr = NULL;
500 struct list_head *list_head_ptr = NULL;
501
502 list_for_each (list_head_ptr, &rio_vg_head) {
503 rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
504 opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
505 if (!opt_rio_ptr) {
506 opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
507 if (!opt_rio_ptr)
508 return -ENOMEM;
509 memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
510 opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
511 opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
512 opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
513 opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
514 list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
515 } else {
516 opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
517 opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
518 }
519 }
520 print_opt_vg ();
521 return 0;
522}
523
524/*
525 * reorgnizing linked list of expansion box
526 */
527static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
528{
529 struct opt_rio_lo *ptr;
530 struct list_head *ptr1;
531 list_for_each (ptr1, &opt_lo_head) {
532 ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
533 if (ptr->chassis_num == chassis_num)
534 return ptr;
535 }
536 return NULL;
537}
538
539static int combine_wpg_for_expansion (void)
540{
541 struct opt_rio_lo *opt_rio_lo_ptr = NULL;
542 struct rio_detail *rio_detail_ptr = NULL;
543 struct list_head *list_head_ptr = NULL;
544
545 list_for_each (list_head_ptr, &rio_lo_head) {
546 rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
547 opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
548 if (!opt_rio_lo_ptr) {
549 opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
550 if (!opt_rio_lo_ptr)
551 return -ENOMEM;
552 memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
553 opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
554 opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
555 opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
556 opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
557 opt_rio_lo_ptr->pack_count = 1;
558
559 list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
560 } else {
561 opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
562 opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
563 opt_rio_lo_ptr->pack_count = 2;
564 }
565 }
566 return 0;
567}
568
569
570/* Since we don't know the max slot number per each chassis, hence go
571 * through the list of all chassis to find out the range
572 * Arguments: slot_num, 1st slot number of the chassis we think we are on,
573 * var (0 = chassis, 1 = expansion box)
574 */
575static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
576{
577 struct opt_rio *opt_vg_ptr = NULL;
578 struct opt_rio_lo *opt_lo_ptr = NULL;
579 struct list_head *ptr = NULL;
580 int rc = 0;
581
582 if (!var) {
583 list_for_each (ptr, &opt_vg_head) {
584 opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
585 if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
586 rc = -ENODEV;
587 break;
588 }
589 }
590 } else {
591 list_for_each (ptr, &opt_lo_head) {
592 opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
593 if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
594 rc = -ENODEV;
595 break;
596 }
597 }
598 }
599 return rc;
600}
601
602static struct opt_rio_lo * find_rxe_num (u8 slot_num)
603{
604 struct opt_rio_lo *opt_lo_ptr;
605 struct list_head *ptr;
606
607 list_for_each (ptr, &opt_lo_head) {
608 opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
609 //check to see if this slot_num belongs to expansion box
610 if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
611 return opt_lo_ptr;
612 }
613 return NULL;
614}
615
616static struct opt_rio * find_chassis_num (u8 slot_num)
617{
618 struct opt_rio *opt_vg_ptr;
619 struct list_head *ptr;
620
621 list_for_each (ptr, &opt_vg_head) {
622 opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
623 //check to see if this slot_num belongs to chassis
624 if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
625 return opt_vg_ptr;
626 }
627 return NULL;
628}
629
630/* This routine will find out how many slots are in the chassis, so that
631 * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
632 */
633static u8 calculate_first_slot (u8 slot_num)
634{
635 u8 first_slot = 1;
636 struct list_head * list;
637 struct slot * slot_cur;
638
639 list_for_each (list, &ibmphp_slot_head) {
640 slot_cur = list_entry (list, struct slot, ibm_slot_list);
641 if (slot_cur->ctrl) {
642 if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
643 first_slot = slot_cur->ctrl->ending_slot_num;
644 }
645 }
646 return first_slot + 1;
647
648}
649static char *create_file_name (struct slot * slot_cur)
650{
651 struct opt_rio *opt_vg_ptr = NULL;
652 struct opt_rio_lo *opt_lo_ptr = NULL;
653 static char str[30];
654 int which = 0; /* rxe = 1, chassis = 0 */
655 u8 number = 1; /* either chassis or rxe # */
656 u8 first_slot = 1;
657 u8 slot_num;
658 u8 flag = 0;
659
660 if (!slot_cur) {
661 err ("Structure passed is empty\n");
662 return NULL;
663 }
664
665 slot_num = slot_cur->number;
666
667 memset (str, 0, sizeof(str));
668
669 if (rio_table_ptr) {
670 if (rio_table_ptr->ver_num == 3) {
671 opt_vg_ptr = find_chassis_num (slot_num);
672 opt_lo_ptr = find_rxe_num (slot_num);
673 }
674 }
675 if (opt_vg_ptr) {
676 if (opt_lo_ptr) {
677 if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
678 number = opt_lo_ptr->chassis_num;
679 first_slot = opt_lo_ptr->first_slot_num;
680 which = 1; /* it is RXE */
681 } else {
682 first_slot = opt_vg_ptr->first_slot_num;
683 number = opt_vg_ptr->chassis_num;
684 which = 0;
685 }
686 } else {
687 first_slot = opt_vg_ptr->first_slot_num;
688 number = opt_vg_ptr->chassis_num;
689 which = 0;
690 }
691 ++flag;
692 } else if (opt_lo_ptr) {
693 number = opt_lo_ptr->chassis_num;
694 first_slot = opt_lo_ptr->first_slot_num;
695 which = 1;
696 ++flag;
697 } else if (rio_table_ptr) {
698 if (rio_table_ptr->ver_num == 3) {
699 /* if both NULL and we DO have correct RIO table in BIOS */
700 return NULL;
701 }
702 }
703 if (!flag) {
704 if (slot_cur->ctrl->ctlr_type == 4) {
705 first_slot = calculate_first_slot (slot_num);
706 which = 1;
707 } else {
708 which = 0;
709 }
710 }
711
712 sprintf(str, "%s%dslot%d",
713 which == 0 ? "chassis" : "rxe",
714 number, slot_num - first_slot + 1);
715 return str;
716}
717
718static int fillslotinfo(struct hotplug_slot *hotplug_slot)
719{
720 struct slot *slot;
721 int rc = 0;
722
723 if (!hotplug_slot || !hotplug_slot->private)
724 return -EINVAL;
725
726 slot = hotplug_slot->private;
727 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL);
728 if (rc)
729 return rc;
730
731 // power - enabled:1 not:0
732 hotplug_slot->info->power_status = SLOT_POWER(slot->status);
733
734 // attention - off:0, on:1, blinking:2
735 hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status);
736
737 // latch - open:1 closed:0
738 hotplug_slot->info->latch_status = SLOT_LATCH(slot->status);
739
740 // pci board - present:1 not:0
741 if (SLOT_PRESENT (slot->status))
742 hotplug_slot->info->adapter_status = 1;
743 else
744 hotplug_slot->info->adapter_status = 0;
745/*
746 if (slot->bus_on->supported_bus_mode
747 && (slot->bus_on->supported_speed == BUS_SPEED_66))
748 hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
749 else
750 hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed;
751*/
752
753 return rc;
754}
755
756static void release_slot(struct hotplug_slot *hotplug_slot)
757{
758 struct slot *slot;
759
760 if (!hotplug_slot || !hotplug_slot->private)
761 return;
762
763 slot = hotplug_slot->private;
764 kfree(slot->hotplug_slot->info);
765 kfree(slot->hotplug_slot->name);
766 kfree(slot->hotplug_slot);
767 slot->ctrl = NULL;
768 slot->bus_on = NULL;
769
770 /* we don't want to actually remove the resources, since free_resources will do just that */
771 ibmphp_unconfigure_card(&slot, -1);
772
773 kfree (slot);
774}
775
776static struct pci_driver ibmphp_driver;
777
778/*
779 * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
780 * each hpc from physical address to a list of hot plug controllers based on
781 * hpc descriptors.
782 */
783static int __init ebda_rsrc_controller (void)
784{
785 u16 addr, addr_slot, addr_bus;
786 u8 ctlr_id, temp, bus_index;
787 u16 ctlr, slot, bus;
788 u16 slot_num, bus_num, index;
789 struct hotplug_slot *hp_slot_ptr;
790 struct controller *hpc_ptr;
791 struct ebda_hpc_bus *bus_ptr;
792 struct ebda_hpc_slot *slot_ptr;
793 struct bus_info *bus_info_ptr1, *bus_info_ptr2;
794 int rc;
795 struct slot *tmp_slot;
796 struct list_head *list;
797
798 addr = hpc_list_ptr->phys_addr;
799 for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
800 bus_index = 1;
801 ctlr_id = readb (io_mem + addr);
802 addr += 1;
803 slot_num = readb (io_mem + addr);
804
805 addr += 1;
806 addr_slot = addr; /* offset of slot structure */
807 addr += (slot_num * 4);
808
809 bus_num = readb (io_mem + addr);
810
811 addr += 1;
812 addr_bus = addr; /* offset of bus */
813 addr += (bus_num * 9); /* offset of ctlr_type */
814 temp = readb (io_mem + addr);
815
816 addr += 1;
817 /* init hpc structure */
818 hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
819 if (!hpc_ptr ) {
820 rc = -ENOMEM;
821 goto error_no_hpc;
822 }
823 hpc_ptr->ctlr_id = ctlr_id;
824 hpc_ptr->ctlr_relative_id = ctlr;
825 hpc_ptr->slot_count = slot_num;
826 hpc_ptr->bus_count = bus_num;
827 debug ("now enter ctlr data struture ---\n");
828 debug ("ctlr id: %x\n", ctlr_id);
829 debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
830 debug ("count of slots controlled by this ctlr: %x\n", slot_num);
831 debug ("count of buses controlled by this ctlr: %x\n", bus_num);
832
833 /* init slot structure, fetch slot, bus, cap... */
834 slot_ptr = hpc_ptr->slots;
835 for (slot = 0; slot < slot_num; slot++) {
836 slot_ptr->slot_num = readb (io_mem + addr_slot);
837 slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
838 slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
839 slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
840
841 // create bus_info lined list --- if only one slot per bus: slot_min = slot_max
842
843 bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
844 if (!bus_info_ptr2) {
845 bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
846 if (!bus_info_ptr1) {
847 rc = -ENOMEM;
848 goto error_no_hp_slot;
849 }
850 memset (bus_info_ptr1, 0, sizeof (struct bus_info));
851 bus_info_ptr1->slot_min = slot_ptr->slot_num;
852 bus_info_ptr1->slot_max = slot_ptr->slot_num;
853 bus_info_ptr1->slot_count += 1;
854 bus_info_ptr1->busno = slot_ptr->slot_bus_num;
855 bus_info_ptr1->index = bus_index++;
856 bus_info_ptr1->current_speed = 0xff;
857 bus_info_ptr1->current_bus_mode = 0xff;
858
859 bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
860
861 list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
862
863 } else {
864 bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
865 bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
866 bus_info_ptr2->slot_count += 1;
867
868 }
869
870 // end of creating the bus_info linked list
871
872 slot_ptr++;
873 addr_slot += 1;
874 }
875
876 /* init bus structure */
877 bus_ptr = hpc_ptr->buses;
878 for (bus = 0; bus < bus_num; bus++) {
879 bus_ptr->bus_num = readb (io_mem + addr_bus + bus);
880 bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus);
881 bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1);
882
883 bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2);
884
885 bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3);
886
887 bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4);
888
889 bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num);
890 if (bus_info_ptr2) {
891 bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
892 bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
893 bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
894 bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
895 bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;
896 }
897 bus_ptr++;
898 }
899
900 hpc_ptr->ctlr_type = temp;
901
902 switch (hpc_ptr->ctlr_type) {
903 case 1:
904 hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
905 hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
906 hpc_ptr->irq = readb (io_mem + addr + 2);
907 addr += 3;
908 debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
909 hpc_ptr->u.pci_ctlr.bus,
910 hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
911 break;
912
913 case 0:
914 hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
915 hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
916 if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
917 (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
918 "ibmphp")) {
919 rc = -ENODEV;
920 goto error_no_hp_slot;
921 }
922 hpc_ptr->irq = readb (io_mem + addr + 4);
923 addr += 5;
924 break;
925
926 case 2:
927 case 4:
928 hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
929 hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
930 hpc_ptr->irq = readb (io_mem + addr + 5);
931 addr += 6;
932 break;
933 default:
934 rc = -ENODEV;
935 goto error_no_hp_slot;
936 }
937
938 //reorganize chassis' linked list
939 combine_wpg_for_chassis ();
940 combine_wpg_for_expansion ();
941 hpc_ptr->revision = 0xff;
942 hpc_ptr->options = 0xff;
943 hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
944 hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;
945
946 // register slots with hpc core as well as create linked list of ibm slot
947 for (index = 0; index < hpc_ptr->slot_count; index++) {
948
949 hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
950 if (!hp_slot_ptr) {
951 rc = -ENOMEM;
952 goto error_no_hp_slot;
953 }
954 memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr));
955
956 hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL);
957 if (!hp_slot_ptr->info) {
958 rc = -ENOMEM;
959 goto error_no_hp_info;
960 }
961 memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info));
962
963 hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
964 if (!hp_slot_ptr->name) {
965 rc = -ENOMEM;
966 goto error_no_hp_name;
967 }
968
969 tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL);
970 if (!tmp_slot) {
971 rc = -ENOMEM;
972 goto error_no_slot;
973 }
974 memset(tmp_slot, 0, sizeof(*tmp_slot));
975
976 tmp_slot->flag = TRUE;
977
978 tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
979 if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
980 tmp_slot->supported_speed = 3;
981 else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
982 tmp_slot->supported_speed = 2;
983 else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
984 tmp_slot->supported_speed = 1;
985
986 if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
987 tmp_slot->supported_bus_mode = 1;
988 else
989 tmp_slot->supported_bus_mode = 0;
990
991
992 tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
993
994 bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
995 if (!bus_info_ptr1) {
996 rc = -ENODEV;
997 goto error;
998 }
999 tmp_slot->bus_on = bus_info_ptr1;
1000 bus_info_ptr1 = NULL;
1001 tmp_slot->ctrl = hpc_ptr;
1002
1003 tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
1004 tmp_slot->number = hpc_ptr->slots[index].slot_num;
1005 tmp_slot->hotplug_slot = hp_slot_ptr;
1006
1007 hp_slot_ptr->private = tmp_slot;
1008 hp_slot_ptr->release = release_slot;
1009
1010 rc = fillslotinfo(hp_slot_ptr);
1011 if (rc)
1012 goto error;
1013
1014 rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
1015 if (rc)
1016 goto error;
1017 hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
1018
1019 // end of registering ibm slot with hotplug core
1020
1021 list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
1022 }
1023
1024 print_bus_info ();
1025 list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
1026
1027 } /* each hpc */
1028
1029 list_for_each (list, &ibmphp_slot_head) {
1030 tmp_slot = list_entry (list, struct slot, ibm_slot_list);
1031
1032 snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
1033 pci_hp_register (tmp_slot->hotplug_slot);
1034 }
1035
1036 print_ebda_hpc ();
1037 print_ibm_slot ();
1038 return 0;
1039
1040error:
1041 kfree (hp_slot_ptr->private);
1042error_no_slot:
1043 kfree (hp_slot_ptr->name);
1044error_no_hp_name:
1045 kfree (hp_slot_ptr->info);
1046error_no_hp_info:
1047 kfree (hp_slot_ptr);
1048error_no_hp_slot:
1049 free_ebda_hpc (hpc_ptr);
1050error_no_hpc:
1051 iounmap (io_mem);
1052 return rc;
1053}
1054
1055/*
1056 * map info (bus, devfun, start addr, end addr..) of i/o, memory,
1057 * pfm from the physical addr to a list of resource.
1058 */
1059static int __init ebda_rsrc_rsrc (void)
1060{
1061 u16 addr;
1062 short rsrc;
1063 u8 type, rsrc_type;
1064 struct ebda_pci_rsrc *rsrc_ptr;
1065
1066 addr = rsrc_list_ptr->phys_addr;
1067 debug ("now entering rsrc land\n");
1068 debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
1069
1070 for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
1071 type = readb (io_mem + addr);
1072
1073 addr += 1;
1074 rsrc_type = type & EBDA_RSRC_TYPE_MASK;
1075
1076 if (rsrc_type == EBDA_IO_RSRC_TYPE) {
1077 rsrc_ptr = alloc_ebda_pci_rsrc ();
1078 if (!rsrc_ptr) {
1079 iounmap (io_mem);
1080 return -ENOMEM;
1081 }
1082 rsrc_ptr->rsrc_type = type;
1083
1084 rsrc_ptr->bus_num = readb (io_mem + addr);
1085 rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
1086 rsrc_ptr->start_addr = readw (io_mem + addr + 2);
1087 rsrc_ptr->end_addr = readw (io_mem + addr + 4);
1088 addr += 6;
1089
1090 debug ("rsrc from io type ----\n");
1091 debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
1092 rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
1093
1094 list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
1095 }
1096
1097 if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
1098 rsrc_ptr = alloc_ebda_pci_rsrc ();
1099 if (!rsrc_ptr ) {
1100 iounmap (io_mem);
1101 return -ENOMEM;
1102 }
1103 rsrc_ptr->rsrc_type = type;
1104
1105 rsrc_ptr->bus_num = readb (io_mem + addr);
1106 rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
1107 rsrc_ptr->start_addr = readl (io_mem + addr + 2);
1108 rsrc_ptr->end_addr = readl (io_mem + addr + 6);
1109 addr += 10;
1110
1111 debug ("rsrc from mem or pfm ---\n");
1112 debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
1113 rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
1114
1115 list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
1116 }
1117 }
1118 kfree (rsrc_list_ptr);
1119 rsrc_list_ptr = NULL;
1120 print_ebda_pci_rsrc ();
1121 return 0;
1122}
1123
1124u16 ibmphp_get_total_controllers (void)
1125{
1126 return hpc_list_ptr->num_ctlrs;
1127}
1128
1129struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
1130{
1131 struct slot *slot;
1132 struct list_head *list;
1133
1134 list_for_each (list, &ibmphp_slot_head) {
1135 slot = list_entry (list, struct slot, ibm_slot_list);
1136 if (slot->number == physical_num)
1137 return slot;
1138 }
1139 return NULL;
1140}
1141
1142/* To find:
1143 * - the smallest slot number
1144 * - the largest slot number
1145 * - the total number of the slots based on each bus
1146 * (if only one slot per bus slot_min = slot_max )
1147 */
1148struct bus_info *ibmphp_find_same_bus_num (u32 num)
1149{
1150 struct bus_info *ptr;
1151 struct list_head *ptr1;
1152
1153 list_for_each (ptr1, &bus_info_head) {
1154 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
1155 if (ptr->busno == num)
1156 return ptr;
1157 }
1158 return NULL;
1159}
1160
1161/* Finding relative bus number, in order to map corresponding
1162 * bus register
1163 */
1164int ibmphp_get_bus_index (u8 num)
1165{
1166 struct bus_info *ptr;
1167 struct list_head *ptr1;
1168
1169 list_for_each (ptr1, &bus_info_head) {
1170 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
1171 if (ptr->busno == num)
1172 return ptr->index;
1173 }
1174 return -ENODEV;
1175}
1176
1177void ibmphp_free_bus_info_queue (void)
1178{
1179 struct bus_info *bus_info;
1180 struct list_head *list;
1181 struct list_head *next;
1182
1183 list_for_each_safe (list, next, &bus_info_head ) {
1184 bus_info = list_entry (list, struct bus_info, bus_info_list);
1185 kfree (bus_info);
1186 }
1187}
1188
1189void ibmphp_free_ebda_hpc_queue (void)
1190{
1191 struct controller *controller = NULL;
1192 struct list_head *list;
1193 struct list_head *next;
1194 int pci_flag = 0;
1195
1196 list_for_each_safe (list, next, &ebda_hpc_head) {
1197 controller = list_entry (list, struct controller, ebda_hpc_list);
1198 if (controller->ctlr_type == 0)
1199 release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
1200 else if ((controller->ctlr_type == 1) && (!pci_flag)) {
1201 ++pci_flag;
1202 pci_unregister_driver (&ibmphp_driver);
1203 }
1204 free_ebda_hpc (controller);
1205 }
1206}
1207
1208void ibmphp_free_ebda_pci_rsrc_queue (void)
1209{
1210 struct ebda_pci_rsrc *resource;
1211 struct list_head *list;
1212 struct list_head *next;
1213
1214 list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
1215 resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
1216 kfree (resource);
1217 resource = NULL;
1218 }
1219}
1220
1221static struct pci_device_id id_table[] = {
1222 {
1223 .vendor = PCI_VENDOR_ID_IBM,
1224 .device = HPC_DEVICE_ID,
1225 .subvendor = PCI_VENDOR_ID_IBM,
1226 .subdevice = HPC_SUBSYSTEM_ID,
1227 .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1228 }, {}
1229};
1230
1231MODULE_DEVICE_TABLE(pci, id_table);
1232
1233static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
1234static struct pci_driver ibmphp_driver = {
1235 .name = "ibmphp",
1236 .id_table = id_table,
1237 .probe = ibmphp_probe,
1238};
1239
1240int ibmphp_register_pci (void)
1241{
1242 struct controller *ctrl;
1243 struct list_head *tmp;
1244 int rc = 0;
1245
1246 list_for_each (tmp, &ebda_hpc_head) {
1247 ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
1248 if (ctrl->ctlr_type == 1) {
1249 rc = pci_register_driver(&ibmphp_driver);
1250 break;
1251 }
1252 }
1253 return rc;
1254}
1255static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
1256{
1257 struct controller *ctrl;
1258 struct list_head *tmp;
1259
1260 debug ("inside ibmphp_probe\n");
1261
1262 list_for_each (tmp, &ebda_hpc_head) {
1263 ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
1264 if (ctrl->ctlr_type == 1) {
1265 if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
1266 ctrl->ctrl_dev = dev;
1267 debug ("found device!!!\n");
1268 debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
1269 return 0;
1270 }
1271 }
1272 }
1273 return -ENODEV;
1274}
1275
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
new file mode 100644
index 000000000000..6894b548c8ca
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -0,0 +1,1161 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Jyoti Shah, IBM Corporation
5 *
6 * Copyright (C) 2001-2003 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <gregkh@us.ibm.com>
26 * <jshah@us.ibm.com>
27 *
28 */
29
30#include <linux/wait.h>
31#include <linux/time.h>
32#include <linux/delay.h>
33#include <linux/module.h>
34#include <linux/pci.h>
35#include <linux/smp_lock.h>
36#include <linux/init.h>
37#include "ibmphp.h"
38
39static int to_debug = FALSE;
40#define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0)
41
42//----------------------------------------------------------------------------
43// timeout values
44//----------------------------------------------------------------------------
45#define CMD_COMPLETE_TOUT_SEC 60 // give HPC 60 sec to finish cmd
46#define HPC_CTLR_WORKING_TOUT 60 // give HPC 60 sec to finish cmd
47#define HPC_GETACCESS_TIMEOUT 60 // seconds
48#define POLL_INTERVAL_SEC 2 // poll HPC every 2 seconds
49#define POLL_LATCH_CNT 5 // poll latch 5 times, then poll slots
50
51//----------------------------------------------------------------------------
52// Winnipeg Architected Register Offsets
53//----------------------------------------------------------------------------
54#define WPG_I2CMBUFL_OFFSET 0x08 // I2C Message Buffer Low
55#define WPG_I2CMOSUP_OFFSET 0x10 // I2C Master Operation Setup Reg
56#define WPG_I2CMCNTL_OFFSET 0x20 // I2C Master Control Register
57#define WPG_I2CPARM_OFFSET 0x40 // I2C Parameter Register
58#define WPG_I2CSTAT_OFFSET 0x70 // I2C Status Register
59
60//----------------------------------------------------------------------------
61// Winnipeg Store Type commands (Add this commands to the register offset)
62//----------------------------------------------------------------------------
63#define WPG_I2C_AND 0x1000 // I2C AND operation
64#define WPG_I2C_OR 0x2000 // I2C OR operation
65
66//----------------------------------------------------------------------------
67// Command set for I2C Master Operation Setup Regisetr
68//----------------------------------------------------------------------------
69#define WPG_READATADDR_MASK 0x00010000 // read,bytes,I2C shifted,index
70#define WPG_WRITEATADDR_MASK 0x40010000 // write,bytes,I2C shifted,index
71#define WPG_READDIRECT_MASK 0x10010000
72#define WPG_WRITEDIRECT_MASK 0x60010000
73
74
75//----------------------------------------------------------------------------
76// bit masks for I2C Master Control Register
77//----------------------------------------------------------------------------
78#define WPG_I2CMCNTL_STARTOP_MASK 0x00000002 // Start the Operation
79
80//----------------------------------------------------------------------------
81//
82//----------------------------------------------------------------------------
83#define WPG_I2C_IOREMAP_SIZE 0x2044 // size of linear address interval
84
85//----------------------------------------------------------------------------
86// command index
87//----------------------------------------------------------------------------
88#define WPG_1ST_SLOT_INDEX 0x01 // index - 1st slot for ctlr
89#define WPG_CTLR_INDEX 0x0F // index - ctlr
90#define WPG_1ST_EXTSLOT_INDEX 0x10 // index - 1st ext slot for ctlr
91#define WPG_1ST_BUS_INDEX 0x1F // index - 1st bus for ctlr
92
93//----------------------------------------------------------------------------
94// macro utilities
95//----------------------------------------------------------------------------
96// if bits 20,22,25,26,27,29,30 are OFF return TRUE
97#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
98
99//----------------------------------------------------------------------------
100// global variables
101//----------------------------------------------------------------------------
102static int ibmphp_shutdown;
103static int tid_poll;
104static struct semaphore sem_hpcaccess; // lock access to HPC
105static struct semaphore semOperations; // lock all operations and
106 // access to data structures
107static struct semaphore sem_exit; // make sure polling thread goes away
108//----------------------------------------------------------------------------
109// local function prototypes
110//----------------------------------------------------------------------------
111static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
112static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
113static u8 hpc_writecmdtoindex (u8, u8);
114static u8 hpc_readcmdtoindex (u8, u8);
115static void get_hpc_access (void);
116static void free_hpc_access (void);
117static void poll_hpc (void);
118static int process_changeinstatus (struct slot *, struct slot *);
119static int process_changeinlatch (u8, u8, struct controller *);
120static int hpc_poll_thread (void *);
121static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
122//----------------------------------------------------------------------------
123
124
125/*----------------------------------------------------------------------
126* Name: ibmphp_hpc_initvars
127*
128* Action: initialize semaphores and variables
129*---------------------------------------------------------------------*/
130void __init ibmphp_hpc_initvars (void)
131{
132 debug ("%s - Entry\n", __FUNCTION__);
133
134 init_MUTEX (&sem_hpcaccess);
135 init_MUTEX (&semOperations);
136 init_MUTEX_LOCKED (&sem_exit);
137 to_debug = FALSE;
138 ibmphp_shutdown = FALSE;
139 tid_poll = 0;
140
141 debug ("%s - Exit\n", __FUNCTION__);
142}
143
144/*----------------------------------------------------------------------
145* Name: i2c_ctrl_read
146*
147* Action: read from HPC over I2C
148*
149*---------------------------------------------------------------------*/
150static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
151{
152 u8 status;
153 int i;
154 void __iomem *wpg_addr; // base addr + offset
155 unsigned long wpg_data; // data to/from WPG LOHI format
156 unsigned long ultemp;
157 unsigned long data; // actual data HILO format
158
159 debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __FUNCTION__, WPGBbar, index);
160
161 //--------------------------------------------------------------------
162 // READ - step 1
163 // read at address, byte length, I2C address (shifted), index
164 // or read direct, byte length, index
165 if (ctlr_ptr->ctlr_type == 0x02) {
166 data = WPG_READATADDR_MASK;
167 // fill in I2C address
168 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
169 ultemp = ultemp >> 1;
170 data |= (ultemp << 8);
171
172 // fill in index
173 data |= (unsigned long)index;
174 } else if (ctlr_ptr->ctlr_type == 0x04) {
175 data = WPG_READDIRECT_MASK;
176
177 // fill in index
178 ultemp = (unsigned long)index;
179 ultemp = ultemp << 8;
180 data |= ultemp;
181 } else {
182 err ("this controller type is not supported \n");
183 return HPC_ERROR;
184 }
185
186 wpg_data = swab32 (data); // swap data before writing
187 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
188 writel (wpg_data, wpg_addr);
189
190 //--------------------------------------------------------------------
191 // READ - step 2 : clear the message buffer
192 data = 0x00000000;
193 wpg_data = swab32 (data);
194 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
195 writel (wpg_data, wpg_addr);
196
197 //--------------------------------------------------------------------
198 // READ - step 3 : issue start operation, I2C master control bit 30:ON
199 // 2020 : [20] OR operation at [20] offset 0x20
200 data = WPG_I2CMCNTL_STARTOP_MASK;
201 wpg_data = swab32 (data);
202 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
203 writel (wpg_data, wpg_addr);
204
205 //--------------------------------------------------------------------
206 // READ - step 4 : wait until start operation bit clears
207 i = CMD_COMPLETE_TOUT_SEC;
208 while (i) {
209 msleep(10);
210 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
211 wpg_data = readl (wpg_addr);
212 data = swab32 (wpg_data);
213 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
214 break;
215 i--;
216 }
217 if (i == 0) {
218 debug ("%s - Error : WPG timeout\n", __FUNCTION__);
219 return HPC_ERROR;
220 }
221 //--------------------------------------------------------------------
222 // READ - step 5 : read I2C status register
223 i = CMD_COMPLETE_TOUT_SEC;
224 while (i) {
225 msleep(10);
226 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
227 wpg_data = readl (wpg_addr);
228 data = swab32 (wpg_data);
229 if (HPC_I2CSTATUS_CHECK (data))
230 break;
231 i--;
232 }
233 if (i == 0) {
234 debug ("ctrl_read - Exit Error:I2C timeout\n");
235 return HPC_ERROR;
236 }
237
238 //--------------------------------------------------------------------
239 // READ - step 6 : get DATA
240 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
241 wpg_data = readl (wpg_addr);
242 data = swab32 (wpg_data);
243
244 status = (u8) data;
245
246 debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
247
248 return (status);
249}
250
251/*----------------------------------------------------------------------
252* Name: i2c_ctrl_write
253*
254* Action: write to HPC over I2C
255*
256* Return 0 or error codes
257*---------------------------------------------------------------------*/
258static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
259{
260 u8 rc;
261 void __iomem *wpg_addr; // base addr + offset
262 unsigned long wpg_data; // data to/from WPG LOHI format
263 unsigned long ultemp;
264 unsigned long data; // actual data HILO format
265 int i;
266
267 debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __FUNCTION__, WPGBbar, index, cmd);
268
269 rc = 0;
270 //--------------------------------------------------------------------
271 // WRITE - step 1
272 // write at address, byte length, I2C address (shifted), index
273 // or write direct, byte length, index
274 data = 0x00000000;
275
276 if (ctlr_ptr->ctlr_type == 0x02) {
277 data = WPG_WRITEATADDR_MASK;
278 // fill in I2C address
279 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
280 ultemp = ultemp >> 1;
281 data |= (ultemp << 8);
282
283 // fill in index
284 data |= (unsigned long)index;
285 } else if (ctlr_ptr->ctlr_type == 0x04) {
286 data = WPG_WRITEDIRECT_MASK;
287
288 // fill in index
289 ultemp = (unsigned long)index;
290 ultemp = ultemp << 8;
291 data |= ultemp;
292 } else {
293 err ("this controller type is not supported \n");
294 return HPC_ERROR;
295 }
296
297 wpg_data = swab32 (data); // swap data before writing
298 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
299 writel (wpg_data, wpg_addr);
300
301 //--------------------------------------------------------------------
302 // WRITE - step 2 : clear the message buffer
303 data = 0x00000000 | (unsigned long)cmd;
304 wpg_data = swab32 (data);
305 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
306 writel (wpg_data, wpg_addr);
307
308 //--------------------------------------------------------------------
309 // WRITE - step 3 : issue start operation,I2C master control bit 30:ON
310 // 2020 : [20] OR operation at [20] offset 0x20
311 data = WPG_I2CMCNTL_STARTOP_MASK;
312 wpg_data = swab32 (data);
313 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
314 writel (wpg_data, wpg_addr);
315
316 //--------------------------------------------------------------------
317 // WRITE - step 4 : wait until start operation bit clears
318 i = CMD_COMPLETE_TOUT_SEC;
319 while (i) {
320 msleep(10);
321 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
322 wpg_data = readl (wpg_addr);
323 data = swab32 (wpg_data);
324 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
325 break;
326 i--;
327 }
328 if (i == 0) {
329 debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
330 rc = HPC_ERROR;
331 }
332
333 //--------------------------------------------------------------------
334 // WRITE - step 5 : read I2C status register
335 i = CMD_COMPLETE_TOUT_SEC;
336 while (i) {
337 msleep(10);
338 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
339 wpg_data = readl (wpg_addr);
340 data = swab32 (wpg_data);
341 if (HPC_I2CSTATUS_CHECK (data))
342 break;
343 i--;
344 }
345 if (i == 0) {
346 debug ("ctrl_read - Error : I2C timeout\n");
347 rc = HPC_ERROR;
348 }
349
350 debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
351 return (rc);
352}
353
354//------------------------------------------------------------
355// Read from ISA type HPC
356//------------------------------------------------------------
357static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
358{
359 u16 start_address;
360 u16 end_address;
361 u8 data;
362
363 start_address = ctlr_ptr->u.isa_ctlr.io_start;
364 end_address = ctlr_ptr->u.isa_ctlr.io_end;
365 data = inb (start_address + offset);
366 return data;
367}
368
369//--------------------------------------------------------------
370// Write to ISA type HPC
371//--------------------------------------------------------------
372static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
373{
374 u16 start_address;
375 u16 port_address;
376
377 start_address = ctlr_ptr->u.isa_ctlr.io_start;
378 port_address = start_address + (u16) offset;
379 outb (data, port_address);
380}
381
382static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
383{
384 u8 data = 0x00;
385 debug ("inside pci_ctrl_read\n");
386 if (ctrl->ctrl_dev)
387 pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
388 return data;
389}
390
391static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
392{
393 u8 rc = -ENODEV;
394 debug ("inside pci_ctrl_write\n");
395 if (ctrl->ctrl_dev) {
396 pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
397 rc = 0;
398 }
399 return rc;
400}
401
402static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
403{
404 u8 rc;
405 switch (ctlr->ctlr_type) {
406 case 0:
407 rc = isa_ctrl_read (ctlr, offset);
408 break;
409 case 1:
410 rc = pci_ctrl_read (ctlr, offset);
411 break;
412 case 2:
413 case 4:
414 rc = i2c_ctrl_read (ctlr, base, offset);
415 break;
416 default:
417 return -ENODEV;
418 }
419 return rc;
420}
421
422static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
423{
424 u8 rc = 0;
425 switch (ctlr->ctlr_type) {
426 case 0:
427 isa_ctrl_write(ctlr, offset, data);
428 break;
429 case 1:
430 rc = pci_ctrl_write (ctlr, offset, data);
431 break;
432 case 2:
433 case 4:
434 rc = i2c_ctrl_write(ctlr, base, offset, data);
435 break;
436 default:
437 return -ENODEV;
438 }
439 return rc;
440}
441/*----------------------------------------------------------------------
442* Name: hpc_writecmdtoindex()
443*
444* Action: convert a write command to proper index within a controller
445*
446* Return index, HPC_ERROR
447*---------------------------------------------------------------------*/
448static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
449{
450 u8 rc;
451
452 switch (cmd) {
453 case HPC_CTLR_ENABLEIRQ: // 0x00.N.15
454 case HPC_CTLR_CLEARIRQ: // 0x06.N.15
455 case HPC_CTLR_RESET: // 0x07.N.15
456 case HPC_CTLR_IRQSTEER: // 0x08.N.15
457 case HPC_CTLR_DISABLEIRQ: // 0x01.N.15
458 case HPC_ALLSLOT_ON: // 0x11.N.15
459 case HPC_ALLSLOT_OFF: // 0x12.N.15
460 rc = 0x0F;
461 break;
462
463 case HPC_SLOT_OFF: // 0x02.Y.0-14
464 case HPC_SLOT_ON: // 0x03.Y.0-14
465 case HPC_SLOT_ATTNOFF: // 0x04.N.0-14
466 case HPC_SLOT_ATTNON: // 0x05.N.0-14
467 case HPC_SLOT_BLINKLED: // 0x13.N.0-14
468 rc = index;
469 break;
470
471 case HPC_BUS_33CONVMODE:
472 case HPC_BUS_66CONVMODE:
473 case HPC_BUS_66PCIXMODE:
474 case HPC_BUS_100PCIXMODE:
475 case HPC_BUS_133PCIXMODE:
476 rc = index + WPG_1ST_BUS_INDEX - 1;
477 break;
478
479 default:
480 err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
481 rc = HPC_ERROR;
482 }
483
484 return rc;
485}
486
487/*----------------------------------------------------------------------
488* Name: hpc_readcmdtoindex()
489*
490* Action: convert a read command to proper index within a controller
491*
492* Return index, HPC_ERROR
493*---------------------------------------------------------------------*/
494static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
495{
496 u8 rc;
497
498 switch (cmd) {
499 case READ_CTLRSTATUS:
500 rc = 0x0F;
501 break;
502 case READ_SLOTSTATUS:
503 case READ_ALLSTAT:
504 rc = index;
505 break;
506 case READ_EXTSLOTSTATUS:
507 rc = index + WPG_1ST_EXTSLOT_INDEX;
508 break;
509 case READ_BUSSTATUS:
510 rc = index + WPG_1ST_BUS_INDEX - 1;
511 break;
512 case READ_SLOTLATCHLOWREG:
513 rc = 0x28;
514 break;
515 case READ_REVLEVEL:
516 rc = 0x25;
517 break;
518 case READ_HPCOPTIONS:
519 rc = 0x27;
520 break;
521 default:
522 rc = HPC_ERROR;
523 }
524 return rc;
525}
526
527/*----------------------------------------------------------------------
528* Name: HPCreadslot()
529*
530* Action: issue a READ command to HPC
531*
532* Input: pslot - can not be NULL for READ_ALLSTAT
533* pstatus - can be NULL for READ_ALLSTAT
534*
535* Return 0 or error codes
536*---------------------------------------------------------------------*/
537int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
538{
539 void __iomem *wpg_bbar = NULL;
540 struct controller *ctlr_ptr;
541 struct list_head *pslotlist;
542 u8 index, status;
543 int rc = 0;
544 int busindex;
545
546 debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __FUNCTION__, pslot, cmd, pstatus);
547
548 if ((pslot == NULL)
549 || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
550 rc = -EINVAL;
551 err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
552 return rc;
553 }
554
555 if (cmd == READ_BUSSTATUS) {
556 busindex = ibmphp_get_bus_index (pslot->bus);
557 if (busindex < 0) {
558 rc = -EINVAL;
559 err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
560 return rc;
561 } else
562 index = (u8) busindex;
563 } else
564 index = pslot->ctlr_index;
565
566 index = hpc_readcmdtoindex (cmd, index);
567
568 if (index == HPC_ERROR) {
569 rc = -EINVAL;
570 err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
571 return rc;
572 }
573
574 ctlr_ptr = pslot->ctrl;
575
576 get_hpc_access ();
577
578 //--------------------------------------------------------------------
579 // map physical address to logical address
580 //--------------------------------------------------------------------
581 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
582 wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
583
584 //--------------------------------------------------------------------
585 // check controller status before reading
586 //--------------------------------------------------------------------
587 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
588 if (!rc) {
589 switch (cmd) {
590 case READ_ALLSTAT:
591 // update the slot structure
592 pslot->ctrl->status = status;
593 pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
594 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
595 &status);
596 if (!rc)
597 pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
598
599 break;
600
601 case READ_SLOTSTATUS:
602 // DO NOT update the slot structure
603 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
604 break;
605
606 case READ_EXTSLOTSTATUS:
607 // DO NOT update the slot structure
608 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
609 break;
610
611 case READ_CTLRSTATUS:
612 // DO NOT update the slot structure
613 *pstatus = status;
614 break;
615
616 case READ_BUSSTATUS:
617 pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
618 break;
619 case READ_REVLEVEL:
620 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
621 break;
622 case READ_HPCOPTIONS:
623 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
624 break;
625 case READ_SLOTLATCHLOWREG:
626 // DO NOT update the slot structure
627 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
628 break;
629
630 // Not used
631 case READ_ALLSLOT:
632 list_for_each (pslotlist, &ibmphp_slot_head) {
633 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
634 index = pslot->ctlr_index;
635 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
636 wpg_bbar, &status);
637 if (!rc) {
638 pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
639 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
640 ctlr_ptr, wpg_bbar, &status);
641 if (!rc)
642 pslot->ext_status =
643 ctrl_read (ctlr_ptr, wpg_bbar,
644 index + WPG_1ST_EXTSLOT_INDEX);
645 } else {
646 err ("%s - Error ctrl_read failed\n", __FUNCTION__);
647 rc = -EINVAL;
648 break;
649 }
650 }
651 break;
652 default:
653 rc = -EINVAL;
654 break;
655 }
656 }
657 //--------------------------------------------------------------------
658 // cleanup
659 //--------------------------------------------------------------------
660
661 // remove physical to logical address mapping
662 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
663 iounmap (wpg_bbar);
664
665 free_hpc_access ();
666
667 debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
668 return rc;
669}
670
671/*----------------------------------------------------------------------
672* Name: ibmphp_hpc_writeslot()
673*
674* Action: issue a WRITE command to HPC
675*---------------------------------------------------------------------*/
676int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
677{
678 void __iomem *wpg_bbar = NULL;
679 struct controller *ctlr_ptr;
680 u8 index, status;
681 int busindex;
682 u8 done;
683 int rc = 0;
684 int timeout;
685
686 debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __FUNCTION__, pslot, cmd);
687 if (pslot == NULL) {
688 rc = -EINVAL;
689 err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
690 return rc;
691 }
692
693 if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
694 (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
695 (cmd == HPC_BUS_133PCIXMODE)) {
696 busindex = ibmphp_get_bus_index (pslot->bus);
697 if (busindex < 0) {
698 rc = -EINVAL;
699 err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
700 return rc;
701 } else
702 index = (u8) busindex;
703 } else
704 index = pslot->ctlr_index;
705
706 index = hpc_writecmdtoindex (cmd, index);
707
708 if (index == HPC_ERROR) {
709 rc = -EINVAL;
710 err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
711 return rc;
712 }
713
714 ctlr_ptr = pslot->ctrl;
715
716 get_hpc_access ();
717
718 //--------------------------------------------------------------------
719 // map physical address to logical address
720 //--------------------------------------------------------------------
721 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
722 wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
723
724 debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
725 ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
726 ctlr_ptr->u.wpeg_ctlr.i2c_addr);
727 }
728 //--------------------------------------------------------------------
729 // check controller status before writing
730 //--------------------------------------------------------------------
731 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
732 if (!rc) {
733
734 ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
735
736 //--------------------------------------------------------------------
737 // check controller is still not working on the command
738 //--------------------------------------------------------------------
739 timeout = CMD_COMPLETE_TOUT_SEC;
740 done = FALSE;
741 while (!done) {
742 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
743 &status);
744 if (!rc) {
745 if (NEEDTOCHECK_CMDSTATUS (cmd)) {
746 if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
747 done = TRUE;
748 } else
749 done = TRUE;
750 }
751 if (!done) {
752 msleep(1000);
753 if (timeout < 1) {
754 done = TRUE;
755 err ("%s - Error command complete timeout\n", __FUNCTION__);
756 rc = -EFAULT;
757 } else
758 timeout--;
759 }
760 }
761 ctlr_ptr->status = status;
762 }
763 // cleanup
764
765 // remove physical to logical address mapping
766 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
767 iounmap (wpg_bbar);
768 free_hpc_access ();
769
770 debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
771 return rc;
772}
773
774/*----------------------------------------------------------------------
775* Name: get_hpc_access()
776*
777* Action: make sure only one process can access HPC at one time
778*---------------------------------------------------------------------*/
779static void get_hpc_access (void)
780{
781 down (&sem_hpcaccess);
782}
783
784/*----------------------------------------------------------------------
785* Name: free_hpc_access()
786*---------------------------------------------------------------------*/
787void free_hpc_access (void)
788{
789 up (&sem_hpcaccess);
790}
791
792/*----------------------------------------------------------------------
793* Name: ibmphp_lock_operations()
794*
795* Action: make sure only one process can change the data structure
796*---------------------------------------------------------------------*/
797void ibmphp_lock_operations (void)
798{
799 down (&semOperations);
800 to_debug = TRUE;
801}
802
803/*----------------------------------------------------------------------
804* Name: ibmphp_unlock_operations()
805*---------------------------------------------------------------------*/
806void ibmphp_unlock_operations (void)
807{
808 debug ("%s - Entry\n", __FUNCTION__);
809 up (&semOperations);
810 to_debug = FALSE;
811 debug ("%s - Exit\n", __FUNCTION__);
812}
813
814/*----------------------------------------------------------------------
815* Name: poll_hpc()
816*---------------------------------------------------------------------*/
817#define POLL_LATCH_REGISTER 0
818#define POLL_SLOTS 1
819#define POLL_SLEEP 2
820static void poll_hpc (void)
821{
822 struct slot myslot;
823 struct slot *pslot = NULL;
824 struct list_head *pslotlist;
825 int rc;
826 int poll_state = POLL_LATCH_REGISTER;
827 u8 oldlatchlow = 0x00;
828 u8 curlatchlow = 0x00;
829 int poll_count = 0;
830 u8 ctrl_count = 0x00;
831
832 debug ("%s - Entry\n", __FUNCTION__);
833
834 while (!ibmphp_shutdown) {
835 if (ibmphp_shutdown)
836 break;
837
838 /* try to get the lock to do some kind of harware access */
839 down (&semOperations);
840
841 switch (poll_state) {
842 case POLL_LATCH_REGISTER:
843 oldlatchlow = curlatchlow;
844 ctrl_count = 0x00;
845 list_for_each (pslotlist, &ibmphp_slot_head) {
846 if (ctrl_count >= ibmphp_get_total_controllers())
847 break;
848 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
849 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
850 ctrl_count++;
851 if (READ_SLOT_LATCH (pslot->ctrl)) {
852 rc = ibmphp_hpc_readslot (pslot,
853 READ_SLOTLATCHLOWREG,
854 &curlatchlow);
855 if (oldlatchlow != curlatchlow)
856 process_changeinlatch (oldlatchlow,
857 curlatchlow,
858 pslot->ctrl);
859 }
860 }
861 }
862 ++poll_count;
863 poll_state = POLL_SLEEP;
864 break;
865 case POLL_SLOTS:
866 list_for_each (pslotlist, &ibmphp_slot_head) {
867 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
868 // make a copy of the old status
869 memcpy ((void *) &myslot, (void *) pslot,
870 sizeof (struct slot));
871 rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
872 if ((myslot.status != pslot->status)
873 || (myslot.ext_status != pslot->ext_status))
874 process_changeinstatus (pslot, &myslot);
875 }
876 ctrl_count = 0x00;
877 list_for_each (pslotlist, &ibmphp_slot_head) {
878 if (ctrl_count >= ibmphp_get_total_controllers())
879 break;
880 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
881 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
882 ctrl_count++;
883 if (READ_SLOT_LATCH (pslot->ctrl))
884 rc = ibmphp_hpc_readslot (pslot,
885 READ_SLOTLATCHLOWREG,
886 &curlatchlow);
887 }
888 }
889 ++poll_count;
890 poll_state = POLL_SLEEP;
891 break;
892 case POLL_SLEEP:
893 /* don't sleep with a lock on the hardware */
894 up (&semOperations);
895 msleep(POLL_INTERVAL_SEC * 1000);
896
897 if (ibmphp_shutdown)
898 break;
899
900 down (&semOperations);
901
902 if (poll_count >= POLL_LATCH_CNT) {
903 poll_count = 0;
904 poll_state = POLL_SLOTS;
905 } else
906 poll_state = POLL_LATCH_REGISTER;
907 break;
908 }
909 /* give up the harware semaphore */
910 up (&semOperations);
911 /* sleep for a short time just for good measure */
912 msleep(100);
913 }
914 up (&sem_exit);
915 debug ("%s - Exit\n", __FUNCTION__);
916}
917
918
919/*----------------------------------------------------------------------
920* Name: process_changeinstatus
921*
922* Action: compare old and new slot status, process the change in status
923*
924* Input: pointer to slot struct, old slot struct
925*
926* Return 0 or error codes
927* Value:
928*
929* Side
930* Effects: None.
931*
932* Notes:
933*---------------------------------------------------------------------*/
934static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
935{
936 u8 status;
937 int rc = 0;
938 u8 disable = FALSE;
939 u8 update = FALSE;
940
941 debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
942
943 // bit 0 - HPC_SLOT_POWER
944 if ((pslot->status & 0x01) != (poldslot->status & 0x01))
945 update = TRUE;
946
947 // bit 1 - HPC_SLOT_CONNECT
948 // ignore
949
950 // bit 2 - HPC_SLOT_ATTN
951 if ((pslot->status & 0x04) != (poldslot->status & 0x04))
952 update = TRUE;
953
954 // bit 3 - HPC_SLOT_PRSNT2
955 // bit 4 - HPC_SLOT_PRSNT1
956 if (((pslot->status & 0x08) != (poldslot->status & 0x08))
957 || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
958 update = TRUE;
959
960 // bit 5 - HPC_SLOT_PWRGD
961 if ((pslot->status & 0x20) != (poldslot->status & 0x20))
962 // OFF -> ON: ignore, ON -> OFF: disable slot
963 if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))
964 disable = TRUE;
965
966 // bit 6 - HPC_SLOT_BUS_SPEED
967 // ignore
968
969 // bit 7 - HPC_SLOT_LATCH
970 if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
971 update = TRUE;
972 // OPEN -> CLOSE
973 if (pslot->status & 0x80) {
974 if (SLOT_PWRGD (pslot->status)) {
975 // power goes on and off after closing latch
976 // check again to make sure power is still ON
977 msleep(1000);
978 rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
979 if (SLOT_PWRGD (status))
980 update = TRUE;
981 else // overwrite power in pslot to OFF
982 pslot->status &= ~HPC_SLOT_POWER;
983 }
984 }
985 // CLOSE -> OPEN
986 else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
987 && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
988 disable = TRUE;
989 }
990 // else - ignore
991 }
992 // bit 4 - HPC_SLOT_BLINK_ATTN
993 if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
994 update = TRUE;
995
996 if (disable) {
997 debug ("process_changeinstatus - disable slot\n");
998 pslot->flag = FALSE;
999 rc = ibmphp_do_disable_slot (pslot);
1000 }
1001
1002 if (update || disable) {
1003 ibmphp_update_slot_info (pslot);
1004 }
1005
1006 debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
1007
1008 return rc;
1009}
1010
1011/*----------------------------------------------------------------------
1012* Name: process_changeinlatch
1013*
1014* Action: compare old and new latch reg status, process the change
1015*
1016* Input: old and current latch register status
1017*
1018* Return 0 or error codes
1019* Value:
1020*---------------------------------------------------------------------*/
1021static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
1022{
1023 struct slot myslot, *pslot;
1024 u8 i;
1025 u8 mask;
1026 int rc = 0;
1027
1028 debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
1029 // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1030
1031 for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1032 mask = 0x01 << i;
1033 if ((mask & old) != (mask & new)) {
1034 pslot = ibmphp_get_slot_from_physical_num (i);
1035 if (pslot) {
1036 memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
1037 rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
1038 debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
1039 process_changeinstatus (pslot, &myslot);
1040 } else {
1041 rc = -EINVAL;
1042 err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
1043 }
1044 }
1045 }
1046 debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
1047 return rc;
1048}
1049
1050/*----------------------------------------------------------------------
1051* Name: hpc_poll_thread
1052*
1053* Action: polling
1054*
1055* Return 0
1056* Value:
1057*---------------------------------------------------------------------*/
1058static int hpc_poll_thread (void *data)
1059{
1060 debug ("%s - Entry\n", __FUNCTION__);
1061
1062 daemonize("hpc_poll");
1063 allow_signal(SIGKILL);
1064
1065 poll_hpc ();
1066
1067 tid_poll = 0;
1068 debug ("%s - Exit\n", __FUNCTION__);
1069 return 0;
1070}
1071
1072
1073/*----------------------------------------------------------------------
1074* Name: ibmphp_hpc_start_poll_thread
1075*
1076* Action: start polling thread
1077*---------------------------------------------------------------------*/
1078int __init ibmphp_hpc_start_poll_thread (void)
1079{
1080 int rc = 0;
1081
1082 debug ("%s - Entry\n", __FUNCTION__);
1083
1084 tid_poll = kernel_thread (hpc_poll_thread, NULL, 0);
1085 if (tid_poll < 0) {
1086 err ("%s - Error, thread not started\n", __FUNCTION__);
1087 rc = -1;
1088 }
1089
1090 debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
1091 return rc;
1092}
1093
1094/*----------------------------------------------------------------------
1095* Name: ibmphp_hpc_stop_poll_thread
1096*
1097* Action: stop polling thread and cleanup
1098*---------------------------------------------------------------------*/
1099void __exit ibmphp_hpc_stop_poll_thread (void)
1100{
1101 debug ("%s - Entry\n", __FUNCTION__);
1102
1103 ibmphp_shutdown = TRUE;
1104 debug ("before locking operations \n");
1105 ibmphp_lock_operations ();
1106 debug ("after locking operations \n");
1107
1108 // wait for poll thread to exit
1109 debug ("before sem_exit down \n");
1110 down (&sem_exit);
1111 debug ("after sem_exit down \n");
1112
1113 // cleanup
1114 debug ("before free_hpc_access \n");
1115 free_hpc_access ();
1116 debug ("after free_hpc_access \n");
1117 ibmphp_unlock_operations ();
1118 debug ("after unlock operations \n");
1119 up (&sem_exit);
1120 debug ("after sem exit up\n");
1121
1122 debug ("%s - Exit\n", __FUNCTION__);
1123}
1124
1125/*----------------------------------------------------------------------
1126* Name: hpc_wait_ctlr_notworking
1127*
1128* Action: wait until the controller is in a not working state
1129*
1130* Return 0, HPC_ERROR
1131* Value:
1132*---------------------------------------------------------------------*/
1133static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1134 u8 * pstatus)
1135{
1136 int rc = 0;
1137 u8 done = FALSE;
1138
1139 debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1140
1141 while (!done) {
1142 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1143 if (*pstatus == HPC_ERROR) {
1144 rc = HPC_ERROR;
1145 done = TRUE;
1146 }
1147 if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
1148 done = TRUE;
1149 if (!done) {
1150 msleep(1000);
1151 if (timeout < 1) {
1152 done = TRUE;
1153 err ("HPCreadslot - Error ctlr timeout\n");
1154 rc = HPC_ERROR;
1155 } else
1156 timeout--;
1157 }
1158 }
1159 debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1160 return rc;
1161}
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
new file mode 100644
index 000000000000..2335fac65fb4
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -0,0 +1,1747 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001,2002 IBM Corp.
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 <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/list.h>
34#include "ibmphp.h"
35
36
37static int configure_device(struct pci_func *);
38static int configure_bridge(struct pci_func **, u8);
39static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
40static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
41static u8 find_sec_number (u8 primary_busno, u8 slotno);
42
43/*
44 * NOTE..... If BIOS doesn't provide default routing, we assign:
45 * 9 for SCSI, 10 for LAN adapters, and 11 for everything else.
46 * If adapter is bridged, then we assign 11 to it and devices behind it.
47 * We also assign the same irq numbers for multi function devices.
48 * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
49 */
50static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)
51{
52 int j;
53 for (j = 0; j < 4; j++) {
54 if (cur_func->irq[j] == 0xff) {
55 switch (class_code) {
56 case PCI_BASE_CLASS_STORAGE:
57 cur_func->irq[j] = SCSI_IRQ;
58 break;
59 case PCI_BASE_CLASS_NETWORK:
60 cur_func->irq[j] = LAN_IRQ;
61 break;
62 default:
63 cur_func->irq[j] = OTHER_IRQ;
64 break;
65 }
66 }
67 }
68}
69
70/*
71 * Configures the device to be added (will allocate needed resources if it
72 * can), the device can be a bridge or a regular pci device, can also be
73 * multi-functional
74 *
75 * Input: function to be added
76 *
77 * TO DO: The error case with Multifunction device or multi function bridge,
78 * if there is an error, will need to go through all previous functions and
79 * unconfigure....or can add some code into unconfigure_card....
80 */
81int ibmphp_configure_card (struct pci_func *func, u8 slotno)
82{
83 u16 vendor_id;
84 u32 class;
85 u8 class_code;
86 u8 hdr_type, device, sec_number;
87 u8 function;
88 struct pci_func *newfunc; /* for multi devices */
89 struct pci_func *cur_func, *prev_func;
90 int rc, i, j;
91 int cleanup_count;
92 u8 flag;
93 u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
94
95 debug ("inside configure_card, func->busno = %x\n", func->busno);
96
97 device = func->device;
98 cur_func = func;
99
100 /* We only get bus and device from IRQ routing table. So at this point,
101 * func->busno is correct, and func->device contains only device (at the 5
102 * highest bits)
103 */
104
105 /* For every function on the card */
106 for (function = 0x00; function < 0x08; function++) {
107 unsigned int devfn = PCI_DEVFN(device, function);
108 ibmphp_pci_bus->number = cur_func->busno;
109
110 cur_func->function = function;
111
112 debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
113 cur_func->busno, cur_func->device, cur_func->function);
114
115 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
116
117 debug ("vendor_id is %x\n", vendor_id);
118 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
119 /* found correct device!!! */
120 debug ("found valid device, vendor_id = %x\n", vendor_id);
121
122 ++valid_device;
123
124 /* header: x x x x x x x x
125 * | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
126 * |_=> 0 = single function device, 1 = multi-function device
127 */
128
129 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
130 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
131
132 class_code = class >> 24;
133 debug ("hrd_type = %x, class = %x, class_code %x\n", hdr_type, class, class_code);
134 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
135 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
136 err ("The device %x is VGA compatible and as is not supported for hot plugging. "
137 "Please choose another device.\n", cur_func->device);
138 return -ENODEV;
139 } else if (class == PCI_CLASS_DISPLAY_VGA) {
140 err ("The device %x is not supported for hot plugging. "
141 "Please choose another device.\n", cur_func->device);
142 return -ENODEV;
143 }
144 switch (hdr_type) {
145 case PCI_HEADER_TYPE_NORMAL:
146 debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
147 assign_alt_irq (cur_func, class_code);
148 if ((rc = configure_device (cur_func)) < 0) {
149 /* We need to do this in case some other BARs were properly inserted */
150 err ("was not able to configure devfunc %x on bus %x.\n",
151 cur_func->device, cur_func->busno);
152 cleanup_count = 6;
153 goto error;
154 }
155 cur_func->next = NULL;
156 function = 0x8;
157 break;
158 case PCI_HEADER_TYPE_MULTIDEVICE:
159 assign_alt_irq (cur_func, class_code);
160 if ((rc = configure_device (cur_func)) < 0) {
161 /* We need to do this in case some other BARs were properly inserted */
162 err ("was not able to configure devfunc %x on bus %x...bailing out\n",
163 cur_func->device, cur_func->busno);
164 cleanup_count = 6;
165 goto error;
166 }
167 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
168 if (!newfunc) {
169 err ("out of system memory\n");
170 return -ENOMEM;
171 }
172 memset (newfunc, 0, sizeof (struct pci_func));
173 newfunc->busno = cur_func->busno;
174 newfunc->device = device;
175 cur_func->next = newfunc;
176 cur_func = newfunc;
177 for (j = 0; j < 4; j++)
178 newfunc->irq[j] = cur_func->irq[j];
179 break;
180 case PCI_HEADER_TYPE_MULTIBRIDGE:
181 class >>= 8;
182 if (class != PCI_CLASS_BRIDGE_PCI) {
183 err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
184 "Please insert another card.\n", cur_func->device);
185 return -ENODEV;
186 }
187 assign_alt_irq (cur_func, class_code);
188 rc = configure_bridge (&cur_func, slotno);
189 if (rc == -ENODEV) {
190 err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
191 err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
192 return rc;
193 }
194 if (rc) {
195 /* We need to do this in case some other BARs were properly inserted */
196 err ("was not able to hot-add PPB properly.\n");
197 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
198 cleanup_count = 2;
199 goto error;
200 }
201
202 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
203 flag = FALSE;
204 for (i = 0; i < 32; i++) {
205 if (func->devices[i]) {
206 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
207 if (!newfunc) {
208 err ("out of system memory\n");
209 return -ENOMEM;
210 }
211 memset (newfunc, 0, sizeof (struct pci_func));
212 newfunc->busno = sec_number;
213 newfunc->device = (u8) i;
214 for (j = 0; j < 4; j++)
215 newfunc->irq[j] = cur_func->irq[j];
216
217 if (flag) {
218 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
219 prev_func->next = newfunc;
220 } else
221 cur_func->next = newfunc;
222
223 rc = ibmphp_configure_card (newfunc, slotno);
224 /* This could only happen if kmalloc failed */
225 if (rc) {
226 /* We need to do this in case bridge itself got configured properly, but devices behind it failed */
227 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
228 cleanup_count = 2;
229 goto error;
230 }
231 flag = TRUE;
232 }
233 }
234
235 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
236 if (!newfunc) {
237 err ("out of system memory\n");
238 return -ENOMEM;
239 }
240 memset (newfunc, 0, sizeof (struct pci_func));
241 newfunc->busno = cur_func->busno;
242 newfunc->device = device;
243 for (j = 0; j < 4; j++)
244 newfunc->irq[j] = cur_func->irq[j];
245 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
246 prev_func->next = newfunc;
247 cur_func = newfunc;
248 break;
249 case PCI_HEADER_TYPE_BRIDGE:
250 class >>= 8;
251 debug ("class now is %x\n", class);
252 if (class != PCI_CLASS_BRIDGE_PCI) {
253 err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
254 "Please insert another card.\n", cur_func->device);
255 return -ENODEV;
256 }
257
258 assign_alt_irq (cur_func, class_code);
259
260 debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
261 rc = configure_bridge (&cur_func, slotno);
262 if (rc == -ENODEV) {
263 err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
264 err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
265 return rc;
266 }
267 if (rc) {
268 /* We need to do this in case some other BARs were properly inserted */
269 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
270 err ("was not able to hot-add PPB properly.\n");
271 cleanup_count = 2;
272 goto error;
273 }
274 debug ("cur_func->busno = %x, device = %x, function = %x\n",
275 cur_func->busno, device, function);
276 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
277 debug ("after configuring bridge..., sec_number = %x\n", sec_number);
278 flag = FALSE;
279 for (i = 0; i < 32; i++) {
280 if (func->devices[i]) {
281 debug ("inside for loop, device is %x\n", i);
282 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
283 if (!newfunc) {
284 err (" out of system memory\n");
285 return -ENOMEM;
286 }
287 memset (newfunc, 0, sizeof (struct pci_func));
288 newfunc->busno = sec_number;
289 newfunc->device = (u8) i;
290 for (j = 0; j < 4; j++)
291 newfunc->irq[j] = cur_func->irq[j];
292
293 if (flag) {
294 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
295 prev_func->next = newfunc;
296 } else
297 cur_func->next = newfunc;
298
299 rc = ibmphp_configure_card (newfunc, slotno);
300
301 /* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
302 if (rc) {
303 /* We need to do this in case some other BARs were properly inserted */
304 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
305 cleanup_count = 2;
306 goto error;
307 }
308 flag = TRUE;
309 }
310 }
311
312 function = 0x8;
313 break;
314 default:
315 err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
316 return -ENXIO;
317 break;
318 } /* end of switch */
319 } /* end of valid device */
320 } /* end of for */
321
322 if (!valid_device) {
323 err ("Cannot find any valid devices on the card. Or unable to read from card.\n");
324 return -ENODEV;
325 }
326
327 return 0;
328
329error:
330 for (i = 0; i < cleanup_count; i++) {
331 if (cur_func->io[i]) {
332 ibmphp_remove_resource (cur_func->io[i]);
333 cur_func->io[i] = NULL;
334 } else if (cur_func->pfmem[i]) {
335 ibmphp_remove_resource (cur_func->pfmem[i]);
336 cur_func->pfmem[i] = NULL;
337 } else if (cur_func->mem[i]) {
338 ibmphp_remove_resource (cur_func->mem[i]);
339 cur_func->mem[i] = NULL;
340 }
341 }
342 return rc;
343}
344
345/*
346 * This function configures the pci BARs of a single device.
347 * Input: pointer to the pci_func
348 * Output: configured PCI, 0, or error
349 */
350static int configure_device (struct pci_func *func)
351{
352 u32 bar[6];
353 u32 address[] = {
354 PCI_BASE_ADDRESS_0,
355 PCI_BASE_ADDRESS_1,
356 PCI_BASE_ADDRESS_2,
357 PCI_BASE_ADDRESS_3,
358 PCI_BASE_ADDRESS_4,
359 PCI_BASE_ADDRESS_5,
360 0
361 };
362 u8 irq;
363 int count;
364 int len[6];
365 struct resource_node *io[6];
366 struct resource_node *mem[6];
367 struct resource_node *mem_tmp;
368 struct resource_node *pfmem[6];
369 unsigned int devfn;
370
371 debug ("%s - inside\n", __FUNCTION__);
372
373 devfn = PCI_DEVFN(func->device, func->function);
374 ibmphp_pci_bus->number = func->busno;
375
376 for (count = 0; address[count]; count++) { /* for 6 BARs */
377
378 /* not sure if i need this. per scott, said maybe need smth like this
379 if devices don't adhere 100% to the spec, so don't want to write
380 to the reserved bits
381
382 pcibios_read_config_byte(cur_func->busno, cur_func->device,
383 PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
384 if (tmp & 0x01) // IO
385 pcibios_write_config_dword(cur_func->busno, cur_func->device,
386 PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
387 else // Memory
388 pcibios_write_config_dword(cur_func->busno, cur_func->device,
389 PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
390 */
391 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
392 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
393
394 if (!bar[count]) /* This BAR is not implemented */
395 continue;
396
397 debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
398
399 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
400 /* This is IO */
401 debug ("inside IO SPACE\n");
402
403 len[count] = bar[count] & 0xFFFFFFFC;
404 len[count] = ~len[count] + 1;
405
406 debug ("len[count] in IO %x, count %d\n", len[count], count);
407
408 io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
409
410 if (!io[count]) {
411 err ("out of system memory\n");
412 return -ENOMEM;
413 }
414 memset (io[count], 0, sizeof (struct resource_node));
415 io[count]->type = IO;
416 io[count]->busno = func->busno;
417 io[count]->devfunc = PCI_DEVFN(func->device, func->function);
418 io[count]->len = len[count];
419 if (ibmphp_check_resource(io[count], 0) == 0) {
420 ibmphp_add_resource (io[count]);
421 func->io[count] = io[count];
422 } else {
423 err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
424 func->busno, func->device, func->function, len[count]);
425 kfree (io[count]);
426 return -EIO;
427 }
428 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
429
430 /* _______________This is for debugging purposes only_____________________ */
431 debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
432 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
433 debug ("after writing.... the start address is %x\n", bar[count]);
434 /* _________________________________________________________________________*/
435
436 } else {
437 /* This is Memory */
438 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
439 /* pfmem */
440 debug ("PFMEM SPACE\n");
441
442 len[count] = bar[count] & 0xFFFFFFF0;
443 len[count] = ~len[count] + 1;
444
445 debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
446
447 pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
448 if (!pfmem[count]) {
449 err ("out of system memory\n");
450 return -ENOMEM;
451 }
452 memset (pfmem[count], 0, sizeof (struct resource_node));
453 pfmem[count]->type = PFMEM;
454 pfmem[count]->busno = func->busno;
455 pfmem[count]->devfunc = PCI_DEVFN(func->device,
456 func->function);
457 pfmem[count]->len = len[count];
458 pfmem[count]->fromMem = FALSE;
459 if (ibmphp_check_resource (pfmem[count], 0) == 0) {
460 ibmphp_add_resource (pfmem[count]);
461 func->pfmem[count] = pfmem[count];
462 } else {
463 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
464 if (!mem_tmp) {
465 err ("out of system memory\n");
466 kfree (pfmem[count]);
467 return -ENOMEM;
468 }
469 memset (mem_tmp, 0, sizeof (struct resource_node));
470 mem_tmp->type = MEM;
471 mem_tmp->busno = pfmem[count]->busno;
472 mem_tmp->devfunc = pfmem[count]->devfunc;
473 mem_tmp->len = pfmem[count]->len;
474 debug ("there's no pfmem... going into mem.\n");
475 if (ibmphp_check_resource (mem_tmp, 0) == 0) {
476 ibmphp_add_resource (mem_tmp);
477 pfmem[count]->fromMem = TRUE;
478 pfmem[count]->rangeno = mem_tmp->rangeno;
479 pfmem[count]->start = mem_tmp->start;
480 pfmem[count]->end = mem_tmp->end;
481 ibmphp_add_pfmem_from_mem (pfmem[count]);
482 func->pfmem[count] = pfmem[count];
483 } else {
484 err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
485 func->busno, func->device, len[count]);
486 kfree (mem_tmp);
487 kfree (pfmem[count]);
488 return -EIO;
489 }
490 }
491
492 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
493
494 /*_______________This is for debugging purposes only______________________________*/
495 debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);
496 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
497 debug ("after writing, start address is %x\n", bar[count]);
498 /*_________________________________________________________________________________*/
499
500 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
501 debug ("inside the mem 64 case, count %d\n", count);
502 count += 1;
503 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
504 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
505 }
506 } else {
507 /* regular memory */
508 debug ("REGULAR MEM SPACE\n");
509
510 len[count] = bar[count] & 0xFFFFFFF0;
511 len[count] = ~len[count] + 1;
512
513 debug ("len[count] in Mem %x, count %d\n", len[count], count);
514
515 mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
516 if (!mem[count]) {
517 err ("out of system memory\n");
518 return -ENOMEM;
519 }
520 memset (mem[count], 0, sizeof (struct resource_node));
521 mem[count]->type = MEM;
522 mem[count]->busno = func->busno;
523 mem[count]->devfunc = PCI_DEVFN(func->device,
524 func->function);
525 mem[count]->len = len[count];
526 if (ibmphp_check_resource (mem[count], 0) == 0) {
527 ibmphp_add_resource (mem[count]);
528 func->mem[count] = mem[count];
529 } else {
530 err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
531 func->busno, func->device, len[count]);
532 kfree (mem[count]);
533 return -EIO;
534 }
535 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
536 /* _______________________This is for debugging purposes only _______________________*/
537 debug ("b4 writing, start address is %x\n", func->mem[count]->start);
538 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
539 debug ("after writing, the address is %x\n", bar[count]);
540 /* __________________________________________________________________________________*/
541
542 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
543 /* takes up another dword */
544 debug ("inside mem 64 case, reg. mem, count %d\n", count);
545 count += 1;
546 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
547 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
548 }
549 }
550 } /* end of mem */
551 } /* end of for */
552
553 func->bus = 0; /* To indicate that this is not a PPB */
554 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
555 if ((irq > 0x00) && (irq < 0x05))
556 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
557
558 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
559 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
560
561 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
562 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
563
564 return 0;
565}
566
567/******************************************************************************
568 * This routine configures a PCI-2-PCI bridge and the functions behind it
569 * Parameters: pci_func
570 * Returns:
571 ******************************************************************************/
572static int configure_bridge (struct pci_func **func_passed, u8 slotno)
573{
574 int count;
575 int i;
576 int rc;
577 u8 sec_number;
578 u8 io_base;
579 u16 pfmem_base;
580 u32 bar[2];
581 u32 len[2];
582 u8 flag_io = FALSE;
583 u8 flag_mem = FALSE;
584 u8 flag_pfmem = FALSE;
585 u8 need_io_upper = FALSE;
586 u8 need_pfmem_upper = FALSE;
587 struct res_needed *amount_needed = NULL;
588 struct resource_node *io = NULL;
589 struct resource_node *bus_io[2] = {NULL, NULL};
590 struct resource_node *mem = NULL;
591 struct resource_node *bus_mem[2] = {NULL, NULL};
592 struct resource_node *mem_tmp = NULL;
593 struct resource_node *pfmem = NULL;
594 struct resource_node *bus_pfmem[2] = {NULL, NULL};
595 struct bus_node *bus;
596 u32 address[] = {
597 PCI_BASE_ADDRESS_0,
598 PCI_BASE_ADDRESS_1,
599 0
600 };
601 struct pci_func *func = *func_passed;
602 unsigned int devfn;
603 u8 irq;
604 int retval;
605
606 debug ("%s - enter\n", __FUNCTION__);
607
608 devfn = PCI_DEVFN(func->function, func->device);
609 ibmphp_pci_bus->number = func->busno;
610
611 /* Configuring necessary info for the bridge so that we could see the devices
612 * behind it
613 */
614
615 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
616
617 /* _____________________For debugging purposes only __________________________
618 pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
619 debug ("primary # written into the bridge is %x\n", pri_number);
620 ___________________________________________________________________________*/
621
622 /* in EBDA, only get allocated 1 additional bus # per slot */
623 sec_number = find_sec_number (func->busno, slotno);
624 if (sec_number == 0xff) {
625 err ("cannot allocate secondary bus number for the bridged device\n");
626 return -EINVAL;
627 }
628
629 debug ("after find_sec_number, the number we got is %x\n", sec_number);
630 debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
631
632 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
633
634 /* __________________For debugging purposes only __________________________________
635 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
636 debug ("sec_number after write/read is %x\n", sec_number);
637 ________________________________________________________________________________*/
638
639 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
640
641 /* __________________For debugging purposes only ____________________________________
642 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
643 debug ("subordinate number after write/read is %x\n", sec_number);
644 __________________________________________________________________________________*/
645
646 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
647 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
648 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
649
650 debug ("func->busno is %x\n", func->busno);
651 debug ("sec_number after writing is %x\n", sec_number);
652
653
654 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
655 !!!!!!!!!!!!!!!NEED TO ADD!!! FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!!
656 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
657
658
659 /* First we need to allocate mem/io for the bridge itself in case it needs it */
660 for (count = 0; address[count]; count++) { /* for 2 BARs */
661 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
662 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
663
664 if (!bar[count]) {
665 /* This BAR is not implemented */
666 debug ("so we come here then, eh?, count = %d\n", count);
667 continue;
668 }
669 // tmp_bar = bar[count];
670
671 debug ("Bar %d wants %x\n", count, bar[count]);
672
673 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
674 /* This is IO */
675 len[count] = bar[count] & 0xFFFFFFFC;
676 len[count] = ~len[count] + 1;
677
678 debug ("len[count] in IO = %x\n", len[count]);
679
680 bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
681
682 if (!bus_io[count]) {
683 err ("out of system memory\n");
684 retval = -ENOMEM;
685 goto error;
686 }
687 memset (bus_io[count], 0, sizeof (struct resource_node));
688 bus_io[count]->type = IO;
689 bus_io[count]->busno = func->busno;
690 bus_io[count]->devfunc = PCI_DEVFN(func->device,
691 func->function);
692 bus_io[count]->len = len[count];
693 if (ibmphp_check_resource (bus_io[count], 0) == 0) {
694 ibmphp_add_resource (bus_io[count]);
695 func->io[count] = bus_io[count];
696 } else {
697 err ("cannot allocate requested io for bus %x, device %x, len %x\n",
698 func->busno, func->device, len[count]);
699 kfree (bus_io[count]);
700 return -EIO;
701 }
702
703 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
704
705 } else {
706 /* This is Memory */
707 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
708 /* pfmem */
709 len[count] = bar[count] & 0xFFFFFFF0;
710 len[count] = ~len[count] + 1;
711
712 debug ("len[count] in PFMEM = %x\n", len[count]);
713
714 bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
715 if (!bus_pfmem[count]) {
716 err ("out of system memory\n");
717 retval = -ENOMEM;
718 goto error;
719 }
720 memset (bus_pfmem[count], 0, sizeof (struct resource_node));
721 bus_pfmem[count]->type = PFMEM;
722 bus_pfmem[count]->busno = func->busno;
723 bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,
724 func->function);
725 bus_pfmem[count]->len = len[count];
726 bus_pfmem[count]->fromMem = FALSE;
727 if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
728 ibmphp_add_resource (bus_pfmem[count]);
729 func->pfmem[count] = bus_pfmem[count];
730 } else {
731 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
732 if (!mem_tmp) {
733 err ("out of system memory\n");
734 retval = -ENOMEM;
735 goto error;
736 }
737 memset (mem_tmp, 0, sizeof (struct resource_node));
738 mem_tmp->type = MEM;
739 mem_tmp->busno = bus_pfmem[count]->busno;
740 mem_tmp->devfunc = bus_pfmem[count]->devfunc;
741 mem_tmp->len = bus_pfmem[count]->len;
742 if (ibmphp_check_resource (mem_tmp, 0) == 0) {
743 ibmphp_add_resource (mem_tmp);
744 bus_pfmem[count]->fromMem = TRUE;
745 bus_pfmem[count]->rangeno = mem_tmp->rangeno;
746 ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
747 func->pfmem[count] = bus_pfmem[count];
748 } else {
749 err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
750 func->busno, func->device, len[count]);
751 kfree (mem_tmp);
752 kfree (bus_pfmem[count]);
753 return -EIO;
754 }
755 }
756
757 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
758
759 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
760 /* takes up another dword */
761 count += 1;
762 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
763 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
764
765 }
766 } else {
767 /* regular memory */
768 len[count] = bar[count] & 0xFFFFFFF0;
769 len[count] = ~len[count] + 1;
770
771 debug ("len[count] in Memory is %x\n", len[count]);
772
773 bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
774 if (!bus_mem[count]) {
775 err ("out of system memory\n");
776 retval = -ENOMEM;
777 goto error;
778 }
779 memset (bus_mem[count], 0, sizeof (struct resource_node));
780 bus_mem[count]->type = MEM;
781 bus_mem[count]->busno = func->busno;
782 bus_mem[count]->devfunc = PCI_DEVFN(func->device,
783 func->function);
784 bus_mem[count]->len = len[count];
785 if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
786 ibmphp_add_resource (bus_mem[count]);
787 func->mem[count] = bus_mem[count];
788 } else {
789 err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
790 func->busno, func->device, len[count]);
791 kfree (bus_mem[count]);
792 return -EIO;
793 }
794
795 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
796
797 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
798 /* takes up another dword */
799 count += 1;
800 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
801 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
802
803 }
804 }
805 } /* end of mem */
806 } /* end of for */
807
808 /* Now need to see how much space the devices behind the bridge needed */
809 amount_needed = scan_behind_bridge (func, sec_number);
810 if (amount_needed == NULL)
811 return -ENOMEM;
812
813 ibmphp_pci_bus->number = func->busno;
814 debug ("after coming back from scan_behind_bridge\n");
815 debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
816 debug ("amount_needed->io = %x\n", amount_needed->io);
817 debug ("amount_needed->mem = %x\n", amount_needed->mem);
818 debug ("amount_needed->pfmem = %x\n", amount_needed->pfmem);
819
820 if (amount_needed->not_correct) {
821 debug ("amount_needed is not correct\n");
822 for (count = 0; address[count]; count++) {
823 /* for 2 BARs */
824 if (bus_io[count]) {
825 ibmphp_remove_resource (bus_io[count]);
826 func->io[count] = NULL;
827 } else if (bus_pfmem[count]) {
828 ibmphp_remove_resource (bus_pfmem[count]);
829 func->pfmem[count] = NULL;
830 } else if (bus_mem[count]) {
831 ibmphp_remove_resource (bus_mem[count]);
832 func->mem[count] = NULL;
833 }
834 }
835 kfree (amount_needed);
836 return -ENODEV;
837 }
838
839 if (!amount_needed->io) {
840 debug ("it doesn't want IO?\n");
841 flag_io = TRUE;
842 } else {
843 debug ("it wants %x IO behind the bridge\n", amount_needed->io);
844 io = kmalloc(sizeof(*io), GFP_KERNEL);
845
846 if (!io) {
847 err ("out of system memory\n");
848 retval = -ENOMEM;
849 goto error;
850 }
851 memset (io, 0, sizeof (struct resource_node));
852 io->type = IO;
853 io->busno = func->busno;
854 io->devfunc = PCI_DEVFN(func->device, func->function);
855 io->len = amount_needed->io;
856 if (ibmphp_check_resource (io, 1) == 0) {
857 debug ("were we able to add io\n");
858 ibmphp_add_resource (io);
859 flag_io = TRUE;
860 }
861 }
862
863 if (!amount_needed->mem) {
864 debug ("it doesn't want n.e.memory?\n");
865 flag_mem = TRUE;
866 } else {
867 debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
868 mem = kmalloc(sizeof(*mem), GFP_KERNEL);
869 if (!mem) {
870 err ("out of system memory\n");
871 retval = -ENOMEM;
872 goto error;
873 }
874 memset (mem, 0, sizeof (struct resource_node));
875 mem->type = MEM;
876 mem->busno = func->busno;
877 mem->devfunc = PCI_DEVFN(func->device, func->function);
878 mem->len = amount_needed->mem;
879 if (ibmphp_check_resource (mem, 1) == 0) {
880 ibmphp_add_resource (mem);
881 flag_mem = TRUE;
882 debug ("were we able to add mem\n");
883 }
884 }
885
886 if (!amount_needed->pfmem) {
887 debug ("it doesn't want n.e.pfmem mem?\n");
888 flag_pfmem = TRUE;
889 } else {
890 debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
891 pfmem = kmalloc(sizeof(*pfmem), GFP_KERNEL);
892 if (!pfmem) {
893 err ("out of system memory\n");
894 retval = -ENOMEM;
895 goto error;
896 }
897 memset (pfmem, 0, sizeof (struct resource_node));
898 pfmem->type = PFMEM;
899 pfmem->busno = func->busno;
900 pfmem->devfunc = PCI_DEVFN(func->device, func->function);
901 pfmem->len = amount_needed->pfmem;
902 pfmem->fromMem = FALSE;
903 if (ibmphp_check_resource (pfmem, 1) == 0) {
904 ibmphp_add_resource (pfmem);
905 flag_pfmem = TRUE;
906 } else {
907 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
908 if (!mem_tmp) {
909 err ("out of system memory\n");
910 retval = -ENOMEM;
911 goto error;
912 }
913 memset (mem_tmp, 0, sizeof (struct resource_node));
914 mem_tmp->type = MEM;
915 mem_tmp->busno = pfmem->busno;
916 mem_tmp->devfunc = pfmem->devfunc;
917 mem_tmp->len = pfmem->len;
918 if (ibmphp_check_resource (mem_tmp, 1) == 0) {
919 ibmphp_add_resource (mem_tmp);
920 pfmem->fromMem = TRUE;
921 pfmem->rangeno = mem_tmp->rangeno;
922 ibmphp_add_pfmem_from_mem (pfmem);
923 flag_pfmem = TRUE;
924 }
925 }
926 }
927
928 debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
929 debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
930
931 if (flag_io && flag_mem && flag_pfmem) {
932 /* If on bootup, there was a bridged card in this slot,
933 * then card was removed and ibmphp got unloaded and loaded
934 * back again, there's no way for us to remove the bus
935 * struct, so no need to kmalloc, can use existing node
936 */
937 bus = ibmphp_find_res_bus (sec_number);
938 if (!bus) {
939 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
940 if (!bus) {
941 err ("out of system memory\n");
942 retval = -ENOMEM;
943 goto error;
944 }
945 memset (bus, 0, sizeof (struct bus_node));
946 bus->busno = sec_number;
947 debug ("b4 adding new bus\n");
948 rc = add_new_bus (bus, io, mem, pfmem, func->busno);
949 } else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
950 rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
951 else {
952 err ("expected bus structure not empty?\n");
953 retval = -EIO;
954 goto error;
955 }
956 if (rc) {
957 if (rc == -ENOMEM) {
958 ibmphp_remove_bus (bus, func->busno);
959 kfree (amount_needed);
960 return rc;
961 }
962 retval = rc;
963 goto error;
964 }
965 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
966 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
967
968 if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
969 debug ("io 32\n");
970 need_io_upper = TRUE;
971 }
972 if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
973 debug ("pfmem 64\n");
974 need_pfmem_upper = TRUE;
975 }
976
977 if (bus->noIORanges) {
978 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
979 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
980
981 /* _______________This is for debugging purposes only ____________________
982 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
983 debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
984 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
985 debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
986 ________________________________________________________________________*/
987
988 if (need_io_upper) { /* since can't support n.e.ways */
989 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
990 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
991 }
992 } else {
993 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
994 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
995 }
996
997 if (bus->noMemRanges) {
998 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
999 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
1000
1001 /* ____________________This is for debugging purposes only ________________________
1002 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
1003 debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1004 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
1005 debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1006 __________________________________________________________________________________*/
1007
1008 } else {
1009 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
1010 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
1011 }
1012 if (bus->noPFMemRanges) {
1013 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
1014 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
1015
1016 /* __________________________This is for debugging purposes only _______________________
1017 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
1018 debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1019 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
1020 debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1021 ______________________________________________________________________________________*/
1022
1023 if (need_pfmem_upper) { /* since can't support n.e.ways */
1024 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
1025 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
1026 }
1027 } else {
1028 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
1029 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
1030 }
1031
1032 debug ("b4 writing control information\n");
1033
1034 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
1035 if ((irq > 0x00) && (irq < 0x05))
1036 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
1037 /*
1038 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
1039 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
1040 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
1041 */
1042
1043 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
1044 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
1045 for (i = 0; i < 32; i++) {
1046 if (amount_needed->devices[i]) {
1047 debug ("device where devices[i] is 1 = %x\n", i);
1048 func->devices[i] = 1;
1049 }
1050 }
1051 func->bus = 1; /* For unconfiguring, to indicate it's PPB */
1052 func_passed = &func;
1053 debug ("func->busno b4 returning is %x\n", func->busno);
1054 debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
1055 kfree (amount_needed);
1056 return 0;
1057 } else {
1058 err ("Configuring bridge was unsuccessful...\n");
1059 mem_tmp = NULL;
1060 retval = -EIO;
1061 goto error;
1062 }
1063
1064error:
1065 kfree(amount_needed);
1066 if (pfmem)
1067 ibmphp_remove_resource (pfmem);
1068 if (io)
1069 ibmphp_remove_resource (io);
1070 if (mem)
1071 ibmphp_remove_resource (mem);
1072 for (i = 0; i < 2; i++) { /* for 2 BARs */
1073 if (bus_io[i]) {
1074 ibmphp_remove_resource (bus_io[i]);
1075 func->io[i] = NULL;
1076 } else if (bus_pfmem[i]) {
1077 ibmphp_remove_resource (bus_pfmem[i]);
1078 func->pfmem[i] = NULL;
1079 } else if (bus_mem[i]) {
1080 ibmphp_remove_resource (bus_mem[i]);
1081 func->mem[i] = NULL;
1082 }
1083 }
1084 return retval;
1085}
1086
1087/*****************************************************************************
1088 * This function adds up the amount of resources needed behind the PPB bridge
1089 * and passes it to the configure_bridge function
1090 * Input: bridge function
1091 * Ouput: amount of resources needed
1092 *****************************************************************************/
1093static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
1094{
1095 int count, len[6];
1096 u16 vendor_id;
1097 u8 hdr_type;
1098 u8 device, function;
1099 unsigned int devfn;
1100 int howmany = 0; /*this is to see if there are any devices behind the bridge */
1101
1102 u32 bar[6], class;
1103 u32 address[] = {
1104 PCI_BASE_ADDRESS_0,
1105 PCI_BASE_ADDRESS_1,
1106 PCI_BASE_ADDRESS_2,
1107 PCI_BASE_ADDRESS_3,
1108 PCI_BASE_ADDRESS_4,
1109 PCI_BASE_ADDRESS_5,
1110 0
1111 };
1112 struct res_needed *amount;
1113
1114 amount = kmalloc(sizeof(*amount), GFP_KERNEL);
1115 if (amount == NULL)
1116 return NULL;
1117 memset (amount, 0, sizeof (struct res_needed));
1118
1119 ibmphp_pci_bus->number = busno;
1120
1121 debug ("the bus_no behind the bridge is %x\n", busno);
1122 debug ("scanning devices behind the bridge...\n");
1123 for (device = 0; device < 32; device++) {
1124 amount->devices[device] = 0;
1125 for (function = 0; function < 8; function++) {
1126 devfn = PCI_DEVFN(device, function);
1127
1128 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1129
1130 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1131 /* found correct device!!! */
1132 howmany++;
1133
1134 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1135 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
1136
1137 debug ("hdr_type behind the bridge is %x\n", hdr_type);
1138 if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
1139 err ("embedded bridges not supported for hot-plugging.\n");
1140 amount->not_correct = TRUE;
1141 return amount;
1142 }
1143
1144 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
1145 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
1146 err ("The device %x is VGA compatible and as is not supported for hot plugging. "
1147 "Please choose another device.\n", device);
1148 amount->not_correct = TRUE;
1149 return amount;
1150 } else if (class == PCI_CLASS_DISPLAY_VGA) {
1151 err ("The device %x is not supported for hot plugging. "
1152 "Please choose another device.\n", device);
1153 amount->not_correct = TRUE;
1154 return amount;
1155 }
1156
1157 amount->devices[device] = 1;
1158
1159 for (count = 0; address[count]; count++) {
1160 /* for 6 BARs */
1161 /*
1162 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
1163 if (tmp & 0x01) // IO
1164 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
1165 else // MEMORY
1166 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1167 */
1168 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1169 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
1170
1171 debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
1172
1173 if (!bar[count]) /* This BAR is not implemented */
1174 continue;
1175
1176 //tmp_bar = bar[count];
1177
1178 debug ("count %d device %x function %x wants %x resources\n", count, device, function, bar[count]);
1179
1180 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
1181 /* This is IO */
1182 len[count] = bar[count] & 0xFFFFFFFC;
1183 len[count] = ~len[count] + 1;
1184 amount->io += len[count];
1185 } else {
1186 /* This is Memory */
1187 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1188 /* pfmem */
1189 len[count] = bar[count] & 0xFFFFFFF0;
1190 len[count] = ~len[count] + 1;
1191 amount->pfmem += len[count];
1192 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
1193 /* takes up another dword */
1194 count += 1;
1195
1196 } else {
1197 /* regular memory */
1198 len[count] = bar[count] & 0xFFFFFFF0;
1199 len[count] = ~len[count] + 1;
1200 amount->mem += len[count];
1201 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1202 /* takes up another dword */
1203 count += 1;
1204 }
1205 }
1206 }
1207 } /* end for */
1208 } /* end if (valid) */
1209 } /* end for */
1210 } /* end for */
1211
1212 if (!howmany)
1213 amount->not_correct = TRUE;
1214 else
1215 amount->not_correct = FALSE;
1216 if ((amount->io) && (amount->io < IOBRIDGE))
1217 amount->io = IOBRIDGE;
1218 if ((amount->mem) && (amount->mem < MEMBRIDGE))
1219 amount->mem = MEMBRIDGE;
1220 if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
1221 amount->pfmem = MEMBRIDGE;
1222 return amount;
1223}
1224
1225/* The following 3 unconfigure_boot_ routines deal with the case when we had the card
1226 * upon bootup in the system, since we don't allocate func to such case, we need to read
1227 * the start addresses from pci config space and then find the corresponding entries in
1228 * our resource lists. The functions return either 0, -ENODEV, or -1 (general failure)
1229 * Change: we also call these functions even if we configured the card ourselves (i.e., not
1230 * the bootup case), since it should work same way
1231 */
1232static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
1233{
1234 u32 start_address;
1235 u32 address[] = {
1236 PCI_BASE_ADDRESS_0,
1237 PCI_BASE_ADDRESS_1,
1238 PCI_BASE_ADDRESS_2,
1239 PCI_BASE_ADDRESS_3,
1240 PCI_BASE_ADDRESS_4,
1241 PCI_BASE_ADDRESS_5,
1242 0
1243 };
1244 int count;
1245 struct resource_node *io;
1246 struct resource_node *mem;
1247 struct resource_node *pfmem;
1248 struct bus_node *bus;
1249 u32 end_address;
1250 u32 temp_end;
1251 u32 size;
1252 u32 tmp_address;
1253 unsigned int devfn;
1254
1255 debug ("%s - enter\n", __FUNCTION__);
1256
1257 bus = ibmphp_find_res_bus (busno);
1258 if (!bus) {
1259 debug ("cannot find corresponding bus.\n");
1260 return -EINVAL;
1261 }
1262
1263 devfn = PCI_DEVFN(device, function);
1264 ibmphp_pci_bus->number = busno;
1265 for (count = 0; address[count]; count++) { /* for 6 BARs */
1266 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
1267
1268 /* We can do this here, b/c by that time the device driver of the card has been stopped */
1269
1270 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1271 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
1272 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
1273
1274 debug ("start_address is %x\n", start_address);
1275 debug ("busno, device, function %x %x %x\n", busno, device, function);
1276 if (!size) {
1277 /* This BAR is not implemented */
1278 debug ("is this bar no implemented?, count = %d\n", count);
1279 continue;
1280 }
1281 tmp_address = start_address;
1282 if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
1283 /* This is IO */
1284 start_address &= PCI_BASE_ADDRESS_IO_MASK;
1285 size = size & 0xFFFFFFFC;
1286 size = ~size + 1;
1287 end_address = start_address + size - 1;
1288 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1289 err ("cannot find corresponding IO resource to remove\n");
1290 return -EIO;
1291 }
1292 debug ("io->start = %x\n", io->start);
1293 temp_end = io->end;
1294 start_address = io->end + 1;
1295 ibmphp_remove_resource (io);
1296 /* This is needed b/c of the old I/O restrictions in the BIOS */
1297 while (temp_end < end_address) {
1298 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1299 err ("cannot find corresponding IO resource to remove\n");
1300 return -EIO;
1301 }
1302 debug ("io->start = %x\n", io->start);
1303 temp_end = io->end;
1304 start_address = io->end + 1;
1305 ibmphp_remove_resource (io);
1306 }
1307
1308 /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
1309 } else {
1310 /* This is Memory */
1311 start_address &= PCI_BASE_ADDRESS_MEM_MASK;
1312 if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1313 /* pfmem */
1314 debug ("start address of pfmem is %x\n", start_address);
1315
1316 if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
1317 err ("cannot find corresponding PFMEM resource to remove\n");
1318 return -EIO;
1319 }
1320 if (pfmem) {
1321 debug ("pfmem->start = %x\n", pfmem->start);
1322
1323 ibmphp_remove_resource(pfmem);
1324 }
1325 } else {
1326 /* regular memory */
1327 debug ("start address of mem is %x\n", start_address);
1328 if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
1329 err ("cannot find corresponding MEM resource to remove\n");
1330 return -EIO;
1331 }
1332 if (mem) {
1333 debug ("mem->start = %x\n", mem->start);
1334
1335 ibmphp_remove_resource(mem);
1336 }
1337 }
1338 if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1339 /* takes up another dword */
1340 count += 1;
1341 }
1342 } /* end of mem */
1343 } /* end of for */
1344
1345 return 0;
1346}
1347
1348static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
1349{
1350 int count;
1351 int bus_no, pri_no, sub_no, sec_no = 0;
1352 u32 start_address, tmp_address;
1353 u8 sec_number, sub_number, pri_number;
1354 struct resource_node *io = NULL;
1355 struct resource_node *mem = NULL;
1356 struct resource_node *pfmem = NULL;
1357 struct bus_node *bus;
1358 u32 address[] = {
1359 PCI_BASE_ADDRESS_0,
1360 PCI_BASE_ADDRESS_1,
1361 0
1362 };
1363 unsigned int devfn;
1364
1365 devfn = PCI_DEVFN(device, function);
1366 ibmphp_pci_bus->number = busno;
1367 bus_no = (int) busno;
1368 debug ("busno is %x\n", busno);
1369 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
1370 debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
1371
1372 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
1373 debug ("sec_number is %x\n", sec_number);
1374 sec_no = (int) sec_number;
1375 pri_no = (int) pri_number;
1376 if (pri_no != bus_no) {
1377 err ("primary numbers in our structures and pci config space don't match.\n");
1378 return -EINVAL;
1379 }
1380
1381 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
1382 sub_no = (int) sub_number;
1383 debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
1384 if (sec_no != sub_number) {
1385 err ("there're more buses behind this bridge. Hot removal is not supported. Please choose another card\n");
1386 return -ENODEV;
1387 }
1388
1389 bus = ibmphp_find_res_bus (sec_number);
1390 debug ("bus->busno is %x\n", bus->busno);
1391 debug ("sec_number is %x\n", sec_number);
1392 if (!bus) {
1393 err ("cannot find Bus structure for the bridged device\n");
1394 return -EINVAL;
1395 }
1396
1397 ibmphp_remove_bus (bus, busno);
1398
1399 for (count = 0; address[count]; count++) {
1400 /* for 2 BARs */
1401 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
1402
1403 if (!start_address) {
1404 /* This BAR is not implemented */
1405 continue;
1406 }
1407
1408 tmp_address = start_address;
1409
1410 if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
1411 /* This is IO */
1412 start_address &= PCI_BASE_ADDRESS_IO_MASK;
1413 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1414 err ("cannot find corresponding IO resource to remove\n");
1415 return -EIO;
1416 }
1417 if (io)
1418 debug ("io->start = %x\n", io->start);
1419
1420 ibmphp_remove_resource (io);
1421
1422 /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
1423 } else {
1424 /* This is Memory */
1425 start_address &= PCI_BASE_ADDRESS_MEM_MASK;
1426 if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1427 /* pfmem */
1428 if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
1429 err ("cannot find corresponding PFMEM resource to remove\n");
1430 return -EINVAL;
1431 }
1432 if (pfmem) {
1433 debug ("pfmem->start = %x\n", pfmem->start);
1434
1435 ibmphp_remove_resource(pfmem);
1436 }
1437 } else {
1438 /* regular memory */
1439 if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
1440 err ("cannot find corresponding MEM resource to remove\n");
1441 return -EINVAL;
1442 }
1443 if (mem) {
1444 debug ("mem->start = %x\n", mem->start);
1445
1446 ibmphp_remove_resource(mem);
1447 }
1448 }
1449 if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1450 /* takes up another dword */
1451 count += 1;
1452 }
1453 } /* end of mem */
1454 } /* end of for */
1455 debug ("%s - exiting, returning success\n", __FUNCTION__);
1456 return 0;
1457}
1458
1459static int unconfigure_boot_card (struct slot *slot_cur)
1460{
1461 u16 vendor_id;
1462 u32 class;
1463 u8 hdr_type;
1464 u8 device;
1465 u8 busno;
1466 u8 function;
1467 int rc;
1468 unsigned int devfn;
1469 u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
1470
1471 debug ("%s - enter\n", __FUNCTION__);
1472
1473 device = slot_cur->device;
1474 busno = slot_cur->bus;
1475
1476 debug ("b4 for loop, device is %x\n", device);
1477 /* For every function on the card */
1478 for (function = 0x0; function < 0x08; function++) {
1479 devfn = PCI_DEVFN(device, function);
1480 ibmphp_pci_bus->number = busno;
1481
1482 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1483
1484 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1485 /* found correct device!!! */
1486 ++valid_device;
1487
1488 debug ("%s - found correct device\n", __FUNCTION__);
1489
1490 /* header: x x x x x x x x
1491 * | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
1492 * |_=> 0 = single function device, 1 = multi-function device
1493 */
1494
1495 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1496 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
1497
1498 debug ("hdr_type %x, class %x\n", hdr_type, class);
1499 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
1500 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
1501 err ("The device %x function %x is VGA compatible and is not supported for hot removing. "
1502 "Please choose another device.\n", device, function);
1503 return -ENODEV;
1504 } else if (class == PCI_CLASS_DISPLAY_VGA) {
1505 err ("The device %x function %x is not supported for hot removing. "
1506 "Please choose another device.\n", device, function);
1507 return -ENODEV;
1508 }
1509
1510 switch (hdr_type) {
1511 case PCI_HEADER_TYPE_NORMAL:
1512 rc = unconfigure_boot_device (busno, device, function);
1513 if (rc) {
1514 err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
1515 device, function, busno);
1516 return rc;
1517 }
1518 function = 0x8;
1519 break;
1520 case PCI_HEADER_TYPE_MULTIDEVICE:
1521 rc = unconfigure_boot_device (busno, device, function);
1522 if (rc) {
1523 err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
1524 device, function, busno);
1525 return rc;
1526 }
1527 break;
1528 case PCI_HEADER_TYPE_BRIDGE:
1529 class >>= 8;
1530 if (class != PCI_CLASS_BRIDGE_PCI) {
1531 err ("This device %x function %x is not PCI-to-PCI bridge, "
1532 "and is not supported for hot-removing. "
1533 "Please try another card.\n", device, function);
1534 return -ENODEV;
1535 }
1536 rc = unconfigure_boot_bridge (busno, device, function);
1537 if (rc != 0) {
1538 err ("was not able to hot-remove PPB properly.\n");
1539 return rc;
1540 }
1541
1542 function = 0x8;
1543 break;
1544 case PCI_HEADER_TYPE_MULTIBRIDGE:
1545 class >>= 8;
1546 if (class != PCI_CLASS_BRIDGE_PCI) {
1547 err ("This device %x function %x is not PCI-to-PCI bridge, "
1548 "and is not supported for hot-removing. "
1549 "Please try another card.\n", device, function);
1550 return -ENODEV;
1551 }
1552 rc = unconfigure_boot_bridge (busno, device, function);
1553 if (rc != 0) {
1554 err ("was not able to hot-remove PPB properly.\n");
1555 return rc;
1556 }
1557 break;
1558 default:
1559 err ("MAJOR PROBLEM!!!! Cannot read device's header\n");
1560 return -1;
1561 break;
1562 } /* end of switch */
1563 } /* end of valid device */
1564 } /* end of for */
1565
1566 if (!valid_device) {
1567 err ("Could not find device to unconfigure. Or could not read the card.\n");
1568 return -1;
1569 }
1570 return 0;
1571}
1572
1573/*
1574 * free the resources of the card (multi, single, or bridged)
1575 * Parameters: slot, flag to say if this is for removing entire module or just
1576 * unconfiguring the device
1577 * TO DO: will probably need to add some code in case there was some resource,
1578 * to remove it... this is from when we have errors in the configure_card...
1579 * !!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
1580 * Returns: 0, -1, -ENODEV
1581 */
1582int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
1583{
1584 int i;
1585 int count;
1586 int rc;
1587 struct slot *sl = *slot_cur;
1588 struct pci_func *cur_func = NULL;
1589 struct pci_func *temp_func;
1590
1591 debug ("%s - enter\n", __FUNCTION__);
1592
1593 if (!the_end) {
1594 /* Need to unconfigure the card */
1595 rc = unconfigure_boot_card (sl);
1596 if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
1597 /* In all other cases, will still need to get rid of func structure if it exists */
1598 return rc;
1599 }
1600 }
1601
1602 if (sl->func) {
1603 cur_func = sl->func;
1604 while (cur_func) {
1605 /* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
1606 if (cur_func->bus) {
1607 /* in other words, it's a PPB */
1608 count = 2;
1609 } else {
1610 count = 6;
1611 }
1612
1613 for (i = 0; i < count; i++) {
1614 if (cur_func->io[i]) {
1615 debug ("io[%d] exists\n", i);
1616 if (the_end > 0)
1617 ibmphp_remove_resource (cur_func->io[i]);
1618 cur_func->io[i] = NULL;
1619 }
1620 if (cur_func->mem[i]) {
1621 debug ("mem[%d] exists\n", i);
1622 if (the_end > 0)
1623 ibmphp_remove_resource (cur_func->mem[i]);
1624 cur_func->mem[i] = NULL;
1625 }
1626 if (cur_func->pfmem[i]) {
1627 debug ("pfmem[%d] exists\n", i);
1628 if (the_end > 0)
1629 ibmphp_remove_resource (cur_func->pfmem[i]);
1630 cur_func->pfmem[i] = NULL;
1631 }
1632 }
1633
1634 temp_func = cur_func->next;
1635 kfree (cur_func);
1636 cur_func = temp_func;
1637 }
1638 }
1639
1640 sl->func = NULL;
1641 *slot_cur = sl;
1642 debug ("%s - exit\n", __FUNCTION__);
1643 return 0;
1644}
1645
1646/*
1647 * add a new bus resulting from hot-plugging a PPB bridge with devices
1648 *
1649 * Input: bus and the amount of resources needed (we know we can assign those,
1650 * since they've been checked already
1651 * Output: bus added to the correct spot
1652 * 0, -1, error
1653 */
1654static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
1655{
1656 struct range_node *io_range = NULL;
1657 struct range_node *mem_range = NULL;
1658 struct range_node *pfmem_range = NULL;
1659 struct bus_node *cur_bus = NULL;
1660
1661 /* Trying to find the parent bus number */
1662 if (parent_busno != 0xFF) {
1663 cur_bus = ibmphp_find_res_bus (parent_busno);
1664 if (!cur_bus) {
1665 err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
1666 return -ENODEV;
1667 }
1668
1669 list_add (&bus->bus_list, &cur_bus->bus_list);
1670 }
1671 if (io) {
1672 io_range = kmalloc(sizeof(*io_range), GFP_KERNEL);
1673 if (!io_range) {
1674 err ("out of system memory\n");
1675 return -ENOMEM;
1676 }
1677 memset (io_range, 0, sizeof (struct range_node));
1678 io_range->start = io->start;
1679 io_range->end = io->end;
1680 io_range->rangeno = 1;
1681 bus->noIORanges = 1;
1682 bus->rangeIO = io_range;
1683 }
1684 if (mem) {
1685 mem_range = kmalloc(sizeof(*mem_range), GFP_KERNEL);
1686 if (!mem_range) {
1687 err ("out of system memory\n");
1688 return -ENOMEM;
1689 }
1690 memset (mem_range, 0, sizeof (struct range_node));
1691 mem_range->start = mem->start;
1692 mem_range->end = mem->end;
1693 mem_range->rangeno = 1;
1694 bus->noMemRanges = 1;
1695 bus->rangeMem = mem_range;
1696 }
1697 if (pfmem) {
1698 pfmem_range = kmalloc(sizeof(*pfmem_range), GFP_KERNEL);
1699 if (!pfmem_range) {
1700 err ("out of system memory\n");
1701 return -ENOMEM;
1702 }
1703 memset (pfmem_range, 0, sizeof (struct range_node));
1704 pfmem_range->start = pfmem->start;
1705 pfmem_range->end = pfmem->end;
1706 pfmem_range->rangeno = 1;
1707 bus->noPFMemRanges = 1;
1708 bus->rangePFMem = pfmem_range;
1709 }
1710 return 0;
1711}
1712
1713/*
1714 * find the 1st available bus number for PPB to set as its secondary bus
1715 * Parameters: bus_number of the primary bus
1716 * Returns: bus_number of the secondary bus or 0xff in case of failure
1717 */
1718static u8 find_sec_number (u8 primary_busno, u8 slotno)
1719{
1720 int min, max;
1721 u8 busno;
1722 struct bus_info *bus;
1723 struct bus_node *bus_cur;
1724
1725 bus = ibmphp_find_same_bus_num (primary_busno);
1726 if (!bus) {
1727 err ("cannot get slot range of the bus from the BIOS\n");
1728 return 0xff;
1729 }
1730 max = bus->slot_max;
1731 min = bus->slot_min;
1732 if ((slotno > max) || (slotno < min)) {
1733 err ("got the wrong range\n");
1734 return 0xff;
1735 }
1736 busno = (u8) (slotno - (u8) min);
1737 busno += primary_busno + 0x01;
1738 bus_cur = ibmphp_find_res_bus (busno);
1739 /* either there is no such bus number, or there are no ranges, which
1740 * can only happen if we removed the bridged device in previous load
1741 * of the driver, and now only have the skeleton bus struct
1742 */
1743 if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
1744 return busno;
1745 return 0xff;
1746}
1747
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c
new file mode 100644
index 000000000000..9c224c94d698
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_res.c
@@ -0,0 +1,2156 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001,2002 IBM Corp.
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 <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/list.h>
34#include <linux/init.h>
35#include "ibmphp.h"
36
37static int flags = 0; /* for testing */
38
39static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
40static int once_over (void);
41static int remove_ranges (struct bus_node *, struct bus_node *);
42static int update_bridge_ranges (struct bus_node **);
43static int add_range (int type, struct range_node *, struct bus_node *);
44static void fix_resources (struct bus_node *);
45static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
46
47static LIST_HEAD(gbuses);
48
49static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
50{
51 struct bus_node * newbus;
52
53 if (!(curr) && !(flag)) {
54 err ("NULL pointer passed\n");
55 return NULL;
56 }
57
58 newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
59 if (!newbus) {
60 err ("out of system memory\n");
61 return NULL;
62 }
63
64 memset (newbus, 0, sizeof (struct bus_node));
65 if (flag)
66 newbus->busno = busno;
67 else
68 newbus->busno = curr->bus_num;
69 list_add_tail (&newbus->bus_list, &gbuses);
70 return newbus;
71}
72
73static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
74{
75 struct resource_node *rs;
76
77 if (!curr) {
78 err ("NULL passed to allocate\n");
79 return NULL;
80 }
81
82 rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
83 if (!rs) {
84 err ("out of system memory\n");
85 return NULL;
86 }
87 memset (rs, 0, sizeof (struct resource_node));
88 rs->busno = curr->bus_num;
89 rs->devfunc = curr->dev_fun;
90 rs->start = curr->start_addr;
91 rs->end = curr->end_addr;
92 rs->len = curr->end_addr - curr->start_addr + 1;
93 return rs;
94}
95
96static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
97{
98 struct bus_node * newbus;
99 struct range_node *newrange;
100 u8 num_ranges = 0;
101
102 if (first_bus) {
103 newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
104 if (!newbus) {
105 err ("out of system memory.\n");
106 return -ENOMEM;
107 }
108 memset (newbus, 0, sizeof (struct bus_node));
109 newbus->busno = curr->bus_num;
110 } else {
111 newbus = *new_bus;
112 switch (flag) {
113 case MEM:
114 num_ranges = newbus->noMemRanges;
115 break;
116 case PFMEM:
117 num_ranges = newbus->noPFMemRanges;
118 break;
119 case IO:
120 num_ranges = newbus->noIORanges;
121 break;
122 }
123 }
124
125 newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
126 if (!newrange) {
127 if (first_bus)
128 kfree (newbus);
129 err ("out of system memory\n");
130 return -ENOMEM;
131 }
132 memset (newrange, 0, sizeof (struct range_node));
133 newrange->start = curr->start_addr;
134 newrange->end = curr->end_addr;
135
136 if (first_bus || (!num_ranges))
137 newrange->rangeno = 1;
138 else {
139 /* need to insert our range */
140 add_range (flag, newrange, newbus);
141 debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
142 }
143
144 switch (flag) {
145 case MEM:
146 newbus->rangeMem = newrange;
147 if (first_bus)
148 newbus->noMemRanges = 1;
149 else {
150 debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
151 ++newbus->noMemRanges;
152 fix_resources (newbus);
153 }
154 break;
155 case IO:
156 newbus->rangeIO = newrange;
157 if (first_bus)
158 newbus->noIORanges = 1;
159 else {
160 debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
161 ++newbus->noIORanges;
162 fix_resources (newbus);
163 }
164 break;
165 case PFMEM:
166 newbus->rangePFMem = newrange;
167 if (first_bus)
168 newbus->noPFMemRanges = 1;
169 else {
170 debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
171 ++newbus->noPFMemRanges;
172 fix_resources (newbus);
173 }
174
175 break;
176 }
177
178 *new_bus = newbus;
179 *new_range = newrange;
180 return 0;
181}
182
183
184/* Notes:
185 * 1. The ranges are ordered. The buses are not ordered. (First come)
186 *
187 * 2. If cannot allocate out of PFMem range, allocate from Mem ranges. PFmemFromMem
188 * are not sorted. (no need since use mem node). To not change the entire code, we
189 * also add mem node whenever this case happens so as not to change
190 * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
191 */
192
193/*****************************************************************************
194 * This is the Resource Management initialization function. It will go through
195 * the Resource list taken from EBDA and fill in this module's data structures
196 *
197 * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES,
198 * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW
199 *
200 * Input: ptr to the head of the resource list from EBDA
201 * Output: 0, -1 or error codes
202 ***************************************************************************/
203int __init ibmphp_rsrc_init (void)
204{
205 struct ebda_pci_rsrc *curr;
206 struct range_node *newrange = NULL;
207 struct bus_node *newbus = NULL;
208 struct bus_node *bus_cur;
209 struct bus_node *bus_prev;
210 struct list_head *tmp;
211 struct resource_node *new_io = NULL;
212 struct resource_node *new_mem = NULL;
213 struct resource_node *new_pfmem = NULL;
214 int rc;
215 struct list_head *tmp_ebda;
216
217 list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
218 curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
219 if (!(curr->rsrc_type & PCIDEVMASK)) {
220 /* EBDA still lists non PCI devices, so ignore... */
221 debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
222 // continue;
223 }
224
225 /* this is a primary bus resource */
226 if (curr->rsrc_type & PRIMARYBUSMASK) {
227 /* memory */
228 if ((curr->rsrc_type & RESTYPE) == MMASK) {
229 /* no bus structure exists in place yet */
230 if (list_empty (&gbuses)) {
231 if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
232 return rc;
233 list_add_tail (&newbus->bus_list, &gbuses);
234 debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
235 } else {
236 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
237 /* found our bus */
238 if (bus_cur) {
239 rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
240 if (rc)
241 return rc;
242 } else {
243 /* went through all the buses and didn't find ours, need to create a new bus node */
244 if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
245 return rc;
246
247 list_add_tail (&newbus->bus_list, &gbuses);
248 debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
249 }
250 }
251 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
252 /* prefetchable memory */
253 if (list_empty (&gbuses)) {
254 /* no bus structure exists in place yet */
255 if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
256 return rc;
257 list_add_tail (&newbus->bus_list, &gbuses);
258 debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
259 } else {
260 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
261 if (bus_cur) {
262 /* found our bus */
263 rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
264 if (rc)
265 return rc;
266 } else {
267 /* went through all the buses and didn't find ours, need to create a new bus node */
268 if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
269 return rc;
270 list_add_tail (&newbus->bus_list, &gbuses);
271 debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
272 }
273 }
274 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
275 /* IO */
276 if (list_empty (&gbuses)) {
277 /* no bus structure exists in place yet */
278 if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
279 return rc;
280 list_add_tail (&newbus->bus_list, &gbuses);
281 debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
282 } else {
283 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
284 if (bus_cur) {
285 rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
286 if (rc)
287 return rc;
288 } else {
289 /* went through all the buses and didn't find ours, need to create a new bus node */
290 if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
291 return rc;
292 list_add_tail (&newbus->bus_list, &gbuses);
293 debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
294 }
295 }
296
297 } else {
298 ; /* type is reserved WHAT TO DO IN THIS CASE???
299 NOTHING TO DO??? */
300 }
301 } else {
302 /* regular pci device resource */
303 if ((curr->rsrc_type & RESTYPE) == MMASK) {
304 /* Memory resource */
305 new_mem = alloc_resources (curr);
306 if (!new_mem)
307 return -ENOMEM;
308 new_mem->type = MEM;
309 /*
310 * if it didn't find the bus, means PCI dev
311 * came b4 the Primary Bus info, so need to
312 * create a bus rangeno becomes a problem...
313 * assign a -1 and then update once the range
314 * actually appears...
315 */
316 if (ibmphp_add_resource (new_mem) < 0) {
317 newbus = alloc_error_bus (curr, 0, 0);
318 if (!newbus)
319 return -ENOMEM;
320 newbus->firstMem = new_mem;
321 ++newbus->needMemUpdate;
322 new_mem->rangeno = -1;
323 }
324 debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
325
326 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
327 /* PFMemory resource */
328 new_pfmem = alloc_resources (curr);
329 if (!new_pfmem)
330 return -ENOMEM;
331 new_pfmem->type = PFMEM;
332 new_pfmem->fromMem = FALSE;
333 if (ibmphp_add_resource (new_pfmem) < 0) {
334 newbus = alloc_error_bus (curr, 0, 0);
335 if (!newbus)
336 return -ENOMEM;
337 newbus->firstPFMem = new_pfmem;
338 ++newbus->needPFMemUpdate;
339 new_pfmem->rangeno = -1;
340 }
341
342 debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
343 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
344 /* IO resource */
345 new_io = alloc_resources (curr);
346 if (!new_io)
347 return -ENOMEM;
348 new_io->type = IO;
349
350 /*
351 * if it didn't find the bus, means PCI dev
352 * came b4 the Primary Bus info, so need to
353 * create a bus rangeno becomes a problem...
354 * Can assign a -1 and then update once the
355 * range actually appears...
356 */
357 if (ibmphp_add_resource (new_io) < 0) {
358 newbus = alloc_error_bus (curr, 0, 0);
359 if (!newbus)
360 return -ENOMEM;
361 newbus->firstIO = new_io;
362 ++newbus->needIOUpdate;
363 new_io->rangeno = -1;
364 }
365 debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
366 }
367 }
368 }
369
370 list_for_each (tmp, &gbuses) {
371 bus_cur = list_entry (tmp, struct bus_node, bus_list);
372 /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
373 rc = update_bridge_ranges (&bus_cur);
374 if (rc)
375 return rc;
376 }
377 rc = once_over (); /* This is to align ranges (so no -1) */
378 if (rc)
379 return rc;
380 return 0;
381}
382
383/********************************************************************************
384 * This function adds a range into a sorted list of ranges per bus for a particular
385 * range type, it then calls another routine to update the range numbers on the
386 * pci devices' resources for the appropriate resource
387 *
388 * Input: type of the resource, range to add, current bus
389 * Output: 0 or -1, bus and range ptrs
390 ********************************************************************************/
391static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
392{
393 struct range_node *range_cur = NULL;
394 struct range_node *range_prev;
395 int count = 0, i_init;
396 int noRanges = 0;
397
398 switch (type) {
399 case MEM:
400 range_cur = bus_cur->rangeMem;
401 noRanges = bus_cur->noMemRanges;
402 break;
403 case PFMEM:
404 range_cur = bus_cur->rangePFMem;
405 noRanges = bus_cur->noPFMemRanges;
406 break;
407 case IO:
408 range_cur = bus_cur->rangeIO;
409 noRanges = bus_cur->noIORanges;
410 break;
411 }
412
413 range_prev = NULL;
414 while (range_cur) {
415 if (range->start < range_cur->start)
416 break;
417 range_prev = range_cur;
418 range_cur = range_cur->next;
419 count = count + 1;
420 }
421 if (!count) {
422 /* our range will go at the beginning of the list */
423 switch (type) {
424 case MEM:
425 bus_cur->rangeMem = range;
426 break;
427 case PFMEM:
428 bus_cur->rangePFMem = range;
429 break;
430 case IO:
431 bus_cur->rangeIO = range;
432 break;
433 }
434 range->next = range_cur;
435 range->rangeno = 1;
436 i_init = 0;
437 } else if (!range_cur) {
438 /* our range will go at the end of the list */
439 range->next = NULL;
440 range_prev->next = range;
441 range->rangeno = range_prev->rangeno + 1;
442 return 0;
443 } else {
444 /* the range is in the middle */
445 range_prev->next = range;
446 range->next = range_cur;
447 range->rangeno = range_cur->rangeno;
448 i_init = range_prev->rangeno;
449 }
450
451 for (count = i_init; count < noRanges; ++count) {
452 ++range_cur->rangeno;
453 range_cur = range_cur->next;
454 }
455
456 update_resources (bus_cur, type, i_init + 1);
457 return 0;
458}
459
460/*******************************************************************************
461 * This routine goes through the list of resources of type 'type' and updates
462 * the range numbers that they correspond to. It was called from add_range fnc
463 *
464 * Input: bus, type of the resource, the rangeno starting from which to update
465 ******************************************************************************/
466static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
467{
468 struct resource_node *res = NULL;
469 u8 eol = FALSE; /* end of list indicator */
470
471 switch (type) {
472 case MEM:
473 if (bus_cur->firstMem)
474 res = bus_cur->firstMem;
475 break;
476 case PFMEM:
477 if (bus_cur->firstPFMem)
478 res = bus_cur->firstPFMem;
479 break;
480 case IO:
481 if (bus_cur->firstIO)
482 res = bus_cur->firstIO;
483 break;
484 }
485
486 if (res) {
487 while (res) {
488 if (res->rangeno == rangeno)
489 break;
490 if (res->next)
491 res = res->next;
492 else if (res->nextRange)
493 res = res->nextRange;
494 else {
495 eol = TRUE;
496 break;
497 }
498 }
499
500 if (!eol) {
501 /* found the range */
502 while (res) {
503 ++res->rangeno;
504 res = res->next;
505 }
506 }
507 }
508}
509
510static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
511{
512 char * str = "";
513 switch (res->type) {
514 case IO:
515 str = "io";
516 break;
517 case MEM:
518 str = "mem";
519 break;
520 case PFMEM:
521 str = "pfmem";
522 break;
523 }
524
525 while (res) {
526 if (res->rangeno == -1) {
527 while (range) {
528 if ((res->start >= range->start) && (res->end <= range->end)) {
529 res->rangeno = range->rangeno;
530 debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
531 switch (res->type) {
532 case IO:
533 --bus_cur->needIOUpdate;
534 break;
535 case MEM:
536 --bus_cur->needMemUpdate;
537 break;
538 case PFMEM:
539 --bus_cur->needPFMemUpdate;
540 break;
541 }
542 break;
543 }
544 range = range->next;
545 }
546 }
547 if (res->next)
548 res = res->next;
549 else
550 res = res->nextRange;
551 }
552
553}
554
555/*****************************************************************************
556 * This routine reassigns the range numbers to the resources that had a -1
557 * This case can happen only if upon initialization, resources taken by pci dev
558 * appear in EBDA before the resources allocated for that bus, since we don't
559 * know the range, we assign -1, and this routine is called after a new range
560 * is assigned to see the resources with unknown range belong to the added range
561 *
562 * Input: current bus
563 * Output: none, list of resources for that bus are fixed if can be
564 *******************************************************************************/
565static void fix_resources (struct bus_node *bus_cur)
566{
567 struct range_node *range;
568 struct resource_node *res;
569
570 debug ("%s - bus_cur->busno = %d\n", __FUNCTION__, bus_cur->busno);
571
572 if (bus_cur->needIOUpdate) {
573 res = bus_cur->firstIO;
574 range = bus_cur->rangeIO;
575 fix_me (res, bus_cur, range);
576 }
577 if (bus_cur->needMemUpdate) {
578 res = bus_cur->firstMem;
579 range = bus_cur->rangeMem;
580 fix_me (res, bus_cur, range);
581 }
582 if (bus_cur->needPFMemUpdate) {
583 res = bus_cur->firstPFMem;
584 range = bus_cur->rangePFMem;
585 fix_me (res, bus_cur, range);
586 }
587}
588
589/*******************************************************************************
590 * This routine adds a resource to the list of resources to the appropriate bus
591 * based on their resource type and sorted by their starting addresses. It assigns
592 * the ptrs to next and nextRange if needed.
593 *
594 * Input: resource ptr
595 * Output: ptrs assigned (to the node)
596 * 0 or -1
597 *******************************************************************************/
598int ibmphp_add_resource (struct resource_node *res)
599{
600 struct resource_node *res_cur;
601 struct resource_node *res_prev;
602 struct bus_node *bus_cur;
603 struct range_node *range_cur = NULL;
604 struct resource_node *res_start = NULL;
605
606 debug ("%s - enter\n", __FUNCTION__);
607
608 if (!res) {
609 err ("NULL passed to add\n");
610 return -ENODEV;
611 }
612
613 bus_cur = find_bus_wprev (res->busno, NULL, 0);
614
615 if (!bus_cur) {
616 /* didn't find a bus, smth's wrong!!! */
617 debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
618 return -ENODEV;
619 }
620
621 /* Normal case */
622 switch (res->type) {
623 case IO:
624 range_cur = bus_cur->rangeIO;
625 res_start = bus_cur->firstIO;
626 break;
627 case MEM:
628 range_cur = bus_cur->rangeMem;
629 res_start = bus_cur->firstMem;
630 break;
631 case PFMEM:
632 range_cur = bus_cur->rangePFMem;
633 res_start = bus_cur->firstPFMem;
634 break;
635 default:
636 err ("cannot read the type of the resource to add... problem\n");
637 return -EINVAL;
638 }
639 while (range_cur) {
640 if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
641 res->rangeno = range_cur->rangeno;
642 break;
643 }
644 range_cur = range_cur->next;
645 }
646
647 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
648 * this is again the case of rangeno = -1
649 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
650 */
651
652 if (!range_cur) {
653 switch (res->type) {
654 case IO:
655 ++bus_cur->needIOUpdate;
656 break;
657 case MEM:
658 ++bus_cur->needMemUpdate;
659 break;
660 case PFMEM:
661 ++bus_cur->needPFMemUpdate;
662 break;
663 }
664 res->rangeno = -1;
665 }
666
667 debug ("The range is %d\n", res->rangeno);
668 if (!res_start) {
669 /* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
670 switch (res->type) {
671 case IO:
672 bus_cur->firstIO = res;
673 break;
674 case MEM:
675 bus_cur->firstMem = res;
676 break;
677 case PFMEM:
678 bus_cur->firstPFMem = res;
679 break;
680 }
681 res->next = NULL;
682 res->nextRange = NULL;
683 } else {
684 res_cur = res_start;
685 res_prev = NULL;
686
687 debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
688
689 while (res_cur) {
690 if (res_cur->rangeno >= res->rangeno)
691 break;
692 res_prev = res_cur;
693 if (res_cur->next)
694 res_cur = res_cur->next;
695 else
696 res_cur = res_cur->nextRange;
697 }
698
699 if (!res_cur) {
700 /* at the end of the resource list */
701 debug ("i should be here, [%x - %x]\n", res->start, res->end);
702 res_prev->nextRange = res;
703 res->next = NULL;
704 res->nextRange = NULL;
705 } else if (res_cur->rangeno == res->rangeno) {
706 /* in the same range */
707 while (res_cur) {
708 if (res->start < res_cur->start)
709 break;
710 res_prev = res_cur;
711 res_cur = res_cur->next;
712 }
713 if (!res_cur) {
714 /* the last resource in this range */
715 res_prev->next = res;
716 res->next = NULL;
717 res->nextRange = res_prev->nextRange;
718 res_prev->nextRange = NULL;
719 } else if (res->start < res_cur->start) {
720 /* at the beginning or middle of the range */
721 if (!res_prev) {
722 switch (res->type) {
723 case IO:
724 bus_cur->firstIO = res;
725 break;
726 case MEM:
727 bus_cur->firstMem = res;
728 break;
729 case PFMEM:
730 bus_cur->firstPFMem = res;
731 break;
732 }
733 } else if (res_prev->rangeno == res_cur->rangeno)
734 res_prev->next = res;
735 else
736 res_prev->nextRange = res;
737
738 res->next = res_cur;
739 res->nextRange = NULL;
740 }
741 } else {
742 /* this is the case where it is 1st occurrence of the range */
743 if (!res_prev) {
744 /* at the beginning of the resource list */
745 res->next = NULL;
746 switch (res->type) {
747 case IO:
748 res->nextRange = bus_cur->firstIO;
749 bus_cur->firstIO = res;
750 break;
751 case MEM:
752 res->nextRange = bus_cur->firstMem;
753 bus_cur->firstMem = res;
754 break;
755 case PFMEM:
756 res->nextRange = bus_cur->firstPFMem;
757 bus_cur->firstPFMem = res;
758 break;
759 }
760 } else if (res_cur->rangeno > res->rangeno) {
761 /* in the middle of the resource list */
762 res_prev->nextRange = res;
763 res->next = NULL;
764 res->nextRange = res_cur;
765 }
766 }
767 }
768
769 debug ("%s - exit\n", __FUNCTION__);
770 return 0;
771}
772
773/****************************************************************************
774 * This routine will remove the resource from the list of resources
775 *
776 * Input: io, mem, and/or pfmem resource to be deleted
777 * Ouput: modified resource list
778 * 0 or error code
779 ****************************************************************************/
780int ibmphp_remove_resource (struct resource_node *res)
781{
782 struct bus_node *bus_cur;
783 struct resource_node *res_cur = NULL;
784 struct resource_node *res_prev;
785 struct resource_node *mem_cur;
786 char * type = "";
787
788 if (!res) {
789 err ("resource to remove is NULL\n");
790 return -ENODEV;
791 }
792
793 bus_cur = find_bus_wprev (res->busno, NULL, 0);
794
795 if (!bus_cur) {
796 err ("cannot find corresponding bus of the io resource to remove "
797 "bailing out...\n");
798 return -ENODEV;
799 }
800
801 switch (res->type) {
802 case IO:
803 res_cur = bus_cur->firstIO;
804 type = "io";
805 break;
806 case MEM:
807 res_cur = bus_cur->firstMem;
808 type = "mem";
809 break;
810 case PFMEM:
811 res_cur = bus_cur->firstPFMem;
812 type = "pfmem";
813 break;
814 default:
815 err ("unknown type for resource to remove\n");
816 return -EINVAL;
817 }
818 res_prev = NULL;
819
820 while (res_cur) {
821 if ((res_cur->start == res->start) && (res_cur->end == res->end))
822 break;
823 res_prev = res_cur;
824 if (res_cur->next)
825 res_cur = res_cur->next;
826 else
827 res_cur = res_cur->nextRange;
828 }
829
830 if (!res_cur) {
831 if (res->type == PFMEM) {
832 /*
833 * case where pfmem might be in the PFMemFromMem list
834 * so will also need to remove the corresponding mem
835 * entry
836 */
837 res_cur = bus_cur->firstPFMemFromMem;
838 res_prev = NULL;
839
840 while (res_cur) {
841 if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
842 mem_cur = bus_cur->firstMem;
843 while (mem_cur) {
844 if ((mem_cur->start == res_cur->start)
845 && (mem_cur->end == res_cur->end))
846 break;
847 if (mem_cur->next)
848 mem_cur = mem_cur->next;
849 else
850 mem_cur = mem_cur->nextRange;
851 }
852 if (!mem_cur) {
853 err ("cannot find corresponding mem node for pfmem...\n");
854 return -EINVAL;
855 }
856
857 ibmphp_remove_resource (mem_cur);
858 if (!res_prev)
859 bus_cur->firstPFMemFromMem = res_cur->next;
860 else
861 res_prev->next = res_cur->next;
862 kfree (res_cur);
863 return 0;
864 }
865 res_prev = res_cur;
866 if (res_cur->next)
867 res_cur = res_cur->next;
868 else
869 res_cur = res_cur->nextRange;
870 }
871 if (!res_cur) {
872 err ("cannot find pfmem to delete...\n");
873 return -EINVAL;
874 }
875 } else {
876 err ("the %s resource is not in the list to be deleted...\n", type);
877 return -EINVAL;
878 }
879 }
880 if (!res_prev) {
881 /* first device to be deleted */
882 if (res_cur->next) {
883 switch (res->type) {
884 case IO:
885 bus_cur->firstIO = res_cur->next;
886 break;
887 case MEM:
888 bus_cur->firstMem = res_cur->next;
889 break;
890 case PFMEM:
891 bus_cur->firstPFMem = res_cur->next;
892 break;
893 }
894 } else if (res_cur->nextRange) {
895 switch (res->type) {
896 case IO:
897 bus_cur->firstIO = res_cur->nextRange;
898 break;
899 case MEM:
900 bus_cur->firstMem = res_cur->nextRange;
901 break;
902 case PFMEM:
903 bus_cur->firstPFMem = res_cur->nextRange;
904 break;
905 }
906 } else {
907 switch (res->type) {
908 case IO:
909 bus_cur->firstIO = NULL;
910 break;
911 case MEM:
912 bus_cur->firstMem = NULL;
913 break;
914 case PFMEM:
915 bus_cur->firstPFMem = NULL;
916 break;
917 }
918 }
919 kfree (res_cur);
920 return 0;
921 } else {
922 if (res_cur->next) {
923 if (res_prev->rangeno == res_cur->rangeno)
924 res_prev->next = res_cur->next;
925 else
926 res_prev->nextRange = res_cur->next;
927 } else if (res_cur->nextRange) {
928 res_prev->next = NULL;
929 res_prev->nextRange = res_cur->nextRange;
930 } else {
931 res_prev->next = NULL;
932 res_prev->nextRange = NULL;
933 }
934 kfree (res_cur);
935 return 0;
936 }
937
938 return 0;
939}
940
941static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res)
942{
943 struct range_node * range = NULL;
944
945 switch (res->type) {
946 case IO:
947 range = bus_cur->rangeIO;
948 break;
949 case MEM:
950 range = bus_cur->rangeMem;
951 break;
952 case PFMEM:
953 range = bus_cur->rangePFMem;
954 break;
955 default:
956 err ("cannot read resource type in find_range\n");
957 }
958
959 while (range) {
960 if (res->rangeno == range->rangeno)
961 break;
962 range = range->next;
963 }
964 return range;
965}
966
967/*****************************************************************************
968 * This routine will check to make sure the io/mem/pfmem->len that the device asked for
969 * can fit w/i our list of available IO/MEM/PFMEM resources. If cannot, returns -EINVAL,
970 * otherwise, returns 0
971 *
972 * Input: resource
973 * Ouput: the correct start and end address are inputted into the resource node,
974 * 0 or -EINVAL
975 *****************************************************************************/
976int ibmphp_check_resource (struct resource_node *res, u8 bridge)
977{
978 struct bus_node *bus_cur;
979 struct range_node *range = NULL;
980 struct resource_node *res_prev;
981 struct resource_node *res_cur = NULL;
982 u32 len_cur = 0, start_cur = 0, len_tmp = 0;
983 int noranges = 0;
984 u32 tmp_start; /* this is to make sure start address is divisible by the length needed */
985 u32 tmp_divide;
986 u8 flag = FALSE;
987
988 if (!res)
989 return -EINVAL;
990
991 if (bridge) {
992 /* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/
993 if (res->type == IO)
994 tmp_divide = IOBRIDGE;
995 else
996 tmp_divide = MEMBRIDGE;
997 } else
998 tmp_divide = res->len;
999
1000 bus_cur = find_bus_wprev (res->busno, NULL, 0);
1001
1002 if (!bus_cur) {
1003 /* didn't find a bus, smth's wrong!!! */
1004 debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
1005 return -EINVAL;
1006 }
1007
1008 debug ("%s - enter\n", __FUNCTION__);
1009 debug ("bus_cur->busno is %d\n", bus_cur->busno);
1010
1011 /* This is a quick fix to not mess up with the code very much. i.e.,
1012 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
1013 res->len -= 1;
1014
1015 switch (res->type) {
1016 case IO:
1017 res_cur = bus_cur->firstIO;
1018 noranges = bus_cur->noIORanges;
1019 break;
1020 case MEM:
1021 res_cur = bus_cur->firstMem;
1022 noranges = bus_cur->noMemRanges;
1023 break;
1024 case PFMEM:
1025 res_cur = bus_cur->firstPFMem;
1026 noranges = bus_cur->noPFMemRanges;
1027 break;
1028 default:
1029 err ("wrong type of resource to check\n");
1030 return -EINVAL;
1031 }
1032 res_prev = NULL;
1033
1034 while (res_cur) {
1035 range = find_range (bus_cur, res_cur);
1036 debug ("%s - rangeno = %d\n", __FUNCTION__, res_cur->rangeno);
1037
1038 if (!range) {
1039 err ("no range for the device exists... bailing out...\n");
1040 return -EINVAL;
1041 }
1042
1043 /* found our range */
1044 if (!res_prev) {
1045 /* first time in the loop */
1046 if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
1047 debug ("len_tmp = %x\n", len_tmp);
1048
1049 if ((len_tmp < len_cur) || (len_cur == 0)) {
1050
1051 if ((range->start % tmp_divide) == 0) {
1052 /* just perfect, starting address is divisible by length */
1053 flag = TRUE;
1054 len_cur = len_tmp;
1055 start_cur = range->start;
1056 } else {
1057 /* Needs adjusting */
1058 tmp_start = range->start;
1059 flag = FALSE;
1060
1061 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1062 if ((tmp_start % tmp_divide) == 0) {
1063 flag = TRUE;
1064 len_cur = len_tmp;
1065 start_cur = tmp_start;
1066 break;
1067 }
1068 tmp_start += tmp_divide - tmp_start % tmp_divide;
1069 if (tmp_start >= res_cur->start - 1)
1070 break;
1071 }
1072 }
1073
1074 if (flag && len_cur == res->len) {
1075 debug ("but we are not here, right?\n");
1076 res->start = start_cur;
1077 res->len += 1; /* To restore the balance */
1078 res->end = res->start + res->len - 1;
1079 return 0;
1080 }
1081 }
1082 }
1083 }
1084 if (!res_cur->next) {
1085 /* last device on the range */
1086 if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) {
1087 debug ("len_tmp = %x\n", len_tmp);
1088 if ((len_tmp < len_cur) || (len_cur == 0)) {
1089
1090 if (((res_cur->end + 1) % tmp_divide) == 0) {
1091 /* just perfect, starting address is divisible by length */
1092 flag = TRUE;
1093 len_cur = len_tmp;
1094 start_cur = res_cur->end + 1;
1095 } else {
1096 /* Needs adjusting */
1097 tmp_start = res_cur->end + 1;
1098 flag = FALSE;
1099
1100 while ((len_tmp = range->end - tmp_start) >= res->len) {
1101 if ((tmp_start % tmp_divide) == 0) {
1102 flag = TRUE;
1103 len_cur = len_tmp;
1104 start_cur = tmp_start;
1105 break;
1106 }
1107 tmp_start += tmp_divide - tmp_start % tmp_divide;
1108 if (tmp_start >= range->end)
1109 break;
1110 }
1111 }
1112 if (flag && len_cur == res->len) {
1113 res->start = start_cur;
1114 res->len += 1; /* To restore the balance */
1115 res->end = res->start + res->len - 1;
1116 return 0;
1117 }
1118 }
1119 }
1120 }
1121
1122 if (res_prev) {
1123 if (res_prev->rangeno != res_cur->rangeno) {
1124 /* 1st device on this range */
1125 if ((res_cur->start != range->start) &&
1126 ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
1127 if ((len_tmp < len_cur) || (len_cur == 0)) {
1128 if ((range->start % tmp_divide) == 0) {
1129 /* just perfect, starting address is divisible by length */
1130 flag = TRUE;
1131 len_cur = len_tmp;
1132 start_cur = range->start;
1133 } else {
1134 /* Needs adjusting */
1135 tmp_start = range->start;
1136 flag = FALSE;
1137
1138 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1139 if ((tmp_start % tmp_divide) == 0) {
1140 flag = TRUE;
1141 len_cur = len_tmp;
1142 start_cur = tmp_start;
1143 break;
1144 }
1145 tmp_start += tmp_divide - tmp_start % tmp_divide;
1146 if (tmp_start >= res_cur->start - 1)
1147 break;
1148 }
1149 }
1150
1151 if (flag && len_cur == res->len) {
1152 res->start = start_cur;
1153 res->len += 1; /* To restore the balance */
1154 res->end = res->start + res->len - 1;
1155 return 0;
1156 }
1157 }
1158 }
1159 } else {
1160 /* in the same range */
1161 if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) {
1162 if ((len_tmp < len_cur) || (len_cur == 0)) {
1163 if (((res_prev->end + 1) % tmp_divide) == 0) {
1164 /* just perfect, starting address's divisible by length */
1165 flag = TRUE;
1166 len_cur = len_tmp;
1167 start_cur = res_prev->end + 1;
1168 } else {
1169 /* Needs adjusting */
1170 tmp_start = res_prev->end + 1;
1171 flag = FALSE;
1172
1173 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1174 if ((tmp_start % tmp_divide) == 0) {
1175 flag = TRUE;
1176 len_cur = len_tmp;
1177 start_cur = tmp_start;
1178 break;
1179 }
1180 tmp_start += tmp_divide - tmp_start % tmp_divide;
1181 if (tmp_start >= res_cur->start - 1)
1182 break;
1183 }
1184 }
1185
1186 if (flag && len_cur == res->len) {
1187 res->start = start_cur;
1188 res->len += 1; /* To restore the balance */
1189 res->end = res->start + res->len - 1;
1190 return 0;
1191 }
1192 }
1193 }
1194 }
1195 }
1196 /* end if (res_prev) */
1197 res_prev = res_cur;
1198 if (res_cur->next)
1199 res_cur = res_cur->next;
1200 else
1201 res_cur = res_cur->nextRange;
1202 } /* end of while */
1203
1204
1205 if (!res_prev) {
1206 /* 1st device ever */
1207 /* need to find appropriate range */
1208 switch (res->type) {
1209 case IO:
1210 range = bus_cur->rangeIO;
1211 break;
1212 case MEM:
1213 range = bus_cur->rangeMem;
1214 break;
1215 case PFMEM:
1216 range = bus_cur->rangePFMem;
1217 break;
1218 }
1219 while (range) {
1220 if ((len_tmp = range->end - range->start) >= res->len) {
1221 if ((len_tmp < len_cur) || (len_cur == 0)) {
1222 if ((range->start % tmp_divide) == 0) {
1223 /* just perfect, starting address's divisible by length */
1224 flag = TRUE;
1225 len_cur = len_tmp;
1226 start_cur = range->start;
1227 } else {
1228 /* Needs adjusting */
1229 tmp_start = range->start;
1230 flag = FALSE;
1231
1232 while ((len_tmp = range->end - tmp_start) >= res->len) {
1233 if ((tmp_start % tmp_divide) == 0) {
1234 flag = TRUE;
1235 len_cur = len_tmp;
1236 start_cur = tmp_start;
1237 break;
1238 }
1239 tmp_start += tmp_divide - tmp_start % tmp_divide;
1240 if (tmp_start >= range->end)
1241 break;
1242 }
1243 }
1244
1245 if (flag && len_cur == res->len) {
1246 res->start = start_cur;
1247 res->len += 1; /* To restore the balance */
1248 res->end = res->start + res->len - 1;
1249 return 0;
1250 }
1251 }
1252 }
1253 range = range->next;
1254 } /* end of while */
1255
1256 if ((!range) && (len_cur == 0)) {
1257 /* have gone through the list of devices and ranges and haven't found n.e.thing */
1258 err ("no appropriate range.. bailing out...\n");
1259 return -EINVAL;
1260 } else if (len_cur) {
1261 res->start = start_cur;
1262 res->len += 1; /* To restore the balance */
1263 res->end = res->start + res->len - 1;
1264 return 0;
1265 }
1266 }
1267
1268 if (!res_cur) {
1269 debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
1270 if (res_prev->rangeno < noranges) {
1271 /* if there're more ranges out there to check */
1272 switch (res->type) {
1273 case IO:
1274 range = bus_cur->rangeIO;
1275 break;
1276 case MEM:
1277 range = bus_cur->rangeMem;
1278 break;
1279 case PFMEM:
1280 range = bus_cur->rangePFMem;
1281 break;
1282 }
1283 while (range) {
1284 if ((len_tmp = range->end - range->start) >= res->len) {
1285 if ((len_tmp < len_cur) || (len_cur == 0)) {
1286 if ((range->start % tmp_divide) == 0) {
1287 /* just perfect, starting address's divisible by length */
1288 flag = TRUE;
1289 len_cur = len_tmp;
1290 start_cur = range->start;
1291 } else {
1292 /* Needs adjusting */
1293 tmp_start = range->start;
1294 flag = FALSE;
1295
1296 while ((len_tmp = range->end - tmp_start) >= res->len) {
1297 if ((tmp_start % tmp_divide) == 0) {
1298 flag = TRUE;
1299 len_cur = len_tmp;
1300 start_cur = tmp_start;
1301 break;
1302 }
1303 tmp_start += tmp_divide - tmp_start % tmp_divide;
1304 if (tmp_start >= range->end)
1305 break;
1306 }
1307 }
1308
1309 if (flag && len_cur == res->len) {
1310 res->start = start_cur;
1311 res->len += 1; /* To restore the balance */
1312 res->end = res->start + res->len - 1;
1313 return 0;
1314 }
1315 }
1316 }
1317 range = range->next;
1318 } /* end of while */
1319
1320 if ((!range) && (len_cur == 0)) {
1321 /* have gone through the list of devices and ranges and haven't found n.e.thing */
1322 err ("no appropriate range.. bailing out...\n");
1323 return -EINVAL;
1324 } else if (len_cur) {
1325 res->start = start_cur;
1326 res->len += 1; /* To restore the balance */
1327 res->end = res->start + res->len - 1;
1328 return 0;
1329 }
1330 } else {
1331 /* no more ranges to check on */
1332 if (len_cur) {
1333 res->start = start_cur;
1334 res->len += 1; /* To restore the balance */
1335 res->end = res->start + res->len - 1;
1336 return 0;
1337 } else {
1338 /* have gone through the list of devices and haven't found n.e.thing */
1339 err ("no appropriate range.. bailing out...\n");
1340 return -EINVAL;
1341 }
1342 }
1343 } /* end if(!res_cur) */
1344 return -EINVAL;
1345}
1346
1347/********************************************************************************
1348 * This routine is called from remove_card if the card contained PPB.
1349 * It will remove all the resources on the bus as well as the bus itself
1350 * Input: Bus
1351 * Ouput: 0, -ENODEV
1352 ********************************************************************************/
1353int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
1354{
1355 struct resource_node *res_cur;
1356 struct resource_node *res_tmp;
1357 struct bus_node *prev_bus;
1358 int rc;
1359
1360 prev_bus = find_bus_wprev (parent_busno, NULL, 0);
1361
1362 if (!prev_bus) {
1363 debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
1364 return -ENODEV;
1365 }
1366
1367 debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
1368
1369 rc = remove_ranges (bus, prev_bus);
1370 if (rc)
1371 return rc;
1372
1373 if (bus->firstIO) {
1374 res_cur = bus->firstIO;
1375 while (res_cur) {
1376 res_tmp = res_cur;
1377 if (res_cur->next)
1378 res_cur = res_cur->next;
1379 else
1380 res_cur = res_cur->nextRange;
1381 kfree (res_tmp);
1382 res_tmp = NULL;
1383 }
1384 bus->firstIO = NULL;
1385 }
1386 if (bus->firstMem) {
1387 res_cur = bus->firstMem;
1388 while (res_cur) {
1389 res_tmp = res_cur;
1390 if (res_cur->next)
1391 res_cur = res_cur->next;
1392 else
1393 res_cur = res_cur->nextRange;
1394 kfree (res_tmp);
1395 res_tmp = NULL;
1396 }
1397 bus->firstMem = NULL;
1398 }
1399 if (bus->firstPFMem) {
1400 res_cur = bus->firstPFMem;
1401 while (res_cur) {
1402 res_tmp = res_cur;
1403 if (res_cur->next)
1404 res_cur = res_cur->next;
1405 else
1406 res_cur = res_cur->nextRange;
1407 kfree (res_tmp);
1408 res_tmp = NULL;
1409 }
1410 bus->firstPFMem = NULL;
1411 }
1412
1413 if (bus->firstPFMemFromMem) {
1414 res_cur = bus->firstPFMemFromMem;
1415 while (res_cur) {
1416 res_tmp = res_cur;
1417 res_cur = res_cur->next;
1418
1419 kfree (res_tmp);
1420 res_tmp = NULL;
1421 }
1422 bus->firstPFMemFromMem = NULL;
1423 }
1424
1425 list_del (&bus->bus_list);
1426 kfree (bus);
1427 return 0;
1428}
1429
1430/******************************************************************************
1431 * This routine deletes the ranges from a given bus, and the entries from the
1432 * parent's bus in the resources
1433 * Input: current bus, previous bus
1434 * Output: 0, -EINVAL
1435 ******************************************************************************/
1436static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
1437{
1438 struct range_node *range_cur;
1439 struct range_node *range_tmp;
1440 int i;
1441 struct resource_node *res = NULL;
1442
1443 if (bus_cur->noIORanges) {
1444 range_cur = bus_cur->rangeIO;
1445 for (i = 0; i < bus_cur->noIORanges; i++) {
1446 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
1447 return -EINVAL;
1448 ibmphp_remove_resource (res);
1449
1450 range_tmp = range_cur;
1451 range_cur = range_cur->next;
1452 kfree (range_tmp);
1453 range_tmp = NULL;
1454 }
1455 bus_cur->rangeIO = NULL;
1456 }
1457 if (bus_cur->noMemRanges) {
1458 range_cur = bus_cur->rangeMem;
1459 for (i = 0; i < bus_cur->noMemRanges; i++) {
1460 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0)
1461 return -EINVAL;
1462
1463 ibmphp_remove_resource (res);
1464 range_tmp = range_cur;
1465 range_cur = range_cur->next;
1466 kfree (range_tmp);
1467 range_tmp = NULL;
1468 }
1469 bus_cur->rangeMem = NULL;
1470 }
1471 if (bus_cur->noPFMemRanges) {
1472 range_cur = bus_cur->rangePFMem;
1473 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1474 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0)
1475 return -EINVAL;
1476
1477 ibmphp_remove_resource (res);
1478 range_tmp = range_cur;
1479 range_cur = range_cur->next;
1480 kfree (range_tmp);
1481 range_tmp = NULL;
1482 }
1483 bus_cur->rangePFMem = NULL;
1484 }
1485 return 0;
1486}
1487
1488/*
1489 * find the resource node in the bus
1490 * Input: Resource needed, start address of the resource, type of resource
1491 */
1492int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
1493{
1494 struct resource_node *res_cur = NULL;
1495 char * type = "";
1496
1497 if (!bus) {
1498 err ("The bus passed in NULL to find resource\n");
1499 return -ENODEV;
1500 }
1501
1502 switch (flag) {
1503 case IO:
1504 res_cur = bus->firstIO;
1505 type = "io";
1506 break;
1507 case MEM:
1508 res_cur = bus->firstMem;
1509 type = "mem";
1510 break;
1511 case PFMEM:
1512 res_cur = bus->firstPFMem;
1513 type = "pfmem";
1514 break;
1515 default:
1516 err ("wrong type of flag\n");
1517 return -EINVAL;
1518 }
1519
1520 while (res_cur) {
1521 if (res_cur->start == start_address) {
1522 *res = res_cur;
1523 break;
1524 }
1525 if (res_cur->next)
1526 res_cur = res_cur->next;
1527 else
1528 res_cur = res_cur->nextRange;
1529 }
1530
1531 if (!res_cur) {
1532 if (flag == PFMEM) {
1533 res_cur = bus->firstPFMemFromMem;
1534 while (res_cur) {
1535 if (res_cur->start == start_address) {
1536 *res = res_cur;
1537 break;
1538 }
1539 res_cur = res_cur->next;
1540 }
1541 if (!res_cur) {
1542 debug ("SOS...cannot find %s resource in the bus.\n", type);
1543 return -EINVAL;
1544 }
1545 } else {
1546 debug ("SOS... cannot find %s resource in the bus.\n", type);
1547 return -EINVAL;
1548 }
1549 }
1550
1551 if (*res)
1552 debug ("*res->start = %x\n", (*res)->start);
1553
1554 return 0;
1555}
1556
1557/***********************************************************************
1558 * This routine will free the resource structures used by the
1559 * system. It is called from cleanup routine for the module
1560 * Parameters: none
1561 * Returns: none
1562 ***********************************************************************/
1563void ibmphp_free_resources (void)
1564{
1565 struct bus_node *bus_cur = NULL;
1566 struct bus_node *bus_tmp;
1567 struct range_node *range_cur;
1568 struct range_node *range_tmp;
1569 struct resource_node *res_cur;
1570 struct resource_node *res_tmp;
1571 struct list_head *tmp;
1572 struct list_head *next;
1573 int i = 0;
1574 flags = 1;
1575
1576 list_for_each_safe (tmp, next, &gbuses) {
1577 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1578 if (bus_cur->noIORanges) {
1579 range_cur = bus_cur->rangeIO;
1580 for (i = 0; i < bus_cur->noIORanges; i++) {
1581 if (!range_cur)
1582 break;
1583 range_tmp = range_cur;
1584 range_cur = range_cur->next;
1585 kfree (range_tmp);
1586 range_tmp = NULL;
1587 }
1588 }
1589 if (bus_cur->noMemRanges) {
1590 range_cur = bus_cur->rangeMem;
1591 for (i = 0; i < bus_cur->noMemRanges; i++) {
1592 if (!range_cur)
1593 break;
1594 range_tmp = range_cur;
1595 range_cur = range_cur->next;
1596 kfree (range_tmp);
1597 range_tmp = NULL;
1598 }
1599 }
1600 if (bus_cur->noPFMemRanges) {
1601 range_cur = bus_cur->rangePFMem;
1602 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1603 if (!range_cur)
1604 break;
1605 range_tmp = range_cur;
1606 range_cur = range_cur->next;
1607 kfree (range_tmp);
1608 range_tmp = NULL;
1609 }
1610 }
1611
1612 if (bus_cur->firstIO) {
1613 res_cur = bus_cur->firstIO;
1614 while (res_cur) {
1615 res_tmp = res_cur;
1616 if (res_cur->next)
1617 res_cur = res_cur->next;
1618 else
1619 res_cur = res_cur->nextRange;
1620 kfree (res_tmp);
1621 res_tmp = NULL;
1622 }
1623 bus_cur->firstIO = NULL;
1624 }
1625 if (bus_cur->firstMem) {
1626 res_cur = bus_cur->firstMem;
1627 while (res_cur) {
1628 res_tmp = res_cur;
1629 if (res_cur->next)
1630 res_cur = res_cur->next;
1631 else
1632 res_cur = res_cur->nextRange;
1633 kfree (res_tmp);
1634 res_tmp = NULL;
1635 }
1636 bus_cur->firstMem = NULL;
1637 }
1638 if (bus_cur->firstPFMem) {
1639 res_cur = bus_cur->firstPFMem;
1640 while (res_cur) {
1641 res_tmp = res_cur;
1642 if (res_cur->next)
1643 res_cur = res_cur->next;
1644 else
1645 res_cur = res_cur->nextRange;
1646 kfree (res_tmp);
1647 res_tmp = NULL;
1648 }
1649 bus_cur->firstPFMem = NULL;
1650 }
1651
1652 if (bus_cur->firstPFMemFromMem) {
1653 res_cur = bus_cur->firstPFMemFromMem;
1654 while (res_cur) {
1655 res_tmp = res_cur;
1656 res_cur = res_cur->next;
1657
1658 kfree (res_tmp);
1659 res_tmp = NULL;
1660 }
1661 bus_cur->firstPFMemFromMem = NULL;
1662 }
1663
1664 bus_tmp = bus_cur;
1665 list_del (&bus_cur->bus_list);
1666 kfree (bus_tmp);
1667 bus_tmp = NULL;
1668 }
1669}
1670
1671/*********************************************************************************
1672 * This function will go over the PFmem resources to check if the EBDA allocated
1673 * pfmem out of memory buckets of the bus. If so, it will change the range numbers
1674 * and a flag to indicate that this resource is out of memory. It will also move the
1675 * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create
1676 * a new Mem node
1677 * This routine is called right after initialization
1678 *******************************************************************************/
1679static int __init once_over (void)
1680{
1681 struct resource_node *pfmem_cur;
1682 struct resource_node *pfmem_prev;
1683 struct resource_node *mem;
1684 struct bus_node *bus_cur;
1685 struct list_head *tmp;
1686
1687 list_for_each (tmp, &gbuses) {
1688 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1689 if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
1690 for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
1691 pfmem_cur->fromMem = TRUE;
1692 if (pfmem_prev)
1693 pfmem_prev->next = pfmem_cur->next;
1694 else
1695 bus_cur->firstPFMem = pfmem_cur->next;
1696
1697 if (!bus_cur->firstPFMemFromMem)
1698 pfmem_cur->next = NULL;
1699 else
1700 /* we don't need to sort PFMemFromMem since we're using mem node for
1701 all the real work anyways, so just insert at the beginning of the
1702 list
1703 */
1704 pfmem_cur->next = bus_cur->firstPFMemFromMem;
1705
1706 bus_cur->firstPFMemFromMem = pfmem_cur;
1707
1708 mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
1709 if (!mem) {
1710 err ("out of system memory\n");
1711 return -ENOMEM;
1712 }
1713 memset (mem, 0, sizeof (struct resource_node));
1714 mem->type = MEM;
1715 mem->busno = pfmem_cur->busno;
1716 mem->devfunc = pfmem_cur->devfunc;
1717 mem->start = pfmem_cur->start;
1718 mem->end = pfmem_cur->end;
1719 mem->len = pfmem_cur->len;
1720 if (ibmphp_add_resource (mem) < 0)
1721 err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
1722 pfmem_cur->rangeno = mem->rangeno;
1723 } /* end for pfmem */
1724 } /* end if */
1725 } /* end list_for_each bus */
1726 return 0;
1727}
1728
1729int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
1730{
1731 struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
1732
1733 if (!bus_cur) {
1734 err ("cannot find bus of pfmem to add...\n");
1735 return -ENODEV;
1736 }
1737
1738 if (bus_cur->firstPFMemFromMem)
1739 pfmem->next = bus_cur->firstPFMemFromMem;
1740 else
1741 pfmem->next = NULL;
1742
1743 bus_cur->firstPFMemFromMem = pfmem;
1744
1745 return 0;
1746}
1747
1748/* This routine just goes through the buses to see if the bus already exists.
1749 * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
1750 * bridged cards
1751 * Parameters: bus_number
1752 * Returns: Bus pointer or NULL
1753 */
1754struct bus_node *ibmphp_find_res_bus (u8 bus_number)
1755{
1756 return find_bus_wprev (bus_number, NULL, 0);
1757}
1758
1759static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
1760{
1761 struct bus_node *bus_cur;
1762 struct list_head *tmp;
1763 struct list_head *tmp_prev;
1764
1765 list_for_each (tmp, &gbuses) {
1766 tmp_prev = tmp->prev;
1767 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1768 if (flag)
1769 *prev = list_entry (tmp_prev, struct bus_node, bus_list);
1770 if (bus_cur->busno == bus_number)
1771 return bus_cur;
1772 }
1773
1774 return NULL;
1775}
1776
1777void ibmphp_print_test (void)
1778{
1779 int i = 0;
1780 struct bus_node *bus_cur = NULL;
1781 struct range_node *range;
1782 struct resource_node *res;
1783 struct list_head *tmp;
1784
1785 debug_pci ("*****************START**********************\n");
1786
1787 if ((!list_empty(&gbuses)) && flags) {
1788 err ("The GBUSES is not NULL?!?!?!?!?\n");
1789 return;
1790 }
1791
1792 list_for_each (tmp, &gbuses) {
1793 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1794 debug_pci ("This is bus # %d. There are\n", bus_cur->busno);
1795 debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
1796 debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
1797 debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
1798 debug_pci ("The IO Ranges are as follows:\n");
1799 if (bus_cur->rangeIO) {
1800 range = bus_cur->rangeIO;
1801 for (i = 0; i < bus_cur->noIORanges; i++) {
1802 debug_pci ("rangeno is %d\n", range->rangeno);
1803 debug_pci ("[%x - %x]\n", range->start, range->end);
1804 range = range->next;
1805 }
1806 }
1807
1808 debug_pci ("The Mem Ranges are as follows:\n");
1809 if (bus_cur->rangeMem) {
1810 range = bus_cur->rangeMem;
1811 for (i = 0; i < bus_cur->noMemRanges; i++) {
1812 debug_pci ("rangeno is %d\n", range->rangeno);
1813 debug_pci ("[%x - %x]\n", range->start, range->end);
1814 range = range->next;
1815 }
1816 }
1817
1818 debug_pci ("The PFMem Ranges are as follows:\n");
1819
1820 if (bus_cur->rangePFMem) {
1821 range = bus_cur->rangePFMem;
1822 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1823 debug_pci ("rangeno is %d\n", range->rangeno);
1824 debug_pci ("[%x - %x]\n", range->start, range->end);
1825 range = range->next;
1826 }
1827 }
1828
1829 debug_pci ("The resources on this bus are as follows\n");
1830
1831 debug_pci ("IO...\n");
1832 if (bus_cur->firstIO) {
1833 res = bus_cur->firstIO;
1834 while (res) {
1835 debug_pci ("The range # is %d\n", res->rangeno);
1836 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1837 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1838 if (res->next)
1839 res = res->next;
1840 else if (res->nextRange)
1841 res = res->nextRange;
1842 else
1843 break;
1844 }
1845 }
1846 debug_pci ("Mem...\n");
1847 if (bus_cur->firstMem) {
1848 res = bus_cur->firstMem;
1849 while (res) {
1850 debug_pci ("The range # is %d\n", res->rangeno);
1851 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1852 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1853 if (res->next)
1854 res = res->next;
1855 else if (res->nextRange)
1856 res = res->nextRange;
1857 else
1858 break;
1859 }
1860 }
1861 debug_pci ("PFMem...\n");
1862 if (bus_cur->firstPFMem) {
1863 res = bus_cur->firstPFMem;
1864 while (res) {
1865 debug_pci ("The range # is %d\n", res->rangeno);
1866 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1867 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1868 if (res->next)
1869 res = res->next;
1870 else if (res->nextRange)
1871 res = res->nextRange;
1872 else
1873 break;
1874 }
1875 }
1876
1877 debug_pci ("PFMemFromMem...\n");
1878 if (bus_cur->firstPFMemFromMem) {
1879 res = bus_cur->firstPFMemFromMem;
1880 while (res) {
1881 debug_pci ("The range # is %d\n", res->rangeno);
1882 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1883 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1884 res = res->next;
1885 }
1886 }
1887 }
1888 debug_pci ("***********************END***********************\n");
1889}
1890
1891static int range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
1892{
1893 struct range_node * range_cur = NULL;
1894 switch (type) {
1895 case IO:
1896 range_cur = bus_cur->rangeIO;
1897 break;
1898 case MEM:
1899 range_cur = bus_cur->rangeMem;
1900 break;
1901 case PFMEM:
1902 range_cur = bus_cur->rangePFMem;
1903 break;
1904 default:
1905 err ("wrong type passed to find out if range already exists\n");
1906 return -ENODEV;
1907 }
1908
1909 while (range_cur) {
1910 if ((range_cur->start == range->start) && (range_cur->end == range->end))
1911 return 1;
1912 range_cur = range_cur->next;
1913 }
1914
1915 return 0;
1916}
1917
1918/* This routine will read the windows for any PPB we have and update the
1919 * range info for the secondary bus, and will also input this info into
1920 * primary bus, since BIOS doesn't. This is for PPB that are in the system
1921 * on bootup. For bridged cards that were added during previous load of the
1922 * driver, only the ranges and the bus structure are added, the devices are
1923 * added from NVRAM
1924 * Input: primary busno
1925 * Returns: none
1926 * Note: this function doesn't take into account IO restrictions etc,
1927 * so will only work for bridges with no video/ISA devices behind them It
1928 * also will not work for onboard PPB's that can have more than 1 *bus
1929 * behind them All these are TO DO.
1930 * Also need to add more error checkings... (from fnc returns etc)
1931 */
1932static int __init update_bridge_ranges (struct bus_node **bus)
1933{
1934 u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
1935 u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
1936 u32 start_address, end_address, upper_start, upper_end;
1937 struct bus_node *bus_sec;
1938 struct bus_node *bus_cur;
1939 struct resource_node *io;
1940 struct resource_node *mem;
1941 struct resource_node *pfmem;
1942 struct range_node *range;
1943 unsigned int devfn;
1944
1945 bus_cur = *bus;
1946 if (!bus_cur)
1947 return -ENODEV;
1948 ibmphp_pci_bus->number = bus_cur->busno;
1949
1950 debug ("inside %s\n", __FUNCTION__);
1951 debug ("bus_cur->busno = %x\n", bus_cur->busno);
1952
1953 for (device = 0; device < 32; device++) {
1954 for (function = 0x00; function < 0x08; function++) {
1955 devfn = PCI_DEVFN(device, function);
1956 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1957
1958 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1959 /* found correct device!!! */
1960 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1961
1962 switch (hdr_type) {
1963 case PCI_HEADER_TYPE_NORMAL:
1964 function = 0x8;
1965 break;
1966 case PCI_HEADER_TYPE_MULTIDEVICE:
1967 break;
1968 case PCI_HEADER_TYPE_BRIDGE:
1969 function = 0x8;
1970 case PCI_HEADER_TYPE_MULTIBRIDGE:
1971 /* We assume here that only 1 bus behind the bridge
1972 TO DO: add functionality for several:
1973 temp = secondary;
1974 while (temp < subordinate) {
1975 ...
1976 temp++;
1977 }
1978 */
1979 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
1980 bus_sec = find_bus_wprev (sec_busno, NULL, 0);
1981 /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
1982 if (!bus_sec) {
1983 bus_sec = alloc_error_bus (NULL, sec_busno, 1);
1984 /* the rest will be populated during NVRAM call */
1985 return 0;
1986 }
1987 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
1988 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
1989 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
1990 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
1991 start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
1992 start_address |= (upper_io_start << 16);
1993 end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
1994 end_address |= (upper_io_end << 16);
1995
1996 if ((start_address) && (start_address <= end_address)) {
1997 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
1998 if (!range) {
1999 err ("out of system memory\n");
2000 return -ENOMEM;
2001 }
2002 memset (range, 0, sizeof (struct range_node));
2003 range->start = start_address;
2004 range->end = end_address + 0xfff;
2005
2006 if (bus_sec->noIORanges > 0) {
2007 if (!range_exists_already (range, bus_sec, IO)) {
2008 add_range (IO, range, bus_sec);
2009 ++bus_sec->noIORanges;
2010 } else {
2011 kfree (range);
2012 range = NULL;
2013 }
2014 } else {
2015 /* 1st IO Range on the bus */
2016 range->rangeno = 1;
2017 bus_sec->rangeIO = range;
2018 ++bus_sec->noIORanges;
2019 }
2020 fix_resources (bus_sec);
2021
2022 if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
2023 io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2024 if (!io) {
2025 kfree (range);
2026 err ("out of system memory\n");
2027 return -ENOMEM;
2028 }
2029 memset (io, 0, sizeof (struct resource_node));
2030 io->type = IO;
2031 io->busno = bus_cur->busno;
2032 io->devfunc = ((device << 3) | (function & 0x7));
2033 io->start = start_address;
2034 io->end = end_address + 0xfff;
2035 io->len = io->end - io->start + 1;
2036 ibmphp_add_resource (io);
2037 }
2038 }
2039
2040 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
2041 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
2042
2043 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2044 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2045
2046 if ((start_address) && (start_address <= end_address)) {
2047
2048 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
2049 if (!range) {
2050 err ("out of system memory\n");
2051 return -ENOMEM;
2052 }
2053 memset (range, 0, sizeof (struct range_node));
2054 range->start = start_address;
2055 range->end = end_address + 0xfffff;
2056
2057 if (bus_sec->noMemRanges > 0) {
2058 if (!range_exists_already (range, bus_sec, MEM)) {
2059 add_range (MEM, range, bus_sec);
2060 ++bus_sec->noMemRanges;
2061 } else {
2062 kfree (range);
2063 range = NULL;
2064 }
2065 } else {
2066 /* 1st Mem Range on the bus */
2067 range->rangeno = 1;
2068 bus_sec->rangeMem = range;
2069 ++bus_sec->noMemRanges;
2070 }
2071
2072 fix_resources (bus_sec);
2073
2074 if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
2075 mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2076 if (!mem) {
2077 kfree (range);
2078 err ("out of system memory\n");
2079 return -ENOMEM;
2080 }
2081 memset (mem, 0, sizeof (struct resource_node));
2082 mem->type = MEM;
2083 mem->busno = bus_cur->busno;
2084 mem->devfunc = ((device << 3) | (function & 0x7));
2085 mem->start = start_address;
2086 mem->end = end_address + 0xfffff;
2087 mem->len = mem->end - mem->start + 1;
2088 ibmphp_add_resource (mem);
2089 }
2090 }
2091 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
2092 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
2093 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
2094 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
2095 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2096 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2097#if BITS_PER_LONG == 64
2098 start_address |= ((long) upper_start) << 32;
2099 end_address |= ((long) upper_end) << 32;
2100#endif
2101
2102 if ((start_address) && (start_address <= end_address)) {
2103
2104 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
2105 if (!range) {
2106 err ("out of system memory\n");
2107 return -ENOMEM;
2108 }
2109 memset (range, 0, sizeof (struct range_node));
2110 range->start = start_address;
2111 range->end = end_address + 0xfffff;
2112
2113 if (bus_sec->noPFMemRanges > 0) {
2114 if (!range_exists_already (range, bus_sec, PFMEM)) {
2115 add_range (PFMEM, range, bus_sec);
2116 ++bus_sec->noPFMemRanges;
2117 } else {
2118 kfree (range);
2119 range = NULL;
2120 }
2121 } else {
2122 /* 1st PFMem Range on the bus */
2123 range->rangeno = 1;
2124 bus_sec->rangePFMem = range;
2125 ++bus_sec->noPFMemRanges;
2126 }
2127
2128 fix_resources (bus_sec);
2129 if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
2130 pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2131 if (!pfmem) {
2132 kfree (range);
2133 err ("out of system memory\n");
2134 return -ENOMEM;
2135 }
2136 memset (pfmem, 0, sizeof (struct resource_node));
2137 pfmem->type = PFMEM;
2138 pfmem->busno = bus_cur->busno;
2139 pfmem->devfunc = ((device << 3) | (function & 0x7));
2140 pfmem->start = start_address;
2141 pfmem->end = end_address + 0xfffff;
2142 pfmem->len = pfmem->end - pfmem->start + 1;
2143 pfmem->fromMem = FALSE;
2144
2145 ibmphp_add_resource (pfmem);
2146 }
2147 }
2148 break;
2149 } /* end of switch */
2150 } /* end if vendor */
2151 } /* end for function */
2152 } /* end for device */
2153
2154 bus = &bus_cur;
2155 return 0;
2156}
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
new file mode 100644
index 000000000000..57ace325168d
--- /dev/null
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -0,0 +1,180 @@
1/*
2 * PCI HotPlug Core Functions
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28#ifndef _PCI_HOTPLUG_H
29#define _PCI_HOTPLUG_H
30
31
32/* These values come from the PCI Hotplug Spec */
33enum pci_bus_speed {
34 PCI_SPEED_33MHz = 0x00,
35 PCI_SPEED_66MHz = 0x01,
36 PCI_SPEED_66MHz_PCIX = 0x02,
37 PCI_SPEED_100MHz_PCIX = 0x03,
38 PCI_SPEED_133MHz_PCIX = 0x04,
39 PCI_SPEED_66MHz_PCIX_ECC = 0x05,
40 PCI_SPEED_100MHz_PCIX_ECC = 0x06,
41 PCI_SPEED_133MHz_PCIX_ECC = 0x07,
42 PCI_SPEED_66MHz_PCIX_266 = 0x09,
43 PCI_SPEED_100MHz_PCIX_266 = 0x0a,
44 PCI_SPEED_133MHz_PCIX_266 = 0x0b,
45 PCI_SPEED_66MHz_PCIX_533 = 0x11,
46 PCI_SPEED_100MHz_PCIX_533 = 0x12,
47 PCI_SPEED_133MHz_PCIX_533 = 0x13,
48 PCI_SPEED_UNKNOWN = 0xff,
49};
50
51/* These values come from the PCI Express Spec */
52enum pcie_link_width {
53 PCIE_LNK_WIDTH_RESRV = 0x00,
54 PCIE_LNK_X1 = 0x01,
55 PCIE_LNK_X2 = 0x02,
56 PCIE_LNK_X4 = 0x04,
57 PCIE_LNK_X8 = 0x08,
58 PCIE_LNK_X12 = 0x0C,
59 PCIE_LNK_X16 = 0x10,
60 PCIE_LNK_X32 = 0x20,
61 PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
62};
63
64enum pcie_link_speed {
65 PCIE_2PT5GB = 0x14,
66 PCIE_LNK_SPEED_UNKNOWN = 0xFF,
67};
68
69struct hotplug_slot;
70struct hotplug_slot_attribute {
71 struct attribute attr;
72 ssize_t (*show)(struct hotplug_slot *, char *);
73 ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
74};
75#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr);
76
77/**
78 * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
79 * @owner: The module owner of this structure
80 * @enable_slot: Called when the user wants to enable a specific pci slot
81 * @disable_slot: Called when the user wants to disable a specific pci slot
82 * @set_attention_status: Called to set the specific slot's attention LED to
83 * the specified value
84 * @hardware_test: Called to run a specified hardware test on the specified
85 * slot.
86 * @get_power_status: Called to get the current power status of a slot.
87 * If this field is NULL, the value passed in the struct hotplug_slot_info
88 * will be used when this value is requested by a user.
89 * @get_attention_status: Called to get the current attention status of a slot.
90 * If this field is NULL, the value passed in the struct hotplug_slot_info
91 * will be used when this value is requested by a user.
92 * @get_latch_status: Called to get the current latch status of a slot.
93 * If this field is NULL, the value passed in the struct hotplug_slot_info
94 * will be used when this value is requested by a user.
95 * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
96 * If this field is NULL, the value passed in the struct hotplug_slot_info
97 * will be used when this value is requested by a user.
98 * @get_address: Called to get pci address of a slot.
99 * If this field is NULL, the value passed in the struct hotplug_slot_info
100 * will be used when this value is requested by a user.
101 * @get_max_bus_speed: Called to get the max bus speed for a slot.
102 * If this field is NULL, the value passed in the struct hotplug_slot_info
103 * will be used when this value is requested by a user.
104 * @get_cur_bus_speed: Called to get the current bus speed for a slot.
105 * If this field is NULL, the value passed in the struct hotplug_slot_info
106 * will be used when this value is requested by a user.
107 *
108 * The table of function pointers that is passed to the hotplug pci core by a
109 * hotplug pci driver. These functions are called by the hotplug pci core when
110 * the user wants to do something to a specific slot (query it for information,
111 * set an LED, enable / disable power, etc.)
112 */
113struct hotplug_slot_ops {
114 struct module *owner;
115 int (*enable_slot) (struct hotplug_slot *slot);
116 int (*disable_slot) (struct hotplug_slot *slot);
117 int (*set_attention_status) (struct hotplug_slot *slot, u8 value);
118 int (*hardware_test) (struct hotplug_slot *slot, u32 value);
119 int (*get_power_status) (struct hotplug_slot *slot, u8 *value);
120 int (*get_attention_status) (struct hotplug_slot *slot, u8 *value);
121 int (*get_latch_status) (struct hotplug_slot *slot, u8 *value);
122 int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value);
123 int (*get_address) (struct hotplug_slot *slot, u32 *value);
124 int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
125 int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
126};
127
128/**
129 * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
130 * @power: if power is enabled or not (1/0)
131 * @attention_status: if the attention light is enabled or not (1/0)
132 * @latch_status: if the latch (if any) is open or closed (1/0)
133 * @adapter_present: if there is a pci board present in the slot or not (1/0)
134 * @address: (domain << 16 | bus << 8 | dev)
135 *
136 * Used to notify the hotplug pci core of the status of a specific slot.
137 */
138struct hotplug_slot_info {
139 u8 power_status;
140 u8 attention_status;
141 u8 latch_status;
142 u8 adapter_status;
143 u32 address;
144 enum pci_bus_speed max_bus_speed;
145 enum pci_bus_speed cur_bus_speed;
146};
147
148/**
149 * struct hotplug_slot - used to register a physical slot with the hotplug pci core
150 * @name: the name of the slot being registered. This string must
151 * be unique amoung slots registered on this system.
152 * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
153 * @info: pointer to the &struct hotplug_slot_info for the inital values for
154 * this slot.
155 * @release: called during pci_hp_deregister to free memory allocated in a
156 * hotplug_slot structure.
157 * @private: used by the hotplug pci controller driver to store whatever it
158 * needs.
159 */
160struct hotplug_slot {
161 char *name;
162 struct hotplug_slot_ops *ops;
163 struct hotplug_slot_info *info;
164 void (*release) (struct hotplug_slot *slot);
165 void *private;
166
167 /* Variables below this are for use only by the hotplug pci core. */
168 struct list_head slot_list;
169 struct kobject kobj;
170};
171#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
172
173extern int pci_hp_register (struct hotplug_slot *slot);
174extern int pci_hp_deregister (struct hotplug_slot *slot);
175extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
176 struct hotplug_slot_info *info);
177extern struct subsystem pci_hotplug_slots_subsys;
178
179#endif
180
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
new file mode 100644
index 000000000000..c802f6270b89
--- /dev/null
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -0,0 +1,715 @@
1/*
2 * PCI HotPlug Controller Core
3 *
4 * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2001-2002 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <greg@kroah.com>
25 *
26 * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/list.h>
36#include <linux/pagemap.h>
37#include <linux/slab.h>
38#include <linux/smp_lock.h>
39#include <linux/init.h>
40#include <linux/mount.h>
41#include <linux/namei.h>
42#include <linux/pci.h>
43#include <asm/uaccess.h>
44#include <linux/kobject.h>
45#include <linux/sysfs.h>
46#include "pci_hotplug.h"
47
48
49#define MY_NAME "pci_hotplug"
50
51#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
52#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
53#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
54#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
55
56
57/* local variables */
58static int debug;
59
60#define DRIVER_VERSION "0.5"
61#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
62#define DRIVER_DESC "PCI Hot Plug PCI Core"
63
64
65//////////////////////////////////////////////////////////////////
66
67static LIST_HEAD(pci_hotplug_slot_list);
68
69struct subsystem pci_hotplug_slots_subsys;
70
71static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
72 struct attribute *attr, char *buf)
73{
74 struct hotplug_slot *slot = to_hotplug_slot(kobj);
75 struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
76 return attribute->show ? attribute->show(slot, buf) : 0;
77}
78
79static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
80 struct attribute *attr, const char *buf, size_t len)
81{
82 struct hotplug_slot *slot = to_hotplug_slot(kobj);
83 struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
84 return attribute->store ? attribute->store(slot, buf, len) : 0;
85}
86
87static struct sysfs_ops hotplug_slot_sysfs_ops = {
88 .show = hotplug_slot_attr_show,
89 .store = hotplug_slot_attr_store,
90};
91
92static void hotplug_slot_release(struct kobject *kobj)
93{
94 struct hotplug_slot *slot = to_hotplug_slot(kobj);
95 if (slot->release)
96 slot->release(slot);
97}
98
99static struct kobj_type hotplug_slot_ktype = {
100 .sysfs_ops = &hotplug_slot_sysfs_ops,
101 .release = &hotplug_slot_release,
102};
103
104decl_subsys_name(pci_hotplug_slots, slots, &hotplug_slot_ktype, NULL);
105
106/* these strings match up with the values in pci_bus_speed */
107static char *pci_bus_speed_strings[] = {
108 "33 MHz PCI", /* 0x00 */
109 "66 MHz PCI", /* 0x01 */
110 "66 MHz PCIX", /* 0x02 */
111 "100 MHz PCIX", /* 0x03 */
112 "133 MHz PCIX", /* 0x04 */
113 NULL, /* 0x05 */
114 NULL, /* 0x06 */
115 NULL, /* 0x07 */
116 NULL, /* 0x08 */
117 "66 MHz PCIX 266", /* 0x09 */
118 "100 MHz PCIX 266", /* 0x0a */
119 "133 MHz PCIX 266", /* 0x0b */
120 NULL, /* 0x0c */
121 NULL, /* 0x0d */
122 NULL, /* 0x0e */
123 NULL, /* 0x0f */
124 NULL, /* 0x10 */
125 "66 MHz PCIX 533", /* 0x11 */
126 "100 MHz PCIX 533", /* 0x12 */
127 "133 MHz PCIX 533", /* 0x13 */
128 "25 GBps PCI-E", /* 0x14 */
129};
130
131#ifdef CONFIG_HOTPLUG_PCI_CPCI
132extern int cpci_hotplug_init(int debug);
133extern void cpci_hotplug_exit(void);
134#else
135static inline int cpci_hotplug_init(int debug) { return 0; }
136static inline void cpci_hotplug_exit(void) { }
137#endif
138
139/* Weee, fun with macros... */
140#define GET_STATUS(name,type) \
141static int get_##name (struct hotplug_slot *slot, type *value) \
142{ \
143 struct hotplug_slot_ops *ops = slot->ops; \
144 int retval = 0; \
145 if (try_module_get(ops->owner)) { \
146 if (ops->get_##name) \
147 retval = ops->get_##name (slot, value); \
148 else \
149 *value = slot->info->name; \
150 module_put(ops->owner); \
151 } \
152 return retval; \
153}
154
155GET_STATUS(power_status, u8)
156GET_STATUS(attention_status, u8)
157GET_STATUS(latch_status, u8)
158GET_STATUS(adapter_status, u8)
159GET_STATUS(address, u32)
160GET_STATUS(max_bus_speed, enum pci_bus_speed)
161GET_STATUS(cur_bus_speed, enum pci_bus_speed)
162
163static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
164{
165 int retval;
166 u8 value;
167
168 retval = get_power_status (slot, &value);
169 if (retval)
170 goto exit;
171 retval = sprintf (buf, "%d\n", value);
172exit:
173 return retval;
174}
175
176static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
177 size_t count)
178{
179 unsigned long lpower;
180 u8 power;
181 int retval = 0;
182
183 lpower = simple_strtoul (buf, NULL, 10);
184 power = (u8)(lpower & 0xff);
185 dbg ("power = %d\n", power);
186
187 if (!try_module_get(slot->ops->owner)) {
188 retval = -ENODEV;
189 goto exit;
190 }
191 switch (power) {
192 case 0:
193 if (slot->ops->disable_slot)
194 retval = slot->ops->disable_slot(slot);
195 break;
196
197 case 1:
198 if (slot->ops->enable_slot)
199 retval = slot->ops->enable_slot(slot);
200 break;
201
202 default:
203 err ("Illegal value specified for power\n");
204 retval = -EINVAL;
205 }
206 module_put(slot->ops->owner);
207
208exit:
209 if (retval)
210 return retval;
211 return count;
212}
213
214static struct hotplug_slot_attribute hotplug_slot_attr_power = {
215 .attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
216 .show = power_read_file,
217 .store = power_write_file
218};
219
220static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
221{
222 int retval;
223 u8 value;
224
225 retval = get_attention_status (slot, &value);
226 if (retval)
227 goto exit;
228 retval = sprintf (buf, "%d\n", value);
229
230exit:
231 return retval;
232}
233
234static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
235 size_t count)
236{
237 unsigned long lattention;
238 u8 attention;
239 int retval = 0;
240
241 lattention = simple_strtoul (buf, NULL, 10);
242 attention = (u8)(lattention & 0xff);
243 dbg (" - attention = %d\n", attention);
244
245 if (!try_module_get(slot->ops->owner)) {
246 retval = -ENODEV;
247 goto exit;
248 }
249 if (slot->ops->set_attention_status)
250 retval = slot->ops->set_attention_status(slot, attention);
251 module_put(slot->ops->owner);
252
253exit:
254 if (retval)
255 return retval;
256 return count;
257}
258
259static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
260 .attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
261 .show = attention_read_file,
262 .store = attention_write_file
263};
264
265static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
266{
267 int retval;
268 u8 value;
269
270 retval = get_latch_status (slot, &value);
271 if (retval)
272 goto exit;
273 retval = sprintf (buf, "%d\n", value);
274
275exit:
276 return retval;
277}
278
279static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
280 .attr = {.name = "latch", .mode = S_IFREG | S_IRUGO},
281 .show = latch_read_file,
282};
283
284static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
285{
286 int retval;
287 u8 value;
288
289 retval = get_adapter_status (slot, &value);
290 if (retval)
291 goto exit;
292 retval = sprintf (buf, "%d\n", value);
293
294exit:
295 return retval;
296}
297
298static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
299 .attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO},
300 .show = presence_read_file,
301};
302
303static ssize_t address_read_file (struct hotplug_slot *slot, char *buf)
304{
305 int retval;
306 u32 address;
307
308 retval = get_address (slot, &address);
309 if (retval)
310 goto exit;
311 retval = sprintf (buf, "%04x:%02x:%02x\n",
312 (address >> 16) & 0xffff,
313 (address >> 8) & 0xff,
314 address & 0xff);
315
316exit:
317 return retval;
318}
319
320static struct hotplug_slot_attribute hotplug_slot_attr_address = {
321 .attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
322 .show = address_read_file,
323};
324
325static char *unknown_speed = "Unknown bus speed";
326
327static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
328{
329 char *speed_string;
330 int retval;
331 enum pci_bus_speed value;
332
333 retval = get_max_bus_speed (slot, &value);
334 if (retval)
335 goto exit;
336
337 if (value == PCI_SPEED_UNKNOWN)
338 speed_string = unknown_speed;
339 else
340 speed_string = pci_bus_speed_strings[value];
341
342 retval = sprintf (buf, "%s\n", speed_string);
343
344exit:
345 return retval;
346}
347
348static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
349 .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO},
350 .show = max_bus_speed_read_file,
351};
352
353static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
354{
355 char *speed_string;
356 int retval;
357 enum pci_bus_speed value;
358
359 retval = get_cur_bus_speed (slot, &value);
360 if (retval)
361 goto exit;
362
363 if (value == PCI_SPEED_UNKNOWN)
364 speed_string = unknown_speed;
365 else
366 speed_string = pci_bus_speed_strings[value];
367
368 retval = sprintf (buf, "%s\n", speed_string);
369
370exit:
371 return retval;
372}
373
374static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
375 .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO},
376 .show = cur_bus_speed_read_file,
377};
378
379static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
380 size_t count)
381{
382 unsigned long ltest;
383 u32 test;
384 int retval = 0;
385
386 ltest = simple_strtoul (buf, NULL, 10);
387 test = (u32)(ltest & 0xffffffff);
388 dbg ("test = %d\n", test);
389
390 if (!try_module_get(slot->ops->owner)) {
391 retval = -ENODEV;
392 goto exit;
393 }
394 if (slot->ops->hardware_test)
395 retval = slot->ops->hardware_test(slot, test);
396 module_put(slot->ops->owner);
397
398exit:
399 if (retval)
400 return retval;
401 return count;
402}
403
404static struct hotplug_slot_attribute hotplug_slot_attr_test = {
405 .attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
406 .store = test_write_file
407};
408
409static int has_power_file (struct hotplug_slot *slot)
410{
411 if ((!slot) || (!slot->ops))
412 return -ENODEV;
413 if ((slot->ops->enable_slot) ||
414 (slot->ops->disable_slot) ||
415 (slot->ops->get_power_status))
416 return 0;
417 return -ENOENT;
418}
419
420static int has_attention_file (struct hotplug_slot *slot)
421{
422 if ((!slot) || (!slot->ops))
423 return -ENODEV;
424 if ((slot->ops->set_attention_status) ||
425 (slot->ops->get_attention_status))
426 return 0;
427 return -ENOENT;
428}
429
430static int has_latch_file (struct hotplug_slot *slot)
431{
432 if ((!slot) || (!slot->ops))
433 return -ENODEV;
434 if (slot->ops->get_latch_status)
435 return 0;
436 return -ENOENT;
437}
438
439static int has_adapter_file (struct hotplug_slot *slot)
440{
441 if ((!slot) || (!slot->ops))
442 return -ENODEV;
443 if (slot->ops->get_adapter_status)
444 return 0;
445 return -ENOENT;
446}
447
448static int has_address_file (struct hotplug_slot *slot)
449{
450 if ((!slot) || (!slot->ops))
451 return -ENODEV;
452 if (slot->ops->get_address)
453 return 0;
454 return -ENOENT;
455}
456
457static int has_max_bus_speed_file (struct hotplug_slot *slot)
458{
459 if ((!slot) || (!slot->ops))
460 return -ENODEV;
461 if (slot->ops->get_max_bus_speed)
462 return 0;
463 return -ENOENT;
464}
465
466static int has_cur_bus_speed_file (struct hotplug_slot *slot)
467{
468 if ((!slot) || (!slot->ops))
469 return -ENODEV;
470 if (slot->ops->get_cur_bus_speed)
471 return 0;
472 return -ENOENT;
473}
474
475static int has_test_file (struct hotplug_slot *slot)
476{
477 if ((!slot) || (!slot->ops))
478 return -ENODEV;
479 if (slot->ops->hardware_test)
480 return 0;
481 return -ENOENT;
482}
483
484static int fs_add_slot (struct hotplug_slot *slot)
485{
486 if (has_power_file(slot) == 0)
487 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
488
489 if (has_attention_file(slot) == 0)
490 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
491
492 if (has_latch_file(slot) == 0)
493 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
494
495 if (has_adapter_file(slot) == 0)
496 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
497
498 if (has_address_file(slot) == 0)
499 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_address.attr);
500
501 if (has_max_bus_speed_file(slot) == 0)
502 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
503
504 if (has_cur_bus_speed_file(slot) == 0)
505 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
506
507 if (has_test_file(slot) == 0)
508 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
509
510 return 0;
511}
512
513static void fs_remove_slot (struct hotplug_slot *slot)
514{
515 if (has_power_file(slot) == 0)
516 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
517
518 if (has_attention_file(slot) == 0)
519 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
520
521 if (has_latch_file(slot) == 0)
522 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
523
524 if (has_adapter_file(slot) == 0)
525 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
526
527 if (has_address_file(slot) == 0)
528 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr);
529
530 if (has_max_bus_speed_file(slot) == 0)
531 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
532
533 if (has_cur_bus_speed_file(slot) == 0)
534 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
535
536 if (has_test_file(slot) == 0)
537 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
538}
539
540static struct hotplug_slot *get_slot_from_name (const char *name)
541{
542 struct hotplug_slot *slot;
543 struct list_head *tmp;
544
545 list_for_each (tmp, &pci_hotplug_slot_list) {
546 slot = list_entry (tmp, struct hotplug_slot, slot_list);
547 if (strcmp(slot->name, name) == 0)
548 return slot;
549 }
550 return NULL;
551}
552
553/**
554 * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
555 * @slot: pointer to the &struct hotplug_slot to register
556 *
557 * Registers a hotplug slot with the pci hotplug subsystem, which will allow
558 * userspace interaction to the slot.
559 *
560 * Returns 0 if successful, anything else for an error.
561 */
562int pci_hp_register (struct hotplug_slot *slot)
563{
564 int result;
565
566 if (slot == NULL)
567 return -ENODEV;
568 if ((slot->info == NULL) || (slot->ops == NULL))
569 return -EINVAL;
570 if (slot->release == NULL) {
571 dbg("Why are you trying to register a hotplug slot"
572 "without a proper release function?\n");
573 return -EINVAL;
574 }
575
576 kobject_set_name(&slot->kobj, "%s", slot->name);
577 kobj_set_kset_s(slot, pci_hotplug_slots_subsys);
578
579 /* this can fail if we have already registered a slot with the same name */
580 if (kobject_register(&slot->kobj)) {
581 err("Unable to register kobject");
582 return -EINVAL;
583 }
584
585 list_add (&slot->slot_list, &pci_hotplug_slot_list);
586
587 result = fs_add_slot (slot);
588 dbg ("Added slot %s to the list\n", slot->name);
589 return result;
590}
591
592/**
593 * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
594 * @slot: pointer to the &struct hotplug_slot to deregister
595 *
596 * The @slot must have been registered with the pci hotplug subsystem
597 * previously with a call to pci_hp_register().
598 *
599 * Returns 0 if successful, anything else for an error.
600 */
601int pci_hp_deregister (struct hotplug_slot *slot)
602{
603 struct hotplug_slot *temp;
604
605 if (slot == NULL)
606 return -ENODEV;
607
608 temp = get_slot_from_name (slot->name);
609 if (temp != slot) {
610 return -ENODEV;
611 }
612 list_del (&slot->slot_list);
613
614 fs_remove_slot (slot);
615 dbg ("Removed slot %s from the list\n", slot->name);
616 kobject_unregister(&slot->kobj);
617 return 0;
618}
619
620/**
621 * pci_hp_change_slot_info - changes the slot's information structure in the core
622 * @slot: pointer to the slot whose info has changed
623 * @info: pointer to the info copy into the slot's info structure
624 *
625 * @slot must have been registered with the pci
626 * hotplug subsystem previously with a call to pci_hp_register().
627 *
628 * Returns 0 if successful, anything else for an error.
629 */
630int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info)
631{
632 if ((slot == NULL) || (info == NULL))
633 return -ENODEV;
634
635 /*
636 * check all fields in the info structure, and update timestamps
637 * for the files referring to the fields that have now changed.
638 */
639 if ((has_power_file(slot) == 0) &&
640 (slot->info->power_status != info->power_status))
641 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr);
642
643 if ((has_attention_file(slot) == 0) &&
644 (slot->info->attention_status != info->attention_status))
645 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
646
647 if ((has_latch_file(slot) == 0) &&
648 (slot->info->latch_status != info->latch_status))
649 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
650
651 if ((has_adapter_file(slot) == 0) &&
652 (slot->info->adapter_status != info->adapter_status))
653 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
654
655 if ((has_address_file(slot) == 0) &&
656 (slot->info->address != info->address))
657 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_address.attr);
658
659 if ((has_max_bus_speed_file(slot) == 0) &&
660 (slot->info->max_bus_speed != info->max_bus_speed))
661 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
662
663 if ((has_cur_bus_speed_file(slot) == 0) &&
664 (slot->info->cur_bus_speed != info->cur_bus_speed))
665 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
666
667 memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
668
669 return 0;
670}
671
672static int __init pci_hotplug_init (void)
673{
674 int result;
675
676 kset_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys);
677 result = subsystem_register(&pci_hotplug_slots_subsys);
678 if (result) {
679 err("Register subsys with error %d\n", result);
680 goto exit;
681 }
682 result = cpci_hotplug_init(debug);
683 if (result) {
684 err ("cpci_hotplug_init with error %d\n", result);
685 goto err_subsys;
686 }
687
688 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
689 goto exit;
690
691err_subsys:
692 subsystem_unregister(&pci_hotplug_slots_subsys);
693exit:
694 return result;
695}
696
697static void __exit pci_hotplug_exit (void)
698{
699 cpci_hotplug_exit();
700 subsystem_unregister(&pci_hotplug_slots_subsys);
701}
702
703module_init(pci_hotplug_init);
704module_exit(pci_hotplug_exit);
705
706MODULE_AUTHOR(DRIVER_AUTHOR);
707MODULE_DESCRIPTION(DRIVER_DESC);
708MODULE_LICENSE("GPL");
709module_param(debug, bool, 0644);
710MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
711
712EXPORT_SYMBOL_GPL(pci_hotplug_slots_subsys);
713EXPORT_SYMBOL_GPL(pci_hp_register);
714EXPORT_SYMBOL_GPL(pci_hp_deregister);
715EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
new file mode 100644
index 000000000000..f313121d5141
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp.h
@@ -0,0 +1,352 @@
1/*
2 * PCI Express Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29#ifndef _PCIEHP_H
30#define _PCIEHP_H
31
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include <linux/pcieport_if.h>
38#include "pci_hotplug.h"
39
40#define MY_NAME "pciehp"
41
42extern int pciehp_poll_mode;
43extern int pciehp_poll_time;
44extern int pciehp_debug;
45
46/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
47#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
48#define err(format, arg...) printk(KERN_ERR "%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)
51
52struct pci_func {
53 struct pci_func *next;
54 u8 bus;
55 u8 device;
56 u8 function;
57 u8 is_a_board;
58 u16 status;
59 u8 configured;
60 u8 switch_save;
61 u8 presence_save;
62 u32 base_length[0x06];
63 u8 base_type[0x06];
64 u16 reserved2;
65 u32 config_space[0x20];
66 struct pci_resource *mem_head;
67 struct pci_resource *p_mem_head;
68 struct pci_resource *io_head;
69 struct pci_resource *bus_head;
70 struct pci_dev* pci_dev;
71};
72
73struct slot {
74 struct slot *next;
75 u8 bus;
76 u8 device;
77 u32 number;
78 u8 is_a_board;
79 u8 configured;
80 u8 state;
81 u8 switch_save;
82 u8 presence_save;
83 u32 capabilities;
84 u16 reserved2;
85 struct timer_list task_event;
86 u8 hp_slot;
87 struct controller *ctrl;
88 struct hpc_ops *hpc_ops;
89 struct hotplug_slot *hotplug_slot;
90 struct list_head slot_list;
91};
92
93struct pci_resource {
94 struct pci_resource * next;
95 u32 base;
96 u32 length;
97};
98
99struct event_info {
100 u32 event_type;
101 u8 hp_slot;
102};
103
104struct controller {
105 struct controller *next;
106 struct semaphore crit_sect; /* critical section semaphore */
107 void *hpc_ctlr_handle; /* HPC controller handle */
108 int num_slots; /* Number of slots on ctlr */
109 int slot_num_inc; /* 1 or -1 */
110 struct pci_resource *mem_head;
111 struct pci_resource *p_mem_head;
112 struct pci_resource *io_head;
113 struct pci_resource *bus_head;
114 struct pci_dev *pci_dev;
115 struct pci_bus *pci_bus;
116 struct event_info event_queue[10];
117 struct slot *slot;
118 struct hpc_ops *hpc_ops;
119 wait_queue_head_t queue; /* sleep & wake process */
120 u8 next_event;
121 u8 seg;
122 u8 bus;
123 u8 device;
124 u8 function;
125 u8 rev;
126 u8 slot_device_offset;
127 u8 add_support;
128 enum pci_bus_speed speed;
129 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
130 u8 slot_bus; /* Bus where the slots handled by this controller sit */
131 u8 ctrlcap;
132 u16 vendor_id;
133};
134
135struct irq_mapping {
136 u8 barber_pole;
137 u8 valid_INT;
138 u8 interrupt[4];
139};
140
141struct resource_lists {
142 struct pci_resource *mem_head;
143 struct pci_resource *p_mem_head;
144 struct pci_resource *io_head;
145 struct pci_resource *bus_head;
146 struct irq_mapping *irqs;
147};
148
149#define INT_BUTTON_IGNORE 0
150#define INT_PRESENCE_ON 1
151#define INT_PRESENCE_OFF 2
152#define INT_SWITCH_CLOSE 3
153#define INT_SWITCH_OPEN 4
154#define INT_POWER_FAULT 5
155#define INT_POWER_FAULT_CLEAR 6
156#define INT_BUTTON_PRESS 7
157#define INT_BUTTON_RELEASE 8
158#define INT_BUTTON_CANCEL 9
159
160#define STATIC_STATE 0
161#define BLINKINGON_STATE 1
162#define BLINKINGOFF_STATE 2
163#define POWERON_STATE 3
164#define POWEROFF_STATE 4
165
166#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
167
168/* Error messages */
169#define INTERLOCK_OPEN 0x00000002
170#define ADD_NOT_SUPPORTED 0x00000003
171#define CARD_FUNCTIONING 0x00000005
172#define ADAPTER_NOT_SAME 0x00000006
173#define NO_ADAPTER_PRESENT 0x00000009
174#define NOT_ENOUGH_RESOURCES 0x0000000B
175#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
176#define WRONG_BUS_FREQUENCY 0x0000000D
177#define POWER_FAILURE 0x0000000E
178
179#define REMOVE_NOT_SUPPORTED 0x00000003
180
181#define DISABLE_CARD 1
182
183/* Field definitions in Slot Capabilities Register */
184#define ATTN_BUTTN_PRSN 0x00000001
185#define PWR_CTRL_PRSN 0x00000002
186#define MRL_SENS_PRSN 0x00000004
187#define ATTN_LED_PRSN 0x00000008
188#define PWR_LED_PRSN 0x00000010
189#define HP_SUPR_RM_SUP 0x00000020
190
191#define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN)
192#define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN)
193#define MRL_SENS(cap) (cap & MRL_SENS_PRSN)
194#define ATTN_LED(cap) (cap & ATTN_LED_PRSN)
195#define PWR_LED(cap) (cap & PWR_LED_PRSN)
196#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
197
198/*
199 * error Messages
200 */
201#define msg_initialization_err "Initialization failure, error=%d\n"
202#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
203#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
204#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
205#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
206#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
207#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
208#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
209#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
210
211/* controller functions */
212extern int pciehprm_find_available_resources (struct controller *ctrl);
213extern int pciehp_event_start_thread (void);
214extern void pciehp_event_stop_thread (void);
215extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
216extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
217extern int pciehp_enable_slot (struct slot *slot);
218extern int pciehp_disable_slot (struct slot *slot);
219
220extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id);
221extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id);
222extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
223extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
224/* extern void long_delay (int delay); */
225
226/* resource functions */
227extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
228
229/* pci functions */
230extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
231/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
232extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
233extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag);
234extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
235extern void pciehp_destroy_board_resources (struct pci_func * func);
236extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
237extern void pciehp_destroy_resource_list (struct resource_lists * resources);
238extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
239extern int pciehp_unconfigure_device (struct pci_func* func);
240
241
242/* Global variables */
243extern struct controller *pciehp_ctrl_list;
244extern struct pci_func *pciehp_slot_list[256];
245
246/* Inline functions */
247
248static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
249{
250 struct slot *p_slot, *tmp_slot = NULL;
251
252 p_slot = ctrl->slot;
253
254 dbg("p_slot = %p\n", p_slot);
255
256 while (p_slot && (p_slot->device != device)) {
257 tmp_slot = p_slot;
258 p_slot = p_slot->next;
259 dbg("In while loop, p_slot = %p\n", p_slot);
260 }
261 if (p_slot == NULL) {
262 err("ERROR: pciehp_find_slot device=0x%x\n", device);
263 p_slot = tmp_slot;
264 }
265
266 return p_slot;
267}
268
269static inline int wait_for_ctrl_irq(struct controller *ctrl)
270{
271 int retval = 0;
272
273 DECLARE_WAITQUEUE(wait, current);
274
275 dbg("%s : start\n", __FUNCTION__);
276 add_wait_queue(&ctrl->queue, &wait);
277 if (!pciehp_poll_mode)
278 /* Sleep for up to 1 second */
279 msleep_interruptible(1000);
280 else
281 msleep_interruptible(2500);
282
283 remove_wait_queue(&ctrl->queue, &wait);
284 if (signal_pending(current))
285 retval = -EINTR;
286
287 dbg("%s : end\n", __FUNCTION__);
288 return retval;
289}
290
291/* Puts node back in the resource list pointed to by head */
292static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
293{
294 if (!node || !head)
295 return;
296 node->next = *head;
297 *head = node;
298}
299
300#define SLOT_NAME_SIZE 10
301
302static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
303{
304 snprintf(buffer, buffer_size, "%d", slot->number);
305}
306
307enum php_ctlr_type {
308 PCI,
309 ISA,
310 ACPI
311};
312
313typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
314
315int pcie_init(struct controller *ctrl, struct pcie_device *dev,
316 php_intr_callback_t attention_button_callback,
317 php_intr_callback_t switch_change_callback,
318 php_intr_callback_t presence_change_callback,
319 php_intr_callback_t power_fault_callback);
320
321
322/* This has no meaning for PCI Express, as there is only 1 slot per port */
323int pcie_get_ctlr_slot_config(struct controller *ctrl,
324 int *num_ctlr_slots,
325 int *first_device_num,
326 int *physical_slot_num,
327 u8 *ctrlcap);
328
329struct hpc_ops {
330 int (*power_on_slot) (struct slot *slot);
331 int (*power_off_slot) (struct slot *slot);
332 int (*get_power_status) (struct slot *slot, u8 *status);
333 int (*get_attention_status) (struct slot *slot, u8 *status);
334 int (*set_attention_status) (struct slot *slot, u8 status);
335 int (*get_latch_status) (struct slot *slot, u8 *status);
336 int (*get_adapter_status) (struct slot *slot, u8 *status);
337
338 int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
339 int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
340
341 int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value);
342 int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value);
343
344 int (*query_power_fault) (struct slot *slot);
345 void (*green_led_on) (struct slot *slot);
346 void (*green_led_off) (struct slot *slot);
347 void (*green_led_blink) (struct slot *slot);
348 void (*release_ctlr) (struct controller *ctrl);
349 int (*check_lnk_status) (struct controller *ctrl);
350};
351
352#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
new file mode 100644
index 000000000000..8a5b2b51bde4
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -0,0 +1,662 @@
1/*
2 * PCI Express Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "pciehp.h"
42#include "pciehprm.h"
43#include <linux/interrupt.h>
44
45/* Global variables */
46int pciehp_debug;
47int pciehp_poll_mode;
48int pciehp_poll_time;
49struct controller *pciehp_ctrl_list;
50struct pci_func *pciehp_slot_list[256];
51
52#define DRIVER_VERSION "0.4"
53#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
54#define DRIVER_DESC "PCI Express Hot Plug Controller Driver"
55
56MODULE_AUTHOR(DRIVER_AUTHOR);
57MODULE_DESCRIPTION(DRIVER_DESC);
58MODULE_LICENSE("GPL");
59
60module_param(pciehp_debug, bool, 0644);
61module_param(pciehp_poll_mode, bool, 0644);
62module_param(pciehp_poll_time, int, 0644);
63MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
64MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
65MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
66
67#define PCIE_MODULE_NAME "pciehp"
68
69static int pcie_start_thread (void);
70static int set_attention_status (struct hotplug_slot *slot, u8 value);
71static int enable_slot (struct hotplug_slot *slot);
72static int disable_slot (struct hotplug_slot *slot);
73static int get_power_status (struct hotplug_slot *slot, u8 *value);
74static int get_attention_status (struct hotplug_slot *slot, u8 *value);
75static int get_latch_status (struct hotplug_slot *slot, u8 *value);
76static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
77static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
78static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
79
80static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
81 .owner = THIS_MODULE,
82 .set_attention_status = set_attention_status,
83 .enable_slot = enable_slot,
84 .disable_slot = disable_slot,
85 .get_power_status = get_power_status,
86 .get_attention_status = get_attention_status,
87 .get_latch_status = get_latch_status,
88 .get_adapter_status = get_adapter_status,
89 .get_max_bus_speed = get_max_bus_speed,
90 .get_cur_bus_speed = get_cur_bus_speed,
91};
92
93static int init_slots(struct controller *ctrl)
94{
95 struct slot *new_slot;
96 u8 number_of_slots;
97 u8 slot_device;
98 u32 slot_number;
99 int result = -ENOMEM;
100
101 dbg("%s\n",__FUNCTION__);
102
103 number_of_slots = ctrl->num_slots;
104 slot_device = ctrl->slot_device_offset;
105 slot_number = ctrl->first_slot;
106
107 while (number_of_slots) {
108 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
109 if (!new_slot)
110 goto error;
111
112 memset(new_slot, 0, sizeof(struct slot));
113 new_slot->hotplug_slot =
114 kmalloc(sizeof(*(new_slot->hotplug_slot)),
115 GFP_KERNEL);
116 if (!new_slot->hotplug_slot)
117 goto error_slot;
118 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
119
120 new_slot->hotplug_slot->info =
121 kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
122 GFP_KERNEL);
123 if (!new_slot->hotplug_slot->info)
124 goto error_hpslot;
125 memset(new_slot->hotplug_slot->info, 0,
126 sizeof(struct hotplug_slot_info));
127 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE,
128 GFP_KERNEL);
129 if (!new_slot->hotplug_slot->name)
130 goto error_info;
131
132 new_slot->ctrl = ctrl;
133 new_slot->bus = ctrl->slot_bus;
134 new_slot->device = slot_device;
135 new_slot->hpc_ops = ctrl->hpc_ops;
136
137 new_slot->number = ctrl->first_slot;
138 new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
139
140 /* register this slot with the hotplug pci core */
141 new_slot->hotplug_slot->private = new_slot;
142 make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
143 new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops;
144
145 new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
146 new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
147 new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
148 new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
149
150 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n",
151 new_slot->bus, new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
152 result = pci_hp_register (new_slot->hotplug_slot);
153 if (result) {
154 err ("pci_hp_register failed with error %d\n", result);
155 goto error_name;
156 }
157
158 new_slot->next = ctrl->slot;
159 ctrl->slot = new_slot;
160
161 number_of_slots--;
162 slot_device++;
163 slot_number += ctrl->slot_num_inc;
164 }
165
166 return 0;
167
168error_name:
169 kfree(new_slot->hotplug_slot->name);
170error_info:
171 kfree(new_slot->hotplug_slot->info);
172error_hpslot:
173 kfree(new_slot->hotplug_slot);
174error_slot:
175 kfree(new_slot);
176error:
177 return result;
178}
179
180
181static int cleanup_slots (struct controller * ctrl)
182{
183 struct slot *old_slot, *next_slot;
184
185 old_slot = ctrl->slot;
186 ctrl->slot = NULL;
187
188 while (old_slot) {
189 next_slot = old_slot->next;
190 pci_hp_deregister (old_slot->hotplug_slot);
191 kfree(old_slot->hotplug_slot->info);
192 kfree(old_slot->hotplug_slot->name);
193 kfree(old_slot->hotplug_slot);
194 kfree(old_slot);
195 old_slot = next_slot;
196 }
197
198
199 return(0);
200}
201
202static int get_ctlr_slot_config(struct controller *ctrl)
203{
204 int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/
205 int first_device_num; /* Not needed */
206 int physical_slot_num;
207 u8 ctrlcap;
208 int rc;
209
210 rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap);
211 if (rc) {
212 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
213 return (-1);
214 }
215
216 ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */
217 ctrl->slot_device_offset = first_device_num;
218 ctrl->first_slot = physical_slot_num;
219 ctrl->ctrlcap = ctrlcap;
220
221 dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n",
222 __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap,
223 ctrl->bus, ctrl->device);
224
225 return (0);
226}
227
228
229/*
230 * set_attention_status - Turns the Amber LED for a slot on, off or blink
231 */
232static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
233{
234 struct slot *slot = hotplug_slot->private;
235
236 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
237
238 hotplug_slot->info->attention_status = status;
239
240 if (ATTN_LED(slot->ctrl->ctrlcap))
241 slot->hpc_ops->set_attention_status(slot, status);
242
243 return 0;
244}
245
246
247static int enable_slot(struct hotplug_slot *hotplug_slot)
248{
249 struct slot *slot = hotplug_slot->private;
250
251 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
252
253 return pciehp_enable_slot(slot);
254}
255
256
257static int disable_slot(struct hotplug_slot *hotplug_slot)
258{
259 struct slot *slot = hotplug_slot->private;
260
261 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
262
263 return pciehp_disable_slot(slot);
264}
265
266static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
267{
268 struct slot *slot = hotplug_slot->private;
269 int retval;
270
271 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
272
273 retval = slot->hpc_ops->get_power_status(slot, value);
274 if (retval < 0)
275 *value = hotplug_slot->info->power_status;
276
277 return 0;
278}
279
280static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
281{
282 struct slot *slot = hotplug_slot->private;
283 int retval;
284
285 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
286
287 retval = slot->hpc_ops->get_attention_status(slot, value);
288 if (retval < 0)
289 *value = hotplug_slot->info->attention_status;
290
291 return 0;
292}
293
294static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
295{
296 struct slot *slot = hotplug_slot->private;
297 int retval;
298
299 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
300
301 retval = slot->hpc_ops->get_latch_status(slot, value);
302 if (retval < 0)
303 *value = hotplug_slot->info->latch_status;
304
305 return 0;
306}
307
308static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
309{
310 struct slot *slot = hotplug_slot->private;
311 int retval;
312
313 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
314
315 retval = slot->hpc_ops->get_adapter_status(slot, value);
316 if (retval < 0)
317 *value = hotplug_slot->info->adapter_status;
318
319 return 0;
320}
321
322static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
323{
324 struct slot *slot = hotplug_slot->private;
325 int retval;
326
327 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
328
329 retval = slot->hpc_ops->get_max_bus_speed(slot, value);
330 if (retval < 0)
331 *value = PCI_SPEED_UNKNOWN;
332
333 return 0;
334}
335
336static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
337{
338 struct slot *slot = hotplug_slot->private;
339 int retval;
340
341 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
342
343 retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
344 if (retval < 0)
345 *value = PCI_SPEED_UNKNOWN;
346
347 return 0;
348}
349
350static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
351{
352 int rc;
353 struct controller *ctrl;
354 struct slot *t_slot;
355 int first_device_num = 0 ; /* first PCI device number supported by this PCIE */
356 int num_ctlr_slots; /* number of slots supported by this HPC */
357 u8 value;
358 struct pci_dev *pdev;
359
360 dbg("%s: Called by hp_drv\n", __FUNCTION__);
361 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
362 if (!ctrl) {
363 err("%s : out of memory\n", __FUNCTION__);
364 goto err_out_none;
365 }
366 memset(ctrl, 0, sizeof(struct controller));
367
368 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
369
370 pdev = dev->port;
371
372 rc = pcie_init(ctrl, dev,
373 (php_intr_callback_t) pciehp_handle_attention_button,
374 (php_intr_callback_t) pciehp_handle_switch_change,
375 (php_intr_callback_t) pciehp_handle_presence_change,
376 (php_intr_callback_t) pciehp_handle_power_fault);
377 if (rc) {
378 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
379 goto err_out_free_ctrl;
380 }
381
382 ctrl->pci_dev = pdev;
383
384 pci_set_drvdata(pdev, ctrl);
385
386 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
387 if (!ctrl->pci_bus) {
388 err("%s: out of memory\n", __FUNCTION__);
389 rc = -ENOMEM;
390 goto err_out_unmap_mmio_region;
391 }
392 dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
393 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
394 ctrl->bus = pdev->bus->number; /* ctrl bus */
395 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
396
397 ctrl->device = PCI_SLOT(pdev->devfn);
398 ctrl->function = PCI_FUNC(pdev->devfn);
399 dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__,
400 ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
401
402 /*
403 * Save configuration headers for this and subordinate PCI buses
404 */
405
406 rc = get_ctlr_slot_config(ctrl);
407 if (rc) {
408 err(msg_initialization_err, rc);
409 goto err_out_free_ctrl_bus;
410 }
411 first_device_num = ctrl->slot_device_offset;
412 num_ctlr_slots = ctrl->num_slots;
413
414 /* Store PCI Config Space for all devices on this bus */
415 dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
416 __FUNCTION__,ctrl->bus, ctrl->slot_bus);
417 rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
418 if (rc) {
419 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
420 goto err_out_free_ctrl_bus;
421 }
422
423 /* Get IO, memory, and IRQ resources for new devices */
424 rc = pciehprm_find_available_resources(ctrl);
425 ctrl->add_support = !rc;
426
427 if (rc) {
428 dbg("pciehprm_find_available_resources = %#x\n", rc);
429 err("unable to locate PCI configuration resources for hot plug add.\n");
430 goto err_out_free_ctrl_bus;
431 }
432
433 /* Setup the slot information structures */
434 rc = init_slots(ctrl);
435 if (rc) {
436 err(msg_initialization_err, 6);
437 goto err_out_free_ctrl_slot;
438 }
439
440 t_slot = pciehp_find_slot(ctrl, first_device_num);
441 dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
442
443 /* Finish setting up the hot plug ctrl device */
444 ctrl->next_event = 0;
445
446 if (!pciehp_ctrl_list) {
447 pciehp_ctrl_list = ctrl;
448 ctrl->next = NULL;
449 } else {
450 ctrl->next = pciehp_ctrl_list;
451 pciehp_ctrl_list = ctrl;
452 }
453
454 /* Wait for exclusive access to hardware */
455 down(&ctrl->crit_sect);
456
457 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
458 dbg("%s: adpater value %x\n", __FUNCTION__, value);
459
460 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
461 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
462 if (rc) {
463 /* Done with exclusive hardware access */
464 up(&ctrl->crit_sect);
465 goto err_out_free_ctrl_slot;
466 } else
467 /* Wait for the command to complete */
468 wait_for_ctrl_irq (ctrl);
469 }
470
471 /* Done with exclusive hardware access */
472 up(&ctrl->crit_sect);
473
474 return 0;
475
476err_out_free_ctrl_slot:
477 cleanup_slots(ctrl);
478err_out_free_ctrl_bus:
479 kfree(ctrl->pci_bus);
480err_out_unmap_mmio_region:
481 ctrl->hpc_ops->release_ctlr(ctrl);
482err_out_free_ctrl:
483 kfree(ctrl);
484err_out_none:
485 return -ENODEV;
486}
487
488
489static int pcie_start_thread(void)
490{
491 int loop;
492 int retval = 0;
493
494 dbg("Initialize + Start the notification/polling mechanism \n");
495
496 retval = pciehp_event_start_thread();
497 if (retval) {
498 dbg("pciehp_event_start_thread() failed\n");
499 return retval;
500 }
501
502 dbg("Initialize slot lists\n");
503 /* One slot list for each bus in the system */
504 for (loop = 0; loop < 256; loop++) {
505 pciehp_slot_list[loop] = NULL;
506 }
507
508 return retval;
509}
510
511static inline void __exit
512free_pciehp_res(struct pci_resource *res)
513{
514 struct pci_resource *tres;
515
516 while (res) {
517 tres = res;
518 res = res->next;
519 kfree(tres);
520 }
521}
522
523static void __exit unload_pciehpd(void)
524{
525 struct pci_func *next;
526 struct pci_func *TempSlot;
527 int loop;
528 struct controller *ctrl;
529 struct controller *tctrl;
530
531 ctrl = pciehp_ctrl_list;
532
533 while (ctrl) {
534 cleanup_slots(ctrl);
535
536 free_pciehp_res(ctrl->io_head);
537 free_pciehp_res(ctrl->mem_head);
538 free_pciehp_res(ctrl->p_mem_head);
539 free_pciehp_res(ctrl->bus_head);
540
541 kfree (ctrl->pci_bus);
542
543 ctrl->hpc_ops->release_ctlr(ctrl);
544
545 tctrl = ctrl;
546 ctrl = ctrl->next;
547
548 kfree(tctrl);
549 }
550
551 for (loop = 0; loop < 256; loop++) {
552 next = pciehp_slot_list[loop];
553 while (next != NULL) {
554 free_pciehp_res(next->io_head);
555 free_pciehp_res(next->mem_head);
556 free_pciehp_res(next->p_mem_head);
557 free_pciehp_res(next->bus_head);
558
559 TempSlot = next;
560 next = next->next;
561 kfree(TempSlot);
562 }
563 }
564
565 /* Stop the notification mechanism */
566 pciehp_event_stop_thread();
567
568}
569
570int hpdriver_context = 0;
571
572static void pciehp_remove (struct pcie_device *device)
573{
574 printk("%s ENTRY\n", __FUNCTION__);
575 printk("%s -> Call free_irq for irq = %d\n",
576 __FUNCTION__, device->irq);
577 free_irq(device->irq, &hpdriver_context);
578}
579
580#ifdef CONFIG_PM
581static int pciehp_suspend (struct pcie_device *dev, u32 state)
582{
583 printk("%s ENTRY\n", __FUNCTION__);
584 return 0;
585}
586
587static int pciehp_resume (struct pcie_device *dev)
588{
589 printk("%s ENTRY\n", __FUNCTION__);
590 return 0;
591}
592#endif
593
594static struct pcie_port_service_id port_pci_ids[] = { {
595 .vendor = PCI_ANY_ID,
596 .device = PCI_ANY_ID,
597 .port_type = PCIE_RC_PORT,
598 .service_type = PCIE_PORT_SERVICE_HP,
599 .driver_data = 0,
600 }, { /* end: all zeroes */ }
601};
602static const char device_name[] = "hpdriver";
603
604static struct pcie_port_service_driver hpdriver_portdrv = {
605 .name = (char *)device_name,
606 .id_table = &port_pci_ids[0],
607
608 .probe = pciehp_probe,
609 .remove = pciehp_remove,
610
611#ifdef CONFIG_PM
612 .suspend = pciehp_suspend,
613 .resume = pciehp_resume,
614#endif /* PM */
615};
616
617static int __init pcied_init(void)
618{
619 int retval = 0;
620
621#ifdef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
622 pciehp_poll_mode = 1;
623#endif
624
625 retval = pcie_start_thread();
626 if (retval)
627 goto error_hpc_init;
628
629 retval = pciehprm_init(PCI);
630 if (!retval) {
631 retval = pcie_port_service_register(&hpdriver_portdrv);
632 dbg("pcie_port_service_register = %d\n", retval);
633 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
634 if (retval)
635 dbg("%s: Failure to register service\n", __FUNCTION__);
636 }
637
638error_hpc_init:
639 if (retval) {
640 pciehprm_cleanup();
641 pciehp_event_stop_thread();
642 } else
643 pciehprm_print_pirt();
644
645 return retval;
646}
647
648static void __exit pcied_cleanup(void)
649{
650 dbg("unload_pciehpd()\n");
651 unload_pciehpd();
652
653 pciehprm_cleanup();
654
655 dbg("pcie_port_service_unregister\n");
656 pcie_port_service_unregister(&hpdriver_portdrv);
657
658 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
659}
660
661module_init(pcied_init);
662module_exit(pcied_cleanup);
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
new file mode 100644
index 000000000000..0dbcf04aa35e
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -0,0 +1,2706 @@
1/*
2 * PCI Express Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h>
40#include <linux/pci.h>
41#include "../pci.h"
42#include "pciehp.h"
43#include "pciehprm.h"
44
45static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
46 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
47static int configure_new_function( struct controller *ctrl, struct pci_func *func,
48 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
49static void interrupt_event_handler(struct controller *ctrl);
50
51static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
52static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
53static int event_finished;
54static unsigned long pushbutton_pending; /* = 0 */
55static unsigned long surprise_rm_pending; /* = 0 */
56
57u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
58{
59 struct controller *ctrl = (struct controller *) inst_id;
60 struct slot *p_slot;
61 u8 rc = 0;
62 u8 getstatus;
63 struct pci_func *func;
64 struct event_info *taskInfo;
65
66 /* Attention Button Change */
67 dbg("pciehp: Attention button interrupt received.\n");
68
69 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
70
71 /* This is the structure that tells the worker thread what to do */
72 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
73 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
74
75 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
76 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
77
78 ctrl->next_event = (ctrl->next_event + 1) % 10;
79 taskInfo->hp_slot = hp_slot;
80
81 rc++;
82
83 /*
84 * Button pressed - See if need to TAKE ACTION!!!
85 */
86 info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
87 taskInfo->event_type = INT_BUTTON_PRESS;
88
89 if ((p_slot->state == BLINKINGON_STATE)
90 || (p_slot->state == BLINKINGOFF_STATE)) {
91 /* Cancel if we are still blinking; this means that we press the
92 * attention again before the 5 sec. limit expires to cancel hot-add
93 * or hot-remove
94 */
95 taskInfo->event_type = INT_BUTTON_CANCEL;
96 info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
97 } else if ((p_slot->state == POWERON_STATE)
98 || (p_slot->state == POWEROFF_STATE)) {
99 /* Ignore if the slot is on power-on or power-off state; this
100 * means that the previous attention button action to hot-add or
101 * hot-remove is undergoing
102 */
103 taskInfo->event_type = INT_BUTTON_IGNORE;
104 info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
105 }
106
107 if (rc)
108 up(&event_semaphore); /* signal event thread that new event is posted */
109
110 return 0;
111
112}
113
114u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
115{
116 struct controller *ctrl = (struct controller *) inst_id;
117 struct slot *p_slot;
118 u8 rc = 0;
119 u8 getstatus;
120 struct pci_func *func;
121 struct event_info *taskInfo;
122
123 /* Switch Change */
124 dbg("pciehp: Switch interrupt received.\n");
125
126 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
127
128 /* This is the structure that tells the worker thread
129 * what to do
130 */
131 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
132 ctrl->next_event = (ctrl->next_event + 1) % 10;
133 taskInfo->hp_slot = hp_slot;
134
135 rc++;
136 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
137 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
138 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
139
140 if (getstatus) {
141 /*
142 * Switch opened
143 */
144 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
145 func->switch_save = 0;
146 taskInfo->event_type = INT_SWITCH_OPEN;
147 } else {
148 /*
149 * Switch closed
150 */
151 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
152 func->switch_save = 0x10;
153 taskInfo->event_type = INT_SWITCH_CLOSE;
154 }
155
156 if (rc)
157 up(&event_semaphore); /* signal event thread that new event is posted */
158
159 return rc;
160}
161
162u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
163{
164 struct controller *ctrl = (struct controller *) inst_id;
165 struct slot *p_slot;
166 u8 rc = 0;
167 struct pci_func *func;
168 struct event_info *taskInfo;
169
170 /* Presence Change */
171 dbg("pciehp: Presence/Notify input change.\n");
172
173 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
174
175 /* This is the structure that tells the worker thread
176 * what to do
177 */
178 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
179 ctrl->next_event = (ctrl->next_event + 1) % 10;
180 taskInfo->hp_slot = hp_slot;
181
182 rc++;
183 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
184
185 /* Switch is open, assume a presence change
186 * Save the presence state
187 */
188 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
189 if (func->presence_save) {
190 /*
191 * Card Present
192 */
193 info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
194 taskInfo->event_type = INT_PRESENCE_ON;
195 } else {
196 /*
197 * Not Present
198 */
199 info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
200 taskInfo->event_type = INT_PRESENCE_OFF;
201 }
202
203 if (rc)
204 up(&event_semaphore); /* signal event thread that new event is posted */
205
206 return rc;
207}
208
209u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
210{
211 struct controller *ctrl = (struct controller *) inst_id;
212 struct slot *p_slot;
213 u8 rc = 0;
214 struct pci_func *func;
215 struct event_info *taskInfo;
216
217 /* power fault */
218 dbg("pciehp: Power fault interrupt received.\n");
219
220 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
221
222 /* this is the structure that tells the worker thread
223 * what to do
224 */
225 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
226 ctrl->next_event = (ctrl->next_event + 1) % 10;
227 taskInfo->hp_slot = hp_slot;
228
229 rc++;
230 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
231
232 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
233 /*
234 * power fault Cleared
235 */
236 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
237 func->status = 0x00;
238 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
239 } else {
240 /*
241 * power fault
242 */
243 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
244 taskInfo->event_type = INT_POWER_FAULT;
245 /* set power fault status for this board */
246 func->status = 0xFF;
247 info("power fault bit %x set\n", hp_slot);
248 }
249 if (rc)
250 up(&event_semaphore); /* signal event thread that new event is posted */
251
252 return rc;
253}
254
255
256/**
257 * sort_by_size: sort nodes by their length, smallest first.
258 *
259 * @head: list to sort
260 */
261static int sort_by_size(struct pci_resource **head)
262{
263 struct pci_resource *current_res;
264 struct pci_resource *next_res;
265 int out_of_order = 1;
266
267 if (!(*head))
268 return 1;
269
270 if (!((*head)->next))
271 return 0;
272
273 while (out_of_order) {
274 out_of_order = 0;
275
276 /* Special case for swapping list head */
277 if (((*head)->next) &&
278 ((*head)->length > (*head)->next->length)) {
279 out_of_order++;
280 current_res = *head;
281 *head = (*head)->next;
282 current_res->next = (*head)->next;
283 (*head)->next = current_res;
284 }
285
286 current_res = *head;
287
288 while (current_res->next && current_res->next->next) {
289 if (current_res->next->length > current_res->next->next->length) {
290 out_of_order++;
291 next_res = current_res->next;
292 current_res->next = current_res->next->next;
293 current_res = current_res->next;
294 next_res->next = current_res->next;
295 current_res->next = next_res;
296 } else
297 current_res = current_res->next;
298 }
299 } /* End of out_of_order loop */
300
301 return 0;
302}
303
304
305/*
306 * sort_by_max_size
307 *
308 * Sorts nodes on the list by their length.
309 * Largest first.
310 *
311 */
312static int sort_by_max_size(struct pci_resource **head)
313{
314 struct pci_resource *current_res;
315 struct pci_resource *next_res;
316 int out_of_order = 1;
317
318 if (!(*head))
319 return 1;
320
321 if (!((*head)->next))
322 return 0;
323
324 while (out_of_order) {
325 out_of_order = 0;
326
327 /* Special case for swapping list head */
328 if (((*head)->next) &&
329 ((*head)->length < (*head)->next->length)) {
330 out_of_order++;
331 current_res = *head;
332 *head = (*head)->next;
333 current_res->next = (*head)->next;
334 (*head)->next = current_res;
335 }
336
337 current_res = *head;
338
339 while (current_res->next && current_res->next->next) {
340 if (current_res->next->length < current_res->next->next->length) {
341 out_of_order++;
342 next_res = current_res->next;
343 current_res->next = current_res->next->next;
344 current_res = current_res->next;
345 next_res->next = current_res->next;
346 current_res->next = next_res;
347 } else
348 current_res = current_res->next;
349 }
350 } /* End of out_of_order loop */
351
352 return 0;
353}
354
355
356/**
357 * do_pre_bridge_resource_split: return one unused resource node
358 * @head: list to scan
359 *
360 */
361static struct pci_resource *
362do_pre_bridge_resource_split(struct pci_resource **head,
363 struct pci_resource **orig_head, u32 alignment)
364{
365 struct pci_resource *prevnode = NULL;
366 struct pci_resource *node;
367 struct pci_resource *split_node;
368 u32 rc;
369 u32 temp_dword;
370 dbg("do_pre_bridge_resource_split\n");
371
372 if (!(*head) || !(*orig_head))
373 return NULL;
374
375 rc = pciehp_resource_sort_and_combine(head);
376
377 if (rc)
378 return NULL;
379
380 if ((*head)->base != (*orig_head)->base)
381 return NULL;
382
383 if ((*head)->length == (*orig_head)->length)
384 return NULL;
385
386
387 /* If we got here, there the bridge requires some of the resource, but
388 * we may be able to split some off of the front
389 */
390 node = *head;
391
392 if (node->length & (alignment -1)) {
393 /* this one isn't an aligned length, so we'll make a new entry
394 * and split it up.
395 */
396 split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
397
398 if (!split_node)
399 return NULL;
400
401 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
402
403 split_node->base = node->base;
404 split_node->length = temp_dword;
405
406 node->length -= temp_dword;
407 node->base += split_node->length;
408
409 /* Put it in the list */
410 *head = split_node;
411 split_node->next = node;
412 }
413
414 if (node->length < alignment)
415 return NULL;
416
417 /* Now unlink it */
418 if (*head == node) {
419 *head = node->next;
420 } else {
421 prevnode = *head;
422 while (prevnode->next != node)
423 prevnode = prevnode->next;
424
425 prevnode->next = node->next;
426 }
427 node->next = NULL;
428
429 return node;
430}
431
432
433/**
434 * do_bridge_resource_split: return one unused resource node
435 * @head: list to scan
436 *
437 */
438static struct pci_resource *
439do_bridge_resource_split(struct pci_resource **head, u32 alignment)
440{
441 struct pci_resource *prevnode = NULL;
442 struct pci_resource *node;
443 u32 rc;
444 u32 temp_dword;
445
446 if (!(*head))
447 return NULL;
448
449 rc = pciehp_resource_sort_and_combine(head);
450
451 if (rc)
452 return NULL;
453
454 node = *head;
455
456 while (node->next) {
457 prevnode = node;
458 node = node->next;
459 kfree(prevnode);
460 }
461
462 if (node->length < alignment) {
463 kfree(node);
464 return NULL;
465 }
466
467 if (node->base & (alignment - 1)) {
468 /* Short circuit if adjusted size is too small */
469 temp_dword = (node->base | (alignment-1)) + 1;
470 if ((node->length - (temp_dword - node->base)) < alignment) {
471 kfree(node);
472 return NULL;
473 }
474
475 node->length -= (temp_dword - node->base);
476 node->base = temp_dword;
477 }
478
479 if (node->length & (alignment - 1)) {
480 /* There's stuff in use after this node */
481 kfree(node);
482 return NULL;
483 }
484
485 return node;
486}
487
488
489/*
490 * get_io_resource
491 *
492 * this function sorts the resource list by size and then
493 * returns the first node of "size" length that is not in the
494 * ISA aliasing window. If it finds a node larger than "size"
495 * it will split it up.
496 *
497 * size must be a power of two.
498 */
499static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
500{
501 struct pci_resource *prevnode;
502 struct pci_resource *node;
503 struct pci_resource *split_node = NULL;
504 u32 temp_dword;
505
506 if (!(*head))
507 return NULL;
508
509 if ( pciehp_resource_sort_and_combine(head) )
510 return NULL;
511
512 if ( sort_by_size(head) )
513 return NULL;
514
515 for (node = *head; node; node = node->next) {
516 if (node->length < size)
517 continue;
518
519 if (node->base & (size - 1)) {
520 /* this one isn't base aligned properly
521 so we'll make a new entry and split it up */
522 temp_dword = (node->base | (size-1)) + 1;
523
524 /*/ Short circuit if adjusted size is too small */
525 if ((node->length - (temp_dword - node->base)) < size)
526 continue;
527
528 split_node = kmalloc(sizeof(struct pci_resource),
529 GFP_KERNEL);
530
531 if (!split_node)
532 return NULL;
533
534 split_node->base = node->base;
535 split_node->length = temp_dword - node->base;
536 node->base = temp_dword;
537 node->length -= split_node->length;
538
539 /* Put it in the list */
540 split_node->next = node->next;
541 node->next = split_node;
542 } /* End of non-aligned base */
543
544 /* Don't need to check if too small since we already did */
545 if (node->length > size) {
546 /* this one is longer than we need
547 so we'll make a new entry and split it up */
548 split_node = kmalloc(sizeof(struct pci_resource),
549 GFP_KERNEL);
550
551 if (!split_node)
552 return NULL;
553
554 split_node->base = node->base + size;
555 split_node->length = node->length - size;
556 node->length = size;
557
558 /* Put it in the list */
559 split_node->next = node->next;
560 node->next = split_node;
561 } /* End of too big on top end */
562
563 /* For IO make sure it's not in the ISA aliasing space */
564 if (node->base & 0x300L)
565 continue;
566
567 /* If we got here, then it is the right size
568 Now take it out of the list */
569 if (*head == node) {
570 *head = node->next;
571 } else {
572 prevnode = *head;
573 while (prevnode->next != node)
574 prevnode = prevnode->next;
575
576 prevnode->next = node->next;
577 }
578 node->next = NULL;
579 /* Stop looping */
580 break;
581 }
582
583 return node;
584}
585
586
587/*
588 * get_max_resource
589 *
590 * Gets the largest node that is at least "size" big from the
591 * list pointed to by head. It aligns the node on top and bottom
592 * to "size" alignment before returning it.
593 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
594 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
595 */
596static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
597{
598 struct pci_resource *max;
599 struct pci_resource *temp;
600 struct pci_resource *split_node;
601 u32 temp_dword;
602 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
603 int i;
604
605 if (!(*head))
606 return NULL;
607
608 if (pciehp_resource_sort_and_combine(head))
609 return NULL;
610
611 if (sort_by_max_size(head))
612 return NULL;
613
614 for (max = *head;max; max = max->next) {
615
616 /* If not big enough we could probably just bail,
617 instead we'll continue to the next. */
618 if (max->length < size)
619 continue;
620
621 if (max->base & (size - 1)) {
622 /* this one isn't base aligned properly
623 so we'll make a new entry and split it up */
624 temp_dword = (max->base | (size-1)) + 1;
625
626 /* Short circuit if adjusted size is too small */
627 if ((max->length - (temp_dword - max->base)) < size)
628 continue;
629
630 split_node = kmalloc(sizeof(struct pci_resource),
631 GFP_KERNEL);
632
633 if (!split_node)
634 return NULL;
635
636 split_node->base = max->base;
637 split_node->length = temp_dword - max->base;
638 max->base = temp_dword;
639 max->length -= split_node->length;
640
641 /* Put it next in the list */
642 split_node->next = max->next;
643 max->next = split_node;
644 }
645
646 if ((max->base + max->length) & (size - 1)) {
647 /* this one isn't end aligned properly at the top
648 so we'll make a new entry and split it up */
649 split_node = kmalloc(sizeof(struct pci_resource),
650 GFP_KERNEL);
651
652 if (!split_node)
653 return NULL;
654 temp_dword = ((max->base + max->length) & ~(size - 1));
655 split_node->base = temp_dword;
656 split_node->length = max->length + max->base
657 - split_node->base;
658 max->length -= split_node->length;
659
660 /* Put it in the list */
661 split_node->next = max->next;
662 max->next = split_node;
663 }
664
665 /* Make sure it didn't shrink too much when we aligned it */
666 if (max->length < size)
667 continue;
668
669 for ( i = 0; max_size[i] > size; i++) {
670 if (max->length > max_size[i]) {
671 split_node = kmalloc(sizeof(struct pci_resource),
672 GFP_KERNEL);
673 if (!split_node)
674 break; /* return NULL; */
675 split_node->base = max->base + max_size[i];
676 split_node->length = max->length - max_size[i];
677 max->length = max_size[i];
678 /* Put it next in the list */
679 split_node->next = max->next;
680 max->next = split_node;
681 break;
682 }
683 }
684
685 /* Now take it out of the list */
686 temp = (struct pci_resource*) *head;
687 if (temp == max) {
688 *head = max->next;
689 } else {
690 while (temp && temp->next != max) {
691 temp = temp->next;
692 }
693
694 temp->next = max->next;
695 }
696
697 max->next = NULL;
698 return max;
699 }
700
701 /* If we get here, we couldn't find one */
702 return NULL;
703}
704
705
706/*
707 * get_resource
708 *
709 * this function sorts the resource list by size and then
710 * returns the first node of "size" length. If it finds a node
711 * larger than "size" it will split it up.
712 *
713 * size must be a power of two.
714 */
715static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
716{
717 struct pci_resource *prevnode;
718 struct pci_resource *node;
719 struct pci_resource *split_node;
720 u32 temp_dword;
721
722 if (!(*head))
723 return NULL;
724
725 if ( pciehp_resource_sort_and_combine(head) )
726 return NULL;
727
728 if ( sort_by_size(head) )
729 return NULL;
730
731 for (node = *head; node; node = node->next) {
732 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
733 __FUNCTION__, size, node, node->base, node->length);
734 if (node->length < size)
735 continue;
736
737 if (node->base & (size - 1)) {
738 dbg("%s: not aligned\n", __FUNCTION__);
739 /* this one isn't base aligned properly
740 so we'll make a new entry and split it up */
741 temp_dword = (node->base | (size-1)) + 1;
742
743 /* Short circuit if adjusted size is too small */
744 if ((node->length - (temp_dword - node->base)) < size)
745 continue;
746
747 split_node = kmalloc(sizeof(struct pci_resource),
748 GFP_KERNEL);
749
750 if (!split_node)
751 return NULL;
752
753 split_node->base = node->base;
754 split_node->length = temp_dword - node->base;
755 node->base = temp_dword;
756 node->length -= split_node->length;
757
758 /* Put it in the list */
759 split_node->next = node->next;
760 node->next = split_node;
761 } /* End of non-aligned base */
762
763 /* Don't need to check if too small since we already did */
764 if (node->length > size) {
765 dbg("%s: too big\n", __FUNCTION__);
766 /* this one is longer than we need
767 so we'll make a new entry and split it up */
768 split_node = kmalloc(sizeof(struct pci_resource),
769 GFP_KERNEL);
770
771 if (!split_node)
772 return NULL;
773
774 split_node->base = node->base + size;
775 split_node->length = node->length - size;
776 node->length = size;
777
778 /* Put it in the list */
779 split_node->next = node->next;
780 node->next = split_node;
781 } /* End of too big on top end */
782
783 dbg("%s: got one!!!\n", __FUNCTION__);
784 /* If we got here, then it is the right size
785 Now take it out of the list */
786 if (*head == node) {
787 *head = node->next;
788 } else {
789 prevnode = *head;
790 while (prevnode->next != node)
791 prevnode = prevnode->next;
792
793 prevnode->next = node->next;
794 }
795 node->next = NULL;
796 /* Stop looping */
797 break;
798 }
799 return node;
800}
801
802
803/*
804 * pciehp_resource_sort_and_combine
805 *
806 * Sorts all of the nodes in the list in ascending order by
807 * their base addresses. Also does garbage collection by
808 * combining adjacent nodes.
809 *
810 * returns 0 if success
811 */
812int pciehp_resource_sort_and_combine(struct pci_resource **head)
813{
814 struct pci_resource *node1;
815 struct pci_resource *node2;
816 int out_of_order = 1;
817
818 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
819
820 if (!(*head))
821 return 1;
822
823 dbg("*head->next = %p\n",(*head)->next);
824
825 if (!(*head)->next)
826 return 0; /* only one item on the list, already sorted! */
827
828 dbg("*head->base = 0x%x\n",(*head)->base);
829 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
830 while (out_of_order) {
831 out_of_order = 0;
832
833 /* Special case for swapping list head */
834 if (((*head)->next) &&
835 ((*head)->base > (*head)->next->base)) {
836 node1 = *head;
837 (*head) = (*head)->next;
838 node1->next = (*head)->next;
839 (*head)->next = node1;
840 out_of_order++;
841 }
842
843 node1 = (*head);
844
845 while (node1->next && node1->next->next) {
846 if (node1->next->base > node1->next->next->base) {
847 out_of_order++;
848 node2 = node1->next;
849 node1->next = node1->next->next;
850 node1 = node1->next;
851 node2->next = node1->next;
852 node1->next = node2;
853 } else
854 node1 = node1->next;
855 }
856 } /* End of out_of_order loop */
857
858 node1 = *head;
859
860 while (node1 && node1->next) {
861 if ((node1->base + node1->length) == node1->next->base) {
862 /* Combine */
863 dbg("8..\n");
864 node1->length += node1->next->length;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 kfree(node2);
868 } else
869 node1 = node1->next;
870 }
871
872 return 0;
873}
874
875
876/**
877 * pciehp_slot_create - Creates a node and adds it to the proper bus.
878 * @busnumber - bus where new node is to be located
879 *
880 * Returns pointer to the new node or NULL if unsuccessful
881 */
882struct pci_func *pciehp_slot_create(u8 busnumber)
883{
884 struct pci_func *new_slot;
885 struct pci_func *next;
886 dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
887 new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
888
889 if (new_slot == NULL)
890 return new_slot;
891
892 memset(new_slot, 0, sizeof(struct pci_func));
893
894 new_slot->next = NULL;
895 new_slot->configured = 1;
896
897 if (pciehp_slot_list[busnumber] == NULL) {
898 pciehp_slot_list[busnumber] = new_slot;
899 } else {
900 next = pciehp_slot_list[busnumber];
901 while (next->next != NULL)
902 next = next->next;
903 next->next = new_slot;
904 }
905 return new_slot;
906}
907
908
909/**
910 * slot_remove - Removes a node from the linked list of slots.
911 * @old_slot: slot to remove
912 *
913 * Returns 0 if successful, !0 otherwise.
914 */
915static int slot_remove(struct pci_func * old_slot)
916{
917 struct pci_func *next;
918
919 if (old_slot == NULL)
920 return 1;
921
922 next = pciehp_slot_list[old_slot->bus];
923
924 if (next == NULL)
925 return 1;
926
927 if (next == old_slot) {
928 pciehp_slot_list[old_slot->bus] = old_slot->next;
929 pciehp_destroy_board_resources(old_slot);
930 kfree(old_slot);
931 return 0;
932 }
933
934 while ((next->next != old_slot) && (next->next != NULL)) {
935 next = next->next;
936 }
937
938 if (next->next == old_slot) {
939 next->next = old_slot->next;
940 pciehp_destroy_board_resources(old_slot);
941 kfree(old_slot);
942 return 0;
943 } else
944 return 2;
945}
946
947
948/**
949 * bridge_slot_remove - Removes a node from the linked list of slots.
950 * @bridge: bridge to remove
951 *
952 * Returns 0 if successful, !0 otherwise.
953 */
954static int bridge_slot_remove(struct pci_func *bridge)
955{
956 u8 subordinateBus, secondaryBus;
957 u8 tempBus;
958 struct pci_func *next;
959
960 if (bridge == NULL)
961 return 1;
962
963 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
964 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
965
966 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
967 next = pciehp_slot_list[tempBus];
968
969 while (!slot_remove(next)) {
970 next = pciehp_slot_list[tempBus];
971 }
972 }
973
974 next = pciehp_slot_list[bridge->bus];
975
976 if (next == NULL) {
977 return 1;
978 }
979
980 if (next == bridge) {
981 pciehp_slot_list[bridge->bus] = bridge->next;
982 kfree(bridge);
983 return 0;
984 }
985
986 while ((next->next != bridge) && (next->next != NULL)) {
987 next = next->next;
988 }
989
990 if (next->next == bridge) {
991 next->next = bridge->next;
992 kfree(bridge);
993 return 0;
994 } else
995 return 2;
996}
997
998
999/**
1000 * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1001 * @bus: bus to find
1002 * @device: device to find
1003 * @index: is 0 for first function found, 1 for the second...
1004 *
1005 * Returns pointer to the node if successful, %NULL otherwise.
1006 */
1007struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
1008{
1009 int found = -1;
1010 struct pci_func *func;
1011
1012 func = pciehp_slot_list[bus];
1013 dbg("%s: bus %x device %x index %x\n",
1014 __FUNCTION__, bus, device, index);
1015 if (func != NULL) {
1016 dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
1017 __FUNCTION__, func->bus, func->device, func->function,
1018 func->pci_dev);
1019 } else
1020 dbg("%s: func == NULL\n", __FUNCTION__);
1021
1022 if ((func == NULL) || ((func->device == device) && (index == 0)))
1023 return func;
1024
1025 if (func->device == device)
1026 found++;
1027
1028 while (func->next != NULL) {
1029 func = func->next;
1030
1031 dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
1032 __FUNCTION__, func->bus, func->device, func->function,
1033 func->pci_dev);
1034 if (func->device == device)
1035 found++;
1036 dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
1037 found, index);
1038
1039 if ((found == index) || (func->function == index)) {
1040 dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
1041 func->bus, func->device, func->function);
1042 return func;
1043 }
1044 }
1045
1046 return NULL;
1047}
1048
1049static int is_bridge(struct pci_func * func)
1050{
1051 /* Check the header type */
1052 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1053 return 1;
1054 else
1055 return 0;
1056}
1057
1058
1059/* The following routines constitute the bulk of the
1060 hotplug controller logic
1061 */
1062
1063static void set_slot_off(struct controller *ctrl, struct slot * pslot)
1064{
1065 /* Wait for exclusive access to hardware */
1066 down(&ctrl->crit_sect);
1067
1068 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
1069 if (POWER_CTRL(ctrl->ctrlcap)) {
1070 if (pslot->hpc_ops->power_off_slot(pslot)) {
1071 err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
1072 up(&ctrl->crit_sect);
1073 return;
1074 }
1075 wait_for_ctrl_irq (ctrl);
1076 }
1077
1078 if (PWR_LED(ctrl->ctrlcap)) {
1079 pslot->hpc_ops->green_led_off(pslot);
1080 wait_for_ctrl_irq (ctrl);
1081 }
1082
1083 if (ATTN_LED(ctrl->ctrlcap)) {
1084 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
1085 err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
1086 up(&ctrl->crit_sect);
1087 return;
1088 }
1089 wait_for_ctrl_irq (ctrl);
1090 }
1091
1092 /* Done with exclusive hardware access */
1093 up(&ctrl->crit_sect);
1094}
1095
1096/**
1097 * board_added - Called after a board has been added to the system.
1098 *
1099 * Turns power on for the board
1100 * Configures board
1101 *
1102 */
1103static u32 board_added(struct pci_func * func, struct controller * ctrl)
1104{
1105 u8 hp_slot;
1106 int index;
1107 u32 temp_register = 0xFFFFFFFF;
1108 u32 rc = 0;
1109 struct pci_func *new_func = NULL;
1110 struct slot *p_slot;
1111 struct resource_lists res_lists;
1112
1113 p_slot = pciehp_find_slot(ctrl, func->device);
1114 hp_slot = func->device - ctrl->slot_device_offset;
1115
1116 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1117
1118 /* Wait for exclusive access to hardware */
1119 down(&ctrl->crit_sect);
1120
1121 if (POWER_CTRL(ctrl->ctrlcap)) {
1122 /* Power on slot */
1123 rc = p_slot->hpc_ops->power_on_slot(p_slot);
1124 if (rc) {
1125 up(&ctrl->crit_sect);
1126 return -1;
1127 }
1128
1129 /* Wait for the command to complete */
1130 wait_for_ctrl_irq (ctrl);
1131 }
1132
1133 if (PWR_LED(ctrl->ctrlcap)) {
1134 p_slot->hpc_ops->green_led_blink(p_slot);
1135
1136 /* Wait for the command to complete */
1137 wait_for_ctrl_irq (ctrl);
1138 }
1139
1140 /* Done with exclusive hardware access */
1141 up(&ctrl->crit_sect);
1142
1143 /* Wait for ~1 second */
1144 dbg("%s: before long_delay\n", __FUNCTION__);
1145 wait_for_ctrl_irq (ctrl);
1146 dbg("%s: afterlong_delay\n", __FUNCTION__);
1147
1148 /* Check link training status */
1149 rc = p_slot->hpc_ops->check_lnk_status(ctrl);
1150 if (rc) {
1151 err("%s: Failed to check link status\n", __FUNCTION__);
1152 set_slot_off(ctrl, p_slot);
1153 return rc;
1154 }
1155
1156 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1157
1158 /* Check for a power fault */
1159 if (func->status == 0xFF) {
1160 /* power fault occurred, but it was benign */
1161 temp_register = 0xFFFFFFFF;
1162 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1163 rc = POWER_FAILURE;
1164 func->status = 0;
1165 } else {
1166 /* Get vendor/device ID u32 */
1167 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1168 PCI_VENDOR_ID, &temp_register);
1169 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1170 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1171
1172 if (rc != 0) {
1173 /* Something's wrong here */
1174 temp_register = 0xFFFFFFFF;
1175 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1176 }
1177 /* Preset return code. It will be changed later if things go okay. */
1178 rc = NO_ADAPTER_PRESENT;
1179 }
1180
1181 /* All F's is an empty slot or an invalid board */
1182 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1183 res_lists.io_head = ctrl->io_head;
1184 res_lists.mem_head = ctrl->mem_head;
1185 res_lists.p_mem_head = ctrl->p_mem_head;
1186 res_lists.bus_head = ctrl->bus_head;
1187 res_lists.irqs = NULL;
1188
1189 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1190 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1191
1192 ctrl->io_head = res_lists.io_head;
1193 ctrl->mem_head = res_lists.mem_head;
1194 ctrl->p_mem_head = res_lists.p_mem_head;
1195 ctrl->bus_head = res_lists.bus_head;
1196
1197 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1198 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1199 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1200 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1201
1202 if (rc) {
1203 set_slot_off(ctrl, p_slot);
1204 return rc;
1205 }
1206 pciehp_save_slot_config(ctrl, func);
1207
1208 func->status = 0;
1209 func->switch_save = 0x10;
1210 func->is_a_board = 0x01;
1211
1212 /* next, we will instantiate the linux pci_dev structures
1213 * (with appropriate driver notification, if already present)
1214 */
1215 index = 0;
1216 do {
1217 new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
1218 if (new_func && !new_func->pci_dev) {
1219 dbg("%s:call pci_hp_configure_dev, func %x\n",
1220 __FUNCTION__, index);
1221 pciehp_configure_device(ctrl, new_func);
1222 }
1223 } while (new_func);
1224
1225 /*
1226 * Some PCI Express root ports require fixup after hot-plug operation.
1227 */
1228 if (pcie_mch_quirk)
1229 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1230
1231 if (PWR_LED(ctrl->ctrlcap)) {
1232 /* Wait for exclusive access to hardware */
1233 down(&ctrl->crit_sect);
1234
1235 p_slot->hpc_ops->green_led_on(p_slot);
1236
1237 /* Wait for the command to complete */
1238 wait_for_ctrl_irq (ctrl);
1239
1240 /* Done with exclusive hardware access */
1241 up(&ctrl->crit_sect);
1242 }
1243 } else {
1244 set_slot_off(ctrl, p_slot);
1245 return -1;
1246 }
1247 return 0;
1248}
1249
1250
1251/**
1252 * remove_board - Turns off slot and LED's
1253 *
1254 */
1255static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1256{
1257 int index;
1258 u8 skip = 0;
1259 u8 device;
1260 u8 hp_slot;
1261 u32 rc;
1262 struct resource_lists res_lists;
1263 struct pci_func *temp_func;
1264 struct slot *p_slot;
1265
1266 if (func == NULL)
1267 return 1;
1268
1269 if (pciehp_unconfigure_device(func))
1270 return 1;
1271
1272 device = func->device;
1273
1274 hp_slot = func->device - ctrl->slot_device_offset;
1275 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1276
1277 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1278
1279 if ((ctrl->add_support) &&
1280 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1281 /* Here we check to see if we've saved any of the board's
1282 * resources already. If so, we'll skip the attempt to
1283 * determine what's being used.
1284 */
1285 index = 0;
1286
1287 temp_func = func;
1288
1289 while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
1290 if (temp_func->bus_head || temp_func->mem_head
1291 || temp_func->p_mem_head || temp_func->io_head) {
1292 skip = 1;
1293 break;
1294 }
1295 }
1296
1297 if (!skip)
1298 rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
1299 }
1300 /* Change status to shutdown */
1301 if (func->is_a_board)
1302 func->status = 0x01;
1303 func->configured = 0;
1304
1305 /* Wait for exclusive access to hardware */
1306 down(&ctrl->crit_sect);
1307
1308 if (POWER_CTRL(ctrl->ctrlcap)) {
1309 /* power off slot */
1310 rc = p_slot->hpc_ops->power_off_slot(p_slot);
1311 if (rc) {
1312 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1313 up(&ctrl->crit_sect);
1314 return rc;
1315 }
1316 /* Wait for the command to complete */
1317 wait_for_ctrl_irq (ctrl);
1318 }
1319
1320 if (PWR_LED(ctrl->ctrlcap)) {
1321 /* turn off Green LED */
1322 p_slot->hpc_ops->green_led_off(p_slot);
1323
1324 /* Wait for the command to complete */
1325 wait_for_ctrl_irq (ctrl);
1326 }
1327
1328 /* Done with exclusive hardware access */
1329 up(&ctrl->crit_sect);
1330
1331 if (ctrl->add_support) {
1332 while (func) {
1333 res_lists.io_head = ctrl->io_head;
1334 res_lists.mem_head = ctrl->mem_head;
1335 res_lists.p_mem_head = ctrl->p_mem_head;
1336 res_lists.bus_head = ctrl->bus_head;
1337
1338 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
1339 func->bus, func->device, func->function);
1340
1341 pciehp_return_board_resources(func, &res_lists);
1342
1343 ctrl->io_head = res_lists.io_head;
1344 ctrl->mem_head = res_lists.mem_head;
1345 ctrl->p_mem_head = res_lists.p_mem_head;
1346 ctrl->bus_head = res_lists.bus_head;
1347
1348 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1349 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1350 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1351 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1352
1353 if (is_bridge(func)) {
1354 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1355 ctrl->seg, func->bus, func->device, func->function);
1356 bridge_slot_remove(func);
1357 } else {
1358 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1359 ctrl->seg, func->bus, func->device, func->function);
1360 slot_remove(func);
1361 }
1362
1363 func = pciehp_slot_find(ctrl->slot_bus, device, 0);
1364 }
1365
1366 /* Setup slot structure with entry for empty slot */
1367 func = pciehp_slot_create(ctrl->slot_bus);
1368
1369 if (func == NULL) {
1370 return 1;
1371 }
1372
1373 func->bus = ctrl->slot_bus;
1374 func->device = device;
1375 func->function = 0;
1376 func->configured = 0;
1377 func->switch_save = 0x10;
1378 func->is_a_board = 0;
1379 }
1380
1381 return 0;
1382}
1383
1384
1385static void pushbutton_helper_thread(unsigned long data)
1386{
1387 pushbutton_pending = data;
1388
1389 up(&event_semaphore);
1390}
1391
1392/**
1393 * pciehp_pushbutton_thread
1394 *
1395 * Scheduled procedure to handle blocking stuff for the pushbuttons
1396 * Handles all pending events and exits.
1397 *
1398 */
1399static void pciehp_pushbutton_thread(unsigned long slot)
1400{
1401 struct slot *p_slot = (struct slot *) slot;
1402 u8 getstatus;
1403
1404 pushbutton_pending = 0;
1405
1406 if (!p_slot) {
1407 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1408 return;
1409 }
1410
1411 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1412 if (getstatus) {
1413 p_slot->state = POWEROFF_STATE;
1414 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1415
1416 pciehp_disable_slot(p_slot);
1417 p_slot->state = STATIC_STATE;
1418 } else {
1419 p_slot->state = POWERON_STATE;
1420 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1421
1422 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1423 /* Wait for exclusive access to hardware */
1424 down(&p_slot->ctrl->crit_sect);
1425
1426 p_slot->hpc_ops->green_led_off(p_slot);
1427
1428 /* Wait for the command to complete */
1429 wait_for_ctrl_irq (p_slot->ctrl);
1430
1431 /* Done with exclusive hardware access */
1432 up(&p_slot->ctrl->crit_sect);
1433 }
1434 p_slot->state = STATIC_STATE;
1435 }
1436
1437 return;
1438}
1439
1440/**
1441 * pciehp_surprise_rm_thread
1442 *
1443 * Scheduled procedure to handle blocking stuff for the surprise removal
1444 * Handles all pending events and exits.
1445 *
1446 */
1447static void pciehp_surprise_rm_thread(unsigned long slot)
1448{
1449 struct slot *p_slot = (struct slot *) slot;
1450 u8 getstatus;
1451
1452 surprise_rm_pending = 0;
1453
1454 if (!p_slot) {
1455 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1456 return;
1457 }
1458
1459 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1460 if (!getstatus) {
1461 p_slot->state = POWEROFF_STATE;
1462 dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1463
1464 pciehp_disable_slot(p_slot);
1465 p_slot->state = STATIC_STATE;
1466 } else {
1467 p_slot->state = POWERON_STATE;
1468 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1469
1470 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1471 /* Wait for exclusive access to hardware */
1472 down(&p_slot->ctrl->crit_sect);
1473
1474 p_slot->hpc_ops->green_led_off(p_slot);
1475
1476 /* Wait for the command to complete */
1477 wait_for_ctrl_irq (p_slot->ctrl);
1478
1479 /* Done with exclusive hardware access */
1480 up(&p_slot->ctrl->crit_sect);
1481 }
1482 p_slot->state = STATIC_STATE;
1483 }
1484
1485 return;
1486}
1487
1488
1489
1490/* this is the main worker thread */
1491static int event_thread(void* data)
1492{
1493 struct controller *ctrl;
1494 lock_kernel();
1495 daemonize("pciehpd_event");
1496
1497 unlock_kernel();
1498
1499 while (1) {
1500 dbg("!!!!event_thread sleeping\n");
1501 down_interruptible (&event_semaphore);
1502 dbg("event_thread woken finished = %d\n", event_finished);
1503 if (event_finished || signal_pending(current))
1504 break;
1505 /* Do stuff here */
1506 if (pushbutton_pending)
1507 pciehp_pushbutton_thread(pushbutton_pending);
1508 else if (surprise_rm_pending)
1509 pciehp_surprise_rm_thread(surprise_rm_pending);
1510 else
1511 for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next)
1512 interrupt_event_handler(ctrl);
1513 }
1514 dbg("event_thread signals exit\n");
1515 up(&event_exit);
1516 return 0;
1517}
1518
1519int pciehp_event_start_thread(void)
1520{
1521 int pid;
1522
1523 /* initialize our semaphores */
1524 init_MUTEX_LOCKED(&event_exit);
1525 event_finished=0;
1526
1527 init_MUTEX_LOCKED(&event_semaphore);
1528 pid = kernel_thread(event_thread, NULL, 0);
1529
1530 if (pid < 0) {
1531 err ("Can't start up our event thread\n");
1532 return -1;
1533 }
1534 dbg("Our event thread pid = %d\n", pid);
1535 return 0;
1536}
1537
1538
1539void pciehp_event_stop_thread(void)
1540{
1541 event_finished = 1;
1542 dbg("event_thread finish command given\n");
1543 up(&event_semaphore);
1544 dbg("wait for event_thread to exit\n");
1545 down(&event_exit);
1546}
1547
1548
1549static int update_slot_info(struct slot *slot)
1550{
1551 struct hotplug_slot_info *info;
1552 /* char buffer[SLOT_NAME_SIZE]; */
1553 int result;
1554
1555 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
1556 if (!info)
1557 return -ENOMEM;
1558
1559 /* make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); */
1560
1561 slot->hpc_ops->get_power_status(slot, &(info->power_status));
1562 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
1563 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
1564 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
1565
1566 /* result = pci_hp_change_slot_info(buffer, info); */
1567 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1568 kfree (info);
1569 return result;
1570}
1571
1572static void interrupt_event_handler(struct controller *ctrl)
1573{
1574 int loop = 0;
1575 int change = 1;
1576 struct pci_func *func;
1577 u8 hp_slot;
1578 u8 getstatus;
1579 struct slot *p_slot;
1580
1581 while (change) {
1582 change = 0;
1583
1584 for (loop = 0; loop < 10; loop++) {
1585 if (ctrl->event_queue[loop].event_type != 0) {
1586 hp_slot = ctrl->event_queue[loop].hp_slot;
1587
1588 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1589
1590 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1591
1592 dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
1593
1594 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1595 dbg("button cancel\n");
1596 del_timer(&p_slot->task_event);
1597
1598 switch (p_slot->state) {
1599 case BLINKINGOFF_STATE:
1600 /* Wait for exclusive access to hardware */
1601 down(&ctrl->crit_sect);
1602
1603 if (PWR_LED(ctrl->ctrlcap)) {
1604 p_slot->hpc_ops->green_led_on(p_slot);
1605 /* Wait for the command to complete */
1606 wait_for_ctrl_irq (ctrl);
1607 }
1608 if (ATTN_LED(ctrl->ctrlcap)) {
1609 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1610
1611 /* Wait for the command to complete */
1612 wait_for_ctrl_irq (ctrl);
1613 }
1614 /* Done with exclusive hardware access */
1615 up(&ctrl->crit_sect);
1616 break;
1617 case BLINKINGON_STATE:
1618 /* Wait for exclusive access to hardware */
1619 down(&ctrl->crit_sect);
1620
1621 if (PWR_LED(ctrl->ctrlcap)) {
1622 p_slot->hpc_ops->green_led_off(p_slot);
1623 /* Wait for the command to complete */
1624 wait_for_ctrl_irq (ctrl);
1625 }
1626 if (ATTN_LED(ctrl->ctrlcap)){
1627 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1628 /* Wait for the command to complete */
1629 wait_for_ctrl_irq (ctrl);
1630 }
1631 /* Done with exclusive hardware access */
1632 up(&ctrl->crit_sect);
1633
1634 break;
1635 default:
1636 warn("Not a valid state\n");
1637 return;
1638 }
1639 info(msg_button_cancel, p_slot->number);
1640 p_slot->state = STATIC_STATE;
1641 }
1642 /* ***********Button Pressed (No action on 1st press...) */
1643 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1644
1645 if (ATTN_BUTTN(ctrl->ctrlcap)) {
1646 dbg("Button pressed\n");
1647 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1648 if (getstatus) {
1649 /* slot is on */
1650 dbg("slot is on\n");
1651 p_slot->state = BLINKINGOFF_STATE;
1652 info(msg_button_off, p_slot->number);
1653 } else {
1654 /* slot is off */
1655 dbg("slot is off\n");
1656 p_slot->state = BLINKINGON_STATE;
1657 info(msg_button_on, p_slot->number);
1658 }
1659
1660 /* Wait for exclusive access to hardware */
1661 down(&ctrl->crit_sect);
1662
1663 /* blink green LED and turn off amber */
1664 if (PWR_LED(ctrl->ctrlcap)) {
1665 p_slot->hpc_ops->green_led_blink(p_slot);
1666 /* Wait for the command to complete */
1667 wait_for_ctrl_irq (ctrl);
1668 }
1669
1670 if (ATTN_LED(ctrl->ctrlcap)) {
1671 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1672
1673 /* Wait for the command to complete */
1674 wait_for_ctrl_irq (ctrl);
1675 }
1676
1677 /* Done with exclusive hardware access */
1678 up(&ctrl->crit_sect);
1679
1680 init_timer(&p_slot->task_event);
1681 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1682 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1683 p_slot->task_event.data = (unsigned long) p_slot;
1684
1685 dbg("add_timer p_slot = %p\n", (void *) p_slot);
1686 add_timer(&p_slot->task_event);
1687 }
1688 }
1689 /***********POWER FAULT********************/
1690 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1691 if (POWER_CTRL(ctrl->ctrlcap)) {
1692 dbg("power fault\n");
1693 /* Wait for exclusive access to hardware */
1694 down(&ctrl->crit_sect);
1695
1696 if (ATTN_LED(ctrl->ctrlcap)) {
1697 p_slot->hpc_ops->set_attention_status(p_slot, 1);
1698 wait_for_ctrl_irq (ctrl);
1699 }
1700
1701 if (PWR_LED(ctrl->ctrlcap)) {
1702 p_slot->hpc_ops->green_led_off(p_slot);
1703 wait_for_ctrl_irq (ctrl);
1704 }
1705
1706 /* Done with exclusive hardware access */
1707 up(&ctrl->crit_sect);
1708 }
1709 }
1710 /***********SURPRISE REMOVAL********************/
1711 else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) ||
1712 (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) {
1713 if (HP_SUPR_RM(ctrl->ctrlcap)) {
1714 dbg("Surprise Removal\n");
1715 if (p_slot) {
1716 surprise_rm_pending = (unsigned long) p_slot;
1717 up(&event_semaphore);
1718 update_slot_info(p_slot);
1719 }
1720 }
1721 } else {
1722 /* refresh notification */
1723 if (p_slot)
1724 update_slot_info(p_slot);
1725 }
1726
1727 ctrl->event_queue[loop].event_type = 0;
1728
1729 change = 1;
1730 }
1731 } /* End of FOR loop */
1732 }
1733}
1734
1735
1736int pciehp_enable_slot(struct slot *p_slot)
1737{
1738 u8 getstatus = 0;
1739 int rc;
1740 struct pci_func *func;
1741
1742 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1743 if (!func) {
1744 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1745 return 1;
1746 }
1747
1748 /* Check to see if (latch closed, card present, power off) */
1749 down(&p_slot->ctrl->crit_sect);
1750
1751 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1752 if (rc || !getstatus) {
1753 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1754 up(&p_slot->ctrl->crit_sect);
1755 return 1;
1756 }
1757 if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
1758 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1759 if (rc || getstatus) {
1760 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1761 up(&p_slot->ctrl->crit_sect);
1762 return 1;
1763 }
1764 }
1765
1766 if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
1767 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1768 if (rc || getstatus) {
1769 info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
1770 up(&p_slot->ctrl->crit_sect);
1771 return 1;
1772 }
1773 }
1774 up(&p_slot->ctrl->crit_sect);
1775
1776 slot_remove(func);
1777
1778 func = pciehp_slot_create(p_slot->bus);
1779 if (func == NULL)
1780 return 1;
1781
1782 func->bus = p_slot->bus;
1783 func->device = p_slot->device;
1784 func->function = 0;
1785 func->configured = 0;
1786 func->is_a_board = 1;
1787
1788 /* We have to save the presence info for these slots */
1789 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1790 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1791 func->switch_save = !getstatus? 0x10:0;
1792
1793 rc = board_added(func, p_slot->ctrl);
1794 if (rc) {
1795 if (is_bridge(func))
1796 bridge_slot_remove(func);
1797 else
1798 slot_remove(func);
1799
1800 /* Setup slot structure with entry for empty slot */
1801 func = pciehp_slot_create(p_slot->bus);
1802 if (func == NULL)
1803 return 1; /* Out of memory */
1804
1805 func->bus = p_slot->bus;
1806 func->device = p_slot->device;
1807 func->function = 0;
1808 func->configured = 0;
1809 func->is_a_board = 1;
1810
1811 /* We have to save the presence info for these slots */
1812 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1813 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1814 func->switch_save = !getstatus? 0x10:0;
1815 }
1816
1817 if (p_slot)
1818 update_slot_info(p_slot);
1819
1820 return rc;
1821}
1822
1823
1824int pciehp_disable_slot(struct slot *p_slot)
1825{
1826 u8 class_code, header_type, BCR;
1827 u8 index = 0;
1828 u8 getstatus = 0;
1829 u32 rc = 0;
1830 int ret = 0;
1831 unsigned int devfn;
1832 struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
1833 struct pci_func *func;
1834
1835 if (!p_slot->ctrl)
1836 return 1;
1837
1838 /* Check to see if (latch closed, card present, power on) */
1839 down(&p_slot->ctrl->crit_sect);
1840
1841 if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {
1842 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1843 if (ret || !getstatus) {
1844 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1845 up(&p_slot->ctrl->crit_sect);
1846 return 1;
1847 }
1848 }
1849
1850 if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
1851 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1852 if (ret || getstatus) {
1853 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1854 up(&p_slot->ctrl->crit_sect);
1855 return 1;
1856 }
1857 }
1858
1859 if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
1860 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1861 if (ret || !getstatus) {
1862 info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
1863 up(&p_slot->ctrl->crit_sect);
1864 return 1;
1865 }
1866 }
1867
1868 up(&p_slot->ctrl->crit_sect);
1869
1870 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1871
1872 /* Make sure there are no video controllers here
1873 * for all func of p_slot
1874 */
1875 while (func && !rc) {
1876 pci_bus->number = func->bus;
1877 devfn = PCI_DEVFN(func->device, func->function);
1878
1879 /* Check the Class Code */
1880 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
1881 if (rc)
1882 return rc;
1883
1884 if (class_code == PCI_BASE_CLASS_DISPLAY) {
1885 /* Display/Video adapter (not supported) */
1886 rc = REMOVE_NOT_SUPPORTED;
1887 } else {
1888 /* See if it's a bridge */
1889 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1890 if (rc)
1891 return rc;
1892
1893 /* If it's a bridge, check the VGA Enable bit */
1894 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
1895 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
1896 if (rc)
1897 return rc;
1898
1899 /* If the VGA Enable bit is set, remove isn't supported */
1900 if (BCR & PCI_BRIDGE_CTL_VGA) {
1901 rc = REMOVE_NOT_SUPPORTED;
1902 }
1903 }
1904 }
1905
1906 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1907 }
1908
1909 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1910 if ((func != NULL) && !rc) {
1911 rc = remove_board(func, p_slot->ctrl);
1912 } else if (!rc)
1913 rc = 1;
1914
1915 if (p_slot)
1916 update_slot_info(p_slot);
1917
1918 return rc;
1919}
1920
1921
1922/**
1923 * configure_new_device - Configures the PCI header information of one board.
1924 *
1925 * @ctrl: pointer to controller structure
1926 * @func: pointer to function structure
1927 * @behind_bridge: 1 if this is a recursive call, 0 if not
1928 * @resources: pointer to set of resource lists
1929 *
1930 * Returns 0 if success
1931 *
1932 */
1933static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
1934 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
1935{
1936 u8 temp_byte, function, max_functions, stop_it;
1937 int rc;
1938 u32 ID;
1939 struct pci_func *new_slot;
1940 struct pci_bus lpci_bus, *pci_bus;
1941 int index;
1942
1943 new_slot = func;
1944
1945 dbg("%s\n", __FUNCTION__);
1946 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
1947 pci_bus = &lpci_bus;
1948 pci_bus->number = func->bus;
1949
1950 /* Check for Multi-function device */
1951 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
1952 if (rc) {
1953 dbg("%s: rc = %d\n", __FUNCTION__, rc);
1954 return rc;
1955 }
1956
1957 if (temp_byte & 0x80) /* Multi-function device */
1958 max_functions = 8;
1959 else
1960 max_functions = 1;
1961
1962 function = 0;
1963
1964 do {
1965 rc = configure_new_function(ctrl, new_slot, behind_bridge,
1966 resources, bridge_bus, bridge_dev);
1967
1968 if (rc) {
1969 dbg("configure_new_function failed: %d\n", rc);
1970 index = 0;
1971
1972 while (new_slot) {
1973 new_slot = pciehp_slot_find(new_slot->bus,
1974 new_slot->device, index++);
1975
1976 if (new_slot)
1977 pciehp_return_board_resources(new_slot,
1978 resources);
1979 }
1980
1981 return rc;
1982 }
1983
1984 function++;
1985
1986 stop_it = 0;
1987
1988 /* The following loop skips to the next present function
1989 * and creates a board structure
1990 */
1991
1992 while ((function < max_functions) && (!stop_it)) {
1993 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
1994
1995 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
1996 function++;
1997 } else { /* There's something there */
1998 /* Setup slot structure. */
1999 new_slot = pciehp_slot_create(func->bus);
2000
2001 if (new_slot == NULL) {
2002 /* Out of memory */
2003 return 1;
2004 }
2005
2006 new_slot->bus = func->bus;
2007 new_slot->device = func->device;
2008 new_slot->function = function;
2009 new_slot->is_a_board = 1;
2010 new_slot->status = 0;
2011
2012 stop_it++;
2013 }
2014 }
2015
2016 } while (function < max_functions);
2017 dbg("returning from %s\n", __FUNCTION__);
2018
2019 return 0;
2020}
2021
2022/*
2023 * Configuration logic that involves the hotplug data structures and
2024 * their bookkeeping
2025 */
2026
2027/**
2028 * configure_bridge: fill bridge's registers, either configure or disable it.
2029 */
2030static int
2031configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
2032 struct pci_resource *mem_node,
2033 struct pci_resource **hold_mem_node,
2034 int base_addr, int limit_addr)
2035{
2036 u16 temp_word;
2037 u32 rc;
2038
2039 if (mem_node) {
2040 memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
2041 mem_node->next = NULL;
2042
2043 /* set Mem base and Limit registers */
2044 RES_CHECK(mem_node->base, 16);
2045 temp_word = (u16)(mem_node->base >> 16);
2046 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2047
2048 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2049 temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
2050 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2051 } else {
2052 temp_word = 0xFFFF;
2053 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2054
2055 temp_word = 0x0000;
2056 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2057
2058 kfree(*hold_mem_node);
2059 *hold_mem_node = NULL;
2060 }
2061 return rc;
2062}
2063
2064static int
2065configure_new_bridge(struct controller *ctrl, struct pci_func *func,
2066 u8 behind_bridge, struct resource_lists *resources,
2067 struct pci_bus *pci_bus)
2068{
2069 int cloop;
2070 u8 temp_byte;
2071 u8 device;
2072 u16 temp_word;
2073 u32 rc;
2074 u32 ID;
2075 unsigned int devfn;
2076 struct pci_resource *mem_node;
2077 struct pci_resource *p_mem_node;
2078 struct pci_resource *io_node;
2079 struct pci_resource *bus_node;
2080 struct pci_resource *hold_mem_node;
2081 struct pci_resource *hold_p_mem_node;
2082 struct pci_resource *hold_IO_node;
2083 struct pci_resource *hold_bus_node;
2084 struct irq_mapping irqs;
2085 struct pci_func *new_slot;
2086 struct resource_lists temp_resources;
2087
2088 devfn = PCI_DEVFN(func->device, func->function);
2089
2090 /* set Primary bus */
2091 dbg("set Primary bus = 0x%x\n", func->bus);
2092 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2093 if (rc)
2094 return rc;
2095
2096 /* find range of busses to use */
2097 bus_node = get_max_resource(&resources->bus_head, 1L);
2098
2099 /* If we don't have any busses to allocate, we can't continue */
2100 if (!bus_node) {
2101 err("Got NO bus resource to use\n");
2102 return -ENOMEM;
2103 }
2104 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2105
2106 /* set Secondary bus */
2107 temp_byte = (u8)bus_node->base;
2108 dbg("set Secondary bus = 0x%x\n", temp_byte);
2109 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2110 if (rc)
2111 return rc;
2112
2113 /* set subordinate bus */
2114 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2115 dbg("set subordinate bus = 0x%x\n", temp_byte);
2116 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2117 if (rc)
2118 return rc;
2119
2120 /* Set HP parameters (Cache Line Size, Latency Timer) */
2121 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2122 if (rc)
2123 return rc;
2124
2125 /* Setup the IO, memory, and prefetchable windows */
2126
2127 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2128 if (io_node) {
2129 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
2130 io_node->length, io_node->next);
2131 }
2132
2133 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2134 if (mem_node) {
2135 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
2136 mem_node->length, mem_node->next);
2137 }
2138
2139 if (resources->p_mem_head)
2140 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2141 else {
2142 /*
2143 * In some platform implementation, MEM and PMEM are not
2144 * distinguished, and hence ACPI _CRS has only MEM entries
2145 * for both MEM and PMEM.
2146 */
2147 dbg("using MEM for PMEM\n");
2148 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2149 }
2150 if (p_mem_node) {
2151 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2152 p_mem_node->length, p_mem_node->next);
2153 }
2154
2155 /* set up the IRQ info */
2156 if (!resources->irqs) {
2157 irqs.barber_pole = 0;
2158 irqs.interrupt[0] = 0;
2159 irqs.interrupt[1] = 0;
2160 irqs.interrupt[2] = 0;
2161 irqs.interrupt[3] = 0;
2162 irqs.valid_INT = 0;
2163 } else {
2164 irqs.barber_pole = resources->irqs->barber_pole;
2165 irqs.interrupt[0] = resources->irqs->interrupt[0];
2166 irqs.interrupt[1] = resources->irqs->interrupt[1];
2167 irqs.interrupt[2] = resources->irqs->interrupt[2];
2168 irqs.interrupt[3] = resources->irqs->interrupt[3];
2169 irqs.valid_INT = resources->irqs->valid_INT;
2170 }
2171
2172 /* set up resource lists that are now aligned on top and bottom
2173 * for anything behind the bridge.
2174 */
2175 temp_resources.bus_head = bus_node;
2176 temp_resources.io_head = io_node;
2177 temp_resources.mem_head = mem_node;
2178 temp_resources.p_mem_head = p_mem_node;
2179 temp_resources.irqs = &irqs;
2180
2181 /* Make copies of the nodes we are going to pass down so that
2182 * if there is a problem,we can just use these to free resources
2183 */
2184 hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2185 hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2186 hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2187 hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2188
2189 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2190 kfree(hold_bus_node);
2191 kfree(hold_IO_node);
2192 kfree(hold_mem_node);
2193 kfree(hold_p_mem_node);
2194
2195 return 1;
2196 }
2197
2198 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2199
2200 bus_node->base += 1;
2201 bus_node->length -= 1;
2202 bus_node->next = NULL;
2203
2204 /* If we have IO resources copy them and fill in the bridge's
2205 * IO range registers
2206 */
2207 if (io_node) {
2208 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2209 io_node->next = NULL;
2210
2211 /* set IO base and Limit registers */
2212 RES_CHECK(io_node->base, 8);
2213 temp_byte = (u8)(io_node->base >> 8);
2214 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2215
2216 RES_CHECK(io_node->base + io_node->length - 1, 8);
2217 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2218 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2219 } else {
2220 kfree(hold_IO_node);
2221 hold_IO_node = NULL;
2222 }
2223
2224 /* If we have memory resources copy them and fill in the bridge's
2225 * memory range registers. Otherwise, fill in the range
2226 * registers with values that disable them.
2227 */
2228 rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
2229 PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
2230
2231 /* If we have prefetchable memory resources copy them and
2232 * fill in the bridge's memory range registers. Otherwise,
2233 * fill in the range registers with values that disable them.
2234 */
2235 rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
2236 PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
2237
2238 /* Adjust this to compensate for extra adjustment in first loop */
2239 irqs.barber_pole--;
2240
2241 rc = 0;
2242
2243 /* Here we actually find the devices and configure them */
2244 for (device = 0; (device <= 0x1F) && !rc; device++) {
2245 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2246
2247 ID = 0xFFFFFFFF;
2248 pci_bus->number = hold_bus_node->base;
2249 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
2250 pci_bus->number = func->bus;
2251
2252 if (ID != 0xFFFFFFFF) { /* device Present */
2253 /* Setup slot structure. */
2254 new_slot = pciehp_slot_create(hold_bus_node->base);
2255
2256 if (new_slot == NULL) {
2257 /* Out of memory */
2258 rc = -ENOMEM;
2259 continue;
2260 }
2261
2262 new_slot->bus = hold_bus_node->base;
2263 new_slot->device = device;
2264 new_slot->function = 0;
2265 new_slot->is_a_board = 1;
2266 new_slot->status = 0;
2267
2268 rc = configure_new_device(ctrl, new_slot, 1,
2269 &temp_resources, func->bus,
2270 func->device);
2271 dbg("configure_new_device rc=0x%x\n",rc);
2272 } /* End of IF (device in slot?) */
2273 } /* End of FOR loop */
2274
2275 if (rc) {
2276 pciehp_destroy_resource_list(&temp_resources);
2277
2278 return_resource(&(resources->bus_head), hold_bus_node);
2279 return_resource(&(resources->io_head), hold_IO_node);
2280 return_resource(&(resources->mem_head), hold_mem_node);
2281 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2282 return(rc);
2283 }
2284
2285 /* save the interrupt routing information */
2286 if (resources->irqs) {
2287 resources->irqs->interrupt[0] = irqs.interrupt[0];
2288 resources->irqs->interrupt[1] = irqs.interrupt[1];
2289 resources->irqs->interrupt[2] = irqs.interrupt[2];
2290 resources->irqs->interrupt[3] = irqs.interrupt[3];
2291 resources->irqs->valid_INT = irqs.valid_INT;
2292 } else if (!behind_bridge) {
2293 /* We need to hook up the interrupts here */
2294 for (cloop = 0; cloop < 4; cloop++) {
2295 if (irqs.valid_INT & (0x01 << cloop)) {
2296 rc = pciehp_set_irq(func->bus, func->device,
2297 0x0A + cloop, irqs.interrupt[cloop]);
2298 if (rc) {
2299 pciehp_destroy_resource_list (&temp_resources);
2300 return_resource(&(resources->bus_head), hold_bus_node);
2301 return_resource(&(resources->io_head), hold_IO_node);
2302 return_resource(&(resources->mem_head), hold_mem_node);
2303 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2304 return rc;
2305 }
2306 }
2307 } /* end of for loop */
2308 }
2309
2310 /* Return unused bus resources
2311 * First use the temporary node to store information for the board
2312 */
2313 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2314 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2315
2316 hold_bus_node->next = func->bus_head;
2317 func->bus_head = hold_bus_node;
2318
2319 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2320
2321 /* set subordinate bus */
2322 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2323 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2324
2325 if (temp_resources.bus_head->length == 0) {
2326 kfree(temp_resources.bus_head);
2327 temp_resources.bus_head = NULL;
2328 } else {
2329 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2330 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2331 return_resource(&(resources->bus_head), temp_resources.bus_head);
2332 }
2333 }
2334
2335 /* If we have IO space available and there is some left,
2336 * return the unused portion
2337 */
2338 if (hold_IO_node && temp_resources.io_head) {
2339 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2340 &hold_IO_node, 0x1000);
2341
2342 /* Check if we were able to split something off */
2343 if (io_node) {
2344 hold_IO_node->base = io_node->base + io_node->length;
2345
2346 RES_CHECK(hold_IO_node->base, 8);
2347 temp_byte = (u8)((hold_IO_node->base) >> 8);
2348 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2349
2350 return_resource(&(resources->io_head), io_node);
2351 }
2352
2353 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2354
2355 /* Check if we were able to split something off */
2356 if (io_node) {
2357 /* First use the temporary node to store information for the board */
2358 hold_IO_node->length = io_node->base - hold_IO_node->base;
2359
2360 /* If we used any, add it to the board's list */
2361 if (hold_IO_node->length) {
2362 hold_IO_node->next = func->io_head;
2363 func->io_head = hold_IO_node;
2364
2365 RES_CHECK(io_node->base - 1, 8);
2366 temp_byte = (u8)((io_node->base - 1) >> 8);
2367 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2368
2369 return_resource(&(resources->io_head), io_node);
2370 } else {
2371 /* it doesn't need any IO */
2372 temp_byte = 0x00;
2373 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2374
2375 return_resource(&(resources->io_head), io_node);
2376 kfree(hold_IO_node);
2377 }
2378 } else {
2379 /* it used most of the range */
2380 hold_IO_node->next = func->io_head;
2381 func->io_head = hold_IO_node;
2382 }
2383 } else if (hold_IO_node) {
2384 /* it used the whole range */
2385 hold_IO_node->next = func->io_head;
2386 func->io_head = hold_IO_node;
2387 }
2388
2389 /* If we have memory space available and there is some left,
2390 * return the unused portion
2391 */
2392 if (hold_mem_node && temp_resources.mem_head) {
2393 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2394
2395 /* Check if we were able to split something off */
2396 if (mem_node) {
2397 hold_mem_node->base = mem_node->base + mem_node->length;
2398
2399 RES_CHECK(hold_mem_node->base, 16);
2400 temp_word = (u16)((hold_mem_node->base) >> 16);
2401 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2402
2403 return_resource(&(resources->mem_head), mem_node);
2404 }
2405
2406 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2407
2408 /* Check if we were able to split something off */
2409 if (mem_node) {
2410 /* First use the temporary node to store information for the board */
2411 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2412
2413 if (hold_mem_node->length) {
2414 hold_mem_node->next = func->mem_head;
2415 func->mem_head = hold_mem_node;
2416
2417 /* configure end address */
2418 RES_CHECK(mem_node->base - 1, 16);
2419 temp_word = (u16)((mem_node->base - 1) >> 16);
2420 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2421
2422 /* Return unused resources to the pool */
2423 return_resource(&(resources->mem_head), mem_node);
2424 } else {
2425 /* it doesn't need any Mem */
2426 temp_word = 0x0000;
2427 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2428
2429 return_resource(&(resources->mem_head), mem_node);
2430 kfree(hold_mem_node);
2431 }
2432 } else {
2433 /* it used most of the range */
2434 hold_mem_node->next = func->mem_head;
2435 func->mem_head = hold_mem_node;
2436 }
2437 } else if (hold_mem_node) {
2438 /* it used the whole range */
2439 hold_mem_node->next = func->mem_head;
2440 func->mem_head = hold_mem_node;
2441 }
2442
2443 /* If we have prefetchable memory space available and there is some
2444 * left at the end, return the unused portion
2445 */
2446 if (hold_p_mem_node && temp_resources.p_mem_head) {
2447 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2448 &hold_p_mem_node, 0x100000L);
2449
2450 /* Check if we were able to split something off */
2451 if (p_mem_node) {
2452 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2453
2454 RES_CHECK(hold_p_mem_node->base, 16);
2455 temp_word = (u16)((hold_p_mem_node->base) >> 16);
2456 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2457
2458 return_resource(&(resources->p_mem_head), p_mem_node);
2459 }
2460
2461 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2462
2463 /* Check if we were able to split something off */
2464 if (p_mem_node) {
2465 /* First use the temporary node to store information for the board */
2466 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2467
2468 /* If we used any, add it to the board's list */
2469 if (hold_p_mem_node->length) {
2470 hold_p_mem_node->next = func->p_mem_head;
2471 func->p_mem_head = hold_p_mem_node;
2472
2473 RES_CHECK(p_mem_node->base - 1, 16);
2474 temp_word = (u16)((p_mem_node->base - 1) >> 16);
2475 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2476
2477 return_resource(&(resources->p_mem_head), p_mem_node);
2478 } else {
2479 /* it doesn't need any PMem */
2480 temp_word = 0x0000;
2481 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2482
2483 return_resource(&(resources->p_mem_head), p_mem_node);
2484 kfree(hold_p_mem_node);
2485 }
2486 } else {
2487 /* it used the most of the range */
2488 hold_p_mem_node->next = func->p_mem_head;
2489 func->p_mem_head = hold_p_mem_node;
2490 }
2491 } else if (hold_p_mem_node) {
2492 /* it used the whole range */
2493 hold_p_mem_node->next = func->p_mem_head;
2494 func->p_mem_head = hold_p_mem_node;
2495 }
2496
2497 /* We should be configuring an IRQ and the bridge's base address
2498 * registers if it needs them. Although we have never seen such
2499 * a device
2500 */
2501
2502 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2503
2504 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2505
2506 return rc;
2507}
2508
2509/**
2510 * configure_new_function - Configures the PCI header information of one device
2511 *
2512 * @ctrl: pointer to controller structure
2513 * @func: pointer to function structure
2514 * @behind_bridge: 1 if this is a recursive call, 0 if not
2515 * @resources: pointer to set of resource lists
2516 *
2517 * Calls itself recursively for bridged devices.
2518 * Returns 0 if success
2519 *
2520 */
2521static int
2522configure_new_function(struct controller *ctrl, struct pci_func *func,
2523 u8 behind_bridge, struct resource_lists *resources,
2524 u8 bridge_bus, u8 bridge_dev)
2525{
2526 int cloop;
2527 u8 temp_byte;
2528 u8 class_code;
2529 u16 temp_word;
2530 u32 rc;
2531 u32 temp_register;
2532 u32 base;
2533 unsigned int devfn;
2534 struct pci_resource *mem_node;
2535 struct pci_resource *io_node;
2536 struct pci_bus lpci_bus, *pci_bus;
2537
2538 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2539 pci_bus = &lpci_bus;
2540 pci_bus->number = func->bus;
2541 devfn = PCI_DEVFN(func->device, func->function);
2542
2543 /* Check for Bridge */
2544 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2545 if (rc)
2546 return rc;
2547 dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
2548 func->bus, func->device, func->function, temp_byte);
2549
2550 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2551 rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
2552 pci_bus);
2553
2554 if (rc)
2555 return rc;
2556 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2557 /* Standard device */
2558 u64 base64;
2559 rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
2560
2561 if (class_code == PCI_BASE_CLASS_DISPLAY)
2562 return DEVICE_TYPE_NOT_SUPPORTED;
2563
2564 /* Figure out IO and memory needs */
2565 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2566 temp_register = 0xFFFFFFFF;
2567
2568 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2569 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2570 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
2571 func->bus, func->device, func->function);
2572
2573 if (!temp_register)
2574 continue;
2575
2576 base64 = 0L;
2577 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2578 /* Map IO */
2579
2580 /* set base = amount of IO space */
2581 base = temp_register & 0xFFFFFFFC;
2582 base = ~base + 1;
2583
2584 dbg("NEED IO length(0x%x)\n", base);
2585 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2586
2587 /* allocate the resource to the board */
2588 if (io_node) {
2589 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2590 base = (u32)io_node->base;
2591 io_node->next = func->io_head;
2592 func->io_head = io_node;
2593 } else {
2594 err("Got NO IO resource(length=0x%x)\n", base);
2595 return -ENOMEM;
2596 }
2597 } else { /* map MEM */
2598 int prefetchable = 1;
2599 struct pci_resource **res_node = &func->p_mem_head;
2600 char *res_type_str = "PMEM";
2601 u32 temp_register2;
2602
2603 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2604 prefetchable = 0;
2605 res_node = &func->mem_head;
2606 res_type_str++;
2607 }
2608
2609 base = temp_register & 0xFFFFFFF0;
2610 base = ~base + 1;
2611
2612 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2613 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2614 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2615
2616 if (prefetchable && resources->p_mem_head)
2617 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2618 else {
2619 if (prefetchable)
2620 dbg("using MEM for PMEM\n");
2621 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2622 }
2623
2624 /* allocate the resource to the board */
2625 if (mem_node) {
2626 base = (u32)mem_node->base;
2627 mem_node->next = *res_node;
2628 *res_node = mem_node;
2629 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2630 mem_node->length);
2631 } else {
2632 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2633 return -ENOMEM;
2634 }
2635 break;
2636 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2637 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2638 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2639 temp_register, base);
2640
2641 if (prefetchable && resources->p_mem_head)
2642 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2643 else {
2644 if (prefetchable)
2645 dbg("using MEM for PMEM\n");
2646 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2647 }
2648
2649 /* allocate the resource to the board */
2650 if (mem_node) {
2651 base64 = mem_node->base;
2652 mem_node->next = *res_node;
2653 *res_node = mem_node;
2654 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2655 (u32)base64, mem_node->length);
2656 } else {
2657 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2658 return -ENOMEM;
2659 }
2660 break;
2661 default:
2662 dbg("reserved BAR type=0x%x\n", temp_register);
2663 break;
2664 }
2665
2666 }
2667
2668 if (base64) {
2669 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2670 cloop += 4;
2671 base64 >>= 32;
2672
2673 if (base64) {
2674 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2675 base64 = 0x0L;
2676 }
2677
2678 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2679 } else {
2680 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2681 }
2682 } /* End of base register loop */
2683
2684 /* disable ROM base Address */
2685 temp_word = 0x00L;
2686 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
2687
2688 /* Set HP parameters (Cache Line Size, Latency Timer) */
2689 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2690 if (rc)
2691 return rc;
2692
2693 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2694
2695 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
2696 func->function);
2697 } /* End of Not-A-Bridge else */
2698 else {
2699 /* It's some strange type of PCI adapter (Cardbus?) */
2700 return DEVICE_TYPE_NOT_SUPPORTED;
2701 }
2702
2703 func->configured = 1;
2704
2705 return 0;
2706}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
new file mode 100644
index 000000000000..9e70c4681f77
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -0,0 +1,1501 @@
1/*
2 * PCI Express PCI Hot Plug Driver
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>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/pci.h>
39#include <asm/system.h>
40#include "../pci.h"
41#include "pciehp.h"
42
43#ifdef DEBUG
44#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
45#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
46#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
47#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
48#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
49#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
50/* Redefine this flagword to set debug level */
51#define DEBUG_LEVEL DBG_K_STANDARD
52
53#define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
54
55#define DBG_PRINT( dbg_flags, args... ) \
56 do { \
57 if ( DEBUG_LEVEL & ( dbg_flags ) ) \
58 { \
59 int len; \
60 len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
61 __FILE__, __LINE__, __FUNCTION__ ); \
62 sprintf( __dbg_str_buf + len, args ); \
63 printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
64 } \
65 } while (0)
66
67#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
68#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
69#else
70#define DEFINE_DBG_BUFFER
71#define DBG_ENTER_ROUTINE
72#define DBG_LEAVE_ROUTINE
73#endif /* DEBUG */
74
75struct ctrl_reg {
76 u8 cap_id;
77 u8 nxt_ptr;
78 u16 cap_reg;
79 u32 dev_cap;
80 u16 dev_ctrl;
81 u16 dev_status;
82 u32 lnk_cap;
83 u16 lnk_ctrl;
84 u16 lnk_status;
85 u32 slot_cap;
86 u16 slot_ctrl;
87 u16 slot_status;
88 u16 root_ctrl;
89 u16 rsvp;
90 u32 root_status;
91} __attribute__ ((packed));
92
93/* offsets to the controller registers based on the above structure layout */
94enum ctrl_offsets {
95 PCIECAPID = offsetof(struct ctrl_reg, cap_id),
96 NXTCAPPTR = offsetof(struct ctrl_reg, nxt_ptr),
97 CAPREG = offsetof(struct ctrl_reg, cap_reg),
98 DEVCAP = offsetof(struct ctrl_reg, dev_cap),
99 DEVCTRL = offsetof(struct ctrl_reg, dev_ctrl),
100 DEVSTATUS = offsetof(struct ctrl_reg, dev_status),
101 LNKCAP = offsetof(struct ctrl_reg, lnk_cap),
102 LNKCTRL = offsetof(struct ctrl_reg, lnk_ctrl),
103 LNKSTATUS = offsetof(struct ctrl_reg, lnk_status),
104 SLOTCAP = offsetof(struct ctrl_reg, slot_cap),
105 SLOTCTRL = offsetof(struct ctrl_reg, slot_ctrl),
106 SLOTSTATUS = offsetof(struct ctrl_reg, slot_status),
107 ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl),
108 ROOTSTATUS = offsetof(struct ctrl_reg, root_status),
109};
110static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
111
112#define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID )
113#define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR )
114#define CAP_REG ( pcie_cap_base + CAPREG )
115#define DEV_CAP ( pcie_cap_base + DEVCAP )
116#define DEV_CTRL ( pcie_cap_base + DEVCTRL )
117#define DEV_STATUS ( pcie_cap_base + DEVSTATUS )
118#define LNK_CAP ( pcie_cap_base + LNKCAP )
119#define LNK_CTRL ( pcie_cap_base + LNKCTRL )
120#define LNK_STATUS ( pcie_cap_base + LNKSTATUS )
121#define SLOT_CAP ( pcie_cap_base + SLOTCAP )
122#define SLOT_CTRL ( pcie_cap_base + SLOTCTRL )
123#define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS )
124#define ROOT_CTRL ( pcie_cap_base + ROOTCTRL )
125#define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS )
126
127#define hp_register_read_word(pdev, reg , value) \
128 pci_read_config_word(pdev, reg, &value)
129
130#define hp_register_read_dword(pdev, reg , value) \
131 pci_read_config_dword(pdev, reg, &value)
132
133#define hp_register_write_word(pdev, reg , value) \
134 pci_write_config_word(pdev, reg, value)
135
136#define hp_register_dwrite_word(pdev, reg , value) \
137 pci_write_config_dword(pdev, reg, value)
138
139/* Field definitions in PCI Express Capabilities Register */
140#define CAP_VER 0x000F
141#define DEV_PORT_TYPE 0x00F0
142#define SLOT_IMPL 0x0100
143#define MSG_NUM 0x3E00
144
145/* Device or Port Type */
146#define NAT_ENDPT 0x00
147#define LEG_ENDPT 0x01
148#define ROOT_PORT 0x04
149#define UP_STREAM 0x05
150#define DN_STREAM 0x06
151#define PCIE_PCI_BRDG 0x07
152#define PCI_PCIE_BRDG 0x10
153
154/* Field definitions in Device Capabilities Register */
155#define DATTN_BUTTN_PRSN 0x1000
156#define DATTN_LED_PRSN 0x2000
157#define DPWR_LED_PRSN 0x4000
158
159/* Field definitions in Link Capabilities Register */
160#define MAX_LNK_SPEED 0x000F
161#define MAX_LNK_WIDTH 0x03F0
162
163/* Link Width Encoding */
164#define LNK_X1 0x01
165#define LNK_X2 0x02
166#define LNK_X4 0x04
167#define LNK_X8 0x08
168#define LNK_X12 0x0C
169#define LNK_X16 0x10
170#define LNK_X32 0x20
171
172/*Field definitions of Link Status Register */
173#define LNK_SPEED 0x000F
174#define NEG_LINK_WD 0x03F0
175#define LNK_TRN_ERR 0x0400
176#define LNK_TRN 0x0800
177#define SLOT_CLK_CONF 0x1000
178
179/* Field definitions in Slot Capabilities Register */
180#define ATTN_BUTTN_PRSN 0x00000001
181#define PWR_CTRL_PRSN 0x00000002
182#define MRL_SENS_PRSN 0x00000004
183#define ATTN_LED_PRSN 0x00000008
184#define PWR_LED_PRSN 0x00000010
185#define HP_SUPR_RM_SUP 0x00000020
186#define HP_CAP 0x00000040
187#define SLOT_PWR_VALUE 0x000003F8
188#define SLOT_PWR_LIMIT 0x00000C00
189#define PSN 0xFFF80000 /* PSN: Physical Slot Number */
190
191/* Field definitions in Slot Control Register */
192#define ATTN_BUTTN_ENABLE 0x0001
193#define PWR_FAULT_DETECT_ENABLE 0x0002
194#define MRL_DETECT_ENABLE 0x0004
195#define PRSN_DETECT_ENABLE 0x0008
196#define CMD_CMPL_INTR_ENABLE 0x0010
197#define HP_INTR_ENABLE 0x0020
198#define ATTN_LED_CTRL 0x00C0
199#define PWR_LED_CTRL 0x0300
200#define PWR_CTRL 0x0400
201
202/* Attention indicator and Power indicator states */
203#define LED_ON 0x01
204#define LED_BLINK 0x10
205#define LED_OFF 0x11
206
207/* Power Control Command */
208#define POWER_ON 0
209#define POWER_OFF 0x0400
210
211/* Field definitions in Slot Status Register */
212#define ATTN_BUTTN_PRESSED 0x0001
213#define PWR_FAULT_DETECTED 0x0002
214#define MRL_SENS_CHANGED 0x0004
215#define PRSN_DETECT_CHANGED 0x0008
216#define CMD_COMPLETED 0x0010
217#define MRL_STATE 0x0020
218#define PRSN_STATE 0x0040
219
220struct php_ctlr_state_s {
221 struct php_ctlr_state_s *pnext;
222 struct pci_dev *pci_dev;
223 unsigned int irq;
224 unsigned long flags; /* spinlock's */
225 u32 slot_device_offset;
226 u32 num_slots;
227 struct timer_list int_poll_timer; /* Added for poll event */
228 php_intr_callback_t attention_button_callback;
229 php_intr_callback_t switch_change_callback;
230 php_intr_callback_t presence_change_callback;
231 php_intr_callback_t power_fault_callback;
232 void *callback_instance_id;
233 struct ctrl_reg *creg; /* Ptr to controller register space */
234};
235
236
237static spinlock_t hpc_event_lock;
238
239DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
240static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
241static int ctlr_seq_num = 0; /* Controller sequence # */
242static spinlock_t list_lock;
243
244static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
245
246static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
247
248/* This is the interrupt polling timeout function. */
249static void int_poll_timeout(unsigned long lphp_ctlr)
250{
251 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
252
253 DBG_ENTER_ROUTINE
254
255 if ( !php_ctlr ) {
256 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
257 return;
258 }
259
260 /* Poll for interrupt events. regs == NULL => polling */
261 pcie_isr( 0, (void *)php_ctlr, NULL );
262
263 init_timer(&php_ctlr->int_poll_timer);
264
265 if (!pciehp_poll_time)
266 pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
267
268 start_int_poll_timer(php_ctlr, pciehp_poll_time);
269
270 return;
271}
272
273/* This function starts the interrupt polling timer. */
274static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
275{
276 if (!php_ctlr) {
277 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
278 return;
279 }
280
281 if ( ( seconds <= 0 ) || ( seconds > 60 ) )
282 seconds = 2; /* Clamp to sane value */
283
284 php_ctlr->int_poll_timer.function = &int_poll_timeout;
285 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */
286 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
287 add_timer(&php_ctlr->int_poll_timer);
288
289 return;
290}
291
292static int pcie_write_cmd(struct slot *slot, u16 cmd)
293{
294 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
295 int retval = 0;
296 u16 slot_status;
297
298 DBG_ENTER_ROUTINE
299
300 dbg("%s : Enter\n", __FUNCTION__);
301 if (!php_ctlr) {
302 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
303 return -1;
304 }
305
306 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
307 if (retval) {
308 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
309 return retval;
310 }
311 dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
312
313 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
314 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
315 the next command according to spec. Just print out the error message */
316 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
317 }
318
319 dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
320 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
321 if (retval) {
322 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
323 return retval;
324 }
325 dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
326 dbg("%s : Exit\n", __FUNCTION__);
327
328 DBG_LEAVE_ROUTINE
329 return retval;
330}
331
332static int hpc_check_lnk_status(struct controller *ctrl)
333{
334 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
335 u16 lnk_status;
336 int retval = 0;
337
338 DBG_ENTER_ROUTINE
339
340 if (!php_ctlr) {
341 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
342 return -1;
343 }
344
345 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
346
347 if (retval) {
348 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
349 return retval;
350 }
351
352 dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status);
353 if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
354 !(lnk_status & NEG_LINK_WD)) {
355 err("%s : Link Training Error occurs \n", __FUNCTION__);
356 retval = -1;
357 return retval;
358 }
359
360 DBG_LEAVE_ROUTINE
361 return retval;
362}
363
364
365static int hpc_get_attention_status(struct slot *slot, u8 *status)
366{
367 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
368 u16 slot_ctrl;
369 u8 atten_led_state;
370 int retval = 0;
371
372 DBG_ENTER_ROUTINE
373
374 if (!php_ctlr) {
375 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
376 return -1;
377 }
378
379 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
380
381 if (retval) {
382 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
383 return retval;
384 }
385
386 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl);
387
388 atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
389
390 switch (atten_led_state) {
391 case 0:
392 *status = 0xFF; /* Reserved */
393 break;
394 case 1:
395 *status = 1; /* On */
396 break;
397 case 2:
398 *status = 2; /* Blink */
399 break;
400 case 3:
401 *status = 0; /* Off */
402 break;
403 default:
404 *status = 0xFF;
405 break;
406 }
407
408 DBG_LEAVE_ROUTINE
409 return 0;
410}
411
412static int hpc_get_power_status(struct slot * slot, u8 *status)
413{
414 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
415 u16 slot_ctrl;
416 u8 pwr_state;
417 int retval = 0;
418
419 DBG_ENTER_ROUTINE
420
421 if (!php_ctlr) {
422 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
423 return -1;
424 }
425
426 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
427
428 if (retval) {
429 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
430 return retval;
431 }
432 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
433
434 pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
435
436 switch (pwr_state) {
437 case 0:
438 *status = 1;
439 break;
440 case 1:
441 *status = 0;
442 break;
443 default:
444 *status = 0xFF;
445 break;
446 }
447
448 DBG_LEAVE_ROUTINE
449 return retval;
450}
451
452
453static int hpc_get_latch_status(struct slot *slot, u8 *status)
454{
455 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
456 u16 slot_status;
457 int retval = 0;
458
459 DBG_ENTER_ROUTINE
460
461 if (!php_ctlr) {
462 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
463 return -1;
464 }
465
466 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
467
468 if (retval) {
469 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
470 return retval;
471 }
472
473 *status = (((slot_status & MRL_STATE) >> 5) == 0) ? 0 : 1;
474
475 DBG_LEAVE_ROUTINE
476 return 0;
477}
478
479static int hpc_get_adapter_status(struct slot *slot, u8 *status)
480{
481 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
482 u16 slot_status;
483 u8 card_state;
484 int retval = 0;
485
486 DBG_ENTER_ROUTINE
487
488 if (!php_ctlr) {
489 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
490 return -1;
491 }
492
493 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
494
495 if (retval) {
496 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
497 return retval;
498 }
499 card_state = (u8)((slot_status & PRSN_STATE) >> 6);
500 *status = (card_state == 1) ? 1 : 0;
501
502 DBG_LEAVE_ROUTINE
503 return 0;
504}
505
506static int hpc_query_power_fault(struct slot * slot)
507{
508 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
509 u16 slot_status;
510 u8 pwr_fault;
511 int retval = 0;
512 u8 status;
513
514 DBG_ENTER_ROUTINE
515
516 if (!php_ctlr) {
517 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
518 return -1;
519 }
520
521 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
522
523 if (retval) {
524 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
525 return retval;
526 }
527 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
528 status = (pwr_fault != 1) ? 1 : 0;
529
530 DBG_LEAVE_ROUTINE
531 /* Note: Logic 0 => fault */
532 return status;
533}
534
535static int hpc_set_attention_status(struct slot *slot, u8 value)
536{
537 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
538 u16 slot_cmd = 0;
539 u16 slot_ctrl;
540 int rc = 0;
541
542 dbg("%s: \n", __FUNCTION__);
543 if (!php_ctlr) {
544 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
545 return -1;
546 }
547
548 if (slot->hp_slot >= php_ctlr->num_slots) {
549 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
550 return -1;
551 }
552 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
553
554 if (rc) {
555 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
556 return rc;
557 }
558 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
559
560 switch (value) {
561 case 0 : /* turn off */
562 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0;
563 break;
564 case 1: /* turn on */
565 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040;
566 break;
567 case 2: /* turn blink */
568 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080;
569 break;
570 default:
571 return -1;
572 }
573 if (!pciehp_poll_mode)
574 slot_cmd = slot_cmd | HP_INTR_ENABLE;
575
576 pcie_write_cmd(slot, slot_cmd);
577 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
578
579 return rc;
580}
581
582
583static void hpc_set_green_led_on(struct slot *slot)
584{
585 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
586 u16 slot_cmd;
587 u16 slot_ctrl;
588 int rc = 0;
589
590 dbg("%s: \n", __FUNCTION__);
591 if (!php_ctlr) {
592 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
593 return ;
594 }
595
596 if (slot->hp_slot >= php_ctlr->num_slots) {
597 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
598 return ;
599 }
600
601 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
602
603 if (rc) {
604 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
605 return;
606 }
607 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
608 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
609 if (!pciehp_poll_mode)
610 slot_cmd = slot_cmd | HP_INTR_ENABLE;
611
612 pcie_write_cmd(slot, slot_cmd);
613
614 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
615 return;
616}
617
618static void hpc_set_green_led_off(struct slot *slot)
619{
620 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
621 u16 slot_cmd;
622 u16 slot_ctrl;
623 int rc = 0;
624
625 dbg("%s: \n", __FUNCTION__);
626 if (!php_ctlr) {
627 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
628 return ;
629 }
630
631 if (slot->hp_slot >= php_ctlr->num_slots) {
632 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
633 return ;
634 }
635
636 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
637
638 if (rc) {
639 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
640 return;
641 }
642 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
643
644 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
645
646 if (!pciehp_poll_mode)
647 slot_cmd = slot_cmd | HP_INTR_ENABLE;
648 pcie_write_cmd(slot, slot_cmd);
649 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
650
651 return;
652}
653
654static void hpc_set_green_led_blink(struct slot *slot)
655{
656 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
657 u16 slot_cmd;
658 u16 slot_ctrl;
659 int rc = 0;
660
661 dbg("%s: \n", __FUNCTION__);
662 if (!php_ctlr) {
663 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
664 return ;
665 }
666
667 if (slot->hp_slot >= php_ctlr->num_slots) {
668 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
669 return ;
670 }
671
672 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
673
674 if (rc) {
675 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
676 return;
677 }
678 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
679
680 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
681
682 if (!pciehp_poll_mode)
683 slot_cmd = slot_cmd | HP_INTR_ENABLE;
684 pcie_write_cmd(slot, slot_cmd);
685
686 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
687 return;
688}
689
690int pcie_get_ctlr_slot_config(struct controller *ctrl,
691 int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */
692 int *first_device_num, /* PCI dev num of the first slot in this PCIE */
693 int *physical_slot_num, /* phy slot num of the first slot in this PCIE */
694 u8 *ctrlcap)
695{
696 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
697 u32 slot_cap;
698 int rc = 0;
699
700 DBG_ENTER_ROUTINE
701
702 if (!php_ctlr) {
703 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
704 return -1;
705 }
706
707 *first_device_num = 0;
708 *num_ctlr_slots = 1;
709
710 rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
711
712 if (rc) {
713 err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
714 return -1;
715 }
716
717 *physical_slot_num = slot_cap >> 19;
718 dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
719
720 *ctrlcap = slot_cap & 0x0000007f;
721
722 DBG_LEAVE_ROUTINE
723 return 0;
724}
725
726static void hpc_release_ctlr(struct controller *ctrl)
727{
728 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
729 struct php_ctlr_state_s *p, *p_prev;
730
731 DBG_ENTER_ROUTINE
732
733 if (!php_ctlr) {
734 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
735 return ;
736 }
737
738 if (pciehp_poll_mode) {
739 del_timer(&php_ctlr->int_poll_timer);
740 } else {
741 if (php_ctlr->irq) {
742 free_irq(php_ctlr->irq, ctrl);
743 php_ctlr->irq = 0;
744 if (!pcie_mch_quirk)
745 pci_disable_msi(php_ctlr->pci_dev);
746 }
747 }
748 if (php_ctlr->pci_dev)
749 php_ctlr->pci_dev = NULL;
750
751 spin_lock(&list_lock);
752 p = php_ctlr_list_head;
753 p_prev = NULL;
754 while (p) {
755 if (p == php_ctlr) {
756 if (p_prev)
757 p_prev->pnext = p->pnext;
758 else
759 php_ctlr_list_head = p->pnext;
760 break;
761 } else {
762 p_prev = p;
763 p = p->pnext;
764 }
765 }
766 spin_unlock(&list_lock);
767
768 kfree(php_ctlr);
769
770 DBG_LEAVE_ROUTINE
771
772}
773
774static int hpc_power_on_slot(struct slot * slot)
775{
776 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
777 u16 slot_cmd;
778 u16 slot_ctrl;
779
780 int retval = 0;
781
782 DBG_ENTER_ROUTINE
783 dbg("%s: \n", __FUNCTION__);
784
785 if (!php_ctlr) {
786 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
787 return -1;
788 }
789
790 dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
791 if (slot->hp_slot >= php_ctlr->num_slots) {
792 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
793 return -1;
794 }
795
796 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
797
798 if (retval) {
799 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
800 return retval;
801 }
802 dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL,
803 slot_ctrl);
804
805 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
806
807 if (!pciehp_poll_mode)
808 slot_cmd = slot_cmd | HP_INTR_ENABLE;
809
810 retval = pcie_write_cmd(slot, slot_cmd);
811
812 if (retval) {
813 err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
814 return -1;
815 }
816 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
817
818 DBG_LEAVE_ROUTINE
819
820 return retval;
821}
822
823static int hpc_power_off_slot(struct slot * slot)
824{
825 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
826 u16 slot_cmd;
827 u16 slot_ctrl;
828
829 int retval = 0;
830
831 DBG_ENTER_ROUTINE
832 dbg("%s: \n", __FUNCTION__);
833
834 if (!php_ctlr) {
835 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
836 return -1;
837 }
838
839 dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
840 slot->hp_slot = 0;
841 if (slot->hp_slot >= php_ctlr->num_slots) {
842 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
843 return -1;
844 }
845 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
846
847 if (retval) {
848 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
849 return retval;
850 }
851 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL,
852 slot_ctrl);
853
854 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
855
856 if (!pciehp_poll_mode)
857 slot_cmd = slot_cmd | HP_INTR_ENABLE;
858
859 retval = pcie_write_cmd(slot, slot_cmd);
860
861 if (retval) {
862 err("%s: Write command failed!\n", __FUNCTION__);
863 return -1;
864 }
865 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
866
867 DBG_LEAVE_ROUTINE
868
869 return retval;
870}
871
872static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
873{
874 struct controller *ctrl = NULL;
875 struct php_ctlr_state_s *php_ctlr;
876 u8 schedule_flag = 0;
877 u16 slot_status, intr_detect, intr_loc;
878 u16 temp_word;
879 int hp_slot = 0; /* only 1 slot per PCI Express port */
880 int rc = 0;
881
882 if (!dev_id)
883 return IRQ_NONE;
884
885 if (!pciehp_poll_mode) {
886 ctrl = dev_id;
887 php_ctlr = ctrl->hpc_ctlr_handle;
888 } else {
889 php_ctlr = dev_id;
890 ctrl = (struct controller *)php_ctlr->callback_instance_id;
891 }
892
893 if (!ctrl) {
894 dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id);
895 return IRQ_NONE;
896 }
897
898 if (!php_ctlr) {
899 dbg("%s: php_ctlr == NULL\n", __FUNCTION__);
900 return IRQ_NONE;
901 }
902
903 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
904 if (rc) {
905 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
906 return IRQ_NONE;
907 }
908
909 intr_detect = ( ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | MRL_SENS_CHANGED |
910 PRSN_DETECT_CHANGED | CMD_COMPLETED );
911
912 intr_loc = slot_status & intr_detect;
913
914 /* Check to see if it was our interrupt */
915 if ( !intr_loc )
916 return IRQ_NONE;
917
918 dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
919 /* Mask Hot-plug Interrupt Enable */
920 if (!pciehp_poll_mode) {
921 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
922 if (rc) {
923 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
924 return IRQ_NONE;
925 }
926
927 dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
928 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
929 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
930
931 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
932 if (rc) {
933 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
934 return IRQ_NONE;
935 }
936 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
937
938 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
939 if (rc) {
940 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
941 return IRQ_NONE;
942 }
943 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
944
945 /* Clear command complete interrupt caused by this write */
946 temp_word = 0x1f;
947 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
948 if (rc) {
949 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
950 return IRQ_NONE;
951 }
952 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
953 }
954
955 if (intr_loc & CMD_COMPLETED) {
956 /*
957 * Command Complete Interrupt Pending
958 */
959 dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
960 wake_up_interruptible(&ctrl->queue);
961 }
962
963 if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED))
964 schedule_flag += php_ctlr->switch_change_callback(
965 hp_slot, php_ctlr->callback_instance_id);
966 if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED))
967 schedule_flag += php_ctlr->attention_button_callback(
968 hp_slot, php_ctlr->callback_instance_id);
969 if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED))
970 schedule_flag += php_ctlr->presence_change_callback(
971 hp_slot , php_ctlr->callback_instance_id);
972 if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED))
973 schedule_flag += php_ctlr->power_fault_callback(
974 hp_slot, php_ctlr->callback_instance_id);
975
976 /* Clear all events after serving them */
977 temp_word = 0x1F;
978 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
979 if (rc) {
980 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
981 return IRQ_NONE;
982 }
983 /* Unmask Hot-plug Interrupt Enable */
984 if (!pciehp_poll_mode) {
985 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
986 if (rc) {
987 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
988 return IRQ_NONE;
989 }
990
991 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
992 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
993 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
994
995 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
996 if (rc) {
997 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
998 return IRQ_NONE;
999 }
1000 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
1001
1002 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1003 if (rc) {
1004 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1005 return IRQ_NONE;
1006 }
1007 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
1008
1009 /* Clear command complete interrupt caused by this write */
1010 temp_word = 0x1F;
1011 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1012 if (rc) {
1013 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1014 return IRQ_NONE;
1015 }
1016 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
1017 }
1018
1019 return IRQ_HANDLED;
1020}
1021
1022static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
1023{
1024 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1025 enum pcie_link_speed lnk_speed;
1026 u32 lnk_cap;
1027 int retval = 0;
1028
1029 DBG_ENTER_ROUTINE
1030
1031 if (!php_ctlr) {
1032 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1033 return -1;
1034 }
1035
1036 if (slot->hp_slot >= php_ctlr->num_slots) {
1037 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1038 return -1;
1039 }
1040
1041 retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
1042
1043 if (retval) {
1044 err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
1045 return retval;
1046 }
1047
1048 switch (lnk_cap & 0x000F) {
1049 case 1:
1050 lnk_speed = PCIE_2PT5GB;
1051 break;
1052 default:
1053 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
1054 break;
1055 }
1056
1057 *value = lnk_speed;
1058 dbg("Max link speed = %d\n", lnk_speed);
1059 DBG_LEAVE_ROUTINE
1060 return retval;
1061}
1062
1063static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value)
1064{
1065 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1066 enum pcie_link_width lnk_wdth;
1067 u32 lnk_cap;
1068 int retval = 0;
1069
1070 DBG_ENTER_ROUTINE
1071
1072 if (!php_ctlr) {
1073 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1074 return -1;
1075 }
1076
1077 if (slot->hp_slot >= php_ctlr->num_slots) {
1078 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1079 return -1;
1080 }
1081
1082 retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
1083
1084 if (retval) {
1085 err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
1086 return retval;
1087 }
1088
1089 switch ((lnk_cap & 0x03F0) >> 4){
1090 case 0:
1091 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
1092 break;
1093 case 1:
1094 lnk_wdth = PCIE_LNK_X1;
1095 break;
1096 case 2:
1097 lnk_wdth = PCIE_LNK_X2;
1098 break;
1099 case 4:
1100 lnk_wdth = PCIE_LNK_X4;
1101 break;
1102 case 8:
1103 lnk_wdth = PCIE_LNK_X8;
1104 break;
1105 case 12:
1106 lnk_wdth = PCIE_LNK_X12;
1107 break;
1108 case 16:
1109 lnk_wdth = PCIE_LNK_X16;
1110 break;
1111 case 32:
1112 lnk_wdth = PCIE_LNK_X32;
1113 break;
1114 default:
1115 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1116 break;
1117 }
1118
1119 *value = lnk_wdth;
1120 dbg("Max link width = %d\n", lnk_wdth);
1121 DBG_LEAVE_ROUTINE
1122 return retval;
1123}
1124
1125static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
1126{
1127 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1128 enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
1129 int retval = 0;
1130 u16 lnk_status;
1131
1132 DBG_ENTER_ROUTINE
1133
1134 if (!php_ctlr) {
1135 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1136 return -1;
1137 }
1138
1139 if (slot->hp_slot >= php_ctlr->num_slots) {
1140 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1141 return -1;
1142 }
1143
1144 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
1145
1146 if (retval) {
1147 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
1148 return retval;
1149 }
1150
1151 switch (lnk_status & 0x0F) {
1152 case 1:
1153 lnk_speed = PCIE_2PT5GB;
1154 break;
1155 default:
1156 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
1157 break;
1158 }
1159
1160 *value = lnk_speed;
1161 dbg("Current link speed = %d\n", lnk_speed);
1162 DBG_LEAVE_ROUTINE
1163 return retval;
1164}
1165
1166static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value)
1167{
1168 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1169 enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1170 int retval = 0;
1171 u16 lnk_status;
1172
1173 DBG_ENTER_ROUTINE
1174
1175 if (!php_ctlr) {
1176 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1177 return -1;
1178 }
1179
1180 if (slot->hp_slot >= php_ctlr->num_slots) {
1181 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1182 return -1;
1183 }
1184
1185 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
1186
1187 if (retval) {
1188 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
1189 return retval;
1190 }
1191
1192 switch ((lnk_status & 0x03F0) >> 4){
1193 case 0:
1194 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
1195 break;
1196 case 1:
1197 lnk_wdth = PCIE_LNK_X1;
1198 break;
1199 case 2:
1200 lnk_wdth = PCIE_LNK_X2;
1201 break;
1202 case 4:
1203 lnk_wdth = PCIE_LNK_X4;
1204 break;
1205 case 8:
1206 lnk_wdth = PCIE_LNK_X8;
1207 break;
1208 case 12:
1209 lnk_wdth = PCIE_LNK_X12;
1210 break;
1211 case 16:
1212 lnk_wdth = PCIE_LNK_X16;
1213 break;
1214 case 32:
1215 lnk_wdth = PCIE_LNK_X32;
1216 break;
1217 default:
1218 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1219 break;
1220 }
1221
1222 *value = lnk_wdth;
1223 dbg("Current link width = %d\n", lnk_wdth);
1224 DBG_LEAVE_ROUTINE
1225 return retval;
1226}
1227
1228static struct hpc_ops pciehp_hpc_ops = {
1229 .power_on_slot = hpc_power_on_slot,
1230 .power_off_slot = hpc_power_off_slot,
1231 .set_attention_status = hpc_set_attention_status,
1232 .get_power_status = hpc_get_power_status,
1233 .get_attention_status = hpc_get_attention_status,
1234 .get_latch_status = hpc_get_latch_status,
1235 .get_adapter_status = hpc_get_adapter_status,
1236
1237 .get_max_bus_speed = hpc_get_max_lnk_speed,
1238 .get_cur_bus_speed = hpc_get_cur_lnk_speed,
1239 .get_max_lnk_width = hpc_get_max_lnk_width,
1240 .get_cur_lnk_width = hpc_get_cur_lnk_width,
1241
1242 .query_power_fault = hpc_query_power_fault,
1243 .green_led_on = hpc_set_green_led_on,
1244 .green_led_off = hpc_set_green_led_off,
1245 .green_led_blink = hpc_set_green_led_blink,
1246
1247 .release_ctlr = hpc_release_ctlr,
1248 .check_lnk_status = hpc_check_lnk_status,
1249};
1250
1251int pcie_init(struct controller * ctrl,
1252 struct pcie_device *dev,
1253 php_intr_callback_t attention_button_callback,
1254 php_intr_callback_t switch_change_callback,
1255 php_intr_callback_t presence_change_callback,
1256 php_intr_callback_t power_fault_callback)
1257{
1258 struct php_ctlr_state_s *php_ctlr, *p;
1259 void *instance_id = ctrl;
1260 int rc;
1261 static int first = 1;
1262 u16 temp_word;
1263 u16 cap_reg;
1264 u16 intr_enable = 0;
1265 u32 slot_cap;
1266 int cap_base, saved_cap_base;
1267 u16 slot_status, slot_ctrl;
1268 struct pci_dev *pdev;
1269
1270 DBG_ENTER_ROUTINE
1271
1272 spin_lock_init(&list_lock);
1273 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
1274
1275 if (!php_ctlr) { /* allocate controller state data */
1276 err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
1277 goto abort;
1278 }
1279
1280 memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
1281
1282 pdev = dev->port;
1283 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1284
1285 dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
1286 pdev->vendor, pdev->device);
1287
1288 saved_cap_base = pcie_cap_base;
1289
1290 if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) {
1291 dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
1292 goto abort_free_ctlr;
1293 }
1294
1295 pcie_cap_base = cap_base;
1296
1297 dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
1298
1299 rc = hp_register_read_word(pdev, CAP_REG, cap_reg);
1300 if (rc) {
1301 err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
1302 goto abort_free_ctlr;
1303 }
1304 dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg);
1305
1306 if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){
1307 dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
1308 goto abort_free_ctlr;
1309 }
1310
1311 rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
1312 if (rc) {
1313 err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
1314 goto abort_free_ctlr;
1315 }
1316 dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap);
1317
1318 if (!(slot_cap & HP_CAP)) {
1319 dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
1320 goto abort_free_ctlr;
1321 }
1322 /* For debugging purpose */
1323 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1324 if (rc) {
1325 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1326 goto abort_free_ctlr;
1327 }
1328 dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
1329
1330 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
1331 if (rc) {
1332 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1333 goto abort_free_ctlr;
1334 }
1335 dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
1336
1337 if (first) {
1338 spin_lock_init(&hpc_event_lock);
1339 first = 0;
1340 }
1341
1342 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
1343 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1344 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1345 if (pci_resource_len(pdev, rc) > 0)
1346 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
1347 pci_resource_start(pdev, rc), pci_resource_len(pdev, rc));
1348
1349 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
1350 pdev->subsystem_vendor, pdev->subsystem_device);
1351
1352 if (pci_enable_device(pdev))
1353 goto abort_free_ctlr;
1354
1355 init_MUTEX(&ctrl->crit_sect);
1356 /* setup wait queue */
1357 init_waitqueue_head(&ctrl->queue);
1358
1359 /* find the IRQ */
1360 php_ctlr->irq = dev->irq;
1361 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1362
1363 /* Save interrupt callback info */
1364 php_ctlr->attention_button_callback = attention_button_callback;
1365 php_ctlr->switch_change_callback = switch_change_callback;
1366 php_ctlr->presence_change_callback = presence_change_callback;
1367 php_ctlr->power_fault_callback = power_fault_callback;
1368 php_ctlr->callback_instance_id = instance_id;
1369
1370 /* return PCI Controller Info */
1371 php_ctlr->slot_device_offset = 0;
1372 php_ctlr->num_slots = 1;
1373
1374 /* Mask Hot-plug Interrupt Enable */
1375 rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
1376 if (rc) {
1377 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1378 goto abort_free_ctlr;
1379 }
1380
1381 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
1382 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
1383
1384 rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
1385 if (rc) {
1386 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1387 goto abort_free_ctlr;
1388 }
1389 dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
1390
1391 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1392 if (rc) {
1393 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1394 goto abort_free_ctlr;
1395 }
1396 dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
1397
1398 temp_word = 0x1F; /* Clear all events */
1399 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1400 if (rc) {
1401 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1402 goto abort_free_ctlr;
1403 }
1404 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
1405
1406 if (pciehp_poll_mode) {/* Install interrupt polling code */
1407 /* Install and start the interrupt polling timer */
1408 init_timer(&php_ctlr->int_poll_timer);
1409 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
1410 } else {
1411 /* Installs the interrupt handler */
1412 rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
1413 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1414 if (rc) {
1415 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1416 goto abort_free_ctlr;
1417 }
1418 }
1419
1420 rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
1421 if (rc) {
1422 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1423 goto abort_free_ctlr;
1424 }
1425 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
1426 dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
1427
1428 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
1429
1430 if (ATTN_BUTTN(slot_cap))
1431 intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
1432
1433 if (POWER_CTRL(slot_cap))
1434 intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
1435
1436 if (MRL_SENS(slot_cap))
1437 intr_enable = intr_enable | MRL_DETECT_ENABLE;
1438
1439 temp_word = (temp_word & ~intr_enable) | intr_enable;
1440
1441 if (pciehp_poll_mode) {
1442 temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0;
1443 } else {
1444 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
1445 }
1446 dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
1447
1448 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
1449 rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
1450 if (rc) {
1451 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1452 goto abort_free_ctlr;
1453 }
1454 dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
1455 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1456 if (rc) {
1457 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1458 goto abort_free_ctlr;
1459 }
1460 dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
1461 SLOT_STATUS, slot_status);
1462
1463 temp_word = 0x1F; /* Clear all events */
1464 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1465 if (rc) {
1466 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1467 goto abort_free_ctlr;
1468 }
1469 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
1470
1471 /* Add this HPC instance into the HPC list */
1472 spin_lock(&list_lock);
1473 if (php_ctlr_list_head == 0) {
1474 php_ctlr_list_head = php_ctlr;
1475 p = php_ctlr_list_head;
1476 p->pnext = NULL;
1477 } else {
1478 p = php_ctlr_list_head;
1479
1480 while (p->pnext)
1481 p = p->pnext;
1482
1483 p->pnext = php_ctlr;
1484 }
1485 spin_unlock(&list_lock);
1486
1487 ctlr_seq_num++;
1488 ctrl->hpc_ctlr_handle = php_ctlr;
1489 ctrl->hpc_ops = &pciehp_hpc_ops;
1490
1491 DBG_LEAVE_ROUTINE
1492 return 0;
1493
1494 /* We end up here for the many possible ways to fail this API. */
1495abort_free_ctlr:
1496 pcie_cap_base = saved_cap_base;
1497 kfree(php_ctlr);
1498abort:
1499 DBG_LEAVE_ROUTINE
1500 return -1;
1501}
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
new file mode 100644
index 000000000000..723b12c0bb7c
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -0,0 +1,827 @@
1/*
2 * PCI Express Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include "../pci.h"
39#include "pciehp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43
44
45int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)
46{
47 unsigned char bus;
48 struct pci_bus *child;
49 int num;
50
51 if (func->pci_dev == NULL)
52 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
53
54 /* Still NULL ? Well then scan for it ! */
55 if (func->pci_dev == NULL) {
56 dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
57
58 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
59
60 if (num)
61 pci_bus_add_devices(ctrl->pci_dev->subordinate);
62
63 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
64 if (func->pci_dev == NULL) {
65 dbg("ERROR: pci_dev still null\n");
66 return 0;
67 }
68 }
69
70 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
71 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
72 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
73 pci_do_scan_bus(child);
74
75 }
76
77 return 0;
78}
79
80
81int pciehp_unconfigure_device(struct pci_func* func)
82{
83 int rc = 0;
84 int j;
85 struct pci_bus *pbus;
86
87 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
88 func->device, func->function);
89 pbus = func->pci_dev->bus;
90
91 for (j=0; j<8 ; j++) {
92 struct pci_dev* temp = pci_find_slot(func->bus,
93 (func->device << 3) | j);
94 if (temp) {
95 pci_remove_bus_device(temp);
96 }
97 }
98 /*
99 * Some PCI Express root ports require fixup after hot-plug operation.
100 */
101 if (pcie_mch_quirk)
102 pci_fixup_device(pci_fixup_final, pbus->self);
103
104 return rc;
105}
106
107/*
108 * pciehp_set_irq
109 *
110 * @bus_num: bus number of PCI device
111 * @dev_num: device number of PCI device
112 * @slot: pointer to u8 where slot number will be returned
113 */
114int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
115{
116#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
117 int rc;
118 u16 temp_word;
119 struct pci_dev fakedev;
120 struct pci_bus fakebus;
121
122 fakedev.devfn = dev_num << 3;
123 fakedev.bus = &fakebus;
124 fakebus.number = bus_num;
125 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
126 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
127 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
128 dbg("%s: rc %d\n", __FUNCTION__, rc);
129 if (!rc)
130 return !rc;
131
132 /* set the Edge Level Control Register (ELCR) */
133 temp_word = inb(0x4d0);
134 temp_word |= inb(0x4d1) << 8;
135
136 temp_word |= 0x01 << irq_num;
137
138 /* This should only be for x86 as it sets the Edge Level Control Register */
139 outb((u8) (temp_word & 0xFF), 0x4d0);
140 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
141#endif
142 return 0;
143}
144
145/* More PCI configuration routines; this time centered around hotplug controller */
146
147
148/*
149 * pciehp_save_config
150 *
151 * Reads configuration for all slots in a PCI bus and saves info.
152 *
153 * Note: For non-hot plug busses, the slot # saved is the device #
154 *
155 * returns 0 if success
156 */
157int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
158{
159 int rc;
160 u8 class_code;
161 u8 header_type;
162 u32 ID;
163 u8 secondary_bus;
164 struct pci_func *new_slot;
165 int sub_bus;
166 int max_functions;
167 int function;
168 u8 DevError;
169 int device = 0;
170 int cloop = 0;
171 int stop_it;
172 int index;
173 int is_hot_plug = num_ctlr_slots || first_device_num;
174 struct pci_bus lpci_bus, *pci_bus;
175 int FirstSupported, LastSupported;
176
177 dbg("%s: Enter\n", __FUNCTION__);
178
179 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
180 pci_bus = &lpci_bus;
181
182 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
183 num_ctlr_slots, first_device_num);
184
185 /* Decide which slots are supported */
186 if (is_hot_plug) {
187 /*********************************
188 * is_hot_plug is the slot mask
189 *********************************/
190 FirstSupported = first_device_num;
191 LastSupported = FirstSupported + num_ctlr_slots - 1;
192 } else {
193 FirstSupported = 0;
194 LastSupported = 0x1F;
195 }
196
197 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
198 LastSupported);
199
200 /* Save PCI configuration space for all devices in supported slots */
201 dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
202 pci_bus->number = busnumber;
203 dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
204 for (device = FirstSupported; device <= LastSupported; device++) {
205 ID = 0xFFFFFFFF;
206 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
207 PCI_VENDOR_ID, &ID);
208
209 if (ID != 0xFFFFFFFF) { /* device in slot */
210 dbg("%s: ID = %x\n", __FUNCTION__, ID);
211 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
212 0x0B, &class_code);
213 if (rc)
214 return rc;
215
216 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
217 PCI_HEADER_TYPE, &header_type);
218 if (rc)
219 return rc;
220
221 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
222
223 /* If multi-function device, set max_functions to 8 */
224 if (header_type & 0x80)
225 max_functions = 8;
226 else
227 max_functions = 1;
228
229 function = 0;
230
231 do {
232 DevError = 0;
233 dbg("%s: In do loop\n", __FUNCTION__);
234
235 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
236 /* Recurse the subordinate bus
237 * get the subordinate bus number
238 */
239 rc = pci_bus_read_config_byte(pci_bus,
240 PCI_DEVFN(device, function),
241 PCI_SECONDARY_BUS, &secondary_bus);
242 if (rc) {
243 return rc;
244 } else {
245 sub_bus = (int) secondary_bus;
246
247 /* Save secondary bus cfg spc with this recursive call. */
248 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
249 if (rc)
250 return rc;
251 }
252 }
253
254 index = 0;
255 new_slot = pciehp_slot_find(busnumber, device, index++);
256
257 dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
258 __FUNCTION__, new_slot, busnumber, device, index-1);
259
260 while (new_slot && (new_slot->function != (u8) function)) {
261 new_slot = pciehp_slot_find(busnumber, device, index++);
262 dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
263 __FUNCTION__, new_slot, busnumber, device, index-1);
264 }
265 if (!new_slot) {
266 /* Setup slot structure. */
267 new_slot = pciehp_slot_create(busnumber);
268 dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
269 __FUNCTION__, new_slot, busnumber, device, function);
270
271 if (new_slot == NULL)
272 return(1);
273 }
274
275 new_slot->bus = (u8) busnumber;
276 new_slot->device = (u8) device;
277 new_slot->function = (u8) function;
278 new_slot->is_a_board = 1;
279 new_slot->switch_save = 0x10;
280 /* In case of unsupported board */
281 new_slot->status = DevError;
282 new_slot->pci_dev = pci_find_slot(new_slot->bus,
283 (new_slot->device << 3) | new_slot->function);
284 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
285
286 for (cloop = 0; cloop < 0x20; cloop++) {
287 rc = pci_bus_read_config_dword(pci_bus,
288 PCI_DEVFN(device, function),
289 cloop << 2,
290 (u32 *) &(new_slot->config_space [cloop]));
291 /* dbg("new_slot->config_space[%x] = %x\n",
292 cloop, new_slot->config_space[cloop]); */
293 if (rc)
294 return rc;
295 }
296
297 function++;
298
299 stop_it = 0;
300
301 /* this loop skips to the next present function
302 * reading in Class Code and Header type.
303 */
304
305 while ((function < max_functions)&&(!stop_it)) {
306 dbg("%s: In while loop \n", __FUNCTION__);
307 rc = pci_bus_read_config_dword(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_VENDOR_ID, &ID);
310
311 if (ID == 0xFFFFFFFF) { /* nothing there. */
312 function++;
313 dbg("Nothing there\n");
314 } else { /* Something there */
315 rc = pci_bus_read_config_byte(pci_bus,
316 PCI_DEVFN(device, function),
317 0x0B, &class_code);
318 if (rc)
319 return rc;
320
321 rc = pci_bus_read_config_byte(pci_bus,
322 PCI_DEVFN(device, function),
323 PCI_HEADER_TYPE, &header_type);
324 if (rc)
325 return rc;
326
327 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
328 stop_it++;
329 }
330 }
331
332 } while (function < max_functions);
333 /* End of IF (device in slot?) */
334 } else if (is_hot_plug) {
335 /* Setup slot structure with entry for empty slot */
336 new_slot = pciehp_slot_create(busnumber);
337
338 if (new_slot == NULL) {
339 return(1);
340 }
341 dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
342 new_slot->bus, new_slot->device, new_slot->function);
343
344 new_slot->bus = (u8) busnumber;
345 new_slot->device = (u8) device;
346 new_slot->function = 0;
347 new_slot->is_a_board = 0;
348 new_slot->presence_save = 0;
349 new_slot->switch_save = 0;
350 }
351 } /* End of FOR loop */
352
353 dbg("%s: Exit\n", __FUNCTION__);
354 return(0);
355}
356
357
358/*
359 * pciehp_save_slot_config
360 *
361 * Saves configuration info for all PCI devices in a given slot
362 * including subordinate busses.
363 *
364 * returns 0 if success
365 */
366int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
367{
368 int rc;
369 u8 class_code;
370 u8 header_type;
371 u32 ID;
372 u8 secondary_bus;
373 int sub_bus;
374 int max_functions;
375 int function;
376 int cloop = 0;
377 int stop_it;
378 struct pci_bus lpci_bus, *pci_bus;
379 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
380 pci_bus = &lpci_bus;
381 pci_bus->number = new_slot->bus;
382
383 ID = 0xFFFFFFFF;
384
385 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
386 PCI_VENDOR_ID, &ID);
387
388 if (ID != 0xFFFFFFFF) { /* device in slot */
389 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
390 0x0B, &class_code);
391
392 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
393 PCI_HEADER_TYPE, &header_type);
394
395 if (header_type & 0x80) /* Multi-function device */
396 max_functions = 8;
397 else
398 max_functions = 1;
399
400 function = 0;
401
402 do {
403 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
404 /* Recurse the subordinate bus */
405 pci_bus_read_config_byte(pci_bus,
406 PCI_DEVFN(new_slot->device, function),
407 PCI_SECONDARY_BUS, &secondary_bus);
408
409 sub_bus = (int) secondary_bus;
410
411 /* Save the config headers for the secondary bus. */
412 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
413
414 if (rc)
415 return rc;
416
417 } /* End of IF */
418
419 new_slot->status = 0;
420
421 for (cloop = 0; cloop < 0x20; cloop++) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 cloop << 2,
425 (u32 *) &(new_slot->config_space [cloop]));
426 }
427
428 function++;
429
430 stop_it = 0;
431
432 /* this loop skips to the next present function
433 * reading in the Class Code and the Header type.
434 */
435
436 while ((function < max_functions) && (!stop_it)) {
437 pci_bus_read_config_dword(pci_bus,
438 PCI_DEVFN(new_slot->device, function),
439 PCI_VENDOR_ID, &ID);
440
441 if (ID == 0xFFFFFFFF) { /* nothing there. */
442 function++;
443 } else { /* Something there */
444 pci_bus_read_config_byte(pci_bus,
445 PCI_DEVFN(new_slot->device, function),
446 0x0B, &class_code);
447
448 pci_bus_read_config_byte(pci_bus,
449 PCI_DEVFN(new_slot->device, function),
450 PCI_HEADER_TYPE, &header_type);
451
452 stop_it++;
453 }
454 }
455
456 } while (function < max_functions);
457 } /* End of IF (device in slot?) */
458 else {
459 return 2;
460 }
461
462 return 0;
463}
464
465
466/*
467 * pciehp_save_used_resources
468 *
469 * Stores used resource information for existing boards. this is
470 * for boards that were in the system when this driver was loaded.
471 * this function is for hot plug ADD
472 *
473 * returns 0 if success
474 * if disable == 1(DISABLE_CARD),
475 * it loops for all functions of the slot and disables them.
476 * else, it just get resources of the function and return.
477 */
478int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
479{
480 u8 cloop;
481 u8 header_type;
482 u8 secondary_bus;
483 u8 temp_byte;
484 u16 command;
485 u16 save_command;
486 u16 w_base, w_length;
487 u32 temp_register;
488 u32 save_base;
489 u32 base, length;
490 u64 base64 = 0;
491 int index = 0;
492 unsigned int devfn;
493 struct pci_resource *mem_node = NULL;
494 struct pci_resource *p_mem_node = NULL;
495 struct pci_resource *t_mem_node;
496 struct pci_resource *io_node;
497 struct pci_resource *bus_node;
498 struct pci_bus lpci_bus, *pci_bus;
499 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
500 pci_bus = &lpci_bus;
501
502 if (disable)
503 func = pciehp_slot_find(func->bus, func->device, index++);
504
505 while ((func != NULL) && func->is_a_board) {
506 pci_bus->number = func->bus;
507 devfn = PCI_DEVFN(func->device, func->function);
508
509 /* Save the command register */
510 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
511
512 if (disable) {
513 /* disable card */
514 command = 0x00;
515 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
516 }
517
518 /* Check for Bridge */
519 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
520
521 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
522 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
523 func->bus, func->device, save_command);
524 if (disable) {
525 /* Clear Bridge Control Register */
526 command = 0x00;
527 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
528 }
529
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
531 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
532
533 bus_node = kmalloc(sizeof(struct pci_resource),
534 GFP_KERNEL);
535 if (!bus_node)
536 return -ENOMEM;
537
538 bus_node->base = (ulong)secondary_bus;
539 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
540
541 bus_node->next = func->bus_head;
542 func->bus_head = bus_node;
543
544 /* Save IO base and Limit registers */
545 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
546 base = temp_byte;
547 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
548 length = temp_byte;
549
550 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
551 io_node = kmalloc(sizeof(struct pci_resource),
552 GFP_KERNEL);
553 if (!io_node)
554 return -ENOMEM;
555
556 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
557 io_node->length = (ulong)(length - base + 0x10) << 8;
558
559 io_node->next = func->io_head;
560 func->io_head = io_node;
561 }
562
563 /* Save memory base and Limit registers */
564 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
565 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
566
567 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
568 mem_node = kmalloc(sizeof(struct pci_resource),
569 GFP_KERNEL);
570 if (!mem_node)
571 return -ENOMEM;
572
573 mem_node->base = (ulong)w_base << 16;
574 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
575
576 mem_node->next = func->mem_head;
577 func->mem_head = mem_node;
578 }
579 /* Save prefetchable memory base and Limit registers */
580 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
581 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
582
583 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
584 p_mem_node = kmalloc(sizeof(struct pci_resource),
585 GFP_KERNEL);
586 if (!p_mem_node)
587 return -ENOMEM;
588
589 p_mem_node->base = (ulong)w_base << 16;
590 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
591
592 p_mem_node->next = func->p_mem_head;
593 func->p_mem_head = p_mem_node;
594 }
595 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
596 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
597 func->bus, func->device, save_command);
598
599 /* Figure out IO and memory base lengths */
600 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
601 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
602
603 temp_register = 0xFFFFFFFF;
604 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
605 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
606
607 if (!disable)
608 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
609
610 if (!temp_register)
611 continue;
612
613 base = temp_register;
614
615 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
616 (!disable || (save_command & PCI_COMMAND_IO))) {
617 /* IO base */
618 /* set temp_register = amount of IO space requested */
619 base = base & 0xFFFFFFFCL;
620 base = (~base) + 1;
621
622 io_node = kmalloc(sizeof (struct pci_resource),
623 GFP_KERNEL);
624 if (!io_node)
625 return -ENOMEM;
626
627 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
628 io_node->length = (ulong)base;
629 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
630 io_node->base, io_node->length);
631
632 io_node->next = func->io_head;
633 func->io_head = io_node;
634 } else { /* map Memory */
635 int prefetchable = 1;
636 /* struct pci_resources **res_node; */
637 char *res_type_str = "PMEM";
638 u32 temp_register2;
639
640 t_mem_node = kmalloc(sizeof (struct pci_resource),
641 GFP_KERNEL);
642 if (!t_mem_node)
643 return -ENOMEM;
644
645 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
646 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
647 prefetchable = 0;
648 mem_node = t_mem_node;
649 res_type_str++;
650 } else
651 p_mem_node = t_mem_node;
652
653 base = base & 0xFFFFFFF0L;
654 base = (~base) + 1;
655
656 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
657 case PCI_BASE_ADDRESS_MEM_TYPE_32:
658 if (prefetchable) {
659 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
660 p_mem_node->length = (ulong)base;
661 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
662 res_type_str,
663 p_mem_node->base,
664 p_mem_node->length);
665
666 p_mem_node->next = func->p_mem_head;
667 func->p_mem_head = p_mem_node;
668 } else {
669 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
670 mem_node->length = (ulong)base;
671 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
672 res_type_str,
673 mem_node->base,
674 mem_node->length);
675
676 mem_node->next = func->mem_head;
677 func->mem_head = mem_node;
678 }
679 break;
680 case PCI_BASE_ADDRESS_MEM_TYPE_64:
681 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
682 base64 = temp_register2;
683 base64 = (base64 << 32) | save_base;
684
685 if (temp_register2) {
686 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
687 res_type_str, temp_register2, (u32)base64);
688 base64 &= 0x00000000FFFFFFFFL;
689 }
690
691 if (prefetchable) {
692 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
693 p_mem_node->length = base;
694 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
695 res_type_str,
696 p_mem_node->base,
697 p_mem_node->length);
698
699 p_mem_node->next = func->p_mem_head;
700 func->p_mem_head = p_mem_node;
701 } else {
702 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
703 mem_node->length = base;
704 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
705 res_type_str,
706 mem_node->base,
707 mem_node->length);
708
709 mem_node->next = func->mem_head;
710 func->mem_head = mem_node;
711 }
712 cloop += 4;
713 break;
714 default:
715 dbg("asur: reserved BAR type=0x%x\n",
716 temp_register);
717 break;
718 }
719 }
720 } /* End of base register loop */
721 } else { /* Some other unknown header type */
722 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
723 func->bus, func->device);
724 }
725
726 /* find the next device in this slot */
727 if (!disable)
728 break;
729 func = pciehp_slot_find(func->bus, func->device, index++);
730 }
731
732 return 0;
733}
734
735
736/**
737 * kfree_resource_list: release memory of all list members
738 * @res: resource list to free
739 */
740static inline void
741return_resource_list(struct pci_resource **func, struct pci_resource **res)
742{
743 struct pci_resource *node;
744 struct pci_resource *t_node;
745
746 node = *func;
747 *func = NULL;
748 while (node) {
749 t_node = node->next;
750 return_resource(res, node);
751 node = t_node;
752 }
753}
754
755/*
756 * pciehp_return_board_resources
757 *
758 * this routine returns all resources allocated to a board to
759 * the available pool.
760 *
761 * returns 0 if success
762 */
763int pciehp_return_board_resources(struct pci_func * func,
764 struct resource_lists * resources)
765{
766 int rc;
767
768 dbg("%s\n", __FUNCTION__);
769
770 if (!func)
771 return 1;
772
773 return_resource_list(&(func->io_head),&(resources->io_head));
774 return_resource_list(&(func->mem_head),&(resources->mem_head));
775 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
776 return_resource_list(&(func->bus_head),&(resources->bus_head));
777
778 rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
779 rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
780 rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
781 rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
782
783 return rc;
784}
785
786/**
787 * kfree_resource_list: release memory of all list members
788 * @res: resource list to free
789 */
790static inline void
791kfree_resource_list(struct pci_resource **r)
792{
793 struct pci_resource *res, *tres;
794
795 res = *r;
796 *r = NULL;
797
798 while (res) {
799 tres = res;
800 res = res->next;
801 kfree(tres);
802 }
803}
804
805/**
806 * pciehp_destroy_resource_list: put node back in the resource list
807 * @resources: list to put nodes back
808 */
809void pciehp_destroy_resource_list(struct resource_lists * resources)
810{
811 kfree_resource_list(&(resources->io_head));
812 kfree_resource_list(&(resources->mem_head));
813 kfree_resource_list(&(resources->p_mem_head));
814 kfree_resource_list(&(resources->bus_head));
815}
816
817/**
818 * pciehp_destroy_board_resources: put node back in the resource list
819 * @resources: list to put nodes back
820 */
821void pciehp_destroy_board_resources(struct pci_func * func)
822{
823 kfree_resource_list(&(func->io_head));
824 kfree_resource_list(&(func->mem_head));
825 kfree_resource_list(&(func->p_mem_head));
826 kfree_resource_list(&(func->bus_head));
827}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
new file mode 100644
index 000000000000..966775ffb0ff
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm.h
@@ -0,0 +1,52 @@
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>, <dely.l.sy@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
new file mode 100644
index 000000000000..57f4e6d1b27c
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -0,0 +1,1737 @@
1/*
2 * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
3 *
4 * Copyright (C) 2003-2004 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 <dely.l.sy@intel.com>
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <linux/pci-acpi.h>
36#include <asm/uaccess.h>
37#include <asm/system.h>
38#ifdef CONFIG_IA64
39#include <asm/iosapic.h>
40#endif
41#include <acpi/acpi.h>
42#include <acpi/acpi_bus.h>
43#include <acpi/actypes.h>
44#include "pciehp.h"
45#include "pciehprm.h"
46
47#define PCI_MAX_BUS 0x100
48#define ACPI_STA_DEVICE_PRESENT 0x01
49
50#define METHOD_NAME__SUN "_SUN"
51#define METHOD_NAME__HPP "_HPP"
52#define METHOD_NAME_OSHP "OSHP"
53
54/* Status code for running acpi method to gain native control */
55#define NC_NOT_RUN 0
56#define OSC_NOT_EXIST 1
57#define OSC_RUN_FAILED 2
58#define OSHP_NOT_EXIST 3
59#define OSHP_RUN_FAILED 4
60#define NC_RUN_SUCCESS 5
61
62#define PHP_RES_BUS 0xA0
63#define PHP_RES_IO 0xA1
64#define PHP_RES_MEM 0xA2
65#define PHP_RES_PMEM 0xA3
66
67#define BRIDGE_TYPE_P2P 0x00
68#define BRIDGE_TYPE_HOST 0x01
69
70/* this should go to drivers/acpi/include/ */
71struct acpi__hpp {
72 u8 cache_line_size;
73 u8 latency_timer;
74 u8 enable_serr;
75 u8 enable_perr;
76};
77
78struct acpi_php_slot {
79 struct acpi_php_slot *next;
80 struct acpi_bridge *bridge;
81 acpi_handle handle;
82 int seg;
83 int bus;
84 int dev;
85 int fun;
86 u32 sun;
87 struct pci_resource *mem_head;
88 struct pci_resource *p_mem_head;
89 struct pci_resource *io_head;
90 struct pci_resource *bus_head;
91 void *slot_ops; /* _STA, _EJx, etc */
92 struct slot *slot;
93}; /* per func */
94
95struct acpi_bridge {
96 struct acpi_bridge *parent;
97 struct acpi_bridge *next;
98 struct acpi_bridge *child;
99 acpi_handle handle;
100 int seg;
101 int pbus; /* pdev->bus->number */
102 int pdevice; /* PCI_SLOT(pdev->devfn) */
103 int pfunction; /* PCI_DEVFN(pdev->devfn) */
104 int bus; /* pdev->subordinate->number */
105 struct acpi__hpp *_hpp;
106 struct acpi_php_slot *slots;
107 struct pci_resource *tmem_head; /* total from crs */
108 struct pci_resource *tp_mem_head; /* total from crs */
109 struct pci_resource *tio_head; /* total from crs */
110 struct pci_resource *tbus_head; /* total from crs */
111 struct pci_resource *mem_head; /* available */
112 struct pci_resource *p_mem_head; /* available */
113 struct pci_resource *io_head; /* available */
114 struct pci_resource *bus_head; /* available */
115 int scanned;
116 int type;
117};
118
119static struct acpi_bridge *acpi_bridges_head;
120
121static u8 * acpi_path_name( acpi_handle handle)
122{
123 acpi_status status;
124 static u8 path_name[ACPI_PATHNAME_MAX];
125 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
126
127 memset(path_name, 0, sizeof (path_name));
128 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
129
130 if (ACPI_FAILURE(status))
131 return NULL;
132 else
133 return path_name;
134}
135
136static void acpi_get__hpp ( struct acpi_bridge *ab);
137static int acpi_run_oshp ( struct acpi_bridge *ab);
138static int osc_run_status = NC_NOT_RUN;
139static int oshp_run_status = NC_NOT_RUN;
140
141static int acpi_add_slot_to_php_slots(
142 struct acpi_bridge *ab,
143 int bus_num,
144 acpi_handle handle,
145 u32 adr,
146 u32 sun
147 )
148{
149 struct acpi_php_slot *aps;
150 static long samesun = -1;
151
152 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
153 if (!aps) {
154 err ("acpi_pciehprm: alloc for aps fail\n");
155 return -1;
156 }
157 memset(aps, 0, sizeof(struct acpi_php_slot));
158
159 aps->handle = handle;
160 aps->bus = bus_num;
161 aps->dev = (adr >> 16) & 0xffff;
162 aps->fun = adr & 0xffff;
163 aps->sun = sun;
164
165 aps->next = ab->slots; /* cling to the bridge */
166 aps->bridge = ab;
167 ab->slots = aps;
168
169 ab->scanned += 1;
170 if (!ab->_hpp)
171 acpi_get__hpp(ab);
172
173 if (osc_run_status == OSC_NOT_EXIST)
174 oshp_run_status = acpi_run_oshp(ab);
175
176 if (sun != samesun) {
177 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
178 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
179 samesun = sun;
180 }
181 return 0;
182}
183
184static void acpi_get__hpp ( struct acpi_bridge *ab)
185{
186 acpi_status status;
187 u8 nui[4];
188 struct acpi_buffer ret_buf = { 0, NULL};
189 union acpi_object *ext_obj, *package;
190 u8 *path_name = acpi_path_name(ab->handle);
191 int i, len = 0;
192
193 /* get _hpp */
194 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
195 switch (status) {
196 case AE_BUFFER_OVERFLOW:
197 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
198 if (!ret_buf.pointer) {
199 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
200 return;
201 }
202 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
203 if (ACPI_SUCCESS(status))
204 break;
205 default:
206 if (ACPI_FAILURE(status)) {
207 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
208 return;
209 }
210 }
211
212 ext_obj = (union acpi_object *) ret_buf.pointer;
213 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
214 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
215 goto free_and_return;
216 }
217
218 len = ext_obj->package.count;
219 package = (union acpi_object *) ret_buf.pointer;
220 for ( i = 0; (i < len) || (i < 4); i++) {
221 ext_obj = (union acpi_object *) &package->package.elements[i];
222 switch (ext_obj->type) {
223 case ACPI_TYPE_INTEGER:
224 nui[i] = (u8)ext_obj->integer.value;
225 break;
226 default:
227 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
228 goto free_and_return;
229 }
230 }
231
232 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
233 if (!ab->_hpp) {
234 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
235 goto free_and_return;
236 }
237 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
238
239 ab->_hpp->cache_line_size = nui[0];
240 ab->_hpp->latency_timer = nui[1];
241 ab->_hpp->enable_serr = nui[2];
242 ab->_hpp->enable_perr = nui[3];
243
244 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
245 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
246 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
247 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
248
249free_and_return:
250 kfree(ret_buf.pointer);
251}
252
253static int acpi_run_oshp ( struct acpi_bridge *ab)
254{
255 acpi_status status;
256 u8 *path_name = acpi_path_name(ab->handle);
257
258 /* run OSHP */
259 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
260 if (ACPI_FAILURE(status)) {
261 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
262 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
263 } else {
264 oshp_run_status = NC_RUN_SUCCESS;
265 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
266 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
267 }
268 return oshp_run_status;
269}
270
271static acpi_status acpi_evaluate_crs(
272 acpi_handle handle,
273 struct acpi_resource **retbuf
274 )
275{
276 acpi_status status;
277 struct acpi_buffer crsbuf;
278 u8 *path_name = acpi_path_name(handle);
279
280 crsbuf.length = 0;
281 crsbuf.pointer = NULL;
282
283 status = acpi_get_current_resources (handle, &crsbuf);
284
285 switch (status) {
286 case AE_BUFFER_OVERFLOW:
287 break; /* found */
288 case AE_NOT_FOUND:
289 dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
290 return status;
291 default:
292 err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
293 return status;
294 }
295
296 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
297 if (!crsbuf.pointer) {
298 err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
299 return AE_NO_MEMORY;
300 }
301
302 status = acpi_get_current_resources (handle, &crsbuf);
303 if (ACPI_FAILURE(status)) {
304 err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
305 kfree(crsbuf.pointer);
306 return status;
307 }
308
309 *retbuf = crsbuf.pointer;
310
311 return status;
312}
313
314static void free_pci_resource ( struct pci_resource *aprh)
315{
316 struct pci_resource *res, *next;
317
318 for (res = aprh; res; res = next) {
319 next = res->next;
320 kfree(res);
321 }
322}
323
324static void print_pci_resource ( struct pci_resource *aprh)
325{
326 struct pci_resource *res;
327
328 for (res = aprh; res; res = res->next)
329 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
330}
331
332static void print_slot_resources( struct acpi_php_slot *aps)
333{
334 if (aps->bus_head) {
335 dbg(" BUS Resources:\n");
336 print_pci_resource (aps->bus_head);
337 }
338
339 if (aps->io_head) {
340 dbg(" IO Resources:\n");
341 print_pci_resource (aps->io_head);
342 }
343
344 if (aps->mem_head) {
345 dbg(" MEM Resources:\n");
346 print_pci_resource (aps->mem_head);
347 }
348
349 if (aps->p_mem_head) {
350 dbg(" PMEM Resources:\n");
351 print_pci_resource (aps->p_mem_head);
352 }
353}
354
355static void print_pci_resources( struct acpi_bridge *ab)
356{
357 if (ab->tbus_head) {
358 dbg(" Total BUS Resources:\n");
359 print_pci_resource (ab->tbus_head);
360 }
361 if (ab->bus_head) {
362 dbg(" BUS Resources:\n");
363 print_pci_resource (ab->bus_head);
364 }
365
366 if (ab->tio_head) {
367 dbg(" Total IO Resources:\n");
368 print_pci_resource (ab->tio_head);
369 }
370 if (ab->io_head) {
371 dbg(" IO Resources:\n");
372 print_pci_resource (ab->io_head);
373 }
374
375 if (ab->tmem_head) {
376 dbg(" Total MEM Resources:\n");
377 print_pci_resource (ab->tmem_head);
378 }
379 if (ab->mem_head) {
380 dbg(" MEM Resources:\n");
381 print_pci_resource (ab->mem_head);
382 }
383
384 if (ab->tp_mem_head) {
385 dbg(" Total PMEM Resources:\n");
386 print_pci_resource (ab->tp_mem_head);
387 }
388 if (ab->p_mem_head) {
389 dbg(" PMEM Resources:\n");
390 print_pci_resource (ab->p_mem_head);
391 }
392 if (ab->_hpp) {
393 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
394 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
395 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
396 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
397 }
398}
399
400static int pciehprm_delete_resource(
401 struct pci_resource **aprh,
402 ulong base,
403 ulong size)
404{
405 struct pci_resource *res;
406 struct pci_resource *prevnode;
407 struct pci_resource *split_node;
408 ulong tbase;
409
410 pciehp_resource_sort_and_combine(aprh);
411
412 for (res = *aprh; res; res = res->next) {
413 if (res->base > base)
414 continue;
415
416 if ((res->base + res->length) < (base + size))
417 continue;
418
419 if (res->base < base) {
420 tbase = base;
421
422 if ((res->length - (tbase - res->base)) < size)
423 continue;
424
425 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
426 if (!split_node)
427 return -ENOMEM;
428
429 split_node->base = res->base;
430 split_node->length = tbase - res->base;
431 res->base = tbase;
432 res->length -= split_node->length;
433
434 split_node->next = res->next;
435 res->next = split_node;
436 }
437
438 if (res->length >= size) {
439 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
440 if (!split_node)
441 return -ENOMEM;
442
443 split_node->base = res->base + size;
444 split_node->length = res->length - size;
445 res->length = size;
446
447 split_node->next = res->next;
448 res->next = split_node;
449 }
450
451 if (*aprh == res) {
452 *aprh = res->next;
453 } else {
454 prevnode = *aprh;
455 while (prevnode->next != res)
456 prevnode = prevnode->next;
457
458 prevnode->next = res->next;
459 }
460 res->next = NULL;
461 kfree(res);
462 break;
463 }
464
465 return 0;
466}
467
468static int pciehprm_delete_resources(
469 struct pci_resource **aprh,
470 struct pci_resource *this
471 )
472{
473 struct pci_resource *res;
474
475 for (res = this; res; res = res->next)
476 pciehprm_delete_resource(aprh, res->base, res->length);
477
478 return 0;
479}
480
481static int pciehprm_add_resource(
482 struct pci_resource **aprh,
483 ulong base,
484 ulong size)
485{
486 struct pci_resource *res;
487
488 for (res = *aprh; res; res = res->next) {
489 if ((res->base + res->length) == base) {
490 res->length += size;
491 size = 0L;
492 break;
493 }
494 if (res->next == *aprh)
495 break;
496 }
497
498 if (size) {
499 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
500 if (!res) {
501 err ("acpi_pciehprm: alloc for res fail\n");
502 return -ENOMEM;
503 }
504 memset(res, 0, sizeof (struct pci_resource));
505
506 res->base = base;
507 res->length = size;
508 res->next = *aprh;
509 *aprh = res;
510 }
511
512 return 0;
513}
514
515static int pciehprm_add_resources(
516 struct pci_resource **aprh,
517 struct pci_resource *this
518 )
519{
520 struct pci_resource *res;
521 int rc = 0;
522
523 for (res = this; res && !rc; res = res->next)
524 rc = pciehprm_add_resource(aprh, res->base, res->length);
525
526 return rc;
527}
528
529static void acpi_parse_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{
534 struct acpi_resource_io *dataio;
535 dataio = (struct acpi_resource_io *) data;
536
537 dbg("Io Resource\n");
538 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
539 dbg(" Range minimum base: %08X\n", dataio->min_base_address);
540 dbg(" Range maximum base: %08X\n", dataio->max_base_address);
541 dbg(" Alignment: %08X\n", dataio->alignment);
542 dbg(" Range Length: %08X\n", dataio->range_length);
543}
544
545static void acpi_parse_fixed_io (
546 struct acpi_bridge *ab,
547 union acpi_resource_data *data
548 )
549{
550 struct acpi_resource_fixed_io *datafio;
551 datafio = (struct acpi_resource_fixed_io *) data;
552
553 dbg("Fixed Io Resource\n");
554 dbg(" Range base address: %08X", datafio->base_address);
555 dbg(" Range length: %08X", datafio->range_length);
556}
557
558static void acpi_parse_address16_32 (
559 struct acpi_bridge *ab,
560 union acpi_resource_data *data,
561 acpi_resource_type id
562 )
563{
564 /*
565 * acpi_resource_address16 == acpi_resource_address32
566 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
567 */
568 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
569 struct pci_resource **aprh, **tprh;
570
571 if (id == ACPI_RSTYPE_ADDRESS16)
572 dbg("acpi_pciehprm:16-Bit Address Space Resource\n");
573 else
574 dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
575
576 switch (data32->resource_type) {
577 case ACPI_MEMORY_RANGE:
578 dbg(" Resource Type: Memory Range\n");
579 aprh = &ab->mem_head;
580 tprh = &ab->tmem_head;
581
582 switch (data32->attribute.memory.cache_attribute) {
583 case ACPI_NON_CACHEABLE_MEMORY:
584 dbg(" Type Specific: Noncacheable memory\n");
585 break;
586 case ACPI_CACHABLE_MEMORY:
587 dbg(" Type Specific: Cacheable memory\n");
588 break;
589 case ACPI_WRITE_COMBINING_MEMORY:
590 dbg(" Type Specific: Write-combining memory\n");
591 break;
592 case ACPI_PREFETCHABLE_MEMORY:
593 aprh = &ab->p_mem_head;
594 dbg(" Type Specific: Prefetchable memory\n");
595 break;
596 default:
597 dbg(" Type Specific: Invalid cache attribute\n");
598 break;
599 }
600
601 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
602 break;
603
604 case ACPI_IO_RANGE:
605 dbg(" Resource Type: I/O Range\n");
606 aprh = &ab->io_head;
607 tprh = &ab->tio_head;
608
609 switch (data32->attribute.io.range_attribute) {
610 case ACPI_NON_ISA_ONLY_RANGES:
611 dbg(" Type Specific: Non-ISA Io Addresses\n");
612 break;
613 case ACPI_ISA_ONLY_RANGES:
614 dbg(" Type Specific: ISA Io Addresses\n");
615 break;
616 case ACPI_ENTIRE_RANGE:
617 dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
618 break;
619 default:
620 dbg(" Type Specific: Invalid range attribute\n");
621 break;
622 }
623 break;
624
625 case ACPI_BUS_NUMBER_RANGE:
626 dbg(" Resource Type: Bus Number Range(fixed)\n");
627 /* fixup to be compatible with the rest of php driver */
628 data32->min_address_range++;
629 data32->address_length--;
630 aprh = &ab->bus_head;
631 tprh = &ab->tbus_head;
632 break;
633 default:
634 dbg(" Resource Type: Invalid resource type. Exiting.\n");
635 return;
636 }
637
638 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
639 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
640 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
641 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
642 dbg(" Granularity: %08X\n", data32->granularity);
643 dbg(" Address range min: %08X\n", data32->min_address_range);
644 dbg(" Address range max: %08X\n", data32->max_address_range);
645 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
646 dbg(" Address Length: %08X\n", data32->address_length);
647
648 if (0xFF != data32->resource_source.index) {
649 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
650 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
651 }
652
653 pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
654}
655
656static acpi_status acpi_parse_crs(
657 struct acpi_bridge *ab,
658 struct acpi_resource *crsbuf
659 )
660{
661 acpi_status status = AE_OK;
662 struct acpi_resource *resource = crsbuf;
663 u8 count = 0;
664 u8 done = 0;
665
666 while (!done) {
667 dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
668 switch (resource->id) {
669 case ACPI_RSTYPE_IRQ:
670 dbg("Irq -------- Resource\n");
671 break;
672 case ACPI_RSTYPE_DMA:
673 dbg("DMA -------- Resource\n");
674 break;
675 case ACPI_RSTYPE_START_DPF:
676 dbg("Start DPF -------- Resource\n");
677 break;
678 case ACPI_RSTYPE_END_DPF:
679 dbg("End DPF -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_IO:
682 acpi_parse_io (ab, &resource->data);
683 break;
684 case ACPI_RSTYPE_FIXED_IO:
685 acpi_parse_fixed_io (ab, &resource->data);
686 break;
687 case ACPI_RSTYPE_VENDOR:
688 dbg("Vendor -------- Resource\n");
689 break;
690 case ACPI_RSTYPE_END_TAG:
691 dbg("End_tag -------- Resource\n");
692 done = 1;
693 break;
694 case ACPI_RSTYPE_MEM24:
695 dbg("Mem24 -------- Resource\n");
696 break;
697 case ACPI_RSTYPE_MEM32:
698 dbg("Mem32 -------- Resource\n");
699 break;
700 case ACPI_RSTYPE_FIXED_MEM32:
701 dbg("Fixed Mem32 -------- Resource\n");
702 break;
703 case ACPI_RSTYPE_ADDRESS16:
704 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
705 break;
706 case ACPI_RSTYPE_ADDRESS32:
707 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
708 break;
709 case ACPI_RSTYPE_ADDRESS64:
710 info("Address64 -------- Resource unparsed\n");
711 break;
712 case ACPI_RSTYPE_EXT_IRQ:
713 dbg("Ext Irq -------- Resource\n");
714 break;
715 default:
716 dbg("Invalid -------- resource type 0x%x\n", resource->id);
717 break;
718 }
719
720 resource = (struct acpi_resource *) ((char *)resource + resource->length);
721 }
722
723 return status;
724}
725
726static acpi_status acpi_get_crs( struct acpi_bridge *ab)
727{
728 acpi_status status;
729 struct acpi_resource *crsbuf;
730
731 status = acpi_evaluate_crs(ab->handle, &crsbuf);
732 if (ACPI_SUCCESS(status)) {
733 status = acpi_parse_crs(ab, crsbuf);
734 kfree(crsbuf);
735
736 pciehp_resource_sort_and_combine(&ab->bus_head);
737 pciehp_resource_sort_and_combine(&ab->io_head);
738 pciehp_resource_sort_and_combine(&ab->mem_head);
739 pciehp_resource_sort_and_combine(&ab->p_mem_head);
740
741 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
742 pciehprm_add_resources (&ab->tio_head, ab->io_head);
743 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
744 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
745 }
746
747 return status;
748}
749
750/* find acpi_bridge downword from ab. */
751static struct acpi_bridge *
752find_acpi_bridge_by_bus(
753 struct acpi_bridge *ab,
754 int seg,
755 int bus /* pdev->subordinate->number */
756 )
757{
758 struct acpi_bridge *lab = NULL;
759
760 if (!ab)
761 return NULL;
762
763 if ((ab->bus == bus) && (ab->seg == seg))
764 return ab;
765
766 if (ab->child)
767 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
768
769 if (!lab)
770 if (ab->next)
771 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
772
773 return lab;
774}
775
776/*
777 * Build a device tree of ACPI PCI Bridges
778 */
779static void pciehprm_acpi_register_a_bridge (
780 struct acpi_bridge **head,
781 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
782 struct acpi_bridge *cab /* child bridge to add */
783 )
784{
785 struct acpi_bridge *lpab;
786 struct acpi_bridge *lcab;
787
788 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
789 if (!lpab) {
790 if (!(pab->type & BRIDGE_TYPE_HOST))
791 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
792 pab->next = *head;
793 *head = pab;
794 lpab = pab;
795 }
796
797 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
798 return;
799
800 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
801 if (lcab) {
802 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
803 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
804 return;
805 } else
806 lcab = cab;
807
808 lcab->parent = lpab;
809 lcab->next = lpab->child;
810 lpab->child = lcab;
811}
812
813static acpi_status pciehprm_acpi_build_php_slots_callback(
814 acpi_handle handle,
815 u32 Level,
816 void *context,
817 void **retval
818 )
819{
820 ulong bus_num;
821 ulong seg_num;
822 ulong sun, adr;
823 ulong padr = 0;
824 acpi_handle phandle = NULL;
825 struct acpi_bridge *pab = (struct acpi_bridge *)context;
826 struct acpi_bridge *lab;
827 acpi_status status;
828 u8 *path_name = acpi_path_name(handle);
829
830 /* get _SUN */
831 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
832 switch(status) {
833 case AE_NOT_FOUND:
834 return AE_OK;
835 default:
836 if (ACPI_FAILURE(status)) {
837 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
838 return status;
839 }
840 }
841
842 /* get _ADR. _ADR must exist if _SUN exists */
843 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
844 if (ACPI_FAILURE(status)) {
845 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
846 return status;
847 }
848
849 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
850
851 status = acpi_get_parent(handle, &phandle);
852 if (ACPI_FAILURE(status)) {
853 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
854 return (status);
855 }
856
857 bus_num = pab->bus;
858 seg_num = pab->seg;
859
860 if (pab->bus == bus_num) {
861 lab = pab;
862 } else {
863 dbg("WARN: pab is not parent\n");
864 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
865 if (!lab) {
866 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
867 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
868 if (!lab) {
869 err("acpi_pciehprm: alloc for ab fail\n");
870 return AE_NO_MEMORY;
871 }
872 memset(lab, 0, sizeof(struct acpi_bridge));
873
874 lab->handle = phandle;
875 lab->pbus = pab->bus;
876 lab->pdevice = (int)(padr >> 16) & 0xffff;
877 lab->pfunction = (int)(padr & 0xffff);
878 lab->bus = (int)bus_num;
879 lab->scanned = 0;
880 lab->type = BRIDGE_TYPE_P2P;
881
882 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
883 } else
884 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
885 }
886
887 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
888
889 return (status);
890}
891
892static int pciehprm_acpi_build_php_slots(
893 struct acpi_bridge *ab,
894 u32 depth
895 )
896{
897 acpi_status status;
898 u8 *path_name = acpi_path_name(ab->handle);
899
900 /* Walk down this pci bridge to get _SUNs if any behind P2P */
901 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
902 ab->handle,
903 depth,
904 pciehprm_acpi_build_php_slots_callback,
905 ab,
906 NULL );
907 if (ACPI_FAILURE(status)) {
908 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);
909 return -1;
910 }
911
912 return 0;
913}
914
915static void build_a_bridge(
916 struct acpi_bridge *pab,
917 struct acpi_bridge *ab
918 )
919{
920 u8 *path_name = acpi_path_name(ab->handle);
921
922 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
923
924 switch (ab->type) {
925 case BRIDGE_TYPE_HOST:
926 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
927 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
928 break;
929 case BRIDGE_TYPE_P2P:
930 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
931 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
932 break;
933 };
934
935 /* build any immediate PHP slots under this pci bridge */
936 pciehprm_acpi_build_php_slots(ab, 1);
937}
938
939static struct acpi_bridge * add_p2p_bridge(
940 acpi_handle handle,
941 struct acpi_bridge *pab, /* parent */
942 ulong adr
943 )
944{
945 struct acpi_bridge *ab;
946 struct pci_dev *pdev;
947 ulong devnum, funcnum;
948 u8 *path_name = acpi_path_name(handle);
949
950 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
951 if (!ab) {
952 err("acpi_pciehprm: alloc for ab fail\n");
953 return NULL;
954 }
955 memset(ab, 0, sizeof(struct acpi_bridge));
956
957 devnum = (adr >> 16) & 0xffff;
958 funcnum = adr & 0xffff;
959
960 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
961 if (!pdev || !pdev->subordinate) {
962 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
963 kfree(ab);
964 return NULL;
965 }
966
967 ab->handle = handle;
968 ab->seg = pab->seg;
969 ab->pbus = pab->bus; /* or pdev->bus->number */
970 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
971 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
972 ab->bus = pdev->subordinate->number;
973 ab->scanned = 0;
974 ab->type = BRIDGE_TYPE_P2P;
975
976 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
977 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
978 pab->bus, (u32)devnum, (u32)funcnum, path_name);
979
980 build_a_bridge(pab, ab);
981
982 return ab;
983}
984
985static acpi_status scan_p2p_bridge(
986 acpi_handle handle,
987 u32 Level,
988 void *context,
989 void **retval
990 )
991{
992 struct acpi_bridge *pab = (struct acpi_bridge *)context;
993 struct acpi_bridge *ab;
994 acpi_status status;
995 ulong adr = 0;
996 u8 *path_name = acpi_path_name(handle);
997 ulong devnum, funcnum;
998 struct pci_dev *pdev;
999
1000 /* get device, function */
1001 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1002 if (ACPI_FAILURE(status)) {
1003 if (status != AE_NOT_FOUND)
1004 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1005 return AE_OK;
1006 }
1007
1008 devnum = (adr >> 16) & 0xffff;
1009 funcnum = adr & 0xffff;
1010
1011 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
1012 if (!pdev)
1013 return AE_OK;
1014 if (!pdev->subordinate)
1015 return AE_OK;
1016
1017 ab = add_p2p_bridge(handle, pab, adr);
1018 if (ab) {
1019 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1020 handle,
1021 (u32)1,
1022 scan_p2p_bridge,
1023 ab,
1024 NULL);
1025 if (ACPI_FAILURE(status))
1026 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1027 }
1028
1029 return AE_OK;
1030}
1031
1032static struct acpi_bridge * add_host_bridge(
1033 acpi_handle handle,
1034 ulong segnum,
1035 ulong busnum
1036 )
1037{
1038 ulong adr = 0;
1039 acpi_status status;
1040 struct acpi_bridge *ab;
1041 u8 *path_name = acpi_path_name(handle);
1042
1043 /* get device, function: host br adr is always 0000 though. */
1044 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1045 if (ACPI_FAILURE(status)) {
1046 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1047 return NULL;
1048 }
1049 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
1050 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1051
1052 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1053 if (!ab) {
1054 err("acpi_pciehprm: alloc for ab fail\n");
1055 return NULL;
1056 }
1057 memset(ab, 0, sizeof(struct acpi_bridge));
1058
1059 ab->handle = handle;
1060 ab->seg = (int)segnum;
1061 ab->bus = ab->pbus = (int)busnum;
1062 ab->pdevice = (int)(adr >> 16) & 0xffff;
1063 ab->pfunction = (int)(adr & 0xffff);
1064 ab->scanned = 0;
1065 ab->type = BRIDGE_TYPE_HOST;
1066
1067 /* get root pci bridge's current resources */
1068 status = acpi_get_crs(ab);
1069 if (ACPI_FAILURE(status)) {
1070 err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1071 kfree(ab);
1072 return NULL;
1073 }
1074
1075 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
1076 if (ACPI_FAILURE(status)) {
1077 err("%s: status %x\n", __FUNCTION__, status);
1078 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
1079 } else {
1080 osc_run_status = NC_RUN_SUCCESS;
1081 }
1082 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
1083
1084 build_a_bridge(ab, ab);
1085
1086 return ab;
1087}
1088
1089static acpi_status acpi_scan_from_root_pci_callback (
1090 acpi_handle handle,
1091 u32 Level,
1092 void *context,
1093 void **retval
1094 )
1095{
1096 ulong segnum = 0;
1097 ulong busnum = 0;
1098 acpi_status status;
1099 struct acpi_bridge *ab;
1100 u8 *path_name = acpi_path_name(handle);
1101
1102 /* get bus number of this pci root bridge */
1103 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1104 if (ACPI_FAILURE(status)) {
1105 if (status != AE_NOT_FOUND) {
1106 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1107 return status;
1108 }
1109 segnum = 0;
1110 }
1111
1112 /* get bus number of this pci root bridge */
1113 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1114 if (ACPI_FAILURE(status)) {
1115 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1116 return (status);
1117 }
1118
1119 ab = add_host_bridge(handle, segnum, busnum);
1120 if (ab) {
1121 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1122 handle,
1123 1,
1124 scan_p2p_bridge,
1125 ab,
1126 NULL);
1127 if (ACPI_FAILURE(status))
1128 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1129 }
1130
1131 return AE_OK;
1132}
1133
1134static int pciehprm_acpi_scan_pci (void)
1135{
1136 acpi_status status;
1137
1138 /*
1139 * TBD: traverse LDM device tree with the help of
1140 * unified ACPI augmented for php device population.
1141 */
1142 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
1143 acpi_scan_from_root_pci_callback,
1144 NULL,
1145 NULL );
1146 if (ACPI_FAILURE(status)) {
1147 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
1148 return -1;
1149 }
1150
1151 return 0;
1152}
1153
1154int pciehprm_init(enum php_ctlr_type ctlr_type)
1155{
1156 int rc;
1157
1158 if (ctlr_type != PCI)
1159 return -ENODEV;
1160
1161 dbg("pciehprm ACPI init <enter>\n");
1162 acpi_bridges_head = NULL;
1163
1164 /* construct PCI bus:device tree of acpi_handles */
1165 rc = pciehprm_acpi_scan_pci();
1166 if (rc)
1167 return rc;
1168
1169 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
1170 err("Fails to gain control of native hot-plug\n");
1171 rc = -ENODEV;
1172 }
1173
1174 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
1175 return rc;
1176}
1177
1178static void free_a_slot(struct acpi_php_slot *aps)
1179{
1180 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);
1181
1182 free_pci_resource (aps->io_head);
1183 free_pci_resource (aps->bus_head);
1184 free_pci_resource (aps->mem_head);
1185 free_pci_resource (aps->p_mem_head);
1186
1187 kfree(aps);
1188}
1189
1190static void free_a_bridge( struct acpi_bridge *ab)
1191{
1192 struct acpi_php_slot *aps, *next;
1193
1194 switch (ab->type) {
1195 case BRIDGE_TYPE_HOST:
1196 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1197 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1198 break;
1199 case BRIDGE_TYPE_P2P:
1200 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1201 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1202 break;
1203 };
1204
1205 /* free slots first */
1206 for (aps = ab->slots; aps; aps = next) {
1207 next = aps->next;
1208 free_a_slot(aps);
1209 }
1210
1211 free_pci_resource (ab->io_head);
1212 free_pci_resource (ab->tio_head);
1213 free_pci_resource (ab->bus_head);
1214 free_pci_resource (ab->tbus_head);
1215 free_pci_resource (ab->mem_head);
1216 free_pci_resource (ab->tmem_head);
1217 free_pci_resource (ab->p_mem_head);
1218 free_pci_resource (ab->tp_mem_head);
1219
1220 kfree(ab);
1221}
1222
1223static void pciehprm_free_bridges ( struct acpi_bridge *ab)
1224{
1225 if (!ab)
1226 return;
1227
1228 if (ab->child)
1229 pciehprm_free_bridges (ab->child);
1230
1231 if (ab->next)
1232 pciehprm_free_bridges (ab->next);
1233
1234 free_a_bridge(ab);
1235}
1236
1237void pciehprm_cleanup(void)
1238{
1239 pciehprm_free_bridges (acpi_bridges_head);
1240}
1241
1242static int get_number_of_slots (
1243 struct acpi_bridge *ab,
1244 int selfonly
1245 )
1246{
1247 struct acpi_php_slot *aps;
1248 int prev_slot = -1;
1249 int slot_num = 0;
1250
1251 for ( aps = ab->slots; aps; aps = aps->next)
1252 if (aps->dev != prev_slot) {
1253 prev_slot = aps->dev;
1254 slot_num++;
1255 }
1256
1257 if (ab->child)
1258 slot_num += get_number_of_slots (ab->child, 0);
1259
1260 if (selfonly)
1261 return slot_num;
1262
1263 if (ab->next)
1264 slot_num += get_number_of_slots (ab->next, 0);
1265
1266 return slot_num;
1267}
1268
1269static int print_acpi_resources (struct acpi_bridge *ab)
1270{
1271 struct acpi_php_slot *aps;
1272 int i;
1273
1274 switch (ab->type) {
1275 case BRIDGE_TYPE_HOST:
1276 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1277 break;
1278 case BRIDGE_TYPE_P2P:
1279 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1280 break;
1281 };
1282
1283 print_pci_resources (ab);
1284
1285 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1286 if (aps->dev == i)
1287 continue;
1288 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1289 print_slot_resources(aps);
1290 i = aps->dev;
1291 }
1292
1293 if (ab->child)
1294 print_acpi_resources (ab->child);
1295
1296 if (ab->next)
1297 print_acpi_resources (ab->next);
1298
1299 return 0;
1300}
1301
1302int pciehprm_print_pirt(void)
1303{
1304 dbg("PCIEHPRM ACPI Slots\n");
1305 if (acpi_bridges_head)
1306 print_acpi_resources (acpi_bridges_head);
1307
1308 return 0;
1309}
1310
1311static struct acpi_php_slot * get_acpi_slot (
1312 struct acpi_bridge *ab,
1313 u32 sun
1314 )
1315{
1316 struct acpi_php_slot *aps = NULL;
1317
1318 for ( aps = ab->slots; aps; aps = aps->next)
1319 if (aps->sun == sun)
1320 return aps;
1321
1322 if (!aps && ab->child) {
1323 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1324 if (aps)
1325 return aps;
1326 }
1327
1328 if (!aps && ab->next) {
1329 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1330 if (aps)
1331 return aps;
1332 }
1333
1334 return aps;
1335
1336}
1337
1338#if 0
1339void * pciehprm_get_slot(struct slot *slot)
1340{
1341 struct acpi_bridge *ab = acpi_bridges_head;
1342 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1343
1344 aps->slot = slot;
1345
1346 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);
1347
1348 return (void *)aps;
1349}
1350#endif
1351
1352static void pciehprm_dump_func_res( struct pci_func *fun)
1353{
1354 struct pci_func *func = fun;
1355
1356 if (func->bus_head) {
1357 dbg(": BUS Resources:\n");
1358 print_pci_resource (func->bus_head);
1359 }
1360 if (func->io_head) {
1361 dbg(": IO Resources:\n");
1362 print_pci_resource (func->io_head);
1363 }
1364 if (func->mem_head) {
1365 dbg(": MEM Resources:\n");
1366 print_pci_resource (func->mem_head);
1367 }
1368 if (func->p_mem_head) {
1369 dbg(": PMEM Resources:\n");
1370 print_pci_resource (func->p_mem_head);
1371 }
1372}
1373
1374static void pciehprm_dump_ctrl_res( struct controller *ctlr)
1375{
1376 struct controller *ctrl = ctlr;
1377
1378 if (ctrl->bus_head) {
1379 dbg(": BUS Resources:\n");
1380 print_pci_resource (ctrl->bus_head);
1381 }
1382 if (ctrl->io_head) {
1383 dbg(": IO Resources:\n");
1384 print_pci_resource (ctrl->io_head);
1385 }
1386 if (ctrl->mem_head) {
1387 dbg(": MEM Resources:\n");
1388 print_pci_resource (ctrl->mem_head);
1389 }
1390 if (ctrl->p_mem_head) {
1391 dbg(": PMEM Resources:\n");
1392 print_pci_resource (ctrl->p_mem_head);
1393 }
1394}
1395
1396static int pciehprm_get_used_resources (
1397 struct controller *ctrl,
1398 struct pci_func *func
1399 )
1400{
1401 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
1402}
1403
1404static int configure_existing_function(
1405 struct controller *ctrl,
1406 struct pci_func *func
1407 )
1408{
1409 int rc;
1410
1411 /* see how much resources the func has used. */
1412 rc = pciehprm_get_used_resources (ctrl, func);
1413
1414 if (!rc) {
1415 /* subtract the resources used by the func from ctrl resources */
1416 rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
1417 rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
1418 rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
1419 rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1420 if (rc)
1421 warn("aCEF: cannot del used resources\n");
1422 } else
1423 err("aCEF: cannot get used resources\n");
1424
1425 return rc;
1426}
1427
1428static int bind_pci_resources_to_slots ( struct controller *ctrl)
1429{
1430 struct pci_func *func, new_func;
1431 int busn = ctrl->slot_bus;
1432 int devn, funn;
1433 u32 vid;
1434
1435 for (devn = 0; devn < 32; devn++) {
1436 for (funn = 0; funn < 8; funn++) {
1437 /*
1438 if (devn == ctrl->device && funn == ctrl->function)
1439 continue;
1440 */
1441 /* find out if this entry is for an occupied slot */
1442 vid = 0xFFFFFFFF;
1443 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1444
1445 if (vid != 0xFFFFFFFF) {
1446 dbg("%s: vid = %x\n", __FUNCTION__, vid);
1447 func = pciehp_slot_find(busn, devn, funn);
1448 if (!func) {
1449 memset(&new_func, 0, sizeof(struct pci_func));
1450 new_func.bus = busn;
1451 new_func.device = devn;
1452 new_func.function = funn;
1453 new_func.is_a_board = 1;
1454 configure_existing_function(ctrl, &new_func);
1455 pciehprm_dump_func_res(&new_func);
1456 } else {
1457 configure_existing_function(ctrl, func);
1458 pciehprm_dump_func_res(func);
1459 }
1460 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1461 }
1462 }
1463 }
1464
1465 return 0;
1466}
1467
1468static int bind_pci_resources(
1469 struct controller *ctrl,
1470 struct acpi_bridge *ab
1471 )
1472{
1473 int status = 0;
1474
1475 if (ab->bus_head) {
1476 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1477 status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
1478 if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1479 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1480 if (status) {
1481 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1482 return status;
1483 }
1484 } else
1485 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1486
1487 if (ab->io_head) {
1488 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1489 status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
1490 if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
1491 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1492 if (status) {
1493 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1494 return status;
1495 }
1496 } else
1497 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1498
1499 if (ab->mem_head) {
1500 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1501 status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
1502 if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1503 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1504 if (status) {
1505 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1506 return status;
1507 }
1508 } else
1509 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1510
1511 if (ab->p_mem_head) {
1512 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1513 status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1514 if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1515 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1516 if (status) {
1517 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1518 return status;
1519 }
1520 } else
1521 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1522
1523 return status;
1524}
1525
1526static int no_pci_resources( struct acpi_bridge *ab)
1527{
1528 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1529}
1530
1531static int find_pci_bridge_resources (
1532 struct controller *ctrl,
1533 struct acpi_bridge *ab
1534 )
1535{
1536 int rc = 0;
1537 struct pci_func func;
1538
1539 memset(&func, 0, sizeof(struct pci_func));
1540
1541 func.bus = ab->pbus;
1542 func.device = ab->pdevice;
1543 func.function = ab->pfunction;
1544 func.is_a_board = 1;
1545
1546 /* Get used resources for this PCI bridge */
1547 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1548
1549 ab->io_head = func.io_head;
1550 ab->mem_head = func.mem_head;
1551 ab->p_mem_head = func.p_mem_head;
1552 ab->bus_head = func.bus_head;
1553 if (ab->bus_head)
1554 pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
1555
1556 return rc;
1557}
1558
1559static int get_pci_resources_from_bridge(
1560 struct controller *ctrl,
1561 struct acpi_bridge *ab
1562 )
1563{
1564 int rc = 0;
1565
1566 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1567
1568 rc = find_pci_bridge_resources (ctrl, ab);
1569
1570 pciehp_resource_sort_and_combine(&ab->bus_head);
1571 pciehp_resource_sort_and_combine(&ab->io_head);
1572 pciehp_resource_sort_and_combine(&ab->mem_head);
1573 pciehp_resource_sort_and_combine(&ab->p_mem_head);
1574
1575 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
1576 pciehprm_add_resources (&ab->tio_head, ab->io_head);
1577 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
1578 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1579
1580 return rc;
1581}
1582
1583static int get_pci_resources(
1584 struct controller *ctrl,
1585 struct acpi_bridge *ab
1586 )
1587{
1588 int rc = 0;
1589
1590 if (no_pci_resources(ab)) {
1591 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1592 rc = get_pci_resources_from_bridge(ctrl, ab);
1593 }
1594
1595 return rc;
1596}
1597
1598/*
1599 * Get resources for this ctrl.
1600 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1601 * 2. find used resources of existing adapters
1602 * 3. subtract used resources from total resources
1603 */
1604int pciehprm_find_available_resources( struct controller *ctrl)
1605{
1606 int rc = 0;
1607 struct acpi_bridge *ab;
1608
1609 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1610 if (!ab) {
1611 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1612 return -1;
1613 }
1614 if (no_pci_resources(ab)) {
1615 rc = get_pci_resources(ctrl, ab);
1616 if (rc) {
1617 err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1618 return -1;
1619 }
1620 }
1621
1622 rc = bind_pci_resources(ctrl, ab);
1623 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1624 pciehprm_dump_ctrl_res(ctrl);
1625
1626 bind_pci_resources_to_slots (ctrl);
1627
1628 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1629 pciehprm_dump_ctrl_res(ctrl);
1630
1631 return rc;
1632}
1633
1634int pciehprm_set_hpp(
1635 struct controller *ctrl,
1636 struct pci_func *func,
1637 u8 card_type
1638 )
1639{
1640 struct acpi_bridge *ab;
1641 struct pci_bus lpci_bus, *pci_bus;
1642 int rc = 0;
1643 unsigned int devfn;
1644 u8 cls= 0x08; /* default cache line size */
1645 u8 lt = 0x40; /* default latency timer */
1646 u8 ep = 0;
1647 u8 es = 0;
1648
1649 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1650 pci_bus = &lpci_bus;
1651 pci_bus->number = func->bus;
1652 devfn = PCI_DEVFN(func->device, func->function);
1653
1654 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1655
1656 if (ab) {
1657 if (ab->_hpp) {
1658 lt = (u8)ab->_hpp->latency_timer;
1659 cls = (u8)ab->_hpp->cache_line_size;
1660 ep = (u8)ab->_hpp->enable_perr;
1661 es = (u8)ab->_hpp->enable_serr;
1662 } else
1663 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1664 } else
1665 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1666
1667
1668 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1669 /* set subordinate Latency Timer */
1670 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1671 }
1672
1673 /* set base Latency Timer */
1674 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1675 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1676
1677 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1678 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1679
1680 return rc;
1681}
1682
1683void pciehprm_enable_card(
1684 struct controller *ctrl,
1685 struct pci_func *func,
1686 u8 card_type)
1687{
1688 u16 command, cmd, bcommand, bcmd;
1689 struct pci_bus lpci_bus, *pci_bus;
1690 struct acpi_bridge *ab;
1691 unsigned int devfn;
1692 int rc;
1693
1694 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1695 pci_bus = &lpci_bus;
1696 pci_bus->number = func->bus;
1697 devfn = PCI_DEVFN(func->device, func->function);
1698
1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
1700
1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
1703 }
1704
1705 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
1708
1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710 if (ab) {
1711 if (ab->_hpp) {
1712 if (ab->_hpp->enable_perr) {
1713 command |= PCI_COMMAND_PARITY;
1714 bcommand |= PCI_BRIDGE_CTL_PARITY;
1715 } else {
1716 command &= ~PCI_COMMAND_PARITY;
1717 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1718 }
1719 if (ab->_hpp->enable_serr) {
1720 command |= PCI_COMMAND_SERR;
1721 bcommand |= PCI_BRIDGE_CTL_SERR;
1722 } else {
1723 command &= ~PCI_COMMAND_SERR;
1724 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1725 }
1726 } else
1727 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1728 } else
1729 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1730
1731 if (command != cmd) {
1732 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1733 }
1734 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1735 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1736 }
1737}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
new file mode 100644
index 000000000000..79a0aa6238ef
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -0,0 +1,501 @@
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "pciehp.h"
41#include "pciehprm.h"
42#include "pciehprm_nonacpi.h"
43
44
45void pciehprm_cleanup(void)
46{
47 return;
48}
49
50int pciehprm_print_pirt(void)
51{
52 return 0;
53}
54
55int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
56{
57
58 *sun = (u8) (ctrl->first_slot);
59 return 0;
60}
61
62
63static void print_pci_resource ( struct pci_resource *aprh)
64{
65 struct pci_resource *res;
66
67 for (res = aprh; res; res = res->next)
68 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
69}
70
71
72static void phprm_dump_func_res( struct pci_func *fun)
73{
74 struct pci_func *func = fun;
75
76 if (func->bus_head) {
77 dbg(": BUS Resources:\n");
78 print_pci_resource (func->bus_head);
79 }
80 if (func->io_head) {
81 dbg(": IO Resources:\n");
82 print_pci_resource (func->io_head);
83 }
84 if (func->mem_head) {
85 dbg(": MEM Resources:\n");
86 print_pci_resource (func->mem_head);
87 }
88 if (func->p_mem_head) {
89 dbg(": PMEM Resources:\n");
90 print_pci_resource (func->p_mem_head);
91 }
92}
93
94static int phprm_get_used_resources (
95 struct controller *ctrl,
96 struct pci_func *func
97 )
98{
99 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
100}
101
102static int phprm_delete_resource(
103 struct pci_resource **aprh,
104 ulong base,
105 ulong size)
106{
107 struct pci_resource *res;
108 struct pci_resource *prevnode;
109 struct pci_resource *split_node;
110 ulong tbase;
111
112 pciehp_resource_sort_and_combine(aprh);
113
114 for (res = *aprh; res; res = res->next) {
115 if (res->base > base)
116 continue;
117
118 if ((res->base + res->length) < (base + size))
119 continue;
120
121 if (res->base < base) {
122 tbase = base;
123
124 if ((res->length - (tbase - res->base)) < size)
125 continue;
126
127 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
128 if (!split_node)
129 return -ENOMEM;
130
131 split_node->base = res->base;
132 split_node->length = tbase - res->base;
133 res->base = tbase;
134 res->length -= split_node->length;
135
136 split_node->next = res->next;
137 res->next = split_node;
138 }
139
140 if (res->length >= size) {
141 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
142 if (!split_node)
143 return -ENOMEM;
144
145 split_node->base = res->base + size;
146 split_node->length = res->length - size;
147 res->length = size;
148
149 split_node->next = res->next;
150 res->next = split_node;
151 }
152
153 if (*aprh == res) {
154 *aprh = res->next;
155 } else {
156 prevnode = *aprh;
157 while (prevnode->next != res)
158 prevnode = prevnode->next;
159
160 prevnode->next = res->next;
161 }
162 res->next = NULL;
163 kfree(res);
164 break;
165 }
166
167 return 0;
168}
169
170
171static int phprm_delete_resources(
172 struct pci_resource **aprh,
173 struct pci_resource *this
174 )
175{
176 struct pci_resource *res;
177
178 for (res = this; res; res = res->next)
179 phprm_delete_resource(aprh, res->base, res->length);
180
181 return 0;
182}
183
184
185static int configure_existing_function(
186 struct controller *ctrl,
187 struct pci_func *func
188 )
189{
190 int rc;
191
192 /* see how much resources the func has used. */
193 rc = phprm_get_used_resources (ctrl, func);
194
195 if (!rc) {
196 /* subtract the resources used by the func from ctrl resources */
197 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
198 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
199 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
200 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
201 if (rc)
202 warn("aCEF: cannot del used resources\n");
203 } else
204 err("aCEF: cannot get used resources\n");
205
206 return rc;
207}
208
209static int pciehprm_delete_resource(
210 struct pci_resource **aprh,
211 ulong base,
212 ulong size)
213{
214 struct pci_resource *res;
215 struct pci_resource *prevnode;
216 struct pci_resource *split_node;
217 ulong tbase;
218
219 pciehp_resource_sort_and_combine(aprh);
220
221 for (res = *aprh; res; res = res->next) {
222 if (res->base > base)
223 continue;
224
225 if ((res->base + res->length) < (base + size))
226 continue;
227
228 if (res->base < base) {
229 tbase = base;
230
231 if ((res->length - (tbase - res->base)) < size)
232 continue;
233
234 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
235 if (!split_node)
236 return -ENOMEM;
237
238 split_node->base = res->base;
239 split_node->length = tbase - res->base;
240 res->base = tbase;
241 res->length -= split_node->length;
242
243 split_node->next = res->next;
244 res->next = split_node;
245 }
246
247 if (res->length >= size) {
248 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
249 if (!split_node)
250 return -ENOMEM;
251
252 split_node->base = res->base + size;
253 split_node->length = res->length - size;
254 res->length = size;
255
256 split_node->next = res->next;
257 res->next = split_node;
258 }
259
260 if (*aprh == res) {
261 *aprh = res->next;
262 } else {
263 prevnode = *aprh;
264 while (prevnode->next != res)
265 prevnode = prevnode->next;
266
267 prevnode->next = res->next;
268 }
269 res->next = NULL;
270 kfree(res);
271 break;
272 }
273
274 return 0;
275}
276
277static int bind_pci_resources_to_slots ( struct controller *ctrl)
278{
279 struct pci_func *func, new_func;
280 int busn = ctrl->slot_bus;
281 int devn, funn;
282 u32 vid;
283
284 for (devn = 0; devn < 32; devn++) {
285 for (funn = 0; funn < 8; funn++) {
286 /*
287 if (devn == ctrl->device && funn == ctrl->function)
288 continue;
289 */
290 /* find out if this entry is for an occupied slot */
291 vid = 0xFFFFFFFF;
292
293 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
294
295 if (vid != 0xFFFFFFFF) {
296 dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
297 vid, busn, devn, funn);
298 func = pciehp_slot_find(busn, devn, funn);
299 dbg("%s: func = %p\n", __FUNCTION__,func);
300 if (!func) {
301 memset(&new_func, 0, sizeof(struct pci_func));
302 new_func.bus = busn;
303 new_func.device = devn;
304 new_func.function = funn;
305 new_func.is_a_board = 1;
306 configure_existing_function(ctrl, &new_func);
307 phprm_dump_func_res(&new_func);
308 } else {
309 configure_existing_function(ctrl, func);
310 phprm_dump_func_res(func);
311 }
312 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
313 }
314 }
315 }
316
317 return 0;
318}
319
320static void phprm_dump_ctrl_res( struct controller *ctlr)
321{
322 struct controller *ctrl = ctlr;
323
324 if (ctrl->bus_head) {
325 dbg(": BUS Resources:\n");
326 print_pci_resource (ctrl->bus_head);
327 }
328 if (ctrl->io_head) {
329 dbg(": IO Resources:\n");
330 print_pci_resource (ctrl->io_head);
331 }
332 if (ctrl->mem_head) {
333 dbg(": MEM Resources:\n");
334 print_pci_resource (ctrl->mem_head);
335 }
336 if (ctrl->p_mem_head) {
337 dbg(": PMEM Resources:\n");
338 print_pci_resource (ctrl->p_mem_head);
339 }
340}
341
342/*
343 * phprm_find_available_resources
344 *
345 * Finds available memory, IO, and IRQ resources for programming
346 * devices which may be added to the system
347 * this function is for hot plug ADD!
348 *
349 * returns 0 if success
350 */
351int pciehprm_find_available_resources(struct controller *ctrl)
352{
353 struct pci_func func;
354 u32 rc;
355
356 memset(&func, 0, sizeof(struct pci_func));
357
358 func.bus = ctrl->bus;
359 func.device = ctrl->device;
360 func.function = ctrl->function;
361 func.is_a_board = 1;
362
363 /* Get resources for this PCI bridge */
364 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
365 dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
366
367 if (func.mem_head)
368 func.mem_head->next = ctrl->mem_head;
369 ctrl->mem_head = func.mem_head;
370
371 if (func.p_mem_head)
372 func.p_mem_head->next = ctrl->p_mem_head;
373 ctrl->p_mem_head = func.p_mem_head;
374
375 if (func.io_head)
376 func.io_head->next = ctrl->io_head;
377 ctrl->io_head = func.io_head;
378
379 if(func.bus_head)
380 func.bus_head->next = ctrl->bus_head;
381 ctrl->bus_head = func.bus_head;
382
383 if (ctrl->bus_head)
384 pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
385
386 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
387 phprm_dump_ctrl_res(ctrl);
388
389 dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
390
391 bind_pci_resources_to_slots (ctrl);
392
393 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
394 phprm_dump_ctrl_res(ctrl);
395
396 return (rc);
397}
398
399int pciehprm_set_hpp(
400 struct controller *ctrl,
401 struct pci_func *func,
402 u8 card_type)
403{
404 u32 rc;
405 u8 temp_byte;
406 struct pci_bus lpci_bus, *pci_bus;
407 unsigned int devfn;
408 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
409 pci_bus = &lpci_bus;
410 pci_bus->number = func->bus;
411 devfn = PCI_DEVFN(func->device, func->function);
412
413 temp_byte = 0x40; /* hard coded value for LT */
414 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
415 /* set subordinate Latency Timer */
416 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
417
418 if (rc) {
419 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
420 func->bus, func->device, func->function);
421 return rc;
422 }
423 }
424
425 /* set base Latency Timer */
426 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
427
428 if (rc) {
429 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
430 return rc;
431 }
432
433 /* set Cache Line size */
434 temp_byte = 0x08; /* hard coded value for CLS */
435
436 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
437
438 if (rc) {
439 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
440 }
441
442 /* set enable_perr */
443 /* set enable_serr */
444
445 return rc;
446}
447
448void pciehprm_enable_card(
449 struct controller *ctrl,
450 struct pci_func *func,
451 u8 card_type)
452{
453 u16 command, bcommand;
454 struct pci_bus lpci_bus, *pci_bus;
455 unsigned int devfn;
456 int rc;
457
458 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
459 pci_bus = &lpci_bus;
460 pci_bus->number = func->bus;
461 devfn = PCI_DEVFN(func->device, func->function);
462
463 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
464
465 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
466 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
467 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
468
469 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
470
471 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
472
473 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
474
475 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
476 | PCI_BRIDGE_CTL_NO_ISA;
477
478 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
479 }
480}
481
482static int legacy_pciehprm_init_pci(void)
483{
484 return 0;
485}
486
487int pciehprm_init(enum php_ctlr_type ctrl_type)
488{
489 int retval;
490
491 switch (ctrl_type) {
492 case PCI:
493 retval = legacy_pciehprm_init_pci();
494 break;
495 default:
496 retval = -ENODEV;
497 break;
498 }
499
500 return retval;
501}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
new file mode 100644
index 000000000000..87c90e85ede9
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.h
@@ -0,0 +1,56 @@
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>, <dely.l.sy@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_ */
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
new file mode 100644
index 000000000000..6605d6bda529
--- /dev/null
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -0,0 +1,375 @@
1/*
2 * PCI Hot Plug Controller Skeleton Driver - 0.2
3 *
4 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2001,2003 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * This driver is to be used as a skeleton driver to be show how to interface
25 * with the pci hotplug core easily.
26 *
27 * Send feedback to <greg@kroah.com>
28 *
29 */
30
31#include <linux/config.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/slab.h>
36#include <linux/pci.h>
37#include <linux/init.h>
38#include "pci_hotplug.h"
39
40struct slot {
41 u8 number;
42 struct hotplug_slot *hotplug_slot;
43 struct list_head slot_list;
44};
45
46static LIST_HEAD(slot_list);
47
48#define MY_NAME "pcihp_skeleton"
49
50#define dbg(format, arg...) \
51 do { \
52 if (debug) \
53 printk (KERN_DEBUG "%s: " format "\n", \
54 MY_NAME , ## arg); \
55 } while (0)
56#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
57#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
58#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
59
60
61
62/* local variables */
63static int debug;
64static int num_slots;
65
66#define DRIVER_VERSION "0.3"
67#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
68#define DRIVER_DESC "Hot Plug PCI Controller Skeleton Driver"
69
70MODULE_AUTHOR(DRIVER_AUTHOR);
71MODULE_DESCRIPTION(DRIVER_DESC);
72MODULE_LICENSE("GPL");
73module_param(debug, bool, 0644);
74MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
75
76static int enable_slot (struct hotplug_slot *slot);
77static int disable_slot (struct hotplug_slot *slot);
78static int set_attention_status (struct hotplug_slot *slot, u8 value);
79static int hardware_test (struct hotplug_slot *slot, u32 value);
80static int get_power_status (struct hotplug_slot *slot, u8 *value);
81static int get_attention_status (struct hotplug_slot *slot, u8 *value);
82static int get_latch_status (struct hotplug_slot *slot, u8 *value);
83static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
84
85static struct hotplug_slot_ops skel_hotplug_slot_ops = {
86 .owner = THIS_MODULE,
87 .enable_slot = enable_slot,
88 .disable_slot = disable_slot,
89 .set_attention_status = set_attention_status,
90 .hardware_test = hardware_test,
91 .get_power_status = get_power_status,
92 .get_attention_status = get_attention_status,
93 .get_latch_status = get_latch_status,
94 .get_adapter_status = get_adapter_status,
95};
96
97static int enable_slot(struct hotplug_slot *hotplug_slot)
98{
99 struct slot *slot = hotplug_slot->private;
100 int retval = 0;
101
102 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
103
104 /*
105 * Fill in code here to enable the specified slot
106 */
107
108 return retval;
109}
110
111
112static int disable_slot(struct hotplug_slot *hotplug_slot)
113{
114 struct slot *slot = hotplug_slot->private;
115 int retval = 0;
116
117 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
118
119 /*
120 * Fill in code here to disable the specified slot
121 */
122
123 return retval;
124}
125
126static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
127{
128 struct slot *slot = hotplug_slot->private;
129 int retval = 0;
130
131 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
132
133 switch (status) {
134 case 0:
135 /*
136 * Fill in code here to turn light off
137 */
138 break;
139
140 case 1:
141 default:
142 /*
143 * Fill in code here to turn light on
144 */
145 break;
146 }
147
148 return retval;
149}
150
151static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
152{
153 struct slot *slot = hotplug_slot->private;
154 int retval = 0;
155
156 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
157
158 switch (value) {
159 case 0:
160 /* Specify a test here */
161 break;
162 case 1:
163 /* Specify another test here */
164 break;
165 }
166
167 return retval;
168}
169
170static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
171{
172 struct slot *slot = hotplug_slot->private;
173 int retval = 0;
174
175 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
176
177 /*
178 * Fill in logic to get the current power status of the specific
179 * slot and store it in the *value location.
180 */
181
182 return retval;
183}
184
185static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
186{
187 struct slot *slot = hotplug_slot->private;
188 int retval = 0;
189
190 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
191
192 /*
193 * Fill in logic to get the current attention status of the specific
194 * slot and store it in the *value location.
195 */
196
197 return retval;
198}
199
200static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
201{
202 struct slot *slot = hotplug_slot->private;
203 int retval = 0;
204
205 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
206
207 /*
208 * Fill in logic to get the current latch status of the specific
209 * slot and store it in the *value location.
210 */
211
212 return retval;
213}
214
215static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
216{
217 struct slot *slot = hotplug_slot->private;
218 int retval = 0;
219
220 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
221
222 /*
223 * Fill in logic to get the current adapter status of the specific
224 * slot and store it in the *value location.
225 */
226
227 return retval;
228}
229
230static void release_slot(struct hotplug_slot *hotplug_slot)
231{
232 struct slot *slot = hotplug_slot->private;
233
234 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
235 kfree(slot->hotplug_slot->info);
236 kfree(slot->hotplug_slot->name);
237 kfree(slot->hotplug_slot);
238 kfree(slot);
239}
240
241#define SLOT_NAME_SIZE 10
242static void make_slot_name(struct slot *slot)
243{
244 /*
245 * Stupid way to make a filename out of the slot name.
246 * replace this if your hardware provides a better way to name slots.
247 */
248 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d", slot->number);
249}
250
251/**
252 * init_slots - initialize 'struct slot' structures for each slot
253 *
254 */
255static int __init init_slots(void)
256{
257 struct slot *slot;
258 struct hotplug_slot *hotplug_slot;
259 struct hotplug_slot_info *info;
260 char *name;
261 int retval = -ENOMEM;
262 int i;
263
264 /*
265 * Create a structure for each slot, and register that slot
266 * with the pci_hotplug subsystem.
267 */
268 for (i = 0; i < num_slots; ++i) {
269 slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
270 if (!slot)
271 goto error;
272 memset(slot, 0, sizeof(struct slot));
273
274 hotplug_slot = kmalloc(sizeof(struct hotplug_slot),
275 GFP_KERNEL);
276 if (!hotplug_slot)
277 goto error_slot;
278 memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
279 slot->hotplug_slot = hotplug_slot;
280
281 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
282 if (!info)
283 goto error_hpslot;
284 memset(info, 0, sizeof (struct hotplug_slot_info));
285 hotplug_slot->info = info;
286
287 name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
288 if (!name)
289 goto error_info;
290 hotplug_slot->name = name;
291
292 slot->number = i;
293
294 hotplug_slot->private = slot;
295 hotplug_slot->release = &release_slot;
296 make_slot_name(slot);
297 hotplug_slot->ops = &skel_hotplug_slot_ops;
298
299 /*
300 * Initilize the slot info structure with some known
301 * good values.
302 */
303 info->power_status = get_power_status(slot);
304 info->attention_status = get_attention_status(slot);
305 info->latch_status = get_latch_status(slot);
306 info->adapter_status = get_adapter_status(slot);
307
308 dbg("registering slot %d\n", i);
309 retval = pci_hp_register(slot->hotplug_slot);
310 if (retval) {
311 err("pci_hp_register failed with error %d\n", retval);
312 goto error_name;
313 }
314
315 /* add slot to our internal list */
316 list_add(&slot->slot_list, &slot_list);
317 }
318
319 return 0;
320error_name:
321 kfree(name);
322error_info:
323 kfree(info);
324error_hpslot:
325 kfree(hotplug_slot);
326error_slot:
327 kfree(slot);
328error:
329 return retval;
330}
331
332static void __exit cleanup_slots(void)
333{
334 struct list_head *tmp;
335 struct list_head *next;
336 struct slot *slot;
337
338 /*
339 * Unregister all of our slots with the pci_hotplug subsystem.
340 * Memory will be freed in release_slot() callback after slot's
341 * lifespan is finished.
342 */
343 list_for_each_safe(tmp, next, &slot_list) {
344 slot = list_entry(tmp, struct slot, slot_list);
345 list_del(&slot->slot_list);
346 pci_hp_deregister(slot->hotplug_slot);
347 }
348}
349
350static int __init pcihp_skel_init(void)
351{
352 int retval;
353
354 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
355 /*
356 * Do specific initialization stuff for your driver here
357 * Like initializing your controller hardware (if any) and
358 * determining the number of slots you have in the system
359 * right now.
360 */
361 num_slots = 5;
362
363 return init_slots();
364}
365
366static void __exit pcihp_skel_exit(void)
367{
368 /*
369 * Clean everything up.
370 */
371 cleanup_slots();
372}
373
374module_init(pcihp_skel_init);
375module_exit(pcihp_skel_exit);
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h
new file mode 100644
index 000000000000..4a0a59b82eae
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar.h
@@ -0,0 +1,24 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * October 2003
7 *
8 * Copyright (C) 2003 IBM.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#ifndef _RPADLPAR_IO_H_
16#define _RPADLPAR_IO_H_
17
18extern int dlpar_sysfs_init(void);
19extern void dlpar_sysfs_exit(void);
20
21extern int dlpar_add_slot(char *drc_name);
22extern int dlpar_remove_slot(char *drc_name);
23
24#endif
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
new file mode 100644
index 000000000000..86b384e42717
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -0,0 +1,503 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * Linda Xie <lxie@us.ibm.com>
7 *
8 * October 2003
9 *
10 * Copyright (C) 2003 IBM.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17#include <linux/init.h>
18#include <linux/pci.h>
19#include <asm/pci-bridge.h>
20#include <asm/semaphore.h>
21#include <asm/rtas.h>
22#include "../pci.h"
23#include "rpaphp.h"
24#include "rpadlpar.h"
25
26static DECLARE_MUTEX(rpadlpar_sem);
27
28#define NODE_TYPE_VIO 1
29#define NODE_TYPE_SLOT 2
30#define NODE_TYPE_PHB 3
31
32static struct device_node *find_php_slot_vio_node(char *drc_name)
33{
34 struct device_node *child;
35 struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
36 char *loc_code;
37
38 if (!parent)
39 return NULL;
40
41 for (child = of_get_next_child(parent, NULL);
42 child; child = of_get_next_child(parent, child)) {
43 loc_code = get_property(child, "ibm,loc-code", NULL);
44 if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
45 return child;
46 }
47
48 return NULL;
49}
50
51/* Find dlpar-capable pci node that contains the specified name and type */
52static struct device_node *find_php_slot_pci_node(char *drc_name,
53 char *drc_type)
54{
55 struct device_node *np = NULL;
56 char *name;
57 char *type;
58 int rc;
59
60 while ((np = of_find_node_by_type(np, "pci"))) {
61 rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL);
62 if (rc == 0)
63 if (!strcmp(drc_name, name) && !strcmp(drc_type, type))
64 break;
65 }
66
67 return np;
68}
69
70static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
71{
72 struct device_node *dn;
73
74 dn = find_php_slot_pci_node(drc_name, "SLOT");
75 if (dn) {
76 *node_type = NODE_TYPE_SLOT;
77 return dn;
78 }
79
80 dn = find_php_slot_pci_node(drc_name, "PHB");
81 if (dn) {
82 *node_type = NODE_TYPE_PHB;
83 return dn;
84 }
85
86 dn = find_php_slot_vio_node(drc_name);
87 if (dn) {
88 *node_type = NODE_TYPE_VIO;
89 return dn;
90 }
91
92 return NULL;
93}
94
95static struct slot *find_slot(char *drc_name)
96{
97 struct list_head *tmp, *n;
98 struct slot *slot;
99
100 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
101 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
102 if (strcmp(slot->location, drc_name) == 0)
103 return slot;
104 }
105
106 return NULL;
107}
108
109static void rpadlpar_claim_one_bus(struct pci_bus *b)
110{
111 struct list_head *ld;
112 struct pci_bus *child_bus;
113
114 for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
115 struct pci_dev *dev = pci_dev_b(ld);
116 int i;
117
118 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
119 struct resource *r = &dev->resource[i];
120
121 if (r->parent || !r->start || !r->flags)
122 continue;
123 rpaphp_claim_resource(dev, i);
124 }
125 }
126
127 list_for_each_entry(child_bus, &b->children, node)
128 rpadlpar_claim_one_bus(child_bus);
129}
130
131static int pci_add_secondary_bus(struct device_node *dn,
132 struct pci_dev *bridge_dev)
133{
134 struct pci_controller *hose = dn->phb;
135 struct pci_bus *child;
136 u8 sec_busno;
137
138 /* Get busno of downstream bus */
139 pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
140
141 /* Allocate and add to children of bridge_dev->bus */
142 child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
143 if (!child) {
144 printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
145 return -ENOMEM;
146 }
147
148 sprintf(child->name, "PCI Bus #%02x", child->number);
149
150 /* Fixup subordinate bridge bases and resources */
151 pcibios_fixup_bus(child);
152
153 /* Claim new bus resources */
154 rpadlpar_claim_one_bus(bridge_dev->bus);
155
156 if (hose->last_busno < child->number)
157 hose->last_busno = child->number;
158
159 dn->bussubno = child->number;
160
161 /* ioremap() for child bus, which may or may not succeed */
162 remap_bus_range(child);
163
164 return 0;
165}
166
167static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
168{
169 struct pci_controller *hose = dn->phb;
170 struct pci_dev *dev = NULL;
171
172 /* Scan phb bus for EADS device, adding new one to bus->devices */
173 if (!pci_scan_single_device(hose->bus, dn->devfn)) {
174 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
175 return NULL;
176 }
177
178 /* Add new devices to global lists. Register in proc, sysfs. */
179 pci_bus_add_devices(hose->bus);
180
181 /* Confirm new bridge dev was created */
182 dev = rpaphp_find_pci_dev(dn);
183 if (!dev) {
184 printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__);
185 return NULL;
186 }
187
188 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
189 printk(KERN_ERR "%s: unexpected header type %d\n",
190 __FUNCTION__, dev->hdr_type);
191 return NULL;
192 }
193
194 if (pci_add_secondary_bus(dn, dev))
195 return NULL;
196
197 return dev;
198}
199
200static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev)
201{
202 struct pci_bus *secondary_bus;
203
204 if (!bridge_dev) {
205 printk(KERN_ERR "%s: unexpected null device\n",
206 __FUNCTION__);
207 return -EINVAL;
208 }
209
210 secondary_bus = bridge_dev->subordinate;
211
212 if (unmap_bus_range(secondary_bus)) {
213 printk(KERN_ERR "%s: failed to unmap bus range\n",
214 __FUNCTION__);
215 return -ERANGE;
216 }
217
218 pci_remove_bus_device(bridge_dev);
219 return 0;
220}
221
222static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
223{
224 struct pci_dev *dev;
225
226 /* Add pci bus */
227 dev = dlpar_pci_add_bus(dn);
228 if (!dev) {
229 printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__,
230 drc_name);
231 return -EIO;
232 }
233
234 return 0;
235}
236
237static int dlpar_remove_root_bus(struct pci_controller *phb)
238{
239 struct pci_bus *phb_bus;
240 int rc;
241
242 phb_bus = phb->bus;
243 if (!(list_empty(&phb_bus->children) &&
244 list_empty(&phb_bus->devices))) {
245 return -EBUSY;
246 }
247
248 rc = pcibios_remove_root_bus(phb);
249 if (rc)
250 return -EIO;
251
252 device_unregister(phb_bus->bridge);
253 pci_remove_bus(phb_bus);
254
255 return 0;
256}
257
258static int dlpar_remove_phb(struct slot *slot)
259{
260 struct pci_controller *phb;
261 struct device_node *dn;
262 int rc = 0;
263
264 dn = slot->dn;
265 if (!dn) {
266 printk(KERN_ERR "%s: unexpected NULL slot device node\n",
267 __FUNCTION__);
268 return -EIO;
269 }
270
271 phb = dn->phb;
272 if (!phb) {
273 printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
274 __FUNCTION__);
275 return -EIO;
276 }
277
278 if (rpaphp_remove_slot(slot)) {
279 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
280 __FUNCTION__, slot->location);
281 return -EIO;
282 }
283
284 rc = dlpar_remove_root_bus(phb);
285 if (rc < 0)
286 return rc;
287
288 return 0;
289}
290
291static int dlpar_add_phb(struct device_node *dn)
292{
293 struct pci_controller *phb;
294
295 phb = init_phb_dynamic(dn);
296 if (!phb)
297 return -EINVAL;
298
299 return 0;
300}
301
302/**
303 * dlpar_add_slot - DLPAR add an I/O Slot
304 * @drc_name: drc-name of newly added slot
305 *
306 * Make the hotplug module and the kernel aware
307 * of a newly added I/O Slot.
308 * Return Codes -
309 * 0 Success
310 * -ENODEV Not a valid drc_name
311 * -EINVAL Slot already added
312 * -ERESTARTSYS Signalled before obtaining lock
313 * -EIO Internal PCI Error
314 */
315int dlpar_add_slot(char *drc_name)
316{
317 struct device_node *dn = NULL;
318 int node_type;
319 int rc = 0;
320
321 if (down_interruptible(&rpadlpar_sem))
322 return -ERESTARTSYS;
323
324 /* Check for existing hotplug slot */
325 if (find_slot(drc_name)) {
326 rc = -EINVAL;
327 goto exit;
328 }
329
330 dn = find_newly_added_node(drc_name, &node_type);
331 if (!dn) {
332 rc = -ENODEV;
333 goto exit;
334 }
335
336 switch (node_type) {
337 case NODE_TYPE_VIO:
338 /* Just add hotplug slot */
339 break;
340 case NODE_TYPE_SLOT:
341 rc = dlpar_add_pci_slot(drc_name, dn);
342 break;
343 case NODE_TYPE_PHB:
344 rc = dlpar_add_phb(dn);
345 break;
346 default:
347 printk("%s: unexpected node type\n", __FUNCTION__);
348 return -EIO;
349 }
350
351 if (!rc && rpaphp_add_slot(dn)) {
352 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
353 __FUNCTION__, drc_name);
354 rc = -EIO;
355 }
356exit:
357 up(&rpadlpar_sem);
358 return rc;
359}
360
361/**
362 * dlpar_remove_vio_slot - DLPAR remove a virtual I/O Slot
363 * @drc_name: drc-name of newly added slot
364 *
365 * Remove the kernel and hotplug representations
366 * of an I/O Slot.
367 * Return Codes:
368 * 0 Success
369 * -EIO Internal Error
370 */
371int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
372{
373 /* Remove hotplug slot */
374
375 if (rpaphp_remove_slot(slot)) {
376 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
377 __FUNCTION__, drc_name);
378 return -EIO;
379 }
380 return 0;
381}
382
383/**
384 * dlpar_remove_slot - DLPAR remove a PCI I/O Slot
385 * @drc_name: drc-name of newly added slot
386 *
387 * Remove the kernel and hotplug representations
388 * of a PCI I/O Slot.
389 * Return Codes:
390 * 0 Success
391 * -ENODEV Not a valid drc_name
392 * -EIO Internal PCI Error
393 */
394int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
395{
396 struct pci_dev *bridge_dev;
397
398 bridge_dev = slot->bridge;
399 if (!bridge_dev) {
400 printk(KERN_ERR "%s: unexpected null bridge device\n",
401 __FUNCTION__);
402 return -EIO;
403 }
404
405 /* Remove hotplug slot */
406 if (rpaphp_remove_slot(slot)) {
407 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
408 __FUNCTION__, drc_name);
409 return -EIO;
410 }
411
412 /* Remove pci bus */
413
414 if (dlpar_pci_remove_bus(bridge_dev)) {
415 printk(KERN_ERR "%s: unable to remove pci bus %s\n",
416 __FUNCTION__, drc_name);
417 return -EIO;
418 }
419 return 0;
420}
421
422/**
423 * dlpar_remove_slot - DLPAR remove an I/O Slot
424 * @drc_name: drc-name of newly added slot
425 *
426 * Remove the kernel and hotplug representations
427 * of an I/O Slot.
428 * Return Codes:
429 * 0 Success
430 * -ENODEV Not a valid drc_name
431 * -EINVAL Slot already removed
432 * -ERESTARTSYS Signalled before obtaining lock
433 * -EIO Internal Error
434 */
435int dlpar_remove_slot(char *drc_name)
436{
437 struct slot *slot;
438 int rc = 0;
439
440 if (down_interruptible(&rpadlpar_sem))
441 return -ERESTARTSYS;
442
443 if (!find_php_slot_vio_node(drc_name) &&
444 !find_php_slot_pci_node(drc_name, "SLOT") &&
445 !find_php_slot_pci_node(drc_name, "PHB")) {
446 rc = -ENODEV;
447 goto exit;
448 }
449
450 slot = find_slot(drc_name);
451 if (!slot) {
452 rc = -EINVAL;
453 goto exit;
454 }
455
456 if (slot->type == PHB) {
457 rc = dlpar_remove_phb(slot);
458 } else {
459 switch (slot->dev_type) {
460 case PCI_DEV:
461 rc = dlpar_remove_pci_slot(slot, drc_name);
462 break;
463
464 case VIO_DEV:
465 rc = dlpar_remove_vio_slot(slot, drc_name);
466 break;
467 }
468 }
469exit:
470 up(&rpadlpar_sem);
471 return rc;
472}
473
474static inline int is_dlpar_capable(void)
475{
476 int rc = rtas_token("ibm,configure-connector");
477
478 return (int) (rc != RTAS_UNKNOWN_SERVICE);
479}
480
481int __init rpadlpar_io_init(void)
482{
483 int rc = 0;
484
485 if (!is_dlpar_capable()) {
486 printk(KERN_WARNING "%s: partition not DLPAR capable\n",
487 __FUNCTION__);
488 return -EPERM;
489 }
490
491 rc = dlpar_sysfs_init();
492 return rc;
493}
494
495void rpadlpar_io_exit(void)
496{
497 dlpar_sysfs_exit();
498 return;
499}
500
501module_init(rpadlpar_io_init);
502module_exit(rpadlpar_io_exit);
503MODULE_LICENSE("GPL");
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
new file mode 100644
index 000000000000..3285b822478d
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -0,0 +1,151 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * October 2003
7 *
8 * Copyright (C) 2003 IBM.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#include <linux/kobject.h>
16#include <linux/string.h>
17#include "pci_hotplug.h"
18#include "rpadlpar.h"
19
20#define DLPAR_KOBJ_NAME "control"
21#define ADD_SLOT_ATTR_NAME "add_slot"
22#define REMOVE_SLOT_ATTR_NAME "remove_slot"
23
24#define MAX_DRC_NAME_LEN 64
25
26/* Store return code of dlpar operation in attribute struct */
27struct dlpar_io_attr {
28 int rc;
29 struct attribute attr;
30 ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf,
31 size_t nbytes);
32};
33
34/* Common show callback for all attrs, display the return code
35 * of the dlpar op */
36static ssize_t
37dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
38{
39 struct dlpar_io_attr *dlpar_attr = container_of(attr,
40 struct dlpar_io_attr, attr);
41 return sprintf(buf, "%d\n", dlpar_attr->rc);
42}
43
44static ssize_t
45dlpar_attr_store(struct kobject * kobj, struct attribute * attr,
46 const char *buf, size_t nbytes)
47{
48 struct dlpar_io_attr *dlpar_attr = container_of(attr,
49 struct dlpar_io_attr, attr);
50 return dlpar_attr->store ?
51 dlpar_attr->store(dlpar_attr, buf, nbytes) : 0;
52}
53
54static struct sysfs_ops dlpar_attr_sysfs_ops = {
55 .show = dlpar_attr_show,
56 .store = dlpar_attr_store,
57};
58
59static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr,
60 const char *buf, size_t nbytes)
61{
62 char drc_name[MAX_DRC_NAME_LEN];
63 char *end;
64
65 if (nbytes > MAX_DRC_NAME_LEN)
66 return 0;
67
68 memcpy(drc_name, buf, nbytes);
69
70 end = strchr(drc_name, '\n');
71 if (!end)
72 end = &drc_name[nbytes];
73 *end = '\0';
74
75 dlpar_attr->rc = dlpar_add_slot(drc_name);
76
77 return nbytes;
78}
79
80static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr,
81 const char *buf, size_t nbytes)
82{
83 char drc_name[MAX_DRC_NAME_LEN];
84 char *end;
85
86 if (nbytes > MAX_DRC_NAME_LEN)
87 return 0;
88
89 memcpy(drc_name, buf, nbytes);
90
91 end = strchr(drc_name, '\n');
92 if (!end)
93 end = &drc_name[nbytes];
94 *end = '\0';
95
96 dlpar_attr->rc = dlpar_remove_slot(drc_name);
97
98 return nbytes;
99}
100
101static struct dlpar_io_attr add_slot_attr = {
102 .rc = 0,
103 .attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, },
104 .store = add_slot_store,
105};
106
107static struct dlpar_io_attr remove_slot_attr = {
108 .rc = 0,
109 .attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644},
110 .store = remove_slot_store,
111};
112
113static struct attribute *default_attrs[] = {
114 &add_slot_attr.attr,
115 &remove_slot_attr.attr,
116 NULL,
117};
118
119static void dlpar_io_release(struct kobject *kobj)
120{
121 /* noop */
122 return;
123}
124
125struct kobj_type ktype_dlpar_io = {
126 .release = dlpar_io_release,
127 .sysfs_ops = &dlpar_attr_sysfs_ops,
128 .default_attrs = default_attrs,
129};
130
131struct kset dlpar_io_kset = {
132 .subsys = &pci_hotplug_slots_subsys,
133 .kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,},
134 .ktype = &ktype_dlpar_io,
135};
136
137int dlpar_sysfs_init(void)
138{
139 if (kset_register(&dlpar_io_kset)) {
140 printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n",
141 dlpar_io_kset.kobj.name);
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148void dlpar_sysfs_exit(void)
149{
150 kset_unregister(&dlpar_io_kset);
151}
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
new file mode 100644
index 000000000000..81746e6e0e0f
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -0,0 +1,138 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 *
4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
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 <lxie@us.ibm.com>,
24 *
25 */
26
27#ifndef _PPC64PHP_H
28#define _PPC64PHP_H
29
30#include <linux/pci.h>
31#include "pci_hotplug.h"
32
33#define PHB 2
34#define HOTPLUG 1
35#define EMBEDDED 0
36
37#define DR_INDICATOR 9002
38#define DR_ENTITY_SENSE 9003
39
40#define POWER_ON 100
41#define POWER_OFF 0
42
43#define LED_OFF 0
44#define LED_ON 1 /* continuous on */
45#define LED_ID 2 /* slow blinking */
46#define LED_ACTION 3 /* fast blinking */
47
48/* Sensor values from rtas_get-sensor */
49#define EMPTY 0 /* No card in slot */
50#define PRESENT 1 /* Card in slot */
51
52#define MY_NAME "rpaphp"
53extern int debug;
54#define dbg(format, arg...) \
55 do { \
56 if (debug) \
57 printk(KERN_DEBUG "%s: " format, \
58 MY_NAME , ## arg); \
59 } while (0)
60#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
61#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
62#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
63
64/* slot types */
65#define VIO_DEV 1
66#define PCI_DEV 2
67
68/* slot states */
69
70#define NOT_VALID 3
71#define NOT_CONFIGURED 2
72#define CONFIGURED 1
73#define EMPTY 0
74
75struct rpaphp_pci_func {
76 struct pci_dev *pci_dev;
77 struct list_head sibling;
78};
79
80/*
81 * struct slot - slot information for each *physical* slot
82 */
83struct slot {
84 struct list_head rpaphp_slot_list;
85 int state;
86 u32 index;
87 u32 type;
88 u32 power_domain;
89 char *name;
90 char *location;
91 u8 removable;
92 u8 dev_type; /* VIO or PCI */
93 struct device_node *dn; /* slot's device_node in OFDT */
94 /* dn has phb info */
95 struct pci_dev *bridge; /* slot's pci_dev in pci_devices */
96 union {
97 struct list_head *pci_devs; /* pci_devs in PCI slot */
98 struct vio_dev *vio_dev; /* vio_dev in VIO slot */
99 } dev;
100 struct hotplug_slot *hotplug_slot;
101};
102
103extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops;
104extern struct list_head rpaphp_slot_head;
105extern int num_slots;
106
107/* function prototypes */
108
109/* rpaphp_pci.c */
110extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn);
111extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
112extern int rpaphp_enable_pci_slot(struct slot *slot);
113extern int register_pci_slot(struct slot *slot);
114extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
115extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
116extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev);
117
118/* rpaphp_core.c */
119extern int rpaphp_add_slot(struct device_node *dn);
120extern int rpaphp_remove_slot(struct slot *slot);
121extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
122 char **drc_name, char **drc_type, int *drc_power_domain);
123
124/* rpaphp_vio.c */
125extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
126extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
127extern int register_vio_slot(struct device_node *dn);
128extern int rpaphp_enable_vio_slot(struct slot *slot);
129
130/* rpaphp_slot.c */
131extern void dealloc_slot_struct(struct slot *slot);
132extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
133extern int register_slot(struct slot *slot);
134extern int deregister_slot(struct slot *slot);
135extern int rpaphp_get_power_status(struct slot *slot, u8 * value);
136extern int rpaphp_set_attention_status(struct slot *slot, u8 status);
137
138#endif /* _PPC64PHP_H */
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
new file mode 100644
index 000000000000..29117a3a3287
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -0,0 +1,536 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/config.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/pci.h>
30#include <linux/slab.h>
31#include <linux/smp.h>
32#include <linux/smp_lock.h>
33#include <linux/init.h>
34#include <asm/eeh.h> /* for eeh_add_device() */
35#include <asm/rtas.h> /* rtas_call */
36#include <asm/pci-bridge.h> /* for pci_controller */
37#include "../pci.h" /* for pci_add_new_bus */
38 /* and pci_do_scan_bus */
39#include "rpaphp.h"
40#include "pci_hotplug.h"
41
42int debug;
43static struct semaphore rpaphp_sem;
44LIST_HEAD(rpaphp_slot_head);
45int num_slots;
46
47#define DRIVER_VERSION "0.1"
48#define DRIVER_AUTHOR "Linda Xie <lxie@us.ibm.com>"
49#define DRIVER_DESC "RPA HOT Plug PCI Controller Driver"
50
51#define MAX_LOC_CODE 128
52
53MODULE_AUTHOR(DRIVER_AUTHOR);
54MODULE_DESCRIPTION(DRIVER_DESC);
55MODULE_LICENSE("GPL");
56
57module_param(debug, bool, 0644);
58
59static int enable_slot(struct hotplug_slot *slot);
60static int disable_slot(struct hotplug_slot *slot);
61static int set_attention_status(struct hotplug_slot *slot, u8 value);
62static int get_power_status(struct hotplug_slot *slot, u8 * value);
63static int get_attention_status(struct hotplug_slot *slot, u8 * value);
64static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
65static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
66
67struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
68 .owner = THIS_MODULE,
69 .enable_slot = enable_slot,
70 .disable_slot = disable_slot,
71 .set_attention_status = set_attention_status,
72 .get_power_status = get_power_status,
73 .get_attention_status = get_attention_status,
74 .get_adapter_status = get_adapter_status,
75 .get_max_bus_speed = get_max_bus_speed,
76};
77
78static int rpaphp_get_attention_status(struct slot *slot)
79{
80 return slot->hotplug_slot->info->attention_status;
81}
82
83/**
84 * set_attention_status - set attention LED
85 * echo 0 > attention -- set LED OFF
86 * echo 1 > attention -- set LED ON
87 * echo 2 > attention -- set LED ID(identify, light is blinking)
88 *
89 */
90static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
91{
92 int retval = 0;
93 struct slot *slot = (struct slot *)hotplug_slot->private;
94
95 down(&rpaphp_sem);
96 switch (value) {
97 case 0:
98 retval = rpaphp_set_attention_status(slot, LED_OFF);
99 hotplug_slot->info->attention_status = 0;
100 break;
101 case 1:
102 default:
103 retval = rpaphp_set_attention_status(slot, LED_ON);
104 hotplug_slot->info->attention_status = 1;
105 break;
106 case 2:
107 retval = rpaphp_set_attention_status(slot, LED_ID);
108 hotplug_slot->info->attention_status = 2;
109 break;
110 }
111 up(&rpaphp_sem);
112 return retval;
113}
114
115/**
116 * get_power_status - get power status of a slot
117 * @hotplug_slot: slot to get status
118 * @value: pointer to store status
119 *
120 *
121 */
122static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
123{
124 int retval;
125 struct slot *slot = (struct slot *)hotplug_slot->private;
126
127 down(&rpaphp_sem);
128 retval = rpaphp_get_power_status(slot, value);
129 up(&rpaphp_sem);
130 return retval;
131}
132
133/**
134 * get_attention_status - get attention LED status
135 *
136 *
137 */
138static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
139{
140 int retval = 0;
141 struct slot *slot = (struct slot *)hotplug_slot->private;
142
143 down(&rpaphp_sem);
144 *value = rpaphp_get_attention_status(slot);
145 up(&rpaphp_sem);
146 return retval;
147}
148
149static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
150{
151 struct slot *slot = (struct slot *)hotplug_slot->private;
152 int retval = 0;
153
154 down(&rpaphp_sem);
155 /* have to go through this */
156 switch (slot->dev_type) {
157 case PCI_DEV:
158 retval = rpaphp_get_pci_adapter_status(slot, 0, value);
159 break;
160 case VIO_DEV:
161 retval = rpaphp_get_vio_adapter_status(slot, 0, value);
162 break;
163 default:
164 retval = -EINVAL;
165 }
166 up(&rpaphp_sem);
167 return retval;
168}
169
170static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
171{
172 struct slot *slot = (struct slot *)hotplug_slot->private;
173
174 down(&rpaphp_sem);
175 switch (slot->type) {
176 case 1:
177 case 2:
178 case 3:
179 case 4:
180 case 5:
181 case 6:
182 *value = PCI_SPEED_33MHz; /* speed for case 1-6 */
183 break;
184 case 7:
185 case 8:
186 *value = PCI_SPEED_66MHz;
187 break;
188 case 11:
189 case 14:
190 *value = PCI_SPEED_66MHz_PCIX;
191 break;
192 case 12:
193 case 15:
194 *value = PCI_SPEED_100MHz_PCIX;
195 break;
196 case 13:
197 case 16:
198 *value = PCI_SPEED_133MHz_PCIX;
199 break;
200 default:
201 *value = PCI_SPEED_UNKNOWN;
202 break;
203
204 }
205 up(&rpaphp_sem);
206 return 0;
207}
208
209int rpaphp_remove_slot(struct slot *slot)
210{
211 return deregister_slot(slot);
212}
213
214static int get_children_props(struct device_node *dn, int **drc_indexes,
215 int **drc_names, int **drc_types, int **drc_power_domains)
216{
217 int *indexes, *names;
218 int *types, *domains;
219
220 indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
221 names = (int *) get_property(dn, "ibm,drc-names", NULL);
222 types = (int *) get_property(dn, "ibm,drc-types", NULL);
223 domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
224
225 if (!indexes || !names || !types || !domains) {
226 /* Slot does not have dynamically-removable children */
227 return -EINVAL;
228 }
229 if (drc_indexes)
230 *drc_indexes = indexes;
231 if (drc_names)
232 /* &drc_names[1] contains NULL terminated slot names */
233 *drc_names = names;
234 if (drc_types)
235 /* &drc_types[1] contains NULL terminated slot types */
236 *drc_types = types;
237 if (drc_power_domains)
238 *drc_power_domains = domains;
239
240 return 0;
241}
242
243/* To get the DRC props describing the current node, first obtain it's
244 * my-drc-index property. Next obtain the DRC list from it's parent. Use
245 * the my-drc-index for correlation, and obtain the requested properties.
246 */
247int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
248 char **drc_name, char **drc_type, int *drc_power_domain)
249{
250 int *indexes, *names;
251 int *types, *domains;
252 unsigned int *my_index;
253 char *name_tmp, *type_tmp;
254 int i, rc;
255
256 my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
257 if (!my_index) {
258 /* Node isn't DLPAR/hotplug capable */
259 return -EINVAL;
260 }
261
262 rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
263 if (rc < 0) {
264 return -EINVAL;
265 }
266
267 name_tmp = (char *) &names[1];
268 type_tmp = (char *) &types[1];
269
270 /* Iterate through parent properties, looking for my-drc-index */
271 for (i = 0; i < indexes[0]; i++) {
272 if ((unsigned int) indexes[i + 1] == *my_index) {
273 if (drc_name)
274 *drc_name = name_tmp;
275 if (drc_type)
276 *drc_type = type_tmp;
277 if (drc_index)
278 *drc_index = *my_index;
279 if (drc_power_domain)
280 *drc_power_domain = domains[i+1];
281 return 0;
282 }
283 name_tmp += (strlen(name_tmp) + 1);
284 type_tmp += (strlen(type_tmp) + 1);
285 }
286
287 return -EINVAL;
288}
289
290static int is_php_type(char *drc_type)
291{
292 unsigned long value;
293 char *endptr;
294
295 /* PCI Hotplug nodes have an integer for drc_type */
296 value = simple_strtoul(drc_type, &endptr, 10);
297 if (endptr == drc_type)
298 return 0;
299
300 return 1;
301}
302
303static int is_php_dn(struct device_node *dn, int **indexes, int **names,
304 int **types, int **power_domains)
305{
306 int *drc_types;
307 int rc;
308
309 rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
310 if (rc >= 0) {
311 if (is_php_type((char *) &drc_types[1])) {
312 *types = drc_types;
313 return 1;
314 }
315 }
316
317 return 0;
318}
319
320static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
321 int **types, int **power_domains, int **my_drc_index)
322{
323 int rc;
324
325 *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
326 if(!*my_drc_index)
327 return (0);
328
329 if (!dn->parent)
330 return (0);
331
332 rc = get_children_props(dn->parent, indexes, names, types,
333 power_domains);
334 return (rc >= 0);
335}
336
337static inline int is_vdevice_root(struct device_node *dn)
338{
339 return !strcmp(dn->name, "vdevice");
340}
341
342int is_dlpar_type(const char *type_str)
343{
344 /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
345 return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
346}
347
348/****************************************************************
349 * rpaphp not only registers PCI hotplug slots(HOTPLUG),
350 * but also logical DR slots(EMBEDDED).
351 * HOTPLUG slot: An adapter can be physically added/removed.
352 * EMBEDDED slot: An adapter can be logically removed/added
353 * from/to a partition with the slot.
354 ***************************************************************/
355int rpaphp_add_slot(struct device_node *dn)
356{
357 struct slot *slot;
358 int retval = 0;
359 int i, *my_drc_index, slot_type;
360 int *indexes, *names, *types, *power_domains;
361 char *name, *type;
362
363 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
364
365 if (dn->parent && is_vdevice_root(dn->parent)) {
366 /* register a VIO device */
367 retval = register_vio_slot(dn);
368 goto exit;
369 }
370
371 /* register PCI devices */
372 if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
373 if (is_php_dn(dn, &indexes, &names, &types, &power_domains))
374 slot_type = HOTPLUG;
375 else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index))
376 slot_type = EMBEDDED;
377 else goto exit;
378
379 name = (char *) &names[1];
380 type = (char *) &types[1];
381 for (i = 0; i < indexes[0]; i++,
382 name += (strlen(name) + 1), type += (strlen(type) + 1)) {
383
384 if (slot_type == HOTPLUG ||
385 (slot_type == EMBEDDED &&
386 indexes[i + 1] == my_drc_index[0] &&
387 is_dlpar_type(type))) {
388 if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
389 power_domains[i + 1]))) {
390 retval = -ENOMEM;
391 goto exit;
392 }
393 if (!strcmp(type, "PHB"))
394 slot->type = PHB;
395 else if (slot_type == EMBEDDED)
396 slot->type = EMBEDDED;
397 else
398 slot->type = simple_strtoul(type, NULL, 10);
399
400 dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n",
401 indexes[i + 1], name, type);
402
403 retval = register_pci_slot(slot);
404 if (slot_type == EMBEDDED)
405 goto exit;
406 }
407 }
408 }
409exit:
410 dbg("%s - Exit: num_slots=%d rc[%d]\n",
411 __FUNCTION__, num_slots, retval);
412 return retval;
413}
414
415/*
416 * init_slots - initialize 'struct slot' structures for each slot
417 *
418 */
419static void init_slots(void)
420{
421 struct device_node *dn;
422
423 for (dn = find_all_nodes(); dn; dn = dn->next)
424 rpaphp_add_slot(dn);
425}
426
427static int __init init_rpa(void)
428{
429
430 init_MUTEX(&rpaphp_sem);
431
432 /* initialize internal data structure etc. */
433 init_slots();
434 if (!num_slots)
435 return -ENODEV;
436
437 return 0;
438}
439
440static void __exit cleanup_slots(void)
441{
442 struct list_head *tmp, *n;
443 struct slot *slot;
444
445 /*
446 * Unregister all of our slots with the pci_hotplug subsystem,
447 * and free up all memory that we had allocated.
448 * memory will be freed in release_slot callback.
449 */
450
451 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
452 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
453 list_del(&slot->rpaphp_slot_list);
454 pci_hp_deregister(slot->hotplug_slot);
455 }
456 return;
457}
458
459static int __init rpaphp_init(void)
460{
461 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
462
463 /* read all the PRA info from the system */
464 return init_rpa();
465}
466
467static void __exit rpaphp_exit(void)
468{
469 cleanup_slots();
470}
471
472static int enable_slot(struct hotplug_slot *hotplug_slot)
473{
474 int retval = 0;
475 struct slot *slot = (struct slot *)hotplug_slot->private;
476
477 if (slot->state == CONFIGURED) {
478 dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name);
479 goto exit;
480 }
481
482 dbg("ENABLING SLOT %s\n", slot->name);
483 down(&rpaphp_sem);
484 switch (slot->dev_type) {
485 case PCI_DEV:
486 retval = rpaphp_enable_pci_slot(slot);
487 break;
488 case VIO_DEV:
489 retval = rpaphp_enable_vio_slot(slot);
490 break;
491 default:
492 retval = -EINVAL;
493 }
494 up(&rpaphp_sem);
495exit:
496 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
497 return retval;
498}
499
500static int disable_slot(struct hotplug_slot *hotplug_slot)
501{
502 int retval = -EINVAL;
503 struct slot *slot = (struct slot *)hotplug_slot->private;
504
505 dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name);
506
507 if (slot->state == NOT_CONFIGURED) {
508 dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name);
509 goto exit;
510 }
511
512 dbg("DISABLING SLOT %s\n", slot->name);
513 down(&rpaphp_sem);
514 switch (slot->dev_type) {
515 case PCI_DEV:
516 retval = rpaphp_unconfig_pci_adapter(slot);
517 break;
518 case VIO_DEV:
519 retval = rpaphp_unconfig_vio_adapter(slot);
520 break;
521 default:
522 retval = -ENODEV;
523 }
524 up(&rpaphp_sem);
525exit:
526 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
527 return retval;
528}
529
530module_init(rpaphp_init);
531module_exit(rpaphp_exit);
532
533EXPORT_SYMBOL_GPL(rpaphp_add_slot);
534EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
535EXPORT_SYMBOL_GPL(rpaphp_slot_head);
536EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
new file mode 100644
index 000000000000..d8305a935aab
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -0,0 +1,538 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/pci.h>
26#include <asm/pci-bridge.h>
27#include <asm/rtas.h>
28#include <asm/machdep.h>
29#include "../pci.h" /* for pci_add_new_bus */
30
31#include "rpaphp.h"
32
33struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn)
34{
35 struct pci_dev *dev = NULL;
36 char bus_id[BUS_ID_SIZE];
37
38 sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number,
39 dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn));
40 for_each_pci_dev(dev) {
41 if (!strcmp(pci_name(dev), bus_id)) {
42 break;
43 }
44 }
45 return dev;
46}
47
48EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev);
49
50int rpaphp_claim_resource(struct pci_dev *dev, int resource)
51{
52 struct resource *res = &dev->resource[resource];
53 struct resource *root = pci_find_parent_resource(dev, res);
54 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
55 int err = -EINVAL;
56
57 if (root != NULL) {
58 err = request_resource(root, res);
59 }
60
61 if (err) {
62 err("PCI: %s region %d of %s %s [%lx:%lx]\n",
63 root ? "Address space collision on" :
64 "No parent found for",
65 resource, dtype, pci_name(dev), res->start, res->end);
66 }
67 return err;
68}
69
70EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
71
72static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot)
73{
74 return rpaphp_find_pci_dev(slot->dn);
75}
76
77static int rpaphp_get_sensor_state(struct slot *slot, int *state)
78{
79 int rc;
80 int setlevel;
81
82 rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
83
84 if (rc < 0) {
85 if (rc == -EFAULT || rc == -EEXIST) {
86 dbg("%s: slot must be power up to get sensor-state\n",
87 __FUNCTION__);
88
89 /* some slots have to be powered up
90 * before get-sensor will succeed.
91 */
92 rc = rtas_set_power_level(slot->power_domain, POWER_ON,
93 &setlevel);
94 if (rc < 0) {
95 dbg("%s: power on slot[%s] failed rc=%d.\n",
96 __FUNCTION__, slot->name, rc);
97 } else {
98 rc = rtas_get_sensor(DR_ENTITY_SENSE,
99 slot->index, state);
100 }
101 } else if (rc == -ENODEV)
102 info("%s: slot is unusable\n", __FUNCTION__);
103 else
104 err("%s failed to get sensor state\n", __FUNCTION__);
105 }
106 return rc;
107}
108
109/**
110 * get_pci_adapter_status - get the status of a slot
111 *
112 * 0-- slot is empty
113 * 1-- adapter is configured
114 * 2-- adapter is not configured
115 * 3-- not valid
116 */
117int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
118{
119 int state, rc;
120 struct device_node *child_dn;
121 struct pci_dev *child_dev = NULL;
122
123 *value = NOT_VALID;
124 rc = rpaphp_get_sensor_state(slot, &state);
125 if (rc)
126 goto exit;
127
128 if ((state == EMPTY) || (slot->type == PHB)) {
129 dbg("slot is empty\n");
130 *value = EMPTY;
131 }
132 else if (state == PRESENT) {
133 if (!is_init) {
134 /* at run-time slot->state can be changed by */
135 /* config/unconfig adapter */
136 *value = slot->state;
137 } else {
138 child_dn = slot->dn->child;
139 if (child_dn)
140 child_dev = rpaphp_find_pci_dev(child_dn);
141
142 if (child_dev)
143 *value = CONFIGURED;
144 else if (!child_dn)
145 dbg("%s: %s is not valid OFDT node\n",
146 __FUNCTION__, slot->dn->full_name);
147 else {
148 err("%s: can't find pdev of adapter in slot[%s]\n",
149 __FUNCTION__, slot->dn->full_name);
150 *value = NOT_CONFIGURED;
151 }
152 }
153 }
154exit:
155 return rc;
156}
157
158/* Must be called before pci_bus_add_devices */
159static void
160rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
161{
162 struct pci_dev *dev;
163
164 list_for_each_entry(dev, &bus->devices, bus_list) {
165 /*
166 * Skip already-present devices (which are on the
167 * global device list.)
168 */
169 if (list_empty(&dev->global_list)) {
170 int i;
171
172 /* Need to setup IOMMU tables */
173 ppc_md.iommu_dev_setup(dev);
174
175 if(fix_bus)
176 pcibios_fixup_device_resources(dev, bus);
177 pci_read_irq_line(dev);
178 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
179 struct resource *r = &dev->resource[i];
180
181 if (r->parent || !r->start || !r->flags)
182 continue;
183 rpaphp_claim_resource(dev, i);
184 }
185 }
186 }
187}
188
189static int rpaphp_pci_config_bridge(struct pci_dev *dev);
190
191/*****************************************************************************
192 rpaphp_pci_config_slot() will configure all devices under the
193 given slot->dn and return the the first pci_dev.
194 *****************************************************************************/
195static struct pci_dev *
196rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus)
197{
198 struct device_node *eads_first_child = dn->child;
199 struct pci_dev *dev = NULL;
200 int num;
201
202 dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
203
204 if (eads_first_child) {
205 /* pci_scan_slot should find all children of EADs */
206 num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0));
207 if (num) {
208 rpaphp_fixup_new_pci_devices(bus, 1);
209 pci_bus_add_devices(bus);
210 }
211 dev = rpaphp_find_pci_dev(eads_first_child);
212 if (!dev) {
213 err("No new device found\n");
214 return NULL;
215 }
216 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
217 rpaphp_pci_config_bridge(dev);
218 }
219 return dev;
220}
221
222static int rpaphp_pci_config_bridge(struct pci_dev *dev)
223{
224 u8 sec_busno;
225 struct pci_bus *child_bus;
226 struct pci_dev *child_dev;
227
228 dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev));
229
230 /* get busno of downstream bus */
231 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
232
233 /* add to children of PCI bridge dev->bus */
234 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
235 if (!child_bus) {
236 err("%s: could not add second bus\n", __FUNCTION__);
237 return -EIO;
238 }
239 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
240 /* do pci_scan_child_bus */
241 pci_scan_child_bus(child_bus);
242
243 list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
244 eeh_add_device_late(child_dev);
245 }
246
247 /* fixup new pci devices without touching bus struct */
248 rpaphp_fixup_new_pci_devices(child_bus, 0);
249
250 /* Make the discovered devices available */
251 pci_bus_add_devices(child_bus);
252 return 0;
253}
254
255static void enable_eeh(struct device_node *dn)
256{
257 struct device_node *sib;
258
259 for (sib = dn->child; sib; sib = sib->sibling)
260 enable_eeh(sib);
261 eeh_add_device_early(dn);
262 return;
263
264}
265
266static void print_slot_pci_funcs(struct slot *slot)
267{
268 struct pci_dev *dev;
269
270 if (slot->dev_type == PCI_DEV) {
271 dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name);
272 list_for_each_entry (dev, slot->dev.pci_devs, bus_list)
273 dbg("\t%s\n", pci_name(dev));
274 }
275 return;
276}
277
278static int rpaphp_config_pci_adapter(struct slot *slot)
279{
280 struct pci_bus *pci_bus;
281 struct pci_dev *dev;
282 int rc = -ENODEV;
283
284 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
285
286 if (slot->bridge) {
287
288 pci_bus = slot->bridge->subordinate;
289 if (!pci_bus) {
290 err("%s: can't find bus structure\n", __FUNCTION__);
291 goto exit;
292 }
293 enable_eeh(slot->dn);
294 dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
295 if (!dev) {
296 err("%s: can't find any devices.\n", __FUNCTION__);
297 goto exit;
298 }
299 print_slot_pci_funcs(slot);
300 rc = 0;
301 } else {
302 /* slot is not enabled */
303 err("slot doesn't have pci_dev structure\n");
304 }
305exit:
306 dbg("Exit %s: rc=%d\n", __FUNCTION__, rc);
307 return rc;
308}
309
310static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
311{
312 eeh_remove_device(dev);
313 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
314 struct pci_bus *bus = dev->subordinate;
315 struct list_head *ln;
316 if (!bus)
317 return;
318 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
319 struct pci_dev *pdev = pci_dev_b(ln);
320 if (pdev)
321 rpaphp_eeh_remove_bus_device(pdev);
322 }
323
324 }
325 return;
326}
327
328int rpaphp_unconfig_pci_adapter(struct slot *slot)
329{
330 struct pci_dev *dev;
331 int retval = 0;
332
333 list_for_each_entry(dev, slot->dev.pci_devs, bus_list)
334 rpaphp_eeh_remove_bus_device(dev);
335
336 pci_remove_behind_bridge(slot->bridge);
337 slot->state = NOT_CONFIGURED;
338 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
339 slot->name);
340 return retval;
341}
342
343static int setup_pci_hotplug_slot_info(struct slot *slot)
344{
345 dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
346 __FUNCTION__);
347 rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status);
348 rpaphp_get_pci_adapter_status(slot, 1,
349 &slot->hotplug_slot->info->
350 adapter_status);
351 if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {
352 err("%s: NOT_VALID: skip dn->full_name=%s\n",
353 __FUNCTION__, slot->dn->full_name);
354 return -EINVAL;
355 }
356 return 0;
357}
358
359static int set_phb_slot_name(struct slot *slot)
360{
361 struct device_node *dn;
362 struct pci_controller *phb;
363 struct pci_bus *bus;
364
365 dn = slot->dn;
366 if (!dn) {
367 return -EINVAL;
368 }
369 phb = dn->phb;
370 if (!phb) {
371 return -EINVAL;
372 }
373 bus = phb->bus;
374 if (!bus) {
375 return -EINVAL;
376 }
377
378 sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
379 bus->number, 0, 0);
380 return 0;
381}
382
383static int setup_pci_slot(struct slot *slot)
384{
385 struct pci_bus *bus;
386 int rc;
387
388 if (slot->type == PHB) {
389 rc = set_phb_slot_name(slot);
390 if (rc < 0) {
391 err("%s: failed to set phb slot name\n", __FUNCTION__);
392 goto exit_rc;
393 }
394 } else {
395 slot->bridge = rpaphp_find_bridge_pdev(slot);
396 if (!slot->bridge) {
397 /* slot being added doesn't have pci_dev yet */
398 err("%s: no pci_dev for bridge dn %s\n",
399 __FUNCTION__, slot->name);
400 goto exit_rc;
401 }
402
403 bus = slot->bridge->subordinate;
404 if (!bus)
405 goto exit_rc;
406 slot->dev.pci_devs = &bus->devices;
407
408 dbg("%s set slot->name to %s\n", __FUNCTION__,
409 pci_name(slot->bridge));
410 strcpy(slot->name, pci_name(slot->bridge));
411 }
412
413 /* find slot's pci_dev if it's not empty */
414 if (slot->hotplug_slot->info->adapter_status == EMPTY) {
415 slot->state = EMPTY; /* slot is empty */
416 } else {
417 /* slot is occupied */
418 if (!(slot->dn->child)) {
419 /* non-empty slot has to have child */
420 err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
421 __FUNCTION__, slot->name);
422 goto exit_rc;
423 }
424
425 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
426 dbg("%s CONFIGURING pci adapter in slot[%s]\n",
427 __FUNCTION__, slot->name);
428 if (rpaphp_config_pci_adapter(slot)) {
429 err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
430 goto exit_rc;
431 }
432
433 } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) {
434 err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
435 __FUNCTION__, slot->name);
436 goto exit_rc;
437 }
438 print_slot_pci_funcs(slot);
439 if (!list_empty(slot->dev.pci_devs)) {
440 slot->state = CONFIGURED;
441 } else {
442 /* DLPAR add as opposed to
443 * boot time */
444 slot->state = NOT_CONFIGURED;
445 }
446 }
447 return 0;
448exit_rc:
449 dealloc_slot_struct(slot);
450 return -EINVAL;
451}
452
453int register_pci_slot(struct slot *slot)
454{
455 int rc = -EINVAL;
456
457 slot->dev_type = PCI_DEV;
458 if ((slot->type == EMBEDDED) || (slot->type == PHB))
459 slot->removable = 0;
460 else
461 slot->removable = 1;
462 if (setup_pci_hotplug_slot_info(slot))
463 goto exit_rc;
464 if (setup_pci_slot(slot))
465 goto exit_rc;
466 rc = register_slot(slot);
467exit_rc:
468 return rc;
469}
470
471int rpaphp_enable_pci_slot(struct slot *slot)
472{
473 int retval = 0, state;
474
475 retval = rpaphp_get_sensor_state(slot, &state);
476 if (retval)
477 goto exit;
478 dbg("%s: sensor state[%d]\n", __FUNCTION__, state);
479 /* if slot is not empty, enable the adapter */
480 if (state == PRESENT) {
481 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
482 retval = rpaphp_config_pci_adapter(slot);
483 if (!retval) {
484 slot->state = CONFIGURED;
485 dbg("%s: PCI devices in slot[%s] has been configured\n",
486 __FUNCTION__, slot->name);
487 } else {
488 slot->state = NOT_CONFIGURED;
489 dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
490 __FUNCTION__, slot->name);
491 }
492 } else if (state == EMPTY) {
493 dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name);
494 slot->state = EMPTY;
495 } else {
496 err("%s: slot[%s] is in invalid state\n", __FUNCTION__,
497 slot->name);
498 slot->state = NOT_VALID;
499 retval = -EINVAL;
500 }
501exit:
502 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
503 return retval;
504}
505
506struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev)
507{
508 struct list_head *tmp, *n;
509 struct slot *slot;
510
511 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
512 struct pci_bus *bus;
513 struct list_head *ln;
514
515 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
516 if (slot->bridge == NULL) {
517 if (slot->dev_type == PCI_DEV) {
518 printk(KERN_WARNING "PCI slot missing bridge %s %s \n",
519 slot->name, slot->location);
520 }
521 continue;
522 }
523
524 bus = slot->bridge->subordinate;
525 if (!bus) {
526 continue; /* should never happen? */
527 }
528 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
529 struct pci_dev *pdev = pci_dev_b(ln);
530 if (pdev == dev)
531 return slot->hotplug_slot;
532 }
533 }
534
535 return NULL;
536}
537
538EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot);
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
new file mode 100644
index 000000000000..ff2cbf0652d8
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -0,0 +1,267 @@
1/*
2 * RPA Virtual I/O device functions
3 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/kobject.h>
28#include <linux/sysfs.h>
29#include <linux/pci.h>
30#include <asm/rtas.h>
31#include "rpaphp.h"
32
33static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf)
34{
35 u8 value;
36 int retval = -ENOENT;
37 struct slot *slot = (struct slot *)php_slot->private;
38
39 if (!slot)
40 return retval;
41
42 value = slot->removable;
43 retval = sprintf (buf, "%d\n", value);
44 return retval;
45}
46
47static struct hotplug_slot_attribute hotplug_slot_attr_removable = {
48 .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO},
49 .show = removable_read_file,
50};
51
52static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot)
53{
54 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
55}
56
57static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot)
58{
59 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
60}
61
62static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
63{
64 char *value;
65 int retval = -ENOENT;
66 struct slot *slot = (struct slot *)php_slot->private;
67
68 if (!slot)
69 return retval;
70
71 value = slot->location;
72 retval = sprintf (buf, "%s\n", value);
73 return retval;
74}
75
76static struct hotplug_slot_attribute hotplug_slot_attr_location = {
77 .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
78 .show = location_read_file,
79};
80
81static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
82{
83 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
84}
85
86static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
87{
88 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
89}
90
91/* free up the memory used by a slot */
92static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
93{
94 struct slot *slot = (struct slot *) hotplug_slot->private;
95
96 dealloc_slot_struct(slot);
97}
98
99void dealloc_slot_struct(struct slot *slot)
100{
101 kfree(slot->hotplug_slot->info);
102 kfree(slot->hotplug_slot->name);
103 kfree(slot->hotplug_slot);
104 kfree(slot);
105 return;
106}
107
108struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name,
109 int power_domain)
110{
111 struct slot *slot;
112
113 slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
114 if (!slot)
115 goto error_nomem;
116 memset(slot, 0, sizeof (struct slot));
117 slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
118 if (!slot->hotplug_slot)
119 goto error_slot;
120 memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
121 slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info),
122 GFP_KERNEL);
123 if (!slot->hotplug_slot->info)
124 goto error_hpslot;
125 memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
126 slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL);
127 if (!slot->hotplug_slot->name)
128 goto error_info;
129 slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
130 if (!slot->location)
131 goto error_name;
132 slot->name = slot->hotplug_slot->name;
133 slot->dn = dn;
134 slot->index = drc_index;
135 strcpy(slot->location, drc_name);
136 slot->power_domain = power_domain;
137 slot->hotplug_slot->private = slot;
138 slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
139 slot->hotplug_slot->release = &rpaphp_release_slot;
140
141 return (slot);
142
143error_name:
144 kfree(slot->hotplug_slot->name);
145error_info:
146 kfree(slot->hotplug_slot->info);
147error_hpslot:
148 kfree(slot->hotplug_slot);
149error_slot:
150 kfree(slot);
151error_nomem:
152 return NULL;
153}
154
155static int is_registered(struct slot *slot)
156{
157 struct slot *tmp_slot;
158
159 list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) {
160 if (!strcmp(tmp_slot->name, slot->name))
161 return 1;
162 }
163 return 0;
164}
165
166int deregister_slot(struct slot *slot)
167{
168 int retval = 0;
169 struct hotplug_slot *php_slot = slot->hotplug_slot;
170
171 dbg("%s - Entry: deregistering slot=%s\n",
172 __FUNCTION__, slot->name);
173
174 list_del(&slot->rpaphp_slot_list);
175
176 /* remove "phy_location" file */
177 rpaphp_sysfs_remove_attr_location(php_slot);
178
179 /* remove "phy_removable" file */
180 rpaphp_sysfs_remove_attr_removable(php_slot);
181
182 retval = pci_hp_deregister(php_slot);
183 if (retval)
184 err("Problem unregistering a slot %s\n", slot->name);
185 else
186 num_slots--;
187
188 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
189 return retval;
190}
191
192int register_slot(struct slot *slot)
193{
194 int retval;
195
196 dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
197 __FUNCTION__, slot->dn->full_name, slot->index, slot->name,
198 slot->power_domain, slot->type);
199 /* should not try to register the same slot twice */
200 if (is_registered(slot)) { /* should't be here */
201 err("register_slot: slot[%s] is already registered\n", slot->name);
202 rpaphp_release_slot(slot->hotplug_slot);
203 return -EAGAIN;
204 }
205 retval = pci_hp_register(slot->hotplug_slot);
206 if (retval) {
207 err("pci_hp_register failed with error %d\n", retval);
208 rpaphp_release_slot(slot->hotplug_slot);
209 return retval;
210 }
211
212 /* create "phy_locatoin" file */
213 rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
214
215 /* create "phy_removable" file */
216 rpaphp_sysfs_add_attr_removable(slot->hotplug_slot);
217
218 /* add slot to our internal list */
219 dbg("%s adding slot[%s] to rpaphp_slot_list\n",
220 __FUNCTION__, slot->name);
221
222 list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
223
224 if (slot->dev_type == VIO_DEV)
225 info("Slot [%s](VIO location=%s) registered\n",
226 slot->name, slot->location);
227 else
228 info("Slot [%s](PCI location=%s) registered\n",
229 slot->name, slot->location);
230 num_slots++;
231 return 0;
232}
233
234int rpaphp_get_power_status(struct slot *slot, u8 * value)
235{
236 int rc = 0, level;
237
238 if (slot->type == HOTPLUG) {
239 rc = rtas_get_power_level(slot->power_domain, &level);
240 if (!rc) {
241 dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
242 __FUNCTION__, slot->name, slot->power_domain, level);
243 *value = level;
244 } else
245 err("failed to get power-level for slot(%s), rc=0x%x\n",
246 slot->location, rc);
247 } else {
248 dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
249 __FUNCTION__, slot->location);
250 *value = (u8) POWER_ON;
251 }
252
253 return rc;
254}
255
256int rpaphp_set_attention_status(struct slot *slot, u8 status)
257{
258 int rc;
259
260 /* status: LED_OFF or LED_ON */
261 rc = rtas_set_indicator(DR_INDICATOR, slot->index, status);
262 if (rc < 0)
263 err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n",
264 slot->name, slot->location, slot->index, status, rc);
265
266 return rc;
267}
diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
new file mode 100644
index 000000000000..74df6a305e64
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_vio.c
@@ -0,0 +1,129 @@
1/*
2 * RPA Hot Plug Virtual I/O device functions
3 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <asm/vio.h>
26#include "rpaphp.h"
27
28/*
29 * get_vio_adapter_status - get the status of a slot
30 *
31 * status:
32 *
33 * 1-- adapter is configured
34 * 2-- adapter is not configured
35 * 3-- not valid
36 */
37inline int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 *value)
38{
39 *value = slot->state;
40 return 0;
41}
42
43int rpaphp_unconfig_vio_adapter(struct slot *slot)
44{
45 int retval = 0;
46
47 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
48 if (!slot->dev.vio_dev) {
49 info("%s: no VIOA in slot[%s]\n", __FUNCTION__, slot->name);
50 retval = -EINVAL;
51 goto exit;
52 }
53 /* remove the device from the vio core */
54 vio_unregister_device(slot->dev.vio_dev);
55 slot->state = NOT_CONFIGURED;
56 info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, slot->name);
57exit:
58 dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
59 return retval;
60}
61
62static int setup_vio_hotplug_slot_info(struct slot *slot)
63{
64 slot->hotplug_slot->info->power_status = 1;
65 rpaphp_get_vio_adapter_status(slot, 1,
66 &slot->hotplug_slot->info->adapter_status);
67 return 0;
68}
69
70int register_vio_slot(struct device_node *dn)
71{
72 u32 *index;
73 char *name;
74 int rc = -EINVAL;
75 struct slot *slot = NULL;
76
77 rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
78 if (rc < 0)
79 goto exit_rc;
80 index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
81 if (!index)
82 goto exit_rc;
83 if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
84 rc = -ENOMEM;
85 goto exit_rc;
86 }
87 slot->dev_type = VIO_DEV;
88 slot->dev.vio_dev = vio_find_node(dn);
89 if (slot->dev.vio_dev) {
90 /*
91 * rpaphp is the only owner of vio devices and
92 * does not need extra reference taken by
93 * vio_find_node
94 */
95 put_device(&slot->dev.vio_dev->dev);
96 } else
97 slot->dev.vio_dev = vio_register_device_node(dn);
98 if (slot->dev.vio_dev)
99 slot->state = CONFIGURED;
100 else
101 slot->state = NOT_CONFIGURED;
102 if (setup_vio_hotplug_slot_info(slot))
103 goto exit_rc;
104 strcpy(slot->name, slot->dev.vio_dev->dev.bus_id);
105 info("%s: registered VIO device[name=%s vio_dev=%p]\n",
106 __FUNCTION__, slot->name, slot->dev.vio_dev);
107 rc = register_slot(slot);
108exit_rc:
109 if (rc && slot)
110 dealloc_slot_struct(slot);
111 return (rc);
112}
113
114int rpaphp_enable_vio_slot(struct slot *slot)
115{
116 int retval = 0;
117
118 if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) {
119 info("%s: VIO adapter %s in slot[%s] has been configured\n",
120 __FUNCTION__, slot->dn->name, slot->name);
121 slot->state = CONFIGURED;
122 } else {
123 info("%s: no vio_dev struct for adapter in slot[%s]\n",
124 __FUNCTION__, slot->name);
125 slot->state = NOT_CONFIGURED;
126 }
127
128 return retval;
129}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
new file mode 100644
index 000000000000..67b6a3370ceb
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp.h
@@ -0,0 +1,463 @@
1/*
2 * Standard Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM
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>,<dely.l.sy@intel.com>
27 *
28 */
29#ifndef _SHPCHP_H
30#define _SHPCHP_H
31
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include "pci_hotplug.h"
38
39#if !defined(MODULE)
40 #define MY_NAME "shpchp"
41#else
42 #define MY_NAME THIS_MODULE->name
43#endif
44
45extern int shpchp_poll_mode;
46extern int shpchp_poll_time;
47extern int shpchp_debug;
48
49/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
50#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
51#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
52#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
53#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
54
55struct pci_func {
56 struct pci_func *next;
57 u8 bus;
58 u8 device;
59 u8 function;
60 u8 is_a_board;
61 u16 status;
62 u8 configured;
63 u8 switch_save;
64 u8 presence_save;
65 u8 pwr_save;
66 u32 base_length[0x06];
67 u8 base_type[0x06];
68 u16 reserved2;
69 u32 config_space[0x20];
70 struct pci_resource *mem_head;
71 struct pci_resource *p_mem_head;
72 struct pci_resource *io_head;
73 struct pci_resource *bus_head;
74 struct pci_dev* pci_dev;
75};
76
77#define SLOT_MAGIC 0x67267321
78struct slot {
79 u32 magic;
80 struct slot *next;
81 u8 bus;
82 u8 device;
83 u32 number;
84 u8 is_a_board;
85 u8 configured;
86 u8 state;
87 u8 switch_save;
88 u8 presence_save;
89 u32 capabilities;
90 u16 reserved2;
91 struct timer_list task_event;
92 u8 hp_slot;
93 struct controller *ctrl;
94 struct hpc_ops *hpc_ops;
95 struct hotplug_slot *hotplug_slot;
96 struct list_head slot_list;
97};
98
99struct pci_resource {
100 struct pci_resource * next;
101 u32 base;
102 u32 length;
103};
104
105struct event_info {
106 u32 event_type;
107 u8 hp_slot;
108};
109
110struct controller {
111 struct controller *next;
112 struct semaphore crit_sect; /* critical section semaphore */
113 void * hpc_ctlr_handle; /* HPC controller handle */
114 int num_slots; /* Number of slots on ctlr */
115 int slot_num_inc; /* 1 or -1 */
116 struct pci_resource *mem_head;
117 struct pci_resource *p_mem_head;
118 struct pci_resource *io_head;
119 struct pci_resource *bus_head;
120 struct pci_dev *pci_dev;
121 struct pci_bus *pci_bus;
122 struct event_info event_queue[10];
123 struct slot *slot;
124 struct hpc_ops *hpc_ops;
125 wait_queue_head_t queue; /* sleep & wake process */
126 u8 next_event;
127 u8 seg;
128 u8 bus;
129 u8 device;
130 u8 function;
131 u8 rev;
132 u8 slot_device_offset;
133 u8 add_support;
134 enum pci_bus_speed speed;
135 u32 first_slot; /* First physical slot number */
136 u8 slot_bus; /* Bus where the slots handled by this controller sit */
137 u8 push_flag;
138 u16 ctlrcap;
139 u16 vendor_id;
140};
141
142struct irq_mapping {
143 u8 barber_pole;
144 u8 valid_INT;
145 u8 interrupt[4];
146};
147
148struct resource_lists {
149 struct pci_resource *mem_head;
150 struct pci_resource *p_mem_head;
151 struct pci_resource *io_head;
152 struct pci_resource *bus_head;
153 struct irq_mapping *irqs;
154};
155
156/* Define AMD SHPC ID */
157#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
158
159#define INT_BUTTON_IGNORE 0
160#define INT_PRESENCE_ON 1
161#define INT_PRESENCE_OFF 2
162#define INT_SWITCH_CLOSE 3
163#define INT_SWITCH_OPEN 4
164#define INT_POWER_FAULT 5
165#define INT_POWER_FAULT_CLEAR 6
166#define INT_BUTTON_PRESS 7
167#define INT_BUTTON_RELEASE 8
168#define INT_BUTTON_CANCEL 9
169
170#define STATIC_STATE 0
171#define BLINKINGON_STATE 1
172#define BLINKINGOFF_STATE 2
173#define POWERON_STATE 3
174#define POWEROFF_STATE 4
175
176#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
177
178/* Error messages */
179#define INTERLOCK_OPEN 0x00000002
180#define ADD_NOT_SUPPORTED 0x00000003
181#define CARD_FUNCTIONING 0x00000005
182#define ADAPTER_NOT_SAME 0x00000006
183#define NO_ADAPTER_PRESENT 0x00000009
184#define NOT_ENOUGH_RESOURCES 0x0000000B
185#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
186#define WRONG_BUS_FREQUENCY 0x0000000D
187#define POWER_FAILURE 0x0000000E
188
189#define REMOVE_NOT_SUPPORTED 0x00000003
190
191#define DISABLE_CARD 1
192
193/*
194 * error Messages
195 */
196#define msg_initialization_err "Initialization failure, error=%d\n"
197#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
198#define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n"
199#define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n"
200#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
201#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
202#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
203#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
204#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
205
206/* sysfs functions for the hotplug controller info */
207extern void shpchp_create_ctrl_files (struct controller *ctrl);
208
209/* controller functions */
210extern int shpchprm_find_available_resources(struct controller *ctrl);
211extern int shpchp_event_start_thread(void);
212extern void shpchp_event_stop_thread(void);
213extern struct pci_func *shpchp_slot_create(unsigned char busnumber);
214extern struct pci_func *shpchp_slot_find(unsigned char bus, unsigned char device, unsigned char index);
215extern int shpchp_enable_slot(struct slot *slot);
216extern int shpchp_disable_slot(struct slot *slot);
217
218extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
219extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
220extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
221extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
222
223/* resource functions */
224extern int shpchp_resource_sort_and_combine(struct pci_resource **head);
225
226/* pci functions */
227extern int shpchp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
228/*extern int shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
229extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
230extern int shpchp_save_used_resources(struct controller *ctrl, struct pci_func * func, int flag);
231extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
232extern void shpchp_destroy_board_resources(struct pci_func * func);
233extern int shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources);
234extern void shpchp_destroy_resource_list(struct resource_lists * resources);
235extern int shpchp_configure_device(struct controller* ctrl, struct pci_func* func);
236extern int shpchp_unconfigure_device(struct pci_func* func);
237
238
239/* Global variables */
240extern struct controller *shpchp_ctrl_list;
241extern struct pci_func *shpchp_slot_list[256];
242
243/* These are added to support AMD shpc */
244extern u8 shpchp_nic_irq;
245extern u8 shpchp_disk_irq;
246
247struct ctrl_reg {
248 volatile u32 base_offset;
249 volatile u32 slot_avail1;
250 volatile u32 slot_avail2;
251 volatile u32 slot_config;
252 volatile u16 sec_bus_config;
253 volatile u8 msi_ctrl;
254 volatile u8 prog_interface;
255 volatile u16 cmd;
256 volatile u16 cmd_status;
257 volatile u32 intr_loc;
258 volatile u32 serr_loc;
259 volatile u32 serr_intr_enable;
260 volatile u32 slot1;
261 volatile u32 slot2;
262 volatile u32 slot3;
263 volatile u32 slot4;
264 volatile u32 slot5;
265 volatile u32 slot6;
266 volatile u32 slot7;
267 volatile u32 slot8;
268 volatile u32 slot9;
269 volatile u32 slot10;
270 volatile u32 slot11;
271 volatile u32 slot12;
272} __attribute__ ((packed));
273
274/* offsets to the controller registers based on the above structure layout */
275enum ctrl_offsets {
276 BASE_OFFSET = offsetof(struct ctrl_reg, base_offset),
277 SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1),
278 SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2),
279 SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config),
280 SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config),
281 MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl),
282 PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface),
283 CMD = offsetof(struct ctrl_reg, cmd),
284 CMD_STATUS = offsetof(struct ctrl_reg, cmd_status),
285 INTR_LOC = offsetof(struct ctrl_reg, intr_loc),
286 SERR_LOC = offsetof(struct ctrl_reg, serr_loc),
287 SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
288 SLOT1 = offsetof(struct ctrl_reg, slot1),
289 SLOT2 = offsetof(struct ctrl_reg, slot2),
290 SLOT3 = offsetof(struct ctrl_reg, slot3),
291 SLOT4 = offsetof(struct ctrl_reg, slot4),
292 SLOT5 = offsetof(struct ctrl_reg, slot5),
293 SLOT6 = offsetof(struct ctrl_reg, slot6),
294 SLOT7 = offsetof(struct ctrl_reg, slot7),
295 SLOT8 = offsetof(struct ctrl_reg, slot8),
296 SLOT9 = offsetof(struct ctrl_reg, slot9),
297 SLOT10 = offsetof(struct ctrl_reg, slot10),
298 SLOT11 = offsetof(struct ctrl_reg, slot11),
299 SLOT12 = offsetof(struct ctrl_reg, slot12),
300};
301typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
302struct php_ctlr_state_s {
303 struct php_ctlr_state_s *pnext;
304 struct pci_dev *pci_dev;
305 unsigned int irq;
306 unsigned long flags; /* spinlock's */
307 u32 slot_device_offset;
308 u32 num_slots;
309 struct timer_list int_poll_timer; /* Added for poll event */
310 php_intr_callback_t attention_button_callback;
311 php_intr_callback_t switch_change_callback;
312 php_intr_callback_t presence_change_callback;
313 php_intr_callback_t power_fault_callback;
314 void *callback_instance_id;
315 void __iomem *creg; /* Ptr to controller register space */
316};
317/* Inline functions */
318
319
320/* Inline functions to check the sanity of a pointer that is passed to us */
321static inline int slot_paranoia_check (struct slot *slot, const char *function)
322{
323 if (!slot) {
324 dbg("%s - slot == NULL", function);
325 return -1;
326 }
327 if (slot->magic != SLOT_MAGIC) {
328 dbg("%s - bad magic number for slot", function);
329 return -1;
330 }
331 if (!slot->hotplug_slot) {
332 dbg("%s - slot->hotplug_slot == NULL!", function);
333 return -1;
334 }
335 return 0;
336}
337
338static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
339{
340 struct slot *slot;
341
342 if (!hotplug_slot) {
343 dbg("%s - hotplug_slot == NULL\n", function);
344 return NULL;
345 }
346
347 slot = (struct slot *)hotplug_slot->private;
348 if (slot_paranoia_check (slot, function))
349 return NULL;
350 return slot;
351}
352
353static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
354{
355 struct slot *p_slot, *tmp_slot = NULL;
356
357 if (!ctrl)
358 return NULL;
359
360 p_slot = ctrl->slot;
361
362 dbg("p_slot = %p\n", p_slot);
363
364 while (p_slot && (p_slot->device != device)) {
365 tmp_slot = p_slot;
366 p_slot = p_slot->next;
367 dbg("In while loop, p_slot = %p\n", p_slot);
368 }
369 if (p_slot == NULL) {
370 err("ERROR: shpchp_find_slot device=0x%x\n", device);
371 p_slot = tmp_slot;
372 }
373
374 return (p_slot);
375}
376
377static inline int wait_for_ctrl_irq (struct controller *ctrl)
378{
379 DECLARE_WAITQUEUE(wait, current);
380 int retval = 0;
381
382 dbg("%s : start\n",__FUNCTION__);
383
384 add_wait_queue(&ctrl->queue, &wait);
385
386 if (!shpchp_poll_mode) {
387 /* Sleep for up to 1 second */
388 msleep_interruptible(1000);
389 } else {
390 /* Sleep for up to 2 seconds */
391 msleep_interruptible(2000);
392 }
393 remove_wait_queue(&ctrl->queue, &wait);
394 if (signal_pending(current))
395 retval = -EINTR;
396
397 dbg("%s : end\n", __FUNCTION__);
398 return retval;
399}
400
401/* Puts node back in the resource list pointed to by head */
402static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
403{
404 if (!node || !head)
405 return;
406 node->next = *head;
407 *head = node;
408}
409
410#define SLOT_NAME_SIZE 10
411
412static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
413{
414 snprintf(buffer, buffer_size, "%d", slot->number);
415}
416
417enum php_ctlr_type {
418 PCI,
419 ISA,
420 ACPI
421};
422
423int shpc_init( struct controller *ctrl, struct pci_dev *pdev,
424 php_intr_callback_t attention_button_callback,
425 php_intr_callback_t switch_change_callback,
426 php_intr_callback_t presence_change_callback,
427 php_intr_callback_t power_fault_callback);
428
429int shpc_get_ctlr_slot_config( struct controller *ctrl,
430 int *num_ctlr_slots,
431 int *first_device_num,
432 int *physical_slot_num,
433 int *updown,
434 int *flags);
435
436struct hpc_ops {
437 int (*power_on_slot ) (struct slot *slot);
438 int (*slot_enable ) (struct slot *slot);
439 int (*slot_disable ) (struct slot *slot);
440 int (*enable_all_slots) (struct slot *slot);
441 int (*pwr_on_all_slots) (struct slot *slot);
442 int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed);
443 int (*get_power_status) (struct slot *slot, u8 *status);
444 int (*get_attention_status) (struct slot *slot, u8 *status);
445 int (*set_attention_status) (struct slot *slot, u8 status);
446 int (*get_latch_status) (struct slot *slot, u8 *status);
447 int (*get_adapter_status) (struct slot *slot, u8 *status);
448
449 int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
450 int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
451 int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed);
452 int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode);
453 int (*get_prog_int) (struct slot *slot, u8 *prog_int);
454
455 int (*query_power_fault) (struct slot *slot);
456 void (*green_led_on) (struct slot *slot);
457 void (*green_led_off) (struct slot *slot);
458 void (*green_led_blink) (struct slot *slot);
459 void (*release_ctlr) (struct controller *ctrl);
460 int (*check_cmd_status) (struct controller *ctrl);
461};
462
463#endif /* _SHPCHP_H */
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
new file mode 100644
index 000000000000..f0c53f850aed
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -0,0 +1,630 @@
1/*
2 * Standard Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "shpchp.h"
42#include "shpchprm.h"
43
44/* Global variables */
45int shpchp_debug;
46int shpchp_poll_mode;
47int shpchp_poll_time;
48struct controller *shpchp_ctrl_list; /* = NULL */
49struct pci_func *shpchp_slot_list[256];
50
51#define DRIVER_VERSION "0.4"
52#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
53#define DRIVER_DESC "Standard Hot Plug PCI Controller Driver"
54
55MODULE_AUTHOR(DRIVER_AUTHOR);
56MODULE_DESCRIPTION(DRIVER_DESC);
57MODULE_LICENSE("GPL");
58
59module_param(shpchp_debug, bool, 0644);
60module_param(shpchp_poll_mode, bool, 0644);
61module_param(shpchp_poll_time, int, 0644);
62MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
63MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
64MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
65
66#define SHPC_MODULE_NAME "shpchp"
67
68static int shpc_start_thread (void);
69static int set_attention_status (struct hotplug_slot *slot, u8 value);
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72static int get_power_status (struct hotplug_slot *slot, u8 *value);
73static int get_attention_status (struct hotplug_slot *slot, u8 *value);
74static int get_latch_status (struct hotplug_slot *slot, u8 *value);
75static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
76static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
77static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
78
79static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
80 .owner = THIS_MODULE,
81 .set_attention_status = set_attention_status,
82 .enable_slot = enable_slot,
83 .disable_slot = disable_slot,
84 .get_power_status = get_power_status,
85 .get_attention_status = get_attention_status,
86 .get_latch_status = get_latch_status,
87 .get_adapter_status = get_adapter_status,
88 .get_max_bus_speed = get_max_bus_speed,
89 .get_cur_bus_speed = get_cur_bus_speed,
90};
91
92/**
93 * release_slot - free up the memory used by a slot
94 * @hotplug_slot: slot to free
95 */
96static void release_slot(struct hotplug_slot *hotplug_slot)
97{
98 struct slot *slot = (struct slot *)hotplug_slot->private;
99
100 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
101
102 kfree(slot->hotplug_slot->info);
103 kfree(slot->hotplug_slot->name);
104 kfree(slot->hotplug_slot);
105 kfree(slot);
106}
107
108static int init_slots(struct controller *ctrl)
109{
110 struct slot *new_slot;
111 u8 number_of_slots;
112 u8 slot_device;
113 u32 slot_number, sun;
114 int result = -ENOMEM;
115
116 dbg("%s\n",__FUNCTION__);
117
118 number_of_slots = ctrl->num_slots;
119 slot_device = ctrl->slot_device_offset;
120 slot_number = ctrl->first_slot;
121
122 while (number_of_slots) {
123 new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
124 if (!new_slot)
125 goto error;
126
127 memset(new_slot, 0, sizeof(struct slot));
128 new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
129 if (!new_slot->hotplug_slot)
130 goto error_slot;
131 memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
132
133 new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
134 if (!new_slot->hotplug_slot->info)
135 goto error_hpslot;
136 memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
137 new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
138 if (!new_slot->hotplug_slot->name)
139 goto error_info;
140
141 new_slot->magic = SLOT_MAGIC;
142 new_slot->ctrl = ctrl;
143 new_slot->bus = ctrl->slot_bus;
144 new_slot->device = slot_device;
145 new_slot->hpc_ops = ctrl->hpc_ops;
146
147 if (shpchprm_get_physical_slot_number(ctrl, &sun,
148 new_slot->bus, new_slot->device))
149 goto error_name;
150
151 new_slot->number = sun;
152 new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
153
154 /* register this slot with the hotplug pci core */
155 new_slot->hotplug_slot->private = new_slot;
156 new_slot->hotplug_slot->release = &release_slot;
157 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
158 new_slot->hotplug_slot->ops = &shpchp_hotplug_slot_ops;
159
160 new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
161 new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
162 new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
163 new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
164
165 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", new_slot->bus,
166 new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
167 result = pci_hp_register (new_slot->hotplug_slot);
168 if (result) {
169 err ("pci_hp_register failed with error %d\n", result);
170 goto error_name;
171 }
172
173 new_slot->next = ctrl->slot;
174 ctrl->slot = new_slot;
175
176 number_of_slots--;
177 slot_device++;
178 slot_number += ctrl->slot_num_inc;
179 }
180
181 return 0;
182
183error_name:
184 kfree(new_slot->hotplug_slot->name);
185error_info:
186 kfree(new_slot->hotplug_slot->info);
187error_hpslot:
188 kfree(new_slot->hotplug_slot);
189error_slot:
190 kfree(new_slot);
191error:
192 return result;
193}
194
195static void cleanup_slots(struct controller *ctrl)
196{
197 struct slot *old_slot, *next_slot;
198
199 old_slot = ctrl->slot;
200 ctrl->slot = NULL;
201
202 while (old_slot) {
203 next_slot = old_slot->next;
204 pci_hp_deregister(old_slot->hotplug_slot);
205 old_slot = next_slot;
206 }
207}
208
209static int get_ctlr_slot_config(struct controller *ctrl)
210{
211 int num_ctlr_slots;
212 int first_device_num;
213 int physical_slot_num;
214 int updown;
215 int rc;
216 int flags;
217
218 rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags);
219 if (rc) {
220 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
221 return -1;
222 }
223
224 ctrl->num_slots = num_ctlr_slots;
225 ctrl->slot_device_offset = first_device_num;
226 ctrl->first_slot = physical_slot_num;
227 ctrl->slot_num_inc = updown; /* either -1 or 1 */
228
229 dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n",
230 __FUNCTION__, num_ctlr_slots, first_device_num, physical_slot_num, updown, ctrl->bus, ctrl->device);
231
232 return 0;
233}
234
235
236/*
237 * set_attention_status - Turns the Amber LED for a slot on, off or blink
238 */
239static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
240{
241 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
242
243 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
244
245 hotplug_slot->info->attention_status = status;
246 slot->hpc_ops->set_attention_status(slot, status);
247
248 return 0;
249}
250
251
252static int enable_slot (struct hotplug_slot *hotplug_slot)
253{
254 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
255
256 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
257
258 return shpchp_enable_slot(slot);
259}
260
261
262static int disable_slot (struct hotplug_slot *hotplug_slot)
263{
264 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
265
266 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
267
268 return shpchp_disable_slot(slot);
269}
270
271static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
272{
273 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
274 int retval;
275
276 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
277
278 retval = slot->hpc_ops->get_power_status(slot, value);
279 if (retval < 0)
280 *value = hotplug_slot->info->power_status;
281
282 return 0;
283}
284
285static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
286{
287 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
288 int retval;
289
290 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
291
292 retval = slot->hpc_ops->get_attention_status(slot, value);
293 if (retval < 0)
294 *value = hotplug_slot->info->attention_status;
295
296 return 0;
297}
298
299static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
300{
301 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
302 int retval;
303
304 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
305
306 retval = slot->hpc_ops->get_latch_status(slot, value);
307 if (retval < 0)
308 *value = hotplug_slot->info->latch_status;
309
310 return 0;
311}
312
313static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
314{
315 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
316 int retval;
317
318 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
319
320 retval = slot->hpc_ops->get_adapter_status(slot, value);
321 if (retval < 0)
322 *value = hotplug_slot->info->adapter_status;
323
324 return 0;
325}
326
327static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
328{
329 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
330 int retval;
331
332 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
333
334 retval = slot->hpc_ops->get_max_bus_speed(slot, value);
335 if (retval < 0)
336 *value = PCI_SPEED_UNKNOWN;
337
338 return 0;
339}
340
341static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
342{
343 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
344 int retval;
345
346 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
347
348 retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
349 if (retval < 0)
350 *value = PCI_SPEED_UNKNOWN;
351
352 return 0;
353}
354
355static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
356{
357 int rc;
358 struct controller *ctrl;
359 struct slot *t_slot;
360 int first_device_num; /* first PCI device number supported by this SHPC */
361 int num_ctlr_slots; /* number of slots supported by this SHPC */
362
363 ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
364 if (!ctrl) {
365 err("%s : out of memory\n", __FUNCTION__);
366 goto err_out_none;
367 }
368 memset(ctrl, 0, sizeof(struct controller));
369
370 dbg("DRV_thread pid = %d\n", current->pid);
371
372 rc = shpc_init(ctrl, pdev,
373 (php_intr_callback_t) shpchp_handle_attention_button,
374 (php_intr_callback_t) shpchp_handle_switch_change,
375 (php_intr_callback_t) shpchp_handle_presence_change,
376 (php_intr_callback_t) shpchp_handle_power_fault);
377 if (rc) {
378 dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME);
379 goto err_out_free_ctrl;
380 }
381
382 dbg("%s: controller initialization success\n", __FUNCTION__);
383 ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
384
385 pci_set_drvdata(pdev, ctrl);
386
387 ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
388 if (!ctrl->pci_bus) {
389 err("out of memory\n");
390 rc = -ENOMEM;
391 goto err_out_unmap_mmio_region;
392 }
393
394 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
395 ctrl->bus = pdev->bus->number;
396 ctrl->slot_bus = pdev->subordinate->number;
397
398 ctrl->device = PCI_SLOT(pdev->devfn);
399 ctrl->function = PCI_FUNC(pdev->devfn);
400 dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
401
402 /*
403 * Save configuration headers for this and subordinate PCI buses
404 */
405
406 rc = get_ctlr_slot_config(ctrl);
407 if (rc) {
408 err(msg_initialization_err, rc);
409 goto err_out_free_ctrl_bus;
410 }
411 first_device_num = ctrl->slot_device_offset;
412 num_ctlr_slots = ctrl->num_slots;
413
414 /* Store PCI Config Space for all devices on this bus */
415 rc = shpchp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
416 if (rc) {
417 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
418 goto err_out_free_ctrl_bus;
419 }
420
421 /* Get IO, memory, and IRQ resources for new devices */
422 rc = shpchprm_find_available_resources(ctrl);
423 ctrl->add_support = !rc;
424
425 if (rc) {
426 dbg("shpchprm_find_available_resources = %#x\n", rc);
427 err("unable to locate PCI configuration resources for hot plug add.\n");
428 goto err_out_free_ctrl_bus;
429 }
430
431 /* Setup the slot information structures */
432 rc = init_slots(ctrl);
433 if (rc) {
434 err(msg_initialization_err, 6);
435 goto err_out_free_ctrl_slot;
436 }
437
438 /* Now hpc_functions (slot->hpc_ops->functions) are ready */
439 t_slot = shpchp_find_slot(ctrl, first_device_num);
440
441 /* Check for operation bus speed */
442 rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
443 dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
444
445 if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
446 err(SHPC_MODULE_NAME ": Can't get current bus speed. Set to 33MHz PCI.\n");
447 ctrl->speed = PCI_SPEED_33MHz;
448 }
449
450 /* Finish setting up the hot plug ctrl device */
451 ctrl->next_event = 0;
452
453 if (!shpchp_ctrl_list) {
454 shpchp_ctrl_list = ctrl;
455 ctrl->next = NULL;
456 } else {
457 ctrl->next = shpchp_ctrl_list;
458 shpchp_ctrl_list = ctrl;
459 }
460
461 shpchp_create_ctrl_files(ctrl);
462
463 return 0;
464
465err_out_free_ctrl_slot:
466 cleanup_slots(ctrl);
467err_out_free_ctrl_bus:
468 kfree(ctrl->pci_bus);
469err_out_unmap_mmio_region:
470 ctrl->hpc_ops->release_ctlr(ctrl);
471err_out_free_ctrl:
472 kfree(ctrl);
473err_out_none:
474 return -ENODEV;
475}
476
477
478static int shpc_start_thread(void)
479{
480 int loop;
481 int retval = 0;
482
483 dbg("Initialize + Start the notification/polling mechanism \n");
484
485 retval = shpchp_event_start_thread();
486 if (retval) {
487 dbg("shpchp_event_start_thread() failed\n");
488 return retval;
489 }
490
491 dbg("Initialize slot lists\n");
492 /* One slot list for each bus in the system */
493 for (loop = 0; loop < 256; loop++) {
494 shpchp_slot_list[loop] = NULL;
495 }
496
497 return retval;
498}
499
500static inline void __exit
501free_shpchp_res(struct pci_resource *res)
502{
503 struct pci_resource *tres;
504
505 while (res) {
506 tres = res;
507 res = res->next;
508 kfree(tres);
509 }
510}
511
512static void __exit unload_shpchpd(void)
513{
514 struct pci_func *next;
515 struct pci_func *TempSlot;
516 int loop;
517 struct controller *ctrl;
518 struct controller *tctrl;
519
520 ctrl = shpchp_ctrl_list;
521
522 while (ctrl) {
523 cleanup_slots(ctrl);
524
525 free_shpchp_res(ctrl->io_head);
526 free_shpchp_res(ctrl->mem_head);
527 free_shpchp_res(ctrl->p_mem_head);
528 free_shpchp_res(ctrl->bus_head);
529
530 kfree (ctrl->pci_bus);
531
532 dbg("%s: calling release_ctlr\n", __FUNCTION__);
533 ctrl->hpc_ops->release_ctlr(ctrl);
534
535 tctrl = ctrl;
536 ctrl = ctrl->next;
537
538 kfree(tctrl);
539 }
540
541 for (loop = 0; loop < 256; loop++) {
542 next = shpchp_slot_list[loop];
543 while (next != NULL) {
544 free_shpchp_res(next->io_head);
545 free_shpchp_res(next->mem_head);
546 free_shpchp_res(next->p_mem_head);
547 free_shpchp_res(next->bus_head);
548
549 TempSlot = next;
550 next = next->next;
551 kfree(TempSlot);
552 }
553 }
554
555 /* Stop the notification mechanism */
556 shpchp_event_stop_thread();
557
558}
559
560
561static struct pci_device_id shpcd_pci_tbl[] = {
562 {
563 .class = ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
564 .class_mask = ~0,
565 .vendor = PCI_ANY_ID,
566 .device = PCI_ANY_ID,
567 .subvendor = PCI_ANY_ID,
568 .subdevice = PCI_ANY_ID,
569 },
570
571 { /* end: all zeroes */ }
572};
573
574MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl);
575
576
577
578static struct pci_driver shpc_driver = {
579 .name = SHPC_MODULE_NAME,
580 .id_table = shpcd_pci_tbl,
581 .probe = shpc_probe,
582 /* remove: shpc_remove_one, */
583};
584
585
586
587static int __init shpcd_init(void)
588{
589 int retval = 0;
590
591#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
592 shpchp_poll_mode = 1;
593#endif
594
595 retval = shpc_start_thread();
596 if (retval)
597 goto error_hpc_init;
598
599 retval = shpchprm_init(PCI);
600 if (!retval) {
601 retval = pci_register_driver(&shpc_driver);
602 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
603 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
604 }
605
606error_hpc_init:
607 if (retval) {
608 shpchprm_cleanup();
609 shpchp_event_stop_thread();
610 } else
611 shpchprm_print_pirt();
612
613 return retval;
614}
615
616static void __exit shpcd_cleanup(void)
617{
618 dbg("unload_shpchpd()\n");
619 unload_shpchpd();
620
621 shpchprm_cleanup();
622
623 dbg("pci_unregister_driver\n");
624 pci_unregister_driver(&shpc_driver);
625
626 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
627}
628
629module_init(shpcd_init);
630module_exit(shpcd_cleanup);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
new file mode 100644
index 000000000000..9f90eb8e6ecd
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -0,0 +1,2848 @@
1/*
2 * Standard Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h>
40#include <linux/pci.h>
41#include "shpchp.h"
42#include "shpchprm.h"
43
44static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
45 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
46static int configure_new_function( struct controller *ctrl, struct pci_func *func,
47 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
48static void interrupt_event_handler(struct controller *ctrl);
49
50static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
51static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
52static int event_finished;
53static unsigned long pushbutton_pending; /* = 0 */
54
55u8 shpchp_disk_irq;
56u8 shpchp_nic_irq;
57
58u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
59{
60 struct controller *ctrl = (struct controller *) inst_id;
61 struct slot *p_slot;
62 u8 rc = 0;
63 u8 getstatus;
64 struct pci_func *func;
65 struct event_info *taskInfo;
66
67 /* Attention Button Change */
68 dbg("shpchp: Attention button interrupt received.\n");
69
70 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
71
72 /* This is the structure that tells the worker thread what to do */
73 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
74 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
75
76 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
77 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
78
79 ctrl->next_event = (ctrl->next_event + 1) % 10;
80 taskInfo->hp_slot = hp_slot;
81
82 rc++;
83
84 /*
85 * Button pressed - See if need to TAKE ACTION!!!
86 */
87 info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
88 taskInfo->event_type = INT_BUTTON_PRESS;
89
90 if ((p_slot->state == BLINKINGON_STATE)
91 || (p_slot->state == BLINKINGOFF_STATE)) {
92 /* Cancel if we are still blinking; this means that we press the
93 * attention again before the 5 sec. limit expires to cancel hot-add
94 * or hot-remove
95 */
96 taskInfo->event_type = INT_BUTTON_CANCEL;
97 info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
98 } else if ((p_slot->state == POWERON_STATE)
99 || (p_slot->state == POWEROFF_STATE)) {
100 /* Ignore if the slot is on power-on or power-off state; this
101 * means that the previous attention button action to hot-add or
102 * hot-remove is undergoing
103 */
104 taskInfo->event_type = INT_BUTTON_IGNORE;
105 info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
106 }
107
108 if (rc)
109 up(&event_semaphore); /* signal event thread that new event is posted */
110
111 return 0;
112
113}
114
115u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
116{
117 struct controller *ctrl = (struct controller *) inst_id;
118 struct slot *p_slot;
119 u8 rc = 0;
120 u8 getstatus;
121 struct pci_func *func;
122 struct event_info *taskInfo;
123
124 /* Switch Change */
125 dbg("shpchp: Switch interrupt received.\n");
126
127 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
128
129 /* This is the structure that tells the worker thread
130 * what to do
131 */
132 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
133 ctrl->next_event = (ctrl->next_event + 1) % 10;
134 taskInfo->hp_slot = hp_slot;
135
136 rc++;
137 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
138 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
139 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
140 dbg("%s: Card present %x Power status %x\n", __FUNCTION__,
141 func->presence_save, func->pwr_save);
142
143 if (getstatus) {
144 /*
145 * Switch opened
146 */
147 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
148 func->switch_save = 0;
149 taskInfo->event_type = INT_SWITCH_OPEN;
150 if (func->pwr_save && func->presence_save) {
151 taskInfo->event_type = INT_POWER_FAULT;
152 err("Surprise Removal of card\n");
153 }
154 } else {
155 /*
156 * Switch closed
157 */
158 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
159 func->switch_save = 0x10;
160 taskInfo->event_type = INT_SWITCH_CLOSE;
161 }
162
163 if (rc)
164 up(&event_semaphore); /* signal event thread that new event is posted */
165
166 return rc;
167}
168
169u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
170{
171 struct controller *ctrl = (struct controller *) inst_id;
172 struct slot *p_slot;
173 u8 rc = 0;
174 /*u8 temp_byte;*/
175 struct pci_func *func;
176 struct event_info *taskInfo;
177
178 /* Presence Change */
179 dbg("shpchp: Presence/Notify input change.\n");
180
181 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
182
183 /* This is the structure that tells the worker thread
184 * what to do
185 */
186 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
187 ctrl->next_event = (ctrl->next_event + 1) % 10;
188 taskInfo->hp_slot = hp_slot;
189
190 rc++;
191 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
192
193 /*
194 * Save the presence state
195 */
196 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
197 if (func->presence_save) {
198 /*
199 * Card Present
200 */
201 info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
202 taskInfo->event_type = INT_PRESENCE_ON;
203 } else {
204 /*
205 * Not Present
206 */
207 info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
208 taskInfo->event_type = INT_PRESENCE_OFF;
209 }
210
211 if (rc)
212 up(&event_semaphore); /* signal event thread that new event is posted */
213
214 return rc;
215}
216
217u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
218{
219 struct controller *ctrl = (struct controller *) inst_id;
220 struct slot *p_slot;
221 u8 rc = 0;
222 struct pci_func *func;
223 struct event_info *taskInfo;
224
225 /* Power fault */
226 dbg("shpchp: Power fault interrupt received.\n");
227
228 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
229
230 /* This is the structure that tells the worker thread
231 * what to do
232 */
233 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
234 ctrl->next_event = (ctrl->next_event + 1) % 10;
235 taskInfo->hp_slot = hp_slot;
236
237 rc++;
238 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
239
240 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
241 /*
242 * Power fault Cleared
243 */
244 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
245 func->status = 0x00;
246 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
247 } else {
248 /*
249 * Power fault
250 */
251 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
252 taskInfo->event_type = INT_POWER_FAULT;
253 /* set power fault status for this board */
254 func->status = 0xFF;
255 info("power fault bit %x set\n", hp_slot);
256 }
257 if (rc)
258 up(&event_semaphore); /* signal event thread that new event is posted */
259
260 return rc;
261}
262
263
264/*
265 * sort_by_size
266 *
267 * Sorts nodes on the list by their length.
268 * Smallest first.
269 *
270 */
271static int sort_by_size(struct pci_resource **head)
272{
273 struct pci_resource *current_res;
274 struct pci_resource *next_res;
275 int out_of_order = 1;
276
277 if (!(*head))
278 return(1);
279
280 if (!((*head)->next))
281 return(0);
282
283 while (out_of_order) {
284 out_of_order = 0;
285
286 /* Special case for swapping list head */
287 if (((*head)->next) &&
288 ((*head)->length > (*head)->next->length)) {
289 out_of_order++;
290 current_res = *head;
291 *head = (*head)->next;
292 current_res->next = (*head)->next;
293 (*head)->next = current_res;
294 }
295
296 current_res = *head;
297
298 while (current_res->next && current_res->next->next) {
299 if (current_res->next->length > current_res->next->next->length) {
300 out_of_order++;
301 next_res = current_res->next;
302 current_res->next = current_res->next->next;
303 current_res = current_res->next;
304 next_res->next = current_res->next;
305 current_res->next = next_res;
306 } else
307 current_res = current_res->next;
308 }
309 } /* End of out_of_order loop */
310
311 return(0);
312}
313
314
315/*
316 * sort_by_max_size
317 *
318 * Sorts nodes on the list by their length.
319 * Largest first.
320 *
321 */
322static int sort_by_max_size(struct pci_resource **head)
323{
324 struct pci_resource *current_res;
325 struct pci_resource *next_res;
326 int out_of_order = 1;
327
328 if (!(*head))
329 return(1);
330
331 if (!((*head)->next))
332 return(0);
333
334 while (out_of_order) {
335 out_of_order = 0;
336
337 /* Special case for swapping list head */
338 if (((*head)->next) &&
339 ((*head)->length < (*head)->next->length)) {
340 out_of_order++;
341 current_res = *head;
342 *head = (*head)->next;
343 current_res->next = (*head)->next;
344 (*head)->next = current_res;
345 }
346
347 current_res = *head;
348
349 while (current_res->next && current_res->next->next) {
350 if (current_res->next->length < current_res->next->next->length) {
351 out_of_order++;
352 next_res = current_res->next;
353 current_res->next = current_res->next->next;
354 current_res = current_res->next;
355 next_res->next = current_res->next;
356 current_res->next = next_res;
357 } else
358 current_res = current_res->next;
359 }
360 } /* End of out_of_order loop */
361
362 return(0);
363}
364
365
366/*
367 * do_pre_bridge_resource_split
368 *
369 * Returns zero or one node of resources that aren't in use
370 *
371 */
372static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
373{
374 struct pci_resource *prevnode = NULL;
375 struct pci_resource *node;
376 struct pci_resource *split_node;
377 u32 rc;
378 u32 temp_dword;
379 dbg("do_pre_bridge_resource_split\n");
380
381 if (!(*head) || !(*orig_head))
382 return(NULL);
383
384 rc = shpchp_resource_sort_and_combine(head);
385
386 if (rc)
387 return(NULL);
388
389 if ((*head)->base != (*orig_head)->base)
390 return(NULL);
391
392 if ((*head)->length == (*orig_head)->length)
393 return(NULL);
394
395
396 /* If we got here, there the bridge requires some of the resource, but
397 * we may be able to split some off of the front
398 */
399 node = *head;
400
401 if (node->length & (alignment -1)) {
402 /* This one isn't an aligned length, so we'll make a new entry
403 * and split it up.
404 */
405 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
406
407 if (!split_node)
408 return(NULL);
409
410 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
411
412 split_node->base = node->base;
413 split_node->length = temp_dword;
414
415 node->length -= temp_dword;
416 node->base += split_node->length;
417
418 /* Put it in the list */
419 *head = split_node;
420 split_node->next = node;
421 }
422
423 if (node->length < alignment) {
424 return(NULL);
425 }
426
427 /* Now unlink it */
428 if (*head == node) {
429 *head = node->next;
430 node->next = NULL;
431 } else {
432 prevnode = *head;
433 while (prevnode->next != node)
434 prevnode = prevnode->next;
435
436 prevnode->next = node->next;
437 node->next = NULL;
438 }
439
440 return(node);
441}
442
443
444/*
445 * do_bridge_resource_split
446 *
447 * Returns zero or one node of resources that aren't in use
448 *
449 */
450static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
451{
452 struct pci_resource *prevnode = NULL;
453 struct pci_resource *node;
454 u32 rc;
455 u32 temp_dword;
456
457 if (!(*head))
458 return(NULL);
459
460 rc = shpchp_resource_sort_and_combine(head);
461
462 if (rc)
463 return(NULL);
464
465 node = *head;
466
467 while (node->next) {
468 prevnode = node;
469 node = node->next;
470 kfree(prevnode);
471 }
472
473 if (node->length < alignment) {
474 kfree(node);
475 return(NULL);
476 }
477
478 if (node->base & (alignment - 1)) {
479 /* Short circuit if adjusted size is too small */
480 temp_dword = (node->base | (alignment-1)) + 1;
481 if ((node->length - (temp_dword - node->base)) < alignment) {
482 kfree(node);
483 return(NULL);
484 }
485
486 node->length -= (temp_dword - node->base);
487 node->base = temp_dword;
488 }
489
490 if (node->length & (alignment - 1)) {
491 /* There's stuff in use after this node */
492 kfree(node);
493 return(NULL);
494 }
495
496 return(node);
497}
498
499
500/*
501 * get_io_resource
502 *
503 * this function sorts the resource list by size and then
504 * returns the first node of "size" length that is not in the
505 * ISA aliasing window. If it finds a node larger than "size"
506 * it will split it up.
507 *
508 * size must be a power of two.
509 */
510static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
511{
512 struct pci_resource *prevnode;
513 struct pci_resource *node;
514 struct pci_resource *split_node = NULL;
515 u32 temp_dword;
516
517 if (!(*head))
518 return(NULL);
519
520 if ( shpchp_resource_sort_and_combine(head) )
521 return(NULL);
522
523 if ( sort_by_size(head) )
524 return(NULL);
525
526 for (node = *head; node; node = node->next) {
527 if (node->length < size)
528 continue;
529
530 if (node->base & (size - 1)) {
531 /* This one isn't base aligned properly
532 so we'll make a new entry and split it up */
533 temp_dword = (node->base | (size-1)) + 1;
534
535 /*/ Short circuit if adjusted size is too small */
536 if ((node->length - (temp_dword - node->base)) < size)
537 continue;
538
539 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
540
541 if (!split_node)
542 return(NULL);
543
544 split_node->base = node->base;
545 split_node->length = temp_dword - node->base;
546 node->base = temp_dword;
547 node->length -= split_node->length;
548
549 /* Put it in the list */
550 split_node->next = node->next;
551 node->next = split_node;
552 } /* End of non-aligned base */
553
554 /* Don't need to check if too small since we already did */
555 if (node->length > size) {
556 /* This one is longer than we need
557 so we'll make a new entry and split it up */
558 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
559
560 if (!split_node)
561 return(NULL);
562
563 split_node->base = node->base + size;
564 split_node->length = node->length - size;
565 node->length = size;
566
567 /* Put it in the list */
568 split_node->next = node->next;
569 node->next = split_node;
570 } /* End of too big on top end */
571
572 /* For IO make sure it's not in the ISA aliasing space */
573 if (node->base & 0x300L)
574 continue;
575
576 /* If we got here, then it is the right size
577 Now take it out of the list */
578 if (*head == node) {
579 *head = node->next;
580 } else {
581 prevnode = *head;
582 while (prevnode->next != node)
583 prevnode = prevnode->next;
584
585 prevnode->next = node->next;
586 }
587 node->next = NULL;
588 /* Stop looping */
589 break;
590 }
591
592 return(node);
593}
594
595
596/*
597 * get_max_resource
598 *
599 * Gets the largest node that is at least "size" big from the
600 * list pointed to by head. It aligns the node on top and bottom
601 * to "size" alignment before returning it.
602 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
603 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
604 */
605static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
606{
607 struct pci_resource *max;
608 struct pci_resource *temp;
609 struct pci_resource *split_node;
610 u32 temp_dword;
611 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
612 int i;
613
614 if (!(*head))
615 return(NULL);
616
617 if (shpchp_resource_sort_and_combine(head))
618 return(NULL);
619
620 if (sort_by_max_size(head))
621 return(NULL);
622
623 for (max = *head;max; max = max->next) {
624
625 /* If not big enough we could probably just bail,
626 instead we'll continue to the next. */
627 if (max->length < size)
628 continue;
629
630 if (max->base & (size - 1)) {
631 /* This one isn't base aligned properly
632 so we'll make a new entry and split it up */
633 temp_dword = (max->base | (size-1)) + 1;
634
635 /* Short circuit if adjusted size is too small */
636 if ((max->length - (temp_dword - max->base)) < size)
637 continue;
638
639 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
640
641 if (!split_node)
642 return(NULL);
643
644 split_node->base = max->base;
645 split_node->length = temp_dword - max->base;
646 max->base = temp_dword;
647 max->length -= split_node->length;
648
649 /* Put it next in the list */
650 split_node->next = max->next;
651 max->next = split_node;
652 }
653
654 if ((max->base + max->length) & (size - 1)) {
655 /* This one isn't end aligned properly at the top
656 so we'll make a new entry and split it up */
657 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
658
659 if (!split_node)
660 return(NULL);
661 temp_dword = ((max->base + max->length) & ~(size - 1));
662 split_node->base = temp_dword;
663 split_node->length = max->length + max->base
664 - split_node->base;
665 max->length -= split_node->length;
666
667 /* Put it in the list */
668 split_node->next = max->next;
669 max->next = split_node;
670 }
671
672 /* Make sure it didn't shrink too much when we aligned it */
673 if (max->length < size)
674 continue;
675
676 for ( i = 0; max_size[i] > size; i++) {
677 if (max->length > max_size[i]) {
678 split_node = kmalloc(sizeof(*split_node),
679 GFP_KERNEL);
680 if (!split_node)
681 break; /* return (NULL); */
682 split_node->base = max->base + max_size[i];
683 split_node->length = max->length - max_size[i];
684 max->length = max_size[i];
685 /* Put it next in the list */
686 split_node->next = max->next;
687 max->next = split_node;
688 break;
689 }
690 }
691
692 /* Now take it out of the list */
693 temp = (struct pci_resource*) *head;
694 if (temp == max) {
695 *head = max->next;
696 } else {
697 while (temp && temp->next != max) {
698 temp = temp->next;
699 }
700
701 temp->next = max->next;
702 }
703
704 max->next = NULL;
705 return(max);
706 }
707
708 /* If we get here, we couldn't find one */
709 return(NULL);
710}
711
712
713/*
714 * get_resource
715 *
716 * this function sorts the resource list by size and then
717 * returns the first node of "size" length. If it finds a node
718 * larger than "size" it will split it up.
719 *
720 * size must be a power of two.
721 */
722static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
723{
724 struct pci_resource *prevnode;
725 struct pci_resource *node;
726 struct pci_resource *split_node;
727 u32 temp_dword;
728
729 if (!(*head))
730 return(NULL);
731
732 if ( shpchp_resource_sort_and_combine(head) )
733 return(NULL);
734
735 if ( sort_by_size(head) )
736 return(NULL);
737
738 for (node = *head; node; node = node->next) {
739 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
740 __FUNCTION__, size, node, node->base, node->length);
741 if (node->length < size)
742 continue;
743
744 if (node->base & (size - 1)) {
745 dbg("%s: not aligned\n", __FUNCTION__);
746 /* this one isn't base aligned properly
747 so we'll make a new entry and split it up */
748 temp_dword = (node->base | (size-1)) + 1;
749
750 /* Short circuit if adjusted size is too small */
751 if ((node->length - (temp_dword - node->base)) < size)
752 continue;
753
754 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
755
756 if (!split_node)
757 return(NULL);
758
759 split_node->base = node->base;
760 split_node->length = temp_dword - node->base;
761 node->base = temp_dword;
762 node->length -= split_node->length;
763
764 /* Put it in the list */
765 split_node->next = node->next;
766 node->next = split_node;
767 } /* End of non-aligned base */
768
769 /* Don't need to check if too small since we already did */
770 if (node->length > size) {
771 dbg("%s: too big\n", __FUNCTION__);
772 /* this one is longer than we need
773 so we'll make a new entry and split it up */
774 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
775
776 if (!split_node)
777 return(NULL);
778
779 split_node->base = node->base + size;
780 split_node->length = node->length - size;
781 node->length = size;
782
783 /* Put it in the list */
784 split_node->next = node->next;
785 node->next = split_node;
786 } /* End of too big on top end */
787
788 dbg("%s: got one!!!\n", __FUNCTION__);
789 /* If we got here, then it is the right size
790 Now take it out of the list */
791 if (*head == node) {
792 *head = node->next;
793 } else {
794 prevnode = *head;
795 while (prevnode->next != node)
796 prevnode = prevnode->next;
797
798 prevnode->next = node->next;
799 }
800 node->next = NULL;
801 /* Stop looping */
802 break;
803 }
804 return(node);
805}
806
807
808/*
809 * shpchp_resource_sort_and_combine
810 *
811 * Sorts all of the nodes in the list in ascending order by
812 * their base addresses. Also does garbage collection by
813 * combining adjacent nodes.
814 *
815 * returns 0 if success
816 */
817int shpchp_resource_sort_and_combine(struct pci_resource **head)
818{
819 struct pci_resource *node1;
820 struct pci_resource *node2;
821 int out_of_order = 1;
822
823 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
824
825 if (!(*head))
826 return(1);
827
828 dbg("*head->next = %p\n",(*head)->next);
829
830 if (!(*head)->next)
831 return(0); /* only one item on the list, already sorted! */
832
833 dbg("*head->base = 0x%x\n",(*head)->base);
834 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
835 while (out_of_order) {
836 out_of_order = 0;
837
838 /* Special case for swapping list head */
839 if (((*head)->next) &&
840 ((*head)->base > (*head)->next->base)) {
841 node1 = *head;
842 (*head) = (*head)->next;
843 node1->next = (*head)->next;
844 (*head)->next = node1;
845 out_of_order++;
846 }
847
848 node1 = (*head);
849
850 while (node1->next && node1->next->next) {
851 if (node1->next->base > node1->next->next->base) {
852 out_of_order++;
853 node2 = node1->next;
854 node1->next = node1->next->next;
855 node1 = node1->next;
856 node2->next = node1->next;
857 node1->next = node2;
858 } else
859 node1 = node1->next;
860 }
861 } /* End of out_of_order loop */
862
863 node1 = *head;
864
865 while (node1 && node1->next) {
866 if ((node1->base + node1->length) == node1->next->base) {
867 /* Combine */
868 dbg("8..\n");
869 node1->length += node1->next->length;
870 node2 = node1->next;
871 node1->next = node1->next->next;
872 kfree(node2);
873 } else
874 node1 = node1->next;
875 }
876
877 return(0);
878}
879
880
881/**
882 * shpchp_slot_create - Creates a node and adds it to the proper bus.
883 * @busnumber - bus where new node is to be located
884 *
885 * Returns pointer to the new node or NULL if unsuccessful
886 */
887struct pci_func *shpchp_slot_create(u8 busnumber)
888{
889 struct pci_func *new_slot;
890 struct pci_func *next;
891
892 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
893
894 if (new_slot == NULL) {
895 return(new_slot);
896 }
897
898 memset(new_slot, 0, sizeof(struct pci_func));
899
900 new_slot->next = NULL;
901 new_slot->configured = 1;
902
903 if (shpchp_slot_list[busnumber] == NULL) {
904 shpchp_slot_list[busnumber] = new_slot;
905 } else {
906 next = shpchp_slot_list[busnumber];
907 while (next->next != NULL)
908 next = next->next;
909 next->next = new_slot;
910 }
911 return(new_slot);
912}
913
914
915/*
916 * slot_remove - Removes a node from the linked list of slots.
917 * @old_slot: slot to remove
918 *
919 * Returns 0 if successful, !0 otherwise.
920 */
921static int slot_remove(struct pci_func * old_slot)
922{
923 struct pci_func *next;
924
925 if (old_slot == NULL)
926 return(1);
927
928 next = shpchp_slot_list[old_slot->bus];
929
930 if (next == NULL) {
931 return(1);
932 }
933
934 if (next == old_slot) {
935 shpchp_slot_list[old_slot->bus] = old_slot->next;
936 shpchp_destroy_board_resources(old_slot);
937 kfree(old_slot);
938 return(0);
939 }
940
941 while ((next->next != old_slot) && (next->next != NULL)) {
942 next = next->next;
943 }
944
945 if (next->next == old_slot) {
946 next->next = old_slot->next;
947 shpchp_destroy_board_resources(old_slot);
948 kfree(old_slot);
949 return(0);
950 } else
951 return(2);
952}
953
954
955/**
956 * bridge_slot_remove - Removes a node from the linked list of slots.
957 * @bridge: bridge to remove
958 *
959 * Returns 0 if successful, !0 otherwise.
960 */
961static int bridge_slot_remove(struct pci_func *bridge)
962{
963 u8 subordinateBus, secondaryBus;
964 u8 tempBus;
965 struct pci_func *next;
966
967 if (bridge == NULL)
968 return(1);
969
970 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
971 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
972
973 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
974 next = shpchp_slot_list[tempBus];
975
976 while (!slot_remove(next)) {
977 next = shpchp_slot_list[tempBus];
978 }
979 }
980
981 next = shpchp_slot_list[bridge->bus];
982
983 if (next == NULL) {
984 return(1);
985 }
986
987 if (next == bridge) {
988 shpchp_slot_list[bridge->bus] = bridge->next;
989 kfree(bridge);
990 return(0);
991 }
992
993 while ((next->next != bridge) && (next->next != NULL)) {
994 next = next->next;
995 }
996
997 if (next->next == bridge) {
998 next->next = bridge->next;
999 kfree(bridge);
1000 return(0);
1001 } else
1002 return(2);
1003}
1004
1005
1006/**
1007 * shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1008 * @bus: bus to find
1009 * @device: device to find
1010 * @index: is 0 for first function found, 1 for the second...
1011 *
1012 * Returns pointer to the node if successful, %NULL otherwise.
1013 */
1014struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index)
1015{
1016 int found = -1;
1017 struct pci_func *func;
1018
1019 func = shpchp_slot_list[bus];
1020
1021 if ((func == NULL) || ((func->device == device) && (index == 0)))
1022 return(func);
1023
1024 if (func->device == device)
1025 found++;
1026
1027 while (func->next != NULL) {
1028 func = func->next;
1029
1030 if (func->device == device)
1031 found++;
1032
1033 if (found == index)
1034 return(func);
1035 }
1036
1037 return(NULL);
1038}
1039
1040static int is_bridge(struct pci_func * func)
1041{
1042 /* Check the header type */
1043 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1044 return 1;
1045 else
1046 return 0;
1047}
1048
1049
1050/* The following routines constitute the bulk of the
1051 hotplug controller logic
1052 */
1053static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
1054{
1055 u32 rc = 0;
1056
1057 dbg("%s: change to speed %d\n", __FUNCTION__, speed);
1058 down(&ctrl->crit_sect);
1059 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
1060 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
1061 up(&ctrl->crit_sect);
1062 return WRONG_BUS_FREQUENCY;
1063 }
1064 wait_for_ctrl_irq (ctrl);
1065
1066 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1067 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
1068 __FUNCTION__);
1069 err("%s: Error code (%d)\n", __FUNCTION__, rc);
1070 up(&ctrl->crit_sect);
1071 return WRONG_BUS_FREQUENCY;
1072 }
1073 up(&ctrl->crit_sect);
1074 return rc;
1075}
1076
1077static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag,
1078enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
1079{
1080 u32 rc = 0;
1081
1082 if (flag != 0) { /* Other slots on the same bus are occupied */
1083 if ( asp < bsp ) {
1084 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
1085 return WRONG_BUS_FREQUENCY;
1086 }
1087 } else {
1088 /* Other slots on the same bus are empty */
1089 if (msp == bsp) {
1090 /* if adapter_speed >= bus_speed, do nothing */
1091 if (asp < bsp) {
1092 /*
1093 * Try to lower bus speed to accommodate the adapter if other slots
1094 * on the same controller are empty
1095 */
1096 if ((rc = change_bus_speed(ctrl, pslot, asp)))
1097 return rc;
1098 }
1099 } else {
1100 if (asp < msp) {
1101 if ((rc = change_bus_speed(ctrl, pslot, asp)))
1102 return rc;
1103 } else {
1104 if ((rc = change_bus_speed(ctrl, pslot, msp)))
1105 return rc;
1106 }
1107 }
1108 }
1109 return rc;
1110}
1111
1112/**
1113 * board_added - Called after a board has been added to the system.
1114 *
1115 * Turns power on for the board
1116 * Configures board
1117 *
1118 */
1119static u32 board_added(struct pci_func * func, struct controller * ctrl)
1120{
1121 u8 hp_slot;
1122 u8 slots_not_empty = 0;
1123 int index;
1124 u32 temp_register = 0xFFFFFFFF;
1125 u32 retval, rc = 0;
1126 struct pci_func *new_func = NULL;
1127 struct slot *p_slot;
1128 struct resource_lists res_lists;
1129 enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
1130 u8 pi, mode;
1131
1132 p_slot = shpchp_find_slot(ctrl, func->device);
1133 hp_slot = func->device - ctrl->slot_device_offset;
1134
1135 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1136
1137 /* Wait for exclusive access to hardware */
1138 down(&ctrl->crit_sect);
1139
1140 /* Power on slot without connecting to bus */
1141 rc = p_slot->hpc_ops->power_on_slot(p_slot);
1142 if (rc) {
1143 err("%s: Failed to power on slot\n", __FUNCTION__);
1144 /* Done with exclusive hardware access */
1145 up(&ctrl->crit_sect);
1146 return -1;
1147 }
1148
1149 /* Wait for the command to complete */
1150 wait_for_ctrl_irq (ctrl);
1151
1152 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1153 if (rc) {
1154 err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
1155 /* Done with exclusive hardware access */
1156 up(&ctrl->crit_sect);
1157 return -1;
1158 }
1159
1160
1161 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
1162 if (slots_not_empty)
1163 return WRONG_BUS_FREQUENCY;
1164
1165 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
1166 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
1167 up(&ctrl->crit_sect);
1168 return WRONG_BUS_FREQUENCY;
1169 }
1170 wait_for_ctrl_irq (ctrl);
1171
1172 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1173 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
1174 __FUNCTION__);
1175 err("%s: Error code (%d)\n", __FUNCTION__, rc);
1176 up(&ctrl->crit_sect);
1177 return WRONG_BUS_FREQUENCY;
1178 }
1179 /* turn on board, blink green LED, turn off Amber LED */
1180 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
1181 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1182 up(&ctrl->crit_sect);
1183 return rc;
1184 }
1185 wait_for_ctrl_irq (ctrl);
1186
1187 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1188 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
1189 up(&ctrl->crit_sect);
1190 return rc;
1191 }
1192 }
1193
1194 rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
1195 /* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */
1196 /* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC, 0xa = PCI-X 133 Mhz 266, */
1197 /* 0xd = PCI-X 133 Mhz 533 */
1198 /* This encoding is different from the one used in cur_bus_speed & */
1199 /* max_bus_speed */
1200
1201 if (rc || adapter_speed == PCI_SPEED_UNKNOWN) {
1202 err("%s: Can't get adapter speed or bus mode mismatch\n", __FUNCTION__);
1203 /* Done with exclusive hardware access */
1204 up(&ctrl->crit_sect);
1205 return WRONG_BUS_FREQUENCY;
1206 }
1207
1208 rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed);
1209 if (rc || bus_speed == PCI_SPEED_UNKNOWN) {
1210 err("%s: Can't get bus operation speed\n", __FUNCTION__);
1211 /* Done with exclusive hardware access */
1212 up(&ctrl->crit_sect);
1213 return WRONG_BUS_FREQUENCY;
1214 }
1215
1216 rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
1217 if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
1218 err("%s: Can't get max bus operation speed\n", __FUNCTION__);
1219 max_bus_speed = bus_speed;
1220 }
1221
1222 /* Done with exclusive hardware access */
1223 up(&ctrl->crit_sect);
1224
1225 if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
1226 err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
1227 pi = 1;
1228 }
1229
1230 /* Check if there are other slots or devices on the same bus */
1231 if (!list_empty(&ctrl->pci_dev->subordinate->devices))
1232 slots_not_empty = 1;
1233
1234 dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__,
1235 slots_not_empty, pi);
1236 dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n",
1237 adapter_speed, bus_speed, max_bus_speed);
1238
1239 if (pi == 2) {
1240 dbg("%s: In PI = %d\n", __FUNCTION__, pi);
1241 if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
1242 err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
1243 mode = 0;
1244 }
1245
1246 switch (adapter_speed) {
1247 case PCI_SPEED_133MHz_PCIX_533:
1248 case PCI_SPEED_133MHz_PCIX_266:
1249 if ((bus_speed != adapter_speed) &&
1250 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1251 return rc;
1252 break;
1253 case PCI_SPEED_133MHz_PCIX_ECC:
1254 case PCI_SPEED_133MHz_PCIX:
1255 if (mode) { /* Bus - Mode 1 ECC */
1256 if ((bus_speed != 0x7) &&
1257 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1258 return rc;
1259 } else {
1260 if ((bus_speed != 0x4) &&
1261 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1262 return rc;
1263 }
1264 break;
1265 case PCI_SPEED_66MHz_PCIX_ECC:
1266 case PCI_SPEED_66MHz_PCIX:
1267 if (mode) { /* Bus - Mode 1 ECC */
1268 if ((bus_speed != 0x5) &&
1269 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1270 return rc;
1271 } else {
1272 if ((bus_speed != 0x2) &&
1273 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1274 return rc;
1275 }
1276 break;
1277 case PCI_SPEED_66MHz:
1278 if ((bus_speed != 0x1) &&
1279 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1280 return rc;
1281 break;
1282 case PCI_SPEED_33MHz:
1283 if (bus_speed > 0x0) {
1284 if (slots_not_empty == 0) {
1285 if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
1286 return rc;
1287 } else {
1288 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
1289 return WRONG_BUS_FREQUENCY;
1290 }
1291 }
1292 break;
1293 default:
1294 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
1295 return WRONG_BUS_FREQUENCY;
1296 }
1297 } else {
1298 /* If adpater_speed == bus_speed, nothing to do here */
1299 dbg("%s: In PI = %d\n", __FUNCTION__, pi);
1300 if ((adapter_speed != bus_speed) &&
1301 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1302 return rc;
1303 }
1304
1305 down(&ctrl->crit_sect);
1306 /* turn on board, blink green LED, turn off Amber LED */
1307 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
1308 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1309 up(&ctrl->crit_sect);
1310 return rc;
1311 }
1312 wait_for_ctrl_irq (ctrl);
1313
1314 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1315 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
1316 up(&ctrl->crit_sect);
1317 return rc;
1318 }
1319
1320 up(&ctrl->crit_sect);
1321
1322 /* Wait for ~1 second */
1323 dbg("%s: before long_delay\n", __FUNCTION__);
1324 wait_for_ctrl_irq (ctrl);
1325 dbg("%s: after long_delay\n", __FUNCTION__);
1326
1327 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1328 /* Check for a power fault */
1329 if (func->status == 0xFF) {
1330 /* power fault occurred, but it was benign */
1331 temp_register = 0xFFFFFFFF;
1332 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1333 rc = POWER_FAILURE;
1334 func->status = 0;
1335 } else {
1336 /* Get vendor/device ID u32 */
1337 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1338 PCI_VENDOR_ID, &temp_register);
1339 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1340 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1341
1342 if (rc != 0) {
1343 /* Something's wrong here */
1344 temp_register = 0xFFFFFFFF;
1345 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1346 }
1347 /* Preset return code. It will be changed later if things go okay. */
1348 rc = NO_ADAPTER_PRESENT;
1349 }
1350
1351 /* All F's is an empty slot or an invalid board */
1352 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1353 res_lists.io_head = ctrl->io_head;
1354 res_lists.mem_head = ctrl->mem_head;
1355 res_lists.p_mem_head = ctrl->p_mem_head;
1356 res_lists.bus_head = ctrl->bus_head;
1357 res_lists.irqs = NULL;
1358
1359 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1360 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1361
1362 ctrl->io_head = res_lists.io_head;
1363 ctrl->mem_head = res_lists.mem_head;
1364 ctrl->p_mem_head = res_lists.p_mem_head;
1365 ctrl->bus_head = res_lists.bus_head;
1366
1367 shpchp_resource_sort_and_combine(&(ctrl->mem_head));
1368 shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
1369 shpchp_resource_sort_and_combine(&(ctrl->io_head));
1370 shpchp_resource_sort_and_combine(&(ctrl->bus_head));
1371
1372 if (rc) {
1373 /* Wait for exclusive access to hardware */
1374 down(&ctrl->crit_sect);
1375
1376 /* turn off slot, turn on Amber LED, turn off Green LED */
1377 retval = p_slot->hpc_ops->slot_disable(p_slot);
1378 if (retval) {
1379 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1380 /* Done with exclusive hardware access */
1381 up(&ctrl->crit_sect);
1382 return retval;
1383 }
1384 /* Wait for the command to complete */
1385 wait_for_ctrl_irq (ctrl);
1386
1387 retval = p_slot->hpc_ops->check_cmd_status(ctrl);
1388 if (retval) {
1389 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval);
1390 /* Done with exclusive hardware access */
1391 up(&ctrl->crit_sect);
1392 return retval;
1393 }
1394
1395 /* Done with exclusive hardware access */
1396 up(&ctrl->crit_sect);
1397
1398 return(rc);
1399 }
1400 shpchp_save_slot_config(ctrl, func);
1401
1402 func->status = 0;
1403 func->switch_save = 0x10;
1404 func->is_a_board = 0x01;
1405 func->pwr_save = 1;
1406
1407 /* Next, we will instantiate the linux pci_dev structures
1408 * (with appropriate driver notification, if already present)
1409 */
1410 index = 0;
1411 do {
1412 new_func = shpchp_slot_find(ctrl->slot_bus, func->device, index++);
1413 if (new_func && !new_func->pci_dev) {
1414 dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__);
1415 shpchp_configure_device(ctrl, new_func);
1416 }
1417 } while (new_func);
1418
1419 /* Wait for exclusive access to hardware */
1420 down(&ctrl->crit_sect);
1421
1422 p_slot->hpc_ops->green_led_on(p_slot);
1423
1424 /* Wait for the command to complete */
1425 wait_for_ctrl_irq (ctrl);
1426
1427
1428 /* Done with exclusive hardware access */
1429 up(&ctrl->crit_sect);
1430
1431 } else {
1432 /* Wait for exclusive access to hardware */
1433 down(&ctrl->crit_sect);
1434
1435 /* turn off slot, turn on Amber LED, turn off Green LED */
1436 rc = p_slot->hpc_ops->slot_disable(p_slot);
1437 if (rc) {
1438 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1439 /* Done with exclusive hardware access */
1440 up(&ctrl->crit_sect);
1441 return rc;
1442 }
1443 /* Wait for the command to complete */
1444 wait_for_ctrl_irq (ctrl);
1445
1446 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1447 if (rc) {
1448 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
1449 /* Done with exclusive hardware access */
1450 up(&ctrl->crit_sect);
1451 return rc;
1452 }
1453
1454 /* Done with exclusive hardware access */
1455 up(&ctrl->crit_sect);
1456
1457 return(rc);
1458 }
1459 return 0;
1460}
1461
1462
1463/**
1464 * remove_board - Turns off slot and LED's
1465 *
1466 */
1467static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1468{
1469 int index;
1470 u8 skip = 0;
1471 u8 device;
1472 u8 hp_slot;
1473 u32 rc;
1474 struct resource_lists res_lists;
1475 struct pci_func *temp_func;
1476 struct slot *p_slot;
1477
1478 if (func == NULL)
1479 return(1);
1480
1481 if (shpchp_unconfigure_device(func))
1482 return(1);
1483
1484 device = func->device;
1485
1486 hp_slot = func->device - ctrl->slot_device_offset;
1487 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1488
1489 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1490
1491 if ((ctrl->add_support) &&
1492 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1493 /* Here we check to see if we've saved any of the board's
1494 * resources already. If so, we'll skip the attempt to
1495 * determine what's being used.
1496 */
1497 index = 0;
1498
1499 temp_func = func;
1500
1501 while ((temp_func = shpchp_slot_find(temp_func->bus, temp_func->device, index++))) {
1502 if (temp_func->bus_head || temp_func->mem_head
1503 || temp_func->p_mem_head || temp_func->io_head) {
1504 skip = 1;
1505 break;
1506 }
1507 }
1508
1509 if (!skip)
1510 rc = shpchp_save_used_resources(ctrl, func, DISABLE_CARD);
1511 }
1512 /* Change status to shutdown */
1513 if (func->is_a_board)
1514 func->status = 0x01;
1515 func->configured = 0;
1516
1517 /* Wait for exclusive access to hardware */
1518 down(&ctrl->crit_sect);
1519
1520 /* turn off slot, turn on Amber LED, turn off Green LED */
1521 rc = p_slot->hpc_ops->slot_disable(p_slot);
1522 if (rc) {
1523 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1524 /* Done with exclusive hardware access */
1525 up(&ctrl->crit_sect);
1526 return rc;
1527 }
1528 /* Wait for the command to complete */
1529 wait_for_ctrl_irq (ctrl);
1530
1531 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1532 if (rc) {
1533 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
1534 /* Done with exclusive hardware access */
1535 up(&ctrl->crit_sect);
1536 return rc;
1537 }
1538
1539 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
1540 if (rc) {
1541 err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
1542 /* Done with exclusive hardware access */
1543 up(&ctrl->crit_sect);
1544 return rc;
1545 }
1546 /* Wait for the command to complete */
1547 wait_for_ctrl_irq (ctrl);
1548
1549 /* Done with exclusive hardware access */
1550 up(&ctrl->crit_sect);
1551
1552 if (ctrl->add_support) {
1553 while (func) {
1554 res_lists.io_head = ctrl->io_head;
1555 res_lists.mem_head = ctrl->mem_head;
1556 res_lists.p_mem_head = ctrl->p_mem_head;
1557 res_lists.bus_head = ctrl->bus_head;
1558
1559 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus,
1560 func->device, func->function);
1561
1562 shpchp_return_board_resources(func, &res_lists);
1563
1564 ctrl->io_head = res_lists.io_head;
1565 ctrl->mem_head = res_lists.mem_head;
1566 ctrl->p_mem_head = res_lists.p_mem_head;
1567 ctrl->bus_head = res_lists.bus_head;
1568
1569 shpchp_resource_sort_and_combine(&(ctrl->mem_head));
1570 shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
1571 shpchp_resource_sort_and_combine(&(ctrl->io_head));
1572 shpchp_resource_sort_and_combine(&(ctrl->bus_head));
1573
1574 if (is_bridge(func)) {
1575 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
1576 func->device, func->function);
1577 bridge_slot_remove(func);
1578 } else
1579 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
1580 func->device, func->function);
1581 slot_remove(func);
1582
1583 func = shpchp_slot_find(ctrl->slot_bus, device, 0);
1584 }
1585
1586 /* Setup slot structure with entry for empty slot */
1587 func = shpchp_slot_create(ctrl->slot_bus);
1588
1589 if (func == NULL) {
1590 return(1);
1591 }
1592
1593 func->bus = ctrl->slot_bus;
1594 func->device = device;
1595 func->function = 0;
1596 func->configured = 0;
1597 func->switch_save = 0x10;
1598 func->pwr_save = 0;
1599 func->is_a_board = 0;
1600 }
1601
1602 return 0;
1603}
1604
1605
1606static void pushbutton_helper_thread (unsigned long data)
1607{
1608 pushbutton_pending = data;
1609
1610 up(&event_semaphore);
1611}
1612
1613
1614/**
1615 * shpchp_pushbutton_thread
1616 *
1617 * Scheduled procedure to handle blocking stuff for the pushbuttons
1618 * Handles all pending events and exits.
1619 *
1620 */
1621static void shpchp_pushbutton_thread (unsigned long slot)
1622{
1623 struct slot *p_slot = (struct slot *) slot;
1624 u8 getstatus;
1625
1626 pushbutton_pending = 0;
1627
1628 if (!p_slot) {
1629 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1630 return;
1631 }
1632
1633 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1634 if (getstatus) {
1635 p_slot->state = POWEROFF_STATE;
1636 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1637
1638 shpchp_disable_slot(p_slot);
1639 p_slot->state = STATIC_STATE;
1640 } else {
1641 p_slot->state = POWERON_STATE;
1642 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1643
1644 if (shpchp_enable_slot(p_slot)) {
1645 /* Wait for exclusive access to hardware */
1646 down(&p_slot->ctrl->crit_sect);
1647
1648 p_slot->hpc_ops->green_led_off(p_slot);
1649
1650 /* Wait for the command to complete */
1651 wait_for_ctrl_irq (p_slot->ctrl);
1652
1653 /* Done with exclusive hardware access */
1654 up(&p_slot->ctrl->crit_sect);
1655 }
1656 p_slot->state = STATIC_STATE;
1657 }
1658
1659 return;
1660}
1661
1662
1663/* this is the main worker thread */
1664static int event_thread(void* data)
1665{
1666 struct controller *ctrl;
1667 lock_kernel();
1668 daemonize("shpchpd_event");
1669 unlock_kernel();
1670
1671 while (1) {
1672 dbg("!!!!event_thread sleeping\n");
1673 down_interruptible (&event_semaphore);
1674 dbg("event_thread woken finished = %d\n", event_finished);
1675 if (event_finished || signal_pending(current))
1676 break;
1677 /* Do stuff here */
1678 if (pushbutton_pending)
1679 shpchp_pushbutton_thread(pushbutton_pending);
1680 else
1681 for (ctrl = shpchp_ctrl_list; ctrl; ctrl=ctrl->next)
1682 interrupt_event_handler(ctrl);
1683 }
1684 dbg("event_thread signals exit\n");
1685 up(&event_exit);
1686 return 0;
1687}
1688
1689int shpchp_event_start_thread (void)
1690{
1691 int pid;
1692
1693 /* initialize our semaphores */
1694 init_MUTEX_LOCKED(&event_exit);
1695 event_finished=0;
1696
1697 init_MUTEX_LOCKED(&event_semaphore);
1698 pid = kernel_thread(event_thread, NULL, 0);
1699
1700 if (pid < 0) {
1701 err ("Can't start up our event thread\n");
1702 return -1;
1703 }
1704 dbg("Our event thread pid = %d\n", pid);
1705 return 0;
1706}
1707
1708
1709void shpchp_event_stop_thread (void)
1710{
1711 event_finished = 1;
1712 dbg("event_thread finish command given\n");
1713 up(&event_semaphore);
1714 dbg("wait for event_thread to exit\n");
1715 down(&event_exit);
1716}
1717
1718
1719static int update_slot_info (struct slot *slot)
1720{
1721 struct hotplug_slot_info *info;
1722 int result;
1723
1724 info = kmalloc(sizeof(*info), GFP_KERNEL);
1725 if (!info)
1726 return -ENOMEM;
1727
1728 slot->hpc_ops->get_power_status(slot, &(info->power_status));
1729 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
1730 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
1731 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
1732
1733 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1734 kfree (info);
1735 return result;
1736}
1737
1738static void interrupt_event_handler(struct controller *ctrl)
1739{
1740 int loop = 0;
1741 int change = 1;
1742 struct pci_func *func;
1743 u8 hp_slot;
1744 u8 getstatus;
1745 struct slot *p_slot;
1746
1747 dbg("%s:\n", __FUNCTION__);
1748 while (change) {
1749 change = 0;
1750
1751 for (loop = 0; loop < 10; loop++) {
1752 if (ctrl->event_queue[loop].event_type != 0) {
1753 dbg("%s:loop %x event_type %x\n", __FUNCTION__, loop,
1754 ctrl->event_queue[loop].event_type);
1755 hp_slot = ctrl->event_queue[loop].hp_slot;
1756
1757 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1758
1759 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1760
1761 dbg("%s: hp_slot %d, func %p, p_slot %p\n", __FUNCTION__, hp_slot, func, p_slot);
1762
1763 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1764 dbg("%s: button cancel\n", __FUNCTION__);
1765 del_timer(&p_slot->task_event);
1766
1767 switch (p_slot->state) {
1768 case BLINKINGOFF_STATE:
1769 /* Wait for exclusive access to hardware */
1770 down(&ctrl->crit_sect);
1771
1772 p_slot->hpc_ops->green_led_on(p_slot);
1773 /* Wait for the command to complete */
1774 wait_for_ctrl_irq (ctrl);
1775
1776 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1777
1778 /* Wait for the command to complete */
1779 wait_for_ctrl_irq (ctrl);
1780
1781 /* Done with exclusive hardware access */
1782 up(&ctrl->crit_sect);
1783 break;
1784 case BLINKINGON_STATE:
1785 /* Wait for exclusive access to hardware */
1786 down(&ctrl->crit_sect);
1787
1788 p_slot->hpc_ops->green_led_off(p_slot);
1789 /* Wait for the command to complete */
1790 wait_for_ctrl_irq (ctrl);
1791
1792 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1793 /* Wait for the command to complete */
1794 wait_for_ctrl_irq (ctrl);
1795
1796 /* Done with exclusive hardware access */
1797 up(&ctrl->crit_sect);
1798
1799 break;
1800 default:
1801 warn("Not a valid state\n");
1802 return;
1803 }
1804 info(msg_button_cancel, p_slot->number);
1805 p_slot->state = STATIC_STATE;
1806 } else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1807 /* Button Pressed (No action on 1st press...) */
1808 dbg("%s: Button pressed\n", __FUNCTION__);
1809
1810 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1811 if (getstatus) {
1812 /* slot is on */
1813 dbg("%s: slot is on\n", __FUNCTION__);
1814 p_slot->state = BLINKINGOFF_STATE;
1815 info(msg_button_off, p_slot->number);
1816 } else {
1817 /* slot is off */
1818 dbg("%s: slot is off\n", __FUNCTION__);
1819 p_slot->state = BLINKINGON_STATE;
1820 info(msg_button_on, p_slot->number);
1821 }
1822
1823 /* Wait for exclusive access to hardware */
1824 down(&ctrl->crit_sect);
1825
1826 /* blink green LED and turn off amber */
1827 p_slot->hpc_ops->green_led_blink(p_slot);
1828 /* Wait for the command to complete */
1829 wait_for_ctrl_irq (ctrl);
1830
1831 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1832
1833 /* Wait for the command to complete */
1834 wait_for_ctrl_irq (ctrl);
1835
1836 /* Done with exclusive hardware access */
1837 up(&ctrl->crit_sect);
1838
1839 init_timer(&p_slot->task_event);
1840 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1841 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1842 p_slot->task_event.data = (unsigned long) p_slot;
1843
1844 dbg("%s: add_timer p_slot = %p\n", __FUNCTION__,(void *) p_slot);
1845 add_timer(&p_slot->task_event);
1846 } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1847 /***********POWER FAULT********************/
1848 dbg("%s: power fault\n", __FUNCTION__);
1849 /* Wait for exclusive access to hardware */
1850 down(&ctrl->crit_sect);
1851
1852 p_slot->hpc_ops->set_attention_status(p_slot, 1);
1853 /* Wait for the command to complete */
1854 wait_for_ctrl_irq (ctrl);
1855
1856 p_slot->hpc_ops->green_led_off(p_slot);
1857 /* Wait for the command to complete */
1858 wait_for_ctrl_irq (ctrl);
1859
1860 /* Done with exclusive hardware access */
1861 up(&ctrl->crit_sect);
1862 } else {
1863 /* refresh notification */
1864 if (p_slot)
1865 update_slot_info(p_slot);
1866 }
1867
1868 ctrl->event_queue[loop].event_type = 0;
1869
1870 change = 1;
1871 }
1872 } /* End of FOR loop */
1873 }
1874
1875 return;
1876}
1877
1878
1879int shpchp_enable_slot (struct slot *p_slot)
1880{
1881 u8 getstatus = 0;
1882 int rc;
1883 struct pci_func *func;
1884
1885 func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
1886 if (!func) {
1887 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1888 return 1;
1889 }
1890
1891 /* Check to see if (latch closed, card present, power off) */
1892 down(&p_slot->ctrl->crit_sect);
1893 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1894 if (rc || !getstatus) {
1895 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1896 up(&p_slot->ctrl->crit_sect);
1897 return 1;
1898 }
1899 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1900 if (rc || getstatus) {
1901 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1902 up(&p_slot->ctrl->crit_sect);
1903 return 1;
1904 }
1905 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1906 if (rc || getstatus) {
1907 info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
1908 up(&p_slot->ctrl->crit_sect);
1909 return 1;
1910 }
1911 up(&p_slot->ctrl->crit_sect);
1912
1913 slot_remove(func);
1914
1915 func = shpchp_slot_create(p_slot->bus);
1916 if (func == NULL)
1917 return 1;
1918
1919 func->bus = p_slot->bus;
1920 func->device = p_slot->device;
1921 func->function = 0;
1922 func->configured = 0;
1923 func->is_a_board = 1;
1924
1925 /* We have to save the presence info for these slots */
1926 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1927 p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save));
1928 dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save);
1929 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1930 func->switch_save = !getstatus? 0x10:0;
1931
1932 rc = board_added(func, p_slot->ctrl);
1933 if (rc) {
1934 if (is_bridge(func))
1935 bridge_slot_remove(func);
1936 else
1937 slot_remove(func);
1938
1939 /* Setup slot structure with entry for empty slot */
1940 func = shpchp_slot_create(p_slot->bus);
1941 if (func == NULL)
1942 return (1); /* Out of memory */
1943
1944 func->bus = p_slot->bus;
1945 func->device = p_slot->device;
1946 func->function = 0;
1947 func->configured = 0;
1948 func->is_a_board = 1;
1949
1950 /* We have to save the presence info for these slots */
1951 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1952 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1953 func->switch_save = !getstatus? 0x10:0;
1954 }
1955
1956 if (p_slot)
1957 update_slot_info(p_slot);
1958
1959 return rc;
1960}
1961
1962
1963int shpchp_disable_slot (struct slot *p_slot)
1964{
1965 u8 class_code, header_type, BCR;
1966 u8 index = 0;
1967 u8 getstatus = 0;
1968 u32 rc = 0;
1969 int ret = 0;
1970 unsigned int devfn;
1971 struct pci_bus *pci_bus;
1972 struct pci_func *func;
1973
1974 if (!p_slot->ctrl)
1975 return 1;
1976
1977 pci_bus = p_slot->ctrl->pci_dev->subordinate;
1978
1979 /* Check to see if (latch closed, card present, power on) */
1980 down(&p_slot->ctrl->crit_sect);
1981
1982 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1983 if (ret || !getstatus) {
1984 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1985 up(&p_slot->ctrl->crit_sect);
1986 return 1;
1987 }
1988 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1989 if (ret || getstatus) {
1990 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1991 up(&p_slot->ctrl->crit_sect);
1992 return 1;
1993 }
1994 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1995 if (ret || !getstatus) {
1996 info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
1997 up(&p_slot->ctrl->crit_sect);
1998 return 1;
1999 }
2000 up(&p_slot->ctrl->crit_sect);
2001
2002 func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
2003
2004 /* Make sure there are no video controllers here
2005 * for all func of p_slot
2006 */
2007 while (func && !rc) {
2008 pci_bus->number = func->bus;
2009 devfn = PCI_DEVFN(func->device, func->function);
2010
2011 /* Check the Class Code */
2012 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2013 if (rc)
2014 return rc;
2015
2016 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2017 /* Display/Video adapter (not supported) */
2018 rc = REMOVE_NOT_SUPPORTED;
2019 } else {
2020 /* See if it's a bridge */
2021 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
2022 if (rc)
2023 return rc;
2024
2025 /* If it's a bridge, check the VGA Enable bit */
2026 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2027 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
2028 if (rc)
2029 return rc;
2030
2031 /* If the VGA Enable bit is set, remove isn't supported */
2032 if (BCR & PCI_BRIDGE_CTL_VGA) {
2033 rc = REMOVE_NOT_SUPPORTED;
2034 }
2035 }
2036 }
2037
2038 func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
2039 }
2040
2041 func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
2042 if ((func != NULL) && !rc) {
2043 rc = remove_board(func, p_slot->ctrl);
2044 } else if (!rc)
2045 rc = 1;
2046
2047 if (p_slot)
2048 update_slot_info(p_slot);
2049
2050 return(rc);
2051}
2052
2053
2054/**
2055 * configure_new_device - Configures the PCI header information of one board.
2056 *
2057 * @ctrl: pointer to controller structure
2058 * @func: pointer to function structure
2059 * @behind_bridge: 1 if this is a recursive call, 0 if not
2060 * @resources: pointer to set of resource lists
2061 *
2062 * Returns 0 if success
2063 *
2064 */
2065static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
2066 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
2067{
2068 u8 temp_byte, function, max_functions, stop_it;
2069 int rc;
2070 u32 ID;
2071 struct pci_func *new_slot;
2072 struct pci_bus lpci_bus, *pci_bus;
2073 int index;
2074
2075 new_slot = func;
2076
2077 dbg("%s\n", __FUNCTION__);
2078 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2079 pci_bus = &lpci_bus;
2080 pci_bus->number = func->bus;
2081
2082 /* Check for Multi-function device */
2083 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
2084 if (rc) {
2085 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2086 return rc;
2087 }
2088
2089 if (temp_byte & 0x80) /* Multi-function device */
2090 max_functions = 8;
2091 else
2092 max_functions = 1;
2093
2094 function = 0;
2095
2096 do {
2097 rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev);
2098
2099 if (rc) {
2100 dbg("configure_new_function failed %d\n",rc);
2101 index = 0;
2102
2103 while (new_slot) {
2104 new_slot = shpchp_slot_find(new_slot->bus, new_slot->device, index++);
2105
2106 if (new_slot)
2107 shpchp_return_board_resources(new_slot, resources);
2108 }
2109
2110 return(rc);
2111 }
2112
2113 function++;
2114
2115 stop_it = 0;
2116
2117 /* The following loop skips to the next present function
2118 * and creates a board structure
2119 */
2120
2121 while ((function < max_functions) && (!stop_it)) {
2122 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
2123
2124 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
2125 function++;
2126 } else { /* There's something there */
2127 /* Setup slot structure. */
2128 new_slot = shpchp_slot_create(func->bus);
2129
2130 if (new_slot == NULL) {
2131 /* Out of memory */
2132 return(1);
2133 }
2134
2135 new_slot->bus = func->bus;
2136 new_slot->device = func->device;
2137 new_slot->function = function;
2138 new_slot->is_a_board = 1;
2139 new_slot->status = 0;
2140
2141 stop_it++;
2142 }
2143 }
2144
2145 } while (function < max_functions);
2146 dbg("returning from configure_new_device\n");
2147
2148 return 0;
2149}
2150
2151
2152/*
2153 * Configuration logic that involves the hotplug data structures and
2154 * their bookkeeping
2155 */
2156
2157
2158/**
2159 * configure_new_function - Configures the PCI header information of one device
2160 *
2161 * @ctrl: pointer to controller structure
2162 * @func: pointer to function structure
2163 * @behind_bridge: 1 if this is a recursive call, 0 if not
2164 * @resources: pointer to set of resource lists
2165 *
2166 * Calls itself recursively for bridged devices.
2167 * Returns 0 if success
2168 *
2169 */
2170static int configure_new_function (struct controller * ctrl, struct pci_func * func,
2171 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev)
2172{
2173 int cloop;
2174 u8 temp_byte;
2175 u8 device;
2176 u8 class_code;
2177 u16 temp_word;
2178 u32 rc;
2179 u32 temp_register;
2180 u32 base;
2181 u32 ID;
2182 unsigned int devfn;
2183 struct pci_resource *mem_node;
2184 struct pci_resource *p_mem_node;
2185 struct pci_resource *io_node;
2186 struct pci_resource *bus_node;
2187 struct pci_resource *hold_mem_node;
2188 struct pci_resource *hold_p_mem_node;
2189 struct pci_resource *hold_IO_node;
2190 struct pci_resource *hold_bus_node;
2191 struct irq_mapping irqs;
2192 struct pci_func *new_slot;
2193 struct pci_bus lpci_bus, *pci_bus;
2194 struct resource_lists temp_resources;
2195#if defined(CONFIG_X86_64)
2196 u8 IRQ=0;
2197#endif
2198
2199 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2200 pci_bus = &lpci_bus;
2201 pci_bus->number = func->bus;
2202 devfn = PCI_DEVFN(func->device, func->function);
2203
2204 /* Check for Bridge */
2205 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2206 if (rc)
2207 return rc;
2208
2209 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2210 /* set Primary bus */
2211 dbg("set Primary bus = 0x%x\n", func->bus);
2212 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2213 if (rc)
2214 return rc;
2215
2216 /* find range of busses to use */
2217 bus_node = get_max_resource(&resources->bus_head, 1L);
2218
2219 /* If we don't have any busses to allocate, we can't continue */
2220 if (!bus_node) {
2221 err("Got NO bus resource to use\n");
2222 return -ENOMEM;
2223 }
2224 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2225
2226 /* set Secondary bus */
2227 temp_byte = (u8)bus_node->base;
2228 dbg("set Secondary bus = 0x%x\n", temp_byte);
2229 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2230 if (rc)
2231 return rc;
2232
2233 /* set subordinate bus */
2234 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2235 dbg("set subordinate bus = 0x%x\n", temp_byte);
2236 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2237 if (rc)
2238 return rc;
2239
2240 /* Set HP parameters (Cache Line Size, Latency Timer) */
2241 rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2242 if (rc)
2243 return rc;
2244
2245 /* Setup the IO, memory, and prefetchable windows */
2246
2247 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2248 if (io_node) {
2249 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
2250 }
2251
2252 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2253 if (mem_node) {
2254 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
2255 }
2256
2257 if (resources->p_mem_head)
2258 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2259 else {
2260 /*
2261 * In some platform implementation, MEM and PMEM are not
2262 * distinguished, and hence ACPI _CRS has only MEM entries
2263 * for both MEM and PMEM.
2264 */
2265 dbg("using MEM for PMEM\n");
2266 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2267 }
2268 if (p_mem_node) {
2269 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
2270 }
2271
2272 /* set up the IRQ info */
2273 if (!resources->irqs) {
2274 irqs.barber_pole = 0;
2275 irqs.interrupt[0] = 0;
2276 irqs.interrupt[1] = 0;
2277 irqs.interrupt[2] = 0;
2278 irqs.interrupt[3] = 0;
2279 irqs.valid_INT = 0;
2280 } else {
2281 irqs.barber_pole = resources->irqs->barber_pole;
2282 irqs.interrupt[0] = resources->irqs->interrupt[0];
2283 irqs.interrupt[1] = resources->irqs->interrupt[1];
2284 irqs.interrupt[2] = resources->irqs->interrupt[2];
2285 irqs.interrupt[3] = resources->irqs->interrupt[3];
2286 irqs.valid_INT = resources->irqs->valid_INT;
2287 }
2288
2289 /* set up resource lists that are now aligned on top and bottom
2290 * for anything behind the bridge.
2291 */
2292 temp_resources.bus_head = bus_node;
2293 temp_resources.io_head = io_node;
2294 temp_resources.mem_head = mem_node;
2295 temp_resources.p_mem_head = p_mem_node;
2296 temp_resources.irqs = &irqs;
2297
2298 /* Make copies of the nodes we are going to pass down so that
2299 * if there is a problem,we can just use these to free resources
2300 */
2301 hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
2302 hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
2303 hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
2304 hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
2305
2306 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2307 kfree(hold_bus_node);
2308 kfree(hold_IO_node);
2309 kfree(hold_mem_node);
2310 kfree(hold_p_mem_node);
2311
2312 return 1;
2313 }
2314
2315 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2316
2317 bus_node->base += 1;
2318 bus_node->length -= 1;
2319 bus_node->next = NULL;
2320
2321 /* If we have IO resources copy them and fill in the bridge's
2322 * IO range registers
2323 */
2324 if (io_node) {
2325 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2326 io_node->next = NULL;
2327
2328 /* set IO base and Limit registers */
2329 RES_CHECK(io_node->base, 8);
2330 temp_byte = (u8)(io_node->base >> 8);
2331 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
2332
2333 RES_CHECK(io_node->base + io_node->length - 1, 8);
2334 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2335 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2336 } else {
2337 kfree(hold_IO_node);
2338 hold_IO_node = NULL;
2339 }
2340
2341 /* If we have memory resources copy them and fill in the bridge's
2342 * memory range registers. Otherwise, fill in the range
2343 * registers with values that disable them.
2344 */
2345 if (mem_node) {
2346 memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2347 mem_node->next = NULL;
2348
2349 /* set Mem base and Limit registers */
2350 RES_CHECK(mem_node->base, 16);
2351 temp_word = (u32)(mem_node->base >> 16);
2352 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2353
2354 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2355 temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
2356 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2357 } else {
2358 temp_word = 0xFFFF;
2359 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2360
2361 temp_word = 0x0000;
2362 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2363
2364 kfree(hold_mem_node);
2365 hold_mem_node = NULL;
2366 }
2367
2368 /* If we have prefetchable memory resources copy them and
2369 * fill in the bridge's memory range registers. Otherwise,
2370 * fill in the range registers with values that disable them.
2371 */
2372 if (p_mem_node) {
2373 memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2374 p_mem_node->next = NULL;
2375
2376 /* set Pre Mem base and Limit registers */
2377 RES_CHECK(p_mem_node->base, 16);
2378 temp_word = (u32)(p_mem_node->base >> 16);
2379 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2380
2381 RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
2382 temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16);
2383 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2384 } else {
2385 temp_word = 0xFFFF;
2386 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2387
2388 temp_word = 0x0000;
2389 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2390
2391 kfree(hold_p_mem_node);
2392 hold_p_mem_node = NULL;
2393 }
2394
2395 /* Adjust this to compensate for extra adjustment in first loop */
2396 irqs.barber_pole--;
2397
2398 rc = 0;
2399
2400 /* Here we actually find the devices and configure them */
2401 for (device = 0; (device <= 0x1F) && !rc; device++) {
2402 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2403
2404 ID = 0xFFFFFFFF;
2405 pci_bus->number = hold_bus_node->base;
2406 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
2407 PCI_VENDOR_ID, &ID);
2408 pci_bus->number = func->bus;
2409
2410 if (ID != 0xFFFFFFFF) { /* device Present */
2411 /* Setup slot structure. */
2412 new_slot = shpchp_slot_create(hold_bus_node->base);
2413
2414 if (new_slot == NULL) {
2415 /* Out of memory */
2416 rc = -ENOMEM;
2417 continue;
2418 }
2419
2420 new_slot->bus = hold_bus_node->base;
2421 new_slot->device = device;
2422 new_slot->function = 0;
2423 new_slot->is_a_board = 1;
2424 new_slot->status = 0;
2425
2426 rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device);
2427 dbg("configure_new_device rc=0x%x\n",rc);
2428 } /* End of IF (device in slot?) */
2429 } /* End of FOR loop */
2430
2431 if (rc) {
2432 shpchp_destroy_resource_list(&temp_resources);
2433
2434 return_resource(&(resources->bus_head), hold_bus_node);
2435 return_resource(&(resources->io_head), hold_IO_node);
2436 return_resource(&(resources->mem_head), hold_mem_node);
2437 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2438 return(rc);
2439 }
2440
2441 /* save the interrupt routing information */
2442 if (resources->irqs) {
2443 resources->irqs->interrupt[0] = irqs.interrupt[0];
2444 resources->irqs->interrupt[1] = irqs.interrupt[1];
2445 resources->irqs->interrupt[2] = irqs.interrupt[2];
2446 resources->irqs->interrupt[3] = irqs.interrupt[3];
2447 resources->irqs->valid_INT = irqs.valid_INT;
2448 } else if (!behind_bridge) {
2449 /* We need to hook up the interrupts here */
2450 for (cloop = 0; cloop < 4; cloop++) {
2451 if (irqs.valid_INT & (0x01 << cloop)) {
2452 rc = shpchp_set_irq(func->bus, func->device,
2453 0x0A + cloop, irqs.interrupt[cloop]);
2454 if (rc) {
2455 shpchp_destroy_resource_list (&temp_resources);
2456 return_resource(&(resources->bus_head), hold_bus_node);
2457 return_resource(&(resources->io_head), hold_IO_node);
2458 return_resource(&(resources->mem_head), hold_mem_node);
2459 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2460 return rc;
2461 }
2462 }
2463 } /* end of for loop */
2464 }
2465
2466 /* Return unused bus resources
2467 * First use the temporary node to store information for the board
2468 */
2469 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2470 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2471
2472 hold_bus_node->next = func->bus_head;
2473 func->bus_head = hold_bus_node;
2474
2475 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2476
2477 /* set subordinate bus */
2478 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2479 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2480
2481 if (temp_resources.bus_head->length == 0) {
2482 kfree(temp_resources.bus_head);
2483 temp_resources.bus_head = NULL;
2484 } else {
2485 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2486 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2487 return_resource(&(resources->bus_head), temp_resources.bus_head);
2488 }
2489 }
2490
2491 /* If we have IO space available and there is some left,
2492 * return the unused portion
2493 */
2494 if (hold_IO_node && temp_resources.io_head) {
2495 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2496 &hold_IO_node, 0x1000);
2497
2498 /* Check if we were able to split something off */
2499 if (io_node) {
2500 hold_IO_node->base = io_node->base + io_node->length;
2501
2502 RES_CHECK(hold_IO_node->base, 8);
2503 temp_byte = (u8)((hold_IO_node->base) >> 8);
2504 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2505
2506 return_resource(&(resources->io_head), io_node);
2507 }
2508
2509 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2510
2511 /* Check if we were able to split something off */
2512 if (io_node) {
2513 /* First use the temporary node to store information for the board */
2514 hold_IO_node->length = io_node->base - hold_IO_node->base;
2515
2516 /* If we used any, add it to the board's list */
2517 if (hold_IO_node->length) {
2518 hold_IO_node->next = func->io_head;
2519 func->io_head = hold_IO_node;
2520
2521 RES_CHECK(io_node->base - 1, 8);
2522 temp_byte = (u8)((io_node->base - 1) >> 8);
2523 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2524
2525 return_resource(&(resources->io_head), io_node);
2526 } else {
2527 /* it doesn't need any IO */
2528 temp_byte = 0x00;
2529 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2530
2531 return_resource(&(resources->io_head), io_node);
2532 kfree(hold_IO_node);
2533 }
2534 } else {
2535 /* it used most of the range */
2536 hold_IO_node->next = func->io_head;
2537 func->io_head = hold_IO_node;
2538 }
2539 } else if (hold_IO_node) {
2540 /* it used the whole range */
2541 hold_IO_node->next = func->io_head;
2542 func->io_head = hold_IO_node;
2543 }
2544
2545 /* If we have memory space available and there is some left,
2546 * return the unused portion
2547 */
2548 if (hold_mem_node && temp_resources.mem_head) {
2549 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2550
2551 /* Check if we were able to split something off */
2552 if (mem_node) {
2553 hold_mem_node->base = mem_node->base + mem_node->length;
2554
2555 RES_CHECK(hold_mem_node->base, 16);
2556 temp_word = (u32)((hold_mem_node->base) >> 16);
2557 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2558
2559 return_resource(&(resources->mem_head), mem_node);
2560 }
2561
2562 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2563
2564 /* Check if we were able to split something off */
2565 if (mem_node) {
2566 /* First use the temporary node to store information for the board */
2567 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2568
2569 if (hold_mem_node->length) {
2570 hold_mem_node->next = func->mem_head;
2571 func->mem_head = hold_mem_node;
2572
2573 /* configure end address */
2574 RES_CHECK(mem_node->base - 1, 16);
2575 temp_word = (u32)((mem_node->base - 1) >> 16);
2576 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2577
2578 /* Return unused resources to the pool */
2579 return_resource(&(resources->mem_head), mem_node);
2580 } else {
2581 /* it doesn't need any Mem */
2582 temp_word = 0x0000;
2583 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2584
2585 return_resource(&(resources->mem_head), mem_node);
2586 kfree(hold_mem_node);
2587 }
2588 } else {
2589 /* it used most of the range */
2590 hold_mem_node->next = func->mem_head;
2591 func->mem_head = hold_mem_node;
2592 }
2593 } else if (hold_mem_node) {
2594 /* it used the whole range */
2595 hold_mem_node->next = func->mem_head;
2596 func->mem_head = hold_mem_node;
2597 }
2598
2599 /* If we have prefetchable memory space available and there is some
2600 * left at the end, return the unused portion
2601 */
2602 if (hold_p_mem_node && temp_resources.p_mem_head) {
2603 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2604 &hold_p_mem_node, 0x100000L);
2605
2606 /* Check if we were able to split something off */
2607 if (p_mem_node) {
2608 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2609
2610 RES_CHECK(hold_p_mem_node->base, 16);
2611 temp_word = (u32)((hold_p_mem_node->base) >> 16);
2612 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2613
2614 return_resource(&(resources->p_mem_head), p_mem_node);
2615 }
2616
2617 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2618
2619 /* Check if we were able to split something off */
2620 if (p_mem_node) {
2621 /* First use the temporary node to store information for the board */
2622 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2623
2624 /* If we used any, add it to the board's list */
2625 if (hold_p_mem_node->length) {
2626 hold_p_mem_node->next = func->p_mem_head;
2627 func->p_mem_head = hold_p_mem_node;
2628
2629 RES_CHECK(p_mem_node->base - 1, 16);
2630 temp_word = (u32)((p_mem_node->base - 1) >> 16);
2631 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2632
2633 return_resource(&(resources->p_mem_head), p_mem_node);
2634 } else {
2635 /* it doesn't need any PMem */
2636 temp_word = 0x0000;
2637 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2638
2639 return_resource(&(resources->p_mem_head), p_mem_node);
2640 kfree(hold_p_mem_node);
2641 }
2642 } else {
2643 /* it used the most of the range */
2644 hold_p_mem_node->next = func->p_mem_head;
2645 func->p_mem_head = hold_p_mem_node;
2646 }
2647 } else if (hold_p_mem_node) {
2648 /* it used the whole range */
2649 hold_p_mem_node->next = func->p_mem_head;
2650 func->p_mem_head = hold_p_mem_node;
2651 }
2652
2653 /* We should be configuring an IRQ and the bridge's base address
2654 * registers if it needs them. Although we have never seen such
2655 * a device
2656 */
2657
2658 shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2659
2660 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2661 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2662 /* Standard device */
2663 u64 base64;
2664 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2665
2666 if (class_code == PCI_BASE_CLASS_DISPLAY)
2667 return (DEVICE_TYPE_NOT_SUPPORTED);
2668
2669 /* Figure out IO and memory needs */
2670 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2671 temp_register = 0xFFFFFFFF;
2672
2673 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2674 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2675 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device,
2676 func->function);
2677
2678 if (!temp_register)
2679 continue;
2680
2681 base64 = 0L;
2682 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2683 /* Map IO */
2684
2685 /* set base = amount of IO space */
2686 base = temp_register & 0xFFFFFFFC;
2687 base = ~base + 1;
2688
2689 dbg("NEED IO length(0x%x)\n", base);
2690 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2691
2692 /* allocate the resource to the board */
2693 if (io_node) {
2694 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2695 base = (u32)io_node->base;
2696 io_node->next = func->io_head;
2697 func->io_head = io_node;
2698 } else {
2699 err("Got NO IO resource(length=0x%x)\n", base);
2700 return -ENOMEM;
2701 }
2702 } else { /* map MEM */
2703 int prefetchable = 1;
2704 struct pci_resource **res_node = &func->p_mem_head;
2705 char *res_type_str = "PMEM";
2706 u32 temp_register2;
2707
2708 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2709 prefetchable = 0;
2710 res_node = &func->mem_head;
2711 res_type_str++;
2712 }
2713
2714 base = temp_register & 0xFFFFFFF0;
2715 base = ~base + 1;
2716
2717 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2718 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2719 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2720
2721 if (prefetchable && resources->p_mem_head)
2722 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2723 else {
2724 if (prefetchable)
2725 dbg("using MEM for PMEM\n");
2726 mem_node=get_resource(&(resources->mem_head), (ulong)base);
2727 }
2728
2729 /* allocate the resource to the board */
2730 if (mem_node) {
2731 base = (u32)mem_node->base;
2732 mem_node->next = *res_node;
2733 *res_node = mem_node;
2734 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2735 mem_node->length);
2736 } else {
2737 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2738 return -ENOMEM;
2739 }
2740 break;
2741 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2742 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2743 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2744 temp_register, base);
2745
2746 if (prefetchable && resources->p_mem_head)
2747 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2748 else {
2749 if (prefetchable)
2750 dbg("using MEM for PMEM\n");
2751 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2752 }
2753
2754 /* allocate the resource to the board */
2755 if (mem_node) {
2756 base64 = mem_node->base;
2757 mem_node->next = *res_node;
2758 *res_node = mem_node;
2759 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2760 (u32)base64, mem_node->length);
2761 } else {
2762 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2763 return -ENOMEM;
2764 }
2765 break;
2766 default:
2767 dbg("reserved BAR type=0x%x\n", temp_register);
2768 break;
2769 }
2770
2771 }
2772
2773 if (base64) {
2774 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2775 cloop += 4;
2776 base64 >>= 32;
2777
2778 if (base64) {
2779 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2780 base64 = 0x0L;
2781 }
2782
2783 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2784 } else {
2785 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2786 }
2787 } /* End of base register loop */
2788
2789#if defined(CONFIG_X86_64)
2790 /* Figure out which interrupt pin this function uses */
2791 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
2792
2793 /* If this function needs an interrupt and we are behind a bridge
2794 and the pin is tied to something that's alread mapped,
2795 set this one the same
2796 */
2797 if (temp_byte && resources->irqs &&
2798 (resources->irqs->valid_INT &
2799 (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
2800 /* We have to share with something already set up */
2801 IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
2802 } else {
2803 /* Program IRQ based on card type */
2804 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2805
2806 if (class_code == PCI_BASE_CLASS_STORAGE) {
2807 IRQ = shpchp_disk_irq;
2808 } else {
2809 IRQ = shpchp_nic_irq;
2810 }
2811 }
2812
2813 /* IRQ Line */
2814 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
2815
2816 if (!behind_bridge) {
2817 rc = shpchp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
2818 if (rc)
2819 return(1);
2820 } else {
2821 /* TBD - this code may also belong in the other clause of this If statement */
2822 resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
2823 resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
2824 }
2825#endif
2826 /* Disable ROM base Address */
2827 temp_word = 0x00L;
2828 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
2829
2830 /* Set HP parameters (Cache Line Size, Latency Timer) */
2831 rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2832 if (rc)
2833 return rc;
2834
2835 shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2836
2837 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2838 } /* End of Not-A-Bridge else */
2839 else {
2840 /* It's some strange type of PCI adapter (Cardbus?) */
2841 return(DEVICE_TYPE_NOT_SUPPORTED);
2842 }
2843
2844 func->configured = 1;
2845
2846 return 0;
2847}
2848
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
new file mode 100644
index 000000000000..38c5d9066697
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -0,0 +1,1620 @@
1/*
2 * Standard PCI Hot Plug Driver
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>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/delay.h>
39#include <linux/pci.h>
40#include <asm/system.h>
41#include "shpchp.h"
42
43#ifdef DEBUG
44#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
45#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
46#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
47#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
48#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
49#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
50/* Redefine this flagword to set debug level */
51#define DEBUG_LEVEL DBG_K_STANDARD
52
53#define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
54
55#define DBG_PRINT( dbg_flags, args... ) \
56 do { \
57 if ( DEBUG_LEVEL & ( dbg_flags ) ) \
58 { \
59 int len; \
60 len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
61 __FILE__, __LINE__, __FUNCTION__ ); \
62 sprintf( __dbg_str_buf + len, args ); \
63 printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
64 } \
65 } while (0)
66
67#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
68#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
69#else
70#define DEFINE_DBG_BUFFER
71#define DBG_ENTER_ROUTINE
72#define DBG_LEAVE_ROUTINE
73#endif /* DEBUG */
74
75/* Slot Available Register I field definition */
76#define SLOT_33MHZ 0x0000001f
77#define SLOT_66MHZ_PCIX 0x00001f00
78#define SLOT_100MHZ_PCIX 0x001f0000
79#define SLOT_133MHZ_PCIX 0x1f000000
80
81/* Slot Available Register II field definition */
82#define SLOT_66MHZ 0x0000001f
83#define SLOT_66MHZ_PCIX_266 0x00000f00
84#define SLOT_100MHZ_PCIX_266 0x0000f000
85#define SLOT_133MHZ_PCIX_266 0x000f0000
86#define SLOT_66MHZ_PCIX_533 0x00f00000
87#define SLOT_100MHZ_PCIX_533 0x0f000000
88#define SLOT_133MHZ_PCIX_533 0xf0000000
89
90
91/* Secondary Bus Configuration Register */
92/* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */
93#define PCI_33MHZ 0x0
94#define PCI_66MHZ 0x1
95#define PCIX_66MHZ 0x2
96#define PCIX_100MHZ 0x3
97#define PCIX_133MHZ 0x4
98
99/* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */
100#define PCI_33MHZ 0x0
101#define PCI_66MHZ 0x1
102#define PCIX_66MHZ 0x2
103#define PCIX_100MHZ 0x3
104#define PCIX_133MHZ 0x4
105#define PCIX_66MHZ_ECC 0x5
106#define PCIX_100MHZ_ECC 0x6
107#define PCIX_133MHZ_ECC 0x7
108#define PCIX_66MHZ_266 0x9
109#define PCIX_100MHZ_266 0xa
110#define PCIX_133MHZ_266 0xb
111#define PCIX_66MHZ_533 0x11
112#define PCIX_100MHZ_533 0x12
113#define PCIX_133MHZ_533 0x13
114
115/* Slot Configuration */
116#define SLOT_NUM 0x0000001F
117#define FIRST_DEV_NUM 0x00001F00
118#define PSN 0x07FF0000
119#define UPDOWN 0x20000000
120#define MRLSENSOR 0x40000000
121#define ATTN_BUTTON 0x80000000
122
123/* Slot Status Field Definitions */
124/* Slot State */
125#define PWR_ONLY 0x0001
126#define ENABLED 0x0002
127#define DISABLED 0x0003
128
129/* Power Indicator State */
130#define PWR_LED_ON 0x0004
131#define PWR_LED_BLINK 0x0008
132#define PWR_LED_OFF 0x000c
133
134/* Attention Indicator State */
135#define ATTEN_LED_ON 0x0010
136#define ATTEN_LED_BLINK 0x0020
137#define ATTEN_LED_OFF 0x0030
138
139/* Power Fault */
140#define pwr_fault 0x0040
141
142/* Attention Button */
143#define ATTEN_BUTTON 0x0080
144
145/* MRL Sensor */
146#define MRL_SENSOR 0x0100
147
148/* 66 MHz Capable */
149#define IS_66MHZ_CAP 0x0200
150
151/* PRSNT1#/PRSNT2# */
152#define SLOT_EMP 0x0c00
153
154/* PCI-X Capability */
155#define NON_PCIX 0x0000
156#define PCIX_66 0x1000
157#define PCIX_133 0x3000
158#define PCIX_266 0x4000 /* For PI = 2 only */
159#define PCIX_533 0x5000 /* For PI = 2 only */
160
161/* SHPC 'write' operations/commands */
162
163/* Slot operation - 0x00h to 0x3Fh */
164
165#define NO_CHANGE 0x00
166
167/* Slot state - Bits 0 & 1 of controller command register */
168#define SET_SLOT_PWR 0x01
169#define SET_SLOT_ENABLE 0x02
170#define SET_SLOT_DISABLE 0x03
171
172/* Power indicator state - Bits 2 & 3 of controller command register*/
173#define SET_PWR_ON 0x04
174#define SET_PWR_BLINK 0x08
175#define SET_PWR_OFF 0x0C
176
177/* Attention indicator state - Bits 4 & 5 of controller command register*/
178#define SET_ATTN_ON 0x010
179#define SET_ATTN_BLINK 0x020
180#define SET_ATTN_OFF 0x030
181
182/* Set bus speed/mode A - 0x40h to 0x47h */
183#define SETA_PCI_33MHZ 0x40
184#define SETA_PCI_66MHZ 0x41
185#define SETA_PCIX_66MHZ 0x42
186#define SETA_PCIX_100MHZ 0x43
187#define SETA_PCIX_133MHZ 0x44
188#define RESERV_1 0x45
189#define RESERV_2 0x46
190#define RESERV_3 0x47
191
192/* Set bus speed/mode B - 0x50h to 0x5fh */
193#define SETB_PCI_33MHZ 0x50
194#define SETB_PCI_66MHZ 0x51
195#define SETB_PCIX_66MHZ_PM 0x52
196#define SETB_PCIX_100MHZ_PM 0x53
197#define SETB_PCIX_133MHZ_PM 0x54
198#define SETB_PCIX_66MHZ_EM 0x55
199#define SETB_PCIX_100MHZ_EM 0x56
200#define SETB_PCIX_133MHZ_EM 0x57
201#define SETB_PCIX_66MHZ_266 0x58
202#define SETB_PCIX_100MHZ_266 0x59
203#define SETB_PCIX_133MHZ_266 0x5a
204#define SETB_PCIX_66MHZ_533 0x5b
205#define SETB_PCIX_100MHZ_533 0x5c
206#define SETB_PCIX_133MHZ_533 0x5d
207
208
209/* Power-on all slots - 0x48h */
210#define SET_PWR_ON_ALL 0x48
211
212/* Enable all slots - 0x49h */
213#define SET_ENABLE_ALL 0x49
214
215/* SHPC controller command error code */
216#define SWITCH_OPEN 0x1
217#define INVALID_CMD 0x2
218#define INVALID_SPEED_MODE 0x4
219
220/* For accessing SHPC Working Register Set */
221#define DWORD_SELECT 0x2
222#define DWORD_DATA 0x4
223#define BASE_OFFSET 0x0
224
225/* Field Offset in Logical Slot Register - byte boundary */
226#define SLOT_EVENT_LATCH 0x2
227#define SLOT_SERR_INT_MASK 0x3
228
229static spinlock_t hpc_event_lock;
230
231DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
232static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
233static int ctlr_seq_num = 0; /* Controller sequenc # */
234static spinlock_t list_lock;
235
236static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
237
238static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
239
240/* This is the interrupt polling timeout function. */
241static void int_poll_timeout(unsigned long lphp_ctlr)
242{
243 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
244
245 DBG_ENTER_ROUTINE
246
247 if ( !php_ctlr ) {
248 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
249 return;
250 }
251
252 /* Poll for interrupt events. regs == NULL => polling */
253 shpc_isr( 0, (void *)php_ctlr, NULL );
254
255 init_timer(&php_ctlr->int_poll_timer);
256 if (!shpchp_poll_time)
257 shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
258
259 start_int_poll_timer(php_ctlr, shpchp_poll_time);
260
261 return;
262}
263
264/* This function starts the interrupt polling timer. */
265static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
266{
267 if (!php_ctlr) {
268 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
269 return;
270 }
271
272 if ( ( seconds <= 0 ) || ( seconds > 60 ) )
273 seconds = 2; /* Clamp to sane value */
274
275 php_ctlr->int_poll_timer.function = &int_poll_timeout;
276 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */
277 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
278 add_timer(&php_ctlr->int_poll_timer);
279
280 return;
281}
282
283static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
284{
285 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
286 u16 cmd_status;
287 int retval = 0;
288 u16 temp_word;
289 int i;
290
291 DBG_ENTER_ROUTINE
292
293 if (!php_ctlr) {
294 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
295 return -1;
296 }
297
298 for (i = 0; i < 10; i++) {
299 cmd_status = readw(php_ctlr->creg + CMD_STATUS);
300
301 if (!(cmd_status & 0x1))
302 break;
303 /* Check every 0.1 sec for a total of 1 sec*/
304 msleep(100);
305 }
306
307 cmd_status = readw(php_ctlr->creg + CMD_STATUS);
308
309 if (cmd_status & 0x1) {
310 /* After 1 sec and and the controller is still busy */
311 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
312 return -1;
313 }
314
315 ++t_slot;
316 temp_word = (t_slot << 8) | (cmd & 0xFF);
317 dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd);
318
319 /* To make sure the Controller Busy bit is 0 before we send out the
320 * command.
321 */
322 writew(temp_word, php_ctlr->creg + CMD);
323 dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word);
324
325 DBG_LEAVE_ROUTINE
326 return retval;
327}
328
329static int hpc_check_cmd_status(struct controller *ctrl)
330{
331 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
332 u16 cmd_status;
333 int retval = 0;
334
335 DBG_ENTER_ROUTINE
336
337 if (!ctrl->hpc_ctlr_handle) {
338 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
339 return -1;
340 }
341
342 cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F;
343
344 switch (cmd_status >> 1) {
345 case 0:
346 retval = 0;
347 break;
348 case 1:
349 retval = SWITCH_OPEN;
350 err("%s: Switch opened!\n", __FUNCTION__);
351 break;
352 case 2:
353 retval = INVALID_CMD;
354 err("%s: Invalid HPC command!\n", __FUNCTION__);
355 break;
356 case 4:
357 retval = INVALID_SPEED_MODE;
358 err("%s: Invalid bus speed/mode!\n", __FUNCTION__);
359 break;
360 default:
361 retval = cmd_status;
362 }
363
364 DBG_LEAVE_ROUTINE
365 return retval;
366}
367
368
369static int hpc_get_attention_status(struct slot *slot, u8 *status)
370{
371 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
372 u32 slot_reg;
373 u16 slot_status;
374 u8 atten_led_state;
375
376 DBG_ENTER_ROUTINE
377
378 if (!slot->ctrl->hpc_ctlr_handle) {
379 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
380 return -1;
381 }
382
383 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
384 slot_status = (u16) slot_reg;
385 atten_led_state = (slot_status & 0x0030) >> 4;
386
387 switch (atten_led_state) {
388 case 0:
389 *status = 0xFF; /* Reserved */
390 break;
391 case 1:
392 *status = 1; /* On */
393 break;
394 case 2:
395 *status = 2; /* Blink */
396 break;
397 case 3:
398 *status = 0; /* Off */
399 break;
400 default:
401 *status = 0xFF;
402 break;
403 }
404
405 DBG_LEAVE_ROUTINE
406 return 0;
407}
408
409static int hpc_get_power_status(struct slot * slot, u8 *status)
410{
411 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
412 u32 slot_reg;
413 u16 slot_status;
414 u8 slot_state;
415 int retval = 0;
416
417 DBG_ENTER_ROUTINE
418
419 if (!slot->ctrl->hpc_ctlr_handle) {
420 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
421 return -1;
422 }
423
424 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
425 slot_status = (u16) slot_reg;
426 slot_state = (slot_status & 0x0003);
427
428 switch (slot_state) {
429 case 0:
430 *status = 0xFF;
431 break;
432 case 1:
433 *status = 2; /* Powered only */
434 break;
435 case 2:
436 *status = 1; /* Enabled */
437 break;
438 case 3:
439 *status = 0; /* Disabled */
440 break;
441 default:
442 *status = 0xFF;
443 break;
444 }
445
446 DBG_LEAVE_ROUTINE
447 return retval;
448}
449
450
451static int hpc_get_latch_status(struct slot *slot, u8 *status)
452{
453 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
454 u32 slot_reg;
455 u16 slot_status;
456
457 DBG_ENTER_ROUTINE
458
459 if (!slot->ctrl->hpc_ctlr_handle) {
460 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
461 return -1;
462 }
463
464 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
465 slot_status = (u16)slot_reg;
466
467 *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */
468
469
470 DBG_LEAVE_ROUTINE
471 return 0;
472}
473
474static int hpc_get_adapter_status(struct slot *slot, u8 *status)
475{
476 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
477 u32 slot_reg;
478 u16 slot_status;
479 u8 card_state;
480
481 DBG_ENTER_ROUTINE
482
483 if (!slot->ctrl->hpc_ctlr_handle) {
484 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
485 return -1;
486 }
487
488 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
489 slot_status = (u16)slot_reg;
490 card_state = (u8)((slot_status & 0x0C00) >> 10);
491 *status = (card_state != 0x3) ? 1 : 0;
492
493 DBG_LEAVE_ROUTINE
494 return 0;
495}
496
497static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
498{
499 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
500
501 DBG_ENTER_ROUTINE
502
503 if (!slot->ctrl->hpc_ctlr_handle) {
504 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
505 return -1;
506 }
507
508 *prog_int = readb(php_ctlr->creg + PROG_INTERFACE);
509
510 DBG_LEAVE_ROUTINE
511 return 0;
512}
513
514static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
515{
516 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
517 u32 slot_reg;
518 u16 slot_status, sec_bus_status;
519 u8 m66_cap, pcix_cap, pi;
520 int retval = 0;
521
522 DBG_ENTER_ROUTINE
523
524 if (!slot->ctrl->hpc_ctlr_handle) {
525 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
526 return -1;
527 }
528
529 if (slot->hp_slot >= php_ctlr->num_slots) {
530 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
531 return -1;
532 }
533
534 pi = readb(php_ctlr->creg + PROG_INTERFACE);
535 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
536 dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg);
537 slot_status = (u16) slot_reg;
538 dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status);
539 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
540
541 pcix_cap = (u8) ((slot_status & 0x3000) >> 12);
542 dbg("%s: pcix_cap = %x\n", __FUNCTION__, pcix_cap);
543 m66_cap = (u8) ((slot_status & 0x0200) >> 9);
544 dbg("%s: m66_cap = %x\n", __FUNCTION__, m66_cap);
545
546
547 if (pi == 2) {
548 switch (pcix_cap) {
549 case 0:
550 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
551 break;
552 case 1:
553 *value = PCI_SPEED_66MHz_PCIX;
554 break;
555 case 3:
556 *value = PCI_SPEED_133MHz_PCIX;
557 break;
558 case 4:
559 *value = PCI_SPEED_133MHz_PCIX_266;
560 break;
561 case 5:
562 *value = PCI_SPEED_133MHz_PCIX_533;
563 break;
564 case 2: /* Reserved */
565 default:
566 *value = PCI_SPEED_UNKNOWN;
567 retval = -ENODEV;
568 break;
569 }
570 } else {
571 switch (pcix_cap) {
572 case 0:
573 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
574 break;
575 case 1:
576 *value = PCI_SPEED_66MHz_PCIX;
577 break;
578 case 3:
579 *value = PCI_SPEED_133MHz_PCIX;
580 break;
581 case 2: /* Reserved */
582 default:
583 *value = PCI_SPEED_UNKNOWN;
584 retval = -ENODEV;
585 break;
586 }
587 }
588
589 dbg("Adapter speed = %d\n", *value);
590
591 DBG_LEAVE_ROUTINE
592 return retval;
593}
594
595static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
596{
597 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
598 u16 sec_bus_status;
599 u8 pi;
600 int retval = 0;
601
602 DBG_ENTER_ROUTINE
603
604 if (!slot->ctrl->hpc_ctlr_handle) {
605 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
606 return -1;
607 }
608
609 pi = readb(php_ctlr->creg + PROG_INTERFACE);
610 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
611
612 if (pi == 2) {
613 *mode = (sec_bus_status & 0x0100) >> 7;
614 } else {
615 retval = -1;
616 }
617
618 dbg("Mode 1 ECC cap = %d\n", *mode);
619
620 DBG_LEAVE_ROUTINE
621 return retval;
622}
623
624static int hpc_query_power_fault(struct slot * slot)
625{
626 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
627 u32 slot_reg;
628 u16 slot_status;
629 u8 pwr_fault_state, status;
630
631 DBG_ENTER_ROUTINE
632
633 if (!slot->ctrl->hpc_ctlr_handle) {
634 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
635 return -1;
636 }
637
638 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
639 slot_status = (u16) slot_reg;
640 pwr_fault_state = (slot_status & 0x0040) >> 7;
641 status = (pwr_fault_state == 1) ? 0 : 1;
642
643 DBG_LEAVE_ROUTINE
644 /* Note: Logic 0 => fault */
645 return status;
646}
647
648static int hpc_set_attention_status(struct slot *slot, u8 value)
649{
650 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
651 u8 slot_cmd = 0;
652 int rc = 0;
653
654 if (!slot->ctrl->hpc_ctlr_handle) {
655 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
656 return -1;
657 }
658
659 if (slot->hp_slot >= php_ctlr->num_slots) {
660 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
661 return -1;
662 }
663
664 switch (value) {
665 case 0 :
666 slot_cmd = 0x30; /* OFF */
667 break;
668 case 1:
669 slot_cmd = 0x10; /* ON */
670 break;
671 case 2:
672 slot_cmd = 0x20; /* BLINK */
673 break;
674 default:
675 return -1;
676 }
677
678 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
679
680 return rc;
681}
682
683
684static void hpc_set_green_led_on(struct slot *slot)
685{
686 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
687 u8 slot_cmd;
688
689 if (!slot->ctrl->hpc_ctlr_handle) {
690 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
691 return ;
692 }
693
694 if (slot->hp_slot >= php_ctlr->num_slots) {
695 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
696 return ;
697 }
698
699 slot_cmd = 0x04;
700
701 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
702
703 return;
704}
705
706static void hpc_set_green_led_off(struct slot *slot)
707{
708 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
709 u8 slot_cmd;
710
711 if (!slot->ctrl->hpc_ctlr_handle) {
712 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
713 return ;
714 }
715
716 if (slot->hp_slot >= php_ctlr->num_slots) {
717 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
718 return ;
719 }
720
721 slot_cmd = 0x0C;
722
723 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
724
725 return;
726}
727
728static void hpc_set_green_led_blink(struct slot *slot)
729{
730 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
731 u8 slot_cmd;
732
733 if (!slot->ctrl->hpc_ctlr_handle) {
734 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
735 return ;
736 }
737
738 if (slot->hp_slot >= php_ctlr->num_slots) {
739 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
740 return ;
741 }
742
743 slot_cmd = 0x08;
744
745 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
746
747 return;
748}
749
750int shpc_get_ctlr_slot_config(struct controller *ctrl,
751 int *num_ctlr_slots, /* number of slots in this HPC */
752 int *first_device_num, /* PCI dev num of the first slot in this SHPC */
753 int *physical_slot_num, /* phy slot num of the first slot in this SHPC */
754 int *updown, /* physical_slot_num increament: 1 or -1 */
755 int *flags)
756{
757 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
758
759 DBG_ENTER_ROUTINE
760
761 if (!ctrl->hpc_ctlr_handle) {
762 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
763 return -1;
764 }
765
766 *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */
767 *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */
768
769 *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16;
770 dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
771 *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1;
772
773 DBG_LEAVE_ROUTINE
774 return 0;
775}
776
777static void hpc_release_ctlr(struct controller *ctrl)
778{
779 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
780 struct php_ctlr_state_s *p, *p_prev;
781
782 DBG_ENTER_ROUTINE
783
784 if (!ctrl->hpc_ctlr_handle) {
785 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
786 return ;
787 }
788
789 if (shpchp_poll_mode) {
790 del_timer(&php_ctlr->int_poll_timer);
791 } else {
792 if (php_ctlr->irq) {
793 free_irq(php_ctlr->irq, ctrl);
794 php_ctlr->irq = 0;
795 pci_disable_msi(php_ctlr->pci_dev);
796 }
797 }
798 if (php_ctlr->pci_dev) {
799 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
800 iounmap(php_ctlr->creg);
801 release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
802 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
803 php_ctlr->pci_dev = NULL;
804 }
805
806 spin_lock(&list_lock);
807 p = php_ctlr_list_head;
808 p_prev = NULL;
809 while (p) {
810 if (p == php_ctlr) {
811 if (p_prev)
812 p_prev->pnext = p->pnext;
813 else
814 php_ctlr_list_head = p->pnext;
815 break;
816 } else {
817 p_prev = p;
818 p = p->pnext;
819 }
820 }
821 spin_unlock(&list_lock);
822
823 kfree(php_ctlr);
824
825DBG_LEAVE_ROUTINE
826
827}
828
829static int hpc_power_on_slot(struct slot * slot)
830{
831 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
832 u8 slot_cmd;
833 int retval = 0;
834
835 DBG_ENTER_ROUTINE
836
837 if (!slot->ctrl->hpc_ctlr_handle) {
838 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
839 return -1;
840 }
841
842 if (slot->hp_slot >= php_ctlr->num_slots) {
843 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
844 return -1;
845 }
846 slot_cmd = 0x01;
847
848 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
849
850 if (retval) {
851 err("%s: Write command failed!\n", __FUNCTION__);
852 return -1;
853 }
854
855 DBG_LEAVE_ROUTINE
856
857 return retval;
858}
859
860static int hpc_slot_enable(struct slot * slot)
861{
862 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
863 u8 slot_cmd;
864 int retval = 0;
865
866 DBG_ENTER_ROUTINE
867
868 if (!slot->ctrl->hpc_ctlr_handle) {
869 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
870 return -1;
871 }
872
873 if (slot->hp_slot >= php_ctlr->num_slots) {
874 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
875 return -1;
876 }
877 /* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
878 slot_cmd = 0x3A;
879
880 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
881
882 if (retval) {
883 err("%s: Write command failed!\n", __FUNCTION__);
884 return -1;
885 }
886
887 DBG_LEAVE_ROUTINE
888 return retval;
889}
890
891static int hpc_slot_disable(struct slot * slot)
892{
893 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
894 u8 slot_cmd;
895 int retval = 0;
896
897 DBG_ENTER_ROUTINE
898
899 if (!slot->ctrl->hpc_ctlr_handle) {
900 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
901 return -1;
902 }
903
904 if (slot->hp_slot >= php_ctlr->num_slots) {
905 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
906 return -1;
907 }
908
909 /* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */
910 slot_cmd = 0x1F;
911
912 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
913
914 if (retval) {
915 err("%s: Write command failed!\n", __FUNCTION__);
916 return -1;
917 }
918
919 DBG_LEAVE_ROUTINE
920 return retval;
921}
922
923static int hpc_enable_all_slots( struct slot *slot )
924{
925 int retval = 0;
926
927 DBG_ENTER_ROUTINE
928
929 if (!slot->ctrl->hpc_ctlr_handle) {
930 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
931 return -1;
932 }
933
934 retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL);
935 if (retval) {
936 err("%s: Write command failed!\n", __FUNCTION__);
937 return -1;
938 }
939
940 DBG_LEAVE_ROUTINE
941
942 return retval;
943}
944
945static int hpc_pwr_on_all_slots(struct slot *slot)
946{
947 int retval = 0;
948
949 DBG_ENTER_ROUTINE
950
951 retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL);
952
953 if (retval) {
954 err("%s: Write command failed!\n", __FUNCTION__);
955 return -1;
956 }
957
958 DBG_LEAVE_ROUTINE
959 return retval;
960}
961
962static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
963{
964 u8 slot_cmd;
965 u8 pi;
966 int retval = 0;
967 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
968
969 DBG_ENTER_ROUTINE
970
971 if (!slot->ctrl->hpc_ctlr_handle) {
972 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
973 return -1;
974 }
975
976 pi = readb(php_ctlr->creg + PROG_INTERFACE);
977
978 if (pi == 1) {
979 switch (value) {
980 case 0:
981 slot_cmd = SETA_PCI_33MHZ;
982 break;
983 case 1:
984 slot_cmd = SETA_PCI_66MHZ;
985 break;
986 case 2:
987 slot_cmd = SETA_PCIX_66MHZ;
988 break;
989 case 3:
990 slot_cmd = SETA_PCIX_100MHZ;
991 break;
992 case 4:
993 slot_cmd = SETA_PCIX_133MHZ;
994 break;
995 default:
996 slot_cmd = PCI_SPEED_UNKNOWN;
997 retval = -ENODEV;
998 return retval;
999 }
1000 } else {
1001 switch (value) {
1002 case 0:
1003 slot_cmd = SETB_PCI_33MHZ;
1004 break;
1005 case 1:
1006 slot_cmd = SETB_PCI_66MHZ;
1007 break;
1008 case 2:
1009 slot_cmd = SETB_PCIX_66MHZ_PM;
1010 break;
1011 case 3:
1012 slot_cmd = SETB_PCIX_100MHZ_PM;
1013 break;
1014 case 4:
1015 slot_cmd = SETB_PCIX_133MHZ_PM;
1016 break;
1017 case 5:
1018 slot_cmd = SETB_PCIX_66MHZ_EM;
1019 break;
1020 case 6:
1021 slot_cmd = SETB_PCIX_100MHZ_EM;
1022 break;
1023 case 7:
1024 slot_cmd = SETB_PCIX_133MHZ_EM;
1025 break;
1026 case 8:
1027 slot_cmd = SETB_PCIX_66MHZ_266;
1028 break;
1029 case 0x9:
1030 slot_cmd = SETB_PCIX_100MHZ_266;
1031 break;
1032 case 0xa:
1033 slot_cmd = SETB_PCIX_133MHZ_266;
1034 break;
1035 case 0xb:
1036 slot_cmd = SETB_PCIX_66MHZ_533;
1037 break;
1038 case 0xc:
1039 slot_cmd = SETB_PCIX_100MHZ_533;
1040 break;
1041 case 0xd:
1042 slot_cmd = SETB_PCIX_133MHZ_533;
1043 break;
1044 default:
1045 slot_cmd = PCI_SPEED_UNKNOWN;
1046 retval = -ENODEV;
1047 return retval;
1048 }
1049
1050 }
1051 retval = shpc_write_cmd(slot, 0, slot_cmd);
1052 if (retval) {
1053 err("%s: Write command failed!\n", __FUNCTION__);
1054 return -1;
1055 }
1056
1057 DBG_LEAVE_ROUTINE
1058 return retval;
1059}
1060
1061static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1062{
1063 struct controller *ctrl = NULL;
1064 struct php_ctlr_state_s *php_ctlr;
1065 u8 schedule_flag = 0;
1066 u8 temp_byte;
1067 u32 temp_dword, intr_loc, intr_loc2;
1068 int hp_slot;
1069
1070 if (!dev_id)
1071 return IRQ_NONE;
1072
1073 if (!shpchp_poll_mode) {
1074 ctrl = (struct controller *)dev_id;
1075 php_ctlr = ctrl->hpc_ctlr_handle;
1076 } else {
1077 php_ctlr = (struct php_ctlr_state_s *) dev_id;
1078 ctrl = (struct controller *)php_ctlr->callback_instance_id;
1079 }
1080
1081 if (!ctrl)
1082 return IRQ_NONE;
1083
1084 if (!php_ctlr || !php_ctlr->creg)
1085 return IRQ_NONE;
1086
1087 /* Check to see if it was our interrupt */
1088 intr_loc = readl(php_ctlr->creg + INTR_LOC);
1089
1090 if (!intr_loc)
1091 return IRQ_NONE;
1092 dbg("%s: shpc_isr proceeds\n", __FUNCTION__);
1093 dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
1094
1095 if(!shpchp_poll_mode) {
1096 /* Mask Global Interrupt Mask - see implementation note on p. 139 */
1097 /* of SHPC spec rev 1.0*/
1098 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1099 dbg("%s: Before masking global interrupt, temp_dword = %x\n",
1100 __FUNCTION__, temp_dword);
1101 temp_dword |= 0x00000001;
1102 dbg("%s: After masking global interrupt, temp_dword = %x\n",
1103 __FUNCTION__, temp_dword);
1104 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1105
1106 intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1107 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1108 }
1109
1110 if (intr_loc & 0x0001) {
1111 /*
1112 * Command Complete Interrupt Pending
1113 * RO only - clear by writing 0 to the Command Completion
1114 * Detect bit in Controller SERR-INT register
1115 */
1116 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1117 dbg("%s: Before clearing CCIP, temp_dword = %x\n",
1118 __FUNCTION__, temp_dword);
1119 temp_dword &= 0xfffeffff;
1120 dbg("%s: After clearing CCIP, temp_dword = %x\n",
1121 __FUNCTION__, temp_dword);
1122 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1123 wake_up_interruptible(&ctrl->queue);
1124 }
1125
1126 if ((intr_loc = (intr_loc >> 1)) == 0) {
1127 /* Unmask Global Interrupt Mask */
1128 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1129 dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n",
1130 __FUNCTION__, temp_dword);
1131 temp_dword &= 0xfffffffe;
1132 dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n",
1133 __FUNCTION__, temp_dword);
1134 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1135
1136 return IRQ_NONE;
1137 }
1138
1139 for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
1140 /* To find out which slot has interrupt pending */
1141 if ((intr_loc >> hp_slot) & 0x01) {
1142 temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot));
1143 dbg("%s: Slot %x with intr, temp_dword = %x\n",
1144 __FUNCTION__, hp_slot, temp_dword);
1145 temp_byte = (temp_dword >> 16) & 0xFF;
1146 dbg("%s: Slot with intr, temp_byte = %x\n",
1147 __FUNCTION__, temp_byte);
1148 if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08))
1149 schedule_flag += php_ctlr->switch_change_callback(
1150 hp_slot, php_ctlr->callback_instance_id);
1151 if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04))
1152 schedule_flag += php_ctlr->attention_button_callback(
1153 hp_slot, php_ctlr->callback_instance_id);
1154 if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01))
1155 schedule_flag += php_ctlr->presence_change_callback(
1156 hp_slot , php_ctlr->callback_instance_id);
1157 if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12))
1158 schedule_flag += php_ctlr->power_fault_callback(
1159 hp_slot, php_ctlr->callback_instance_id);
1160
1161 /* Clear all slot events */
1162 temp_dword = 0xe01f3fff;
1163 dbg("%s: Clearing slot events, temp_dword = %x\n",
1164 __FUNCTION__, temp_dword);
1165 writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1166
1167 intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1168 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1169 }
1170 }
1171 if (!shpchp_poll_mode) {
1172 /* Unmask Global Interrupt Mask */
1173 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1174 dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n",
1175 __FUNCTION__, temp_dword);
1176 temp_dword &= 0xfffffffe;
1177 dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n",
1178 __FUNCTION__, temp_dword);
1179 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1180 }
1181
1182 return IRQ_HANDLED;
1183}
1184
1185static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1186{
1187 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1188 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1189 int retval = 0;
1190 u8 pi;
1191 u32 slot_avail1, slot_avail2;
1192 int slot_num;
1193
1194 DBG_ENTER_ROUTINE
1195
1196 if (!slot->ctrl->hpc_ctlr_handle) {
1197 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1198 return -1;
1199 }
1200
1201 if (slot->hp_slot >= php_ctlr->num_slots) {
1202 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1203 return -1;
1204 }
1205
1206 pi = readb(php_ctlr->creg + PROG_INTERFACE);
1207 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1);
1208 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
1209
1210 if (pi == 2) {
1211 if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27) ) != 0 )
1212 bus_speed = PCIX_133MHZ_533;
1213 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23) ) != 0 )
1214 bus_speed = PCIX_100MHZ_533;
1215 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19) ) != 0 )
1216 bus_speed = PCIX_66MHZ_533;
1217 else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15) ) != 0 )
1218 bus_speed = PCIX_133MHZ_266;
1219 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11) ) != 0 )
1220 bus_speed = PCIX_100MHZ_266;
1221 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7) ) != 0 )
1222 bus_speed = PCIX_66MHZ_266;
1223 else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
1224 bus_speed = PCIX_133MHZ;
1225 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
1226 bus_speed = PCIX_100MHZ;
1227 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
1228 bus_speed = PCIX_66MHZ;
1229 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1230 bus_speed = PCI_66MHZ;
1231 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1232 bus_speed = PCI_33MHZ;
1233 else bus_speed = PCI_SPEED_UNKNOWN;
1234 } else {
1235 if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
1236 bus_speed = PCIX_133MHZ;
1237 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
1238 bus_speed = PCIX_100MHZ;
1239 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
1240 bus_speed = PCIX_66MHZ;
1241 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1242 bus_speed = PCI_66MHZ;
1243 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1244 bus_speed = PCI_33MHZ;
1245 else bus_speed = PCI_SPEED_UNKNOWN;
1246 }
1247
1248 *value = bus_speed;
1249 dbg("Max bus speed = %d\n", bus_speed);
1250 DBG_LEAVE_ROUTINE
1251 return retval;
1252}
1253
1254static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1255{
1256 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1257 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1258 u16 sec_bus_status;
1259 int retval = 0;
1260 u8 pi;
1261
1262 DBG_ENTER_ROUTINE
1263
1264 if (!slot->ctrl->hpc_ctlr_handle) {
1265 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1266 return -1;
1267 }
1268
1269 if (slot->hp_slot >= php_ctlr->num_slots) {
1270 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1271 return -1;
1272 }
1273
1274 pi = readb(php_ctlr->creg + PROG_INTERFACE);
1275 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
1276
1277 if (pi == 2) {
1278 switch (sec_bus_status & 0x000f) {
1279 case 0:
1280 bus_speed = PCI_SPEED_33MHz;
1281 break;
1282 case 1:
1283 bus_speed = PCI_SPEED_66MHz;
1284 break;
1285 case 2:
1286 bus_speed = PCI_SPEED_66MHz_PCIX;
1287 break;
1288 case 3:
1289 bus_speed = PCI_SPEED_100MHz_PCIX;
1290 break;
1291 case 4:
1292 bus_speed = PCI_SPEED_133MHz_PCIX;
1293 break;
1294 case 5:
1295 bus_speed = PCI_SPEED_66MHz_PCIX_ECC;
1296 break;
1297 case 6:
1298 bus_speed = PCI_SPEED_100MHz_PCIX_ECC;
1299 break;
1300 case 7:
1301 bus_speed = PCI_SPEED_133MHz_PCIX_ECC;
1302 break;
1303 case 8:
1304 bus_speed = PCI_SPEED_66MHz_PCIX_266;
1305 break;
1306 case 9:
1307 bus_speed = PCI_SPEED_100MHz_PCIX_266;
1308 break;
1309 case 0xa:
1310 bus_speed = PCI_SPEED_133MHz_PCIX_266;
1311 break;
1312 case 0xb:
1313 bus_speed = PCI_SPEED_66MHz_PCIX_533;
1314 break;
1315 case 0xc:
1316 bus_speed = PCI_SPEED_100MHz_PCIX_533;
1317 break;
1318 case 0xd:
1319 bus_speed = PCI_SPEED_133MHz_PCIX_533;
1320 break;
1321 case 0xe:
1322 case 0xf:
1323 default:
1324 bus_speed = PCI_SPEED_UNKNOWN;
1325 break;
1326 }
1327 } else {
1328 /* In the case where pi is undefined, default it to 1 */
1329 switch (sec_bus_status & 0x0007) {
1330 case 0:
1331 bus_speed = PCI_SPEED_33MHz;
1332 break;
1333 case 1:
1334 bus_speed = PCI_SPEED_66MHz;
1335 break;
1336 case 2:
1337 bus_speed = PCI_SPEED_66MHz_PCIX;
1338 break;
1339 case 3:
1340 bus_speed = PCI_SPEED_100MHz_PCIX;
1341 break;
1342 case 4:
1343 bus_speed = PCI_SPEED_133MHz_PCIX;
1344 break;
1345 case 5:
1346 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1347 break;
1348 case 6:
1349 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1350 break;
1351 case 7:
1352 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1353 break;
1354 default:
1355 bus_speed = PCI_SPEED_UNKNOWN;
1356 break;
1357 }
1358 }
1359
1360 *value = bus_speed;
1361 dbg("Current bus speed = %d\n", bus_speed);
1362 DBG_LEAVE_ROUTINE
1363 return retval;
1364}
1365
1366static struct hpc_ops shpchp_hpc_ops = {
1367 .power_on_slot = hpc_power_on_slot,
1368 .slot_enable = hpc_slot_enable,
1369 .slot_disable = hpc_slot_disable,
1370 .enable_all_slots = hpc_enable_all_slots,
1371 .pwr_on_all_slots = hpc_pwr_on_all_slots,
1372 .set_bus_speed_mode = hpc_set_bus_speed_mode,
1373 .set_attention_status = hpc_set_attention_status,
1374 .get_power_status = hpc_get_power_status,
1375 .get_attention_status = hpc_get_attention_status,
1376 .get_latch_status = hpc_get_latch_status,
1377 .get_adapter_status = hpc_get_adapter_status,
1378
1379 .get_max_bus_speed = hpc_get_max_bus_speed,
1380 .get_cur_bus_speed = hpc_get_cur_bus_speed,
1381 .get_adapter_speed = hpc_get_adapter_speed,
1382 .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap,
1383 .get_prog_int = hpc_get_prog_int,
1384
1385 .query_power_fault = hpc_query_power_fault,
1386 .green_led_on = hpc_set_green_led_on,
1387 .green_led_off = hpc_set_green_led_off,
1388 .green_led_blink = hpc_set_green_led_blink,
1389
1390 .release_ctlr = hpc_release_ctlr,
1391 .check_cmd_status = hpc_check_cmd_status,
1392};
1393
1394int shpc_init(struct controller * ctrl,
1395 struct pci_dev * pdev,
1396 php_intr_callback_t attention_button_callback,
1397 php_intr_callback_t switch_change_callback,
1398 php_intr_callback_t presence_change_callback,
1399 php_intr_callback_t power_fault_callback)
1400{
1401 struct php_ctlr_state_s *php_ctlr, *p;
1402 void *instance_id = ctrl;
1403 int rc;
1404 u8 hp_slot;
1405 static int first = 1;
1406 u32 shpc_cap_offset, shpc_base_offset;
1407 u32 tempdword, slot_reg;
1408 u16 vendor_id, device_id;
1409 u8 i;
1410
1411 DBG_ENTER_ROUTINE
1412
1413 spin_lock_init(&list_lock);
1414 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
1415
1416 if (!php_ctlr) { /* allocate controller state data */
1417 err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
1418 goto abort;
1419 }
1420
1421 memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
1422
1423 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1424
1425 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
1426 dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id);
1427 if (rc) {
1428 err("%s: unable to read PCI configuration data\n", __FUNCTION__);
1429 goto abort_free_ctlr;
1430 }
1431
1432 rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);
1433 dbg("%s: Device ID: %x\n",__FUNCTION__, device_id);
1434 if (rc) {
1435 err("%s: unable to read PCI configuration data\n", __FUNCTION__);
1436 goto abort_free_ctlr;
1437 }
1438
1439 if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) {
1440 shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */
1441 } else {
1442 if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
1443 err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
1444 goto abort_free_ctlr;
1445 }
1446 dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);
1447
1448 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
1449 if (rc) {
1450 err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1451 goto abort_free_ctlr;
1452 }
1453
1454 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset);
1455 if (rc) {
1456 err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1457 goto abort_free_ctlr;
1458 }
1459
1460 for (i = 0; i <= 14; i++) {
1461 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , i);
1462 if (rc) {
1463 err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1464 goto abort_free_ctlr;
1465 }
1466
1467 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword);
1468 if (rc) {
1469 err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1470 goto abort_free_ctlr;
1471 }
1472 dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword);
1473 }
1474 }
1475
1476 if (first) {
1477 spin_lock_init(&hpc_event_lock);
1478 first = 0;
1479 }
1480
1481 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn),
1482 PCI_FUNC(pdev->devfn), pdev->irq);
1483 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1484 if (pci_resource_len(pdev, rc) > 0)
1485 dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc,
1486 pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset);
1487
1488 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
1489 pdev->subsystem_device);
1490
1491 if (pci_enable_device(pdev))
1492 goto abort_free_ctlr;
1493
1494 if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) {
1495 err("%s: cannot reserve MMIO region\n", __FUNCTION__);
1496 goto abort_free_ctlr;
1497 }
1498
1499 php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1500 if (!php_ctlr->creg) {
1501 err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0),
1502 pci_resource_start(pdev, 0) + shpc_base_offset);
1503 release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1504 goto abort_free_ctlr;
1505 }
1506 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
1507 dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0));
1508
1509 init_MUTEX(&ctrl->crit_sect);
1510 /* Setup wait queue */
1511 init_waitqueue_head(&ctrl->queue);
1512
1513 /* Find the IRQ */
1514 php_ctlr->irq = pdev->irq;
1515 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1516
1517 /* Save interrupt callback info */
1518 php_ctlr->attention_button_callback = attention_button_callback;
1519 php_ctlr->switch_change_callback = switch_change_callback;
1520 php_ctlr->presence_change_callback = presence_change_callback;
1521 php_ctlr->power_fault_callback = power_fault_callback;
1522 php_ctlr->callback_instance_id = instance_id;
1523
1524 /* Return PCI Controller Info */
1525 php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8;
1526 php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM;
1527 dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
1528 dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
1529
1530 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
1531 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1532 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1533 tempdword = 0x0003000f;
1534 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1535 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1536 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1537
1538 /* Mask the MRL sensor SERR Mask of individual slot in
1539 * Slot SERR-INT Mask & clear all the existing event if any
1540 */
1541 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1542 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1543 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1544 hp_slot, slot_reg);
1545 tempdword = 0xffff3fff;
1546 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1547 }
1548
1549 if (shpchp_poll_mode) {/* Install interrupt polling code */
1550 /* Install and start the interrupt polling timer */
1551 init_timer(&php_ctlr->int_poll_timer);
1552 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
1553 } else {
1554 /* Installs the interrupt handler */
1555 rc = pci_enable_msi(pdev);
1556 if (rc) {
1557 info("Can't get msi for the hotplug controller\n");
1558 info("Use INTx for the hotplug controller\n");
1559 dbg("%s: rc = %x\n", __FUNCTION__, rc);
1560 } else
1561 php_ctlr->irq = pdev->irq;
1562
1563 rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
1564 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1565 if (rc) {
1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1567 goto abort_free_ctlr;
1568 }
1569 /* Execute OSHP method here */
1570 }
1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
1572
1573 /* Add this HPC instance into the HPC list */
1574 spin_lock(&list_lock);
1575 if (php_ctlr_list_head == 0) {
1576 php_ctlr_list_head = php_ctlr;
1577 p = php_ctlr_list_head;
1578 p->pnext = NULL;
1579 } else {
1580 p = php_ctlr_list_head;
1581
1582 while (p->pnext)
1583 p = p->pnext;
1584
1585 p->pnext = php_ctlr;
1586 }
1587 spin_unlock(&list_lock);
1588
1589
1590 ctlr_seq_num++;
1591 ctrl->hpc_ctlr_handle = php_ctlr;
1592 ctrl->hpc_ops = &shpchp_hpc_ops;
1593
1594 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1595 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1596 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1597 hp_slot, slot_reg);
1598 tempdword = 0xe01f3fff;
1599 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1600 }
1601 if (!shpchp_poll_mode) {
1602 /* Unmask all general input interrupts and SERR */
1603 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1604 tempdword = 0x0000000a;
1605 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1606 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1607 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1608 }
1609
1610 dbg("%s: Leaving shpc_init\n", __FUNCTION__);
1611 DBG_LEAVE_ROUTINE
1612 return 0;
1613
1614 /* We end up here for the many possible ways to fail this API. */
1615abort_free_ctlr:
1616 kfree(php_ctlr);
1617abort:
1618 DBG_LEAVE_ROUTINE
1619 return -1;
1620}
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
new file mode 100644
index 000000000000..90113e9cd69b
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -0,0 +1,810 @@
1/*
2 * Standard Hot Plug Controller Driver
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include "../pci.h"
39#include "shpchp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43
44int shpchp_configure_device (struct controller* ctrl, struct pci_func* func)
45{
46 unsigned char bus;
47 struct pci_bus *child;
48 int num;
49
50 if (func->pci_dev == NULL)
51 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
52
53 /* Still NULL ? Well then scan for it ! */
54 if (func->pci_dev == NULL) {
55 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
56 if (num) {
57 dbg("%s: subordiante %p number %x\n", __FUNCTION__, ctrl->pci_dev->subordinate,
58 ctrl->pci_dev->subordinate->number);
59 pci_bus_add_devices(ctrl->pci_dev->subordinate);
60 }
61
62 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
63 if (func->pci_dev == NULL) {
64 dbg("ERROR: pci_dev still null\n");
65 return 0;
66 }
67 }
68
69 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
70 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
71 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
72 pci_do_scan_bus(child);
73
74 }
75
76 return 0;
77}
78
79
80int shpchp_unconfigure_device(struct pci_func* func)
81{
82 int rc = 0;
83 int j;
84
85 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
86 func->device, func->function);
87
88 for (j=0; j<8 ; j++) {
89 struct pci_dev* temp = pci_find_slot(func->bus,
90 (func->device << 3) | j);
91 if (temp) {
92 pci_remove_bus_device(temp);
93 }
94 }
95 return rc;
96}
97
98/*
99 * shpchp_set_irq
100 *
101 * @bus_num: bus number of PCI device
102 * @dev_num: device number of PCI device
103 * @slot: pointer to u8 where slot number will be returned
104 */
105int shpchp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
106{
107#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
108 int rc;
109 u16 temp_word;
110 struct pci_dev fakedev;
111 struct pci_bus fakebus;
112
113 fakedev.devfn = dev_num << 3;
114 fakedev.bus = &fakebus;
115 fakebus.number = bus_num;
116 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
117 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
118 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
119 dbg("%s: rc %d\n", __FUNCTION__, rc);
120 if (!rc)
121 return !rc;
122
123 /* set the Edge Level Control Register (ELCR) */
124 temp_word = inb(0x4d0);
125 temp_word |= inb(0x4d1) << 8;
126
127 temp_word |= 0x01 << irq_num;
128
129 /* This should only be for x86 as it sets the Edge Level Control Register */
130 outb((u8) (temp_word & 0xFF), 0x4d0);
131 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
132#endif
133 return 0;
134}
135
136/* More PCI configuration routines; this time centered around hotplug controller */
137
138
139/*
140 * shpchp_save_config
141 *
142 * Reads configuration for all slots in a PCI bus and saves info.
143 *
144 * Note: For non-hot plug busses, the slot # saved is the device #
145 *
146 * returns 0 if success
147 */
148int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
149{
150 int rc;
151 u8 class_code;
152 u8 header_type;
153 u32 ID;
154 u8 secondary_bus;
155 struct pci_func *new_slot;
156 int sub_bus;
157 int FirstSupported;
158 int LastSupported;
159 int max_functions;
160 int function;
161 u8 DevError;
162 int device = 0;
163 int cloop = 0;
164 int stop_it;
165 int index;
166 int is_hot_plug = num_ctlr_slots || first_device_num;
167 struct pci_bus lpci_bus, *pci_bus;
168
169 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
170 num_ctlr_slots, first_device_num);
171
172 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
173 pci_bus = &lpci_bus;
174
175 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
176 num_ctlr_slots, first_device_num);
177
178 /* Decide which slots are supported */
179 if (is_hot_plug) {
180 /*********************************
181 * is_hot_plug is the slot mask
182 *********************************/
183 FirstSupported = first_device_num;
184 LastSupported = FirstSupported + num_ctlr_slots - 1;
185 } else {
186 FirstSupported = 0;
187 LastSupported = 0x1F;
188 }
189
190 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
191 LastSupported);
192
193 /* Save PCI configuration space for all devices in supported slots */
194 pci_bus->number = busnumber;
195 for (device = FirstSupported; device <= LastSupported; device++) {
196 ID = 0xFFFFFFFF;
197 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
198 PCI_VENDOR_ID, &ID);
199
200 if (ID != 0xFFFFFFFF) { /* device in slot */
201 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
202 0x0B, &class_code);
203 if (rc)
204 return rc;
205
206 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
207 PCI_HEADER_TYPE, &header_type);
208 if (rc)
209 return rc;
210
211 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
212
213 /* If multi-function device, set max_functions to 8 */
214 if (header_type & 0x80)
215 max_functions = 8;
216 else
217 max_functions = 1;
218
219 function = 0;
220
221 do {
222 DevError = 0;
223
224 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
225 /* Recurse the subordinate bus
226 * get the subordinate bus number
227 */
228 rc = pci_bus_read_config_byte(pci_bus,
229 PCI_DEVFN(device, function),
230 PCI_SECONDARY_BUS, &secondary_bus);
231 if (rc) {
232 return rc;
233 } else {
234 sub_bus = (int) secondary_bus;
235
236 /* Save secondary bus cfg spc with this recursive call. */
237 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
238 if (rc)
239 return rc;
240 }
241 }
242
243 index = 0;
244 new_slot = shpchp_slot_find(busnumber, device, index++);
245
246 dbg("new_slot = %p\n", new_slot);
247
248 while (new_slot && (new_slot->function != (u8) function)) {
249 new_slot = shpchp_slot_find(busnumber, device, index++);
250 dbg("new_slot = %p\n", new_slot);
251 }
252 if (!new_slot) {
253 /* Setup slot structure. */
254 new_slot = shpchp_slot_create(busnumber);
255 dbg("new_slot = %p\n", new_slot);
256
257 if (new_slot == NULL)
258 return(1);
259 }
260
261 new_slot->bus = (u8) busnumber;
262 new_slot->device = (u8) device;
263 new_slot->function = (u8) function;
264 new_slot->is_a_board = 1;
265 new_slot->switch_save = 0x10;
266 new_slot->pwr_save = 1;
267 /* In case of unsupported board */
268 new_slot->status = DevError;
269 new_slot->pci_dev = pci_find_slot(new_slot->bus,
270 (new_slot->device << 3) | new_slot->function);
271 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
272
273 for (cloop = 0; cloop < 0x20; cloop++) {
274 rc = pci_bus_read_config_dword(pci_bus,
275 PCI_DEVFN(device, function),
276 cloop << 2,
277 (u32 *) &(new_slot->config_space [cloop]));
278 /* dbg("new_slot->config_space[%x] = %x\n",
279 cloop, new_slot->config_space[cloop]); */
280 if (rc)
281 return rc;
282 }
283
284 function++;
285
286 stop_it = 0;
287
288 /* this loop skips to the next present function
289 * reading in Class Code and Header type.
290 */
291
292 while ((function < max_functions)&&(!stop_it)) {
293 rc = pci_bus_read_config_dword(pci_bus,
294 PCI_DEVFN(device, function),
295 PCI_VENDOR_ID, &ID);
296
297 if (ID == 0xFFFFFFFF) { /* nothing there. */
298 function++;
299 dbg("Nothing there\n");
300 } else { /* Something there */
301 rc = pci_bus_read_config_byte(pci_bus,
302 PCI_DEVFN(device, function),
303 0x0B, &class_code);
304 if (rc)
305 return rc;
306
307 rc = pci_bus_read_config_byte(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_HEADER_TYPE, &header_type);
310 if (rc)
311 return rc;
312
313 dbg("class_code = %x, header_type = %x\n",
314 class_code, header_type);
315 stop_it++;
316 }
317 }
318
319 } while (function < max_functions);
320 /* End of IF (device in slot?) */
321 } else if (is_hot_plug) {
322 /* Setup slot structure with entry for empty slot */
323 new_slot = shpchp_slot_create(busnumber);
324
325 if (new_slot == NULL) {
326 return(1);
327 }
328 dbg("new_slot = %p\n", new_slot);
329
330 new_slot->bus = (u8) busnumber;
331 new_slot->device = (u8) device;
332 new_slot->function = 0;
333 new_slot->is_a_board = 0;
334 new_slot->presence_save = 0;
335 new_slot->switch_save = 0;
336 }
337 } /* End of FOR loop */
338
339 return(0);
340}
341
342
343/*
344 * shpchp_save_slot_config
345 *
346 * Saves configuration info for all PCI devices in a given slot
347 * including subordinate busses.
348 *
349 * returns 0 if success
350 */
351int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
352{
353 int rc;
354 u8 class_code;
355 u8 header_type;
356 u32 ID;
357 u8 secondary_bus;
358 int sub_bus;
359 int max_functions;
360 int function;
361 int cloop = 0;
362 int stop_it;
363 struct pci_bus lpci_bus, *pci_bus;
364 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
365 pci_bus = &lpci_bus;
366 pci_bus->number = new_slot->bus;
367
368 ID = 0xFFFFFFFF;
369
370 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
371 PCI_VENDOR_ID, &ID);
372
373 if (ID != 0xFFFFFFFF) { /* device in slot */
374 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
375 0x0B, &class_code);
376
377 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
378 PCI_HEADER_TYPE, &header_type);
379
380 if (header_type & 0x80) /* Multi-function device */
381 max_functions = 8;
382 else
383 max_functions = 1;
384
385 function = 0;
386
387 do {
388 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
389 /* Recurse the subordinate bus */
390 pci_bus_read_config_byte(pci_bus,
391 PCI_DEVFN(new_slot->device, function),
392 PCI_SECONDARY_BUS, &secondary_bus);
393
394 sub_bus = (int) secondary_bus;
395
396 /* Save the config headers for the secondary bus. */
397 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
398
399 if (rc)
400 return rc;
401
402 } /* End of IF */
403
404 new_slot->status = 0;
405
406 for (cloop = 0; cloop < 0x20; cloop++) {
407 pci_bus_read_config_dword(pci_bus,
408 PCI_DEVFN(new_slot->device, function),
409 cloop << 2,
410 (u32 *) &(new_slot->config_space [cloop]));
411 }
412
413 function++;
414
415 stop_it = 0;
416
417 /* this loop skips to the next present function
418 * reading in the Class Code and the Header type.
419 */
420
421 while ((function < max_functions) && (!stop_it)) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 PCI_VENDOR_ID, &ID);
425
426 if (ID == 0xFFFFFFFF) { /* nothing there. */
427 function++;
428 } else { /* Something there */
429 pci_bus_read_config_byte(pci_bus,
430 PCI_DEVFN(new_slot->device, function),
431 0x0B, &class_code);
432
433 pci_bus_read_config_byte(pci_bus,
434 PCI_DEVFN(new_slot->device, function),
435 PCI_HEADER_TYPE, &header_type);
436
437 stop_it++;
438 }
439 }
440
441 } while (function < max_functions);
442 } /* End of IF (device in slot?) */
443 else {
444 return 2;
445 }
446
447 return 0;
448}
449
450
451/*
452 * shpchp_save_used_resources
453 *
454 * Stores used resource information for existing boards. this is
455 * for boards that were in the system when this driver was loaded.
456 * this function is for hot plug ADD
457 *
458 * returns 0 if success
459 * if disable == 1(DISABLE_CARD),
460 * it loops for all functions of the slot and disables them.
461 * else, it just get resources of the function and return.
462 */
463int shpchp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
464{
465 u8 cloop;
466 u8 header_type;
467 u8 secondary_bus;
468 u8 temp_byte;
469 u16 command;
470 u16 save_command;
471 u16 w_base, w_length;
472 u32 temp_register;
473 u32 save_base;
474 u32 base, length;
475 u64 base64 = 0;
476 int index = 0;
477 unsigned int devfn;
478 struct pci_resource *mem_node = NULL;
479 struct pci_resource *p_mem_node = NULL;
480 struct pci_resource *t_mem_node;
481 struct pci_resource *io_node;
482 struct pci_resource *bus_node;
483 struct pci_bus lpci_bus, *pci_bus;
484 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
485 pci_bus = &lpci_bus;
486
487 if (disable)
488 func = shpchp_slot_find(func->bus, func->device, index++);
489
490 while ((func != NULL) && func->is_a_board) {
491 pci_bus->number = func->bus;
492 devfn = PCI_DEVFN(func->device, func->function);
493
494 /* Save the command register */
495 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
496
497 if (disable) {
498 /* disable card */
499 command = 0x00;
500 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
501 }
502
503 /* Check for Bridge */
504 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
505
506 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
507 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
508 func->bus, func->device, save_command);
509 if (disable) {
510 /* Clear Bridge Control Register */
511 command = 0x00;
512 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
513 }
514
515 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
516 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
517
518 bus_node = kmalloc(sizeof(struct pci_resource),
519 GFP_KERNEL);
520 if (!bus_node)
521 return -ENOMEM;
522
523 bus_node->base = (ulong)secondary_bus;
524 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
525
526 bus_node->next = func->bus_head;
527 func->bus_head = bus_node;
528
529 /* Save IO base and Limit registers */
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
531 base = temp_byte;
532 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
533 length = temp_byte;
534
535 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
536 io_node = kmalloc(sizeof(struct pci_resource),
537 GFP_KERNEL);
538 if (!io_node)
539 return -ENOMEM;
540
541 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
542 io_node->length = (ulong)(length - base + 0x10) << 8;
543
544 io_node->next = func->io_head;
545 func->io_head = io_node;
546 }
547
548 /* Save memory base and Limit registers */
549 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
550 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
551
552 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
553 mem_node = kmalloc(sizeof(struct pci_resource),
554 GFP_KERNEL);
555 if (!mem_node)
556 return -ENOMEM;
557
558 mem_node->base = (ulong)w_base << 16;
559 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
560
561 mem_node->next = func->mem_head;
562 func->mem_head = mem_node;
563 }
564 /* Save prefetchable memory base and Limit registers */
565 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
566 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
567
568 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
569 p_mem_node = kmalloc(sizeof(struct pci_resource),
570 GFP_KERNEL);
571 if (!p_mem_node)
572 return -ENOMEM;
573
574 p_mem_node->base = (ulong)w_base << 16;
575 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
576
577 p_mem_node->next = func->p_mem_head;
578 func->p_mem_head = p_mem_node;
579 }
580 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
581 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
582 func->bus, func->device, save_command);
583
584 /* Figure out IO and memory base lengths */
585 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
586 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
587
588 temp_register = 0xFFFFFFFF;
589 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
590 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
591
592 if (!disable)
593 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
594
595 if (!temp_register)
596 continue;
597
598 base = temp_register;
599
600 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
601 (!disable || (save_command & PCI_COMMAND_IO))) {
602 /* IO base */
603 /* set temp_register = amount of IO space requested */
604 base = base & 0xFFFFFFFCL;
605 base = (~base) + 1;
606
607 io_node = kmalloc(sizeof (struct pci_resource),
608 GFP_KERNEL);
609 if (!io_node)
610 return -ENOMEM;
611
612 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
613 io_node->length = (ulong)base;
614 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
615 io_node->base, io_node->length);
616
617 io_node->next = func->io_head;
618 func->io_head = io_node;
619 } else { /* map Memory */
620 int prefetchable = 1;
621 /* struct pci_resources **res_node; */
622 char *res_type_str = "PMEM";
623 u32 temp_register2;
624
625 t_mem_node = kmalloc(sizeof (struct pci_resource),
626 GFP_KERNEL);
627 if (!t_mem_node)
628 return -ENOMEM;
629
630 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
631 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
632 prefetchable = 0;
633 mem_node = t_mem_node;
634 res_type_str++;
635 } else
636 p_mem_node = t_mem_node;
637
638 base = base & 0xFFFFFFF0L;
639 base = (~base) + 1;
640
641 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
642 case PCI_BASE_ADDRESS_MEM_TYPE_32:
643 if (prefetchable) {
644 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
645 p_mem_node->length = (ulong)base;
646 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
647 res_type_str,
648 p_mem_node->base,
649 p_mem_node->length);
650
651 p_mem_node->next = func->p_mem_head;
652 func->p_mem_head = p_mem_node;
653 } else {
654 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
655 mem_node->length = (ulong)base;
656 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
657 res_type_str,
658 mem_node->base,
659 mem_node->length);
660
661 mem_node->next = func->mem_head;
662 func->mem_head = mem_node;
663 }
664 break;
665 case PCI_BASE_ADDRESS_MEM_TYPE_64:
666 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
667 base64 = temp_register2;
668 base64 = (base64 << 32) | save_base;
669
670 if (temp_register2) {
671 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
672 res_type_str, temp_register2, (u32)base64);
673 base64 &= 0x00000000FFFFFFFFL;
674 }
675
676 if (prefetchable) {
677 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
678 p_mem_node->length = base;
679 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
680 res_type_str,
681 p_mem_node->base,
682 p_mem_node->length);
683
684 p_mem_node->next = func->p_mem_head;
685 func->p_mem_head = p_mem_node;
686 } else {
687 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
688 mem_node->length = base;
689 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
690 res_type_str,
691 mem_node->base,
692 mem_node->length);
693
694 mem_node->next = func->mem_head;
695 func->mem_head = mem_node;
696 }
697 cloop += 4;
698 break;
699 default:
700 dbg("asur: reserved BAR type=0x%x\n",
701 temp_register);
702 break;
703 }
704 }
705 } /* End of base register loop */
706 } else { /* Some other unknown header type */
707 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
708 func->bus, func->device);
709 }
710
711 /* find the next device in this slot */
712 if (!disable)
713 break;
714 func = shpchp_slot_find(func->bus, func->device, index++);
715 }
716
717 return 0;
718}
719
720/**
721 * kfree_resource_list: release memory of all list members
722 * @res: resource list to free
723 */
724static inline void
725return_resource_list(struct pci_resource **func, struct pci_resource **res)
726{
727 struct pci_resource *node;
728 struct pci_resource *t_node;
729
730 node = *func;
731 *func = NULL;
732 while (node) {
733 t_node = node->next;
734 return_resource(res, node);
735 node = t_node;
736 }
737}
738
739/*
740 * shpchp_return_board_resources
741 *
742 * this routine returns all resources allocated to a board to
743 * the available pool.
744 *
745 * returns 0 if success
746 */
747int shpchp_return_board_resources(struct pci_func * func,
748 struct resource_lists * resources)
749{
750 int rc;
751 dbg("%s\n", __FUNCTION__);
752
753 if (!func)
754 return 1;
755
756 return_resource_list(&(func->io_head),&(resources->io_head));
757 return_resource_list(&(func->mem_head),&(resources->mem_head));
758 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
759 return_resource_list(&(func->bus_head),&(resources->bus_head));
760
761 rc = shpchp_resource_sort_and_combine(&(resources->mem_head));
762 rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head));
763 rc |= shpchp_resource_sort_and_combine(&(resources->io_head));
764 rc |= shpchp_resource_sort_and_combine(&(resources->bus_head));
765
766 return rc;
767}
768
769/**
770 * kfree_resource_list: release memory of all list members
771 * @res: resource list to free
772 */
773static inline void
774kfree_resource_list(struct pci_resource **r)
775{
776 struct pci_resource *res, *tres;
777
778 res = *r;
779 *r = NULL;
780
781 while (res) {
782 tres = res;
783 res = res->next;
784 kfree(tres);
785 }
786}
787
788/**
789 * shpchp_destroy_resource_list: put node back in the resource list
790 * @resources: list to put nodes back
791 */
792void shpchp_destroy_resource_list(struct resource_lists *resources)
793{
794 kfree_resource_list(&(resources->io_head));
795 kfree_resource_list(&(resources->mem_head));
796 kfree_resource_list(&(resources->p_mem_head));
797 kfree_resource_list(&(resources->bus_head));
798}
799
800/**
801 * shpchp_destroy_board_resources: put node back in the resource list
802 * @resources: list to put nodes back
803 */
804void shpchp_destroy_board_resources(struct pci_func * func)
805{
806 kfree_resource_list(&(func->io_head));
807 kfree_resource_list(&(func->mem_head));
808 kfree_resource_list(&(func->p_mem_head));
809 kfree_resource_list(&(func->bus_head));
810}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
new file mode 100644
index 000000000000..9a1ee132d12c
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -0,0 +1,143 @@
1/*
2 * Compaq Hot Plug Controller Driver
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 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/workqueue.h>
35#include <linux/pci.h>
36#include "shpchp.h"
37
38
39/* A few routines that create sysfs entries for the hot plug controller */
40
41static ssize_t show_ctrl (struct device *dev, char *buf)
42{
43 struct pci_dev *pci_dev;
44 struct controller *ctrl;
45 char * out = buf;
46 int index;
47 struct pci_resource *res;
48
49 pci_dev = container_of (dev, struct pci_dev, dev);
50 ctrl = pci_get_drvdata(pci_dev);
51
52 out += sprintf(buf, "Free resources: memory\n");
53 index = 11;
54 res = ctrl->mem_head;
55 while (res && index--) {
56 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
57 res = res->next;
58 }
59 out += sprintf(out, "Free resources: prefetchable memory\n");
60 index = 11;
61 res = ctrl->p_mem_head;
62 while (res && index--) {
63 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
64 res = res->next;
65 }
66 out += sprintf(out, "Free resources: IO\n");
67 index = 11;
68 res = ctrl->io_head;
69 while (res && index--) {
70 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
71 res = res->next;
72 }
73 out += sprintf(out, "Free resources: bus numbers\n");
74 index = 11;
75 res = ctrl->bus_head;
76 while (res && index--) {
77 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
78 res = res->next;
79 }
80
81 return out - buf;
82}
83static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
84
85static ssize_t show_dev (struct device *dev, char *buf)
86{
87 struct pci_dev *pci_dev;
88 struct controller *ctrl;
89 char * out = buf;
90 int index;
91 struct pci_resource *res;
92 struct pci_func *new_slot;
93 struct slot *slot;
94
95 pci_dev = container_of (dev, struct pci_dev, dev);
96 ctrl = pci_get_drvdata(pci_dev);
97
98 slot=ctrl->slot;
99
100 while (slot) {
101 new_slot = shpchp_slot_find(slot->bus, slot->device, 0);
102 if (!new_slot)
103 break;
104 out += sprintf(out, "assigned resources: memory\n");
105 index = 11;
106 res = new_slot->mem_head;
107 while (res && index--) {
108 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
109 res = res->next;
110 }
111 out += sprintf(out, "assigned resources: prefetchable memory\n");
112 index = 11;
113 res = new_slot->p_mem_head;
114 while (res && index--) {
115 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
116 res = res->next;
117 }
118 out += sprintf(out, "assigned resources: IO\n");
119 index = 11;
120 res = new_slot->io_head;
121 while (res && index--) {
122 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
123 res = res->next;
124 }
125 out += sprintf(out, "assigned resources: bus numbers\n");
126 index = 11;
127 res = new_slot->bus_head;
128 while (res && index--) {
129 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
130 res = res->next;
131 }
132 slot=slot->next;
133 }
134
135 return out - buf;
136}
137static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
138
139void shpchp_create_ctrl_files (struct controller *ctrl)
140{
141 device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
142 device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
143}
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
new file mode 100644
index 000000000000..88aeb978c911
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm.h
@@ -0,0 +1,55 @@
1/*
2 * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI 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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_H_
31#define _SHPCHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
34#include "shpchprm_legacy.h"
35#else
36#include "shpchprm_nonacpi.h"
37#endif
38
39int shpchprm_init(enum php_ctlr_type ct);
40void shpchprm_cleanup(void);
41int shpchprm_print_pirt(void);
42int shpchprm_find_available_resources(struct controller *ctrl);
43int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
44void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
45int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
46
47#ifdef DEBUG
48#define RES_CHECK(this, bits) \
49 { if (((this) & (bits - 1))) \
50 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
51#else
52#define RES_CHECK(this, bits)
53#endif
54
55#endif /* _SHPCHPRM_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
new file mode 100644
index 000000000000..243a51d88b86
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -0,0 +1,1713 @@
1/*
2 * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform
3 *
4 * Copyright (C) 2003-2004 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 <dely.l.sy@intel.com>
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <asm/uaccess.h>
36#include <asm/system.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include <acpi/acpi.h>
41#include <acpi/acpi_bus.h>
42#include <acpi/actypes.h>
43#include "shpchp.h"
44#include "shpchprm.h"
45
46#define PCI_MAX_BUS 0x100
47#define ACPI_STA_DEVICE_PRESENT 0x01
48
49#define METHOD_NAME__SUN "_SUN"
50#define METHOD_NAME__HPP "_HPP"
51#define METHOD_NAME_OSHP "OSHP"
52
53#define PHP_RES_BUS 0xA0
54#define PHP_RES_IO 0xA1
55#define PHP_RES_MEM 0xA2
56#define PHP_RES_PMEM 0xA3
57
58#define BRIDGE_TYPE_P2P 0x00
59#define BRIDGE_TYPE_HOST 0x01
60
61/* this should go to drivers/acpi/include/ */
62struct acpi__hpp {
63 u8 cache_line_size;
64 u8 latency_timer;
65 u8 enable_serr;
66 u8 enable_perr;
67};
68
69struct acpi_php_slot {
70 struct acpi_php_slot *next;
71 struct acpi_bridge *bridge;
72 acpi_handle handle;
73 int seg;
74 int bus;
75 int dev;
76 int fun;
77 u32 sun;
78 struct pci_resource *mem_head;
79 struct pci_resource *p_mem_head;
80 struct pci_resource *io_head;
81 struct pci_resource *bus_head;
82 void *slot_ops; /* _STA, _EJx, etc */
83 struct slot *slot;
84}; /* per func */
85
86struct acpi_bridge {
87 struct acpi_bridge *parent;
88 struct acpi_bridge *next;
89 struct acpi_bridge *child;
90 acpi_handle handle;
91 int seg;
92 int pbus; /* pdev->bus->number */
93 int pdevice; /* PCI_SLOT(pdev->devfn) */
94 int pfunction; /* PCI_DEVFN(pdev->devfn) */
95 int bus; /* pdev->subordinate->number */
96 struct acpi__hpp *_hpp;
97 struct acpi_php_slot *slots;
98 struct pci_resource *tmem_head; /* total from crs */
99 struct pci_resource *tp_mem_head; /* total from crs */
100 struct pci_resource *tio_head; /* total from crs */
101 struct pci_resource *tbus_head; /* total from crs */
102 struct pci_resource *mem_head; /* available */
103 struct pci_resource *p_mem_head; /* available */
104 struct pci_resource *io_head; /* available */
105 struct pci_resource *bus_head; /* available */
106 int scanned;
107 int type;
108};
109
110static struct acpi_bridge *acpi_bridges_head;
111
112static u8 * acpi_path_name( acpi_handle handle)
113{
114 acpi_status status;
115 static u8 path_name[ACPI_PATHNAME_MAX];
116 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
117
118 memset(path_name, 0, sizeof (path_name));
119 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
120
121 if (ACPI_FAILURE(status))
122 return NULL;
123 else
124 return path_name;
125}
126
127static void acpi_get__hpp ( struct acpi_bridge *ab);
128static void acpi_run_oshp ( struct acpi_bridge *ab);
129
130static int acpi_add_slot_to_php_slots(
131 struct acpi_bridge *ab,
132 int bus_num,
133 acpi_handle handle,
134 u32 adr,
135 u32 sun
136 )
137{
138 struct acpi_php_slot *aps;
139 static long samesun = -1;
140
141 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
142 if (!aps) {
143 err ("acpi_shpchprm: alloc for aps fail\n");
144 return -1;
145 }
146 memset(aps, 0, sizeof(struct acpi_php_slot));
147
148 aps->handle = handle;
149 aps->bus = bus_num;
150 aps->dev = (adr >> 16) & 0xffff;
151 aps->fun = adr & 0xffff;
152 aps->sun = sun;
153
154 aps->next = ab->slots; /* cling to the bridge */
155 aps->bridge = ab;
156 ab->slots = aps;
157
158 ab->scanned += 1;
159 if (!ab->_hpp)
160 acpi_get__hpp(ab);
161
162 acpi_run_oshp(ab);
163
164 if (sun != samesun) {
165 info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg,
166 aps->bus, aps->dev, aps->fun);
167 samesun = sun;
168 }
169 return 0;
170}
171
172static void acpi_get__hpp ( struct acpi_bridge *ab)
173{
174 acpi_status status;
175 u8 nui[4];
176 struct acpi_buffer ret_buf = { 0, NULL};
177 union acpi_object *ext_obj, *package;
178 u8 *path_name = acpi_path_name(ab->handle);
179 int i, len = 0;
180
181 /* get _hpp */
182 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
183 switch (status) {
184 case AE_BUFFER_OVERFLOW:
185 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
186 if (!ret_buf.pointer) {
187 err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name);
188 return;
189 }
190 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
191 if (ACPI_SUCCESS(status))
192 break;
193 default:
194 if (ACPI_FAILURE(status)) {
195 err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status);
196 return;
197 }
198 }
199
200 ext_obj = (union acpi_object *) ret_buf.pointer;
201 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
202 err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name);
203 goto free_and_return;
204 }
205
206 len = ext_obj->package.count;
207 package = (union acpi_object *) ret_buf.pointer;
208 for ( i = 0; (i < len) || (i < 4); i++) {
209 ext_obj = (union acpi_object *) &package->package.elements[i];
210 switch (ext_obj->type) {
211 case ACPI_TYPE_INTEGER:
212 nui[i] = (u8)ext_obj->integer.value;
213 break;
214 default:
215 err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name);
216 goto free_and_return;
217 }
218 }
219
220 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
221 if (!ab->_hpp) {
222 err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name);
223 goto free_and_return;
224 }
225 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
226
227 ab->_hpp->cache_line_size = nui[0];
228 ab->_hpp->latency_timer = nui[1];
229 ab->_hpp->enable_serr = nui[2];
230 ab->_hpp->enable_perr = nui[3];
231
232 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
233 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
234 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
235 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
236
237free_and_return:
238 kfree(ret_buf.pointer);
239}
240
241static void acpi_run_oshp ( struct acpi_bridge *ab)
242{
243 acpi_status status;
244 u8 *path_name = acpi_path_name(ab->handle);
245
246 /* run OSHP */
247 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
248 if (ACPI_FAILURE(status)) {
249 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
250 } else
251 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
252 return;
253}
254
255static acpi_status acpi_evaluate_crs(
256 acpi_handle handle,
257 struct acpi_resource **retbuf
258 )
259{
260 acpi_status status;
261 struct acpi_buffer crsbuf;
262 u8 *path_name = acpi_path_name(handle);
263
264 crsbuf.length = 0;
265 crsbuf.pointer = NULL;
266
267 status = acpi_get_current_resources (handle, &crsbuf);
268
269 switch (status) {
270 case AE_BUFFER_OVERFLOW:
271 break; /* found */
272 case AE_NOT_FOUND:
273 dbg("acpi_shpchprm:%s _CRS not found\n", path_name);
274 return status;
275 default:
276 err ("acpi_shpchprm:%s _CRS fail=0x%x\n", path_name, status);
277 return status;
278 }
279
280 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
281 if (!crsbuf.pointer) {
282 err ("acpi_shpchprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
283 return AE_NO_MEMORY;
284 }
285
286 status = acpi_get_current_resources (handle, &crsbuf);
287 if (ACPI_FAILURE(status)) {
288 err("acpi_shpchprm: %s _CRS fail=0x%x.\n", path_name, status);
289 kfree(crsbuf.pointer);
290 return status;
291 }
292
293 *retbuf = crsbuf.pointer;
294
295 return status;
296}
297
298static void free_pci_resource ( struct pci_resource *aprh)
299{
300 struct pci_resource *res, *next;
301
302 for (res = aprh; res; res = next) {
303 next = res->next;
304 kfree(res);
305 }
306}
307
308static void print_pci_resource ( struct pci_resource *aprh)
309{
310 struct pci_resource *res;
311
312 for (res = aprh; res; res = res->next)
313 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
314}
315
316static void print_slot_resources( struct acpi_php_slot *aps)
317{
318 if (aps->bus_head) {
319 dbg(" BUS Resources:\n");
320 print_pci_resource (aps->bus_head);
321 }
322
323 if (aps->io_head) {
324 dbg(" IO Resources:\n");
325 print_pci_resource (aps->io_head);
326 }
327
328 if (aps->mem_head) {
329 dbg(" MEM Resources:\n");
330 print_pci_resource (aps->mem_head);
331 }
332
333 if (aps->p_mem_head) {
334 dbg(" PMEM Resources:\n");
335 print_pci_resource (aps->p_mem_head);
336 }
337}
338
339static void print_pci_resources( struct acpi_bridge *ab)
340{
341 if (ab->tbus_head) {
342 dbg(" Total BUS Resources:\n");
343 print_pci_resource (ab->tbus_head);
344 }
345 if (ab->bus_head) {
346 dbg(" BUS Resources:\n");
347 print_pci_resource (ab->bus_head);
348 }
349
350 if (ab->tio_head) {
351 dbg(" Total IO Resources:\n");
352 print_pci_resource (ab->tio_head);
353 }
354 if (ab->io_head) {
355 dbg(" IO Resources:\n");
356 print_pci_resource (ab->io_head);
357 }
358
359 if (ab->tmem_head) {
360 dbg(" Total MEM Resources:\n");
361 print_pci_resource (ab->tmem_head);
362 }
363 if (ab->mem_head) {
364 dbg(" MEM Resources:\n");
365 print_pci_resource (ab->mem_head);
366 }
367
368 if (ab->tp_mem_head) {
369 dbg(" Total PMEM Resources:\n");
370 print_pci_resource (ab->tp_mem_head);
371 }
372 if (ab->p_mem_head) {
373 dbg(" PMEM Resources:\n");
374 print_pci_resource (ab->p_mem_head);
375 }
376 if (ab->_hpp) {
377 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
378 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
379 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
380 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
381 }
382}
383
384static int shpchprm_delete_resource(
385 struct pci_resource **aprh,
386 ulong base,
387 ulong size)
388{
389 struct pci_resource *res;
390 struct pci_resource *prevnode;
391 struct pci_resource *split_node;
392 ulong tbase;
393
394 shpchp_resource_sort_and_combine(aprh);
395
396 for (res = *aprh; res; res = res->next) {
397 if (res->base > base)
398 continue;
399
400 if ((res->base + res->length) < (base + size))
401 continue;
402
403 if (res->base < base) {
404 tbase = base;
405
406 if ((res->length - (tbase - res->base)) < size)
407 continue;
408
409 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
410 if (!split_node)
411 return -ENOMEM;
412
413 split_node->base = res->base;
414 split_node->length = tbase - res->base;
415 res->base = tbase;
416 res->length -= split_node->length;
417
418 split_node->next = res->next;
419 res->next = split_node;
420 }
421
422 if (res->length >= size) {
423 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
424 if (!split_node)
425 return -ENOMEM;
426
427 split_node->base = res->base + size;
428 split_node->length = res->length - size;
429 res->length = size;
430
431 split_node->next = res->next;
432 res->next = split_node;
433 }
434
435 if (*aprh == res) {
436 *aprh = res->next;
437 } else {
438 prevnode = *aprh;
439 while (prevnode->next != res)
440 prevnode = prevnode->next;
441
442 prevnode->next = res->next;
443 }
444 res->next = NULL;
445 kfree(res);
446 break;
447 }
448
449 return 0;
450}
451
452static int shpchprm_delete_resources(
453 struct pci_resource **aprh,
454 struct pci_resource *this
455 )
456{
457 struct pci_resource *res;
458
459 for (res = this; res; res = res->next)
460 shpchprm_delete_resource(aprh, res->base, res->length);
461
462 return 0;
463}
464
465static int shpchprm_add_resource(
466 struct pci_resource **aprh,
467 ulong base,
468 ulong size)
469{
470 struct pci_resource *res;
471
472 for (res = *aprh; res; res = res->next) {
473 if ((res->base + res->length) == base) {
474 res->length += size;
475 size = 0L;
476 break;
477 }
478 if (res->next == *aprh)
479 break;
480 }
481
482 if (size) {
483 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
484 if (!res) {
485 err ("acpi_shpchprm: alloc for res fail\n");
486 return -ENOMEM;
487 }
488 memset(res, 0, sizeof (struct pci_resource));
489
490 res->base = base;
491 res->length = size;
492 res->next = *aprh;
493 *aprh = res;
494 }
495
496 return 0;
497}
498
499static int shpchprm_add_resources(
500 struct pci_resource **aprh,
501 struct pci_resource *this
502 )
503{
504 struct pci_resource *res;
505 int rc = 0;
506
507 for (res = this; res && !rc; res = res->next)
508 rc = shpchprm_add_resource(aprh, res->base, res->length);
509
510 return rc;
511}
512
513static void acpi_parse_io (
514 struct acpi_bridge *ab,
515 union acpi_resource_data *data
516 )
517{
518 struct acpi_resource_io *dataio;
519 dataio = (struct acpi_resource_io *) data;
520
521 dbg("Io Resource\n");
522 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
523 dbg(" Range minimum base: %08X\n", dataio->min_base_address);
524 dbg(" Range maximum base: %08X\n", dataio->max_base_address);
525 dbg(" Alignment: %08X\n", dataio->alignment);
526 dbg(" Range Length: %08X\n", dataio->range_length);
527}
528
529static void acpi_parse_fixed_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{
534 struct acpi_resource_fixed_io *datafio;
535 datafio = (struct acpi_resource_fixed_io *) data;
536
537 dbg("Fixed Io Resource\n");
538 dbg(" Range base address: %08X", datafio->base_address);
539 dbg(" Range length: %08X", datafio->range_length);
540}
541
542static void acpi_parse_address16_32 (
543 struct acpi_bridge *ab,
544 union acpi_resource_data *data,
545 acpi_resource_type id
546 )
547{
548 /*
549 * acpi_resource_address16 == acpi_resource_address32
550 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
551 */
552 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
553 struct pci_resource **aprh, **tprh;
554
555 if (id == ACPI_RSTYPE_ADDRESS16)
556 dbg("acpi_shpchprm:16-Bit Address Space Resource\n");
557 else
558 dbg("acpi_shpchprm:32-Bit Address Space Resource\n");
559
560 switch (data32->resource_type) {
561 case ACPI_MEMORY_RANGE:
562 dbg(" Resource Type: Memory Range\n");
563 aprh = &ab->mem_head;
564 tprh = &ab->tmem_head;
565
566 switch (data32->attribute.memory.cache_attribute) {
567 case ACPI_NON_CACHEABLE_MEMORY:
568 dbg(" Type Specific: Noncacheable memory\n");
569 break;
570 case ACPI_CACHABLE_MEMORY:
571 dbg(" Type Specific: Cacheable memory\n");
572 break;
573 case ACPI_WRITE_COMBINING_MEMORY:
574 dbg(" Type Specific: Write-combining memory\n");
575 break;
576 case ACPI_PREFETCHABLE_MEMORY:
577 aprh = &ab->p_mem_head;
578 dbg(" Type Specific: Prefetchable memory\n");
579 break;
580 default:
581 dbg(" Type Specific: Invalid cache attribute\n");
582 break;
583 }
584
585 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
586 break;
587
588 case ACPI_IO_RANGE:
589 dbg(" Resource Type: I/O Range\n");
590 aprh = &ab->io_head;
591 tprh = &ab->tio_head;
592
593 switch (data32->attribute.io.range_attribute) {
594 case ACPI_NON_ISA_ONLY_RANGES:
595 dbg(" Type Specific: Non-ISA Io Addresses\n");
596 break;
597 case ACPI_ISA_ONLY_RANGES:
598 dbg(" Type Specific: ISA Io Addresses\n");
599 break;
600 case ACPI_ENTIRE_RANGE:
601 dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
602 break;
603 default:
604 dbg(" Type Specific: Invalid range attribute\n");
605 break;
606 }
607 break;
608
609 case ACPI_BUS_NUMBER_RANGE:
610 dbg(" Resource Type: Bus Number Range(fixed)\n");
611 /* fixup to be compatible with the rest of php driver */
612 data32->min_address_range++;
613 data32->address_length--;
614 aprh = &ab->bus_head;
615 tprh = &ab->tbus_head;
616 break;
617 default:
618 dbg(" Resource Type: Invalid resource type. Exiting.\n");
619 return;
620 }
621
622 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
623 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
624 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
625 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
626 dbg(" Granularity: %08X\n", data32->granularity);
627 dbg(" Address range min: %08X\n", data32->min_address_range);
628 dbg(" Address range max: %08X\n", data32->max_address_range);
629 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
630 dbg(" Address Length: %08X\n", data32->address_length);
631
632 if (0xFF != data32->resource_source.index) {
633 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
634 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
635 }
636
637 shpchprm_add_resource(aprh, data32->min_address_range, data32->address_length);
638}
639
640static acpi_status acpi_parse_crs(
641 struct acpi_bridge *ab,
642 struct acpi_resource *crsbuf
643 )
644{
645 acpi_status status = AE_OK;
646 struct acpi_resource *resource = crsbuf;
647 u8 count = 0;
648 u8 done = 0;
649
650 while (!done) {
651 dbg("acpi_shpchprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
652 switch (resource->id) {
653 case ACPI_RSTYPE_IRQ:
654 dbg("Irq -------- Resource\n");
655 break;
656 case ACPI_RSTYPE_DMA:
657 dbg("DMA -------- Resource\n");
658 break;
659 case ACPI_RSTYPE_START_DPF:
660 dbg("Start DPF -------- Resource\n");
661 break;
662 case ACPI_RSTYPE_END_DPF:
663 dbg("End DPF -------- Resource\n");
664 break;
665 case ACPI_RSTYPE_IO:
666 acpi_parse_io (ab, &resource->data);
667 break;
668 case ACPI_RSTYPE_FIXED_IO:
669 acpi_parse_fixed_io (ab, &resource->data);
670 break;
671 case ACPI_RSTYPE_VENDOR:
672 dbg("Vendor -------- Resource\n");
673 break;
674 case ACPI_RSTYPE_END_TAG:
675 dbg("End_tag -------- Resource\n");
676 done = 1;
677 break;
678 case ACPI_RSTYPE_MEM24:
679 dbg("Mem24 -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_MEM32:
682 dbg("Mem32 -------- Resource\n");
683 break;
684 case ACPI_RSTYPE_FIXED_MEM32:
685 dbg("Fixed Mem32 -------- Resource\n");
686 break;
687 case ACPI_RSTYPE_ADDRESS16:
688 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
689 break;
690 case ACPI_RSTYPE_ADDRESS32:
691 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
692 break;
693 case ACPI_RSTYPE_ADDRESS64:
694 info("Address64 -------- Resource unparsed\n");
695 break;
696 case ACPI_RSTYPE_EXT_IRQ:
697 dbg("Ext Irq -------- Resource\n");
698 break;
699 default:
700 dbg("Invalid -------- resource type 0x%x\n", resource->id);
701 break;
702 }
703
704 resource = (struct acpi_resource *) ((char *)resource + resource->length);
705 }
706
707 return status;
708}
709
710static acpi_status acpi_get_crs( struct acpi_bridge *ab)
711{
712 acpi_status status;
713 struct acpi_resource *crsbuf;
714
715 status = acpi_evaluate_crs(ab->handle, &crsbuf);
716 if (ACPI_SUCCESS(status)) {
717 status = acpi_parse_crs(ab, crsbuf);
718 kfree(crsbuf);
719
720 shpchp_resource_sort_and_combine(&ab->bus_head);
721 shpchp_resource_sort_and_combine(&ab->io_head);
722 shpchp_resource_sort_and_combine(&ab->mem_head);
723 shpchp_resource_sort_and_combine(&ab->p_mem_head);
724
725 shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
726 shpchprm_add_resources (&ab->tio_head, ab->io_head);
727 shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
728 shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
729 }
730
731 return status;
732}
733
734/* find acpi_bridge downword from ab. */
735static struct acpi_bridge *
736find_acpi_bridge_by_bus(
737 struct acpi_bridge *ab,
738 int seg,
739 int bus /* pdev->subordinate->number */
740 )
741{
742 struct acpi_bridge *lab = NULL;
743
744 if (!ab)
745 return NULL;
746
747 if ((ab->bus == bus) && (ab->seg == seg))
748 return ab;
749
750 if (ab->child)
751 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
752
753 if (!lab)
754 if (ab->next)
755 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
756
757 return lab;
758}
759
760/*
761 * Build a device tree of ACPI PCI Bridges
762 */
763static void shpchprm_acpi_register_a_bridge (
764 struct acpi_bridge **head,
765 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
766 struct acpi_bridge *cab /* child bridge to add */
767 )
768{
769 struct acpi_bridge *lpab;
770 struct acpi_bridge *lcab;
771
772 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
773 if (!lpab) {
774 if (!(pab->type & BRIDGE_TYPE_HOST))
775 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
776 pab->next = *head;
777 *head = pab;
778 lpab = pab;
779 }
780
781 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
782 return;
783
784 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
785 if (lcab) {
786 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
787 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
788 return;
789 } else
790 lcab = cab;
791
792 lcab->parent = lpab;
793 lcab->next = lpab->child;
794 lpab->child = lcab;
795}
796
797static acpi_status shpchprm_acpi_build_php_slots_callback(
798 acpi_handle handle,
799 u32 Level,
800 void *context,
801 void **retval
802 )
803{
804 ulong bus_num;
805 ulong seg_num;
806 ulong sun, adr;
807 ulong padr = 0;
808 acpi_handle phandle = NULL;
809 struct acpi_bridge *pab = (struct acpi_bridge *)context;
810 struct acpi_bridge *lab;
811 acpi_status status;
812 u8 *path_name = acpi_path_name(handle);
813
814 /* get _SUN */
815 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
816 switch(status) {
817 case AE_NOT_FOUND:
818 return AE_OK;
819 default:
820 if (ACPI_FAILURE(status)) {
821 err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
822 return status;
823 }
824 }
825
826 /* get _ADR. _ADR must exist if _SUN exists */
827 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
828 if (ACPI_FAILURE(status)) {
829 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
830 return status;
831 }
832
833 dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
834
835 status = acpi_get_parent(handle, &phandle);
836 if (ACPI_FAILURE(status)) {
837 err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status);
838 return (status);
839 }
840
841 bus_num = pab->bus;
842 seg_num = pab->seg;
843
844 if (pab->bus == bus_num) {
845 lab = pab;
846 } else {
847 dbg("WARN: pab is not parent\n");
848 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
849 if (!lab) {
850 dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
851 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
852 if (!lab) {
853 err("acpi_shpchprm: alloc for ab fail\n");
854 return AE_NO_MEMORY;
855 }
856 memset(lab, 0, sizeof(struct acpi_bridge));
857
858 lab->handle = phandle;
859 lab->pbus = pab->bus;
860 lab->pdevice = (int)(padr >> 16) & 0xffff;
861 lab->pfunction = (int)(padr & 0xffff);
862 lab->bus = (int)bus_num;
863 lab->scanned = 0;
864 lab->type = BRIDGE_TYPE_P2P;
865
866 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
867 } else
868 dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
869 }
870
871 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
872 return (status);
873}
874
875static int shpchprm_acpi_build_php_slots(
876 struct acpi_bridge *ab,
877 u32 depth
878 )
879{
880 acpi_status status;
881 u8 *path_name = acpi_path_name(ab->handle);
882
883 /* Walk down this pci bridge to get _SUNs if any behind P2P */
884 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
885 ab->handle,
886 depth,
887 shpchprm_acpi_build_php_slots_callback,
888 ab,
889 NULL );
890 if (ACPI_FAILURE(status)) {
891 dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
892 return -1;
893 }
894
895 return 0;
896}
897
898static void build_a_bridge(
899 struct acpi_bridge *pab,
900 struct acpi_bridge *ab
901 )
902{
903 u8 *path_name = acpi_path_name(ab->handle);
904
905 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
906
907 switch (ab->type) {
908 case BRIDGE_TYPE_HOST:
909 dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
910 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
911 break;
912 case BRIDGE_TYPE_P2P:
913 dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
914 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
915 break;
916 };
917
918 /* build any immediate PHP slots under this pci bridge */
919 shpchprm_acpi_build_php_slots(ab, 1);
920}
921
922static struct acpi_bridge * add_p2p_bridge(
923 acpi_handle handle,
924 struct acpi_bridge *pab, /* parent */
925 ulong adr
926 )
927{
928 struct acpi_bridge *ab;
929 struct pci_dev *pdev;
930 ulong devnum, funcnum;
931 u8 *path_name = acpi_path_name(handle);
932
933 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
934 if (!ab) {
935 err("acpi_shpchprm: alloc for ab fail\n");
936 return NULL;
937 }
938 memset(ab, 0, sizeof(struct acpi_bridge));
939
940 devnum = (adr >> 16) & 0xffff;
941 funcnum = adr & 0xffff;
942
943 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
944 if (!pdev || !pdev->subordinate) {
945 err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
946 kfree(ab);
947 return NULL;
948 }
949
950 ab->handle = handle;
951 ab->seg = pab->seg;
952 ab->pbus = pab->bus; /* or pdev->bus->number */
953 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
954 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
955 ab->bus = pdev->subordinate->number;
956 ab->scanned = 0;
957 ab->type = BRIDGE_TYPE_P2P;
958
959 dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
960 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
961 pab->bus, (u32)devnum, (u32)funcnum, path_name);
962
963 build_a_bridge(pab, ab);
964
965 return ab;
966}
967
968static acpi_status scan_p2p_bridge(
969 acpi_handle handle,
970 u32 Level,
971 void *context,
972 void **retval
973 )
974{
975 struct acpi_bridge *pab = (struct acpi_bridge *)context;
976 struct acpi_bridge *ab;
977 acpi_status status;
978 ulong adr = 0;
979 u8 *path_name = acpi_path_name(handle);
980 ulong devnum, funcnum;
981 struct pci_dev *pdev;
982
983 /* get device, function */
984 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
985 if (ACPI_FAILURE(status)) {
986 if (status != AE_NOT_FOUND)
987 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
988 return AE_OK;
989 }
990
991 devnum = (adr >> 16) & 0xffff;
992 funcnum = adr & 0xffff;
993
994 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
995 if (!pdev)
996 return AE_OK;
997 if (!pdev->subordinate)
998 return AE_OK;
999
1000 ab = add_p2p_bridge(handle, pab, adr);
1001 if (ab) {
1002 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1003 handle,
1004 (u32)1,
1005 scan_p2p_bridge,
1006 ab,
1007 NULL);
1008 if (ACPI_FAILURE(status))
1009 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
1010 }
1011
1012 return AE_OK;
1013}
1014
1015static struct acpi_bridge * add_host_bridge(
1016 acpi_handle handle,
1017 ulong segnum,
1018 ulong busnum
1019 )
1020{
1021 ulong adr = 0;
1022 acpi_status status;
1023 struct acpi_bridge *ab;
1024 u8 *path_name = acpi_path_name(handle);
1025
1026 /* get device, function: host br adr is always 0000 though. */
1027 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1028 if (ACPI_FAILURE(status)) {
1029 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
1030 return NULL;
1031 }
1032 dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum,
1033 (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1034
1035 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1036 if (!ab) {
1037 err("acpi_shpchprm: alloc for ab fail\n");
1038 return NULL;
1039 }
1040 memset(ab, 0, sizeof(struct acpi_bridge));
1041
1042 ab->handle = handle;
1043 ab->seg = (int)segnum;
1044 ab->bus = ab->pbus = (int)busnum;
1045 ab->pdevice = (int)(adr >> 16) & 0xffff;
1046 ab->pfunction = (int)(adr & 0xffff);
1047 ab->scanned = 0;
1048 ab->type = BRIDGE_TYPE_HOST;
1049
1050 /* get root pci bridge's current resources */
1051 status = acpi_get_crs(ab);
1052 if (ACPI_FAILURE(status)) {
1053 err("acpi_shpchprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1054 kfree(ab);
1055 return NULL;
1056 }
1057 build_a_bridge(ab, ab);
1058
1059 return ab;
1060}
1061
1062static acpi_status acpi_scan_from_root_pci_callback (
1063 acpi_handle handle,
1064 u32 Level,
1065 void *context,
1066 void **retval
1067 )
1068{
1069 ulong segnum = 0;
1070 ulong busnum = 0;
1071 acpi_status status;
1072 struct acpi_bridge *ab;
1073 u8 *path_name = acpi_path_name(handle);
1074
1075 /* get bus number of this pci root bridge */
1076 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1077 if (ACPI_FAILURE(status)) {
1078 if (status != AE_NOT_FOUND) {
1079 err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1080 return status;
1081 }
1082 segnum = 0;
1083 }
1084
1085 /* get bus number of this pci root bridge */
1086 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1087 if (ACPI_FAILURE(status)) {
1088 err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1089 return (status);
1090 }
1091
1092 ab = add_host_bridge(handle, segnum, busnum);
1093 if (ab) {
1094 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1095 handle,
1096 1,
1097 scan_p2p_bridge,
1098 ab,
1099 NULL);
1100 if (ACPI_FAILURE(status))
1101 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
1102 }
1103
1104 return AE_OK;
1105}
1106
1107static int shpchprm_acpi_scan_pci (void)
1108{
1109 acpi_status status;
1110
1111 /*
1112 * TBD: traverse LDM device tree with the help of
1113 * unified ACPI augmented for php device population.
1114 */
1115 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
1116 acpi_scan_from_root_pci_callback,
1117 NULL,
1118 NULL );
1119 if (ACPI_FAILURE(status)) {
1120 err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
1121 return -1;
1122 }
1123
1124 return 0;
1125}
1126
1127int shpchprm_init(enum php_ctlr_type ctlr_type)
1128{
1129 int rc;
1130
1131 if (ctlr_type != PCI)
1132 return -ENODEV;
1133
1134 dbg("shpchprm ACPI init <enter>\n");
1135 acpi_bridges_head = NULL;
1136
1137 /* construct PCI bus:device tree of acpi_handles */
1138 rc = shpchprm_acpi_scan_pci();
1139 if (rc)
1140 return rc;
1141
1142 dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
1143 return rc;
1144}
1145
1146static void free_a_slot(struct acpi_php_slot *aps)
1147{
1148 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);
1149
1150 free_pci_resource (aps->io_head);
1151 free_pci_resource (aps->bus_head);
1152 free_pci_resource (aps->mem_head);
1153 free_pci_resource (aps->p_mem_head);
1154
1155 kfree(aps);
1156}
1157
1158static void free_a_bridge( struct acpi_bridge *ab)
1159{
1160 struct acpi_php_slot *aps, *next;
1161
1162 switch (ab->type) {
1163 case BRIDGE_TYPE_HOST:
1164 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1165 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1166 break;
1167 case BRIDGE_TYPE_P2P:
1168 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1169 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1170 break;
1171 };
1172
1173 /* free slots first */
1174 for (aps = ab->slots; aps; aps = next) {
1175 next = aps->next;
1176 free_a_slot(aps);
1177 }
1178
1179 free_pci_resource (ab->io_head);
1180 free_pci_resource (ab->tio_head);
1181 free_pci_resource (ab->bus_head);
1182 free_pci_resource (ab->tbus_head);
1183 free_pci_resource (ab->mem_head);
1184 free_pci_resource (ab->tmem_head);
1185 free_pci_resource (ab->p_mem_head);
1186 free_pci_resource (ab->tp_mem_head);
1187
1188 kfree(ab);
1189}
1190
1191static void shpchprm_free_bridges ( struct acpi_bridge *ab)
1192{
1193 if (!ab)
1194 return;
1195
1196 if (ab->child)
1197 shpchprm_free_bridges (ab->child);
1198
1199 if (ab->next)
1200 shpchprm_free_bridges (ab->next);
1201
1202 free_a_bridge(ab);
1203}
1204
1205void shpchprm_cleanup(void)
1206{
1207 shpchprm_free_bridges (acpi_bridges_head);
1208}
1209
1210static int get_number_of_slots (
1211 struct acpi_bridge *ab,
1212 int selfonly
1213 )
1214{
1215 struct acpi_php_slot *aps;
1216 int prev_slot = -1;
1217 int slot_num = 0;
1218
1219 for ( aps = ab->slots; aps; aps = aps->next)
1220 if (aps->dev != prev_slot) {
1221 prev_slot = aps->dev;
1222 slot_num++;
1223 }
1224
1225 if (ab->child)
1226 slot_num += get_number_of_slots (ab->child, 0);
1227
1228 if (selfonly)
1229 return slot_num;
1230
1231 if (ab->next)
1232 slot_num += get_number_of_slots (ab->next, 0);
1233
1234 return slot_num;
1235}
1236
1237static int print_acpi_resources (struct acpi_bridge *ab)
1238{
1239 struct acpi_php_slot *aps;
1240 int i;
1241
1242 switch (ab->type) {
1243 case BRIDGE_TYPE_HOST:
1244 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1245 break;
1246 case BRIDGE_TYPE_P2P:
1247 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1248 break;
1249 };
1250
1251 print_pci_resources (ab);
1252
1253 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1254 if (aps->dev == i)
1255 continue;
1256 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1257 print_slot_resources(aps);
1258 i = aps->dev;
1259 }
1260
1261 if (ab->child)
1262 print_acpi_resources (ab->child);
1263
1264 if (ab->next)
1265 print_acpi_resources (ab->next);
1266
1267 return 0;
1268}
1269
1270int shpchprm_print_pirt(void)
1271{
1272 dbg("SHPCHPRM ACPI Slots\n");
1273 if (acpi_bridges_head)
1274 print_acpi_resources (acpi_bridges_head);
1275 return 0;
1276}
1277
1278static struct acpi_php_slot * get_acpi_slot (
1279 struct acpi_bridge *ab,
1280 u32 sun
1281 )
1282{
1283 struct acpi_php_slot *aps = NULL;
1284
1285 for ( aps = ab->slots; aps; aps = aps->next)
1286 if (aps->sun == sun)
1287 return aps;
1288
1289 if (!aps && ab->child) {
1290 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1291 if (aps)
1292 return aps;
1293 }
1294
1295 if (!aps && ab->next) {
1296 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1297 if (aps)
1298 return aps;
1299 }
1300
1301 return aps;
1302
1303}
1304
1305#if 0
1306static void * shpchprm_get_slot(struct slot *slot)
1307{
1308 struct acpi_bridge *ab = acpi_bridges_head;
1309 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1310
1311 aps->slot = slot;
1312
1313 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);
1314
1315 return (void *)aps;
1316}
1317#endif
1318
1319static void shpchprm_dump_func_res( struct pci_func *fun)
1320{
1321 struct pci_func *func = fun;
1322
1323 if (func->bus_head) {
1324 dbg(": BUS Resources:\n");
1325 print_pci_resource (func->bus_head);
1326 }
1327 if (func->io_head) {
1328 dbg(": IO Resources:\n");
1329 print_pci_resource (func->io_head);
1330 }
1331 if (func->mem_head) {
1332 dbg(": MEM Resources:\n");
1333 print_pci_resource (func->mem_head);
1334 }
1335 if (func->p_mem_head) {
1336 dbg(": PMEM Resources:\n");
1337 print_pci_resource (func->p_mem_head);
1338 }
1339}
1340
1341static void shpchprm_dump_ctrl_res( struct controller *ctlr)
1342{
1343 struct controller *ctrl = ctlr;
1344
1345 if (ctrl->bus_head) {
1346 dbg(": BUS Resources:\n");
1347 print_pci_resource (ctrl->bus_head);
1348 }
1349 if (ctrl->io_head) {
1350 dbg(": IO Resources:\n");
1351 print_pci_resource (ctrl->io_head);
1352 }
1353 if (ctrl->mem_head) {
1354 dbg(": MEM Resources:\n");
1355 print_pci_resource (ctrl->mem_head);
1356 }
1357 if (ctrl->p_mem_head) {
1358 dbg(": PMEM Resources:\n");
1359 print_pci_resource (ctrl->p_mem_head);
1360 }
1361}
1362
1363static int shpchprm_get_used_resources (
1364 struct controller *ctrl,
1365 struct pci_func *func
1366 )
1367{
1368 return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
1369}
1370
1371static int configure_existing_function(
1372 struct controller *ctrl,
1373 struct pci_func *func
1374 )
1375{
1376 int rc;
1377
1378 /* see how much resources the func has used. */
1379 rc = shpchprm_get_used_resources (ctrl, func);
1380
1381 if (!rc) {
1382 /* subtract the resources used by the func from ctrl resources */
1383 rc = shpchprm_delete_resources (&ctrl->bus_head, func->bus_head);
1384 rc |= shpchprm_delete_resources (&ctrl->io_head, func->io_head);
1385 rc |= shpchprm_delete_resources (&ctrl->mem_head, func->mem_head);
1386 rc |= shpchprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1387 if (rc)
1388 warn("aCEF: cannot del used resources\n");
1389 } else
1390 err("aCEF: cannot get used resources\n");
1391
1392 return rc;
1393}
1394
1395static int bind_pci_resources_to_slots ( struct controller *ctrl)
1396{
1397 struct pci_func *func, new_func;
1398 int busn = ctrl->slot_bus;
1399 int devn, funn;
1400 u32 vid;
1401
1402 for (devn = 0; devn < 32; devn++) {
1403 for (funn = 0; funn < 8; funn++) {
1404 /*
1405 if (devn == ctrl->device && funn == ctrl->function)
1406 continue;
1407 */
1408 /* find out if this entry is for an occupied slot */
1409 vid = 0xFFFFFFFF;
1410 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1411
1412 if (vid != 0xFFFFFFFF) {
1413 func = shpchp_slot_find(busn, devn, funn);
1414 if (!func) {
1415 memset(&new_func, 0, sizeof(struct pci_func));
1416 new_func.bus = busn;
1417 new_func.device = devn;
1418 new_func.function = funn;
1419 new_func.is_a_board = 1;
1420 configure_existing_function(ctrl, &new_func);
1421 shpchprm_dump_func_res(&new_func);
1422 } else {
1423 configure_existing_function(ctrl, func);
1424 shpchprm_dump_func_res(func);
1425 }
1426 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1427 }
1428 }
1429 }
1430
1431 return 0;
1432}
1433
1434static int bind_pci_resources(
1435 struct controller *ctrl,
1436 struct acpi_bridge *ab
1437 )
1438{
1439 int status = 0;
1440
1441 if (ab->bus_head) {
1442 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1443 status = shpchprm_add_resources (&ctrl->bus_head, ab->bus_head);
1444 if (shpchprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1445 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1446 if (status) {
1447 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1448 return status;
1449 }
1450 } else
1451 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1452
1453 if (ab->io_head) {
1454 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1455 status = shpchprm_add_resources (&ctrl->io_head, ab->io_head);
1456 if (shpchprm_delete_resources (&ab->io_head, ctrl->io_head))
1457 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1458 if (status) {
1459 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1460 return status;
1461 }
1462 } else
1463 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1464
1465 if (ab->mem_head) {
1466 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1467 status = shpchprm_add_resources (&ctrl->mem_head, ab->mem_head);
1468 if (shpchprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1469 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1470 if (status) {
1471 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1472 return status;
1473 }
1474 } else
1475 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1476
1477 if (ab->p_mem_head) {
1478 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1479 status = shpchprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1480 if (shpchprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1481 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1482 if (status) {
1483 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1484 return status;
1485 }
1486 } else
1487 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1488
1489 return status;
1490}
1491
1492static int no_pci_resources( struct acpi_bridge *ab)
1493{
1494 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1495}
1496
1497static int find_pci_bridge_resources (
1498 struct controller *ctrl,
1499 struct acpi_bridge *ab
1500 )
1501{
1502 int rc = 0;
1503 struct pci_func func;
1504
1505 memset(&func, 0, sizeof(struct pci_func));
1506
1507 func.bus = ab->pbus;
1508 func.device = ab->pdevice;
1509 func.function = ab->pfunction;
1510 func.is_a_board = 1;
1511
1512 /* Get used resources for this PCI bridge */
1513 rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1514
1515 ab->io_head = func.io_head;
1516 ab->mem_head = func.mem_head;
1517 ab->p_mem_head = func.p_mem_head;
1518 ab->bus_head = func.bus_head;
1519 if (ab->bus_head)
1520 shpchprm_delete_resource(&ab->bus_head, ctrl->bus, 1);
1521
1522 return rc;
1523}
1524
1525static int get_pci_resources_from_bridge(
1526 struct controller *ctrl,
1527 struct acpi_bridge *ab
1528 )
1529{
1530 int rc = 0;
1531
1532 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1533
1534 rc = find_pci_bridge_resources (ctrl, ab);
1535
1536 shpchp_resource_sort_and_combine(&ab->bus_head);
1537 shpchp_resource_sort_and_combine(&ab->io_head);
1538 shpchp_resource_sort_and_combine(&ab->mem_head);
1539 shpchp_resource_sort_and_combine(&ab->p_mem_head);
1540
1541 shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
1542 shpchprm_add_resources (&ab->tio_head, ab->io_head);
1543 shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
1544 shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1545
1546 return rc;
1547}
1548
1549static int get_pci_resources(
1550 struct controller *ctrl,
1551 struct acpi_bridge *ab
1552 )
1553{
1554 int rc = 0;
1555
1556 if (no_pci_resources(ab)) {
1557 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1558 rc = get_pci_resources_from_bridge(ctrl, ab);
1559 }
1560
1561 return rc;
1562}
1563
1564int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
1565{
1566 int offset = devnum - ctrl->slot_device_offset;
1567
1568 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
1569 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
1570 return 0;
1571}
1572
1573/*
1574 * Get resources for this ctrl.
1575 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1576 * 2. find used resources of existing adapters
1577 * 3. subtract used resources from total resources
1578 */
1579int shpchprm_find_available_resources( struct controller *ctrl)
1580{
1581 int rc = 0;
1582 struct acpi_bridge *ab;
1583
1584 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1585 if (!ab) {
1586 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1587 return -1;
1588 }
1589 if (no_pci_resources(ab)) {
1590 rc = get_pci_resources(ctrl, ab);
1591 if (rc) {
1592 err("pfar:cannot get pci resources of PCI 0x%x.\n",ctrl->pci_dev->subordinate->number);
1593 return -1;
1594 }
1595 }
1596
1597 rc = bind_pci_resources(ctrl, ab);
1598 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1599 shpchprm_dump_ctrl_res(ctrl);
1600
1601 bind_pci_resources_to_slots (ctrl);
1602
1603 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1604 shpchprm_dump_ctrl_res(ctrl);
1605
1606 return rc;
1607}
1608
1609int shpchprm_set_hpp(
1610 struct controller *ctrl,
1611 struct pci_func *func,
1612 u8 card_type
1613 )
1614{
1615 struct acpi_bridge *ab;
1616 struct pci_bus lpci_bus, *pci_bus;
1617 int rc = 0;
1618 unsigned int devfn;
1619 u8 cls= 0x08; /* default cache line size */
1620 u8 lt = 0x40; /* default latency timer */
1621 u8 ep = 0;
1622 u8 es = 0;
1623
1624 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1625 pci_bus = &lpci_bus;
1626 pci_bus->number = func->bus;
1627 devfn = PCI_DEVFN(func->device, func->function);
1628
1629 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1630
1631 if (ab) {
1632 if (ab->_hpp) {
1633 lt = (u8)ab->_hpp->latency_timer;
1634 cls = (u8)ab->_hpp->cache_line_size;
1635 ep = (u8)ab->_hpp->enable_perr;
1636 es = (u8)ab->_hpp->enable_serr;
1637 } else
1638 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1639 } else
1640 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1641
1642
1643 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1644 /* set subordinate Latency Timer */
1645 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1646 }
1647
1648 /* set base Latency Timer */
1649 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1650 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1651
1652 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1653 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1654
1655 return rc;
1656}
1657
1658void shpchprm_enable_card(
1659 struct controller *ctrl,
1660 struct pci_func *func,
1661 u8 card_type)
1662{
1663 u16 command, cmd, bcommand, bcmd;
1664 struct pci_bus lpci_bus, *pci_bus;
1665 struct acpi_bridge *ab;
1666 unsigned int devfn;
1667 int rc;
1668
1669 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1670 pci_bus = &lpci_bus;
1671 pci_bus->number = func->bus;
1672 devfn = PCI_DEVFN(func->device, func->function);
1673
1674 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
1675
1676 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1677 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
1678 }
1679
1680 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1681 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1682 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
1683
1684 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1685 if (ab) {
1686 if (ab->_hpp) {
1687 if (ab->_hpp->enable_perr) {
1688 command |= PCI_COMMAND_PARITY;
1689 bcommand |= PCI_BRIDGE_CTL_PARITY;
1690 } else {
1691 command &= ~PCI_COMMAND_PARITY;
1692 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1693 }
1694 if (ab->_hpp->enable_serr) {
1695 command |= PCI_COMMAND_SERR;
1696 bcommand |= PCI_BRIDGE_CTL_SERR;
1697 } else {
1698 command &= ~PCI_COMMAND_SERR;
1699 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1700 }
1701 } else
1702 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1703 } else
1704 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1705
1706 if (command != cmd) {
1707 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1708 }
1709 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1710 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1711 }
1712}
1713
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
new file mode 100644
index 000000000000..37fa77a98289
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -0,0 +1,439 @@
1/*
2 * SHPCHPRM Legacy: 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>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "shpchp.h"
41#include "shpchprm.h"
42#include "shpchprm_legacy.h"
43
44static void __iomem *shpchp_rom_start;
45static u16 unused_IRQ;
46
47void shpchprm_cleanup(void)
48{
49 if (shpchp_rom_start)
50 iounmap(shpchp_rom_start);
51}
52
53int shpchprm_print_pirt(void)
54{
55 return 0;
56}
57
58int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
59{
60 int offset = devnum - ctrl->slot_device_offset;
61
62 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
63 return 0;
64}
65
66/* Find the Hot Plug Resource Table in the specified region of memory */
67static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
68{
69 void __iomem *fp;
70 void __iomem *endp;
71 u8 temp1, temp2, temp3, temp4;
72 int status = 0;
73
74 endp = (end - sizeof(struct hrt) + 1);
75
76 for (fp = begin; fp <= endp; fp += 16) {
77 temp1 = readb(fp + SIG0);
78 temp2 = readb(fp + SIG1);
79 temp3 = readb(fp + SIG2);
80 temp4 = readb(fp + SIG3);
81 if (temp1 == '$' && temp2 == 'H' && temp3 == 'R' && temp4 == 'T') {
82 status = 1;
83 break;
84 }
85 }
86
87 if (!status)
88 fp = NULL;
89
90 dbg("Discovered Hotplug Resource Table at %p\n", fp);
91 return fp;
92}
93
94/*
95 * shpchprm_find_available_resources
96 *
97 * Finds available memory, IO, and IRQ resources for programming
98 * devices which may be added to the system
99 * this function is for hot plug ADD!
100 *
101 * returns 0 if success
102 */
103int shpchprm_find_available_resources(struct controller *ctrl)
104{
105 u8 populated_slot;
106 u8 bridged_slot;
107 void __iomem *one_slot;
108 struct pci_func *func = NULL;
109 int i = 10, index = 0;
110 u32 temp_dword, rc;
111 ulong temp_ulong;
112 struct pci_resource *mem_node;
113 struct pci_resource *p_mem_node;
114 struct pci_resource *io_node;
115 struct pci_resource *bus_node;
116 void __iomem *rom_resource_table;
117 struct pci_bus lpci_bus, *pci_bus;
118 u8 cfgspc_irq, temp;
119
120 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
121 pci_bus = &lpci_bus;
122 rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_rom_start + 0xffff);
123 dbg("rom_resource_table = %p\n", rom_resource_table);
124 if (rom_resource_table == NULL)
125 return -ENODEV;
126
127 /* Sum all resources and setup resource maps */
128 unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
129 dbg("unused_IRQ = %x\n", unused_IRQ);
130
131 temp = 0;
132 while (unused_IRQ) {
133 if (unused_IRQ & 1) {
134 shpchp_disk_irq = temp;
135 break;
136 }
137 unused_IRQ = unused_IRQ >> 1;
138 temp++;
139 }
140
141 dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq);
142 unused_IRQ = unused_IRQ >> 1;
143 temp++;
144
145 while (unused_IRQ) {
146 if (unused_IRQ & 1) {
147 shpchp_nic_irq = temp;
148 break;
149 }
150 unused_IRQ = unused_IRQ >> 1;
151 temp++;
152 }
153
154 dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq);
155 unused_IRQ = readl(rom_resource_table + PCIIRQ);
156
157 temp = 0;
158
159 pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq);
160
161 if (!shpchp_nic_irq) {
162 shpchp_nic_irq = cfgspc_irq;
163 }
164
165 if (!shpchp_disk_irq) {
166 shpchp_disk_irq = cfgspc_irq;
167 }
168
169 dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq);
170
171 one_slot = rom_resource_table + sizeof(struct hrt);
172
173 i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
174 dbg("number_of_entries = %d\n", i);
175
176 if (!readb(one_slot + SECONDARY_BUS))
177 return (1);
178
179 dbg("dev|IO base|length|MEMbase|length|PM base|length|PB SB MB\n");
180
181 while (i && readb(one_slot + SECONDARY_BUS)) {
182 u8 dev_func = readb(one_slot + DEV_FUNC);
183 u8 primary_bus = readb(one_slot + PRIMARY_BUS);
184 u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
185 u8 max_bus = readb(one_slot + MAX_BUS);
186 u16 io_base = readw(one_slot + IO_BASE);
187 u16 io_length = readw(one_slot + IO_LENGTH);
188 u16 mem_base = readw(one_slot + MEM_BASE);
189 u16 mem_length = readw(one_slot + MEM_LENGTH);
190 u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
191 u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
192
193 dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
194 dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
195 primary_bus, secondary_bus, max_bus);
196
197 /* If this entry isn't for our controller's bus, ignore it */
198 if (primary_bus != ctrl->slot_bus) {
199 i--;
200 one_slot += sizeof(struct slot_rt);
201 continue;
202 }
203 /* find out if this entry is for an occupied slot */
204 temp_dword = 0xFFFFFFFF;
205 pci_bus->number = primary_bus;
206 pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
207
208 dbg("temp_D_word = %x\n", temp_dword);
209
210 if (temp_dword != 0xFFFFFFFF) {
211 index = 0;
212 func = shpchp_slot_find(primary_bus, dev_func >> 3, 0);
213
214 while (func && (func->function != (dev_func & 0x07))) {
215 dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index);
216 func = shpchp_slot_find(primary_bus, dev_func >> 3, index++);
217 }
218
219 /* If we can't find a match, skip this table entry */
220 if (!func) {
221 i--;
222 one_slot += sizeof(struct slot_rt);
223 continue;
224 }
225 /* this may not work and shouldn't be used */
226 if (secondary_bus != primary_bus)
227 bridged_slot = 1;
228 else
229 bridged_slot = 0;
230
231 populated_slot = 1;
232 } else {
233 populated_slot = 0;
234 bridged_slot = 0;
235 }
236 dbg("slot populated =%s \n", populated_slot?"yes":"no");
237
238 /* If we've got a valid IO base, use it */
239
240 temp_ulong = io_base + io_length;
241
242 if ((io_base) && (temp_ulong <= 0x10000)) {
243 io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
244 if (!io_node)
245 return -ENOMEM;
246
247 io_node->base = (ulong)io_base;
248 io_node->length = (ulong)io_length;
249 dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
250
251 if (!populated_slot) {
252 io_node->next = ctrl->io_head;
253 ctrl->io_head = io_node;
254 } else {
255 io_node->next = func->io_head;
256 func->io_head = io_node;
257 }
258 }
259
260 /* If we've got a valid memory base, use it */
261 temp_ulong = mem_base + mem_length;
262 if ((mem_base) && (temp_ulong <= 0x10000)) {
263 mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
264 if (!mem_node)
265 return -ENOMEM;
266
267 mem_node->base = (ulong)mem_base << 16;
268 mem_node->length = (ulong)(mem_length << 16);
269 dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
270
271 if (!populated_slot) {
272 mem_node->next = ctrl->mem_head;
273 ctrl->mem_head = mem_node;
274 } else {
275 mem_node->next = func->mem_head;
276 func->mem_head = mem_node;
277 }
278 }
279
280 /*
281 * If we've got a valid prefetchable memory base, and
282 * the base + length isn't greater than 0xFFFF
283 */
284 temp_ulong = pre_mem_base + pre_mem_length;
285 if ((pre_mem_base) && (temp_ulong <= 0x10000)) {
286 p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
287 if (!p_mem_node)
288 return -ENOMEM;
289
290 p_mem_node->base = (ulong)pre_mem_base << 16;
291 p_mem_node->length = (ulong)pre_mem_length << 16;
292 dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
293
294 if (!populated_slot) {
295 p_mem_node->next = ctrl->p_mem_head;
296 ctrl->p_mem_head = p_mem_node;
297 } else {
298 p_mem_node->next = func->p_mem_head;
299 func->p_mem_head = p_mem_node;
300 }
301 }
302
303 /*
304 * If we've got a valid bus number, use it
305 * The second condition is to ignore bus numbers on
306 * populated slots that don't have PCI-PCI bridges
307 */
308 if (secondary_bus && (secondary_bus != primary_bus)) {
309 bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
310 if (!bus_node)
311 return -ENOMEM;
312
313 bus_node->base = (ulong)secondary_bus;
314 bus_node->length = (ulong)(max_bus - secondary_bus + 1);
315 dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
316
317 if (!populated_slot) {
318 bus_node->next = ctrl->bus_head;
319 ctrl->bus_head = bus_node;
320 } else {
321 bus_node->next = func->bus_head;
322 func->bus_head = bus_node;
323 }
324 }
325
326 i--;
327 one_slot += sizeof(struct slot_rt);
328 }
329
330 /* If all of the following fail, we don't have any resources for hot plug add */
331 rc = 1;
332 rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
333 rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
334 rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
335 rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
336
337 return (rc);
338}
339
340int shpchprm_set_hpp(
341 struct controller *ctrl,
342 struct pci_func *func,
343 u8 card_type)
344{
345 u32 rc;
346 u8 temp_byte;
347 struct pci_bus lpci_bus, *pci_bus;
348 unsigned int devfn;
349 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
350 pci_bus = &lpci_bus;
351 pci_bus->number = func->bus;
352 devfn = PCI_DEVFN(func->device, func->function);
353
354 temp_byte = 0x40; /* hard coded value for LT */
355 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
356 /* set subordinate Latency Timer */
357 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
358 if (rc) {
359 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
360 func->device, func->function);
361 return rc;
362 }
363 }
364
365 /* set base Latency Timer */
366 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
367 if (rc) {
368 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
369 return rc;
370 }
371
372 /* set Cache Line size */
373 temp_byte = 0x08; /* hard coded value for CLS */
374 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
375 if (rc) {
376 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
377 }
378
379 /* set enable_perr */
380 /* set enable_serr */
381
382 return rc;
383}
384
385void shpchprm_enable_card(
386 struct controller *ctrl,
387 struct pci_func *func,
388 u8 card_type)
389{
390 u16 command, bcommand;
391 struct pci_bus lpci_bus, *pci_bus;
392 unsigned int devfn;
393 int rc;
394
395 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
396 pci_bus = &lpci_bus;
397 pci_bus->number = func->bus;
398 devfn = PCI_DEVFN(func->device, func->function);
399
400 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
401 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
402 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
403 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
404 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
405
406 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
407 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
408 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
409 | PCI_BRIDGE_CTL_NO_ISA;
410 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
411 }
412}
413
414static int legacy_shpchprm_init_pci(void)
415{
416 shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
417 if (!shpchp_rom_start) {
418 err("Could not ioremap memory region for ROM\n");
419 return -EIO;
420 }
421
422 return 0;
423}
424
425int shpchprm_init(enum php_ctlr_type ctrl_type)
426{
427 int retval;
428
429 switch (ctrl_type) {
430 case PCI:
431 retval = legacy_shpchprm_init_pci();
432 break;
433 default:
434 retval = -ENODEV;
435 break;
436 }
437
438 return retval;
439}
diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h
new file mode 100644
index 000000000000..29ccea5e57e5
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_legacy.h
@@ -0,0 +1,113 @@
1/*
2 * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT
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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_LEGACY_H_
31#define _SHPCHPRM_LEGACY_H_
32
33#define ROM_PHY_ADDR 0x0F0000
34#define ROM_PHY_LEN 0x00FFFF
35
36struct slot_rt {
37 u8 dev_func;
38 u8 primary_bus;
39 u8 secondary_bus;
40 u8 max_bus;
41 u16 io_base;
42 u16 io_length;
43 u16 mem_base;
44 u16 mem_length;
45 u16 pre_mem_base;
46 u16 pre_mem_length;
47} __attribute__ ((packed));
48
49/* offsets to the hotplug slot resource table registers based on the above structure layout */
50enum slot_rt_offsets {
51 DEV_FUNC = offsetof(struct slot_rt, dev_func),
52 PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
53 SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
54 MAX_BUS = offsetof(struct slot_rt, max_bus),
55 IO_BASE = offsetof(struct slot_rt, io_base),
56 IO_LENGTH = offsetof(struct slot_rt, io_length),
57 MEM_BASE = offsetof(struct slot_rt, mem_base),
58 MEM_LENGTH = offsetof(struct slot_rt, mem_length),
59 PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
60 PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
61};
62
63struct hrt {
64 char sig0;
65 char sig1;
66 char sig2;
67 char sig3;
68 u16 unused_IRQ;
69 u16 PCIIRQ;
70 u8 number_of_entries;
71 u8 revision;
72 u16 reserved1;
73 u32 reserved2;
74} __attribute__ ((packed));
75
76/* offsets to the hotplug resource table registers based on the above structure layout */
77enum hrt_offsets {
78 SIG0 = offsetof(struct hrt, sig0),
79 SIG1 = offsetof(struct hrt, sig1),
80 SIG2 = offsetof(struct hrt, sig2),
81 SIG3 = offsetof(struct hrt, sig3),
82 UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
83 PCIIRQ = offsetof(struct hrt, PCIIRQ),
84 NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
85 REVISION = offsetof(struct hrt, revision),
86 HRT_RESERVED1 = offsetof(struct hrt, reserved1),
87 HRT_RESERVED2 = offsetof(struct hrt, reserved2),
88};
89
90struct irq_info {
91 u8 bus, devfn; /* bus, device and function */
92 struct {
93 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
94 u16 bitmap; /* Available IRQs */
95 } __attribute__ ((packed)) irq[4];
96 u8 slot; /* slot number, 0=onboard */
97 u8 rfu;
98} __attribute__ ((packed));
99
100struct irq_routing_table {
101 u32 signature; /* PIRQ_SIGNATURE should be here */
102 u16 version; /* PIRQ_VERSION */
103 u16 size; /* Table size in bytes */
104 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
105 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
106 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
107 u32 miniport_data; /* Crap */
108 u8 rfu[11];
109 u8 checksum; /* Modulo 256 checksum must give zero */
110 struct irq_info slots[0];
111} __attribute__ ((packed));
112
113#endif /* _SHPCHPRM_LEGACY_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
new file mode 100644
index 000000000000..88f4d9f41886
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -0,0 +1,434 @@
1/*
2 * SHPCHPRM 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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "shpchp.h"
41#include "shpchprm.h"
42#include "shpchprm_nonacpi.h"
43
44void shpchprm_cleanup(void)
45{
46 return;
47}
48
49int shpchprm_print_pirt(void)
50{
51 return 0;
52}
53
54int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
55{
56 int offset = devnum - ctrl->slot_device_offset;
57
58 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
59 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
60 return 0;
61}
62
63static void print_pci_resource ( struct pci_resource *aprh)
64{
65 struct pci_resource *res;
66
67 for (res = aprh; res; res = res->next)
68 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
69}
70
71
72static void phprm_dump_func_res( struct pci_func *fun)
73{
74 struct pci_func *func = fun;
75
76 if (func->bus_head) {
77 dbg(": BUS Resources:\n");
78 print_pci_resource (func->bus_head);
79 }
80 if (func->io_head) {
81 dbg(": IO Resources:\n");
82 print_pci_resource (func->io_head);
83 }
84 if (func->mem_head) {
85 dbg(": MEM Resources:\n");
86 print_pci_resource (func->mem_head);
87 }
88 if (func->p_mem_head) {
89 dbg(": PMEM Resources:\n");
90 print_pci_resource (func->p_mem_head);
91 }
92}
93
94static int phprm_get_used_resources (
95 struct controller *ctrl,
96 struct pci_func *func
97 )
98{
99 return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
100}
101
102static int phprm_delete_resource(
103 struct pci_resource **aprh,
104 ulong base,
105 ulong size)
106{
107 struct pci_resource *res;
108 struct pci_resource *prevnode;
109 struct pci_resource *split_node;
110 ulong tbase;
111
112 shpchp_resource_sort_and_combine(aprh);
113
114 for (res = *aprh; res; res = res->next) {
115 if (res->base > base)
116 continue;
117
118 if ((res->base + res->length) < (base + size))
119 continue;
120
121 if (res->base < base) {
122 tbase = base;
123
124 if ((res->length - (tbase - res->base)) < size)
125 continue;
126
127 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
128 if (!split_node)
129 return -ENOMEM;
130
131 split_node->base = res->base;
132 split_node->length = tbase - res->base;
133 res->base = tbase;
134 res->length -= split_node->length;
135
136 split_node->next = res->next;
137 res->next = split_node;
138 }
139
140 if (res->length >= size) {
141 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
142 if (!split_node)
143 return -ENOMEM;
144
145 split_node->base = res->base + size;
146 split_node->length = res->length - size;
147 res->length = size;
148
149 split_node->next = res->next;
150 res->next = split_node;
151 }
152
153 if (*aprh == res) {
154 *aprh = res->next;
155 } else {
156 prevnode = *aprh;
157 while (prevnode->next != res)
158 prevnode = prevnode->next;
159
160 prevnode->next = res->next;
161 }
162 res->next = NULL;
163 kfree(res);
164 break;
165 }
166
167 return 0;
168}
169
170
171static int phprm_delete_resources(
172 struct pci_resource **aprh,
173 struct pci_resource *this
174 )
175{
176 struct pci_resource *res;
177
178 for (res = this; res; res = res->next)
179 phprm_delete_resource(aprh, res->base, res->length);
180
181 return 0;
182}
183
184
185static int configure_existing_function(
186 struct controller *ctrl,
187 struct pci_func *func
188 )
189{
190 int rc;
191
192 /* see how much resources the func has used. */
193 rc = phprm_get_used_resources (ctrl, func);
194
195 if (!rc) {
196 /* subtract the resources used by the func from ctrl resources */
197 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
198 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
199 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
200 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
201 if (rc)
202 warn("aCEF: cannot del used resources\n");
203 } else
204 err("aCEF: cannot get used resources\n");
205
206 return rc;
207}
208
209static int bind_pci_resources_to_slots ( struct controller *ctrl)
210{
211 struct pci_func *func, new_func;
212 int busn = ctrl->slot_bus;
213 int devn, funn;
214 u32 vid;
215
216 for (devn = 0; devn < 32; devn++) {
217 for (funn = 0; funn < 8; funn++) {
218 /*
219 if (devn == ctrl->device && funn == ctrl->function)
220 continue;
221 */
222 /* find out if this entry is for an occupied slot */
223 vid = 0xFFFFFFFF;
224
225 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
226
227 if (vid != 0xFFFFFFFF) {
228 func = shpchp_slot_find(busn, devn, funn);
229 if (!func) {
230 memset(&new_func, 0, sizeof(struct pci_func));
231 new_func.bus = busn;
232 new_func.device = devn;
233 new_func.function = funn;
234 new_func.is_a_board = 1;
235 configure_existing_function(ctrl, &new_func);
236 phprm_dump_func_res(&new_func);
237 } else {
238 configure_existing_function(ctrl, func);
239 phprm_dump_func_res(func);
240 }
241 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
242 }
243 }
244 }
245
246 return 0;
247}
248
249static void phprm_dump_ctrl_res( struct controller *ctlr)
250{
251 struct controller *ctrl = ctlr;
252
253 if (ctrl->bus_head) {
254 dbg(": BUS Resources:\n");
255 print_pci_resource (ctrl->bus_head);
256 }
257 if (ctrl->io_head) {
258 dbg(": IO Resources:\n");
259 print_pci_resource (ctrl->io_head);
260 }
261 if (ctrl->mem_head) {
262 dbg(": MEM Resources:\n");
263 print_pci_resource (ctrl->mem_head);
264 }
265 if (ctrl->p_mem_head) {
266 dbg(": PMEM Resources:\n");
267 print_pci_resource (ctrl->p_mem_head);
268 }
269}
270
271/*
272 * phprm_find_available_resources
273 *
274 * Finds available memory, IO, and IRQ resources for programming
275 * devices which may be added to the system
276 * this function is for hot plug ADD!
277 *
278 * returns 0 if success
279 */
280int shpchprm_find_available_resources(struct controller *ctrl)
281{
282 struct pci_func func;
283 u32 rc;
284
285 memset(&func, 0, sizeof(struct pci_func));
286
287 func.bus = ctrl->bus;
288 func.device = ctrl->device;
289 func.function = ctrl->function;
290 func.is_a_board = 1;
291
292 /* Get resources for this PCI bridge */
293 rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
294 dbg("%s: shpchp_save_used_resources rc = %d\n", __FUNCTION__, rc);
295
296 if (func.mem_head)
297 func.mem_head->next = ctrl->mem_head;
298 ctrl->mem_head = func.mem_head;
299
300 if (func.p_mem_head)
301 func.p_mem_head->next = ctrl->p_mem_head;
302 ctrl->p_mem_head = func.p_mem_head;
303
304 if (func.io_head)
305 func.io_head->next = ctrl->io_head;
306 ctrl->io_head = func.io_head;
307
308 if(func.bus_head)
309 func.bus_head->next = ctrl->bus_head;
310 ctrl->bus_head = func.bus_head;
311 if (ctrl->bus_head)
312 phprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
313
314 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
315 phprm_dump_ctrl_res(ctrl);
316 bind_pci_resources_to_slots (ctrl);
317
318 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
319 phprm_dump_ctrl_res(ctrl);
320
321
322 /* If all of the following fail, we don't have any resources for hot plug add */
323 rc = 1;
324 rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
325 rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
326 rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
327 rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
328
329 return (rc);
330}
331
332int shpchprm_set_hpp(
333 struct controller *ctrl,
334 struct pci_func *func,
335 u8 card_type)
336{
337 u32 rc;
338 u8 temp_byte;
339 struct pci_bus lpci_bus, *pci_bus;
340 unsigned int devfn;
341 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
342 pci_bus = &lpci_bus;
343 pci_bus->number = func->bus;
344 devfn = PCI_DEVFN(func->device, func->function);
345
346 temp_byte = 0x40; /* hard coded value for LT */
347 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
348 /* set subordinate Latency Timer */
349 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
350
351 if (rc) {
352 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
353 func->device, func->function);
354 return rc;
355 }
356 }
357
358 /* set base Latency Timer */
359 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
360
361 if (rc) {
362 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
363 return rc;
364 }
365
366 /* set Cache Line size */
367 temp_byte = 0x08; /* hard coded value for CLS */
368
369 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
370
371 if (rc) {
372 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
373 }
374
375 /* set enable_perr */
376 /* set enable_serr */
377
378 return rc;
379}
380
381void shpchprm_enable_card(
382 struct controller *ctrl,
383 struct pci_func *func,
384 u8 card_type)
385{
386 u16 command, bcommand;
387 struct pci_bus lpci_bus, *pci_bus;
388 unsigned int devfn;
389 int rc;
390
391 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
392 pci_bus = &lpci_bus;
393 pci_bus->number = func->bus;
394 devfn = PCI_DEVFN(func->device, func->function);
395
396 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
397
398 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
399 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
400 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
401
402 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
403
404 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
405
406 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
407
408 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
409 | PCI_BRIDGE_CTL_NO_ISA;
410
411 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
412 }
413}
414
415static int legacy_shpchprm_init_pci(void)
416{
417 return 0;
418}
419
420int shpchprm_init(enum php_ctlr_type ctrl_type)
421{
422 int retval;
423
424 switch (ctrl_type) {
425 case PCI:
426 retval = legacy_shpchprm_init_pci();
427 break;
428 default:
429 retval = -ENODEV;
430 break;
431 }
432
433 return retval;
434}
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h
new file mode 100644
index 000000000000..6bc8668023c3
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.h
@@ -0,0 +1,56 @@
1/*
2 * SHPCHPRM 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>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_NONACPI_H_
31#define _SHPCHPRM_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 /* _SHPCHPRM_NONACPI_H_ */