[Stgt-devel] [PATCH] Prepare for variable block write support

Mark Harvey markh794
Fri Jul 25 09:30:30 CEST 2008


>From 90c4b72a52ee4879f45670b92a78ebbcc711087e Mon Sep 17 00:00:00 2001
From: Mark Harvey <markh794 at gmail.com>
Date: Fri, 25 Jul 2008 16:55:29 +1000
Subject: Prepare for variable block write support

MODE descriptor block needs to match the specified block size.
 - 'primary' block size stored in ssc_info structure.
 - BLOCK DESCRIPTOR data built based on this value.

Signed-off-by: Mark Harvey <markh794 at gmail.com>
---
 usr/ssc.c |   54 +++++++++++++++++++++++++++++++++------------------
 usr/ssc.h |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/usr/ssc.c b/usr/ssc.c
index ba6e36b..cdcf0f2 100644
--- a/usr/ssc.c
+++ b/usr/ssc.c
@@ -32,11 +32,14 @@
 #include "driver.h"
 #include "scsi.h"
 #include "spc.h"
+#include "ssc.h"
 #include "tgtadm_error.h"
 
 #define BLK_SHIFT	9
 #define GRANULARITY	9
 
+#define MAX_BLK_SIZE	1048576
+#define MIN_BLK_SIZE	4
 
 static int ssc_rw(int host_no, struct scsi_cmd *cmd)
 {
@@ -50,9 +53,6 @@ static int ssc_rw(int host_no, struct scsi_cmd *cmd)
 
 	cmd->scsi_cmd_done = target_cmd_io_done;
 
-/* 	cmd->offset = (((cmd->scb[2] << 16) | (cmd->scb[3] << 8) | */
-/* 			(cmd->scb[4])) << BLK_SHIFT); */
-
 	ret = cmd->dev->bst->bs_cmd_submit(cmd);
 	if (ret) {
 		key = HARDWARE_ERROR;
@@ -70,31 +70,45 @@ static int ssc_rw(int host_no, struct scsi_cmd *cmd)
 	return SAM_STAT_CHECK_CONDITION;
 }
 
+#define READ_BLK_LIMITS_SZ	6
 static int ssc_read_block_limit(int host_no, struct scsi_cmd *cmd)
 {
-	uint8_t *data;
-	uint8_t buf[256];
-	uint16_t blk_len = 1 << GRANULARITY;
+	struct ssc_info *ssc = dtype_priv(cmd->dev);
+	uint8_t buf[READ_BLK_LIMITS_SZ];
 
 	memset(buf, 0, sizeof(buf));
-	data = buf;
 
-	data[0] = GRANULARITY;
-	data[1] = (blk_len >> 16) &0xff;
-	data[2] = (blk_len >> 8) &0xff;
-	data[3] = blk_len & 0xff;
-	data[4] = (blk_len >> 8) &0xff;
-	data[5] = blk_len & 0xff;
+	if (ssc->blk_sz) {	/* Fixed block size */
+		buf[0] = GRANULARITY;
+		buf[1] = (ssc->blk_sz >> 16) & 0xff;
+		buf[2] = (ssc->blk_sz >> 8) & 0xff;
+		buf[3] = ssc->blk_sz & 0xff;
+		buf[4] = (ssc->blk_sz >> 8) & 0xff;
+		buf[5] = ssc->blk_sz & 0xff;
+	} else {	/* Variable block size */
+		buf[0] = GRANULARITY;
+		buf[1] = (MAX_BLK_SIZE >> 16) & 0xff;
+		buf[2] = (MAX_BLK_SIZE >> 8) & 0xff;
+		buf[3] = MAX_BLK_SIZE & 0xff;
+		buf[4] = (MIN_BLK_SIZE >> 8) & 0xff;
+		buf[5] = MIN_BLK_SIZE & 0xff;
+	}
 
-	memcpy(scsi_get_in_buffer(cmd), data, 6);
+	memcpy(scsi_get_in_buffer(cmd), buf, READ_BLK_LIMITS_SZ);
 	eprintf("In ssc_read_block_limit \n");
 	return SAM_STAT_GOOD;
 }
 
 static int ssc_lu_init(struct scsi_lu *lu)
 {
-	uint64_t size;
 	uint8_t *data;
+	struct ssc_info *ssc;
+
+	ssc = zalloc(sizeof(struct ssc_info));
+	if (ssc)
+		dtype_priv(lu) = ssc;
+	else
+		return -ENOMEM;
 
 	if (spc_lu_init(lu))
 		return TGTADM_NOMEM;
@@ -107,11 +121,13 @@ static int ssc_lu_init(struct scsi_lu *lu)
 	lu->attrs.removable = 1;
 
 	data = lu->mode_block_descriptor;
-	size = lu->size >> BLK_SHIFT;
+	ssc->blk_sz = 1 << BLK_SHIFT;
+
+	/* SSC devices do not need to set number of blks */
+	*(uint32_t *)(data) = 0;
 
-	*(uint32_t *)(data) = (size >> 32) ?
-			__cpu_to_be32(0xffffffff) : __cpu_to_be32(size);
-	*(uint32_t *)(data + 4) = __cpu_to_be32(1 << BLK_SHIFT);
+	/* Set default blk size */
+	*(uint32_t *)(data + 4) = __cpu_to_be32(ssc->blk_sz);
 
 	/* Vendor uniq - However most apps seem to call for mode page 0*/
 	add_mode_page(lu, "0:0:0");
diff --git a/usr/ssc.h b/usr/ssc.h
new file mode 100644
index 0000000..59fef75
--- /dev/null
+++ b/usr/ssc.h
@@ -0,0 +1,64 @@
+/*
+ * SCSI Streaming specific header
+ */
+
+#ifndef _SSC_H_
+#define _SSC_H_
+
+/*
+ * MAM structure based from IBM Ultrium SCSI Reference WB1109-02
+ */
+struct MAM {
+	uint32_t tape_fmt_version;
+
+	uint64_t remaining_capacity;
+	uint64_t max_capacity;
+	uint64_t TapeAlert;
+	uint64_t load_count;
+	uint64_t MAM_space_remaining;
+	uint8_t assigning_organization_1[8];
+	uint8_t formatted_density_code;
+	uint8_t initialization_count[2];
+	uint8_t dev_make_serial_last_load[4][40];
+	uint64_t written_in_medium_life;
+	uint64_t read_in_medium_life;
+	uint64_t written_in_last_load;
+	uint64_t read_in_last_load;
+
+	uint8_t medium_manufacturer[8];
+	uint8_t medium_serial_number[32];
+	uint32_t medium_length;
+	uint32_t medium_width;
+	uint8_t assigning_organization_2[8];
+	uint8_t medium_density_code;
+	uint8_t medium_manufacture_date[8];
+	uint64_t MAM_capacity;
+	uint8_t medium_type;
+	uint16_t medium_type_information;
+
+	uint8_t application_vendor[8];
+	uint8_t application_name[32];
+	uint8_t application_version[8];
+	uint8_t user_medium_text_label[160];
+	uint8_t date_time_last_written[12];
+	uint8_t localization_identifier;
+	uint8_t barcode[32];
+	uint8_t owning_host_textual_name[80];
+	uint8_t media_pool[160];
+
+	uint8_t vendor_unique[256];
+
+	uint8_t dirty;
+};
+
+struct ssc_info {
+/* blk_size is 'master'. Build block descriptor data from this value */
+	uint32_t blk_sz;
+	uint64_t bytes_read;	/* Bytes read this load */
+	uint64_t bytes_written;	/* Bytes written this load */
+
+	struct MAM mam;
+};
+
+#endif
+
-- 
1.5.4.3





More information about the stgt mailing list