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