* [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups.
@ 2009-11-17 10:17 Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection Gerd Hoffmann
` (15 more replies)
0 siblings, 16 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
First batch of scsi patches. They bring some data structure unification
and a bunch of fixes and cleanups. In preparation for the other scsi
patches, but also useful on its own IMHO, so I'm hoping for a quick and
painless merge.
The major rewrite which needs more discussion and regression testing
is not included here.
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:11 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure Gerd Hoffmann
` (14 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Also delete the leftover and unused scsi-disk.h file.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/esp.h | 5 ++++
hw/scsi-disk.h | 67 --------------------------------------------------------
hw/scsi.h | 4 +-
3 files changed, 7 insertions(+), 69 deletions(-)
delete mode 100644 hw/scsi-disk.h
diff --git a/hw/esp.h b/hw/esp.h
index 369998f..190bc2e 100644
--- a/hw/esp.h
+++ b/hw/esp.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_HW_ESP_H
+#define QEMU_HW_ESP_H
+
/* esp.c */
#define ESP_MAX_DEVS 7
typedef void (*espdma_memory_read_write)(void *opaque, uint8_t *buf, int len);
@@ -5,3 +8,5 @@ void esp_init(target_phys_addr_t espaddr, int it_shift,
espdma_memory_read_write dma_memory_read,
espdma_memory_read_write dma_memory_write,
void *dma_opaque, qemu_irq irq, qemu_irq *reset);
+
+#endif
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
deleted file mode 100644
index b6b6c12..0000000
--- a/hw/scsi-disk.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef SCSI_DISK_H
-#define SCSI_DISK_H
-
-#include "qdev.h"
-
-/* scsi-disk.c */
-enum scsi_reason {
- SCSI_REASON_DONE, /* Command complete. */
- SCSI_REASON_DATA /* Transfer complete, more data required. */
-};
-
-typedef struct SCSIBus SCSIBus;
-typedef struct SCSIDevice SCSIDevice;
-typedef struct SCSIDeviceInfo SCSIDeviceInfo;
-typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag,
- uint32_t arg);
-
-struct SCSIDevice
-{
- DeviceState qdev;
- uint32_t id;
- SCSIDeviceInfo *info;
-};
-
-/* cdrom.c */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-
-/* scsi-bus.c */
-typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
-struct SCSIDeviceInfo {
- DeviceInfo qdev;
- scsi_qdev_initfn init;
- void (*destroy)(SCSIDevice *s);
- int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
- int lun);
- void (*read_data)(SCSIDevice *s, uint32_t tag);
- int (*write_data)(SCSIDevice *s, uint32_t tag);
- void (*cancel_io)(SCSIDevice *s, uint32_t tag);
- uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag);
-};
-
-typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
- int unit);
-struct SCSIBus {
- BusState qbus;
- int busnr;
-
- int tcq, ndev;
- scsi_completionfn complete;
-
- SCSIDevice *devs[8];
-};
-
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
- scsi_completionfn complete);
-void scsi_qdev_register(SCSIDeviceInfo *info);
-
-static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
-{
- return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
-}
-
-SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
-void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
-
-#endif
diff --git a/hw/scsi.h b/hw/scsi.h
index b6b6c12..d2b274c 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -1,5 +1,5 @@
-#ifndef SCSI_DISK_H
-#define SCSI_DISK_H
+#ifndef QEMU_HW_SCSI_H
+#define QEMU_HW_SCSI_H
#include "qdev.h"
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:12 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ Gerd Hoffmann
` (13 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Rename the SCSIRequest structs in scsi-disk.c and scsi-generic.c to
SCSIDiskReq and SCSIGenericReq. Create a SCSIRequest struct and move
the common elements over.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-disk.c | 109 ++++++++++++++++++++++++++---------------------------
hw/scsi-generic.c | 104 +++++++++++++++++++++++++-------------------------
hw/scsi.h | 8 ++++
3 files changed, 114 insertions(+), 107 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a92b62f..142d81d 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -46,10 +46,8 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
typedef struct SCSIDiskState SCSIDiskState;
-typedef struct SCSIRequest {
- SCSIBus *bus;
- SCSIDiskState *dev;
- uint32_t tag;
+typedef struct SCSIDiskReq {
+ SCSIRequest req;
/* ??? We should probably keep track of whether the data transfer is
a read or a write. Currently we rely on the host getting it right. */
/* Both sector and sector_count are in terms of qemu 512 byte blocks. */
@@ -57,16 +55,15 @@ typedef struct SCSIRequest {
uint32_t sector_count;
struct iovec iov;
QEMUIOVector qiov;
- BlockDriverAIOCB *aiocb;
- struct SCSIRequest *next;
+ struct SCSIDiskReq *next;
uint32_t status;
-} SCSIRequest;
+} SCSIDiskReq;
struct SCSIDiskState
{
SCSIDevice qdev;
DriveInfo *dinfo;
- SCSIRequest *requests;
+ SCSIDiskReq *requests;
/* The qemu block layer uses a fixed 512 byte sector size.
This is the number of 512 byte blocks in a single scsi sector. */
int cluster_size;
@@ -77,26 +74,26 @@ struct SCSIDiskState
};
/* Global pool of SCSIRequest structures. */
-static SCSIRequest *free_requests = NULL;
+static SCSIDiskReq *free_requests = NULL;
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
+static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
- SCSIRequest *r;
+ SCSIDiskReq *r;
if (free_requests) {
r = free_requests;
free_requests = r->next;
} else {
- r = qemu_malloc(sizeof(SCSIRequest));
+ r = qemu_malloc(sizeof(SCSIDiskReq));
r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
}
- r->bus = scsi_bus_from_device(d);
- r->dev = s;
- r->tag = tag;
+ r->req.bus = scsi_bus_from_device(d);
+ r->req.dev = d;
+ r->req.tag = tag;
r->sector_count = 0;
r->iov.iov_len = 0;
- r->aiocb = NULL;
+ r->req.aiocb = NULL;
r->status = 0;
r->next = s->requests;
@@ -104,10 +101,10 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
return r;
}
-static void scsi_remove_request(SCSIRequest *r)
+static void scsi_remove_request(SCSIDiskReq *r)
{
- SCSIRequest *last;
- SCSIDiskState *s = r->dev;
+ SCSIDiskReq *last;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
if (s->requests == r) {
s->requests = r->next;
@@ -125,64 +122,65 @@ static void scsi_remove_request(SCSIRequest *r)
free_requests = r;
}
-static SCSIRequest *scsi_find_request(SCSIDiskState *s, uint32_t tag)
+static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
{
- SCSIRequest *r;
+ SCSIDiskReq *r;
r = s->requests;
- while (r && r->tag != tag)
+ while (r && r->req.tag != tag)
r = r->next;
return r;
}
/* Helper function for command completion. */
-static void scsi_command_complete(SCSIRequest *r, int status, int sense)
+static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
{
- SCSIDiskState *s = r->dev;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint32_t tag;
- DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r->tag, status, sense);
+ DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
+ r->req.tag, status, sense);
s->sense = sense;
- tag = r->tag;
+ tag = r->req.tag;
scsi_remove_request(r);
- r->bus->complete(r->bus, SCSI_REASON_DONE, tag, status);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
}
/* Cancel a pending data transfer. */
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
- SCSIRequest *r;
+ SCSIDiskReq *r;
DPRINTF("Cancel tag=0x%x\n", tag);
r = scsi_find_request(s, tag);
if (r) {
- if (r->aiocb)
- bdrv_aio_cancel(r->aiocb);
- r->aiocb = NULL;
+ if (r->req.aiocb)
+ bdrv_aio_cancel(r->req.aiocb);
+ r->req.aiocb = NULL;
scsi_remove_request(r);
}
}
static void scsi_read_complete(void * opaque, int ret)
{
- SCSIRequest *r = (SCSIRequest *)opaque;
+ SCSIDiskReq *r = (SCSIDiskReq *)opaque;
if (ret) {
DPRINTF("IO error\n");
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, 0);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0);
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
return;
}
- DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->tag, r->iov.iov_len);
+ DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->req.tag, r->iov.iov_len);
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
}
/* Read more data from scsi device into buffer. */
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
- SCSIRequest *r;
+ SCSIDiskReq *r;
uint32_t n;
r = scsi_find_request(s, tag);
@@ -195,7 +193,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
if (r->sector_count == (uint32_t)-1) {
DPRINTF("Read buf_len=%" PRId64 "\n", r->iov.iov_len);
r->sector_count = 0;
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
return;
}
DPRINTF("Read sector_count=%d\n", r->sector_count);
@@ -210,17 +208,18 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
r->iov.iov_len = n * 512;
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
- r->aiocb = bdrv_aio_readv(s->dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_readv(s->dinfo->bdrv, r->sector, &r->qiov, n,
scsi_read_complete, r);
- if (r->aiocb == NULL)
+ if (r->req.aiocb == NULL)
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
r->sector += n;
r->sector_count -= n;
}
-static int scsi_handle_write_error(SCSIRequest *r, int error)
+static int scsi_handle_write_error(SCSIDiskReq *r, int error)
{
- BlockInterfaceErrorAction action = drive_get_onerror(r->dev->dinfo->bdrv);
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+ BlockInterfaceErrorAction action = drive_get_onerror(s->dinfo->bdrv);
if (action == BLOCK_ERR_IGNORE)
return 0;
@@ -239,11 +238,11 @@ static int scsi_handle_write_error(SCSIRequest *r, int error)
static void scsi_write_complete(void * opaque, int ret)
{
- SCSIRequest *r = (SCSIRequest *)opaque;
+ SCSIDiskReq *r = (SCSIDiskReq *)opaque;
uint32_t len;
uint32_t n;
- r->aiocb = NULL;
+ r->req.aiocb = NULL;
if (ret) {
if (scsi_handle_write_error(r, -ret))
@@ -261,22 +260,22 @@ static void scsi_write_complete(void * opaque, int ret)
len = SCSI_DMA_BUF_SIZE;
}
r->iov.iov_len = len;
- DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, len);
+ DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
}
}
-static void scsi_write_request(SCSIRequest *r)
+static void scsi_write_request(SCSIDiskReq *r)
{
- SCSIDiskState *s = r->dev;
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint32_t n;
n = r->iov.iov_len / 512;
if (n) {
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
- r->aiocb = bdrv_aio_writev(s->dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_writev(s->dinfo->bdrv, r->sector, &r->qiov, n,
scsi_write_complete, r);
- if (r->aiocb == NULL)
+ if (r->req.aiocb == NULL)
scsi_command_complete(r, STATUS_CHECK_CONDITION,
SENSE_HARDWARE_ERROR);
} else {
@@ -290,7 +289,7 @@ static void scsi_write_request(SCSIRequest *r)
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
- SCSIRequest *r;
+ SCSIDiskReq *r;
DPRINTF("Write data tag=0x%x\n", tag);
r = scsi_find_request(s, tag);
@@ -300,7 +299,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
return 1;
}
- if (r->aiocb)
+ if (r->req.aiocb)
BADF("Data transfer already in progress\n");
scsi_write_request(r);
@@ -311,7 +310,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
static void scsi_dma_restart_bh(void *opaque)
{
SCSIDiskState *s = opaque;
- SCSIRequest *r = s->requests;
+ SCSIDiskReq *r = s->requests;
qemu_bh_delete(s->bh);
s->bh = NULL;
@@ -342,7 +341,7 @@ static void scsi_dma_restart_cb(void *opaque, int running, int reason)
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
- SCSIRequest *r;
+ SCSIDiskReq *r;
r = scsi_find_request(s, tag);
if (!r) {
@@ -368,7 +367,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
int is_write;
uint8_t command;
uint8_t *outbuf;
- SCSIRequest *r;
+ SCSIDiskReq *r;
command = buf[0];
r = scsi_find_request(s, tag);
@@ -606,7 +605,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[3] = 2; /* Format 2 */
outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
/* Sync data transfer and TCQ. */
- outbuf[7] = 0x10 | (r->bus->tcq ? 0x02 : 0);
+ outbuf[7] = 0x10 | (r->req.bus->tcq ? 0x02 : 0);
r->iov.iov_len = len;
break;
case 0x16:
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 92ef771..89f3080 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -54,24 +54,21 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
typedef struct SCSIGenericState SCSIGenericState;
-typedef struct SCSIRequest {
- BlockDriverAIOCB *aiocb;
- struct SCSIRequest *next;
- SCSIBus *bus;
- SCSIGenericState *dev;
- uint32_t tag;
+typedef struct SCSIGenericReq {
+ SCSIRequest req;
+ struct SCSIGenericReq *next;
uint8_t cmd[SCSI_CMD_BUF_SIZE];
int cmdlen;
uint8_t *buf;
int buflen;
int len;
sg_io_hdr_t io_header;
-} SCSIRequest;
+} SCSIGenericReq;
struct SCSIGenericState
{
SCSIDevice qdev;
- SCSIRequest *requests;
+ SCSIGenericReq *requests;
DriveInfo *dinfo;
int type;
int blocksize;
@@ -81,30 +78,30 @@ struct SCSIGenericState
uint8_t senselen;
};
-/* Global pool of SCSIRequest structures. */
-static SCSIRequest *free_requests = NULL;
+/* Global pool of SCSIGenericReq structures. */
+static SCSIGenericReq *free_requests = NULL;
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
+static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r;
+ SCSIGenericReq *r;
if (free_requests) {
r = free_requests;
free_requests = r->next;
} else {
- r = qemu_malloc(sizeof(SCSIRequest));
+ r = qemu_malloc(sizeof(SCSIGenericReq));
r->buf = NULL;
r->buflen = 0;
}
- r->bus = scsi_bus_from_device(d);
- r->dev = s;
- r->tag = tag;
+ r->req.bus = scsi_bus_from_device(d);
+ r->req.dev = d;
+ r->req.tag = tag;
memset(r->cmd, 0, sizeof(r->cmd));
memset(&r->io_header, 0, sizeof(r->io_header));
r->cmdlen = 0;
r->len = 0;
- r->aiocb = NULL;
+ r->req.aiocb = NULL;
/* link */
@@ -113,10 +110,10 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
return r;
}
-static void scsi_remove_request(SCSIRequest *r)
+static void scsi_remove_request(SCSIGenericReq *r)
{
- SCSIRequest *last;
- SCSIGenericState *s = r->dev;
+ SCSIGenericReq *last;
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
if (s->requests == r) {
s->requests = r->next;
@@ -134,12 +131,12 @@ static void scsi_remove_request(SCSIRequest *r)
free_requests = r;
}
-static SCSIRequest *scsi_find_request(SCSIGenericState *s, uint32_t tag)
+static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
{
- SCSIRequest *r;
+ SCSIGenericReq *r;
r = s->requests;
- while (r && r->tag != tag)
+ while (r && r->req.tag != tag)
r = r->next;
return r;
@@ -148,8 +145,8 @@ static SCSIRequest *scsi_find_request(SCSIGenericState *s, uint32_t tag)
/* Helper function for command completion. */
static void scsi_command_complete(void *opaque, int ret)
{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIGenericState *s = r->dev;
+ SCSIGenericReq *r = (SCSIGenericReq *)opaque;
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
uint32_t tag;
int status;
@@ -171,10 +168,10 @@ static void scsi_command_complete(void *opaque, int ret)
status = GOOD << 1;
}
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
- r, r->tag, status);
- tag = r->tag;
+ r, r->req.tag, status);
+ tag = r->req.tag;
scsi_remove_request(r);
- r->bus->complete(r->bus, SCSI_REASON_DONE, tag, status);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
}
/* Cancel a pending data transfer. */
@@ -182,35 +179,37 @@ static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
{
DPRINTF("scsi_cancel_io 0x%x\n", tag);
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r;
+ SCSIGenericReq *r;
DPRINTF("Cancel tag=0x%x\n", tag);
r = scsi_find_request(s, tag);
if (r) {
- if (r->aiocb)
- bdrv_aio_cancel(r->aiocb);
- r->aiocb = NULL;
+ if (r->req.aiocb)
+ bdrv_aio_cancel(r->req.aiocb);
+ r->req.aiocb = NULL;
scsi_remove_request(r);
}
}
static int execute_command(BlockDriverState *bdrv,
- SCSIRequest *r, int direction,
+ SCSIGenericReq *r, int direction,
BlockDriverCompletionFunc *complete)
{
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
+
r->io_header.interface_id = 'S';
r->io_header.dxfer_direction = direction;
r->io_header.dxferp = r->buf;
r->io_header.dxfer_len = r->buflen;
r->io_header.cmdp = r->cmd;
r->io_header.cmd_len = r->cmdlen;
- r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
- r->io_header.sbp = r->dev->sensebuf;
+ r->io_header.mx_sb_len = sizeof(s->sensebuf);
+ r->io_header.sbp = s->sensebuf;
r->io_header.timeout = MAX_UINT;
r->io_header.usr_ptr = r;
r->io_header.flags |= SG_FLAG_DIRECT_IO;
- r->aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
- if (r->aiocb == NULL) {
+ 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;
}
@@ -220,7 +219,7 @@ static int execute_command(BlockDriverState *bdrv,
static void scsi_read_complete(void * opaque, int ret)
{
- SCSIRequest *r = (SCSIRequest *)opaque;
+ SCSIGenericReq *r = (SCSIGenericReq *)opaque;
int len;
if (ret) {
@@ -229,10 +228,10 @@ static void scsi_read_complete(void * opaque, int ret)
return;
}
len = r->io_header.dxfer_len - r->io_header.resid;
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
+ DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
r->len = -1;
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, len);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
if (len == 0)
scsi_command_complete(r, 0);
}
@@ -241,7 +240,7 @@ static void scsi_read_complete(void * opaque, int ret)
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r;
+ SCSIGenericReq *r;
int ret;
DPRINTF("scsi_read_data 0x%x\n", tag);
@@ -266,11 +265,11 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
r->io_header.status = 0;
r->io_header.dxfer_len = s->senselen;
r->len = -1;
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
+ DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
r->buf[0], r->buf[1], r->buf[2], r->buf[3],
r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, s->senselen);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen);
return;
}
@@ -283,7 +282,8 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
static void scsi_write_complete(void * opaque, int ret)
{
- SCSIRequest *r = (SCSIRequest *)opaque;
+ SCSIGenericReq *r = (SCSIGenericReq *)opaque;
+ SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
DPRINTF("scsi_write_complete() ret = %d\n", ret);
if (ret) {
@@ -293,9 +293,9 @@ static void scsi_write_complete(void * opaque, int ret)
}
if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
- r->dev->type == TYPE_TAPE) {
- r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
- DPRINTF("block size %d\n", r->dev->blocksize);
+ s->type == TYPE_TAPE) {
+ s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
+ DPRINTF("block size %d\n", s->blocksize);
}
scsi_command_complete(r, ret);
@@ -306,7 +306,7 @@ static void scsi_write_complete(void * opaque, int ret)
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r;
+ SCSIGenericReq *r;
int ret;
DPRINTF("scsi_write_data 0x%x\n", tag);
@@ -320,7 +320,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
if (r->len == 0) {
r->len = r->buflen;
- r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, r->len);
+ r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len);
return 0;
}
@@ -337,7 +337,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r;
+ SCSIGenericReq *r;
r = scsi_find_request(s, tag);
if (!r) {
BADF("Bad buffer tag 0x%x\n", tag);
@@ -512,7 +512,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
uint32_t len=0;
int cmdlen=0;
- SCSIRequest *r;
+ SCSIGenericReq *r;
SCSIBus *bus;
int ret;
@@ -653,7 +653,7 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
static void scsi_destroy(SCSIDevice *d)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIRequest *r, *n;
+ SCSIGenericReq *r, *n;
r = s->requests;
while (r) {
diff --git a/hw/scsi.h b/hw/scsi.h
index d2b274c..7906877 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -2,6 +2,7 @@
#define QEMU_HW_SCSI_H
#include "qdev.h"
+#include "block.h"
/* scsi-disk.c */
enum scsi_reason {
@@ -15,6 +16,13 @@ typedef struct SCSIDeviceInfo SCSIDeviceInfo;
typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag,
uint32_t arg);
+typedef struct SCSIRequest {
+ SCSIBus *bus;
+ SCSIDevice *dev;
+ uint32_t tag;
+ BlockDriverAIOCB *aiocb;
+} SCSIRequest;
+
struct SCSIDevice
{
DeviceState qdev;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:15 ` Christoph Hellwig
2009-11-17 11:59 ` Paul Brook
2009-11-17 10:17 ` [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init() Gerd Hoffmann
` (12 subsequent siblings)
15 siblings, 2 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Changes:
* Move from open-coded lists to QTAILQ macros.
* Move the struct elements to the common data structures
(SCSIDevice + SCSIRequest).
* Fix request cleanup in the destroy callback.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 1 +
hw/scsi-disk.c | 58 ++++++++++++++++++----------------------------
hw/scsi-generic.c | 66 ++++++++++++++--------------------------------------
hw/scsi.h | 2 +
4 files changed, 44 insertions(+), 83 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 641db81..801922b 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -50,6 +50,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
bus->devs[dev->id] = dev;
dev->info = info;
+ QTAILQ_INIT(&dev->requests);
rc = dev->info->init(dev);
if (rc != 0) {
bus->devs[dev->id] = NULL;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 142d81d..2b13635 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -55,7 +55,6 @@ typedef struct SCSIDiskReq {
uint32_t sector_count;
struct iovec iov;
QEMUIOVector qiov;
- struct SCSIDiskReq *next;
uint32_t status;
} SCSIDiskReq;
@@ -63,7 +62,6 @@ struct SCSIDiskState
{
SCSIDevice qdev;
DriveInfo *dinfo;
- SCSIDiskReq *requests;
/* The qemu block layer uses a fixed 512 byte sector size.
This is the number of 512 byte blocks in a single scsi sector. */
int cluster_size;
@@ -74,16 +72,15 @@ struct SCSIDiskState
};
/* Global pool of SCSIRequest structures. */
-static SCSIDiskReq *free_requests = NULL;
+static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests);
static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
{
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
SCSIDiskReq *r;
- if (free_requests) {
- r = free_requests;
- free_requests = r->next;
+ if (!QTAILQ_EMPTY(&free_requests)) {
+ r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&free_requests));
+ QTAILQ_REMOVE(&free_requests, &r->req, next);
} else {
r = qemu_malloc(sizeof(SCSIDiskReq));
r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
@@ -96,41 +93,26 @@ static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
r->req.aiocb = NULL;
r->status = 0;
- r->next = s->requests;
- s->requests = r;
+ QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
return r;
}
static void scsi_remove_request(SCSIDiskReq *r)
{
- SCSIDiskReq *last;
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
- if (s->requests == r) {
- s->requests = r->next;
- } else {
- last = s->requests;
- while (last && last->next != r)
- last = last->next;
- if (last) {
- last->next = r->next;
- } else {
- BADF("Orphaned request\n");
- }
- }
- r->next = free_requests;
- free_requests = r;
+ QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next);
+ QTAILQ_INSERT_HEAD(&free_requests, &r->req, next);
}
static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
{
- SCSIDiskReq *r;
+ SCSIRequest *req;
- r = s->requests;
- while (r && r->req.tag != tag)
- r = r->next;
-
- return r;
+ QTAILQ_FOREACH(req, &s->qdev.requests, next) {
+ if (req->tag == tag) {
+ return DO_UPCAST(SCSIDiskReq, req, req);
+ }
+ }
+ return NULL;
}
/* Helper function for command completion. */
@@ -310,17 +292,18 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
static void scsi_dma_restart_bh(void *opaque)
{
SCSIDiskState *s = opaque;
- SCSIDiskReq *r = s->requests;
+ SCSIRequest *req;
+ SCSIDiskReq *r;
qemu_bh_delete(s->bh);
s->bh = NULL;
- while (r) {
+ QTAILQ_FOREACH(req, &s->qdev.requests, next) {
+ r = DO_UPCAST(SCSIDiskReq, req, req);
if (r->status & SCSI_REQ_STATUS_RETRY) {
r->status &= ~SCSI_REQ_STATUS_RETRY;
scsi_write_request(r);
}
- r = r->next;
}
}
@@ -959,7 +942,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
static void scsi_destroy(SCSIDevice *dev)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+ SCSIDiskReq *r;
+ while (!QTAILQ_EMPTY(&s->qdev.requests)) {
+ r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
+ scsi_remove_request(r);
+ }
drive_uninit(s->dinfo);
}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 89f3080..5ca6840 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -56,7 +56,6 @@ typedef struct SCSIGenericState SCSIGenericState;
typedef struct SCSIGenericReq {
SCSIRequest req;
- struct SCSIGenericReq *next;
uint8_t cmd[SCSI_CMD_BUF_SIZE];
int cmdlen;
uint8_t *buf;
@@ -68,7 +67,6 @@ typedef struct SCSIGenericReq {
struct SCSIGenericState
{
SCSIDevice qdev;
- SCSIGenericReq *requests;
DriveInfo *dinfo;
int type;
int blocksize;
@@ -79,16 +77,15 @@ struct SCSIGenericState
};
/* Global pool of SCSIGenericReq structures. */
-static SCSIGenericReq *free_requests = NULL;
+static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests);
static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
{
- SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
SCSIGenericReq *r;
- if (free_requests) {
- r = free_requests;
- free_requests = r->next;
+ if (!QTAILQ_EMPTY(&free_requests)) {
+ r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&free_requests));
+ QTAILQ_REMOVE(&free_requests, &r->req, next);
} else {
r = qemu_malloc(sizeof(SCSIGenericReq));
r->buf = NULL;
@@ -103,43 +100,26 @@ static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
r->len = 0;
r->req.aiocb = NULL;
- /* link */
-
- r->next = s->requests;
- s->requests = r;
+ QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
return r;
}
static void scsi_remove_request(SCSIGenericReq *r)
{
- SCSIGenericReq *last;
- SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
-
- if (s->requests == r) {
- s->requests = r->next;
- } else {
- last = s->requests;
- while (last && last->next != r)
- last = last->next;
- if (last) {
- last->next = r->next;
- } else {
- BADF("Orphaned request\n");
- }
- }
- r->next = free_requests;
- free_requests = r;
+ QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next);
+ QTAILQ_INSERT_HEAD(&free_requests, &r->req, next);
}
static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag)
{
- SCSIGenericReq *r;
-
- r = s->requests;
- while (r && r->req.tag != tag)
- r = r->next;
+ SCSIRequest *req;
- return r;
+ QTAILQ_FOREACH(req, &s->qdev.requests, next) {
+ if (req->tag == tag) {
+ return DO_UPCAST(SCSIGenericReq, req, req);
+ }
+ }
+ return NULL;
}
/* Helper function for command completion. */
@@ -653,22 +633,12 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
static void scsi_destroy(SCSIDevice *d)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- SCSIGenericReq *r, *n;
-
- r = s->requests;
- while (r) {
- n = r->next;
- qemu_free(r);
- r = n;
- }
+ SCSIGenericReq *r;
- r = free_requests;
- while (r) {
- n = r->next;
- qemu_free(r);
- r = n;
+ while (!QTAILQ_EMPTY(&s->qdev.requests)) {
+ r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
+ scsi_remove_request(r);
}
-
drive_uninit(s->dinfo);
}
diff --git a/hw/scsi.h b/hw/scsi.h
index 7906877..a9b846c 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -21,6 +21,7 @@ typedef struct SCSIRequest {
SCSIDevice *dev;
uint32_t tag;
BlockDriverAIOCB *aiocb;
+ QTAILQ_ENTRY(SCSIRequest) next;
} SCSIRequest;
struct SCSIDevice
@@ -28,6 +29,7 @@ struct SCSIDevice
DeviceState qdev;
uint32_t id;
SCSIDeviceInfo *info;
+ QTAILQ_HEAD(, SCSIRequest) requests;
};
/* cdrom.c */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init()
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (2 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:16 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest Gerd Hoffmann
` (11 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Helper function to init SCSIRequest, so scsi-disk and scsi-generic
don't duplicate init code for the common bits.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 9 +++++++++
hw/scsi-disk.c | 9 +++------
hw/scsi-generic.c | 9 +++------
hw/scsi.h | 3 +++
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 801922b..c74d085 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -111,3 +111,12 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
scsi_bus_legacy_add_drive(bus, dinfo, unit);
}
}
+
+void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun)
+{
+ req->bus = scsi_bus_from_device(d);
+ req->dev = d;
+ req->tag = tag;
+ req->lun = lun;
+ req->aiocb = NULL;
+}
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 2b13635..bb2d68c 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -74,7 +74,7 @@ struct SCSIDiskState
/* Global pool of SCSIRequest structures. */
static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests);
-static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
+static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
{
SCSIDiskReq *r;
@@ -85,12 +85,9 @@ static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
r = qemu_malloc(sizeof(SCSIDiskReq));
r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
}
- r->req.bus = scsi_bus_from_device(d);
- r->req.dev = d;
- r->req.tag = tag;
+ scsi_req_init(&r->req, d, tag, lun);
r->sector_count = 0;
r->iov.iov_len = 0;
- r->req.aiocb = NULL;
r->status = 0;
QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
@@ -360,7 +357,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
/* ??? Tags are not unique for different luns. We only implement a
single lun, so this should not matter. */
- r = scsi_new_request(d, tag);
+ r = scsi_new_request(d, tag, lun);
outbuf = (uint8_t *)r->iov.iov_base;
is_write = 0;
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 5ca6840..1e1907e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -79,7 +79,7 @@ struct SCSIGenericState
/* Global pool of SCSIGenericReq structures. */
static QTAILQ_HEAD(, SCSIRequest) free_requests = QTAILQ_HEAD_INITIALIZER(free_requests);
-static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
+static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
{
SCSIGenericReq *r;
@@ -91,14 +91,11 @@ static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag)
r->buf = NULL;
r->buflen = 0;
}
- r->req.bus = scsi_bus_from_device(d);
- r->req.dev = d;
- r->req.tag = tag;
+ scsi_req_init(&r->req, d, tag, lun);
memset(r->cmd, 0, sizeof(r->cmd));
memset(&r->io_header, 0, sizeof(r->io_header));
r->cmdlen = 0;
r->len = 0;
- r->req.aiocb = NULL;
QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
return r;
@@ -534,7 +531,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
BADF("Tag 0x%x already in use %p\n", tag, r);
scsi_cancel_io(d, tag);
}
- r = scsi_new_request(d, tag);
+ r = scsi_new_request(d, tag, lun);
memcpy(r->cmd, cmd, cmdlen);
r->cmdlen = cmdlen;
diff --git a/hw/scsi.h b/hw/scsi.h
index a9b846c..85ce8a9 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -20,6 +20,7 @@ typedef struct SCSIRequest {
SCSIBus *bus;
SCSIDevice *dev;
uint32_t tag;
+ uint32_t lun;
BlockDriverAIOCB *aiocb;
QTAILQ_ENTRY(SCSIRequest) next;
} SCSIRequest;
@@ -74,4 +75,6 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
+void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun);
+
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (3 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init() Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:17 ` Christoph Hellwig
2009-11-17 11:55 ` Paul Brook
2009-11-17 10:17 ` [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice Gerd Hoffmann
` (10 subsequent siblings)
15 siblings, 2 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 1 +
hw/scsi-generic.c | 17 ++++++-----------
hw/scsi.h | 6 ++++++
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index c74d085..73cfe58 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -119,4 +119,5 @@ void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun)
req->tag = tag;
req->lun = lun;
req->aiocb = NULL;
+ memset(&req->cmd, 0, sizeof(req->cmd));
}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 1e1907e..68518da 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -42,7 +42,6 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
#define SET_CD_SPEED 0xbb
#define BLANK 0xa1
-#define SCSI_CMD_BUF_SIZE 16
#define SCSI_SENSE_BUF_SIZE 96
#define SG_ERR_DRIVER_TIMEOUT 0x06
@@ -56,8 +55,6 @@ typedef struct SCSIGenericState SCSIGenericState;
typedef struct SCSIGenericReq {
SCSIRequest req;
- uint8_t cmd[SCSI_CMD_BUF_SIZE];
- int cmdlen;
uint8_t *buf;
int buflen;
int len;
@@ -92,9 +89,7 @@ static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lu
r->buflen = 0;
}
scsi_req_init(&r->req, d, tag, lun);
- memset(r->cmd, 0, sizeof(r->cmd));
memset(&r->io_header, 0, sizeof(r->io_header));
- r->cmdlen = 0;
r->len = 0;
QTAILQ_INSERT_TAIL(&d->requests, &r->req, next);
@@ -177,8 +172,8 @@ static int execute_command(BlockDriverState *bdrv,
r->io_header.dxfer_direction = direction;
r->io_header.dxferp = r->buf;
r->io_header.dxfer_len = r->buflen;
- r->io_header.cmdp = r->cmd;
- r->io_header.cmd_len = r->cmdlen;
+ r->io_header.cmdp = r->req.cmd.buf;
+ r->io_header.cmd_len = r->req.cmd.len;
r->io_header.mx_sb_len = sizeof(s->sensebuf);
r->io_header.sbp = s->sensebuf;
r->io_header.timeout = MAX_UINT;
@@ -234,7 +229,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
return;
}
- if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
+ if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
{
s->senselen = MIN(r->len, s->senselen);
memcpy(r->buf, s->sensebuf, s->senselen);
@@ -269,7 +264,7 @@ static void scsi_write_complete(void * opaque, int ret)
return;
}
- if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
+ if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
s->type == TYPE_TAPE) {
s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
DPRINTF("block size %d\n", s->blocksize);
@@ -533,8 +528,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
r = scsi_new_request(d, tag, lun);
- memcpy(r->cmd, cmd, cmdlen);
- r->cmdlen = cmdlen;
+ memcpy(r->req.cmd.buf, cmd, cmdlen);
+ r->req.cmd.len = cmdlen;
if (len == 0) {
if (r->buf != NULL)
diff --git a/hw/scsi.h b/hw/scsi.h
index 85ce8a9..e3f28ea 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -4,6 +4,8 @@
#include "qdev.h"
#include "block.h"
+#define SCSI_CMD_BUF_SIZE 16
+
/* scsi-disk.c */
enum scsi_reason {
SCSI_REASON_DONE, /* Command complete. */
@@ -21,6 +23,10 @@ typedef struct SCSIRequest {
SCSIDevice *dev;
uint32_t tag;
uint32_t lun;
+ struct {
+ uint8_t buf[SCSI_CMD_BUF_SIZE];
+ int len;
+ } cmd;
BlockDriverAIOCB *aiocb;
QTAILQ_ENTRY(SCSIRequest) next;
} SCSIRequest;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (4 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:34 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h Gerd Hoffmann
` (9 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-disk.c | 1 +
hw/scsi-generic.c | 23 +++++++++++------------
hw/scsi.h | 1 +
3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index bb2d68c..00d2944 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -963,6 +963,7 @@ static int scsi_disk_initfn(SCSIDevice *dev)
} else {
s->cluster_size = 1;
}
+ s->qdev.blocksize = 512;
bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
nb_sectors /= s->cluster_size;
if (nb_sectors)
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 68518da..02ccf54 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -66,7 +66,6 @@ struct SCSIGenericState
SCSIDevice qdev;
DriveInfo *dinfo;
int type;
- int blocksize;
int lun;
int driver_status;
uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
@@ -266,7 +265,7 @@ static void scsi_write_complete(void * opaque, int ret)
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
s->type == TYPE_TAPE) {
- s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
+ s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
DPRINTF("block size %d\n", s->blocksize);
}
@@ -489,12 +488,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
int ret;
if (s->type == TYPE_TAPE) {
- if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
+ if (scsi_stream_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
BADF("Unsupported command length, command %x\n", cmd[0]);
return 0;
}
} else {
- if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
+ if (scsi_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
BADF("Unsupported command length, command %x\n", cmd[0]);
return 0;
}
@@ -670,20 +669,20 @@ static int scsi_generic_initfn(SCSIDevice *dev)
s->type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->type);
if (s->type == TYPE_TAPE) {
- s->blocksize = get_stream_blocksize(s->dinfo->bdrv);
- if (s->blocksize == -1)
- s->blocksize = 0;
+ s->qdev.blocksize = get_stream_blocksize(s->dinfo->bdrv);
+ if (s->qdev.blocksize == -1)
+ s->qdev.blocksize = 0;
} else {
- s->blocksize = get_blocksize(s->dinfo->bdrv);
+ s->qdev.blocksize = get_blocksize(s->dinfo->bdrv);
/* removable media returns 0 if not present */
- if (s->blocksize <= 0) {
+ if (s->qdev.blocksize <= 0) {
if (s->type == TYPE_ROM || s->type == TYPE_WORM)
- s->blocksize = 2048;
+ s->qdev.blocksize = 2048;
else
- s->blocksize = 512;
+ s->qdev.blocksize = 512;
}
}
- DPRINTF("block size %d\n", s->blocksize);
+ DPRINTF("block size %d\n", s->qdev.blocksize);
s->driver_status = 0;
memset(s->sensebuf, 0, sizeof(s->sensebuf));
return 0;
diff --git a/hw/scsi.h b/hw/scsi.h
index e3f28ea..bba88f3 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -37,6 +37,7 @@ struct SCSIDevice
uint32_t id;
SCSIDeviceInfo *info;
QTAILQ_HEAD(, SCSIRequest) requests;
+ int blocksize;
};
/* cdrom.c */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (5 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:35 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice Gerd Hoffmann
` (8 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Largely based on <scsi/scsi.h> from linux. Added into the tree so we
can use the defines everywhere, not just in scsi-generic.c (which is
linux-specific).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-defs.h | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/scsi-disk.c | 41 ++++++--------
hw/scsi-generic.c | 8 +---
3 files changed, 174 insertions(+), 31 deletions(-)
create mode 100644 hw/scsi-defs.h
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
new file mode 100644
index 0000000..1701521
--- /dev/null
+++ b/hw/scsi-defs.h
@@ -0,0 +1,156 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * This header file contains public constants and structures used by
+ * the scsi code for linux.
+ */
+
+/*
+ * SCSI opcodes
+ */
+
+#define TEST_UNIT_READY 0x00
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+#define REASSIGN_BLOCKS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define WRITE_VERIFY 0x2e
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+#define READ_TOC 0x43
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define MODE_SELECT_10 0x55
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define MOVE_MEDIUM 0xa5
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define WRITE_VERIFY_12 0xae
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+
+/* from hw/scsi-generic.c */
+#define REWIND 0x01
+#define REPORT_DENSITY_SUPPORT 0x44
+#define LOAD_UNLOAD 0xa6
+#define SET_CD_SPEED 0xbb
+#define BLANK 0xa1
+
+/*
+ * 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 STATUS_MASK 0x3e
+
+/*
+ * SENSE KEYS
+ */
+
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+
+
+/*
+ * DEVICE TYPES
+ */
+
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+#define TYPE_PROCESSOR 0x03 /* HP scanners use this */
+#define TYPE_WORM 0x04 /* Treated as ROM by our system */
+#define TYPE_ROM 0x05
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07 /* Magneto-optical disk -
+ * - treated as TYPE_DISK */
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
+#define TYPE_NO_LUN 0x7f
+
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 00d2944..a01a786 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -30,14 +30,7 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#include "qemu-common.h"
#include "block.h"
#include "scsi.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 2
+#include "scsi-defs.h"
#define SCSI_DMA_BUF_SIZE 131072
#define SCSI_MAX_INQUIRY_LEN 256
@@ -147,7 +140,7 @@ static void scsi_read_complete(void * opaque, int ret)
if (ret) {
DPRINTF("IO error\n");
r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0);
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
+ scsi_command_complete(r, CHECK_CONDITION, NO_SENSE);
return;
}
DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->req.tag, r->iov.iov_len);
@@ -166,7 +159,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
if (!r) {
BADF("Bad read tag 0x%x\n", tag);
/* ??? This is the wrong error. */
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
return;
}
if (r->sector_count == (uint32_t)-1) {
@@ -177,7 +170,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
}
DPRINTF("Read sector_count=%d\n", r->sector_count);
if (r->sector_count == 0) {
- scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
+ scsi_command_complete(r, GOOD, NO_SENSE);
return;
}
@@ -190,7 +183,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
r->req.aiocb = bdrv_aio_readv(s->dinfo->bdrv, r->sector, &r->qiov, n,
scsi_read_complete, r);
if (r->req.aiocb == NULL)
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
r->sector += n;
r->sector_count -= n;
}
@@ -208,8 +201,8 @@ static int scsi_handle_write_error(SCSIDiskReq *r, int error)
r->status |= SCSI_REQ_STATUS_RETRY;
vm_stop(0);
} else {
- scsi_command_complete(r, STATUS_CHECK_CONDITION,
- SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION,
+ HARDWARE_ERROR);
}
return 1;
@@ -232,7 +225,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, STATUS_GOOD, SENSE_NO_SENSE);
+ scsi_command_complete(r, GOOD, NO_SENSE);
} else {
len = r->sector_count * 512;
if (len > SCSI_DMA_BUF_SIZE) {
@@ -255,8 +248,8 @@ static void scsi_write_request(SCSIDiskReq *r)
r->req.aiocb = bdrv_aio_writev(s->dinfo->bdrv, r->sector, &r->qiov, n,
scsi_write_complete, r);
if (r->req.aiocb == NULL)
- scsi_command_complete(r, STATUS_CHECK_CONDITION,
- SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION,
+ HARDWARE_ERROR);
} else {
/* Invoke completion routine to fetch data from host. */
scsi_write_complete(r, 0);
@@ -274,7 +267,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
r = scsi_find_request(s, tag);
if (!r) {
BADF("Bad write tag 0x%x\n", tag);
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
return 1;
}
@@ -420,7 +413,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
goto fail;
memset(outbuf, 0, 4);
r->iov.iov_len = 4;
- if (s->sense == SENSE_NOT_READY && len >= 18) {
+ if (s->sense == NOT_READY && len >= 18) {
memset(outbuf, 0, 18);
r->iov.iov_len = 18;
outbuf[7] = 10;
@@ -786,7 +779,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->iov.iov_len = 8;
} else {
notready:
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
+ scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
return 0;
}
break;
@@ -896,7 +889,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
/* Protection, exponent and lowest lba field left blank. */
r->iov.iov_len = len;
} else {
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
+ scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
return 0;
}
break;
@@ -917,14 +910,14 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
default:
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
fail:
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);
+ scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
return 0;
illegal_lba:
- scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
+ scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
return 0;
}
if (r->sector_count == 0 && r->iov.iov_len == 0) {
- scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
+ scsi_command_complete(r, GOOD, 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 02ccf54..31b2b7c 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -34,13 +34,7 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
#include <sys/stat.h>
#include <unistd.h>
#include <scsi/sg.h>
-#include <scsi/scsi.h>
-
-#define REWIND 0x01
-#define REPORT_DENSITY_SUPPORT 0x44
-#define LOAD_UNLOAD 0xa6
-#define SET_CD_SPEED 0xbb
-#define BLANK 0xa1
+#include "scsi-defs.h"
#define SCSI_SENSE_BUF_SIZE 96
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (6 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:36 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code Gerd Hoffmann
` (7 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-disk.c | 1 +
hw/scsi-generic.c | 13 ++++++-------
hw/scsi.h | 1 +
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a01a786..25f8eaa 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -957,6 +957,7 @@ static int scsi_disk_initfn(SCSIDevice *dev)
s->cluster_size = 1;
}
s->qdev.blocksize = 512;
+ s->qdev.type = TYPE_DISK;
bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
nb_sectors /= s->cluster_size;
if (nb_sectors)
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 31b2b7c..7c003b7 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -59,7 +59,6 @@ struct SCSIGenericState
{
SCSIDevice qdev;
DriveInfo *dinfo;
- int type;
int lun;
int driver_status;
uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
@@ -258,7 +257,7 @@ static void scsi_write_complete(void * opaque, int ret)
}
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
- s->type == TYPE_TAPE) {
+ s->qdev.type == TYPE_TAPE) {
s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
DPRINTF("block size %d\n", s->blocksize);
}
@@ -481,7 +480,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
SCSIBus *bus;
int ret;
- if (s->type == TYPE_TAPE) {
+ if (s->qdev.type == TYPE_TAPE) {
if (scsi_stream_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
BADF("Unsupported command length, command %x\n", cmd[0]);
return 0;
@@ -660,9 +659,9 @@ static int scsi_generic_initfn(SCSIDevice *dev)
/* define device state */
s->lun = scsiid.lun;
DPRINTF("LUN %d\n", s->lun);
- s->type = scsiid.scsi_type;
- DPRINTF("device type %d\n", s->type);
- if (s->type == TYPE_TAPE) {
+ s->qdev.type = scsiid.scsi_type;
+ DPRINTF("device type %d\n", s->qdev.type);
+ if (s->qdev.type == TYPE_TAPE) {
s->qdev.blocksize = get_stream_blocksize(s->dinfo->bdrv);
if (s->qdev.blocksize == -1)
s->qdev.blocksize = 0;
@@ -670,7 +669,7 @@ static int scsi_generic_initfn(SCSIDevice *dev)
s->qdev.blocksize = get_blocksize(s->dinfo->bdrv);
/* removable media returns 0 if not present */
if (s->qdev.blocksize <= 0) {
- if (s->type == TYPE_ROM || s->type == TYPE_WORM)
+ if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
s->qdev.blocksize = 2048;
else
s->qdev.blocksize = 512;
diff --git a/hw/scsi.h b/hw/scsi.h
index bba88f3..1217bf7 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -38,6 +38,7 @@ struct SCSIDevice
SCSIDeviceInfo *info;
QTAILQ_HEAD(, SCSIRequest) requests;
int blocksize;
+ int type;
};
/* cdrom.c */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (7 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:50 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c Gerd Hoffmann
` (6 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/scsi-generic.c | 156 ++++++++------------------------------------------
hw/scsi.h | 3 +
3 files changed, 191 insertions(+), 132 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 73cfe58..0b31924 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1,6 +1,7 @@
#include "hw.h"
#include "sysemu.h"
#include "scsi.h"
+#include "scsi-defs.h"
#include "block.h"
#include "qdev.h"
@@ -121,3 +122,166 @@ void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun)
req->aiocb = NULL;
memset(&req->cmd, 0, sizeof(req->cmd));
}
+
+static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
+{
+ switch (cmd[0] >> 5) {
+ case 0:
+ req->cmd.xfer = cmd[4];
+ req->cmd.len = 6;
+ /* length 0 means 256 blocks */
+ if (req->cmd.xfer == 0)
+ req->cmd.xfer = 256;
+ break;
+ case 1:
+ case 2:
+ req->cmd.xfer = cmd[8] | (cmd[7] << 8);
+ req->cmd.len = 10;
+ break;
+ case 4:
+ req->cmd.xfer = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
+ req->cmd.len = 16;
+ break;
+ case 5:
+ req->cmd.xfer = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
+ req->cmd.len = 12;
+ break;
+ default:
+ return -1;
+ }
+
+ switch(cmd[0]) {
+ case TEST_UNIT_READY:
+ case REZERO_UNIT:
+ case START_STOP:
+ case SEEK_6:
+ case WRITE_FILEMARKS:
+ case SPACE:
+ case ERASE:
+ case ALLOW_MEDIUM_REMOVAL:
+ case VERIFY:
+ case SEEK_10:
+ case SYNCHRONIZE_CACHE:
+ case LOCK_UNLOCK_CACHE:
+ case LOAD_UNLOAD:
+ case SET_CD_SPEED:
+ case SET_LIMITS:
+ case WRITE_LONG:
+ case MOVE_MEDIUM:
+ case UPDATE_BLOCK:
+ req->cmd.xfer = 0;
+ break;
+ case MODE_SENSE:
+ break;
+ case WRITE_SAME:
+ req->cmd.xfer = 1;
+ break;
+ case READ_CAPACITY:
+ req->cmd.xfer = 8;
+ break;
+ case READ_BLOCK_LIMITS:
+ req->cmd.xfer = 6;
+ break;
+ case READ_POSITION:
+ req->cmd.xfer = 20;
+ break;
+ case SEND_VOLUME_TAG:
+ req->cmd.xfer *= 40;
+ break;
+ case MEDIUM_SCAN:
+ req->cmd.xfer *= 8;
+ break;
+ case WRITE_10:
+ case WRITE_VERIFY:
+ case WRITE_6:
+ case WRITE_12:
+ case WRITE_VERIFY_12:
+ req->cmd.xfer *= req->dev->blocksize;
+ break;
+ case READ_10:
+ case READ_6:
+ case READ_REVERSE:
+ case RECOVER_BUFFERED_DATA:
+ case READ_12:
+ req->cmd.xfer *= req->dev->blocksize;
+ break;
+ case INQUIRY:
+ req->cmd.xfer = cmd[4] | (cmd[3] << 8);
+ break;
+ }
+ return 0;
+}
+
+static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd)
+{
+ switch(cmd[0]) {
+ /* stream commands */
+ case READ_6:
+ case READ_REVERSE:
+ case RECOVER_BUFFERED_DATA:
+ case WRITE_6:
+ req->cmd.len = 6;
+ req->cmd.xfer = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
+ if (cmd[1] & 0x01) /* fixed */
+ req->cmd.xfer *= req->dev->blocksize;
+ break;
+ case REWIND:
+ case START_STOP:
+ req->cmd.len = 6;
+ req->cmd.xfer = 0;
+ break;
+ /* generic commands */
+ default:
+ return scsi_req_length(req, cmd);
+ }
+ return 0;
+}
+
+static uint64_t scsi_req_lba(SCSIRequest *req)
+{
+ uint8_t *buf = req->cmd.buf;
+ uint64_t lba;
+
+ switch (buf[0] >> 5) {
+ case 0:
+ lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
+ (((uint64_t) buf[1] & 0x1f) << 16);
+ break;
+ case 1:
+ case 2:
+ lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
+ ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
+ break;
+ case 4:
+ lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
+ ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
+ ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
+ ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
+ break;
+ case 5:
+ lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
+ ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
+ break;
+ default:
+ lba = -1;
+
+ }
+ return lba;
+}
+
+int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
+{
+ int rc;
+
+ if (req->dev->type == TYPE_TAPE) {
+ rc = scsi_req_stream_length(req, buf);
+ } else {
+ rc = scsi_req_length(req, buf);
+ }
+ if (rc != 0)
+ return rc;
+
+ memcpy(req->cmd.buf, buf, req->cmd.len);
+ req->cmd.lba = scsi_req_lba(req);
+ return 0;
+}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 7c003b7..3f4fbbb 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -310,121 +310,23 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
return r->buf;
}
-static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
+static void scsi_req_fixup(SCSIRequest *req)
{
- switch (cmd[0] >> 5) {
- case 0:
- *len = cmd[4];
- *cmdlen = 6;
- /* length 0 means 256 blocks */
- if (*len == 0)
- *len = 256;
- break;
- case 1:
- case 2:
- *len = cmd[8] | (cmd[7] << 8);
- *cmdlen = 10;
- break;
- case 4:
- *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
- *cmdlen = 16;
- break;
- case 5:
- *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
- *cmdlen = 12;
- break;
- default:
- return -1;
- }
-
- switch(cmd[0]) {
- case TEST_UNIT_READY:
- case REZERO_UNIT:
- case START_STOP:
- case SEEK_6:
- case WRITE_FILEMARKS:
- case SPACE:
- case ERASE:
- case ALLOW_MEDIUM_REMOVAL:
- case VERIFY:
- case SEEK_10:
- case SYNCHRONIZE_CACHE:
- case LOCK_UNLOCK_CACHE:
- case LOAD_UNLOAD:
- case SET_CD_SPEED:
- case SET_LIMITS:
- case WRITE_LONG:
- case MOVE_MEDIUM:
- case UPDATE_BLOCK:
- *len = 0;
- break;
- case MODE_SENSE:
- break;
- case WRITE_SAME:
- *len = 1;
- break;
- case READ_CAPACITY:
- *len = 8;
- break;
- case READ_BLOCK_LIMITS:
- *len = 6;
- break;
- case READ_POSITION:
- *len = 20;
- break;
- case SEND_VOLUME_TAG:
- *len *= 40;
- break;
- case MEDIUM_SCAN:
- *len *= 8;
- break;
+ switch(req->cmd.buf[0]) {
case WRITE_10:
- cmd[1] &= ~0x08; /* disable FUA */
- case WRITE_VERIFY:
- case WRITE_6:
- case WRITE_12:
- case WRITE_VERIFY_12:
- *len *= blocksize;
+ req->cmd.buf[1] &= ~0x08; /* disable FUA */
break;
case READ_10:
- cmd[1] &= ~0x08; /* disable FUA */
- case READ_6:
- case READ_REVERSE:
- case RECOVER_BUFFERED_DATA:
- case READ_12:
- *len *= blocksize;
- break;
- case INQUIRY:
- *len = cmd[4] | (cmd[3] << 8);
- break;
- }
- return 0;
-}
-
-static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
-{
- switch(cmd[0]) {
- /* stream commands */
- case READ_6:
- case READ_REVERSE:
- case RECOVER_BUFFERED_DATA:
- case WRITE_6:
- *cmdlen = 6;
- *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
- if (cmd[1] & 0x01) /* fixed */
- *len *= blocksize;
+ req->cmd.buf[1] &= ~0x08; /* disable FUA */
break;
case REWIND:
case START_STOP:
- *cmdlen = 6;
- *len = 0;
- cmd[1] = 0x01; /* force IMMED, otherwise qemu waits end of command */
+ if (req->dev->type == TYPE_TAPE) {
+ /* force IMMED, otherwise qemu waits end of command */
+ req->cmd.buf[1] = 0x01;
+ }
break;
- /* generic commands */
- default:
- return scsi_length(cmd, blocksize, cmdlen, len);
}
- return 0;
}
static int is_write(int command)
@@ -474,27 +376,10 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
uint8_t *cmd, int lun)
{
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
- uint32_t len=0;
- int cmdlen=0;
SCSIGenericReq *r;
SCSIBus *bus;
int ret;
- if (s->qdev.type == TYPE_TAPE) {
- if (scsi_stream_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
- BADF("Unsupported command length, command %x\n", cmd[0]);
- return 0;
- }
- } else {
- if (scsi_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
- BADF("Unsupported command length, command %x\n", cmd[0]);
- return 0;
- }
- }
-
- DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
- cmd[0], len);
-
if (cmd[0] != REQUEST_SENSE &&
(lun != s->lun || (cmd[1] >> 5) != s->lun)) {
DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
@@ -520,10 +405,17 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
r = scsi_new_request(d, tag, lun);
- memcpy(r->req.cmd.buf, cmd, cmdlen);
- r->req.cmd.len = cmdlen;
+ if (-1 == scsi_req_parse(&r->req, cmd)) {
+ BADF("Unsupported command length, command %x\n", cmd[0]);
+ scsi_remove_request(r);
+ return 0;
+ }
+ scsi_req_fixup(&r->req);
+
+ DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
+ cmd[0], r->req.cmd.xfer);
- if (len == 0) {
+ if (r->req.cmd.xfer == 0) {
if (r->buf != NULL)
free(r->buf);
r->buflen = 0;
@@ -536,21 +428,21 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
return 0;
}
- if (r->buflen != len) {
+ if (r->buflen != r->req.cmd.xfer) {
if (r->buf != NULL)
free(r->buf);
- r->buf = qemu_malloc(len);
- r->buflen = len;
+ r->buf = qemu_malloc(r->req.cmd.xfer);
+ r->buflen = r->req.cmd.xfer;
}
memset(r->buf, 0, r->buflen);
- r->len = len;
+ r->len = r->req.cmd.xfer;
if (is_write(cmd[0])) {
r->len = 0;
- return -len;
+ return -r->req.cmd.xfer;
}
- return len;
+ return r->req.cmd.xfer;
}
static int get_blocksize(BlockDriverState *bdrv)
diff --git a/hw/scsi.h b/hw/scsi.h
index 1217bf7..8eec616 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -26,6 +26,8 @@ typedef struct SCSIRequest {
struct {
uint8_t buf[SCSI_CMD_BUF_SIZE];
int len;
+ size_t xfer;
+ uint64_t lba;
} cmd;
BlockDriverAIOCB *aiocb;
QTAILQ_ENTRY(SCSIRequest) next;
@@ -84,5 +86,6 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun);
+int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (8 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:51 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 11/15] scsi: add xfer mode Gerd Hoffmann
` (5 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-disk.c | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 25f8eaa..2068187 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -398,16 +398,16 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
if (lun || buf[1] >> 5) {
/* Only LUN 0 supported. */
DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
- if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */
+ if (command != REQUEST_SENSE && command != INQUIRY)
goto fail;
}
switch (command) {
- case 0x0:
+ case TEST_UNIT_READY:
DPRINTF("Test Unit Ready\n");
if (!bdrv_is_inserted(s->dinfo->bdrv))
goto notready;
break;
- case 0x03:
+ case REQUEST_SENSE:
DPRINTF("Request Sense (len %d)\n", len);
if (len < 4)
goto fail;
@@ -425,7 +425,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[1] = 0;
outbuf[2] = s->sense;
break;
- case 0x12:
+ case INQUIRY:
DPRINTF("Inquiry (len %d)\n", len);
if (buf[1] & 0x2) {
/* Command support data - optional, not implemented */
@@ -581,18 +581,18 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[7] = 0x10 | (r->req.bus->tcq ? 0x02 : 0);
r->iov.iov_len = len;
break;
- case 0x16:
+ case RESERVE:
DPRINTF("Reserve(6)\n");
if (buf[1] & 1)
goto fail;
break;
- case 0x17:
+ case RELEASE:
DPRINTF("Release(6)\n");
if (buf[1] & 1)
goto fail;
break;
- case 0x1a:
- case 0x5a:
+ case MODE_SENSE:
+ case MODE_SENSE_10:
{
uint8_t *p;
int page;
@@ -743,18 +743,18 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->iov.iov_len = len;
}
break;
- case 0x1b:
+ case START_STOP:
DPRINTF("Start Stop Unit\n");
if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM &&
(buf[4] & 2))
/* load/eject medium */
bdrv_eject(s->dinfo->bdrv, !(buf[4] & 1));
break;
- case 0x1e:
+ case ALLOW_MEDIUM_REMOVAL:
DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
bdrv_set_locked(s->dinfo->bdrv, buf[4] & 1);
break;
- case 0x25:
+ case READ_CAPACITY:
DPRINTF("Read Capacity\n");
/* The normal LEN field for this command is zero. */
memset(outbuf, 0, 8);
@@ -783,8 +783,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
return 0;
}
break;
- case 0x08:
- case 0x28:
+ case READ_6:
+ case READ_10:
case 0x88:
DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
if (lba > s->max_lba)
@@ -792,8 +792,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->sector = lba * s->cluster_size;
r->sector_count = len * s->cluster_size;
break;
- case 0x0a:
- case 0x2a:
+ case WRITE_6:
+ case WRITE_10:
case 0x8a:
DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
if (lba > s->max_lba)
@@ -802,11 +802,11 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->sector_count = len * s->cluster_size;
is_write = 1;
break;
- case 0x35:
+ case SYNCHRONIZE_CACHE:
DPRINTF("Synchronise cache (sector %" PRId64 ", count %d)\n", lba, len);
bdrv_flush(s->dinfo->bdrv);
break;
- case 0x43:
+ case READ_TOC:
{
int start_track, format, msf, toclen;
@@ -852,12 +852,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[7] = 8; // CD-ROM
r->iov.iov_len = 8;
break;
- case 0x56:
+ case RESERVE_10:
DPRINTF("Reserve(10)\n");
if (buf[1] & 3)
goto fail;
break;
- case 0x57:
+ case RELEASE_10:
DPRINTF("Release(10)\n");
if (buf[1] & 3)
goto fail;
@@ -904,7 +904,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[3] = 8;
r->iov.iov_len = 16;
break;
- case 0x2f:
+ case VERIFY:
DPRINTF("Verify (sector %" PRId64 ", count %d)\n", lba, len);
break;
default:
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 11/15] scsi: add xfer mode
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (9 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:53 ` Christoph Hellwig
2009-11-17 11:58 ` Paul Brook
2009-11-17 10:17 ` [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct Gerd Hoffmann
` (4 subsequent siblings)
15 siblings, 2 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
hw/scsi-generic.c | 40 ++++++----------------------------------
hw/scsi.h | 7 +++++++
3 files changed, 59 insertions(+), 34 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0b31924..77409de 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -237,6 +237,51 @@ static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd)
return 0;
}
+static void scsi_req_xfer_mode(SCSIRequest *req)
+{
+ switch (req->cmd.buf[0]) {
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_VERIFY:
+ case WRITE_12:
+ case WRITE_VERIFY_12:
+ case COPY:
+ case COPY_VERIFY:
+ case COMPARE:
+ case CHANGE_DEFINITION:
+ case LOG_SELECT:
+ case MODE_SELECT:
+ case MODE_SELECT_10:
+ case SEND_DIAGNOSTIC:
+ case WRITE_BUFFER:
+ case FORMAT_UNIT:
+ case REASSIGN_BLOCKS:
+ case RESERVE:
+ case SEARCH_EQUAL:
+ case SEARCH_HIGH:
+ case SEARCH_LOW:
+ case UPDATE_BLOCK:
+ case WRITE_LONG:
+ case WRITE_SAME:
+ case SEARCH_HIGH_12:
+ case SEARCH_EQUAL_12:
+ case SEARCH_LOW_12:
+ case SET_WINDOW:
+ case MEDIUM_SCAN:
+ case SEND_VOLUME_TAG:
+ case WRITE_LONG_2:
+ req->cmd.mode = SCSI_XFER_TO_DEV;
+ break;
+ default:
+ if (req->cmd.xfer)
+ req->cmd.mode = SCSI_XFER_FROM_DEV;
+ else {
+ req->cmd.mode = SCSI_XFER_NONE;
+ }
+ break;
+ }
+}
+
static uint64_t scsi_req_lba(SCSIRequest *req)
{
uint8_t *buf = req->cmd.buf;
@@ -282,6 +327,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
return rc;
memcpy(req->cmd.buf, buf, req->cmd.len);
+ scsi_req_xfer_mode(req);
req->cmd.lba = scsi_req_lba(req);
return 0;
}
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 3f4fbbb..d9f08b6 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -329,42 +329,14 @@ static void scsi_req_fixup(SCSIRequest *req)
}
}
-static int is_write(int command)
+static int is_write(SCSIGenericReq *r)
{
- switch (command) {
- case COPY:
- case COPY_VERIFY:
- case COMPARE:
- case CHANGE_DEFINITION:
- case LOG_SELECT:
- case MODE_SELECT:
- case MODE_SELECT_10:
- case SEND_DIAGNOSTIC:
- case WRITE_BUFFER:
- case FORMAT_UNIT:
- case REASSIGN_BLOCKS:
- case RESERVE:
- case SEARCH_EQUAL:
- case SEARCH_HIGH:
- case SEARCH_LOW:
- case WRITE_6:
- case WRITE_10:
- case WRITE_VERIFY:
- case UPDATE_BLOCK:
- case WRITE_LONG:
- case WRITE_SAME:
- case SEARCH_HIGH_12:
- case SEARCH_EQUAL_12:
- case SEARCH_LOW_12:
- case WRITE_12:
- case WRITE_VERIFY_12:
- case SET_WINDOW:
- case MEDIUM_SCAN:
- case SEND_VOLUME_TAG:
- case WRITE_LONG_2:
+ switch (r->req.cmd.mode) {
+ case SCSI_XFER_TO_DEV:
return 1;
+ default:
+ return 0;
}
- return 0;
}
/* Execute a scsi command. Returns the length of the data expected by the
@@ -437,7 +409,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
memset(r->buf, 0, r->buflen);
r->len = r->req.cmd.xfer;
- if (is_write(cmd[0])) {
+ if (is_write(r)) {
r->len = 0;
return -r->req.cmd.xfer;
}
diff --git a/hw/scsi.h b/hw/scsi.h
index 8eec616..f2d033f 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -18,6 +18,12 @@ typedef struct SCSIDeviceInfo SCSIDeviceInfo;
typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag,
uint32_t arg);
+enum SCSIXferMode {
+ SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */
+ SCSI_XFER_FROM_DEV, /* READ, INQUIRY, MODE_SENSE, ... */
+ SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */
+};
+
typedef struct SCSIRequest {
SCSIBus *bus;
SCSIDevice *dev;
@@ -28,6 +34,7 @@ typedef struct SCSIRequest {
int len;
size_t xfer;
uint64_t lba;
+ enum SCSIXferMode mode;
} cmd;
BlockDriverAIOCB *aiocb;
QTAILQ_ENTRY(SCSIRequest) next;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (10 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 11/15] scsi: add xfer mode Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 11:54 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice Gerd Hoffmann
` (3 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 10 ++++++++++
hw/scsi-disk.c | 8 ++++----
hw/scsi.h | 8 ++++++++
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 77409de..493e220 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -113,6 +113,16 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
}
}
+void scsi_dev_clear_sense(SCSIDevice *dev)
+{
+ memset(&dev->sense, 0, sizeof(dev->sense));
+}
+
+void scsi_dev_set_sense(SCSIDevice *dev, uint8_t key)
+{
+ dev->sense.key = key;
+}
+
void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun)
{
req->bus = scsi_bus_from_device(d);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 2068187..c0c407b 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -59,7 +59,6 @@ struct SCSIDiskState
This is the number of 512 byte blocks in a single scsi sector. */
int cluster_size;
uint64_t max_lba;
- int sense;
char drive_serial_str[21];
QEMUBH *bh;
};
@@ -112,7 +111,7 @@ static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
uint32_t tag;
DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
r->req.tag, status, sense);
- s->sense = sense;
+ scsi_dev_set_sense(&s->qdev, sense);
tag = r->req.tag;
scsi_remove_request(r);
r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
@@ -413,7 +412,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
goto fail;
memset(outbuf, 0, 4);
r->iov.iov_len = 4;
- if (s->sense == NOT_READY && len >= 18) {
+ if (s->qdev.sense.key == NOT_READY && len >= 18) {
memset(outbuf, 0, 18);
r->iov.iov_len = 18;
outbuf[7] = 10;
@@ -423,7 +422,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
}
outbuf[0] = 0xf0;
outbuf[1] = 0;
- outbuf[2] = s->sense;
+ outbuf[2] = s->qdev.sense.key;
+ scsi_dev_clear_sense(&s->qdev);
break;
case INQUIRY:
DPRINTF("Inquiry (len %d)\n", len);
diff --git a/hw/scsi.h b/hw/scsi.h
index f2d033f..bdba1db 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -24,6 +24,10 @@ enum SCSIXferMode {
SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */
};
+typedef struct SCSISense {
+ uint8_t key;
+} SCSISense;
+
typedef struct SCSIRequest {
SCSIBus *bus;
SCSIDevice *dev;
@@ -48,6 +52,7 @@ struct SCSIDevice
QTAILQ_HEAD(, SCSIRequest) requests;
int blocksize;
int type;
+ struct SCSISense sense;
};
/* cdrom.c */
@@ -92,6 +97,9 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
+void scsi_dev_clear_sense(SCSIDevice *dev);
+void scsi_dev_set_sense(SCSIDevice *dev, uint8_t key);
+
void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun);
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (11 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 12:00 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest Gerd Hoffmann
` (2 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-disk.c | 63 ++++++++++++++++++++++++++---------------------------
hw/scsi-generic.c | 23 +++++++++----------
hw/scsi.h | 1 +
3 files changed, 43 insertions(+), 44 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index c0c407b..e072226 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -54,7 +54,6 @@ typedef struct SCSIDiskReq {
struct SCSIDiskState
{
SCSIDevice qdev;
- DriveInfo *dinfo;
/* The qemu block layer uses a fixed 512 byte sector size.
This is the number of 512 byte blocks in a single scsi sector. */
int cluster_size;
@@ -179,7 +178,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
r->iov.iov_len = n * 512;
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
- r->req.aiocb = bdrv_aio_readv(s->dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_readv(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
scsi_read_complete, r);
if (r->req.aiocb == NULL)
scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
@@ -190,7 +189,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
static int scsi_handle_write_error(SCSIDiskReq *r, int error)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- BlockInterfaceErrorAction action = drive_get_onerror(s->dinfo->bdrv);
+ BlockInterfaceErrorAction action = drive_get_onerror(s->qdev.dinfo->bdrv);
if (action == BLOCK_ERR_IGNORE)
return 0;
@@ -244,7 +243,7 @@ static void scsi_write_request(SCSIDiskReq *r)
n = r->iov.iov_len / 512;
if (n) {
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
- r->req.aiocb = bdrv_aio_writev(s->dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_writev(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
scsi_write_complete, r);
if (r->req.aiocb == NULL)
scsi_command_complete(r, CHECK_CONDITION,
@@ -403,7 +402,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
switch (command) {
case TEST_UNIT_READY:
DPRINTF("Test Unit Ready\n");
- if (!bdrv_is_inserted(s->dinfo->bdrv))
+ if (!bdrv_is_inserted(s->qdev.dinfo->bdrv))
goto notready;
break;
case REQUEST_SENSE:
@@ -450,7 +449,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->iov.iov_len = 0;
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
outbuf[r->iov.iov_len++] = 5;
} else {
outbuf[r->iov.iov_len++] = 0;
@@ -481,7 +480,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
r->iov.iov_len = 0;
/* Supported page codes */
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
outbuf[r->iov.iov_len++] = 5;
} else {
outbuf[r->iov.iov_len++] = 0;
@@ -499,14 +498,14 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
{
/* Device identification page, mandatory */
int max_len = 255 - 8;
- int id_len = strlen(bdrv_get_device_name(s->dinfo->bdrv));
+ int id_len = strlen(bdrv_get_device_name(s->qdev.dinfo->bdrv));
if (id_len > max_len)
id_len = max_len;
DPRINTF("Inquiry EVPD[Device identification] "
"buffer size %d\n", len);
r->iov.iov_len = 0;
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
outbuf[r->iov.iov_len++] = 5;
} else {
outbuf[r->iov.iov_len++] = 0;
@@ -522,7 +521,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
outbuf[r->iov.iov_len++] = id_len; // length of data following
memcpy(&outbuf[r->iov.iov_len],
- bdrv_get_device_name(s->dinfo->bdrv), id_len);
+ bdrv_get_device_name(s->qdev.dinfo->bdrv), id_len);
r->iov.iov_len += id_len;
}
break;
@@ -562,7 +561,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
if (lun || buf[1] >> 5) {
outbuf[0] = 0x7f; /* LUN not supported */
- } else if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ } else if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
outbuf[0] = 5;
outbuf[1] = 0x80;
memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
@@ -605,12 +604,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
memset(p, 0, 4);
outbuf[1] = 0; /* Default media type. */
outbuf[3] = 0; /* Block descriptor length. */
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM ||
- bdrv_is_read_only(s->dinfo->bdrv)) {
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM ||
+ bdrv_is_read_only(s->qdev.dinfo->bdrv)) {
outbuf[2] = 0x80; /* Readonly. */
}
p += 4;
- bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
if ((~dbd) & nb_sectors) {
nb_sectors /= s->cluster_size;
nb_sectors--;
@@ -635,7 +634,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
p[0] = 4;
p[1] = 0x16;
/* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->dinfo->bdrv, &cylinders, &heads, &secs);
+ bdrv_get_geometry_hint(s->qdev.dinfo->bdrv, &cylinders, &heads, &secs);
p[2] = (cylinders >> 16) & 0xff;
p[3] = (cylinders >> 8) & 0xff;
p[4] = cylinders & 0xff;
@@ -669,7 +668,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
p[2] = 5000 >> 8;
p[3] = 5000 & 0xff;
/* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->dinfo->bdrv, &cylinders, &heads, &secs);
+ bdrv_get_geometry_hint(s->qdev.dinfo->bdrv, &cylinders, &heads, &secs);
p[4] = heads & 0xff;
p[5] = secs & 0xff;
p[6] = s->cluster_size * 2;
@@ -702,13 +701,13 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
memset(p,0,20);
p[0] = 8;
p[1] = 0x12;
- if (bdrv_enable_write_cache(s->dinfo->bdrv)) {
+ if (bdrv_enable_write_cache(s->qdev.dinfo->bdrv)) {
p[2] = 4; /* WCE */
}
p += 20;
}
if ((page == 0x3f || page == 0x2a)
- && (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM)) {
+ && (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM)) {
/* CD Capabilities and Mechanical Status page. */
p[0] = 0x2a;
p[1] = 0x14;
@@ -719,7 +718,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
p[5] = 0xff; /* CD DA, DA accurate, RW supported,
RW corrected, C2 errors, ISRC,
UPC, Bar code */
- p[6] = 0x2d | (bdrv_is_locked(s->dinfo->bdrv)? 2 : 0);
+ p[6] = 0x2d | (bdrv_is_locked(s->qdev.dinfo->bdrv)? 2 : 0);
/* Locking supported, jumper present, eject, tray */
p[7] = 0; /* no volume & mute control, no
changer */
@@ -745,20 +744,20 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
break;
case START_STOP:
DPRINTF("Start Stop Unit\n");
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM &&
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM &&
(buf[4] & 2))
/* load/eject medium */
- bdrv_eject(s->dinfo->bdrv, !(buf[4] & 1));
+ bdrv_eject(s->qdev.dinfo->bdrv, !(buf[4] & 1));
break;
case ALLOW_MEDIUM_REMOVAL:
DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
- bdrv_set_locked(s->dinfo->bdrv, buf[4] & 1);
+ bdrv_set_locked(s->qdev.dinfo->bdrv, buf[4] & 1);
break;
case READ_CAPACITY:
DPRINTF("Read Capacity\n");
/* The normal LEN field for this command is zero. */
memset(outbuf, 0, 8);
- bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
nb_sectors /= s->cluster_size;
/* Returned value is the address of the last sector. */
if (nb_sectors) {
@@ -804,7 +803,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
break;
case SYNCHRONIZE_CACHE:
DPRINTF("Synchronise cache (sector %" PRId64 ", count %d)\n", lba, len);
- bdrv_flush(s->dinfo->bdrv);
+ bdrv_flush(s->qdev.dinfo->bdrv);
break;
case READ_TOC:
{
@@ -813,7 +812,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
msf = buf[1] & 2;
format = buf[2] & 0xf;
start_track = buf[6];
- bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
nb_sectors /= s->cluster_size;
switch(format) {
@@ -867,7 +866,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
if ((buf[1] & 31) == 0x10) {
DPRINTF("SAI READ CAPACITY(16)\n");
memset(outbuf, 0, len);
- bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
nb_sectors /= s->cluster_size;
/* Returned value is the address of the last sector. */
if (nb_sectors) {
@@ -938,7 +937,7 @@ static void scsi_destroy(SCSIDevice *dev)
r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
scsi_remove_request(r);
}
- drive_uninit(s->dinfo);
+ drive_uninit(s->qdev.dinfo);
}
static int scsi_disk_initfn(SCSIDevice *dev)
@@ -946,24 +945,24 @@ static int scsi_disk_initfn(SCSIDevice *dev)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
uint64_t nb_sectors;
- if (!s->dinfo || !s->dinfo->bdrv) {
+ if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
qemu_error("scsi-disk: drive property not set\n");
return -1;
}
- if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
s->cluster_size = 4;
} else {
s->cluster_size = 1;
}
s->qdev.blocksize = 512;
s->qdev.type = TYPE_DISK;
- bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
nb_sectors /= s->cluster_size;
if (nb_sectors)
nb_sectors--;
s->max_lba = nb_sectors;
- strncpy(s->drive_serial_str, drive_get_serial(s->dinfo->bdrv),
+ strncpy(s->drive_serial_str, drive_get_serial(s->qdev.dinfo->bdrv),
sizeof(s->drive_serial_str));
if (strlen(s->drive_serial_str) == 0)
pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0");
@@ -983,7 +982,7 @@ static SCSIDeviceInfo scsi_disk_info = {
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("drive", SCSIDiskState, dinfo),
+ DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo),
DEFINE_PROP_END_OF_LIST(),
},
};
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index d9f08b6..150bd93 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -58,7 +58,6 @@ typedef struct SCSIGenericReq {
struct SCSIGenericState
{
SCSIDevice qdev;
- DriveInfo *dinfo;
int lun;
int driver_status;
uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
@@ -237,7 +236,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
return;
}
- ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
+ ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
if (ret == -1) {
scsi_command_complete(r, -EINVAL);
return;
@@ -288,7 +287,7 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
return 0;
}
- ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
+ ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
if (ret == -1) {
scsi_command_complete(r, -EINVAL);
return 1;
@@ -392,7 +391,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
free(r->buf);
r->buflen = 0;
r->buf = NULL;
- ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
+ ret = execute_command(s->qdev.dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
if (ret == -1) {
scsi_command_complete(r, -EINVAL);
return 0;
@@ -487,7 +486,7 @@ static void scsi_destroy(SCSIDevice *d)
r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
scsi_remove_request(r);
}
- drive_uninit(s->dinfo);
+ drive_uninit(s->qdev.dinfo);
}
static int scsi_generic_initfn(SCSIDevice *dev)
@@ -496,26 +495,26 @@ static int scsi_generic_initfn(SCSIDevice *dev)
int sg_version;
struct sg_scsi_id scsiid;
- if (!s->dinfo || !s->dinfo->bdrv) {
+ if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
qemu_error("scsi-generic: drive property not set\n");
return -1;
}
/* check we are really using a /dev/sg* file */
- if (!bdrv_is_sg(s->dinfo->bdrv)) {
+ if (!bdrv_is_sg(s->qdev.dinfo->bdrv)) {
qemu_error("scsi-generic: not /dev/sg*\n");
return -1;
}
/* check we are using a driver managing SG_IO (version 3 and after */
- if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
+ if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
sg_version < 30000) {
qemu_error("scsi-generic: scsi generic interface too old\n");
return -1;
}
/* get LUN of the /dev/sg? */
- if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
+ if (bdrv_ioctl(s->qdev.dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
return -1;
}
@@ -526,11 +525,11 @@ static int scsi_generic_initfn(SCSIDevice *dev)
s->qdev.type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->qdev.type);
if (s->qdev.type == TYPE_TAPE) {
- s->qdev.blocksize = get_stream_blocksize(s->dinfo->bdrv);
+ s->qdev.blocksize = get_stream_blocksize(s->qdev.dinfo->bdrv);
if (s->qdev.blocksize == -1)
s->qdev.blocksize = 0;
} else {
- s->qdev.blocksize = get_blocksize(s->dinfo->bdrv);
+ s->qdev.blocksize = get_blocksize(s->qdev.dinfo->bdrv);
/* removable media returns 0 if not present */
if (s->qdev.blocksize <= 0) {
if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
@@ -557,7 +556,7 @@ static SCSIDeviceInfo scsi_generic_info = {
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("drive", SCSIGenericState, dinfo),
+ DEFINE_PROP_DRIVE("drive", SCSIGenericState, qdev.dinfo),
DEFINE_PROP_END_OF_LIST(),
},
};
diff --git a/hw/scsi.h b/hw/scsi.h
index bdba1db..cb85864 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -48,6 +48,7 @@ struct SCSIDevice
{
DeviceState qdev;
uint32_t id;
+ DriveInfo *dinfo;
SCSIDeviceInfo *info;
QTAILQ_HEAD(, SCSIRequest) requests;
int blocksize;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (12 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 12:01 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print() Gerd Hoffmann
2009-11-17 13:19 ` [Qemu-devel] Re: [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Also add and use the scsi_req_complete() helper function for calling the
completion callback.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 9 +++++++++
hw/scsi-disk.c | 13 ++++++++-----
hw/scsi-generic.c | 18 ++++++++----------
hw/scsi.h | 2 ++
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 493e220..edfe099 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -131,6 +131,7 @@ void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun)
req->lun = lun;
req->aiocb = NULL;
memset(&req->cmd, 0, sizeof(req->cmd));
+ req->status = -1;
}
static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
@@ -341,3 +342,11 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
req->cmd.lba = scsi_req_lba(req);
return 0;
}
+
+void scsi_req_complete(SCSIRequest *req)
+{
+ assert(req->status != -1);
+ req->bus->complete(req->bus, SCSI_REASON_DONE,
+ req->tag,
+ req->status);
+}
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index e072226..bc0fc31 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -103,17 +103,20 @@ static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
return NULL;
}
+static void scsi_req_set_status(SCSIRequest *req, int status, int sense_code)
+{
+ req->status = status;
+ scsi_dev_set_sense(req->dev, sense_code);
+}
+
/* Helper function for command completion. */
static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
{
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- uint32_t tag;
DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
r->req.tag, status, sense);
- scsi_dev_set_sense(&s->qdev, sense);
- tag = r->req.tag;
+ scsi_req_set_status(&r->req, status, sense);
+ scsi_req_complete(&r->req);
scsi_remove_request(r);
- r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
}
/* Cancel a pending data transfer. */
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 150bd93..557b833 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -110,31 +110,29 @@ static void scsi_command_complete(void *opaque, int ret)
{
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
- uint32_t tag;
- int status;
s->driver_status = r->io_header.driver_status;
if (s->driver_status & SG_ERR_DRIVER_SENSE)
s->senselen = r->io_header.sb_len_wr;
if (ret != 0)
- status = BUSY << 1;
+ r->req.status = BUSY << 1;
else {
if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
- status = BUSY << 1;
+ r->req.status = BUSY << 1;
BADF("Driver Timeout\n");
} else if (r->io_header.status)
- status = r->io_header.status;
+ r->req.status = r->io_header.status;
else if (s->driver_status & SG_ERR_DRIVER_SENSE)
- status = CHECK_CONDITION << 1;
+ r->req.status = CHECK_CONDITION << 1;
else
- status = GOOD << 1;
+ r->req.status = GOOD << 1;
}
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
- r, r->req.tag, status);
- tag = r->req.tag;
+ r, r->req.tag, r->req.status);
+
+ scsi_req_complete(&r->req);
scsi_remove_request(r);
- r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
}
/* Cancel a pending data transfer. */
diff --git a/hw/scsi.h b/hw/scsi.h
index cb85864..370932b 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -33,6 +33,7 @@ typedef struct SCSIRequest {
SCSIDevice *dev;
uint32_t tag;
uint32_t lun;
+ uint32_t status;
struct {
uint8_t buf[SCSI_CMD_BUF_SIZE];
int len;
@@ -103,5 +104,6 @@ void scsi_dev_set_sense(SCSIDevice *dev, uint8_t key);
void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun);
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
+void scsi_req_complete(SCSIRequest *req);
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print()
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (13 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest Gerd Hoffmann
@ 2009-11-17 10:17 ` Gerd Hoffmann
2009-11-17 12:02 ` Christoph Hellwig
2009-11-17 13:19 ` [Qemu-devel] Re: [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
15 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 10:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Handy for debugging.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/scsi-bus.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/scsi.h | 1 +
2 files changed, 115 insertions(+), 0 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index edfe099..50fc03a 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -343,6 +343,120 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
return 0;
}
+static const char *scsi_command_name(uint8_t cmd)
+{
+ static const char *names[] = {
+ [ TEST_UNIT_READY ] = "TEST_UNIT_READY",
+ [ REZERO_UNIT ] = "REZERO_UNIT",
+ [ REQUEST_SENSE ] = "REQUEST_SENSE",
+ [ FORMAT_UNIT ] = "FORMAT_UNIT",
+ [ READ_BLOCK_LIMITS ] = "READ_BLOCK_LIMITS",
+ [ REASSIGN_BLOCKS ] = "REASSIGN_BLOCKS",
+ [ READ_6 ] = "READ_6",
+ [ WRITE_6 ] = "WRITE_6",
+ [ SEEK_6 ] = "SEEK_6",
+ [ READ_REVERSE ] = "READ_REVERSE",
+ [ WRITE_FILEMARKS ] = "WRITE_FILEMARKS",
+ [ SPACE ] = "SPACE",
+ [ INQUIRY ] = "INQUIRY",
+ [ RECOVER_BUFFERED_DATA ] = "RECOVER_BUFFERED_DATA",
+ [ MODE_SELECT ] = "MODE_SELECT",
+ [ RESERVE ] = "RESERVE",
+ [ RELEASE ] = "RELEASE",
+ [ COPY ] = "COPY",
+ [ ERASE ] = "ERASE",
+ [ MODE_SENSE ] = "MODE_SENSE",
+ [ START_STOP ] = "START_STOP",
+ [ RECEIVE_DIAGNOSTIC ] = "RECEIVE_DIAGNOSTIC",
+ [ SEND_DIAGNOSTIC ] = "SEND_DIAGNOSTIC",
+ [ ALLOW_MEDIUM_REMOVAL ] = "ALLOW_MEDIUM_REMOVAL",
+
+ [ SET_WINDOW ] = "SET_WINDOW",
+ [ READ_CAPACITY ] = "READ_CAPACITY",
+ [ READ_10 ] = "READ_10",
+ [ WRITE_10 ] = "WRITE_10",
+ [ SEEK_10 ] = "SEEK_10",
+ [ WRITE_VERIFY ] = "WRITE_VERIFY",
+ [ VERIFY ] = "VERIFY",
+ [ SEARCH_HIGH ] = "SEARCH_HIGH",
+ [ SEARCH_EQUAL ] = "SEARCH_EQUAL",
+ [ SEARCH_LOW ] = "SEARCH_LOW",
+ [ SET_LIMITS ] = "SET_LIMITS",
+ [ PRE_FETCH ] = "PRE_FETCH",
+ [ READ_POSITION ] = "READ_POSITION",
+ [ SYNCHRONIZE_CACHE ] = "SYNCHRONIZE_CACHE",
+ [ LOCK_UNLOCK_CACHE ] = "LOCK_UNLOCK_CACHE",
+ [ READ_DEFECT_DATA ] = "READ_DEFECT_DATA",
+ [ MEDIUM_SCAN ] = "MEDIUM_SCAN",
+ [ COMPARE ] = "COMPARE",
+ [ COPY_VERIFY ] = "COPY_VERIFY",
+ [ WRITE_BUFFER ] = "WRITE_BUFFER",
+ [ READ_BUFFER ] = "READ_BUFFER",
+ [ UPDATE_BLOCK ] = "UPDATE_BLOCK",
+ [ READ_LONG ] = "READ_LONG",
+ [ WRITE_LONG ] = "WRITE_LONG",
+ [ CHANGE_DEFINITION ] = "CHANGE_DEFINITION",
+ [ WRITE_SAME ] = "WRITE_SAME",
+ [ READ_TOC ] = "READ_TOC",
+ [ LOG_SELECT ] = "LOG_SELECT",
+ [ LOG_SENSE ] = "LOG_SENSE",
+ [ MODE_SELECT_10 ] = "MODE_SELECT_10",
+ [ RESERVE_10 ] = "RESERVE_10",
+ [ RELEASE_10 ] = "RELEASE_10",
+ [ MODE_SENSE_10 ] = "MODE_SENSE_10",
+ [ PERSISTENT_RESERVE_IN ] = "PERSISTENT_RESERVE_IN",
+ [ PERSISTENT_RESERVE_OUT ] = "PERSISTENT_RESERVE_OUT",
+ [ MOVE_MEDIUM ] = "MOVE_MEDIUM",
+ [ READ_12 ] = "READ_12",
+ [ WRITE_12 ] = "WRITE_12",
+ [ WRITE_VERIFY_12 ] = "WRITE_VERIFY_12",
+ [ SEARCH_HIGH_12 ] = "SEARCH_HIGH_12",
+ [ SEARCH_EQUAL_12 ] = "SEARCH_EQUAL_12",
+ [ SEARCH_LOW_12 ] = "SEARCH_LOW_12",
+ [ READ_ELEMENT_STATUS ] = "READ_ELEMENT_STATUS",
+ [ SEND_VOLUME_TAG ] = "SEND_VOLUME_TAG",
+ [ WRITE_LONG_2 ] = "WRITE_LONG_2",
+
+ [ REWIND ] = "REWIND",
+ [ REPORT_DENSITY_SUPPORT ] = "REPORT_DENSITY_SUPPORT",
+ [ LOAD_UNLOAD ] = "LOAD_UNLOAD",
+ [ SET_CD_SPEED ] = "SET_CD_SPEED",
+ [ BLANK ] = "BLANK",
+ };
+
+ if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL)
+ return "*UNKNOWN*";
+ return names[cmd];
+}
+
+void scsi_req_print(SCSIRequest *req)
+{
+ FILE *fp = stderr;
+ int i;
+
+ fprintf(fp, "[%s id=%d] %s",
+ req->dev->qdev.parent_bus->name,
+ req->dev->id,
+ scsi_command_name(req->cmd.buf[0]));
+ for (i = 1; i < req->cmd.len; i++) {
+ fprintf(fp, " 0x%02x", req->cmd.buf[i]);
+ }
+ switch (req->cmd.mode) {
+ case SCSI_XFER_NONE:
+ fprintf(fp, " - none\n");
+ break;
+ case SCSI_XFER_FROM_DEV:
+ fprintf(fp, " - from-dev len=%zd\n", req->cmd.xfer);
+ break;
+ case SCSI_XFER_TO_DEV:
+ fprintf(fp, " - to-dev len=%zd\n", req->cmd.xfer);
+ break;
+ default:
+ fprintf(fp, " - Oops\n");
+ break;
+ }
+}
+
void scsi_req_complete(SCSIRequest *req)
{
assert(req->status != -1);
diff --git a/hw/scsi.h b/hw/scsi.h
index 370932b..3b151cf 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -104,6 +104,7 @@ void scsi_dev_set_sense(SCSIDevice *dev, uint8_t key);
void scsi_req_init(SCSIRequest *req, SCSIDevice *d, uint32_t tag, uint32_t lun);
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
+void scsi_req_print(SCSIRequest *req);
void scsi_req_complete(SCSIRequest *req);
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection Gerd Hoffmann
@ 2009-11-17 11:11 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:11 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:37AM +0100, Gerd Hoffmann wrote:
> Also delete the leftover and unused scsi-disk.h file.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure Gerd Hoffmann
@ 2009-11-17 11:12 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:12 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:38AM +0100, Gerd Hoffmann wrote:
> Rename the SCSIRequest structs in scsi-disk.c and scsi-generic.c to
> SCSIDiskReq and SCSIGenericReq. Create a SCSIRequest struct and move
> the common elements over.
Nice, have been waiting for this for a long time.
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ Gerd Hoffmann
@ 2009-11-17 11:15 ` Christoph Hellwig
2009-11-17 11:59 ` Paul Brook
1 sibling, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:15 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:39AM +0100, Gerd Hoffmann wrote:
> Changes:
> * Move from open-coded lists to QTAILQ macros.
> * Move the struct elements to the common data structures
> (SCSIDevice + SCSIRequest).
> * Fix request cleanup in the destroy callback.
Perfect, the old, duplicated list handling was quite horrible.
Reviewed-by: Christoph Hellwig <hch@lst.de>
> + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next);
> + QTAILQ_INSERT_HEAD(&free_requests, &r->req, next);
Would be nice if we had a move from one head to another abstraction. Or
just a copy of the linux list handling header :)
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init()
2009-11-17 10:17 ` [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init() Gerd Hoffmann
@ 2009-11-17 11:16 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:16 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:40AM +0100, Gerd Hoffmann wrote:
> Helper function to init SCSIRequest, so scsi-disk and scsi-generic
> don't duplicate init code for the common bits.
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest Gerd Hoffmann
@ 2009-11-17 11:17 ` Christoph Hellwig
2009-11-17 11:55 ` Paul Brook
1 sibling, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:17 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:41AM +0100, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
A little description of why you can it would be good. I will
defintively help with my SBC thin provisioning implementation later, so
no complaints from me :)
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice
2009-11-17 10:17 ` [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice Gerd Hoffmann
@ 2009-11-17 11:34 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:34 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:42AM +0100, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h
2009-11-17 10:17 ` [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h Gerd Hoffmann
@ 2009-11-17 11:35 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:35 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:43AM +0100, Gerd Hoffmann wrote:
> Largely based on <scsi/scsi.h> from linux. Added into the tree so we
> can use the defines everywhere, not just in scsi-generic.c (which is
> linux-specific).
Btw, I'm not sure having the name clash with the Linux header is a good
idea as we need to include it for ioctls. Also the complete lack of
prefixes for the defines might causes some problems.
Otherwise a good idea,
Reviewed-by: Christoph Hellwig <hch@lst.de>
> @@ -0,0 +1,156 @@
> +/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
You probably want to take the kernel scsi.h to base things upon as it's
a lot more uptodate than the glibc one.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice
2009-11-17 10:17 ` [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice Gerd Hoffmann
@ 2009-11-17 11:36 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:36 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code Gerd Hoffmann
@ 2009-11-17 11:50 ` Christoph Hellwig
2009-11-17 12:27 ` Paul Brook
0 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:50 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
The subject is a bit confusing - it's not the full request parsing but
just some helpers.
> +static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
> +{
> + switch (cmd[0] >> 5) {
I know qemu code tends to be very uncommented and the code this is
lifted from too, but some comments on how transfer and command length
related to the group in the higher bit of the command would be pretty
useful for the casual observer of this code.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c
2009-11-17 10:17 ` [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c Gerd Hoffmann
@ 2009-11-17 11:51 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:51 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:46AM +0100, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 11/15] scsi: add xfer mode
2009-11-17 10:17 ` [Qemu-devel] [PATCH 11/15] scsi: add xfer mode Gerd Hoffmann
@ 2009-11-17 11:53 ` Christoph Hellwig
2009-11-17 11:58 ` Paul Brook
1 sibling, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:53 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:47AM +0100, Gerd Hoffmann wrote:
> +static void scsi_req_xfer_mode(SCSIRequest *req)
> +{
> + switch (req->cmd.buf[0]) {
Having this as a void seem a bit odd to me. I'd make it return the
mode, and maybe just pass the cmd to it to make it more clear.
> +static int is_write(SCSIGenericReq *r)
> {
> + switch (r->req.cmd.mode) {
> + case SCSI_XFER_TO_DEV:
> return 1;
> + default:
> + return 0;
> }
> }
Does this helper relaly buy anything over a simple
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
check?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct Gerd Hoffmann
@ 2009-11-17 11:54 ` Christoph Hellwig
2009-11-17 12:54 ` Gerd Hoffmann
0 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 11:54 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Looks good. Long term we might want to make this a pointer to be able
to deal with block format sense descriptors more nicely.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest Gerd Hoffmann
2009-11-17 11:17 ` Christoph Hellwig
@ 2009-11-17 11:55 ` Paul Brook
2009-11-17 12:45 ` Gerd Hoffmann
1 sibling, 1 reply; 43+ messages in thread
From: Paul Brook @ 2009-11-17 11:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
> move scsi command from SCSIGenericReq to SCSIRequest.
Why? AFAICS This has precisely one user, and more importantly it is not
populated by scsi-disk.c.
Sharing common code is good. Implementing shared fields inconsistently or
putting implementation specific fields in common structures.
Paul
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 11/15] scsi: add xfer mode
2009-11-17 10:17 ` [Qemu-devel] [PATCH 11/15] scsi: add xfer mode Gerd Hoffmann
2009-11-17 11:53 ` Christoph Hellwig
@ 2009-11-17 11:58 ` Paul Brook
1 sibling, 0 replies; 43+ messages in thread
From: Paul Brook @ 2009-11-17 11:58 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
> add xfer mode
This should also be used by scsi-disc.c
Paul
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ Gerd Hoffmann
2009-11-17 11:15 ` Christoph Hellwig
@ 2009-11-17 11:59 ` Paul Brook
2009-11-17 12:39 ` Gerd Hoffmann
1 sibling, 1 reply; 43+ messages in thread
From: Paul Brook @ 2009-11-17 11:59 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
On Tuesday 17 November 2009, Gerd Hoffmann wrote:
> Changes:
> * Move from open-coded lists to QTAILQ macros.
> * Move the struct elements to the common data structures
> (SCSIDevice + SCSIRequest).
> * Fix request cleanup in the destroy callback.
This feels like the abstraction boundaries wrong. If the request chain fields
are in common structures then I'd also expect the allocation and linking code
to be common.
Paul
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice
2009-11-17 10:17 ` [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice Gerd Hoffmann
@ 2009-11-17 12:00 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 12:00 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:49AM +0100, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest.
2009-11-17 10:17 ` [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest Gerd Hoffmann
@ 2009-11-17 12:01 ` Christoph Hellwig
0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 12:01 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:50AM +0100, Gerd Hoffmann wrote:
> Also add and use the scsi_req_complete() helper function for calling the
> completion callback.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Look good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print()
2009-11-17 10:17 ` [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print() Gerd Hoffmann
@ 2009-11-17 12:02 ` Christoph Hellwig
2009-11-17 12:56 ` Gerd Hoffmann
0 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2009-11-17 12:02 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On Tue, Nov 17, 2009 at 11:17:51AM +0100, Gerd Hoffmann wrote:
> Handy for debugging.
Yes, nice one, but what about getting rid of the ad-hoc printfs in
scsi-disk, too?
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code.
2009-11-17 11:50 ` Christoph Hellwig
@ 2009-11-17 12:27 ` Paul Brook
2009-11-17 12:51 ` Gerd Hoffmann
0 siblings, 1 reply; 43+ messages in thread
From: Paul Brook @ 2009-11-17 12:27 UTC (permalink / raw)
To: qemu-devel; +Cc: Christoph Hellwig, Gerd Hoffmann
On Tuesday 17 November 2009, Christoph Hellwig wrote:
> The subject is a bit confusing - it's not the full request parsing but
> just some helpers.
This is a good example of a patch with an insufficient commit message.
Given the way GIT treats the first line of the commit mesaage, my advice is to
make both the subject and the body of the commit message independent.
On a more technical note, why aren't you also using this function in scsi-
disc.c? Surely that's the whole point of moving it into common code.
Paul
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ.
2009-11-17 11:59 ` Paul Brook
@ 2009-11-17 12:39 ` Gerd Hoffmann
2009-11-18 9:44 ` Gerd Hoffmann
0 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 12:39 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
On 11/17/09 12:59, Paul Brook wrote:
> On Tuesday 17 November 2009, Gerd Hoffmann wrote:
>> Changes:
>> * Move from open-coded lists to QTAILQ macros.
>> * Move the struct elements to the common data structures
>> (SCSIDevice + SCSIRequest).
>> * Fix request cleanup in the destroy callback.
>
> This feels like the abstraction boundaries wrong. If the request chain fields
> are in common structures then I'd also expect the allocation and linking code
> to be common.
Isn't that easy because scsi-disk and scsi-generic keep a pool of unused
request structures. I didn't change that for now, although I've
considered dropping it. Not sure how important it is these days, malloc
implementations don't do slow+stupid list walks any more ...
When the pools are gone we can easily move scsi_remove_request() to
common code and have the common scsi_req_init() function handle
allocation and linking too (and probably name it 'alloc' or 'get').
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest.
2009-11-17 11:55 ` Paul Brook
@ 2009-11-17 12:45 ` Gerd Hoffmann
0 siblings, 0 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 12:45 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
On 11/17/09 12:55, Paul Brook wrote:
>> move scsi command from SCSIGenericReq to SCSIRequest.
>
> Why? AFAICS This has precisely one user, and more importantly it is not
> populated by scsi-disk.c.
Next patch of scsi patches will make scsi-disk use it too.
(in the git tree: a bunch of patches prefixed "scsi-disk: ").
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code.
2009-11-17 12:27 ` Paul Brook
@ 2009-11-17 12:51 ` Gerd Hoffmann
2009-11-17 13:43 ` Paul Brook
0 siblings, 1 reply; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 12:51 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel, Christoph Hellwig
On 11/17/09 13:27, Paul Brook wrote:
> On Tuesday 17 November 2009, Christoph Hellwig wrote:
>> The subject is a bit confusing - it's not the full request parsing but
>> just some helpers.
>
> This is a good example of a patch with an insufficient commit message.
> Given the way GIT treats the first line of the commit mesaage, my advice is to
> make both the subject and the body of the commit message independent.
>
> On a more technical note, why aren't you also using this function in scsi-
> disc.c? Surely that's the whole point of moving it into common code.
Same as with the command move: next patch series will rework scsi-disk
to put the new fields and functions into use.
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct.
2009-11-17 11:54 ` Christoph Hellwig
@ 2009-11-17 12:54 ` Gerd Hoffmann
0 siblings, 0 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 12:54 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: qemu-devel
On 11/17/09 12:54, Christoph Hellwig wrote:
> Looks good. Long term we might want to make this a pointer to be able
> to deal with block format sense descriptors more nicely.
Did already happen ;)
I just can't move up that patch easily without causing massive churn in
the patch series ...
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print()
2009-11-17 12:02 ` Christoph Hellwig
@ 2009-11-17 12:56 ` Gerd Hoffmann
0 siblings, 0 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 12:56 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: qemu-devel
On 11/17/09 13:02, Christoph Hellwig wrote:
> On Tue, Nov 17, 2009 at 11:17:51AM +0100, Gerd Hoffmann wrote:
>> Handy for debugging.
>
> Yes, nice one, but what about getting rid of the ad-hoc printfs in
> scsi-disk, too?
Will be part of the next scsi patch series which reworks scsi-disk.c
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* [Qemu-devel] Re: [PATCH 00/15] scsi: data structures and cleanups.
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
` (14 preceding siblings ...)
2009-11-17 10:17 ` [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print() Gerd Hoffmann
@ 2009-11-17 13:19 ` Gerd Hoffmann
15 siblings, 0 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-17 13:19 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
On 11/17/09 11:17, Gerd Hoffmann wrote:
> Hi,
>
> First batch of scsi patches. They bring some data structure unification
> and a bunch of fixes and cleanups. In preparation for the other scsi
> patches, but also useful on its own IMHO, so I'm hoping for a quick and
> painless merge.
>
> The major rewrite which needs more discussion and regression testing
> is not included here.
Full scsi patch series is pushed now, available here:
http://repo.or.cz/w/qemu/kraxel.git/shortlog/refs/heads/scsi.v8
scsi.batch1 branch is this patch series
scsi.batch2 branch is what I plan to prepare for submission next (rework
scsi-disk, including using the new bits in common code added by these
patches).
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code.
2009-11-17 12:51 ` Gerd Hoffmann
@ 2009-11-17 13:43 ` Paul Brook
0 siblings, 0 replies; 43+ messages in thread
From: Paul Brook @ 2009-11-17 13:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Christoph Hellwig
> > Why aren't you also using this function in scsi- disc.c? Surely that's the
> > whole point of moving it into common code.
>
> Same as with the command move: next patch series will rework scsi-disk
> to put the new fields and functions into use.
Hmm, maybe you need to rethink your patch sequencing then.
Paul
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ.
2009-11-17 12:39 ` Gerd Hoffmann
@ 2009-11-18 9:44 ` Gerd Hoffmann
0 siblings, 0 replies; 43+ messages in thread
From: Gerd Hoffmann @ 2009-11-18 9:44 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
On 11/17/09 13:39, Gerd Hoffmann wrote:
> Isn't that easy because scsi-disk and scsi-generic keep a pool of unused
> request structures. I didn't change that for now, although I've
> considered dropping it. Not sure how important it is these days, malloc
> implementations don't do slow+stupid list walks any more ...
No strong objections -> I'll go zap the pools and move more bits into
common code.
cheers,
Gerd
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2009-11-18 9:45 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-17 10:17 [Qemu-devel] [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 01/15] scsi: add/fix header protection Gerd Hoffmann
2009-11-17 11:11 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 02/15] scsi: create common SCSIRequest structure Gerd Hoffmann
2009-11-17 11:12 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 03/15] scsi: move request lists to QTAILQ Gerd Hoffmann
2009-11-17 11:15 ` Christoph Hellwig
2009-11-17 11:59 ` Paul Brook
2009-11-17 12:39 ` Gerd Hoffmann
2009-11-18 9:44 ` Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 04/15] scsi: add scsi_req_init() Gerd Hoffmann
2009-11-17 11:16 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 05/15] scsi: move scsi command from SCSIGenericReq to SCSIRequest Gerd Hoffmann
2009-11-17 11:17 ` Christoph Hellwig
2009-11-17 11:55 ` Paul Brook
2009-11-17 12:45 ` Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 06/15] scsi: move blocksize from SCSIGenericState to SCSIDevice Gerd Hoffmann
2009-11-17 11:34 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 07/15] scsi: add scsi-defs.h Gerd Hoffmann
2009-11-17 11:35 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 08/15] scsi: move type from SCSIGenericState to SCSIDevice Gerd Hoffmann
2009-11-17 11:36 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 09/15] scsi: move scsi request parsing into generic code Gerd Hoffmann
2009-11-17 11:50 ` Christoph Hellwig
2009-11-17 12:27 ` Paul Brook
2009-11-17 12:51 ` Gerd Hoffmann
2009-11-17 13:43 ` Paul Brook
2009-11-17 10:17 ` [Qemu-devel] [PATCH 10/15] scsi: use command defines in scsi-disk.c Gerd Hoffmann
2009-11-17 11:51 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 11/15] scsi: add xfer mode Gerd Hoffmann
2009-11-17 11:53 ` Christoph Hellwig
2009-11-17 11:58 ` Paul Brook
2009-11-17 10:17 ` [Qemu-devel] [PATCH 12/15] scsi: move sense to SCSIDevice, create SCSISense struct Gerd Hoffmann
2009-11-17 11:54 ` Christoph Hellwig
2009-11-17 12:54 ` Gerd Hoffmann
2009-11-17 10:17 ` [Qemu-devel] [PATCH 13/15] scsi: move dinfo to SCSIDevice Gerd Hoffmann
2009-11-17 12:00 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 14/15] scsi: move status to SCSIRequest Gerd Hoffmann
2009-11-17 12:01 ` Christoph Hellwig
2009-11-17 10:17 ` [Qemu-devel] [PATCH 15/15] scsi: add scsi_req_print() Gerd Hoffmann
2009-11-17 12:02 ` Christoph Hellwig
2009-11-17 12:56 ` Gerd Hoffmann
2009-11-17 13:19 ` [Qemu-devel] Re: [PATCH 00/15] scsi: data structures and cleanups Gerd Hoffmann
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).