]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/target/target_core_spc.c
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[karo-tx-linux.git] / drivers / target / target_core_spc.c
index 9fabbf7214cd70cc3d4ad3e1bfa74f7ac516cdd0..074539558a542d5a38dc4f911f0032dc4ed0c998 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SCSI Primary Commands (SPC) parsing and emulation.
  *
- * (c) Copyright 2002-2012 RisingTide Systems LLC.
+ * (c) Copyright 2002-2013 Datera, Inc.
  *
  * Nicholas A. Bellinger <nab@kernel.org>
  *
@@ -35,7 +35,7 @@
 #include "target_core_alua.h"
 #include "target_core_pr.h"
 #include "target_core_ua.h"
-
+#include "target_core_xcopy.h"
 
 static void spc_fill_alua_data(struct se_port *port, unsigned char *buf)
 {
@@ -95,6 +95,12 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
         */
        spc_fill_alua_data(lun->lun_sep, buf);
 
+       /*
+        * Set Third-Party Copy (3PC) bit to indicate support for EXTENDED_COPY
+        */
+       if (dev->dev_attrib.emulate_3pc)
+               buf[5] |= 0x8;
+
        buf[7] = 0x2; /* CmdQue=1 */
 
        memcpy(&buf[8], "LIO-ORG ", 8);
@@ -129,8 +135,8 @@ spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
        return 0;
 }
 
-static void spc_parse_naa_6h_vendor_specific(struct se_device *dev,
-               unsigned char *buf)
+void spc_parse_naa_6h_vendor_specific(struct se_device *dev,
+                                     unsigned char *buf)
 {
        unsigned char *p = &dev->t10_wwn.unit_serial[0];
        int cnt;
@@ -460,6 +466,11 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 
        /* Set WSNZ to 1 */
        buf[4] = 0x01;
+       /*
+        * Set MAXIMUM COMPARE AND WRITE LENGTH
+        */
+       if (dev->dev_attrib.emulate_caw)
+               buf[5] = 0x01;
 
        /*
         * Set OPTIMAL TRANSFER LENGTH GRANULARITY
@@ -1250,8 +1261,14 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
                *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
                break;
        case EXTENDED_COPY:
-       case READ_ATTRIBUTE:
+               *size = get_unaligned_be32(&cdb[10]);
+               cmd->execute_cmd = target_do_xcopy;
+               break;
        case RECEIVE_COPY_RESULTS:
+               *size = get_unaligned_be32(&cdb[10]);
+               cmd->execute_cmd = target_do_receive_copy_results;
+               break;
+       case READ_ATTRIBUTE:
        case WRITE_ATTRIBUTE:
                *size = (cdb[10] << 24) | (cdb[11] << 16) |
                       (cdb[12] << 8) | cdb[13];