mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
scsi: scsi_debug: Implement GET STREAM STATUS
Implement the GET STREAM STATUS SCSI command. Report that the first five stream indexes correspond to permanent streams. Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Douglas Gilbert <dgilbert@interlog.com> Tested-by: Douglas Gilbert <dgilbert@interlog.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Link: https://lore.kernel.org/r/20240130214911.1863909-19-bvanassche@acm.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
f8ab271017
commit
ad620becda
@ -533,6 +533,8 @@ static int resp_write_scat(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_start_stop(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_readcap16(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_get_lba_status(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_get_stream_status(struct scsi_cmnd *scp,
|
||||
struct sdebug_dev_info *devip);
|
||||
static int resp_report_tgtpgs(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_unmap(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
static int resp_rsup_opcodes(struct scsi_cmnd *, struct sdebug_dev_info *);
|
||||
@ -607,6 +609,9 @@ static const struct opcode_info_t sa_in_16_iarr[] = {
|
||||
{0, 0x9e, 0x12, F_SA_LOW | F_D_IN, resp_get_lba_status, NULL,
|
||||
{16, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0, 0xc7} }, /* GET LBA STATUS(16) */
|
||||
{0, 0x9e, 0x16, F_SA_LOW | F_D_IN, resp_get_stream_status, NULL,
|
||||
{16, 0x16, 0, 0, 0xff, 0xff, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff,
|
||||
0, 0} }, /* GET STREAM STATUS */
|
||||
};
|
||||
|
||||
static const struct opcode_info_t vl_iarr[] = { /* VARIABLE LENGTH */
|
||||
@ -4573,6 +4578,51 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
|
||||
return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN);
|
||||
}
|
||||
|
||||
static int resp_get_stream_status(struct scsi_cmnd *scp,
|
||||
struct sdebug_dev_info *devip)
|
||||
{
|
||||
u16 starting_stream_id, stream_id;
|
||||
const u8 *cmd = scp->cmnd;
|
||||
u32 alloc_len, offset;
|
||||
u8 arr[256] = {};
|
||||
struct scsi_stream_status_header *h = (void *)arr;
|
||||
|
||||
starting_stream_id = get_unaligned_be16(cmd + 4);
|
||||
alloc_len = get_unaligned_be32(cmd + 10);
|
||||
|
||||
if (alloc_len < 8) {
|
||||
mk_sense_invalid_fld(scp, SDEB_IN_CDB, 10, -1);
|
||||
return check_condition_result;
|
||||
}
|
||||
|
||||
if (starting_stream_id >= MAXIMUM_NUMBER_OF_STREAMS) {
|
||||
mk_sense_invalid_fld(scp, SDEB_IN_CDB, 4, -1);
|
||||
return check_condition_result;
|
||||
}
|
||||
|
||||
/*
|
||||
* The GET STREAM STATUS command only reports status information
|
||||
* about open streams. Treat the non-permanent stream as open.
|
||||
*/
|
||||
put_unaligned_be16(MAXIMUM_NUMBER_OF_STREAMS,
|
||||
&h->number_of_open_streams);
|
||||
|
||||
for (offset = 8, stream_id = starting_stream_id;
|
||||
offset + 8 <= min_t(u32, alloc_len, sizeof(arr)) &&
|
||||
stream_id < MAXIMUM_NUMBER_OF_STREAMS;
|
||||
offset += 8, stream_id++) {
|
||||
struct scsi_stream_status *stream_status = (void *)arr + offset;
|
||||
|
||||
stream_status->perm = stream_id < PERMANENT_STREAM_COUNT;
|
||||
put_unaligned_be16(stream_id,
|
||||
&stream_status->stream_identifier);
|
||||
stream_status->rel_lifetime = stream_id + 1;
|
||||
}
|
||||
put_unaligned_be32(offset - 8, &h->len); /* PARAMETER DATA LENGTH */
|
||||
|
||||
return fill_from_dev_buffer(scp, arr, min(offset, alloc_len));
|
||||
}
|
||||
|
||||
static int resp_sync_cache(struct scsi_cmnd *scp,
|
||||
struct sdebug_dev_info *devip)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user