--- linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 79 ++++++++++++----- linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 4 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 17 ++- linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 14 +++ linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c | 6 + linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 86 +++++++++++++------ linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 4 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 17 ++- linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 14 +++ tools/python/xen/xend/server/blkif.py | 3 tools/python/xen/xm/create.py | 7 + xen/include/public/io/blkif.h | 81 +++++++++++++++-- 12 files changed, 264 insertions(+), 68 deletions(-) Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -298,17 +298,33 @@ irqreturn_t blkif_be_int(int irq, void * static int do_block_io_op(blkif_t *blkif) { - blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_v1_back_ring_t *blk_v1_ring = NULL; + blkif_v2_back_ring_t *blk_v2_ring = NULL; blkif_request_t req; pending_req_t *pending_req; RING_IDX rc, rp; int more_to_do = 0; - rc = blk_ring->req_cons; - rp = blk_ring->sring->req_prod; + if (1 == blkif->blk_protocol) { + blk_v1_ring = &blkif->blk_v1_ring; + rc = blk_v1_ring->req_cons; + rp = blk_v1_ring->sring->req_prod; + } else { + blk_v2_ring = &blkif->blk_v2_ring; + rc = blk_v2_ring->req_cons; + rp = blk_v2_ring->sring->req_prod; + } rmb(); /* Ensure we see queued requests up to 'rp'. */ - while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) { + while ((rc != rp)) { + + if (1 == blkif->blk_protocol) { + if (RING_REQUEST_CONS_OVERFLOW(blk_v1_ring, rc)) + break; + } else { + if (RING_REQUEST_CONS_OVERFLOW(blk_v2_ring, rc)) + break; + } pending_req = alloc_req(); if (NULL == pending_req) { @@ -317,8 +333,13 @@ static int do_block_io_op(blkif_t *blkif break; } - memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req)); - blk_ring->req_cons = ++rc; /* before make_response() */ + if (1 == blkif->blk_protocol) { + blkif_get_v1_req(&req, RING_GET_REQUEST(blk_v1_ring, rc)); + blk_v1_ring->req_cons = ++rc; /* before make_response() */ + } else { + blkif_get_v2_req(&req, RING_GET_REQUEST(blk_v2_ring, rc)); + blk_v2_ring->req_cons = ++rc; /* before make_response() */ + } switch (req.operation) { case BLKIF_OP_READ: @@ -500,32 +521,48 @@ static void make_response(blkif_t *blkif { blkif_response_t *resp; unsigned long flags; - blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_v1_back_ring_t *blk_v1_ring = NULL; + blkif_v2_back_ring_t *blk_v2_ring = NULL; int more_to_do = 0; int notify; spin_lock_irqsave(&blkif->blk_ring_lock, flags); /* Place on the response ring for the relevant domain. */ - resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); + if (1 == blkif->blk_protocol) { + blk_v1_ring = &blkif->blk_v1_ring; + resp = RING_GET_RESPONSE(blk_v1_ring, blk_v1_ring->rsp_prod_pvt); + } else { + blk_v2_ring = &blkif->blk_v2_ring; + resp = RING_GET_RESPONSE(blk_v2_ring, blk_v2_ring->rsp_prod_pvt); + } resp->id = id; resp->operation = op; resp->status = st; - blk_ring->rsp_prod_pvt++; - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); - - if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) { - /* - * Tail check for pending requests. Allows frontend to avoid - * notifications if requests are already in flight (lower - * overheads and promotes batching). - */ - RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); - - } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { - more_to_do = 1; + if (1 == blkif->blk_protocol) { + blk_v1_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_v1_ring, notify); + if (blk_v1_ring->rsp_prod_pvt == blk_v1_ring->req_cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(blk_v1_ring, more_to_do); + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_v1_ring)) { + more_to_do = 1; + } + } else { + blk_v2_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_v2_ring, notify); + if (blk_v2_ring->rsp_prod_pvt == blk_v2_ring->req_cons) { + RING_FINAL_CHECK_FOR_REQUESTS(blk_v2_ring, more_to_do); + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_v2_ring)) { + more_to_do = 1; + } } + spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); if (more_to_do) Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/common.h =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blkback/common.h +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/common.h @@ -68,7 +68,9 @@ typedef struct blkif_st { unsigned int evtchn; unsigned int irq; /* Comms information. */ - blkif_back_ring_t blk_ring; + int blk_protocol; + blkif_v1_back_ring_t blk_v1_ring; + blkif_v2_back_ring_t blk_v2_ring; struct vm_struct *blk_ring_area; /* The VBD attached to this interface. */ struct vbd vbd; Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -95,7 +95,8 @@ static void unmap_frontend_page(blkif_t int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { - blkif_sring_t *sring; + blkif_v1_sring_t *sring_v1; + blkif_v2_sring_t *sring_v2; int err; struct evtchn_bind_interdomain bind_interdomain; @@ -125,8 +126,13 @@ int blkif_map(blkif_t *blkif, unsigned l blkif->evtchn = bind_interdomain.local_port; - sring = (blkif_sring_t *)blkif->blk_ring_area->addr; - BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); + if (1 == blkif->blk_protocol) { + sring_v1 = (blkif_v1_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_v1_ring, sring_v1, PAGE_SIZE); + } else { + sring_v2 = (blkif_v2_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_v2_ring, sring_v2, PAGE_SIZE); + } blkif->irq = bind_evtchn_to_irqhandler( blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif); @@ -150,10 +156,11 @@ void blkif_disconnect(blkif_t *blkif) blkif->irq = 0; } - if (blkif->blk_ring.sring) { + if (blkif->blk_v1_ring.sring || blkif->blk_v2_ring.sring) { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); - blkif->blk_ring.sring = NULL; + blkif->blk_v1_ring.sring = NULL; + blkif->blk_v2_ring.sring = NULL; } } Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -435,6 +435,7 @@ static int connect_ring(struct backend_i struct xenbus_device *dev = be->dev; unsigned long ring_ref; unsigned int evtchn; + unsigned int protocol; int err; DPRINTK("%s", dev->otherend); @@ -448,6 +449,19 @@ static int connect_ring(struct backend_i return err; } + err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", + "%u", &protocol, NULL); + if (err) + protocol = BLKIF_NATIVE_PROTOCOL; + if (protocol < 1 || protocol > 2) { + xenbus_dev_fatal(dev, err, "unknown fe protocol %d", protocol); + return -1; + } + be->blkif->blk_protocol = protocol; + + printk("blkback: ring-ref %ld, event-channel %d, protocol %d\n", + ring_ref, evtchn, protocol); + /* Map the shared frame, irq etc. */ err = blkif_map(be->blkif, ring_ref, evtchn); if (err) { Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -180,6 +180,12 @@ again: message = "writing event-channel"; goto abort_transaction; } + err = xenbus_printf(xbt, dev->nodename, + "protocol", "%u", BLKIF_NATIVE_PROTOCOL); + if (err) { + message = "writing protocol"; + goto abort_transaction; + } err = xenbus_transaction_end(xbt, 0); if (err) { Index: build-64-release304-12901/xen/include/public/io/blkif.h =================================================================== --- build-64-release304-12901.orig/xen/include/public/io/blkif.h +++ build-64-release304-12901/xen/include/public/io/blkif.h @@ -71,20 +71,36 @@ */ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 -struct blkif_request { +struct blkif_request_segment { + grant_ref_t gref; /* reference to I/O buffer frame */ + /* @first_sect: first sector in frame to transfer (inclusive). */ + /* @last_sect: last sector in frame to transfer (inclusive). */ + uint8_t first_sect, last_sect; +}; + +/* i386 protocol version */ +#pragma pack(push, 4) +struct blkif_v1_request { uint8_t operation; /* BLKIF_OP_??? */ uint8_t nr_segments; /* number of segments */ blkif_vdev_t handle; /* only for read/write requests */ uint64_t id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ - struct blkif_request_segment { - grant_ref_t gref; /* reference to I/O buffer frame */ - /* @first_sect: first sector in frame to transfer (inclusive). */ - /* @last_sect: last sector in frame to transfer (inclusive). */ - uint8_t first_sect, last_sect; - } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; }; -typedef struct blkif_request blkif_request_t; +typedef struct blkif_v1_request blkif_v1_request_t; +#pragma pack(pop) + +/* x86_64 protocol version */ +struct blkif_v2_request { + uint8_t operation; /* BLKIF_OP_??? */ + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint64_t __attribute__((__aligned__(8))) id; + blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ + struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; +}; +typedef struct blkif_v2_request blkif_v2_request_t; struct blkif_response { uint64_t id; /* copied from request */ @@ -107,7 +123,54 @@ typedef struct blkif_response blkif_resp * Generate blkif ring structures and types. */ -DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); +DEFINE_RING_TYPES(blkif_v1, struct blkif_v1_request, struct blkif_response); +DEFINE_RING_TYPES(blkif_v2, struct blkif_v2_request, struct blkif_response); + +#if defined(__i386__) + +#define BLKIF_NATIVE_PROTOCOL 1 +typedef struct blkif_v1_request blkif_request_t; +DEFINE_RING_TYPES(blkif, struct blkif_v1_request, struct blkif_response); + +#elif defined(__x86_64__) + +#define BLKIF_NATIVE_PROTOCOL 2 +typedef struct blkif_v2_request blkif_request_t; +DEFINE_RING_TYPES(blkif, struct blkif_v2_request, struct blkif_response); + +#else +# error arch fixup needed here +#endif + +#ifdef __KERNEL__ + +/* translate requests: v1/v2 to native */ +#if 1 == BLKIF_NATIVE_PROTOCOL +static void inline blkif_get_v1_req(blkif_request_t *dst, blkif_v1_request_t *src) +#else +static void inline blkif_get_v2_req(blkif_request_t *dst, blkif_v2_request_t *src) +#endif +{ + memcpy(dst, src, sizeof(*dst)); +} + +#if 1 == BLKIF_NATIVE_PROTOCOL +static void inline blkif_get_v2_req(blkif_request_t *dst, blkif_v2_request_t *src) +#else +static void inline blkif_get_v1_req(blkif_request_t *dst, blkif_v1_request_t *src) +#endif +{ + int i; + dst->operation = src->operation; + dst->nr_segments = src->nr_segments; + dst->handle = src->handle; + dst->id = src->id; + dst->sector_number = src->sector_number; + for (i = 0; i < src->nr_segments; i++) + dst->seg[i] = src->seg[i]; +} + +#endif #define VDISK_CDROM 0x1 #define VDISK_REMOVABLE 0x2 Index: build-64-release304-12901/tools/python/xen/xend/server/blkif.py =================================================================== --- build-64-release304-12901.orig/tools/python/xen/xend/server/blkif.py +++ build-64-release304-12901/tools/python/xen/xend/server/blkif.py @@ -38,6 +38,7 @@ class BlkifController(DevController): """@see DevController.getDeviceDetails""" uname = config.get('uname', '') dev = config.get('dev', '') + protocol = config.get('protocol') if 'ioemu:' in dev: (_, dev) = string.split(dev, ':', 1) @@ -85,6 +86,8 @@ class BlkifController(DevController): front = { 'virtual-device' : "%i" % devid, 'device-type' : dev_type } + if protocol: + front.update({ 'protocol' : protocol }); return (devid, back, front) Index: build-64-release304-12901/tools/python/xen/xm/create.py =================================================================== --- build-64-release304-12901.orig/tools/python/xen/xm/create.py +++ build-64-release304-12901/tools/python/xen/xm/create.py @@ -531,7 +531,7 @@ def configure_image(vals): def configure_disks(config_devs, vals): """Create the config for disks (virtual block devices). """ - for (uname, dev, mode, backend) in vals.disk: + for (uname, dev, mode, backend, protocol) in vals.disk: if uname.startswith('tap:'): cls = 'tap' else: @@ -543,6 +543,8 @@ def configure_disks(config_devs, vals): ['mode', mode ] ] if backend: config_vbd.append(['backend', backend]) + if protocol: + config_vbd.append(['protocol', protocol]) config_devs.append(['device', config_vbd]) def configure_pci(config_devs, vals): @@ -787,7 +789,10 @@ def preprocess_disk(vals): n = len(d) if n == 3: d.append(None) + d.append(None) elif n == 4: + d.append(None) + elif n == 5: pass else: err('Invalid disk specifier: ' + v) Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c @@ -1094,15 +1094,24 @@ irqreturn_t tap_blkif_be_int(int irq, vo static int print_dbug = 1; static int do_block_io_op(blkif_t *blkif) { - blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_v1_back_ring_t *blk_v1_ring = NULL; + blkif_v2_back_ring_t *blk_v2_ring = NULL; blkif_request_t req; pending_req_t *pending_req; RING_IDX rc, rp; - int more_to_do = 0; + int retval, more_to_do = 0; tap_blkif_t *info; - rc = blk_ring->req_cons; - rp = blk_ring->sring->req_prod; + if (1 == blkif->blk_protocol) { + blk_v1_ring = &blkif->blk_v1_ring; + rc = blk_v1_ring->req_cons; + rp = blk_v1_ring->sring->req_prod; + } else { + blk_v2_ring = &blkif->blk_v2_ring; + rc = blk_v2_ring->req_cons; + rp = blk_v2_ring->sring->req_prod; + } + rmb(); /* Ensure we see queued requests up to 'rp'. */ /*Check blkif has corresponding UE ring*/ @@ -1133,8 +1142,11 @@ static int do_block_io_op(blkif_t *blkif more_to_do = 1; break; } - - if (RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) { + + retval = (1 == blkif->blk_protocol) + ? RING_REQUEST_CONS_OVERFLOW(blk_v1_ring, rc) + : RING_REQUEST_CONS_OVERFLOW(blk_v2_ring, rc); + if (retval) { WPRINTK("RING_REQUEST_CONS_OVERFLOW!" " More to do\n"); more_to_do = 1; @@ -1148,8 +1160,13 @@ static int do_block_io_op(blkif_t *blkif break; } - memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req)); - blk_ring->req_cons = ++rc; /* before make_response() */ + if (1 == blkif->blk_protocol) { + blkif_get_v1_req(&req, RING_GET_REQUEST(blk_v1_ring, rc)); + blk_v1_ring->req_cons = ++rc; /* before make_response() */ + } else { + blkif_get_v2_req(&req, RING_GET_REQUEST(blk_v2_ring, rc)); + blk_v2_ring->req_cons = ++rc; /* before make_response() */ + } switch (req.operation) { case BLKIF_OP_READ: @@ -1225,7 +1242,9 @@ static void dispatch_rw_block_io(blkif_t WPRINTK("blktap: fe_ring is full, can't add " "IO Request will be dropped. %d %d\n", RING_SIZE(&info->ufe_ring), - RING_SIZE(&blkif->blk_ring)); + (1 == blkif->blk_protocol) + ? RING_SIZE(&blkif->blk_v1_ring) + : RING_SIZE(&blkif->blk_v2_ring)); goto fail_response; } @@ -1415,30 +1434,47 @@ static void make_response(blkif_t *blkif { blkif_response_t *resp; unsigned long flags; - blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_v1_back_ring_t *blk_v1_ring = NULL; + blkif_v2_back_ring_t *blk_v2_ring = NULL; int more_to_do = 0; int notify; + spin_lock_irqsave(&blkif->blk_ring_lock, flags); - /* Place on the response ring for the relevant domain. */ - resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); + /* Place on the response ring for the relevant domain. */ + if (1 == blkif->blk_protocol) { + blk_v1_ring = &blkif->blk_v1_ring; + resp = RING_GET_RESPONSE(blk_v1_ring, blk_v1_ring->rsp_prod_pvt); + } else { + blk_v2_ring = &blkif->blk_v2_ring; + resp = RING_GET_RESPONSE(blk_v2_ring, blk_v2_ring->rsp_prod_pvt); + } resp->id = id; resp->operation = op; resp->status = st; - blk_ring->rsp_prod_pvt++; - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); - - if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) { - /* - * Tail check for pending requests. Allows frontend to avoid - * notifications if requests are already in flight (lower - * overheads and promotes batching). - */ - RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); - } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { - more_to_do = 1; + if (1 == blkif->blk_protocol) { + blk_v1_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_v1_ring, notify); + if (blk_v1_ring->rsp_prod_pvt == blk_v1_ring->req_cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(blk_v1_ring, more_to_do); + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_v1_ring)) { + more_to_do = 1; + } + } else { + blk_v2_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_v2_ring, notify); + if (blk_v2_ring->rsp_prod_pvt == blk_v2_ring->req_cons) { + RING_FINAL_CHECK_FOR_REQUESTS(blk_v2_ring, more_to_do); + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_v2_ring)) { + more_to_do = 1; + } + } - } spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); if (more_to_do) blkif_notify_work(blkif); Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/common.h =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blktap/common.h +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/common.h @@ -59,7 +59,9 @@ typedef struct blkif_st { unsigned int evtchn; unsigned int irq; /* Comms information. */ - blkif_back_ring_t blk_ring; + int blk_protocol; + blkif_v1_back_ring_t blk_v1_ring; + blkif_v2_back_ring_t blk_v2_ring; struct vm_struct *blk_ring_area; /* Back pointer to the backend_info. */ struct backend_info *be; Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c @@ -96,7 +96,8 @@ static void unmap_frontend_page(blkif_t int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { - blkif_sring_t *sring; + blkif_v1_sring_t *sring_v1; + blkif_v2_sring_t *sring_v2; int err; struct evtchn_bind_interdomain bind_interdomain; @@ -126,8 +127,13 @@ int tap_blkif_map(blkif_t *blkif, unsign blkif->evtchn = bind_interdomain.local_port; - sring = (blkif_sring_t *)blkif->blk_ring_area->addr; - BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); + if (1 == blkif->blk_protocol) { + sring_v1 = (blkif_v1_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_v1_ring, sring_v1, PAGE_SIZE); + } else { + sring_v2 = (blkif_v2_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_v2_ring, sring_v2, PAGE_SIZE); + } blkif->irq = bind_evtchn_to_irqhandler( blkif->evtchn, tap_blkif_be_int, 0, "blkif-backend", blkif); @@ -141,10 +147,11 @@ void tap_blkif_unmap(blkif_t *blkif) unbind_from_irqhandler(blkif->irq, blkif); blkif->irq = 0; } - if (blkif->blk_ring.sring) { + if (blkif->blk_v1_ring.sring || blkif->blk_v2_ring.sring) { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); - blkif->blk_ring.sring = NULL; + blkif->blk_v1_ring.sring = NULL; + blkif->blk_v2_ring.sring = NULL; } } Index: build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c =================================================================== --- build-64-release304-12901.orig/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c +++ build-64-release304-12901/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c @@ -316,6 +316,7 @@ static int connect_ring(struct backend_i struct xenbus_device *dev = be->dev; unsigned long ring_ref; unsigned int evtchn; + unsigned int protocol; int err; DPRINTK("%s\n", dev->otherend); @@ -329,6 +330,19 @@ static int connect_ring(struct backend_i return err; } + err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", + "%u", &protocol, NULL); + if (err) + protocol = BLKIF_NATIVE_PROTOCOL; + if (protocol < 1 || protocol > 2) { + xenbus_dev_fatal(dev, err, "unknown fe protocol %d", protocol); + return -1; + } + be->blkif->blk_protocol = protocol; + + printk("blktap: ring-ref %ld, event-channel %d, protocol %d\n", + ring_ref, evtchn, protocol); + /* Map the shared frame, irq etc. */ err = tap_blkif_map(be->blkif, ring_ref, evtchn); if (err) {