On Tue, 2010-06-15 at 17:16 +0200, Hannes Reinecke wrote: > Any SCSI emulation is supposed to return status codes as defined > by SAM, not the linux ones which are shifted by one. > > Signed-off-by: Hannes Reinecke <h...@suse.de> > --- > hw/megasas.c | 12 +++++++----- > hw/scsi-bus.c | 4 +++- > hw/scsi-defs.h | 20 +++++++++++--------- > hw/scsi-generic.c | 12 ++++++------ > 4 files changed, 27 insertions(+), 21 deletions(-) >
Wow, good catch. Commited. --nab > diff --git a/hw/megasas.c b/hw/megasas.c > index 6ddb757..bc35566 100644 > --- a/hw/megasas.c > +++ b/hw/megasas.c > @@ -1125,7 +1125,7 @@ static int megasas_handle_scsi(MPTState *s, struct > megasas_cmd_t *cmd, int is_lo > cmd->frame->header.target_id, cmd->frame->header.lun_id, > cmd->frame->header.cdb_len); > megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE)); > - megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1); > + megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION); > s->event_count++; > return MFI_STAT_SCSI_DONE_WITH_ERROR; > } > @@ -1177,7 +1177,7 @@ static int megasas_handle_io(MPTState *s, struct > megasas_cmd_t *cmd) > cmd->frame->header.target_id, cmd->frame->header.lun_id, > cmd->frame->header.cdb_len); > megasas_build_sense(cmd, SENSE_CODE(INVALID_OPCODE)); > - megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION << 1); > + megasas_frame_set_scsi_status(cmd->pa, CHECK_CONDITION); > s->event_count++; > return MFI_STAT_SCSI_DONE_WITH_ERROR; > } > @@ -1236,9 +1236,11 @@ static void megasas_command_complete(SCSIRequest *req) > DPRINTF_IO("%s req %p cmd %p lun %p finished with status %x len > %u\n", > mfi_frame_desc[cmd->frame->header.frame_cmd], req, cmd, > cmd->sdev, > req->status, (unsigned)req->xferlen); > - if (req->status == CHECK_CONDITION << 1) { > - megasas_build_sense(cmd, cmd->sdev->sense); > + if (req->status != GOOD) { > cmd_status = MFI_STAT_SCSI_DONE_WITH_ERROR; > + } > + if (req->status == CHECK_CONDITION) { > + megasas_build_sense(cmd, cmd->sdev->sense); > scsi_dev_clear_sense(cmd->sdev); > } > > @@ -1302,7 +1304,7 @@ static void megasas_handle_frame(MPTState *s, > target_phys_addr_t frame_addr, > cmd = megasas_enqueue_frame(s, frame_addr); > if (!cmd) { > /* reply queue full */ > - megasas_frame_set_scsi_status(frame_addr, BUSY << 1); > + megasas_frame_set_scsi_status(frame_addr, BUSY); > frame_status = MFI_STAT_SCSI_DONE_WITH_ERROR; > s->event_count++; > goto frame_done; > diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c > index 7d80405..c0e6dd3 100644 > --- a/hw/scsi-bus.c > +++ b/hw/scsi-bus.c > @@ -525,7 +525,9 @@ const char *scsi_status_name(uint8_t status) > [ INTERMEDIATE_C_GOOD ] = "INTERMEDIATE_C_GOOD", > [ RESERVATION_CONFLICT ] = "RESERVATION_CONFLICT", > [ COMMAND_TERMINATED ] = "COMMAND_TERMINATED", > - [ QUEUE_FULL ] = "QUEUE_FULL", > + [ TASK_SET_FULL ] = "TASK_SET_FULL", > + [ ACA_ACTIVE ] = "ACA_ACTIVE", > + [ TASK_ABORTED ] = "TASK_ABORTED", > }; > > if (status >= ARRAY_SIZE(names) || names[status] == NULL) > diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h > index a4a3518..1473ecb 100644 > --- a/hw/scsi-defs.h > +++ b/hw/scsi-defs.h > @@ -111,18 +111,20 @@ > #define BLANK 0xa1 > > /* > - * Status codes > + * SAM Status codes > */ > > #define GOOD 0x00 > -#define CHECK_CONDITION 0x01 > -#define CONDITION_GOOD 0x02 > -#define BUSY 0x04 > -#define INTERMEDIATE_GOOD 0x08 > -#define INTERMEDIATE_C_GOOD 0x0a > -#define RESERVATION_CONFLICT 0x0c > -#define COMMAND_TERMINATED 0x11 > -#define QUEUE_FULL 0x14 > +#define CHECK_CONDITION 0x02 > +#define CONDITION_GOOD 0x04 > +#define BUSY 0x08 > +#define INTERMEDIATE_GOOD 0x10 > +#define INTERMEDIATE_C_GOOD 0x14 > +#define RESERVATION_CONFLICT 0x18 > +#define COMMAND_TERMINATED 0x22 > +#define TASK_SET_FULL 0x28 > +#define ACA_ACTIVE 0x30 > +#define TASK_ABORTED 0x40 > > #define STATUS_MASK 0x3e > > diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c > index af76826..33d7e52 100644 > --- a/hw/scsi-generic.c > +++ b/hw/scsi-generic.c > @@ -99,7 +99,7 @@ static void scsi_command_complete(void *opaque, int ret) > if (ret == -EDOM) { > /* sg driver uses EDOM to signal queue busy */ > fprintf(stderr, "%s: sg queue busy\n", __FUNCTION__); > - r->req.status = QUEUE_FULL << 1; > + r->req.status = TASK_SET_FULL; > } else { > scsi_req_print(&r->req); > fprintf(stderr, "%s: ret %d (%s)\n", __FUNCTION__, > @@ -107,13 +107,13 @@ static void scsi_command_complete(void *opaque, int ret) > s->senselen = scsi_build_sense(SENSE_CODE(INVALID_FIELD), > s->sensebuf, SCSI_SENSE_BUF_SIZE, 0); > s->driver_status = SG_ERR_DRIVER_SENSE; > - r->req.status = CHECK_CONDITION << 1; > + r->req.status = CHECK_CONDITION; > } > } else { > if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) { > scsi_req_print(&r->req); > fprintf(stderr, "%s: timeout\n", __FUNCTION__); > - r->req.status = BUSY << 1; > + r->req.status = BUSY; > } else if (r->io_header.status) { > #if 0 > scsi_req_print(&r->req); > @@ -124,9 +124,9 @@ static void scsi_command_complete(void *opaque, int ret) > } else if (s->driver_status & SG_ERR_DRIVER_SENSE) { > scsi_req_print(&r->req); > fprintf(stderr, "%s: driver sense\n", __FUNCTION__); > - r->req.status = CHECK_CONDITION << 1; > + r->req.status = CHECK_CONDITION; > } else { > - r->req.status = GOOD << 1; > + r->req.status = GOOD; > } > } > DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", > @@ -451,7 +451,7 @@ static int scsi_generic_req_common(SCSIRequest *req, > uint8_t *buffer) > s->senselen = scsi_build_sense(SENSE_CODE(LUN_NOT_SUPPORTED), > s->sensebuf, SCSI_SENSE_BUF_SIZE, 0); > s->driver_status = SG_ERR_DRIVER_SENSE; > - req->status = CHECK_CONDITION << 1; > + req->status = CHECK_CONDITION; > return 1; > } > if (r->req.cmd.buf[0] == REQUEST_SENSE &&