This patch is borrow code from commit 0f5e2ec46dd64579c0770f3822764f94db4fa465 Author: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> Date: Sat Jan 18 09:32:56 2014 +0000 target/file: Add DIF protection init/format support This patch adds support for DIF protection init/format support into the FILEIO backend. It involves using a seperate $FILE.protection for storing PI that is opened via fd_init_prot() using the common pi_prot_type attribute. The actual formatting of the protection is done via fd_format_prot() using the common pi_prot_format attribute, that will populate the initial PI data based upon the currently configured pi_prot_type. Based on original FILEIO code from Sagi. v1 changes: - Fix sparse warnings in fd_init_format_buf (Fengguang) Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Hannes Reinecke <hare@xxxxxxx> Cc: Sagi Grimberg <sagig@xxxxxxxxxxxx> Cc: Or Gerlitz <ogerlitz@xxxxxxxxxxxx> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> --- drivers/target/target_core_rd.c | 64 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 66a5aba..01dda0b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -603,7 +603,7 @@ static int rd_init_prot(struct se_device *dev) { struct rd_dev *rd_dev = RD_DEV(dev); - if (!dev->dev_attrib.pi_prot_type) + if (!dev->dev_attrib.pi_prot_type) return 0; return rd_build_prot_space(rd_dev, dev->prot_length); @@ -616,6 +616,67 @@ static void rd_free_prot(struct se_device *dev) rd_release_prot_space(rd_dev); } +static void rd_init_format_buf(struct se_device *dev, unsigned char *buf, + u32 unit_size, u32 *ref_tag, u16 app_tag, + bool inc_reftag) +{ + unsigned char *p = buf; + int i; + + for (i = 0; i < unit_size; i += dev->prot_length) { + *((u16 *)&p[0]) = 0xffff; + *((__be16 *)&p[2]) = cpu_to_be16(app_tag); + *((__be32 *)&p[4]) = cpu_to_be32(*ref_tag); + + if (inc_reftag) + (*ref_tag)++; + + p += dev->prot_length; + } +} + +static int rd_format_prot(struct se_device *dev) +{ + struct rd_dev *rd_dev = RD_DEV(dev); + u32 ref_tag = 0; + int i,j; + bool inc_reftag = false; + struct rd_dev_sg_table *pt; + struct scatterlist *sg; + void *paddr; + + if (!dev->dev_attrib.pi_prot_type) { + pr_err("Unable to format_prot while pi_prot_type == 0\n"); + return -ENODEV; + } + + switch (dev->dev_attrib.pi_prot_type) { + case TARGET_DIF_TYPE3_PROT: + ref_tag = 0xffffffff; + break; + case TARGET_DIF_TYPE2_PROT: + case TARGET_DIF_TYPE1_PROT: + inc_reftag = true; + break; + default: + break; + } + + for (i=0; i < rd_dev->sg_prot_count; i++) { + pt= &rd_dev->sg_prot_array[i]; + for_each_sg(pt->sg_table, sg, pt->rd_sg_count, j) { + paddr = kmap(sg_page(sg)) + sg->offset; + + rd_init_format_buf(dev, paddr, sg->length, &ref_tag, + 0xffff, inc_reftag); + kunmap(paddr); + } + } + + return 0; +} + + static struct sbc_ops rd_sbc_ops = { .execute_rw = rd_execute_rw, }; @@ -642,6 +703,7 @@ static struct se_subsystem_api rd_mcp_template = { .get_device_type = sbc_get_device_type, .get_blocks = rd_get_blocks, .init_prot = rd_init_prot, + .format_prot = rd_format_prot, .free_prot = rd_free_prot, }; -- 1.8.4.GIT -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html