remove bdrv_aio_read/bdrv_aio_write (Christoph Hellwig)
Always use the vectored APIs to reduce code churn once we switch the BlockDriver API to be vectored. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7019 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
f1b2f712a4
commit
c87c067293
28
block-qcow.c
28
block-qcow.c
|
@ -530,6 +530,8 @@ typedef struct QCowAIOCB {
|
||||||
int n;
|
int n;
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
uint8_t *cluster_data;
|
uint8_t *cluster_data;
|
||||||
|
struct iovec hd_iov;
|
||||||
|
QEMUIOVector hd_qiov;
|
||||||
BlockDriverAIOCB *hd_aiocb;
|
BlockDriverAIOCB *hd_aiocb;
|
||||||
} QCowAIOCB;
|
} QCowAIOCB;
|
||||||
|
|
||||||
|
@ -584,8 +586,11 @@ static void qcow_aio_read_cb(void *opaque, int ret)
|
||||||
if (!acb->cluster_offset) {
|
if (!acb->cluster_offset) {
|
||||||
if (bs->backing_hd) {
|
if (bs->backing_hd) {
|
||||||
/* read from the base image */
|
/* read from the base image */
|
||||||
acb->hd_aiocb = bdrv_aio_read(bs->backing_hd,
|
acb->hd_iov.iov_base = acb->buf;
|
||||||
acb->sector_num, acb->buf, acb->n, qcow_aio_read_cb, acb);
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
|
acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
|
||||||
|
&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
|
@ -605,9 +610,12 @@ static void qcow_aio_read_cb(void *opaque, int ret)
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
acb->hd_aiocb = bdrv_aio_read(s->hd,
|
acb->hd_iov.iov_base = acb->buf;
|
||||||
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
|
acb->hd_aiocb = bdrv_aio_readv(s->hd,
|
||||||
(acb->cluster_offset >> 9) + index_in_cluster,
|
(acb->cluster_offset >> 9) + index_in_cluster,
|
||||||
acb->buf, acb->n, qcow_aio_read_cb, acb);
|
&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -687,10 +695,14 @@ static void qcow_aio_write_cb(void *opaque, int ret)
|
||||||
} else {
|
} else {
|
||||||
src_buf = acb->buf;
|
src_buf = acb->buf;
|
||||||
}
|
}
|
||||||
acb->hd_aiocb = bdrv_aio_write(s->hd,
|
|
||||||
(cluster_offset >> 9) + index_in_cluster,
|
acb->hd_iov.iov_base = (void *)src_buf;
|
||||||
src_buf, acb->n,
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
qcow_aio_write_cb, acb);
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
|
acb->hd_aiocb = bdrv_aio_writev(s->hd,
|
||||||
|
(cluster_offset >> 9) + index_in_cluster,
|
||||||
|
&acb->hd_qiov, acb->n,
|
||||||
|
qcow_aio_write_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1270,6 +1270,8 @@ typedef struct QCowAIOCB {
|
||||||
uint64_t cluster_offset;
|
uint64_t cluster_offset;
|
||||||
uint8_t *cluster_data;
|
uint8_t *cluster_data;
|
||||||
BlockDriverAIOCB *hd_aiocb;
|
BlockDriverAIOCB *hd_aiocb;
|
||||||
|
struct iovec hd_iov;
|
||||||
|
QEMUIOVector hd_qiov;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
QCowL2Meta l2meta;
|
QCowL2Meta l2meta;
|
||||||
} QCowAIOCB;
|
} QCowAIOCB;
|
||||||
|
@ -1347,8 +1349,12 @@ fail:
|
||||||
n1 = backing_read1(bs->backing_hd, acb->sector_num,
|
n1 = backing_read1(bs->backing_hd, acb->sector_num,
|
||||||
acb->buf, acb->n);
|
acb->buf, acb->n);
|
||||||
if (n1 > 0) {
|
if (n1 > 0) {
|
||||||
acb->hd_aiocb = bdrv_aio_read(bs->backing_hd, acb->sector_num,
|
acb->hd_iov.iov_base = acb->buf;
|
||||||
acb->buf, acb->n, qcow_aio_read_cb, acb);
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
|
acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
|
||||||
|
&acb->hd_qiov, acb->n,
|
||||||
|
qcow_aio_read_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1377,9 +1383,13 @@ fail:
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
acb->hd_aiocb = bdrv_aio_read(s->hd,
|
|
||||||
|
acb->hd_iov.iov_base = acb->buf;
|
||||||
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
|
acb->hd_aiocb = bdrv_aio_readv(s->hd,
|
||||||
(acb->cluster_offset >> 9) + index_in_cluster,
|
(acb->cluster_offset >> 9) + index_in_cluster,
|
||||||
acb->buf, acb->n, qcow_aio_read_cb, acb);
|
&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1476,10 +1486,13 @@ static void qcow_aio_write_cb(void *opaque, int ret)
|
||||||
} else {
|
} else {
|
||||||
src_buf = acb->buf;
|
src_buf = acb->buf;
|
||||||
}
|
}
|
||||||
acb->hd_aiocb = bdrv_aio_write(s->hd,
|
acb->hd_iov.iov_base = (void *)src_buf;
|
||||||
(acb->cluster_offset >> 9) + index_in_cluster,
|
acb->hd_iov.iov_len = acb->n * 512;
|
||||||
src_buf, acb->n,
|
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
|
||||||
qcow_aio_write_cb, acb);
|
acb->hd_aiocb = bdrv_aio_writev(s->hd,
|
||||||
|
(acb->cluster_offset >> 9) + index_in_cluster,
|
||||||
|
&acb->hd_qiov, acb->n,
|
||||||
|
qcow_aio_write_cb, acb);
|
||||||
if (acb->hd_aiocb == NULL)
|
if (acb->hd_aiocb == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
10
block.c
10
block.c
|
@ -55,6 +55,12 @@ typedef struct BlockDriverAIOCBSync {
|
||||||
int ret;
|
int ret;
|
||||||
} BlockDriverAIOCBSync;
|
} BlockDriverAIOCBSync;
|
||||||
|
|
||||||
|
static BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs,
|
||||||
|
int64_t sector_num, uint8_t *buf, int nb_sectors,
|
||||||
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
|
static BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs,
|
||||||
|
int64_t sector_num, const uint8_t *buf, int nb_sectors,
|
||||||
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
|
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
|
||||||
int64_t sector_num, uint8_t *buf, int nb_sectors,
|
int64_t sector_num, uint8_t *buf, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque);
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
|
@ -1370,7 +1376,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
|
||||||
cb, opaque, 1);
|
cb, opaque, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
|
static BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors,
|
uint8_t *buf, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque)
|
BlockDriverCompletionFunc *cb, void *opaque)
|
||||||
{
|
{
|
||||||
|
@ -1393,7 +1399,7 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
|
static BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
|
||||||
const uint8_t *buf, int nb_sectors,
|
const uint8_t *buf, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque)
|
BlockDriverCompletionFunc *cb, void *opaque)
|
||||||
{
|
{
|
||||||
|
|
7
block.h
7
block.h
|
@ -96,13 +96,6 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
|
||||||
BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
|
BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
|
||||||
QEMUIOVector *iov, int nb_sectors,
|
QEMUIOVector *iov, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque);
|
BlockDriverCompletionFunc *cb, void *opaque);
|
||||||
|
|
||||||
BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
uint8_t *buf, int nb_sectors,
|
|
||||||
BlockDriverCompletionFunc *cb, void *opaque);
|
|
||||||
BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
|
|
||||||
const uint8_t *buf, int nb_sectors,
|
|
||||||
BlockDriverCompletionFunc *cb, void *opaque);
|
|
||||||
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
|
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
|
||||||
|
|
||||||
/* sg packet commands */
|
/* sg packet commands */
|
||||||
|
|
10
hw/ide.c
10
hw/ide.c
|
@ -496,6 +496,8 @@ typedef struct BMDMAState {
|
||||||
IDEState *ide_if;
|
IDEState *ide_if;
|
||||||
BlockDriverCompletionFunc *dma_cb;
|
BlockDriverCompletionFunc *dma_cb;
|
||||||
BlockDriverAIOCB *aiocb;
|
BlockDriverAIOCB *aiocb;
|
||||||
|
struct iovec iov;
|
||||||
|
QEMUIOVector qiov;
|
||||||
int64_t sector_num;
|
int64_t sector_num;
|
||||||
uint32_t nsector;
|
uint32_t nsector;
|
||||||
} BMDMAState;
|
} BMDMAState;
|
||||||
|
@ -1467,9 +1469,11 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
|
||||||
#ifdef DEBUG_AIO
|
#ifdef DEBUG_AIO
|
||||||
printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
|
printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
|
||||||
#endif
|
#endif
|
||||||
bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
|
bm->iov.iov_base = s->io_buffer + data_offset;
|
||||||
s->io_buffer + data_offset, n * 4,
|
bm->iov.iov_len = n * 4 * 512;
|
||||||
ide_atapi_cmd_read_dma_cb, bm);
|
qemu_iovec_init_external(&bm->qiov, &bm->iov, 1);
|
||||||
|
bm->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, &bm->qiov,
|
||||||
|
n * 4, ide_atapi_cmd_read_dma_cb, bm);
|
||||||
if (!bm->aiocb) {
|
if (!bm->aiocb) {
|
||||||
/* Note: media not present is the most likely case */
|
/* Note: media not present is the most likely case */
|
||||||
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
||||||
|
|
125
hw/scsi-disk.c
125
hw/scsi-disk.c
|
@ -52,9 +52,8 @@ typedef struct SCSIRequest {
|
||||||
/* Both sector and sector_count are in terms of qemu 512 byte blocks. */
|
/* Both sector and sector_count are in terms of qemu 512 byte blocks. */
|
||||||
uint64_t sector;
|
uint64_t sector;
|
||||||
uint32_t sector_count;
|
uint32_t sector_count;
|
||||||
/* The amounnt of data in the buffer. */
|
struct iovec iov;
|
||||||
int buf_len;
|
QEMUIOVector qiov;
|
||||||
uint8_t *dma_buf;
|
|
||||||
BlockDriverAIOCB *aiocb;
|
BlockDriverAIOCB *aiocb;
|
||||||
struct SCSIRequest *next;
|
struct SCSIRequest *next;
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
|
@ -89,12 +88,12 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
|
||||||
free_requests = r->next;
|
free_requests = r->next;
|
||||||
} else {
|
} else {
|
||||||
r = qemu_malloc(sizeof(SCSIRequest));
|
r = qemu_malloc(sizeof(SCSIRequest));
|
||||||
r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
|
r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
|
||||||
}
|
}
|
||||||
r->dev = s;
|
r->dev = s;
|
||||||
r->tag = tag;
|
r->tag = tag;
|
||||||
r->sector_count = 0;
|
r->sector_count = 0;
|
||||||
r->buf_len = 0;
|
r->iov.iov_len = 0;
|
||||||
r->aiocb = NULL;
|
r->aiocb = NULL;
|
||||||
r->status = 0;
|
r->status = 0;
|
||||||
|
|
||||||
|
@ -173,9 +172,9 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
|
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
|
DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->iov.iov_len);
|
||||||
|
|
||||||
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
|
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read more data from scsi device into buffer. */
|
/* Read more data from scsi device into buffer. */
|
||||||
|
@ -193,9 +192,9 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (r->sector_count == (uint32_t)-1) {
|
if (r->sector_count == (uint32_t)-1) {
|
||||||
DPRINTF("Read buf_len=%d\n", r->buf_len);
|
DPRINTF("Read buf_len=%d\n", r->iov.iov_len);
|
||||||
r->sector_count = 0;
|
r->sector_count = 0;
|
||||||
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
|
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DPRINTF("Read sector_count=%d\n", r->sector_count);
|
DPRINTF("Read sector_count=%d\n", r->sector_count);
|
||||||
|
@ -208,9 +207,10 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
|
||||||
if (n > SCSI_DMA_BUF_SIZE / 512)
|
if (n > SCSI_DMA_BUF_SIZE / 512)
|
||||||
n = SCSI_DMA_BUF_SIZE / 512;
|
n = SCSI_DMA_BUF_SIZE / 512;
|
||||||
|
|
||||||
r->buf_len = n * 512;
|
r->iov.iov_len = n * 512;
|
||||||
r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
|
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
|
||||||
scsi_read_complete, r);
|
r->aiocb = bdrv_aio_readv(s->bdrv, r->sector, &r->qiov, n,
|
||||||
|
scsi_read_complete, r);
|
||||||
if (r->aiocb == NULL)
|
if (r->aiocb == NULL)
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
|
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
|
||||||
r->sector += n;
|
r->sector += n;
|
||||||
|
@ -250,7 +250,7 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = r->buf_len / 512;
|
n = r->iov.iov_len / 512;
|
||||||
r->sector += n;
|
r->sector += n;
|
||||||
r->sector_count -= n;
|
r->sector_count -= n;
|
||||||
if (r->sector_count == 0) {
|
if (r->sector_count == 0) {
|
||||||
|
@ -260,7 +260,7 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||||
if (len > SCSI_DMA_BUF_SIZE) {
|
if (len > SCSI_DMA_BUF_SIZE) {
|
||||||
len = SCSI_DMA_BUF_SIZE;
|
len = SCSI_DMA_BUF_SIZE;
|
||||||
}
|
}
|
||||||
r->buf_len = len;
|
r->iov.iov_len = len;
|
||||||
DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
|
DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
|
||||||
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
|
s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
|
||||||
}
|
}
|
||||||
|
@ -271,10 +271,11 @@ static void scsi_write_request(SCSIRequest *r)
|
||||||
SCSIDeviceState *s = r->dev;
|
SCSIDeviceState *s = r->dev;
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
n = r->buf_len / 512;
|
n = r->iov.iov_len / 512;
|
||||||
if (n) {
|
if (n) {
|
||||||
r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
|
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
|
||||||
scsi_write_complete, r);
|
r->aiocb = bdrv_aio_writev(s->bdrv, r->sector, &r->qiov, n,
|
||||||
|
scsi_write_complete, r);
|
||||||
if (r->aiocb == NULL)
|
if (r->aiocb == NULL)
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION,
|
scsi_command_complete(r, STATUS_CHECK_CONDITION,
|
||||||
SENSE_HARDWARE_ERROR);
|
SENSE_HARDWARE_ERROR);
|
||||||
|
@ -334,7 +335,7 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
|
||||||
BADF("Bad buffer tag 0x%x\n", tag);
|
BADF("Bad buffer tag 0x%x\n", tag);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return r->dma_buf;
|
return r->iov.iov_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute a scsi command. Returns the length of the data expected by the
|
/* Execute a scsi command. Returns the length of the data expected by the
|
||||||
|
@ -364,7 +365,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
/* ??? Tags are not unique for different luns. We only implement a
|
/* ??? Tags are not unique for different luns. We only implement a
|
||||||
single lun, so this should not matter. */
|
single lun, so this should not matter. */
|
||||||
r = scsi_new_request(s, tag);
|
r = scsi_new_request(s, tag);
|
||||||
outbuf = r->dma_buf;
|
outbuf = r->iov.iov_base;
|
||||||
is_write = 0;
|
is_write = 0;
|
||||||
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
|
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
|
||||||
switch (command >> 5) {
|
switch (command >> 5) {
|
||||||
|
@ -425,10 +426,10 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
if (len < 4)
|
if (len < 4)
|
||||||
goto fail;
|
goto fail;
|
||||||
memset(outbuf, 0, 4);
|
memset(outbuf, 0, 4);
|
||||||
r->buf_len = 4;
|
r->iov.iov_len = 4;
|
||||||
if (s->sense == SENSE_NOT_READY && len >= 18) {
|
if (s->sense == SENSE_NOT_READY && len >= 18) {
|
||||||
memset(outbuf, 0, 18);
|
memset(outbuf, 0, 18);
|
||||||
r->buf_len = 18;
|
r->iov.iov_len = 18;
|
||||||
outbuf[7] = 10;
|
outbuf[7] = 10;
|
||||||
/* asc 0x3a, ascq 0: Medium not present */
|
/* asc 0x3a, ascq 0: Medium not present */
|
||||||
outbuf[12] = 0x3a;
|
outbuf[12] = 0x3a;
|
||||||
|
@ -461,20 +462,20 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
DPRINTF("Inquiry EVPD[Supported pages] "
|
DPRINTF("Inquiry EVPD[Supported pages] "
|
||||||
"buffer size %d\n", len);
|
"buffer size %d\n", len);
|
||||||
|
|
||||||
r->buf_len = 0;
|
r->iov.iov_len = 0;
|
||||||
|
|
||||||
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
||||||
outbuf[r->buf_len++] = 5;
|
outbuf[r->iov.iov_len++] = 5;
|
||||||
} else {
|
} else {
|
||||||
outbuf[r->buf_len++] = 0;
|
outbuf[r->iov.iov_len++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outbuf[r->buf_len++] = 0x00; // this page
|
outbuf[r->iov.iov_len++] = 0x00; // this page
|
||||||
outbuf[r->buf_len++] = 0x00;
|
outbuf[r->iov.iov_len++] = 0x00;
|
||||||
outbuf[r->buf_len++] = 3; // number of pages
|
outbuf[r->iov.iov_len++] = 3; // number of pages
|
||||||
outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
|
outbuf[r->iov.iov_len++] = 0x00; // list of supported pages (this page)
|
||||||
outbuf[r->buf_len++] = 0x80; // unit serial number
|
outbuf[r->iov.iov_len++] = 0x80; // unit serial number
|
||||||
outbuf[r->buf_len++] = 0x83; // device identification
|
outbuf[r->iov.iov_len++] = 0x83; // device identification
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x80:
|
case 0x80:
|
||||||
|
@ -491,20 +492,20 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
|
DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
|
||||||
l = MIN(len, strlen(s->drive_serial_str));
|
l = MIN(len, strlen(s->drive_serial_str));
|
||||||
|
|
||||||
r->buf_len = 0;
|
r->iov.iov_len = 0;
|
||||||
|
|
||||||
/* Supported page codes */
|
/* Supported page codes */
|
||||||
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
||||||
outbuf[r->buf_len++] = 5;
|
outbuf[r->iov.iov_len++] = 5;
|
||||||
} else {
|
} else {
|
||||||
outbuf[r->buf_len++] = 0;
|
outbuf[r->iov.iov_len++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outbuf[r->buf_len++] = 0x80; // this page
|
outbuf[r->iov.iov_len++] = 0x80; // this page
|
||||||
outbuf[r->buf_len++] = 0x00;
|
outbuf[r->iov.iov_len++] = 0x00;
|
||||||
outbuf[r->buf_len++] = l;
|
outbuf[r->iov.iov_len++] = l;
|
||||||
memcpy(&outbuf[r->buf_len], s->drive_serial_str, l);
|
memcpy(&outbuf[r->iov.iov_len], s->drive_serial_str, l);
|
||||||
r->buf_len += l;
|
r->iov.iov_len += l;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -518,25 +519,25 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
|
|
||||||
DPRINTF("Inquiry EVPD[Device identification] "
|
DPRINTF("Inquiry EVPD[Device identification] "
|
||||||
"buffer size %d\n", len);
|
"buffer size %d\n", len);
|
||||||
r->buf_len = 0;
|
r->iov.iov_len = 0;
|
||||||
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
|
||||||
outbuf[r->buf_len++] = 5;
|
outbuf[r->iov.iov_len++] = 5;
|
||||||
} else {
|
} else {
|
||||||
outbuf[r->buf_len++] = 0;
|
outbuf[r->iov.iov_len++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outbuf[r->buf_len++] = 0x83; // this page
|
outbuf[r->iov.iov_len++] = 0x83; // this page
|
||||||
outbuf[r->buf_len++] = 0x00;
|
outbuf[r->iov.iov_len++] = 0x00;
|
||||||
outbuf[r->buf_len++] = 3 + id_len;
|
outbuf[r->iov.iov_len++] = 3 + id_len;
|
||||||
|
|
||||||
outbuf[r->buf_len++] = 0x2; // ASCII
|
outbuf[r->iov.iov_len++] = 0x2; // ASCII
|
||||||
outbuf[r->buf_len++] = 0; // not officially assigned
|
outbuf[r->iov.iov_len++] = 0; // not officially assigned
|
||||||
outbuf[r->buf_len++] = 0; // reserved
|
outbuf[r->iov.iov_len++] = 0; // reserved
|
||||||
outbuf[r->buf_len++] = id_len; // length of data following
|
outbuf[r->iov.iov_len++] = id_len; // length of data following
|
||||||
|
|
||||||
memcpy(&outbuf[r->buf_len],
|
memcpy(&outbuf[r->iov.iov_len],
|
||||||
bdrv_get_device_name(s->bdrv), id_len);
|
bdrv_get_device_name(s->bdrv), id_len);
|
||||||
r->buf_len += id_len;
|
r->iov.iov_len += id_len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -592,7 +593,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
|
outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
|
||||||
/* Sync data transfer and TCQ. */
|
/* Sync data transfer and TCQ. */
|
||||||
outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
|
outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
|
||||||
r->buf_len = len;
|
r->iov.iov_len = len;
|
||||||
break;
|
break;
|
||||||
case 0x16:
|
case 0x16:
|
||||||
DPRINTF("Reserve(6)\n");
|
DPRINTF("Reserve(6)\n");
|
||||||
|
@ -727,10 +728,10 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
p[21] = (16 * 176) & 0xff;
|
p[21] = (16 * 176) & 0xff;
|
||||||
p += 22;
|
p += 22;
|
||||||
}
|
}
|
||||||
r->buf_len = p - outbuf;
|
r->iov.iov_len = p - outbuf;
|
||||||
outbuf[0] = r->buf_len - 4;
|
outbuf[0] = r->iov.iov_len - 4;
|
||||||
if (r->buf_len > len)
|
if (r->iov.iov_len > len)
|
||||||
r->buf_len = len;
|
r->iov.iov_len = len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
|
@ -766,7 +767,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
outbuf[5] = 0;
|
outbuf[5] = 0;
|
||||||
outbuf[6] = s->cluster_size * 2;
|
outbuf[6] = s->cluster_size * 2;
|
||||||
outbuf[7] = 0;
|
outbuf[7] = 0;
|
||||||
r->buf_len = 8;
|
r->iov.iov_len = 8;
|
||||||
} else {
|
} else {
|
||||||
notready:
|
notready:
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
|
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
|
||||||
|
@ -827,7 +828,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
if (toclen > 0) {
|
if (toclen > 0) {
|
||||||
if (len > toclen)
|
if (len > toclen)
|
||||||
len = toclen;
|
len = toclen;
|
||||||
r->buf_len = len;
|
r->iov.iov_len = len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_cmd:
|
error_cmd:
|
||||||
|
@ -840,7 +841,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
/* ??? This should probably return much more information. For now
|
/* ??? This should probably return much more information. For now
|
||||||
just return the basic header indicating the CD-ROM profile. */
|
just return the basic header indicating the CD-ROM profile. */
|
||||||
outbuf[7] = 8; // CD-ROM
|
outbuf[7] = 8; // CD-ROM
|
||||||
r->buf_len = 8;
|
r->iov.iov_len = 8;
|
||||||
break;
|
break;
|
||||||
case 0x56:
|
case 0x56:
|
||||||
DPRINTF("Reserve(10)\n");
|
DPRINTF("Reserve(10)\n");
|
||||||
|
@ -877,7 +878,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
outbuf[10] = s->cluster_size * 2;
|
outbuf[10] = s->cluster_size * 2;
|
||||||
outbuf[11] = 0;
|
outbuf[11] = 0;
|
||||||
/* Protection, exponent and lowest lba field left blank. */
|
/* Protection, exponent and lowest lba field left blank. */
|
||||||
r->buf_len = len;
|
r->iov.iov_len = len;
|
||||||
} else {
|
} else {
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
|
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -892,7 +893,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
goto fail;
|
goto fail;
|
||||||
memset(outbuf, 0, 16);
|
memset(outbuf, 0, 16);
|
||||||
outbuf[3] = 8;
|
outbuf[3] = 8;
|
||||||
r->buf_len = 16;
|
r->iov.iov_len = 16;
|
||||||
break;
|
break;
|
||||||
case 0x2f:
|
case 0x2f:
|
||||||
DPRINTF("Verify (sector %d, count %d)\n", lba, len);
|
DPRINTF("Verify (sector %d, count %d)\n", lba, len);
|
||||||
|
@ -906,10 +907,10 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
|
scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (r->sector_count == 0 && r->buf_len == 0) {
|
if (r->sector_count == 0 && r->iov.iov_len == 0) {
|
||||||
scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
|
scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
|
||||||
}
|
}
|
||||||
len = r->sector_count * 512 + r->buf_len;
|
len = r->sector_count * 512 + r->iov.iov_len;
|
||||||
if (is_write) {
|
if (is_write) {
|
||||||
return -len;
|
return -len;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue