Skip to content

Commit f8ab271

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: scsi_debug: Implement the IO Advice Hints Grouping mode page
Implement an IO Advice Hints Grouping mode page with three permanent streams. A permanent stream is a stream for which the device server does not allow closing or otherwise modifying the configuration of that stream. The stream identifier enable (ST_ENBLE) bit specifies whether the stream identifier may be used in the GROUP NUMBER field of SCSI WRITE commands. 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-18-bvanassche@acm.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent b952eb2 commit f8ab271

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

drivers/scsi/scsi_debug.c

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,11 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
19691969
arr[4] = 0x5; /* SPT: GRD_CHK:1, REF_CHK:1 */
19701970
else
19711971
arr[4] = 0x0; /* no protection stuff */
1972-
arr[5] = 0x7; /* head of q, ordered + simple q's */
1972+
/*
1973+
* GROUP_SUP=1; HEADSUP=1 (HEAD OF QUEUE); ORDSUP=1
1974+
* (ORDERED queuing); SIMPSUP=1 (SIMPLE queuing).
1975+
*/
1976+
arr[5] = 0x17;
19731977
} else if (0x87 == cmd[2]) { /* mode page policy */
19741978
arr[3] = 0x8; /* number of following entries */
19751979
arr[4] = 0x2; /* disconnect-reconnect mp */
@@ -2559,6 +2563,40 @@ static int resp_ctrl_m_pg(unsigned char *p, int pcontrol, int target)
25592563
return sizeof(ctrl_m_pg);
25602564
}
25612565

2566+
/* IO Advice Hints Grouping mode page */
2567+
static int resp_grouping_m_pg(unsigned char *p, int pcontrol, int target)
2568+
{
2569+
/* IO Advice Hints Grouping mode page */
2570+
struct grouping_m_pg {
2571+
u8 page_code; /* OR 0x40 when subpage_code > 0 */
2572+
u8 subpage_code;
2573+
__be16 page_length;
2574+
u8 reserved[12];
2575+
struct scsi_io_group_descriptor descr[MAXIMUM_NUMBER_OF_STREAMS];
2576+
};
2577+
static const struct grouping_m_pg gr_m_pg = {
2578+
.page_code = 0xa | 0x40,
2579+
.subpage_code = 5,
2580+
.page_length = cpu_to_be16(sizeof(gr_m_pg) - 4),
2581+
.descr = {
2582+
{ .st_enble = 1 },
2583+
{ .st_enble = 1 },
2584+
{ .st_enble = 1 },
2585+
{ .st_enble = 1 },
2586+
{ .st_enble = 1 },
2587+
{ .st_enble = 0 },
2588+
}
2589+
};
2590+
2591+
BUILD_BUG_ON(sizeof(struct grouping_m_pg) !=
2592+
16 + MAXIMUM_NUMBER_OF_STREAMS * 16);
2593+
memcpy(p, &gr_m_pg, sizeof(gr_m_pg));
2594+
if (1 == pcontrol) {
2595+
/* There are no changeable values so clear from byte 4 on. */
2596+
memset(p + 4, 0, sizeof(gr_m_pg) - 4);
2597+
}
2598+
return sizeof(gr_m_pg);
2599+
}
25622600

25632601
static int resp_iec_m_pg(unsigned char *p, int pcontrol, int target)
25642602
{ /* Informational Exceptions control mode page for mode_sense */
@@ -2708,6 +2746,10 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
27082746
ap = arr + offset;
27092747
}
27102748

2749+
/*
2750+
* N.B. If len>0 before resp_*_pg() call, then form of that call should be:
2751+
* len += resp_*_pg(ap + len, pcontrol, target);
2752+
*/
27112753
switch (pcode) {
27122754
case 0x1: /* Read-Write error recovery page, direct access */
27132755
if (subpcode > 0x0 && subpcode < 0xff)
@@ -2742,9 +2784,20 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
27422784
}
27432785
break;
27442786
case 0xa: /* Control Mode page, all devices */
2745-
if (subpcode > 0x0 && subpcode < 0xff)
2787+
switch (subpcode) {
2788+
case 0:
2789+
len = resp_ctrl_m_pg(ap, pcontrol, target);
2790+
break;
2791+
case 0x05:
2792+
len = resp_grouping_m_pg(ap, pcontrol, target);
2793+
break;
2794+
case 0xff:
2795+
len = resp_ctrl_m_pg(ap, pcontrol, target);
2796+
len += resp_grouping_m_pg(ap + len, pcontrol, target);
2797+
break;
2798+
default:
27462799
goto bad_subpcode;
2747-
len = resp_ctrl_m_pg(ap, pcontrol, target);
2800+
}
27482801
offset += len;
27492802
break;
27502803
case 0x19: /* if spc==1 then sas phy, control+discover */
@@ -2778,6 +2831,8 @@ static int resp_mode_sense(struct scsi_cmnd *scp,
27782831
len += resp_caching_pg(ap + len, pcontrol, target);
27792832
}
27802833
len += resp_ctrl_m_pg(ap + len, pcontrol, target);
2834+
if (0xff == subpcode)
2835+
len += resp_grouping_m_pg(ap + len, pcontrol, target);
27812836
len += resp_sas_sf_m_pg(ap + len, pcontrol, target);
27822837
if (0xff == subpcode) {
27832838
len += resp_sas_pcd_m_spg(ap + len, pcontrol, target,

0 commit comments

Comments
 (0)