iSeries_pci.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:39k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * iSeries_pci.c
  3.  *
  4.  * Copyright (C) 2001 Allan Trautman, IBM Corporation
  5.  *
  6.  * iSeries specific routines for PCI.
  7.  * /
  8.  * Based on code from pci.c and iSeries_pci.c 32bit
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  * 
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  * 
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  23.  */
  24. #include <linux/config.h>
  25. #include <linux/kernel.h>
  26. #include <linux/list.h> 
  27. #include <linux/string.h>
  28. #include <linux/init.h>
  29. #include <linux/ide.h>
  30. #include <linux/pci.h>
  31. #include <linux/rtc.h>
  32. #include <linux/time.h>
  33. #include <asm/io.h>
  34. #include <asm/irq.h>
  35. #include <asm/prom.h>
  36. #include <asm/machdep.h>
  37. #include <asm/pci-bridge.h>
  38. #include <asm/ppcdebug.h>
  39. #include <asm/naca.h>
  40. #include <asm/flight_recorder.h>
  41. #include <asm/hardirq.h>
  42. #include <asm/time.h>
  43. #include <asm/pci_dma.h>
  44. #include <asm/iSeries/HvCallPci.h>
  45. #include <asm/iSeries/HvCallSm.h>
  46. #include <asm/iSeries/HvCallXm.h>
  47. #include <asm/iSeries/LparData.h>
  48. #include <asm/iSeries/iSeries_irq.h>
  49. #include <asm/iSeries/iSeries_pci.h>
  50. #include <asm/iSeries/mf.h>
  51. #include "iSeries_IoMmTable.h"
  52. #include "pci.h"
  53. extern struct pci_controller* hose_head;
  54. extern struct pci_controller** hose_tail;
  55. extern int    global_phb_number;
  56. extern int    panic_timeout;
  57. extern struct device_node *allnodes;
  58. extern unsigned long phb_tce_table_init(struct pci_controller *phb);
  59. extern unsigned long iSeries_Base_Io_Memory;    
  60. extern struct pci_ops iSeries_pci_ops;
  61. extern struct flightRecorder* PciFr;
  62. extern struct TceTable* tceTables[256];
  63. /*******************************************************************
  64.  * Counters and control flags. 
  65.  *******************************************************************/
  66. extern long   Pci_Io_Read_Count;
  67. extern long   Pci_Io_Write_Count;
  68. extern long   Pci_Cfg_Read_Count;
  69. extern long   Pci_Cfg_Write_Count;
  70. extern long   Pci_Error_Count;
  71. extern int    Pci_Retry_Max;
  72. extern int    Pci_Error_Flag;
  73. extern int    Pci_Trace_Flag;
  74. /*******************************************************************
  75.  * Forward declares of prototypes. 
  76.  *******************************************************************/
  77. struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
  78. struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev);
  79. unsigned long find_and_init_phbs(void);
  80. void          fixup_resources(struct pci_dev *dev);
  81. void          iSeries_pcibios_fixup(void);
  82. struct        pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
  83. void  iSeries_Scan_PHBs_Slots(struct pci_controller* Phb);
  84. void  iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
  85. int   iSeries_Scan_Bridge_Slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo* Info);
  86. void  list_device_nodes(void);
  87. struct pci_dev;
  88. extern struct list_head iSeries_Global_Device_List;
  89. int DeviceCount = 0;
  90. /**********************************************************************************
  91.  * Log Error infor in Flight Recorder to system Console.
  92.  * Filter out the device not there errors.
  93.  * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
  94.  * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
  95.  * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
  96.  **********************************************************************************/
  97. void  pci_Log_Error(char* Error_Text, int Bus, int SubBus, int AgentId, int HvRc)
  98. {
  99. if( HvRc != 0x0302) { 
  100. char ErrorString[128];
  101. sprintf(ErrorString,"%s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",Error_Text,Bus,SubBus,AgentId,HvRc);
  102. PCIFR(ErrorString);
  103. printk("PCI: %sn",ErrorString);
  104. }
  105. }
  106. /**********************************************************************************
  107.  * Dump the iSeries Temp Device Node 
  108.  *<4>buswalk [swapper : - DeviceNode: 0xC000000000634300
  109.  *<4>00. Device Node   = 0xC000000000634300
  110.  *<4>    - PciDev      = 0x0000000000000000
  111.  *<4>    - tDevice     = 0x  17:01.00  0x1022 00
  112.  *<4>  4. Device Node = 0xC000000000634480
  113.  *<4>     - PciDev    = 0x0000000000000000
  114.  *<4>     - Device    = 0x  18:38.16 Irq:0xA7 Vendor:0x1014  Flags:0x00
  115.  *<4>     - Devfn     = 0xB0: 22.18
  116.  **********************************************************************************/
  117. void dumpDevice_Node(struct iSeries_Device_Node* DevNode)
  118. {
  119. udbg_printf("Device Node      = 0x%pn",DevNode);
  120. udbg_printf("     - PciDev    = 0x%pn",DevNode->PciDev);
  121. udbg_printf("     - Device    = 0x%4X:%02X.%02X (0x%02X)n",
  122.     ISERIES_BUS(DevNode),
  123.     ISERIES_SUBBUS(DevNode),
  124.     DevNode->AgentId,
  125.     DevNode->DevFn);
  126. udbg_printf("     - LSlot     = 0x%02Xn",DevNode->LogicalSlot);
  127. udbg_printf("     - TceTable  = 0x%pn  ",DevNode->DevTceTable);
  128. udbg_printf("     - DSA       = 0x%04Xn",ISERIES_DSA(DevNode)>>32 );
  129. udbg_printf("                 = Irq:0x%02X Vendor:0x%04X  Flags:0x%02Xn",
  130.     DevNode->Irq,
  131.     DevNode->Vendor,
  132.     DevNode->Flags );
  133. udbg_printf("     - Location  = %sn",DevNode->CardLocation);
  134. }
  135. /**********************************************************************************
  136.  * Walk down the device node chain 
  137.  **********************************************************************************/
  138. void  list_device_nodes(void)
  139. {
  140. struct list_head* Device_Node_Ptr = iSeries_Global_Device_List.next;
  141. while(Device_Node_Ptr != &iSeries_Global_Device_List) {
  142. dumpDevice_Node( (struct iSeries_Device_Node*)Device_Node_Ptr );
  143. Device_Node_Ptr = Device_Node_Ptr->next;
  144. }
  145. }
  146. /***********************************************************************
  147.  * build_device_node(u16 Bus, int SubBus, u8 DevFn)
  148.  *
  149.  ***********************************************************************/
  150. struct iSeries_Device_Node* build_device_node(HvBusNumber Bus, HvSubBusNumber  SubBus, int AgentId, int Function)
  151. {
  152. struct iSeries_Device_Node*  DeviceNode;
  153. PPCDBG(PPCDBG_BUSWALK,"-build_device_node 0x%02X.%02X.%02X Function: %02Xn",Bus,SubBus,AgentId, Function);
  154. DeviceNode = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
  155. if(DeviceNode == NULL) return NULL;
  156. memset(DeviceNode,0,sizeof(struct iSeries_Device_Node) );
  157. list_add_tail(&DeviceNode->Device_List,&iSeries_Global_Device_List);
  158. /*DeviceNode->DsaAddr      = ((u64)Bus<<48)+((u64)SubBus<<40)+((u64)0x10<<32); */
  159. ISERIES_BUS(DeviceNode)       = Bus;
  160. ISERIES_SUBBUS(DeviceNode)    = SubBus;
  161. DeviceNode->DsaAddr.deviceId  = 0x10;
  162.         DeviceNode->DsaAddr.barNumber = 0;
  163. DeviceNode->AgentId           = AgentId;
  164. DeviceNode->DevFn             = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId),Function );
  165. DeviceNode->IoRetry           = 0;
  166. iSeries_Get_Location_Code(DeviceNode);
  167. PCIFR("Device 0x%02X.%2X, Node:0x%p ",ISERIES_BUS(DeviceNode),ISERIES_DEVFUN(DeviceNode),DeviceNode);
  168. return DeviceNode;
  169. }
  170. /****************************************************************************
  171. * Allocate pci_controller(phb) initialized common variables. 
  172. *****************************************************************************/
  173. struct pci_controller* pci_alloc_pci_controllerX(char *model, enum phb_types controller_type)
  174. {
  175. struct pci_controller *hose;
  176. hose = (struct pci_controller*)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
  177. if(hose == NULL) return NULL;
  178. memset(hose, 0, sizeof(struct pci_controller));
  179. if(strlen(model) < 8) strcpy(hose->what,model);
  180. else                  memcpy(hose->what,model,7);
  181. hose->type = controller_type;
  182. hose->global_number = global_phb_number;
  183. global_phb_number++;
  184. *hose_tail = hose;
  185. hose_tail = &hose->next;
  186. return hose;
  187. }
  188. /****************************************************************************
  189.  *
  190.  * unsigned int __init find_and_init_phbs(void)
  191.  *
  192.  * Description:
  193.  *   This function checks for all possible system PCI host bridges that connect
  194.  *   PCI buses.  The system hypervisor is queried as to the guest partition
  195.  *   ownership status.  A pci_controller is build for any bus which is partially
  196.  *   owned or fully owned by this guest partition.
  197.  ****************************************************************************/
  198. unsigned long __init find_and_init_phbs(void)
  199. {
  200. struct      pci_controller* phb;
  201. HvBusNumber BusNumber;
  202. PPCDBG(PPCDBG_BUSWALK,"find_and_init_phbs Entryn");
  203. /* Check all possible buses. */
  204. for (BusNumber = 0; BusNumber < 256; BusNumber++) {
  205. int RtnCode = HvCallXm_testBus(BusNumber);
  206. if (RtnCode == 0) {
  207. phb = pci_alloc_pci_controllerX("PHB HV", phb_type_hypervisor);
  208. if(phb == NULL) {
  209. printk("PCI: Allocate pci_controller failed.n");
  210. PCIFR(      "Allocate pci_controller failed.");
  211. return -1;
  212. }
  213. phb->pci_mem_offset = phb->local_number = BusNumber;
  214. phb->first_busno  = BusNumber;
  215. phb->last_busno   = BusNumber;
  216. phb->ops          = &iSeries_pci_ops;
  217. PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04Xn",phb,BusNumber);
  218. PCIFR("Create iSeries PHB controller: %04X",BusNumber);
  219. /***************************************************/
  220. /* Find and connect the devices.                   */
  221. /***************************************************/
  222. iSeries_Scan_PHBs_Slots(phb);
  223. }
  224. /* Check for Unexpected Return code, a clue that something */
  225. /* has gone wrong.                                         */
  226. else if(RtnCode != 0x0301) {
  227. PCIFR("Unexpected Return on Probe(0x%04X): 0x%04X",BusNumber,RtnCode);
  228. }
  229. }
  230. return 0;
  231. }
  232. /*********************************************************************** 
  233.  * ppc64_pcibios_init
  234.  *  
  235.  * Chance to initialize and structures or variable before PCI Bus walk.
  236.  *  
  237.  *<4>buswalk [swapper : iSeries_pcibios_init Entry.
  238.  *<4>buswalk [swapper : IoMmTable Initialized 0xC00000000034BD30
  239.  *<4>buswalk [swapper : find_and_init_phbs Entry
  240.  *<4>buswalk [swapper : Create iSeries pci_controller:(0xC00000001F5C7000), Bus 0x0017
  241.  *<4>buswalk [swapper : Connect EADs: 0x17.00.12 = 0x00
  242.  *<4>buswalk [swapper : iSeries_assign_IRQ   0x0017.00.12 = 0x0091
  243.  *<4>buswalk [swapper : - allocate and assign IRQ 0x17.00.12 = 0x91
  244.  *<4>buswalk [swapper : - FoundDevice: 0x17.28.10 = 0x12AE
  245.  *<4>buswalk [swapper : - build_device_node 0x17.28.12
  246.  *<4>buswalk [swapper : iSeries_pcibios_init Exit.
  247.  ***********************************************************************/
  248. void iSeries_pcibios_init(void)
  249. {
  250. PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_init Entry.n"); 
  251. iSeries_IoMmTable_Initialize();
  252. find_and_init_phbs();
  253. pci_assign_all_busses = 0;
  254. PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_init Exit.n"); 
  255. }
  256. /***********************************************************************
  257.  * iSeries_pcibios_fixup(void)  
  258.  ***********************************************************************/
  259. void __init iSeries_pcibios_fixup(void)
  260. {
  261. struct pci_dev* PciDev;
  262. struct iSeries_Device_Node* DeviceNode;
  263. char   Buffer[256];
  264.      int    DeviceCount = 0;
  265. PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup Entry.n"); 
  266. /******************************************************/
  267. /* Fix up at the device node and pci_dev relationship */
  268. /******************************************************/
  269. mf_displaySrc(0xC9000100);
  270. pci_for_each_dev(PciDev) {
  271. DeviceNode = find_Device_Node(PciDev);
  272. if(DeviceNode != NULL) {
  273. ++DeviceCount;
  274. PciDev->sysdata    = (void*)DeviceNode;
  275. DeviceNode->PciDev = PciDev;
  276. PPCDBG(PPCDBG_BUSWALK,"PciDev 0x%p <==> DevNode 0x%pn",PciDev,DeviceNode );
  277. iSeries_allocateDeviceBars(PciDev);
  278. PPCDBGCALL(PPCDBG_BUSWALK,dumpPci_Dev(PciDev) );
  279. iSeries_Device_Information(PciDev,Buffer, sizeof(Buffer) );
  280. printk("%d. %sn",DeviceCount,Buffer);
  281. create_pci_bus_tce_table((unsigned long)DeviceNode);
  282. } else {
  283. printk("PCI: Device Tree not found for 0x%016lXn",(unsigned long)PciDev);
  284. }
  285. }
  286. iSeries_IoMmTable_Status();
  287. iSeries_activate_IRQs();
  288. mf_displaySrc(0xC9000200);
  289. }
  290. /***********************************************************************
  291.  * iSeries_pcibios_fixup_bus(int Bus)
  292.  *
  293.  ***********************************************************************/
  294. void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus)
  295. {
  296. PPCDBG(PPCDBG_BUSWALK,"iSeries_pcibios_fixup_bus(0x%04X) Entry.n",PciBus->number); 
  297. }
  298. /***********************************************************************
  299.  * fixup_resources(struct pci_dev *dev) 
  300.  *
  301.  ***********************************************************************/
  302. void fixup_resources(struct pci_dev *PciDev)
  303. {
  304. PPCDBG(PPCDBG_BUSWALK,"fixup_resources PciDev %pn",PciDev);
  305. }   
  306. /********************************************************************************
  307. * Loop through each node function to find usable EADs bridges.  
  308. *********************************************************************************/
  309. void  iSeries_Scan_PHBs_Slots(struct pci_controller* Phb)
  310. {
  311. struct HvCallPci_DeviceInfo* DevInfo;
  312. HvBusNumber    Bus       = Phb->local_number;       /* System Bus        */
  313. HvSubBusNumber SubBus    = 0;                       /* EADs is always 0. */
  314. int            HvRc      = 0;
  315. int            IdSel     = 1;
  316. int            MaxAgents = 8;
  317. DevInfo    = (struct HvCallPci_DeviceInfo*)kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
  318. if(DevInfo == NULL) return;
  319. /********************************************************************************
  320.  * Probe for EADs Bridges      
  321.  ********************************************************************************/
  322. for (IdSel=1; IdSel < MaxAgents; ++IdSel) {
  323.      HvRc = HvCallPci_getDeviceInfo(Bus, SubBus, IdSel,REALADDR(DevInfo), sizeof(struct HvCallPci_DeviceInfo));
  324. if (HvRc == 0) {
  325. if(DevInfo->deviceType == HvCallPci_NodeDevice) {
  326. iSeries_Scan_EADs_Bridge(Bus, SubBus, IdSel);
  327. }
  328. else {
  329. printk("PCI: Invalid System Configuration(0x%02X).n",DevInfo->deviceType);
  330. PCIFR(      "Invalid System Configuration(0x%02X).",  DevInfo->deviceType);
  331. }
  332. }
  333. else pci_Log_Error("getDeviceInfo",Bus, SubBus, IdSel,HvRc);
  334. }
  335. kfree(DevInfo);
  336. }
  337. /********************************************************************************
  338. *********************************************************************************/
  339. void  iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel)
  340. {
  341. struct HvCallPci_BridgeInfo* BridgeInfo;
  342. HvAgentId      AgentId;
  343. int            Function;
  344. int            HvRc;
  345. BridgeInfo = (struct HvCallPci_BridgeInfo*)kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
  346. if(BridgeInfo == NULL) return;
  347. /*********************************************************************
  348.  * Note: hvSubBus and irq is always be 0 at this level!
  349.  *********************************************************************/
  350. for (Function=0; Function < 8; ++Function) {
  351.    AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
  352. HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, 0);
  353.   if (HvRc == 0) {
  354.    /*  Connect EADs: 0x18.00.12 = 0x00 */
  355. PPCDBG(PPCDBG_BUSWALK,"PCI:Connect EADs: 0x%02X.%02X.%02Xn",Bus, SubBus, AgentId);
  356. PCIFR(                    "Connect EADs: 0x%02X.%02X.%02X",  Bus, SubBus, AgentId);
  357.      HvRc = HvCallPci_getBusUnitInfo(Bus, SubBus, AgentId, 
  358.                                 REALADDR(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo));
  359.   if (HvRc == 0) {
  360. PPCDBG(PPCDBG_BUSWALK,"PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02Xn",
  361.        BridgeInfo->busUnitInfo.deviceType,
  362.        BridgeInfo->subBusNumber,
  363.        BridgeInfo->maxAgents,
  364.        BridgeInfo->maxSubBusNumber,
  365.        BridgeInfo->logicalSlotNumber);
  366. PCIFR(                     "BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X",
  367.        BridgeInfo->busUnitInfo.deviceType,
  368.        BridgeInfo->subBusNumber,
  369.        BridgeInfo->maxAgents,
  370.        BridgeInfo->maxSubBusNumber,
  371.        BridgeInfo->logicalSlotNumber);
  372. if (BridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice)  {
  373. /* Scan_Bridge_Slot...: 0x18.00.12 */
  374. iSeries_Scan_Bridge_Slot(Bus,BridgeInfo);
  375. }
  376. else printk("PCI: Invalid Bridge Configuration(0x%02X)",BridgeInfo->busUnitInfo.deviceType);
  377. }
  378.      }
  379. else if(HvRc != 0x000B) pci_Log_Error("EADs Connect",Bus,SubBus,AgentId,HvRc);
  380. }
  381. kfree(BridgeInfo);
  382. }
  383. /********************************************************************************
  384. * This assumes that the node slot is always on the primary bus!
  385. *
  386. *********************************************************************************/
  387. int iSeries_Scan_Bridge_Slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo* BridgeInfo)
  388. {
  389. struct iSeries_Device_Node* DeviceNode;
  390. HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
  391. u16       VendorId    = 0;
  392. int       HvRc        = 0;
  393. u8        Irq         = 0;
  394. int       IdSel       = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
  395. int       Function    = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
  396. HvAgentId AgentId     = ISERIES_PCI_AGENTID(IdSel, Function);
  397. HvAgentId EADsIdSel   = ISERIES_PCI_AGENTID(IdSel, Function);
  398. int       FirstSlotId = 0; 
  399. /**********************************************************/
  400. /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3)                */
  401. /**********************************************************/
  402.    Irq   = iSeries_allocate_IRQ(Bus, 0, AgentId);
  403. iSeries_assign_IRQ(Irq, Bus, 0, AgentId);
  404. PPCDBG(PPCDBG_BUSWALK,"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02Xn",Bus, 0, AgentId, Irq );
  405. /****************************************************************************
  406.  * Connect all functions of any device found.  
  407.  ****************************************************************************/
  408.    for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
  409.      for (Function = 0; Function < 8; ++Function) {
  410. AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
  411. HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq);
  412. if( HvRc == 0) {
  413. HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, PCI_VENDOR_ID, &VendorId);
  414. if( HvRc == 0) {
  415. /**********************************************************/
  416. /* FoundDevice: 0x18.28.10 = 0x12AE                       */
  417. /**********************************************************/
  418. PPCDBG(PPCDBG_BUSWALK,"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04Xn",
  419.                                        Bus, SubBus, AgentId, VendorId);
  420. HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq);  
  421. if( HvRc != 0) {
  422. pci_Log_Error("PciCfgStore Irq Failed!",Bus,SubBus,AgentId,HvRc);
  423. }
  424. ++DeviceCount;
  425. DeviceNode = build_device_node(Bus, SubBus, EADsIdSel, Function);
  426. DeviceNode->Vendor      = VendorId;
  427. DeviceNode->Irq         = Irq;
  428. DeviceNode->LogicalSlot = BridgeInfo->logicalSlotNumber;
  429. PCIFR("Device(%4d): 0x%02X.%02X.%02X 0x%02X 0x%04X",
  430.       DeviceCount,Bus, SubBus, AgentId,
  431.       DeviceNode->LogicalSlot,DeviceNode->Vendor);
  432. /***********************************************************
  433.  * On the first device/function, assign irq to slot
  434.  ***********************************************************/
  435. if(Function == 0) { 
  436. FirstSlotId = AgentId;
  437. // AHT iSeries_assign_IRQ(Irq, Bus, SubBus, AgentId);
  438.      }
  439. }
  440. else pci_Log_Error("Read Vendor",Bus,SubBus,AgentId,HvRc);
  441. }
  442. else pci_Log_Error("Connect Bus Unit",Bus,SubBus, AgentId,HvRc);
  443. } /* for (Function = 0; Function < 8; ++Function) */
  444. } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
  445. return HvRc;
  446. }
  447. /************************************************************************/
  448. /* I/0 Memory copy MUST use mmio commands on iSeries                    */
  449. /* To do; For performance, include the hv call directly                 */
  450. /************************************************************************/
  451. void* iSeries_memset_io(void* dest, char c, size_t Count)
  452. {
  453. u8    ByteValue     = c;
  454. long  NumberOfBytes = Count;
  455. char* IoBuffer      = dest;
  456. while(NumberOfBytes > 0) {
  457. iSeries_Write_Byte( ByteValue, (void*)IoBuffer );
  458. ++IoBuffer;
  459. -- NumberOfBytes;
  460. }
  461. return dest;
  462. }
  463. void* iSeries_memcpy_toio(void *dest, void *source, size_t count)
  464. {
  465. char *dst           = dest;
  466. char *src           = source;
  467. long  NumberOfBytes = count;
  468. while(NumberOfBytes > 0) {
  469. iSeries_Write_Byte(*src++, (void*)dst++);
  470. -- NumberOfBytes;
  471. }
  472. return dest;
  473. }
  474. void* iSeries_memcpy_fromio(void *dest, void *source, size_t count)
  475. {
  476. char *dst = dest;
  477. char *src = source;
  478. long  NumberOfBytes = count;
  479. while(NumberOfBytes > 0) {
  480. *dst++ = iSeries_Read_Byte( (void*)src++);
  481. -- NumberOfBytes;
  482. }
  483. return dest;
  484. }
  485. /**********************************************************************************
  486.  * Look down the chain to find the matching Device Device
  487.  **********************************************************************************/
  488. struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev)
  489. {
  490. struct list_head* Device_Node_Ptr = iSeries_Global_Device_List.next;
  491. int Bus   = PciDev->bus->number;
  492. int DevFn = PciDev->devfn;
  493. while(Device_Node_Ptr != &iSeries_Global_Device_List) { 
  494. struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)Device_Node_Ptr;
  495. if(Bus == ISERIES_BUS(DevNode) && DevFn == DevNode->DevFn) {
  496. return DevNode;
  497. }
  498. Device_Node_Ptr = Device_Node_Ptr->next;
  499. }
  500. return NULL;
  501. }
  502. /******************************************************************/
  503. /* Returns the device node for the passed pci_dev                 */
  504. /* Sanity Check Node PciDev to passed pci_dev                     */
  505. /* If none is found, returns a NULL which the client must handle. */
  506. /******************************************************************/
  507. struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev)
  508. {
  509. struct iSeries_Device_Node* Node;
  510. Node = (struct iSeries_Device_Node*)PciDev->sysdata;
  511. if(Node == NULL ) {
  512. Node = find_Device_Node(PciDev);
  513. }
  514. else if(Node->PciDev != PciDev) { 
  515. Node = find_Device_Node(PciDev);
  516. }
  517. return Node;
  518. }
  519. /******************************************************************/
  520. /* Set and reset Device Node Lock                                 */
  521. /******************************************************************/
  522. #define setIoLock() 
  523.     unsigned long IrqFlags; 
  524.     spin_lock_irqsave(&DevNode->IoLock, IrqFlags ); 
  525. #define resetIoLock() 
  526.     int RtnCode = DevNode->ReturnCode; 
  527.     spin_unlock_irqrestore( &DevNode->IoLock, IrqFlags ); 
  528.     return RtnCode;
  529. /**********************************************************************************
  530.  *
  531.  * Read PCI Config Space Code 
  532.  *
  533.  **********************************************************************************/
  534. /** BYTE  *************************************************************************/
  535. int iSeries_Node_read_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8* ReadValue)
  536. {
  537. u8  ReadData;
  538. setIoLock();
  539. ++Pci_Cfg_Read_Count;
  540. DevNode->ReturnCode = HvCallPci_configLoad8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  541.                                                 Offset,&ReadData);
  542. if(Pci_Trace_Flag == 1) {
  543. PCIFR("RCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
  544. }
  545. if(DevNode->ReturnCode != 0 ) { 
  546. printk("PCI: RCB: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  547. PCIFR(      "RCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  548. }
  549. *ReadValue = ReadData;
  550. resetIoLock();
  551. }
  552. /** WORD  *************************************************************************/
  553. int iSeries_Node_read_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16* ReadValue)
  554. {
  555. u16  ReadData; 
  556. setIoLock();
  557. ++Pci_Cfg_Read_Count;
  558. DevNode->ReturnCode = HvCallPci_configLoad16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  559.                                                 Offset,&ReadData);
  560. if(Pci_Trace_Flag == 1) {
  561. PCIFR("RCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
  562. }
  563. if(DevNode->ReturnCode != 0 ) { 
  564. printk("PCI: RCW: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  565. PCIFR(      "RCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  566. }
  567. *ReadValue = ReadData;
  568. resetIoLock();
  569. }
  570. /** DWORD *************************************************************************/
  571. int iSeries_Node_read_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32* ReadValue)
  572. {
  573.   u32  ReadData; 
  574. setIoLock();
  575. ++Pci_Cfg_Read_Count;
  576. DevNode->ReturnCode = HvCallPci_configLoad32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  577.                                                 Offset,&ReadData);
  578. if(Pci_Trace_Flag == 1) {
  579. PCIFR("RCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,ReadData);
  580. }
  581. if(DevNode->ReturnCode != 0 ) { 
  582. printk("PCI: RCL: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  583. PCIFR(      "RCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  584. }
  585. *ReadValue = ReadData;
  586. resetIoLock();
  587. }
  588. int iSeries_pci_read_config_byte(struct pci_dev* PciDev, int Offset, u8* ReadValue) { 
  589. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  590. if(DevNode == NULL) return 0x0301;
  591. return iSeries_Node_read_config_byte( DevNode ,Offset,ReadValue);
  592. }
  593. int iSeries_pci_read_config_word(struct pci_dev* PciDev, int Offset, u16* ReadValue) { 
  594. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  595. if(DevNode == NULL) return 0x0301;
  596. return iSeries_Node_read_config_word( DevNode ,Offset,ReadValue );
  597. }
  598. int iSeries_pci_read_config_dword(struct pci_dev* PciDev, int Offset, u32* ReadValue) { 
  599. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  600. if(DevNode == NULL) return 0x0301;
  601. return iSeries_Node_read_config_dword(DevNode ,Offset,ReadValue  );
  602. }
  603. /**********************************************************************************/
  604. /*                                                                                */
  605. /* Write PCI Config Space                                                         */
  606. /*                                                                                */
  607. /** BYTE  *************************************************************************/
  608. int iSeries_Node_write_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8 WriteData)
  609. {
  610. setIoLock();
  611. ++Pci_Cfg_Write_Count;
  612. DevNode->ReturnCode = HvCallPci_configStore8(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  613.                                                   Offset,WriteData);
  614. if(Pci_Trace_Flag == 1) {
  615. PCIFR("WCB: 0x%04X.%02X 0x%04X = 0x%02X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
  616. }
  617. if(DevNode->ReturnCode != 0 ) { 
  618. printk("PCI: WCB: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  619. PCIFR(      "WCB: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  620. }
  621. resetIoLock();
  622. }
  623. /** WORD  *************************************************************************/
  624. int iSeries_Node_write_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16 WriteData)
  625. {
  626. setIoLock();
  627. ++Pci_Cfg_Write_Count;
  628. DevNode->ReturnCode = HvCallPci_configStore16(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  629.                                                   Offset,WriteData);
  630. if(Pci_Trace_Flag == 1) {
  631. PCIFR("WCW: 0x%04X.%02X 0x%04X = 0x%04X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
  632. }
  633. if(DevNode->ReturnCode != 0 ) { 
  634. printk("PCI: WCW: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  635. PCIFR(      "WCW: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  636. }
  637. resetIoLock();
  638. }
  639. /** DWORD *************************************************************************/
  640. int iSeries_Node_write_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32 WriteData)
  641. {
  642. setIoLock();
  643. ++Pci_Cfg_Write_Count;
  644. DevNode->ReturnCode = HvCallPci_configStore32(ISERIES_BUS(DevNode),ISERIES_SUBBUS(DevNode),0x10,
  645.                                                   Offset,WriteData);
  646. if(Pci_Trace_Flag == 1) {
  647. PCIFR("WCL: 0x%04X.%02X 0x%04X = 0x%08X",ISERIES_BUS(DevNode),DevNode->DevFn,Offset,WriteData);
  648. }
  649. if(DevNode->ReturnCode != 0 ) { 
  650. printk("PCI: WCL: 0x%04X.%02X  Error: 0x%04Xn",ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  651. PCIFR(      "WCL: 0x%04X.%02X  Error: 0x%04X",  ISERIES_BUS(DevNode),DevNode->DevFn,DevNode->ReturnCode);
  652. }
  653. resetIoLock();
  654. }
  655. int iSeries_pci_write_config_byte( struct pci_dev* PciDev,int Offset, u8 WriteValue)
  656. {
  657. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  658. if(DevNode == NULL) return 0x0301;
  659. return iSeries_Node_write_config_byte( DevNode,Offset,WriteValue);
  660. }
  661. int iSeries_pci_write_config_word( struct pci_dev* PciDev,int Offset,u16 WriteValue)
  662. {
  663. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  664. if(DevNode == NULL) return 0x0301;
  665. return iSeries_Node_write_config_word( DevNode,Offset,WriteValue);
  666. }
  667. int iSeries_pci_write_config_dword(struct pci_dev* PciDev,int Offset,u32 WriteValue)
  668. {
  669. struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
  670. if(DevNode == NULL) return 0x0301;
  671. return iSeries_Node_write_config_dword(DevNode,Offset,WriteValue);
  672. }
  673. /************************************************************************/
  674. /* Branch Table                                                         */
  675. /************************************************************************/
  676. struct pci_ops iSeries_pci_ops = {
  677. iSeries_pci_read_config_byte,
  678. iSeries_pci_read_config_word,
  679. iSeries_pci_read_config_dword,
  680. iSeries_pci_write_config_byte,
  681. iSeries_pci_write_config_word,
  682. iSeries_pci_write_config_dword 
  683. };
  684. /************************************************************************
  685.  * Log Pci Error and check Retry Count 
  686.  * -> On Failure, print and log information.
  687.  *    Increment Retry Count, if exceeds max, panic partition.
  688.  * -> If in retry, print and log success
  689.  ************************************************************************/
  690. void logPciError(char* ErrorTxt, void* IoAddress, struct iSeries_Device_Node* DevNode, u64 RtnCode)
  691. {
  692. ++DevNode->IoRetry;
  693. ++Pci_Error_Count;
  694. PCIFR("%s: I/O Error(%1d/%1d):0x%04X  IoAddress:0x%p  Device:0x%04X:%02X",  
  695.       ErrorTxt, DevNode->IoRetry, in_interrupt(), RtnCode, IoAddress, ISERIES_BUS(DevNode),DevNode->AgentId);
  696. /*******************************************************/
  697. /* Filter out EADs freeze and alignment errors         */
  698. /*******************************************************/
  699. if(RtnCode == 0x0102) {
  700. PCIFR("EADS Freeze error.......Panic........");
  701. mf_displaySrc(0xB6000103);
  702. panic_timeout = 0; 
  703. panic("PCI: EADs Freeze error SRC B6000103n");
  704. }
  705. else if(RtnCode == 0x0241) {
  706. PCIFR("MMIO Alignment error: 0x%p",IoAddress);
  707. mf_displaySrc(0xB6000103);
  708. panic_timeout = 0; 
  709. panic("PCI: MMIO Alignment error. SRC B6000103n");
  710. }
  711. /*******************************************************/
  712. /* Bump the retry and check for retry count exceeded.  */
  713. /* If, Exceeded, panic the system.                     */           
  714. /*******************************************************/
  715. if(DevNode->IoRetry > Pci_Retry_Max && Pci_Error_Flag != 0 ) {
  716. mf_displaySrc(0xB6000103);
  717. panic_timeout = 0; 
  718. panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled.n");
  719. }
  720. /**************************************************************/
  721. /* Wait x ms before retrying I/O to give I/O time to recover. */
  722. /* Retry wait delay logic.                                    */
  723. /* - On first retry, no delay, maybe just glitch.             */
  724. /* - On successify retries, vary the delay to avoid being in a*/
  725.         /*   repetitive timing window.                                */ 
  726. /**************************************************************/
  727. if(DevNode->IoRetry > 0) {
  728. udelay(DevNode->IoRetry * 50);
  729. }
  730. }
  731. /************************************************************************
  732.  * Retry was successful
  733.  ************************************************************************/
  734. void  pciRetrySuccessful(struct iSeries_Device_Node* DevNode)
  735. {
  736. struct  timeval  TimeClock;
  737. struct  rtc_time CurTime;
  738. do_gettimeofday(&TimeClock);
  739. to_tm(TimeClock.tv_sec, &CurTime);
  740. PCIFR("Retry Successful(%2d) on Device 0x%04X:%02X at %02d.%02d.%02d",
  741.       DevNode->IoRetry,ISERIES_BUS(DevNode),DevNode->AgentId,
  742.       CurTime.tm_hour,CurTime.tm_min,CurTime.tm_sec);
  743. DevNode->IoRetry = 0;
  744. }
  745. /************************************************************************/
  746. /* Translate the I/O Address into a device node, bar, and bar offset.   */
  747. /* Note: Make sure the passed variable end up on the stack to avoid     */
  748. /* the exposure of being device global.                                 */
  749. /* The Device Node is Lock to block other I/O to device.                */
  750. /************************************************************************/
  751. #define setUpMmIo(IoAddress,Type) 
  752. unsigned long   IrqFlags; 
  753. struct HvCallPci_LoadReturn Return; 
  754. union HvDsaMap  DsaData;  
  755. u64             BarOffset;
  756. unsigned long BaseIoAddr = (unsigned long)IoAddress-iSeries_Base_Io_Memory; 
  757. long          TableIndex = (BaseIoAddr/iSeries_IoMmTable_Entry_Size);       
  758. struct iSeries_Device_Node* DevNode = *(iSeries_IoMmTable+TableIndex);      
  759. if(DevNode != NULL) { 
  760.     DsaData.DsaAddr       = ISERIES_DSA(DevNode); 
  761.     DsaData.Dsa.barNumber = *(iSeries_IoBarTable+TableIndex); 
  762.     BarOffset             = BaseIoAddr % iSeries_IoMmTable_Entry_Size; 
  763.     ++Pci_Io_##Type##_Count; 
  764.     spin_lock_irqsave(&DevNode->IoLock, IrqFlags ); 
  765. else panic("PCI: Invalid PCI IoAddress detected 0x%p!n",IoAddress);
  766. /************************************************************************/
  767. /* Read MM I/O Instructions for the iSeries                             */
  768. /* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*/
  769. /* else, data is returned in big Endian format.                         */
  770. /************************************************************************/
  771. /* iSeries_Read_Byte = Read Byte  ( 8 bit)                              */
  772. /* iSeries_Read_Word = Read Word  (16 bit)                              */
  773. /* iSeries_Read_Long = Read Long  (32 bit)                              */
  774. /************************************************************************/
  775. u8  iSeries_Read_Byte(void* IoAddress)
  776. {
  777. setUpMmIo(IoAddress,Read);
  778. do {
  779. HvCall3Ret16(HvCallPciBarLoad8, &Return, DsaData.DsaAddr,BarOffset, 0);
  780. if(Return.rc != 0 ) {
  781. logPciError("RDB",IoAddress, DevNode, Return.rc);
  782. }
  783. else if ( DevNode->IoRetry > 0) {
  784. pciRetrySuccessful(DevNode);
  785. }
  786. } while (Return.rc != 0);
  787. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  788. if(Pci_Trace_Flag == 1 ) PCIFR("RDB: IoAddress 0x%p = 0x%02X",IoAddress, (u8)Return.value);
  789. return (u8)Return.value;
  790. }
  791. int Retry_Test = 0;
  792. u16  iSeries_Read_Word(void* IoAddress)
  793. {
  794. setUpMmIo(IoAddress,Read);
  795. do {
  796. HvCall3Ret16(HvCallPciBarLoad16,&Return, DsaData.DsaAddr,BarOffset, 0);
  797. if(Return.rc != 0 ) {
  798. logPciError("RDW",IoAddress, DevNode, Return.rc);
  799. }
  800. else if ( DevNode->IoRetry > 0) {
  801. pciRetrySuccessful(DevNode);
  802. }
  803. } while (Return.rc != 0);
  804. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  805. if(Pci_Trace_Flag == 1 ) PCIFR("RDW: IoAddress 0x%p = 0x%04X",IoAddress, (u16)Return.value);
  806. return swab16((u16)Return.value);
  807. }
  808. u32  iSeries_Read_Long(void* IoAddress)
  809. {
  810. setUpMmIo(IoAddress,Read);
  811. do {
  812. HvCall3Ret16(HvCallPciBarLoad32,&Return, DsaData.DsaAddr,BarOffset, 0);
  813. if(Return.rc != 0 ) {
  814. logPciError("RDL",IoAddress, DevNode, Return.rc);
  815. }
  816. else if ( DevNode->IoRetry > 0) {
  817. pciRetrySuccessful(DevNode);
  818. }
  819. } while (Return.rc != 0);
  820. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  821. if(Pci_Trace_Flag == 1 ) PCIFR("RDL: IoAddress 0x%p = 0x%08X",IoAddress, swab32((u32)Return.value));
  822. return swab32((u32)Return.value);
  823. }
  824. /************************************************************************/
  825. /* Write MM I/O Instructions for the iSeries                            */
  826. /************************************************************************/
  827. /* iSeries_Write_Byte = Write Byte (8 bit)                              */
  828. /* iSeries_Write_Word = Write Word(16 bit)                              */
  829. /* iSeries_Write_Long = Write Long(32 bit)                              */
  830. /************************************************************************/
  831. void iSeries_Write_Byte(u8 Data, void* IoAddress)
  832. {
  833. setUpMmIo(IoAddress,Write);
  834. do {
  835. Return.rc = HvCall4(HvCallPciBarStore8, DsaData.DsaAddr,BarOffset, Data, 0);
  836. if(Return.rc != 0 ) {
  837. logPciError("WWB",IoAddress, DevNode, Return.rc);
  838. }
  839. else if ( DevNode->IoRetry > 0) {
  840. pciRetrySuccessful(DevNode);
  841. }
  842. } while (Return.rc != 0);
  843. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  844. if(Pci_Trace_Flag == 1) PCIFR("WWB: IoAddress 0x%p = 0x%02X",IoAddress,Data);
  845. }
  846. void iSeries_Write_Word(u16 Data, void* IoAddress)
  847. {
  848. setUpMmIo(IoAddress,Write);
  849. do {
  850. Return.rc = HvCall4(HvCallPciBarStore16,DsaData.DsaAddr,BarOffset, swab16(Data), 0);
  851. if(Return.rc != 0 ) {
  852. logPciError("WWW",IoAddress, DevNode, Return.rc);
  853. }
  854. else if ( DevNode->IoRetry > 0) {
  855. pciRetrySuccessful(DevNode);
  856. }
  857. } while (Return.rc != 0);
  858. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  859. if(Pci_Trace_Flag == 1) PCIFR("WWW: IoAddress 0x%p = 0x%04X",IoAddress,Data);
  860. }
  861. void iSeries_Write_Long(u32 Data, void* IoAddress)
  862. {
  863. setUpMmIo(IoAddress,Write);
  864. do {
  865. Return.rc = HvCall4(HvCallPciBarStore32,DsaData.DsaAddr,BarOffset, swab32(Data), 0);
  866. if(Return.rc != 0 ) {
  867. logPciError("WWL",IoAddress, DevNode, Return.rc);
  868. }
  869. else if ( DevNode->IoRetry > 0) {
  870. pciRetrySuccessful(DevNode);
  871. }
  872. } while (Return.rc != 0);
  873. spin_unlock_irqrestore(&DevNode->IoLock, IrqFlags ); 
  874. if(Pci_Trace_Flag == 1) PCIFR("WWL: IoAddress 0x%p = 0x%08X",IoAddress, Data);
  875. }
  876. /*
  877.  * This is called very early before the page table is setup.
  878.  * There are warnings here because of type mismatches.. Okay for now. AHT
  879.  */
  880. void 
  881. iSeries_pcibios_init_early(void)
  882. {
  883. //ppc_md.pcibios_read_config_byte   = iSeries_Node_read_config_byte;
  884. //ppc_md.pcibios_read_config_word   = iSeries_Node_read_config_word;
  885. //ppc_md.pcibios_read_config_dword  = iSeries_Node_read_config_dword;
  886. //ppc_md.pcibios_write_config_byte  = iSeries_Node_write_config_byte;
  887. //ppc_md.pcibios_write_config_word  = iSeries_Node_write_config_word;
  888. //ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
  889. }
  890. /************************************************************************/
  891. /* Set the slot reset line to the state passed in.                      */
  892. /* This is the platform specific for code for the pci_reset_device      */
  893. /* function.                                                            */
  894. /************************************************************************/
  895. int pci_set_reset(struct pci_dev* PciDev, int State) {
  896. struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
  897.   if (DeviceNode == NULL) { 
  898. printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %pn",PciDev);
  899. return -1;
  900. }
  901. DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,State);
  902. return DeviceNode->ReturnCode;
  903. }