Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/pci: base support

Add PCI support for s390, (only 64 bit mode is supported by hardware):
- PCI facility tests
- PCI instructions: pcilg, pcistg, pcistb, stpcifc, mpcifc, rpcit
- map readb/w/l/q and writeb/w/l/q to pcilg and pcistg instructions
- pci_iomap implementation
- memcpy_fromio/toio
- pci_root_ops using special pcilg/pcistg
- device, bus and domain allocation

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Jan Glauber and committed by
Martin Schwidefsky
cd248341 d07dc5d8

+1201 -9
+1
arch/s390/Kbuild
··· 6 6 obj-$(CONFIG_APPLDATA_BASE) += appldata/ 7 7 obj-$(CONFIG_MATHEMU) += math-emu/ 8 8 obj-y += net/ 9 + obj-$(CONFIG_PCI) += pci/
+51 -4
arch/s390/include/asm/io.h
··· 9 9 #ifndef _S390_IO_H 10 10 #define _S390_IO_H 11 11 12 + #include <linux/kernel.h> 12 13 #include <asm/page.h> 13 - 14 - #define IO_SPACE_LIMIT 0xffffffff 14 + #include <asm/pci_io.h> 15 15 16 16 /* 17 17 * Change virtual addresses to physical addresses and vv. ··· 24 24 " lra %0,0(%1)\n" 25 25 " jz 0f\n" 26 26 " la %0,0\n" 27 - "0:" 27 + "0:" 28 28 : "=a" (real_address) : "a" (address) : "cc"); 29 - return real_address; 29 + return real_address; 30 30 } 31 + #define virt_to_phys virt_to_phys 31 32 32 33 static inline void * phys_to_virt(unsigned long address) 33 34 { ··· 42 41 * Convert a virtual cached pointer to an uncached pointer 43 42 */ 44 43 #define xlate_dev_kmem_ptr(p) p 44 + 45 + #define IO_SPACE_LIMIT 0 46 + 47 + #ifdef CONFIG_PCI 48 + 49 + #define ioremap_nocache(addr, size) ioremap(addr, size) 50 + #define ioremap_wc ioremap_nocache 51 + 52 + /* TODO: s390 cannot support io_remap_pfn_range... */ 53 + #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 54 + remap_pfn_range(vma, vaddr, pfn, size, prot) 55 + 56 + static inline void __iomem *ioremap(unsigned long offset, unsigned long size) 57 + { 58 + return (void __iomem *) offset; 59 + } 60 + 61 + static inline void iounmap(volatile void __iomem *addr) 62 + { 63 + } 64 + 65 + /* 66 + * s390 needs a private implementation of pci_iomap since ioremap with its 67 + * offset parameter isn't sufficient. That's because BAR spaces are not 68 + * disjunctive on s390 so we need the bar parameter of pci_iomap to find 69 + * the corresponding device and create the mapping cookie. 70 + */ 71 + #define pci_iomap pci_iomap 72 + #define pci_iounmap pci_iounmap 73 + 74 + #define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count) 75 + #define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count) 76 + #define memset_io(dst, val, count) zpci_memset_io(dst, val, count) 77 + 78 + #define __raw_readb zpci_read_u8 79 + #define __raw_readw zpci_read_u16 80 + #define __raw_readl zpci_read_u32 81 + #define __raw_readq zpci_read_u64 82 + #define __raw_writeb zpci_write_u8 83 + #define __raw_writew zpci_write_u16 84 + #define __raw_writel zpci_write_u32 85 + #define __raw_writeq zpci_write_u64 86 + 87 + #endif /* CONFIG_PCI */ 88 + 89 + #include <asm-generic/io.h> 45 90 46 91 #endif
+78 -4
arch/s390/include/asm/pci.h
··· 1 1 #ifndef __ASM_S390_PCI_H 2 2 #define __ASM_S390_PCI_H 3 3 4 - /* S/390 systems don't have a PCI bus. This file is just here because some stupid .c code 5 - * includes it even if CONFIG_PCI is not set. 6 - */ 4 + /* must be set before including asm-generic/pci.h */ 7 5 #define PCI_DMA_BUS_IS_PHYS (0) 6 + /* must be set before including pci_clp.h */ 7 + #define PCI_BAR_COUNT 6 8 8 9 - #endif /* __ASM_S390_PCI_H */ 9 + #include <asm-generic/pci.h> 10 + #include <asm-generic/pci-dma-compat.h> 10 11 12 + #define PCIBIOS_MIN_IO 0x1000 13 + #define PCIBIOS_MIN_MEM 0x10000000 14 + 15 + #define pcibios_assign_all_busses() (0) 16 + 17 + void __iomem *pci_iomap(struct pci_dev *, int, unsigned long); 18 + void pci_iounmap(struct pci_dev *, void __iomem *); 19 + int pci_domain_nr(struct pci_bus *); 20 + int pci_proc_domain(struct pci_bus *); 21 + 22 + #define ZPCI_BUS_NR 0 /* default bus number */ 23 + #define ZPCI_DEVFN 0 /* default device number */ 24 + 25 + /* PCI Function Controls */ 26 + #define ZPCI_FC_FN_ENABLED 0x80 27 + #define ZPCI_FC_ERROR 0x40 28 + #define ZPCI_FC_BLOCKED 0x20 29 + #define ZPCI_FC_DMA_ENABLED 0x10 30 + 31 + enum zpci_state { 32 + ZPCI_FN_STATE_RESERVED, 33 + ZPCI_FN_STATE_STANDBY, 34 + ZPCI_FN_STATE_CONFIGURED, 35 + ZPCI_FN_STATE_ONLINE, 36 + NR_ZPCI_FN_STATES, 37 + }; 38 + 39 + struct zpci_bar_struct { 40 + u32 val; /* bar start & 3 flag bits */ 41 + u8 size; /* order 2 exponent */ 42 + u16 map_idx; /* index into bar mapping array */ 43 + }; 44 + 45 + /* Private data per function */ 46 + struct zpci_dev { 47 + struct pci_dev *pdev; 48 + struct pci_bus *bus; 49 + struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */ 50 + 51 + enum zpci_state state; 52 + u32 fid; /* function ID, used by sclp */ 53 + u32 fh; /* function handle, used by insn's */ 54 + u16 pchid; /* physical channel ID */ 55 + u8 pfgid; /* function group ID */ 56 + u16 domain; 57 + 58 + struct zpci_bar_struct bars[PCI_BAR_COUNT]; 59 + 60 + enum pci_bus_speed max_bus_speed; 61 + }; 62 + 63 + static inline bool zdev_enabled(struct zpci_dev *zdev) 64 + { 65 + return (zdev->fh & (1UL << 31)) ? true : false; 66 + } 67 + 68 + /* ----------------------------------------------------------------------------- 69 + Prototypes 70 + ----------------------------------------------------------------------------- */ 71 + /* Base stuff */ 72 + struct zpci_dev *zpci_alloc_device(void); 73 + int zpci_create_device(struct zpci_dev *); 74 + int zpci_enable_device(struct zpci_dev *); 75 + void zpci_stop_device(struct zpci_dev *); 76 + void zpci_free_device(struct zpci_dev *); 77 + int zpci_scan_device(struct zpci_dev *); 78 + 79 + /* Helpers */ 80 + struct zpci_dev *get_zdev(struct pci_dev *); 81 + struct zpci_dev *get_zdev_by_fid(u32); 82 + bool zpci_fid_present(u32); 83 + 84 + #endif
+280
arch/s390/include/asm/pci_insn.h
··· 1 + #ifndef _ASM_S390_PCI_INSN_H 2 + #define _ASM_S390_PCI_INSN_H 3 + 4 + #include <linux/delay.h> 5 + 6 + #define ZPCI_INSN_BUSY_DELAY 1 /* 1 millisecond */ 7 + 8 + /* Load/Store status codes */ 9 + #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 10 + #define ZPCI_PCI_ST_FUNC_IN_ERR 8 11 + #define ZPCI_PCI_ST_BLOCKED 12 12 + #define ZPCI_PCI_ST_INSUF_RES 16 13 + #define ZPCI_PCI_ST_INVAL_AS 20 14 + #define ZPCI_PCI_ST_FUNC_ALREADY_ENABLED 24 15 + #define ZPCI_PCI_ST_DMA_AS_NOT_ENABLED 28 16 + #define ZPCI_PCI_ST_2ND_OP_IN_INV_AS 36 17 + #define ZPCI_PCI_ST_FUNC_NOT_AVAIL 40 18 + #define ZPCI_PCI_ST_ALREADY_IN_RQ_STATE 44 19 + 20 + /* Load/Store return codes */ 21 + #define ZPCI_PCI_LS_OK 0 22 + #define ZPCI_PCI_LS_ERR 1 23 + #define ZPCI_PCI_LS_BUSY 2 24 + #define ZPCI_PCI_LS_INVAL_HANDLE 3 25 + 26 + /* Load/Store address space identifiers */ 27 + #define ZPCI_PCIAS_MEMIO_0 0 28 + #define ZPCI_PCIAS_MEMIO_1 1 29 + #define ZPCI_PCIAS_MEMIO_2 2 30 + #define ZPCI_PCIAS_MEMIO_3 3 31 + #define ZPCI_PCIAS_MEMIO_4 4 32 + #define ZPCI_PCIAS_MEMIO_5 5 33 + #define ZPCI_PCIAS_CFGSPC 15 34 + 35 + /* Modify PCI Function Controls */ 36 + #define ZPCI_MOD_FC_REG_INT 2 37 + #define ZPCI_MOD_FC_DEREG_INT 3 38 + #define ZPCI_MOD_FC_REG_IOAT 4 39 + #define ZPCI_MOD_FC_DEREG_IOAT 5 40 + #define ZPCI_MOD_FC_REREG_IOAT 6 41 + #define ZPCI_MOD_FC_RESET_ERROR 7 42 + #define ZPCI_MOD_FC_RESET_BLOCK 9 43 + #define ZPCI_MOD_FC_SET_MEASURE 10 44 + 45 + /* FIB function controls */ 46 + #define ZPCI_FIB_FC_ENABLED 0x80 47 + #define ZPCI_FIB_FC_ERROR 0x40 48 + #define ZPCI_FIB_FC_LS_BLOCKED 0x20 49 + #define ZPCI_FIB_FC_DMAAS_REG 0x10 50 + 51 + /* FIB function controls */ 52 + #define ZPCI_FIB_FC_ENABLED 0x80 53 + #define ZPCI_FIB_FC_ERROR 0x40 54 + #define ZPCI_FIB_FC_LS_BLOCKED 0x20 55 + #define ZPCI_FIB_FC_DMAAS_REG 0x10 56 + 57 + /* Function Information Block */ 58 + struct zpci_fib { 59 + u32 fmt : 8; /* format */ 60 + u32 : 24; 61 + u32 reserved1; 62 + u8 fc; /* function controls */ 63 + u8 reserved2; 64 + u16 reserved3; 65 + u32 reserved4; 66 + u64 pba; /* PCI base address */ 67 + u64 pal; /* PCI address limit */ 68 + u64 iota; /* I/O Translation Anchor */ 69 + u32 : 1; 70 + u32 isc : 3; /* Interrupt subclass */ 71 + u32 noi : 12; /* Number of interrupts */ 72 + u32 : 2; 73 + u32 aibvo : 6; /* Adapter interrupt bit vector offset */ 74 + u32 sum : 1; /* Adapter int summary bit enabled */ 75 + u32 : 1; 76 + u32 aisbo : 6; /* Adapter int summary bit offset */ 77 + u32 reserved5; 78 + u64 aibv; /* Adapter int bit vector address */ 79 + u64 aisb; /* Adapter int summary bit address */ 80 + u64 fmb_addr; /* Function measurement block address and key */ 81 + u64 reserved6; 82 + u64 reserved7; 83 + } __packed; 84 + 85 + /* Modify PCI Function Controls */ 86 + static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) 87 + { 88 + u8 cc; 89 + 90 + asm volatile ( 91 + " .insn rxy,0xe300000000d0,%[req],%[fib]\n" 92 + " ipm %[cc]\n" 93 + " srl %[cc],28\n" 94 + : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) 95 + : : "cc"); 96 + *status = req >> 24 & 0xff; 97 + return cc; 98 + } 99 + 100 + static inline int mpcifc_instr(u64 req, struct zpci_fib *fib) 101 + { 102 + u8 cc, status; 103 + 104 + do { 105 + cc = __mpcifc(req, fib, &status); 106 + if (cc == 2) 107 + msleep(ZPCI_INSN_BUSY_DELAY); 108 + } while (cc == 2); 109 + 110 + if (cc) 111 + printk_once(KERN_ERR "%s: error cc: %d status: %d\n", 112 + __func__, cc, status); 113 + return (cc) ? -EIO : 0; 114 + } 115 + 116 + /* Refresh PCI Translations */ 117 + static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) 118 + { 119 + register u64 __addr asm("2") = addr; 120 + register u64 __range asm("3") = range; 121 + u8 cc; 122 + 123 + asm volatile ( 124 + " .insn rre,0xb9d30000,%[fn],%[addr]\n" 125 + " ipm %[cc]\n" 126 + " srl %[cc],28\n" 127 + : [cc] "=d" (cc), [fn] "+d" (fn) 128 + : [addr] "d" (__addr), "d" (__range) 129 + : "cc"); 130 + *status = fn >> 24 & 0xff; 131 + return cc; 132 + } 133 + 134 + static inline int rpcit_instr(u64 fn, u64 addr, u64 range) 135 + { 136 + u8 cc, status; 137 + 138 + do { 139 + cc = __rpcit(fn, addr, range, &status); 140 + if (cc == 2) 141 + msleep(ZPCI_INSN_BUSY_DELAY); 142 + } while (cc == 2); 143 + 144 + if (cc) 145 + printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", 146 + __func__, cc, status, addr, range); 147 + return (cc) ? -EIO : 0; 148 + } 149 + 150 + /* Store PCI function controls */ 151 + static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status) 152 + { 153 + u64 fn = (u64) handle << 32 | space << 16; 154 + u8 cc; 155 + 156 + asm volatile ( 157 + " .insn rxy,0xe300000000d4,%[fn],%[fib]\n" 158 + " ipm %[cc]\n" 159 + " srl %[cc],28\n" 160 + : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib) 161 + : : "cc"); 162 + *status = fn >> 24 & 0xff; 163 + return cc; 164 + } 165 + 166 + /* Set Interruption Controls */ 167 + static inline void sic_instr(u16 ctl, char *unused, u8 isc) 168 + { 169 + asm volatile ( 170 + " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" 171 + : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); 172 + } 173 + 174 + /* PCI Load */ 175 + static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status) 176 + { 177 + register u64 __req asm("2") = req; 178 + register u64 __offset asm("3") = offset; 179 + u64 __data; 180 + u8 cc; 181 + 182 + asm volatile ( 183 + " .insn rre,0xb9d20000,%[data],%[req]\n" 184 + " ipm %[cc]\n" 185 + " srl %[cc],28\n" 186 + : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req) 187 + : "d" (__offset) 188 + : "cc"); 189 + *status = __req >> 24 & 0xff; 190 + *data = __data; 191 + return cc; 192 + } 193 + 194 + static inline int pcilg_instr(u64 *data, u64 req, u64 offset) 195 + { 196 + u8 cc, status; 197 + 198 + do { 199 + cc = __pcilg(data, req, offset, &status); 200 + if (cc == 2) 201 + msleep(ZPCI_INSN_BUSY_DELAY); 202 + } while (cc == 2); 203 + 204 + if (cc) { 205 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 206 + __func__, cc, status, req, offset); 207 + /* TODO: on IO errors set data to 0xff... 208 + * here or in users of pcilg (le conversion)? 209 + */ 210 + } 211 + return (cc) ? -EIO : 0; 212 + } 213 + 214 + /* PCI Store */ 215 + static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status) 216 + { 217 + register u64 __req asm("2") = req; 218 + register u64 __offset asm("3") = offset; 219 + u8 cc; 220 + 221 + asm volatile ( 222 + " .insn rre,0xb9d00000,%[data],%[req]\n" 223 + " ipm %[cc]\n" 224 + " srl %[cc],28\n" 225 + : [cc] "=d" (cc), [req] "+d" (__req) 226 + : "d" (__offset), [data] "d" (data) 227 + : "cc"); 228 + *status = __req >> 24 & 0xff; 229 + return cc; 230 + } 231 + 232 + static inline int pcistg_instr(u64 data, u64 req, u64 offset) 233 + { 234 + u8 cc, status; 235 + 236 + do { 237 + cc = __pcistg(data, req, offset, &status); 238 + if (cc == 2) 239 + msleep(ZPCI_INSN_BUSY_DELAY); 240 + } while (cc == 2); 241 + 242 + if (cc) 243 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 244 + __func__, cc, status, req, offset); 245 + return (cc) ? -EIO : 0; 246 + } 247 + 248 + /* PCI Store Block */ 249 + static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) 250 + { 251 + u8 cc; 252 + 253 + asm volatile ( 254 + " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" 255 + " ipm %[cc]\n" 256 + " srl %[cc],28\n" 257 + : [cc] "=d" (cc), [req] "+d" (req) 258 + : [offset] "d" (offset), [data] "Q" (*data) 259 + : "cc"); 260 + *status = req >> 24 & 0xff; 261 + return cc; 262 + } 263 + 264 + static inline int pcistb_instr(const u64 *data, u64 req, u64 offset) 265 + { 266 + u8 cc, status; 267 + 268 + do { 269 + cc = __pcistb(data, req, offset, &status); 270 + if (cc == 2) 271 + msleep(ZPCI_INSN_BUSY_DELAY); 272 + } while (cc == 2); 273 + 274 + if (cc) 275 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 276 + __func__, cc, status, req, offset); 277 + return (cc) ? -EIO : 0; 278 + } 279 + 280 + #endif
+194
arch/s390/include/asm/pci_io.h
··· 1 + #ifndef _ASM_S390_PCI_IO_H 2 + #define _ASM_S390_PCI_IO_H 3 + 4 + #ifdef CONFIG_PCI 5 + 6 + #include <linux/kernel.h> 7 + #include <linux/slab.h> 8 + #include <asm/pci_insn.h> 9 + 10 + /* I/O Map */ 11 + #define ZPCI_IOMAP_MAX_ENTRIES 0x7fff 12 + #define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL 13 + #define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL 14 + #define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL 15 + 16 + struct zpci_iomap_entry { 17 + u32 fh; 18 + u8 bar; 19 + }; 20 + 21 + extern struct zpci_iomap_entry *zpci_iomap_start; 22 + 23 + #define ZPCI_IDX(addr) \ 24 + (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48) 25 + #define ZPCI_OFFSET(addr) \ 26 + ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK) 27 + 28 + #define ZPCI_CREATE_REQ(handle, space, len) \ 29 + ((u64) handle << 32 | space << 16 | len) 30 + 31 + #define zpci_read(LENGTH, RETTYPE) \ 32 + static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ 33 + { \ 34 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)]; \ 35 + u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ 36 + u64 data; \ 37 + int rc; \ 38 + \ 39 + rc = pcilg_instr(&data, req, ZPCI_OFFSET(addr)); \ 40 + if (rc) \ 41 + data = -1ULL; \ 42 + return (RETTYPE) data; \ 43 + } 44 + 45 + #define zpci_write(LENGTH, VALTYPE) \ 46 + static inline void zpci_write_##VALTYPE(VALTYPE val, \ 47 + const volatile void __iomem *addr) \ 48 + { \ 49 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)]; \ 50 + u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ 51 + u64 data = (VALTYPE) val; \ 52 + \ 53 + pcistg_instr(data, req, ZPCI_OFFSET(addr)); \ 54 + } 55 + 56 + zpci_read(8, u64) 57 + zpci_read(4, u32) 58 + zpci_read(2, u16) 59 + zpci_read(1, u8) 60 + zpci_write(8, u64) 61 + zpci_write(4, u32) 62 + zpci_write(2, u16) 63 + zpci_write(1, u8) 64 + 65 + static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len) 66 + { 67 + u64 val; 68 + 69 + switch (len) { 70 + case 1: 71 + val = (u64) *((u8 *) data); 72 + break; 73 + case 2: 74 + val = (u64) *((u16 *) data); 75 + break; 76 + case 4: 77 + val = (u64) *((u32 *) data); 78 + break; 79 + case 8: 80 + val = (u64) *((u64 *) data); 81 + break; 82 + default: 83 + val = 0; /* let FW report error */ 84 + break; 85 + } 86 + return pcistg_instr(val, req, offset); 87 + } 88 + 89 + static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) 90 + { 91 + u64 data; 92 + u8 cc; 93 + 94 + cc = pcilg_instr(&data, req, offset); 95 + switch (len) { 96 + case 1: 97 + *((u8 *) dst) = (u8) data; 98 + break; 99 + case 2: 100 + *((u16 *) dst) = (u16) data; 101 + break; 102 + case 4: 103 + *((u32 *) dst) = (u32) data; 104 + break; 105 + case 8: 106 + *((u64 *) dst) = (u64) data; 107 + break; 108 + } 109 + return cc; 110 + } 111 + 112 + static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) 113 + { 114 + return pcistb_instr(data, req, offset); 115 + } 116 + 117 + static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) 118 + { 119 + int count = len > max ? max : len, size = 1; 120 + 121 + while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { 122 + dst = dst >> 1; 123 + src = src >> 1; 124 + size = size << 1; 125 + } 126 + return size; 127 + } 128 + 129 + static inline int zpci_memcpy_fromio(void *dst, 130 + const volatile void __iomem *src, 131 + unsigned long n) 132 + { 133 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(src)]; 134 + u64 req, offset = ZPCI_OFFSET(src); 135 + int size, rc = 0; 136 + 137 + while (n > 0) { 138 + size = zpci_get_max_write_size((u64) src, (u64) dst, n, 8); 139 + req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 140 + rc = zpci_read_single(req, dst, offset, size); 141 + if (rc) 142 + break; 143 + offset += size; 144 + dst += size; 145 + n -= size; 146 + } 147 + return rc; 148 + } 149 + 150 + static inline int zpci_memcpy_toio(volatile void __iomem *dst, 151 + const void *src, unsigned long n) 152 + { 153 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(dst)]; 154 + u64 req, offset = ZPCI_OFFSET(dst); 155 + int size, rc = 0; 156 + 157 + if (!src) 158 + return -EINVAL; 159 + 160 + while (n > 0) { 161 + size = zpci_get_max_write_size((u64) dst, (u64) src, n, 128); 162 + req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 163 + 164 + if (size > 8) /* main path */ 165 + rc = zpci_write_block(req, src, offset); 166 + else 167 + rc = zpci_write_single(req, src, offset, size); 168 + if (rc) 169 + break; 170 + offset += size; 171 + src += size; 172 + n -= size; 173 + } 174 + return rc; 175 + } 176 + 177 + static inline int zpci_memset_io(volatile void __iomem *dst, 178 + unsigned char val, size_t count) 179 + { 180 + u8 *src = kmalloc(count, GFP_KERNEL); 181 + int rc; 182 + 183 + if (src == NULL) 184 + return -ENOMEM; 185 + memset(src, val, count); 186 + 187 + rc = zpci_memcpy_toio(dst, src, count); 188 + kfree(src); 189 + return rc; 190 + } 191 + 192 + #endif /* CONFIG_PCI */ 193 + 194 + #endif /* _ASM_S390_PCI_IO_H */
+15
arch/s390/kernel/dis.c
··· 399 399 LONG_INSN_TABORT, 400 400 LONG_INSN_TBEGIN, 401 401 LONG_INSN_TBEGINC, 402 + LONG_INSN_PCISTG, 403 + LONG_INSN_MPCIFC, 404 + LONG_INSN_STPCIFC, 405 + LONG_INSN_PCISTB, 402 406 }; 403 407 404 408 static char *long_insn_name[] = { ··· 473 469 [LONG_INSN_TABORT] = "tabort", 474 470 [LONG_INSN_TBEGIN] = "tbegin", 475 471 [LONG_INSN_TBEGINC] = "tbeginc", 472 + [LONG_INSN_PCISTG] = "pcistg", 473 + [LONG_INSN_MPCIFC] = "mpcifc", 474 + [LONG_INSN_STPCIFC] = "stpcifc", 475 + [LONG_INSN_PCISTB] = "pcistb", 476 476 }; 477 477 478 478 static struct insn opcode[] = { ··· 1123 1115 { { 0, LONG_INSN_SLHHHR }, 0xcb, INSTR_RRF_R0RR2 }, 1124 1116 { "chhr", 0xcd, INSTR_RRE_RR }, 1125 1117 { "clhhr", 0xcf, INSTR_RRE_RR }, 1118 + { { 0, LONG_INSN_PCISTG }, 0xd0, INSTR_RRE_RR }, 1119 + { "pcilg", 0xd2, INSTR_RRE_RR }, 1120 + { "rpcit", 0xd3, INSTR_RRE_RR }, 1126 1121 { "ahhlr", 0xd8, INSTR_RRF_R0RR2 }, 1127 1122 { "shhlr", 0xd9, INSTR_RRF_R0RR2 }, 1128 1123 { { 0, LONG_INSN_ALHHLR }, 0xda, INSTR_RRF_R0RR2 }, ··· 1357 1346 { "stfh", 0xcb, INSTR_RXY_RRRD }, 1358 1347 { "chf", 0xcd, INSTR_RXY_RRRD }, 1359 1348 { "clhf", 0xcf, INSTR_RXY_RRRD }, 1349 + { { 0, LONG_INSN_MPCIFC }, 0xd0, INSTR_RXY_RRRD }, 1350 + { { 0, LONG_INSN_STPCIFC }, 0xd4, INSTR_RXY_RRRD }, 1360 1351 #endif 1361 1352 { "lrv", 0x1e, INSTR_RXY_RRRD }, 1362 1353 { "lrvh", 0x1f, INSTR_RXY_RRRD }, ··· 1436 1423 { "lmy", 0x98, INSTR_RSY_RRRD }, 1437 1424 { "lamy", 0x9a, INSTR_RSY_AARD }, 1438 1425 { "stamy", 0x9b, INSTR_RSY_AARD }, 1426 + { { 0, LONG_INSN_PCISTB }, 0xd0, INSTR_RSY_RRRD }, 1427 + { "sic", 0xd1, INSTR_RSY_RRRD }, 1439 1428 { "srak", 0xdc, INSTR_RSY_RRRD }, 1440 1429 { "slak", 0xdd, INSTR_RSY_RRRD }, 1441 1430 { "srlk", 0xde, INSTR_RSY_RRRD },
+5
arch/s390/pci/Makefile
··· 1 + # 2 + # Makefile for the s390 PCI subsystem. 3 + # 4 + 5 + obj-$(CONFIG_PCI) += pci.o
+557
arch/s390/pci/pci.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + * 7 + * The System z PCI code is a rewrite from a prototype by 8 + * the following people (Kudoz!): 9 + * Alexander Schmidt <alexschm@de.ibm.com> 10 + * Christoph Raisch <raisch@de.ibm.com> 11 + * Hannes Hering <hering2@de.ibm.com> 12 + * Hoang-Nam Nguyen <hnguyen@de.ibm.com> 13 + * Jan-Bernd Themann <themann@de.ibm.com> 14 + * Stefan Roscher <stefan.roscher@de.ibm.com> 15 + * Thomas Klein <tklein@de.ibm.com> 16 + */ 17 + 18 + #define COMPONENT "zPCI" 19 + #define pr_fmt(fmt) COMPONENT ": " fmt 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/slab.h> 23 + #include <linux/err.h> 24 + #include <linux/export.h> 25 + #include <linux/delay.h> 26 + #include <linux/seq_file.h> 27 + #include <linux/pci.h> 28 + #include <linux/msi.h> 29 + 30 + #include <asm/facility.h> 31 + #include <asm/pci_insn.h> 32 + 33 + #define DEBUG /* enable pr_debug */ 34 + 35 + #define ZPCI_NR_DMA_SPACES 1 36 + #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS 37 + 38 + /* list of all detected zpci devices */ 39 + LIST_HEAD(zpci_list); 40 + DEFINE_MUTEX(zpci_list_lock); 41 + 42 + static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); 43 + static DEFINE_SPINLOCK(zpci_domain_lock); 44 + 45 + /* I/O Map */ 46 + static DEFINE_SPINLOCK(zpci_iomap_lock); 47 + static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 48 + struct zpci_iomap_entry *zpci_iomap_start; 49 + EXPORT_SYMBOL_GPL(zpci_iomap_start); 50 + 51 + struct zpci_dev *get_zdev(struct pci_dev *pdev) 52 + { 53 + return (struct zpci_dev *) pdev->sysdata; 54 + } 55 + 56 + struct zpci_dev *get_zdev_by_fid(u32 fid) 57 + { 58 + struct zpci_dev *tmp, *zdev = NULL; 59 + 60 + mutex_lock(&zpci_list_lock); 61 + list_for_each_entry(tmp, &zpci_list, entry) { 62 + if (tmp->fid == fid) { 63 + zdev = tmp; 64 + break; 65 + } 66 + } 67 + mutex_unlock(&zpci_list_lock); 68 + return zdev; 69 + } 70 + 71 + bool zpci_fid_present(u32 fid) 72 + { 73 + return (get_zdev_by_fid(fid) != NULL) ? true : false; 74 + } 75 + 76 + static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) 77 + { 78 + return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; 79 + } 80 + 81 + int pci_domain_nr(struct pci_bus *bus) 82 + { 83 + return ((struct zpci_dev *) bus->sysdata)->domain; 84 + } 85 + EXPORT_SYMBOL_GPL(pci_domain_nr); 86 + 87 + int pci_proc_domain(struct pci_bus *bus) 88 + { 89 + return pci_domain_nr(bus); 90 + } 91 + EXPORT_SYMBOL_GPL(pci_proc_domain); 92 + 93 + /* Store PCI function information block */ 94 + static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) 95 + { 96 + struct zpci_fib *fib; 97 + u8 status, cc; 98 + 99 + fib = (void *) get_zeroed_page(GFP_KERNEL); 100 + if (!fib) 101 + return -ENOMEM; 102 + 103 + do { 104 + cc = __stpcifc(zdev->fh, 0, fib, &status); 105 + if (cc == 2) { 106 + msleep(ZPCI_INSN_BUSY_DELAY); 107 + memset(fib, 0, PAGE_SIZE); 108 + } 109 + } while (cc == 2); 110 + 111 + if (cc) 112 + pr_err_once("%s: cc: %u status: %u\n", 113 + __func__, cc, status); 114 + 115 + /* Return PCI function controls */ 116 + *fc = fib->fc; 117 + 118 + free_page((unsigned long) fib); 119 + return (cc) ? -EIO : 0; 120 + } 121 + 122 + #define ZPCI_PCIAS_CFGSPC 15 123 + 124 + static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 125 + { 126 + u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 127 + u64 data; 128 + int rc; 129 + 130 + rc = pcilg_instr(&data, req, offset); 131 + data = data << ((8 - len) * 8); 132 + data = le64_to_cpu(data); 133 + if (!rc) 134 + *val = (u32) data; 135 + else 136 + *val = 0xffffffff; 137 + return rc; 138 + } 139 + 140 + static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) 141 + { 142 + u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 143 + u64 data = val; 144 + int rc; 145 + 146 + data = cpu_to_le64(data); 147 + data = data >> ((8 - len) * 8); 148 + rc = pcistg_instr(data, req, offset); 149 + return rc; 150 + } 151 + 152 + void __devinit pcibios_fixup_bus(struct pci_bus *bus) 153 + { 154 + } 155 + 156 + resource_size_t pcibios_align_resource(void *data, const struct resource *res, 157 + resource_size_t size, 158 + resource_size_t align) 159 + { 160 + return 0; 161 + } 162 + 163 + /* Create a virtual mapping cookie for a PCI BAR */ 164 + void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max) 165 + { 166 + struct zpci_dev *zdev = get_zdev(pdev); 167 + u64 addr; 168 + int idx; 169 + 170 + if ((bar & 7) != bar) 171 + return NULL; 172 + 173 + idx = zdev->bars[bar].map_idx; 174 + spin_lock(&zpci_iomap_lock); 175 + zpci_iomap_start[idx].fh = zdev->fh; 176 + zpci_iomap_start[idx].bar = bar; 177 + spin_unlock(&zpci_iomap_lock); 178 + 179 + addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); 180 + return (void __iomem *) addr; 181 + } 182 + EXPORT_SYMBOL_GPL(pci_iomap); 183 + 184 + void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) 185 + { 186 + unsigned int idx; 187 + 188 + idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; 189 + spin_lock(&zpci_iomap_lock); 190 + zpci_iomap_start[idx].fh = 0; 191 + zpci_iomap_start[idx].bar = 0; 192 + spin_unlock(&zpci_iomap_lock); 193 + } 194 + EXPORT_SYMBOL_GPL(pci_iounmap); 195 + 196 + static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, 197 + int size, u32 *val) 198 + { 199 + struct zpci_dev *zdev = get_zdev_by_bus(bus); 200 + 201 + if (!zdev || devfn != ZPCI_DEVFN) 202 + return 0; 203 + return zpci_cfg_load(zdev, where, val, size); 204 + } 205 + 206 + static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, 207 + int size, u32 val) 208 + { 209 + struct zpci_dev *zdev = get_zdev_by_bus(bus); 210 + 211 + if (!zdev || devfn != ZPCI_DEVFN) 212 + return 0; 213 + return zpci_cfg_store(zdev, where, val, size); 214 + } 215 + 216 + static struct pci_ops pci_root_ops = { 217 + .read = pci_read, 218 + .write = pci_write, 219 + }; 220 + 221 + static void zpci_map_resources(struct zpci_dev *zdev) 222 + { 223 + struct pci_dev *pdev = zdev->pdev; 224 + resource_size_t len; 225 + int i; 226 + 227 + for (i = 0; i < PCI_BAR_COUNT; i++) { 228 + len = pci_resource_len(pdev, i); 229 + if (!len) 230 + continue; 231 + pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); 232 + pdev->resource[i].end = pdev->resource[i].start + len - 1; 233 + pr_debug("BAR%i: -> start: %Lx end: %Lx\n", 234 + i, pdev->resource[i].start, pdev->resource[i].end); 235 + } 236 + }; 237 + 238 + static void zpci_unmap_resources(struct pci_dev *pdev) 239 + { 240 + resource_size_t len; 241 + int i; 242 + 243 + for (i = 0; i < PCI_BAR_COUNT; i++) { 244 + len = pci_resource_len(pdev, i); 245 + if (!len) 246 + continue; 247 + pci_iounmap(pdev, (void *) pdev->resource[i].start); 248 + } 249 + }; 250 + 251 + struct zpci_dev *zpci_alloc_device(void) 252 + { 253 + struct zpci_dev *zdev; 254 + 255 + /* Alloc memory for our private pci device data */ 256 + zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); 257 + if (!zdev) 258 + return ERR_PTR(-ENOMEM); 259 + return zdev; 260 + } 261 + 262 + void zpci_free_device(struct zpci_dev *zdev) 263 + { 264 + kfree(zdev); 265 + } 266 + 267 + /* Called on removal of pci_dev, leaves zpci and bus device */ 268 + static void zpci_remove_device(struct pci_dev *pdev) 269 + { 270 + struct zpci_dev *zdev = get_zdev(pdev); 271 + 272 + dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); 273 + zdev->state = ZPCI_FN_STATE_CONFIGURED; 274 + zpci_unmap_resources(pdev); 275 + list_del(&zdev->entry); /* can be called from init */ 276 + zdev->pdev = NULL; 277 + } 278 + 279 + static void zpci_scan_devices(void) 280 + { 281 + struct zpci_dev *zdev; 282 + 283 + mutex_lock(&zpci_list_lock); 284 + list_for_each_entry(zdev, &zpci_list, entry) 285 + if (zdev->state == ZPCI_FN_STATE_CONFIGURED) 286 + zpci_scan_device(zdev); 287 + mutex_unlock(&zpci_list_lock); 288 + } 289 + 290 + /* 291 + * Too late for any s390 specific setup, since interrupts must be set up 292 + * already which requires DMA setup too and the pci scan will access the 293 + * config space, which only works if the function handle is enabled. 294 + */ 295 + int pcibios_enable_device(struct pci_dev *pdev, int mask) 296 + { 297 + struct resource *res; 298 + u16 cmd; 299 + int i; 300 + 301 + pci_read_config_word(pdev, PCI_COMMAND, &cmd); 302 + 303 + for (i = 0; i < PCI_BAR_COUNT; i++) { 304 + res = &pdev->resource[i]; 305 + 306 + if (res->flags & IORESOURCE_IO) 307 + return -EINVAL; 308 + 309 + if (res->flags & IORESOURCE_MEM) 310 + cmd |= PCI_COMMAND_MEMORY; 311 + } 312 + pci_write_config_word(pdev, PCI_COMMAND, cmd); 313 + return 0; 314 + } 315 + 316 + void pcibios_disable_device(struct pci_dev *pdev) 317 + { 318 + zpci_remove_device(pdev); 319 + pdev->sysdata = NULL; 320 + } 321 + 322 + static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 323 + unsigned long flags, int domain) 324 + { 325 + struct resource *r; 326 + char *name; 327 + int rc; 328 + 329 + r = kzalloc(sizeof(*r), GFP_KERNEL); 330 + if (!r) 331 + return ERR_PTR(-ENOMEM); 332 + r->start = start; 333 + r->end = r->start + size - 1; 334 + r->flags = flags; 335 + r->parent = &iomem_resource; 336 + name = kmalloc(18, GFP_KERNEL); 337 + if (!name) { 338 + kfree(r); 339 + return ERR_PTR(-ENOMEM); 340 + } 341 + sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR); 342 + r->name = name; 343 + 344 + rc = request_resource(&iomem_resource, r); 345 + if (rc) 346 + pr_debug("request resource %pR failed\n", r); 347 + return r; 348 + } 349 + 350 + static int zpci_alloc_iomap(struct zpci_dev *zdev) 351 + { 352 + int entry; 353 + 354 + spin_lock(&zpci_iomap_lock); 355 + entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 356 + if (entry == ZPCI_IOMAP_MAX_ENTRIES) { 357 + spin_unlock(&zpci_iomap_lock); 358 + return -ENOSPC; 359 + } 360 + set_bit(entry, zpci_iomap); 361 + spin_unlock(&zpci_iomap_lock); 362 + return entry; 363 + } 364 + 365 + static void zpci_free_iomap(struct zpci_dev *zdev, int entry) 366 + { 367 + spin_lock(&zpci_iomap_lock); 368 + memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); 369 + clear_bit(entry, zpci_iomap); 370 + spin_unlock(&zpci_iomap_lock); 371 + } 372 + 373 + static int zpci_create_device_bus(struct zpci_dev *zdev) 374 + { 375 + struct resource *res; 376 + LIST_HEAD(resources); 377 + int i; 378 + 379 + /* allocate mapping entry for each used bar */ 380 + for (i = 0; i < PCI_BAR_COUNT; i++) { 381 + unsigned long addr, size, flags; 382 + int entry; 383 + 384 + if (!zdev->bars[i].size) 385 + continue; 386 + entry = zpci_alloc_iomap(zdev); 387 + if (entry < 0) 388 + return entry; 389 + zdev->bars[i].map_idx = entry; 390 + 391 + /* only MMIO is supported */ 392 + flags = IORESOURCE_MEM; 393 + if (zdev->bars[i].val & 8) 394 + flags |= IORESOURCE_PREFETCH; 395 + if (zdev->bars[i].val & 4) 396 + flags |= IORESOURCE_MEM_64; 397 + 398 + addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); 399 + 400 + size = 1UL << zdev->bars[i].size; 401 + 402 + res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain); 403 + if (IS_ERR(res)) { 404 + zpci_free_iomap(zdev, entry); 405 + return PTR_ERR(res); 406 + } 407 + pci_add_resource(&resources, res); 408 + } 409 + 410 + zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, 411 + zdev, &resources); 412 + if (!zdev->bus) 413 + return -EIO; 414 + 415 + zdev->bus->max_bus_speed = zdev->max_bus_speed; 416 + return 0; 417 + } 418 + 419 + static int zpci_alloc_domain(struct zpci_dev *zdev) 420 + { 421 + spin_lock(&zpci_domain_lock); 422 + zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); 423 + if (zdev->domain == ZPCI_NR_DEVICES) { 424 + spin_unlock(&zpci_domain_lock); 425 + return -ENOSPC; 426 + } 427 + set_bit(zdev->domain, zpci_domain); 428 + spin_unlock(&zpci_domain_lock); 429 + return 0; 430 + } 431 + 432 + static void zpci_free_domain(struct zpci_dev *zdev) 433 + { 434 + spin_lock(&zpci_domain_lock); 435 + clear_bit(zdev->domain, zpci_domain); 436 + spin_unlock(&zpci_domain_lock); 437 + } 438 + 439 + int zpci_create_device(struct zpci_dev *zdev) 440 + { 441 + int rc; 442 + 443 + rc = zpci_alloc_domain(zdev); 444 + if (rc) 445 + goto out; 446 + 447 + rc = zpci_create_device_bus(zdev); 448 + if (rc) 449 + goto out_bus; 450 + 451 + mutex_lock(&zpci_list_lock); 452 + list_add_tail(&zdev->entry, &zpci_list); 453 + mutex_unlock(&zpci_list_lock); 454 + 455 + if (zdev->state == ZPCI_FN_STATE_STANDBY) 456 + return 0; 457 + 458 + return 0; 459 + 460 + out_bus: 461 + zpci_free_domain(zdev); 462 + out: 463 + return rc; 464 + } 465 + 466 + void zpci_stop_device(struct zpci_dev *zdev) 467 + { 468 + /* 469 + * Note: SCLP disables fh via set-pci-fn so don't 470 + * do that here. 471 + */ 472 + } 473 + EXPORT_SYMBOL_GPL(zpci_stop_device); 474 + 475 + int zpci_scan_device(struct zpci_dev *zdev) 476 + { 477 + zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN); 478 + if (!zdev->pdev) { 479 + pr_err("pci_scan_single_device failed for fid: 0x%x\n", 480 + zdev->fid); 481 + goto out; 482 + } 483 + 484 + zpci_map_resources(zdev); 485 + pci_bus_add_devices(zdev->bus); 486 + 487 + /* now that pdev was added to the bus mark it as used */ 488 + zdev->state = ZPCI_FN_STATE_ONLINE; 489 + return 0; 490 + 491 + out: 492 + return -EIO; 493 + } 494 + EXPORT_SYMBOL_GPL(zpci_scan_device); 495 + 496 + static inline int barsize(u8 size) 497 + { 498 + return (size) ? (1 << size) >> 10 : 0; 499 + } 500 + 501 + static int zpci_mem_init(void) 502 + { 503 + /* TODO: use realloc */ 504 + zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 505 + GFP_KERNEL); 506 + if (!zpci_iomap_start) 507 + goto error_zdev; 508 + return 0; 509 + 510 + error_zdev: 511 + return -ENOMEM; 512 + } 513 + 514 + static void zpci_mem_exit(void) 515 + { 516 + kfree(zpci_iomap_start); 517 + } 518 + 519 + unsigned int pci_probe = 1; 520 + EXPORT_SYMBOL_GPL(pci_probe); 521 + 522 + char * __init pcibios_setup(char *str) 523 + { 524 + if (!strcmp(str, "off")) { 525 + pci_probe = 0; 526 + return NULL; 527 + } 528 + return str; 529 + } 530 + 531 + static int __init pci_base_init(void) 532 + { 533 + int rc; 534 + 535 + if (!pci_probe) 536 + return 0; 537 + 538 + if (!test_facility(2) || !test_facility(69) 539 + || !test_facility(71) || !test_facility(72)) 540 + return 0; 541 + 542 + pr_info("Probing PCI hardware: PCI:%d SID:%d AEN:%d\n", 543 + test_facility(69), test_facility(70), 544 + test_facility(71)); 545 + 546 + rc = zpci_mem_init(); 547 + if (rc) 548 + goto out_mem; 549 + 550 + zpci_scan_devices(); 551 + return 0; 552 + 553 + zpci_mem_exit(); 554 + out_mem: 555 + return rc; 556 + } 557 + subsys_initcall(pci_base_init);
+20 -1
include/asm-generic/io.h
··· 83 83 #define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr) 84 84 85 85 #ifdef CONFIG_64BIT 86 + #ifndef __raw_readq 86 87 static inline u64 __raw_readq(const volatile void __iomem *addr) 87 88 { 88 89 return *(const volatile u64 __force *) addr; 89 90 } 91 + #endif 92 + 90 93 #define readq(addr) __le64_to_cpu(__raw_readq(addr)) 91 94 95 + #ifndef __raw_writeq 92 96 static inline void __raw_writeq(u64 b, volatile void __iomem *addr) 93 97 { 94 98 *(volatile u64 __force *) addr = b; 95 99 } 96 - #define writeq(b,addr) __raw_writeq(__cpu_to_le64(b),addr) 97 100 #endif 101 + 102 + #define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr) 103 + #endif /* CONFIG_64BIT */ 98 104 99 105 #ifndef PCI_IOBASE 100 106 #define PCI_IOBASE ((void __iomem *) 0) ··· 292 286 293 287 #ifndef CONFIG_GENERIC_IOMAP 294 288 struct pci_dev; 289 + extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); 290 + 291 + #ifndef pci_iounmap 295 292 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) 296 293 { 297 294 } 295 + #endif 298 296 #endif /* CONFIG_GENERIC_IOMAP */ 299 297 300 298 /* 301 299 * Change virtual addresses to physical addresses and vv. 302 300 * These are pretty trivial 303 301 */ 302 + #ifndef virt_to_phys 304 303 static inline unsigned long virt_to_phys(volatile void *address) 305 304 { 306 305 return __pa((unsigned long)address); ··· 315 304 { 316 305 return __va(address); 317 306 } 307 + #endif 318 308 319 309 /* 320 310 * Change "struct page" to physical address. ··· 375 363 } 376 364 #endif 377 365 366 + #ifndef memset_io 378 367 #define memset_io(a, b, c) memset(__io_virt(a), (b), (c)) 368 + #endif 369 + 370 + #ifndef memcpy_fromio 379 371 #define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c)) 372 + #endif 373 + #ifndef memcpy_toio 380 374 #define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c)) 375 + #endif 381 376 382 377 #endif /* __KERNEL__ */ 383 378