1 #ifndef _ASM_S390_PCI_INSN_H
2 #define _ASM_S390_PCI_INSN_H
4 #include <linux/delay.h>
6 #define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */
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
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
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
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
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
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
57 /* Function Information Block */
59 u32 fmt : 8; /* format */
62 u8 fc; /* function controls */
66 u64 pba; /* PCI base address */
67 u64 pal; /* PCI address limit */
68 u64 iota; /* I/O Translation Anchor */
70 u32 isc : 3; /* Interrupt subclass */
71 u32 noi : 12; /* Number of interrupts */
73 u32 aibvo : 6; /* Adapter interrupt bit vector offset */
74 u32 sum : 1; /* Adapter int summary bit enabled */
76 u32 aisbo : 6; /* Adapter int summary bit offset */
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 */
85 /* Modify PCI Function Controls */
86 static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
91 " .insn rxy,0xe300000000d0,%[req],%[fib]\n"
94 : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib)
96 *status = req >> 24 & 0xff;
100 static inline int mpcifc_instr(u64 req, struct zpci_fib *fib)
105 cc = __mpcifc(req, fib, &status);
107 msleep(ZPCI_INSN_BUSY_DELAY);
111 printk_once(KERN_ERR "%s: error cc: %d status: %d\n",
112 __func__, cc, status);
113 return (cc) ? -EIO : 0;
116 /* Refresh PCI Translations */
117 static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
119 register u64 __addr asm("2") = addr;
120 register u64 __range asm("3") = range;
124 " .insn rre,0xb9d30000,%[fn],%[addr]\n"
127 : [cc] "=d" (cc), [fn] "+d" (fn)
128 : [addr] "d" (__addr), "d" (__range)
130 *status = fn >> 24 & 0xff;
134 static inline int rpcit_instr(u64 fn, u64 addr, u64 range)
139 cc = __rpcit(fn, addr, range, &status);
141 udelay(ZPCI_INSN_BUSY_DELAY);
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;
150 /* Store PCI function controls */
151 static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status)
153 u64 fn = (u64) handle << 32 | space << 16;
157 " .insn rxy,0xe300000000d4,%[fn],%[fib]\n"
160 : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib)
162 *status = fn >> 24 & 0xff;
166 /* Set Interruption Controls */
167 static inline void sic_instr(u16 ctl, char *unused, u8 isc)
170 " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n"
171 : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused));
175 static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
177 register u64 __req asm("2") = req;
178 register u64 __offset asm("3") = offset;
183 " .insn rre,0xb9d20000,%[data],%[req]\n"
186 : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req)
189 *status = __req >> 24 & 0xff;
194 static inline int pcilg_instr(u64 *data, u64 req, u64 offset)
199 cc = __pcilg(data, req, offset, &status);
201 udelay(ZPCI_INSN_BUSY_DELAY);
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)?
211 return (cc) ? -EIO : 0;
215 static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status)
217 register u64 __req asm("2") = req;
218 register u64 __offset asm("3") = offset;
222 " .insn rre,0xb9d00000,%[data],%[req]\n"
225 : [cc] "=d" (cc), [req] "+d" (__req)
226 : "d" (__offset), [data] "d" (data)
228 *status = __req >> 24 & 0xff;
232 static inline int pcistg_instr(u64 data, u64 req, u64 offset)
237 cc = __pcistg(data, req, offset, &status);
239 udelay(ZPCI_INSN_BUSY_DELAY);
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;
248 /* PCI Store Block */
249 static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
254 " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n"
257 : [cc] "=d" (cc), [req] "+d" (req)
258 : [offset] "d" (offset), [data] "Q" (*data)
260 *status = req >> 24 & 0xff;
264 static inline int pcistb_instr(const u64 *data, u64 req, u64 offset)
269 cc = __pcistb(data, req, offset, &status);
271 udelay(ZPCI_INSN_BUSY_DELAY);
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;