qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] scsi_command_complete() sends invalid values
@ 2008-09-26 15:08 Laurent Vivier
  2008-09-26 15:40 ` Anthony Liguori
  0 siblings, 1 reply; 3+ messages in thread
From: Laurent Vivier @ 2008-09-26 15:08 UTC (permalink / raw)
  To: qemu-devel@nongnu.org; +Cc: Paul Brook

[-- Attachment #1: Type: text/plain, Size: 1524 bytes --]

Hi,

it seems there are some inconsistencies between hw/lsi53c895a.c,
hw/scsi-disk.c and what linux driver is waiting (I found this by tracing
the linux driver).

The sense value sent by qemu/hw/scsi-disk.c in:

static void scsi_command_complete(SCSIRequest *r, int sense)
{
    SCSIDeviceState *s = r->dev;
    uint32_t tag;
    DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
    s->sense = sense;
    tag = r->tag;
    scsi_remove_request(r);
    s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
}

is decoded by linux/drivers/scsi/sym53c8xx_2/sym_hipd.c,
sym_sir_bad_scsi_status(), in s_status, and must be one of these values:

drivers/scsi/sym53c8xx_2/sym_defs.h

#define S_GOOD          SAM_STAT_GOOD
#define S_CHECK_COND    SAM_STAT_CHECK_CONDITION
#define S_COND_MET      SAM_STAT_CONDITION_MET
#define S_BUSY          SAM_STAT_BUSY
#define S_INT           SAM_STAT_INTERMEDIATE
#define S_INT_COND_MET  SAM_STAT_INTERMEDIATE_CONDITION_MET
#define S_CONFLICT      SAM_STAT_RESERVATION_CONFLICT
#define S_TERMINATED    SAM_STAT_COMMAND_TERMINATED
#define S_QUEUE_FULL    SAM_STAT_TASK_SET_FULL
#define S_ILLEGAL       (0xff)

The attached patch is a try to correct this.

It corrects also hw/scsi-generic.c, allowing to use commands like "mt
eod" or "mt fsf 4" on a SCSI stream device (tape).

Regards,
Laurent
-- 
----------------- Laurent.Vivier@bull.net  ------------------
"Programmers who subconsciously view themselves as artists
 will enjoy what they do and will do it better." D. Knuth

[-- Attachment #2: scsi-status.patch --]
[-- Type: text/x-patch, Size: 4905 bytes --]

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
 hw/scsi-disk.c    |   28 ++++++++++++++--------------
 hw/scsi-generic.c |    8 ++++----
 2 files changed, 18 insertions(+), 18 deletions(-)

Index: qemu/hw/scsi-generic.c
===================================================================
--- qemu.orig/hw/scsi-generic.c	2008-09-26 17:00:54.000000000 +0200
+++ qemu/hw/scsi-generic.c	2008-09-26 17:00:58.000000000 +0200
@@ -158,15 +158,15 @@ static void scsi_command_complete(void *
 
     s->driver_status = r->io_header.driver_status;
     if (ret != 0)
-        sense = HARDWARE_ERROR;
+        sense = CHECK_CONDITION;
     else {
         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
-            sense = HARDWARE_ERROR;
+            sense = CHECK_CONDITION;
             BADF("Driver Timeout\n");
         } else if ((s->driver_status & SG_ERR_DRIVER_SENSE) == 0)
-            sense = NO_SENSE;
+            sense = GOOD;
         else
-            sense = s->sensebuf[2];
+            sense = CHECK_CONDITION;
     }
 
     DPRINTF("Command complete 0x%p tag=0x%x sense=%d\n", r, r->tag, sense);
Index: qemu/hw/scsi-disk.c
===================================================================
--- qemu.orig/hw/scsi-disk.c	2008-09-26 17:00:51.000000000 +0200
+++ qemu/hw/scsi-disk.c	2008-09-26 17:00:58.000000000 +0200
@@ -29,10 +29,10 @@ do { fprintf(stderr, "scsi-disk: " fmt ,
 #include "block.h"
 #include "scsi-disk.h"
 
-#define SENSE_NO_SENSE        0
-#define SENSE_NOT_READY       2
-#define SENSE_HARDWARE_ERROR  4
-#define SENSE_ILLEGAL_REQUEST 5
+#define STATUS_GOOD            0
+#define STATUS_CHECK_CONDITION 1
+#define STATUS_BUSY            4
+#define STATUS_ILLEGAL         (0xff)
 
 #define SCSI_DMA_BUF_SIZE    131072
 
@@ -157,7 +157,7 @@ static void scsi_read_complete(void * op
 
     if (ret) {
         DPRINTF("IO error\n");
-        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
+        scsi_command_complete(r, STATUS_CHECK_CONDITION);
         return;
     }
     DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
@@ -176,7 +176,7 @@ static void scsi_read_data(SCSIDevice *d
     if (!r) {
         BADF("Bad read tag 0x%x\n", tag);
         /* ??? This is the wrong error.  */
-        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
+        scsi_command_complete(r, STATUS_CHECK_CONDITION);
         return;
     }
     if (r->sector_count == (uint32_t)-1) {
@@ -187,7 +187,7 @@ static void scsi_read_data(SCSIDevice *d
     }
     DPRINTF("Read sector_count=%d\n", r->sector_count);
     if (r->sector_count == 0) {
-        scsi_command_complete(r, SENSE_NO_SENSE);
+        scsi_command_complete(r, STATUS_GOOD);
         return;
     }
 
@@ -199,7 +199,7 @@ static void scsi_read_data(SCSIDevice *d
     r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
                              scsi_read_complete, r);
     if (r->aiocb == NULL)
-        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
+        scsi_command_complete(r, STATUS_CHECK_CONDITION);
     r->sector += n;
     r->sector_count -= n;
 }
@@ -217,7 +217,7 @@ static void scsi_write_complete(void * o
 
     r->aiocb = NULL;
     if (r->sector_count == 0) {
-        scsi_command_complete(r, SENSE_NO_SENSE);
+        scsi_command_complete(r, STATUS_GOOD);
     } else {
         len = r->sector_count * 512;
         if (len > SCSI_DMA_BUF_SIZE) {
@@ -241,7 +241,7 @@ static int scsi_write_data(SCSIDevice *d
     r = scsi_find_request(s, tag);
     if (!r) {
         BADF("Bad write tag 0x%x\n", tag);
-        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
+        scsi_command_complete(r, STATUS_CHECK_CONDITION);
         return 1;
     }
     if (r->aiocb)
@@ -251,7 +251,7 @@ static int scsi_write_data(SCSIDevice *d
         r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
                                   scsi_write_complete, r);
         if (r->aiocb == NULL)
-            scsi_command_complete(r, SENSE_HARDWARE_ERROR);
+            scsi_command_complete(r, STATUS_CHECK_CONDITION);
         r->sector += n;
         r->sector_count -= n;
     } else {
@@ -670,7 +670,7 @@ static int32_t scsi_send_command(SCSIDev
             outbuf[7] = 0;
             r->buf_len = 8;
         } else {
-            scsi_command_complete(r, SENSE_NOT_READY);
+            scsi_command_complete(r, STATUS_BUSY);
             return 0;
         }
 	break;
@@ -757,11 +757,11 @@ static int32_t scsi_send_command(SCSIDev
     default:
 	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
     fail:
-        scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
+        scsi_command_complete(r, STATUS_ILLEGAL);
 	return 0;
     }
     if (r->sector_count == 0 && r->buf_len == 0) {
-        scsi_command_complete(r, SENSE_NO_SENSE);
+        scsi_command_complete(r, STATUS_GOOD);
     }
     len = r->sector_count * 512 + r->buf_len;
     if (is_write) {

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-09-26 22:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-26 15:08 [Qemu-devel] [PATCH] scsi_command_complete() sends invalid values Laurent Vivier
2008-09-26 15:40 ` Anthony Liguori
2008-09-26 22:10   ` Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).