^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/fs/9p/trans_xen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Xen transport layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2017 by Stefano Stabellini <stefano@aporeto.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * modify it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * as published by the Free Software Foundation; or, when distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * separately from the Linux kernel or incorporated into other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * software packages, subject to the following license:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Permission is hereby granted, free of charge, to any person obtaining a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * of this source file (the "Software"), to deal in the Software without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * restriction, including without limitation the rights to use, copy, modify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * merge, publish, distribute, sublicense, and/or sell copies of the Software,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * and to permit persons to whom the Software is furnished to do so, subject to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The above copyright notice and this permission notice shall be included in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * all copies or substantial portions of the Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <xen/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <xen/grant_table.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <xen/xen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <xen/xenbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <xen/interface/io/9pfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <net/9p/9p.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <net/9p/client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <net/9p/transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define XEN_9PFS_NUM_RINGS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define XEN_9PFS_RING_ORDER 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define XEN_9PFS_RING_SIZE(ring) XEN_FLEX_RING_SIZE(ring->intf->ring_order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct xen_9pfs_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) uint32_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) uint8_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) uint16_t tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* uint8_t sdata[]; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* One per ring, more than one per 9pfs share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct xen_9pfs_dataring {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct xen_9pfs_front_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct xen_9pfs_data_intf *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) grant_ref_t ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int evtchn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* protect a ring from concurrent accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct xen_9pfs_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) wait_queue_head_t wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* One per 9pfs share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct xen_9pfs_front_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct xenbus_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) char *tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct p9_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int num_rings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct xen_9pfs_dataring *rings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static LIST_HEAD(xen_9pfs_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static DEFINE_RWLOCK(xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* We don't currently allow canceling of requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int p9_xen_cancel(struct p9_client *client, struct p9_req_t *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int p9_xen_create(struct p9_client *client, const char *addr, char *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct xen_9pfs_front_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (addr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) read_lock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) list_for_each_entry(priv, &xen_9pfs_devs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!strcmp(priv->tag, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) priv->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) read_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) read_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void p9_xen_close(struct p9_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct xen_9pfs_front_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) read_lock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) list_for_each_entry(priv, &xen_9pfs_devs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (priv->client == client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) priv->client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) read_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) read_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) RING_IDX cons, prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) cons = ring->intf->out_cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) prod = ring->intf->out_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) virt_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return XEN_9PFS_RING_SIZE(ring) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) >= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct xen_9pfs_front_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) RING_IDX cons, prod, masked_cons, masked_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 size = p9_req->tc.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct xen_9pfs_dataring *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) read_lock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) list_for_each_entry(priv, &xen_9pfs_devs, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (priv->client == client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) read_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (list_entry_is_head(priv, &xen_9pfs_devs, list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) num = p9_req->tc.tag % priv->num_rings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ring = &priv->rings[num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) while (wait_event_killable(ring->wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) p9_xen_write_todo(ring, size)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) spin_lock_irqsave(&ring->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) cons = ring->intf->out_cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) prod = ring->intf->out_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) virt_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (XEN_9PFS_RING_SIZE(ring) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) spin_unlock_irqrestore(&ring->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) &masked_prod, masked_cons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) p9_req->status = REQ_STATUS_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) virt_wmb(); /* write ring before updating pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) prod += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ring->intf->out_prod = prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spin_unlock_irqrestore(&ring->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) notify_remote_via_irq(ring->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) p9_req_put(p9_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void p9_xen_response(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct xen_9pfs_front_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct xen_9pfs_dataring *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) RING_IDX cons, prod, masked_cons, masked_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct xen_9pfs_header h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct p9_req_t *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ring = container_of(work, struct xen_9pfs_dataring, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) priv = ring->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) cons = ring->intf->in_cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) prod = ring->intf->in_prod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) virt_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) sizeof(h)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) notify_remote_via_irq(ring->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* First, read just the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) xen_9pfs_read_packet(&h, ring->data.in, sizeof(h),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) masked_prod, &masked_cons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) req = p9_tag_lookup(priv->client, h.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!req || req->status != REQ_STATUS_SENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_warn(&priv->dev->dev, "Wrong req tag=%x\n", h.tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cons += h.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) virt_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ring->intf->in_cons = cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) memcpy(&req->rc, &h, sizeof(h));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) req->rc.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Then, read the whole packet (including the header) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) masked_prod, &masked_cons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) XEN_9PFS_RING_SIZE(ring));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) virt_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) cons += h.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ring->intf->in_cons = cons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) status = (req->status != REQ_STATUS_ERROR) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) REQ_STATUS_RCVD : REQ_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) p9_client_cb(priv->client, req, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct xen_9pfs_dataring *ring = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!ring || !ring->priv->client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* ignore spurious interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) wake_up_interruptible(&ring->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) schedule_work(&ring->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static struct p9_trans_module p9_xen_trans = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .name = "xen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT - 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .def = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .create = p9_xen_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .close = p9_xen_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .request = p9_xen_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .cancel = p9_xen_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static const struct xenbus_device_id xen_9pfs_front_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { "9pfs" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) write_lock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) list_del(&priv->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) write_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) for (i = 0; i < priv->num_rings; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!priv->rings[i].intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (priv->rings[i].irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unbind_from_irqhandler(priv->rings[i].irq, priv->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (priv->rings[i].data.in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) for (j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) j < (1 << priv->rings[i].intf->ring_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) grant_ref_t ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ref = priv->rings[i].intf->ref[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) gnttab_end_foreign_access(ref, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) free_pages_exact(priv->rings[i].data.in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 1UL << (priv->rings[i].intf->ring_order +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) XEN_PAGE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) free_page((unsigned long)priv->rings[i].intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) kfree(priv->rings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) kfree(priv->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int xen_9pfs_front_remove(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) xen_9pfs_front_free(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct xen_9pfs_dataring *ring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned int order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) void *bytes = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) init_waitqueue_head(&ring->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) spin_lock_init(&ring->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) INIT_WORK(&ring->work, p9_xen_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ring->intf = (struct xen_9pfs_data_intf *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!ring->intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = gnttab_grant_foreign_access(dev->otherend_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) virt_to_gfn(ring->intf), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ring->ref = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) bytes = alloc_pages_exact(1UL << (order + XEN_PAGE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) for (; i < (1 << order); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = gnttab_grant_foreign_access(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) dev->otherend_id, virt_to_gfn(bytes) + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ring->intf->ref[i] = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ring->intf->ring_order = order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ring->data.in = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ring->data.out = bytes + XEN_FLEX_RING_SIZE(order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = xenbus_alloc_evtchn(dev, &ring->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ring->irq = bind_evtchn_to_irqhandler(ring->evtchn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) xen_9pfs_front_event_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 0, "xen_9pfs-frontend", ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ring->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) xenbus_free_evtchn(dev, ring->evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = ring->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (i--; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) free_pages_exact(bytes, 1UL << (order + XEN_PAGE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) gnttab_end_foreign_access(ring->ref, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) free_page((unsigned long)ring->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int xen_9pfs_front_probe(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const struct xenbus_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct xenbus_transaction xbt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct xen_9pfs_front_priv *priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) char *versions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) unsigned int max_rings, max_ring_order, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (IS_ERR(versions))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return PTR_ERR(versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (strcmp(versions, "1")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) kfree(versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) kfree(versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) max_rings = xenbus_read_unsigned(dev->otherend, "max-rings", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (max_rings < XEN_9PFS_NUM_RINGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) max_ring_order = xenbus_read_unsigned(dev->otherend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) "max-ring-page-order", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (max_ring_order > XEN_9PFS_RING_ORDER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) max_ring_order = XEN_9PFS_RING_ORDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) priv->num_rings = XEN_9PFS_NUM_RINGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!priv->rings) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) for (i = 0; i < priv->num_rings; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) priv->rings[i].priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) max_ring_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = xenbus_transaction_start(&xbt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) xenbus_dev_fatal(dev, ret, "starting transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto error_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = xenbus_printf(xbt, dev->nodename, "num-rings", "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) priv->num_rings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto error_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) for (i = 0; i < priv->num_rings; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) char str[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) BUILD_BUG_ON(XEN_9PFS_NUM_RINGS > 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) sprintf(str, "ring-ref%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = xenbus_printf(xbt, dev->nodename, str, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) priv->rings[i].ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto error_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sprintf(str, "event-channel-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ret = xenbus_printf(xbt, dev->nodename, str, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) priv->rings[i].evtchn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto error_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) priv->tag = xenbus_read(xbt, dev->nodename, "tag", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (IS_ERR(priv->tag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = PTR_ERR(priv->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto error_xenbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = xenbus_transaction_end(xbt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (ret == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) xenbus_dev_fatal(dev, ret, "completing transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) write_lock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) list_add_tail(&priv->list, &xen_9pfs_devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) write_unlock(&xen_9pfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dev_set_drvdata(&dev->dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) xenbus_switch_state(dev, XenbusStateInitialised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) error_xenbus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) xenbus_transaction_end(xbt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) xenbus_dev_fatal(dev, ret, "writing xenstore");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) dev_set_drvdata(&dev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) xen_9pfs_front_free(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int xen_9pfs_front_resume(struct xenbus_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev_warn(&dev->dev, "suspend/resume unsupported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static void xen_9pfs_front_changed(struct xenbus_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) enum xenbus_state backend_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) switch (backend_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case XenbusStateReconfiguring:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case XenbusStateReconfigured:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) case XenbusStateInitialising:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case XenbusStateInitialised:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case XenbusStateUnknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case XenbusStateInitWait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case XenbusStateConnected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) xenbus_switch_state(dev, XenbusStateConnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) case XenbusStateClosed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (dev->state == XenbusStateClosed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) fallthrough; /* Missed the backend's CLOSING state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) case XenbusStateClosing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) xenbus_frontend_closed(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static struct xenbus_driver xen_9pfs_front_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .ids = xen_9pfs_front_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .probe = xen_9pfs_front_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .remove = xen_9pfs_front_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .resume = xen_9pfs_front_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .otherend_changed = xen_9pfs_front_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int p9_trans_xen_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!xen_domain())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) pr_info("Initialising Xen transport for 9pfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) v9fs_register_trans(&p9_xen_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) rc = xenbus_register_frontend(&xen_9pfs_front_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) v9fs_unregister_trans(&p9_xen_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) module_init(p9_trans_xen_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static void p9_trans_xen_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) v9fs_unregister_trans(&p9_xen_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return xenbus_unregister_driver(&xen_9pfs_front_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) module_exit(p9_trans_xen_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) MODULE_AUTHOR("Stefano Stabellini <stefano@aporeto.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) MODULE_DESCRIPTION("Xen Transport for 9P");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) MODULE_LICENSE("GPL");