aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/iSeries_VpdInfo.c
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2005-06-21 20:15:48 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:30 -0400
commit061c063efce96b33f9e26d5f83a8eb0643fa493c (patch)
tree6e40638f187b5d1f540d0c777d2cdc4f83ccfbd0 /arch/ppc64/kernel/iSeries_VpdInfo.c
parenta2ebaf250fabc5c5644b707dbee44c9e0ec442e9 (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.c137
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 */
95int 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 */
126static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, 84static 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 */
159static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, 116static 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 */
202static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) 161static 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 */
226static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, 185static 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
246void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) 207static 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, 230out_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 */
243void __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}