aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi-disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/scsi-disk.c')
-rw-r--r--hw/scsi-disk.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 384c098a0..d281b8cbb 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -25,7 +25,9 @@ do { printf("scsi-disk: " fmt , ##args); } while (0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
-#include "vl.h"
+#include "qemu-common.h"
+#include "block.h"
+#include "scsi-disk.h"
#define SENSE_NO_SENSE 0
#define SENSE_NOT_READY 2
@@ -35,7 +37,7 @@ do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
#define SCSI_DMA_BUF_SIZE 65536
typedef struct SCSIRequest {
- SCSIDevice *dev;
+ SCSIDeviceState *dev;
uint32_t tag;
/* ??? We should probably keep track of whether the data trasfer is
a read or a write. Currently we rely on the host getting it right. */
@@ -49,7 +51,7 @@ typedef struct SCSIRequest {
struct SCSIRequest *next;
} SCSIRequest;
-struct SCSIDevice
+struct SCSIDeviceState
{
BlockDriverState *bdrv;
SCSIRequest *requests;
@@ -67,7 +69,7 @@ struct SCSIDevice
/* Global pool of SCSIRequest structures. */
static SCSIRequest *free_requests = NULL;
-static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
+static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
{
SCSIRequest *r;
@@ -91,7 +93,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
static void scsi_remove_request(SCSIRequest *r)
{
SCSIRequest *last;
- SCSIDevice *s = r->dev;
+ SCSIDeviceState *s = r->dev;
if (s->requests == r) {
s->requests = r->next;
@@ -109,7 +111,7 @@ static void scsi_remove_request(SCSIRequest *r)
free_requests = r;
}
-static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
+static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
{
SCSIRequest *r;
@@ -123,7 +125,7 @@ static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
/* Helper function for command completion. */
static void scsi_command_complete(SCSIRequest *r, int sense)
{
- SCSIDevice *s = r->dev;
+ SCSIDeviceState *s = r->dev;
uint32_t tag;
DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
s->sense = sense;
@@ -133,8 +135,9 @@ static void scsi_command_complete(SCSIRequest *r, int sense)
}
/* Cancel a pending data transfer. */
-void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
+static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
{
+ SCSIDeviceState *s = d->state;
SCSIRequest *r;
DPRINTF("Cancel tag=0x%x\n", tag);
r = scsi_find_request(s, tag);
@@ -149,7 +152,7 @@ void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
static void scsi_read_complete(void * opaque, int ret)
{
SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDevice *s = r->dev;
+ SCSIDeviceState *s = r->dev;
if (ret) {
DPRINTF("IO error\n");
@@ -162,8 +165,9 @@ static void scsi_read_complete(void * opaque, int ret)
}
/* Read more data from scsi device into buffer. */
-void scsi_read_data(SCSIDevice *s, uint32_t tag)
+static void scsi_read_data(SCSIDevice *d, uint32_t tag)
{
+ SCSIDeviceState *s = d->state;
SCSIRequest *r;
uint32_t n;
@@ -202,7 +206,7 @@ void scsi_read_data(SCSIDevice *s, uint32_t tag)
static void scsi_write_complete(void * opaque, int ret)
{
SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDevice *s = r->dev;
+ SCSIDeviceState *s = r->dev;
uint32_t len;
if (ret) {
@@ -226,8 +230,9 @@ static void scsi_write_complete(void * opaque, int ret)
/* Write data to a scsi device. Returns nonzero on failure.
The transfer may complete asynchronously. */
-int scsi_write_data(SCSIDevice *s, uint32_t tag)
+static int scsi_write_data(SCSIDevice *d, uint32_t tag)
{
+ SCSIDeviceState *s = d->state;
SCSIRequest *r;
uint32_t n;
@@ -257,8 +262,9 @@ int scsi_write_data(SCSIDevice *s, uint32_t tag)
}
/* Return a pointer to the data buffer. */
-uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
+static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
{
+ SCSIDeviceState *s = d->state;
SCSIRequest *r;
r = scsi_find_request(s, tag);
@@ -274,8 +280,10 @@ uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
(eg. disk reads), negative for transfers to the device (eg. disk writes),
and zero if the command does not transfer any data. */
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
+static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
+ uint8_t *buf, int lun)
{
+ SCSIDeviceState *s = d->state;
int64_t nb_sectors;
uint32_t lba;
uint32_t len;
@@ -289,7 +297,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
r = scsi_find_request(s, tag);
if (r) {
BADF("Tag 0x%x already in use\n", tag);
- scsi_cancel_io(s, tag);
+ scsi_cancel_io(d, tag);
}
/* ??? Tags are not unique for different luns. We only implement a
single lun, so this should not matter. */
@@ -574,19 +582,19 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
}
}
-void scsi_disk_destroy(SCSIDevice *s)
+static void scsi_destroy(SCSIDevice *d)
{
- qemu_free(s);
+ qemu_free(d->state);
+ qemu_free(d);
}
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
- int tcq,
- scsi_completionfn completion,
- void *opaque)
+SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
+ scsi_completionfn completion, void *opaque)
{
- SCSIDevice *s;
+ SCSIDevice *d;
+ SCSIDeviceState *s;
- s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
+ s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
s->bdrv = bdrv;
s->tcq = tcq;
s->completion = completion;
@@ -597,6 +605,14 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
s->cluster_size = 1;
}
- return s;
-}
+ d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
+ d->state = s;
+ d->destroy = scsi_destroy;
+ d->send_command = scsi_send_command;
+ d->read_data = scsi_read_data;
+ d->write_data = scsi_write_data;
+ d->cancel_io = scsi_cancel_io;
+ d->get_buf = scsi_get_buf;
+ return d;
+}