diff options
-rw-r--r-- | sys/conf/files | 6 | ||||
-rw-r--r-- | sys/dev/xen/blkfront/blkfront.c | 299 | ||||
-rw-r--r-- | sys/dev/xen/blkfront/block.h | 4 | ||||
-rw-r--r-- | sys/dev/xen/netfront/netfront.c | 238 | ||||
-rw-r--r-- | sys/i386/xen/xen_machdep.c | 4 | ||||
-rw-r--r-- | sys/xen/gnttab.c | 6 | ||||
-rw-r--r-- | sys/xen/gnttab.h | 2 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_client.c | 80 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_comms.c | 8 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_comms.h | 9 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_dev.c | 7 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_if.m | 37 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_probe.c | 1245 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_probe_backend.c | 1 | ||||
-rw-r--r-- | sys/xen/xenbus/xenbus_xs.c | 4 | ||||
-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", §ors, "info", "%u", &binfo, "sector-size", "%lu", §or_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", - ¤t_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 */ |