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