1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "ftl_l2p.h" 7 #include "ftl_core.h" 8 #include "ftl_band.h" 9 #include "ftl_utils.h" 10 #include "ftl_l2p_flat.h" 11 #include "utils/ftl_addr_utils.h" 12 13 static struct ftl_md * 14 get_l2p_md(struct spdk_ftl_dev *dev) 15 { 16 return dev->layout.md[FTL_LAYOUT_REGION_TYPE_L2P]; 17 } 18 19 struct ftl_l2p_flat { 20 void *l2p; 21 bool is_halted; 22 }; 23 24 void 25 ftl_l2p_flat_pin(struct spdk_ftl_dev *dev, struct ftl_l2p_pin_ctx *pin_ctx) 26 { 27 assert(dev->num_lbas >= pin_ctx->lba + pin_ctx->count); 28 29 ftl_l2p_pin_complete(dev, 0, pin_ctx); 30 } 31 32 void 33 ftl_l2p_flat_unpin(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count) 34 { 35 assert(dev->num_lbas >= lba + count); 36 } 37 38 void 39 ftl_l2p_flat_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr) 40 { 41 struct ftl_l2p_flat *l2p_flat = dev->l2p; 42 43 assert(dev->num_lbas > lba); 44 45 ftl_addr_store(dev, l2p_flat->l2p, lba, addr); 46 } 47 48 ftl_addr 49 ftl_l2p_flat_get(struct spdk_ftl_dev *dev, uint64_t lba) 50 { 51 struct ftl_l2p_flat *l2p_flat = dev->l2p; 52 53 assert(dev->num_lbas > lba); 54 55 return ftl_addr_load(dev, l2p_flat->l2p, lba); 56 } 57 58 static void 59 md_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status) 60 { 61 ftl_l2p_cb cb = md->owner.private; 62 void *cb_ctx = md->owner.cb_ctx; 63 64 cb(dev, status, cb_ctx); 65 } 66 67 void 68 ftl_l2p_flat_clear(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 69 { 70 struct ftl_l2p_flat *l2p_flat = dev->l2p; 71 struct ftl_md *md; 72 73 memset(l2p_flat->l2p, (int)FTL_ADDR_INVALID, 74 ftl_md_get_buffer_size(get_l2p_md(dev))); 75 76 md = get_l2p_md(dev); 77 md->cb = md_cb; 78 md->owner.cb_ctx = cb_ctx; 79 md->owner.private = cb; 80 ftl_md_persist(md); 81 } 82 83 static int 84 ftl_l2p_flat_init_dram(struct spdk_ftl_dev *dev, struct ftl_l2p_flat *l2p_flat, 85 size_t l2p_size) 86 { 87 struct ftl_md *md = get_l2p_md(dev); 88 89 assert(ftl_md_get_buffer_size(md) >= l2p_size); 90 91 l2p_flat->l2p = ftl_md_get_buffer(md); 92 if (!l2p_flat->l2p) { 93 FTL_ERRLOG(dev, "Failed to allocate l2p table\n"); 94 return -1; 95 } 96 97 return 0; 98 } 99 100 int 101 ftl_l2p_flat_init(struct spdk_ftl_dev *dev) 102 { 103 size_t l2p_size = dev->num_lbas * dev->layout.l2p.addr_size; 104 struct ftl_l2p_flat *l2p_flat; 105 int ret; 106 107 if (dev->num_lbas == 0) { 108 FTL_ERRLOG(dev, "Invalid l2p table size\n"); 109 return -1; 110 } 111 112 if (dev->l2p) { 113 FTL_ERRLOG(dev, "L2p table already allocated\n"); 114 return -1; 115 } 116 117 l2p_flat = calloc(1, sizeof(*l2p_flat)); 118 if (!l2p_flat) { 119 FTL_ERRLOG(dev, "Failed to allocate l2p_flat\n"); 120 return -1; 121 } 122 123 ret = ftl_l2p_flat_init_dram(dev, l2p_flat, l2p_size); 124 125 if (ret) { 126 free(l2p_flat); 127 return ret; 128 } 129 130 dev->l2p = l2p_flat; 131 return 0; 132 } 133 134 void 135 ftl_l2p_flat_deinit(struct spdk_ftl_dev *dev) 136 { 137 struct ftl_l2p_flat *l2p_flat = dev->l2p; 138 139 if (!l2p_flat) { 140 return; 141 } 142 143 free(l2p_flat); 144 145 dev->l2p = NULL; 146 } 147 148 void 149 ftl_l2p_flat_unmap(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 150 { 151 cb(dev, 0, cb_ctx); 152 } 153 154 void 155 ftl_l2p_flat_process(struct spdk_ftl_dev *dev) 156 { 157 } 158 159 bool 160 ftl_l2p_flat_is_halted(struct spdk_ftl_dev *dev) 161 { 162 return true; 163 } 164 165 void 166 ftl_l2p_flat_halt(struct spdk_ftl_dev *dev) 167 { 168 } 169