1*1666fcfcSDamiano Cipriani /* SPDX-License-Identifier: BSD-3-Clause
2*1666fcfcSDamiano Cipriani * Copyright (C) 2023 SUSE LLC.
3*1666fcfcSDamiano Cipriani * All rights reserved.
4*1666fcfcSDamiano Cipriani */
5*1666fcfcSDamiano Cipriani
6*1666fcfcSDamiano Cipriani #include "thread/thread_internal.h"
7*1666fcfcSDamiano Cipriani #include "spdk/blob.h"
8*1666fcfcSDamiano Cipriani
9*1666fcfcSDamiano Cipriani
10*1666fcfcSDamiano Cipriani #define EXT_DEV_BUFFER_SIZE (4 * 1024 * 1024)
11*1666fcfcSDamiano Cipriani uint8_t g_ext_dev_buffer[EXT_DEV_BUFFER_SIZE];
12*1666fcfcSDamiano Cipriani struct spdk_io_channel g_ext_io_channel;
13*1666fcfcSDamiano Cipriani
14*1666fcfcSDamiano Cipriani static struct spdk_io_channel *
ext_dev_create_channel(struct spdk_bs_dev * dev)15*1666fcfcSDamiano Cipriani ext_dev_create_channel(struct spdk_bs_dev *dev)
16*1666fcfcSDamiano Cipriani {
17*1666fcfcSDamiano Cipriani return &g_ext_io_channel;
18*1666fcfcSDamiano Cipriani }
19*1666fcfcSDamiano Cipriani
20*1666fcfcSDamiano Cipriani static void
ext_dev_destroy_channel(struct spdk_bs_dev * dev,struct spdk_io_channel * channel)21*1666fcfcSDamiano Cipriani ext_dev_destroy_channel(struct spdk_bs_dev *dev, struct spdk_io_channel *channel)
22*1666fcfcSDamiano Cipriani {
23*1666fcfcSDamiano Cipriani }
24*1666fcfcSDamiano Cipriani
25*1666fcfcSDamiano Cipriani static void
ext_dev_destroy(struct spdk_bs_dev * dev)26*1666fcfcSDamiano Cipriani ext_dev_destroy(struct spdk_bs_dev *dev)
27*1666fcfcSDamiano Cipriani {
28*1666fcfcSDamiano Cipriani free(dev);
29*1666fcfcSDamiano Cipriani }
30*1666fcfcSDamiano Cipriani
31*1666fcfcSDamiano Cipriani static void
ext_dev_read(struct spdk_bs_dev * dev,struct spdk_io_channel * channel,void * payload,uint64_t lba,uint32_t lba_count,struct spdk_bs_dev_cb_args * cb_args)32*1666fcfcSDamiano Cipriani ext_dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
33*1666fcfcSDamiano Cipriani uint64_t lba, uint32_t lba_count,
34*1666fcfcSDamiano Cipriani struct spdk_bs_dev_cb_args *cb_args)
35*1666fcfcSDamiano Cipriani {
36*1666fcfcSDamiano Cipriani uint64_t offset, length;
37*1666fcfcSDamiano Cipriani
38*1666fcfcSDamiano Cipriani offset = lba * dev->blocklen;
39*1666fcfcSDamiano Cipriani length = lba_count * dev->blocklen;
40*1666fcfcSDamiano Cipriani SPDK_CU_ASSERT_FATAL(offset + length <= EXT_DEV_BUFFER_SIZE);
41*1666fcfcSDamiano Cipriani
42*1666fcfcSDamiano Cipriani if (length > 0) {
43*1666fcfcSDamiano Cipriani memcpy(payload, &g_ext_dev_buffer[offset], length);
44*1666fcfcSDamiano Cipriani }
45*1666fcfcSDamiano Cipriani
46*1666fcfcSDamiano Cipriani cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
47*1666fcfcSDamiano Cipriani }
48*1666fcfcSDamiano Cipriani
49*1666fcfcSDamiano Cipriani static void
ext_dev_write(struct spdk_bs_dev * dev,struct spdk_io_channel * channel,void * payload,uint64_t lba,uint32_t lba_count,struct spdk_bs_dev_cb_args * cb_args)50*1666fcfcSDamiano Cipriani ext_dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
51*1666fcfcSDamiano Cipriani uint64_t lba, uint32_t lba_count,
52*1666fcfcSDamiano Cipriani struct spdk_bs_dev_cb_args *cb_args)
53*1666fcfcSDamiano Cipriani {
54*1666fcfcSDamiano Cipriani uint64_t offset, length;
55*1666fcfcSDamiano Cipriani
56*1666fcfcSDamiano Cipriani offset = lba * dev->blocklen;
57*1666fcfcSDamiano Cipriani length = lba_count * dev->blocklen;
58*1666fcfcSDamiano Cipriani SPDK_CU_ASSERT_FATAL(offset + length <= EXT_DEV_BUFFER_SIZE);
59*1666fcfcSDamiano Cipriani
60*1666fcfcSDamiano Cipriani memcpy(&g_ext_dev_buffer[offset], payload, length);
61*1666fcfcSDamiano Cipriani
62*1666fcfcSDamiano Cipriani cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
63*1666fcfcSDamiano Cipriani }
64*1666fcfcSDamiano Cipriani
65*1666fcfcSDamiano Cipriani static struct spdk_bs_dev *
init_ext_dev(uint64_t blockcnt,uint32_t blocklen)66*1666fcfcSDamiano Cipriani init_ext_dev(uint64_t blockcnt, uint32_t blocklen)
67*1666fcfcSDamiano Cipriani {
68*1666fcfcSDamiano Cipriani struct spdk_bs_dev *dev = calloc(1, sizeof(*dev));
69*1666fcfcSDamiano Cipriani
70*1666fcfcSDamiano Cipriani SPDK_CU_ASSERT_FATAL(dev != NULL);
71*1666fcfcSDamiano Cipriani
72*1666fcfcSDamiano Cipriani dev->create_channel = ext_dev_create_channel;
73*1666fcfcSDamiano Cipriani dev->destroy_channel = ext_dev_destroy_channel;
74*1666fcfcSDamiano Cipriani dev->destroy = ext_dev_destroy;
75*1666fcfcSDamiano Cipriani dev->read = ext_dev_read;
76*1666fcfcSDamiano Cipriani dev->write = ext_dev_write;
77*1666fcfcSDamiano Cipriani dev->blockcnt = blockcnt;
78*1666fcfcSDamiano Cipriani dev->blocklen = blocklen;
79*1666fcfcSDamiano Cipriani
80*1666fcfcSDamiano Cipriani return dev;
81*1666fcfcSDamiano Cipriani }
82