@@ -533,6 +533,8 @@ static int resp_write_scat(struct scsi_cmnd *, struct sdebug_dev_info *);
533
533
static int resp_start_stop (struct scsi_cmnd * , struct sdebug_dev_info * );
534
534
static int resp_readcap16 (struct scsi_cmnd * , struct sdebug_dev_info * );
535
535
static int resp_get_lba_status (struct scsi_cmnd * , struct sdebug_dev_info * );
536
+ static int resp_get_stream_status (struct scsi_cmnd * scp ,
537
+ struct sdebug_dev_info * devip );
536
538
static int resp_report_tgtpgs (struct scsi_cmnd * , struct sdebug_dev_info * );
537
539
static int resp_unmap (struct scsi_cmnd * , struct sdebug_dev_info * );
538
540
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[] = {
607
609
{0 , 0x9e , 0x12 , F_SA_LOW | F_D_IN , resp_get_lba_status , NULL ,
608
610
{16 , 0x12 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
609
611
0xff , 0xff , 0xff , 0 , 0xc7 } }, /* GET LBA STATUS(16) */
612
+ {0 , 0x9e , 0x16 , F_SA_LOW | F_D_IN , resp_get_stream_status , NULL ,
613
+ {16 , 0x16 , 0 , 0 , 0xff , 0xff , 0 , 0 , 0 , 0 , 0xff , 0xff , 0xff , 0xff ,
614
+ 0 , 0 } }, /* GET STREAM STATUS */
610
615
};
611
616
612
617
static const struct opcode_info_t vl_iarr [] = { /* VARIABLE LENGTH */
@@ -4573,6 +4578,51 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
4573
4578
return fill_from_dev_buffer (scp , arr , SDEBUG_GET_LBA_STATUS_LEN );
4574
4579
}
4575
4580
4581
+ static int resp_get_stream_status (struct scsi_cmnd * scp ,
4582
+ struct sdebug_dev_info * devip )
4583
+ {
4584
+ u16 starting_stream_id , stream_id ;
4585
+ const u8 * cmd = scp -> cmnd ;
4586
+ u32 alloc_len , offset ;
4587
+ u8 arr [256 ] = {};
4588
+ struct scsi_stream_status_header * h = (void * )arr ;
4589
+
4590
+ starting_stream_id = get_unaligned_be16 (cmd + 4 );
4591
+ alloc_len = get_unaligned_be32 (cmd + 10 );
4592
+
4593
+ if (alloc_len < 8 ) {
4594
+ mk_sense_invalid_fld (scp , SDEB_IN_CDB , 10 , -1 );
4595
+ return check_condition_result ;
4596
+ }
4597
+
4598
+ if (starting_stream_id >= MAXIMUM_NUMBER_OF_STREAMS ) {
4599
+ mk_sense_invalid_fld (scp , SDEB_IN_CDB , 4 , -1 );
4600
+ return check_condition_result ;
4601
+ }
4602
+
4603
+ /*
4604
+ * The GET STREAM STATUS command only reports status information
4605
+ * about open streams. Treat the non-permanent stream as open.
4606
+ */
4607
+ put_unaligned_be16 (MAXIMUM_NUMBER_OF_STREAMS ,
4608
+ & h -> number_of_open_streams );
4609
+
4610
+ for (offset = 8 , stream_id = starting_stream_id ;
4611
+ offset + 8 <= min_t (u32 , alloc_len , sizeof (arr )) &&
4612
+ stream_id < MAXIMUM_NUMBER_OF_STREAMS ;
4613
+ offset += 8 , stream_id ++ ) {
4614
+ struct scsi_stream_status * stream_status = (void * )arr + offset ;
4615
+
4616
+ stream_status -> perm = stream_id < PERMANENT_STREAM_COUNT ;
4617
+ put_unaligned_be16 (stream_id ,
4618
+ & stream_status -> stream_identifier );
4619
+ stream_status -> rel_lifetime = stream_id + 1 ;
4620
+ }
4621
+ put_unaligned_be32 (offset - 8 , & h -> len ); /* PARAMETER DATA LENGTH */
4622
+
4623
+ return fill_from_dev_buffer (scp , arr , min (offset , alloc_len ));
4624
+ }
4625
+
4576
4626
static int resp_sync_cache (struct scsi_cmnd * scp ,
4577
4627
struct sdebug_dev_info * devip )
4578
4628
{
0 commit comments