diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-28 17:28:41 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-28 17:28:41 +0000 |
commit | 221f715d90ec5fec569a19119887445c037bca86 (patch) | |
tree | 01d6f162df77773cf09c6193c6dc84219f297370 /block-raw-posix.c | |
parent | 64a7fde8e85fbadb0dadee6ed1c293cd86f5fb29 (diff) |
new scsi-generic abstraction, use SG_IO (Christoph Hellwig)
Okay, I started looking into how to handle scsi-generic I/O in the
new world order.
I think the best is to use the SG_IO ioctl instead of the read/write
interface as that allows us to support scsi passthrough on disk/cdrom
devices, too. See Hannes patch on the kvm list from August for an
example.
Now that we always do ioctls we don't need another abstraction than
bdrv_ioctl for the synchronous requests for now, and for asynchronous
requests I've added a aio_ioctl abstraction keeping it simple.
Long-term we might want to move the ops to a higher-level abstraction
and let the low-level code fill out the request header, but I'm lazy
enough to leave that to the people trying to support scsi-passthrough
on a non-Linux OS.
Tested lightly by issuing various sg_ commands from sg3-utils in a guest
to a host CDROM device.
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@6895 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'block-raw-posix.c')
-rw-r--r-- | block-raw-posix.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/block-raw-posix.c b/block-raw-posix.c index be6dd8333f..b35c9d09b2 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -1209,6 +1209,26 @@ static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) return ioctl(s->fd, req, buf); } + +static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, + unsigned long int req, void *buf, + BlockDriverCompletionFunc *cb, void *opaque) +{ + RawAIOCB *acb; + + acb = raw_aio_setup(bs, 0, buf, 0, cb, opaque); + if (!acb) + return NULL; + + acb->aiocb.aio_ioctl_cmd = req; + if (qemu_paio_ioctl(&acb->aiocb) < 0) { + raw_aio_remove(acb); + return NULL; + } + + return &acb->common; +} + #elif defined(__FreeBSD__) static int fd_open(BlockDriverState *bs) @@ -1349,33 +1369,14 @@ static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) { return -ENOTSUP; } -#endif /* !linux && !FreeBSD */ - -static int raw_sg_send_command(BlockDriverState *bs, void *buf, int count) -{ - return raw_pwrite(bs, -1, buf, count); -} - -static int raw_sg_recv_response(BlockDriverState *bs, void *buf, int count) -{ - return raw_pread(bs, -1, buf, count); -} - -static BlockDriverAIOCB *raw_sg_aio_read(BlockDriverState *bs, - void *buf, int count, - BlockDriverCompletionFunc *cb, - void *opaque) -{ - return raw_aio_read(bs, 0, buf, -(int64_t)count, cb, opaque); -} -static BlockDriverAIOCB *raw_sg_aio_write(BlockDriverState *bs, - void *buf, int count, - BlockDriverCompletionFunc *cb, - void *opaque) +static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, + unsigned long int req, void *buf, + BlockDriverCompletionFunc *cb, void *opaque) { - return raw_aio_write(bs, 0, buf, -(int64_t)count, cb, opaque); + return -ENOTSUP; } +#endif /* !linux && !FreeBSD */ BlockDriver bdrv_host_device = { .format_name = "host_device", @@ -1402,8 +1403,5 @@ BlockDriver bdrv_host_device = { .bdrv_set_locked = raw_set_locked, /* generic scsi device */ .bdrv_ioctl = raw_ioctl, - .bdrv_sg_send_command = raw_sg_send_command, - .bdrv_sg_recv_response = raw_sg_recv_response, - .bdrv_sg_aio_read = raw_sg_aio_read, - .bdrv_sg_aio_write = raw_sg_aio_write, + .bdrv_aio_ioctl = raw_aio_ioctl, }; |