[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