vserver 1.9.3
[linux-2.6.git] / arch / ppc64 / kernel / iSeries_pci.c
1 #define PCIFR(...)
2 /*
3  * iSeries_pci.c
4  *
5  * Copyright (C) 2001 Allan Trautman, IBM Corporation
6  *
7  * iSeries specific routines for PCI.
8  * 
9  * Based on code from pci.c and iSeries_pci.c 32bit
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  */
25 #include <linux/kernel.h>
26 #include <linux/list.h> 
27 #include <linux/string.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/ide.h>
31 #include <linux/pci.h>
32
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/iommu.h>
41
42 #include <asm/iSeries/HvCallPci.h>
43 #include <asm/iSeries/HvCallSm.h>
44 #include <asm/iSeries/HvCallXm.h>
45 #include <asm/iSeries/LparData.h>
46 #include <asm/iSeries/iSeries_irq.h>
47 #include <asm/iSeries/iSeries_pci.h>
48 #include <asm/iSeries/mf.h>
49
50 #include "iSeries_IoMmTable.h"
51 #include "pci.h"
52
53 extern int panic_timeout;
54
55 extern unsigned long iSeries_Base_Io_Memory;    
56
57 extern struct iommu_table *tceTables[256];
58
59 extern void iSeries_MmIoTest(void);
60
61 /*
62  * Forward declares of prototypes. 
63  */
64 static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
65 static void iSeries_Scan_PHBs_Slots(struct pci_controller *Phb);
66 static void iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus,
67                 int IdSel);
68 static int iSeries_Scan_Bridge_Slot(HvBusNumber Bus,
69                 struct HvCallPci_BridgeInfo *Info);
70
71 LIST_HEAD(iSeries_Global_Device_List);
72
73 static int DeviceCount;
74
75 /* Counters and control flags. */
76 static long Pci_Io_Read_Count;
77 static long Pci_Io_Write_Count;
78 #if 0
79 static long Pci_Cfg_Read_Count;
80 static long Pci_Cfg_Write_Count;
81 #endif
82 static long Pci_Error_Count;
83
84 static int Pci_Retry_Max = 3;   /* Only retry 3 times  */       
85 static int Pci_Error_Flag = 1;  /* Set Retry Error on. */
86
87 static struct pci_ops iSeries_pci_ops;
88
89 /*
90  * Log Error infor in Flight Recorder to system Console.
91  * Filter out the device not there errors.
92  * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
93  * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
94  * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
95  */
96 static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
97                 int AgentId, int HvRc)
98 {
99         if (HvRc == 0x0302)
100                 return;
101
102         printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
103                Error_Text, Bus, SubBus, AgentId, HvRc);
104 }
105
106 /*
107  * build_device_node(u16 Bus, int SubBus, u8 DevFn)
108  */
109 static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
110                 HvSubBusNumber SubBus, int AgentId, int Function)
111 {
112         struct iSeries_Device_Node *node;
113
114         PPCDBG(PPCDBG_BUSWALK,
115                         "-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
116                         Bus, SubBus, AgentId, Function);
117
118         node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
119         if (node == NULL)
120                 return NULL;
121
122         memset(node, 0, sizeof(struct iSeries_Device_Node));
123         list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
124 #if 0
125         node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
126 #endif
127         node->DsaAddr.DsaAddr = 0;
128         node->DsaAddr.Dsa.busNumber = Bus;
129         node->DsaAddr.Dsa.subBusNumber = SubBus;
130         node->DsaAddr.Dsa.deviceId = 0x10;
131         node->AgentId = AgentId;
132         node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
133         node->IoRetry = 0;
134         iSeries_Get_Location_Code(node);
135         PCIFR("Device 0x%02X.%2X, Node:0x%p ", ISERIES_BUS(node),
136                         ISERIES_DEVFUN(node), node);
137         return node;
138 }
139
140 /*
141  * unsigned long __init find_and_init_phbs(void)
142  *
143  * Description:
144  *   This function checks for all possible system PCI host bridges that connect
145  *   PCI buses.  The system hypervisor is queried as to the guest partition
146  *   ownership status.  A pci_controller is built for any bus which is partially
147  *   owned or fully owned by this guest partition.
148  */
149 unsigned long __init find_and_init_phbs(void)
150 {
151         struct pci_controller *phb;
152         HvBusNumber bus;
153
154         PPCDBG(PPCDBG_BUSWALK, "find_and_init_phbs Entry\n");
155
156         /* Check all possible buses. */
157         for (bus = 0; bus < 256; bus++) {
158                 int ret = HvCallXm_testBus(bus);
159                 if (ret == 0) {
160                         printk("bus %d appears to exist\n", bus);
161                         phb = pci_alloc_pci_controller(phb_type_hypervisor);
162                         if (phb == NULL) {
163                                 PCIFR("Allocate pci_controller failed.");
164                                 return -1;
165                         }
166                         phb->pci_mem_offset = phb->local_number = bus;
167                         phb->first_busno = bus;
168                         phb->last_busno = bus;
169                         phb->ops = &iSeries_pci_ops;
170
171                         PPCDBG(PPCDBG_BUSWALK, "PCI:Create iSeries pci_controller(%p), Bus: %04X\n",
172                                         phb, bus);
173                         PCIFR("Create iSeries PHB controller: %04X", bus);
174
175                         /* Find and connect the devices. */
176                         iSeries_Scan_PHBs_Slots(phb);
177                 }
178                 /*
179                  * Check for Unexpected Return code, a clue that something
180                  * has gone wrong.
181                  */
182                 else if (ret != 0x0301)
183                         printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
184                                bus, ret);
185         }
186         return 0;
187 }
188
189 /*
190  * iSeries_pcibios_init
191  *  
192  * Chance to initialize and structures or variable before PCI Bus walk.
193  */
194 void iSeries_pcibios_init(void)
195 {
196         PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); 
197         iSeries_IoMmTable_Initialize();
198         find_and_init_phbs();
199         /* pci_assign_all_busses = 0;           SFRXXX*/
200         PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); 
201 }
202
203 /*
204  * iSeries_pci_final_fixup(void)  
205  */
206 void __init iSeries_pci_final_fixup(void)
207 {
208         struct pci_dev *pdev = NULL;
209         struct iSeries_Device_Node *node;
210         char Buffer[256];
211         int DeviceCount = 0;
212
213         PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); 
214
215         /* Fix up at the device node and pci_dev relationship */
216         mf_displaySrc(0xC9000100);
217
218         printk("pcibios_final_fixup\n");
219         while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))
220                         != NULL) {
221                 node = find_Device_Node(pdev->bus->number, pdev->devfn);
222                 printk("pci dev %p (%x.%x), node %p\n", pdev,
223                        pdev->bus->number, pdev->devfn, node);
224
225                 if (node != NULL) {
226                         ++DeviceCount;
227                         pdev->sysdata = (void *)node;
228                         node->PciDev = pdev;
229                         PPCDBG(PPCDBG_BUSWALK,
230                                         "pdev 0x%p <==> DevNode 0x%p\n",
231                                         pdev, node);
232                         iSeries_allocateDeviceBars(pdev);
233                         iSeries_Device_Information(pdev, Buffer,
234                                         sizeof(Buffer));
235                         printk("%d. %s\n", DeviceCount, Buffer);
236                         iommu_devnode_init(node);
237                 } else
238                         printk("PCI: Device Tree not found for 0x%016lX\n",
239                                         (unsigned long)pdev);
240                 pdev->irq = node->Irq;
241         }
242         iSeries_IoMmTable_Status();
243         iSeries_activate_IRQs();
244         mf_displaySrc(0xC9000200);
245 }
246
247 void pcibios_fixup_bus(struct pci_bus *PciBus)
248 {
249         PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
250                         PciBus->number); 
251 }
252
253 void pcibios_fixup_resources(struct pci_dev *pdev)
254 {
255         PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
256 }   
257
258 /*
259  * Loop through each node function to find usable EADs bridges.  
260  */
261 static void iSeries_Scan_PHBs_Slots(struct pci_controller *Phb)
262 {
263         struct HvCallPci_DeviceInfo *DevInfo;
264         HvBusNumber bus = Phb->local_number;    /* System Bus */        
265         const HvSubBusNumber SubBus = 0;        /* EADs is always 0. */
266         int HvRc = 0;
267         int IdSel;      
268         const int MaxAgents = 8;
269
270         DevInfo = (struct HvCallPci_DeviceInfo*)
271                 kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
272         if (DevInfo == NULL)
273                 return;
274
275         /*
276          * Probe for EADs Bridges      
277          */
278         for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
279                 HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
280                                 ISERIES_HV_ADDR(DevInfo),
281                                 sizeof(struct HvCallPci_DeviceInfo));
282                 if (HvRc == 0) {
283                         if (DevInfo->deviceType == HvCallPci_NodeDevice)
284                                 iSeries_Scan_EADs_Bridge(bus, SubBus, IdSel);
285                         else
286                                 printk("PCI: Invalid System Configuration(0x%02X)"
287                                        " for bus 0x%02x id 0x%02x.\n",
288                                        DevInfo->deviceType, bus, IdSel);
289                 }
290                 else
291                         pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
292         }
293         kfree(DevInfo);
294 }
295
296 static void iSeries_Scan_EADs_Bridge(HvBusNumber bus, HvSubBusNumber SubBus,
297                 int IdSel)
298 {
299         struct HvCallPci_BridgeInfo *BridgeInfo;
300         HvAgentId AgentId;
301         int Function;
302         int HvRc;
303
304         BridgeInfo = (struct HvCallPci_BridgeInfo *)
305                 kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
306         if (BridgeInfo == NULL)
307                 return;
308
309         /* Note: hvSubBus and irq is always be 0 at this level! */
310         for (Function = 0; Function < 8; ++Function) {
311                 AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
312                 HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
313                 if (HvRc == 0) {
314                         printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
315                                bus, IdSel, Function, AgentId);
316                         /*  Connect EADs: 0x18.00.12 = 0x00 */
317                         PPCDBG(PPCDBG_BUSWALK,
318                                         "PCI:Connect EADs: 0x%02X.%02X.%02X\n",
319                                         bus, SubBus, AgentId);
320                         HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
321                                         ISERIES_HV_ADDR(BridgeInfo),
322                                         sizeof(struct HvCallPci_BridgeInfo));
323                         if (HvRc == 0) {
324                                 printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
325                                         BridgeInfo->busUnitInfo.deviceType,
326                                         BridgeInfo->subBusNumber,
327                                         BridgeInfo->maxAgents,
328                                         BridgeInfo->maxSubBusNumber,
329                                         BridgeInfo->logicalSlotNumber);
330                                 PPCDBG(PPCDBG_BUSWALK,
331                                         "PCI: BridgeInfo, Type:0x%02X, SubBus:0x%02X, MaxAgents:0x%02X, MaxSubBus: 0x%02X, LSlot: 0x%02X\n",
332                                         BridgeInfo->busUnitInfo.deviceType,
333                                         BridgeInfo->subBusNumber,
334                                         BridgeInfo->maxAgents,
335                                         BridgeInfo->maxSubBusNumber,
336                                         BridgeInfo->logicalSlotNumber);
337
338                                 if (BridgeInfo->busUnitInfo.deviceType ==
339                                                 HvCallPci_BridgeDevice)  {
340                                         /* Scan_Bridge_Slot...: 0x18.00.12 */
341                                         iSeries_Scan_Bridge_Slot(bus, BridgeInfo);
342                                 } else
343                                         printk("PCI: Invalid Bridge Configuration(0x%02X)",
344                                                 BridgeInfo->busUnitInfo.deviceType);
345                         }
346                 } else if (HvRc != 0x000B)
347                         pci_Log_Error("EADs Connect",
348                                         bus, SubBus, AgentId, HvRc);
349         }
350         kfree(BridgeInfo);
351 }
352
353 /*
354  * This assumes that the node slot is always on the primary bus!
355  */
356 static int iSeries_Scan_Bridge_Slot(HvBusNumber Bus,
357                 struct HvCallPci_BridgeInfo *BridgeInfo)
358 {
359         struct iSeries_Device_Node *node;
360         HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
361         u16 VendorId = 0;
362         int HvRc = 0;
363         u8 Irq = 0;
364         int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
365         int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
366         HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
367
368         /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
369         Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
370         PPCDBG(PPCDBG_BUSWALK,
371                 "PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
372                 Bus, 0, EADsIdSel, Irq);
373
374         /*
375          * Connect all functions of any device found.  
376          */
377         for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
378                 for (Function = 0; Function < 8; ++Function) {
379                         HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
380                         HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
381                                         AgentId, Irq);
382                         if (HvRc != 0) {
383                                 pci_Log_Error("Connect Bus Unit",
384                                               Bus, SubBus, AgentId, HvRc);
385                                 continue;
386                         }
387
388                         HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
389                                                       PCI_VENDOR_ID, &VendorId);
390                         if (HvRc != 0) {
391                                 pci_Log_Error("Read Vendor",
392                                               Bus, SubBus, AgentId, HvRc);
393                                 continue;
394                         }
395                         printk("read vendor ID: %x\n", VendorId);
396
397                         /* FoundDevice: 0x18.28.10 = 0x12AE */
398                         PPCDBG(PPCDBG_BUSWALK,
399                                "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
400                                Bus, SubBus, AgentId, VendorId, Irq);
401                         HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
402                                                       PCI_INTERRUPT_LINE, Irq);  
403                         if (HvRc != 0)
404                                 pci_Log_Error("PciCfgStore Irq Failed!",
405                                               Bus, SubBus, AgentId, HvRc);
406
407                         ++DeviceCount;
408                         node = build_device_node(Bus, SubBus, EADsIdSel, Function);
409                         node->Vendor = VendorId;
410                         node->Irq = Irq;
411                         node->LogicalSlot = BridgeInfo->logicalSlotNumber;
412
413                 } /* for (Function = 0; Function < 8; ++Function) */
414         } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
415         return HvRc;
416 }
417
418 /*
419  * I/0 Memory copy MUST use mmio commands on iSeries
420  * To do; For performance, include the hv call directly
421  */
422 void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
423 {
424         u8 ByteValue = c;
425         long NumberOfBytes = Count;
426
427         while (NumberOfBytes > 0) {
428                 iSeries_Write_Byte(ByteValue, dest++);
429                 -- NumberOfBytes;
430         }
431 }
432 EXPORT_SYMBOL(iSeries_memset_io);
433
434 void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
435 {
436         char *src = source;
437         long NumberOfBytes = count;
438
439         while (NumberOfBytes > 0) {
440                 iSeries_Write_Byte(*src++, dest++);
441                 -- NumberOfBytes;
442         }
443 }
444 EXPORT_SYMBOL(iSeries_memcpy_toio);
445
446 void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
447 {
448         char *dst = dest;
449         long NumberOfBytes = count;
450
451         while (NumberOfBytes > 0) {
452                 *dst++ = iSeries_Read_Byte(src++);
453                 -- NumberOfBytes;
454         }
455 }
456 EXPORT_SYMBOL(iSeries_memcpy_fromio);
457
458 /*
459  * Look down the chain to find the matching Device Device
460  */
461 static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
462 {
463         struct list_head *pos;
464
465         list_for_each(pos, &iSeries_Global_Device_List) {
466                 struct iSeries_Device_Node *node =
467                         list_entry(pos, struct iSeries_Device_Node, Device_List);
468
469                 if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
470                         return node;
471         }
472         return NULL;
473 }
474
475 #if 0
476 /*
477  * Returns the device node for the passed pci_dev
478  * Sanity Check Node PciDev to passed pci_dev
479  * If none is found, returns a NULL which the client must handle.
480  */
481 static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
482 {
483         struct iSeries_Device_Node *node;
484
485         node = pdev->sysdata;
486         if (node == NULL || node->PciDev != pdev)
487                 node = find_Device_Node(pdev->bus->number, pdev->devfn);
488         return node;
489 }
490 #endif
491
492 /*
493  * Config space read and write functions.
494  * For now at least, we look for the device node for the bus and devfn
495  * that we are asked to access.  It may be possible to translate the devfn
496  * to a subbus and deviceid more directly.
497  */
498 static u64 hv_cfg_read_func[4]  = {
499         HvCallPciConfigLoad8, HvCallPciConfigLoad16,
500         HvCallPciConfigLoad32, HvCallPciConfigLoad32
501 };
502
503 static u64 hv_cfg_write_func[4] = {
504         HvCallPciConfigStore8, HvCallPciConfigStore16,
505         HvCallPciConfigStore32, HvCallPciConfigStore32
506 };
507
508 /*
509  * Read PCI config space
510  */
511 static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
512                 int offset, int size, u32 *val)
513 {
514         struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
515         u64 fn;
516         struct HvCallPci_LoadReturn ret;
517
518         if (node == NULL)
519                 return PCIBIOS_DEVICE_NOT_FOUND;
520
521         fn = hv_cfg_read_func[(size - 1) & 3];
522         HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
523
524         if (ret.rc != 0) {
525                 *val = ~0;
526                 return PCIBIOS_DEVICE_NOT_FOUND;        /* or something */
527         }
528
529         *val = ret.value;
530         return 0;
531 }
532
533 /*
534  * Write PCI config space
535  */
536
537 static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
538                 int offset, int size, u32 val)
539 {
540         struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
541         u64 fn;
542         u64 ret;
543
544         if (node == NULL)
545                 return PCIBIOS_DEVICE_NOT_FOUND;
546
547         fn = hv_cfg_write_func[(size - 1) & 3];
548         ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);
549
550         if (ret != 0)
551                 return PCIBIOS_DEVICE_NOT_FOUND;
552
553         return 0;
554 }
555
556 static struct pci_ops iSeries_pci_ops = {
557         .read = iSeries_pci_read_config,
558         .write = iSeries_pci_write_config
559 };
560
561 /*
562  * Check Return Code
563  * -> On Failure, print and log information.
564  *    Increment Retry Count, if exceeds max, panic partition.
565  * -> If in retry, print and log success 
566  *
567  * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
568  * PCI: Device 23.90 ReadL Retry( 1)
569  * PCI: Device 23.90 ReadL Retry Successful(1)
570  */
571 static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
572                 u64 ret)
573 {
574         if (ret != 0)  {
575                 ++Pci_Error_Count;
576                 ++DevNode->IoRetry;
577                 printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
578                                 TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
579                                 DevNode->IoRetry, (int)ret);
580                 /*
581                  * Bump the retry and check for retry count exceeded.
582                  * If, Exceeded, panic the system.
583                  */
584                 if ((DevNode->IoRetry > Pci_Retry_Max) &&
585                                 (Pci_Error_Flag > 0)) {
586                         mf_displaySrc(0xB6000103);
587                         panic_timeout = 0; 
588                         panic("PCI: Hardware I/O Error, SRC B6000103, "
589                                         "Automatic Reboot Disabled.\n");
590                 }
591                 return -1;      /* Retry Try */
592         }
593         /* If retry was in progress, log success and rest retry count */
594         if (DevNode->IoRetry > 0) {
595                 PCIFR("%s: Device 0x%04X:%02X Retry Successful(%2d).",
596                                 TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
597                                 DevNode->IoRetry);
598                 DevNode->IoRetry = 0;
599         }
600         return 0; 
601 }
602
603 /*
604  * Translate the I/O Address into a device node, bar, and bar offset.
605  * Note: Make sure the passed variable end up on the stack to avoid
606  * the exposure of being device global.
607  */
608 static inline struct iSeries_Device_Node *xlateIoMmAddress(const volatile void __iomem *IoAddress,
609                  u64 *dsaptr, u64 *BarOffsetPtr)
610 {
611         unsigned long OrigIoAddr;
612         unsigned long BaseIoAddr;
613         unsigned long TableIndex;
614         struct iSeries_Device_Node *DevNode;
615
616         OrigIoAddr = (unsigned long __force)IoAddress;
617         if ((OrigIoAddr < iSeries_Base_Io_Memory) ||
618                         (OrigIoAddr >= iSeries_Max_Io_Memory))
619                 return NULL;
620         BaseIoAddr = OrigIoAddr - iSeries_Base_Io_Memory;
621         TableIndex = BaseIoAddr / iSeries_IoMmTable_Entry_Size;
622         DevNode = iSeries_IoMmTable[TableIndex];
623
624         if (DevNode != NULL) {
625                 int barnum = iSeries_IoBarTable[TableIndex];
626                 *dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
627                 *BarOffsetPtr = BaseIoAddr % iSeries_IoMmTable_Entry_Size;
628         } else
629                 panic("PCI: Invalid PCI IoAddress detected!\n");
630         return DevNode;
631 }
632
633 /*
634  * Read MM I/O Instructions for the iSeries
635  * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
636  * else, data is returned in big Endian format.
637  *
638  * iSeries_Read_Byte = Read Byte  ( 8 bit)
639  * iSeries_Read_Word = Read Word  (16 bit)
640  * iSeries_Read_Long = Read Long  (32 bit)
641  */
642 u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
643 {
644         u64 BarOffset;
645         u64 dsa;
646         struct HvCallPci_LoadReturn ret;
647         struct iSeries_Device_Node *DevNode =
648                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
649
650         if (DevNode == NULL) {
651                 static unsigned long last_jiffies;
652                 static int num_printed;
653
654                 if ((jiffies - last_jiffies) > 60 * HZ) {
655                         last_jiffies = jiffies;
656                         num_printed = 0;
657                 }
658                 if (num_printed++ < 10)
659                         printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
660                 return 0xff;
661         }
662         do {
663                 ++Pci_Io_Read_Count;
664                 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
665         } while (CheckReturnCode("RDB", DevNode, ret.rc) != 0);
666
667         return (u8)ret.value;
668 }
669 EXPORT_SYMBOL(iSeries_Read_Byte);
670
671 u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
672 {
673         u64 BarOffset;
674         u64 dsa;
675         struct HvCallPci_LoadReturn ret;
676         struct iSeries_Device_Node *DevNode =
677                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
678
679         if (DevNode == NULL) {
680                 static unsigned long last_jiffies;
681                 static int num_printed;
682
683                 if ((jiffies - last_jiffies) > 60 * HZ) {
684                         last_jiffies = jiffies;
685                         num_printed = 0;
686                 }
687                 if (num_printed++ < 10)
688                         printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
689                 return 0xffff;
690         }
691         do {
692                 ++Pci_Io_Read_Count;
693                 HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
694                                 BarOffset, 0);
695         } while (CheckReturnCode("RDW", DevNode, ret.rc) != 0);
696
697         return swab16((u16)ret.value);
698 }
699 EXPORT_SYMBOL(iSeries_Read_Word);
700
701 u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
702 {
703         u64 BarOffset;
704         u64 dsa;
705         struct HvCallPci_LoadReturn ret;
706         struct iSeries_Device_Node *DevNode =
707                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
708
709         if (DevNode == NULL) {
710                 static unsigned long last_jiffies;
711                 static int num_printed;
712
713                 if ((jiffies - last_jiffies) > 60 * HZ) {
714                         last_jiffies = jiffies;
715                         num_printed = 0;
716                 }
717                 if (num_printed++ < 10)
718                         printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
719                 return 0xffffffff;
720         }
721         do {
722                 ++Pci_Io_Read_Count;
723                 HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
724                                 BarOffset, 0);
725         } while (CheckReturnCode("RDL", DevNode, ret.rc) != 0);
726
727         return swab32((u32)ret.value);
728 }
729 EXPORT_SYMBOL(iSeries_Read_Long);
730
731 /*
732  * Write MM I/O Instructions for the iSeries
733  *
734  * iSeries_Write_Byte = Write Byte (8 bit)
735  * iSeries_Write_Word = Write Word(16 bit)
736  * iSeries_Write_Long = Write Long(32 bit)
737  */
738 void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
739 {
740         u64 BarOffset;
741         u64 dsa;
742         u64 rc;
743         struct iSeries_Device_Node *DevNode =
744                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
745
746         if (DevNode == NULL) {
747                 static unsigned long last_jiffies;
748                 static int num_printed;
749
750                 if ((jiffies - last_jiffies) > 60 * HZ) {
751                         last_jiffies = jiffies;
752                         num_printed = 0;
753                 }
754                 if (num_printed++ < 10)
755                         printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
756                 return;
757         }
758         do {
759                 ++Pci_Io_Write_Count;
760                 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
761         } while (CheckReturnCode("WWB", DevNode, rc) != 0);
762 }
763 EXPORT_SYMBOL(iSeries_Write_Byte);
764
765 void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
766 {
767         u64 BarOffset;
768         u64 dsa;
769         u64 rc;
770         struct iSeries_Device_Node *DevNode =
771                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
772
773         if (DevNode == NULL) {
774                 static unsigned long last_jiffies;
775                 static int num_printed;
776
777                 if ((jiffies - last_jiffies) > 60 * HZ) {
778                         last_jiffies = jiffies;
779                         num_printed = 0;
780                 }
781                 if (num_printed++ < 10)
782                         printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
783                 return;
784         }
785         do {
786                 ++Pci_Io_Write_Count;
787                 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
788         } while (CheckReturnCode("WWW", DevNode, rc) != 0);
789 }
790 EXPORT_SYMBOL(iSeries_Write_Word);
791
792 void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
793 {
794         u64 BarOffset;
795         u64 dsa;
796         u64 rc;
797         struct iSeries_Device_Node *DevNode =
798                 xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
799
800         if (DevNode == NULL) {
801                 static unsigned long last_jiffies;
802                 static int num_printed;
803
804                 if ((jiffies - last_jiffies) > 60 * HZ) {
805                         last_jiffies = jiffies;
806                         num_printed = 0;
807                 }
808                 if (num_printed++ < 10)
809                         printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
810                 return;
811         }
812         do {
813                 ++Pci_Io_Write_Count;
814                 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
815         } while (CheckReturnCode("WWL", DevNode, rc) != 0);
816 }
817 EXPORT_SYMBOL(iSeries_Write_Long);