1*94c4a1e1SFrank Piva // SPDX-License-Identifier: MIT or GPL-2.0-only
2*94c4a1e1SFrank Piva
3*94c4a1e1SFrank Piva #include <config.h>
4*94c4a1e1SFrank Piva
5*94c4a1e1SFrank Piva #include "ublksrv_tgt.h"
6*94c4a1e1SFrank Piva
null_init_tgt(struct ublksrv_dev * dev,int type,int argc,char * argv[])7*94c4a1e1SFrank Piva static int null_init_tgt(struct ublksrv_dev *dev, int type, int argc,
8*94c4a1e1SFrank Piva char *argv[])
9*94c4a1e1SFrank Piva {
10*94c4a1e1SFrank Piva struct ublksrv_tgt_info *tgt = &dev->tgt;
11*94c4a1e1SFrank Piva const struct ublksrv_ctrl_dev_info *info =
12*94c4a1e1SFrank Piva ublksrv_ctrl_get_dev_info(ublksrv_get_ctrl_dev(dev));
13*94c4a1e1SFrank Piva int jbuf_size;
14*94c4a1e1SFrank Piva char *jbuf = ublksrv_tgt_return_json_buf(dev, &jbuf_size);
15*94c4a1e1SFrank Piva struct ublksrv_tgt_base_json tgt_json = {
16*94c4a1e1SFrank Piva .type = type,
17*94c4a1e1SFrank Piva };
18*94c4a1e1SFrank Piva unsigned long long dev_size = 250UL * 1024 * 1024 * 1024;
19*94c4a1e1SFrank Piva struct ublk_params p = {
20*94c4a1e1SFrank Piva .types = UBLK_PARAM_TYPE_BASIC,
21*94c4a1e1SFrank Piva .basic = {
22*94c4a1e1SFrank Piva .logical_bs_shift = 9,
23*94c4a1e1SFrank Piva .physical_bs_shift = 12,
24*94c4a1e1SFrank Piva .io_opt_shift = 12,
25*94c4a1e1SFrank Piva .io_min_shift = 9,
26*94c4a1e1SFrank Piva .max_sectors = info->max_io_buf_bytes >> 9,
27*94c4a1e1SFrank Piva .dev_sectors = dev_size >> 9,
28*94c4a1e1SFrank Piva },
29*94c4a1e1SFrank Piva };
30*94c4a1e1SFrank Piva
31*94c4a1e1SFrank Piva strcpy(tgt_json.name, "null");
32*94c4a1e1SFrank Piva
33*94c4a1e1SFrank Piva if (type != UBLKSRV_TGT_TYPE_NULL)
34*94c4a1e1SFrank Piva return -1;
35*94c4a1e1SFrank Piva
36*94c4a1e1SFrank Piva tgt_json.dev_size = tgt->dev_size = dev_size;
37*94c4a1e1SFrank Piva tgt->tgt_ring_depth = info->queue_depth;
38*94c4a1e1SFrank Piva tgt->nr_fds = 0;
39*94c4a1e1SFrank Piva ublksrv_tgt_set_io_data_size(tgt);
40*94c4a1e1SFrank Piva
41*94c4a1e1SFrank Piva ublk_json_write_dev_info(dev, &jbuf, &jbuf_size);
42*94c4a1e1SFrank Piva ublk_json_write_target_base(dev, &jbuf, &jbuf_size, &tgt_json);
43*94c4a1e1SFrank Piva ublk_json_write_params(dev, &jbuf, &jbuf_size, &p);
44*94c4a1e1SFrank Piva
45*94c4a1e1SFrank Piva return 0;
46*94c4a1e1SFrank Piva }
47*94c4a1e1SFrank Piva
null_recovery_tgt(struct ublksrv_dev * dev,int type)48*94c4a1e1SFrank Piva static int null_recovery_tgt(struct ublksrv_dev *dev, int type)
49*94c4a1e1SFrank Piva {
50*94c4a1e1SFrank Piva const struct ublksrv_ctrl_dev *cdev = ublksrv_get_ctrl_dev(dev);
51*94c4a1e1SFrank Piva const char *jbuf = ublksrv_ctrl_get_recovery_jbuf(cdev);
52*94c4a1e1SFrank Piva const struct ublksrv_ctrl_dev_info *info =
53*94c4a1e1SFrank Piva ublksrv_ctrl_get_dev_info(cdev);
54*94c4a1e1SFrank Piva struct ublksrv_tgt_info *tgt = &dev->tgt;
55*94c4a1e1SFrank Piva int ret;
56*94c4a1e1SFrank Piva struct ublk_params p;
57*94c4a1e1SFrank Piva
58*94c4a1e1SFrank Piva ublk_assert(jbuf);
59*94c4a1e1SFrank Piva ublk_assert(info->state == UBLK_S_DEV_QUIESCED);
60*94c4a1e1SFrank Piva ublk_assert(type == UBLKSRV_TGT_TYPE_NULL);
61*94c4a1e1SFrank Piva
62*94c4a1e1SFrank Piva ret = ublksrv_json_read_params(&p, jbuf);
63*94c4a1e1SFrank Piva if (ret) {
64*94c4a1e1SFrank Piva ublk_err( "%s: read ublk params failed %d\n",
65*94c4a1e1SFrank Piva __func__, ret);
66*94c4a1e1SFrank Piva return ret;
67*94c4a1e1SFrank Piva }
68*94c4a1e1SFrank Piva
69*94c4a1e1SFrank Piva ublksrv_tgt_set_io_data_size(tgt);
70*94c4a1e1SFrank Piva tgt->dev_size = p.basic.dev_sectors << 9;
71*94c4a1e1SFrank Piva tgt->tgt_ring_depth = info->queue_depth;
72*94c4a1e1SFrank Piva tgt->nr_fds = 0;
73*94c4a1e1SFrank Piva return 0;
74*94c4a1e1SFrank Piva }
75*94c4a1e1SFrank Piva
__null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data,int tag)76*94c4a1e1SFrank Piva static co_io_job __null_handle_io_async(const struct ublksrv_queue *q,
77*94c4a1e1SFrank Piva const struct ublk_io_data *data, int tag)
78*94c4a1e1SFrank Piva {
79*94c4a1e1SFrank Piva ublksrv_complete_io(q, tag, data->iod->nr_sectors << 9);
80*94c4a1e1SFrank Piva
81*94c4a1e1SFrank Piva co_return;
82*94c4a1e1SFrank Piva }
83*94c4a1e1SFrank Piva
null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data)84*94c4a1e1SFrank Piva static int null_handle_io_async(const struct ublksrv_queue *q,
85*94c4a1e1SFrank Piva const struct ublk_io_data *data)
86*94c4a1e1SFrank Piva {
87*94c4a1e1SFrank Piva struct ublk_io_tgt *io = __ublk_get_io_tgt_data(data);
88*94c4a1e1SFrank Piva
89*94c4a1e1SFrank Piva io->co = __null_handle_io_async(q, data, data->tag);
90*94c4a1e1SFrank Piva
91*94c4a1e1SFrank Piva return 0;
92*94c4a1e1SFrank Piva }
93*94c4a1e1SFrank Piva
94*94c4a1e1SFrank Piva struct ublksrv_tgt_type null_tgt_type = {
95*94c4a1e1SFrank Piva .handle_io_async = null_handle_io_async,
96*94c4a1e1SFrank Piva .init_tgt = null_init_tgt,
97*94c4a1e1SFrank Piva .type = UBLKSRV_TGT_TYPE_NULL,
98*94c4a1e1SFrank Piva .name = "null",
99*94c4a1e1SFrank Piva .recovery_tgt = null_recovery_tgt,
100*94c4a1e1SFrank Piva };
101*94c4a1e1SFrank Piva
102*94c4a1e1SFrank Piva static void tgt_null_init() __attribute__((constructor));
103*94c4a1e1SFrank Piva
tgt_null_init(void)104*94c4a1e1SFrank Piva static void tgt_null_init(void)
105*94c4a1e1SFrank Piva {
106*94c4a1e1SFrank Piva ublksrv_register_tgt_type(&null_tgt_type);
107*94c4a1e1SFrank Piva }
108*94c4a1e1SFrank Piva
109