]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "spdk/stdinc.h" | |
35 | ||
36 | #include "spdk_internal/mock.h" | |
37 | ||
38 | #include "spdk/env.h" | |
39 | #include "spdk/queue.h" | |
9f95a23c | 40 | #include "spdk/util.h" |
11fdf7f2 TL |
41 | |
42 | DEFINE_STUB(spdk_process_is_primary, bool, (void), true) | |
43 | DEFINE_STUB(spdk_memzone_lookup, void *, (const char *name), NULL) | |
9f95a23c TL |
44 | DEFINE_STUB(spdk_pci_nvme_get_driver, struct spdk_pci_driver *, (void), NULL) |
45 | DEFINE_STUB(spdk_pci_ioat_get_driver, struct spdk_pci_driver *, (void), NULL) | |
46 | DEFINE_STUB(spdk_pci_virtio_get_driver, struct spdk_pci_driver *, (void), NULL) | |
11fdf7f2 TL |
47 | |
48 | /* | |
49 | * These mocks don't use the DEFINE_STUB macros because | |
50 | * their default implementation is more complex. | |
51 | */ | |
52 | ||
53 | DEFINE_RETURN_MOCK(spdk_memzone_reserve, void *); | |
54 | void * | |
55 | spdk_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags) | |
56 | { | |
57 | HANDLE_RETURN_MOCK(spdk_memzone_reserve); | |
58 | ||
59 | return malloc(len); | |
60 | } | |
61 | ||
62 | DEFINE_RETURN_MOCK(spdk_memzone_reserve_aligned, void *); | |
63 | void * | |
64 | spdk_memzone_reserve_aligned(const char *name, size_t len, int socket_id, | |
65 | unsigned flags, unsigned align) | |
66 | { | |
67 | HANDLE_RETURN_MOCK(spdk_memzone_reserve_aligned); | |
68 | ||
69 | return malloc(len); | |
70 | } | |
71 | ||
72 | DEFINE_RETURN_MOCK(spdk_malloc, void *); | |
73 | void * | |
74 | spdk_malloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags) | |
75 | { | |
76 | HANDLE_RETURN_MOCK(spdk_malloc); | |
77 | ||
78 | void *buf = NULL; | |
9f95a23c TL |
79 | |
80 | if (align == 0) { | |
81 | align = 8; | |
82 | } | |
83 | ||
11fdf7f2 TL |
84 | if (posix_memalign(&buf, align, size)) { |
85 | return NULL; | |
86 | } | |
87 | if (phys_addr) { | |
88 | *phys_addr = (uint64_t)buf; | |
89 | } | |
90 | ||
91 | return buf; | |
92 | } | |
93 | ||
94 | DEFINE_RETURN_MOCK(spdk_zmalloc, void *); | |
95 | void * | |
96 | spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags) | |
97 | { | |
98 | HANDLE_RETURN_MOCK(spdk_zmalloc); | |
99 | ||
100 | void *buf = spdk_malloc(size, align, phys_addr, -1, 1); | |
101 | ||
102 | if (buf != NULL) { | |
103 | memset(buf, 0, size); | |
104 | } | |
105 | return buf; | |
106 | } | |
107 | ||
108 | DEFINE_RETURN_MOCK(spdk_dma_malloc, void *); | |
109 | void * | |
110 | spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr) | |
111 | { | |
112 | HANDLE_RETURN_MOCK(spdk_dma_malloc); | |
113 | ||
114 | return spdk_malloc(size, align, phys_addr, -1, 1); | |
115 | } | |
116 | ||
9f95a23c TL |
117 | DEFINE_RETURN_MOCK(spdk_realloc, void *); |
118 | void * | |
119 | spdk_realloc(void *buf, size_t size, size_t align) | |
120 | { | |
121 | HANDLE_RETURN_MOCK(spdk_realloc); | |
122 | ||
123 | return realloc(buf, size); | |
124 | } | |
125 | ||
11fdf7f2 TL |
126 | DEFINE_RETURN_MOCK(spdk_dma_zmalloc, void *); |
127 | void * | |
128 | spdk_dma_zmalloc(size_t size, size_t align, uint64_t *phys_addr) | |
129 | { | |
130 | HANDLE_RETURN_MOCK(spdk_dma_zmalloc); | |
131 | ||
132 | return spdk_zmalloc(size, align, phys_addr, -1, 1); | |
133 | } | |
134 | ||
135 | DEFINE_RETURN_MOCK(spdk_dma_malloc_socket, void *); | |
136 | void * | |
137 | spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) | |
138 | { | |
139 | HANDLE_RETURN_MOCK(spdk_dma_malloc_socket); | |
140 | ||
141 | return spdk_dma_malloc(size, align, phys_addr); | |
142 | } | |
143 | ||
144 | DEFINE_RETURN_MOCK(spdk_dma_zmalloc_socket, void *); | |
145 | void * | |
146 | spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) | |
147 | { | |
148 | HANDLE_RETURN_MOCK(spdk_dma_zmalloc_socket); | |
149 | ||
150 | return spdk_dma_zmalloc(size, align, phys_addr); | |
151 | } | |
152 | ||
153 | DEFINE_RETURN_MOCK(spdk_dma_realloc, void *); | |
154 | void * | |
155 | spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr) | |
156 | { | |
157 | HANDLE_RETURN_MOCK(spdk_dma_realloc); | |
158 | ||
159 | return realloc(buf, size); | |
160 | } | |
161 | ||
162 | void | |
163 | spdk_free(void *buf) | |
164 | { | |
9f95a23c TL |
165 | /* fix for false-positives in *certain* static analysis tools. */ |
166 | assert((uintptr_t)buf != UINTPTR_MAX); | |
11fdf7f2 TL |
167 | free(buf); |
168 | } | |
169 | ||
170 | void | |
171 | spdk_dma_free(void *buf) | |
172 | { | |
173 | return spdk_free(buf); | |
174 | } | |
175 | ||
9f95a23c | 176 | #ifndef UNIT_TEST_NO_VTOPHYS |
11fdf7f2 TL |
177 | DEFINE_RETURN_MOCK(spdk_vtophys, uint64_t); |
178 | uint64_t | |
9f95a23c | 179 | spdk_vtophys(void *buf, uint64_t *size) |
11fdf7f2 TL |
180 | { |
181 | HANDLE_RETURN_MOCK(spdk_vtophys); | |
182 | ||
183 | return (uintptr_t)buf; | |
184 | } | |
9f95a23c | 185 | #endif |
11fdf7f2 TL |
186 | |
187 | void | |
188 | spdk_memzone_dump(FILE *f) | |
189 | { | |
190 | return; | |
191 | } | |
192 | ||
193 | DEFINE_RETURN_MOCK(spdk_memzone_free, int); | |
194 | int | |
195 | spdk_memzone_free(const char *name) | |
196 | { | |
197 | HANDLE_RETURN_MOCK(spdk_memzone_free); | |
198 | ||
199 | return 0; | |
200 | } | |
201 | ||
202 | struct test_mempool { | |
203 | size_t count; | |
9f95a23c | 204 | size_t ele_size; |
11fdf7f2 TL |
205 | }; |
206 | ||
207 | DEFINE_RETURN_MOCK(spdk_mempool_create, struct spdk_mempool *); | |
208 | struct spdk_mempool * | |
209 | spdk_mempool_create(const char *name, size_t count, | |
210 | size_t ele_size, size_t cache_size, int socket_id) | |
211 | { | |
212 | struct test_mempool *mp; | |
213 | ||
214 | HANDLE_RETURN_MOCK(spdk_mempool_create); | |
215 | ||
216 | mp = calloc(1, sizeof(*mp)); | |
217 | if (mp == NULL) { | |
218 | return NULL; | |
219 | } | |
220 | ||
221 | mp->count = count; | |
9f95a23c | 222 | mp->ele_size = ele_size; |
11fdf7f2 TL |
223 | |
224 | return (struct spdk_mempool *)mp; | |
225 | } | |
226 | ||
227 | void | |
228 | spdk_mempool_free(struct spdk_mempool *_mp) | |
229 | { | |
230 | struct test_mempool *mp = (struct test_mempool *)_mp; | |
231 | ||
232 | free(mp); | |
233 | } | |
234 | ||
235 | DEFINE_RETURN_MOCK(spdk_mempool_get, void *); | |
236 | void * | |
237 | spdk_mempool_get(struct spdk_mempool *_mp) | |
238 | { | |
239 | struct test_mempool *mp = (struct test_mempool *)_mp; | |
9f95a23c | 240 | size_t ele_size = 0x10000; |
11fdf7f2 TL |
241 | void *buf; |
242 | ||
243 | HANDLE_RETURN_MOCK(spdk_mempool_get); | |
244 | ||
245 | if (mp && mp->count == 0) { | |
246 | return NULL; | |
247 | } | |
248 | ||
9f95a23c TL |
249 | if (mp) { |
250 | ele_size = mp->ele_size; | |
251 | } | |
252 | ||
253 | if (posix_memalign(&buf, 64, spdk_align32pow2(ele_size))) { | |
11fdf7f2 TL |
254 | return NULL; |
255 | } else { | |
256 | if (mp) { | |
257 | mp->count--; | |
258 | } | |
259 | return buf; | |
260 | } | |
261 | } | |
262 | ||
263 | int | |
264 | spdk_mempool_get_bulk(struct spdk_mempool *mp, void **ele_arr, size_t count) | |
265 | { | |
266 | for (size_t i = 0; i < count; i++) { | |
267 | ele_arr[i] = spdk_mempool_get(mp); | |
268 | if (ele_arr[i] == NULL) { | |
269 | return -1; | |
270 | } | |
271 | } | |
272 | return 0; | |
273 | } | |
274 | ||
275 | void | |
276 | spdk_mempool_put(struct spdk_mempool *_mp, void *ele) | |
277 | { | |
278 | struct test_mempool *mp = (struct test_mempool *)_mp; | |
279 | ||
280 | if (mp) { | |
281 | mp->count++; | |
282 | } | |
283 | free(ele); | |
284 | } | |
285 | ||
286 | void | |
287 | spdk_mempool_put_bulk(struct spdk_mempool *mp, void **ele_arr, size_t count) | |
288 | { | |
289 | for (size_t i = 0; i < count; i++) { | |
290 | spdk_mempool_put(mp, ele_arr[i]); | |
291 | } | |
292 | } | |
293 | ||
294 | DEFINE_RETURN_MOCK(spdk_mempool_count, size_t); | |
295 | size_t | |
296 | spdk_mempool_count(const struct spdk_mempool *_mp) | |
297 | { | |
298 | struct test_mempool *mp = (struct test_mempool *)_mp; | |
299 | ||
300 | HANDLE_RETURN_MOCK(spdk_mempool_count); | |
301 | ||
302 | if (mp) { | |
303 | return mp->count; | |
304 | } else { | |
305 | return 1024; | |
306 | } | |
307 | } | |
308 | ||
309 | struct spdk_ring_ele { | |
310 | void *ele; | |
311 | TAILQ_ENTRY(spdk_ring_ele) link; | |
312 | }; | |
313 | ||
314 | struct spdk_ring { | |
315 | TAILQ_HEAD(, spdk_ring_ele) elements; | |
9f95a23c TL |
316 | pthread_mutex_t lock; |
317 | size_t count; | |
11fdf7f2 TL |
318 | }; |
319 | ||
320 | DEFINE_RETURN_MOCK(spdk_ring_create, struct spdk_ring *); | |
321 | struct spdk_ring * | |
322 | spdk_ring_create(enum spdk_ring_type type, size_t count, int socket_id) | |
323 | { | |
324 | struct spdk_ring *ring; | |
325 | ||
326 | HANDLE_RETURN_MOCK(spdk_ring_create); | |
327 | ||
328 | ring = calloc(1, sizeof(*ring)); | |
9f95a23c TL |
329 | if (!ring) { |
330 | return NULL; | |
331 | } | |
332 | ||
333 | if (pthread_mutex_init(&ring->lock, NULL)) { | |
334 | free(ring); | |
335 | return NULL; | |
11fdf7f2 TL |
336 | } |
337 | ||
9f95a23c | 338 | TAILQ_INIT(&ring->elements); |
11fdf7f2 TL |
339 | return ring; |
340 | } | |
341 | ||
342 | void | |
343 | spdk_ring_free(struct spdk_ring *ring) | |
344 | { | |
9f95a23c TL |
345 | struct spdk_ring_ele *ele, *tmp; |
346 | ||
347 | if (!ring) { | |
348 | return; | |
349 | } | |
350 | ||
351 | TAILQ_FOREACH_SAFE(ele, &ring->elements, link, tmp) { | |
352 | free(ele); | |
353 | } | |
354 | ||
355 | pthread_mutex_destroy(&ring->lock); | |
11fdf7f2 TL |
356 | free(ring); |
357 | } | |
358 | ||
359 | DEFINE_RETURN_MOCK(spdk_ring_enqueue, size_t); | |
360 | size_t | |
9f95a23c TL |
361 | spdk_ring_enqueue(struct spdk_ring *ring, void **objs, size_t count, |
362 | size_t *free_space) | |
11fdf7f2 TL |
363 | { |
364 | struct spdk_ring_ele *ele; | |
365 | size_t i; | |
366 | ||
367 | HANDLE_RETURN_MOCK(spdk_ring_enqueue); | |
368 | ||
9f95a23c TL |
369 | pthread_mutex_lock(&ring->lock); |
370 | ||
11fdf7f2 TL |
371 | for (i = 0; i < count; i++) { |
372 | ele = calloc(1, sizeof(*ele)); | |
373 | if (!ele) { | |
374 | break; | |
375 | } | |
376 | ||
377 | ele->ele = objs[i]; | |
378 | TAILQ_INSERT_TAIL(&ring->elements, ele, link); | |
9f95a23c | 379 | ring->count++; |
11fdf7f2 TL |
380 | } |
381 | ||
9f95a23c | 382 | pthread_mutex_unlock(&ring->lock); |
11fdf7f2 TL |
383 | return i; |
384 | } | |
385 | ||
386 | DEFINE_RETURN_MOCK(spdk_ring_dequeue, size_t); | |
387 | size_t | |
388 | spdk_ring_dequeue(struct spdk_ring *ring, void **objs, size_t count) | |
389 | { | |
390 | struct spdk_ring_ele *ele, *tmp; | |
391 | size_t i = 0; | |
392 | ||
393 | HANDLE_RETURN_MOCK(spdk_ring_dequeue); | |
394 | ||
395 | if (count == 0) { | |
396 | return 0; | |
397 | } | |
398 | ||
9f95a23c TL |
399 | pthread_mutex_lock(&ring->lock); |
400 | ||
11fdf7f2 TL |
401 | TAILQ_FOREACH_SAFE(ele, &ring->elements, link, tmp) { |
402 | TAILQ_REMOVE(&ring->elements, ele, link); | |
9f95a23c | 403 | ring->count--; |
11fdf7f2 TL |
404 | objs[i] = ele->ele; |
405 | free(ele); | |
406 | i++; | |
407 | if (i >= count) { | |
408 | break; | |
409 | } | |
410 | } | |
411 | ||
9f95a23c | 412 | pthread_mutex_unlock(&ring->lock); |
11fdf7f2 TL |
413 | return i; |
414 | ||
415 | } | |
416 | ||
9f95a23c TL |
417 | |
418 | DEFINE_RETURN_MOCK(spdk_ring_count, size_t); | |
419 | size_t | |
420 | spdk_ring_count(struct spdk_ring *ring) | |
421 | { | |
422 | HANDLE_RETURN_MOCK(spdk_ring_count); | |
423 | return ring->count; | |
424 | } | |
425 | ||
11fdf7f2 TL |
426 | DEFINE_RETURN_MOCK(spdk_get_ticks, uint64_t); |
427 | uint64_t | |
428 | spdk_get_ticks(void) | |
429 | { | |
430 | HANDLE_RETURN_MOCK(spdk_get_ticks); | |
431 | ||
432 | return ut_spdk_get_ticks; | |
433 | } | |
434 | ||
435 | DEFINE_RETURN_MOCK(spdk_get_ticks_hz, uint64_t); | |
436 | uint64_t | |
437 | spdk_get_ticks_hz(void) | |
438 | { | |
439 | HANDLE_RETURN_MOCK(spdk_get_ticks_hz); | |
440 | ||
441 | return 1000000; | |
442 | } | |
443 | ||
444 | void | |
445 | spdk_delay_us(unsigned int us) | |
446 | { | |
447 | /* spdk_get_ticks_hz is 1000000, meaning 1 tick per us. */ | |
448 | ut_spdk_get_ticks += us; | |
449 | } | |
450 | ||
9f95a23c | 451 | #ifndef UNIT_TEST_NO_PCI_ADDR |
11fdf7f2 TL |
452 | DEFINE_RETURN_MOCK(spdk_pci_addr_parse, int); |
453 | int | |
454 | spdk_pci_addr_parse(struct spdk_pci_addr *addr, const char *bdf) | |
455 | { | |
456 | unsigned domain, bus, dev, func; | |
457 | ||
458 | HANDLE_RETURN_MOCK(spdk_pci_addr_parse); | |
459 | ||
460 | if (addr == NULL || bdf == NULL) { | |
461 | return -EINVAL; | |
462 | } | |
463 | ||
464 | if ((sscanf(bdf, "%x:%x:%x.%x", &domain, &bus, &dev, &func) == 4) || | |
465 | (sscanf(bdf, "%x.%x.%x.%x", &domain, &bus, &dev, &func) == 4)) { | |
466 | /* Matched a full address - all variables are initialized */ | |
467 | } else if (sscanf(bdf, "%x:%x:%x", &domain, &bus, &dev) == 3) { | |
468 | func = 0; | |
469 | } else if ((sscanf(bdf, "%x:%x.%x", &bus, &dev, &func) == 3) || | |
470 | (sscanf(bdf, "%x.%x.%x", &bus, &dev, &func) == 3)) { | |
471 | domain = 0; | |
472 | } else if ((sscanf(bdf, "%x:%x", &bus, &dev) == 2) || | |
473 | (sscanf(bdf, "%x.%x", &bus, &dev) == 2)) { | |
474 | domain = 0; | |
475 | func = 0; | |
476 | } else { | |
477 | return -EINVAL; | |
478 | } | |
479 | ||
480 | if (bus > 0xFF || dev > 0x1F || func > 7) { | |
481 | return -EINVAL; | |
482 | } | |
483 | ||
484 | addr->domain = domain; | |
485 | addr->bus = bus; | |
486 | addr->dev = dev; | |
487 | addr->func = func; | |
488 | ||
489 | return 0; | |
490 | } | |
491 | ||
492 | DEFINE_RETURN_MOCK(spdk_pci_addr_fmt, int); | |
493 | int | |
494 | spdk_pci_addr_fmt(char *bdf, size_t sz, const struct spdk_pci_addr *addr) | |
495 | { | |
496 | int rc; | |
497 | ||
498 | HANDLE_RETURN_MOCK(spdk_pci_addr_fmt); | |
499 | ||
500 | rc = snprintf(bdf, sz, "%04x:%02x:%02x.%x", | |
501 | addr->domain, addr->bus, | |
502 | addr->dev, addr->func); | |
503 | ||
504 | if (rc > 0 && (size_t)rc < sz) { | |
505 | return 0; | |
506 | } | |
507 | ||
508 | return -1; | |
509 | } | |
510 | ||
511 | DEFINE_RETURN_MOCK(spdk_pci_addr_compare, int); | |
512 | int | |
513 | spdk_pci_addr_compare(const struct spdk_pci_addr *a1, const struct spdk_pci_addr *a2) | |
514 | { | |
515 | HANDLE_RETURN_MOCK(spdk_pci_addr_compare); | |
516 | ||
517 | if (a1->domain > a2->domain) { | |
518 | return 1; | |
519 | } else if (a1->domain < a2->domain) { | |
520 | return -1; | |
521 | } else if (a1->bus > a2->bus) { | |
522 | return 1; | |
523 | } else if (a1->bus < a2->bus) { | |
524 | return -1; | |
525 | } else if (a1->dev > a2->dev) { | |
526 | return 1; | |
527 | } else if (a1->dev < a2->dev) { | |
528 | return -1; | |
529 | } else if (a1->func > a2->func) { | |
530 | return 1; | |
531 | } else if (a1->func < a2->func) { | |
532 | return -1; | |
533 | } | |
534 | ||
535 | return 0; | |
536 | } | |
9f95a23c | 537 | #endif |