4 * Xenbus interface for USB backend driver.
6 * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
7 * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
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, see <http://www.gnu.org/licenses/>.
24 * When distributed separately from the Linux kernel or incorporated into
25 * other software packages, subject to the following license:
27 * Permission is hereby granted, free of charge, to any person obtaining a copy
28 * of this software and associated documentation files (the "Software"), to
29 * deal in the Software without restriction, including without limitation the
30 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
31 * sell copies of the Software, and to permit persons to whom the Software is
32 * furnished to do so, subject to the following conditions:
34 * The above copyright notice and this permission notice shall be included in
35 * all copies or substantial portions of the Software.
37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 * DEALINGS IN THE SOFTWARE.
48 static int start_xenusbd(usbif_t *usbif)
51 char name[TASK_COMM_LEN];
53 snprintf(name, TASK_COMM_LEN, "usbback.%d.%d", usbif->domid,
55 usbif->xenusbd = kthread_run(usbbk_schedule, usbif, name);
56 if (IS_ERR(usbif->xenusbd)) {
57 err = PTR_ERR(usbif->xenusbd);
58 usbif->xenusbd = NULL;
59 xenbus_dev_error(usbif->xbdev, err, "start xenusbd");
65 static void backend_changed(struct xenbus_watch *watch,
66 const char **vec, unsigned int len)
68 struct xenbus_transaction xbt;
73 struct vusb_port_id *portid = NULL;
75 usbif_t *usbif = container_of(watch, usbif_t, backend_watch);
76 struct xenbus_device *dev = usbif->xbdev;
79 err = xenbus_transaction_start(&xbt);
81 xenbus_dev_fatal(dev, err, "starting transaction");
85 for (i = 1; i <= usbif->num_ports; i++) {
86 sprintf(node, "port/%d", i);
87 busid = xenbus_read(xbt, dev->nodename, node, NULL);
90 xenbus_dev_fatal(dev, err, "reading port/%d", i);
95 * remove portid, if the port is not connected,
97 if (strlen(busid) == 0) {
98 portid = find_portid(usbif->domid, usbif->handle, i);
100 if (portid->is_connected)
101 xenbus_dev_fatal(dev, err,
102 "can't remove port/%d, unbind first", i);
104 portid_remove(usbif->domid, usbif->handle, i);
106 continue; /* never configured, ignore */
111 * if the port is not configured and not used from other usbif.
113 portid = find_portid(usbif->domid, usbif->handle, i);
115 if ((strncmp(portid->phys_bus, busid, USBBACK_BUS_ID_SIZE)))
116 xenbus_dev_fatal(dev, err,
117 "can't add port/%d, remove first", i);
119 continue; /* already configured, ignore */
121 if (find_portid_by_busid(busid))
122 xenbus_dev_fatal(dev, err,
123 "can't add port/%d, busid already used", i);
125 portid_add(busid, usbif->domid, usbif->handle, i);
129 err = xenbus_transaction_end(xbt, 0);
133 xenbus_dev_fatal(dev, err, "completing transaction");
138 xenbus_transaction_end(xbt, 1);
143 static int usbback_remove(struct xenbus_device *dev)
145 usbif_t *usbif = dev_get_drvdata(&dev->dev);
148 if (usbif->backend_watch.node) {
149 unregister_xenbus_watch(&usbif->backend_watch);
150 kfree(usbif->backend_watch.node);
151 usbif->backend_watch.node = NULL;
155 /* remove all ports */
156 for (i = 1; i <= usbif->num_ports; i++)
157 portid_remove(usbif->domid, usbif->handle, i);
158 usbif_disconnect(usbif);
161 dev_set_drvdata(&dev->dev, NULL);
166 static int usbback_probe(struct xenbus_device *dev,
167 const struct xenbus_device_id *id)
178 handle = simple_strtoul(strrchr(dev->otherend, '/') + 1, NULL, 0);
179 usbif = usbif_alloc(dev->otherend_id, handle);
181 xenbus_dev_fatal(dev, -ENOMEM, "allocating backend interface");
185 dev_set_drvdata(&dev->dev, usbif);
187 err = xenbus_scanf(XBT_NIL, dev->nodename,
188 "num-ports", "%d", &num_ports);
190 xenbus_dev_fatal(dev, err, "reading num-ports");
193 if (num_ports < 1 || num_ports > USB_MAXCHILDREN) {
194 xenbus_dev_fatal(dev, err, "invalid num-ports");
197 usbif->num_ports = num_ports;
199 err = xenbus_scanf(XBT_NIL, dev->nodename,
200 "usb-ver", "%d", &usb_ver);
202 xenbus_dev_fatal(dev, err, "reading usb-ver");
208 usbif->usb_ver = usb_ver;
211 xenbus_dev_fatal(dev, err, "invalid usb-ver");
215 err = xenbus_switch_state(dev, XenbusStateInitWait);
226 static int connect_rings(usbif_t *usbif)
228 struct xenbus_device *dev = usbif->xbdev;
229 unsigned int urb_ring_ref, conn_ring_ref, evtchn;
232 err = xenbus_gather(XBT_NIL, dev->otherend,
233 "urb-ring-ref", "%u", &urb_ring_ref,
234 "conn-ring-ref", "%u", &conn_ring_ref,
235 "event-channel", "%u", &evtchn, NULL);
237 xenbus_dev_fatal(dev, err,
238 "reading %s/ring-ref and event-channel",
243 pr_info("usbback: urb-ring-ref %u, conn-ring-ref %u,"
244 " event-channel %u\n",
245 urb_ring_ref, conn_ring_ref, evtchn);
247 err = usbif_map(usbif, urb_ring_ref, conn_ring_ref, evtchn);
249 xenbus_dev_fatal(dev, err,
250 "mapping urb-ring-ref %u conn-ring-ref %u port %u",
251 urb_ring_ref, conn_ring_ref, evtchn);
258 static void frontend_changed(struct xenbus_device *dev,
259 enum xenbus_state frontend_state)
261 usbif_t *usbif = dev_get_drvdata(&dev->dev);
264 switch (frontend_state) {
265 case XenbusStateInitialised:
266 case XenbusStateReconfiguring:
267 case XenbusStateReconfigured:
270 case XenbusStateInitialising:
271 if (dev->state == XenbusStateClosed) {
272 pr_info("%s: %s: prepare for reconnect\n",
273 __FUNCTION__, dev->nodename);
274 xenbus_switch_state(dev, XenbusStateInitWait);
278 case XenbusStateConnected:
279 if (dev->state == XenbusStateConnected)
281 err = connect_rings(usbif);
284 err = start_xenusbd(usbif);
287 err = xenbus_watch_path2(dev, dev->nodename, "port",
288 &usbif->backend_watch, backend_changed);
291 xenbus_switch_state(dev, XenbusStateConnected);
294 case XenbusStateClosing:
295 usbif_disconnect(usbif);
296 xenbus_switch_state(dev, XenbusStateClosing);
299 case XenbusStateClosed:
300 xenbus_switch_state(dev, XenbusStateClosed);
301 if (xenbus_dev_is_online(dev))
303 /* fall through if not online */
304 case XenbusStateUnknown:
305 device_unregister(&dev->dev);
309 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
315 static const struct xenbus_device_id usbback_ids[] = {
320 static DEFINE_XENBUS_DRIVER(usbback, ,
321 .probe = usbback_probe,
322 .otherend_changed = frontend_changed,
323 .remove = usbback_remove,
326 int __init usbback_xenbus_init(void)
328 return xenbus_register_backend(&usbback_driver);
331 void __exit usbback_xenbus_exit(void)
333 xenbus_unregister_driver(&usbback_driver);