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.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1285122092..d510da4aad 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -60,6 +60,7 @@ typedef struct SCSIDiskReq {
struct SCSIDiskState
{
SCSIDevice qdev;
+ BlockDriverState *bs;
/* 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;
@@ -168,7 +169,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->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
scsi_read_complete, r);
if (r->req.aiocb == NULL)
scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
@@ -179,11 +180,10 @@ 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_on_error(s->qdev.dinfo->bdrv, 0);
+ BlockInterfaceErrorAction action = drive_get_on_error(s->bs, 0);
if (action == BLOCK_ERR_IGNORE) {
- bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_IGNORE, 0);
+ bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, 0);
return 0;
}
@@ -191,11 +191,11 @@ static int scsi_handle_write_error(SCSIDiskReq *r, int error)
|| action == BLOCK_ERR_STOP_ANY) {
r->status |= SCSI_REQ_STATUS_RETRY;
vm_stop(0);
- bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_STOP, 0);
+ bdrv_mon_event(s->bs, BDRV_ACTION_STOP, 0);
} else {
scsi_command_complete(r, CHECK_CONDITION,
HARDWARE_ERROR);
- bdrv_mon_event(s->qdev.dinfo->bdrv, BDRV_ACTION_REPORT, 0);
+ bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, 0);
}
return 1;
@@ -238,7 +238,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->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
+ r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
scsi_write_complete, r);
if (r->req.aiocb == NULL)
scsi_command_complete(r, CHECK_CONDITION,
@@ -319,7 +319,6 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
- BlockDriverState *bdrv = req->dev->dinfo->bdrv;
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
int buflen = 0;
@@ -338,7 +337,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
return -1;
}
- if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
outbuf[buflen++] = 5;
} else {
outbuf[buflen++] = 0;
@@ -358,8 +357,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
case 0x80: /* Device serial number, optional */
{
- const char *serial = req->dev->dinfo->serial ?
- req->dev->dinfo->serial : "0";
+ const char *serial = req->dev->conf.dinfo->serial ?
+ req->dev->conf.dinfo->serial : "0";
int l = strlen(serial);
if (l > req->cmd.xfer)
@@ -378,7 +377,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
case 0x83: /* Device identification page, mandatory */
{
int max_len = 255 - 8;
- int id_len = strlen(bdrv_get_device_name(bdrv));
+ int id_len = strlen(bdrv_get_device_name(s->bs));
if (id_len > max_len)
id_len = max_len;
@@ -391,7 +390,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
outbuf[buflen++] = 0; // reserved
outbuf[buflen++] = id_len; // length of data following
- memcpy(outbuf+buflen, bdrv_get_device_name(bdrv), id_len);
+ memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
buflen += id_len;
break;
}
@@ -429,7 +428,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
return buflen;
}
- if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
outbuf[0] = 5;
outbuf[1] = 0x80;
memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
@@ -460,7 +459,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
- BlockDriverState *bdrv = req->dev->dinfo->bdrv;
+ BlockDriverState *bdrv = s->bs;
int cylinders, heads, secs;
switch (page) {
@@ -532,7 +531,7 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p)
case 8: /* Caching page. */
p[0] = 8;
p[1] = 0x12;
- if (bdrv_enable_write_cache(s->qdev.dinfo->bdrv)) {
+ if (bdrv_enable_write_cache(s->bs)) {
p[2] = 4; /* WCE */
}
return 20;
@@ -549,7 +548,7 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p)
p[5] = 0xff; /* CD DA, DA accurate, RW supported,
RW corrected, C2 errors, ISRC,
UPC, Bar code */
- p[6] = 0x2d | (bdrv_is_locked(s->qdev.dinfo->bdrv)? 2 : 0);
+ p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
/* Locking supported, jumper present, eject, tray */
p[7] = 0; /* no volume & mute control, no
changer */
@@ -575,7 +574,6 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p)
static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
- BlockDriverState *bdrv = req->dev->dinfo->bdrv;
uint64_t nb_sectors;
int page, dbd, buflen;
uint8_t *p;
@@ -588,13 +586,13 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
p[1] = 0; /* Default media type. */
p[3] = 0; /* Block descriptor length. */
- if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM ||
- bdrv_is_read_only(bdrv)) {
+ if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM ||
+ bdrv_is_read_only(s->bs)) {
p[2] = 0x80; /* Readonly. */
}
p += 4;
- bdrv_get_geometry(bdrv, &nb_sectors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
if ((~dbd) & nb_sectors) {
outbuf[3] = 8; /* Block descriptor length */
nb_sectors /= s->cluster_size;
@@ -635,14 +633,13 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
- BlockDriverState *bdrv = req->dev->dinfo->bdrv;
int start_track, format, msf, toclen;
uint64_t nb_sectors;
msf = req->cmd.buf[1] & 2;
format = req->cmd.buf[2] & 0xf;
start_track = req->cmd.buf[6];
- bdrv_get_geometry(bdrv, &nb_sectors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
nb_sectors /= s->cluster_size;
switch (format) {
@@ -671,13 +668,12 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
- BlockDriverState *bdrv = req->dev->dinfo->bdrv;
uint64_t nb_sectors;
int buflen = 0;
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
- if (!bdrv_is_inserted(bdrv))
+ if (!bdrv_is_inserted(s->bs))
goto not_ready;
break;
case REQUEST_SENSE:
@@ -731,18 +727,18 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
goto illegal_request;
break;
case START_STOP:
- if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
+ if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
/* load/eject medium */
- bdrv_eject(bdrv, !(req->cmd.buf[4] & 1));
+ bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
}
break;
case ALLOW_MEDIUM_REMOVAL:
- bdrv_set_locked(bdrv, req->cmd.buf[4] & 1);
+ bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
break;
case READ_CAPACITY:
/* The normal LEN field for this command is zero. */
memset(outbuf, 0, 8);
- bdrv_get_geometry(bdrv, &nb_sectors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
if (!nb_sectors)
goto not_ready;
nb_sectors /= s->cluster_size;
@@ -764,7 +760,7 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
buflen = 8;
break;
case SYNCHRONIZE_CACHE:
- bdrv_flush(bdrv);
+ bdrv_flush(s->bs);
break;
case GET_CONFIGURATION:
memset(outbuf, 0, 8);
@@ -778,7 +774,7 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
if ((req->cmd.buf[1] & 31) == 0x10) {
DPRINTF("SAI READ CAPACITY(16)\n");
memset(outbuf, 0, req->cmd.xfer);
- bdrv_get_geometry(bdrv, &nb_sectors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
if (!nb_sectors)
goto not_ready;
nb_sectors /= s->cluster_size;
@@ -993,7 +989,7 @@ static void scsi_destroy(SCSIDevice *dev)
r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
scsi_remove_request(r);
}
- drive_uninit(s->qdev.dinfo);
+ drive_uninit(s->qdev.conf.dinfo);
}
static int scsi_disk_initfn(SCSIDevice *dev)
@@ -1001,19 +997,20 @@ static int scsi_disk_initfn(SCSIDevice *dev)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
uint64_t nb_sectors;
- if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
+ if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
qemu_error("scsi-disk: drive property not set\n");
return -1;
}
+ s->bs = s->qdev.conf.dinfo->bdrv;
- if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
s->cluster_size = 4;
} else {
s->cluster_size = 1;
}
s->qdev.blocksize = 512 * s->cluster_size;
s->qdev.type = TYPE_DISK;
- bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
+ bdrv_get_geometry(s->bs, &nb_sectors);
nb_sectors /= s->cluster_size;
if (nb_sectors)
nb_sectors--;
@@ -1034,7 +1031,7 @@ static SCSIDeviceInfo scsi_disk_info = {
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo),
+ DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_STRING("ver", SCSIDiskState, version),
DEFINE_PROP_END_OF_LIST(),
},