/*
  * Bus Vpd Tags
  */
-#define  VpdEndOfDataTag   0x78
 #define  VpdEndOfAreaTag   0x79
 #define  VpdIdStringTag    0x82
 #define  VpdVendorAreaTag  0x84
 /*
  * Mfg Area Tags
  */
-#define  VpdFruFlag       0x4647     // "FG"
 #define  VpdFruFrameId    0x4649     // "FI"
 #define  VpdSlotMapFormat 0x4D46     // "MF"
-#define  VpdAsmPartNumber 0x504E     // "PN"
-#define  VpdFruSerial     0x534E     // "SN"
 #define  VpdSlotMap       0x534D     // "SM"
 
 /*
 typedef struct SlotMapStruct SlotMap;
 #define SLOT_ENTRY_SIZE   16
 
-/*
- * Formats the device information.
- * - Pass in pci_dev* pointer to the device.
- * - Pass in buffer to place the data.  Danger here is the buffer must
- *   be as big as the client says it is.   Should be at least 128 bytes.
- * Return will the length of the string data put in the buffer.
- * Format:
- * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
- * controller
- */
-int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer,
-               int BufferSize)
-{
-       struct iSeries_Device_Node *DevNode =
-               (struct iSeries_Device_Node *)PciDev->sysdata;
-       int len;
-
-       if (DevNode == NULL)
-               return sprintf(buffer,
-                               "PCI: iSeries_Device_Information DevNode is NULL");
-
-       if (BufferSize < 128)
-               return 0;
-
-       len = sprintf(buffer, "PCI: Bus%3d, Device%3d, Vendor %04X ",
-                       ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn),
-                       PciDev->vendor);
-       len += sprintf(buffer + len, "Frame%3d, Card %4s  ",
-                       DevNode->FrameId, DevNode->CardLocation);
-       if (pci_class_name(PciDev->class >> 8) == 0)
-               len += sprintf(buffer + len, "0x%04X  ",
-                               (int)(PciDev->class >> 8));
-       else
-               len += sprintf(buffer + len, "%s",
-                               pci_class_name(PciDev->class >> 8));
-       return len;
-}
-
 /*
  * Parse the Slot Area
  */
-static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
-               struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
+               HvAgentId agent, u8 *PhbId, char card[4])
 {
        int SlotMapLen = MapLen;
        SlotMap *SlotMapPtr = MapPtr;
         * Parse Slot label until we find the one requested
         */
        while (SlotMapLen > 0) {
-               if (SlotMapPtr->AgentId == DevNode->AgentId ) {
+               if (SlotMapPtr->AgentId == agent) {
                        /*
                         * If Phb wasn't found, grab the entry first one found.
                         */
-                       if (DevNode->PhbId == 0xff)
-                               DevNode->PhbId = SlotMapPtr->PhbId; 
+                       if (*PhbId == 0xff)
+                               *PhbId = SlotMapPtr->PhbId;
                        /* Found it, extract the data. */
-                       if (SlotMapPtr->PhbId == DevNode->PhbId ) {
-                               memcpy(&DevNode->CardLocation,
-                                               &SlotMapPtr->CardLocation, 3);
-                               DevNode->CardLocation[3]  = 0;
+                       if (SlotMapPtr->PhbId == *PhbId) {
+                               memcpy(card, &SlotMapPtr->CardLocation, 3);
+                               card[3]  = 0;
                                break;
                        }
                }
 /*
  * Parse the Mfg Area
  */
-static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
-               struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
+               HvAgentId agent, u8 *PhbId,
+               u8 *frame, char card[4])
 {
        MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
        int MfgAreaLen = AreaLen;
                int MfgTagLen = MfgAreaPtr->TagLength;
                /* Frame ID         (FI 4649020310 ) */
                if (MfgAreaPtr->Tag == VpdFruFrameId)           /* FI  */
-                       DevNode->FrameId = MfgAreaPtr->AreaData1;
+                       *frame = MfgAreaPtr->AreaData1;
                /* Slot Map Format  (MF 4D46020004 ) */
                else if (MfgAreaPtr->Tag == VpdSlotMapFormat)   /* MF  */
                        SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
                        else
                                SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
                                                + MFG_ENTRY_SIZE);
-                       iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode);
+                       iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
+                                       agent, PhbId, card);
                }
                /*
                 * Point to the next Mfg Area
  * Look for "BUS".. Data is not Null terminated.
  * PHBID of 0xFF indicates PHB was not found in VPD Data.
  */
-static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
+static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
 {
        u8 *PhbPtr = AreaPtr;
        int DataLen = AreaLength;
 /*
  * Parse out the VPD Areas
  */
-static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
-               struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
+               HvAgentId agent, u8 *frame, char card[4])
 {
        u8 *TagPtr = VpdData;
        int DataLen = VpdDataLen - 3;
+       u8 PhbId;
 
        while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
                int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
                u8 *AreaData  = TagPtr + 3;
 
                if (*TagPtr == VpdIdStringTag)
-                       DevNode->PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
+                       PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
                else if (*TagPtr == VpdVendorAreaTag)
-                       iSeries_Parse_MfgArea(AreaData, AreaLen, DevNode);
+                       iSeries_Parse_MfgArea(AreaData, AreaLen,
+                                       agent, &PhbId, frame, card);
                /* Point to next Area. */
                TagPtr  = AreaData + AreaLen;
                DataLen -= AreaLen;
        }
 }
 
-void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
+               u8 *frame, char card[4])
 {
        int BusVpdLen = 0;
        u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
                printk("PCI: Bus VPD Buffer allocation failure.\n");
                return;
        }
-       BusVpdLen = HvCallPci_getBusVpd(ISERIES_BUS(DevNode),
-                                       ISERIES_HV_ADDR(BusVpdPtr),
+       BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr),
                                        BUS_VPDSIZE);
        if (BusVpdLen == 0) {
-               kfree(BusVpdPtr);
                printk("PCI: Bus VPD Buffer zero length.\n");
-               return;
+               goto out_free;
        }
        /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
        /* Make sure this is what I think it is */
        if (*BusVpdPtr != VpdIdStringTag) {     /* 0x82 */
                printk("PCI: Bus VPD Buffer missing starting tag.\n");
-               kfree(BusVpdPtr);
-               return;
+               goto out_free;
        }
-       iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode);
-       sprintf(DevNode->Location, "Frame%3d, Card %-4s", DevNode->FrameId,
-                       DevNode->CardLocation);
+       iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
+out_free:
        kfree(BusVpdPtr);
 }
+
+/*
+ * Prints the device information.
+ * - Pass in pci_dev* pointer to the device.
+ * - Pass in the device count
+ *
+ * Format:
+ * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
+ * controller
+ */
+void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
+{
+       struct iSeries_Device_Node *DevNode = PciDev->sysdata;
+       u16 bus;
+       u8 frame;
+       char card[4];
+       HvSubBusNumber subbus;
+       HvAgentId agent;
+
+       if (DevNode == NULL) {
+               printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
+                               count);
+               return;
+       }
+
+       bus = ISERIES_BUS(DevNode);
+       subbus = ISERIES_SUBBUS(DevNode);
+       agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
+                       ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
+       iSeries_Get_Location_Code(bus, agent, &frame, card);
+
+       printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s  ",
+                       count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
+                       frame, card);
+       if (pci_class_name(PciDev->class >> 8) == 0)
+               printk("0x%04X\n", (int)(PciDev->class >> 8));
+       else
+               printk("%s\n", pci_class_name(PciDev->class >> 8));
+}