+++ /dev/null
-Subject: CDROM removable media-present attribute plus handling code
-From: plc@novell.com
-Patch-mainline: obsolete
-References: 159907
-
-Index: head-2008-05-08/drivers/xen/blkback/Makefile
-===================================================================
---- head-2008-05-08.orig/drivers/xen/blkback/Makefile 2008-05-08 15:34:23.000000000 +0200
-+++ head-2008-05-08/drivers/xen/blkback/Makefile 2008-05-08 15:05:13.000000000 +0200
-@@ -1,3 +1,3 @@
- obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
-
--blkbk-y := blkback.o xenbus.o interface.o vbd.o
-+blkbk-y := blkback.o xenbus.o interface.o vbd.o cdrom.o
-Index: head-2008-05-08/drivers/xen/blkback/cdrom.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ head-2008-05-08/drivers/xen/blkback/cdrom.c 2008-05-13 15:34:40.000000000 +0200
-@@ -0,0 +1,162 @@
-+/******************************************************************************
-+ * blkback/cdrom.c
-+ *
-+ * Routines for managing cdrom watch and media-present attribute of a
-+ * cdrom type virtual block device (VBD).
-+ *
-+ * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
-+ * Copyright (c) 2007 Pat Campbell
-+ *
-+ * 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 "common.h"
-+
-+#undef DPRINTK
-+#define DPRINTK(_f, _a...) \
-+ printk("(%s() file=%s, line=%d) " _f "\n", \
-+ __PRETTY_FUNCTION__, __FILE__ , __LINE__ , ##_a )
-+
-+
-+#define MEDIA_PRESENT "media-present"
-+
-+static void cdrom_media_changed(struct xenbus_watch *, const char **, unsigned int);
-+
-+/**
-+ * Writes media-present=1 attribute for the given vbd device if not
-+ * already there
-+ */
-+static int cdrom_xenstore_write_media_present(struct backend_info *be)
-+{
-+ struct xenbus_device *dev = be->dev;
-+ struct xenbus_transaction xbt;
-+ int err;
-+ int media_present;
-+
-+ err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
-+ &media_present);
-+ if (0 < err) {
-+ DPRINTK("already written err%d", err);
-+ return(0);
-+ }
-+ media_present = 1;
-+
-+again:
-+ err = xenbus_transaction_start(&xbt);
-+ if (err) {
-+ xenbus_dev_fatal(dev, err, "starting transaction");
-+ return(-1);
-+ }
-+
-+ err = xenbus_printf(xbt, dev->nodename, MEDIA_PRESENT, "%d", media_present );
-+ if (err) {
-+ xenbus_dev_fatal(dev, err, "writing %s/%s",
-+ dev->nodename, MEDIA_PRESENT);
-+ goto abort;
-+ }
-+ err = xenbus_transaction_end(xbt, 0);
-+ if (err == -EAGAIN)
-+ goto again;
-+ if (err)
-+ xenbus_dev_fatal(dev, err, "ending transaction");
-+ return 0;
-+ abort:
-+ xenbus_transaction_end(xbt, 1);
-+ return -1;
-+}
-+
-+/**
-+ *
-+ */
-+static int cdrom_is_type(struct backend_info *be)
-+{
-+ DPRINTK("type:%x", be->blkif->vbd.type );
-+ return (be->blkif->vbd.type & VDISK_CDROM)
-+ && (be->blkif->vbd.type & GENHD_FL_REMOVABLE);
-+}
-+
-+/**
-+ *
-+ */
-+void cdrom_add_media_watch(struct backend_info *be)
-+{
-+ struct xenbus_device *dev = be->dev;
-+ int err;
-+
-+ DPRINTK("nodename:%s", dev->nodename);
-+ if (cdrom_is_type(be)) {
-+ DPRINTK("is a cdrom");
-+ if ( cdrom_xenstore_write_media_present(be) == 0 ) {
-+ DPRINTK( "xenstore wrote OK");
-+ err = xenbus_watch_path2(dev, dev->nodename, MEDIA_PRESENT,
-+ &be->backend_cdrom_watch,
-+ cdrom_media_changed);
-+ if (err)
-+ DPRINTK( "media_present watch add failed" );
-+ }
-+ }
-+}
-+
-+/**
-+ * Callback received when the "media_present" xenstore node is changed
-+ */
-+static void cdrom_media_changed(struct xenbus_watch *watch,
-+ const char **vec, unsigned int len)
-+{
-+ int err;
-+ unsigned media_present;
-+ struct backend_info *be
-+ = container_of(watch, struct backend_info, backend_cdrom_watch);
-+ struct xenbus_device *dev = be->dev;
-+
-+ if (!cdrom_is_type(be)) {
-+ DPRINTK("callback not for a cdrom" );
-+ return;
-+ }
-+
-+ err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
-+ &media_present);
-+ if (err == 0 || err == -ENOENT) {
-+ DPRINTK("xenbus_read of cdrom media_present node error:%d",err);
-+ return;
-+ }
-+
-+ if (media_present == 0)
-+ vbd_free(&be->blkif->vbd);
-+ else {
-+ char *p = strrchr(dev->otherend, '/') + 1;
-+ long handle = simple_strtoul(p, NULL, 0);
-+
-+ if (!be->blkif->vbd.bdev) {
-+ err = vbd_create(be->blkif, handle, be->major, be->minor,
-+ !strchr(be->mode, 'w'), 1);
-+ if (err) {
-+ be->major = be->minor = 0;
-+ xenbus_dev_fatal(dev, err, "creating vbd structure");
-+ return;
-+ }
-+ }
-+ }
-+}
-Index: head-2008-05-08/drivers/xen/blkback/common.h
-===================================================================
---- head-2008-05-08.orig/drivers/xen/blkback/common.h 2008-05-08 15:34:23.000000000 +0200
-+++ head-2008-05-08/drivers/xen/blkback/common.h 2008-05-13 15:35:13.000000000 +0200
-@@ -96,6 +96,17 @@ typedef struct blkif_st {
- grant_ref_t shmem_ref;
- } blkif_t;
-
-+struct backend_info
-+{
-+ struct xenbus_device *dev;
-+ blkif_t *blkif;
-+ struct xenbus_watch backend_watch;
-+ struct xenbus_watch backend_cdrom_watch;
-+ unsigned major;
-+ unsigned minor;
-+ char *mode;
-+};
-+
- blkif_t *blkif_alloc(domid_t domid);
- void blkif_disconnect(blkif_t *blkif);
- void blkif_free(blkif_t *blkif);
-@@ -136,4 +147,7 @@ int blkif_schedule(void *arg);
- int blkback_barrier(struct xenbus_transaction xbt,
- struct backend_info *be, int state);
-
-+/* cdrom media change */
-+void cdrom_add_media_watch(struct backend_info *be);
-+
- #endif /* __BLKIF__BACKEND__COMMON_H__ */
-Index: head-2008-05-08/drivers/xen/blkback/vbd.c
-===================================================================
---- head-2008-05-08.orig/drivers/xen/blkback/vbd.c 2008-05-08 15:34:23.000000000 +0200
-+++ head-2008-05-08/drivers/xen/blkback/vbd.c 2008-05-08 15:05:13.000000000 +0200
-@@ -106,6 +106,9 @@ int vbd_translate(struct phys_req *req,
- if ((operation != READ) && vbd->readonly)
- goto out;
-
-+ if (vbd->bdev == NULL)
-+ goto out;
-+
- if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
- goto out;
-
-Index: head-2008-05-08/drivers/xen/blkback/xenbus.c
-===================================================================
---- head-2008-05-08.orig/drivers/xen/blkback/xenbus.c 2008-05-08 15:34:23.000000000 +0200
-+++ head-2008-05-08/drivers/xen/blkback/xenbus.c 2008-05-08 15:05:13.000000000 +0200
-@@ -28,16 +28,6 @@
- pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \
- __FUNCTION__, __LINE__, ##args)
-
--struct backend_info
--{
-- struct xenbus_device *dev;
-- blkif_t *blkif;
-- struct xenbus_watch backend_watch;
-- unsigned major;
-- unsigned minor;
-- char *mode;
--};
--
- static void connect(struct backend_info *);
- static int connect_ring(struct backend_info *);
- static void backend_changed(struct xenbus_watch *, const char **,
-@@ -183,6 +173,12 @@ static int blkback_remove(struct xenbus_
- be->backend_watch.node = NULL;
- }
-
-+ if (be->backend_cdrom_watch.node) {
-+ unregister_xenbus_watch(&be->backend_cdrom_watch);
-+ kfree(be->backend_cdrom_watch.node);
-+ be->backend_cdrom_watch.node = NULL;
-+ }
-+
- if (be->blkif) {
- blkif_disconnect(be->blkif);
- vbd_free(&be->blkif->vbd);
-@@ -339,6 +335,9 @@ static void backend_changed(struct xenbu
-
- /* We're potentially connected now */
- update_blkif_status(be->blkif);
-+
-+ /* Add watch for cdrom media status if necessay */
-+ cdrom_add_media_watch(be);
- }
- }
-