]> Pileus Git - ~andy/linux/blobdiff - drivers/target/target_core_spc.c
nfsd: fix lost nfserrno() call in nfsd_setattr()
[~andy/linux] / drivers / target / target_core_spc.c
index f9889fd829949820d369ba8c2db7e596110414a8..43c5ca9878bc5b6f3f1d675c04779b245ccc1a22 100644 (file)
@@ -100,6 +100,11 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
         */
        if (dev->dev_attrib.emulate_3pc)
                buf[5] |= 0x8;
+       /*
+        * Set Protection (PROTECT) bit when DIF has been enabled.
+        */
+       if (dev->dev_attrib.pi_prot_type)
+               buf[5] |= 0x1;
 
        buf[7] = 0x2; /* CmdQue=1 */
 
@@ -470,6 +475,15 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
        struct se_device *dev = cmd->se_dev;
 
        buf[3] = 0x3c;
+       /*
+        * Set GRD_CHK + REF_CHK for TYPE1 protection, or GRD_CHK
+        * only for TYPE3 protection.
+        */
+       if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE1_PROT)
+               buf[4] = 0x5;
+       else if (dev->dev_attrib.pi_prot_type == TARGET_DIF_TYPE3_PROT)
+               buf[4] = 0x4;
+
        /* Set HEADSUP, ORDSUP, SIMPSUP */
        buf[5] = 0x07;
 
@@ -697,11 +711,15 @@ spc_emulate_inquiry(struct se_cmd *cmd)
        struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg;
        unsigned char *rbuf;
        unsigned char *cdb = cmd->t_task_cdb;
-       unsigned char buf[SE_INQUIRY_BUF];
+       unsigned char *buf;
        sense_reason_t ret;
        int p;
 
-       memset(buf, 0, SE_INQUIRY_BUF);
+       buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL);
+       if (!buf) {
+               pr_err("Unable to allocate response buffer for INQUIRY\n");
+               return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       }
 
        if (dev == tpg->tpg_virt_lun0.lun_se_dev)
                buf[0] = 0x3f; /* Not connected */
@@ -734,9 +752,10 @@ spc_emulate_inquiry(struct se_cmd *cmd)
 out:
        rbuf = transport_kmap_data_sg(cmd);
        if (rbuf) {
-               memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+               memcpy(rbuf, buf, min_t(u32, SE_INQUIRY_BUF, cmd->data_length));
                transport_kunmap_data_sg(cmd);
        }
+       kfree(buf);
 
        if (!ret)
                target_complete_cmd(cmd, GOOD);
@@ -839,6 +858,19 @@ static int spc_modesense_control(struct se_device *dev, u8 pc, u8 *p)
         * status (see SAM-4).
         */
        p[5] = (dev->dev_attrib.emulate_tas) ? 0x40 : 0x00;
+       /*
+        * From spc4r30, section 7.5.7 Control mode page
+        *
+        * Application Tag Owner (ATO) bit set to one.
+        *
+        * If the ATO bit is set to one the device server shall not modify the
+        * LOGICAL BLOCK APPLICATION TAG field and, depending on the protection
+        * type, shall not modify the contents of the LOGICAL BLOCK REFERENCE
+        * TAG field.
+        */
+       if (dev->dev_attrib.pi_prot_type)
+               p[5] |= 0x80;
+
        p[8] = 0xff;
        p[9] = 0xff;
        p[11] = 30;