qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Hannes Reinecke <hare@suse.de>
Subject: [Qemu-devel] [PATCH v5 13/25] scsi: Update sense code handling
Date: Thu, 26 May 2011 12:56:39 +0200	[thread overview]
Message-ID: <1306407411-4290-14-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1306407411-4290-1-git-send-email-pbonzini@redhat.com>

From: Hannes Reinecke <hare@suse.de>

The SCSI spec has a quite detailed list of sense codes available.
It even mandates the use of specific ones for some failure cases.
The current implementation just has one type of generic error
which is actually a violation of the spec in certain cases.
This patch introduces various predefined sense codes to have the
sense code reporting more in line with the spec.

On top of Hannes's patch I fixed the reply to REQUEST SENSE commands
with DESC=0 and a small (<18) length.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 hw/scsi-bus.c     |   91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/scsi-disk.c    |   82 ++++++++++++++++++++++-------------------------
 hw/scsi-generic.c |   63 ++++++++++++++++++++++++-------------
 hw/scsi.h         |   39 ++++++++++++++++++++++-
 4 files changed, 208 insertions(+), 67 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 20bffe2..732772a 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -154,7 +154,7 @@ void scsi_req_enqueue(SCSIRequest *req)
     QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
 }
 
-void scsi_req_dequeue(SCSIRequest *req)
+static void scsi_req_dequeue(SCSIRequest *req)
 {
     trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag);
     if (req->enqueued) {
@@ -391,6 +391,95 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
     return 0;
 }
 
+/*
+ * Predefined sense codes
+ */
+
+/* No sense data available */
+const struct SCSISense sense_code_NO_SENSE = {
+    .key = NO_SENSE , .asc = 0x00 , .ascq = 0x00
+};
+
+/* LUN not ready, Manual intervention required */
+const struct SCSISense sense_code_LUN_NOT_READY = {
+    .key = NOT_READY, .asc = 0x04, .ascq = 0x03
+};
+
+/* LUN not ready, Medium not present */
+const struct SCSISense sense_code_NO_MEDIUM = {
+    .key = NOT_READY, .asc = 0x3a, .ascq = 0x00
+};
+
+/* Hardware error, internal target failure */
+const struct SCSISense sense_code_TARGET_FAILURE = {
+    .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
+};
+
+/* Illegal request, invalid command operation code */
+const struct SCSISense sense_code_INVALID_OPCODE = {
+    .key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00
+};
+
+/* Illegal request, LBA out of range */
+const struct SCSISense sense_code_LBA_OUT_OF_RANGE = {
+    .key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00
+};
+
+/* Illegal request, Invalid field in CDB */
+const struct SCSISense sense_code_INVALID_FIELD = {
+    .key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00
+};
+
+/* Illegal request, LUN not supported */
+const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
+    .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
+};
+
+/* Command aborted, I/O process terminated */
+const struct SCSISense sense_code_IO_ERROR = {
+    .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
+};
+
+/* Command aborted, I_T Nexus loss occurred */
+const struct SCSISense sense_code_I_T_NEXUS_LOSS = {
+    .key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07
+};
+
+/* Command aborted, Logical Unit failure */
+const struct SCSISense sense_code_LUN_FAILURE = {
+    .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
+};
+
+/*
+ * scsi_build_sense
+ *
+ * Build a sense buffer
+ */
+int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed)
+{
+    if (!fixed && len < 8) {
+        return 0;
+    }
+
+    memset(buf, 0, len);
+    if (fixed) {
+        /* Return fixed format sense buffer */
+        buf[0] = 0xf0;
+        buf[2] = sense.key;
+        buf[7] = 7;
+        buf[12] = sense.asc;
+        buf[13] = sense.ascq;
+        return MIN(len, 18);
+    } else {
+        /* Return descriptor format sense buffer */
+        buf[0] = 0x72;
+        buf[1] = sense.key;
+        buf[2] = sense.asc;
+        buf[3] = sense.ascq;
+        return 8;
+    }
+}
+
 static const char *scsi_command_name(uint8_t cmd)
 {
     static const char *names[] = {
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 08633db..63aa8f1 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -49,10 +49,6 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 
 typedef struct SCSIDiskState SCSIDiskState;
 
-typedef struct SCSISense {
-    uint8_t key;
-} SCSISense;
-
 typedef struct SCSIDiskReq {
     SCSIRequest req;
     /* ??? We should probably keep track of whether the data transfer is
@@ -111,24 +107,19 @@ static void scsi_disk_clear_sense(SCSIDiskState *s)
     memset(&s->sense, 0, sizeof(s->sense));
 }
 
-static void scsi_disk_set_sense(SCSIDiskState *s, uint8_t key)
-{
-    s->sense.key = key;
-}
-
-static void scsi_req_set_status(SCSIDiskReq *r, int status, int sense_code)
+static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
 
     r->req.status = status;
-    scsi_disk_set_sense(s, sense_code);
+    s->sense = sense;
 }
 
 /* Helper function for command completion.  */
-static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
+static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
 {
-    DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
-            r->req.tag, status, sense);
+    DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
+            r->req.tag, status, sense.key, sense.asc, sense.ascq);
     scsi_req_set_status(r, status, sense);
     scsi_req_complete(&r->req);
 }
@@ -182,7 +173,7 @@ static void scsi_read_data(SCSIRequest *req)
     }
     DPRINTF("Read sector_count=%d\n", r->sector_count);
     if (r->sector_count == 0) {
-        scsi_command_complete(r, GOOD, NO_SENSE);
+        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
         return;
     }
 
@@ -225,8 +216,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
         if (type == SCSI_REQ_STATUS_RETRY_READ) {
             scsi_req_data(&r->req, 0);
         }
-        scsi_command_complete(r, CHECK_CONDITION,
-                HARDWARE_ERROR);
+        if (error == ENOMEM) {
+            scsi_command_complete(r, CHECK_CONDITION,
+                                  SENSE_CODE(TARGET_FAILURE));
+        } else {
+            scsi_command_complete(r, CHECK_CONDITION,
+                                  SENSE_CODE(IO_ERROR));
+        }
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
     }
 
@@ -251,7 +247,7 @@ static void scsi_write_complete(void * opaque, int ret)
     r->sector += n;
     r->sector_count -= n;
     if (r->sector_count == 0) {
-        scsi_command_complete(r, GOOD, NO_SENSE);
+        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
     } else {
         len = r->sector_count * 512;
         if (len > SCSI_DMA_BUF_SIZE) {
@@ -278,7 +274,7 @@ static int scsi_write_data(SCSIRequest *req)
         r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
                                    scsi_write_complete, r);
         if (r->req.aiocb == NULL) {
-            scsi_write_complete(r, -EIO);
+            scsi_write_complete(r, -ENOMEM);
         }
     } else {
         /* Invoke completion routine to fetch data from host.  */
@@ -316,7 +312,7 @@ static void scsi_dma_restart_bh(void *opaque)
             case SCSI_REQ_STATUS_RETRY_FLUSH:
                 ret = scsi_disk_emulate_command(r, r->iov.iov_base);
                 if (ret == 0) {
-                    scsi_command_complete(r, GOOD, NO_SENSE);
+                    scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
                 }
             }
         }
@@ -815,19 +811,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
     case REQUEST_SENSE:
         if (req->cmd.xfer < 4)
             goto illegal_request;
-        memset(outbuf, 0, 4);
-        buflen = 4;
-        if (s->sense.key == NOT_READY && req->cmd.xfer >= 18) {
-            memset(outbuf, 0, 18);
-            buflen = 18;
-            outbuf[7] = 10;
-            /* asc 0x3a, ascq 0: Medium not present */
-            outbuf[12] = 0x3a;
-            outbuf[13] = 0;
-        }
-        outbuf[0] = 0xf0;
-        outbuf[1] = 0;
-        outbuf[2] = s->sense.key;
+        buflen = scsi_build_sense(s->sense, outbuf, req->cmd.xfer,
+                                  req->cmd.xfer > 13);
         scsi_disk_clear_sense(s);
         break;
     case INQUIRY:
@@ -965,17 +950,22 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         }
         break;
     default:
-        goto illegal_request;
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        return -1;
     }
-    scsi_req_set_status(r, GOOD, NO_SENSE);
+    scsi_req_set_status(r, GOOD, SENSE_CODE(NO_SENSE));
     return buflen;
 
 not_ready:
-    scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
+    if (!bdrv_is_inserted(s->bs)) {
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(NO_MEDIUM));
+    } else {
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LUN_NOT_READY));
+    }
     return -1;
 
 illegal_request:
-    scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
+    scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
     return -1;
 }
 
@@ -1002,7 +992,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
 
     if (scsi_req_parse(&r->req, buf) != 0) {
         BADF("Unsupported command length, command %x\n", command);
-        goto fail;
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        return 0;
     }
 #ifdef DEBUG_SCSI
     {
@@ -1017,8 +1008,11 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     if (req->lun || buf[1] >> 5) {
         /* Only LUN 0 supported.  */
         DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : buf[1] >> 5);
-        if (command != REQUEST_SENSE && command != INQUIRY)
-            goto fail;
+        if (command != REQUEST_SENSE && command != INQUIRY) {
+            scsi_command_complete(r, CHECK_CONDITION,
+                                  SENSE_CODE(LUN_NOT_SUPPORTED));
+            return 0;
+        }
     }
     switch (command) {
     case TEST_UNIT_READY:
@@ -1126,15 +1120,17 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         break;
     default:
         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        return 0;
     fail:
-        scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
         return 0;
     illegal_lba:
-        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
+        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
     }
     if (r->sector_count == 0 && r->iov.iov_len == 0) {
-        scsi_command_complete(r, GOOD, NO_SENSE);
+        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
     }
     len = r->sector_count * 512 + r->iov.iov_len;
     if (is_write) {
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 229d24f..64cbe8b 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -66,6 +66,19 @@ struct SCSIGenericState
     uint8_t senselen;
 };
 
+static void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
+{
+    s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
+    s->driver_status = SG_ERR_DRIVER_SENSE;
+}
+
+static void scsi_clear_sense(SCSIGenericState *s)
+{
+    memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
+    s->senselen = 0;
+    s->driver_status = 0;
+}
+
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
 {
     SCSIRequest *req;
@@ -92,9 +105,22 @@ static void scsi_command_complete(void *opaque, int ret)
     if (s->driver_status & SG_ERR_DRIVER_SENSE)
         s->senselen = r->io_header.sb_len_wr;
 
-    if (ret != 0)
-        r->req.status = BUSY;
-    else {
+    if (ret != 0) {
+        switch (ret) {
+        case -EINVAL:
+            r->req.status = CHECK_CONDITION;
+            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
+            break;
+        case -ENOMEM:
+            r->req.status = CHECK_CONDITION;
+            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
+            break;
+        default:
+            r->req.status = CHECK_CONDITION;
+            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
+            break;
+        }
+    } else {
         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
             r->req.status = BUSY;
             BADF("Driver Timeout\n");
@@ -144,7 +170,7 @@ static int execute_command(BlockDriverState *bdrv,
     r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
     if (r->req.aiocb == NULL) {
         BADF("execute_command: read failed !\n");
-        return -1;
+        return -ENOMEM;
     }
 
     return 0;
@@ -198,12 +224,14 @@ static void scsi_read_data(SCSIRequest *req)
                 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
                 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
         scsi_req_data(&r->req, s->senselen);
+        /* Clear sensebuf after REQUEST_SENSE */
+        scsi_clear_sense(s);
         return;
     }
 
     ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
-    if (ret == -1) {
-        scsi_command_complete(r, -EINVAL);
+    if (ret < 0) {
+        scsi_command_complete(r, ret);
         return;
     }
 }
@@ -246,8 +274,8 @@ static int scsi_write_data(SCSIRequest *req)
     }
 
     ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
-    if (ret == -1) {
-        scsi_command_complete(r, -EINVAL);
+    if (ret < 0) {
+        scsi_command_complete(r, ret);
         return 1;
     }
 
@@ -296,16 +324,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     if (cmd[0] != REQUEST_SENSE &&
         (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
         DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
-
-        s->sensebuf[0] = 0x70;
-        s->sensebuf[1] = 0x00;
-        s->sensebuf[2] = ILLEGAL_REQUEST;
-        s->sensebuf[3] = 0x00;
-        s->sensebuf[4] = 0x00;
-        s->sensebuf[5] = 0x00;
-        s->sensebuf[6] = 0x00;
-        s->senselen = 7;
-        s->driver_status = SG_ERR_DRIVER_SENSE;
+        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
         r->req.status = CHECK_CONDITION;
         scsi_req_complete(&r->req);
         return 0;
@@ -313,8 +332,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 
     if (-1 == scsi_req_parse(&r->req, cmd)) {
         BADF("Unsupported command length, command %x\n", cmd[0]);
-        scsi_req_dequeue(&r->req);
-        scsi_req_unref(&r->req);
+        scsi_command_complete(r, -EINVAL);
         return 0;
     }
     scsi_req_fixup(&r->req);
@@ -338,8 +356,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
         r->buflen = 0;
         r->buf = NULL;
         ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
-        if (ret == -1) {
-            scsi_command_complete(r, -EINVAL);
+        if (ret < 0) {
+            scsi_command_complete(r, ret);
+            return 0;
         }
         return 0;
     }
diff --git a/hw/scsi.h b/hw/scsi.h
index e2dc7cb..7a7c9ef 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -27,6 +27,12 @@ enum SCSIXferMode {
     SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
 };
 
+typedef struct SCSISense {
+    uint8_t key;
+    uint8_t asc;
+    uint8_t ascq;
+} SCSISense;
+
 struct SCSIRequest {
     SCSIBus           *bus;
     SCSIDevice        *dev;
@@ -104,10 +110,41 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                       int unit, bool removable);
 int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
 
+/*
+ * Predefined sense codes
+ */
+
+/* No sense data available */
+extern const struct SCSISense sense_code_NO_SENSE;
+/* LUN not ready, Manual intervention required */
+extern const struct SCSISense sense_code_LUN_NOT_READY;
+/* LUN not ready, Medium not present */
+extern const struct SCSISense sense_code_NO_MEDIUM;
+/* Hardware error, internal target failure */
+extern const struct SCSISense sense_code_TARGET_FAILURE;
+/* Illegal request, invalid command operation code */
+extern const struct SCSISense sense_code_INVALID_OPCODE;
+/* Illegal request, LBA out of range */
+extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
+/* Illegal request, Invalid field in CDB */
+extern const struct SCSISense sense_code_INVALID_FIELD;
+/* Illegal request, LUN not supported */
+extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
+/* Command aborted, I/O process terminated */
+extern const struct SCSISense sense_code_IO_ERROR;
+/* Command aborted, I_T Nexus loss occurred */
+extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
+/* Command aborted, Logical Unit failure */
+extern const struct SCSISense sense_code_LUN_FAILURE;
+
+#define SENSE_CODE(x) sense_code_ ## x
+
+int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
+int scsi_sense_valid(SCSISense sense);
+
 SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
 void scsi_req_enqueue(SCSIRequest *req);
 void scsi_req_free(SCSIRequest *req);
-void scsi_req_dequeue(SCSIRequest *req);
 SCSIRequest *scsi_req_ref(SCSIRequest *req);
 void scsi_req_unref(SCSIRequest *req);
 
-- 
1.7.4.4

  parent reply	other threads:[~2011-05-26 10:57 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-26 10:56 [Qemu-devel] [PULL v5 00/25] SCSI subsystem improvements Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 01/25] scsi: add tracing of scsi requests Paolo Bonzini
2011-05-26 20:20   ` Blue Swirl
2011-05-27  8:32     ` Stefan Hajnoczi
2011-05-27 12:43       ` Paolo Bonzini
2011-05-27 12:51   ` [Qemu-devel] [PATCH v6 " Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 02/25] scsi-generic: Remove bogus double complete Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 03/25] scsi: introduce scsi_req_data Paolo Bonzini
2011-05-27 12:51   ` [Qemu-devel] [PATCH v6 " Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 04/25] scsi: introduce SCSIBusOps Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 05/25] scsi-generic: do not use a stale aiocb Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 06/25] scsi: reference-count requests Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 07/25] lsi: extract lsi_find_by_tag Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 08/25] scsi: Use 'SCSIRequest' directly Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 09/25] scsi: commonize purging requests Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 10/25] scsi: introduce scsi_req_abort Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 11/25] scsi: introduce scsi_req_cancel Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 12/25] scsi: use scsi_req_complete Paolo Bonzini
2011-05-26 10:56 ` Paolo Bonzini [this message]
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 14/25] scsi: do not call send_command directly Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 15/25] scsi: introduce scsi_req_new Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 16/25] scsi: introduce scsi_req_continue Paolo Bonzini
2011-05-27 12:51   ` [Qemu-devel] [PATCH v6 " Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 17/25] scsi: introduce scsi_req_get_buf Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 18/25] scsi: Implement 'get_sense' callback Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 19/25] scsi-disk: add data direction checking Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 20/25] scsi: make write_data return void Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 21/25] scsi-generic: Handle queue full Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 22/25] esp: rename sense to status Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 23/25] scsi: split command_complete callback in two Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 24/25] scsi: rename arguments to the new callbacks Paolo Bonzini
2011-05-26 10:56 ` [Qemu-devel] [PATCH v5 25/25] scsi: ignore LUN field in the CDB Paolo Bonzini
2011-05-31 13:38 ` [Qemu-devel] [PULL v5 00/25] SCSI subsystem improvements Anthony Liguori
2011-06-02 14:54   ` Andreas Färber
2011-06-03  6:58     ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1306407411-4290-14-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=hare@suse.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).