SCSI passthrough cleanup
cover SCSI passthrough cleanup
This series of patches makes some cleanups in SCSI passthrough and add functionnalities.
[PATCH 1/5] reverse scsi-generic
Reverse previous implementation and restore block-raw-posix.c.
[PATCH 2/5] Move AIO
This patche moves raw AIO part from block-raw-posix.c to qemu-aio-raw.c.
[PATCH 3/5] Add block SG interface
This patch re-implement scsi-generic.c using a new block interface.
[PATCH 4/5] DVD movie support
This patch allows to read a protected/encrypted movie from a DVD.
[PATCH 5/5] SCSI device DMA split
This patch allows to split a READ or WRITE into several READ or WRITE.
Laurent
PATCH 5/5 SCSI device DMA split
In reply to Laurent VivierWith some emulated SCSI devices, like usb-storage or ide-scsi, DMA transfers are limited to 64 kiB or 32 kiB.
This patch allows to split a READ or WRITE into several READ or WRITE.
Laurent
--- block-sg.c | 1 hw/scsi-generic.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 6 deletions(-)
hw/scsi-generic.c +105 -5
@@ -60,6 +60,8 @@ do { fprintf(stderr, "scsi-generic: " fm#define MAX_UINT ((unsigned int)-1)#endif +#define MAX_CHUNK 65536 + typedef struct SCSIRequest { SGRequest sg; struct SCSIRequest *next;
@@ -70,6 +72,8 @@ typedef struct SCSIRequest {uint8_t *buf;int buflen;int len; +int remaining; +int offset; } SCSIRequest;struct SCSIDeviceState
@@ -81,6 +85,7 @@ struct SCSIDeviceStatevoid *card;int driver_status;uint8_t sensebuf[SCSI_SENSE_BUF_SIZE ]; +int max_chunk; };/* Global pool of SCSIRequest structures. */
@@ -98,6 +103,7 @@ static SCSIRequest *scsi_new_request(SCS r->buf =NULL ; r->buflen =0 ; } + r->offset =0 ; r->dev = s; r->tag = tag;memset (r->cmd,0 ,sizeof (r->cmd));
@@ -186,23 +192,93 @@ static void scsi_cancel_io(SCSIDevice *d } } +static void scsi_cmd_next (uint8_t *cmd,uint32_t inc) +{ +uint32_t addr; +switch (cmd[0 ] >>5 ) { +case 0 : + addr = cmd[3 ] | (cmd[2 ] <<8 ); + addr += inc; + cmd[2 ] = addr >>8 ; + cmd[3 ] = addr; +break ; +case 1 : +case 2 : +case 4 : +case 5 : + addr = cmd[5 ] | ((cmd[4 ] <<8 ) | ((cmd[3 ] <<16 ) | (cmd[2 ] <<24 ))); + addr += inc; + cmd[2 ] = addr >>24 ; + cmd[3 ] = addr >>16 ; + cmd[4 ] = addr >>8 ; + cmd[5 ] = addr; +break ; + } +} +static void scsi_set_length (uint8_t *cmd,uint32_t len) +{ +switch (cmd[0 ] >>5 ) { +case 0 : + cmd[4 ] = len; +break ; +case 1 : +case 2 : + cmd[7 ] = (len >>8 ); + cmd[8 ] = len; +break ; +case 4 : + cmd[10 ] = len >>24 ; + cmd[11 ] = len >>16 ; + cmd[12 ] = len >>8 ; + cmd[13 ] = len; +break ; +case 5 : + cmd[6 ] = len >>24 ; + cmd[7 ] = len >>16 ; + cmd[8 ] = len >>8 ; + cmd[9 ] = len; +break ; + } +} + +static int execute_command (BlockDriverState *bdrv,SCSIRequest *r,int direction,BlockDriverCompletionFunc *complete) { +int ret; +SCSIDeviceState *s = r->dev; + + r->remaining =0 ; +retry: +if (s->max_chunk && r->buflen > s->max_chunk) { + r->remaining = r->buflen - s->max_chunk; +scsi_set_length (r->cmd, s->max_chunk / s->blocksize); + r->buflen = s->max_chunk; + }memset (&r->sg,0 ,sizeof (r->sg)); r->sg.io_header.interface_id ='S' ; + r->sg.io_header.dxferp = r->buf + r->offset; r->sg.io_header.dxfer_direction = direction; r->sg.io_header.cmd_len = r->cmdlen; - r->sg.io_header.mx_sb_len =sizeof (r->dev->sensebuf); r->sg.io_header.dxfer_len = r->buflen; - r->sg.io_header.dxferp = r->buf; + r->sg.io_header.mx_sb_len =sizeof (s->sensebuf); + r->sg.io_header.sbp = s->sensebuf; r->sg.io_header.cmdp = r->cmd; - r->sg.io_header.sbp = r->dev->sensebuf; r->sg.io_header.timeout =MAX_UINT ; r->sg.io_header.flags |=SG_FLAG_DIRECT_IO ; -return bdrv_execute (bdrv, &r->sg, complete); + ret =bdrv_execute (bdrv, &r->sg, complete); +if (ret ==-1 && errno ==12 ) { +if (!s->max_chunk) { + s->max_chunk =MAX_CHUNK ; + goto retry; + }else if (s->max_chunk > s->blocksize) { + s->max_chunk >>=1 ; + goto retry; + } + } +return ret; }static void scsi_read_complete (void *request,int ret)
@@ -216,7 +292,18 @@ static void scsi_read_complete(void *reqscsi_command_complete (r, ret);return ; } - len = r->sg.io_header.dxfer_len - r->sg.io_header.resid; + r->offset += r->sg.io_header.dxfer_len - r->sg.io_header.resid; +if (r->remaining !=0 ) { +scsi_cmd_next (r->cmd, r->buflen / s->blocksize); +scsi_set_length (r->cmd, r->remaining / s->blocksize); + r->buflen = r->remaining; + ret =execute_command (s->bdrv, r,SG_DXFER_FROM_DEV , + scsi_read_complete); +if (ret ==-1 ) +scsi_command_complete (r, -EINVAL ); +return ; + } + len = r->offset;DPRINTF ("Data ready tag=0x%x len=%d\n" , r->tag, len); r->len =-1 ;
@@ -263,12 +350,24 @@ static void scsi_read_data(SCSIDevice *dstatic void scsi_write_complete (void * request,int ret) {SCSIRequest * r = (SCSIRequest *)request; +SCSIDeviceState *s = r->dev;DPRINTF ("scsi_write_complete() ret = %d\n" , ret);if (ret) {DPRINTF ("IO error\n" );scsi_command_complete (r, ret);return ; } + r->offset += r->sg.io_header.dxfer_len - r->sg.io_header.resid; +if (r->remaining !=0 ) { +scsi_cmd_next (r->cmd, r->buflen / s->blocksize); +scsi_set_length (r->cmd, r->remaining / s->blocksize); + r->buflen = r->remaining; + ret =execute_command (s->bdrv, r,SG_DXFER_TO_DEV , + scsi_write_complete); +if (ret ==-1 ) +scsi_command_complete (r, -EINVAL ); +return ; + }scsi_command_complete (r, ret); }
@@ -591,6 +690,7 @@ SCSIDevice *scsi_generic_init(BlockDrive s->card = card; s->blocksize =get_blocksize (s->bdrv); s->driver_status =0 ; + s->max_chunk =0 ;memset (s->sensebuf,0 ,sizeof (s->sensebuf));/* removable media returns 0 if not present */ if (s->blocksize <=0 )
block-sg.c +0 -1
@@ -151,7 +151,6 @@ int sg_execute(BlockDriverState *bs, voiif (sg_write (bs, (const uint8_t *)&r->io_header,sizeof (r->io_header)) ==-1 ) { -BADF ("execute_command: write failed ! (%d)\n" , errno);return -1 ; }if (complete ==NULL ) {
PATCH 3/5 Add block SG interface
In reply to Laurent VivierThis patch re-implement scsi-generic.c using a new block interface called block-sg.c instead of block-raw-posix.c.
It adds a new interface (bdrv_execute) allowing to send command to the device.
Laurent
--- Makefile | 2 Makefile.target | 2 block-sg.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ block-sg.h | 18 +++++ block.c | 21 +++++ block.h | 4 + block_int.h | 4 + hw/scsi-generic.c | 176 +++++++++++++++++------------------------------- 8 files changed, 303 insertions(+), 118 deletions(-)
block.c +19 -2
@@ -126,13 +126,14 @@ void path_combine(char *dest, int dest_sstatic void bdrv_register (BlockDriver *bdrv) { -if (!bdrv->bdrv_aio_read) { +if (!bdrv->bdrv_aio_read && !bdrv->bdrv_execute) {/* add AIO emulation layer */ bdrv->bdrv_aio_read = bdrv_aio_read_em; bdrv->bdrv_aio_write = bdrv_aio_write_em; bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em; bdrv->aiocb_size =sizeof (BlockDriverAIOCBSync); - }else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) { + }else if (!bdrv->bdrv_read && !bdrv->bdrv_pread && + !bdrv->bdrv_execute) {/* add synchronous IO emulation layer */ bdrv->bdrv_read = bdrv_read_em; bdrv->bdrv_write = bdrv_write_em;
@@ -267,6 +268,8 @@ static BlockDriver *find_image_format(costruct stat st;if (stat (filename, &st) >=0 && (S_ISCHR (st.st_mode) ||S_ISBLK (st.st_mode))) { +if ((st.st_rdev >>8 ) ==0x15 )/* SG device */ +return &bdrv_sg_device;return &bdrv_host_device; } }
@@ -1289,6 +1292,7 @@ void bdrv_init(void)bdrv_register (&bdrv_vvfat);bdrv_register (&bdrv_qcow2);bdrv_register (&bdrv_parallels); +bdrv_register (&bdrv_sg_device); } void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
@@ -1394,3 +1398,16 @@ void bdrv_set_locked(BlockDriverState *b drv->bdrv_set_locked (bs, locked); } } + +/* send a command to a device, needed for generic scsi interface */ + +int bdrv_execute (BlockDriverState *bs,void *request, +BlockDriverCompletionFunc *complete) +{ +BlockDriver *drv = bs->drv; + +if (drv && drv->bdrv_execute) { +return drv->bdrv_execute (bs, request, complete); + } +return -ENOTSUP ; +}
block.h +4 -0
@@ -16,6 +16,7 @@ extern BlockDriver bdrv_vpc;extern BlockDriver bdrv_vvfat;extern BlockDriver bdrv_qcow2;extern BlockDriver bdrv_parallels; +extern BlockDriver bdrv_sg_device; typedef struct BlockDriverInfo { /* in bytes, 0 if irrelevant */
@@ -148,6 +149,9 @@ int bdrv_snapshot_delete(BlockDriverStatint bdrv_snapshot_list (BlockDriverState *bs,QEMUSnapshotInfo **psn_info);char *bdrv_snapshot_dump (char *buf,int buf_size,QEMUSnapshotInfo *sn); +int bdrv_execute (BlockDriverState *bs,void *request, +BlockDriverCompletionFunc *complete); +char *get_human_readable_size (char *buf,int buf_size,int64_t size);int path_is_absolute (const char *path);
block-sg.c new file +194 -0
194 lines not on this page · raw message
hw/scsi-generic.c +62 -114
360 lines not on this page · raw message
Makefile.target +1 -1
@@ -398,7 +398,7 @@ VL_OBJS=vl.o osdep.o monitor.o pci.o loa ifdef CONFIG_WIN32 VL_OBJS+=block-raw-win32.o else -VL_OBJS+=block-raw-posix.o qemu-aio-posix.o +VL_OBJS+=block-raw-posix.o block-sg.o qemu-aio-posix.o endif ifdef CONFIG_ALSA
Makefile +1 -1
@@ -40,7 +40,7 @@ recurse-all: $(patsubst %,subdir-%, $(TA BLOCK_OBJS=cutils.o BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o -BLOCK_OBJS+=block-qcow2.o block-parallels.o +BLOCK_OBJS+=block-qcow2.o block-parallels.o block-sg.o ###################################################################### # libqemu_common.a: Target indepedent part of system emulation. The
block-sg.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +* Generic SCSI Device support +* +* Copyright (c) 2008 Bull S.A.S. +* +* Written by Laurent Vivier <[email protected]> +* +* This code is licenced under the LGPL. +* +*/ + +#define SG_ERR_DRIVER_TIMEOUT 0x06 +#define SG_ERR_DRIVER_SENSE 0x08 + +typedef struct SGRequest { +sg_io_hdr_t io_header; +BlockDriverAIOCB *aiocb; +}SGRequest ;
block_int.h +4 -0
@@ -82,6 +82,10 @@ struct BlockDriver {int (*bdrv_eject)(BlockDriverState *bs,int eject_flag);int (*bdrv_set_locked)(BlockDriverState *bs,int locked); +/* SG device */ +int (*bdrv_execute)(BlockDriverState *bs,void *request, +BlockDriverCompletionFunc *complete); +BlockDriverAIOCB *free_aiocb;struct BlockDriver *next; };
PATCH 4/5 DVD movie support
This patch allows to read a protected/encrypted movie from a DVD. (With a Movie Player having the key to decode it, tested with powerDVD)
Laurent
--- hw/scsi-generic.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
hw/scsi-generic.c +11 -1
@@ -46,9 +46,12 @@ do { fprintf(stderr, "scsi-generic: " fm#include <scsi/scsi.h> #include "block-sg.h" +#define BLANK 0xa1 +#define SEND_KEY 0xa3 +#define REPORT_KEY 0xa4#define LOAD_UNLOAD 0xa6 +#define READ_DVD_STRUCTURE 0xad#define SET_CD_SPEED 0xbb -#define BLANK 0xa1#define SCSI_CMD_BUF_SIZE 16#define SCSI_SENSE_BUF_SIZE 32
@@ -398,6 +401,12 @@ static int scsi_length(uint8_t *cmd, intcase READ_12 : *len *= blocksize;break ; +case READ_DVD_STRUCTURE : +case SEND_KEY : +case REPORT_KEY : + *len &=0xffff ; +break ; + }return 0 ; }
@@ -435,6 +444,7 @@ static int is_write(int command)case MEDIUM_SCAN :case SEND_VOLUME_TAG :case WRITE_LONG_2 : +case SEND_KEY :return 1 ; }return 0 ;
PATCH 1/5 reverse scsi-generic
In reply to Laurent VivierThis patch removes modifications in block interface introduced by the scsi-generic implementation, and disables scsi-generic support.
Files restored are:
block-raw-posix.c revision 1.2 block.c revision 1.52 block.h revision 1.5 block_int.h revision 1.15
Laurent
--- block-raw-posix.c | 23 +++-------------------- block.c | 16 ---------------- block.h | 2 -- block_int.h | 4 ---- hw/scsi-generic.c | 3 ++- 5 files changed, 5 insertions(+), 43 deletions(-)
block.c +0 -16
@@ -786,11 +786,6 @@ int bdrv_is_read_only(BlockDriverState *return bs->read_only; } -int bdrv_is_sg (BlockDriverState *bs) -{ -return bs->sg; -} -/* XXX: no longer used */ void bdrv_set_change_cb (BlockDriverState *bs,void (*change_cb)(void *opaque),void *opaque)
@@ -1399,14 +1394,3 @@ void bdrv_set_locked(BlockDriverState *b drv->bdrv_set_locked (bs, locked); } } - -/* needed for generic scsi interface */ - -int bdrv_ioctl (BlockDriverState *bs,unsigned long int req,void *buf) -{ -BlockDriver *drv = bs->drv; - -if (drv && drv->bdrv_ioctl) -return drv->bdrv_ioctl (bs, req, buf); -return -ENOTSUP ; -}
block.h +0 -2
@@ -119,7 +119,6 @@ int bdrv_get_type_hint(BlockDriverStateint bdrv_get_translation_hint (BlockDriverState *bs);int bdrv_is_removable (BlockDriverState *bs);int bdrv_is_read_only (BlockDriverState *bs); -int bdrv_is_sg (BlockDriverState *bs);int bdrv_is_inserted (BlockDriverState *bs);int bdrv_media_changed (BlockDriverState *bs);int bdrv_is_locked (BlockDriverState *bs);
@@ -149,7 +148,6 @@ int bdrv_snapshot_delete(BlockDriverStatint bdrv_snapshot_list (BlockDriverState *bs,QEMUSnapshotInfo **psn_info);char *bdrv_snapshot_dump (char *buf,int buf_size,QEMUSnapshotInfo *sn); -int bdrv_ioctl (BlockDriverState *bs,unsigned long int req,void *buf);char *get_human_readable_size (char *buf,int buf_size,int64_t size);int path_is_absolute (const char *path);
block_int.h +0 -4
@@ -82,9 +82,6 @@ struct BlockDriver {int (*bdrv_eject)(BlockDriverState *bs,int eject_flag);int (*bdrv_set_locked)(BlockDriverState *bs,int locked); -/* to control generic scsi devices */ -int (*bdrv_ioctl)(BlockDriverState *bs,unsigned long int req,void *buf); -BlockDriverAIOCB *free_aiocb;struct BlockDriver *next; };
@@ -96,7 +93,6 @@ struct BlockDriverState {int removable;/* if true, the media can be removed */ int locked;/* if true, the media cannot temporarily be ejected */ int encrypted;/* if true, the media is encrypted */ -int sg;/* if true, the device is a /dev/sg* */ /* event callback when inserting/removing */ void (*change_cb)(void *opaque);void *change_opaque;
block-raw-posix.c +3 -20
@@ -151,7 +151,7 @@ static int raw_pread(BlockDriverState *bif (ret <0 )return ret; -if (offset >=0 &&lseek (s->fd, offset,SEEK_SET ) == (off_t)-1 ) { +if (lseek (s->fd, offset,SEEK_SET ) == (off_t)-1 ) { ++(s->lseek_err_cnt);if (s->lseek_err_cnt <=10 ) { DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
@@ -204,7 +204,7 @@ static int raw_pwrite(BlockDriverState *if (ret <0 )return ret; -if (offset >=0 &&lseek (s->fd, offset,SEEK_SET ) == (off_t)-1 ) { +if (lseek (s->fd, offset,SEEK_SET ) == (off_t)-1 ) { ++(s->lseek_err_cnt);if (s->lseek_err_cnt) { DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
@@ -387,10 +387,7 @@ static RawAIOCB *raw_aio_setup(BlockDriv acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num; acb->aiocb.aio_sigevent.sigev_notify =SIGEV_SIGNAL ; acb->aiocb.aio_buf = buf; -if (nb_sectors <0 ) - acb->aiocb.aio_nbytes = -nb_sectors; -else - acb->aiocb.aio_nbytes = nb_sectors *512 ; + acb->aiocb.aio_nbytes = nb_sectors *512 ; acb->aiocb.aio_offset = sector_num *512 ; acb->next = first_aio; first_aio = acb;
@@ -682,8 +679,6 @@ static int hdev_open(BlockDriverState *b s->fd_open_flags = open_flags;/* open will not fail even if no floppy is inserted */ open_flags |= O_NONBLOCK; - }else if (strstart (filename,"/dev/sg" ,NULL )) { - bs->sg =1 ; }#endif fd =open (filename, open_flags,0644 );
@@ -863,12 +858,6 @@ static int raw_set_locked(BlockDriverSta return 0; } -static int raw_ioctl (BlockDriverState *bs,unsigned long int req,void *buf) -{ -BDRVRawState *s = bs->opaque; - -return ioctl (s->fd, req, buf); -}#else static int raw_is_inserted (BlockDriverState *bs)
@@ -891,10 +880,6 @@ static int raw_set_locked(BlockDriverStareturn -ENOTSUP ; } -static int raw_ioctl (BlockDriverState *bs,unsigned long int req,void *buf) -{ -return -ENOTSUP ; -}#endif /* !linux */ BlockDriver bdrv_host_device = {
@@ -921,6 +906,4 @@ BlockDriver bdrv_host_device = { .bdrv_media_changed = raw_media_changed, .bdrv_eject = raw_eject, .bdrv_set_locked = raw_set_locked, - /* generic scsi device */ - .bdrv_ioctl = raw_ioctl, };
hw/scsi-generic.c +2 -1
@@ -15,7 +15,8 @@#include "block.h" #include "scsi-disk.h" -#ifndef __linux__ +//#ifndef __linux__ +#if 1 SCSIDevice *scsi_generic_init (BlockDriverState *bdrv,int tcq,scsi_completionfn completion,void *opaque)
PATCH 2/5 Move AIO
This patche moves raw AIO part from block-raw-posix.c to qemu-aio-raw.c to be able to use raw AIO from other files.
Laurent
--- Makefile | 2 Makefile.target | 2 block-raw-posix.c | 205 ++------------------------------------------- qemu-aio-posix.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-aio-posix.h | 39 ++++++++ 5 files changed, 293 insertions(+), 196 deletions(-)
Makefile.target +1 -1
@@ -398,7 +398,7 @@ VL_OBJS=vl.o osdep.o monitor.o pci.o loa ifdef CONFIG_WIN32 VL_OBJS+=block-raw-win32.o else -VL_OBJS+=block-raw-posix.o +VL_OBJS+=block-raw-posix.o qemu-aio-posix.o endif ifdef CONFIG_ALSA
block-raw-posix.c +11 -194
246 lines not on this page · raw message
Makefile +1 -1
@@ -136,7 +136,7 @@ QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS) ifdef CONFIG_WIN32 QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o else -QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o +QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o qemu-img-qemu-aio-posix.o endif ######################################################################
qemu-aio-posix.c new file +241 -0
241 lines not on this page · raw message
qemu-aio-posix.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* QEMU Asynchronous I/O +* +* Copyright (c) 2006 Fabrice Bellard +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include <aio.h> + +typedef struct RawAIOCB { +BlockDriverAIOCB common; +struct aiocb aiocb; +struct RawAIOCB *next; +}RawAIOCB ; + +RawAIOCB *qemu_aio_read (BlockDriverState *bs, +int64_t offset,uint8_t *buf,int nb_bytes, +BlockDriverCompletionFunc *cb,void *opaque); +RawAIOCB *qemu_aio_write (BlockDriverState *bs, +int64_t offset,const uint8_t *buf,int nb_bytes, +BlockDriverCompletionFunc *cb,void *opaque); +void qemu_aio_cancel (RawAIOCB *acb);
Two questions:
- Why do you use AIO ? If the Linux sg device supports selects, then using the QEMU select() callback suffices.
- Why do you use a block device ?
Regards,
Fabrice.
Quoted 29 lines · Laurent Vivier
This series of patches makes some cleanups in SCSI passthrough and add functionnalities.
[PATCH 1/5] reverse scsi-generic
Reverse previous implementation and restore
block-raw-posix.c.[PATCH 2/5] Move AIO
This patche moves raw AIO part from
block-raw-posix.ctoqemu-aio-raw.c.[PATCH 3/5] Add block SG interface
This patch re-implement
scsi-generic.cusing a new block interface.[PATCH 4/5] DVD movie support
This patch allows to read a protected/encrypted movie from a DVD.
[PATCH 5/5] SCSI device DMA split
This patch allows to split a READ or WRITE into several READ or WRITE.
Laurent
Quoted 4 lines · Fabrice Bellard
Two questions:
- Why do you use AIO ? If the Linux sg device supports selects, then using the QEMU
select()callback suffices.
Basically because when I want to have asynchronous I/O I use AIO... If you explain me briefly how to use selects in Qemu I can try.
Quoted 1 line
- Why do you use a block device ?
Because to communicate with SG device we need a file descriptor, and using current mechanism (with -drive) allows to have this file descriptor without modifying anything else (without adding a new parameter). Moreover, to use Qemu AIO I need a BlockDriverState (but it related to the first question...)
I agree to change all of this if you give me tips to use selects in Qemu and if you thing adding a new command line parameter is not an issue.
Quoted 3 lines
Regards,
Fabrice.
Thank you for your comments and help,
Laurent
Quoted 32 lines
Quoted 29 lines · Laurent Vivier
This series of patches makes some cleanups in SCSI passthrough and add functionnalities.
[PATCH 1/5] reverse scsi-generic
Reverse previous implementation and restore
block-raw-posix.c.[PATCH 2/5] Move AIO
This patche moves raw AIO part from
block-raw-posix.ctoqemu-aio-raw.c.[PATCH 3/5] Add block SG interface
This patch re-implement
scsi-generic.cusing a new block interface.[PATCH 4/5] DVD movie support
This patch allows to read a protected/encrypted movie from a DVD.
[PATCH 5/5] SCSI device DMA split
This patch allows to split a READ or WRITE into several READ or WRITE.
Laurent
Signature · 3 lines
----------------- [email protected] ------------------ "La perfection est atteinte non quand il ne reste rien à ajouter mais quand il ne reste rien à enlever." Saint Exupéry