ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/netback/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 291e816acbf4
children 9ead08216805
line source
1 /* Xenbus code for netif 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 netif_t *netif;
30 long int frontend_id;
31 #if 0
32 long int pdev;
33 long int readonly;
34 #endif
36 /* watch back end for changes */
37 struct xenbus_watch backend_watch;
39 /* watch front end for changes */
40 struct xenbus_watch watch;
41 char *frontpath;
42 };
44 static int netback_remove(struct xenbus_device *dev)
45 {
46 struct backend_info *be = dev->data;
48 if (be->watch.node)
49 unregister_xenbus_watch(&be->watch);
50 unregister_xenbus_watch(&be->backend_watch);
51 if (be->netif)
52 netif_disconnect(be->netif);
53 kfree(be->frontpath);
54 kfree(be);
55 return 0;
56 }
58 /* Front end tells us frame. */
59 static void frontend_changed(struct xenbus_watch *watch, const char *node)
60 {
61 unsigned long tx_ring_ref, rx_ring_ref;
62 unsigned int evtchn;
63 int err;
64 struct backend_info *be
65 = container_of(watch, struct backend_info, watch);
66 char *mac, *e, *s;
67 int i;
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->netif == NULL || be->netif->status == CONNECTED)
76 return;
78 mac = xenbus_read(be->frontpath, "mac", NULL);
79 if (IS_ERR(mac)) {
80 err = PTR_ERR(mac);
81 xenbus_dev_error(be->dev, err, "reading %s/mac",
82 be->dev->nodename);
83 return;
84 }
85 s = mac;
86 for (i = 0; i < ETH_ALEN; i++) {
87 be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16);
88 if (s == e || (e[0] != ':' && e[0] != 0)) {
89 kfree(mac);
90 err = -ENOENT;
91 xenbus_dev_error(be->dev, err, "parsing %s/mac",
92 be->dev->nodename);
93 return;
94 }
95 s = &e[1];
96 }
97 kfree(mac);
99 err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref,
100 "rx-ring-ref", "%lu", &rx_ring_ref,
101 "event-channel", "%u", &evtchn, NULL);
102 if (err) {
103 xenbus_dev_error(be->dev, err,
104 "reading %s/ring-ref and event-channel",
105 be->frontpath);
106 return;
107 }
109 /* Map the shared frame, irq etc. */
110 err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
111 if (err) {
112 xenbus_dev_error(be->dev, err,
113 "mapping shared-frames %lu/%lu port %u",
114 tx_ring_ref, rx_ring_ref, evtchn);
115 return;
116 }
118 xenbus_dev_ok(be->dev);
120 return;
121 }
123 /*
124 Setup supplies physical device.
125 We provide event channel and device details to front end.
126 Frontend supplies shared frame and event channel.
127 */
128 static void backend_changed(struct xenbus_watch *watch, const char *node)
129 {
130 int err;
131 long int handle;
132 struct backend_info *be
133 = container_of(watch, struct backend_info, backend_watch);
134 struct xenbus_device *dev = be->dev;
135 u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
137 err = xenbus_scanf(dev->nodename, "handle", "%li", &handle);
138 if (XENBUS_EXIST_ERR(err))
139 return;
140 if (err < 0) {
141 xenbus_dev_error(dev, err, "reading handle");
142 return;
143 }
145 if (be->netif == NULL) {
146 be->netif = alloc_netif(be->frontend_id, handle, be_mac);
147 if (IS_ERR(be->netif)) {
148 err = PTR_ERR(be->netif);
149 be->netif = NULL;
150 xenbus_dev_error(dev, err, "creating interface");
151 return;
152 }
154 #if 0
155 err = vbd_create(be->netif, handle, be->pdev, be->readonly);
156 if (err) {
157 xenbus_dev_error(dev, err, "creating vbd structure");
158 return;
159 }
160 #endif
162 kobject_hotplug(&dev->dev.kobj, KOBJ_ONLINE);
164 /* Pass in NULL node to skip exist test. */
165 frontend_changed(&be->watch, NULL);
166 }
167 }
169 static int netback_hotplug(struct xenbus_device *xdev, char **envp,
170 int num_envp, char *buffer, int buffer_size)
171 {
172 struct backend_info *be;
173 netif_t *netif;
174 char **key, *val;
175 int i = 0, length = 0;
176 static char *env_vars[] = { "script", "domain", "mac", "bridge", "ip",
177 NULL };
179 be = xdev->data;
180 netif = be->netif;
182 add_hotplug_env_var(envp, num_envp, &i,
183 buffer, buffer_size, &length,
184 "vif=%s", netif->dev->name);
186 key = env_vars;
187 while (*key != NULL) {
188 val = xenbus_read(xdev->nodename, *key, NULL);
189 if (!IS_ERR(val)) {
190 char buf[strlen(*key) + 4];
191 sprintf(buf, "%s=%%s", *key);
192 add_hotplug_env_var(envp, num_envp, &i,
193 buffer, buffer_size, &length,
194 buf, val);
195 kfree(val);
196 }
197 key++;
198 }
200 envp[i] = NULL;
202 return 0;
203 }
205 static int netback_probe(struct xenbus_device *dev,
206 const struct xenbus_device_id *id)
207 {
208 struct backend_info *be;
209 char *frontend;
210 int err;
212 be = kmalloc(sizeof(*be), GFP_KERNEL);
213 if (!be) {
214 xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
215 return -ENOMEM;
216 }
217 memset(be, 0, sizeof(*be));
219 frontend = NULL;
220 err = xenbus_gather(dev->nodename,
221 "frontend-id", "%li", &be->frontend_id,
222 "frontend", NULL, &frontend,
223 NULL);
224 if (XENBUS_EXIST_ERR(err))
225 goto free_be;
226 if (err < 0) {
227 xenbus_dev_error(dev, err,
228 "reading %s/frontend or frontend-id",
229 dev->nodename);
230 goto free_be;
231 }
232 if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
233 /* If we can't get a frontend path and a frontend-id,
234 * then our bus-id is no longer valid and we need to
235 * destroy the backend device.
236 */
237 err = -ENOENT;
238 goto free_be;
239 }
241 be->dev = dev;
242 be->backend_watch.node = dev->nodename;
243 be->backend_watch.callback = backend_changed;
244 err = register_xenbus_watch(&be->backend_watch);
245 if (err) {
246 be->backend_watch.node = NULL;
247 xenbus_dev_error(dev, err, "adding backend watch on %s",
248 dev->nodename);
249 goto free_be;
250 }
252 be->frontpath = frontend;
253 be->watch.node = be->frontpath;
254 be->watch.callback = frontend_changed;
255 err = register_xenbus_watch(&be->watch);
256 if (err) {
257 be->watch.node = NULL;
258 xenbus_dev_error(dev, err,
259 "adding frontend watch on %s",
260 be->frontpath);
261 goto free_be;
262 }
264 dev->data = be;
266 backend_changed(&be->backend_watch, dev->nodename);
267 return 0;
269 free_be:
270 if (be->backend_watch.node)
271 unregister_xenbus_watch(&be->backend_watch);
272 kfree(frontend);
273 kfree(be);
274 return err;
275 }
277 static struct xenbus_device_id netback_ids[] = {
278 { "vif" },
279 { "" }
280 };
282 static struct xenbus_driver netback = {
283 .name = "vif",
284 .owner = THIS_MODULE,
285 .ids = netback_ids,
286 .probe = netback_probe,
287 .remove = netback_remove,
288 .hotplug = netback_hotplug,
289 };
291 void netif_xenbus_init(void)
292 {
293 xenbus_register_backend(&netback);
294 }