30 #include <linux/string.h>
34 #include <linux/slab.h>
36 #include <scsi/scsi.h>
54 rd_host = kzalloc(
sizeof(
struct rd_host),
GFP_KERNEL);
56 pr_err(
"Unable to allocate memory for struct rd_host\n");
64 pr_debug(
"CORE_HBA[%d] - TCM Ramdisk HBA Driver %s on"
65 " Generic Target Core Stack %s\n", hba->
hba_id,
71 static void rd_detach_hba(
struct se_hba *hba)
73 struct rd_host *rd_host = hba->
hba_ptr;
75 pr_debug(
"CORE_HBA[%d] - Detached Ramdisk HBA: %u from"
86 static void rd_release_device_space(
struct rd_dev *
rd_dev)
88 u32 i,
j, page_count = 0, sg_per_table;
102 for (j = 0; j < sg_per_table; j++) {
103 pg = sg_page(&sg[j]);
113 pr_debug(
"CORE_RD[%u] - Released device space for Ramdisk"
114 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
128 static int rd_build_device_space(
struct rd_dev *rd_dev)
130 u32 i = 0,
j,
page_offset = 0, sg_per_table, sg_tables, total_sg_needed;
138 pr_err(
"Illegal page count: %u for Ramdisk device\n",
144 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
148 pr_err(
"Unable to allocate memory for Ramdisk"
149 " scatterlist tables\n");
156 while (total_sg_needed) {
157 sg_per_table = (total_sg_needed > max_sg_per_table) ?
158 max_sg_per_table : total_sg_needed;
160 sg = kzalloc(sg_per_table *
sizeof(
struct scatterlist),
163 pr_err(
"Unable to allocate scatterlist array"
164 " for struct rd_dev\n");
176 for (j = 0; j < sg_per_table; j++) {
179 pr_err(
"Unable to allocate scatterlist"
180 " pages for struct rd_dev_sg_table\n");
183 sg_assign_page(&sg[j], pg);
187 page_offset += sg_per_table;
188 total_sg_needed -= sg_per_table;
191 pr_debug(
"CORE_RD[%u] - Built Ramdisk Device ID: %u space of"
192 " %u pages in %u tables\n", rd_dev->
rd_host->rd_host_id,
199 static void *rd_allocate_virtdevice(
struct se_hba *hba,
const char *
name)
201 struct rd_dev *rd_dev;
202 struct rd_host *rd_host = hba->
hba_ptr;
204 rd_dev = kzalloc(
sizeof(
struct rd_dev),
GFP_KERNEL);
206 pr_err(
"Unable to allocate memory for struct rd_dev\n");
220 struct rd_dev *rd_dev =
p;
221 struct rd_host *rd_host = hba->
hba_ptr;
222 int dev_flags = 0,
ret;
223 char prod[16],
rev[4];
227 ret = rd_build_device_space(rd_dev);
235 dev_limits.limits.max_hw_sectors =
UINT_MAX;
236 dev_limits.limits.max_sectors =
UINT_MAX;
241 &rd_mcp_template, se_dev, dev_flags, rd_dev,
242 &dev_limits, prod, rev);
248 pr_debug(
"CORE_RD[%u] - Added TCM MEMCPY Ramdisk Device ID: %u of"
249 " %u pages in %u tables, %lu total bytes\n",
257 rd_release_device_space(rd_dev);
261 static void rd_free_device(
void *p)
263 struct rd_dev *rd_dev =
p;
265 rd_release_device_space(rd_dev);
281 pr_err(
"Unable to locate struct rd_dev_sg_table for page: %u\n",
287 static int rd_execute_rw(
struct se_cmd *
cmd)
293 struct rd_dev *dev = se_dev->
dev_ptr;
308 table = rd_get_sg_table(dev, rd_page);
314 pr_debug(
"RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n",
317 cmd->
t_task_lba, rd_size, rd_page, rd_offset);
328 len =
min((
u32)
m.length, src_len);
331 rd_addr = sg_virt(rd_sg) + rd_offset;
352 if (rd_page <= table->page_end_offset) {
357 table = rd_get_sg_table(dev, rd_page);
381 static ssize_t rd_set_configfs_dev_params(
398 while ((ptr =
strsep(&opts,
",\n")) !=
NULL) {
407 pr_debug(
"RAMDISK: Referencing Page"
417 return (!ret) ? count :
ret;
425 pr_debug(
"Missing rd_pages= parameter\n");
432 static ssize_t rd_show_configfs_dev_params(
440 bl +=
sprintf(b + bl,
" PAGES/PAGE_SIZE: %u*%lu"
458 struct rd_dev *rd_dev = dev->
dev_ptr;
460 dev->
se_sub_dev->se_dev_attrib.block_size) - 1;
465 static struct spc_ops rd_spc_ops = {
466 .execute_rw = rd_execute_rw,
469 static int rd_parse_cdb(
struct se_cmd *cmd)
477 .attach_hba = rd_attach_hba,
478 .detach_hba = rd_detach_hba,
479 .allocate_virtdevice = rd_allocate_virtdevice,
480 .create_virtdevice = rd_create_virtdevice,
481 .free_device = rd_free_device,
482 .parse_cdb = rd_parse_cdb,
483 .check_configfs_dev_params = rd_check_configfs_dev_params,
484 .set_configfs_dev_params = rd_set_configfs_dev_params,
485 .show_configfs_dev_params = rd_show_configfs_dev_params,
486 .get_device_rev = rd_get_device_rev,
487 .get_device_type = rd_get_device_type,
488 .get_blocks = rd_get_blocks,