mirror of https://github.com/xemu-project/xemu.git
scsi-bus: prepare scsi_req_new for introduction of parse_cdb
The per-SCSIDevice parse_cdb callback must not be called if the request will go through special SCSIReqOps, so detect the special cases early enough. Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
5a73480450
commit
769998a1db
|
@ -561,23 +561,12 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
|
||||||
uint8_t *buf, void *hba_private)
|
uint8_t *buf, void *hba_private)
|
||||||
{
|
{
|
||||||
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
|
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
|
||||||
|
const SCSIReqOps *ops;
|
||||||
SCSIRequest *req;
|
SCSIRequest *req;
|
||||||
SCSICommand cmd;
|
SCSICommand cmd = { .len = 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (scsi_req_parse(&cmd, d, buf) != 0) {
|
if ((d->unit_attention.key == UNIT_ATTENTION ||
|
||||||
trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
|
|
||||||
req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
|
|
||||||
} else {
|
|
||||||
trace_scsi_req_parsed(d->id, lun, tag, buf[0],
|
|
||||||
cmd.mode, cmd.xfer);
|
|
||||||
if (cmd.lba != -1) {
|
|
||||||
trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
|
|
||||||
cmd.lba);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd.xfer > INT32_MAX) {
|
|
||||||
req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private);
|
|
||||||
} else if ((d->unit_attention.key == UNIT_ATTENTION ||
|
|
||||||
bus->unit_attention.key == UNIT_ATTENTION) &&
|
bus->unit_attention.key == UNIT_ATTENTION) &&
|
||||||
(buf[0] != INQUIRY &&
|
(buf[0] != INQUIRY &&
|
||||||
buf[0] != REPORT_LUNS &&
|
buf[0] != REPORT_LUNS &&
|
||||||
|
@ -589,13 +578,32 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
|
||||||
* report this one before triggering another one.
|
* report this one before triggering another one.
|
||||||
*/
|
*/
|
||||||
!(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
|
!(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
|
||||||
req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
|
ops = &reqops_unit_attention;
|
||||||
hba_private);
|
|
||||||
} else if (lun != d->lun ||
|
} else if (lun != d->lun ||
|
||||||
buf[0] == REPORT_LUNS ||
|
buf[0] == REPORT_LUNS ||
|
||||||
(buf[0] == REQUEST_SENSE && d->sense_len)) {
|
(buf[0] == REQUEST_SENSE && d->sense_len)) {
|
||||||
req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
|
ops = &reqops_target_command;
|
||||||
hba_private);
|
} else {
|
||||||
|
ops = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scsi_req_parse(&cmd, d, buf);
|
||||||
|
if (ret != 0) {
|
||||||
|
trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
|
||||||
|
req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
|
||||||
|
} else {
|
||||||
|
assert(cmd.len != 0);
|
||||||
|
trace_scsi_req_parsed(d->id, lun, tag, buf[0],
|
||||||
|
cmd.mode, cmd.xfer);
|
||||||
|
if (cmd.lba != -1) {
|
||||||
|
trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
|
||||||
|
cmd.lba);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.xfer > INT32_MAX) {
|
||||||
|
req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private);
|
||||||
|
} else if (ops) {
|
||||||
|
req = scsi_req_alloc(ops, d, tag, lun, hba_private);
|
||||||
} else {
|
} else {
|
||||||
req = scsi_device_alloc_req(d, tag, lun, buf, hba_private);
|
req = scsi_device_alloc_req(d, tag, lun, buf, hba_private);
|
||||||
}
|
}
|
||||||
|
@ -1186,6 +1194,7 @@ static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
cmd->lba = -1;
|
||||||
switch (buf[0] >> 5) {
|
switch (buf[0] >> 5) {
|
||||||
case 0:
|
case 0:
|
||||||
cmd->len = 6;
|
cmd->len = 6;
|
||||||
|
|
Loading…
Reference in New Issue