Imported xen patches.
[people/pmueller/ipfire-2.x.git] / src / patches / 60043_xen-blkback-cdrom.patch1
1 Subject: CDROM removable media-present attribute plus handling code
2 From: plc@novell.com
3 Patch-mainline: obsolete
4 References: 159907
5
6 Index: head-2008-05-08/drivers/xen/blkback/Makefile
7 ===================================================================
8 --- head-2008-05-08.orig/drivers/xen/blkback/Makefile 2008-05-08 15:34:23.000000000 +0200
9 +++ head-2008-05-08/drivers/xen/blkback/Makefile 2008-05-08 15:05:13.000000000 +0200
10 @@ -1,3 +1,3 @@
11 obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
12
13 -blkbk-y := blkback.o xenbus.o interface.o vbd.o
14 +blkbk-y := blkback.o xenbus.o interface.o vbd.o cdrom.o
15 Index: head-2008-05-08/drivers/xen/blkback/cdrom.c
16 ===================================================================
17 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
18 +++ head-2008-05-08/drivers/xen/blkback/cdrom.c 2008-05-13 15:34:40.000000000 +0200
19 @@ -0,0 +1,162 @@
20 +/******************************************************************************
21 + * blkback/cdrom.c
22 + *
23 + * Routines for managing cdrom watch and media-present attribute of a
24 + * cdrom type virtual block device (VBD).
25 + *
26 + * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
27 + * Copyright (c) 2007 Pat Campbell
28 + *
29 + * This program is free software; you can redistribute it and/or
30 + * modify it under the terms of the GNU General Public License version 2
31 + * as published by the Free Software Foundation; or, when distributed
32 + * separately from the Linux kernel or incorporated into other
33 + * software packages, subject to the following license:
34 + *
35 + * Permission is hereby granted, free of charge, to any person obtaining a copy
36 + * of this source file (the "Software"), to deal in the Software without
37 + * restriction, including without limitation the rights to use, copy, modify,
38 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
39 + * and to permit persons to whom the Software is furnished to do so, subject to
40 + * the following conditions:
41 + *
42 + * The above copyright notice and this permission notice shall be included in
43 + * all copies or substantial portions of the Software.
44 + *
45 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
50 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
51 + * IN THE SOFTWARE.
52 + */
53 +
54 +#include "common.h"
55 +
56 +#undef DPRINTK
57 +#define DPRINTK(_f, _a...) \
58 + printk("(%s() file=%s, line=%d) " _f "\n", \
59 + __PRETTY_FUNCTION__, __FILE__ , __LINE__ , ##_a )
60 +
61 +
62 +#define MEDIA_PRESENT "media-present"
63 +
64 +static void cdrom_media_changed(struct xenbus_watch *, const char **, unsigned int);
65 +
66 +/**
67 + * Writes media-present=1 attribute for the given vbd device if not
68 + * already there
69 + */
70 +static int cdrom_xenstore_write_media_present(struct backend_info *be)
71 +{
72 + struct xenbus_device *dev = be->dev;
73 + struct xenbus_transaction xbt;
74 + int err;
75 + int media_present;
76 +
77 + err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
78 + &media_present);
79 + if (0 < err) {
80 + DPRINTK("already written err%d", err);
81 + return(0);
82 + }
83 + media_present = 1;
84 +
85 +again:
86 + err = xenbus_transaction_start(&xbt);
87 + if (err) {
88 + xenbus_dev_fatal(dev, err, "starting transaction");
89 + return(-1);
90 + }
91 +
92 + err = xenbus_printf(xbt, dev->nodename, MEDIA_PRESENT, "%d", media_present );
93 + if (err) {
94 + xenbus_dev_fatal(dev, err, "writing %s/%s",
95 + dev->nodename, MEDIA_PRESENT);
96 + goto abort;
97 + }
98 + err = xenbus_transaction_end(xbt, 0);
99 + if (err == -EAGAIN)
100 + goto again;
101 + if (err)
102 + xenbus_dev_fatal(dev, err, "ending transaction");
103 + return 0;
104 + abort:
105 + xenbus_transaction_end(xbt, 1);
106 + return -1;
107 +}
108 +
109 +/**
110 + *
111 + */
112 +static int cdrom_is_type(struct backend_info *be)
113 +{
114 + DPRINTK("type:%x", be->blkif->vbd.type );
115 + return (be->blkif->vbd.type & VDISK_CDROM)
116 + && (be->blkif->vbd.type & GENHD_FL_REMOVABLE);
117 +}
118 +
119 +/**
120 + *
121 + */
122 +void cdrom_add_media_watch(struct backend_info *be)
123 +{
124 + struct xenbus_device *dev = be->dev;
125 + int err;
126 +
127 + DPRINTK("nodename:%s", dev->nodename);
128 + if (cdrom_is_type(be)) {
129 + DPRINTK("is a cdrom");
130 + if ( cdrom_xenstore_write_media_present(be) == 0 ) {
131 + DPRINTK( "xenstore wrote OK");
132 + err = xenbus_watch_path2(dev, dev->nodename, MEDIA_PRESENT,
133 + &be->backend_cdrom_watch,
134 + cdrom_media_changed);
135 + if (err)
136 + DPRINTK( "media_present watch add failed" );
137 + }
138 + }
139 +}
140 +
141 +/**
142 + * Callback received when the "media_present" xenstore node is changed
143 + */
144 +static void cdrom_media_changed(struct xenbus_watch *watch,
145 + const char **vec, unsigned int len)
146 +{
147 + int err;
148 + unsigned media_present;
149 + struct backend_info *be
150 + = container_of(watch, struct backend_info, backend_cdrom_watch);
151 + struct xenbus_device *dev = be->dev;
152 +
153 + if (!cdrom_is_type(be)) {
154 + DPRINTK("callback not for a cdrom" );
155 + return;
156 + }
157 +
158 + err = xenbus_scanf(XBT_NIL, dev->nodename, MEDIA_PRESENT, "%d",
159 + &media_present);
160 + if (err == 0 || err == -ENOENT) {
161 + DPRINTK("xenbus_read of cdrom media_present node error:%d",err);
162 + return;
163 + }
164 +
165 + if (media_present == 0)
166 + vbd_free(&be->blkif->vbd);
167 + else {
168 + char *p = strrchr(dev->otherend, '/') + 1;
169 + long handle = simple_strtoul(p, NULL, 0);
170 +
171 + if (!be->blkif->vbd.bdev) {
172 + err = vbd_create(be->blkif, handle, be->major, be->minor,
173 + !strchr(be->mode, 'w'), 1);
174 + if (err) {
175 + be->major = be->minor = 0;
176 + xenbus_dev_fatal(dev, err, "creating vbd structure");
177 + return;
178 + }
179 + }
180 + }
181 +}
182 Index: head-2008-05-08/drivers/xen/blkback/common.h
183 ===================================================================
184 --- head-2008-05-08.orig/drivers/xen/blkback/common.h 2008-05-08 15:34:23.000000000 +0200
185 +++ head-2008-05-08/drivers/xen/blkback/common.h 2008-05-13 15:35:13.000000000 +0200
186 @@ -96,6 +96,17 @@ typedef struct blkif_st {
187 grant_ref_t shmem_ref;
188 } blkif_t;
189
190 +struct backend_info
191 +{
192 + struct xenbus_device *dev;
193 + blkif_t *blkif;
194 + struct xenbus_watch backend_watch;
195 + struct xenbus_watch backend_cdrom_watch;
196 + unsigned major;
197 + unsigned minor;
198 + char *mode;
199 +};
200 +
201 blkif_t *blkif_alloc(domid_t domid);
202 void blkif_disconnect(blkif_t *blkif);
203 void blkif_free(blkif_t *blkif);
204 @@ -136,4 +147,7 @@ int blkif_schedule(void *arg);
205 int blkback_barrier(struct xenbus_transaction xbt,
206 struct backend_info *be, int state);
207
208 +/* cdrom media change */
209 +void cdrom_add_media_watch(struct backend_info *be);
210 +
211 #endif /* __BLKIF__BACKEND__COMMON_H__ */
212 Index: head-2008-05-08/drivers/xen/blkback/vbd.c
213 ===================================================================
214 --- head-2008-05-08.orig/drivers/xen/blkback/vbd.c 2008-05-08 15:34:23.000000000 +0200
215 +++ head-2008-05-08/drivers/xen/blkback/vbd.c 2008-05-08 15:05:13.000000000 +0200
216 @@ -106,6 +106,9 @@ int vbd_translate(struct phys_req *req,
217 if ((operation != READ) && vbd->readonly)
218 goto out;
219
220 + if (vbd->bdev == NULL)
221 + goto out;
222 +
223 if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
224 goto out;
225
226 Index: head-2008-05-08/drivers/xen/blkback/xenbus.c
227 ===================================================================
228 --- head-2008-05-08.orig/drivers/xen/blkback/xenbus.c 2008-05-08 15:34:23.000000000 +0200
229 +++ head-2008-05-08/drivers/xen/blkback/xenbus.c 2008-05-08 15:05:13.000000000 +0200
230 @@ -28,16 +28,6 @@
231 pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \
232 __FUNCTION__, __LINE__, ##args)
233
234 -struct backend_info
235 -{
236 - struct xenbus_device *dev;
237 - blkif_t *blkif;
238 - struct xenbus_watch backend_watch;
239 - unsigned major;
240 - unsigned minor;
241 - char *mode;
242 -};
243 -
244 static void connect(struct backend_info *);
245 static int connect_ring(struct backend_info *);
246 static void backend_changed(struct xenbus_watch *, const char **,
247 @@ -183,6 +173,12 @@ static int blkback_remove(struct xenbus_
248 be->backend_watch.node = NULL;
249 }
250
251 + if (be->backend_cdrom_watch.node) {
252 + unregister_xenbus_watch(&be->backend_cdrom_watch);
253 + kfree(be->backend_cdrom_watch.node);
254 + be->backend_cdrom_watch.node = NULL;
255 + }
256 +
257 if (be->blkif) {
258 blkif_disconnect(be->blkif);
259 vbd_free(&be->blkif->vbd);
260 @@ -339,6 +335,9 @@ static void backend_changed(struct xenbu
261
262 /* We're potentially connected now */
263 update_blkif_status(be->blkif);
264 +
265 + /* Add watch for cdrom media status if necessay */
266 + cdrom_add_media_watch(be);
267 }
268 }
269