⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iseries_pci.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	iSeries_IoMmTable_Status();	iSeries_activate_IRQs();	mf_displaySrc(0xC9000200);}/*********************************************************************** * iSeries_pcibios_fixup_bus(int Bus) * ***********************************************************************/void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus){	PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",PciBus->number); }/*********************************************************************** * fixup_resources(struct pci_dev *dev)  *	 ***********************************************************************/void fixup_resources(struct pci_dev *PciDev){	PPCDBG(PPCDBG_BUSWALK,"fixup_resources PciDev %p\n",PciDev);}   /********************************************************************************* Loop through each node function to find usable EADs bridges.  *********************************************************************************/void  iSeries_Scan_PHBs_Slots(struct pci_controller* Phb){	struct HvCallPci_DeviceInfo* DevInfo;	HvBusNumber    Bus       = Phb->local_number;       /* System Bus        */		HvSubBusNumber SubBus    = 0;                       /* EADs is always 0. */	int            HvRc      = 0;	int            IdSel     = 1;		int            MaxAgents = 8;	DevInfo    = (struct HvCallPci_DeviceInfo*)kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);	if(DevInfo == NULL) return;	/********************************************************************************	 * Probe for EADs Bridges      	 ********************************************************************************/	for (IdSel=1; IdSel < MaxAgents; ++IdSel) {    		HvRc = HvCallPci_getDeviceInfo(Bus, SubBus, IdSel,REALADDR(DevInfo), sizeof(struct HvCallPci_DeviceInfo));		if (HvRc == 0) {			if(DevInfo->deviceType == HvCallPci_NodeDevice) {				iSeries_Scan_EADs_Bridge(Bus, SubBus, IdSel);			}			else {				printk("PCI: Invalid System Configuration(0x%02X).\n",DevInfo->deviceType);				PCIFR(      "Invalid System Configuration(0x%02X).",  DevInfo->deviceType);			}		}		else pci_Log_Error("getDeviceInfo",Bus, SubBus, IdSel,HvRc);	}	kfree(DevInfo);}/********************************************************************************* *********************************************************************************/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;}/************************************************************************//* I/0 Memory copy MUST use mmio commands on iSeries                    *//* To do; For performance, include the hv call directly                 *//************************************************************************/void* iSeries_memset_io(void* dest, char c, size_t Count){	u8    ByteValue     = c;	long  NumberOfBytes = Count;	char* IoBuffer      = dest;	while(NumberOfBytes > 0) {		iSeries_Write_Byte( ByteValue, (void*)IoBuffer );		++IoBuffer;		-- NumberOfBytes;	}	return dest;}	void* iSeries_memcpy_toio(void *dest, void *source, size_t count){	char *dst           = dest;	char *src           = source;	long  NumberOfBytes = count;	while(NumberOfBytes > 0) {		iSeries_Write_Byte(*src++, (void*)dst++);		-- NumberOfBytes;	}	return dest;}void* iSeries_memcpy_fromio(void *dest, void *source, size_t count){	char *dst = dest;	char *src = source;	long  NumberOfBytes = count;	while(NumberOfBytes > 0) {		*dst++ = iSeries_Read_Byte( (void*)src++);		-- NumberOfBytes;	}	return dest;}/********************************************************************************** * Look down the chain to find the matching Device Device **********************************************************************************/struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev){	struct list_head* Device_Node_Ptr = iSeries_Global_Device_List.next;	int Bus   = PciDev->bus->number;	int DevFn = PciDev->devfn;		while(Device_Node_Ptr != &iSeries_Global_Device_List) { 		struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)Device_Node_Ptr;		if(Bus == ISERIES_BUS(DevNode) && DevFn == DevNode->DevFn) {			return DevNode;		}		Device_Node_Ptr = Device_Node_Ptr->next;	}	return NULL;}/******************************************************************//* Returns the device node for the passed pci_dev                 *//* Sanity Check Node PciDev to passed pci_dev                     *//* If none is found, returns a NULL which the client must handle. *//******************************************************************/struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev){	struct iSeries_Device_Node* Node;	Node = (struct iSeries_Device_Node*)PciDev->sysdata;	if(Node == NULL ) {		Node = find_Device_Node(PciDev);	}	else if(Node->PciDev != PciDev) { 		Node = find_Device_Node(PciDev);	}	return Node;}/******************************************************************//* Set and reset Device Node Lock                                 *//******************************************************************/#define setIoLock() \    unsigned long IrqFlags; \    spin_lock_irqsave(&DevNode->IoLock, IrqFlags ); #define resetIoLock() \    int RtnCode = DevNode->ReturnCode; \    spin_unlock_irqrestore( &DevNode->IoLock, IrqFlags ); \    return RtnCode;/********************************************************************************** * * Read PCI Config Space Code  * **********************************************************************************//** BYTE  *************************************************************************/int iSeries_Node_read_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8* ReadValue){	u8  ReadData;	setIoLock();	++Pci_Cfg_Read_Count;	DevNode->ReturnCode = HvCallPci_configLoad8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                Offset,&ReadData);	if(Pci_Trace_Flag == 1) {		PCIFR("RCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: RCB: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "RCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	*ReadValue = ReadData;	resetIoLock();}/** WORD  *************************************************************************/int iSeries_Node_read_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16* ReadValue){	u16  ReadData; 	setIoLock();	++Pci_Cfg_Read_Count;	DevNode->ReturnCode = HvCallPci_configLoad16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                Offset,&ReadData);	if(Pci_Trace_Flag == 1) {		PCIFR("RCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: RCW: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "RCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	*ReadValue = ReadData;	resetIoLock();}/** DWORD *************************************************************************/int iSeries_Node_read_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32* ReadValue){ 	u32  ReadData; 	setIoLock();	++Pci_Cfg_Read_Count;	DevNode->ReturnCode = HvCallPci_configLoad32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                Offset,&ReadData);	if(Pci_Trace_Flag == 1) {		PCIFR("RCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: RCL: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "RCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	*ReadValue = ReadData;	resetIoLock();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -