Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.5575
blktap-pv-cdrom.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File blktap-pv-cdrom.patch of Package xen.5575
--- tools/blktap/drivers/Makefile | 6 tools/blktap/drivers/block-cdrom.c | 565 +++++++++++++++++++++++ tools/blktap/drivers/tapdisk.c | 16 tools/blktap/drivers/tapdisk.h | 16 tools/blktap/lib/blktaplib.h | 1 xen/include/public/io/blkif.h | 2 xen/include/public/io/cdromif.h | 122 ++++ 7 files changed, 726 insertions(+), 3 deletions(-) Index: xen-4.5.1-testing/tools/blktap/drivers/Makefile =================================================================== --- xen-4.5.1-testing.orig/tools/blktap/drivers/Makefile +++ xen-4.5.1-testing/tools/blktap/drivers/Makefile @@ -35,8 +35,9 @@ AIOLIBS := -laio CFLAGS += $(PTHREAD_CFLAGS) LDFLAGS += $(PTHREAD_LDFLAGS) -LDLIBS_blktapctrl := $(MEMSHRLIBS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) -L../lib -lblktap -lrt -lm $(PTHREAD_LIBS) -LDLIBS_img := $(AIOLIBS) $(CRYPT_LIB) $(PTHREAD_LIBS) -lz +LDLIBS_xen := $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) +LDLIBS_blktapctrl := $(MEMSHRLIBS) $(LDLIBS_xen) -L../lib -lblktap -lrt -lm $(PTHREAD_LIBS) +LDLIBS_img := $(AIOLIBS) $(CRYPT_LIB) $(PTHREAD_LIBS) -lz $(LDLIBS_xen) BLK-OBJS-y := block-aio.o BLK-OBJS-y += block-sync.o @@ -44,6 +45,7 @@ BLK-OBJS-y += block-vmdk.o BLK-OBJS-y += block-ram.o BLK-OBJS-y += block-qcow.o BLK-OBJS-y += block-qcow2.o +BLK-OBJS-y += block-cdrom.o BLK-OBJS-y += aes.o BLK-OBJS-y += tapaio.o BLK-OBJS-$(CONFIG_Linux) += blk_linux.o Index: xen-4.5.1-testing/tools/blktap/drivers/block-cdrom.c =================================================================== --- /dev/null +++ xen-4.5.1-testing/tools/blktap/drivers/block-cdrom.c @@ -0,0 +1,568 @@ +/* block-cdrom.c + * + * simple slow synchronous cdrom disk implementation. Based off + * of block-sync.c + * + * (c) 2006 Andrew Warfield and Julian Chesterfield + * (c) 2008 Novell Inc. <plc@novell.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (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 <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/statvfs.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/mount.h> + +#include "tapdisk.h" +#include <xen/io/cdromif.h> + +struct tdcdrom_state { + int fd; + int xs_fd; /* for xen event polling */ + int media_present; + int media_changed; + struct xs_handle *xs_handle; + char *dev_name; + int dev_type; + td_flag_t flags; +}; + +#define BLOCK_DEVICE 0 +#define FILE_DEVICE 1 +#define CDROM_DEFAULT_SECTOR_SIZE 2048 +#define CDROM_DEFAULT_SIZE 2000000000 + +/*Get Image size, secsize*/ +static void get_image_info(struct disk_driver *dd) +{ + int ret; + long size; + unsigned long total_size; + struct statvfs statBuf; + struct stat stat; + struct td_state *s = dd->td_state; + struct tdcdrom_state *prv = dd->private; + + s->size = 0; + s->sector_size = CDROM_DEFAULT_SECTOR_SIZE; + s->info = (VDISK_CDROM | VDISK_REMOVABLE | VDISK_READONLY); + prv->media_present = 0; + + ret = fstat(prv->fd, &stat); + if (ret != 0) { + DPRINTF("ERROR: fstat failed, Couldn't stat image"); + return; + } + + if (S_ISBLK(stat.st_mode)) { + /*Accessing block device directly*/ + int status; + + prv->dev_type = BLOCK_DEVICE; + status = ioctl(prv->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); + if (status == CDS_DISC_OK) { + prv->media_present = 1; + if ((ret =ioctl(prv->fd,BLKGETSIZE,&s->size))!=0) { + DPRINTF("ERR: BLKGETSIZE failed, couldn't stat image"); + s->size = CDROM_DEFAULT_SIZE; + } + } + else { + s->size = CDROM_DEFAULT_SIZE; + } + /*Get the sector size*/ +#if defined(BLKSSZGET) + { + int arg; + s->sector_size = CDROM_DEFAULT_SECTOR_SIZE; + ioctl(prv->fd, BLKSSZGET, &s->sector_size); + + if (s->sector_size != CDROM_DEFAULT_SECTOR_SIZE) + DPRINTF("Note: sector size is %llu (not %d)\n", + (long long unsigned)s->sector_size, + CDROM_DEFAULT_SECTOR_SIZE); + } +#else + s->sector_size = CDROM_DEFAULT_SECTOR_SIZE; +#endif + DPRINTF("Block Device: Image size: %llu" + " media_present: %d sector_size: %llu\n", + (long long unsigned)s->size, prv->media_present, + (long long unsigned)s->sector_size); + } else { + /*Local file? try fstat instead*/ + prv->dev_type = FILE_DEVICE; + prv->media_present = 1; + s->size = (stat.st_size >> SECTOR_SHIFT); + s->sector_size = DEFAULT_SECTOR_SIZE; + DPRINTF("Local File: Image size: %llu\n", + (long long unsigned)s->size); + } + return; +} + +static inline void init_fds(struct disk_driver *dd) +{ + int i; + struct tdcdrom_state *prv = dd->private; + + for(i = 0; i < MAX_IOFD; i++) + dd->io_fd[i] = 0; + + prv->xs_handle = xs_daemon_open(); + prv->xs_fd = xs_fileno(prv->xs_handle); + dd->io_fd[0] = prv->xs_fd; +} + +void open_device (struct disk_driver *dd) +{ + struct tdcdrom_state *prv = dd->private; + int o_flags; + + o_flags = O_NONBLOCK | O_LARGEFILE | + ((prv->flags == TD_RDONLY) ? O_RDONLY : O_RDWR); + + if (prv->fd < 0) { + prv->fd = open(prv->dev_name, o_flags); + if (prv->fd == -1) { + DPRINTF("Unable tp open: (%s)\n", prv->dev_name); + return; + } + } + + if (prv->fd != -1) { + + get_image_info(dd); + + if (prv->dev_type == BLOCK_DEVICE) { + int status; + status = ioctl(prv->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); + switch (status) { + case CDS_DISC_OK: + prv->media_present = 1; + break; + default: + prv->media_present = 0; + } + } + else + prv->media_present = 1; + } +} + +/* + * Main entry point, called when first loaded + */ +int tdcdrom_open (struct disk_driver *dd, const char *name, td_flag_t flags) +{ + int ret; + struct tdcdrom_state *prv = dd->private; + + ret = asprintf(&prv->dev_name, "%s", name); + if (ret < 0) { + prv->dev_name = NULL; + goto out; + } + prv->fd = -1; + prv->media_changed = 0; + prv->media_present = 0; + prv->flags = flags; + init_fds(dd); + + open_device(dd); + +out: + return ret; +} + +int tdcdrom_queue_read(struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *private) +{ + struct td_state *s = dd->td_state; + struct tdcdrom_state *prv = dd->private; + int size = nb_sectors * s->sector_size; + uint64_t offset = sector * (uint64_t)s->sector_size; + int ret; + + if (prv->fd == -1 || prv->media_present == 0) { + ret = 0 - ENOMEDIUM; + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); + } + size = nb_sectors * 512; + offset = sector * (uint64_t)512; + ret = lseek(prv->fd, offset, SEEK_SET); + if (ret != (off_t)-1) { + ret = read(prv->fd, buf, size); + if (ret != size) { + ret = 0 - errno; + } else { + ret = 1; + } + } else ret = 0 - errno; + + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); +} + +int tdcdrom_queue_write(struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *private) +{ + struct td_state *s = dd->td_state; + struct tdcdrom_state *prv = dd->private; + int size = nb_sectors * s->sector_size; + uint64_t offset = sector * (uint64_t)s->sector_size; + int ret = 0; + + if (prv->fd == -1 || prv->media_present == 0) { + ret = 0 - ENOMEDIUM; + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); + } + ret = lseek(prv->fd, offset, SEEK_SET); + if (ret != (off_t)-1) { + ret = write(prv->fd, buf, size); + if (ret != size) { + ret = 0 - errno; + } else { + ret = 1; + } + } else ret = 0 - errno; + + return cb(dd, (ret < 0) ? ret : 0, sector, nb_sectors, id, private); +} + +int tdcdrom_queue_packet(struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *private) +{ + struct td_state *s = dd->td_state; + struct tdcdrom_state *prv = dd->private; + int size = nb_sectors * s->sector_size; + uint64_t offset = sector * (uint64_t)s->sector_size; + int ret = 0; + + union xen_block_packet *sp; + struct xen_cdrom_packet *xcp; + struct xen_cdrom_support *xcs; + struct xen_cdrom_open *xco; + struct xen_cdrom_media_info *xcmi; + struct xen_cdrom_media_changed *xcmc; + struct cdrom_generic_command cgc; + struct vcd_generic_command * vgc; + struct request_sense sense; + + sp = (union xen_block_packet *)buf; + switch(sp->type) { + case XEN_TYPE_CDROM_SUPPORT: + xcs = &(sp->xcs); + xcs->err = 0; + xcs->ret = 0; + xcs->supported = 1; + break; + case XEN_TYPE_CDROM_PACKET: + xcp = &(sp->xcp); + xcp->err = 0; + xcp->ret = 0; + vgc = (struct vcd_generic_command *)(buf + PACKET_PAYLOAD_OFFSET); + + memset( &cgc, 0, sizeof(struct cdrom_generic_command)); + memcpy(cgc.cmd, vgc->cmd, CDROM_PACKET_SIZE); + cgc.stat = vgc->stat; + cgc.data_direction = vgc->data_direction; + cgc.quiet = vgc->quiet; + cgc.timeout = vgc->timeout; + + if (prv->fd == -1) { + xcp = &(sp->xcp); + xcp->ret = -1; + xcp->err = 0 - ENODEV; + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); + } + if (prv->dev_type == FILE_DEVICE) { + DPRINTF("%s() FILE_DEVICE inappropriate packetcmd \n",__func__); + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); + } + switch ( cgc.cmd[0]) { + case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + { + int lock; + lock = cgc.cmd[4] & 1; + if (ioctl (prv->fd, CDROM_LOCKDOOR, lock) < 0) { + xcp->err = -(errno); + xcp->ret = -1; + } + } + break; + case GPCMD_START_STOP_UNIT: + { + int start, eject; + start = cgc.cmd[4] & 1; + eject = (cgc.cmd[4] >> 1) & 1; + if (eject && !start) { + if (ioctl (prv->fd, CDROMEJECT, NULL) < 0) { + xcp->err = -(errno); + xcp->ret = -1; + } + } else if (eject && start) { + if (ioctl (prv->fd, CDROMCLOSETRAY, NULL) < 0) { + xcp->err = -(errno); + xcp->ret = -1; + } + } + } + break; + default: + { + if (vgc->sense_offset) { + cgc.sense = &sense; + } + if (vgc->buffer_offset) { + cgc.buffer = malloc(vgc->buflen); + memcpy(cgc.buffer, (char *)sp + PACKET_BUFFER_OFFSET, vgc->buflen); + cgc.buflen = vgc->buflen; + } + if (ioctl (prv->fd, CDROM_SEND_PACKET, &cgc) < 0 ) { + xcp->err = -(errno); + xcp->ret = -1; + } + if (cgc.sense) { + memcpy((char *)sp + PACKET_SENSE_OFFSET, cgc.sense, sizeof(struct request_sense)); + } + if (cgc.buffer) { + vgc->buflen = cgc.buflen; + memcpy((char *)sp + PACKET_BUFFER_OFFSET, cgc.buffer, cgc.buflen); + free(cgc.buffer); + } + break; + } + } + break; + case XEN_TYPE_CDROM_OPEN: + { + unsigned int len; + struct stat statbuf; + int major = 0; + int minor = 0; + + if (stat (prv->dev_name, &statbuf) == 0) { + major = major (statbuf.st_rdev); + minor = minor (statbuf.st_rdev); + } + xco = &(sp->xco); + xco->err = 0; + xco->ret = 0; + if (xco->payload_offset) { + char *present; + char *buf; + char *num; + char *nodename; + char media_present[2]; + nodename = (char *)sp + xco->payload_offset; + if (asprintf(&buf, "%s/media-present", nodename) < 0) + goto out_payload_offset; + present = xs_read(prv->xs_handle, XBT_NULL, buf, &len); + if (present) { + free(buf); + goto out_payload_offset_free; + } + + sprintf(media_present, "%d", prv->media_present); + xs_write(prv->xs_handle, XBT_NULL, buf, media_present, strlen(media_present)); + xs_watch(prv->xs_handle, buf, "media-present"); + free(buf); + + if (asprintf(&buf, "%s/params", nodename) < 0) + goto out_payload_offset_free; + xs_watch(prv->xs_handle, buf, "params"); + free(buf); + + if (asprintf(&num, "%x:%x", major, minor) < 0) + goto out_payload_offset_free; + if (asprintf(&buf, "%s/physical-device", nodename) < 0) { + free(num); + goto out_payload_offset_free; + } + xs_write(prv->xs_handle, XBT_NULL, buf, num, strlen(num)); + free(buf); + free(num); +out_payload_offset_free: + free(present); +out_payload_offset: + ; + } + + xco->media_present = prv->media_present; + xco->sectors = 0; + xco->sector_size = 2048; + if (prv->media_present && prv->fd != -1 ) { + get_image_info(dd); + xco->sectors = s->size; + xco->sector_size = s->sector_size; + } + } + break; + case XEN_TYPE_CDROM_MEDIA_CHANGED: + xcmc = &(sp->xcmc); + xcmc->err = 0; + xcmc->ret = 0; + xcmc->media_changed = prv->media_changed; + prv->media_changed = 0; + break; + default: + xcp = &(sp->xcp); + xcp->err = -EINVAL; + xcp->ret = -1; + break; + } + + return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private); +} + +int tdcdrom_submit(struct disk_driver *dd) +{ + return 0; +} + +int tdcdrom_close(struct disk_driver *dd) +{ + struct tdcdrom_state *prv = dd->private; + + if (prv->fd != -1) { + close(prv->fd); + prv->fd = -1; + } + prv->xs_fd = -1; + xs_daemon_close(prv->xs_handle); + free(prv->dev_name); + + return 0; +} + +void tdcdrom_process_media_change_event(struct disk_driver *dd, char **vec) +{ + struct tdcdrom_state *prv = dd->private; + char *media_present; + unsigned int len; + + media_present = xs_read(prv->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], &len); + if (media_present == NULL) + return; + + if (strcmp(media_present, "0") == 0) { + close(prv->fd); + prv->fd = -1; + prv->media_present = 0; + } + else { + open_device(dd); + prv->media_changed = 1; + } + free(media_present); +} + +void tdcrom_process_params_event(struct disk_driver *dd, char **vec) +{ + struct tdcdrom_state *prv = dd->private; + char *params; + unsigned int len; + + params = xs_read(prv->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], &len); + if (params) { + char *cp = strchr(params, ':'); + if (cp) { + cp++; + if (prv->dev_name) + free(prv->dev_name); + if (asprintf(&prv->dev_name, "%s", cp) < 0) { + prv->dev_name = NULL; + return; + } + if (prv->fd != -1) { + close(prv->fd); + prv->fd = -1; + } + open_device(dd); + prv->media_changed = 1; + } + free(params); + } +} + +int tdcdrom_do_callbacks(struct disk_driver *dd, int sid) +{ + struct tdcdrom_state *prv = dd->private; + char **vec; + unsigned int num; + + vec = xs_read_watch(prv->xs_handle, &num); + if (!vec) + return 1; + + if (!strcmp(vec[XS_WATCH_TOKEN], "media-present")) { + tdcdrom_process_media_change_event(dd, vec); + goto out; + } + + if (!strcmp(vec[XS_WATCH_TOKEN], "params")) { + tdcrom_process_params_event(dd, vec); + goto out; + } + + out: + free(vec); + return 1; +} + +int tdcdrom_get_parent_id(struct disk_driver *dd, struct disk_id *id) +{ + return TD_NO_PARENT; +} + +int tdcdrom_validate_parent(struct disk_driver *dd, + struct disk_driver *parent, td_flag_t flags) +{ + return -EINVAL; +} + +struct tap_disk tapdisk_cdrom = { + .disk_type = "tapdisk_cdrom", + .private_data_size = sizeof(struct tdcdrom_state), + .td_open = tdcdrom_open, + .td_queue_read = tdcdrom_queue_read, + .td_queue_packet = tdcdrom_queue_packet, + .td_queue_write = tdcdrom_queue_write, + .td_submit = tdcdrom_submit, + .td_close = tdcdrom_close, + .td_do_callbacks = tdcdrom_do_callbacks, + .td_get_parent_id = tdcdrom_get_parent_id, + .td_validate_parent = tdcdrom_validate_parent +}; Index: xen-4.5.1-testing/tools/blktap/drivers/tapdisk.c =================================================================== --- xen-4.5.1-testing.orig/tools/blktap/drivers/tapdisk.c +++ xen-4.5.1-testing/tools/blktap/drivers/tapdisk.c @@ -735,6 +735,22 @@ static void get_io_request(struct td_sta goto out; } break; + case BLKIF_OP_PACKET: + ret = 0; + if (drv->td_queue_packet) + ret = drv->td_queue_packet(dd, sector_nr, + nsects, page, + send_responses, + idx, (void *)(long)i); + if (ret > 0) dd->early += ret; + else if (ret == -EBUSY) { + /* put req back on queue */ + --info->fe_ring.req_cons; + info->busy.req = req; + info->busy.seg_idx = i; + goto out; + } + break; default: DPRINTF("Unknown block operation\n"); break; Index: xen-4.5.1-testing/tools/blktap/drivers/tapdisk.h =================================================================== --- xen-4.5.1-testing.orig/tools/blktap/drivers/tapdisk.h +++ xen-4.5.1-testing/tools/blktap/drivers/tapdisk.h @@ -137,6 +137,9 @@ struct tap_disk { int (*td_get_parent_id) (struct disk_driver *dd, struct disk_id *id); int (*td_validate_parent)(struct disk_driver *dd, struct disk_driver *p, td_flag_t flags); + int (*td_queue_packet) (struct disk_driver *dd, uint64_t sector, + int nb_sectors, char *buf, td_callback_t cb, + int id, void *prv); }; typedef struct disk_info { @@ -160,6 +163,7 @@ extern struct tap_disk tapdisk_vmdk; extern struct tap_disk tapdisk_ram; extern struct tap_disk tapdisk_qcow; extern struct tap_disk tapdisk_qcow2; +extern struct tap_disk tapdisk_cdrom; /*Define Individual Disk Parameters here */ @@ -229,6 +233,17 @@ static disk_info_t qcow2_disk = { #endif }; +static disk_info_t cdrom_disk = { + DISK_TYPE_CDROM, + "raw image (cdrom)", + "cdrom", + 0, + 0, +#ifdef TAPDISK + &tapdisk_cdrom, +#endif +}; + /*Main disk info array */ static disk_info_t *dtypes[] = { &aio_disk, @@ -237,6 +252,7 @@ static disk_info_t *dtypes[] = { &ram_disk, &qcow_disk, &qcow2_disk, + &cdrom_disk, }; typedef struct driver_list_entry { Index: xen-4.5.1-testing/tools/blktap/lib/blktaplib.h =================================================================== --- xen-4.5.1-testing.orig/tools/blktap/lib/blktaplib.h +++ xen-4.5.1-testing/tools/blktap/lib/blktaplib.h @@ -219,6 +219,7 @@ typedef struct msg_pid { #define DISK_TYPE_RAM 3 #define DISK_TYPE_QCOW 4 #define DISK_TYPE_QCOW2 5 +#define DISK_TYPE_CDROM 6 /* xenstore/xenbus: */ #define DOMNAME "Domain-0" Index: xen-4.5.1-testing/xen/include/public/io/blkif.h =================================================================== --- xen-4.5.1-testing.orig/xen/include/public/io/blkif.h +++ xen-4.5.1-testing/xen/include/public/io/blkif.h @@ -485,7 +485,7 @@ * Used in SLES sources for device specific command packet * contained within the request. Reserved for that purpose. */ -#define BLKIF_OP_RESERVED_1 4 +#define BLKIF_OP_PACKET 4 /* * Indicate to the backend device that a region of storage is no longer in * use, and may be discarded at any time without impact to the client. If Index: xen-4.5.1-testing/xen/include/public/io/cdromif.h =================================================================== --- /dev/null +++ xen-4.5.1-testing/xen/include/public/io/cdromif.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * cdromif.h + * + * Shared definitions between backend driver and Xen guest Virtual CDROM + * block device. + * + * Copyright (c) 2008, Pat Campell plc@novell.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (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. + */ + +#ifndef __XEN_PUBLIC_IO_CDROMIF_H__ +#define __XEN_PUBLIC_IO_CDROMIF_H__ + +#include <linux/cdrom.h> + +/* + * Queries backend for CDROM support + */ +#define XEN_TYPE_CDROM_SUPPORT _IO('c', 1) + +struct xen_cdrom_support +{ + uint32_t type; + int8_t ret; /* returned, 0 succeded, -1 error */ + int8_t err; /* returned, backend errno */ + int8_t supported; /* returned, 1 supported */ +}; + +/* + * Opens backend device, returns drive geometry or + * any encountered errors + */ +#define XEN_TYPE_CDROM_OPEN _IO('c', 2) + +struct xen_cdrom_open +{ + uint32_t type; + int8_t ret; + int8_t err; + int8_t pad; + int8_t media_present; /* returned */ + uint32_t sectors; /* returned */ + uint32_t sector_size; /* returned */ + int32_t payload_offset; /* offset to backend node name payload */ +}; + +/* + * Queries backend for media changed status + */ +#define XEN_TYPE_CDROM_MEDIA_CHANGED _IO('c', 3) + +struct xen_cdrom_media_changed +{ + uint32_t type; + int8_t ret; + int8_t err; + int8_t media_changed; /* returned */ +}; + +/* + * Sends vcd generic CDROM packet to backend, followed + * immediately by the vcd_generic_command payload + */ +#define XEN_TYPE_CDROM_PACKET _IO('c', 4) + +struct xen_cdrom_packet +{ + uint32_t type; + int8_t ret; + int8_t err; + int8_t pad[2]; + int32_t payload_offset; /* offset to struct vcd_generic_command payload */ +}; + +/* CDROM_PACKET_COMMAND, payload for XEN_TYPE_CDROM_PACKET */ +struct vcd_generic_command +{ + uint8_t cmd[CDROM_PACKET_SIZE]; + uint8_t pad[4]; + uint32_t buffer_offset; + uint32_t buflen; + int32_t stat; + uint32_t sense_offset; + uint8_t data_direction; + uint8_t pad1[3]; + int32_t quiet; + int32_t timeout; +}; + +union xen_block_packet +{ + uint32_t type; + struct xen_cdrom_support xcs; + struct xen_cdrom_open xco; + struct xen_cdrom_media_changed xcmc; + struct xen_cdrom_packet xcp; +}; + +#define PACKET_PAYLOAD_OFFSET (sizeof(struct xen_cdrom_packet)) +#define PACKET_SENSE_OFFSET (PACKET_PAYLOAD_OFFSET + sizeof(struct vcd_generic_command)) +#define PACKET_BUFFER_OFFSET (PACKET_SENSE_OFFSET + sizeof(struct request_sense)) +#define MAX_PACKET_DATA (PAGE_SIZE - sizeof(struct xen_cdrom_packet) - \ + sizeof(struct vcd_generic_command) - sizeof(struct request_sense)) + +#endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor