aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_rd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/target_core_rd.c')
-rw-r--r--drivers/target/target_core_rd.c252
1 files changed, 207 insertions, 45 deletions
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 4ffe5f2ec0e9..66a5aba5a0d9 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -78,23 +78,14 @@ static void rd_detach_hba(struct se_hba *hba)
78 hba->hba_ptr = NULL; 78 hba->hba_ptr = NULL;
79} 79}
80 80
81/* rd_release_device_space(): 81static u32 rd_release_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table *sg_table,
82 * 82 u32 sg_table_count)
83 *
84 */
85static void rd_release_device_space(struct rd_dev *rd_dev)
86{ 83{
87 u32 i, j, page_count = 0, sg_per_table;
88 struct rd_dev_sg_table *sg_table;
89 struct page *pg; 84 struct page *pg;
90 struct scatterlist *sg; 85 struct scatterlist *sg;
86 u32 i, j, page_count = 0, sg_per_table;
91 87
92 if (!rd_dev->sg_table_array || !rd_dev->sg_table_count) 88 for (i = 0; i < sg_table_count; i++) {
93 return;
94
95 sg_table = rd_dev->sg_table_array;
96
97 for (i = 0; i < rd_dev->sg_table_count; i++) {
98 sg = sg_table[i].sg_table; 89 sg = sg_table[i].sg_table;
99 sg_per_table = sg_table[i].rd_sg_count; 90 sg_per_table = sg_table[i].rd_sg_count;
100 91
@@ -105,16 +96,28 @@ static void rd_release_device_space(struct rd_dev *rd_dev)
105 page_count++; 96 page_count++;
106 } 97 }
107 } 98 }
108
109 kfree(sg); 99 kfree(sg);
110 } 100 }
111 101
102 kfree(sg_table);
103 return page_count;
104}
105
106static void rd_release_device_space(struct rd_dev *rd_dev)
107{
108 u32 page_count;
109
110 if (!rd_dev->sg_table_array || !rd_dev->sg_table_count)
111 return;
112
113 page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_table_array,
114 rd_dev->sg_table_count);
115
112 pr_debug("CORE_RD[%u] - Released device space for Ramdisk" 116 pr_debug("CORE_RD[%u] - Released device space for Ramdisk"
113 " Device ID: %u, pages %u in %u tables total bytes %lu\n", 117 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
114 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count, 118 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count,
115 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE); 119 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE);
116 120
117 kfree(sg_table);
118 rd_dev->sg_table_array = NULL; 121 rd_dev->sg_table_array = NULL;
119 rd_dev->sg_table_count = 0; 122 rd_dev->sg_table_count = 0;
120} 123}
@@ -124,38 +127,15 @@ static void rd_release_device_space(struct rd_dev *rd_dev)
124 * 127 *
125 * 128 *
126 */ 129 */
127static int rd_build_device_space(struct rd_dev *rd_dev) 130static int rd_allocate_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table *sg_table,
131 u32 total_sg_needed, unsigned char init_payload)
128{ 132{
129 u32 i = 0, j, page_offset = 0, sg_per_table, sg_tables, total_sg_needed; 133 u32 i = 0, j, page_offset = 0, sg_per_table;
130 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE / 134 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
131 sizeof(struct scatterlist)); 135 sizeof(struct scatterlist));
132 struct rd_dev_sg_table *sg_table;
133 struct page *pg; 136 struct page *pg;
134 struct scatterlist *sg; 137 struct scatterlist *sg;
135 138 unsigned char *p;
136 if (rd_dev->rd_page_count <= 0) {
137 pr_err("Illegal page count: %u for Ramdisk device\n",
138 rd_dev->rd_page_count);
139 return -EINVAL;
140 }
141
142 /* Don't need backing pages for NULLIO */
143 if (rd_dev->rd_flags & RDF_NULLIO)
144 return 0;
145
146 total_sg_needed = rd_dev->rd_page_count;
147
148 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
149
150 sg_table = kzalloc(sg_tables * sizeof(struct rd_dev_sg_table), GFP_KERNEL);
151 if (!sg_table) {
152 pr_err("Unable to allocate memory for Ramdisk"
153 " scatterlist tables\n");
154 return -ENOMEM;
155 }
156
157 rd_dev->sg_table_array = sg_table;
158 rd_dev->sg_table_count = sg_tables;
159 139
160 while (total_sg_needed) { 140 while (total_sg_needed) {
161 sg_per_table = (total_sg_needed > max_sg_per_table) ? 141 sg_per_table = (total_sg_needed > max_sg_per_table) ?
@@ -186,16 +166,114 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
186 } 166 }
187 sg_assign_page(&sg[j], pg); 167 sg_assign_page(&sg[j], pg);
188 sg[j].length = PAGE_SIZE; 168 sg[j].length = PAGE_SIZE;
169
170 p = kmap(pg);
171 memset(p, init_payload, PAGE_SIZE);
172 kunmap(pg);
189 } 173 }
190 174
191 page_offset += sg_per_table; 175 page_offset += sg_per_table;
192 total_sg_needed -= sg_per_table; 176 total_sg_needed -= sg_per_table;
193 } 177 }
194 178
179 return 0;
180}
181
182static int rd_build_device_space(struct rd_dev *rd_dev)
183{
184 struct rd_dev_sg_table *sg_table;
185 u32 sg_tables, total_sg_needed;
186 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
187 sizeof(struct scatterlist));
188 int rc;
189
190 if (rd_dev->rd_page_count <= 0) {
191 pr_err("Illegal page count: %u for Ramdisk device\n",
192 rd_dev->rd_page_count);
193 return -EINVAL;
194 }
195
196 /* Don't need backing pages for NULLIO */
197 if (rd_dev->rd_flags & RDF_NULLIO)
198 return 0;
199
200 total_sg_needed = rd_dev->rd_page_count;
201
202 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
203
204 sg_table = kzalloc(sg_tables * sizeof(struct rd_dev_sg_table), GFP_KERNEL);
205 if (!sg_table) {
206 pr_err("Unable to allocate memory for Ramdisk"
207 " scatterlist tables\n");
208 return -ENOMEM;
209 }
210
211 rd_dev->sg_table_array = sg_table;
212 rd_dev->sg_table_count = sg_tables;
213
214 rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0x00);
215 if (rc)
216 return rc;
217
195 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u space of" 218 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u space of"
196 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id, 219 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id,
197 rd_dev->rd_dev_id, rd_dev->rd_page_count, 220 rd_dev->rd_dev_id, rd_dev->rd_page_count,
198 rd_dev->sg_table_count); 221 rd_dev->sg_table_count);
222
223 return 0;
224}
225
226static void rd_release_prot_space(struct rd_dev *rd_dev)
227{
228 u32 page_count;
229
230 if (!rd_dev->sg_prot_array || !rd_dev->sg_prot_count)
231 return;
232
233 page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_prot_array,
234 rd_dev->sg_prot_count);
235
236 pr_debug("CORE_RD[%u] - Released protection space for Ramdisk"
237 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
238 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count,
239 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE);
240
241 rd_dev->sg_prot_array = NULL;
242 rd_dev->sg_prot_count = 0;
243}
244
245static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length)
246{
247 struct rd_dev_sg_table *sg_table;
248 u32 total_sg_needed, sg_tables;
249 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
250 sizeof(struct scatterlist));
251 int rc;
252
253 if (rd_dev->rd_flags & RDF_NULLIO)
254 return 0;
255
256 total_sg_needed = rd_dev->rd_page_count / prot_length;
257
258 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
259
260 sg_table = kzalloc(sg_tables * sizeof(struct rd_dev_sg_table), GFP_KERNEL);
261 if (!sg_table) {
262 pr_err("Unable to allocate memory for Ramdisk protection"
263 " scatterlist tables\n");
264 return -ENOMEM;
265 }
266
267 rd_dev->sg_prot_array = sg_table;
268 rd_dev->sg_prot_count = sg_tables;
269
270 rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0xff);
271 if (rc)
272 return rc;
273
274 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u prot space of"
275 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id,
276 rd_dev->rd_dev_id, total_sg_needed, rd_dev->sg_prot_count);
199 277
200 return 0; 278 return 0;
201} 279}
@@ -278,6 +356,26 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
278 return NULL; 356 return NULL;
279} 357}
280 358
359static struct rd_dev_sg_table *rd_get_prot_table(struct rd_dev *rd_dev, u32 page)
360{
361 struct rd_dev_sg_table *sg_table;
362 u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
363 sizeof(struct scatterlist));
364
365 i = page / sg_per_table;
366 if (i < rd_dev->sg_prot_count) {
367 sg_table = &rd_dev->sg_prot_array[i];
368 if ((sg_table->page_start_offset <= page) &&
369 (sg_table->page_end_offset >= page))
370 return sg_table;
371 }
372
373 pr_err("Unable to locate struct prot rd_dev_sg_table for page: %u\n",
374 page);
375
376 return NULL;
377}
378
281static sense_reason_t 379static sense_reason_t
282rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, 380rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
283 enum dma_data_direction data_direction) 381 enum dma_data_direction data_direction)
@@ -292,6 +390,7 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
292 u32 rd_page; 390 u32 rd_page;
293 u32 src_len; 391 u32 src_len;
294 u64 tmp; 392 u64 tmp;
393 sense_reason_t rc;
295 394
296 if (dev->rd_flags & RDF_NULLIO) { 395 if (dev->rd_flags & RDF_NULLIO) {
297 target_complete_cmd(cmd, SAM_STAT_GOOD); 396 target_complete_cmd(cmd, SAM_STAT_GOOD);
@@ -314,6 +413,28 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
314 data_direction == DMA_FROM_DEVICE ? "Read" : "Write", 413 data_direction == DMA_FROM_DEVICE ? "Read" : "Write",
315 cmd->t_task_lba, rd_size, rd_page, rd_offset); 414 cmd->t_task_lba, rd_size, rd_page, rd_offset);
316 415
416 if (cmd->prot_type && data_direction == DMA_TO_DEVICE) {
417 struct rd_dev_sg_table *prot_table;
418 struct scatterlist *prot_sg;
419 u32 sectors = cmd->data_length / se_dev->dev_attrib.block_size;
420 u32 prot_offset, prot_page;
421
422 tmp = cmd->t_task_lba * se_dev->prot_length;
423 prot_offset = do_div(tmp, PAGE_SIZE);
424 prot_page = tmp;
425
426 prot_table = rd_get_prot_table(dev, prot_page);
427 if (!prot_table)
428 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
429
430 prot_sg = &prot_table->sg_table[prot_page - prot_table->page_start_offset];
431
432 rc = sbc_dif_verify_write(cmd, cmd->t_task_lba, sectors, 0,
433 prot_sg, prot_offset);
434 if (rc)
435 return rc;
436 }
437
317 src_len = PAGE_SIZE - rd_offset; 438 src_len = PAGE_SIZE - rd_offset;
318 sg_miter_start(&m, sgl, sgl_nents, 439 sg_miter_start(&m, sgl, sgl_nents,
319 data_direction == DMA_FROM_DEVICE ? 440 data_direction == DMA_FROM_DEVICE ?
@@ -375,6 +496,28 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
375 } 496 }
376 sg_miter_stop(&m); 497 sg_miter_stop(&m);
377 498
499 if (cmd->prot_type && data_direction == DMA_FROM_DEVICE) {
500 struct rd_dev_sg_table *prot_table;
501 struct scatterlist *prot_sg;
502 u32 sectors = cmd->data_length / se_dev->dev_attrib.block_size;
503 u32 prot_offset, prot_page;
504
505 tmp = cmd->t_task_lba * se_dev->prot_length;
506 prot_offset = do_div(tmp, PAGE_SIZE);
507 prot_page = tmp;
508
509 prot_table = rd_get_prot_table(dev, prot_page);
510 if (!prot_table)
511 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
512
513 prot_sg = &prot_table->sg_table[prot_page - prot_table->page_start_offset];
514
515 rc = sbc_dif_verify_read(cmd, cmd->t_task_lba, sectors, 0,
516 prot_sg, prot_offset);
517 if (rc)
518 return rc;
519 }
520
378 target_complete_cmd(cmd, SAM_STAT_GOOD); 521 target_complete_cmd(cmd, SAM_STAT_GOOD);
379 return 0; 522 return 0;
380} 523}
@@ -456,6 +599,23 @@ static sector_t rd_get_blocks(struct se_device *dev)
456 return blocks_long; 599 return blocks_long;
457} 600}
458 601
602static int rd_init_prot(struct se_device *dev)
603{
604 struct rd_dev *rd_dev = RD_DEV(dev);
605
606 if (!dev->dev_attrib.pi_prot_type)
607 return 0;
608
609 return rd_build_prot_space(rd_dev, dev->prot_length);
610}
611
612static void rd_free_prot(struct se_device *dev)
613{
614 struct rd_dev *rd_dev = RD_DEV(dev);
615
616 rd_release_prot_space(rd_dev);
617}
618
459static struct sbc_ops rd_sbc_ops = { 619static struct sbc_ops rd_sbc_ops = {
460 .execute_rw = rd_execute_rw, 620 .execute_rw = rd_execute_rw,
461}; 621};
@@ -481,6 +641,8 @@ static struct se_subsystem_api rd_mcp_template = {
481 .show_configfs_dev_params = rd_show_configfs_dev_params, 641 .show_configfs_dev_params = rd_show_configfs_dev_params,
482 .get_device_type = sbc_get_device_type, 642 .get_device_type = sbc_get_device_type,
483 .get_blocks = rd_get_blocks, 643 .get_blocks = rd_get_blocks,
644 .init_prot = rd_init_prot,
645 .free_prot = rd_free_prot,
484}; 646};
485 647
486int __init rd_module_init(void) 648int __init rd_module_init(void)