[PATCH 1/5] SCSI: Add support for 32-byte CDBs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



DIF Type 2 drives require 32-byte commands.  Add a suitable flag to
struct scsi_device that will cause scsi_setup_fs_cmnd() to allocate a
bigger command buffer.

Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
---
 drivers/scsi/scsi_lib.c    |   38 +++++++++++++++++++++++++++++++++++++-
 include/scsi/scsi.h        |    1 +
 include/scsi/scsi_cmnd.h   |    6 ++++++
 include/scsi/scsi_device.h |    1 +
 4 files changed, 45 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 662024d..643769c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -67,6 +67,9 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
 
 struct kmem_cache *scsi_sdb_cache;
 
+struct kmem_cache *cdb_cache;
+mempool_t *cdb_pool;
+
 static void scsi_run_queue(struct request_queue *q);
 
 /*
@@ -642,6 +645,11 @@ static void __scsi_release_buffers(struct scsi_cmnd *cmd, int do_bidi_check)
 
 	if (scsi_prot_sg_count(cmd))
 		scsi_free_sgtable(cmd->prot_sdb);
+
+	if (cmd->flags & SCSI_CMND_EXT_CDB) {
+		mempool_free(cmd->cmnd, cdb_pool);
+		cmd->flags &= ~SCSI_CMND_EXT_CDB;
+	}
 }
 
 /*
@@ -1109,7 +1117,19 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
 	if (unlikely(!cmd))
 		return BLKPREP_DEFER;
 
-	memset(cmd->cmnd, 0, BLK_MAX_CDB);
+	if (sdev->use_32_for_rw) {
+		req->cmd = mempool_alloc(cdb_pool, GFP_ATOMIC);
+
+		if (unlikely(!req->cmd))
+			return BLKPREP_DEFER;
+
+		cmd->cmnd = req->cmd;
+		cmd->cmd_len = req->cmd_len = SCSI_EXT_CDB_SIZE;
+		cmd->flags |= SCSI_CMND_EXT_CDB;
+		memset(cmd->cmnd, 0, cmd->cmd_len);
+	} else
+		memset(cmd->cmnd, 0, BLK_MAX_CDB);
+
 	return scsi_init_io(cmd, GFP_ATOMIC);
 }
 EXPORT_SYMBOL(scsi_setup_fs_cmnd);
@@ -1745,6 +1765,19 @@ int __init scsi_init_queue(void)
 		}
 	}
 
+	cdb_cache = kmem_cache_create("scsi_cdb_32", SCSI_EXT_CDB_SIZE,
+				      0, 0, NULL);
+	if (!cdb_cache) {
+		printk(KERN_ERR "SCSI: can't init scsi cdb cache\n");
+		goto cleanup_sdb;
+	}
+
+	cdb_pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE, cdb_cache);
+	if (!cdb_pool) {
+		printk(KERN_ERR "SCSI: can't init scsi cdb pool\n");
+		goto cleanup_sdb;
+	}
+
 	return 0;
 
 cleanup_sdb:
@@ -1771,6 +1804,9 @@ void scsi_exit_queue(void)
 		mempool_destroy(sgp->pool);
 		kmem_cache_destroy(sgp->slab);
 	}
+
+	mempool_destroy(cdb_pool);
+	kmem_cache_destroy(cdb_cache);
 }
 
 /**
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 084478e..a7ae10a 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -138,6 +138,7 @@ struct scsi_cmnd;
  *	SCSI command lengths
  */
 
+#define SCSI_EXT_CDB_SIZE 32
 #define SCSI_MAX_VARLEN_CDB_SIZE 260
 
 /* defined in T10 SCSI Primary Commands-2 (SPC2) */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 3878d1d..d4a6a80 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -50,6 +50,10 @@ struct scsi_pointer {
 	volatile int phase;
 };
 
+enum scsi_cmnd_flags {
+	SCSI_CMND_EXT_CDB = 1 << 0,
+};
+
 struct scsi_cmnd {
 	struct scsi_device *device;
 	struct list_head list;  /* scsi_cmnd participates in queue lists */
@@ -129,6 +133,8 @@ struct scsi_cmnd {
 	int result;		/* Status code from lower level driver */
 
 	unsigned char tag;	/* SCSI-II queued command tag */
+
+	enum scsi_cmnd_flags flags;
 };
 
 extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 3f566af..de2966b 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -129,6 +129,7 @@ struct scsi_device {
 				 * this device */
 	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
 				     * because we did a bus reset. */
+	unsigned use_32_for_rw:1; /* use 32-byte read / write (DIF Type 2) */
 	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
 	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
 	unsigned skip_ms_page_8:1;	/* do not use MODE SENSE page 0x08 */
-- 
1.6.0.6

--
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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux