summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files6
-rw-r--r--sys/dev/xen/blkfront/blkfront.c299
-rw-r--r--sys/dev/xen/blkfront/block.h4
-rw-r--r--sys/dev/xen/netfront/netfront.c238
-rw-r--r--sys/i386/xen/xen_machdep.c4
-rw-r--r--sys/xen/gnttab.c6
-rw-r--r--sys/xen/gnttab.h2
-rw-r--r--sys/xen/xenbus/xenbus_client.c80
-rw-r--r--sys/xen/xenbus/xenbus_comms.c8
-rw-r--r--sys/xen/xenbus/xenbus_comms.h9
-rw-r--r--sys/xen/xenbus/xenbus_dev.c7
-rw-r--r--sys/xen/xenbus/xenbus_if.m37
-rw-r--r--sys/xen/xenbus/xenbus_probe.c1245
-rw-r--r--sys/xen/xenbus/xenbus_probe_backend.c1
-rw-r--r--sys/xen/xenbus/xenbus_xs.c4
-rw-r--r--sys/xen/xenbus/xenbusvar.h (renamed from sys/i386/include/xen/xenbus.h)147
16 files changed, 754 insertions, 1343 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 8b5b75e..151a227 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2763,10 +2763,14 @@ xen/evtchn/evtchn_dev.c optional xen
xen/xenbus/xenbus_client.c optional xen
xen/xenbus/xenbus_comms.c optional xen
xen/xenbus/xenbus_dev.c optional xen
+xen/xenbus/xenbus_if.m optional xen
xen/xenbus/xenbus_probe.c optional xen
-xen/xenbus/xenbus_probe_backend.c optional xen
+#xen/xenbus/xenbus_probe_backend.c optional xen
xen/xenbus/xenbus_xs.c optional xen
dev/xen/console/console.c optional xen
dev/xen/console/xencons_ring.c optional xen
dev/xen/blkfront/blkfront.c optional xen
dev/xen/netfront/netfront.c optional xen
+#dev/xen/xenpci/xenpci.c optional xen
+#xen/xenbus/xenbus_newbus.c optional xenhvm
+
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index 3bdc4f8..dc36007 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -43,9 +43,10 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/hypervisor.h>
#include <machine/xen/xen-os.h>
#include <machine/xen/xen_intr.h>
-#include <machine/xen/xenbus.h>
#include <machine/xen/evtchn.h>
#include <xen/interface/grant_table.h>
+#include <xen/interface/io/protocols.h>
+#include <xen/xenbus/xenbusvar.h>
#include <geom/geom_disk.h>
#include <machine/xen/xenfunc.h>
@@ -53,15 +54,17 @@ __FBSDID("$FreeBSD$");
#include <dev/xen/blkfront/block.h>
+#include "xenbus_if.h"
+
#define ASSERT(S) KASSERT(S, (#S))
/* prototypes */
struct xb_softc;
static void xb_startio(struct xb_softc *sc);
-static void connect(struct blkfront_info *);
-static void blkfront_closing(struct xenbus_device *);
-static int blkfront_remove(struct xenbus_device *);
-static int talk_to_backend(struct xenbus_device *, struct blkfront_info *);
-static int setup_blkring(struct xenbus_device *, struct blkfront_info *);
+static void connect(device_t, struct blkfront_info *);
+static void blkfront_closing(device_t);
+static int blkfront_detach(device_t);
+static int talk_to_backend(device_t, struct blkfront_info *);
+static int setup_blkring(device_t, struct blkfront_info *);
static void blkif_int(void *);
#if 0
static void blkif_restart_queue(void *arg);
@@ -136,22 +139,95 @@ pfn_to_mfn(vm_paddr_t pfn)
}
+/*
+ * Translate Linux major/minor to an appropriate name and unit
+ * number. For HVM guests, this allows us to use the same drive names
+ * with blkfront as the emulated drives, easing transition slightly.
+ */
+static void
+blkfront_vdevice_to_unit(int vdevice, int *unit, const char **name)
+{
+ static struct vdev_info {
+ int major;
+ int shift;
+ int base;
+ const char *name;
+ } info[] = {
+ {3, 6, 0, "ad"}, /* ide0 */
+ {22, 6, 2, "ad"}, /* ide1 */
+ {33, 6, 4, "ad"}, /* ide2 */
+ {34, 6, 6, "ad"}, /* ide3 */
+ {56, 6, 8, "ad"}, /* ide4 */
+ {57, 6, 10, "ad"}, /* ide5 */
+ {88, 6, 12, "ad"}, /* ide6 */
+ {89, 6, 14, "ad"}, /* ide7 */
+ {90, 6, 16, "ad"}, /* ide8 */
+ {91, 6, 18, "ad"}, /* ide9 */
+
+ {8, 4, 0, "da"}, /* scsi disk0 */
+ {65, 4, 16, "da"}, /* scsi disk1 */
+ {66, 4, 32, "da"}, /* scsi disk2 */
+ {67, 4, 48, "da"}, /* scsi disk3 */
+ {68, 4, 64, "da"}, /* scsi disk4 */
+ {69, 4, 80, "da"}, /* scsi disk5 */
+ {70, 4, 96, "da"}, /* scsi disk6 */
+ {71, 4, 112, "da"}, /* scsi disk7 */
+ {128, 4, 128, "da"}, /* scsi disk8 */
+ {129, 4, 144, "da"}, /* scsi disk9 */
+ {130, 4, 160, "da"}, /* scsi disk10 */
+ {131, 4, 176, "da"}, /* scsi disk11 */
+ {132, 4, 192, "da"}, /* scsi disk12 */
+ {133, 4, 208, "da"}, /* scsi disk13 */
+ {134, 4, 224, "da"}, /* scsi disk14 */
+ {135, 4, 240, "da"}, /* scsi disk15 */
+
+ {202, 4, 0, "xbd"}, /* xbd */
+
+ {0, 0, 0, NULL},
+ };
+ int major = vdevice >> 8;
+ int minor = vdevice & 0xff;
+ int i;
+
+ if (vdevice & (1 << 28)) {
+ *unit = (vdevice & ((1 << 28) - 1)) >> 8;
+ *name = "xbd";
+ }
+
+ for (i = 0; info[i].major; i++) {
+ if (info[i].major == major) {
+ *unit = info[i].base + (minor >> info[i].shift);
+ *name = info[i].name;
+ return;
+ }
+ }
+
+ *unit = minor >> 4;
+ *name = "xbd";
+}
+
int
-xlvbd_add(blkif_sector_t capacity, int unit, uint16_t vdisk_info, uint16_t sector_size,
- struct blkfront_info *info)
+xlvbd_add(device_t dev, blkif_sector_t capacity,
+ int vdevice, uint16_t vdisk_info, uint16_t sector_size,
+ struct blkfront_info *info)
{
struct xb_softc *sc;
- int error = 0;
- int unitno = unit - 767;
+ 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);
- sc->xb_unit = unitno;
+ sc->xb_unit = unit;
sc->xb_info = info;
info->sc = sc;
+ if (strcmp(name, "xbd"))
+ device_printf(dev, "attaching as %s%d\n", name, unit);
+
memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
sc->xb_disk = disk_alloc();
- sc->xb_disk->d_unit = unitno;
+ sc->xb_disk->d_unit = unit;
sc->xb_disk->d_open = blkif_open;
sc->xb_disk->d_close = blkif_close;
sc->xb_disk->d_ioctl = blkif_ioctl;
@@ -226,19 +302,33 @@ xb_strategy(struct bio *bp)
return;
}
+static int
+blkfront_probe(device_t dev)
+{
+
+ if (!strcmp(xenbus_get_type(dev), "vbd")) {
+ device_set_desc(dev, "Virtual Block Device");
+ device_quiet(dev);
+ return (0);
+ }
-/* Setup supplies the backend dir, virtual device.
+ return (ENXIO);
+}
-We place an event channel and shared frame entries.
-We watch backend to wait if it's ok. */
-static int blkfront_probe(struct xenbus_device *dev,
- const struct xenbus_device_id *id)
+/*
+ * Setup supplies the backend dir, virtual device. We place an event
+ * channel and shared frame entries. We watch backend to wait if it's
+ * ok.
+ */
+static int
+blkfront_attach(device_t dev)
{
- int err, vdevice, i;
+ int err, vdevice, i, unit;
struct blkfront_info *info;
+ const char *name;
/* FIXME: Use dynamic device id if this is not set. */
- err = xenbus_scanf(XBT_NIL, dev->nodename,
+ err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
"virtual-device", "%i", &vdevice);
if (err != 1) {
xenbus_dev_fatal(dev, err, "reading virtual-device");
@@ -246,11 +336,11 @@ static int blkfront_probe(struct xenbus_device *dev,
return (err);
}
- info = malloc(sizeof(*info), M_DEVBUF, M_NOWAIT|M_ZERO);
- if (info == NULL) {
- xenbus_dev_fatal(dev, ENOMEM, "allocating info structure");
- return ENOMEM;
- }
+ blkfront_vdevice_to_unit(vdevice, &unit, &name);
+ if (!strcmp(name, "xbd"))
+ device_set_unit(dev, unit);
+
+ info = device_get_softc(dev);
/*
* XXX debug only
@@ -270,23 +360,20 @@ static int blkfront_probe(struct xenbus_device *dev,
info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
/* Front end dir is a number, which is used as the id. */
- info->handle = strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
- dev->dev_driver_data = info;
+ info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
err = talk_to_backend(dev, info);
if (err) {
- free(info, M_DEVBUF);
- dev->dev_driver_data = NULL;
return err;
}
- return 0;
+ return (0);
}
-
-static int blkfront_resume(struct xenbus_device *dev)
+static int
+blkfront_resume(device_t dev)
{
- struct blkfront_info *info = dev->dev_driver_data;
+ struct blkfront_info *info = device_get_softc(dev);
int err;
DPRINTK("blkfront_resume: %s\n", dev->nodename);
@@ -301,8 +388,8 @@ static int blkfront_resume(struct xenbus_device *dev)
}
/* Common code used when first setting up, and when resuming. */
-static int talk_to_backend(struct xenbus_device *dev,
- struct blkfront_info *info)
+static int
+talk_to_backend(device_t dev, struct blkfront_info *info)
{
const char *message = NULL;
struct xenbus_transaction xbt;
@@ -320,19 +407,24 @@ static int talk_to_backend(struct xenbus_device *dev,
goto destroy_blkring;
}
- err = xenbus_printf(xbt, dev->nodename,
+ err = xenbus_printf(xbt, xenbus_get_node(dev),
"ring-ref","%u", info->ring_ref);
if (err) {
message = "writing ring-ref";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename,
+ err = xenbus_printf(xbt, xenbus_get_node(dev),
"event-channel", "%u", irq_to_evtchn_port(info->irq));
if (err) {
message = "writing event-channel";
goto abort_transaction;
}
-
+ err = xenbus_printf(xbt, xenbus_get_node(dev),
+ "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
+ if (err) {
+ message = "writing protocol";
+ goto abort_transaction;
+ }
err = xenbus_transaction_end(xbt, 0);
if (err) {
if (err == -EAGAIN)
@@ -340,7 +432,7 @@ static int talk_to_backend(struct xenbus_device *dev,
xenbus_dev_fatal(dev, err, "completing transaction");
goto destroy_blkring;
}
- xenbus_switch_state(dev, XenbusStateInitialised);
+ xenbus_set_state(dev, XenbusStateInitialised);
return 0;
@@ -355,7 +447,7 @@ static int talk_to_backend(struct xenbus_device *dev,
}
static int
-setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
+setup_blkring(device_t dev, struct blkfront_info *info)
{
blkif_sring_t *sring;
int err;
@@ -378,7 +470,7 @@ setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
}
info->ring_ref = err;
- err = bind_listening_port_to_irqhandler(dev->otherend_id,
+ err = 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) {
@@ -398,10 +490,10 @@ setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
/**
* Callback received when the backend's state changes.
*/
-static void backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
+static void
+blkfront_backend_changed(device_t dev, XenbusState backend_state)
{
- struct blkfront_info *info = dev->dev_driver_data;
+ struct blkfront_info *info = device_get_softc(dev);
DPRINTK("blkfront:backend_changed.\n");
@@ -416,7 +508,7 @@ static void backend_changed(struct xenbus_device *dev,
break;
case XenbusStateConnected:
- connect(info);
+ connect(dev, info);
break;
case XenbusStateClosing:
@@ -447,7 +539,7 @@ static void backend_changed(struct xenbus_device *dev,
** the details about the physical device - #sectors, size, etc).
*/
static void
-connect(struct blkfront_info *info)
+connect(device_t dev, struct blkfront_info *info)
{
unsigned long sectors, sector_size;
unsigned int binfo;
@@ -457,28 +549,34 @@ connect(struct blkfront_info *info)
(info->connected == BLKIF_STATE_SUSPENDED) )
return;
- DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
+ DPRINTK("blkfront.c:connect:%s.\n", xenbus_get_otherend_path(dev));
- err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+ err = xenbus_gather(XBT_NIL, xenbus_get_otherend_path(dev),
"sectors", "%lu", &sectors,
"info", "%u", &binfo,
"sector-size", "%lu", &sector_size,
NULL);
if (err) {
- xenbus_dev_fatal(info->xbdev, err,
- "reading backend fields at %s",
- info->xbdev->otherend);
+ xenbus_dev_fatal(dev, err,
+ "reading backend fields at %s",
+ xenbus_get_otherend_path(dev));
return;
}
- err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+ err = xenbus_gather(XBT_NIL, xenbus_get_otherend_path(dev),
"feature-barrier", "%lu", &info->feature_barrier,
NULL);
if (err)
info->feature_barrier = 0;
- xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
+ device_printf(dev, "%juMB <%s> at %s",
+ (uintmax_t) sectors / (1048576 / sector_size),
+ device_get_desc(dev),
+ xenbus_get_node(dev));
+ bus_print_child_footer(device_get_parent(dev), dev);
- (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
+ xlvbd_add(dev, sectors, info->vdevice, binfo, sector_size, info);
+
+ (void)xenbus_set_state(dev, XenbusStateConnected);
/* Kick pending requests. */
mtx_lock(&blkif_io_lock);
@@ -498,11 +596,12 @@ connect(struct blkfront_info *info)
* the backend. Once is this done, we can switch to Closed in
* acknowledgement.
*/
-static void blkfront_closing(struct xenbus_device *dev)
+static void
+blkfront_closing(device_t dev)
{
- struct blkfront_info *info = dev->dev_driver_data;
+ struct blkfront_info *info = device_get_softc(dev);
- DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
+ DPRINTK("blkfront_closing: %s removed\n", xenbus_get_node(dev));
if (info->mi) {
DPRINTK("Calling xlvbd_del\n");
@@ -510,20 +609,19 @@ static void blkfront_closing(struct xenbus_device *dev)
info->mi = NULL;
}
- xenbus_switch_state(dev, XenbusStateClosed);
+ xenbus_set_state(dev, XenbusStateClosed);
}
-static int blkfront_remove(struct xenbus_device *dev)
+static int
+blkfront_detach(device_t dev)
{
- struct blkfront_info *info = dev->dev_driver_data;
+ struct blkfront_info *info = device_get_softc(dev);
- DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
+ DPRINTK("blkfront_remove: %s removed\n", xenbus_get_node(dev));
blkif_free(info, 0);
- free(info, M_DEVBUF);
-
return 0;
}
@@ -631,8 +729,9 @@ blkif_close(struct disk *dp)
/* Check whether we have been instructed to close. We will
have ignored this request initially, as the device was
still mounted. */
- struct xenbus_device * dev = sc->xb_info->xbdev;
- XenbusState state = xenbus_read_driver_state(dev->otherend);
+ device_t dev = sc->xb_info->xbdev;
+ XenbusState state =
+ xenbus_read_driver_state(xenbus_get_otherend_path(dev));
if (state == XenbusStateClosing)
blkfront_closing(dev);
@@ -731,7 +830,7 @@ static int blkif_queue_request(struct bio *bp)
gnttab_grant_foreign_access_ref(
ref,
- info->xbdev->otherend_id,
+ xenbus_get_otherend_id(info->xbdev),
buffer_ma >> PAGE_SHIFT,
ring_req->operation & 1 ); /* ??? */
info->shadow[id].frame[ring_req->nr_segments] =
@@ -952,7 +1051,7 @@ blkif_recover(struct blkfront_info *info)
for (j = 0; j < req->nr_segments; j++)
gnttab_grant_foreign_access_ref(
req->seg[j].gref,
- info->xbdev->otherend_id,
+ xenbus_get_otherend_id(info->xbdev),
pfn_to_mfn(info->shadow[req->id].frame[j]),
0 /* assume not readonly */);
@@ -963,7 +1062,7 @@ blkif_recover(struct blkfront_info *info)
free(copy, M_DEVBUF);
- xenbus_switch_state(info->xbdev, XenbusStateConnected);
+ xenbus_set_state(info->xbdev, XenbusStateConnected);
/* Now safe for us to use the shared ring */
mtx_lock(&blkif_io_lock);
@@ -979,48 +1078,30 @@ blkif_recover(struct blkfront_info *info)
mtx_unlock(&blkif_io_lock);
}
-static int
-blkfront_is_ready(struct xenbus_device *dev)
-{
- struct blkfront_info *info = dev->dev_driver_data;
-
- return info->is_ready;
-}
-
-static struct xenbus_device_id blkfront_ids[] = {
- { "vbd" },
- { "" }
-};
-
-
-static struct xenbus_driver blkfront = {
- .name = "vbd",
- .ids = blkfront_ids,
- .probe = blkfront_probe,
- .remove = blkfront_remove,
- .resume = blkfront_resume,
- .otherend_changed = backend_changed,
- .is_ready = blkfront_is_ready,
-};
-
-
-
-static void
-xenbus_init(void)
-{
- xenbus_register_frontend(&blkfront);
-}
+/* ** Driver registration ** */
+static device_method_t blkfront_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, blkfront_probe),
+ DEVMETHOD(device_attach, blkfront_attach),
+ DEVMETHOD(device_detach, blkfront_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, blkfront_resume),
+
+ /* Xenbus interface */
+ DEVMETHOD(xenbus_backend_changed, blkfront_backend_changed),
+
+ { 0, 0 }
+};
+
+static driver_t blkfront_driver = {
+ "xbd",
+ blkfront_methods,
+ sizeof(struct blkfront_info),
+};
+devclass_t blkfront_devclass;
+
+DRIVER_MODULE(xbd, xenbus, blkfront_driver, blkfront_devclass, 0, 0);
MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_NOWITNESS); /* XXX how does one enroll a lock? */
-SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_SECOND, xenbus_init, NULL);
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 8
- * tab-width: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/sys/dev/xen/blkfront/block.h b/sys/dev/xen/blkfront/block.h
index 0d14459..97dfe7e 100644
--- a/sys/dev/xen/blkfront/block.h
+++ b/sys/dev/xen/blkfront/block.h
@@ -60,7 +60,7 @@ struct xb_softc {
*/
struct blkfront_info
{
- struct xenbus_device *xbdev;
+ device_t xbdev;
dev_t dev;
struct gendisk *gd;
int vdevice;
@@ -89,7 +89,7 @@ struct blkfront_info
/* Note that xlvbd_add doesn't call add_disk for you: you're expected
to call add_disk on info->gd once the disk is properly connected
up. */
-int xlvbd_add(blkif_sector_t capacity, int device,
+int xlvbd_add(device_t, blkif_sector_t capacity, int device,
uint16_t vdisk_info, uint16_t sector_size, struct blkfront_info *info);
void xlvbd_del(struct blkfront_info *info);
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 963808f..607628f 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -25,6 +25,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/queue.h>
@@ -64,13 +65,14 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/hypervisor.h>
#include <machine/xen/xen_intr.h>
#include <machine/xen/evtchn.h>
-#include <machine/xen/xenbus.h>
#include <xen/gnttab.h>
#include <xen/interface/memory.h>
#include <dev/xen/netfront/mbufq.h>
#include <machine/xen/features.h>
#include <xen/interface/io/netif.h>
+#include <xen/xenbus/xenbusvar.h>
+#include "xenbus_if.h"
#define GRANT_INVALID_REF 0
@@ -116,19 +118,19 @@ static void xn_watchdog(struct ifnet *);
static void show_device(struct netfront_info *sc);
#ifdef notyet
-static void netfront_closing(struct xenbus_device *dev);
+static void netfront_closing(device_t dev);
#endif
static void netif_free(struct netfront_info *info);
-static int netfront_remove(struct xenbus_device *dev);
+static int netfront_detach(device_t dev);
-static int talk_to_backend(struct xenbus_device *dev, struct netfront_info *info);
-static int create_netdev(struct xenbus_device *dev, struct ifnet **ifp);
+static int talk_to_backend(device_t dev, struct netfront_info *info);
+static int create_netdev(device_t dev);
static void netif_disconnect_backend(struct netfront_info *info);
-static int setup_device(struct xenbus_device *dev, struct netfront_info *info);
+static int setup_device(device_t dev, struct netfront_info *info);
static void end_access(int ref, void *page);
/* Xenolinux helper functions */
-static int network_connect(struct ifnet *ifp);
+int network_connect(struct netfront_info *);
static void xn_free_rx_ring(struct netfront_info *);
@@ -221,7 +223,7 @@ struct netfront_info {
grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1];
#define TX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
- struct xenbus_device *xbdev;
+ device_t xbdev;
int tx_ring_ref;
int rx_ring_ref;
uint8_t mac[ETHER_ADDR_LEN];
@@ -327,7 +329,7 @@ xennet_get_rx_ref(struct netfront_info *np, RING_IDX ri)
#define WPRINTK(fmt, args...) \
printf("[XEN] " fmt, ##args)
#define DPRINTK(fmt, args...) \
- printf("[XEN] " fmt, ##args)
+ printf("[XEN] %s: " fmt, __func__, ##args)
static __inline struct mbuf*
@@ -340,15 +342,15 @@ makembuf (struct mbuf *buf)
if (! m)
return 0;
- M_MOVE_PKTHDR(m, buf);
+ M_MOVE_PKTHDR(m, buf);
- m_cljget(m, M_DONTWAIT, MJUMPAGESIZE);
+ m_cljget(m, M_DONTWAIT, MJUMPAGESIZE);
m->m_pkthdr.len = buf->m_pkthdr.len;
m->m_len = buf->m_len;
- m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) );
+ m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) );
m->m_ext.ext_arg1 = (caddr_t *)(uintptr_t)(vtophys(mtod(m,caddr_t)) >> PAGE_SHIFT);
-
+
return m;
}
@@ -359,12 +361,12 @@ makembuf (struct mbuf *buf)
* Return 0 on success, or errno on error.
*/
static int
-xen_net_read_mac(struct xenbus_device *dev, uint8_t mac[])
+xen_net_read_mac(device_t dev, uint8_t mac[])
{
char *s;
int i;
char *e;
- char *macstr = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
+ char *macstr = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL);
if (IS_ERR(macstr)) {
return PTR_ERR(macstr);
}
@@ -388,23 +390,28 @@ xen_net_read_mac(struct xenbus_device *dev, uint8_t mac[])
* Connected state.
*/
static int
-netfront_probe(struct xenbus_device *dev, const struct xenbus_device_id *id)
+netfront_probe(device_t dev)
{
+
+ if (!strcmp(xenbus_get_type(dev), "vif")) {
+ device_set_desc(dev, "Virtual Network Interface");
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+static int
+netfront_attach(device_t dev)
+{
int err;
- struct ifnet *ifp;
- struct netfront_info *info;
- printf("netfront_probe() \n");
-
- err = create_netdev(dev, &ifp);
+ err = create_netdev(dev);
if (err) {
xenbus_dev_fatal(dev, err, "creating netdev");
return err;
}
- info = ifp->if_softc;
- dev->dev_driver_data = info;
-
return 0;
}
@@ -416,11 +423,11 @@ netfront_probe(struct xenbus_device *dev, const struct xenbus_device_id *id)
* rest of the kernel.
*/
static int
-netfront_resume(struct xenbus_device *dev)
+netfront_resume(device_t dev)
{
- struct netfront_info *info = dev->dev_driver_data;
+ struct netfront_info *info = device_get_softc(dev);
- DPRINTK("%s\n", dev->nodename);
+ DPRINTK("%s\n", xenbus_get_node(dev));
netif_disconnect_backend(info);
return (0);
@@ -429,15 +436,16 @@ netfront_resume(struct xenbus_device *dev)
/* Common code used when first setting up, and when resuming. */
static int
-talk_to_backend(struct xenbus_device *dev, struct netfront_info *info)
+talk_to_backend(device_t dev, struct netfront_info *info)
{
const char *message;
struct xenbus_transaction xbt;
+ const char *node = xenbus_get_node(dev);
int err;
err = xen_net_read_mac(dev, info->mac);
if (err) {
- xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
+ xenbus_dev_fatal(dev, err, "parsing %s/mac", node);
goto out;
}
@@ -452,47 +460,47 @@ talk_to_backend(struct xenbus_device *dev, struct netfront_info *info)
xenbus_dev_fatal(dev, err, "starting transaction");
goto destroy_ring;
}
- err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
+ err = xenbus_printf(xbt, node, "tx-ring-ref","%u",
info->tx_ring_ref);
if (err) {
message = "writing tx ring-ref";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
+ err = xenbus_printf(xbt, node, "rx-ring-ref","%u",
info->rx_ring_ref);
if (err) {
message = "writing rx ring-ref";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename,
+ err = xenbus_printf(xbt, node,
"event-channel", "%u", irq_to_evtchn_port(info->irq));
if (err) {
message = "writing event-channel";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u",
+ err = xenbus_printf(xbt, node, "request-rx-copy", "%u",
info->copying_receiver);
if (err) {
message = "writing request-rx-copy";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1);
+ err = xenbus_printf(xbt, node, "feature-rx-notify", "%d", 1);
if (err) {
message = "writing feature-rx-notify";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload", "%d", 1);
+ err = xenbus_printf(xbt, node, "feature-no-csum-offload", "%d", 1);
if (err) {
message = "writing feature-no-csum-offload";
goto abort_transaction;
}
- err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
+ err = xenbus_printf(xbt, node, "feature-sg", "%d", 1);
if (err) {
message = "writing feature-sg";
goto abort_transaction;
}
#ifdef HAVE_TSO
- err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
+ err = xenbus_printf(xbt, node, "feature-gso-tcpv4", "%d", 1);
if (err) {
message = "writing feature-gso-tcpv4";
goto abort_transaction;
@@ -520,7 +528,7 @@ talk_to_backend(struct xenbus_device *dev, struct netfront_info *info)
static int
-setup_device(struct xenbus_device *dev, struct netfront_info *info)
+setup_device(device_t dev, struct netfront_info *info)
{
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
@@ -563,9 +571,9 @@ setup_device(struct xenbus_device *dev, struct netfront_info *info)
info->rx_ring_ref = err;
#if 0
- network_connect(ifp);
+ network_connect(info);
#endif
- err = bind_listening_port_to_irqhandler(dev->otherend_id,
+ err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
"xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL);
if (err <= 0) {
@@ -588,14 +596,13 @@ setup_device(struct xenbus_device *dev, struct netfront_info *info)
* Callback received when the backend's state changes.
*/
static void
-backend_changed(struct xenbus_device *dev,
- XenbusState backend_state)
+netfront_backend_changed(device_t dev, XenbusState newstate)
{
- struct netfront_info *sc = dev->dev_driver_data;
+ struct netfront_info *sc = device_get_softc(dev);
- DPRINTK("\n");
-
- switch (backend_state) {
+ DPRINTK("newstate=%d\n", newstate);
+
+ switch (newstate) {
case XenbusStateInitialising:
case XenbusStateInitialised:
case XenbusStateConnected:
@@ -603,19 +610,19 @@ backend_changed(struct xenbus_device *dev,
case XenbusStateClosed:
case XenbusStateReconfigured:
case XenbusStateReconfiguring:
- break;
+ break;
case XenbusStateInitWait:
- if (dev->state != XenbusStateInitialising)
+ if (xenbus_get_state(dev) != XenbusStateInitialising)
break;
- if (network_connect(sc->xn_ifp) != 0)
+ if (network_connect(sc) != 0)
break;
- xenbus_switch_state(dev, XenbusStateConnected);
+ xenbus_set_state(dev, XenbusStateConnected);
#ifdef notyet
(void)send_fake_arp(netdev);
#endif
- break; break;
+ break;
case XenbusStateClosing:
- xenbus_frontend_closed(dev);
+ xenbus_set_state(dev, XenbusStateClosed);
break;
}
}
@@ -674,7 +681,8 @@ netif_release_tx_bufs(struct netfront_info *np)
if (((u_long)m) < KERNBASE)
continue;
gnttab_grant_foreign_access_ref(np->grant_tx_ref[i],
- np->xbdev->otherend_id, virt_to_mfn(mtod(m, vm_offset_t)),
+ xenbus_get_otherend_id(np->xbdev),
+ virt_to_mfn(mtod(m, vm_offset_t)),
GNTMAP_readonly);
gnttab_release_grant_reference(&np->gref_tx_head,
np->grant_tx_ref[i]);
@@ -687,6 +695,7 @@ netif_release_tx_bufs(struct netfront_info *np)
static void
network_alloc_rx_buffers(struct netfront_info *sc)
{
+ int otherend_id = xenbus_get_otherend_id(sc->xbdev);
unsigned short id;
struct mbuf *m_new;
int i, batch_target, notify;
@@ -768,7 +777,7 @@ refill:
if (sc->copying_receiver == 0) {
gnttab_grant_foreign_transfer_ref(ref,
- sc->xbdev->otherend_id, pfn);
+ otherend_id, pfn);
sc->rx_pfn_array[nr_flips] = PFNTOMFN(pfn);
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Remove this page before passing
@@ -781,7 +790,7 @@ refill:
nr_flips++;
} else {
gnttab_grant_foreign_access_ref(ref,
- sc->xbdev->otherend_id,
+ otherend_id,
PFNTOMFN(pfn), 0);
}
req->id = id;
@@ -1298,6 +1307,7 @@ xn_tick(void *xsc)
static void
xn_start_locked(struct ifnet *ifp)
{
+ int otherend_id;
unsigned short id;
struct mbuf *m_head, *new_m;
struct netfront_info *sc;
@@ -1308,6 +1318,7 @@ xn_start_locked(struct ifnet *ifp)
int notify;
sc = ifp->if_softc;
+ otherend_id = xenbus_get_otherend_id(sc->xbdev);
tx_bytes = 0;
if (!netfront_carrier_ok(sc))
@@ -1337,7 +1348,7 @@ xn_start_locked(struct ifnet *ifp)
ref = gnttab_claim_grant_reference(&sc->gref_tx_head);
KASSERT((short)ref >= 0, ("Negative ref"));
mfn = virt_to_mfn(mtod(new_m, vm_offset_t));
- gnttab_grant_foreign_access_ref(ref, sc->xbdev->otherend_id,
+ gnttab_grant_foreign_access_ref(ref, otherend_id,
mfn, GNTMAP_readonly);
tx->gref = sc->grant_tx_ref[id] = ref;
tx->size = new_m->m_pkthdr.len;
@@ -1543,23 +1554,19 @@ xn_stop(struct netfront_info *sc)
}
/* START of Xenolinux helper functions adapted to FreeBSD */
-static int
-network_connect(struct ifnet *ifp)
+int
+network_connect(struct netfront_info *np)
{
- struct netfront_info *np;
int i, requeue_idx, err;
grant_ref_t ref;
netif_rx_request_t *req;
u_int feature_rx_copy, feature_rx_flip;
- printf("network_connect\n");
-
- np = ifp->if_softc;
- err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+ err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
"feature-rx-copy", "%u", &feature_rx_copy);
if (err != 1)
feature_rx_copy = 0;
- err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+ err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev),
"feature-rx-flip", "%u", &feature_rx_flip);
if (err != 1)
feature_rx_flip = 1;
@@ -1576,7 +1583,7 @@ network_connect(struct ifnet *ifp)
/* Recovery procedure: */
err = talk_to_backend(np->xbdev, np);
if (err)
- return (err);
+ return (err);
/* Step 1: Reinitialise variables. */
netif_release_tx_bufs(np);
@@ -1594,11 +1601,11 @@ network_connect(struct ifnet *ifp)
if (!np->copying_receiver) {
gnttab_grant_foreign_transfer_ref(ref,
- np->xbdev->otherend_id,
+ xenbus_get_otherend_id(np->xbdev),
vtophys(mtod(m, vm_offset_t)));
} else {
gnttab_grant_foreign_access_ref(ref,
- np->xbdev->otherend_id,
+ xenbus_get_otherend_id(np->xbdev),
vtophys(mtod(m, vm_offset_t)), 0);
}
req->gref = ref;
@@ -1625,7 +1632,6 @@ network_connect(struct ifnet *ifp)
return (0);
}
-
static void
show_device(struct netfront_info *sc)
{
@@ -1645,25 +1651,18 @@ show_device(struct netfront_info *sc)
#endif
}
-static int ifno = 0;
-
/** Create a network device.
* @param handle device handle
*/
-static int
-create_netdev(struct xenbus_device *dev, struct ifnet **ifpp)
+int
+create_netdev(device_t dev)
{
int i;
struct netfront_info *np;
int err;
struct ifnet *ifp;
- np = (struct netfront_info *)malloc(sizeof(struct netfront_info),
- M_DEVBUF, M_NOWAIT);
- if (np == NULL)
- return (ENOMEM);
-
- memset(np, 0, sizeof(struct netfront_info));
+ np = device_get_softc(dev);
np->xbdev = dev;
@@ -1699,14 +1698,15 @@ create_netdev(struct xenbus_device *dev, struct ifnet **ifpp)
err = xen_net_read_mac(dev, np->mac);
if (err) {
- xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
+ xenbus_dev_fatal(dev, err, "parsing %s/mac",
+ xenbus_get_node(dev));
goto out;
}
/* Set up ifnet structure */
- *ifpp = ifp = np->xn_ifp = if_alloc(IFT_ETHER);
+ ifp = np->xn_ifp = if_alloc(IFT_ETHER);
ifp->if_softc = np;
- if_initname(ifp, "xn", ifno++/* ifno */);
+ if_initname(ifp, "xn", device_get_unit(dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
ifp->if_ioctl = xn_ioctl;
ifp->if_output = ether_output;
@@ -1744,7 +1744,7 @@ out:
* acknowledgement.
*/
#if 0
-static void netfront_closing(struct xenbus_device *dev)
+static void netfront_closing(device_t dev)
{
#if 0
struct netfront_info *info = dev->dev_driver_data;
@@ -1757,14 +1757,13 @@ static void netfront_closing(struct xenbus_device *dev)
}
#endif
-static int netfront_remove(struct xenbus_device *dev)
+static int netfront_detach(device_t dev)
{
- struct netfront_info *info = dev->dev_driver_data;
+ struct netfront_info *info = device_get_softc(dev);
- DPRINTK("%s\n", dev->nodename);
+ DPRINTK("%s\n", xenbus_get_node(dev));
netif_free(info);
- free(info, M_DEVBUF);
return 0;
}
@@ -1806,48 +1805,27 @@ static void end_access(int ref, void *page)
gnttab_end_foreign_access(ref, page);
}
-
/* ** Driver registration ** */
-
-
-static struct xenbus_device_id netfront_ids[] = {
- { "vif" },
- { "" }
-};
-
-
-static struct xenbus_driver netfront = {
- .name = "vif",
- .ids = netfront_ids,
- .probe = netfront_probe,
- .remove = netfront_remove,
- .resume = netfront_resume,
- .otherend_changed = backend_changed,
-};
-
-static void
-netif_init(void *unused)
-{
- if (!is_running_on_xen())
- return;
-
- if (is_initial_xendomain())
- return;
-
- IPRINTK("Initialising virtual ethernet driver.\n");
-
- xenbus_register_frontend(&netfront);
-}
-
-SYSINIT(xennetif, SI_SUB_PSEUDO, SI_ORDER_SECOND, netif_init, NULL);
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 8
- * tab-width: 4
- * indent-tabs-mode: t
- * End:
- */
+static device_method_t netfront_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, netfront_probe),
+ DEVMETHOD(device_attach, netfront_attach),
+ DEVMETHOD(device_detach, netfront_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, netfront_resume),
+
+ /* Xenbus interface */
+ DEVMETHOD(xenbus_backend_changed, netfront_backend_changed),
+
+ { 0, 0 }
+};
+
+static driver_t netfront_driver = {
+ "xn",
+ netfront_methods,
+ sizeof(struct netfront_info),
+};
+devclass_t netfront_devclass;
+
+DRIVER_MODULE(xe, xenbus, netfront_driver, netfront_devclass, 0, 0);
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index 725a552..9f48702 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -867,9 +867,11 @@ initvalues(start_info_t *startinfo)
* Note that only one page directory has been allocated at this point.
* Thus, if KERNBASE
*/
+#if 0
for (i = 0; i < l2_pages; i++)
IdlePTDma[i] = xpmap_ptom(VTOP(IdlePTD + i*PAGE_SIZE));
-
+#endif
+
l2_pages = (l2_pages == 0) ? 1 : l2_pages;
#else
l3_pages = 0;
diff --git a/sys/xen/gnttab.c b/sys/xen/gnttab.c
index 896af7b..fdd3d1b 100644
--- a/sys/xen/gnttab.c
+++ b/sys/xen/gnttab.c
@@ -537,8 +537,8 @@ gnttab_expand(unsigned int req_entries)
return rc;
}
-static int
-gnttab_init(void *unused)
+int
+gnttab_init()
{
int i;
unsigned int max_nr_glist_frames;
@@ -593,4 +593,4 @@ ini_nomem:
}
MTX_SYSINIT(gnttab, &gnttab_list_lock, "GNTTAB LOCK", MTX_DEF);
-SYSINIT(gnttab, SI_SUB_PSEUDO, SI_ORDER_FIRST, gnttab_init, NULL);
+//SYSINIT(gnttab, SI_SUB_PSEUDO, SI_ORDER_FIRST, gnttab_init, NULL);
diff --git a/sys/xen/gnttab.h b/sys/xen/gnttab.h
index 6a24dd2..d1abe14 100644
--- a/sys/xen/gnttab.h
+++ b/sys/xen/gnttab.h
@@ -49,6 +49,8 @@ struct gnttab_free_callback {
uint16_t count;
};
+int gnttab_init(void);
+
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
int flags);
diff --git a/sys/xen/xenbus/xenbus_client.c b/sys/xen/xenbus/xenbus_client.c
index a6f9e6b..d8a1a3f 100644
--- a/sys/xen/xenbus/xenbus_client.c
+++ b/sys/xen/xenbus/xenbus_client.c
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xen-os.h>
#include <machine/xen/evtchn.h>
#include <xen/gnttab.h>
-#include <machine/xen/xenbus.h>
+#include <xen/xenbus/xenbusvar.h>
#include <machine/stdarg.h>
@@ -71,7 +71,7 @@ const char *xenbus_strstate(XenbusState state)
}
int
-xenbus_watch_path(struct xenbus_device *dev, char *path,
+xenbus_watch_path(device_t dev, char *path,
struct xenbus_watch *watch,
void (*callback)(struct xenbus_watch *,
const char **, unsigned int))
@@ -94,7 +94,7 @@ xenbus_watch_path(struct xenbus_device *dev, char *path,
EXPORT_SYMBOL(xenbus_watch_path);
-int xenbus_watch_path2(struct xenbus_device *dev, const char *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))
@@ -119,70 +119,27 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
}
EXPORT_SYMBOL(xenbus_watch_path2);
-
-int xenbus_switch_state(struct xenbus_device *dev,
- XenbusState state)
-{
- /* We check whether the state is currently set to the given value, and
- if not, then the state is set. We don't want to unconditionally
- write the given state, because we don't want to fire watches
- unnecessarily. Furthermore, if the node has gone, we don't write
- to it, as the device will be tearing down, and we don't want to
- resurrect that directory.
- */
-
- int current_state;
- int err;
-
- if (state == dev->state)
- return (0);
-
- err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
- &current_state);
- if (err != 1)
- return 0;
-
- err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
- if (err) {
- if (state != XenbusStateClosing) /* Avoid looping */
- xenbus_dev_fatal(dev, err, "writing new state");
- return err;
- }
-
- dev->state = state;
- return 0;
-
-}
-
-int xenbus_frontend_closed(struct xenbus_device *dev)
-{
- xenbus_switch_state(dev, XenbusStateClosed);
-#if 0
- complete(&dev->down);
-#endif
- return 0;
-}
-
/**
* 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(struct xenbus_device *dev)
+static char *error_path(device_t dev)
{
- char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
+ char *path_buffer = kmalloc(strlen("error/")
+ + strlen(xenbus_get_node(dev)) +
1, GFP_KERNEL);
if (path_buffer == NULL) {
return NULL;
}
strcpy(path_buffer, "error/");
- strcpy(path_buffer + strlen("error/"), dev->nodename);
+ strcpy(path_buffer + strlen("error/"), xenbus_get_node(dev));
return path_buffer;
}
-static void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
+static void _dev_error(device_t dev, int err, const char *fmt,
va_list ap)
{
int ret;
@@ -205,13 +162,13 @@ static void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
if (path_buffer == NULL) {
printk("xenbus: failed to write error node for %s (%s)\n",
- dev->nodename, printf_buffer);
+ 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",
- dev->nodename, printf_buffer);
+ xenbus_get_node(dev), printf_buffer);
goto fail;
}
@@ -223,7 +180,7 @@ static void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
}
-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
+void xenbus_dev_error(device_t dev, int err, const char *fmt,
...)
{
va_list ap;
@@ -235,7 +192,7 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
EXPORT_SYMBOL(xenbus_dev_error);
-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
+void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
...)
{
va_list ap;
@@ -244,14 +201,15 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
_dev_error(dev, err, fmt, ap);
va_end(ap);
- xenbus_switch_state(dev, XenbusStateClosing);
+ xenbus_set_state(dev, XenbusStateClosing);
}
EXPORT_SYMBOL(xenbus_dev_fatal);
-int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
+int xenbus_grant_ring(device_t dev, unsigned long ring_mfn)
{
- int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
+ 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;
@@ -259,13 +217,13 @@ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
EXPORT_SYMBOL(xenbus_grant_ring);
-int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
+int xenbus_alloc_evtchn(device_t dev, int *port)
{
struct evtchn_alloc_unbound alloc_unbound;
int err;
alloc_unbound.dom = DOMID_SELF;
- alloc_unbound.remote_dom = dev->otherend_id;
+ alloc_unbound.remote_dom = xenbus_get_otherend_id(dev);
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
@@ -279,7 +237,7 @@ int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
EXPORT_SYMBOL(xenbus_alloc_evtchn);
-int xenbus_free_evtchn(struct xenbus_device *dev, int port)
+int xenbus_free_evtchn(device_t dev, int port)
{
struct evtchn_close close;
int err;
diff --git a/sys/xen/xenbus/xenbus_comms.c b/sys/xen/xenbus/xenbus_comms.c
index 8f0f171..90f0ea9 100644
--- a/sys/xen/xenbus/xenbus_comms.c
+++ b/sys/xen/xenbus/xenbus_comms.c
@@ -31,8 +31,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
-#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <sys/param.h>
@@ -41,14 +41,12 @@ __FBSDID("$FreeBSD$");
#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/xenbus.h>
#include <machine/xen/xen_intr.h>
#include <xen/xenbus/xenbus_comms.h>
+#include <xen/interface/io/xs_wire.h>
static int xenbus_irq;
diff --git a/sys/xen/xenbus/xenbus_comms.h b/sys/xen/xenbus/xenbus_comms.h
index 871afd5..94a57dc 100644
--- a/sys/xen/xenbus/xenbus_comms.h
+++ b/sys/xen/xenbus/xenbus_comms.h
@@ -125,19 +125,14 @@ struct xen_bus_type
};
-extern void xenbus_backend_probe_and_watch(void);
-int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
- const char *nodename);
-int xenbus_probe_devices(struct xen_bus_type *bus);
-
-int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus);
+#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, ...);
diff --git a/sys/xen/xenbus/xenbus_dev.c b/sys/xen/xenbus/xenbus_dev.c
index 8a13322..52e0b67 100644
--- a/sys/xen/xenbus/xenbus_dev.c
+++ b/sys/xen/xenbus/xenbus_dev.c
@@ -44,16 +44,11 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/conf.h>
-
#include <machine/xen/xen-os.h>
#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/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
diff --git a/sys/xen/xenbus/xenbus_if.m b/sys/xen/xenbus/xenbus_if.m
new file mode 100644
index 0000000..018a2bb
--- /dev/null
+++ b/sys/xen/xenbus/xenbus_if.m
@@ -0,0 +1,37 @@
+#-
+# Copyright (c) 2008 Doug Rabson
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+#include <xen/interface/io/xenbus.h>
+
+INTERFACE xenbus;
+
+METHOD int backend_changed {
+ device_t dev;
+ enum xenbus_state newstate;
+};
diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c
index c45a375..e57e6e3 100644
--- a/sys/xen/xenbus/xenbus_probe.c
+++ b/sys/xen/xenbus/xenbus_probe.c
@@ -1,6 +1,7 @@
/******************************************************************************
* Talks to Xen Store to figure out what devices we have.
*
+ * Copyright (C) 2008 Doug Rabson
* Copyright (C) 2005 Rusty Russell, IBM Corporation
* Copyright (C) 2005 Mike Wray, Hewlett-Packard
* Copyright (C) 2005 XenSource Ltd
@@ -38,838 +39,355 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/time.h>
-#include <sys/sema.h>
-#include <sys/eventhandler.h>
-#include <sys/errno.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/systm.h>
+#include <sys/sysctl.h>
#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
+#include <sys/systm.h>
#include <sys/sx.h>
+#include <sys/taskqueue.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/xen/evtchn.h>
#include <machine/stdarg.h>
+#include <xen/gnttab.h>
+#include <xen/xenbus/xenbusvar.h>
#include <xen/xenbus/xenbus_comms.h>
-struct xendev_list_head xenbus_device_frontend_list;
-struct xendev_list_head xenbus_device_backend_list;
-static LIST_HEAD(, xenbus_driver) xendrv_list;
-
-extern struct sx xenwatch_mutex;
-
-EVENTHANDLER_DECLARE(xenstore_event, xenstore_event_handler_t);
-static struct eventhandler_list *xenstore_chain;
-device_t xenbus_dev;
-device_t xenbus_backend_dev;
-static MALLOC_DEFINE(M_XENDEV, "xenintrdrv", "xen system device");
-
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
-static int watch_otherend(struct xenbus_device *dev);
-
-
-/* If something in array of ids matches this device, return it. */
-static const struct xenbus_device_id *
-match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
-{
- for (; !streq(arr->devicetype, ""); arr++) {
- if (streq(arr->devicetype, dev->devicetype))
- return arr;
- }
- return NULL;
-}
-
-#if 0
-static int xenbus_match(device_t _dev)
-{
- struct xenbus_driver *drv;
- struct xenbus_device *dev;
-
- dev = device_get_softc(_dev);
- drv = dev->driver;
-
- if (!drv->ids)
- return 0;
-
- return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
-}
-#endif
-
-
-/* device/<type>/<id> => <type>-<id> */
-static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-{
- nodename = strchr(nodename, '/');
- if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
- log(LOG_WARNING, "XENBUS: bad frontend %s\n", nodename);
- return -EINVAL;
- }
-
- strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
- if (!strchr(bus_id, '/')) {
- log(LOG_WARNING, "XENBUS: bus_id %s no slash\n", bus_id);
- return -EINVAL;
- }
- *strchr(bus_id, '/') = '-';
- return 0;
-}
-
-
-static void free_otherend_details(struct xenbus_device *dev)
-{
- kfree((void*)(uintptr_t)dev->otherend);
- dev->otherend = NULL;
-}
-
-
-static void free_otherend_watch(struct xenbus_device *dev)
-{
- if (dev->otherend_watch.node) {
- unregister_xenbus_watch(&dev->otherend_watch);
- kfree(dev->otherend_watch.node);
- dev->otherend_watch.node = NULL;
- }
-}
-
-int
-read_otherend_details(struct xenbus_device *xendev, char *id_node,
- char *path_node)
-{
- int err = xenbus_gather(XBT_NIL, xendev->nodename,
- id_node, "%i", &xendev->otherend_id,
- path_node, NULL, &xendev->otherend,
- NULL);
- if (err) {
- xenbus_dev_fatal(xendev, err,
- "reading other end details from %s",
- xendev->nodename);
- return err;
- }
- if (strlen(xendev->otherend) == 0 ||
- !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
- xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
- xendev->nodename);
- kfree((void *)(uintptr_t)xendev->otherend);
- xendev->otherend = NULL;
- return -ENOENT;
- }
-
- return 0;
-}
-
-
-static int read_backend_details(struct xenbus_device *xendev)
-{
- return read_otherend_details(xendev, "backend-id", "backend");
-}
-
-#ifdef notyet
-/* XXX - move to probe backend */
-static int read_frontend_details(struct xenbus_device *xendev)
-{
- if (strncmp(xendev->nodename, "backend", 7))
- return -ENOENT;
- return read_otherend_details(xendev, "frontend-id", "frontend");
-}
-#endif
-
-/* Bus type for frontend drivers. */
-static int xenbus_probe_frontend(const char *type, const char *name);
-static struct xen_bus_type xenbus_frontend = {
- .root = "device",
- .levels = 2, /* device/type/<id> */
- .get_bus_id = frontend_bus_id,
- .probe = xenbus_probe_frontend,
- .bus = &xenbus_device_frontend_list,
-#if 0
- /* this initialization needs to happen dynamically */
- .bus = {
- .name = "xen",
- .match = xenbus_match,
- },
- .dev = {
- .bus_id = "xen",
- },
-#endif
+struct xenbus_softc {
+ struct xenbus_watch xs_devicewatch;
+ struct task xs_probechildren;
+ struct intr_config_hook xs_attachcb;
+ device_t xs_dev;
};
-#if 0
-static int xenbus_hotplug_backend(device_t dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
-{
- panic("implement me");
-#if 0
- struct xenbus_device *xdev;
- struct xenbus_driver *drv = NULL;
- int i = 0;
- int length = 0;
- char *basepath_end;
- char *frontend_id;
-
- DPRINTK("");
-
- if (dev == NULL)
- return -ENODEV;
-
- xdev = to_xenbus_device(dev);
- if (xdev == NULL)
- return -ENODEV;
-
- if (dev->driver)
- drv = to_xenbus_driver(dev->driver);
-
- /* stuff we want to pass to /sbin/hotplug */
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_TYPE=%s", xdev->devicetype);
-
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_PATH=%s", xdev->nodename);
-
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_BASE_PATH=%s", xdev->nodename);
-
- basepath_end = strrchr(envp[i - 1], '/');
- length -= strlen(basepath_end);
- *basepath_end = '\0';
- basepath_end = strrchr(envp[i - 1], '/');
- length -= strlen(basepath_end);
- *basepath_end = '\0';
-
- basepath_end++;
- frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL);
- strcpy(frontend_id, basepath_end);
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_FRONTEND_ID=%s", frontend_id);
- kfree(frontend_id);
-
- /* terminate, set to next free slot, shrink available space */
- envp[i] = NULL;
- envp = &envp[i];
- num_envp -= i;
- buffer = &buffer[length];
- buffer_size -= length;
-
- if (drv && drv->hotplug)
- return drv->hotplug(xdev, envp, num_envp, buffer, buffer_size);
-
-#endif
- return 0;
-}
-#endif
-
-#if 0
-static int xenbus_probe_backend(const char *type, const char *domid, int unit);
-static struct xen_bus_type xenbus_backend = {
- .root = "backend",
- .levels = 3, /* backend/type/<frontend>/<id> */
- .get_bus_id = backend_bus_id,
- .probe = xenbus_probe_backend,
- /* at init time */
- .bus = &xenbus_device_backend_list,
-#if 0
- .bus = {
- .name = "xen-backend",
- .match = xenbus_match,
- .hotplug = xenbus_hotplug_backend,
- },
- .dev = {
- .bus_id = "xen-backend",
- },
-#endif
+struct xenbus_device_ivars {
+ struct xenbus_watch xd_otherend_watch; /* must be first */
+ struct sx xd_lock;
+ device_t xd_dev;
+ char *xd_node; /* node name in xenstore */
+ char *xd_type; /* xen device type */
+ enum xenbus_state xd_state;
+ int xd_otherend_id;
+ char *xd_otherend_path;
};
-#endif
-static void otherend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
+/* Simplified asprintf. */
+char *
+kasprintf(const char *fmt, ...)
{
+ va_list ap;
+ unsigned int len;
+ char *p, dummy[1];
- struct xenbus_device *dev = (struct xenbus_device *)watch;
- struct xenbus_driver *drv = dev->driver;
- XenbusState state;
-
- /* Protect us against watches firing on old details when the otherend
- details change, say immediately after a resume. */
- if (!dev->otherend || strncmp(dev->otherend, vec[XS_WATCH_PATH],
- strlen(dev->otherend))) {
- DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
- return;
- }
-
- state = xenbus_read_driver_state(dev->otherend);
-
- DPRINTK("state is %d, %s, %s", state, dev->otherend_watch.node,
- vec[XS_WATCH_PATH]);
-
- /*
- * Ignore xenbus transitions during shutdown. This prevents us doing
- * work that can fail e.g., when the rootfs is gone.
- */
-#if 0
- if (system_state > SYSTEM_RUNNING) {
- struct xen_bus_type *bus = bus;
- bus = container_of(dev->dev.bus, struct xen_bus_type, bus);
- /* If we're frontend, drive the state machine to Closed. */
- /* This should cause the backend to release our resources. */
- if ((bus == &xenbus_frontend) && (state == XenbusStateClosing))
- xenbus_frontend_closed(dev);
- return;
- }
-#endif
- if (drv->otherend_changed)
- drv->otherend_changed(dev, state);
+ va_start(ap, fmt);
+ /* FIXME: vsnprintf has a bug, NULL should work */
+ len = vsnprintf(dummy, 0, fmt, ap);
+ va_end(ap);
+ p = kmalloc(len + 1, GFP_KERNEL);
+ if (!p)
+ return NULL;
+ va_start(ap, fmt);
+ vsprintf(p, fmt, ap);
+ va_end(ap);
+ return p;
}
-
-static int talk_to_otherend(struct xenbus_device *dev)
+static void
+xenbus_identify(driver_t *driver, device_t parent)
{
- struct xenbus_driver *drv;
-
- drv = dev->driver;
-
- free_otherend_watch(dev);
- free_otherend_details(dev);
-
- return drv->read_otherend_details(dev);
-}
-static int watch_otherend(struct xenbus_device *dev)
-{
- return xenbus_watch_path2(dev, dev->otherend, "state",
- &dev->otherend_watch, otherend_changed);
+ BUS_ADD_CHILD(parent, 0, "xenbus", 0);
}
static int
-xenbus_dev_probe(struct xenbus_device *dev)
+xenbus_probe(device_t dev)
{
- struct xenbus_driver *drv = dev->driver;
- const struct xenbus_device_id *id;
- int err;
-
+ int err = 0;
+
DPRINTK("");
-
- if (!drv->probe) {
- err = -ENODEV;
- goto fail;
- }
-
- id = match_device(drv->ids, dev);
- if (!id) {
- err = -ENODEV;
- goto fail;
- }
-
- err = talk_to_otherend(dev);
+
+ /* Initialize the interface to xenstore. */
+ err = xs_init();
if (err) {
- log(LOG_WARNING,
- "xenbus_probe: talk_to_otherend on %s failed.\n",
- dev->nodename);
- return err;
+ log(LOG_WARNING,
+ "XENBUS: Error initializing xenstore comms: %i\n", err);
+ return (ENXIO);
}
-
- err = drv->probe(dev, id);
- if (err)
- goto fail;
-
- err = watch_otherend(dev);
+ err = gnttab_init();
if (err) {
- log(LOG_WARNING,
- "xenbus_probe: watch_otherend on %s failed.\n",
- dev->nodename);
- return err;
+ log(LOG_WARNING,
+ "XENBUS: Error initializing grant table: %i\n", err);
+ return (ENXIO);
}
-
- return 0;
- fail:
- xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
- xenbus_switch_state(dev, XenbusStateClosed);
- return -ENODEV;
-}
+ device_set_desc(dev, "Xen Devices");
-static void xenbus_dev_free(struct xenbus_device *xendev)
-{
- LIST_REMOVE(xendev, list);
- kfree(xendev);
+ return (0);
}
-int
-xenbus_remove_device(struct xenbus_device *dev)
+static enum xenbus_state
+xenbus_otherend_state(struct xenbus_device_ivars *ivars)
{
- struct xenbus_driver *drv = dev->driver;
-
- DPRINTK("");
-
- free_otherend_watch(dev);
- free_otherend_details(dev);
- if (drv->remove)
- drv->remove(dev);
-
- xenbus_switch_state(dev, XenbusStateClosed);
-
- if (drv->cleanup_device)
- return drv->cleanup_device(dev);
-
- xenbus_dev_free(dev);
-
- return 0;
-}
-
-#if 0
-static int
-xenbus_dev_remove(device_t _dev)
-{
- return xenbus_remove_device(to_xenbus_device(_dev));
+ return (xenbus_read_driver_state(ivars->xd_otherend_path));
}
-#endif
-int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus)
+static void
+xenbus_backend_changed(struct xenbus_watch *watch, const char **vec,
+ unsigned int len)
{
- struct xenbus_device *xdev;
-
-#if 0
- int ret;
- /* this all happens in the driver itself
- * doing this here simple serves to obfuscate
- */
+ struct xenbus_device_ivars *ivars;
+ device_t dev;
+ enum xenbus_state newstate;
- drv->driver.name = drv->name;
- drv->driver.bus = &bus->bus;
- drv->driver.owner = drv->owner;
- drv->driver.probe = xenbus_dev_probe;
- drv->driver.remove = xenbus_dev_remove;
+ ivars = (struct xenbus_device_ivars *) watch;
+ dev = ivars->xd_dev;
- return ret;
-#endif
- sx_xlock(&xenwatch_mutex);
- LIST_INSERT_HEAD(&xendrv_list, drv, list);
- sx_xunlock(&xenwatch_mutex);
- LIST_FOREACH(xdev, bus->bus, list) {
- if (match_device(drv->ids, xdev)) {
- xdev->driver = drv;
- xenbus_dev_probe(xdev);
- }
- }
- return 0;
-}
-
-int xenbus_register_frontend(struct xenbus_driver *drv)
-{
- drv->read_otherend_details = read_backend_details;
+ if (!ivars->xd_otherend_path
+ || strncmp(ivars->xd_otherend_path, vec[XS_WATCH_PATH],
+ strlen(ivars->xd_otherend_path)))
+ return;
- return xenbus_register_driver_common(drv, &xenbus_frontend);
+ newstate = xenbus_otherend_state(ivars);
+ XENBUS_BACKEND_CHANGED(dev, newstate);
}
-EXPORT_SYMBOL(xenbus_register_frontend);
-
-void xenbus_unregister_driver(struct xenbus_driver *drv)
+static int
+xenbus_device_exists(device_t dev, const char *node)
{
-#if 0
- driver_unregister(&drv->driver);
-#endif
-}
-EXPORT_SYMBOL(xenbus_unregister_driver);
+ device_t *kids;
+ struct xenbus_device_ivars *ivars;
+ int i, count, result;
-struct xb_find_info
-{
- struct xenbus_device *dev;
- const char *nodename;
-};
+ if (device_get_children(dev, &kids, &count))
+ return (FALSE);
-static struct xenbus_device *
-xenbus_device_find(const char *nodename, struct xendev_list_head *bus)
-{
- struct xenbus_device *xdev;
- LIST_FOREACH(xdev, bus, list) {
- if (streq(xdev->nodename, nodename)) {
- return xdev;
-#if 0
- get_device(dev);
-#endif
+ result = FALSE;
+ for (i = 0; i < count; i++) {
+ ivars = device_get_ivars(kids[i]);
+ if (!strcmp(ivars->xd_node, node)) {
+ result = TRUE;
+ break;
}
}
- return NULL;
-}
-#if 0
-static int cleanup_dev(device_t dev, void *data)
-{
- struct xenbus_device *xendev = device_get_softc(dev);
- struct xb_find_info *info = data;
- int len = strlen(info->nodename);
+ free(kids, M_TEMP);
- DPRINTK("%s", info->nodename);
-
- if (!strncmp(xendev->nodename, info->nodename, len)) {
- info->dev = xendev;
-#if 0
- get_device(dev);
-#endif
- return 1;
- }
- return 0;
+ return (result);
}
-#endif
-static void xenbus_cleanup_devices(const char *path, struct xendev_list_head * bus)
+static int
+xenbus_add_device(device_t dev, const char *bus,
+ const char *type, const char *id)
{
-#if 0
- struct xb_find_info info = { .nodename = path };
-
- do {
- info.dev = NULL;
- bus_for_each_dev(bus, NULL, &info, cleanup_dev);
- if (info.dev) {
- device_unregister(&info.dev->dev);
- put_device(&info.dev->dev);
- }
- } while (info.dev);
-#endif
-}
+ device_t child;
+ struct xenbus_device_ivars *ivars;
+ enum xenbus_state state;
+ char *statepath;
-#if 0
-void xenbus_dev_release(device_t dev)
-{
- /*
- * nothing to do softc gets freed with the device
- */
-
-}
-#endif
-/* Simplified asprintf. */
-char *kasprintf(const char *fmt, ...)
-{
- va_list ap;
- unsigned int len;
- char *p, dummy[1];
+ ivars = malloc(sizeof(struct xenbus_device_ivars),
+ M_DEVBUF, M_ZERO|M_WAITOK);
+ ivars->xd_node = kasprintf("%s/%s/%s", bus, type, id);
- va_start(ap, fmt);
- /* FIXME: vsnprintf has a bug, NULL should work */
- len = vsnprintf(dummy, 0, fmt, ap);
- va_end(ap);
-
- p = kmalloc(len + 1, GFP_KERNEL);
- if (!p)
- return NULL;
- va_start(ap, fmt);
- vsprintf(p, fmt, ap);
- va_end(ap);
- return p;
-}
-
-#if 0
-static ssize_t xendev_show_nodename(struct device *dev, char *buf)
-{
- return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
-}
-DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
-
-static ssize_t xendev_show_devtype(struct device *dev, char *buf)
-{
- return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
-}
-DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
-#endif
-
-int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
- const char *nodename)
-{
-#define CHECK_FAIL \
- do { \
- if (err) \
- goto fail; \
- } while (0) \
-
-
-
- int err;
- struct xenbus_device *xendev;
- struct xenbus_driver *xdrv;
- size_t stringlen;
- char *tmpstring;
+ if (xenbus_device_exists(dev, ivars->xd_node)) {
+ /*
+ * We are already tracking this node
+ */
+ free(ivars->xd_node, M_DEVBUF);
+ free(ivars, M_DEVBUF);
+ return (0);
+ }
- XenbusState state = xenbus_read_driver_state(nodename);
+ state = xenbus_read_driver_state(ivars->xd_node);
- if (bus->error)
- return (bus->error);
-
-
if (state != XenbusStateInitialising) {
- /* Device is not new, so ignore it. This can happen if a
- device is going away after switching to Closed. */
- return 0;
+ /*
+ * Device is not new, so ignore it. This can
+ * happen if a device is going away after
+ * switching to Closed.
+ */
+ free(ivars->xd_node, M_DEVBUF);
+ free(ivars, M_DEVBUF);
+ return (0);
}
-
- stringlen = strlen(nodename) + 1 + strlen(type) + 1;
- xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
- if (!xendev)
- return -ENOMEM;
- memset(xendev, 0, sizeof(*xendev));
- xendev->state = XenbusStateInitialising;
-
- /* Copy the strings into the extra space. */
-
- tmpstring = (char *)(xendev + 1);
- strcpy(tmpstring, nodename);
- xendev->nodename = tmpstring;
-
- tmpstring += strlen(tmpstring) + 1;
- strcpy(tmpstring, type);
- xendev->devicetype = tmpstring;
+
/*
- * equivalent to device registration
- * events
+ * Find the backend details
*/
- LIST_INSERT_HEAD(bus->bus, xendev, list);
- LIST_FOREACH(xdrv, &xendrv_list, list) {
- if (match_device(xdrv->ids, xendev)) {
- xendev->driver = xdrv;
- if (!xenbus_dev_probe(xendev))
- break;
- }
- }
+ xenbus_gather(XBT_NIL, ivars->xd_node,
+ "backend-id", "%i", &ivars->xd_otherend_id,
+ "backend", NULL, &ivars->xd_otherend_path,
+ NULL);
-#if 0
- xendev->dev.parent = &bus->dev;
- xendev->dev.bus = &bus->bus;
- xendev->dev.release = xenbus_dev_release;
-
- err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
- CHECK_FAIL;
-
- /* Register with generic device framework. */
- err = device_register(&xendev->dev);
- CHECK_FAIL;
-
- device_create_file(&xendev->dev, &dev_attr_nodename);
- device_create_file(&xendev->dev, &dev_attr_devtype);
-#endif
- return 0;
-
-#undef CHECK_FAIL
-#if 0
- fail:
- xenbus_dev_free(xendev);
-#endif
- return err;
-}
+ sx_init(&ivars->xd_lock, "xdlock");
+ ivars->xd_type = strdup(type, M_DEVBUF);
+ ivars->xd_state = XenbusStateInitialising;
-/* device/<typename>/<name> */
-static int xenbus_probe_frontend(const char *type, const char *name)
-{
- char *nodename;
- int err;
+ statepath = malloc(strlen(ivars->xd_otherend_path)
+ + strlen("/state") + 1, M_DEVBUF, M_NOWAIT);
+ sprintf(statepath, "%s/state", ivars->xd_otherend_path);
- nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
- if (!nodename)
- return -ENOMEM;
+ ivars->xd_otherend_watch.node = statepath;
+ ivars->xd_otherend_watch.callback = xenbus_backend_changed;
- DPRINTK("%s", nodename);
+ child = device_add_child(dev, NULL, -1);
+ ivars->xd_dev = child;
+ device_set_ivars(child, ivars);
- err = xenbus_probe_node(&xenbus_frontend, type, nodename);
- kfree(nodename);
- return err;
+ return (0);
}
-static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
+static int
+xenbus_enumerate_type(device_t dev, const char *bus, const char *type)
{
- int err = 0;
char **dir;
- unsigned int dir_n = 0;
- int i;
+ unsigned int i, count;
- dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
+ dir = xenbus_directory(XBT_NIL, bus, type, &count);
if (IS_ERR(dir))
- return PTR_ERR(dir);
+ return (EINVAL);
+ for (i = 0; i < count; i++)
+ xenbus_add_device(dev, bus, type, dir[i]);
- for (i = 0; i < dir_n; i++) {
- err = bus->probe(type, dir[i]);
- if (err)
- break;
- }
- kfree(dir);
- return err;
+ free(dir, M_DEVBUF);
+
+ return (0);
}
-int xenbus_probe_devices(struct xen_bus_type *bus)
+static int
+xenbus_enumerate_bus(device_t dev, const char *bus)
{
- int err = 0;
char **dir;
- unsigned int i, dir_n;
+ unsigned int i, count;
- dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
+ dir = xenbus_directory(XBT_NIL, bus, "", &count);
if (IS_ERR(dir))
- return PTR_ERR(dir);
-
- for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_device_type(bus, dir[i]);
- if (err)
- break;
+ return (EINVAL);
+ for (i = 0; i < count; i++) {
+ xenbus_enumerate_type(dev, bus, dir[i]);
}
- kfree(dir);
+ free(dir, M_DEVBUF);
- return err;
+ return (0);
}
-static unsigned int char_count(const char *str, char c)
+static int
+xenbus_probe_children(device_t dev)
{
- unsigned int i, ret = 0;
+ device_t *kids;
+ struct xenbus_device_ivars *ivars;
+ int i, count;
+
+ /*
+ * Probe any new devices and register watches for any that
+ * attach successfully. Since part of the protocol which
+ * establishes a connection with the other end is interrupt
+ * driven, we sleep until the device reaches a stable state
+ * (closed or connected).
+ */
+ if (device_get_children(dev, &kids, &count) == 0) {
+ for (i = 0; i < count; i++) {
+ if (device_get_state(kids[i]) != DS_NOTPRESENT)
+ continue;
+
+ if (device_probe_and_attach(kids[i]))
+ continue;
+ ivars = device_get_ivars(kids[i]);
+ register_xenbus_watch(
+ &ivars->xd_otherend_watch);
+ sx_xlock(&ivars->xd_lock);
+ while (ivars->xd_state != XenbusStateClosed
+ && ivars->xd_state != XenbusStateConnected)
+ sx_sleep(&ivars->xd_state, &ivars->xd_lock,
+ 0, "xdattach", 0);
+ sx_xunlock(&ivars->xd_lock);
+ }
+ free(kids, M_TEMP);
+ }
- for (i = 0; str[i]; i++)
- if (str[i] == c)
- ret++;
- return ret;
+ return (0);
}
-static int strsep_len(const char *str, char c, unsigned int len)
+static void
+xenbus_probe_children_cb(void *arg, int pending)
{
- unsigned int i;
+ device_t dev = (device_t) arg;
- for (i = 0; str[i]; i++)
- if (str[i] == c) {
- if (len == 0)
- return i;
- len--;
- }
- return (len == 0) ? i : -ERANGE;
+ xenbus_probe_children(dev);
}
-void dev_changed(const char *node, struct xen_bus_type *bus)
+static void
+xenbus_devices_changed(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
{
- int exists, rootlen;
- struct xenbus_device *dev;
- char type[BUS_ID_SIZE];
- const char *p;
- char *root;
-
- DPRINTK("");
- if (char_count(node, '/') < 2)
- return;
-
- exists = xenbus_exists(XBT_NIL, node, "");
- if (!exists) {
- xenbus_cleanup_devices(node, bus->bus);
- return;
- }
-
- /* backend/<type>/... or device/<type>/... */
- p = strchr(node, '/') + 1;
- snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
- type[BUS_ID_SIZE-1] = '\0';
+ struct xenbus_softc *sc = (struct xenbus_softc *) watch;
+ device_t dev = sc->xs_dev;
+ char *node, *bus, *type, *id, *p;
- rootlen = strsep_len(node, '/', bus->levels);
- if (rootlen < 0)
- return;
- root = kasprintf("%.*s", rootlen, node);
- if (!root)
- return;
+ node = strdup(vec[XS_WATCH_PATH], M_DEVBUF);;
+ p = strchr(node, '/');
+ if (!p)
+ goto out;
+ bus = node;
+ *p = 0;
+ type = p + 1;
- dev = xenbus_device_find(root, bus->bus);
- if (!dev)
- xenbus_probe_node(bus, type, root);
-#if 0
- else
- put_device(&dev->dev);
-#endif
- kfree(root);
-}
+ p = strchr(type, '/');
+ if (!p)
+ goto out;
+ *p = 0;
+ id = p + 1;
-static void frontend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
-{
- DPRINTK("");
+ p = strchr(id, '/');
+ if (p)
+ *p = 0;
- dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
+ xenbus_add_device(dev, bus, type, id);
+ taskqueue_enqueue(taskqueue_thread, &sc->xs_probechildren);
+out:
+ free(node, M_DEVBUF);
}
-/* We watch for devices appearing and vanishing. */
-static struct xenbus_watch fe_watch = {
- .node = "device",
- .callback = frontend_changed,
-};
-
-#ifdef notyet
-
-static int suspend_dev(device_t dev, void *data)
+static void
+xenbus_attach_deferred(void *arg)
{
- int err = 0;
- struct xenbus_driver *drv;
- struct xenbus_device *xdev;
-
- DPRINTK("");
+ device_t dev = (device_t) arg;
+ struct xenbus_softc *sc = device_get_softc(dev);
+ int error;
+
+ error = xenbus_enumerate_bus(dev, "device");
+ if (error)
+ return;
+ xenbus_probe_children(dev);
- xdev = device_get_softc(dev);
+ sc->xs_dev = dev;
+ sc->xs_devicewatch.node = "device";
+ sc->xs_devicewatch.callback = xenbus_devices_changed;
- drv = xdev->driver;
+ TASK_INIT(&sc->xs_probechildren, 0, xenbus_probe_children_cb, dev);
- if (device_get_driver(dev) == NULL)
- return 0;
+ register_xenbus_watch(&sc->xs_devicewatch);
- if (drv->suspend)
- err = drv->suspend(xdev);
-#if 0
- /* bus_id ? */
- if (err)
- log(LOG_WARNING, "xenbus: suspend %s failed: %i\n",
- dev->bus_id, err);
-#endif
- return 0;
+ config_intrhook_disestablish(&sc->xs_attachcb);
}
-
-
-static int resume_dev(device_t dev, void *data)
+static int
+xenbus_attach(device_t dev)
{
- int err;
- struct xenbus_driver *drv;
- struct xenbus_device *xdev;
+ struct xenbus_softc *sc = device_get_softc(dev);
- DPRINTK("");
+ sc->xs_attachcb.ich_func = xenbus_attach_deferred;
+ sc->xs_attachcb.ich_arg = dev;
+ config_intrhook_establish(&sc->xs_attachcb);
- if (device_get_driver(dev) == NULL)
- return 0;
- xdev = device_get_softc(dev);
- drv = xdev->driver;
-
- err = talk_to_otherend(xdev);
-#if 0
- if (err) {
- log(LOG_WARNING,
- "xenbus: resume (talk_to_otherend) %s failed: %i\n",
- dev->bus_id, err);
- return err;
- }
-#endif
- if (drv->resume)
- err = drv->resume(xdev);
-
- err = watch_otherend(xdev);
-#if 0
- /* bus_id? */
- if (err)
- log(LOG_WARNING,
- "xenbus: resume %s failed: %i\n", dev->bus_id, err);
-#endif
- return err;
+ return (0);
}
-#endif
-void xenbus_suspend(void)
+static void
+xenbus_suspend(device_t dev)
{
DPRINTK("");
panic("implement me");
@@ -879,9 +397,9 @@ void xenbus_suspend(void)
#endif
xs_suspend();
}
-EXPORT_SYMBOL(xenbus_suspend);
-void xenbus_resume(void)
+static void
+xenbus_resume(device_t dev)
{
xb_init_comms();
xs_resume();
@@ -891,218 +409,115 @@ void xenbus_resume(void)
bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
#endif
}
-EXPORT_SYMBOL(xenbus_resume);
-
-#if 0
-static device_t
-xenbus_add_child(device_t bus, int order, const char *name, int unit)
-{
- device_t child;
-
- child = device_add_child_ordered(bus, order, name, unit);
-
- return(child);
-}
-#endif
-
-/* A flag to determine if xenstored is 'ready' (i.e. has started) */
-int xenstored_ready = 0;
-
-int register_xenstore_notifier(xenstore_event_handler_t func, void *arg, int priority)
+static int
+xenbus_print_child(device_t dev, device_t child)
{
- int ret = 0;
+ struct xenbus_device_ivars *ivars = device_get_ivars(child);
+ int retval = 0;
- if (xenstored_ready > 0)
- ret = func(NULL);
- else
- eventhandler_register(xenstore_chain, "xenstore", func, arg, priority);
+ retval += bus_print_child_header(dev, child);
+ retval += printf(" at %s", ivars->xd_node);
+ retval += bus_print_child_footer(dev, child);
- return ret;
+ return (retval);
}
-EXPORT_SYMBOL(register_xenstore_notifier);
-#if 0
-void unregister_xenstore_notifier(struct notifier_block *nb)
-{
- notifier_chain_unregister(&xenstore_chain, nb);
-}
-EXPORT_SYMBOL(unregister_xenstore_notifier);
-#endif
-
-
-#ifdef DOM0
-static struct proc_dir_entry *xsd_mfn_intf;
-static struct proc_dir_entry *xsd_port_intf;
-
-
-static int xsd_mfn_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int
+xenbus_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t * result)
{
- int len;
- len = sprintf(page, "%ld", xen_start_info->store_mfn);
- *eof = 1;
- return len;
-}
+ struct xenbus_device_ivars *ivars = device_get_ivars(child);
-static int xsd_port_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
+ switch (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);
- len = sprintf(page, "%d", xen_start_info->store_evtchn);
- *eof = 1;
- return len;
-}
+ case XENBUS_IVAR_OTHEREND_ID:
+ *result = (uintptr_t) ivars->xd_otherend_id;
+ return (0);
-#endif
-
-static int dom0 = 0;
-
-static int
-xenbus_probe_sysinit(void *unused)
-{
- int err = 0;
-
- DPRINTK("");
-
- LIST_INIT(&xenbus_device_frontend_list);
- LIST_INIT(&xenbus_device_backend_list);
- LIST_INIT(&xendrv_list);
-#if 0
- if (xen_init() < 0) {
- DPRINTK("failed");
- return -ENODEV;
+ case XENBUS_IVAR_OTHEREND_PATH:
+ *result = (uintptr_t) ivars->xd_otherend_path;
+ return (0);
}
+ return (ENOENT);
+}
- /* Register ourselves with the kernel bus & device subsystems */
- bus_register(&xenbus_frontend.bus);
- bus_register(&xenbus_backend.bus);
- device_register(&xenbus_frontend.dev);
- device_register(&xenbus_backend.dev);
-#endif
-
- /*
- ** Domain0 doesn't have a store_evtchn or store_mfn yet.
- */
- dom0 = (xen_start_info->store_evtchn == 0);
-
-
-#ifdef DOM0
- if (dom0) {
-
- unsigned long page;
- evtchn_op_t op = { 0 };
- int ret;
-
+static int
+xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
+{
+ struct xenbus_device_ivars *ivars = device_get_ivars(child);
+ enum xenbus_state newstate;
+ int currstate;
+ int error;
- /* Allocate page. */
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
+ switch (index) {
+ case XENBUS_IVAR_STATE:
+ newstate = (enum xenbus_state) value;
+ sx_xlock(&ivars->xd_lock);
+ if (ivars->xd_state == newstate)
+ goto out;
- /* We don't refcnt properly, so set reserved on page.
- * (this allocation is permanent) */
- SetPageReserved(virt_to_page(page));
+ error = xenbus_scanf(XBT_NIL, ivars->xd_node, "state",
+ "%d", &currstate);
+ if (error < 0)
+ goto out;
- xen_start_info->store_mfn =
- pfn_to_mfn(virt_to_phys((void *)page) >>
- PAGE_SHIFT);
-
- /* Next allocate a local port which xenstored can bind to */
- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = 0;
-
- ret = HYPERVISOR_event_channel_op(&op);
- BUG_ON(ret);
- xen_start_info->store_evtchn = op.u.alloc_unbound.port;
-
- /* And finally publish the above info in /proc/xen */
- if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400)))
- xsd_mfn_intf->read_proc = xsd_mfn_read;
- if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
- xsd_port_intf->read_proc = xsd_port_read;
- }
-#endif
- /* Initialize the interface to xenstore. */
- err = xs_init();
- if (err) {
- log(LOG_WARNING,
- "XENBUS: Error initializing xenstore comms: %i\n", err);
- return err;
+ error = xenbus_printf(XBT_NIL, ivars->xd_node, "state",
+ "%d", newstate);
+ if (error) {
+ if (newstate != XenbusStateClosing) /* Avoid looping */
+ xenbus_dev_fatal(dev, error, "writing new state");
+ goto out;
+ }
+ ivars->xd_state = newstate;
+ wakeup(&ivars->xd_state);
+ out:
+ sx_xunlock(&ivars->xd_lock);
+ return (0);
+
+ case XENBUS_IVAR_NODE:
+ case XENBUS_IVAR_TYPE:
+ case XENBUS_IVAR_OTHEREND_ID:
+ case XENBUS_IVAR_OTHEREND_PATH:
+ /*
+ * These variables are read-only.
+ */
+ return (EINVAL);
}
-
- return 0;
+ return (ENOENT);
}
-
-static int
-xenbus_probe_sysinit2(void *unused)
-{
- if (!dom0) {
- xenstored_ready = 1;
+SYSCTL_DECL(_dev);
+SYSCTL_NODE(_dev, OID_AUTO, xen, CTLFLAG_RD, NULL, "Xen");
#if 0
- xenbus_dev = BUS_ADD_CHILD(parent, 0, "xenbus", 0);
- if (xenbus_dev == NULL)
- panic("xenbus: could not attach");
- xenbus_backend_dev = BUS_ADD_CHILD(parent, 0, "xb_be", 0);
- if (xenbus_backend_dev == NULL)
- panic("xenbus: could not attach");
+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
- BUG_ON((xenstored_ready <= 0));
-
-
- /* Enumerate devices in xenstore. */
- xenbus_probe_devices(&xenbus_frontend);
- register_xenbus_watch(&fe_watch);
- xenbus_backend_probe_and_watch();
-
- /* Notify others that xenstore is up */
- EVENTHANDLER_INVOKE(xenstore_event);
- }
- return (0);
-}
-
-
-SYSINIT(xenbus_probe_sysinit, SI_SUB_PSEUDO, SI_ORDER_FIRST, xenbus_probe_sysinit, NULL);
-SYSINIT(xenbus_probe_sysinit2, SI_SUB_PSEUDO, SI_ORDER_ANY,
- xenbus_probe_sysinit2, NULL);
-
-#if 0
static device_method_t xenbus_methods[] = {
/* Device interface */
-#if 0
- DEVMETHOD(device_identify, xenbus_identify),
+ DEVMETHOD(device_identify, xenbus_identify),
DEVMETHOD(device_probe, xenbus_probe),
DEVMETHOD(device_attach, xenbus_attach),
-
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
-#endif
DEVMETHOD(device_suspend, xenbus_suspend),
DEVMETHOD(device_resume, xenbus_resume),
/* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_add_child, xenbus_add_child),
- DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
- DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
-#if 0
- DEVMETHOD(bus_set_resource, bus_generic_set_resource),
- DEVMETHOD(bus_get_resource, bus_generic_get_resource),
-#endif
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
-#if 0
- DEVMETHOD(bus_delete_resource, bus_generic_delete_resource),
-#endif
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_print_child, xenbus_print_child),
+ DEVMETHOD(bus_read_ivar, xenbus_read_ivar),
+ DEVMETHOD(bus_write_ivar, xenbus_write_ivar),
{ 0, 0 }
};
@@ -1111,24 +526,12 @@ static char driver_name[] = "xenbus";
static driver_t xenbus_driver = {
driver_name,
xenbus_methods,
- sizeof(struct xenbus_device),
+ sizeof(struct xenbus_softc),
};
devclass_t xenbus_devclass;
-DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0);
-
+#ifdef XENHVM
+DRIVER_MODULE(xenbus, xenpci, xenbus_driver, xenbus_devclass, 0, 0);
+#else
+DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0);
#endif
-
-
-
-
-
-/*
- * 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/xenbus_probe_backend.c b/sys/xen/xenbus/xenbus_probe_backend.c
index 3cb8e67..af83fe6 100644
--- a/sys/xen/xenbus/xenbus_probe_backend.c
+++ b/sys/xen/xenbus/xenbus_probe_backend.c
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xen-os.h>
#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
#include <machine/xen/evtchn.h>
#include <machine/stdarg.h>
diff --git a/sys/xen/xenbus/xenbus_xs.c b/sys/xen/xenbus/xenbus_xs.c
index a5d8a34..332a509 100644
--- a/sys/xen/xenbus/xenbus_xs.c
+++ b/sys/xen/xenbus/xenbus_xs.c
@@ -53,9 +53,9 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xen-os.h>
#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.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);
@@ -788,8 +788,6 @@ static void xenwatch_thread(void *unused)
{
struct xs_stored_msg *msg;
- xenwatch_running = 1;
-
DELAY(100000);
while (xenwatch_inline) {
printf("xenwatch inline still running\n");
diff --git a/sys/i386/include/xen/xenbus.h b/sys/xen/xenbus/xenbusvar.h
index cc90f29..1331c43 100644
--- a/sys/i386/include/xen/xenbus.h
+++ b/sys/xen/xenbus/xenbusvar.h
@@ -30,16 +30,56 @@
* $FreeBSD$
*/
-#ifndef _ASM_XEN_XENBUS_H
-#define _ASM_XEN_XENBUS_H
+#ifndef _XEN_XENBUS_XENBUSVAR_H
+#define _XEN_XENBUS_XENBUSVAR_H
#include <sys/queue.h>
#include <sys/bus.h>
#include <sys/eventhandler.h>
+#include <machine/xen/xen-os.h>
#include <xen/interface/io/xenbus.h>
#include <xen/interface/io/xs_wire.h>
-LIST_HEAD(xendev_list_head, xenbus_device);
+#include "xenbus_if.h"
+
+enum {
+ /*
+ * Path of this device node.
+ */
+ XENBUS_IVAR_NODE,
+
+ /*
+ * The device type (e.g. vif, vbd).
+ */
+ XENBUS_IVAR_TYPE,
+
+ /*
+ * The state of this device (not the otherend's state).
+ */
+ XENBUS_IVAR_STATE,
+
+ /*
+ * Domain ID of the other end device.
+ */
+ XENBUS_IVAR_OTHEREND_ID,
+
+ /*
+ * Path of the other end device.
+ */
+ XENBUS_IVAR_OTHEREND_PATH
+};
+
+/*
+ * Simplified accessors for xenbus devices
+ */
+#define XENBUS_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(xenbus, var, XENBUS, ivar, type)
+
+XENBUS_ACCESSOR(node, NODE, const char *)
+XENBUS_ACCESSOR(type, TYPE, const char *)
+XENBUS_ACCESSOR(state, STATE, enum xenbus_state)
+XENBUS_ACCESSOR(otherend_id, OTHEREND_ID, int)
+XENBUS_ACCESSOR(otherend_path, OTHEREND_PATH, const char *)
/* Register callback to watch this node. */
struct xenbus_watch
@@ -54,72 +94,8 @@ struct xenbus_watch
const char **vec, unsigned int len);
};
-
-/* A xenbus device. */
-struct xenbus_device {
- struct xenbus_watch otherend_watch; /* must be first */
- const char *devicetype;
- const char *nodename;
- const char *otherend;
- int otherend_id;
- struct xendev_list_head *bus;
- struct xenbus_driver *driver;
- int has_error;
- enum xenbus_state state;
- void *dev_driver_data;
- LIST_ENTRY(xenbus_device) list;
-};
-
-static inline struct xenbus_device *to_xenbus_device(device_t dev)
-{
- return device_get_softc(dev);
-}
-
-struct xenbus_device_id
-{
- /* .../device/<device_type>/<identifier> */
- char devicetype[32]; /* General class of device. */
-};
-
-/* A xenbus driver. */
-struct xenbus_driver {
- char *name;
- struct module *owner;
- const struct xenbus_device_id *ids;
- int (*probe)(struct xenbus_device *dev,
- const struct xenbus_device_id *id);
- void (*otherend_changed)(struct xenbus_device *dev,
- XenbusState backend_state);
- int (*remove)(struct xenbus_device *dev);
- int (*suspend)(struct xenbus_device *dev);
- int (*resume)(struct xenbus_device *dev);
- int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
-#if 0
- struct device_driver driver;
-#endif
- driver_t driver;
- int (*read_otherend_details)(struct xenbus_device *dev);
- int (*watch_otherend)(struct xenbus_device *dev);
- int (*cleanup_device)(struct xenbus_device *dev);
- int (*is_ready)(struct xenbus_device *dev);
- LIST_ENTRY(xenbus_driver) list;
-};
-
-static inline struct xenbus_driver *to_xenbus_driver(driver_t *drv)
-{
-#if 0
- return container_of(drv, struct xenbus_driver, driver);
-#endif
- return NULL;
-}
typedef int (*xenstore_event_handler_t)(void *);
-int xenbus_register_frontend(struct xenbus_driver *drv);
-int xenbus_register_backend(struct xenbus_driver *drv);
-void xenbus_unregister_driver(struct xenbus_driver *drv);
-
-int xenbus_remove_device(struct xenbus_device *dev);
-
struct xenbus_transaction
{
uint32_t id;
@@ -168,10 +144,6 @@ void xs_resume(void);
/* Used by xenbus_dev to borrow kernel's store connection. */
void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-/* Called from xen core code. */
-void xenbus_suspend(void);
-void xenbus_resume(void);
-
#define XENBUS_IS_ERR_READ(str) ({ \
if (!IS_ERR(str) && strlen(str) == 0) { \
free(str, M_DEVBUF); \
@@ -182,7 +154,6 @@ void xenbus_resume(void);
#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
@@ -191,7 +162,7 @@ void xenbus_resume(void);
* be NULL, the device will switch to XenbusStateClosing, and the error will
* be saved in the store.
*/
-int xenbus_watch_path(struct xenbus_device *dev, char *path,
+int xenbus_watch_path(device_t dev, char *path,
struct xenbus_watch *watch,
void (*callback)(struct xenbus_watch *,
const char **, unsigned int));
@@ -206,7 +177,7 @@ int xenbus_watch_path(struct xenbus_device *dev, char *path,
* free, the device will switch to XenbusStateClosing, and the error will be
* saved in the store.
*/
-int xenbus_watch_path2(struct xenbus_device *dev, const char *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));
@@ -218,7 +189,7 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
* 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(struct xenbus_device *dev,
+int xenbus_switch_state(device_t dev,
XenbusState new_state);
@@ -227,7 +198,7 @@ int xenbus_switch_state(struct xenbus_device *dev,
* 0 on success, or -errno on error. On error, the device will switch to
* XenbusStateClosing, and the error will be saved in the store.
*/
-int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
+int xenbus_grant_ring(device_t dev, unsigned long ring_mfn);
/**
@@ -236,13 +207,13 @@ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
* error, the device will switch to XenbusStateClosing, and the error will be
* saved in the store.
*/
-int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
+int xenbus_alloc_evtchn(device_t dev, int *port);
/**
* Free an existing event channel. Returns 0 on success or -errno on error.
*/
-int xenbus_free_evtchn(struct xenbus_device *dev, int port);
+int xenbus_free_evtchn(device_t dev, int port);
/**
@@ -256,7 +227,7 @@ XenbusState xenbus_read_driver_state(const char *path);
* Report the given negative errno into the store, along with the given
* formatted message.
*/
-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
+void xenbus_dev_error(device_t dev, int err, const char *fmt,
...);
@@ -265,23 +236,13 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
* xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
* closedown of this driver and its peer.
*/
-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
+void xenbus_dev_fatal(device_t dev, int err, const char *fmt,
...);
int xenbus_dev_init(void);
const char *xenbus_strstate(enum xenbus_state state);
-int xenbus_dev_is_online(struct xenbus_device *dev);
-int xenbus_frontend_closed(struct xenbus_device *dev);
+int xenbus_dev_is_online(device_t dev);
+int xenbus_frontend_closed(device_t dev);
-#endif /* _ASM_XEN_XENBUS_H */
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
+#endif /* _XEN_XENBUS_XENBUSVAR_H */
OpenPOWER on IntegriCloud