aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKip Macy <kmacy@FreeBSD.org>2008-12-29 06:31:03 +0000
committerKip Macy <kmacy@FreeBSD.org>2008-12-29 06:31:03 +0000
commit3a6d1fcf9c8ed864c98e449a0b7696be6c838aea (patch)
tree78f4ff4cfc0d598fd6e8ccc01fa628fc8ded089f
parent42d866dd69a50317c56b8e8ac29f020b739b3202 (diff)
downloadsrc-3a6d1fcf9c8ed864c98e449a0b7696be6c838aea.tar.gz
src-3a6d1fcf9c8ed864c98e449a0b7696be6c838aea.zip
merge 186535, 186537, and 186538 from releng_7_xen
Log: - merge in latest xenbus from dfr's xenhvm - fix race condition in xs_read_reply by converting tsleep to mtx_sleep Log: unmask evtchn in bind_{virq, ipi}_to_irq Log: - remove code for handling case of not being able to sleep - eliminate tsleep - make sleeps atomic
Notes
Notes: svn path=/head/; revision=186557
-rw-r--r--sys/dev/xen/blkfront/blkfront.c49
-rw-r--r--sys/dev/xen/console/console.c27
-rw-r--r--sys/dev/xen/console/xencons_ring.c11
-rw-r--r--sys/dev/xen/evtchn/evtchn_dev.c4
-rw-r--r--sys/dev/xen/netfront/netfront.c115
-rw-r--r--sys/i386/conf/XEN6
-rw-r--r--sys/i386/i386/genassym.c2
-rw-r--r--sys/i386/i386/machdep.c4
-rw-r--r--sys/i386/i386/vm_machdep.c2
-rw-r--r--sys/i386/include/xen/xenfunc.h2
-rw-r--r--sys/i386/isa/npx.c2
-rw-r--r--sys/i386/xen/clock.c33
-rw-r--r--sys/i386/xen/mp_machdep.c21
-rw-r--r--sys/i386/xen/mptable.c2
-rw-r--r--sys/i386/xen/pmap.c2
-rw-r--r--sys/i386/xen/xen_machdep.c2
-rw-r--r--sys/xen/evtchn.h (renamed from sys/i386/include/xen/evtchn.h)2
-rw-r--r--sys/xen/evtchn/evtchn.c118
-rw-r--r--sys/xen/evtchn/evtchn_dev.c6
-rw-r--r--sys/xen/features.c2
-rw-r--r--sys/xen/gnttab.c65
-rw-r--r--sys/xen/gnttab.h5
-rw-r--r--sys/xen/hypervisor.h (renamed from sys/i386/include/xen/hypervisor.h)2
-rw-r--r--sys/xen/xen_intr.h (renamed from sys/i386/include/xen/xen_intr.h)17
-rw-r--r--sys/xen/xenbus/xenbus_client.c183
-rw-r--r--sys/xen/xenbus/xenbus_comms.c317
-rw-r--r--sys/xen/xenbus/xenbus_comms.h116
-rw-r--r--sys/xen/xenbus/xenbus_dev.c133
-rw-r--r--sys/xen/xenbus/xenbus_probe.c118
-rw-r--r--sys/xen/xenbus/xenbus_probe_backend.c5
-rw-r--r--sys/xen/xenbus/xenbus_xs.c1307
-rw-r--r--sys/xen/xenbus/xenbusvar.h65
32 files changed, 1328 insertions, 1417 deletions
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index dc36007f82f2..fdebc9d34b2c 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -40,10 +40,10 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/vmparam.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/evtchn.h>
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/protocols.h>
#include <xen/xenbus/xenbusvar.h>
@@ -214,7 +214,7 @@ xlvbd_add(device_t dev, blkif_sector_t capacity,
struct xb_softc *sc;
int unit, error = 0;
const char *name;
-
+
blkfront_vdevice_to_unit(vdevice, &unit, &name);
sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
@@ -227,12 +227,12 @@ xlvbd_add(device_t dev, blkif_sector_t capacity,
memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
sc->xb_disk = disk_alloc();
- sc->xb_disk->d_unit = unit;
+ sc->xb_disk->d_unit = sc->xb_unit;
sc->xb_disk->d_open = blkif_open;
sc->xb_disk->d_close = blkif_close;
sc->xb_disk->d_ioctl = blkif_ioctl;
sc->xb_disk->d_strategy = xb_strategy;
- sc->xb_disk->d_name = "xbd";
+ sc->xb_disk->d_name = name;
sc->xb_disk->d_drv1 = sc;
sc->xb_disk->d_sectorsize = sector_size;
@@ -329,8 +329,8 @@ blkfront_attach(device_t dev)
/* FIXME: Use dynamic device id if this is not set. */
err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
- "virtual-device", "%i", &vdevice);
- if (err != 1) {
+ "virtual-device", NULL, "%i", &vdevice);
+ if (err) {
xenbus_dev_fatal(dev, err, "reading virtual-device");
printf("couldn't find virtual device");
return (err);
@@ -363,9 +363,8 @@ blkfront_attach(device_t dev)
info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
err = talk_to_backend(dev, info);
- if (err) {
- return err;
- }
+ if (err)
+ return (err);
return (0);
}
@@ -381,7 +380,8 @@ blkfront_resume(device_t dev)
blkif_free(info, 1);
err = talk_to_backend(dev, info);
- if (!err)
+
+ if (info->connected == BLKIF_STATE_SUSPENDED && !err)
blkif_recover(info);
return err;
@@ -427,7 +427,7 @@ talk_to_backend(device_t dev, struct blkfront_info *info)
}
err = xenbus_transaction_end(xbt, 0);
if (err) {
- if (err == -EAGAIN)
+ if (err == EAGAIN)
goto again;
xenbus_dev_fatal(dev, err, "completing transaction");
goto destroy_blkring;
@@ -450,7 +450,7 @@ static int
setup_blkring(device_t dev, struct blkfront_info *info)
{
blkif_sring_t *sring;
- int err;
+ int error;
info->ring_ref = GRANT_INVALID_REF;
@@ -462,28 +462,27 @@ setup_blkring(device_t dev, struct blkfront_info *info)
SHARED_RING_INIT(sring);
FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
- err = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT));
- if (err < 0) {
+ error = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT),
+ &info->ring_ref);
+ if (error) {
free(sring, M_DEVBUF);
info->ring.sring = NULL;
goto fail;
}
- info->ring_ref = err;
- err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
+ error = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
"xbd", (driver_intr_t *)blkif_int, info,
- INTR_TYPE_BIO | INTR_MPSAFE, NULL);
- if (err <= 0) {
- xenbus_dev_fatal(dev, err,
+ INTR_TYPE_BIO | INTR_MPSAFE, &info->irq);
+ if (error) {
+ xenbus_dev_fatal(dev, error,
"bind_evtchn_to_irqhandler failed");
goto fail;
}
- info->irq = err;
- return 0;
+ return (0);
fail:
blkif_free(info, 0);
- return err;
+ return (error);
}
@@ -999,7 +998,7 @@ blkif_free(struct blkfront_info *info, int suspend)
info->ring.sring = NULL;
}
if (info->irq)
- unbind_from_irqhandler(info->irq, info);
+ unbind_from_irqhandler(info->irq);
info->irq = 0;
}
diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
index 5b556c250490..a3d616a74856 100644
--- a/sys/dev/xen/console/console.c
+++ b/sys/dev/xen/console/console.c
@@ -15,8 +15,8 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/stdarg.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
#include <sys/cons.h>
#include <sys/priv.h>
#include <sys/proc.h>
@@ -75,17 +75,17 @@ static unsigned int wc, wp; /* write_cons, write_prod */
#define XCUNIT(x) (dev2unit(x))
#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN))
#define CN_LOCK_INIT(x, _name) \
- mtx_init(&x, _name, NULL, MTX_SPIN|MTX_RECURSE)
+ mtx_init(&x, _name, NULL, MTX_DEF|MTX_RECURSE)
#define CN_LOCK(l) \
do { \
if (panicstr == NULL) \
- mtx_lock_spin(&(l)); \
+ mtx_lock(&(l)); \
} while (0)
#define CN_UNLOCK(l) \
do { \
if (panicstr == NULL) \
- mtx_unlock_spin(&(l)); \
+ mtx_unlock(&(l)); \
} while (0)
#define CN_LOCK_ASSERT(x) mtx_assert(&x, MA_OWNED)
#define CN_LOCK_DESTROY(x) mtx_destroy(&x)
@@ -216,6 +216,8 @@ xc_probe(device_t dev)
static int
xc_attach(device_t dev)
{
+ int error;
+ struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev);
if (xen_start_info->flags & SIF_INITDOMAIN) {
xc_consdev.cn_putc = xccnputc_dom0;
@@ -232,14 +234,15 @@ xc_attach(device_t dev)
callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons);
if (xen_start_info->flags & SIF_INITDOMAIN) {
- PANIC_IF(bind_virq_to_irqhandler(
- VIRQ_CONSOLE,
- 0,
- "console",
- NULL,
- xencons_priv_interrupt,
- INTR_TYPE_TTY) < 0);
+ error = bind_virq_to_irqhandler(
+ VIRQ_CONSOLE,
+ 0,
+ "console",
+ NULL,
+ xencons_priv_interrupt,
+ sc, INTR_TYPE_TTY, NULL);
+ KASSERT(error >= 0, ("can't register console interrupt"));
}
diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c
index 3d2323765c8e..596b5de48d36 100644
--- a/sys/dev/xen/console/xencons_ring.c
+++ b/sys/dev/xen/console/xencons_ring.c
@@ -15,19 +15,20 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/stdarg.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
#include <sys/cons.h>
#include <dev/xen/console/xencons_ring.h>
-#include <machine/xen/evtchn.h>
+#include <xen/evtchn.h>
#include <xen/interface/io/console.h>
#define console_evtchn console.domU.evtchn
extern char *console_page;
-
+extern struct mtx cn_mtx;
+
static inline struct xencons_interface *
xencons_interface(void)
{
@@ -82,6 +83,7 @@ xencons_handle_input(void *unused)
struct xencons_interface *intf;
XENCONS_RING_IDX cons, prod;
+ mtx_lock(&cn_mtx);
intf = xencons_interface();
cons = intf->in_cons;
@@ -99,6 +101,7 @@ xencons_handle_input(void *unused)
notify_remote_via_evtchn(xen_start_info->console_evtchn);
xencons_tx();
+ mtx_unlock(&cn_mtx);
}
void
diff --git a/sys/dev/xen/evtchn/evtchn_dev.c b/sys/dev/xen/evtchn/evtchn_dev.c
index a20670857197..6925a22a17ae 100644
--- a/sys/dev/xen/evtchn/evtchn_dev.c
+++ b/sys/dev/xen/evtchn/evtchn_dev.c
@@ -26,13 +26,13 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen-os.h>
-#include <machine/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/synch_bitops.h>
-#include <machine/hypervisor.h>
+#include <xen/hypervisor.h>
typedef struct evtchn_sotfc {
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 607628f9f2be..7efeb2007f35 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -62,9 +62,9 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
#include <xen/gnttab.h>
#include <xen/interface/memory.h>
#include <dev/xen/netfront/mbufq.h>
@@ -363,24 +363,25 @@ makembuf (struct mbuf *buf)
static int
xen_net_read_mac(device_t dev, uint8_t mac[])
{
- char *s;
- int i;
- char *e;
- char *macstr = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL);
- if (IS_ERR(macstr)) {
- return PTR_ERR(macstr);
- }
+ int error, i;
+ char *s, *e, *macstr;
+
+ error = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL,
+ (void **) &macstr);
+ if (error)
+ return (error);
+
s = macstr;
for (i = 0; i < ETHER_ADDR_LEN; i++) {
mac[i] = strtoul(s, &e, 16);
if (s == e || (e[0] != ':' && e[0] != 0)) {
free(macstr, M_DEVBUF);
- return ENOENT;
+ return (ENOENT);
}
s = &e[1];
}
free(macstr, M_DEVBUF);
- return 0;
+ return (0);
}
/**
@@ -422,13 +423,11 @@ netfront_attach(device_t dev)
* leave the device-layer structures intact so that this is transparent to the
* rest of the kernel.
*/
-static int
+static int
netfront_resume(device_t dev)
{
struct netfront_info *info = device_get_softc(dev);
-
- DPRINTK("%s\n", xenbus_get_node(dev));
-
+
netif_disconnect_backend(info);
return (0);
}
@@ -532,7 +531,7 @@ setup_device(device_t dev, struct netfront_info *info)
{
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
- int err;
+ int error;
struct ifnet *ifp;
ifp = info->xn_ifp;
@@ -545,51 +544,45 @@ setup_device(device_t dev, struct netfront_info *info)
txs = (netif_tx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
if (!txs) {
- err = ENOMEM;
- xenbus_dev_fatal(dev, err, "allocating tx ring page");
+ error = ENOMEM;
+ xenbus_dev_fatal(dev, error, "allocating tx ring page");
goto fail;
}
SHARED_RING_INIT(txs);
FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
- err = xenbus_grant_ring(dev, virt_to_mfn(txs));
- if (err < 0)
+ error = xenbus_grant_ring(dev, virt_to_mfn(txs), &info->tx_ring_ref);
+ if (error)
goto fail;
- info->tx_ring_ref = err;
rxs = (netif_rx_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
if (!rxs) {
- err = ENOMEM;
- xenbus_dev_fatal(dev, err, "allocating rx ring page");
+ error = ENOMEM;
+ xenbus_dev_fatal(dev, error, "allocating rx ring page");
goto fail;
}
SHARED_RING_INIT(rxs);
FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
- err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
- if (err < 0)
+ error = xenbus_grant_ring(dev, virt_to_mfn(rxs), &info->rx_ring_ref);
+ if (error)
goto fail;
- info->rx_ring_ref = err;
-#if 0
- network_connect(info);
-#endif
- err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
- "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL);
+ error = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
+ "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, &info->irq);
- if (err <= 0) {
- xenbus_dev_fatal(dev, err,
+ if (error) {
+ xenbus_dev_fatal(dev, error,
"bind_evtchn_to_irqhandler failed");
goto fail;
}
- info->irq = err;
-
+
show_device(info);
- return 0;
+ return (0);
fail:
netif_free(info);
- return err;
+ return (error);
}
/**
@@ -1225,7 +1218,7 @@ xennet_get_responses(struct netfront_info *np,
MULTI_update_va_mapping(mcl, (u_long)vaddr,
(((vm_paddr_t)mfn) << PAGE_SHIFT) | PG_RW |
PG_V | PG_M | PG_A, 0);
- pfn = (uint32_t)m->m_ext.ext_arg1;
+ pfn = (uintptr_t)m->m_ext.ext_arg1;
mmu->ptr = ((vm_paddr_t)mfn << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE;
mmu->val = pfn;
@@ -1557,18 +1550,18 @@ xn_stop(struct netfront_info *sc)
int
network_connect(struct netfront_info *np)
{
- int i, requeue_idx, err;
+ int i, requeue_idx, error;
grant_ref_t ref;
netif_rx_request_t *req;
u_int feature_rx_copy, feature_rx_flip;
- err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
- "feature-rx-copy", "%u", &feature_rx_copy);
- if (err != 1)
+ error = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
+ "feature-rx-copy", NULL, "%u", &feature_rx_copy);
+ if (error)
feature_rx_copy = 0;
- err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
- "feature-rx-flip", "%u", &feature_rx_flip);
- if (err != 1)
+ error = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
+ "feature-rx-flip", NULL, "%u", &feature_rx_flip);
+ if (error)
feature_rx_flip = 1;
/*
@@ -1581,9 +1574,9 @@ network_connect(struct netfront_info *np)
XN_LOCK(np);
/* Recovery procedure: */
- err = talk_to_backend(np->xbdev, np);
- if (err)
- return (err);
+ error = talk_to_backend(np->xbdev, np);
+ if (error)
+ return (error);
/* Step 1: Reinitialise variables. */
netif_release_tx_bufs(np);
@@ -1591,6 +1584,7 @@ network_connect(struct netfront_info *np)
/* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
struct mbuf *m;
+ u_long pfn;
if (np->rx_mbufs[i] == NULL)
continue;
@@ -1598,15 +1592,16 @@ network_connect(struct netfront_info *np)
m = np->rx_mbufs[requeue_idx] = xennet_get_rx_mbuf(np, i);
ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
req = RING_GET_REQUEST(&np->rx, requeue_idx);
+ pfn = vtophys(mtod(m, vm_offset_t)) >> PAGE_SHIFT;
if (!np->copying_receiver) {
gnttab_grant_foreign_transfer_ref(ref,
xenbus_get_otherend_id(np->xbdev),
- vtophys(mtod(m, vm_offset_t)));
+ pfn);
} else {
gnttab_grant_foreign_access_ref(ref,
xenbus_get_otherend_id(np->xbdev),
- vtophys(mtod(m, vm_offset_t)), 0);
+ PFNTOMFN(pfn), 0);
}
req->gref = ref;
req->id = requeue_idx;
@@ -1707,7 +1702,7 @@ create_netdev(device_t dev)
ifp = np->xn_ifp = if_alloc(IFT_ETHER);
ifp->if_softc = np;
if_initname(ifp, "xn", device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = xn_ioctl;
ifp->if_output = ether_output;
ifp->if_start = xn_start;
@@ -1777,11 +1772,14 @@ static void netif_free(struct netfront_info *info)
#endif
}
-
-
static void netif_disconnect_backend(struct netfront_info *info)
{
- xn_stop(info);
+ XN_RX_LOCK(info);
+ XN_TX_LOCK(info);
+ netfront_carrier_off(info);
+ XN_TX_UNLOCK(info);
+ XN_RX_UNLOCK(info);
+
end_access(info->tx_ring_ref, info->tx.sring);
end_access(info->rx_ring_ref, info->rx.sring);
info->tx_ring_ref = GRANT_INVALID_REF;
@@ -1789,12 +1787,9 @@ static void netif_disconnect_backend(struct netfront_info *info)
info->tx.sring = NULL;
info->rx.sring = NULL;
-#if 0
if (info->irq)
- unbind_from_irqhandler(info->irq, info->netdev);
-#else
- panic("FIX ME");
-#endif
+ unbind_from_irqhandler(info->irq);
+
info->irq = 0;
}
diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN
index 92958440a4e0..7ddc776d8cb7 100644
--- a/sys/i386/conf/XEN
+++ b/sys/i386/conf/XEN
@@ -9,9 +9,9 @@ ident XEN
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions MODULES_OVERRIDE=""
-#options SCHED_ULE # ULE scheduler
-#options PREEMPTION # Enable kernel thread preemption
-options SCHED_4BSD
+options SCHED_ULE # ULE scheduler
+options PREEMPTION # Enable kernel thread preemption
+#options SCHED_4BSD
options INET # InterNETworking
options INET6 # IPv6 communications protocols
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 059e2ab394c2..7c6acf0ee5ad 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -234,7 +234,7 @@ ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat));
#endif
#ifdef XEN
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
ASSYM(PC_CR3, offsetof(struct pcpu, pc_cr3));
ASSYM(HYPERVISOR_VIRT_START, __HYPERVISOR_VIRT_START);
#endif
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index d824b26dea9f..803d8d15b0f7 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -144,11 +144,11 @@ uint32_t arch_i386_xbox_memsize = 0;
#ifdef XEN
/* XEN includes */
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
void Xhypervisor_callback(void);
void failsafe_callback(void);
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 502be4d47385..15233c5a6cf3 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#ifdef XEN
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#endif
#ifdef PC98
#include <pc98/cbus/cbus.h>
diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h
index e1a707d74629..2851709cb955 100644
--- a/sys/i386/include/xen/xenfunc.h
+++ b/sys/i386/include/xen/xenfunc.h
@@ -33,7 +33,7 @@
#define _XEN_XENFUNC_H_
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xenpmap.h>
#include <machine/segments.h>
#include <sys/pcpu.h>
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 6be3da9ac7a9..29dc2ca9702f 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#ifdef XEN
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#endif
#ifdef DEV_ISA
diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c
index 3b4b6f3b8a19..db5b09cb75b6 100644
--- a/sys/i386/xen/clock.c
+++ b/sys/i386/xen/clock.c
@@ -78,11 +78,11 @@ __FBSDID("$FreeBSD$");
#include <i386/isa/isa.h>
#include <isa/rtc.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/pmap.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/xen/xenfunc.h>
#include <xen/interface/vcpu.h>
@@ -791,18 +791,20 @@ static struct vcpu_set_periodic_timer xen_set_periodic_tick;
void
cpu_initclocks(void)
{
- int time_irq;
-
+ unsigned int time_irq;
+ int error;
+
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
&xen_set_periodic_tick);
-
- if ((time_irq = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
- clkintr, NULL,
- INTR_TYPE_CLK | INTR_FAST)) < 0) {
+
+ error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
+ clkintr, NULL, NULL,
+ INTR_TYPE_CLK | INTR_FAST, &time_irq);
+ if (error)
panic("failed to register clock interrupt\n");
- }
+
/* should fast clock be enabled ? */
@@ -811,18 +813,19 @@ cpu_initclocks(void)
int
ap_cpu_initclocks(int cpu)
{
- int time_irq;
+ unsigned int time_irq;
+ int error;
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
&xen_set_periodic_tick);
-
- if ((time_irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, "clk",
- clkintr2, NULL,
- INTR_TYPE_CLK | INTR_FAST)) < 0) {
+ error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
+ clkintr, NULL, NULL,
+ INTR_TYPE_CLK | INTR_FAST, &time_irq);
+ if (error)
panic("failed to register clock interrupt\n");
- }
+
return (0);
}
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index 4b6c77c107ac..874cde886b51 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -85,9 +85,9 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xen-os.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/xen_intr.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/xen_intr.h>
+#include <xen/hypervisor.h>
#include <xen/interface/vcpu.h>
#define stop_cpus_with_nmi 0
@@ -464,7 +464,8 @@ static int
xen_smp_intr_init(unsigned int cpu)
{
int rc;
-
+ unsigned int irq;
+
per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1;
sprintf(resched_name[cpu], "resched%u", cpu);
@@ -472,22 +473,22 @@ xen_smp_intr_init(unsigned int cpu)
cpu,
resched_name[cpu],
smp_reschedule_interrupt,
- INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE);
+ INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE, &irq);
printf("cpu=%d irq=%d vector=%d\n",
cpu, rc, RESCHEDULE_VECTOR);
- per_cpu(resched_irq, cpu) = rc;
+ per_cpu(resched_irq, cpu) = irq;
sprintf(callfunc_name[cpu], "callfunc%u", cpu);
rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
cpu,
callfunc_name[cpu],
smp_call_function_interrupt,
- INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE);
+ INTR_FAST|INTR_TYPE_TTY|INTR_MPSAFE, &irq);
if (rc < 0)
goto fail;
- per_cpu(callfunc_irq, cpu) = rc;
+ per_cpu(callfunc_irq, cpu) = irq;
printf("cpu=%d irq=%d vector=%d\n",
cpu, rc, CALL_FUNCTION_VECTOR);
@@ -500,9 +501,9 @@ xen_smp_intr_init(unsigned int cpu)
fail:
if (per_cpu(resched_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+ unbind_from_irqhandler(per_cpu(resched_irq, cpu));
if (per_cpu(callfunc_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
+ unbind_from_irqhandler(per_cpu(callfunc_irq, cpu));
return rc;
}
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
index 99edc50e31cf..c6c7d53ccb5e 100644
--- a/sys/i386/xen/mptable.c
+++ b/sys/i386/xen/mptable.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/mptable.h>
#include <machine/specialreg.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/smp.h>
#include <xen/interface/vcpu.h>
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index d6464583ad45..6ad67ffd7653 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -154,7 +154,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <xen/interface/xen.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/hypercall.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index 9f487025d32b..0c86c62b2fe1 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/xenvar.h>
#include <machine/xen/xenfunc.h>
#include <machine/xen/xenpmap.h>
diff --git a/sys/i386/include/xen/evtchn.h b/sys/xen/evtchn.h
index f86a8abc0e79..721742f6de40 100644
--- a/sys/i386/include/xen/evtchn.h
+++ b/sys/xen/evtchn.h
@@ -12,7 +12,7 @@
#ifndef __ASM_EVTCHN_H__
#define __ASM_EVTCHN_H__
#include <machine/pcpu.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/synch_bitops.h>
#include <machine/frame.h>
diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c
index b28315cb548f..884270c666a6 100644
--- a/sys/xen/evtchn/evtchn.c
+++ b/sys/xen/evtchn/evtchn.c
@@ -23,10 +23,10 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/xen/synch_bitops.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/hypervisor.h>
#include <sys/smp.h>
@@ -76,6 +76,7 @@ static struct mtx irq_mapping_update_lock;
static struct xenpic *xp;
struct xenpic_intsrc {
struct intsrc xp_intsrc;
+ void *xp_cookie;
uint8_t xp_vector;
boolean_t xp_masked;
};
@@ -295,6 +296,7 @@ bind_caller_port_to_irq(unsigned int caller_port)
}
irq_bindcount[irq]++;
+ unmask_evtchn(caller_port);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -320,6 +322,7 @@ bind_local_port_to_irq(unsigned int local_port)
evtchn_to_irq[local_port] = irq;
irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
irq_bindcount[irq]++;
+ unmask_evtchn(local_port);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -361,7 +364,7 @@ static int
bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
- int evtchn, irq;
+ int evtchn = 0, irq;
mtx_lock_spin(&irq_mapping_update_lock);
@@ -385,6 +388,7 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu)
}
irq_bindcount[irq]++;
+ unmask_evtchn(evtchn);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -398,8 +402,9 @@ int
bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
struct evtchn_bind_ipi bind_ipi;
- int evtchn, irq;
-
+ int irq;
+ int evtchn = 0;
+
mtx_lock_spin(&irq_mapping_update_lock);
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
@@ -418,6 +423,7 @@ bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
bind_evtchn_to_cpu(evtchn, cpu);
}
irq_bindcount[irq]++;
+ unmask_evtchn(evtchn);
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -465,20 +471,25 @@ bind_caller_port_to_irqhandler(unsigned int caller_port,
driver_intr_t handler,
void *arg,
unsigned long irqflags,
- void **cookiep)
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_caller_port_to_irq(caller_port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
+ &xp->xp_pins[irq].xp_cookie);
+
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+
+ return (0);
}
int
@@ -488,43 +499,50 @@ bind_listening_port_to_irqhandler(
driver_intr_t handler,
void *arg,
unsigned long irqflags,
- void **cookiep)
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_listening_port_to_irq(remote_domain);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
+ &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
-
- return irq;
+ if (irqp)
+ *irqp = irq;
+
+ return (0);
}
int
bind_interdomain_evtchn_to_irqhandler(
- unsigned int remote_domain,
- unsigned int remote_port,
- const char *devname,
- driver_filter_t filter,
- driver_intr_t handler,
- unsigned long irqflags)
+ unsigned int remote_domain,
+ unsigned int remote_port,
+ const char *devname,
+ driver_filter_t filter,
+ driver_intr_t handler,
+ unsigned long irqflags,
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, handler, NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, handler, NULL,
+ irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
int
@@ -533,20 +551,25 @@ bind_virq_to_irqhandler(unsigned int virq,
const char *devname,
driver_filter_t filter,
driver_intr_t handler,
- unsigned long irqflags)
+ void *arg,
+ unsigned long irqflags,
+ unsigned int *irqp)
{
unsigned int irq;
- int retval;
+ int error;
irq = bind_virq_to_irq(virq, cpu);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, handler, NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, handler,
+ arg, irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
int
@@ -554,27 +577,30 @@ bind_ipi_to_irqhandler(unsigned int ipi,
unsigned int cpu,
const char *devname,
driver_filter_t filter,
- unsigned long irqflags)
+ unsigned long irqflags,
+ unsigned int *irqp)
{
- int irq, retval;
+ unsigned int irq;
+ int error;
irq = bind_ipi_to_irq(ipi, cpu);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
- retval = intr_add_handler(devname, irq, filter, NULL,
- NULL, irqflags, NULL);
- if (retval != 0) {
+ error = intr_add_handler(devname, irq, filter, NULL,
+ NULL, irqflags, &xp->xp_pins[irq].xp_cookie);
+ if (error) {
unbind_from_irq(irq);
- return -retval;
+ return (error);
}
- return irq;
+ if (irqp)
+ *irqp = irq;
+ return (0);
}
void
-unbind_from_irqhandler(unsigned int irq, void *dev_id)
+unbind_from_irqhandler(unsigned int irq)
{
- if (dev_id)
- intr_remove_handler(dev_id); /* XXX */
+ intr_remove_handler(xp->xp_pins[irq].xp_cookie);
unbind_from_irq(irq);
}
diff --git a/sys/xen/evtchn/evtchn_dev.c b/sys/xen/evtchn/evtchn_dev.c
index 111b066b4bcf..ea12860dbefb 100644
--- a/sys/xen/evtchn/evtchn_dev.c
+++ b/sys/xen/evtchn/evtchn_dev.c
@@ -26,13 +26,13 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/xen_intr.h>
+#include <xen/xen_intr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/xen/synch_bitops.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/evtchn.h>
typedef struct evtchn_sotfc {
diff --git a/sys/xen/features.c b/sys/xen/features.c
index 51d68990e98f..876a7d1e568f 100644
--- a/sys/xen/features.c
+++ b/sys/xen/features.c
@@ -3,7 +3,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/features.h>
uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32] /* __read_mostly */;
diff --git a/sys/xen/gnttab.c b/sys/xen/gnttab.c
index fdd3d1b2356c..967565506dfc 100644
--- a/sys/xen/gnttab.c
+++ b/sys/xen/gnttab.c
@@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/xen/synch_bitops.h>
#include <xen/gnttab.h>
@@ -70,14 +70,14 @@ static int gnttab_expand(unsigned int req_entries);
#define gnttab_entry(entry) (gnttab_list[(entry) / RPP][(entry) % RPP])
static int
-get_free_entries(int count)
+get_free_entries(int count, int *entries)
{
int ref, rc;
grant_ref_t head;
mtx_lock(&gnttab_list_lock);
if ((gnttab_free_count < count) &&
- ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
+ ((rc = gnttab_expand(count - gnttab_free_count)) != 0)) {
mtx_unlock(&gnttab_list_lock);
return (rc);
}
@@ -88,10 +88,10 @@ get_free_entries(int count)
gnttab_free_head = gnttab_entry(head);
gnttab_entry(head) = GNTTAB_LIST_END;
mtx_unlock(&gnttab_list_lock);
- return (ref);
-}
-#define get_free_entry() get_free_entries(1)
+ *entries = ref;
+ return (0);
+}
static void
do_free_callbacks(void)
@@ -138,19 +138,25 @@ put_free_entry(grant_ref_t ref)
*/
int
-gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly,
+ grant_ref_t *result)
{
- int ref;
+ int error, ref;
- if (unlikely((ref = get_free_entry()) == -1))
- return -ENOSPC;
+ error = get_free_entries(1, &ref);
+
+ if (unlikely(error))
+ return (error);
shared[ref].frame = frame;
shared[ref].domid = domid;
wmb();
shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
- return ref;
+ if (result)
+ *result = ref;
+
+ return (0);
}
void
@@ -209,10 +215,11 @@ gnttab_end_foreign_access(grant_ref_t ref, void *page)
int
gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
{
- int ref;
-
- if (unlikely((ref = get_free_entry()) == -1))
- return -ENOSPC;
+ int error, ref;
+
+ error = get_free_entries(1, &ref);
+ if (unlikely(error))
+ return (error);
gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
@@ -300,14 +307,14 @@ gnttab_free_grant_references(grant_ref_t head)
int
gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head)
{
- int h = get_free_entries(count);
+ int ref, error;
- if (h == -1)
- return -ENOSPC;
+ error = get_free_entries(count, &ref);
+ if (unlikely(error))
+ return (error);
- *head = h;
-
- return 0;
+ *head = ref;
+ return (0);
}
int
@@ -322,7 +329,7 @@ gnttab_claim_grant_reference(grant_ref_t *private_head)
grant_ref_t g = *private_head;
if (unlikely(g == GNTTAB_LIST_END))
- return -ENOSPC;
+ return (ENOSPC);
*private_head = gnttab_entry(g);
return (g);
@@ -468,7 +475,7 @@ gnttab_map(unsigned int start_idx, unsigned int end_idx)
frames = malloc(nr_gframes * sizeof(unsigned long), M_DEVBUF, M_NOWAIT);
if (!frames)
- return -ENOMEM;
+ return (ENOMEM);
setup.dom = DOMID_SELF;
setup.nr_frames = nr_gframes;
@@ -477,7 +484,7 @@ gnttab_map(unsigned int start_idx, unsigned int end_idx)
rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
if (rc == -ENOSYS) {
free(frames, M_DEVBUF);
- return -ENOSYS;
+ return (ENOSYS);
}
PANIC_IF(rc || setup.status);
@@ -529,7 +536,7 @@ gnttab_expand(unsigned int req_entries)
extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
GREFS_PER_GRANT_FRAME);
if (cur + extra > max_nr_grant_frames())
- return -ENOSPC;
+ return (ENOSPC);
if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
rc = grow_gnttab_list(extra);
@@ -561,7 +568,7 @@ gnttab_init()
M_DEVBUF, M_NOWAIT);
if (gnttab_list == NULL)
- return -ENOMEM;
+ return (ENOMEM);
for (i = 0; i < nr_grant_frames; i++) {
gnttab_list[i] = (grant_ref_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
@@ -569,8 +576,8 @@ gnttab_init()
goto ini_nomem;
}
- if (gnttab_resume() < 0)
- return -ENODEV;
+ if (gnttab_resume())
+ return (ENODEV);
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
@@ -588,7 +595,7 @@ ini_nomem:
for (i--; i >= 0; i--)
free(gnttab_list[i], M_DEVBUF);
free(gnttab_list, M_DEVBUF);
- return -ENOMEM;
+ return (ENOMEM);
}
diff --git a/sys/xen/gnttab.h b/sys/xen/gnttab.h
index d1abe14c9fb7..bcefbbc131bf 100644
--- a/sys/xen/gnttab.h
+++ b/sys/xen/gnttab.h
@@ -36,10 +36,9 @@
#ifndef __ASM_GNTTAB_H__
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <xen/interface/grant_table.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
#include <machine/xen/features.h>
struct gnttab_free_callback {
@@ -52,7 +51,7 @@ struct gnttab_free_callback {
int gnttab_init(void);
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
- int flags);
+ int flags, grant_ref_t *result);
/*
* End access through the given grant reference, iff the grant entry is no
diff --git a/sys/i386/include/xen/hypervisor.h b/sys/xen/hypervisor.h
index 7f7ca20fc828..369b0c4d5b6c 100644
--- a/sys/i386/include/xen/hypervisor.h
+++ b/sys/xen/hypervisor.h
@@ -4,6 +4,8 @@
* Linux-specific hypervisor handling.
*
* Copyright (c) 2002, K A Fraser
+ *
+ * $FreeBSD$
*/
#ifndef __HYPERVISOR_H__
diff --git a/sys/i386/include/xen/xen_intr.h b/sys/xen/xen_intr.h
index a0e6c8844404..528fa7f40d80 100644
--- a/sys/i386/include/xen/xen_intr.h
+++ b/sys/xen/xen_intr.h
@@ -34,28 +34,31 @@ extern void unbind_from_irq(int irq);
extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
const char *devname, driver_intr_t handler, void *arg,
- unsigned long irqflags, void **cookiep);
+ unsigned long irqflags, unsigned int *irqp);
extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
const char *devname, driver_intr_t handler, void *arg, unsigned long irqflags,
- void **cookiep);
-extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, const char *devname,
- driver_filter_t filter, driver_intr_t handler, unsigned long irqflags);
+ unsigned int *irqp);
+extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
+ const char *devname, driver_filter_t filter, driver_intr_t handler,
+ void *arg, unsigned long irqflags, unsigned int *irqp);
extern int bind_ipi_to_irqhandler(unsigned int ipi,
unsigned int cpu,
const char *devname,
driver_filter_t handler,
- unsigned long irqflags);
+ unsigned long irqflags,
+ unsigned int *irqp);
extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
unsigned int remote_port,
const char *devname,
driver_filter_t filter,
driver_intr_t handler,
- unsigned long irqflags);
+ unsigned long irqflags,
+ unsigned int *irqp);
-extern void unbind_from_irqhandler(unsigned int evtchn, void *dev_id);
+extern void unbind_from_irqhandler(unsigned int evtchn);
static __inline__ int irq_cannonicalize(int irq)
{
return (irq == 2) ? 9 : irq;
diff --git a/sys/xen/xenbus/xenbus_client.c b/sys/xen/xenbus/xenbus_client.c
index d8a1a3f4a488..740d66409e14 100644
--- a/sys/xen/xenbus/xenbus_client.c
+++ b/sys/xen/xenbus/xenbus_client.c
@@ -44,19 +44,14 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <xen/evtchn.h>
#include <xen/gnttab.h>
#include <xen/xenbus/xenbusvar.h>
#include <machine/stdarg.h>
-
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free(ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-
-
-const char *xenbus_strstate(XenbusState state)
+const char *
+xenbus_strstate(XenbusState state)
{
static const char *const name[] = {
[ XenbusStateUnknown ] = "Unknown",
@@ -67,121 +62,108 @@ const char *xenbus_strstate(XenbusState state)
[ XenbusStateClosing ] = "Closing",
[ XenbusStateClosed ] = "Closed",
};
- return (state < (XenbusStateClosed + 1)) ? name[state] : "INVALID";
+
+ return ((state < (XenbusStateClosed + 1)) ? name[state] : "INVALID");
}
int
-xenbus_watch_path(device_t dev, char *path,
- struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
+xenbus_watch_path(device_t dev, char *path, struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *, const char **, unsigned int))
{
- int err;
+ int error;
watch->node = path;
watch->callback = callback;
- err = register_xenbus_watch(watch);
+ error = register_xenbus_watch(watch);
- if (err) {
+ if (error) {
watch->node = NULL;
watch->callback = NULL;
- xenbus_dev_fatal(dev, err, "adding watch on %s", path);
+ xenbus_dev_fatal(dev, error, "adding watch on %s", path);
}
- return err;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_watch_path);
-
-int xenbus_watch_path2(device_t dev, const char *path,
- const char *path2, struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
+int
+xenbus_watch_path2(device_t dev, const char *path,
+ const char *path2, struct xenbus_watch *watch,
+ void (*callback)(struct xenbus_watch *, const char **, unsigned int))
{
- int err;
- char *state =
- kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
- if (!state) {
- xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
- return -ENOMEM;
- }
+ int error;
+ char *state = malloc(strlen(path) + 1 + strlen(path2) + 1,
+ M_DEVBUF, M_WAITOK);
+
strcpy(state, path);
strcat(state, "/");
strcat(state, path2);
- err = xenbus_watch_path(dev, state, watch, callback);
-
- if (err) {
- kfree(state);
+ error = xenbus_watch_path(dev, state, watch, callback);
+ if (error) {
+ free(state, M_DEVBUF);
}
- return err;
+
+ return (error);
}
-EXPORT_SYMBOL(xenbus_watch_path2);
/**
* Return the path to the error node for the given device, or NULL on failure.
* If the value returned is non-NULL, then it is the caller's to kfree.
*/
-static char *error_path(device_t dev)
+static char *
+error_path(device_t dev)
{
- char *path_buffer = kmalloc(strlen("error/")
- + strlen(xenbus_get_node(dev)) +
- 1, GFP_KERNEL);
- if (path_buffer == NULL) {
- return NULL;
- }
+ char *path_buffer = malloc(strlen("error/")
+ + strlen(xenbus_get_node(dev)) + 1, M_DEVBUF, M_WAITOK);
strcpy(path_buffer, "error/");
strcpy(path_buffer + strlen("error/"), xenbus_get_node(dev));
- return path_buffer;
+ return (path_buffer);
}
-static void _dev_error(device_t dev, int err, const char *fmt,
- va_list ap)
+static void
+_dev_error(device_t dev, int err, const char *fmt, va_list ap)
{
int ret;
unsigned int len;
char *printf_buffer = NULL, *path_buffer = NULL;
#define PRINTF_BUFFER_SIZE 4096
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- goto fail;
+ printf_buffer = malloc(PRINTF_BUFFER_SIZE, M_DEVBUF, M_WAITOK);
- len = sprintf(printf_buffer, "%i ", -err);
+ len = sprintf(printf_buffer, "%i ", err);
ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
- BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
+ KASSERT(len + ret <= PRINTF_BUFFER_SIZE-1, ("xenbus error message too big"));
#if 0
dev_err(&dev->dev, "%s\n", printf_buffer);
#endif
path_buffer = error_path(dev);
if (path_buffer == NULL) {
- printk("xenbus: failed to write error node for %s (%s)\n",
+ printf("xenbus: failed to write error node for %s (%s)\n",
xenbus_get_node(dev), printf_buffer);
goto fail;
}
if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
- printk("xenbus: failed to write error node for %s (%s)\n",
+ printf("xenbus: failed to write error node for %s (%s)\n",
xenbus_get_node(dev), printf_buffer);
goto fail;
}
fail:
if (printf_buffer)
- kfree(printf_buffer);
+ free(printf_buffer, M_DEVBUF);
if (path_buffer)
- kfree(path_buffer);
+ free(path_buffer, M_DEVBUF);
}
-
-void xenbus_dev_error(device_t dev, int err, const char *fmt,
- ...)
+void
+xenbus_dev_error(device_t dev, int err, const char *fmt, ...)
{
va_list ap;
@@ -189,11 +171,9 @@ void xenbus_dev_error(device_t dev, int err, const char *fmt,
_dev_error(dev, err, fmt, ap);
va_end(ap);
}
-EXPORT_SYMBOL(xenbus_dev_error);
-
-void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
- ...)
+void
+xenbus_dev_fatal(device_t dev, int err, const char *fmt, ...)
{
va_list ap;
@@ -203,21 +183,26 @@ void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
xenbus_set_state(dev, XenbusStateClosing);
}
-EXPORT_SYMBOL(xenbus_dev_fatal);
-
-int xenbus_grant_ring(device_t dev, unsigned long ring_mfn)
+int
+xenbus_grant_ring(device_t dev, unsigned long ring_mfn, int *refp)
{
- int err = gnttab_grant_foreign_access(
- xenbus_get_otherend_id(dev), ring_mfn, 0);
- if (err < 0)
- xenbus_dev_fatal(dev, err, "granting access to ring page");
- return err;
-}
-EXPORT_SYMBOL(xenbus_grant_ring);
+ int error;
+ grant_ref_t ref;
+
+ error = gnttab_grant_foreign_access(
+ xenbus_get_otherend_id(dev), ring_mfn, 0, &ref);
+ if (error) {
+ xenbus_dev_fatal(dev, error, "granting access to ring page");
+ return (error);
+ }
+ *refp = ref;
+ return (0);
+}
-int xenbus_alloc_evtchn(device_t dev, int *port)
+int
+xenbus_alloc_evtchn(device_t dev, int *port)
{
struct evtchn_alloc_unbound alloc_unbound;
int err;
@@ -228,16 +213,16 @@ int xenbus_alloc_evtchn(device_t dev, int *port)
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
- if (err)
- xenbus_dev_fatal(dev, err, "allocating event channel");
- else
- *port = alloc_unbound.port;
- return err;
+ if (err) {
+ xenbus_dev_fatal(dev, -err, "allocating event channel");
+ return (-err);
+ }
+ *port = alloc_unbound.port;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_alloc_evtchn);
-
-int xenbus_free_evtchn(device_t dev, int port)
+int
+xenbus_free_evtchn(device_t dev, int port)
{
struct evtchn_close close;
int err;
@@ -245,32 +230,22 @@ int xenbus_free_evtchn(device_t dev, int port)
close.port = port;
err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
- if (err)
- xenbus_dev_error(dev, err, "freeing event channel %d", port);
- return err;
+ if (err) {
+ xenbus_dev_error(dev, -err, "freeing event channel %d", port);
+ return (-err);
+ }
+ return (0);
}
-EXPORT_SYMBOL(xenbus_free_evtchn);
-
-XenbusState xenbus_read_driver_state(const char *path)
+XenbusState
+xenbus_read_driver_state(const char *path)
{
XenbusState result;
+ int error;
- int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
- if (err)
+ error = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
+ if (error)
result = XenbusStateClosed;
- return result;
+ return (result);
}
-EXPORT_SYMBOL(xenbus_read_driver_state);
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_comms.c b/sys/xen/xenbus/xenbus_comms.c
index 90f0ea94f6ab..2f0395517921 100644
--- a/sys/xen/xenbus/xenbus_comms.c
+++ b/sys/xen/xenbus/xenbus_comms.c
@@ -33,217 +33,194 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
-#include <sys/time.h>
-#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/xen_intr.h>
-#include <xen/xenbus/xenbus_comms.h>
-#include <xen/interface/io/xs_wire.h>
+#include <xen/hypervisor.h>
-static int xenbus_irq;
+#include <xen/xen_intr.h>
+#include <xen/evtchn.h>
+#include <xen/interface/io/xs_wire.h>
+#include <xen/xenbus/xenbus_comms.h>
-extern void xenbus_probe(void *);
-extern int xenstored_ready;
-#if 0
-static DECLARE_WORK(probe_work, xenbus_probe, NULL);
-#endif
-int xb_wait;
-extern char *xen_store;
-#define wake_up wakeup
-#define xb_waitq xb_wait
-#define pr_debug(a,b,c)
+static unsigned int xenstore_irq;
-static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
+static inline struct xenstore_domain_interface *
+xenstore_domain_interface(void)
{
- return (struct xenstore_domain_interface *)xen_store;
+
+ return (struct xenstore_domain_interface *)xen_store;
}
static void
-wake_waiting(void * arg __attribute__((unused)))
+xb_intr(void * arg __attribute__((unused)))
{
-#if 0
- if (unlikely(xenstored_ready == 0)) {
- xenstored_ready = 1;
- schedule_work(&probe_work);
- }
-#endif
- wakeup(&xb_wait);
-}
-static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
- return ((prod - cons) <= XENSTORE_RING_SIZE);
+ wakeup(xen_store);
}
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- char *buf, uint32_t *len)
+static int
+xb_check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
- if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
- *len = XENSTORE_RING_SIZE - (prod - cons);
- return buf + MASK_XENSTORE_IDX(prod);
-}
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- const char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
- if ((prod - cons) < *len)
- *len = prod - cons;
- return buf + MASK_XENSTORE_IDX(cons);
+ return ((prod - cons) <= XENSTORE_RING_SIZE);
}
-int xb_write(const void *tdata, unsigned len)
+static void *
+xb_get_output_chunk(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod,
+ char *buf, uint32_t *len)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- const char *data = (const char *)tdata;
-
- while (len != 0) {
- void *dst;
- unsigned int avail;
-
- wait_event_interruptible(&xb_waitq,
- (intf->req_prod - intf->req_cons) !=
- XENSTORE_RING_SIZE);
-
- /* Read indexes, then verify. */
- cons = intf->req_cons;
- prod = intf->req_prod;
- mb();
- if (!check_indexes(cons, prod)) {
- intf->req_cons = intf->req_prod = 0;
- return -EIO;
- }
-
- dst = get_output_chunk(cons, prod, intf->req, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
- mb();
-
- memcpy(dst, data, avail);
- data += avail;
- len -= avail;
-
- /* Other side must not see new header until data is there. */
- wmb();
- intf->req_prod += avail;
- /* This implies mb() before other side sees interrupt. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
-
- return 0;
+ *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
+ if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
+ *len = XENSTORE_RING_SIZE - (prod - cons);
+ return (buf + MASK_XENSTORE_IDX(prod));
}
-#ifdef notyet
-int xb_data_to_read(void)
+static const void *
+xb_get_input_chunk(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod,
+ const char *buf, uint32_t *len)
{
- struct xenstore_domain_interface *intf = xen_store_interface;
- return (intf->rsp_cons != intf->rsp_prod);
-}
-int xb_wait_for_data_to_read(void)
-{
- return wait_event_interruptible(xb_waitq, xb_data_to_read());
+ *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
+ if ((prod - cons) < *len)
+ *len = prod - cons;
+ return (buf + MASK_XENSTORE_IDX(cons));
}
-#endif
-
-int xb_read(void *tdata, unsigned len)
+int
+xb_write(const void *tdata, unsigned len, struct lock_object *lock)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- char *data = (char *)tdata;
-
- while (len != 0) {
- unsigned int avail;
- const char *src;
-
- wait_event_interruptible(&xb_waitq,
- intf->rsp_cons != intf->rsp_prod);
-
- /* Read indexes, then verify. */
- cons = intf->rsp_cons;
- prod = intf->rsp_prod;
- if (!check_indexes(cons, prod)) {
- intf->rsp_cons = intf->rsp_prod = 0;
- return -EIO;
- }
-
- src = get_input_chunk(cons, prod, intf->rsp, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
-
- /* We must read header before we read data. */
- rmb();
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ XENSTORE_RING_IDX cons, prod;
+ const char *data = (const char *)tdata;
+ int error;
+
+ while (len != 0) {
+ void *dst;
+ unsigned int avail;
+
+ while ((intf->req_prod - intf->req_cons)
+ == XENSTORE_RING_SIZE) {
+ error = _sleep(intf,
+ lock,
+ PCATCH, "xbwrite", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
+ }
- memcpy(data, src, avail);
- data += avail;
- len -= avail;
+ /* Read indexes, then verify. */
+ cons = intf->req_cons;
+ prod = intf->req_prod;
+ mb();
+ if (!xb_check_indexes(cons, prod)) {
+ intf->req_cons = intf->req_prod = 0;
+ return (EIO);
+ }
- /* Other side must not see free space until we've copied out */
- mb();
- intf->rsp_cons += avail;
+ dst = xb_get_output_chunk(cons, prod, intf->req, &avail);
+ if (avail == 0)
+ continue;
+ if (avail > len)
+ avail = len;
+ mb();
+
+ memcpy(dst, data, avail);
+ data += avail;
+ len -= avail;
- pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
+ /* Other side must not see new header until data is there. */
+ wmb();
+ intf->req_prod += avail;
- /* Implies mb(): they will see new header. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
+ /* This implies mb() before other side sees interrupt. */
+ notify_remote_via_evtchn(xen_store_evtchn);
+ }
- return 0;
+ return (0);
}
-/* Set up interrupt handler off store event channel. */
-int xb_init_comms(void)
+int
+xb_read(void *tdata, unsigned len, struct lock_object *lock)
{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- int err;
-
- if (intf->rsp_prod != intf->rsp_cons) {
- log(LOG_WARNING, "XENBUS response ring is not quiescent "
- "(%08x:%08x): fixing up\n",
- intf->rsp_cons, intf->rsp_prod);
- intf->rsp_cons = intf->rsp_prod;
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ XENSTORE_RING_IDX cons, prod;
+ char *data = (char *)tdata;
+ int error;
+
+ while (len != 0) {
+ unsigned int avail;
+ const char *src;
+
+ while (intf->rsp_cons == intf->rsp_prod) {
+ error = _sleep(intf, lock,
+ PCATCH, "xbread", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
}
+
+ /* Read indexes, then verify. */
+ cons = intf->rsp_cons;
+ prod = intf->rsp_prod;
+ if (!xb_check_indexes(cons, prod)) {
+ intf->rsp_cons = intf->rsp_prod = 0;
+ return (EIO);
+ }
+
+ src = xb_get_input_chunk(cons, prod, intf->rsp, &avail);
+ if (avail == 0)
+ continue;
+ if (avail > len)
+ avail = len;
- if (xenbus_irq)
- unbind_from_irqhandler(xenbus_irq, &xb_waitq);
+ /* We must read header before we read data. */
+ rmb();
- err = bind_caller_port_to_irqhandler(
- xen_start_info->store_evtchn,
- "xenbus", wake_waiting, NULL, INTR_TYPE_NET, NULL);
- if (err <= 0) {
- log(LOG_WARNING, "XENBUS request irq failed %i\n", err);
- return err;
- }
+ memcpy(data, src, avail);
+ data += avail;
+ len -= avail;
+
+ /* Other side must not see free space until we've copied out */
+ mb();
+ intf->rsp_cons += avail;
- xenbus_irq = err;
+ /* Implies mb(): they will see new header. */
+ notify_remote_via_evtchn(xen_store_evtchn);
+ }
- return 0;
+ return (0);
}
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
+/* Set up interrupt handler off store event channel. */
+int
+xb_init_comms(void)
+{
+ struct xenstore_domain_interface *intf = xenstore_domain_interface();
+ int error;
+
+ if (intf->rsp_prod != intf->rsp_cons) {
+ log(LOG_WARNING, "XENBUS response ring is not quiescent "
+ "(%08x:%08x): fixing up\n",
+ intf->rsp_cons, intf->rsp_prod);
+ intf->rsp_cons = intf->rsp_prod;
+ }
+
+ if (xenstore_irq)
+ unbind_from_irqhandler(xenstore_irq);
+
+ error = bind_caller_port_to_irqhandler(
+ xen_store_evtchn, "xenbus",
+ xb_intr, NULL, INTR_TYPE_NET, &xenstore_irq);
+ if (error) {
+ log(LOG_WARNING, "XENBUS request irq failed %i\n", error);
+ return (error);
+ }
+
+ return (0);
+}
diff --git a/sys/xen/xenbus/xenbus_comms.h b/sys/xen/xenbus/xenbus_comms.h
index 94a57dc58c43..fa4733109d99 100644
--- a/sys/xen/xenbus/xenbus_comms.h
+++ b/sys/xen/xenbus/xenbus_comms.h
@@ -30,123 +30,19 @@
#ifndef _XENBUS_COMMS_H
#define _XENBUS_COMMS_H
+struct sx;
+extern int xen_store_evtchn;
+extern char *xen_store;
+
int xs_init(void);
int xb_init_comms(void);
/* Low level routines. */
-int xb_write(const void *data, unsigned len);
-int xb_read(void *data, unsigned len);
-int xs_input_avail(void);
-extern int xb_waitq;
+int xb_write(const void *data, unsigned len, struct lock_object *);
+int xb_read(void *data, unsigned len, struct lock_object *);
extern int xenbus_running;
-#define __wait_event_interruptible(wchan, condition, ret) \
-do { \
- for (;;) { \
- if (xenbus_running == 0) { \
- break; \
- } \
- if (condition) \
- break; \
- if ((ret = !tsleep(wchan, PWAIT | PCATCH, "waitev", hz/10))) \
- break; \
- } \
-} while (0)
-
-
-#define wait_event_interruptible(wchan, condition) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_event_interruptible(wchan, condition, __ret); \
- __ret; \
-})
-
-
-
-#define DECLARE_MUTEX(lock) struct sema lock
-#define semaphore sema
-#define rw_semaphore sema
-
-#define down sema_wait
-#define up sema_post
-#define down_read sema_wait
-#define up_read sema_post
-#define down_write sema_wait
-#define up_write sema_post
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * XXX
- *
- */
-
-#define GFP_KERNEL 1
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free((void *)(uintptr_t)ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
-#define wake_up wakeup
-#define BUS_ID_SIZE 128
-
-struct xen_bus_type
-{
- char *root;
- unsigned int levels;
- int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
- int (*probe)(const char *type, const char *dir);
- struct xendev_list_head *bus;
- int error;
-#if 0
- struct bus_type bus;
- struct device dev;
-#endif
-};
-
-
-#if 0
-
-void dev_changed(const char *node, struct xen_bus_type *bus);
-
-int
-read_otherend_details(struct xenbus_device *xendev, char *id_node,
- char *path_node);
-#endif
-
char *kasprintf(const char *fmt, ...);
-
-
#endif /* _XENBUS_COMMS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_dev.c b/sys/xen/xenbus/xenbus_dev.c
index 52e0b67cb0ac..ac3f103e1fae 100644
--- a/sys/xen/xenbus/xenbus_dev.c
+++ b/sys/xen/xenbus/xenbus_dev.c
@@ -45,19 +45,10 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <xen/xenbus/xenbusvar.h>
#include <xen/xenbus/xenbus_comms.h>
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define simple_strtoul strtoul
-
struct xenbus_dev_transaction {
LIST_ENTRY(xenbus_dev_transaction) list;
struct xenbus_transaction handle;
@@ -78,62 +69,65 @@ struct xenbus_dev_data {
#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
char read_buffer[PAGE_SIZE];
unsigned int read_cons, read_prod;
- int read_waitq;
};
-#if 0
-static struct proc_dir_entry *xenbus_dev_intf;
-#endif
+
static int
xenbus_dev_read(struct cdev *dev, struct uio *uio, int ioflag)
{
- int i = 0;
+ int error;
struct xenbus_dev_data *u = dev->si_drv1;
- if (wait_event_interruptible(&u->read_waitq,
- u->read_prod != u->read_cons))
- return EINTR;
+ while (u->read_prod == u->read_cons) {
+ error = tsleep(u, PCATCH, "xbdread", hz/10);
+ if (error && error != EWOULDBLOCK)
+ return (error);
+ }
- for (i = 0; i < uio->uio_iov[0].iov_len; i++) {
+ while (uio->uio_resid > 0) {
if (u->read_cons == u->read_prod)
break;
- copyout(&u->read_buffer[MASK_READ_IDX(u->read_cons)], (char *)uio->uio_iov[0].iov_base+i, 1);
+ error = uiomove(&u->read_buffer[MASK_READ_IDX(u->read_cons)],
+ 1, uio);
+ if (error)
+ return (error);
u->read_cons++;
- uio->uio_resid--;
}
- return 0;
+ return (0);
}
-static void queue_reply(struct xenbus_dev_data *u,
- char *data, unsigned int len)
+static void
+queue_reply(struct xenbus_dev_data *u, char *data, unsigned int len)
{
int i;
for (i = 0; i < len; i++, u->read_prod++)
u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
- BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
+ KASSERT((u->read_prod - u->read_cons) <= sizeof(u->read_buffer),
+ ("xenstore reply too big"));
- wakeup(&u->read_waitq);
+ wakeup(u);
}
static int
xenbus_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
{
- int err = 0;
+ int error;
struct xenbus_dev_data *u = dev->si_drv1;
struct xenbus_dev_transaction *trans;
void *reply;
- int len = uio->uio_iov[0].iov_len;
+ int len = uio->uio_resid;
if ((len + u->len) > sizeof(u->u.buffer))
- return EINVAL;
+ return (EINVAL);
- if (copyin(u->u.buffer + u->len, uio->uio_iov[0].iov_base, len) != 0)
- return EFAULT;
+ error = uiomove(u->u.buffer + u->len, len, uio);
+ if (error)
+ return (error);
u->len += len;
if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
- return len;
+ return (0);
switch (u->u.msg.type) {
case XS_TRANSACTION_START:
@@ -147,67 +141,59 @@ xenbus_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
case XS_MKDIR:
case XS_RM:
case XS_SET_PERMS:
- reply = xenbus_dev_request_and_reply(&u->u.msg);
- if (IS_ERR(reply)) {
- err = PTR_ERR(reply);
- } else {
+ error = xenbus_dev_request_and_reply(&u->u.msg, &reply);
+ if (!error) {
if (u->u.msg.type == XS_TRANSACTION_START) {
- trans = kmalloc(sizeof(*trans), GFP_KERNEL);
- trans->handle.id = simple_strtoul(reply, NULL, 0);
+ trans = malloc(sizeof(*trans), M_DEVBUF,
+ M_WAITOK);
+ trans->handle.id = strtoul(reply, NULL, 0);
LIST_INSERT_HEAD(&u->transactions, trans, list);
} else if (u->u.msg.type == XS_TRANSACTION_END) {
- LIST_FOREACH(trans, &u->transactions,
- list)
- if (trans->handle.id ==
- u->u.msg.tx_id)
+ LIST_FOREACH(trans, &u->transactions, list)
+ if (trans->handle.id == u->u.msg.tx_id)
break;
#if 0 /* XXX does this mean the list is empty? */
BUG_ON(&trans->list == &u->transactions);
#endif
LIST_REMOVE(trans, list);
- kfree(trans);
+ free(trans, M_DEVBUF);
}
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
queue_reply(u, (char *)reply, u->u.msg.len);
- kfree(reply);
+ free(reply, M_DEVBUF);
}
break;
default:
- err = EINVAL;
+ error = EINVAL;
break;
}
- if (err == 0) {
+ if (error == 0)
u->len = 0;
- err = len;
- }
- return err;
+ return (error);
}
-static int xenbus_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+static int
+xenbus_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
struct xenbus_dev_data *u;
- if (xen_start_info->store_evtchn == 0)
- return ENOENT;
+ if (xen_store_evtchn == 0)
+ return (ENOENT);
#if 0 /* XXX figure out if equiv needed */
nonseekable_open(inode, filp);
#endif
- u = kmalloc(sizeof(*u), GFP_KERNEL);
- if (u == NULL)
- return ENOMEM;
-
- memset(u, 0, sizeof(*u));
+ u = malloc(sizeof(*u), M_DEVBUF, M_WAITOK|M_ZERO);
LIST_INIT(&u->transactions);
-
dev->si_drv1 = u;
- return 0;
+ return (0);
}
-static int xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+static int
+xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
struct xenbus_dev_data *u = dev->si_drv1;
struct xenbus_dev_transaction *trans, *tmp;
@@ -215,11 +201,11 @@ static int xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thr
LIST_FOREACH_SAFE(trans, &u->transactions, list, tmp) {
xenbus_transaction_end(trans->handle, 1);
LIST_REMOVE(trans, list);
- kfree(trans);
+ free(trans, M_DEVBUF);
}
- kfree(u);
- return 0;
+ free(u, M_DEVBUF);
+ return (0);
}
static struct cdevsw xenbus_dev_cdevsw = {
@@ -234,21 +220,10 @@ static struct cdevsw xenbus_dev_cdevsw = {
static int
xenbus_dev_sysinit(void)
{
- make_dev(&xenbus_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400, "xenbus");
+ make_dev(&xenbus_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400,
+ "xen/xenbus");
- return 0;
+ return (0);
}
-SYSINIT(xenbus_dev_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, xenbus_dev_sysinit, NULL);
-/* SYSINIT NEEDED XXX */
-
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
+SYSINIT(xenbus_dev_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE,
+ xenbus_dev_sysinit, NULL);
diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c
index e57e6e3ef5fc..3d2cb4bb81ca 100644
--- a/sys/xen/xenbus/xenbus_probe.c
+++ b/sys/xen/xenbus/xenbus_probe.c
@@ -88,9 +88,7 @@ kasprintf(const char *fmt, ...)
len = vsnprintf(dummy, 0, fmt, ap);
va_end(ap);
- p = kmalloc(len + 1, GFP_KERNEL);
- if (!p)
- return NULL;
+ p = malloc(len + 1, M_DEVBUF, M_WAITOK);
va_start(ap, fmt);
vsprintf(p, fmt, ap);
va_end(ap);
@@ -187,6 +185,7 @@ xenbus_add_device(device_t dev, const char *bus,
struct xenbus_device_ivars *ivars;
enum xenbus_state state;
char *statepath;
+ int error;
ivars = malloc(sizeof(struct xenbus_device_ivars),
M_DEVBUF, M_ZERO|M_WAITOK);
@@ -217,17 +216,19 @@ xenbus_add_device(device_t dev, const char *bus,
/*
* Find the backend details
*/
- xenbus_gather(XBT_NIL, ivars->xd_node,
+ error = xenbus_gather(XBT_NIL, ivars->xd_node,
"backend-id", "%i", &ivars->xd_otherend_id,
"backend", NULL, &ivars->xd_otherend_path,
NULL);
+ if (error)
+ return (error);
sx_init(&ivars->xd_lock, "xdlock");
ivars->xd_type = strdup(type, M_DEVBUF);
ivars->xd_state = XenbusStateInitialising;
statepath = malloc(strlen(ivars->xd_otherend_path)
- + strlen("/state") + 1, M_DEVBUF, M_NOWAIT);
+ + strlen("/state") + 1, M_DEVBUF, M_WAITOK);
sprintf(statepath, "%s/state", ivars->xd_otherend_path);
ivars->xd_otherend_watch.node = statepath;
@@ -245,10 +246,11 @@ xenbus_enumerate_type(device_t dev, const char *bus, const char *type)
{
char **dir;
unsigned int i, count;
+ int error;
- dir = xenbus_directory(XBT_NIL, bus, type, &count);
- if (IS_ERR(dir))
- return (EINVAL);
+ error = xenbus_directory(XBT_NIL, bus, type, &count, &dir);
+ if (error)
+ return (error);
for (i = 0; i < count; i++)
xenbus_add_device(dev, bus, type, dir[i]);
@@ -262,10 +264,11 @@ xenbus_enumerate_bus(device_t dev, const char *bus)
{
char **dir;
unsigned int i, count;
+ int error;
- dir = xenbus_directory(XBT_NIL, bus, "", &count);
- if (IS_ERR(dir))
- return (EINVAL);
+ error = xenbus_directory(XBT_NIL, bus, "", &count, &dir);
+ if (error)
+ return (error);
for (i = 0; i < count; i++) {
xenbus_enumerate_type(dev, bus, dir[i]);
}
@@ -386,28 +389,90 @@ xenbus_attach(device_t dev)
return (0);
}
-static void
+static int
xenbus_suspend(device_t dev)
{
+ int error;
+
DPRINTK("");
- panic("implement me");
-#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
-#endif
+
+ error = bus_generic_suspend(dev);
+ if (error)
+ return (error);
+
xs_suspend();
+
+ return (0);
}
-static void
+static int
xenbus_resume(device_t dev)
{
+ device_t *kids;
+ struct xenbus_device_ivars *ivars;
+ int i, count, error;
+ char *statepath;
+
xb_init_comms();
xs_resume();
- panic("implement me");
+
+ /*
+ * We must re-examine each device and find the new path for
+ * its backend.
+ */
+ if (device_get_children(dev, &kids, &count) == 0) {
+ for (i = 0; i < count; i++) {
+ if (device_get_state(kids[i]) == DS_NOTPRESENT)
+ continue;
+
+ ivars = device_get_ivars(kids[i]);
+
+ unregister_xenbus_watch(
+ &ivars->xd_otherend_watch);
+ ivars->xd_state = XenbusStateInitialising;
+
+ /*
+ * Find the new backend details and
+ * re-register our watch.
+ */
+ free(ivars->xd_otherend_path, M_DEVBUF);
+ error = xenbus_gather(XBT_NIL, ivars->xd_node,
+ "backend-id", "%i", &ivars->xd_otherend_id,
+ "backend", NULL, &ivars->xd_otherend_path,
+ NULL);
+ if (error)
+ return (error);
+
+ DEVICE_RESUME(kids[i]);
+
+ statepath = malloc(strlen(ivars->xd_otherend_path)
+ + strlen("/state") + 1, M_DEVBUF, M_WAITOK);
+ sprintf(statepath, "%s/state", ivars->xd_otherend_path);
+
+ free(ivars->xd_otherend_watch.node, M_DEVBUF);
+ ivars->xd_otherend_watch.node = statepath;
+ register_xenbus_watch(
+ &ivars->xd_otherend_watch);
+
#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
-#endif
+ /*
+ * Can't do this yet since we are running in
+ * the xenwatch thread and if we sleep here,
+ * we will stop delivering watch notifications
+ * and the device will never come back online.
+ */
+ sx_xlock(&ivars->xd_lock);
+ while (ivars->xd_state != XenbusStateClosed
+ && ivars->xd_state != XenbusStateConnected)
+ sx_sleep(&ivars->xd_state, &ivars->xd_lock,
+ 0, "xdresume", 0);
+ sx_xunlock(&ivars->xd_lock);
+#endif
+ }
+ free(kids, M_TEMP);
+ }
+
+ return (0);
}
static int
@@ -433,9 +498,11 @@ xenbus_read_ivar(device_t dev, device_t child, int index,
case XENBUS_IVAR_NODE:
*result = (uintptr_t) ivars->xd_node;
return (0);
+
case XENBUS_IVAR_TYPE:
*result = (uintptr_t) ivars->xd_type;
return (0);
+
case XENBUS_IVAR_STATE:
*result = (uintptr_t) ivars->xd_state;
return (0);
@@ -468,8 +535,8 @@ xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
goto out;
error = xenbus_scanf(XBT_NIL, ivars->xd_node, "state",
- "%d", &currstate);
- if (error < 0)
+ NULL, "%d", &currstate);
+ if (error)
goto out;
error = xenbus_printf(XBT_NIL, ivars->xd_node, "state",
@@ -494,15 +561,14 @@ xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
*/
return (EINVAL);
}
+
return (ENOENT);
}
SYSCTL_DECL(_dev);
SYSCTL_NODE(_dev, OID_AUTO, xen, CTLFLAG_RD, NULL, "Xen");
-#if 0
SYSCTL_INT(_dev_xen, OID_AUTO, xsd_port, CTLFLAG_RD, &xen_store_evtchn, 0, "");
SYSCTL_ULONG(_dev_xen, OID_AUTO, xsd_kva, CTLFLAG_RD, (u_long *) &xen_store, 0, "");
-#endif
static device_method_t xenbus_methods[] = {
/* Device interface */
diff --git a/sys/xen/xenbus/xenbus_probe_backend.c b/sys/xen/xenbus/xenbus_probe_backend.c
index af83fe6fee83..20cc49f82293 100644
--- a/sys/xen/xenbus/xenbus_probe_backend.c
+++ b/sys/xen/xenbus/xenbus_probe_backend.c
@@ -57,10 +57,11 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
+#include <xen/hypervisor.h>
+#include <machine/xen/xenbus.h>
#include <machine/stdarg.h>
+#include <xen/evtchn.h>
#include <xen/xenbus/xenbus_comms.h>
#define BUG_ON PANIC_IF
diff --git a/sys/xen/xenbus/xenbus_xs.c b/sys/xen/xenbus/xenbus_xs.c
index 332a509f1f0f..9e0f7798fcf7 100644
--- a/sys/xen/xenbus/xenbus_xs.c
+++ b/sys/xen/xenbus/xenbus_xs.c
@@ -33,91 +33,77 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/unistd.h>
-#include <sys/errno.h>
#include <sys/uio.h>
#include <sys/kernel.h>
-#include <sys/time.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sx.h>
-#include <sys/sema.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
-#include <sys/libkern.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/kthread.h>
+#include <sys/unistd.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
+#include <xen/hypervisor.h>
#include <machine/stdarg.h>
#include <xen/xenbus/xenbusvar.h>
#include <xen/xenbus/xenbus_comms.h>
-static int xs_process_msg(enum xsd_sockmsg_type *type);
+#include <xen/interface/hvm/params.h>
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+static int xs_process_msg(enum xsd_sockmsg_type *type);
-#define streq(a, b) (strcmp((a), (b)) == 0)
int xenwatch_running = 0;
int xenbus_running = 0;
-
-struct kvec {
- const void *iov_base;
- size_t iov_len;
-};
+int xen_store_evtchn;
struct xs_stored_msg {
- TAILQ_ENTRY(xs_stored_msg) list;
-
- struct xsd_sockmsg hdr;
-
- union {
- /* Queued replies. */
- struct {
- char *body;
- } reply;
-
- /* Queued watch events. */
- struct {
- struct xenbus_watch *handle;
- char **vec;
- unsigned int vec_size;
- } watch;
- } u;
+ TAILQ_ENTRY(xs_stored_msg) list;
+
+ struct xsd_sockmsg hdr;
+
+ union {
+ /* Queued replies. */
+ struct {
+ char *body;
+ } reply;
+
+ /* Queued watch events. */
+ struct {
+ struct xenbus_watch *handle;
+ char **vec;
+ unsigned int vec_size;
+ } watch;
+ } u;
};
struct xs_handle {
- /* A list of replies. Currently only one will ever be outstanding. */
- TAILQ_HEAD(xs_handle_list, xs_stored_msg) reply_list;
- struct mtx reply_lock;
- int reply_waitq;
+ /* A list of replies. Currently only one will ever be outstanding. */
+ TAILQ_HEAD(xs_handle_list, xs_stored_msg) reply_list;
+ struct mtx reply_lock;
+ int reply_waitq;
- /* One request at a time. */
- struct sx request_mutex;
+ /* One request at a time. */
+ struct sx request_mutex;
- /* Protect transactions against save/restore. */
- struct sx suspend_mutex;
+ /* Protect transactions against save/restore. */
+ struct sx suspend_mutex;
};
static struct xs_handle xs_state;
/* List of registered watches, and a lock to protect it. */
static LIST_HEAD(watch_list_head, xenbus_watch) watches;
-static DEFINE_SPINLOCK(watches_lock);
+static struct mtx watches_lock;
/* List of pending watch callback events, and a lock to protect it. */
static TAILQ_HEAD(event_list_head, xs_stored_msg) watch_events;
-static DEFINE_SPINLOCK(watch_events_lock);
+static struct mtx watch_events_lock;
+
/*
* Details of the xenwatch callback kernel thread. The thread waits on the
* watch_events_waitq for work to do (queued on watch_events list). When it
@@ -128,831 +114,814 @@ static pid_t xenwatch_pid;
struct sx xenwatch_mutex;
static int watch_events_waitq;
-static int get_error(const char *errorstring)
+#define xsd_error_count (sizeof(xsd_errors) / sizeof(xsd_errors[0]))
+
+static int
+xs_get_error(const char *errorstring)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
- if (i == ARRAY_SIZE(xsd_errors) - 1) {
- log(LOG_WARNING, "XENBUS xen store gave: unknown error %s",
- errorstring);
- return EINVAL;
- }
- }
- return xsd_errors[i].errnum;
+ for (i = 0; i < xsd_error_count; i++) {
+ if (!strcmp(errorstring, xsd_errors[i].errstring))
+ return (xsd_errors[i].errnum);
+ }
+ log(LOG_WARNING, "XENBUS xen store gave: unknown error %s",
+ errorstring);
+ return (EINVAL);
}
-extern void idle_block(void);
extern void kdb_backtrace(void);
-static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
+static int
+xs_read_reply(enum xsd_sockmsg_type *type, unsigned int *len, void **result)
{
- struct xs_stored_msg *msg;
- char *body;
- int i, err;
- enum xsd_sockmsg_type itype = *type;
-
- printf("read_reply ");
- if (xenbus_running == 0) {
- /*
- * Give other domain time to run :-/
- */
- for (i = 0; i < 1000000 && (xenbus_running == 0); i++) {
- err = xs_process_msg(type);
-
- if ((err == 0)
- && (*type != XS_WATCH_EVENT))
- break;
-
- HYPERVISOR_yield();
+ struct xs_stored_msg *msg;
+ char *body;
+ int error;
+
+ mtx_lock(&xs_state.reply_lock);
+
+ while (TAILQ_EMPTY(&xs_state.reply_list)) {
+ while (TAILQ_EMPTY(&xs_state.reply_list)) {
+ error = mtx_sleep(&xs_state.reply_waitq,
+ &xs_state.reply_lock,
+ PCATCH, "xswait", hz/10);
+ if (error && error != EWOULDBLOCK) {
+ mtx_unlock(&xs_state.reply_lock);
+ return (error);
}
- if (list_empty(&xs_state.reply_list)) {
- printf("giving up and returning an error type=%d\n",
- *type);
- kdb_backtrace();
- return (ERR_PTR(-1));
- }
+ }
+
}
- mtx_lock(&xs_state.reply_lock);
- if (xenbus_running) {
- while (list_empty(&xs_state.reply_list)) {
- mtx_unlock(&xs_state.reply_lock);
- wait_event_interruptible(&xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
-
- mtx_lock(&xs_state.reply_lock);
- }
- }
- msg = TAILQ_FIRST(&xs_state.reply_list);
- list_del(&xs_state.reply_list, msg);
+ msg = TAILQ_FIRST(&xs_state.reply_list);
+ TAILQ_REMOVE(&xs_state.reply_list, msg, list);
- mtx_unlock(&xs_state.reply_lock);
+ mtx_unlock(&xs_state.reply_lock);
- printf("itype=%d htype=%d ", itype, msg->hdr.type);
- *type = msg->hdr.type;
- if (len)
- *len = msg->hdr.len;
- body = msg->u.reply.body;
+ *type = msg->hdr.type;
+ if (len)
+ *len = msg->hdr.len;
+ body = msg->u.reply.body;
- kfree(msg);
- if (len)
- printf("len=%d\n", *len);
- else
- printf("len=NULL\n");
- return body;
+ free(msg, M_DEVBUF);
+ *result = body;
+ return (0);
}
#if 0
/* Emergency write. UNUSED*/
void xenbus_debug_write(const char *str, unsigned int count)
{
- struct xsd_sockmsg msg = { 0 };
+ struct xsd_sockmsg msg = { 0 };
- msg.type = XS_DEBUG;
- msg.len = sizeof("print") + count + 1;
+ msg.type = XS_DEBUG;
+ msg.len = sizeof("print") + count + 1;
- sx_xlock(&xs_state.request_mutex);
- xb_write(&msg, sizeof(msg));
- xb_write("print", sizeof("print"));
- xb_write(str, count);
- xb_write("", 1);
- sx_xunlock(&xs_state.request_mutex);
+ sx_xlock(&xs_state.request_mutex);
+ xb_write(&msg, sizeof(msg));
+ xb_write("print", sizeof("print"));
+ xb_write(str, count);
+ xb_write("", 1);
+ sx_xunlock(&xs_state.request_mutex);
}
#endif
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
+
+int
+xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void **result)
{
- void *ret;
- struct xsd_sockmsg req_msg = *msg;
- int err;
+ struct xsd_sockmsg req_msg = *msg;
+ int error;
- if (req_msg.type == XS_TRANSACTION_START)
- sx_slock(&xs_state.suspend_mutex);
+ if (req_msg.type == XS_TRANSACTION_START)
+ sx_slock(&xs_state.suspend_mutex);
- sx_xlock(&xs_state.request_mutex);
+ sx_xlock(&xs_state.request_mutex);
- err = xb_write(msg, sizeof(*msg) + msg->len);
- if (err) {
- msg->type = XS_ERROR;
- ret = ERR_PTR(err);
- } else {
- ret = read_reply(&msg->type, &msg->len);
- }
+ error = xb_write(msg, sizeof(*msg) + msg->len, &xs_state.request_mutex.lock_object);
+ if (error) {
+ msg->type = XS_ERROR;
+ } else {
+ error = xs_read_reply(&msg->type, &msg->len, result);
+ }
- sx_xunlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.request_mutex);
- if ((msg->type == XS_TRANSACTION_END) ||
- ((req_msg.type == XS_TRANSACTION_START) &&
- (msg->type == XS_ERROR)))
- sx_sunlock(&xs_state.suspend_mutex);
+ if ((msg->type == XS_TRANSACTION_END) ||
+ ((req_msg.type == XS_TRANSACTION_START) &&
+ (msg->type == XS_ERROR)))
+ sx_sunlock(&xs_state.suspend_mutex);
- return ret;
+ return (error);
}
-static int xenwatch_inline;
-
-/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
+/*
+ * Send message to xs. The reply is returned in *result and should be
+ * fred with free(*result, M_DEVBUF). Return zero on success or an
+ * error code on failure.
+ */
+static int
+xs_talkv(struct xenbus_transaction t, enum xsd_sockmsg_type type,
+ const struct iovec *iovec, unsigned int num_vecs,
+ unsigned int *len, void **result)
{
- struct xsd_sockmsg msg;
- void *ret = NULL;
- unsigned int i;
- int err;
-
- msg.tx_id = t.id;
- msg.req_id = 0;
- msg.type = type;
- msg.len = 0;
- for (i = 0; i < num_vecs; i++)
- msg.len += iovec[i].iov_len;
-
- printf("xs_talkv ");
-
- sx_xlock(&xs_state.request_mutex);
-
- err = xb_write(&msg, sizeof(msg));
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
-
- for (i = 0; i < num_vecs; i++) {
- err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
+ struct xsd_sockmsg msg;
+ void *ret = NULL;
+ unsigned int i;
+ int error;
+
+ msg.tx_id = t.id;
+ msg.req_id = 0;
+ msg.type = type;
+ msg.len = 0;
+ for (i = 0; i < num_vecs; i++)
+ msg.len += iovec[i].iov_len;
+
+ sx_xlock(&xs_state.request_mutex);
+
+ error = xb_write(&msg, sizeof(msg), &xs_state.request_mutex.lock_object);
+ if (error) {
+ sx_xunlock(&xs_state.request_mutex);
+ printf("xs_talkv failed %d\n", error);
+ return (error);
+ }
+
+ for (i = 0; i < num_vecs; i++) {
+ error = xb_write(iovec[i].iov_base, iovec[i].iov_len, &xs_state.request_mutex.lock_object);
+ if (error) {
+ sx_xunlock(&xs_state.request_mutex);
+ printf("xs_talkv failed %d\n", error);
+ return (error);
}
+ }
- ret = read_reply(&msg.type, len);
+ error = xs_read_reply(&msg.type, len, &ret);
- sx_xunlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.request_mutex);
- if (IS_ERR(ret))
- return ret;
+ if (error)
+ return (error);
- if (msg.type == XS_ERROR) {
- err = get_error(ret);
- kfree(ret);
- return ERR_PTR(-err);
- }
+ if (msg.type == XS_ERROR) {
+ error = xs_get_error(ret);
+ free(ret, M_DEVBUF);
+ return (error);
+ }
- if ((xenwatch_running == 0) && (xenwatch_inline == 0)) {
- xenwatch_inline = 1;
- while (!TAILQ_EMPTY(&watch_events)
- && xenwatch_running == 0) {
+#if 0
+ if ((xenwatch_running == 0) && (xenwatch_inline == 0)) {
+ xenwatch_inline = 1;
+ while (!TAILQ_EMPTY(&watch_events)
+ && xenwatch_running == 0) {
- struct xs_stored_msg *wmsg = TAILQ_FIRST(&watch_events);
- list_del(&watch_events, wmsg);
- printf("handling %p ...", wmsg->u.watch.handle->callback);
+ struct xs_stored_msg *wmsg = TAILQ_FIRST(&watch_events);
+ TAILQ_REMOVE(&watch_events, wmsg, list);
- wmsg->u.watch.handle->callback(
- wmsg->u.watch.handle,
- (const char **)wmsg->u.watch.vec,
- wmsg->u.watch.vec_size);
- printf("... %p done\n", wmsg->u.watch.handle->callback);
- kfree(wmsg->u.watch.vec);
- kfree(wmsg);
- }
- xenwatch_inline = 0;
+ wmsg->u.watch.handle->callback(
+ wmsg->u.watch.handle,
+ (const char **)wmsg->u.watch.vec,
+ wmsg->u.watch.vec_size);
+ free(wmsg->u.watch.vec, M_DEVBUF);
+ free(wmsg, M_DEVBUF);
}
- BUG_ON(msg.type != type);
+ xenwatch_inline = 0;
+ }
+#endif
+ KASSERT(msg.type == type, ("bad xenstore message type"));
- return ret;
+ if (result)
+ *result = ret;
+ else
+ free(ret, M_DEVBUF);
+
+ return (0);
}
/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const char *string,
- unsigned int *len)
+static int
+xs_single(struct xenbus_transaction t, enum xsd_sockmsg_type type,
+ const char *string, unsigned int *len, void **result)
{
- struct kvec iovec;
+ struct iovec iovec;
- printf("xs_single %s ", string);
- iovec.iov_base = (const void *)string;
- iovec.iov_len = strlen(string) + 1;
- return xs_talkv(t, type, &iovec, 1, len);
-}
+ iovec.iov_base = (void *)(uintptr_t) string;
+ iovec.iov_len = strlen(string) + 1;
-/* Many commands only need an ack, don't care what it says. */
-static int xs_error(char *reply)
-{
- if (IS_ERR(reply))
- return PTR_ERR(reply);
- kfree(reply);
- return 0;
+ return (xs_talkv(t, type, &iovec, 1, len, result));
}
-static unsigned int count_strings(const char *strings, unsigned int len)
+static unsigned int
+count_strings(const char *strings, unsigned int len)
{
- unsigned int num;
- const char *p;
+ unsigned int num;
+ const char *p;
- for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
- num++;
+ for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
+ num++;
- return num;
+ return num;
}
/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
-static char *join(const char *dir, const char *name)
+static char *
+join(const char *dir, const char *name)
{
- char *buffer;
+ char *buffer;
- buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
- GFP_KERNEL);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
+ buffer = malloc(strlen(dir) + strlen("/") + strlen(name) + 1,
+ M_DEVBUF, M_WAITOK);
- strcpy(buffer, dir);
- if (!streq(name, "")) {
- strcat(buffer, "/");
- strcat(buffer, name);
- }
+ strcpy(buffer, dir);
+ if (strcmp(name, "")) {
+ strcat(buffer, "/");
+ strcat(buffer, name);
+ }
- return buffer;
+ return (buffer);
}
-static char **split(char *strings, unsigned int len, unsigned int *num)
+static char **
+split(char *strings, unsigned int len, unsigned int *num)
{
- char *p, **ret;
+ char *p, **ret;
- /* Count the strings. */
- *num = count_strings(strings, len) + 1;
+ /* Count the strings. */
+ *num = count_strings(strings, len) + 1;
- /* Transfer to one big alloc for easy freeing. */
- ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
- if (!ret) {
- kfree(strings);
- return ERR_PTR(-ENOMEM);
- }
- memcpy(&ret[*num], strings, len);
- kfree(strings);
+ /* Transfer to one big alloc for easy freeing. */
+ ret = malloc(*num * sizeof(char *) + len, M_DEVBUF, M_WAITOK);
+ memcpy(&ret[*num], strings, len);
+ free(strings, M_DEVBUF);
- strings = (char *)&ret[*num];
- for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
- ret[(*num)++] = p;
+ strings = (char *)&ret[*num];
+ for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
+ ret[(*num)++] = p;
- ret[*num] = strings + len;
+ ret[*num] = strings + len;
- return ret;
+ return ret;
}
-char **xenbus_directory(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *num)
+/*
+ * Return the contents of a directory in *result which should be freed
+ * with free(*result, M_DEVBUF).
+ */
+int
+xenbus_directory(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *num, char ***result)
{
- char *strings, *path;
- unsigned int len = 0;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (char **)path;
+ char *strings, *path;
+ unsigned int len = 0;
+ int error;
- strings = xs_single(t, XS_DIRECTORY, path, &len);
- kfree(path);
- if (IS_ERR(strings))
- return (char **)strings;
+ path = join(dir, node);
+ error = xs_single(t, XS_DIRECTORY, path, &len, (void **) &strings);
+ free(path, M_DEVBUF);
+ if (error)
+ return (error);
- return split(strings, len, num);
+ *result = split(strings, len, num);
+ return (0);
}
-EXPORT_SYMBOL(xenbus_directory);
-/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction t,
- const char *dir, const char *node)
+/*
+ * Check if a path exists. Return 1 if it does.
+ */
+int
+xenbus_exists(struct xenbus_transaction t, const char *dir, const char *node)
{
- char **d;
- int dir_n;
+ char **d;
+ int error, dir_n;
- d = xenbus_directory(t, dir, node, &dir_n);
- if (IS_ERR(d))
- return 0;
- kfree(d);
- return 1;
+ error = xenbus_directory(t, dir, node, &dir_n, &d);
+ if (error)
+ return (0);
+ free(d, M_DEVBUF);
+ return (1);
}
-EXPORT_SYMBOL(xenbus_exists);
-/* Get the value of a single file.
- * Returns a kmalloced value: call free() on it after use.
- * len indicates length in bytes.
+/*
+ * Get the value of a single file. Returns the contents in *result
+ * which should be freed with free(*result, M_DEVBUF) after use.
+ * The length of the value in bytes is returned in *len.
*/
-void *xenbus_read(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *len)
+int
+xenbus_read(struct xenbus_transaction t, const char *dir, const char *node,
+ unsigned int *len, void **result)
{
- char *path;
- void *ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (void *)path;
+ char *path;
+ void *ret;
+ int error;
- printf("xs_read ");
- ret = xs_single(t, XS_READ, path, len);
- kfree(path);
- return ret;
+ path = join(dir, node);
+ error = xs_single(t, XS_READ, path, len, &ret);
+ free(path, M_DEVBUF);
+ if (error)
+ return (error);
+ *result = ret;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_read);
-/* Write the value of a single file.
- * Returns -err on failure.
+/*
+ * Write the value of a single file. Returns error on failure.
*/
-int xenbus_write(struct xenbus_transaction t,
- const char *dir, const char *node, const char *string)
+int
+xenbus_write(struct xenbus_transaction t, const char *dir, const char *node,
+ const char *string)
{
- char *path;
- struct kvec iovec[2];
- int ret;
+ char *path;
+ struct iovec iovec[2];
+ int error;
+
+ path = join(dir, node);
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ iovec[0].iov_base = (void *)(uintptr_t) path;
+ iovec[0].iov_len = strlen(path) + 1;
+ iovec[1].iov_base = (void *)(uintptr_t) string;
+ iovec[1].iov_len = strlen(string);
- iovec[0].iov_base = path;
- iovec[0].iov_len = strlen(path) + 1;
- iovec[1].iov_base = string;
- iovec[1].iov_len = strlen(string);
+ error = xs_talkv(t, XS_WRITE, iovec, 2, NULL, NULL);
+ free(path, M_DEVBUF);
- printf("xenbus_write dir=%s val=%s ", dir, string);
- ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
- kfree(path);
- return ret;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_write);
-/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction t,
- const char *dir, const char *node)
+/*
+ * Create a new directory.
+ */
+int
+xenbus_mkdir(struct xenbus_transaction t, const char *dir, const char *node)
{
- char *path;
- int ret;
+ char *path;
+ int ret;
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ path = join(dir, node);
+ ret = xs_single(t, XS_MKDIR, path, NULL, NULL);
+ free(path, M_DEVBUF);
- ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
- kfree(path);
- return ret;
+ return (ret);
}
-EXPORT_SYMBOL(xenbus_mkdir);
-/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
+/*
+ * Destroy a file or directory (directories must be empty).
+ */
+int
+xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
{
- char *path;
- int ret;
+ char *path;
+ int ret;
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
+ path = join(dir, node);
+ ret = xs_single(t, XS_RM, path, NULL, NULL);
+ free(path, M_DEVBUF);
- ret = xs_error(xs_single(t, XS_RM, path, NULL));
- kfree(path);
- return ret;
+ return (ret);
}
-EXPORT_SYMBOL(xenbus_rm);
-/* Start a transaction: changes by others will not be seen during this
+/*
+ * Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
*/
-int xenbus_transaction_start(struct xenbus_transaction *t)
+int
+xenbus_transaction_start(struct xenbus_transaction *t)
{
- char *id_str;
+ char *id_str;
+ int error;
- sx_slock(&xs_state.suspend_mutex);
- id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
- if (IS_ERR(id_str)) {
- sx_sunlock(&xs_state.suspend_mutex);
- return PTR_ERR(id_str);
- }
+ sx_slock(&xs_state.suspend_mutex);
+ error = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL,
+ (void **) &id_str);
+ if (error) {
+ sx_sunlock(&xs_state.suspend_mutex);
+ return (error);
+ }
- t->id = simple_strtoul(id_str, NULL, 0);
- kfree(id_str);
+ t->id = strtoul(id_str, NULL, 0);
+ free(id_str, M_DEVBUF);
- return 0;
+ return (0);
}
-EXPORT_SYMBOL(xenbus_transaction_start);
-/* End a transaction.
- * If abandon is true, transaction is discarded instead of committed.
+/*
+ * End a transaction. If abandon is true, transaction is discarded
+ * instead of committed.
*/
int xenbus_transaction_end(struct xenbus_transaction t, int abort)
{
- char abortstr[2];
- int err;
+ char abortstr[2];
+ int error;
- if (abort)
- strcpy(abortstr, "F");
- else
- strcpy(abortstr, "T");
+ if (abort)
+ strcpy(abortstr, "F");
+ else
+ strcpy(abortstr, "T");
- printf("xenbus_transaction_end ");
- err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
+ error = xs_single(t, XS_TRANSACTION_END, abortstr, NULL, NULL);
- sx_sunlock(&xs_state.suspend_mutex);
+ sx_sunlock(&xs_state.suspend_mutex);
- return err;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_transaction_end);
-/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
+/* Single read and scanf: returns zero or errno. */
+int
+xenbus_scanf(struct xenbus_transaction t,
+ const char *dir, const char *node, int *scancountp, const char *fmt, ...)
{
- va_list ap;
- int ret;
- char *val;
-
- val = xenbus_read(t, dir, node, NULL);
- if (IS_ERR(val))
- return PTR_ERR(val);
-
- va_start(ap, fmt);
- ret = vsscanf(val, fmt, ap);
- va_end(ap);
- kfree(val);
- /* Distinctive errno. */
- if (ret == 0)
- return -ERANGE;
- return ret;
-}
-EXPORT_SYMBOL(xenbus_scanf);
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
+ va_list ap;
+ int error, ns;
+ char *val;
+
+ error = xenbus_read(t, dir, node, NULL, (void **) &val);
+ if (error)
+ return (error);
+
+ va_start(ap, fmt);
+ ns = vsscanf(val, fmt, ap);
+ va_end(ap);
+ free(val, M_DEVBUF);
+ /* Distinctive errno. */
+ if (ns == 0)
+ return (ERANGE);
+ if (scancountp)
+ *scancountp = ns;
+ return (0);
+}
+
+/* Single printf and write: returns zero or errno. */
+int
+xenbus_printf(struct xenbus_transaction t,
+ const char *dir, const char *node, const char *fmt, ...)
{
- va_list ap;
- int ret;
+ va_list ap;
+ int error, ret;
#define PRINTF_BUFFER_SIZE 4096
- char *printf_buffer;
+ char *printf_buffer;
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- return -ENOMEM;
+ printf_buffer = malloc(PRINTF_BUFFER_SIZE, M_DEVBUF, M_WAITOK);
- va_start(ap, fmt);
- ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
- va_end(ap);
+ va_start(ap, fmt);
+ ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
+ va_end(ap);
- BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
- ret = xenbus_write(t, dir, node, printf_buffer);
+ KASSERT(ret <= PRINTF_BUFFER_SIZE-1, ("xenbus_printf: message too large"));
+ error = xenbus_write(t, dir, node, printf_buffer);
- kfree(printf_buffer);
+ free(printf_buffer, M_DEVBUF);
- return ret;
+ return (error);
}
-EXPORT_SYMBOL(xenbus_printf);
/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
+int
+xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
{
- va_list ap;
- const char *name;
- int i, ret = 0;
+ va_list ap;
+ const char *name;
+ int error, i;
- for (i = 0; i < 10000; i++)
- HYPERVISOR_yield();
+ for (i = 0; i < 10000; i++)
+ HYPERVISOR_yield();
- printf("gather ");
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- p = xenbus_read(t, dir, name, NULL);
- if (IS_ERR(p)) {
- ret = PTR_ERR(p);
- break;
- }
- printf(" %s ", p);
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = -EINVAL;
- kfree(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- printf("\n");
- return ret;
-}
-EXPORT_SYMBOL(xenbus_gather);
-
-static int xs_watch(const char *path, const char *token)
+ va_start(ap, dir);
+ error = 0;
+ while (error == 0 && (name = va_arg(ap, char *)) != NULL) {
+ const char *fmt = va_arg(ap, char *);
+ void *result = va_arg(ap, void *);
+ char *p;
+
+ error = xenbus_read(t, dir, name, NULL, (void **) &p);
+ if (error)
+ break;
+
+ if (fmt) {
+ if (sscanf(p, fmt, result) == 0)
+ error = EINVAL;
+ free(p, M_DEVBUF);
+ } else
+ *(char **)result = p;
+ }
+ va_end(ap);
+
+ return (error);
+}
+
+static int
+xs_watch(const char *path, const char *token)
{
- struct kvec iov[2];
+ struct iovec iov[2];
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
+ iov[0].iov_base = (void *)(uintptr_t) path;
+ iov[0].iov_len = strlen(path) + 1;
+ iov[1].iov_base = (void *)(uintptr_t) token;
+ iov[1].iov_len = strlen(token) + 1;
- return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
- ARRAY_SIZE(iov), NULL));
+ return (xs_talkv(XBT_NIL, XS_WATCH, iov, 2, NULL, NULL));
}
-static int xs_unwatch(const char *path, const char *token)
+static int
+xs_unwatch(const char *path, const char *token)
{
- struct kvec iov[2];
+ struct iovec iov[2];
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
+ iov[0].iov_base = (void *)(uintptr_t) path;
+ iov[0].iov_len = strlen(path) + 1;
+ iov[1].iov_base = (void *)(uintptr_t) token;
+ iov[1].iov_len = strlen(token) + 1;
- return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
- ARRAY_SIZE(iov), NULL));
+ return (xs_talkv(XBT_NIL, XS_UNWATCH, iov, 2, NULL, NULL));
}
-static struct xenbus_watch *find_watch(const char *token)
+static struct xenbus_watch *
+find_watch(const char *token)
{
- struct xenbus_watch *i, *cmp;
+ struct xenbus_watch *i, *cmp;
- cmp = (void *)simple_strtoul(token, NULL, 16);
+ cmp = (void *)strtoul(token, NULL, 16);
- LIST_FOREACH(i, &watches, list)
- if (i == cmp)
- return i;
+ LIST_FOREACH(i, &watches, list)
+ if (i == cmp)
+ return (i);
- return NULL;
+ return (NULL);
}
/* Register callback to watch this node. */
-int register_xenbus_watch(struct xenbus_watch *watch)
+int
+register_xenbus_watch(struct xenbus_watch *watch)
{
- /* Pointer in ascii is the token. */
- char token[sizeof(watch) * 2 + 1];
- int err;
+ /* Pointer in ascii is the token. */
+ char token[sizeof(watch) * 2 + 1];
+ int error;
- sprintf(token, "%lX", (long)watch);
+ sprintf(token, "%lX", (long)watch);
- sx_slock(&xs_state.suspend_mutex);
+ sx_slock(&xs_state.suspend_mutex);
- mtx_lock(&watches_lock);
- BUG_ON(find_watch(token) != NULL);
- LIST_INSERT_HEAD(&watches, watch, list);
- mtx_unlock(&watches_lock);
+ mtx_lock(&watches_lock);
+ KASSERT(find_watch(token) == NULL, ("watch already registered"));
+ LIST_INSERT_HEAD(&watches, watch, list);
+ mtx_unlock(&watches_lock);
- err = xs_watch(watch->node, token);
+ error = xs_watch(watch->node, token);
- /* Ignore errors due to multiple registration. */
- if ((err != 0) && (err != -EEXIST)) {
- mtx_lock(&watches_lock);
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
- }
+ /* Ignore errors due to multiple registration. */
+ if (error == EEXIST) {
+ mtx_lock(&watches_lock);
+ LIST_REMOVE(watch, list);
+ mtx_unlock(&watches_lock);
+ }
- sx_sunlock(&xs_state.suspend_mutex);
+ sx_sunlock(&xs_state.suspend_mutex);
- return err;
+ return (error);
}
-EXPORT_SYMBOL(register_xenbus_watch);
-void unregister_xenbus_watch(struct xenbus_watch *watch)
+void
+unregister_xenbus_watch(struct xenbus_watch *watch)
{
- struct xs_stored_msg *msg, *tmp;
- char token[sizeof(watch) * 2 + 1];
- int err;
+ struct xs_stored_msg *msg, *tmp;
+ char token[sizeof(watch) * 2 + 1];
+ int error;
- sprintf(token, "%lX", (long)watch);
+ sprintf(token, "%lX", (long)watch);
- sx_slock(&xs_state.suspend_mutex);
-
- mtx_lock(&watches_lock);
- BUG_ON(!find_watch(token));
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
+ sx_slock(&xs_state.suspend_mutex);
+
+ mtx_lock(&watches_lock);
+ KASSERT(find_watch(token), ("watch not registered"));
+ LIST_REMOVE(watch, list);
+ mtx_unlock(&watches_lock);
+
+ error = xs_unwatch(watch->node, token);
+ if (error)
+ log(LOG_WARNING, "XENBUS Failed to release watch %s: %i\n",
+ watch->node, error);
+
+ sx_sunlock(&xs_state.suspend_mutex);
+
+ /* Cancel pending watch events. */
+ mtx_lock(&watch_events_lock);
+ TAILQ_FOREACH_SAFE(msg, &watch_events, list, tmp) {
+ if (msg->u.watch.handle != watch)
+ continue;
+ TAILQ_REMOVE(&watch_events, msg, list);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
+ }
+ mtx_unlock(&watch_events_lock);
+
+ /* Flush any currently-executing callback, unless we are it. :-) */
+ if (curproc->p_pid != xenwatch_pid) {
+ sx_xlock(&xenwatch_mutex);
+ sx_xunlock(&xenwatch_mutex);
+ }
+}
+
+void
+xs_suspend(void)
+{
- err = xs_unwatch(watch->node, token);
- if (err)
- log(LOG_WARNING, "XENBUS Failed to release watch %s: %i\n",
- watch->node, err);
+ sx_xlock(&xs_state.suspend_mutex);
+ sx_xlock(&xs_state.request_mutex);
+}
- sx_sunlock(&xs_state.suspend_mutex);
+void
+xs_resume(void)
+{
+ struct xenbus_watch *watch;
+ char token[sizeof(watch) * 2 + 1];
- /* Cancel pending watch events. */
- mtx_lock(&watch_events_lock);
- TAILQ_FOREACH_SAFE(msg, &watch_events, list, tmp) {
- if (msg->u.watch.handle != watch)
- continue;
- list_del(&watch_events, msg);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watch_events_lock);
+ sx_xunlock(&xs_state.request_mutex);
- /* Flush any currently-executing callback, unless we are it. :-) */
- if (curproc->p_pid != xenwatch_pid) {
- sx_xlock(&xenwatch_mutex);
- sx_xunlock(&xenwatch_mutex);
- }
-}
-EXPORT_SYMBOL(unregister_xenbus_watch);
+ /* No need for watches_lock: the suspend_mutex is sufficient. */
+ LIST_FOREACH(watch, &watches, list) {
+ sprintf(token, "%lX", (long)watch);
+ xs_watch(watch->node, token);
+ }
-void xs_suspend(void)
-{
- sx_xlock(&xs_state.suspend_mutex);
- sx_xlock(&xs_state.request_mutex);
+ sx_xunlock(&xs_state.suspend_mutex);
}
-void xs_resume(void)
+static void
+xenwatch_thread(void *unused)
{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
+ struct xs_stored_msg *msg;
- sx_xunlock(&xs_state.request_mutex);
+ for (;;) {
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- LIST_FOREACH(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_watch(watch->node, token);
- }
+ mtx_lock(&watch_events_lock);
+ while (TAILQ_EMPTY(&watch_events))
+ mtx_sleep(&watch_events_waitq,
+ &watch_events_lock,
+ PWAIT | PCATCH, "waitev", hz/10);
- sx_xunlock(&xs_state.suspend_mutex);
-}
+ mtx_unlock(&watch_events_lock);
+ sx_xlock(&xenwatch_mutex);
-static void xenwatch_thread(void *unused)
-{
- struct xs_stored_msg *msg;
+ mtx_lock(&watch_events_lock);
+ msg = TAILQ_FIRST(&watch_events);
+ if (msg)
+ TAILQ_REMOVE(&watch_events, msg, list);
+ mtx_unlock(&watch_events_lock);
- DELAY(100000);
- while (xenwatch_inline) {
- printf("xenwatch inline still running\n");
- DELAY(100000);
+ if (msg != NULL) {
+ msg->u.watch.handle->callback(
+ msg->u.watch.handle,
+ (const char **)msg->u.watch.vec,
+ msg->u.watch.vec_size);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
}
-
-
- for (;;) {
-
- while (list_empty(&watch_events))
- tsleep(&watch_events_waitq,
- PWAIT | PCATCH, "waitev", hz/10);
-
- sx_xlock(&xenwatch_mutex);
-
- mtx_lock(&watch_events_lock);
- msg = TAILQ_FIRST(&watch_events);
- if (msg)
- list_del(&watch_events, msg);
- mtx_unlock(&watch_events_lock);
-
- if (msg != NULL) {
- msg->u.watch.handle->callback(
- msg->u.watch.handle,
- (const char **)msg->u.watch.vec,
- msg->u.watch.vec_size);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- sx_xunlock(&xenwatch_mutex);
- }
+ sx_xunlock(&xenwatch_mutex);
+ }
}
-static int xs_process_msg(enum xsd_sockmsg_type *type)
+static int
+xs_process_msg(enum xsd_sockmsg_type *type)
{
- struct xs_stored_msg *msg;
- char *body;
- int err;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL)
- return -ENOMEM;
-
- err = xb_read(&msg->hdr, sizeof(msg->hdr));
- if (err) {
- kfree(msg);
- return err;
- }
-
- body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
- if (body == NULL) {
- kfree(msg);
- return -ENOMEM;
- }
+ struct xs_stored_msg *msg;
+ char *body;
+ int error;
- err = xb_read(body, msg->hdr.len);
- if (err) {
- kfree(body);
- kfree(msg);
- return err;
- }
- body[msg->hdr.len] = '\0';
-
- *type = msg->hdr.type;
- if (msg->hdr.type == XS_WATCH_EVENT) {
- msg->u.watch.vec = split(body, msg->hdr.len,
- &msg->u.watch.vec_size);
- if (IS_ERR(msg->u.watch.vec)) {
- kfree(msg);
- return PTR_ERR(msg->u.watch.vec);
- }
+ msg = malloc(sizeof(*msg), M_DEVBUF, M_WAITOK);
+ mtx_lock(&xs_state.reply_lock);
+ error = xb_read(&msg->hdr, sizeof(msg->hdr), &xs_state.reply_lock.lock_object);
+ mtx_unlock(&xs_state.reply_lock);
+ if (error) {
+ free(msg, M_DEVBUF);
+ return (error);
+ }
+
+ body = malloc(msg->hdr.len + 1, M_DEVBUF, M_WAITOK);
+ mtx_lock(&xs_state.reply_lock);
+ error = xb_read(body, msg->hdr.len, &xs_state.reply_lock.lock_object);
+ mtx_unlock(&xs_state.reply_lock);
+ if (error) {
+ free(body, M_DEVBUF);
+ free(msg, M_DEVBUF);
+ return (error);
+ }
+ body[msg->hdr.len] = '\0';
+
+ *type = msg->hdr.type;
+ if (msg->hdr.type == XS_WATCH_EVENT) {
+ msg->u.watch.vec = split(body, msg->hdr.len,
+ &msg->u.watch.vec_size);
- mtx_lock(&watches_lock);
- msg->u.watch.handle = find_watch(
- msg->u.watch.vec[XS_WATCH_TOKEN]);
- if (msg->u.watch.handle != NULL) {
- mtx_lock(&watch_events_lock);
- TAILQ_INSERT_TAIL(&watch_events, msg, list);
- wakeup(&watch_events_waitq);
- mtx_unlock(&watch_events_lock);
- } else {
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watches_lock);
+ mtx_lock(&watches_lock);
+ msg->u.watch.handle = find_watch(
+ msg->u.watch.vec[XS_WATCH_TOKEN]);
+ if (msg->u.watch.handle != NULL) {
+ mtx_lock(&watch_events_lock);
+ TAILQ_INSERT_TAIL(&watch_events, msg, list);
+ wakeup(&watch_events_waitq);
+ mtx_unlock(&watch_events_lock);
} else {
- printf("event=%d ", *type);
- msg->u.reply.body = body;
- mtx_lock(&xs_state.reply_lock);
- TAILQ_INSERT_TAIL(&xs_state.reply_list, msg, list);
- wakeup(&xs_state.reply_waitq);
- mtx_unlock(&xs_state.reply_lock);
+ free(msg->u.watch.vec, M_DEVBUF);
+ free(msg, M_DEVBUF);
}
- if (*type == XS_WATCH_EVENT)
- printf("\n");
+ mtx_unlock(&watches_lock);
+ } else {
+ msg->u.reply.body = body;
+ mtx_lock(&xs_state.reply_lock);
+ TAILQ_INSERT_TAIL(&xs_state.reply_list, msg, list);
+ wakeup(&xs_state.reply_waitq);
+ mtx_unlock(&xs_state.reply_lock);
+ }
- return 0;
+ return 0;
}
-static void xenbus_thread(void *unused)
+static void
+xenbus_thread(void *unused)
{
- int err;
- enum xsd_sockmsg_type type;
+ int error;
+ enum xsd_sockmsg_type type;
+ xenbus_running = 1;
- DELAY(10000);
- xenbus_running = 1;
- pause("xenbus", hz/10);
+ for (;;) {
+ error = xs_process_msg(&type);
+ if (error)
+ printf("XENBUS error %d while reading message\n",
+ error);
+ }
+}
- for (;;) {
- err = xs_process_msg(&type);
- if (err)
- printf("XENBUS error %d while reading "
- "message\n", err);
+#ifdef XENHVM
+static unsigned long xen_store_mfn;
+char *xen_store;
- }
+static inline unsigned long
+hvm_get_parameter(int index)
+{
+ struct xen_hvm_param xhv;
+ int error;
+
+ xhv.domid = DOMID_SELF;
+ xhv.index = index;
+ error = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+ if (error) {
+ printf("hvm_get_parameter: failed to get %d, error %d\n",
+ index, error);
+ return (0);
+ }
+ return (xhv.value);
}
-int xs_init(void)
+#endif
+
+int
+xs_init(void)
{
- int err;
- struct proc *p;
+ int error;
+ struct proc *p;
+
+#ifdef XENHVM
+ xen_store_evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN);
+ xen_store_mfn = hvm_get_parameter(HVM_PARAM_STORE_PFN);
+ xen_store = pmap_mapdev(xen_store_mfn * PAGE_SIZE, PAGE_SIZE);
+#else
+ xen_store_evtchn = xen_start_info->store_evtchn;
+#endif
- TAILQ_INIT(&xs_state.reply_list);
- TAILQ_INIT(&watch_events);
- sx_init(&xenwatch_mutex, "xenwatch");
+ TAILQ_INIT(&xs_state.reply_list);
+ TAILQ_INIT(&watch_events);
+ sx_init(&xenwatch_mutex, "xenwatch");
- mtx_init(&xs_state.reply_lock, "state reply", NULL, MTX_DEF);
- sx_init(&xs_state.request_mutex, "xenstore request");
- sx_init(&xs_state.suspend_mutex, "xenstore suspend");
+ mtx_init(&xs_state.reply_lock, "state reply", NULL, MTX_DEF);
+ sx_init(&xs_state.request_mutex, "xenstore request");
+ sx_init(&xs_state.suspend_mutex, "xenstore suspend");
#if 0
- mtx_init(&xs_state.suspend_mutex, "xenstore suspend", NULL, MTX_DEF);
- sema_init(&xs_state.request_mutex, 1, "xenstore request");
- sema_init(&xenwatch_mutex, 1, "xenwatch");
+ mtx_init(&xs_state.suspend_mutex, "xenstore suspend", NULL, MTX_DEF);
+ sema_init(&xs_state.request_mutex, 1, "xenstore request");
+ sema_init(&xenwatch_mutex, 1, "xenwatch");
#endif
- mtx_init(&watches_lock, "watches", NULL, MTX_DEF);
- mtx_init(&watch_events_lock, "watch events", NULL, MTX_DEF);
+ mtx_init(&watches_lock, "watches", NULL, MTX_DEF);
+ mtx_init(&watch_events_lock, "watch events", NULL, MTX_DEF);
- /* Initialize the shared memory rings to talk to xenstored */
- err = xb_init_comms();
- if (err)
- return err;
-
- err = kproc_create(xenwatch_thread, NULL, &p,
- RFHIGHPID, 0, "xenwatch");
- if (err)
- return err;
- xenwatch_pid = p->p_pid;
-
- err = kproc_create(xenbus_thread, NULL, NULL,
- RFHIGHPID, 0, "xenbus");
+ /* Initialize the shared memory rings to talk to xenstored */
+ error = xb_init_comms();
+ if (error)
+ return (error);
+
+ xenwatch_running = 1;
+ error = kproc_create(xenwatch_thread, NULL, &p,
+ RFHIGHPID, 0, "xenwatch");
+ if (error)
+ return (error);
+ xenwatch_pid = p->p_pid;
+
+ error = kproc_create(xenbus_thread, NULL, NULL,
+ RFHIGHPID, 0, "xenbus");
- return err;
+ return (error);
}
-
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
diff --git a/sys/xen/xenbus/xenbusvar.h b/sys/xen/xenbus/xenbusvar.h
index 1331c4377fe0..651166421eab 100644
--- a/sys/xen/xenbus/xenbusvar.h
+++ b/sys/xen/xenbus/xenbusvar.h
@@ -103,32 +103,37 @@ struct xenbus_transaction
#define XBT_NIL ((struct xenbus_transaction) { 0 })
-char **xenbus_directory(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction t,
- const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction t,
- const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction t,
- const char *dir, const char *node);
+int xenbus_directory(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *num, char ***result);
+int xenbus_read(struct xenbus_transaction t, const char *dir,
+ const char *node, unsigned int *len, void **result);
+int xenbus_write(struct xenbus_transaction t, const char *dir,
+ const char *node, const char *string);
+int xenbus_mkdir(struct xenbus_transaction t, const char *dir,
+ const char *node);
+int xenbus_exists(struct xenbus_transaction t, const char *dir,
+ const char *node);
int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
int xenbus_transaction_start(struct xenbus_transaction *t);
int xenbus_transaction_end(struct xenbus_transaction t, int abort);
-/* Single read and scanf: returns -errno or num scanned if > 0. */
+/*
+ * Single read and scanf: returns errno or zero. If scancountp is
+ * non-null, then number of items scanned is returned in *scanncountp.
+ */
int xenbus_scanf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
- __attribute__((format(scanf, 4, 5)));
+ const char *dir, const char *node, int *scancountp, const char *fmt, ...)
+ __attribute__((format(scanf, 5, 6)));
-/* Single printf and write: returns -errno or 0. */
+/* Single printf and write: returns errno or 0. */
int xenbus_printf(struct xenbus_transaction t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(printf, 4, 5)));
-/* Generic read function: NULL-terminated triples of name,
- * sprintf-style type string, and pointer. Returns 0 or errno.*/
+/*
+ * Generic read function: NULL-terminated triples of name,
+ * sprintf-style type string, and pointer. Returns 0 or errno.
+ */
int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
/* notifer routines for when the xenstore comes up */
@@ -142,7 +147,9 @@ void xs_suspend(void);
void xs_resume(void);
/* Used by xenbus_dev to borrow kernel's store connection. */
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
+int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void **result);
+
+#if 0
#define XENBUS_IS_ERR_READ(str) ({ \
if (!IS_ERR(str) && strlen(str) == 0) { \
@@ -152,12 +159,15 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
IS_ERR(str); \
})
-#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
+#endif
+
+#define XENBUS_EXIST_ERR(err) ((err) == ENOENT || (err) == ERANGE)
+
/**
* Register a watch on the given path, using the given xenbus_watch structure
* for storage, and the given callback function as the callback. Return 0 on
- * success, or -errno on error. On success, the given path will be saved as
+ * success, or errno on error. On success, the given path will be saved as
* watch->node, and remains the caller's to free. On error, watch->node will
* be NULL, the device will switch to XenbusStateClosing, and the error will
* be saved in the store.
@@ -171,7 +181,7 @@ int xenbus_watch_path(device_t dev, char *path,
/**
* Register a watch on the given path/path2, using the given xenbus_watch
* structure for storage, and the given callback function as the callback.
- * Return 0 on success, or -errno on error. On success, the watched path
+ * Return 0 on success, or errno on error. On success, the watched path
* (path/path2) will be saved as watch->node, and becomes the caller's to
* kfree(). On error, watch->node will be NULL, so the caller has nothing to
* free, the device will switch to XenbusStateClosing, and the error will be
@@ -186,7 +196,7 @@ int xenbus_watch_path2(device_t dev, const char *path,
/**
* Advertise in the store a change of the given driver to the given new_state.
* which case this is performed inside its own transaction. Return 0 on
- * success, or -errno on error. On error, the device will switch to
+ * success, or errno on error. On error, the device will switch to
* XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(device_t dev,
@@ -194,16 +204,17 @@ int xenbus_switch_state(device_t dev,
/**
- * Grant access to the given ring_mfn to the peer of the given device. Return
- * 0 on success, or -errno on error. On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
+ * Grant access to the given ring_mfn to the peer of the given device.
+ * Return 0 on success, or errno on error. On error, the device will
+ * switch to XenbusStateClosing, and the error will be saved in the
+ * store. The grant ring reference is returned in *refp.
*/
-int xenbus_grant_ring(device_t dev, unsigned long ring_mfn);
+int xenbus_grant_ring(device_t dev, unsigned long ring_mfn, int *refp);
/**
* Allocate an event channel for the given xenbus_device, assigning the newly
- * created local port to *port. Return 0 on success, or -errno on error. On
+ * created local port to *port. Return 0 on success, or errno on error. On
* error, the device will switch to XenbusStateClosing, and the error will be
* saved in the store.
*/
@@ -211,7 +222,7 @@ int xenbus_alloc_evtchn(device_t dev, int *port);
/**
- * Free an existing event channel. Returns 0 on success or -errno on error.
+ * Free an existing event channel. Returns 0 on success or errno on error.
*/
int xenbus_free_evtchn(device_t dev, int port);