@@ -533,6 +533,8 @@ static int resp_write_scat(struct scsi_cmnd *, struct sdebug_dev_info *);
533533static int resp_start_stop (struct scsi_cmnd * , struct sdebug_dev_info * );
534534static int resp_readcap16 (struct scsi_cmnd * , struct sdebug_dev_info * );
535535static 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 );
536538static int resp_report_tgtpgs (struct scsi_cmnd * , struct sdebug_dev_info * );
537539static int resp_unmap (struct scsi_cmnd * , struct sdebug_dev_info * );
538540static 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[] = {
607609 {0 , 0x9e , 0x12 , F_SA_LOW | F_D_IN , resp_get_lba_status , NULL ,
608610 {16 , 0x12 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
609611 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 */
610615};
611616
612617static const struct opcode_info_t vl_iarr [] = { /* VARIABLE LENGTH */
@@ -4573,6 +4578,51 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
45734578 return fill_from_dev_buffer (scp , arr , SDEBUG_GET_LBA_STATUS_LEN );
45744579}
45754580
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+
45764626static int resp_sync_cache (struct scsi_cmnd * scp ,
45774627 struct sdebug_dev_info * devip )
45784628{
0 commit comments