1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*******************************************************************************
3 * Filename: target_core_rd.c
4 *
5 * This file contains the Storage Engine <-> Ramdisk transport
6 * specific functions.
7 *
8 * (c) Copyright 2003-2013 Datera, Inc.
9 *
10 * Nicholas A. Bellinger <nab@kernel.org>
11 *
12 ******************************************************************************/
13
14 #include <linux/string.h>
15 #include <linux/parser.h>
16 #include <linux/highmem.h>
17 #include <linux/timer.h>
18 #include <linux/scatterlist.h>
19 #include <linux/slab.h>
20 #include <linux/spinlock.h>
21 #include <scsi/scsi_proto.h>
22
23 #include <target/target_core_base.h>
24 #include <target/target_core_backend.h>
25
26 #include "target_core_rd.h"
27
RD_DEV(struct se_device * dev)28 static inline struct rd_dev *RD_DEV(struct se_device *dev)
29 {
30 return container_of(dev, struct rd_dev, dev);
31 }
32
rd_attach_hba(struct se_hba * hba,u32 host_id)33 static int rd_attach_hba(struct se_hba *hba, u32 host_id)
34 {
35 struct rd_host *rd_host;
36
37 rd_host = kzalloc_obj(*rd_host);
38 if (!rd_host)
39 return -ENOMEM;
40
41 rd_host->rd_host_id = host_id;
42
43 hba->hba_ptr = rd_host;
44
45 pr_debug("CORE_HBA[%d] - TCM Ramdisk HBA Driver %s on"
46 " Generic Target Core Stack %s\n", hba->hba_id,
47 RD_HBA_VERSION, TARGET_CORE_VERSION);
48
49 return 0;
50 }
51
rd_detach_hba(struct se_hba * hba)52 static void rd_detach_hba(struct se_hba *hba)
53 {
54 struct rd_host *rd_host = hba->hba_ptr;
55
56 pr_debug("CORE_HBA[%d] - Detached Ramdisk HBA: %u from"
57 " Generic Target Core\n", hba->hba_id, rd_host->rd_host_id);
58
59 kfree(rd_host);
60 hba->hba_ptr = NULL;
61 }
62
rd_release_sgl_table(struct rd_dev * rd_dev,struct rd_dev_sg_table * sg_table,u32 sg_table_count)63 static u32 rd_release_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table *sg_table,
64 u32 sg_table_count)
65 {
66 struct page *pg;
67 struct scatterlist *sg;
68 u32 i, j, page_count = 0, sg_per_table;
69
70 for (i = 0; i < sg_table_count; i++) {
71 sg = sg_table[i].sg_table;
72 sg_per_table = sg_table[i].rd_sg_count;
73
74 for (j = 0; j < sg_per_table; j++) {
75 pg = sg_page(&sg[j]);
76 if (pg) {
77 __free_page(pg);
78 page_count++;
79 }
80 }
81 kfree(sg);
82 }
83
84 kfree(sg_table);
85 return page_count;
86 }
87
rd_release_device_space(struct rd_dev * rd_dev)88 static void rd_release_device_space(struct rd_dev *rd_dev)
89 {
90 u32 page_count;
91
92 if (!rd_dev->sg_table_array || !rd_dev->sg_table_count)
93 return;
94
95 page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_table_array,
96 rd_dev->sg_table_count);
97
98 pr_debug("CORE_RD[%u] - Released device space for Ramdisk"
99 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
100 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count,
101 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE);
102
103 rd_dev->sg_table_array = NULL;
104 rd_dev->sg_table_count = 0;
105 }
106
107
108 /* rd_build_device_space():
109 *
110 *
111 */
rd_allocate_sgl_table(struct rd_dev * rd_dev,struct rd_dev_sg_table * sg_table,u32 total_sg_needed,unsigned char init_payload)112 static int rd_allocate_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table *sg_table,
113 u32 total_sg_needed, unsigned char init_payload)
114 {
115 u32 i = 0, j, page_offset = 0, sg_per_table;
116 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
117 sizeof(struct scatterlist));
118 struct page *pg;
119 struct scatterlist *sg;
120 unsigned char *p;
121
122 while (total_sg_needed) {
123 unsigned int chain_entry = 0;
124
125 sg_per_table = (total_sg_needed > max_sg_per_table) ?
126 max_sg_per_table : total_sg_needed;
127
128 /*
129 * Reserve extra element for chain entry
130 */
131 if (sg_per_table < total_sg_needed)
132 chain_entry = 1;
133
134 sg = kmalloc_objs(*sg, sg_per_table + chain_entry);
135 if (!sg)
136 return -ENOMEM;
137
138 sg_init_table(sg, sg_per_table + chain_entry);
139
140 if (i > 0) {
141 sg_chain(sg_table[i - 1].sg_table,
142 max_sg_per_table + 1, sg);
143 }
144
145 sg_table[i].sg_table = sg;
146 sg_table[i].rd_sg_count = sg_per_table;
147 sg_table[i].page_start_offset = page_offset;
148 sg_table[i++].page_end_offset = (page_offset + sg_per_table)
149 - 1;
150
151 for (j = 0; j < sg_per_table; j++) {
152 pg = alloc_pages(GFP_KERNEL, 0);
153 if (!pg) {
154 pr_err("Unable to allocate scatterlist"
155 " pages for struct rd_dev_sg_table\n");
156 return -ENOMEM;
157 }
158 sg_assign_page(&sg[j], pg);
159 sg[j].length = PAGE_SIZE;
160
161 p = kmap(pg);
162 memset(p, init_payload, PAGE_SIZE);
163 kunmap(pg);
164 }
165
166 page_offset += sg_per_table;
167 total_sg_needed -= sg_per_table;
168 }
169
170 return 0;
171 }
172
rd_build_device_space(struct rd_dev * rd_dev)173 static int rd_build_device_space(struct rd_dev *rd_dev)
174 {
175 struct rd_dev_sg_table *sg_table;
176 u32 sg_tables, total_sg_needed;
177 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
178 sizeof(struct scatterlist));
179 int rc;
180
181 if (rd_dev->rd_page_count <= 0) {
182 pr_err("Illegal page count: %u for Ramdisk device\n",
183 rd_dev->rd_page_count);
184 return -EINVAL;
185 }
186
187 /* Don't need backing pages for NULLIO */
188 if (rd_dev->rd_flags & RDF_NULLIO)
189 return 0;
190
191 total_sg_needed = rd_dev->rd_page_count;
192
193 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
194 sg_table = kzalloc_objs(*sg_table, sg_tables);
195 if (!sg_table)
196 return -ENOMEM;
197
198 rd_dev->sg_table_array = sg_table;
199 rd_dev->sg_table_count = sg_tables;
200
201 rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0x00);
202 if (rc)
203 return rc;
204
205 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u space of"
206 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id,
207 rd_dev->rd_dev_id, rd_dev->rd_page_count,
208 rd_dev->sg_table_count);
209
210 return 0;
211 }
212
rd_release_prot_space(struct rd_dev * rd_dev)213 static void rd_release_prot_space(struct rd_dev *rd_dev)
214 {
215 u32 page_count;
216
217 if (!rd_dev->sg_prot_array || !rd_dev->sg_prot_count)
218 return;
219
220 page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_prot_array,
221 rd_dev->sg_prot_count);
222
223 pr_debug("CORE_RD[%u] - Released protection space for Ramdisk"
224 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
225 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count,
226 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE);
227
228 rd_dev->sg_prot_array = NULL;
229 rd_dev->sg_prot_count = 0;
230 }
231
rd_build_prot_space(struct rd_dev * rd_dev,int prot_length,int block_size)232 static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length, int block_size)
233 {
234 struct rd_dev_sg_table *sg_table;
235 u32 total_sg_needed, sg_tables;
236 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
237 sizeof(struct scatterlist));
238 int rc;
239
240 if (rd_dev->rd_flags & RDF_NULLIO)
241 return 0;
242 /*
243 * prot_length=8byte dif data
244 * tot sg needed = rd_page_count * (PGSZ/block_size) *
245 * (prot_length/block_size) + pad
246 * PGSZ canceled each other.
247 */
248 total_sg_needed = (rd_dev->rd_page_count * prot_length / block_size) + 1;
249
250 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
251 sg_table = kzalloc_objs(*sg_table, sg_tables);
252 if (!sg_table)
253 return -ENOMEM;
254
255 rd_dev->sg_prot_array = sg_table;
256 rd_dev->sg_prot_count = sg_tables;
257
258 rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0xff);
259 if (rc)
260 return rc;
261
262 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u prot space of"
263 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id,
264 rd_dev->rd_dev_id, total_sg_needed, rd_dev->sg_prot_count);
265
266 return 0;
267 }
268
rd_alloc_device(struct se_hba * hba,const char * name)269 static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name)
270 {
271 struct rd_dev *rd_dev;
272 struct rd_host *rd_host = hba->hba_ptr;
273
274 rd_dev = kzalloc_obj(*rd_dev);
275 if (!rd_dev)
276 return NULL;
277
278 rd_dev->rd_host = rd_host;
279
280 return &rd_dev->dev;
281 }
282
rd_configure_device(struct se_device * dev)283 static int rd_configure_device(struct se_device *dev)
284 {
285 struct rd_dev *rd_dev = RD_DEV(dev);
286 struct rd_host *rd_host = dev->se_hba->hba_ptr;
287 int ret;
288
289 if (!(rd_dev->rd_flags & RDF_HAS_PAGE_COUNT)) {
290 pr_debug("Missing rd_pages= parameter\n");
291 return -EINVAL;
292 }
293
294 ret = rd_build_device_space(rd_dev);
295 if (ret < 0)
296 goto fail;
297
298 dev->dev_attrib.hw_block_size = RD_BLOCKSIZE;
299 dev->dev_attrib.hw_max_sectors = UINT_MAX;
300 dev->dev_attrib.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH;
301 dev->dev_attrib.is_nonrot = 1;
302
303 rd_dev->rd_dev_id = rd_host->rd_host_dev_id_count++;
304
305 pr_debug("CORE_RD[%u] - Added TCM MEMCPY Ramdisk Device ID: %u of"
306 " %u pages in %u tables, %lu total bytes\n",
307 rd_host->rd_host_id, rd_dev->rd_dev_id, rd_dev->rd_page_count,
308 rd_dev->sg_table_count,
309 (unsigned long)(rd_dev->rd_page_count * PAGE_SIZE));
310
311 return 0;
312
313 fail:
314 rd_release_device_space(rd_dev);
315 return ret;
316 }
317
rd_dev_call_rcu(struct rcu_head * p)318 static void rd_dev_call_rcu(struct rcu_head *p)
319 {
320 struct se_device *dev = container_of(p, struct se_device, rcu_head);
321 struct rd_dev *rd_dev = RD_DEV(dev);
322
323 kfree(rd_dev);
324 }
325
rd_free_device(struct se_device * dev)326 static void rd_free_device(struct se_device *dev)
327 {
328 call_rcu(&dev->rcu_head, rd_dev_call_rcu);
329 }
330
rd_destroy_device(struct se_device * dev)331 static void rd_destroy_device(struct se_device *dev)
332 {
333 struct rd_dev *rd_dev = RD_DEV(dev);
334
335 rd_release_device_space(rd_dev);
336 }
337
rd_get_sg_table(struct rd_dev * rd_dev,u32 page)338 static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
339 {
340 struct rd_dev_sg_table *sg_table;
341 u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
342 sizeof(struct scatterlist));
343
344 i = page / sg_per_table;
345 if (i < rd_dev->sg_table_count) {
346 sg_table = &rd_dev->sg_table_array[i];
347 if ((sg_table->page_start_offset <= page) &&
348 (sg_table->page_end_offset >= page))
349 return sg_table;
350 }
351
352 pr_err("Unable to locate struct rd_dev_sg_table for page: %u\n",
353 page);
354
355 return NULL;
356 }
357
rd_get_prot_table(struct rd_dev * rd_dev,u32 page)358 static struct rd_dev_sg_table *rd_get_prot_table(struct rd_dev *rd_dev, u32 page)
359 {
360 struct rd_dev_sg_table *sg_table;
361 u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
362 sizeof(struct scatterlist));
363
364 i = page / sg_per_table;
365 if (i < rd_dev->sg_prot_count) {
366 sg_table = &rd_dev->sg_prot_array[i];
367 if ((sg_table->page_start_offset <= page) &&
368 (sg_table->page_end_offset >= page))
369 return sg_table;
370 }
371
372 pr_err("Unable to locate struct prot rd_dev_sg_table for page: %u\n",
373 page);
374
375 return NULL;
376 }
377
rd_do_prot_rw(struct se_cmd * cmd,bool is_read)378 static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read)
379 {
380 struct se_device *se_dev = cmd->se_dev;
381 struct rd_dev *dev = RD_DEV(se_dev);
382 struct rd_dev_sg_table *prot_table;
383 struct scatterlist *prot_sg;
384 u32 sectors = cmd->data_length / se_dev->dev_attrib.block_size;
385 u32 prot_offset, prot_page;
386 u32 prot_npages __maybe_unused;
387 u64 tmp;
388 sense_reason_t rc = 0;
389
390 tmp = cmd->t_task_lba * se_dev->prot_length;
391 prot_offset = do_div(tmp, PAGE_SIZE);
392 prot_page = tmp;
393
394 prot_table = rd_get_prot_table(dev, prot_page);
395 if (!prot_table)
396 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
397
398 prot_sg = &prot_table->sg_table[prot_page -
399 prot_table->page_start_offset];
400
401 if (se_dev->dev_attrib.pi_prot_verify) {
402 if (is_read)
403 rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
404 prot_sg, prot_offset);
405 else
406 rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0,
407 cmd->t_prot_sg, 0);
408 }
409 if (!rc)
410 sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
411
412 return rc;
413 }
414
415 static sense_reason_t
rd_execute_rw(struct se_cmd * cmd,struct scatterlist * sgl,u32 sgl_nents,enum dma_data_direction data_direction)416 rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
417 enum dma_data_direction data_direction)
418 {
419 struct se_device *se_dev = cmd->se_dev;
420 struct rd_dev *dev = RD_DEV(se_dev);
421 struct rd_dev_sg_table *table;
422 struct scatterlist *rd_sg;
423 struct sg_mapping_iter m;
424 u32 rd_offset;
425 u32 rd_size;
426 u32 rd_page;
427 u32 src_len;
428 u64 tmp;
429 sense_reason_t rc;
430
431 if (dev->rd_flags & RDF_NULLIO) {
432 target_complete_cmd(cmd, SAM_STAT_GOOD);
433 return 0;
434 }
435
436 tmp = cmd->t_task_lba * se_dev->dev_attrib.block_size;
437 rd_offset = do_div(tmp, PAGE_SIZE);
438 rd_page = tmp;
439 rd_size = cmd->data_length;
440
441 table = rd_get_sg_table(dev, rd_page);
442 if (!table)
443 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
444
445 rd_sg = &table->sg_table[rd_page - table->page_start_offset];
446
447 pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n",
448 dev->rd_dev_id,
449 data_direction == DMA_FROM_DEVICE ? "Read" : "Write",
450 cmd->t_task_lba, rd_size, rd_page, rd_offset);
451
452 if (cmd->prot_type && se_dev->dev_attrib.pi_prot_type &&
453 data_direction == DMA_TO_DEVICE) {
454 rc = rd_do_prot_rw(cmd, false);
455 if (rc)
456 return rc;
457 }
458
459 src_len = PAGE_SIZE - rd_offset;
460 sg_miter_start(&m, sgl, sgl_nents,
461 data_direction == DMA_FROM_DEVICE ?
462 SG_MITER_TO_SG : SG_MITER_FROM_SG);
463 while (rd_size) {
464 u32 len;
465 void *rd_addr;
466
467 sg_miter_next(&m);
468 if (!(u32)m.length) {
469 pr_debug("RD[%u]: invalid sgl %p len %zu\n",
470 dev->rd_dev_id, m.addr, m.length);
471 sg_miter_stop(&m);
472 return TCM_INCORRECT_AMOUNT_OF_DATA;
473 }
474 len = min((u32)m.length, src_len);
475 if (len > rd_size) {
476 pr_debug("RD[%u]: size underrun page %d offset %d "
477 "size %d\n", dev->rd_dev_id,
478 rd_page, rd_offset, rd_size);
479 len = rd_size;
480 }
481 m.consumed = len;
482
483 rd_addr = sg_virt(rd_sg) + rd_offset;
484
485 if (data_direction == DMA_FROM_DEVICE)
486 memcpy(m.addr, rd_addr, len);
487 else
488 memcpy(rd_addr, m.addr, len);
489
490 rd_size -= len;
491 if (!rd_size)
492 continue;
493
494 src_len -= len;
495 if (src_len) {
496 rd_offset += len;
497 continue;
498 }
499
500 /* rd page completed, next one please */
501 rd_page++;
502 rd_offset = 0;
503 src_len = PAGE_SIZE;
504 if (rd_page <= table->page_end_offset) {
505 rd_sg++;
506 continue;
507 }
508
509 table = rd_get_sg_table(dev, rd_page);
510 if (!table) {
511 sg_miter_stop(&m);
512 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
513 }
514
515 /* since we increment, the first sg entry is correct */
516 rd_sg = table->sg_table;
517 }
518 sg_miter_stop(&m);
519
520 if (cmd->prot_type && se_dev->dev_attrib.pi_prot_type &&
521 data_direction == DMA_FROM_DEVICE) {
522 rc = rd_do_prot_rw(cmd, true);
523 if (rc)
524 return rc;
525 }
526
527 target_complete_cmd(cmd, SAM_STAT_GOOD);
528 return 0;
529 }
530
531 enum {
532 Opt_rd_pages, Opt_rd_nullio, Opt_rd_dummy, Opt_err
533 };
534
535 static match_table_t tokens = {
536 {Opt_rd_pages, "rd_pages=%d"},
537 {Opt_rd_nullio, "rd_nullio=%d"},
538 {Opt_rd_dummy, "rd_dummy=%d"},
539 {Opt_err, NULL}
540 };
541
rd_set_configfs_dev_params(struct se_device * dev,const char * page,ssize_t count)542 static ssize_t rd_set_configfs_dev_params(struct se_device *dev,
543 const char *page, ssize_t count)
544 {
545 struct rd_dev *rd_dev = RD_DEV(dev);
546 char *orig, *ptr, *opts;
547 substring_t args[MAX_OPT_ARGS];
548 int arg, token;
549
550 opts = kstrdup(page, GFP_KERNEL);
551 if (!opts)
552 return -ENOMEM;
553
554 orig = opts;
555
556 while ((ptr = strsep(&opts, ",\n")) != NULL) {
557 if (!*ptr)
558 continue;
559
560 token = match_token(ptr, tokens, args);
561 switch (token) {
562 case Opt_rd_pages:
563 match_int(args, &arg);
564 rd_dev->rd_page_count = arg;
565 pr_debug("RAMDISK: Referencing Page"
566 " Count: %u\n", rd_dev->rd_page_count);
567 rd_dev->rd_flags |= RDF_HAS_PAGE_COUNT;
568 break;
569 case Opt_rd_nullio:
570 match_int(args, &arg);
571 if (arg != 1)
572 break;
573
574 pr_debug("RAMDISK: Setting NULLIO flag: %d\n", arg);
575 rd_dev->rd_flags |= RDF_NULLIO;
576 break;
577 case Opt_rd_dummy:
578 match_int(args, &arg);
579 if (arg != 1)
580 break;
581
582 pr_debug("RAMDISK: Setting DUMMY flag: %d\n", arg);
583 rd_dev->rd_flags |= RDF_DUMMY;
584 break;
585 default:
586 break;
587 }
588 }
589
590 kfree(orig);
591 return count;
592 }
593
rd_show_configfs_dev_params(struct se_device * dev,char * b)594 static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b)
595 {
596 struct rd_dev *rd_dev = RD_DEV(dev);
597
598 ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n",
599 rd_dev->rd_dev_id);
600 bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu"
601 " SG_table_count: %u nullio: %d dummy: %d\n",
602 rd_dev->rd_page_count,
603 PAGE_SIZE, rd_dev->sg_table_count,
604 !!(rd_dev->rd_flags & RDF_NULLIO),
605 !!(rd_dev->rd_flags & RDF_DUMMY));
606 return bl;
607 }
608
rd_get_device_type(struct se_device * dev)609 static u32 rd_get_device_type(struct se_device *dev)
610 {
611 if (RD_DEV(dev)->rd_flags & RDF_DUMMY)
612 return 0x3f; /* Unknown device type, not connected */
613 else
614 return sbc_get_device_type(dev);
615 }
616
rd_get_blocks(struct se_device * dev)617 static sector_t rd_get_blocks(struct se_device *dev)
618 {
619 struct rd_dev *rd_dev = RD_DEV(dev);
620
621 unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) /
622 dev->dev_attrib.block_size) - 1;
623
624 return blocks_long;
625 }
626
rd_init_prot(struct se_device * dev)627 static int rd_init_prot(struct se_device *dev)
628 {
629 struct rd_dev *rd_dev = RD_DEV(dev);
630
631 if (!dev->dev_attrib.pi_prot_type)
632 return 0;
633
634 return rd_build_prot_space(rd_dev, dev->prot_length,
635 dev->dev_attrib.block_size);
636 }
637
rd_free_prot(struct se_device * dev)638 static void rd_free_prot(struct se_device *dev)
639 {
640 struct rd_dev *rd_dev = RD_DEV(dev);
641
642 rd_release_prot_space(rd_dev);
643 }
644
645 static struct exec_cmd_ops rd_exec_cmd_ops = {
646 .execute_rw = rd_execute_rw,
647 };
648
649 static sense_reason_t
rd_parse_cdb(struct se_cmd * cmd)650 rd_parse_cdb(struct se_cmd *cmd)
651 {
652 return sbc_parse_cdb(cmd, &rd_exec_cmd_ops);
653 }
654
655 static const struct target_backend_ops rd_mcp_ops = {
656 .name = "rd_mcp",
657 .inquiry_prod = "RAMDISK-MCP",
658 .inquiry_rev = RD_MCP_VERSION,
659 .attach_hba = rd_attach_hba,
660 .detach_hba = rd_detach_hba,
661 .alloc_device = rd_alloc_device,
662 .configure_device = rd_configure_device,
663 .destroy_device = rd_destroy_device,
664 .free_device = rd_free_device,
665 .parse_cdb = rd_parse_cdb,
666 .set_configfs_dev_params = rd_set_configfs_dev_params,
667 .show_configfs_dev_params = rd_show_configfs_dev_params,
668 .get_device_type = rd_get_device_type,
669 .get_blocks = rd_get_blocks,
670 .init_prot = rd_init_prot,
671 .free_prot = rd_free_prot,
672 .tb_dev_attrib_attrs = sbc_attrib_attrs,
673 };
674
rd_module_init(void)675 int __init rd_module_init(void)
676 {
677 return transport_backend_register(&rd_mcp_ops);
678 }
679
rd_module_exit(void)680 void rd_module_exit(void)
681 {
682 target_backend_unregister(&rd_mcp_ops);
683 }
684