root/arch/s390/include/asm/pci_io.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. zpci_read
  2. zpci_read_single
  3. zpci_get_max_write_size
  4. zpci_memcpy_fromio
  5. zpci_memcpy_toio
  6. zpci_memset_io

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _ASM_S390_PCI_IO_H
   3 #define _ASM_S390_PCI_IO_H
   4 
   5 #ifdef CONFIG_PCI
   6 
   7 #include <linux/kernel.h>
   8 #include <linux/slab.h>
   9 #include <asm/pci_insn.h>
  10 
  11 /* I/O size constraints */
  12 #define ZPCI_MAX_READ_SIZE      8
  13 #define ZPCI_MAX_WRITE_SIZE     128
  14 
  15 /* I/O Map */
  16 #define ZPCI_IOMAP_SHIFT                48
  17 #define ZPCI_IOMAP_ADDR_BASE            0x8000000000000000UL
  18 #define ZPCI_IOMAP_ADDR_OFF_MASK        ((1UL << ZPCI_IOMAP_SHIFT) - 1)
  19 #define ZPCI_IOMAP_MAX_ENTRIES                                                  \
  20         ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT))
  21 #define ZPCI_IOMAP_ADDR_IDX_MASK                                                \
  22         (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE)
  23 
  24 struct zpci_iomap_entry {
  25         u32 fh;
  26         u8 bar;
  27         u16 count;
  28 };
  29 
  30 extern struct zpci_iomap_entry *zpci_iomap_start;
  31 
  32 #define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
  33 #define ZPCI_IDX(addr)                                                          \
  34         (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
  35 #define ZPCI_OFFSET(addr)                                                       \
  36         ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
  37 
  38 #define ZPCI_CREATE_REQ(handle, space, len)                                     \
  39         ((u64) handle << 32 | space << 16 | len)
  40 
  41 #define zpci_read(LENGTH, RETTYPE)                                              \
  42 static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr)    \
  43 {                                                                               \
  44         u64 data;                                                               \
  45         int rc;                                                                 \
  46                                                                                 \
  47         rc = zpci_load(&data, addr, LENGTH);                                    \
  48         if (rc)                                                                 \
  49                 data = -1ULL;                                                   \
  50         return (RETTYPE) data;                                                  \
  51 }
  52 
  53 #define zpci_write(LENGTH, VALTYPE)                                             \
  54 static inline void zpci_write_##VALTYPE(VALTYPE val,                            \
  55                                         const volatile void __iomem *addr)      \
  56 {                                                                               \
  57         u64 data = (VALTYPE) val;                                               \
  58                                                                                 \
  59         zpci_store(addr, data, LENGTH);                                         \
  60 }
  61 
  62 zpci_read(8, u64)
  63 zpci_read(4, u32)
  64 zpci_read(2, u16)
  65 zpci_read(1, u8)
  66 zpci_write(8, u64)
  67 zpci_write(4, u32)
  68 zpci_write(2, u16)
  69 zpci_write(1, u8)
  70 
  71 static inline int zpci_write_single(volatile void __iomem *dst, const void *src,
  72                                     unsigned long len)
  73 {
  74         u64 val;
  75 
  76         switch (len) {
  77         case 1:
  78                 val = (u64) *((u8 *) src);
  79                 break;
  80         case 2:
  81                 val = (u64) *((u16 *) src);
  82                 break;
  83         case 4:
  84                 val = (u64) *((u32 *) src);
  85                 break;
  86         case 8:
  87                 val = (u64) *((u64 *) src);
  88                 break;
  89         default:
  90                 val = 0;                /* let FW report error */
  91                 break;
  92         }
  93         return zpci_store(dst, val, len);
  94 }
  95 
  96 static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
  97                                    unsigned long len)
  98 {
  99         u64 data;
 100         int cc;
 101 
 102         cc = zpci_load(&data, src, len);
 103         if (cc)
 104                 goto out;
 105 
 106         switch (len) {
 107         case 1:
 108                 *((u8 *) dst) = (u8) data;
 109                 break;
 110         case 2:
 111                 *((u16 *) dst) = (u16) data;
 112                 break;
 113         case 4:
 114                 *((u32 *) dst) = (u32) data;
 115                 break;
 116         case 8:
 117                 *((u64 *) dst) = (u64) data;
 118                 break;
 119         }
 120 out:
 121         return cc;
 122 }
 123 
 124 int zpci_write_block(volatile void __iomem *dst, const void *src,
 125                      unsigned long len);
 126 
 127 static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max)
 128 {
 129         int count = len > max ? max : len, size = 1;
 130 
 131         while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) {
 132                 dst = dst >> 1;
 133                 src = src >> 1;
 134                 size = size << 1;
 135         }
 136         return size;
 137 }
 138 
 139 static inline int zpci_memcpy_fromio(void *dst,
 140                                      const volatile void __iomem *src,
 141                                      unsigned long n)
 142 {
 143         int size, rc = 0;
 144 
 145         while (n > 0) {
 146                 size = zpci_get_max_write_size((u64 __force) src,
 147                                                (u64) dst, n,
 148                                                ZPCI_MAX_READ_SIZE);
 149                 rc = zpci_read_single(dst, src, size);
 150                 if (rc)
 151                         break;
 152                 src += size;
 153                 dst += size;
 154                 n -= size;
 155         }
 156         return rc;
 157 }
 158 
 159 static inline int zpci_memcpy_toio(volatile void __iomem *dst,
 160                                    const void *src, unsigned long n)
 161 {
 162         int size, rc = 0;
 163 
 164         if (!src)
 165                 return -EINVAL;
 166 
 167         while (n > 0) {
 168                 size = zpci_get_max_write_size((u64 __force) dst,
 169                                                (u64) src, n,
 170                                                ZPCI_MAX_WRITE_SIZE);
 171                 if (size > 8) /* main path */
 172                         rc = zpci_write_block(dst, src, size);
 173                 else
 174                         rc = zpci_write_single(dst, src, size);
 175                 if (rc)
 176                         break;
 177                 src += size;
 178                 dst += size;
 179                 n -= size;
 180         }
 181         return rc;
 182 }
 183 
 184 static inline int zpci_memset_io(volatile void __iomem *dst,
 185                                  unsigned char val, size_t count)
 186 {
 187         u8 *src = kmalloc(count, GFP_KERNEL);
 188         int rc;
 189 
 190         if (src == NULL)
 191                 return -ENOMEM;
 192         memset(src, val, count);
 193 
 194         rc = zpci_memcpy_toio(dst, src, count);
 195         kfree(src);
 196         return rc;
 197 }
 198 
 199 #endif /* CONFIG_PCI */
 200 
 201 #endif /* _ASM_S390_PCI_IO_H */

/* [<][>][^][v][top][bottom][index][help] */