aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r--arch/ppc64/kernel/iSeries_VpdInfo.c137
-rw-r--r--arch/ppc64/kernel/iSeries_pci.c7
2 files changed, 68 insertions, 76 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}
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
index 0a28b6ca65d0..356e4fd9a94f 100644
--- a/arch/ppc64/kernel/iSeries_pci.c
+++ b/arch/ppc64/kernel/iSeries_pci.c
@@ -223,9 +223,7 @@ static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
223 node->DsaAddr.Dsa.busNumber = Bus; 223 node->DsaAddr.Dsa.busNumber = Bus;
224 node->DsaAddr.Dsa.subBusNumber = SubBus; 224 node->DsaAddr.Dsa.subBusNumber = SubBus;
225 node->DsaAddr.Dsa.deviceId = 0x10; 225 node->DsaAddr.Dsa.deviceId = 0x10;
226 node->AgentId = AgentId;
227 node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); 226 node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
228 iSeries_Get_Location_Code(node);
229 return node; 227 return node;
230} 228}
231 229
@@ -299,7 +297,6 @@ void __init iSeries_pci_final_fixup(void)
299{ 297{
300 struct pci_dev *pdev = NULL; 298 struct pci_dev *pdev = NULL;
301 struct iSeries_Device_Node *node; 299 struct iSeries_Device_Node *node;
302 char Buffer[256];
303 int DeviceCount = 0; 300 int DeviceCount = 0;
304 301
305 PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); 302 PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
@@ -321,9 +318,7 @@ void __init iSeries_pci_final_fixup(void)
321 "pdev 0x%p <==> DevNode 0x%p\n", 318 "pdev 0x%p <==> DevNode 0x%p\n",
322 pdev, node); 319 pdev, node);
323 allocate_device_bars(pdev); 320 allocate_device_bars(pdev);
324 iSeries_Device_Information(pdev, Buffer, 321 iSeries_Device_Information(pdev, DeviceCount);
325 sizeof(Buffer));
326 printk("%d. %s\n", DeviceCount, Buffer);
327 iommu_devnode_init_iSeries(node); 322 iommu_devnode_init_iSeries(node);
328 } else 323 } else
329 printk("PCI: Device Tree not found for 0x%016lX\n", 324 printk("PCI: Device Tree not found for 0x%016lX\n",