1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Copyright IBM Corp. 2000 7 * 8 * History of changes 9 * 07/24/00 new file 10 * 05/04/02 code restructuring. 11 */ 12 13 #ifndef _S390_IDALS_H 14 #define _S390_IDALS_H 15 16 #include <linux/errno.h> 17 #include <linux/err.h> 18 #include <linux/types.h> 19 #include <linux/slab.h> 20 #include <linux/uaccess.h> 21 #include <linux/kmemleak.h> 22 #include <asm/dma-types.h> 23 #include <asm/cio.h> 24 25 #define IDA_SIZE_SHIFT 12 26 #define IDA_BLOCK_SIZE (1UL << IDA_SIZE_SHIFT) 27 28 #define IDA_2K_SIZE_SHIFT 11 29 #define IDA_2K_BLOCK_SIZE (1UL << IDA_2K_SIZE_SHIFT) 30 31 /* 32 * Test if an address/length pair needs an idal list. 33 */ 34 static inline bool idal_is_needed(void *vaddr, unsigned int length) 35 { 36 dma64_t paddr = virt_to_dma64(vaddr); 37 38 return (((__force unsigned long)(paddr) + length - 1) >> 31) != 0; 39 } 40 41 /* 42 * Return the number of idal words needed for an address/length pair. 43 */ 44 static inline unsigned int idal_nr_words(void *vaddr, unsigned int length) 45 { 46 unsigned int cidaw; 47 48 cidaw = (unsigned long)vaddr & (IDA_BLOCK_SIZE - 1); 49 cidaw += length + IDA_BLOCK_SIZE - 1; 50 cidaw >>= IDA_SIZE_SHIFT; 51 return cidaw; 52 } 53 54 /* 55 * Return the number of 2K IDA words needed for an address/length pair. 56 */ 57 static inline unsigned int idal_2k_nr_words(void *vaddr, unsigned int length) 58 { 59 unsigned int cidaw; 60 61 cidaw = (unsigned long)vaddr & (IDA_2K_BLOCK_SIZE - 1); 62 cidaw += length + IDA_2K_BLOCK_SIZE - 1; 63 cidaw >>= IDA_2K_SIZE_SHIFT; 64 return cidaw; 65 } 66 67 /* 68 * Create the list of idal words for an address/length pair. 69 */ 70 static inline dma64_t *idal_create_words(dma64_t *idaws, void *vaddr, unsigned int length) 71 { 72 dma64_t paddr = virt_to_dma64(vaddr); 73 unsigned int cidaw; 74 75 *idaws++ = paddr; 76 cidaw = idal_nr_words(vaddr, length); 77 paddr = dma64_and(paddr, -IDA_BLOCK_SIZE); 78 while (--cidaw > 0) { 79 paddr = dma64_add(paddr, IDA_BLOCK_SIZE); 80 *idaws++ = paddr; 81 } 82 return idaws; 83 } 84 85 /* 86 * Sets the address of the data in CCW. 87 * If necessary it allocates an IDAL and sets the appropriate flags. 88 */ 89 static inline int set_normalized_cda(struct ccw1 *ccw, void *vaddr) 90 { 91 unsigned int nridaws; 92 dma64_t *idal; 93 94 if (ccw->flags & CCW_FLAG_IDA) 95 return -EINVAL; 96 nridaws = idal_nr_words(vaddr, ccw->count); 97 if (nridaws > 0) { 98 idal = kzalloc_objs(*idal, nridaws, GFP_ATOMIC | GFP_DMA); 99 if (!idal) 100 return -ENOMEM; 101 idal_create_words(idal, vaddr, ccw->count); 102 ccw->flags |= CCW_FLAG_IDA; 103 vaddr = idal; 104 } 105 ccw->cda = virt_to_dma32(vaddr); 106 return 0; 107 } 108 109 /* 110 * Releases any allocated IDAL related to the CCW. 111 */ 112 static inline void clear_normalized_cda(struct ccw1 *ccw) 113 { 114 if (ccw->flags & CCW_FLAG_IDA) { 115 kfree(dma32_to_virt(ccw->cda)); 116 ccw->flags &= ~CCW_FLAG_IDA; 117 } 118 ccw->cda = 0; 119 } 120 121 /* 122 * Idal buffer extension 123 */ 124 struct idal_buffer { 125 size_t size; 126 size_t page_order; 127 dma64_t data[]; 128 }; 129 130 /* 131 * Allocate an idal buffer 132 */ 133 static inline struct idal_buffer *idal_buffer_alloc(size_t size, int page_order) 134 { 135 int nr_chunks, nr_ptrs, i; 136 struct idal_buffer *ib; 137 void *vaddr; 138 139 nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_SHIFT; 140 nr_chunks = (PAGE_SIZE << page_order) >> IDA_SIZE_SHIFT; 141 ib = kmalloc_flex(*ib, data, nr_ptrs, GFP_DMA | GFP_KERNEL); 142 if (!ib) 143 return ERR_PTR(-ENOMEM); 144 ib->size = size; 145 ib->page_order = page_order; 146 for (i = 0; i < nr_ptrs; i++) { 147 if (i & (nr_chunks - 1)) { 148 ib->data[i] = dma64_add(ib->data[i - 1], IDA_BLOCK_SIZE); 149 continue; 150 } 151 vaddr = kmalloc(PAGE_SIZE << page_order, GFP_KERNEL); 152 if (!vaddr) 153 goto error; 154 /* Only DMA addresses are retained in ib->data. */ 155 kmemleak_ignore(vaddr); 156 ib->data[i] = virt_to_dma64(vaddr); 157 } 158 return ib; 159 error: 160 while (i >= nr_chunks) { 161 i -= nr_chunks; 162 vaddr = dma64_to_virt(ib->data[i]); 163 kfree(vaddr); 164 } 165 kfree(ib); 166 return ERR_PTR(-ENOMEM); 167 } 168 169 /* 170 * Free an idal buffer. 171 */ 172 static inline void idal_buffer_free(struct idal_buffer *ib) 173 { 174 int nr_chunks, nr_ptrs, i; 175 void *vaddr; 176 177 nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_SHIFT; 178 nr_chunks = (PAGE_SIZE << ib->page_order) >> IDA_SIZE_SHIFT; 179 for (i = 0; i < nr_ptrs; i += nr_chunks) { 180 vaddr = dma64_to_virt(ib->data[i]); 181 kfree(vaddr); 182 } 183 kfree(ib); 184 } 185 186 /* 187 * Allocate an array of IDAL buffers to cover a total data size of @size. The 188 * resulting array is null-terminated. 189 * 190 * The amount of individual IDAL buffers is determined based on @size. 191 * Each IDAL buffer can have a maximum size of @CCW_MAX_BYTE_COUNT. 192 */ 193 static inline struct idal_buffer **idal_buffer_array_alloc(size_t size, int page_order) 194 { 195 struct idal_buffer **ibs; 196 size_t ib_size; /* Size of a single idal buffer */ 197 int count; /* Amount of individual idal buffers */ 198 int i; 199 200 count = (size + CCW_MAX_BYTE_COUNT - 1) / CCW_MAX_BYTE_COUNT; 201 ibs = kmalloc_objs(*ibs, count + 1); 202 for (i = 0; i < count; i++) { 203 /* Determine size for the current idal buffer */ 204 ib_size = min(size, CCW_MAX_BYTE_COUNT); 205 size -= ib_size; 206 ibs[i] = idal_buffer_alloc(ib_size, page_order); 207 if (IS_ERR(ibs[i])) { 208 while (i--) 209 idal_buffer_free(ibs[i]); 210 kfree(ibs); 211 ibs = NULL; 212 return ERR_PTR(-ENOMEM); 213 } 214 } 215 ibs[i] = NULL; 216 return ibs; 217 } 218 219 /* 220 * Free array of IDAL buffers 221 */ 222 static inline void idal_buffer_array_free(struct idal_buffer ***ibs) 223 { 224 struct idal_buffer **p; 225 226 if (!ibs || !*ibs) 227 return; 228 for (p = *ibs; *p; p++) 229 idal_buffer_free(*p); 230 kfree(*ibs); 231 *ibs = NULL; 232 } 233 234 /* 235 * Determine size of IDAL buffer array 236 */ 237 static inline int idal_buffer_array_size(struct idal_buffer **ibs) 238 { 239 int size = 0; 240 241 while (ibs && *ibs) { 242 size++; 243 ibs++; 244 } 245 return size; 246 } 247 248 /* 249 * Determine total data size covered by IDAL buffer array 250 */ 251 static inline size_t idal_buffer_array_datasize(struct idal_buffer **ibs) 252 { 253 size_t size = 0; 254 255 while (ibs && *ibs) { 256 size += (*ibs)->size; 257 ibs++; 258 } 259 return size; 260 } 261 262 /* 263 * Test if a idal list is really needed. 264 */ 265 static inline bool __idal_buffer_is_needed(struct idal_buffer *ib) 266 { 267 if (ib->size > (PAGE_SIZE << ib->page_order)) 268 return true; 269 return idal_is_needed(dma64_to_virt(ib->data[0]), ib->size); 270 } 271 272 /* 273 * Set channel data address to idal buffer. 274 */ 275 static inline void idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw) 276 { 277 void *vaddr; 278 279 if (__idal_buffer_is_needed(ib)) { 280 /* Setup idals */ 281 ccw->cda = virt_to_dma32(ib->data); 282 ccw->flags |= CCW_FLAG_IDA; 283 } else { 284 /* 285 * No idals needed - use direct addressing. Convert from 286 * dma64_t to virt and then to dma32_t only because of type 287 * checking. The physical address is known to be below 2GB. 288 */ 289 vaddr = dma64_to_virt(ib->data[0]); 290 ccw->cda = virt_to_dma32(vaddr); 291 } 292 ccw->count = ib->size; 293 } 294 295 /* 296 * Copy count bytes from an idal buffer to user memory 297 */ 298 static inline size_t idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count) 299 { 300 size_t left; 301 void *vaddr; 302 int i; 303 304 BUG_ON(count > ib->size); 305 for (i = 0; count > IDA_BLOCK_SIZE; i++) { 306 vaddr = dma64_to_virt(ib->data[i]); 307 left = copy_to_user(to, vaddr, IDA_BLOCK_SIZE); 308 if (left) 309 return left + count - IDA_BLOCK_SIZE; 310 to = (void __user *)to + IDA_BLOCK_SIZE; 311 count -= IDA_BLOCK_SIZE; 312 } 313 vaddr = dma64_to_virt(ib->data[i]); 314 return copy_to_user(to, vaddr, count); 315 } 316 317 /* 318 * Copy count bytes from user memory to an idal buffer 319 */ 320 static inline size_t idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count) 321 { 322 size_t left; 323 void *vaddr; 324 int i; 325 326 BUG_ON(count > ib->size); 327 for (i = 0; count > IDA_BLOCK_SIZE; i++) { 328 vaddr = dma64_to_virt(ib->data[i]); 329 left = copy_from_user(vaddr, from, IDA_BLOCK_SIZE); 330 if (left) 331 return left + count - IDA_BLOCK_SIZE; 332 from = (void __user *)from + IDA_BLOCK_SIZE; 333 count -= IDA_BLOCK_SIZE; 334 } 335 vaddr = dma64_to_virt(ib->data[i]); 336 return copy_from_user(vaddr, from, count); 337 } 338 339 #endif 340