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 |