summaryrefslogtreecommitdiffstats
path: root/sys/dev/xen
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2008-12-04 07:59:05 +0000
committerkmacy <kmacy@FreeBSD.org>2008-12-04 07:59:05 +0000
commit77ba713706a3fffb53f651616e1a3d43caffe7ac (patch)
treeff76f522d9d91397c9adee09cba8d5e6b0f32df5 /sys/dev/xen
parent0db39db0278da23ed458007116b629ab4a578a3e (diff)
downloadFreeBSD-src-77ba713706a3fffb53f651616e1a3d43caffe7ac.zip
FreeBSD-src-77ba713706a3fffb53f651616e1a3d43caffe7ac.tar.gz
Integrate 185578 from dfr
Use newbus to managed devices
Diffstat (limited to 'sys/dev/xen')
-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
3 files changed, 300 insertions, 241 deletions
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);
OpenPOWER on IntegriCloud