From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LnU2V-0008PX-Be for qemu-devel@nongnu.org; Sat, 28 Mar 2009 04:37:15 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LnU2U-0008PL-I0 for qemu-devel@nongnu.org; Sat, 28 Mar 2009 04:37:14 -0400 Received: from [199.232.76.173] (port=46345 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LnU2U-0008PE-FB for qemu-devel@nongnu.org; Sat, 28 Mar 2009 04:37:14 -0400 Received: from savannah.gnu.org ([199.232.41.3]:55721 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LnU2U-0000KD-4Y for qemu-devel@nongnu.org; Sat, 28 Mar 2009 04:37:14 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1LnU2T-0003g6-O1 for qemu-devel@nongnu.org; Sat, 28 Mar 2009 08:37:13 +0000 Received: from blueswir1 by cvs.savannah.gnu.org with local (Exim 4.69) (envelope-from ) id 1LnU2T-0003g2-H5 for qemu-devel@nongnu.org; Sat, 28 Mar 2009 08:37:13 +0000 MIME-Version: 1.0 Errors-To: blueswir1 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Blue Swirl Message-Id: Date: Sat, 28 Mar 2009 08:37:13 +0000 Subject: [Qemu-devel] [6888] FreeBSD host physical cdrom fixes Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 6888 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6888 Author: blueswir1 Date: 2009-03-28 08:37:13 +0000 (Sat, 28 Mar 2009) Log Message: ----------- FreeBSD host physical cdrom fixes This improves physical cdrom support on FreeBSD hosts to be almost as good as on Linux, with the only notable exception that you still need to either have the guest itself eject the disc if you want to take it out/change it, or do a change command in the monitor after taking out a disc in case a guest cannot eject it itself - otherwise the guest may continue using state (like size) of the old disc. Signed-off-by: Juergen Lock Modified Paths: -------------- trunk/block-raw-posix.c Modified: trunk/block-raw-posix.c =================================================================== --- trunk/block-raw-posix.c 2009-03-28 08:24:44 UTC (rev 6887) +++ trunk/block-raw-posix.c 2009-03-28 08:37:13 UTC (rev 6888) @@ -55,6 +55,7 @@ #ifdef __FreeBSD__ #include #include +#include #endif #ifdef __OpenBSD__ @@ -110,6 +111,9 @@ int fd_got_error; int fd_media_changed; #endif +#if defined(__FreeBSD__) + int cd_open_flags; +#endif uint8_t* aligned_buf; } BDRVRawState; @@ -117,6 +121,12 @@ static int fd_open(BlockDriverState *bs); +#if defined(__FreeBSD__) +static int cd_open(BlockDriverState *bs); +#endif + +static int raw_is_inserted(BlockDriverState *bs); + static int raw_open(BlockDriverState *bs, const char *filename, int flags) { BDRVRawState *s = bs->opaque; @@ -773,7 +783,10 @@ int64_t size; #ifdef HOST_BSD struct stat sb; +#ifdef __FreeBSD__ + int reopened = 0; #endif +#endif #ifdef __sun__ struct dk_minfo minfo; int rv; @@ -785,6 +798,9 @@ return ret; #ifdef HOST_BSD +#ifdef __FreeBSD__ +again: +#endif if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { #ifdef DIOCGMEDIASIZE if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) @@ -803,6 +819,19 @@ #else size = lseek(fd, 0LL, SEEK_END); #endif +#ifdef __FreeBSD__ + switch(s->type) { + case FTYPE_CD: + /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */ + if (size == 2048LL * (unsigned)-1) + size = 0; + /* XXX no disc? maybe we need to reopen... */ + if (size <= 0 && !reopened && cd_open(bs) >= 0) { + reopened = 1; + goto again; + } + } +#endif } else #endif #ifdef __sun__ @@ -993,6 +1022,14 @@ bs->sg = 1; } #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; @@ -1001,6 +1038,11 @@ 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) { @@ -1167,15 +1209,124 @@ return ioctl(s->fd, req, buf); } -#else +#elif defined(__FreeBSD__) static int fd_open(BlockDriverState *bs) { + BDRVRawState *s = bs->opaque; + + /* this is just to ensure s->fd is sane (its called by io ops) */ + if (s->fd >= 0) + 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) +{ + return 0; +} + +static int raw_is_inserted(BlockDriverState *bs) +{ return 1; } @@ -1198,7 +1349,7 @@ { return -ENOTSUP; } -#endif /* !linux */ +#endif /* !linux && !FreeBSD */ static int raw_sg_send_command(BlockDriverState *bs, void *buf, int count) {