[stgt] SSC Changes that allow BakBone NetVault to work ...

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Wed Aug 27 16:31:29 CEST 2008


On Sun, 17 Aug 2008 12:33:42 -0700
"Richard Sharpe" <realrichardsharpe at gmail.com> wrote:

> Hi,
> 
> Attached are the diffs for my current SSC implementation. These
> changes, along with the diffs I posted for SMC, allow BakBone to work,
> to see a Tape Library, and to backup to tapes in the library.

Really nice!


> There are undoubtedly many problems with the code, not the least of
> which is that it is pretty ugly :-)

> --- /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;
> +}

We have a scheme to handle MODE SELECT. Can you see sbc_mode_select()?


> +/*
> + * 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;
> +}

PREVENT ALLOW MEDIA REMOVAL is not ssc specific. It's SPC, right? I'll
send patches.


> +/*
> + * 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;
> +}

We need a new scheme like one for mode pages for log pages... I'll try
to invent something unless someone beats me.


> +/*
> + * 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);

0x31 is a vendor specific, right?


> +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");

This doesn't work. You can find a message in the log like:

Aug 27 22:58:28 viola tgtd: add_mode_page(845) Mode Page 17 (0x00):
param_count 1 != MODE PAGE size : 3

This should be something like this:

add_mode_page(lu, "0x11:0:8:0:0:0x18:3:9:0:0:100");


Can you check this again?
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list