Doug, >> I am collecting "bad" SES pages from these devices. I have added >> support for RECEIVE DIAGNOSTICS to scsi_debug and added a bunch of >> deliberately broken SES pages so we could debug this > > Patches ?? I have included the plumbing below. However, I need to synthesize the contents of the pages with problems. I can't share the ones I have received from customers so I removed the arrays from the patch. -- Martin K. Petersen Oracle Linux Engineering >From 968dfc5cd498d2ea6e77801cc9b9183a1a28b35d Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" <martin.petersen@xxxxxxxxxx> Date: Thu, 28 Mar 2019 22:29:13 -0400 Subject: [PATCH] scsi: scsi_debug: Implement support for Receive Diagnostics command Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2740a90501a0..db8745a7000e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -356,7 +356,8 @@ enum sdeb_opcode_index { SDEB_I_WRITE_SAME = 26, /* 10, 16 */ SDEB_I_SYNC_CACHE = 27, /* 10, 16 */ SDEB_I_COMP_WRITE = 28, - SDEB_I_LAST_ELEMENT = 29, /* keep this last (previous + 1) */ + SDEB_I_RECV_DIAG = 29, + SDEB_I_LAST_ELEMENT = 30, /* keep this last (previous + 1) */ }; @@ -367,8 +368,8 @@ static const unsigned char opcode_ind_arr[256] = { SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0, 0, 0, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, SDEB_I_RELEASE, - 0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, 0, SDEB_I_SEND_DIAG, - SDEB_I_ALLOW_REMOVAL, 0, + 0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, SDEB_I_RECV_DIAG, + SDEB_I_SEND_DIAG, SDEB_I_ALLOW_REMOVAL, 0, /* 0x20; 0x20->0x3f: 10 byte cdbs */ 0, 0, 0, 0, 0, SDEB_I_READ_CAPACITY, 0, 0, SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, SDEB_I_VERIFY, @@ -433,6 +434,7 @@ static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_sync_cache(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_recv_diag(struct scsi_cmnd *, struct sdebug_dev_info *); /* * The following are overflow arrays for cdbs that "hit" the same index in @@ -613,8 +615,9 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { {0, 0x89, 0, F_D_OUT | FF_MEDIA_IO, resp_comp_write, NULL, {16, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, 0x3f, 0xc7} }, /* COMPARE AND WRITE */ - -/* 29 */ + {0, 0x1c, 0, FF_RESPOND | F_D_IN, resp_recv_diag, NULL, /* RECV DIAG */ + {6, 0x1, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, +/* 30 */ {0xff, 0, 0, 0, NULL, NULL, /* terminating element */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, }; @@ -1516,7 +1519,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) arr[5] = (int)have_dif_prot; /* PROTECT bit */ if (sdebug_vpd_use_hostno == 0) arr[5] |= 0x10; /* claim: implicit TPGS */ - arr[6] = 0x10; /* claim: MultiP */ + arr[6] = 0x10 | 0x40; /* claim: MultiP */ /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ arr[7] = 0xa; /* claim: LINKED + CMDQUE */ memcpy(&arr[8], sdebug_inq_vendor_id, 8); @@ -3597,6 +3600,36 @@ static int resp_sync_cache(struct scsi_cmnd *scp, return res; } +static unsigned char diag0[] = { + 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x06, 0x07, 0x0a, 0xa0, 0x00, +}; +#define DIAG0_LEN 12 + + +static int resp_recv_diag(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) +{ + unsigned char *cmd = scp->cmnd; + + switch(cmd[2]) { + case 0: + return fill_from_dev_buffer(scp, diag0, DIAG0_LEN); + case 1: + return fill_from_dev_buffer(scp, diag1, DIAG1_LEN); + case 2: + return fill_from_dev_buffer(scp, diag2, DIAG2_LEN); + case 6: + return fill_from_dev_buffer(scp, diag6, DIAG6_LEN); + case 7: + return fill_from_dev_buffer(scp, diag7, DIAG7_LEN); + case 0xa: + return fill_from_dev_buffer(scp, diaga, DIAGA_LEN); + case 0xa0: + return fill_from_dev_buffer(scp, diaga0, DIAGA0_LEN); + } + + return DID_ERROR << 16; +} + #define RL_BUCKET_ELEMS 8 /* Even though each pseudo target has a REPORT LUNS "well known logical unit"