/*
 *  xen paravirt block device backend
 *
 *  (c) Gerd Hoffmann <kraxel@redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <inttypes.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/uio.h>

#include <xs.h>
#include <xenctrl.h>
#include <xen/io/xenbus.h>

#include "hw.h"
#include "block_int.h"
#include "qemu-char.h"
#include "xen_blkif.h"
#include "xen_backend.h"

/* ------------------------------------------------------------- */

static int syncwrite    = 0;
static int batch_maps   = 0;

static int max_requests = 32;
static int use_aio      = 1;

/* ------------------------------------------------------------- */

#define BLOCK_SIZE  512
#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)

struct ioreq {
    blkif_request_t     req;
    int16_t             status;

    /* parsed request */
    off_t               start;
    QEMUIOVector        v;
    int                 presync;
    int                 postsync;

    /* grant mapping */
    uint32_t            domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    uint32_t            refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    int                 prot;
    void                *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    void                *pages;

    /* aio status */
    int                 aio_inflight;
    int                 aio_errors;

    struct XenBlkDev    *blkdev;
    QLIST_ENTRY(ioreq)   list;
};

struct XenBlkDev {
    struct XenDevice    xendev;  /* must be first */
    char                *params;
    char                *mode;
    char                *type;
    char                *dev;
    char                *devtype;
    const char          *fileproto;
    const char          *filename;
    int                 ring_ref;
    void                *sring;
    int64_t             file_blk;
    int64_t             file_size;
    int                 protocol;
    blkif_back_rings_t  rings;
    int                 more_work;
    int                 cnt_map;

    /* request lists */
    QLIST_HEAD(inflight_head, ioreq) inflight;
    QLIST_HEAD(finished_head, ioreq) finished;
    QLIST_HEAD(freelist_head, ioreq) freelist;
    int                 requests_total;
    int                 requests_inflight;
    int                 requests_finished;

    /* qemu block driver */
    DriveInfo           *dinfo;
    BlockDriverState    *bs;
    QEMUBH              *bh;
};

/* ------------------------------------------------------------- */

static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
{
    struct ioreq *ioreq = NULL;

    if (QLIST_EMPTY(&blkdev->freelist)) {
	if (blkdev->requests_total >= max_requests)
	    goto out;
	/* allocate new struct */
	ioreq = qemu_mallocz(sizeof(*ioreq));
	ioreq->blkdev = blkdev;
	blkdev->requests_total++;
        qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
    } else {
	/* get one from freelist */
	ioreq = QLIST_FIRST(&blkdev->freelist);
	QLIST_REMOVE(ioreq, list);
        qemu_iovec_reset(&ioreq->v);
    }
    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
    blkdev->requests_inflight++;

out:
    return ioreq;
}

static void ioreq_finish(struct ioreq *ioreq)
{
    struct XenBlkDev *blkdev = ioreq->blkdev;

    QLIST_REMOVE(ioreq, list);
    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
    blkdev->requests_inflight--;
    blkdev->requests_finished++;
}

static void ioreq_release(struct ioreq *ioreq)
{
    struct XenBlkDev *blkdev = ioreq->blkdev;

    QLIST_REMOVE(ioreq, list);
    memset(ioreq, 0, sizeof(*ioreq));
    ioreq->blkdev = blkdev;
    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
    blkdev->requests_finished--;
}

/*
 * translate request into iovec + start offset
 * do sanity checks along the way
 */
static int ioreq_parse(struct ioreq *ioreq)
{
    struct XenBlkDev *blkdev = ioreq->blkdev;
    uintptr_t mem;
    size_t len;
    int i;

    xen_be_printf(&blkdev->xendev, 3,
		  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
		  ioreq->req.operation, ioreq->req.nr_segments,
		  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
    switch (ioreq->req.operation) {
    case BLKIF_OP_READ:
	ioreq->prot = PROT_WRITE; /* to memory */
	break;
    case BLKIF_OP_WRITE_BARRIER:
	if (!syncwrite)
	    ioreq->presync = ioreq->postsync = 1;
	/* fall through */
    case BLKIF_OP_WRITE:
	ioreq->prot = PROT_READ; /* from memory */
	if (syncwrite)
	    ioreq->postsync = 1;
	break;
    default:
	xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
		      ioreq->req.operation);
	goto err;
    };

    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
        xen_be_printf(&blkdev->xendev, 0, "error: write req for ro device\n");
        goto err;
    }

    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
    for (i = 0; i < ioreq->req.nr_segments; i++) {
	if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
	    xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
	    goto err;
	}
	if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
	    xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
	    goto err;
	}
	if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
	    xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
	    goto err;
	}

	ioreq->domids[i] = blkdev->xendev.dom;
	ioreq->refs[i]   = ioreq->req.seg[i].gref;

	mem = ioreq->req.seg[i].first_sect * blkdev->file_blk;
	len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
        qemu_iovec_add(&ioreq->v, (void*)mem, len);
    }
    if (ioreq->start + ioreq->v.size > blkdev->file_size) {
	xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
	goto err;
    }
    return 0;

err:
    ioreq->status = BLKIF_RSP_ERROR;
    return -1;
}

static void ioreq_unmap(struct ioreq *ioreq)
{
    int gnt = ioreq->blkdev->xendev.gnttabdev;
    int i;

    if (ioreq->v.niov == 0)
        return;
    if (batch_maps) {
	if (!ioreq->pages)
	    return;
	if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0)
	    xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
			  strerror(errno));
	ioreq->blkdev->cnt_map -= ioreq->v.niov;
	ioreq->pages = NULL;
    } else {
	for (i = 0; i < ioreq->v.niov; i++) {
	    if (!ioreq->page[i])
		continue;
	    if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0)
		xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
			      strerror(errno));
	    ioreq->blkdev->cnt_map--;
	    ioreq->page[i] = NULL;
	}
    }
}

static int ioreq_map(struct ioreq *ioreq)
{
    int gnt = ioreq->blkdev->xendev.gnttabdev;
    int i;

    if (ioreq->v.niov == 0)
        return 0;
    if (batch_maps) {
	ioreq->pages = xc_gnttab_map_grant_refs
	    (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
	if (ioreq->pages == NULL) {
	    xen_be_printf(&ioreq->blkdev->xendev, 0,
			  "can't map %d grant refs (%s, %d maps)\n",
			  ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map);
	    return -1;
	}
	for (i = 0; i < ioreq->v.niov; i++)
	    ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE +
		(uintptr_t)ioreq->v.iov[i].iov_base;
	ioreq->blkdev->cnt_map += ioreq->v.niov;
    } else  {
	for (i = 0; i < ioreq->v.niov; i++) {
	    ioreq->page[i] = xc_gnttab_map_grant_ref
		(gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
	    if (ioreq->page[i] == NULL) {
		xen_be_printf(&ioreq->blkdev->xendev, 0,
			      "can't map grant ref %d (%s, %d maps)\n",
			      ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map);
		ioreq_unmap(ioreq);
		return -1;
	    }
	    ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base;
	    ioreq->blkdev->cnt_map++;
	}
    }
    return 0;
}

static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
{
    struct XenBlkDev *blkdev = ioreq->blkdev;
    int i, rc, len = 0;
    off_t pos;

    if (ioreq_map(ioreq) == -1)
	goto err;
    if (ioreq->presync)
	bdrv_flush(blkdev->bs);

    switch (ioreq->req.operation) {
    case BLKIF_OP_READ:
	pos = ioreq->start;
	for (i = 0; i < ioreq->v.niov; i++) {
	    rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,
			   ioreq->v.iov[i].iov_base,
			   ioreq->v.iov[i].iov_len / BLOCK_SIZE);
	    if (rc != 0) {
		xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",
			      ioreq->v.iov[i].iov_base,
			      ioreq->v.iov[i].iov_len);
		goto err;
	    }
	    len += ioreq->v.iov[i].iov_len;
	    pos += ioreq->v.iov[i].iov_len;
	}
	break;
    case BLKIF_OP_WRITE:
    case BLKIF_OP_WRITE_BARRIER:
	pos = ioreq->start;
	for (i = 0; i < ioreq->v.niov; i++) {
	    rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,
			    ioreq->v.iov[i].iov_base,
			    ioreq->v.iov[i].iov_len / BLOCK_SIZE);
	    if (rc != 0) {
		xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",
			      ioreq->v.iov[i].iov_base,
			      ioreq->v.iov[i].iov_len);
		goto err;
	    }
	    len += ioreq->v.iov[i].iov_len;
	    pos += ioreq->v.iov[i].iov_len;
	}
	break;
    default:
	/* unknown operation (shouldn't happen -- parse catches this) */
	goto err;
    }

    if (ioreq->postsync)
	bdrv_flush(blkdev->bs);
    ioreq->status = BLKIF_RSP_OKAY;

    ioreq_unmap(ioreq);
    ioreq_finish(ioreq);
    return 0;

err:
    ioreq->status = BLKIF_RSP_ERROR;
    return -1;
}

static void qemu_aio_complete(void *opaque, int ret)
{
    struct ioreq *ioreq = opaque;

    if (ret != 0) {
        xen_be_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
        ioreq->aio_errors++;
    }

    ioreq->aio_inflight--;
    if (ioreq->aio_inflight > 0)
        return;

    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
    ioreq_unmap(ioreq);
    ioreq_finish(ioreq);
    qemu_bh_schedule(ioreq->blkdev->bh);
}

static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
{
    struct XenBlkDev *blkdev = ioreq->blkdev;

    if (ioreq_map(ioreq) == -1)
	goto err;

    ioreq->aio_inflight++;
    if (ioreq->presync)
	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */

    switch (ioreq->req.operation) {
    case BLKIF_OP_READ:
        ioreq->aio_inflight++;
        bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                       &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                       qemu_aio_complete, ioreq);
	break;
    case BLKIF_OP_WRITE:
    case BLKIF_OP_WRITE_BARRIER:
        ioreq->aio_inflight++;
        bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                        qemu_aio_complete, ioreq);
	break;
    default:
	/* unknown operation (shouldn't happen -- parse catches this) */
	goto err;
    }

    if (ioreq->postsync)
	bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */
    qemu_aio_complete(ioreq, 0);

    return 0;

err:
    ioreq->status = BLKIF_RSP_ERROR;
    return -1;
}

static int blk_send_response_one(struct ioreq *ioreq)
{
    struct XenBlkDev  *blkdev = ioreq->blkdev;
    int               send_notify   = 0;
    int               have_requests = 0;
    blkif_response_t  resp;
    void              *dst;

    resp.id        = ioreq->req.id;
    resp.operation = ioreq->req.operation;
    resp.status    = ioreq->status;

    /* Place on the response ring for the relevant domain. */
    switch (blkdev->protocol) {
    case BLKIF_PROTOCOL_NATIVE:
	dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
	break;
    case BLKIF_PROTOCOL_X86_32:
        dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
                                blkdev->rings.x86_32_part.rsp_prod_pvt);
	break;
    case BLKIF_PROTOCOL_X86_64:
        dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
                                blkdev->rings.x86_64_part.rsp_prod_pvt);
	break;
    default:
	dst = NULL;
    }
    memcpy(dst, &resp, sizeof(resp));
    blkdev->rings.common.rsp_prod_pvt++;

    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.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(&blkdev->rings.common, have_requests);
    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
	have_requests = 1;
    }

    if (have_requests)
	blkdev->more_work++;
    return send_notify;
}

/* walk finished list, send outstanding responses, free requests */
static void blk_send_response_all(struct XenBlkDev *blkdev)
{
    struct ioreq *ioreq;
    int send_notify = 0;

    while (!QLIST_EMPTY(&blkdev->finished)) {
        ioreq = QLIST_FIRST(&blkdev->finished);
	send_notify += blk_send_response_one(ioreq);
	ioreq_release(ioreq);
    }
    if (send_notify)
	xen_be_send_notify(&blkdev->xendev);
}

static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
{
    switch (blkdev->protocol) {
    case BLKIF_PROTOCOL_NATIVE:
	memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
	       sizeof(ioreq->req));
	break;
    case BLKIF_PROTOCOL_X86_32:
        blkif_get_x86_32_req(&ioreq->req,
                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
	break;
    case BLKIF_PROTOCOL_X86_64:
        blkif_get_x86_64_req(&ioreq->req,
                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
	break;
    }
    return 0;
}

static void blk_handle_requests(struct XenBlkDev *blkdev)
{
    RING_IDX rc, rp;
    struct ioreq *ioreq;

    blkdev->more_work = 0;

    rc = blkdev->rings.common.req_cons;
    rp = blkdev->rings.common.sring->req_prod;
    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

    if (use_aio)
        blk_send_response_all(blkdev);
    while (rc != rp) {
        /* pull request from ring */
        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc))
            break;
        ioreq = ioreq_start(blkdev);
        if (ioreq == NULL) {
            blkdev->more_work++;
            break;
        }
        blk_get_request(blkdev, ioreq, rc);
        blkdev->rings.common.req_cons = ++rc;

        /* parse them */
        if (ioreq_parse(ioreq) != 0) {
            if (blk_send_response_one(ioreq))
                xen_be_send_notify(&blkdev->xendev);
            ioreq_release(ioreq);
            continue;
        }

        if (use_aio) {
            /* run i/o in aio mode */
            ioreq_runio_qemu_aio(ioreq);
        } else {
            /* run i/o in sync mode */
            ioreq_runio_qemu_sync(ioreq);
        }
    }
    if (!use_aio)
        blk_send_response_all(blkdev);

    if (blkdev->more_work && blkdev->requests_inflight < max_requests)
        qemu_bh_schedule(blkdev->bh);
}

/* ------------------------------------------------------------- */

static void blk_bh(void *opaque)
{
    struct XenBlkDev *blkdev = opaque;
    blk_handle_requests(blkdev);
}

static void blk_alloc(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    QLIST_INIT(&blkdev->inflight);
    QLIST_INIT(&blkdev->finished);
    QLIST_INIT(&blkdev->freelist);
    blkdev->bh = qemu_bh_new(blk_bh, blkdev);
    if (xen_mode != XEN_EMULATE)
        batch_maps = 1;
}

static int blk_init(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
    int index, qflags, have_barriers, info = 0;
    char *h;

    /* read xenstore entries */
    if (blkdev->params == NULL) {
	blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params");
        h = strchr(blkdev->params, ':');
	if (h != NULL) {
	    blkdev->fileproto = blkdev->params;
	    blkdev->filename  = h+1;
	    *h = 0;
	} else {
	    blkdev->fileproto = "<unset>";
	    blkdev->filename  = blkdev->params;
	}
    }
    if (blkdev->mode == NULL)
	blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode");
    if (blkdev->type == NULL)
	blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type");
    if (blkdev->dev == NULL)
	blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev");
    if (blkdev->devtype == NULL)
	blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type");

    /* do we have all we need? */
    if (blkdev->params == NULL ||
	blkdev->mode == NULL   ||
	blkdev->type == NULL   ||
	blkdev->dev == NULL)
	return -1;

    /* read-only ? */
    if (strcmp(blkdev->mode, "w") == 0) {
	qflags = BDRV_O_RDWR;
    } else {
	qflags = 0;
	info  |= VDISK_READONLY;
    }

    /* cdrom ? */
    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom"))
	info  |= VDISK_CDROM;

    /* init qemu block driver */
    index = (blkdev->xendev.dev - 202 * 256) / 16;
    blkdev->dinfo = drive_get(IF_XEN, 0, index);
    if (!blkdev->dinfo) {
        /* setup via xenbus -> create new block driver instance */
        xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
	blkdev->bs = bdrv_new(blkdev->dev);
	if (blkdev->bs) {
	    if (bdrv_open(blkdev->bs, blkdev->filename, qflags,
                           bdrv_find_whitelisted_format(blkdev->fileproto))
                != 0) {
		bdrv_delete(blkdev->bs);
		blkdev->bs = NULL;
	    }
	}
	if (!blkdev->bs)
	    return -1;
    } else {
        /* setup via qemu cmdline -> already setup for us */
        xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
	blkdev->bs = blkdev->dinfo->bdrv;
    }
    blkdev->file_blk  = BLOCK_SIZE;
    blkdev->file_size = bdrv_getlength(blkdev->bs);
    if (blkdev->file_size < 0) {
        xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
                      (int)blkdev->file_size, strerror(-blkdev->file_size),
                      blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
	blkdev->file_size = 0;
    }
    have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0;

    xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
		  " size %" PRId64 " (%" PRId64 " MB)\n",
		  blkdev->type, blkdev->fileproto, blkdev->filename,
		  blkdev->file_size, blkdev->file_size >> 20);

    /* fill info */
    xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
    xenstore_write_be_int(&blkdev->xendev, "info",            info);
    xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
    xenstore_write_be_int(&blkdev->xendev, "sectors",
			  blkdev->file_size / blkdev->file_blk);
    return 0;
}

static int blk_connect(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1)
	return -1;
    if (xenstore_read_fe_int(&blkdev->xendev, "event-channel",
                             &blkdev->xendev.remote_port) == -1)
	return -1;

    blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
    if (blkdev->xendev.protocol) {
        if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_32) == 0)
            blkdev->protocol = BLKIF_PROTOCOL_X86_32;
        if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_64) == 0)
            blkdev->protocol = BLKIF_PROTOCOL_X86_64;
    }

    blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
					    blkdev->xendev.dom,
					    blkdev->ring_ref,
					    PROT_READ | PROT_WRITE);
    if (!blkdev->sring)
	return -1;
    blkdev->cnt_map++;

    switch (blkdev->protocol) {
    case BLKIF_PROTOCOL_NATIVE:
    {
	blkif_sring_t *sring_native = blkdev->sring;
	BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE);
	break;
    }
    case BLKIF_PROTOCOL_X86_32:
    {
	blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;

        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE);
	break;
    }
    case BLKIF_PROTOCOL_X86_64:
    {
	blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;

        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE);
	break;
    }
    }

    xen_be_bind_evtchn(&blkdev->xendev);

    xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
		  "remote port %d, local port %d\n",
		  blkdev->xendev.protocol, blkdev->ring_ref,
		  blkdev->xendev.remote_port, blkdev->xendev.local_port);
    return 0;
}

static void blk_disconnect(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    if (blkdev->bs) {
        if (!blkdev->dinfo) {
            /* close/delete only if we created it ourself */
            bdrv_close(blkdev->bs);
            bdrv_delete(blkdev->bs);
        }
	blkdev->bs = NULL;
    }
    xen_be_unbind_evtchn(&blkdev->xendev);

    if (blkdev->sring) {
	xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
	blkdev->cnt_map--;
	blkdev->sring = NULL;
    }
}

static int blk_free(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
    struct ioreq *ioreq;

    while (!QLIST_EMPTY(&blkdev->freelist)) {
	ioreq = QLIST_FIRST(&blkdev->freelist);
        QLIST_REMOVE(ioreq, list);
        qemu_iovec_destroy(&ioreq->v);
	qemu_free(ioreq);
    }

    qemu_free(blkdev->params);
    qemu_free(blkdev->mode);
    qemu_free(blkdev->type);
    qemu_free(blkdev->dev);
    qemu_free(blkdev->devtype);
    qemu_bh_delete(blkdev->bh);
    return 0;
}

static void blk_event(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    qemu_bh_schedule(blkdev->bh);
}

struct XenDevOps xen_blkdev_ops = {
    .size       = sizeof(struct XenBlkDev),
    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
    .alloc      = blk_alloc,
    .init       = blk_init,
    .connect    = blk_connect,
    .disconnect = blk_disconnect,
    .event      = blk_event,
    .free       = blk_free,
};
