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);
}
Example #2
0
/*  this is not called anywhere currently */
static void iseries_shutdown_IRQ(unsigned int irq)
{
	u32 bus, dev_id, function, mask;
	const u32 sub_bus = 0;
	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;

	/* irq should be locked by the caller */
	bus = REAL_IRQ_TO_BUS(rirq);
	function = REAL_IRQ_TO_FUNC(rirq);
	dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;

	/* Invalidate the IRQ number in the bridge */
	HvCallXm_connectBusUnit(bus, sub_bus, dev_id, 0);

	/* Mask bridge interrupts in the FISR */
	mask = 0x01010000 << function;
	HvCallPci_maskFisr(bus, sub_bus, dev_id, mask);
}
Example #3
0
/* This is called by iseries_activate_IRQs */
static unsigned int iseries_startup_IRQ(unsigned int irq)
{
	u32 bus, dev_id, function, mask;
	const u32 sub_bus = 0;
	unsigned int rirq = (unsigned int)irq_map[irq].hwirq;

	bus = REAL_IRQ_TO_BUS(rirq);
	function = REAL_IRQ_TO_FUNC(rirq);
	dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;

	/* Link the IRQ number to the bridge */
	HvCallXm_connectBusUnit(bus, sub_bus, dev_id, irq);

	/* Unmask bridge interrupts in the FISR */
	mask = 0x01010000 << function;
	HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
	iseries_enable_IRQ(irq);
	return 0;
}
/********************************************************************************
* 
* 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;
}