ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/tpmback/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 cdfa7dd00c44
children 9ead08216805
line source
1 /* Xenbus code for tpmif backend
2 Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include <stdarg.h>
19 #include <linux/module.h>
20 #include <asm-xen/xenbus.h>
21 #include "common.h"
23 struct backend_info
24 {
25 struct xenbus_device *dev;
27 /* our communications channel */
28 tpmif_t *tpmif;
30 long int frontend_id;
31 long int instance; // instance of TPM
33 /* watch front end for changes */
34 struct xenbus_watch backend_watch;
36 struct xenbus_watch watch;
37 char * frontpath;
38 };
40 static int tpmback_remove(struct xenbus_device *dev)
41 {
42 struct backend_info *be = dev->data;
44 if (be->watch.node) {
45 unregister_xenbus_watch(&be->watch);
46 }
47 unregister_xenbus_watch(&be->backend_watch);
49 tpmif_vtpm_close(be->instance);
51 if (be->tpmif) {
52 tpmif_put(be->tpmif);
53 }
55 kfree(be->frontpath);
56 kfree(be);
57 return 0;
58 }
61 static void frontend_changed(struct xenbus_watch *watch, const char *node)
62 {
63 unsigned long ringref;
64 unsigned int evtchn;
65 unsigned long ready = 1;
66 int err;
67 struct backend_info *be
68 = container_of(watch, struct backend_info, watch);
70 /* If other end is gone, delete ourself. */
71 if (node && !xenbus_exists(be->frontpath, "")) {
72 xenbus_rm(be->dev->nodename, "");
73 device_unregister(&be->dev->dev);
74 return;
75 }
77 if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
78 return;
80 err = xenbus_gather(be->frontpath,
81 "ring-ref", "%lu", &ringref,
82 "event-channel", "%u", &evtchn, NULL);
83 if (err) {
84 xenbus_dev_error(be->dev, err,
85 "reading %s/ring-ref and event-channel",
86 be->frontpath);
87 return;
88 }
91 /*
92 * Tell the front-end that we are ready to go -
93 * unless something bad happens
94 */
95 err = xenbus_transaction_start(be->dev->nodename);
96 if (err) {
97 xenbus_dev_error(be->dev, err, "starting transaction");
98 return;
99 }
101 err = xenbus_printf(be->dev->nodename,
102 "ready", "%lu", ready);
103 if (err) {
104 xenbus_dev_error(be->dev, err, "writing 'ready'");
105 goto abort;
106 }
108 err = tpmif_map(be->tpmif, ringref, evtchn);
109 if (err) {
110 xenbus_dev_error(be->dev, err,
111 "mapping shared-frame %lu port %u",
112 ringref, evtchn);
113 goto abort;
114 }
116 err = tpmif_vtpm_open(be->tpmif,
117 be->frontend_id,
118 be->instance);
119 if (err) {
120 xenbus_dev_error(be->dev, err,
121 "queueing vtpm open packet");
122 /*
123 * Should close down this device and notify FE
124 * about closure.
125 */
126 goto abort;
127 }
129 xenbus_transaction_end(0);
130 xenbus_dev_ok(be->dev);
131 return;
132 abort:
133 xenbus_transaction_end(1);
134 }
137 static void backend_changed(struct xenbus_watch *watch, const char *node)
138 {
139 int err;
140 long int instance;
141 struct backend_info *be
142 = container_of(watch, struct backend_info, backend_watch);
143 struct xenbus_device *dev = be->dev;
145 err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
146 if (XENBUS_EXIST_ERR(err))
147 return;
148 if (err < 0) {
149 xenbus_dev_error(dev, err, "reading 'instance' variable");
150 return;
151 }
153 if (be->instance != -1 && be->instance != instance) {
154 printk(KERN_WARNING
155 "cannot change the instance\n");
156 return;
157 }
158 be->instance = instance;
160 if (be->tpmif == NULL) {
161 be->tpmif = tpmif_find(be->frontend_id,
162 instance);
163 if (IS_ERR(be->tpmif)) {
164 err = PTR_ERR(be->tpmif);
165 be->tpmif = NULL;
166 xenbus_dev_error(dev, err, "creating interface");
167 return;
168 }
170 /* Pass in NULL node to skip exist test. */
171 frontend_changed(&be->watch, be->frontpath);
172 }
173 }
176 static int tpmback_probe(struct xenbus_device *dev,
177 const struct xenbus_device_id *id)
178 {
179 struct backend_info *be;
180 char *frontend;
181 int err;
183 be = kmalloc(sizeof(*be), GFP_KERNEL);
184 if (!be) {
185 xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
186 err = -ENOMEM;
187 }
189 memset(be, 0, sizeof(*be));
191 frontend = NULL;
192 err = xenbus_gather(dev->nodename,
193 "frontend-id", "%li", &be->frontend_id,
194 "frontend", NULL, &frontend,
195 NULL);
196 if (XENBUS_EXIST_ERR(err))
197 goto free_be;
198 if (err < 0) {
199 xenbus_dev_error(dev, err,
200 "reading %s/frontend or frontend-id",
201 dev->nodename);
202 goto free_be;
203 }
204 if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
205 /* If we can't get a frontend path and a frontend-id,
206 * then our bus-id is no longer valid and we need to
207 * destroy the backend device.
208 */
209 err = -ENOENT;
210 goto free_be;
211 }
213 be->dev = dev;
214 be->backend_watch.node = dev->nodename;
215 be->backend_watch.callback = backend_changed;
216 be->instance = -1;
217 err = register_xenbus_watch(&be->backend_watch);
218 if (err) {
219 be->backend_watch.node = NULL;
220 xenbus_dev_error(dev, err, "adding backend watch on %s",
221 dev->nodename);
222 goto free_be;
223 }
225 be->frontpath = frontend;
226 be->watch.node = be->frontpath;
227 be->watch.callback = frontend_changed;
228 err = register_xenbus_watch(&be->watch);
229 if (err) {
230 be->watch.node = NULL;
231 xenbus_dev_error(dev, err,
232 "adding frontend watch on %s",
233 be->frontpath);
234 goto free_be;
235 }
237 dev->data = be;
239 backend_changed(&be->backend_watch, dev->nodename);
240 return err;
242 free_be:
243 if (be->backend_watch.node)
244 unregister_xenbus_watch(&be->backend_watch);
245 kfree(frontend);
246 kfree(be);
247 return err;
248 }
251 static struct xenbus_device_id tpmback_ids[] = {
252 { "vtpm" },
253 { "" }
254 };
257 static struct xenbus_driver tpmback = {
258 .name = "vtpm",
259 .owner = THIS_MODULE,
260 .ids = tpmback_ids,
261 .probe = tpmback_probe,
262 .remove = tpmback_remove,
263 };
266 void tpmif_xenbus_init(void)
267 {
268 xenbus_register_backend(&tpmback);
269 }