diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-06-21 20:15:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 21:46:30 -0400 |
commit | 061c063efce96b33f9e26d5f83a8eb0643fa493c (patch) | |
tree | 6e40638f187b5d1f540d0c777d2cdc4f83ccfbd0 /arch/ppc64/kernel/iSeries_VpdInfo.c | |
parent | a2ebaf250fabc5c5644b707dbee44c9e0ec442e9 (diff) |
[PATCH] ppc64 iSeries: remove some more members of iSeries_Device_Node
The AgentId, PhbId, FrameId, CardLocation and Location members of
iSeries_Device_Node are stored early in the boot process just so that a
message about the device can be printed later in the boot process. Remove
them and construct the message by doing the VPD parsing at the time the
message is printed.
Also remove a few unused defines in iSeries_VpdInfo.c.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/iSeries_VpdInfo.c')
-rw-r--r-- | arch/ppc64/kernel/iSeries_VpdInfo.c | 137 |
1 files changed, 67 insertions, 70 deletions
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index 9c89ce9a3d0b..d11c732daf81 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c | |||
@@ -44,7 +44,6 @@ | |||
44 | /* | 44 | /* |
45 | * Bus Vpd Tags | 45 | * Bus Vpd Tags |
46 | */ | 46 | */ |
47 | #define VpdEndOfDataTag 0x78 | ||
48 | #define VpdEndOfAreaTag 0x79 | 47 | #define VpdEndOfAreaTag 0x79 |
49 | #define VpdIdStringTag 0x82 | 48 | #define VpdIdStringTag 0x82 |
50 | #define VpdVendorAreaTag 0x84 | 49 | #define VpdVendorAreaTag 0x84 |
@@ -52,11 +51,8 @@ | |||
52 | /* | 51 | /* |
53 | * Mfg Area Tags | 52 | * Mfg Area Tags |
54 | */ | 53 | */ |
55 | #define VpdFruFlag 0x4647 // "FG" | ||
56 | #define VpdFruFrameId 0x4649 // "FI" | 54 | #define VpdFruFrameId 0x4649 // "FI" |
57 | #define VpdSlotMapFormat 0x4D46 // "MF" | 55 | #define VpdSlotMapFormat 0x4D46 // "MF" |
58 | #define VpdAsmPartNumber 0x504E // "PN" | ||
59 | #define VpdFruSerial 0x534E // "SN" | ||
60 | #define VpdSlotMap 0x534D // "SM" | 56 | #define VpdSlotMap 0x534D // "SM" |
61 | 57 | ||
62 | /* | 58 | /* |
@@ -83,48 +79,10 @@ typedef struct SlotMapStruct SlotMap; | |||
83 | #define SLOT_ENTRY_SIZE 16 | 79 | #define SLOT_ENTRY_SIZE 16 |
84 | 80 | ||
85 | /* | 81 | /* |
86 | * Formats the device information. | ||
87 | * - Pass in pci_dev* pointer to the device. | ||
88 | * - Pass in buffer to place the data. Danger here is the buffer must | ||
89 | * be as big as the client says it is. Should be at least 128 bytes. | ||
90 | * Return will the length of the string data put in the buffer. | ||
91 | * Format: | ||
92 | * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet | ||
93 | * controller | ||
94 | */ | ||
95 | int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer, | ||
96 | int BufferSize) | ||
97 | { | ||
98 | struct iSeries_Device_Node *DevNode = | ||
99 | (struct iSeries_Device_Node *)PciDev->sysdata; | ||
100 | int len; | ||
101 | |||
102 | if (DevNode == NULL) | ||
103 | return sprintf(buffer, | ||
104 | "PCI: iSeries_Device_Information DevNode is NULL"); | ||
105 | |||
106 | if (BufferSize < 128) | ||
107 | return 0; | ||
108 | |||
109 | len = sprintf(buffer, "PCI: Bus%3d, Device%3d, Vendor %04X ", | ||
110 | ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn), | ||
111 | PciDev->vendor); | ||
112 | len += sprintf(buffer + len, "Frame%3d, Card %4s ", | ||
113 | DevNode->FrameId, DevNode->CardLocation); | ||
114 | if (pci_class_name(PciDev->class >> 8) == 0) | ||
115 | len += sprintf(buffer + len, "0x%04X ", | ||
116 | (int)(PciDev->class >> 8)); | ||
117 | else | ||
118 | len += sprintf(buffer + len, "%s", | ||
119 | pci_class_name(PciDev->class >> 8)); | ||
120 | return len; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Parse the Slot Area | 82 | * Parse the Slot Area |
125 | */ | 83 | */ |
126 | static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | 84 | static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, |
127 | struct iSeries_Device_Node *DevNode) | 85 | HvAgentId agent, u8 *PhbId, char card[4]) |
128 | { | 86 | { |
129 | int SlotMapLen = MapLen; | 87 | int SlotMapLen = MapLen; |
130 | SlotMap *SlotMapPtr = MapPtr; | 88 | SlotMap *SlotMapPtr = MapPtr; |
@@ -133,17 +91,16 @@ static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | |||
133 | * Parse Slot label until we find the one requested | 91 | * Parse Slot label until we find the one requested |
134 | */ | 92 | */ |
135 | while (SlotMapLen > 0) { | 93 | while (SlotMapLen > 0) { |
136 | if (SlotMapPtr->AgentId == DevNode->AgentId ) { | 94 | if (SlotMapPtr->AgentId == agent) { |
137 | /* | 95 | /* |
138 | * If Phb wasn't found, grab the entry first one found. | 96 | * If Phb wasn't found, grab the entry first one found. |
139 | */ | 97 | */ |
140 | if (DevNode->PhbId == 0xff) | 98 | if (*PhbId == 0xff) |
141 | DevNode->PhbId = SlotMapPtr->PhbId; | 99 | *PhbId = SlotMapPtr->PhbId; |
142 | /* Found it, extract the data. */ | 100 | /* Found it, extract the data. */ |
143 | if (SlotMapPtr->PhbId == DevNode->PhbId ) { | 101 | if (SlotMapPtr->PhbId == *PhbId) { |
144 | memcpy(&DevNode->CardLocation, | 102 | memcpy(card, &SlotMapPtr->CardLocation, 3); |
145 | &SlotMapPtr->CardLocation, 3); | 103 | card[3] = 0; |
146 | DevNode->CardLocation[3] = 0; | ||
147 | break; | 104 | break; |
148 | } | 105 | } |
149 | } | 106 | } |
@@ -156,8 +113,9 @@ static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | |||
156 | /* | 113 | /* |
157 | * Parse the Mfg Area | 114 | * Parse the Mfg Area |
158 | */ | 115 | */ |
159 | static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | 116 | static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, |
160 | struct iSeries_Device_Node *DevNode) | 117 | HvAgentId agent, u8 *PhbId, |
118 | u8 *frame, char card[4]) | ||
161 | { | 119 | { |
162 | MfgArea *MfgAreaPtr = (MfgArea *)AreaData; | 120 | MfgArea *MfgAreaPtr = (MfgArea *)AreaData; |
163 | int MfgAreaLen = AreaLen; | 121 | int MfgAreaLen = AreaLen; |
@@ -168,7 +126,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
168 | int MfgTagLen = MfgAreaPtr->TagLength; | 126 | int MfgTagLen = MfgAreaPtr->TagLength; |
169 | /* Frame ID (FI 4649020310 ) */ | 127 | /* Frame ID (FI 4649020310 ) */ |
170 | if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ | 128 | if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ |
171 | DevNode->FrameId = MfgAreaPtr->AreaData1; | 129 | *frame = MfgAreaPtr->AreaData1; |
172 | /* Slot Map Format (MF 4D46020004 ) */ | 130 | /* Slot Map Format (MF 4D46020004 ) */ |
173 | else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ | 131 | else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ |
174 | SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) | 132 | SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) |
@@ -183,7 +141,8 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
183 | else | 141 | else |
184 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr | 142 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr |
185 | + MFG_ENTRY_SIZE); | 143 | + MFG_ENTRY_SIZE); |
186 | iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode); | 144 | iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, |
145 | agent, PhbId, card); | ||
187 | } | 146 | } |
188 | /* | 147 | /* |
189 | * Point to the next Mfg Area | 148 | * Point to the next Mfg Area |
@@ -199,7 +158,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
199 | * Look for "BUS".. Data is not Null terminated. | 158 | * Look for "BUS".. Data is not Null terminated. |
200 | * PHBID of 0xFF indicates PHB was not found in VPD Data. | 159 | * PHBID of 0xFF indicates PHB was not found in VPD Data. |
201 | */ | 160 | */ |
202 | static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | 161 | static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) |
203 | { | 162 | { |
204 | u8 *PhbPtr = AreaPtr; | 163 | u8 *PhbPtr = AreaPtr; |
205 | int DataLen = AreaLength; | 164 | int DataLen = AreaLength; |
@@ -223,27 +182,30 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | |||
223 | /* | 182 | /* |
224 | * Parse out the VPD Areas | 183 | * Parse out the VPD Areas |
225 | */ | 184 | */ |
226 | static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, | 185 | static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, |
227 | struct iSeries_Device_Node *DevNode) | 186 | HvAgentId agent, u8 *frame, char card[4]) |
228 | { | 187 | { |
229 | u8 *TagPtr = VpdData; | 188 | u8 *TagPtr = VpdData; |
230 | int DataLen = VpdDataLen - 3; | 189 | int DataLen = VpdDataLen - 3; |
190 | u8 PhbId; | ||
231 | 191 | ||
232 | while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { | 192 | while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { |
233 | int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); | 193 | int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); |
234 | u8 *AreaData = TagPtr + 3; | 194 | u8 *AreaData = TagPtr + 3; |
235 | 195 | ||
236 | if (*TagPtr == VpdIdStringTag) | 196 | if (*TagPtr == VpdIdStringTag) |
237 | DevNode->PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); | 197 | PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); |
238 | else if (*TagPtr == VpdVendorAreaTag) | 198 | else if (*TagPtr == VpdVendorAreaTag) |
239 | iSeries_Parse_MfgArea(AreaData, AreaLen, DevNode); | 199 | iSeries_Parse_MfgArea(AreaData, AreaLen, |
200 | agent, &PhbId, frame, card); | ||
240 | /* Point to next Area. */ | 201 | /* Point to next Area. */ |
241 | TagPtr = AreaData + AreaLen; | 202 | TagPtr = AreaData + AreaLen; |
242 | DataLen -= AreaLen; | 203 | DataLen -= AreaLen; |
243 | } | 204 | } |
244 | } | 205 | } |
245 | 206 | ||
246 | void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) | 207 | static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, |
208 | u8 *frame, char card[4]) | ||
247 | { | 209 | { |
248 | int BusVpdLen = 0; | 210 | int BusVpdLen = 0; |
249 | u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); | 211 | u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); |
@@ -252,23 +214,58 @@ void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) | |||
252 | printk("PCI: Bus VPD Buffer allocation failure.\n"); | 214 | printk("PCI: Bus VPD Buffer allocation failure.\n"); |
253 | return; | 215 | return; |
254 | } | 216 | } |
255 | BusVpdLen = HvCallPci_getBusVpd(ISERIES_BUS(DevNode), | 217 | BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr), |
256 | ISERIES_HV_ADDR(BusVpdPtr), | ||
257 | BUS_VPDSIZE); | 218 | BUS_VPDSIZE); |
258 | if (BusVpdLen == 0) { | 219 | if (BusVpdLen == 0) { |
259 | kfree(BusVpdPtr); | ||
260 | printk("PCI: Bus VPD Buffer zero length.\n"); | 220 | printk("PCI: Bus VPD Buffer zero length.\n"); |
261 | return; | 221 | goto out_free; |
262 | } | 222 | } |
263 | /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ | 223 | /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ |
264 | /* Make sure this is what I think it is */ | 224 | /* Make sure this is what I think it is */ |
265 | if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ | 225 | if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ |
266 | printk("PCI: Bus VPD Buffer missing starting tag.\n"); | 226 | printk("PCI: Bus VPD Buffer missing starting tag.\n"); |
267 | kfree(BusVpdPtr); | 227 | goto out_free; |
268 | return; | ||
269 | } | 228 | } |
270 | iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode); | 229 | iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); |
271 | sprintf(DevNode->Location, "Frame%3d, Card %-4s", DevNode->FrameId, | 230 | out_free: |
272 | DevNode->CardLocation); | ||
273 | kfree(BusVpdPtr); | 231 | kfree(BusVpdPtr); |
274 | } | 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 | if (pci_class_name(PciDev->class >> 8) == 0) | ||
268 | printk("0x%04X\n", (int)(PciDev->class >> 8)); | ||
269 | else | ||
270 | printk("%s\n", pci_class_name(PciDev->class >> 8)); | ||
271 | } | ||