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

📄 iseries_pci.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
int iSeries_pci_read_config_byte(struct pci_dev* PciDev, int Offset, u8* ReadValue) { 	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_read_config_byte( DevNode ,Offset,ReadValue);}int iSeries_pci_read_config_word(struct pci_dev* PciDev, int Offset, u16* ReadValue) { 	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_read_config_word( DevNode ,Offset,ReadValue );}int iSeries_pci_read_config_dword(struct pci_dev* PciDev, int Offset, u32* ReadValue) { 	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_read_config_dword(DevNode ,Offset,ReadValue  );}/**********************************************************************************//*                                                                                *//* Write PCI Config Space                                                         *//*                                                                                *//** BYTE  *************************************************************************/int iSeries_Node_write_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8 WriteData){	setIoLock();	++Pci_Cfg_Write_Count;	DevNode->ReturnCode = HvCallPci_configStore8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                  Offset,WriteData);	if(Pci_Trace_Flag == 1) {		PCIFR("WCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: WCB: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "WCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	resetIoLock();}/** WORD  *************************************************************************/int iSeries_Node_write_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16 WriteData){	setIoLock();	++Pci_Cfg_Write_Count;	DevNode->ReturnCode = HvCallPci_configStore16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                  Offset,WriteData);	if(Pci_Trace_Flag == 1) {		PCIFR("WCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: WCW: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "WCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	resetIoLock();}/** DWORD *************************************************************************/int iSeries_Node_write_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32 WriteData){	setIoLock();	++Pci_Cfg_Write_Count;	DevNode->ReturnCode = HvCallPci_configStore32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,	                                                  Offset,WriteData);	if(Pci_Trace_Flag == 1) {		PCIFR("WCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);	}	if(DevNode->ReturnCode != 0 ) { 		printk("PCI: WCL: 0x%04X.%02X  Error: 0x%04X\n",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);		PCIFR(      "WCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);	}	resetIoLock();}int iSeries_pci_write_config_byte( struct pci_dev* PciDev,int Offset, u8 WriteValue){	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_write_config_byte( DevNode,Offset,WriteValue);}int iSeries_pci_write_config_word( struct pci_dev* PciDev,int Offset,u16 WriteValue){	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_write_config_word( DevNode,Offset,WriteValue);}int iSeries_pci_write_config_dword(struct pci_dev* PciDev,int Offset,u32 WriteValue){	struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);	if(DevNode == NULL) return 0x0301;	return iSeries_Node_write_config_dword(DevNode,Offset,WriteValue);}/************************************************************************//* Branch Table                                                         *//************************************************************************/struct pci_ops iSeries_pci_ops = {	iSeries_pci_read_config_byte,	iSeries_pci_read_config_word,	iSeries_pci_read_config_dword,	iSeries_pci_write_config_byte,	iSeries_pci_write_config_word,	iSeries_pci_write_config_dword };/************************************************************************ * Log Pci Error and check Retry Count  * -> On Failure, print and log information. *    Increment Retry Count, if exceeds max, panic partition. * -> If in retry, print and log success ************************************************************************/void logPciError(char* ErrorTxt, void* IoAddress, struct iSeries_Device_Node* DevNode, u64 RtnCode){	++DevNode->IoRetry;	++Pci_Error_Count;	PCIFR("%s: I/O Error(%1d/%1d):0x%04X  IoAddress:0x%p  Device:0x%04X:%02X",  	      ErrorTxt, DevNode->IoRetry, in_interrupt(), RtnCode, IoAddress, ISERIES_BUS(DevNode),DevNode->AgentId);	/*******************************************************/	/* Filter out EADs freeze and alignment errors         */	/*******************************************************/	if(RtnCode == 0x0102) {		PCIFR("EADS Freeze error.......Panic........");		mf_displaySrc(0xB6000103);		panic_timeout = 0; 		panic("PCI: EADs Freeze error SRC B6000103\n");	}	else if(RtnCode == 0x0241) {		PCIFR("MMIO Alignment error: 0x%p",IoAddress);		mf_displaySrc(0xB6000103);		panic_timeout = 0; 		panic("PCI: MMIO Alignment error. SRC B6000103\n");	}	/*******************************************************/	/* Bump the retry and check for retry count exceeded.  */	/* If, Exceeded, panic the system.                     */           	/*******************************************************/	if(DevNode->IoRetry > Pci_Retry_Max && Pci_Error_Flag != 0 ) {		mf_displaySrc(0xB6000103);		panic_timeout = 0; 		panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled.\n");	}	/**************************************************************/	/* Wait x ms before retrying I/O to give I/O time to recover. */	/* Retry wait delay logic.                                    */	/* - On first retry, no delay, maybe just glitch.             */	/* - On successify retries, vary the delay to avoid being in a*/        /*   repetitive timing window.                                */ 	/**************************************************************/	if(DevNode->IoRetry > 0) {		udelay(DevNode->IoRetry * 50);	}}/************************************************************************ * Retry was successful ************************************************************************/void  pciRetrySuccessful(struct iSeries_Device_Node* DevNode){	struct  timeval  TimeClock;	struct  rtc_time CurTime;	do_gettimeofday(&TimeClock);	to_tm(TimeClock.tv_sec, &CurTime);	PCIFR("Retry Successful(%2d) on Device 0x%04X:%02X at %02d.%02d.%02d",	      DevNode->IoRetry,ISERIES_BUS(DevNode),DevNode->AgentId,	      CurTime.tm_hour,CurTime.tm_min,CurTime.tm_sec);	DevNode->IoRetry = 0;}/************************************************************************//* Translate the I/O Address into a device node, bar, and bar offset.   *//* Note: Make sure the passed variable end up on the stack to avoid     *//* the exposure of being device global.                                 *//* The Device Node is Lock to block other I/O to device.                *//************************************************************************/#define setUpMmIo(IoAddress,Type) \unsigned long   IrqFlags; \struct HvCallPci_LoadReturn Return; \union HvDsaMap  DsaData;  \u64             BarOffset;\unsigned long BaseIoAddr = (unsigned long)IoAddress-iSeries_Base_Io_Memory; \long          TableIndex = (BaseIoAddr/iSeries_IoMmTable_Entry_Size);       \struct iSeries_Device_Node* DevNode = *(iSeries_IoMmTable+TableIndex);      \if(DevNode != NULL) { \    DsaData.DsaAddr       = ISERIES_DSA(DevNode); \    DsaData.Dsa.barNumber = *(iSeries_IoBarTable+TableIndex); \    BarOffset             = BaseIoAddr % iSeries_IoMmTable_Entry_Size; \    ++Pci_Io_##Type##_Count; \    spin_lock_irqsave(&DevNode->IoLock, IrqFlags ); \} \else panic("PCI: Invalid PCI IoAddress detected 0x%p!\n",IoAddress);/************************************************************************//* Read MM I/O Instructions for the iSeries                             *//* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*//* else, data is returned in big Endian format.                         *//************************************************************************//* iSeries_Read_Byte = Read Byte  ( 8 bit)                              *//* iSeries_Read_Word = Read Word  (16 bit)                              *//* iSeries_Read_Long = Read Long  (32 bit)                              *//************************************************************************/u8  iSeries_Read_Byte(void* IoAddress){	setUpMmIo(IoAddress,Read);	do {		HvCall3Ret16(HvCallPciBarLoad8, &Return, DsaData.DsaAddr,BarOffset, 0);		if(Return.rc != 0 ) {			logPciError("RDB",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1 ) PCIFR("RDB: IoAddress 0x%p = 0x%02X",IoAddress, (u8)Return.value);	return (u8)Return.value;}int Retry_Test = 0;u16  iSeries_Read_Word(void* IoAddress){	setUpMmIo(IoAddress,Read);	do {		HvCall3Ret16(HvCallPciBarLoad16,&Return, DsaData.DsaAddr,BarOffset, 0);		if(Return.rc != 0 ) {			logPciError("RDW",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1 ) PCIFR("RDW: IoAddress 0x%p = 0x%04X",IoAddress, (u16)Return.value);	return swab16((u16)Return.value);}u32  iSeries_Read_Long(void* IoAddress){	setUpMmIo(IoAddress,Read);	do {		HvCall3Ret16(HvCallPciBarLoad32,&Return, DsaData.DsaAddr,BarOffset, 0);		if(Return.rc != 0 ) {			logPciError("RDL",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1 ) PCIFR("RDL: IoAddress 0x%p = 0x%08X",IoAddress, swab32((u32)Return.value));	return swab32((u32)Return.value);}/************************************************************************//* Write MM I/O Instructions for the iSeries                            *//************************************************************************//* iSeries_Write_Byte = Write Byte (8 bit)                              *//* iSeries_Write_Word = Write Word(16 bit)                              *//* iSeries_Write_Long = Write Long(32 bit)                              *//************************************************************************/void iSeries_Write_Byte(u8 Data, void* IoAddress){	setUpMmIo(IoAddress,Write);	do {		Return.rc = HvCall4(HvCallPciBarStore8, DsaData.DsaAddr,BarOffset, Data, 0);		if(Return.rc != 0 ) {			logPciError("WWB",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1) PCIFR("WWB: IoAddress 0x%p = 0x%02X",IoAddress,Data);}void iSeries_Write_Word(u16 Data, void* IoAddress){	setUpMmIo(IoAddress,Write);	do {		Return.rc = HvCall4(HvCallPciBarStore16,DsaData.DsaAddr,BarOffset, swab16(Data), 0);		if(Return.rc != 0 ) {			logPciError("WWW",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1) PCIFR("WWW: IoAddress 0x%p = 0x%04X",IoAddress,Data);}void iSeries_Write_Long(u32 Data, void* IoAddress){	setUpMmIo(IoAddress,Write);	do {		Return.rc = HvCall4(HvCallPciBarStore32,DsaData.DsaAddr,BarOffset, swab32(Data), 0);		if(Return.rc != 0 ) {			logPciError("WWL",IoAddress, DevNode, Return.rc);		}		else if ( DevNode->IoRetry > 0) {			pciRetrySuccessful(DevNode);		}	} while (Return.rc != 0);	spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 	if(Pci_Trace_Flag == 1) PCIFR("WWL: IoAddress 0x%p = 0x%08X",IoAddress, Data);}/* * This is called very early before the page table is setup. * There are warnings here because of type mismatches.. Okay for now. AHT */void iSeries_pcibios_init_early(void){	//ppc_md.pcibios_read_config_byte   = iSeries_Node_read_config_byte;	//ppc_md.pcibios_read_config_word   = iSeries_Node_read_config_word;	//ppc_md.pcibios_read_config_dword  = iSeries_Node_read_config_dword;	//ppc_md.pcibios_write_config_byte  = iSeries_Node_write_config_byte;	//ppc_md.pcibios_write_config_word  = iSeries_Node_write_config_word;	//ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;}/************************************************************************//* Set the slot reset line to the state passed in.                      *//* This is the platform specific for code for the pci_reset_device      *//* function.                                                            *//************************************************************************/int pci_set_reset(struct pci_dev* PciDev, int State) {	struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata; 	if (DeviceNode == NULL) { 		printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);		return -1;	}	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,State);	return DeviceNode->ReturnCode;}

⌨️ 快捷键说明

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