/* * 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 */ static void __init iseries_device_information(struct pci_dev *pdev, u16 bus, HvSubBusNumber subbus) { u8 frame = 0; char card[4]; HvAgentId agent; agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); if (iseries_get_location_code(bus, agent, &frame, card)) { printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, " "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor, frame, card, (int)(pdev->class >> 8)); }
void iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel) { struct HvCallPci_BridgeInfo* BridgeInfo; HvAgentId AgentId; int Function; int HvRc; BridgeInfo = (struct HvCallPci_BridgeInfo*)kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL); if(BridgeInfo == NULL) return; /********************************************************************* * Note: hvSubBus and irq is always be 0 at this level! *********************************************************************/ for (Function=0; Function < 8; ++Function) { AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, 0); if (HvRc == 0) { /* Connect EADs: 0x18.00.12 = 0x00 */ PPCDBG(PPCDBG_BUSWALK,"PCI:Connect EADs: 0x%02X.%02X.%02X\n",Bus, SubBus, AgentId); PCIFR( "Connect EADs: 0x%02X.%02X.%02X", Bus, SubBus, AgentId); HvRc = HvCallPci_getBusUnitInfo(Bus, SubBus, AgentId, REALADDR(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo)); if (HvRc == 0) { PPCDBG(PPCDBG_BUSWALK,"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n", BridgeInfo->busUnitInfo.deviceType, BridgeInfo->subBusNumber, BridgeInfo->maxAgents, BridgeInfo->maxSubBusNumber, BridgeInfo->logicalSlotNumber); PCIFR( "BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X", BridgeInfo->busUnitInfo.deviceType, BridgeInfo->subBusNumber, BridgeInfo->maxAgents, BridgeInfo->maxSubBusNumber, BridgeInfo->logicalSlotNumber); if (BridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice) { /* Scan_Bridge_Slot...: 0x18.00.12 */ iSeries_Scan_Bridge_Slot(Bus,BridgeInfo); } else printk("PCI: Invalid Bridge Configuration(0x%02X)",BridgeInfo->busUnitInfo.deviceType); } } else if(HvRc != 0x000B) pci_Log_Error("EADs Connect",Bus,SubBus,AgentId,HvRc); } kfree(BridgeInfo); }
/******************************************************************************** * * This assumes that the node slot is always on the primary bus! * *********************************************************************************/ int iSeries_Scan_Bridge_Slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo* BridgeInfo) { struct iSeries_Device_Node* DeviceNode; HvSubBusNumber SubBus = BridgeInfo->subBusNumber; u16 VendorId = 0; int HvRc = 0; u8 Irq = 0; int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus); int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus); HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function); int FirstSlotId = 0; /**********************************************************/ /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */ /**********************************************************/ Irq = iSeries_allocate_IRQ(Bus, 0, AgentId); iSeries_assign_IRQ(Irq, Bus, 0, AgentId); PPCDBG(PPCDBG_BUSWALK,"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",Bus, 0, AgentId, Irq ); /**************************************************************************** * Connect all functions of any device found. ****************************************************************************/ for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { for (Function = 0; Function < 8; ++Function) { AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq); if( HvRc == 0) { HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, PCI_VENDOR_ID, &VendorId); if( HvRc == 0) { /**********************************************************/ /* FoundDevice: 0x18.28.10 = 0x12AE */ /**********************************************************/ PPCDBG(PPCDBG_BUSWALK,"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X\n", Bus, SubBus, AgentId, VendorId); HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq); if( HvRc != 0) { pci_Log_Error("PciCfgStore Irq Failed!",Bus,SubBus,AgentId,HvRc); } ++DeviceCount; DeviceNode = build_device_node(Bus, SubBus, EADsIdSel, Function); DeviceNode->Vendor = VendorId; DeviceNode->Irq = Irq; DeviceNode->LogicalSlot = BridgeInfo->logicalSlotNumber; PCIFR("Device(%4d): 0x%02X.%02X.%02X 0x%02X 0x%04X", DeviceCount,Bus, SubBus, AgentId, DeviceNode->LogicalSlot,DeviceNode->Vendor); /*********************************************************** * On the first device/function, assign irq to slot ***********************************************************/ if(Function == 0) { FirstSlotId = AgentId; // AHT iSeries_assign_IRQ(Irq, Bus, SubBus, AgentId); } } else pci_Log_Error("Read Vendor",Bus,SubBus,AgentId,HvRc); } else pci_Log_Error("Connect Bus Unit",Bus,SubBus, AgentId,HvRc); } /* for (Function = 0; Function < 8; ++Function) */ } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ return HvRc; }