1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2023 Solidigm All Rights Reserved
3 */
4
5 #include "spdk/stdinc.h"
6 #include "spdk/queue.h"
7 #include "spdk/log.h"
8
9 #include "ftl_nvc_dev.h"
10 #include "utils/ftl_defs.h"
11
12 static TAILQ_HEAD(, ftl_nv_cache_device_type) g_devs = TAILQ_HEAD_INITIALIZER(g_devs);
13 static pthread_mutex_t g_devs_mutex = PTHREAD_MUTEX_INITIALIZER;
14
15 static const struct ftl_nv_cache_device_type *
ftl_nv_cache_device_type_get_type(const char * name)16 ftl_nv_cache_device_type_get_type(const char *name)
17 {
18 struct ftl_nv_cache_device_type *entry;
19
20 TAILQ_FOREACH(entry, &g_devs, internal.entry) {
21 if (0 == strcmp(entry->name, name)) {
22 return entry;
23 }
24 }
25
26 return NULL;
27 }
28
29 static bool
ftl_nv_cache_device_valid(const struct ftl_nv_cache_device_type * type)30 ftl_nv_cache_device_valid(const struct ftl_nv_cache_device_type *type)
31 {
32 return type && type->name && strlen(type->name) > 0;
33 }
34
35 void
ftl_nv_cache_device_register(struct ftl_nv_cache_device_type * type)36 ftl_nv_cache_device_register(struct ftl_nv_cache_device_type *type)
37 {
38 if (!ftl_nv_cache_device_valid(type)) {
39 SPDK_ERRLOG("NV cache device descriptor is invalid\n");
40 ftl_abort();
41 }
42
43 pthread_mutex_lock(&g_devs_mutex);
44 if (!ftl_nv_cache_device_type_get_type(type->name)) {
45 TAILQ_INSERT_TAIL(&g_devs, type, internal.entry);
46 SPDK_NOTICELOG("Registered NV cache device, name: %s\n", type->name);
47 } else {
48 SPDK_ERRLOG("Cannot register NV cache device, already exists, name: %s\n", type->name);
49 ftl_abort();
50 }
51
52 pthread_mutex_unlock(&g_devs_mutex);
53 }
54
55 const struct ftl_nv_cache_device_type *
ftl_nv_cache_device_get_type_by_bdev(struct spdk_ftl_dev * dev,struct spdk_bdev * bdev)56 ftl_nv_cache_device_get_type_by_bdev(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev)
57 {
58 struct ftl_nv_cache_device_type *entry;
59 const struct ftl_nv_cache_device_type *type = NULL;
60
61 pthread_mutex_lock(&g_devs_mutex);
62 TAILQ_FOREACH(entry, &g_devs, internal.entry) {
63 if (entry->ops.is_bdev_compatible) {
64 if (entry->ops.is_bdev_compatible(dev, bdev)) {
65 type = entry;
66 break;
67 }
68 }
69 }
70 pthread_mutex_unlock(&g_devs_mutex);
71
72 return type;
73 }
74