diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2011-10-12 14:53:43 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-10-28 19:25:51 +0200 |
commit | a3b16e71ab733f76104231b873dff48d43fb3890 (patch) | |
tree | 54fd672ba7870142d2bbee024dfce83dfe817c90 /hw/scsi-generic.c | |
parent | fe0ed71279eb442b920f0080c763438dbaa09f74 (diff) | |
download | qemu-a3b16e71ab733f76104231b873dff48d43fb3890.zip qemu-a3b16e71ab733f76104231b873dff48d43fb3890.tar.gz qemu-a3b16e71ab733f76104231b873dff48d43fb3890.tar.bz2 |
scsi-generic: look at host status
Pass down the host status so that failing transport can be detected
by the guest. Similar treatment of host status could be done in
virtio-blk, too.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/scsi-generic.c')
-rw-r--r-- | hw/scsi-generic.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index c313749..5ad3d57 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -39,8 +39,13 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0) #define SCSI_SENSE_BUF_SIZE 96 -#define SG_ERR_DRIVER_TIMEOUT 0x06 -#define SG_ERR_DRIVER_SENSE 0x08 +#define SG_ERR_DRIVER_TIMEOUT 0x06 +#define SG_ERR_DRIVER_SENSE 0x08 + +#define SG_ERR_DID_OK 0x00 +#define SG_ERR_DID_NO_CONNECT 0x01 +#define SG_ERR_DID_BUS_BUSY 0x02 +#define SG_ERR_DID_TIME_OUT 0x03 #ifndef MAX_UINT #define MAX_UINT ((unsigned int)-1) @@ -68,8 +73,9 @@ static void scsi_command_complete(void *opaque, int ret) SCSIGenericReq *r = (SCSIGenericReq *)opaque; r->req.aiocb = NULL; - if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) + if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { r->req.sense_len = r->io_header.sb_len_wr; + } if (ret != 0) { switch (ret) { @@ -86,9 +92,15 @@ static void scsi_command_complete(void *opaque, int ret) break; } } else { - if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) { + if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT || + r->io_header.host_status == SG_ERR_DID_BUS_BUSY || + r->io_header.host_status == SG_ERR_DID_TIME_OUT || + (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) { status = BUSY; BADF("Driver Timeout\n"); + } else if (r->io_header.host_status) { + status = CHECK_CONDITION; + scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS)); } else if (r->io_header.status) { status = r->io_header.status; } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { |