>From 90c4b72a52ee4879f45670b92a78ebbcc711087e Mon Sep 17 00:00:00 2001
From: Mark Harvey <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
 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


_______________________________________________
Stgt-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/stgt-devel

Reply via email to