--- /home/rsharpe/open-source-devel/linux-scsi-tgt/usr/ssc.c	2008-07-30 10:26:58.000000000 -0700
+++ ssc.c	2008-08-15 15:08:52.000000000 -0700
@@ -99,17 +99,113 @@
 	return SAM_STAT_GOOD;
 }
 
-static int ssc_lu_init(struct scsi_lu *lu)
+/* 
+ * We need one of these ... let's just say all OK ... however, we should 
+ * properly handle buffered mode ... 
+ */
+static int ssc_mode_select(int host_no, struct scsi_cmd *cmd)
+{
+	uint8_t *buf = scsi_get_out_buffer(cmd);
+	uint32_t in_len = scsi_get_out_length(cmd);
+
+	/*
+	 * If the data contains a Block descriptor, check if we should
+	 * save values ...
+	 */
+	if (buf) {
+		struct ssc_info *ssc = dtype_priv(cmd->dev);
+		uint8_t *data;
+
+		eprintf("We are in mode-select and have been given a buffer\n");
+	
+		data = cmd->dev->mode_block_descriptor;
+		
+		if (in_len >= 8 && buf[3]) { /* Block Descriptor length ... */
+			uint32_t block_len;
+	
+			block_len = __be32_to_cpu(*(uint32_t *)(buf + 8));
+
+			ssc->blk_sz = block_len;
+
+			/* Set default blk size back in here */
+			*(uint32_t *)(data + 4) = __cpu_to_be32(ssc->blk_sz);
+
+			eprintf("We set the block len to: %u\n", block_len);
+		}
+	}
+
+	return SAM_STAT_GOOD;
+}
+
+/*
+ * Implement a simple prevent allow medium removal ...
+ */
+static int ssc_prevent_allow_media_removal(int host_no, struct scsi_cmd *cmd)
+{
+
+	return SAM_STAT_GOOD;
+}
+
+/*
+ * Implement a simple log select page ... just say OK so far ...
+ */
+static int ssc_log_select(int host_no, struct scsi_cmd *cmd)
+{
+
+	return SAM_STAT_GOOD;
+}
+
+/*
+ * Implement a simple log sense page. This should be hooked into error counts
+ * that we are not keeping yet.
+ */
+static uint8_t log_write_errors[] = {
+	0x02, 0x00, 0x00, 0x58,
+	0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x02, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x06, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static int ssc_log_sense(int host_no, struct scsi_cmd *cmd)
 {
-	uint8_t *data;
-	struct ssc_info *ssc;
+	uint8_t *buf = scsi_get_in_buffer(cmd);
+	uint32_t len = scsi_get_in_length(cmd);
+
+	eprintf("LogSense called, page: 0x%2X\n", cmd->scb[2]);
+	if ((cmd->scb[2] & 0x3F) == 2) { /* Write errors page ... */
+		uint32_t bytes = min(88, (int)len);
+		memcpy(buf, log_write_errors, bytes);
+		scsi_set_in_resid_by_actual(cmd, bytes);
+	}
+	else if ((cmd->scb[2] & 0x3F) == 0x31) { /* Tape capacity ... */
+		eprintf("Doing tape capacity ...\n");
+		buf[0] = 0x31;
+		buf[3] = 0x20;
+		*(uint32_t *)(buf +  4) = 0x04400100;
+		*(uint32_t *)(buf +  8) = __cpu_to_be32(400000);
+		*(uint32_t *)(buf + 12) = 0x04400200;
+		*(uint32_t *)(buf + 16) = 0;
+		*(uint32_t *)(buf + 20) = 0x04400300;
+		*(uint32_t *)(buf + 24) = __cpu_to_be32(400000);
+		*(uint32_t *)(buf + 28) = 0x04400400;
+		*(uint32_t *)(buf + 32) = 0;
+		scsi_set_in_resid_by_actual(cmd, 20);
+	}
+	else {
+		scsi_set_in_resid_by_actual(cmd, 0);
+		sense_data_build(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB);
+		return SAM_STAT_CHECK_CONDITION;
+	}
 
-	ssc = zalloc(sizeof(struct ssc_info));
-	if (ssc)
-		dtype_priv(lu) = ssc;
-	else
-		return -ENOMEM;
+	return SAM_STAT_GOOD;
+}
 
+static int ssc_lu_init(struct scsi_lu *lu)
+{
 	if (spc_lu_init(lu))
 		return TGTADM_NOMEM;
 
@@ -120,15 +216,6 @@
 	lu->attrs.version_desc[2] = 0x0300; /* SPC-3 */
 	lu->attrs.removable = 1;
 
-	data = lu->mode_block_descriptor;
-	ssc->blk_sz = 1 << BLK_SHIFT;
-
-	/* SSC devices do not need to set number of blks */
-	*(uint32_t *)(data) = 0;
-
-	/* 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");
 	/* Read-Write Error Recovery - Mandatory - SSC3 8.3.5 */
@@ -141,6 +228,8 @@
 	add_mode_page(lu, "15:0:14:0:0:0:0:0:0:0:0:0:0:0:0:0:0");
 	/* Device Configuration - Mandatory - SSC3 8.3.3 */
 	add_mode_page(lu, "16:0:14:0:0:0:128:128:0:0:0:0:0:0:0:0:0");
+	/* Medium Partition Mode Page */
+	add_mode_page(lu, "0x11,0,8,0,0,0x18,3,9,0,0,100");
 	/* Informational Exceptions Control page - Mandatory - SSC3 8.3.6 */
 	add_mode_page(lu, "0x1c:0:10:8:0:0:0:0:0:0:0:0:0");
 	/* Medium Configuration - Mandatory - SSC3 8.3.7 */
@@ -182,7 +271,7 @@
 		{spc_inquiry,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
-		{spc_illegal_op,},
+		{ssc_mode_select,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
 
@@ -192,7 +281,7 @@
 		{spc_start_stop,},
 		{spc_illegal_op,},
 		{spc_illegal_op,},
-		{spc_illegal_op,},
+		{ssc_prevent_allow_media_removal,},
 		{spc_illegal_op,},
 
 		/* 0x20 */
@@ -233,7 +322,11 @@
 		{spc_illegal_op,},
 		{spc_illegal_op,},
 
-		[0x40 ... 0x4f] = {spc_illegal_op,},
+		[0x40 ... 0x4b] = {spc_illegal_op,},
+		{ssc_log_select,},
+		{ssc_log_sense,},
+		{spc_illegal_op,},
+		{spc_illegal_op,},
 
 		/* 0x50 */
 		{spc_illegal_op,},
