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