Merge commit 'block/master' into staging
* commit 'block/master': raw-posix: cleanup ioctl methods block: add bdrv_probe_device method raw-posix: split hdev drivers raw-posix: add a raw_open_common helper raw-posix: always store open flags fix qemu_aio_flush Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
						commit
						e510e05b5d
					
				
							
								
								
									
										8
									
								
								aio.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								aio.c
									
									
									
									
									
								
							@ -103,11 +103,15 @@ void qemu_aio_flush(void)
 | 
			
		||||
    do {
 | 
			
		||||
        ret = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If there are pending emulated aio start them now so flush
 | 
			
		||||
	 * will be able to return 1.
 | 
			
		||||
	 */
 | 
			
		||||
        qemu_aio_wait();
 | 
			
		||||
 | 
			
		||||
        LIST_FOREACH(node, &aio_handlers, node) {
 | 
			
		||||
            ret |= node->io_flush(node->opaque);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qemu_aio_wait();
 | 
			
		||||
    } while (ret > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								block.c
									
									
									
									
									
								
							@ -209,7 +209,7 @@ static int is_windows_drive_prefix(const char *filename)
 | 
			
		||||
            filename[1] == ':');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_windows_drive(const char *filename)
 | 
			
		||||
int is_windows_drive(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    if (is_windows_drive_prefix(filename) &&
 | 
			
		||||
        filename[2] == '\0')
 | 
			
		||||
@ -249,8 +249,28 @@ static BlockDriver *find_protocol(const char *filename)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* XXX: force raw format if block or character device ? It would
 | 
			
		||||
   simplify the BSD case */
 | 
			
		||||
/*
 | 
			
		||||
 * Detect host devices. By convention, /dev/cdrom[N] is always
 | 
			
		||||
 * recognized as a host CDROM.
 | 
			
		||||
 */
 | 
			
		||||
static BlockDriver *find_hdev_driver(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    int score_max = 0, score;
 | 
			
		||||
    BlockDriver *drv = NULL, *d;
 | 
			
		||||
 | 
			
		||||
    for (d = first_drv; d; d = d->next) {
 | 
			
		||||
        if (d->bdrv_probe_device) {
 | 
			
		||||
            score = d->bdrv_probe_device(filename);
 | 
			
		||||
            if (score > score_max) {
 | 
			
		||||
                score_max = score;
 | 
			
		||||
                drv = d;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return drv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriver *find_image_format(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    int ret, score, score_max;
 | 
			
		||||
@ -258,23 +278,6 @@ static BlockDriver *find_image_format(const char *filename)
 | 
			
		||||
    uint8_t buf[2048];
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
 | 
			
		||||
    /* detect host devices. By convention, /dev/cdrom[N] is always
 | 
			
		||||
       recognized as a host CDROM */
 | 
			
		||||
    if (strstart(filename, "/dev/cdrom", NULL))
 | 
			
		||||
        return bdrv_find_format("host_device");
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    if (is_windows_drive(filename))
 | 
			
		||||
        return bdrv_find_format("host_device");
 | 
			
		||||
#else
 | 
			
		||||
    {
 | 
			
		||||
        struct stat st;
 | 
			
		||||
        if (stat(filename, &st) >= 0 &&
 | 
			
		||||
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
 | 
			
		||||
            return bdrv_find_format("host_device");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    drv = find_protocol(filename);
 | 
			
		||||
    /* no need to test disk image formats for vvfat */
 | 
			
		||||
    if (drv && strcmp(drv->format_name, "vvfat") == 0)
 | 
			
		||||
@ -394,8 +397,11 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
    if (flags & BDRV_O_FILE) {
 | 
			
		||||
        drv = find_protocol(filename);
 | 
			
		||||
    } else if (!drv) {
 | 
			
		||||
        drv = find_hdev_driver(filename);
 | 
			
		||||
        if (!drv) {
 | 
			
		||||
            drv = find_image_format(filename);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (!drv) {
 | 
			
		||||
        ret = -ENOENT;
 | 
			
		||||
        goto unlink_and_fail;
 | 
			
		||||
 | 
			
		||||
@ -103,16 +103,13 @@ typedef struct BDRVRawState {
 | 
			
		||||
    int fd;
 | 
			
		||||
    int type;
 | 
			
		||||
    unsigned int lseek_err_cnt;
 | 
			
		||||
    int open_flags;
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
    /* linux floppy specific */
 | 
			
		||||
    int fd_open_flags;
 | 
			
		||||
    int64_t fd_open_time;
 | 
			
		||||
    int64_t fd_error_time;
 | 
			
		||||
    int fd_got_error;
 | 
			
		||||
    int fd_media_changed;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
    int cd_open_flags;
 | 
			
		||||
#endif
 | 
			
		||||
    uint8_t* aligned_buf;
 | 
			
		||||
} BDRVRawState;
 | 
			
		||||
@ -122,40 +119,36 @@ static int posix_aio_init(void);
 | 
			
		||||
static int fd_open(BlockDriverState *bs);
 | 
			
		||||
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
static int cd_open(BlockDriverState *bs);
 | 
			
		||||
static int cdrom_reopen(BlockDriverState *bs);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int raw_is_inserted(BlockDriverState *bs);
 | 
			
		||||
 | 
			
		||||
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
static int raw_open_common(BlockDriverState *bs, const char *filename,
 | 
			
		||||
        int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int fd, open_flags, ret;
 | 
			
		||||
    int fd, ret;
 | 
			
		||||
 | 
			
		||||
    posix_aio_init();
 | 
			
		||||
 | 
			
		||||
    s->lseek_err_cnt = 0;
 | 
			
		||||
 | 
			
		||||
    open_flags = O_BINARY;
 | 
			
		||||
    s->open_flags |= O_BINARY;
 | 
			
		||||
    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
 | 
			
		||||
        open_flags |= O_RDWR;
 | 
			
		||||
        s->open_flags |= O_RDWR;
 | 
			
		||||
    } else {
 | 
			
		||||
        open_flags |= O_RDONLY;
 | 
			
		||||
        s->open_flags |= O_RDONLY;
 | 
			
		||||
        bs->read_only = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (flags & BDRV_O_CREAT)
 | 
			
		||||
        open_flags |= O_CREAT | O_TRUNC;
 | 
			
		||||
 | 
			
		||||
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
 | 
			
		||||
     * and O_DIRECT for no caching. */
 | 
			
		||||
    if ((flags & BDRV_O_NOCACHE))
 | 
			
		||||
        open_flags |= O_DIRECT;
 | 
			
		||||
        s->open_flags |= O_DIRECT;
 | 
			
		||||
    else if (!(flags & BDRV_O_CACHE_WB))
 | 
			
		||||
        open_flags |= O_DSYNC;
 | 
			
		||||
        s->open_flags |= O_DSYNC;
 | 
			
		||||
 | 
			
		||||
    s->type = FTYPE_FILE;
 | 
			
		||||
 | 
			
		||||
    fd = open(filename, open_flags, 0644);
 | 
			
		||||
    s->fd = -1;
 | 
			
		||||
    fd = open(filename, s->open_flags, 0644);
 | 
			
		||||
    if (fd < 0) {
 | 
			
		||||
        ret = -errno;
 | 
			
		||||
        if (ret == -EROFS)
 | 
			
		||||
@ -175,6 +168,17 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    s->type = FTYPE_FILE;
 | 
			
		||||
    if (flags & BDRV_O_CREAT)
 | 
			
		||||
        s->open_flags |= O_CREAT | O_TRUNC;
 | 
			
		||||
 | 
			
		||||
    return raw_open_common(bs, filename, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* XXX: use host sector size if necessary with:
 | 
			
		||||
#ifdef DIOCGSECTORSIZE
 | 
			
		||||
        {
 | 
			
		||||
@ -802,7 +806,7 @@ again:
 | 
			
		||||
            if (size == 2048LL * (unsigned)-1)
 | 
			
		||||
                size = 0;
 | 
			
		||||
            /* XXX no disc?  maybe we need to reopen... */
 | 
			
		||||
            if (size <= 0 && !reopened && cd_open(bs) >= 0) {
 | 
			
		||||
            if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
 | 
			
		||||
                reopened = 1;
 | 
			
		||||
                goto again;
 | 
			
		||||
            }
 | 
			
		||||
@ -949,12 +953,25 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int hdev_probe_device(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    struct stat st;
 | 
			
		||||
 | 
			
		||||
    /* allow a dedicated CD-ROM driver to match with a higher priority */
 | 
			
		||||
    if (strstart(filename, "/dev/cdrom", NULL))
 | 
			
		||||
        return 50;
 | 
			
		||||
 | 
			
		||||
    if (stat(filename, &st) >= 0 &&
 | 
			
		||||
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
 | 
			
		||||
        return 100;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int fd, open_flags, ret;
 | 
			
		||||
 | 
			
		||||
    posix_aio_init();
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_COCOA
 | 
			
		||||
    if (strstart(filename, "/dev/cdrom", NULL)) {
 | 
			
		||||
@ -982,67 +999,15 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
            IOObjectRelease( mediaIterator );
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    open_flags = O_BINARY;
 | 
			
		||||
    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
 | 
			
		||||
        open_flags |= O_RDWR;
 | 
			
		||||
    } else {
 | 
			
		||||
        open_flags |= O_RDONLY;
 | 
			
		||||
        bs->read_only = 1;
 | 
			
		||||
    }
 | 
			
		||||
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
 | 
			
		||||
     * and O_DIRECT for no caching. */
 | 
			
		||||
    if ((flags & BDRV_O_NOCACHE))
 | 
			
		||||
        open_flags |= O_DIRECT;
 | 
			
		||||
    else if (!(flags & BDRV_O_CACHE_WB))
 | 
			
		||||
        open_flags |= O_DSYNC;
 | 
			
		||||
 | 
			
		||||
    s->type = FTYPE_FILE;
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
    if (strstart(filename, "/dev/cd", NULL)) {
 | 
			
		||||
        /* open will not fail even if no CD is inserted */
 | 
			
		||||
        open_flags |= O_NONBLOCK;
 | 
			
		||||
        s->type = FTYPE_CD;
 | 
			
		||||
    } else if (strstart(filename, "/dev/fd", NULL)) {
 | 
			
		||||
        s->type = FTYPE_FD;
 | 
			
		||||
        s->fd_open_flags = open_flags;
 | 
			
		||||
        /* open will not fail even if no floppy is inserted */
 | 
			
		||||
        open_flags |= O_NONBLOCK;
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    } else if (strstart(filename, "/dev/sg", NULL)) {
 | 
			
		||||
#if defined(__linux__) && defined(CONFIG_AIO)
 | 
			
		||||
    if (strstart(filename, "/dev/sg", NULL)) {
 | 
			
		||||
        bs->sg = 1;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
    if (strstart(filename, "/dev/cd", NULL) ||
 | 
			
		||||
        strstart(filename, "/dev/acd", NULL)) {
 | 
			
		||||
        s->type = FTYPE_CD;
 | 
			
		||||
        s->cd_open_flags = open_flags;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    s->fd = -1;
 | 
			
		||||
    fd = open(filename, open_flags, 0644);
 | 
			
		||||
    if (fd < 0) {
 | 
			
		||||
        ret = -errno;
 | 
			
		||||
        if (ret == -EROFS)
 | 
			
		||||
            ret = -EACCES;
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
    /* make sure the door isnt locked at this time */
 | 
			
		||||
    if (s->type == FTYPE_CD)
 | 
			
		||||
        ioctl (s->fd, CDIOCALLOW);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
    /* close fd so that we can reopen it as needed */
 | 
			
		||||
    if (s->type == FTYPE_FD) {
 | 
			
		||||
        close(s->fd);
 | 
			
		||||
        s->fd = -1;
 | 
			
		||||
        s->fd_media_changed = 1;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
    return raw_open_common(bs, filename, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
@ -1073,7 +1038,7 @@ static int fd_open(BlockDriverState *bs)
 | 
			
		||||
#endif
 | 
			
		||||
            return -EIO;
 | 
			
		||||
        }
 | 
			
		||||
        s->fd = open(bs->filename, s->fd_open_flags);
 | 
			
		||||
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
 | 
			
		||||
        if (s->fd < 0) {
 | 
			
		||||
            s->fd_error_time = qemu_get_clock(rt_clock);
 | 
			
		||||
            s->fd_got_error = 1;
 | 
			
		||||
@ -1095,106 +1060,7 @@ static int fd_open(BlockDriverState *bs)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
 | 
			
		||||
        if (ret == CDS_DISC_OK)
 | 
			
		||||
            return 1;
 | 
			
		||||
        else
 | 
			
		||||
            return 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case FTYPE_FD:
 | 
			
		||||
        ret = fd_open(bs);
 | 
			
		||||
        return (ret >= 0);
 | 
			
		||||
    default:
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* currently only used by fdc.c, but a CD version would be good too */
 | 
			
		||||
static int raw_media_changed(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_FD:
 | 
			
		||||
        {
 | 
			
		||||
            int ret;
 | 
			
		||||
            /* XXX: we do not have a true media changed indication. It
 | 
			
		||||
               does not work if the floppy is changed without trying
 | 
			
		||||
               to read it */
 | 
			
		||||
            fd_open(bs);
 | 
			
		||||
            ret = s->fd_media_changed;
 | 
			
		||||
            s->fd_media_changed = 0;
 | 
			
		||||
#ifdef DEBUG_FLOPPY
 | 
			
		||||
            printf("Floppy changed=%d\n", ret);
 | 
			
		||||
#endif
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    default:
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        if (eject_flag) {
 | 
			
		||||
            if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
 | 
			
		||||
                perror("CDROMEJECT");
 | 
			
		||||
        } else {
 | 
			
		||||
            if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
 | 
			
		||||
                perror("CDROMEJECT");
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case FTYPE_FD:
 | 
			
		||||
        {
 | 
			
		||||
            int fd;
 | 
			
		||||
            if (s->fd >= 0) {
 | 
			
		||||
                close(s->fd);
 | 
			
		||||
                s->fd = -1;
 | 
			
		||||
            }
 | 
			
		||||
            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
 | 
			
		||||
            if (fd >= 0) {
 | 
			
		||||
                if (ioctl(fd, FDEJECT, 0) < 0)
 | 
			
		||||
                    perror("FDEJECT");
 | 
			
		||||
                close(fd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
 | 
			
		||||
            /* Note: an error can happen if the distribution automatically
 | 
			
		||||
               mounts the CD-ROM */
 | 
			
		||||
            //        perror("CDROM_LOCKDOOR");
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 | 
			
		||||
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
@ -1202,7 +1068,7 @@ static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
 | 
			
		||||
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
 | 
			
		||||
        unsigned long int req, void *buf,
 | 
			
		||||
        BlockDriverCompletionFunc *cb, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
@ -1235,7 +1101,6 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#elif defined(__FreeBSD__)
 | 
			
		||||
 | 
			
		||||
static int fd_open(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
@ -1245,104 +1110,6 @@ static int fd_open(BlockDriverState *bs)
 | 
			
		||||
        return 0;
 | 
			
		||||
    return -EIO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cd_open(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        /* XXX force reread of possibly changed/newly loaded disc,
 | 
			
		||||
         * FreeBSD seems to not notice sometimes... */
 | 
			
		||||
        if (s->fd >= 0)
 | 
			
		||||
            close (s->fd);
 | 
			
		||||
        fd = open(bs->filename, s->cd_open_flags, 0644);
 | 
			
		||||
        if (fd < 0) {
 | 
			
		||||
            s->fd = -1;
 | 
			
		||||
            return -EIO;
 | 
			
		||||
        }
 | 
			
		||||
        s->fd = fd;
 | 
			
		||||
        /* make sure the door isnt locked at this time */
 | 
			
		||||
        ioctl (s->fd, CDIOCALLOW);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        return (raw_getlength(bs) > 0);
 | 
			
		||||
    case FTYPE_FD:
 | 
			
		||||
        /* XXX handle this */
 | 
			
		||||
        /* FALLTHRU */
 | 
			
		||||
    default:
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_media_changed(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        if (s->fd < 0)
 | 
			
		||||
            return -ENOTSUP;
 | 
			
		||||
        (void) ioctl (s->fd, CDIOCALLOW);
 | 
			
		||||
        if (eject_flag) {
 | 
			
		||||
            if (ioctl (s->fd, CDIOCEJECT) < 0)
 | 
			
		||||
                perror("CDIOCEJECT");
 | 
			
		||||
        } else {
 | 
			
		||||
            if (ioctl (s->fd, CDIOCCLOSE) < 0)
 | 
			
		||||
                perror("CDIOCCLOSE");
 | 
			
		||||
        }
 | 
			
		||||
        if (cd_open(bs) < 0)
 | 
			
		||||
            return -ENOTSUP;
 | 
			
		||||
        break;
 | 
			
		||||
    case FTYPE_FD:
 | 
			
		||||
        /* XXX handle this */
 | 
			
		||||
        /* FALLTHRU */
 | 
			
		||||
    default:
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    switch(s->type) {
 | 
			
		||||
    case FTYPE_CD:
 | 
			
		||||
        if (s->fd < 0)
 | 
			
		||||
            return -ENOTSUP;
 | 
			
		||||
        if (ioctl (s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
 | 
			
		||||
            /* Note: an error can happen if the distribution automatically
 | 
			
		||||
               mounts the CD-ROM */
 | 
			
		||||
            //        perror("CDROM_LOCKDOOR");
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
#else /* !linux && !FreeBSD */
 | 
			
		||||
 | 
			
		||||
static int fd_open(BlockDriverState *bs)
 | 
			
		||||
@ -1350,37 +1117,6 @@ static int fd_open(BlockDriverState *bs)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_media_changed(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 | 
			
		||||
{
 | 
			
		||||
    return -ENOTSUP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
 | 
			
		||||
        unsigned long int req, void *buf,
 | 
			
		||||
        BlockDriverCompletionFunc *cb, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
#endif /* !linux && !FreeBSD */
 | 
			
		||||
 | 
			
		||||
static int hdev_create(const char *filename, QEMUOptionParameter *options)
 | 
			
		||||
@ -1416,6 +1152,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
 | 
			
		||||
static BlockDriver bdrv_host_device = {
 | 
			
		||||
    .format_name	= "host_device",
 | 
			
		||||
    .instance_size	= sizeof(BDRVRawState),
 | 
			
		||||
    .bdrv_probe_device	= hdev_probe_device,
 | 
			
		||||
    .bdrv_open		= hdev_open,
 | 
			
		||||
    .bdrv_close		= raw_close,
 | 
			
		||||
    .bdrv_create        = hdev_create,
 | 
			
		||||
@ -1430,22 +1167,335 @@ static BlockDriver bdrv_host_device = {
 | 
			
		||||
    .bdrv_write         = raw_write,
 | 
			
		||||
    .bdrv_getlength	= raw_getlength,
 | 
			
		||||
 | 
			
		||||
    /* removable device support */
 | 
			
		||||
    .bdrv_is_inserted	= raw_is_inserted,
 | 
			
		||||
    .bdrv_media_changed	= raw_media_changed,
 | 
			
		||||
    .bdrv_eject		= raw_eject,
 | 
			
		||||
    .bdrv_set_locked	= raw_set_locked,
 | 
			
		||||
    /* generic scsi device */
 | 
			
		||||
    .bdrv_ioctl		= raw_ioctl,
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    .bdrv_ioctl         = hdev_ioctl,
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    .bdrv_aio_ioctl	= raw_aio_ioctl,
 | 
			
		||||
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    posix_aio_init();
 | 
			
		||||
 | 
			
		||||
    s->type = FTYPE_FD;
 | 
			
		||||
    /* open will not fail even if no floppy is inserted */
 | 
			
		||||
    s->open_flags |= O_NONBLOCK;
 | 
			
		||||
 | 
			
		||||
    ret = raw_open_common(bs, filename, flags);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    /* close fd so that we can reopen it as needed */
 | 
			
		||||
    close(s->fd);
 | 
			
		||||
    s->fd = -1;
 | 
			
		||||
    s->fd_media_changed = 1;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int floppy_probe_device(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    if (strstart(filename, "/dev/fd", NULL))
 | 
			
		||||
        return 100;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int floppy_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    return fd_open(bs) >= 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int floppy_media_changed(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * XXX: we do not have a true media changed indication.
 | 
			
		||||
     * It does not work if the floppy is changed without trying to read it.
 | 
			
		||||
     */
 | 
			
		||||
    fd_open(bs);
 | 
			
		||||
    ret = s->fd_media_changed;
 | 
			
		||||
    s->fd_media_changed = 0;
 | 
			
		||||
#ifdef DEBUG_FLOPPY
 | 
			
		||||
    printf("Floppy changed=%d\n", ret);
 | 
			
		||||
#endif
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int floppy_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    if (s->fd >= 0) {
 | 
			
		||||
        close(s->fd);
 | 
			
		||||
        s->fd = -1;
 | 
			
		||||
    }
 | 
			
		||||
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
 | 
			
		||||
    if (fd >= 0) {
 | 
			
		||||
        if (ioctl(fd, FDEJECT, 0) < 0)
 | 
			
		||||
            perror("FDEJECT");
 | 
			
		||||
        close(fd);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriver bdrv_host_floppy = {
 | 
			
		||||
    .format_name        = "host_floppy",
 | 
			
		||||
    .instance_size      = sizeof(BDRVRawState),
 | 
			
		||||
    .bdrv_probe_device	= floppy_probe_device,
 | 
			
		||||
    .bdrv_open          = floppy_open,
 | 
			
		||||
    .bdrv_close         = raw_close,
 | 
			
		||||
    .bdrv_create        = hdev_create,
 | 
			
		||||
    .bdrv_flush         = raw_flush,
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    .bdrv_aio_readv     = raw_aio_readv,
 | 
			
		||||
    .bdrv_aio_writev    = raw_aio_writev,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    .bdrv_read          = raw_read,
 | 
			
		||||
    .bdrv_write         = raw_write,
 | 
			
		||||
    .bdrv_getlength	= raw_getlength,
 | 
			
		||||
 | 
			
		||||
    /* removable device support */
 | 
			
		||||
    .bdrv_is_inserted   = floppy_is_inserted,
 | 
			
		||||
    .bdrv_media_changed = floppy_media_changed,
 | 
			
		||||
    .bdrv_eject         = floppy_eject,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    /* open will not fail even if no CD is inserted */
 | 
			
		||||
    s->open_flags |= O_NONBLOCK;
 | 
			
		||||
    s->type = FTYPE_CD;
 | 
			
		||||
 | 
			
		||||
    return raw_open_common(bs, filename, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_probe_device(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    if (strstart(filename, "/dev/cd", NULL))
 | 
			
		||||
        return 100;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
 | 
			
		||||
    if (ret == CDS_DISC_OK)
 | 
			
		||||
        return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    if (eject_flag) {
 | 
			
		||||
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
 | 
			
		||||
            perror("CDROMEJECT");
 | 
			
		||||
    } else {
 | 
			
		||||
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
 | 
			
		||||
            perror("CDROMEJECT");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
 | 
			
		||||
        /*
 | 
			
		||||
         * Note: an error can happen if the distribution automatically
 | 
			
		||||
         * mounts the CD-ROM
 | 
			
		||||
         */
 | 
			
		||||
        /* perror("CDROM_LOCKDOOR"); */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriver bdrv_host_cdrom = {
 | 
			
		||||
    .format_name        = "host_cdrom",
 | 
			
		||||
    .instance_size      = sizeof(BDRVRawState),
 | 
			
		||||
    .bdrv_probe_device	= cdrom_probe_device,
 | 
			
		||||
    .bdrv_open          = cdrom_open,
 | 
			
		||||
    .bdrv_close         = raw_close,
 | 
			
		||||
    .bdrv_create        = hdev_create,
 | 
			
		||||
    .bdrv_flush         = raw_flush,
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    .bdrv_aio_readv     = raw_aio_readv,
 | 
			
		||||
    .bdrv_aio_writev    = raw_aio_writev,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    .bdrv_read          = raw_read,
 | 
			
		||||
    .bdrv_write         = raw_write,
 | 
			
		||||
    .bdrv_getlength     = raw_getlength,
 | 
			
		||||
 | 
			
		||||
    /* removable device support */
 | 
			
		||||
    .bdrv_is_inserted   = cdrom_is_inserted,
 | 
			
		||||
    .bdrv_eject         = cdrom_eject,
 | 
			
		||||
    .bdrv_set_locked    = cdrom_set_locked,
 | 
			
		||||
 | 
			
		||||
    /* generic scsi device */
 | 
			
		||||
    .bdrv_ioctl         = hdev_ioctl,
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
#endif /* __linux__ */
 | 
			
		||||
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    s->type = FTYPE_CD;
 | 
			
		||||
 | 
			
		||||
    ret = raw_open_common(bs, filename, flags);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    /* make sure the door isnt locked at this time */
 | 
			
		||||
    ioctl(s->fd, CDIOCALLOW);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_probe_device(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    if (strstart(filename, "/dev/cd", NULL) ||
 | 
			
		||||
            strstart(filename, "/dev/acd", NULL))
 | 
			
		||||
        return 100;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_reopen(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Force reread of possibly changed/newly loaded disc,
 | 
			
		||||
     * FreeBSD seems to not notice sometimes...
 | 
			
		||||
     */
 | 
			
		||||
    if (s->fd >= 0)
 | 
			
		||||
        close(s->fd);
 | 
			
		||||
    fd = open(bs->filename, s->open_flags, 0644);
 | 
			
		||||
    if (fd < 0) {
 | 
			
		||||
        s->fd = -1;
 | 
			
		||||
        return -EIO;
 | 
			
		||||
    }
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
 | 
			
		||||
    /* make sure the door isnt locked at this time */
 | 
			
		||||
    ioctl(s->fd, CDIOCALLOW);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_is_inserted(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    return raw_getlength(bs) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    if (s->fd < 0)
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
 | 
			
		||||
    (void) ioctl(s->fd, CDIOCALLOW);
 | 
			
		||||
 | 
			
		||||
    if (eject_flag) {
 | 
			
		||||
        if (ioctl(s->fd, CDIOCEJECT) < 0)
 | 
			
		||||
            perror("CDIOCEJECT");
 | 
			
		||||
    } else {
 | 
			
		||||
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
 | 
			
		||||
            perror("CDIOCCLOSE");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (cdrom_reopen(bs) < 0)
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int cdrom_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    if (s->fd < 0)
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
 | 
			
		||||
        /*
 | 
			
		||||
         * Note: an error can happen if the distribution automatically
 | 
			
		||||
         * mounts the CD-ROM
 | 
			
		||||
         */
 | 
			
		||||
        /* perror("CDROM_LOCKDOOR"); */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriver bdrv_host_cdrom = {
 | 
			
		||||
    .format_name        = "host_cdrom",
 | 
			
		||||
    .instance_size      = sizeof(BDRVRawState),
 | 
			
		||||
    .bdrv_probe_device	= cdrom_probe_device,
 | 
			
		||||
    .bdrv_open          = cdrom_open,
 | 
			
		||||
    .bdrv_close         = raw_close,
 | 
			
		||||
    .bdrv_create        = hdev_create,
 | 
			
		||||
    .bdrv_flush         = raw_flush,
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_AIO
 | 
			
		||||
    .bdrv_aio_readv     = raw_aio_readv,
 | 
			
		||||
    .bdrv_aio_writev    = raw_aio_writev,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    .bdrv_read          = raw_read,
 | 
			
		||||
    .bdrv_write         = raw_write,
 | 
			
		||||
    .bdrv_getlength     = raw_getlength,
 | 
			
		||||
 | 
			
		||||
    /* removable device support */
 | 
			
		||||
    .bdrv_is_inserted   = cdrom_is_inserted,
 | 
			
		||||
    .bdrv_eject         = cdrom_eject,
 | 
			
		||||
    .bdrv_set_locked    = cdrom_set_locked,
 | 
			
		||||
};
 | 
			
		||||
#endif /* __FreeBSD__ */
 | 
			
		||||
 | 
			
		||||
static void bdrv_raw_init(void)
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Register all the drivers.  Note that order is important, the driver
 | 
			
		||||
     * registered last will get probed first.
 | 
			
		||||
     */
 | 
			
		||||
    bdrv_register(&bdrv_raw);
 | 
			
		||||
    bdrv_register(&bdrv_host_device);
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    bdrv_register(&bdrv_host_floppy);
 | 
			
		||||
    bdrv_register(&bdrv_host_cdrom);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
    bdrv_register(&bdrv_host_cdrom);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
block_init(bdrv_raw_init);
 | 
			
		||||
 | 
			
		||||
@ -306,6 +306,15 @@ static int find_device_type(BlockDriverState *bs, const char *filename)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int hdev_probe_device(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
    if (strstart(filename, "/dev/cdrom", NULL))
 | 
			
		||||
        return 100;
 | 
			
		||||
    if (is_windows_drive(filename))
 | 
			
		||||
        return 100;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRawState *s = bs->opaque;
 | 
			
		||||
@ -391,6 +400,7 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
 | 
			
		||||
static BlockDriver bdrv_host_device = {
 | 
			
		||||
    .format_name	= "host_device",
 | 
			
		||||
    .instance_size	= sizeof(BDRVRawState),
 | 
			
		||||
    .bdrv_probe_device	= hdev_probe_device,
 | 
			
		||||
    .bdrv_open		= hdev_open,
 | 
			
		||||
    .bdrv_close		= raw_close,
 | 
			
		||||
    .bdrv_flush		= raw_flush,
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,7 @@ struct BlockDriver {
 | 
			
		||||
    const char *format_name;
 | 
			
		||||
    int instance_size;
 | 
			
		||||
    int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
 | 
			
		||||
    int (*bdrv_probe_device)(const char *filename);
 | 
			
		||||
    int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
 | 
			
		||||
    int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
                     uint8_t *buf, int nb_sectors);
 | 
			
		||||
@ -177,4 +178,8 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
 | 
			
		||||
 | 
			
		||||
extern BlockDriverState *bdrv_first;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
int is_windows_drive(const char *filename);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* BLOCK_INT_H */
 | 
			
		||||
 | 
			
		||||
@ -24,9 +24,10 @@ typedef int (AioFlushHandler)(void *opaque);
 | 
			
		||||
 * outstanding AIO operations have been completed or cancelled. */
 | 
			
		||||
void qemu_aio_flush(void);
 | 
			
		||||
 | 
			
		||||
/* Wait for a single AIO completion to occur.  This function will until a
 | 
			
		||||
 * single AIO opeartion has completed.  It is intended to be used as a looping
 | 
			
		||||
 * primative when simulating synchronous IO based on asynchronous IO. */
 | 
			
		||||
/* Wait for a single AIO completion to occur.  This function will wait
 | 
			
		||||
 * until a single AIO event has completed and it will ensure something
 | 
			
		||||
 * has moved before returning. This can issue new pending aio as
 | 
			
		||||
 * result of executing I/O completion or bh callbacks. */
 | 
			
		||||
void qemu_aio_wait(void);
 | 
			
		||||
 | 
			
		||||
/* Register a file descriptor and associated callbacks.  Behaves very similarly
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user