diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-09-27 12:59:19 -0400 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-09-27 12:59:19 -0400 |
commit | da3420fcd62a8967c14a586355e322253a1504a8 (patch) | |
tree | 0aab4d1578097b098f580af3b5d30b88395eddfd /arch/ppc64/kernel/iSeries_VpdInfo.c | |
parent | cb4cf8056ead24ef0595859952319e2a608d5e07 (diff) |
powerpc: Move iSeries_VpdInfo.c to powerpc/platforms/iseries
And rename it to vpdinfo.c.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Diffstat (limited to 'arch/ppc64/kernel/iSeries_VpdInfo.c')
-rw-r--r-- | arch/ppc64/kernel/iSeries_VpdInfo.c | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c deleted file mode 100644 index 5d921792571f..000000000000 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
1 | /* | ||
2 | * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. | ||
3 | * | ||
4 | * This code gets the card location of the hardware | ||
5 | * Copyright (C) 2001 <Allan H Trautman> <IBM Corp> | ||
6 | * Copyright (C) 2005 Stephen Rothwel, IBM Corp | ||
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 | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more 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: | ||
20 | * Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, | ||
22 | * Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | * Change Activity: | ||
25 | * Created, Feb 2, 2001 | ||
26 | * Ported to ppc64, August 20, 2001 | ||
27 | * End Change Activity | ||
28 | */ | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <asm/types.h> | ||
33 | #include <asm/resource.h> | ||
34 | |||
35 | #include <asm/iSeries/HvCallPci.h> | ||
36 | #include <asm/iSeries/HvTypes.h> | ||
37 | #include <asm/iSeries/iSeries_pci.h> | ||
38 | |||
39 | /* | ||
40 | * Size of Bus VPD data | ||
41 | */ | ||
42 | #define BUS_VPDSIZE 1024 | ||
43 | |||
44 | /* | ||
45 | * Bus Vpd Tags | ||
46 | */ | ||
47 | #define VpdEndOfAreaTag 0x79 | ||
48 | #define VpdIdStringTag 0x82 | ||
49 | #define VpdVendorAreaTag 0x84 | ||
50 | |||
51 | /* | ||
52 | * Mfg Area Tags | ||
53 | */ | ||
54 | #define VpdFruFrameId 0x4649 // "FI" | ||
55 | #define VpdSlotMapFormat 0x4D46 // "MF" | ||
56 | #define VpdSlotMap 0x534D // "SM" | ||
57 | |||
58 | /* | ||
59 | * Structures of the areas | ||
60 | */ | ||
61 | struct MfgVpdAreaStruct { | ||
62 | u16 Tag; | ||
63 | u8 TagLength; | ||
64 | u8 AreaData1; | ||
65 | u8 AreaData2; | ||
66 | }; | ||
67 | typedef struct MfgVpdAreaStruct MfgArea; | ||
68 | #define MFG_ENTRY_SIZE 3 | ||
69 | |||
70 | struct SlotMapStruct { | ||
71 | u8 AgentId; | ||
72 | u8 SecondaryAgentId; | ||
73 | u8 PhbId; | ||
74 | char CardLocation[3]; | ||
75 | char Parms[8]; | ||
76 | char Reserved[2]; | ||
77 | }; | ||
78 | typedef struct SlotMapStruct SlotMap; | ||
79 | #define SLOT_ENTRY_SIZE 16 | ||
80 | |||
81 | /* | ||
82 | * Parse the Slot Area | ||
83 | */ | ||
84 | static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | ||
85 | HvAgentId agent, u8 *PhbId, char card[4]) | ||
86 | { | ||
87 | int SlotMapLen = MapLen; | ||
88 | SlotMap *SlotMapPtr = MapPtr; | ||
89 | |||
90 | /* | ||
91 | * Parse Slot label until we find the one requested | ||
92 | */ | ||
93 | while (SlotMapLen > 0) { | ||
94 | if (SlotMapPtr->AgentId == agent) { | ||
95 | /* | ||
96 | * If Phb wasn't found, grab the entry first one found. | ||
97 | */ | ||
98 | if (*PhbId == 0xff) | ||
99 | *PhbId = SlotMapPtr->PhbId; | ||
100 | /* Found it, extract the data. */ | ||
101 | if (SlotMapPtr->PhbId == *PhbId) { | ||
102 | memcpy(card, &SlotMapPtr->CardLocation, 3); | ||
103 | card[3] = 0; | ||
104 | break; | ||
105 | } | ||
106 | } | ||
107 | /* Point to the next Slot */ | ||
108 | SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE); | ||
109 | SlotMapLen -= SLOT_ENTRY_SIZE; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Parse the Mfg Area | ||
115 | */ | ||
116 | static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | ||
117 | HvAgentId agent, u8 *PhbId, | ||
118 | u8 *frame, char card[4]) | ||
119 | { | ||
120 | MfgArea *MfgAreaPtr = (MfgArea *)AreaData; | ||
121 | int MfgAreaLen = AreaLen; | ||
122 | u16 SlotMapFmt = 0; | ||
123 | |||
124 | /* Parse Mfg Data */ | ||
125 | while (MfgAreaLen > 0) { | ||
126 | int MfgTagLen = MfgAreaPtr->TagLength; | ||
127 | /* Frame ID (FI 4649020310 ) */ | ||
128 | if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ | ||
129 | *frame = MfgAreaPtr->AreaData1; | ||
130 | /* Slot Map Format (MF 4D46020004 ) */ | ||
131 | else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ | ||
132 | SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) | ||
133 | + MfgAreaPtr->AreaData2; | ||
134 | /* Slot Map (SM 534D90 */ | ||
135 | else if (MfgAreaPtr->Tag == VpdSlotMap) { /* SM */ | ||
136 | SlotMap *SlotMapPtr; | ||
137 | |||
138 | if (SlotMapFmt == 0x1004) | ||
139 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr | ||
140 | + MFG_ENTRY_SIZE + 1); | ||
141 | else | ||
142 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr | ||
143 | + MFG_ENTRY_SIZE); | ||
144 | iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, | ||
145 | agent, PhbId, card); | ||
146 | } | ||
147 | /* | ||
148 | * Point to the next Mfg Area | ||
149 | * Use defined size, sizeof give wrong answer | ||
150 | */ | ||
151 | MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen | ||
152 | + MFG_ENTRY_SIZE); | ||
153 | MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Look for "BUS".. Data is not Null terminated. | ||
159 | * PHBID of 0xFF indicates PHB was not found in VPD Data. | ||
160 | */ | ||
161 | static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | ||
162 | { | ||
163 | u8 *PhbPtr = AreaPtr; | ||
164 | int DataLen = AreaLength; | ||
165 | char PhbId = 0xFF; | ||
166 | |||
167 | while (DataLen > 0) { | ||
168 | if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U') | ||
169 | && (*(PhbPtr + 2) == 'S')) { | ||
170 | PhbPtr += 3; | ||
171 | while (*PhbPtr == ' ') | ||
172 | ++PhbPtr; | ||
173 | PhbId = (*PhbPtr & 0x0F); | ||
174 | break; | ||
175 | } | ||
176 | ++PhbPtr; | ||
177 | --DataLen; | ||
178 | } | ||
179 | return PhbId; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * Parse out the VPD Areas | ||
184 | */ | ||
185 | static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, | ||
186 | HvAgentId agent, u8 *frame, char card[4]) | ||
187 | { | ||
188 | u8 *TagPtr = VpdData; | ||
189 | int DataLen = VpdDataLen - 3; | ||
190 | u8 PhbId; | ||
191 | |||
192 | while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { | ||
193 | int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); | ||
194 | u8 *AreaData = TagPtr + 3; | ||
195 | |||
196 | if (*TagPtr == VpdIdStringTag) | ||
197 | PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); | ||
198 | else if (*TagPtr == VpdVendorAreaTag) | ||
199 | iSeries_Parse_MfgArea(AreaData, AreaLen, | ||
200 | agent, &PhbId, frame, card); | ||
201 | /* Point to next Area. */ | ||
202 | TagPtr = AreaData + AreaLen; | ||
203 | DataLen -= AreaLen; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, | ||
208 | u8 *frame, char card[4]) | ||
209 | { | ||
210 | int BusVpdLen = 0; | ||
211 | u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); | ||
212 | |||
213 | if (BusVpdPtr == NULL) { | ||
214 | printk("PCI: Bus VPD Buffer allocation failure.\n"); | ||
215 | return; | ||
216 | } | ||
217 | BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr), | ||
218 | BUS_VPDSIZE); | ||
219 | if (BusVpdLen == 0) { | ||
220 | printk("PCI: Bus VPD Buffer zero length.\n"); | ||
221 | goto out_free; | ||
222 | } | ||
223 | /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ | ||
224 | /* Make sure this is what I think it is */ | ||
225 | if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ | ||
226 | printk("PCI: Bus VPD Buffer missing starting tag.\n"); | ||
227 | goto out_free; | ||
228 | } | ||
229 | iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); | ||
230 | out_free: | ||
231 | kfree(BusVpdPtr); | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Prints the device information. | ||
236 | * - Pass in pci_dev* pointer to the device. | ||
237 | * - Pass in the device count | ||
238 | * | ||
239 | * Format: | ||
240 | * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet | ||
241 | * controller | ||
242 | */ | ||
243 | void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) | ||
244 | { | ||
245 | struct iSeries_Device_Node *DevNode = PciDev->sysdata; | ||
246 | u16 bus; | ||
247 | u8 frame; | ||
248 | char card[4]; | ||
249 | HvSubBusNumber subbus; | ||
250 | HvAgentId agent; | ||
251 | |||
252 | if (DevNode == NULL) { | ||
253 | printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n", | ||
254 | count); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | bus = ISERIES_BUS(DevNode); | ||
259 | subbus = ISERIES_SUBBUS(DevNode); | ||
260 | agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), | ||
261 | ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); | ||
262 | iSeries_Get_Location_Code(bus, agent, &frame, card); | ||
263 | |||
264 | printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", | ||
265 | count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, | ||
266 | frame, card); | ||
267 | printk("0x%04X\n", (int)(PciDev->class >> 8)); | ||
268 | } | ||