Skip to content

Commit b055e3b

Browse files
damien-lemoalfloatious
authored andcommitted
ata: libata-scsi: Refactor ata_scsi_simulate()
Factor out the code handling the INQUIRY command in ata_scsi_simulate() using the function ata_scsi_rbuf_fill() with the new actor ata_scsiop_inquiry(). This new actor function calls the existing actors to handle the standard inquiry as well as extended inquiry (VPD page access). Signed-off-by: Damien Le Moal <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Niklas Cassel <[email protected]>
1 parent 08b64ee commit b055e3b

File tree

1 file changed

+63
-43
lines changed

1 file changed

+63
-43
lines changed

drivers/ata/libata-scsi.c

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,7 +1815,7 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
18151815
}
18161816

18171817
/**
1818-
* ata_scsiop_inq_std - Simulate INQUIRY command
1818+
* ata_scsiop_inq_std - Simulate standard INQUIRY command
18191819
* @args: device IDENTIFY data / SCSI command of interest.
18201820
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
18211821
*
@@ -2121,6 +2121,11 @@ static unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf)
21212121

21222122
static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
21232123
{
2124+
if (!(args->dev->flags & ATA_DFLAG_ZAC)) {
2125+
ata_scsi_set_invalid_field(args->dev, args->cmd, 2, 0xff);
2126+
return 1;
2127+
}
2128+
21242129
/*
21252130
* zbc-r05 SCSI Zoned Block device characteristics VPD page
21262131
*/
@@ -2145,6 +2150,11 @@ static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
21452150
u8 *desc = &rbuf[64];
21462151
int i;
21472152

2153+
if (!cpr_log) {
2154+
ata_scsi_set_invalid_field(args->dev, args->cmd, 2, 0xff);
2155+
return 1;
2156+
}
2157+
21482158
/* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
21492159
rbuf[1] = 0xb9;
21502160
put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]);
@@ -2159,6 +2169,57 @@ static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
21592169
return 0;
21602170
}
21612171

2172+
/**
2173+
* ata_scsiop_inquiry - Simulate INQUIRY command
2174+
* @args: device IDENTIFY data / SCSI command of interest.
2175+
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
2176+
*
2177+
* Returns data associated with an INQUIRY command output.
2178+
*
2179+
* LOCKING:
2180+
* spin_lock_irqsave(host lock)
2181+
*/
2182+
static unsigned int ata_scsiop_inquiry(struct ata_scsi_args *args, u8 *rbuf)
2183+
{
2184+
struct ata_device *dev = args->dev;
2185+
struct scsi_cmnd *cmd = args->cmd;
2186+
const u8 *scsicmd = cmd->cmnd;
2187+
2188+
/* is CmdDt set? */
2189+
if (scsicmd[1] & 2) {
2190+
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
2191+
return 1;
2192+
}
2193+
2194+
/* Is EVPD clear? */
2195+
if ((scsicmd[1] & 1) == 0)
2196+
return ata_scsiop_inq_std(args, rbuf);
2197+
2198+
switch (scsicmd[2]) {
2199+
case 0x00:
2200+
return ata_scsiop_inq_00(args, rbuf);
2201+
case 0x80:
2202+
return ata_scsiop_inq_80(args, rbuf);
2203+
case 0x83:
2204+
return ata_scsiop_inq_83(args, rbuf);
2205+
case 0x89:
2206+
return ata_scsiop_inq_89(args, rbuf);
2207+
case 0xb0:
2208+
return ata_scsiop_inq_b0(args, rbuf);
2209+
case 0xb1:
2210+
return ata_scsiop_inq_b1(args, rbuf);
2211+
case 0xb2:
2212+
return ata_scsiop_inq_b2(args, rbuf);
2213+
case 0xb6:
2214+
return ata_scsiop_inq_b6(args, rbuf);
2215+
case 0xb9:
2216+
return ata_scsiop_inq_b9(args, rbuf);
2217+
default:
2218+
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
2219+
return 1;
2220+
}
2221+
}
2222+
21622223
/**
21632224
* modecpy - Prepare response for MODE SENSE
21642225
* @dest: output buffer
@@ -4263,48 +4324,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
42634324

42644325
switch(scsicmd[0]) {
42654326
case INQUIRY:
4266-
if (scsicmd[1] & 2) /* is CmdDt set? */
4267-
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
4268-
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
4269-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
4270-
else switch (scsicmd[2]) {
4271-
case 0x00:
4272-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
4273-
break;
4274-
case 0x80:
4275-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
4276-
break;
4277-
case 0x83:
4278-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
4279-
break;
4280-
case 0x89:
4281-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
4282-
break;
4283-
case 0xb0:
4284-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b0);
4285-
break;
4286-
case 0xb1:
4287-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1);
4288-
break;
4289-
case 0xb2:
4290-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
4291-
break;
4292-
case 0xb6:
4293-
if (dev->flags & ATA_DFLAG_ZAC)
4294-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
4295-
else
4296-
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
4297-
break;
4298-
case 0xb9:
4299-
if (dev->cpr_log)
4300-
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9);
4301-
else
4302-
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
4303-
break;
4304-
default:
4305-
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
4306-
break;
4307-
}
4327+
ata_scsi_rbuf_fill(&args, ata_scsiop_inquiry);
43084328
break;
43094329

43104330
case MODE_SENSE:

0 commit comments

Comments
 (0)