+
+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)
+{
+ 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 */