ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c @ 6742:ac6605bceb9d

remove pointless NULL check before calling kfree

Signed-off-by: Vincent Hanquez <vincent@xensource.com>
author vh249@arcadians.cl.cam.ac.uk
date Sat Sep 10 14:41:16 2005 +0000 (2005-09-10)
parents f59e0163540e
children 9ead08216805
line source
1 /* Xenbus code for blkif tap
3 A Warfield.
5 Hastily modified from the oroginal backend code:
7 Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
24 #include <stdarg.h>
25 #include <linux/module.h>
26 #include <asm-xen/xenbus.h>
27 #include "common.h"
29 struct backend_info
30 {
31 struct xenbus_device *dev;
33 /* our communications channel */
34 blkif_t *blkif;
36 long int frontend_id;
38 /* watch back end for changes */
39 struct xenbus_watch backend_watch;
41 /* watch front end for changes */
42 struct xenbus_watch watch;
43 char *frontpath;
44 };
46 static int blkback_remove(struct xenbus_device *dev)
47 {
48 struct backend_info *be = dev->data;
50 if (be->watch.node)
51 unregister_xenbus_watch(&be->watch);
52 unregister_xenbus_watch(&be->backend_watch);
53 if (be->blkif)
54 blkif_put(be->blkif);
55 kfree(be->frontpath);
56 kfree(be);
57 return 0;
58 }
60 /* Front end tells us frame. */
61 static void frontend_changed(struct xenbus_watch *watch, const char *node)
62 {
63 unsigned long ring_ref;
64 unsigned int evtchn;
65 int err;
66 struct backend_info *be
67 = container_of(watch, struct backend_info, watch);
69 /* If other end is gone, delete ourself. */
70 if (node && !xenbus_exists(be->frontpath, "")) {
71 xenbus_rm(be->dev->nodename, "");
72 device_unregister(&be->dev->dev);
73 return;
74 }
75 if (be->blkif == NULL || be->blkif->status == CONNECTED)
76 return;
78 err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
79 "event-channel", "%u", &evtchn, NULL);
80 if (err) {
81 xenbus_dev_error(be->dev, err,
82 "reading %s/ring-ref and event-channel",
83 be->frontpath);
84 return;
85 }
87 /* Map the shared frame, irq etc. */
88 err = blkif_map(be->blkif, ring_ref, evtchn);
89 if (err) {
90 xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
91 ring_ref, evtchn);
92 goto abort;
93 }
95 xenbus_dev_ok(be->dev);
97 return;
99 abort:
100 xenbus_transaction_end(1);
101 }
103 /*
104 Setup supplies physical device.
105 We provide event channel and device details to front end.
106 Frontend supplies shared frame and event channel.
107 */
108 static void backend_changed(struct xenbus_watch *watch, const char *node)
109 {
110 int err;
111 char *p;
112 long int handle;
113 struct backend_info *be
114 = container_of(watch, struct backend_info, backend_watch);
115 struct xenbus_device *dev = be->dev;
117 if (be->blkif == NULL) {
118 /* Front end dir is a number, which is used as the handle. */
119 p = strrchr(be->frontpath, '/') + 1;
120 handle = simple_strtoul(p, NULL, 0);
122 be->blkif = alloc_blkif(be->frontend_id);
123 if (IS_ERR(be->blkif)) {
124 err = PTR_ERR(be->blkif);
125 be->blkif = NULL;
126 xenbus_dev_error(dev, err, "creating block interface");
127 return;
128 }
130 /* Pass in NULL node to skip exist test. */
131 frontend_changed(&be->watch, NULL);
132 }
133 }
135 static int blkback_probe(struct xenbus_device *dev,
136 const struct xenbus_device_id *id)
137 {
138 struct backend_info *be;
139 char *frontend;
140 int err;
142 be = kmalloc(sizeof(*be), GFP_KERNEL);
143 if (!be) {
144 xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
145 return -ENOMEM;
146 }
147 memset(be, 0, sizeof(*be));
149 frontend = NULL;
150 err = xenbus_gather(dev->nodename,
151 "frontend-id", "%li", &be->frontend_id,
152 "frontend", NULL, &frontend,
153 NULL);
154 if (XENBUS_EXIST_ERR(err))
155 goto free_be;
156 if (err < 0) {
157 xenbus_dev_error(dev, err,
158 "reading %s/frontend or frontend-id",
159 dev->nodename);
160 goto free_be;
161 }
162 if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
163 /* If we can't get a frontend path and a frontend-id,
164 * then our bus-id is no longer valid and we need to
165 * destroy the backend device.
166 */
167 err = -ENOENT;
168 goto free_be;
169 }
171 be->dev = dev;
172 be->backend_watch.node = dev->nodename;
173 be->backend_watch.callback = backend_changed;
174 err = register_xenbus_watch(&be->backend_watch);
175 if (err) {
176 be->backend_watch.node = NULL;
177 xenbus_dev_error(dev, err, "adding backend watch on %s",
178 dev->nodename);
179 goto free_be;
180 }
182 be->frontpath = frontend;
183 be->watch.node = be->frontpath;
184 be->watch.callback = frontend_changed;
185 err = register_xenbus_watch(&be->watch);
186 if (err) {
187 be->watch.node = NULL;
188 xenbus_dev_error(dev, err,
189 "adding frontend watch on %s",
190 be->frontpath);
191 goto free_be;
192 }
194 dev->data = be;
196 backend_changed(&be->backend_watch, dev->nodename);
197 return 0;
199 free_be:
200 if (be->backend_watch.node)
201 unregister_xenbus_watch(&be->backend_watch);
202 kfree(frontend);
203 kfree(be);
204 return err;
205 }
207 static struct xenbus_device_id blkback_ids[] = {
208 { "vbd" },
209 { "" }
210 };
212 static struct xenbus_driver blkback = {
213 .name = "vbd",
214 .owner = THIS_MODULE,
215 .ids = blkback_ids,
216 .probe = blkback_probe,
217 .remove = blkback_remove,
218 };
220 void blkif_xenbus_init(void)
221 {
222 xenbus_register_backend(&blkback);
223 }