diff options
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r-- | arch/ppc64/kernel/iSeries_VpdInfo.c | 137 | ||||
-rw-r--r-- | arch/ppc64/kernel/iSeries_pci.c | 7 |
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 | */ | ||
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 | } | ||
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", |