Yoshiaki Tamura
2009-Mar-12 01:21 UTC
[Xen-devel] [RFC][PATCH 10/13] Kemari: XenbusStateAttached handler for blkback
References: <49B86208.2020205@lab.ntt.co.jp> In-Reply-To: <49B86208.2020205@lab.ntt.co.jp> Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit This is an updated version of the following patch. No major changes. http://lists.xensource.com/archives/html/xen-devel/2009-03/msg00379.html Signed-off-by: Yoshi Tamura <tamura.yoshiaki@lab.ntt.co.jp> Signed-off-by: Yoshisato Yanagisawa <yanagisawa.yoshisato@lab.ntt.co.jp> --- drivers/xen/blkback/common.h | 2 + drivers/xen/blkback/interface.c | 41 +++++++++++++++++++++++++++ drivers/xen/blkback/xenbus.c | 59 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/blkback/common.h --- a/drivers/xen/blkback/common.h Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/blkback/common.h Tue Mar 10 15:40:44 2009 +0900 @@ -100,6 +100,8 @@ void blkif_disconnect(blkif_t *blkif); void blkif_disconnect(blkif_t *blkif); void blkif_free(blkif_t *blkif); int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); +int blkif_attach(blkif_t *blkif, unsigned long shared_page, + unsigned int evtchn); #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) #define blkif_put(_b) \ diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/blkback/interface.c --- a/drivers/xen/blkback/interface.c Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/blkback/interface.c Tue Mar 10 15:40:44 2009 +0900 @@ -144,6 +144,47 @@ int blkif_map(blkif_t *blkif, unsigned l return 0; } +int blkif_attach(blkif_t *blkif, unsigned long shared_page, + unsigned int evtchn) +{ + /* Sorry! Only 32bit curretly. */ + blkif_x86_32_sring_t *sring_x86_32; + int err; + + /* Already connected through? */ + if (blkif->irq) + return 0; + + if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) + return -ENOMEM; + + err = map_frontend_page(blkif, shared_page); + if (err) { + free_vm_area(blkif->blk_ring_area); + return err; + } + + sring_x86_32 + (blkif_x86_32_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_ATTACH(&blkif->blk_rings.x86_32, + sring_x86_32, PAGE_SIZE); + + err = bind_interdomain_evtchn_to_irqhandler( + blkif->domid, evtchn, blkif_be_int, 0, "blkif-backend", blkif); + if (err < 0) + { + unmap_frontend_page(blkif); + free_vm_area(blkif->blk_ring_area); + blkif->blk_rings.common.sring = NULL; + return err; + } + blkif->irq = err; + + blkif->blk_rings.x86_32.req_cons = blkif->blk_rings.x86_32.rsp_prod_pvt; + + return 0; +} + void blkif_disconnect(blkif_t *blkif) { if (blkif->xenblkd) { diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/blkback/xenbus.c --- a/drivers/xen/blkback/xenbus.c Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/blkback/xenbus.c Tue Mar 10 15:40:44 2009 +0900 @@ -39,6 +39,7 @@ struct backend_info static void connect(struct backend_info *); static int connect_ring(struct backend_info *); +static int attach_ring(struct backend_info *); static void backend_changed(struct xenbus_watch *, const char **, unsigned int); @@ -376,6 +377,16 @@ static void frontend_changed(struct xenb update_blkif_status(be->blkif); break; + case XenbusStateAttached: + if (dev->state == XenbusStateAttached) + break; + + err = attach_ring(be); + if (err) + break; + update_blkif_status(be->blkif); + break; + case XenbusStateClosing: blkif_disconnect(be->blkif); xenbus_switch_state(dev, XenbusStateClosing); @@ -515,6 +526,54 @@ static int connect_ring(struct backend_i return 0; } +static int attach_ring(struct backend_info *be) +{ + struct xenbus_device *dev = be->dev; + unsigned long ring_ref; + unsigned int evtchn; + char protocol[64] = ""; + int err; + + DPRINTK("%s", dev->otherend); + + err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref, + "event-channel", "%u", &evtchn, NULL); + if (err) { + xenbus_dev_fatal(dev, err, + "reading %s/ring-ref and event-channel", + dev->otherend); + return err; + } + + be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; + err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", + "%63s", protocol, NULL); + if (err) + strcpy(protocol, "unspecified, assuming native"); + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; + else { + xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); + return -1; + } + printk(KERN_INFO + "blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n", + ring_ref, evtchn, be->blkif->blk_protocol, protocol); + + /* Map the shared frame, irq etc. */ + err = blkif_attach(be->blkif, ring_ref, evtchn); + if (err) { + xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u", + ring_ref, evtchn); + return err; + } + + return 0; +} /* ** Driver Registration ** */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel