direct-io.hg

changeset 10306:db8ec1e48414

[LINUX][BLKTAP] This code doesn't compile, is marked as DANGEROUS, and
is said to be removed when block drivers use grant tables.
So let's remove it.

Signed-off-by: Chris Wright <chrisw@sous-sol.org>
author kaf24@firebug.cl.cam.ac.uk
date Fri Jun 09 14:20:09 2006 +0100 (2006-06-09)
parents afdb70b16a53
children 7cf4cbe7a3be
files buildconfigs/linux-defconfig_xen0_ia64 buildconfigs/linux-defconfig_xen0_x86_32 buildconfigs/linux-defconfig_xen0_x86_64 buildconfigs/linux-defconfig_xen_ia64 buildconfigs/linux-defconfig_xen_x86_32 buildconfigs/linux-defconfig_xen_x86_64 linux-2.6-xen-sparse/drivers/xen/Kconfig linux-2.6-xen-sparse/drivers/xen/Makefile linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h
line diff
     1.1 --- a/buildconfigs/linux-defconfig_xen0_ia64	Fri Jun 09 14:13:18 2006 +0100
     1.2 +++ b/buildconfigs/linux-defconfig_xen0_ia64	Fri Jun 09 14:20:09 2006 +0100
     1.3 @@ -1529,14 +1529,12 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
     1.4  CONFIG_XEN_BACKEND=y
     1.5  # CONFIG_XEN_PCIDEV_BACKEND is not set
     1.6  CONFIG_XEN_BLKDEV_BACKEND=y
     1.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     1.8  CONFIG_XEN_NETDEV_BACKEND=y
     1.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    1.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    1.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    1.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    1.13  CONFIG_XEN_NETDEV_FRONTEND=y
    1.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    1.15  # CONFIG_XEN_SCRUB_PAGES is not set
    1.16  # CONFIG_XEN_DISABLE_SERIAL is not set
    1.17  CONFIG_XEN_SYSFS=y
     2.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Fri Jun 09 14:13:18 2006 +0100
     2.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Fri Jun 09 14:20:09 2006 +0100
     2.3 @@ -1322,14 +1322,12 @@ CONFIG_XEN_PCIDEV_BACKEND=y
     2.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     2.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     2.6  CONFIG_XEN_BLKDEV_BACKEND=y
     2.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     2.8  CONFIG_XEN_NETDEV_BACKEND=y
     2.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    2.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    2.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    2.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    2.13  CONFIG_XEN_NETDEV_FRONTEND=y
    2.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    2.15  CONFIG_XEN_SCRUB_PAGES=y
    2.16  CONFIG_XEN_DISABLE_SERIAL=y
    2.17  CONFIG_XEN_SYSFS=y
     3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64	Fri Jun 09 14:13:18 2006 +0100
     3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64	Fri Jun 09 14:20:09 2006 +0100
     3.3 @@ -1263,14 +1263,12 @@ CONFIG_XEN_PCIDEV_BACKEND=y
     3.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     3.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     3.6  CONFIG_XEN_BLKDEV_BACKEND=y
     3.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     3.8  CONFIG_XEN_NETDEV_BACKEND=y
     3.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    3.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    3.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    3.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    3.13  CONFIG_XEN_NETDEV_FRONTEND=y
    3.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    3.15  CONFIG_XEN_SCRUB_PAGES=y
    3.16  CONFIG_XEN_DISABLE_SERIAL=y
    3.17  CONFIG_XEN_SYSFS=y
     4.1 --- a/buildconfigs/linux-defconfig_xen_ia64	Fri Jun 09 14:13:18 2006 +0100
     4.2 +++ b/buildconfigs/linux-defconfig_xen_ia64	Fri Jun 09 14:20:09 2006 +0100
     4.3 @@ -1535,14 +1535,12 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
     4.4  CONFIG_XEN_BACKEND=y
     4.5  # CONFIG_XEN_PCIDEV_BACKEND is not set
     4.6  CONFIG_XEN_BLKDEV_BACKEND=y
     4.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     4.8  CONFIG_XEN_NETDEV_BACKEND=y
     4.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    4.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    4.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    4.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    4.13  CONFIG_XEN_NETDEV_FRONTEND=y
    4.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    4.15  # CONFIG_XEN_SCRUB_PAGES is not set
    4.16  # CONFIG_XEN_DISABLE_SERIAL is not set
    4.17  CONFIG_XEN_SYSFS=y
     5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Fri Jun 09 14:13:18 2006 +0100
     5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Fri Jun 09 14:20:09 2006 +0100
     5.3 @@ -3022,14 +3022,12 @@ CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
     5.4  # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
     5.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     5.6  CONFIG_XEN_BLKDEV_BACKEND=y
     5.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     5.8  CONFIG_XEN_NETDEV_BACKEND=y
     5.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    5.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    5.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    5.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    5.13  CONFIG_XEN_NETDEV_FRONTEND=y
    5.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    5.15  CONFIG_XEN_SCRUB_PAGES=y
    5.16  CONFIG_XEN_DISABLE_SERIAL=y
    5.17  CONFIG_XEN_SYSFS=y
     6.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Fri Jun 09 14:13:18 2006 +0100
     6.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Fri Jun 09 14:20:09 2006 +0100
     6.3 @@ -2854,7 +2854,6 @@ CONFIG_XEN_PCIDEV_BACKEND=m
     6.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     6.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     6.6  CONFIG_XEN_BLKDEV_BACKEND=y
     6.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     6.8  CONFIG_XEN_NETDEV_BACKEND=y
     6.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    6.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    6.11 @@ -2862,7 +2861,6 @@ CONFIG_XEN_TPMDEV_BACKEND=m
    6.12  # CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set
    6.13  CONFIG_XEN_BLKDEV_FRONTEND=y
    6.14  CONFIG_XEN_NETDEV_FRONTEND=y
    6.15 -# CONFIG_XEN_BLKDEV_TAP is not set
    6.16  CONFIG_XEN_SCRUB_PAGES=y
    6.17  CONFIG_XEN_DISABLE_SERIAL=y
    6.18  CONFIG_XEN_SYSFS=y
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig	Fri Jun 09 14:13:18 2006 +0100
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig	Fri Jun 09 14:20:09 2006 +0100
     7.3 @@ -84,19 +84,6 @@ config XEN_BLKDEV_BACKEND
     7.4  	  block devices to other guests via a high-performance shared-memory
     7.5  	  interface.
     7.6  
     7.7 -config XEN_BLKDEV_TAP_BE
     7.8 -        tristate "Block Tap support for backend driver (DANGEROUS)"
     7.9 -        depends on XEN_BLKDEV_BACKEND
    7.10 -        default n
    7.11 -        help
    7.12 -          If you intend to use the block tap driver, the backend domain will
    7.13 -          not know the domain id of the real frontend, and so will not be able
    7.14 -          to map its data pages.  This modifies the backend to attempt to map
    7.15 -          from both the tap domain and the real frontend.  This presents a
    7.16 -          security risk, and so should ONLY be used for development
    7.17 -          with the blktap.  This option will be removed as the block drivers are
    7.18 -          modified to use grant tables.
    7.19 -
    7.20  config XEN_NETDEV_BACKEND
    7.21  	tristate "Network-device backend driver"
    7.22          depends on XEN_BACKEND && NET
    7.23 @@ -163,16 +150,6 @@ config XEN_NETDEV_FRONTEND
    7.24  	  dedicated device-driver domain, or your master control domain
    7.25  	  (domain 0), then you almost certainly want to say Y here.
    7.26  
    7.27 -config XEN_BLKDEV_TAP
    7.28 -	tristate "Block device tap driver"
    7.29 -        depends on XEN_BACKEND
    7.30 -	default n
    7.31 -	help
    7.32 -	  This driver allows a VM to interact on block device channels
    7.33 -	  to other VMs.  Block messages may be passed through or redirected
    7.34 -	  to a character device, allowing device prototyping in application
    7.35 -	  space.  Odds are that you want to say N here.
    7.36 -
    7.37  config XEN_SCRUB_PAGES
    7.38  	bool "Scrub memory before freeing it to Xen"
    7.39  	default y
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Fri Jun 09 14:13:18 2006 +0100
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Fri Jun 09 14:20:09 2006 +0100
     8.3 @@ -12,6 +12,5 @@ obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netb
     8.4  obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmback/
     8.5  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
     8.6  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
     8.7 -obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
     8.8  obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pciback/
     8.9  obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Jun 09 14:13:18 2006 +0100
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Jun 09 14:20:09 2006 +0100
     9.3 @@ -105,18 +105,6 @@ static inline unsigned long vaddr(pendin
     9.4  	(pending_grant_handles[vaddr_pagenr(_req, _seg)])
     9.5  
     9.6  
     9.7 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
     9.8 -/*
     9.9 - * If the tap driver is used, we may get pages belonging to either the tap
    9.10 - * or (more likely) the real frontend.  The backend must specify which domain
    9.11 - * a given page belongs to in update_va_mapping though.  For the moment, 
    9.12 - * the tap rewrites the ID field of the request to contain the request index
    9.13 - * and the id of the real front end domain.
    9.14 - */
    9.15 -#define BLKTAP_COOKIE 0xbeadfeed
    9.16 -static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
    9.17 -#endif
    9.18 -
    9.19  static int do_block_io_op(blkif_t *blkif);
    9.20  static void dispatch_rw_block_io(blkif_t *blkif,
    9.21  				 blkif_request_t *req,
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Jun 09 14:13:18 2006 +0100
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Jun 09 14:20:09 2006 +0100
    10.3 @@ -73,10 +73,6 @@ typedef struct blkif_st {
    10.4  	/* Back pointer to the backend_info. */
    10.5  	struct backend_info *be; 
    10.6  	/* Private fields. */
    10.7 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    10.8 -	/* Is this a blktap frontend */
    10.9 -	unsigned int     is_blktap;
   10.10 -#endif
   10.11  	spinlock_t       blk_ring_lock;
   10.12  	atomic_t         refcnt;
   10.13  
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile	Fri Jun 09 14:13:18 2006 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,3 +0,0 @@
    11.4 -
    11.5 -obj-y	:= xenbus.o interface.o blktap.o 
    11.6 -
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Fri Jun 09 14:13:18 2006 +0100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,900 +0,0 @@
    12.4 -/******************************************************************************
    12.5 - * arch/xen/drivers/blkif/blktap/blktap.c
    12.6 - * 
    12.7 - * This is a modified version of the block backend driver that remaps requests
    12.8 - * to a user-space memory region.  It is intended to be used to write 
    12.9 - * application-level servers that provide block interfaces to client VMs.
   12.10 - */
   12.11 -
   12.12 -#include <linux/kernel.h>
   12.13 -#include <linux/spinlock.h>
   12.14 -#include <xen/balloon.h>
   12.15 -#include <linux/kernel.h>
   12.16 -#include <linux/fs.h>
   12.17 -#include <linux/mm.h>
   12.18 -#include <linux/miscdevice.h>
   12.19 -#include <linux/errno.h>
   12.20 -#include <linux/major.h>
   12.21 -#include <linux/gfp.h>
   12.22 -#include <linux/poll.h>
   12.23 -#include <asm/tlbflush.h>
   12.24 -#include "common.h"
   12.25 -
   12.26 -/* Only one process may open /dev/xen/blktap at any time. */
   12.27 -static unsigned long blktap_dev_inuse;
   12.28 -unsigned long blktap_ring_ok; /* make this ring->state */
   12.29 -
   12.30 -/* Rings up to user space. */
   12.31 -static blkif_front_ring_t blktap_ufe_ring;
   12.32 -
   12.33 -/* for poll: */
   12.34 -static wait_queue_head_t blktap_wait;
   12.35 -
   12.36 -/* current switching mode */
   12.37 -static unsigned long blktap_mode;
   12.38 -
   12.39 -/* local prototypes */
   12.40 -static int blktap_read_ufe_ring(void);
   12.41 -
   12.42 -
   12.43 -/* /dev/xen/blktap resides at device number major=10, minor=200        */ 
   12.44 -#define BLKTAP_MINOR 202
   12.45 -
   12.46 -/* blktap IOCTLs:                                                      */
   12.47 -#define BLKTAP_IOCTL_KICK_FE         1
   12.48 -#define BLKTAP_IOCTL_KICK_BE         2 /* currently unused */
   12.49 -#define BLKTAP_IOCTL_SETMODE         3
   12.50 -#define BLKTAP_IOCTL_PRINT_IDXS      100  
   12.51 -
   12.52 -/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
   12.53 -#define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
   12.54 -#define BLKTAP_MODE_INTERCEPT_FE     0x00000001
   12.55 -#define BLKTAP_MODE_INTERCEPT_BE     0x00000002  /* unimp. */
   12.56 -#define BLKTAP_MODE_COPY_FE          0x00000004  /* unimp. */
   12.57 -#define BLKTAP_MODE_COPY_BE          0x00000008  /* unimp. */
   12.58 -#define BLKTAP_MODE_COPY_FE_PAGES    0x00000010  /* unimp. */
   12.59 -#define BLKTAP_MODE_COPY_BE_PAGES    0x00000020  /* unimp. */
   12.60 -
   12.61 -#define BLKTAP_MODE_INTERPOSE \
   12.62 -           (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
   12.63 -
   12.64 -#define BLKTAP_MODE_COPY_BOTH \
   12.65 -           (BLKTAP_MODE_COPY_FE | BLKTAP_MODE_COPY_BE)
   12.66 -
   12.67 -#define BLKTAP_MODE_COPY_BOTH_PAGES \
   12.68 -           (BLKTAP_MODE_COPY_FE_PAGES | BLKTAP_MODE_COPY_BE_PAGES)
   12.69 -
   12.70 -static inline int BLKTAP_MODE_VALID(unsigned long arg)
   12.71 -{
   12.72 -	return ((arg == BLKTAP_MODE_PASSTHROUGH ) ||
   12.73 -		(arg == BLKTAP_MODE_INTERCEPT_FE) ||
   12.74 -		(arg == BLKTAP_MODE_INTERPOSE   ));
   12.75 -/*
   12.76 -  return (
   12.77 -  ( arg == BLKTAP_MODE_PASSTHROUGH  ) ||
   12.78 -  ( arg == BLKTAP_MODE_INTERCEPT_FE ) ||
   12.79 -  ( arg == BLKTAP_MODE_INTERCEPT_BE ) ||
   12.80 -  ( arg == BLKTAP_MODE_INTERPOSE    ) ||
   12.81 -  ( (arg & ~BLKTAP_MODE_COPY_FE_PAGES) == BLKTAP_MODE_COPY_FE ) ||
   12.82 -  ( (arg & ~BLKTAP_MODE_COPY_BE_PAGES) == BLKTAP_MODE_COPY_BE ) ||
   12.83 -  ( (arg & ~BLKTAP_MODE_COPY_BOTH_PAGES) == BLKTAP_MODE_COPY_BOTH )
   12.84 -  );
   12.85 -*/
   12.86 -}
   12.87 -
   12.88 -
   12.89 -/******************************************************************
   12.90 - * MMAP REGION
   12.91 - */
   12.92 -
   12.93 -/*
   12.94 - * We use a big chunk of address space to map in-flight requests into,
   12.95 - * and export this region up to user-space.  See the comments in blkback
   12.96 - * about this -- the two must be kept in sync if the tap is used as a 
   12.97 - * passthrough.
   12.98 - */
   12.99 -
  12.100 -#define MAX_PENDING_REQS 64
  12.101 -#define BATCH_PER_DOMAIN 16
  12.102 -
  12.103 -/* immediately before the mmap area, we have a bunch of pages reserved
  12.104 - * for shared memory rings.
  12.105 - */
  12.106 -#define RING_PAGES 1 /* Front */ 
  12.107 -
  12.108 -/* Where things are inside the device mapping. */
  12.109 -struct vm_area_struct *blktap_vma = NULL;
  12.110 -unsigned long mmap_vstart;  /* Kernel pages for mapping in data. */
  12.111 -unsigned long rings_vstart; /* start of mmaped vma               */
  12.112 -unsigned long user_vstart;  /* start of user mappings            */
  12.113 -
  12.114 -#define MMAP_PAGES						\
  12.115 -	(MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
  12.116 -#define MMAP_VADDR(_start, _req,_seg)					\
  12.117 -	(_start +							\
  12.118 -	 ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +	\
  12.119 -	 ((_seg) * PAGE_SIZE))
  12.120 -
  12.121 -/*
  12.122 - * Each outstanding request that we've passed to the lower device layers has a 
  12.123 - * 'pending_req' allocated to it. Each buffer_head that completes decrements 
  12.124 - * the pendcnt towards zero. When it hits zero, the specified domain has a 
  12.125 - * response queued for it, with the saved 'id' passed back.
  12.126 - */
  12.127 -typedef struct {
  12.128 -	blkif_t       *blkif;
  12.129 -	unsigned long  id;
  12.130 -	int            nr_pages;
  12.131 -	atomic_t       pendcnt;
  12.132 -	unsigned short operation;
  12.133 -	int            status;
  12.134 -} pending_req_t;
  12.135 -
  12.136 -/*
  12.137 - * We can't allocate pending_req's in order, since they may complete out of 
  12.138 - * order. We therefore maintain an allocation ring. This ring also indicates 
  12.139 - * when enough work has been passed down -- at that point the allocation ring 
  12.140 - * will be empty.
  12.141 - */
  12.142 -static pending_req_t pending_reqs[MAX_PENDING_REQS];
  12.143 -static unsigned char pending_ring[MAX_PENDING_REQS];
  12.144 -static DEFINE_SPINLOCK(pend_prod_lock);
  12.145 -/* NB. We use a different index type to differentiate from shared blk rings. */
  12.146 -typedef unsigned int PEND_RING_IDX;
  12.147 -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
  12.148 -static PEND_RING_IDX pending_prod, pending_cons;
  12.149 -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
  12.150 -
  12.151 -/* Requests passing through the tap to the backend hijack the id field
  12.152 - * in the request message.  In it we put the AR index _AND_ the fe domid.
  12.153 - * the domid is used by the backend to map the pages properly.
  12.154 - */
  12.155 -
  12.156 -static inline unsigned long MAKE_ID(domid_t fe_dom, PEND_RING_IDX idx)
  12.157 -{
  12.158 -	return ((fe_dom << 16) | MASK_PEND_IDX(idx));
  12.159 -}
  12.160 -
  12.161 -extern inline PEND_RING_IDX ID_TO_IDX(unsigned long id) 
  12.162 -{ 
  12.163 -	return (PEND_RING_IDX)(id & 0x0000ffff);
  12.164 -}
  12.165 -
  12.166 -extern inline domid_t ID_TO_DOM(unsigned long id) 
  12.167 -{ 
  12.168 -	return (domid_t)(id >> 16); 
  12.169 -}
  12.170 -
  12.171 -
  12.172 -
  12.173 -/******************************************************************
  12.174 - * GRANT HANDLES
  12.175 - */
  12.176 -
  12.177 -/* When using grant tables to map a frame for device access then the
  12.178 - * handle returned must be used to unmap the frame. This is needed to
  12.179 - * drop the ref count on the frame.
  12.180 - */
  12.181 -struct grant_handle_pair
  12.182 -{
  12.183 -	grant_handle_t kernel;
  12.184 -	grant_handle_t user;
  12.185 -};
  12.186 -static struct grant_handle_pair pending_grant_handles[MMAP_PAGES];
  12.187 -#define pending_handle(_idx, _i) \
  12.188 -    (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
  12.189 -#define BLKTAP_INVALID_HANDLE(_g) \
  12.190 -    (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
  12.191 -#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
  12.192 -    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
  12.193 -    } while(0)
  12.194 -
  12.195 -
  12.196 -/******************************************************************
  12.197 - * BLKTAP VM OPS
  12.198 - */
  12.199 -
  12.200 -static struct page *blktap_nopage(struct vm_area_struct *vma,
  12.201 -				  unsigned long address,
  12.202 -				  int *type)
  12.203 -{
  12.204 -	/*
  12.205 -	 * if the page has not been mapped in by the driver then generate
  12.206 -	 * a SIGBUS to the domain.
  12.207 -	 */
  12.208 -	force_sig(SIGBUS, current);
  12.209 -
  12.210 -	return 0;
  12.211 -}
  12.212 -
  12.213 -struct vm_operations_struct blktap_vm_ops = {
  12.214 -	.nopage = blktap_nopage,
  12.215 -};
  12.216 -
  12.217 -/******************************************************************
  12.218 - * BLKTAP FILE OPS
  12.219 - */
  12.220 -
  12.221 -static int blktap_open(struct inode *inode, struct file *filp)
  12.222 -{
  12.223 -	blkif_sring_t *sring;
  12.224 -
  12.225 -	if (test_and_set_bit(0, &blktap_dev_inuse))
  12.226 -		return -EBUSY;
  12.227 -    
  12.228 -	/* Allocate the fe ring. */
  12.229 -	sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
  12.230 -	if (sring == NULL)
  12.231 -		return -ENOMEM;
  12.232 -
  12.233 -	SetPageReserved(virt_to_page(sring));
  12.234 -    
  12.235 -	SHARED_RING_INIT(sring);
  12.236 -	FRONT_RING_INIT(&blktap_ufe_ring, sring, PAGE_SIZE);
  12.237 -
  12.238 -	return 0;
  12.239 -}
  12.240 -
  12.241 -static int blktap_release(struct inode *inode, struct file *filp)
  12.242 -{
  12.243 -	blktap_dev_inuse = 0;
  12.244 -	blktap_ring_ok = 0;
  12.245 -
  12.246 -	/* Free the ring page. */
  12.247 -	ClearPageReserved(virt_to_page(blktap_ufe_ring.sring));
  12.248 -	free_page((unsigned long) blktap_ufe_ring.sring);
  12.249 -
  12.250 -	/* Clear any active mappings and free foreign map table */
  12.251 -	if (blktap_vma != NULL) {
  12.252 -		zap_page_range(
  12.253 -			blktap_vma, blktap_vma->vm_start, 
  12.254 -			blktap_vma->vm_end - blktap_vma->vm_start, NULL);
  12.255 -		blktap_vma = NULL;
  12.256 -	}
  12.257 -
  12.258 -	return 0;
  12.259 -}
  12.260 -
  12.261 -
  12.262 -/* Note on mmap:
  12.263 - * We need to map pages to user space in a way that will allow the block
  12.264 - * subsystem set up direct IO to them.  This couldn't be done before, because
  12.265 - * there isn't really a sane way to translate a user virtual address down to a 
  12.266 - * physical address when the page belongs to another domain.
  12.267 - *
  12.268 - * My first approach was to map the page in to kernel memory, add an entry
  12.269 - * for it in the physical frame list (using alloc_lomem_region as in blkback)
  12.270 - * and then attempt to map that page up to user space.  This is disallowed
  12.271 - * by xen though, which realizes that we don't really own the machine frame
  12.272 - * underlying the physical page.
  12.273 - *
  12.274 - * The new approach is to provide explicit support for this in xen linux.
  12.275 - * The VMA now has a flag, VM_FOREIGN, to indicate that it contains pages
  12.276 - * mapped from other vms.  vma->vm_private_data is set up as a mapping 
  12.277 - * from pages to actual page structs.  There is a new clause in get_user_pages
  12.278 - * that does the right thing for this sort of mapping.
  12.279 - */
  12.280 -static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
  12.281 -{
  12.282 -	int size;
  12.283 -	struct page **map;
  12.284 -	int i;
  12.285 -
  12.286 -	DPRINTK(KERN_ALERT "blktap mmap (%lx, %lx)\n",
  12.287 -		vma->vm_start, vma->vm_end);
  12.288 -
  12.289 -	vma->vm_flags |= VM_RESERVED;
  12.290 -	vma->vm_ops = &blktap_vm_ops;
  12.291 -
  12.292 -	size = vma->vm_end - vma->vm_start;
  12.293 -	if (size != ((MMAP_PAGES + RING_PAGES) << PAGE_SHIFT)) {
  12.294 -		printk(KERN_INFO 
  12.295 -		       "blktap: you _must_ map exactly %d pages!\n",
  12.296 -		       MMAP_PAGES + RING_PAGES);
  12.297 -		return -EAGAIN;
  12.298 -	}
  12.299 -
  12.300 -	size >>= PAGE_SHIFT;
  12.301 -	DPRINTK(KERN_INFO "blktap: 2 rings + %d pages.\n", size-1);
  12.302 -    
  12.303 -	rings_vstart = vma->vm_start;
  12.304 -	user_vstart  = rings_vstart + (RING_PAGES << PAGE_SHIFT);
  12.305 -    
  12.306 -	/* Map the ring pages to the start of the region and reserve it. */
  12.307 -
  12.308 -	/* not sure if I really need to do this... */
  12.309 -	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  12.310 -
  12.311 -	if (remap_pfn_range(vma, vma->vm_start, 
  12.312 -			    __pa(blktap_ufe_ring.sring) >> PAGE_SHIFT, 
  12.313 -			    PAGE_SIZE, vma->vm_page_prot)) {
  12.314 -		WPRINTK("Mapping user ring failed!\n");
  12.315 -		goto fail;
  12.316 -	}
  12.317 -
  12.318 -	/* Mark this VM as containing foreign pages, and set up mappings. */
  12.319 -	map = kmalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
  12.320 -		      * sizeof(struct page_struct*),
  12.321 -		      GFP_KERNEL);
  12.322 -	if (map == NULL) {
  12.323 -		WPRINTK("Couldn't alloc VM_FOREIGH map.\n");
  12.324 -		goto fail;
  12.325 -	}
  12.326 -
  12.327 -	for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++)
  12.328 -		map[i] = NULL;
  12.329 -    
  12.330 -	vma->vm_private_data = map;
  12.331 -	vma->vm_flags |= VM_FOREIGN;
  12.332 -
  12.333 -	blktap_vma = vma;
  12.334 -	blktap_ring_ok = 1;
  12.335 -
  12.336 -	return 0;
  12.337 - fail:
  12.338 -	/* Clear any active mappings. */
  12.339 -	zap_page_range(vma, vma->vm_start, 
  12.340 -		       vma->vm_end - vma->vm_start, NULL);
  12.341 -
  12.342 -	return -ENOMEM;
  12.343 -}
  12.344 -
  12.345 -static int blktap_ioctl(struct inode *inode, struct file *filp,
  12.346 -                        unsigned int cmd, unsigned long arg)
  12.347 -{
  12.348 -	switch(cmd) {
  12.349 -	case BLKTAP_IOCTL_KICK_FE: /* There are fe messages to process. */
  12.350 -		return blktap_read_ufe_ring();
  12.351 -
  12.352 -	case BLKTAP_IOCTL_SETMODE:
  12.353 -		if (BLKTAP_MODE_VALID(arg)) {
  12.354 -			blktap_mode = arg;
  12.355 -			/* XXX: may need to flush rings here. */
  12.356 -			printk(KERN_INFO "blktap: set mode to %lx\n", arg);
  12.357 -			return 0;
  12.358 -		}
  12.359 -	case BLKTAP_IOCTL_PRINT_IDXS:
  12.360 -        {
  12.361 -		//print_fe_ring_idxs();
  12.362 -		WPRINTK("User Rings: \n-----------\n");
  12.363 -		WPRINTK("UF: rsp_cons: %2d, req_prod_prv: %2d "
  12.364 -			"| req_prod: %2d, rsp_prod: %2d\n",
  12.365 -			blktap_ufe_ring.rsp_cons,
  12.366 -			blktap_ufe_ring.req_prod_pvt,
  12.367 -			blktap_ufe_ring.sring->req_prod,
  12.368 -			blktap_ufe_ring.sring->rsp_prod);
  12.369 -            
  12.370 -        }
  12.371 -	}
  12.372 -	return -ENOIOCTLCMD;
  12.373 -}
  12.374 -
  12.375 -static unsigned int blktap_poll(struct file *file, poll_table *wait)
  12.376 -{
  12.377 -	poll_wait(file, &blktap_wait, wait);
  12.378 -	if (blktap_ufe_ring.req_prod_pvt != blktap_ufe_ring.sring->req_prod) {
  12.379 -		flush_tlb_all();
  12.380 -		RING_PUSH_REQUESTS(&blktap_ufe_ring);
  12.381 -		return POLLIN | POLLRDNORM;
  12.382 -	}
  12.383 -
  12.384 -	return 0;
  12.385 -}
  12.386 -
  12.387 -void blktap_kick_user(void)
  12.388 -{
  12.389 -	/* blktap_ring->req_prod = blktap_req_prod; */
  12.390 -	wake_up_interruptible(&blktap_wait);
  12.391 -}
  12.392 -
  12.393 -static struct file_operations blktap_fops = {
  12.394 -	.owner   = THIS_MODULE,
  12.395 -	.poll    = blktap_poll,
  12.396 -	.ioctl   = blktap_ioctl,
  12.397 -	.open    = blktap_open,
  12.398 -	.release = blktap_release,
  12.399 -	.mmap    = blktap_mmap,
  12.400 -};
  12.401 -
  12.402 -
  12.403 -
  12.404 -static int do_block_io_op(blkif_t *blkif, int max_to_do);
  12.405 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
  12.406 -static void make_response(blkif_t *blkif, unsigned long id, 
  12.407 -                          unsigned short op, int st);
  12.408 -
  12.409 -
  12.410 -static void fast_flush_area(int idx, int nr_pages)
  12.411 -{
  12.412 -	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
  12.413 -	unsigned int i, op = 0;
  12.414 -	struct grant_handle_pair *handle;
  12.415 -	uint64_t ptep;
  12.416 -	int ret;
  12.417 -
  12.418 -	for ( i = 0; i < nr_pages; i++)
  12.419 -	{
  12.420 -		handle = &pending_handle(idx, i);
  12.421 -		if (BLKTAP_INVALID_HANDLE(handle))
  12.422 -			continue;
  12.423 -
  12.424 -		gnttab_set_unmap_op(&unmap[op],
  12.425 -				    MMAP_VADDR(mmap_vstart, idx, i),
  12.426 -				    GNTMAP_host_map, handle->kernel);
  12.427 -		op++;
  12.428 -
  12.429 -		if (create_lookup_pte_addr(
  12.430 -			    blktap_vma->vm_mm,
  12.431 -			    MMAP_VADDR(user_vstart, idx, i), 
  12.432 -			    &ptep) !=0) {
  12.433 -			DPRINTK("Couldn't get a pte addr!\n");
  12.434 -			return;
  12.435 -		}
  12.436 -		gnttab_set_unmap_grnat_ref(&unmap[op], ptep,
  12.437 -					   GNTMAP_host_map |
  12.438 -					   GNTMAP_application_map |
  12.439 -					   GNTMAP_contains_pte, handle->user);
  12.440 -		op++;
  12.441 -            
  12.442 -		BLKTAP_INVALIDATE_HANDLE(handle);
  12.443 -	}
  12.444 -
  12.445 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, op);
  12.446 -	BUG_ON(ret);
  12.447 -
  12.448 -	if (blktap_vma != NULL)
  12.449 -		zap_page_range(blktap_vma, 
  12.450 -			       MMAP_VADDR(user_vstart, idx, 0), 
  12.451 -			       nr_pages << PAGE_SHIFT, NULL);
  12.452 -}
  12.453 -
  12.454 -/******************************************************************
  12.455 - * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE
  12.456 - */
  12.457 -
  12.458 -static struct list_head blkio_schedule_list;
  12.459 -static spinlock_t blkio_schedule_list_lock;
  12.460 -
  12.461 -static int __on_blkdev_list(blkif_t *blkif)
  12.462 -{
  12.463 -	return blkif->blkdev_list.next != NULL;
  12.464 -}
  12.465 -
  12.466 -static void remove_from_blkdev_list(blkif_t *blkif)
  12.467 -{
  12.468 -	unsigned long flags;
  12.469 -
  12.470 -	if (!__on_blkdev_list(blkif))
  12.471 -		return;
  12.472 -
  12.473 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
  12.474 -	if (__on_blkdev_list(blkif)) {
  12.475 -		list_del(&blkif->blkdev_list);
  12.476 -		blkif->blkdev_list.next = NULL;
  12.477 -		blkif_put(blkif);
  12.478 -	}
  12.479 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
  12.480 -}
  12.481 -
  12.482 -static void add_to_blkdev_list_tail(blkif_t *blkif)
  12.483 -{
  12.484 -	unsigned long flags;
  12.485 -
  12.486 -	if (__on_blkdev_list(blkif))
  12.487 -		return;
  12.488 -
  12.489 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
  12.490 -	if (!__on_blkdev_list(blkif) && (blkif->status == CONNECTED)) {
  12.491 -		list_add_tail(&blkif->blkdev_list, &blkio_schedule_list);
  12.492 -		blkif_get(blkif);
  12.493 -	}
  12.494 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
  12.495 -}
  12.496 -
  12.497 -
  12.498 -/******************************************************************
  12.499 - * SCHEDULER FUNCTIONS
  12.500 - */
  12.501 -
  12.502 -static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait);
  12.503 -
  12.504 -static int blkio_schedule(void *arg)
  12.505 -{
  12.506 -	DECLARE_WAITQUEUE(wq, current);
  12.507 -
  12.508 -	blkif_t          *blkif;
  12.509 -	struct list_head *ent;
  12.510 -
  12.511 -	daemonize("xenblkd");
  12.512 -
  12.513 -	for (;;) {
  12.514 -		/* Wait for work to do. */
  12.515 -		add_wait_queue(&blkio_schedule_wait, &wq);
  12.516 -		set_current_state(TASK_INTERRUPTIBLE);
  12.517 -		if ((NR_PENDING_REQS == MAX_PENDING_REQS) || 
  12.518 -		    list_empty(&blkio_schedule_list))
  12.519 -			schedule();
  12.520 -		__set_current_state(TASK_RUNNING);
  12.521 -		remove_wait_queue(&blkio_schedule_wait, &wq);
  12.522 -
  12.523 -		/* Queue up a batch of requests. */
  12.524 -		while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
  12.525 -		       !list_empty(&blkio_schedule_list)) {
  12.526 -			ent = blkio_schedule_list.next;
  12.527 -			blkif = list_entry(ent, blkif_t, blkdev_list);
  12.528 -			blkif_get(blkif);
  12.529 -			remove_from_blkdev_list(blkif);
  12.530 -			if (do_block_io_op(blkif, BATCH_PER_DOMAIN))
  12.531 -				add_to_blkdev_list_tail(blkif);
  12.532 -			blkif_put(blkif);
  12.533 -		}
  12.534 -	}
  12.535 -}
  12.536 -
  12.537 -static void maybe_trigger_blkio_schedule(void)
  12.538 -{
  12.539 -	/*
  12.540 -	 * Needed so that two processes, who together make the following
  12.541 -	 * predicate true, don't both read stale values and evaluate the
  12.542 -	 * predicate incorrectly. Incredibly unlikely to stall the scheduler
  12.543 -	 * on the x86, but...
  12.544 -	 */
  12.545 -	smp_mb();
  12.546 -
  12.547 -	if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
  12.548 -	    !list_empty(&blkio_schedule_list))
  12.549 -		wake_up(&blkio_schedule_wait);
  12.550 -}
  12.551 -
  12.552 -
  12.553 -
  12.554 -/******************************************************************
  12.555 - * COMPLETION CALLBACK -- Called as bh->b_end_io()
  12.556 - */
  12.557 -
  12.558 -
  12.559 -static int blktap_read_ufe_ring(void)
  12.560 -{
  12.561 -	/* This is called to read responses from the UFE ring. */
  12.562 -
  12.563 -	RING_IDX i, j, rp;
  12.564 -	blkif_response_t *resp;
  12.565 -	blkif_t *blkif;
  12.566 -	int pending_idx;
  12.567 -	pending_req_t *pending_req;
  12.568 -	unsigned long     flags;
  12.569 -
  12.570 -	/* if we are forwarding from UFERring to FERing */
  12.571 -	if (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) {
  12.572 -
  12.573 -		/* for each outstanding message on the UFEring  */
  12.574 -		rp = blktap_ufe_ring.sring->rsp_prod;
  12.575 -		rmb();
  12.576 -        
  12.577 -		for (i = blktap_ufe_ring.rsp_cons; i != rp; i++) {
  12.578 -			resp = RING_GET_RESPONSE(&blktap_ufe_ring, i);
  12.579 -			pending_idx = MASK_PEND_IDX(ID_TO_IDX(resp->id));
  12.580 -			pending_req = &pending_reqs[pending_idx];
  12.581 -            
  12.582 -			blkif = pending_req->blkif;
  12.583 -			for (j = 0; j < pending_req->nr_pages; j++) {
  12.584 -				unsigned long vaddr;
  12.585 -				struct page **map = blktap_vma->vm_private_data;
  12.586 -				int offset; 
  12.587 -
  12.588 -				vaddr  = MMAP_VADDR(user_vstart, pending_idx, j);
  12.589 -				offset = (vaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
  12.590 -
  12.591 -				//ClearPageReserved(virt_to_page(vaddr));
  12.592 -				ClearPageReserved((struct page *)map[offset]);
  12.593 -				map[offset] = NULL;
  12.594 -			}
  12.595 -
  12.596 -			fast_flush_area(pending_idx, pending_req->nr_pages);
  12.597 -			make_response(blkif, pending_req->id, resp->operation, 
  12.598 -				      resp->status);
  12.599 -			blkif_put(pending_req->blkif);
  12.600 -			spin_lock_irqsave(&pend_prod_lock, flags);
  12.601 -			pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
  12.602 -			spin_unlock_irqrestore(&pend_prod_lock, flags);
  12.603 -		}
  12.604 -		blktap_ufe_ring.rsp_cons = i;
  12.605 -		maybe_trigger_blkio_schedule();
  12.606 -	}
  12.607 -	return 0;
  12.608 -}
  12.609 -
  12.610 -
  12.611 -/******************************************************************************
  12.612 - * NOTIFICATION FROM GUEST OS.
  12.613 - */
  12.614 -
  12.615 -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
  12.616 -{
  12.617 -	blkif_t *blkif = dev_id;
  12.618 -	add_to_blkdev_list_tail(blkif);
  12.619 -	maybe_trigger_blkio_schedule();
  12.620 -	return IRQ_HANDLED;
  12.621 -}
  12.622 -
  12.623 -
  12.624 -
  12.625 -/******************************************************************
  12.626 - * DOWNWARD CALLS -- These interface with the block-device layer proper.
  12.627 - */
  12.628 -
  12.629 -static int do_block_io_op(blkif_t *blkif, int max_to_do)
  12.630 -{
  12.631 -	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
  12.632 -	blkif_request_t *req;
  12.633 -	RING_IDX i, rp;
  12.634 -	int more_to_do = 0;
  12.635 -    
  12.636 -	rp = blk_ring->sring->req_prod;
  12.637 -	rmb(); /* Ensure we see queued requests up to 'rp'. */
  12.638 -
  12.639 -	for (i = blk_ring->req_cons; 
  12.640 -	     (i != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, i);
  12.641 -	     i++ ) {
  12.642 -		if ((max_to_do-- == 0) ||
  12.643 -		    (NR_PENDING_REQS == MAX_PENDING_REQS)) {
  12.644 -			more_to_do = 1;
  12.645 -			break;
  12.646 -		}
  12.647 -        
  12.648 -		req = RING_GET_REQUEST(blk_ring, i);
  12.649 -		switch (req->operation) {
  12.650 -		case BLKIF_OP_READ:
  12.651 -		case BLKIF_OP_WRITE:
  12.652 -			dispatch_rw_block_io(blkif, req);
  12.653 -			break;
  12.654 -
  12.655 -		default:
  12.656 -			DPRINTK("error: unknown block io operation [%d]\n",
  12.657 -				req->operation);
  12.658 -			make_response(blkif, req->id, req->operation,
  12.659 -				      BLKIF_RSP_ERROR);
  12.660 -			break;
  12.661 -		}
  12.662 -	}
  12.663 -
  12.664 -	blk_ring->req_cons = i;
  12.665 -	blktap_kick_user();
  12.666 -
  12.667 -	return more_to_do;
  12.668 -}
  12.669 -
  12.670 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
  12.671 -{
  12.672 -	blkif_request_t *target;
  12.673 -	int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
  12.674 -	pending_req_t *pending_req;
  12.675 -	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
  12.676 -	int op, ret;
  12.677 -	unsigned int nseg;
  12.678 -	int retval;
  12.679 -
  12.680 -	/* Check that number of segments is sane. */
  12.681 -	nseg = req->nr_segments;
  12.682 -	if (unlikely(nseg == 0) || 
  12.683 -	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
  12.684 -		DPRINTK("Bad number of segments in request (%d)\n", nseg);
  12.685 -		goto bad_descriptor;
  12.686 -	}
  12.687 -
  12.688 -	/* Make sure userspace is ready. */
  12.689 -	if (!blktap_ring_ok) {
  12.690 -		DPRINTK("blktap: ring not ready for requests!\n");
  12.691 -		goto bad_descriptor;
  12.692 -	}
  12.693 -    
  12.694 -
  12.695 -	if (RING_FULL(&blktap_ufe_ring)) {
  12.696 -		WPRINTK("blktap: fe_ring is full, can't add "
  12.697 -			"(very broken!).\n");
  12.698 -		goto bad_descriptor;
  12.699 -	}
  12.700 -
  12.701 -	flush_cache_all(); /* a noop on intel... */
  12.702 -
  12.703 -	/* Map the foreign pages directly in to the application */    
  12.704 -	op = 0;
  12.705 -	for (i = 0; i < req->nr_segments; i++) {
  12.706 -
  12.707 -		unsigned long uvaddr;
  12.708 -		unsigned long kvaddr;
  12.709 -		uint64_t ptep;
  12.710 -		uint32_t flags;
  12.711 -
  12.712 -		uvaddr = MMAP_VADDR(user_vstart, pending_idx, i);
  12.713 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i);
  12.714 -
  12.715 -		flags = GNTMAP_host_map;
  12.716 -		/* This needs a bit more thought in terms of interposition: 
  12.717 -		 * If we want to be able to modify pages during write using 
  12.718 -		 * grant table mappings, the guest will either need to allow 
  12.719 -		 * it, or we'll need to incur a copy. Bit of an fbufs moment. ;) */
  12.720 -		if (req->operation == BLKIF_OP_WRITE)
  12.721 -			flags |= GNTMAP_readonly;
  12.722 -		/* Map the remote page to kernel. */
  12.723 -		gnttab_set_map_op(&map[op], kvaddr, flags, req->seg[i].gref,
  12.724 -				  blkif->domid);
  12.725 -		op++;
  12.726 -
  12.727 -		/* Now map it to user. */
  12.728 -		ret = create_lookup_pte_addr(blktap_vma->vm_mm, uvaddr, &ptep);
  12.729 -		if (ret) {
  12.730 -			DPRINTK("Couldn't get a pte addr!\n");
  12.731 -			fast_flush_area(pending_idx, req->nr_segments);
  12.732 -			goto bad_descriptor;
  12.733 -		}
  12.734 -
  12.735 -		flags = GNTMAP_host_map | GNTMAP_application_map
  12.736 -			| GNTMAP_contains_pte;
  12.737 -		/* Above interposition comment applies here as well. */
  12.738 -		if (req->operation == BLKIF_OP_WRITE)
  12.739 -			flags |= GNTMAP_readonly;
  12.740 -		gnttab_set_map_op(&map[op], ptep, flags, req->seg[i].gref,
  12.741 -				  blkif->domid);
  12.742 -		op++;
  12.743 -	}
  12.744 -
  12.745 -	retval = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
  12.746 -	BUG_ON(retval);
  12.747 -
  12.748 -	op = 0;
  12.749 -	for (i = 0; i < (req->nr_segments*2); i += 2) {
  12.750 -		unsigned long uvaddr;
  12.751 -		unsigned long kvaddr;
  12.752 -		unsigned long offset;
  12.753 -		int cancel = 0;
  12.754 -
  12.755 -		uvaddr = MMAP_VADDR(user_vstart, pending_idx, i/2);
  12.756 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i/2);
  12.757 -
  12.758 -		if (unlikely(map[i].status)) {
  12.759 -			DPRINTK("Error on kernel grant mapping (%d)\n",
  12.760 -				map[i].status);
  12.761 -			ret = map[i].status;
  12.762 -			cancel = 1;
  12.763 -		}
  12.764 -
  12.765 -		if (unlikely(map[i+1].status)) {
  12.766 -			DPRINTK("Error on user grant mapping (%d)\n",
  12.767 -				map[i+1].status);
  12.768 -			ret = map[i+1].status;
  12.769 -			cancel = 1;
  12.770 -		}
  12.771 -
  12.772 -		if (cancel) {
  12.773 -			fast_flush_area(pending_idx, req->nr_segments);
  12.774 -			goto bad_descriptor;
  12.775 -		}
  12.776 -
  12.777 -		/* Set the necessary mappings in p2m and in the VM_FOREIGN 
  12.778 -		 * vm_area_struct to allow user vaddr -> struct page lookups
  12.779 -		 * to work.  This is needed for direct IO to foreign pages. */
  12.780 -		set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
  12.781 -				FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
  12.782 -
  12.783 -		offset = (uvaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
  12.784 -		((struct page **)blktap_vma->vm_private_data)[offset] =
  12.785 -			pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
  12.786 -
  12.787 -		/* Save handles for unmapping later. */
  12.788 -		pending_handle(pending_idx, i/2).kernel = map[i].handle;
  12.789 -		pending_handle(pending_idx, i/2).user   = map[i+1].handle;
  12.790 -	}
  12.791 -
  12.792 -	/* Mark mapped pages as reserved: */
  12.793 -	for (i = 0; i < req->nr_segments; i++) {
  12.794 -		unsigned long kvaddr;
  12.795 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i);
  12.796 -		SetPageReserved(pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT));
  12.797 -	}
  12.798 -
  12.799 -	pending_req = &pending_reqs[pending_idx];
  12.800 -	pending_req->blkif     = blkif;
  12.801 -	pending_req->id        = req->id;
  12.802 -	pending_req->operation = req->operation;
  12.803 -	pending_req->status    = BLKIF_RSP_OKAY;
  12.804 -	pending_req->nr_pages  = nseg;
  12.805 -	req->id = MAKE_ID(blkif->domid, pending_idx);
  12.806 -	//atomic_set(&pending_req->pendcnt, nbio);
  12.807 -	pending_cons++;
  12.808 -	blkif_get(blkif);
  12.809 -
  12.810 -	/* Finally, write the request message to the user ring. */
  12.811 -	target = RING_GET_REQUEST(&blktap_ufe_ring,
  12.812 -				  blktap_ufe_ring.req_prod_pvt);
  12.813 -	memcpy(target, req, sizeof(*req));
  12.814 -	blktap_ufe_ring.req_prod_pvt++;
  12.815 -	return;
  12.816 -
  12.817 - bad_descriptor:
  12.818 -	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
  12.819 -} 
  12.820 -
  12.821 -
  12.822 -
  12.823 -/******************************************************************
  12.824 - * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
  12.825 - */
  12.826 -
  12.827 -
  12.828 -static void make_response(blkif_t *blkif, unsigned long id, 
  12.829 -                          unsigned short op, int st)
  12.830 -{
  12.831 -	blkif_response_t *resp;
  12.832 -	unsigned long     flags;
  12.833 -	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
  12.834 -
  12.835 -	/* Place on the response ring for the relevant domain. */ 
  12.836 -	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
  12.837 -	resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
  12.838 -	resp->id        = id;
  12.839 -	resp->operation = op;
  12.840 -	resp->status    = st;
  12.841 -	wmb(); /* Ensure other side can see the response fields. */
  12.842 -	blk_ring->rsp_prod_pvt++;
  12.843 -	RING_PUSH_RESPONSES(blk_ring);
  12.844 -	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
  12.845 -
  12.846 -	/* Kick the relevant domain. */
  12.847 -	notify_remote_via_irq(blkif->irq);
  12.848 -}
  12.849 -
  12.850 -static struct miscdevice blktap_miscdev = {
  12.851 -	.minor        = BLKTAP_MINOR,
  12.852 -	.name         = "blktap",
  12.853 -	.fops         = &blktap_fops,
  12.854 -	.devfs_name   = "misc/blktap",
  12.855 -};
  12.856 -
  12.857 -void blkif_deschedule(blkif_t *blkif)
  12.858 -{
  12.859 -	remove_from_blkdev_list(blkif);
  12.860 -}
  12.861 -
  12.862 -static int __init blkif_init(void)
  12.863 -{
  12.864 -	int i, j, err;
  12.865 -	struct page *page;
  12.866 -
  12.867 -	blkif_interface_init();
  12.868 -
  12.869 -	page = balloon_alloc_empty_page_range(MMAP_PAGES);
  12.870 -	BUG_ON(page == NULL);
  12.871 -	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
  12.872 -
  12.873 -	pending_cons = 0;
  12.874 -	pending_prod = MAX_PENDING_REQS;
  12.875 -	memset(pending_reqs, 0, sizeof(pending_reqs));
  12.876 -	for ( i = 0; i < MAX_PENDING_REQS; i++ )
  12.877 -		pending_ring[i] = i;
  12.878 -    
  12.879 -	spin_lock_init(&blkio_schedule_list_lock);
  12.880 -	INIT_LIST_HEAD(&blkio_schedule_list);
  12.881 -
  12.882 -	i = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES);
  12.883 -	BUG_ON(i<0);
  12.884 -
  12.885 -	blkif_xenbus_init();
  12.886 -
  12.887 -	for (i = 0; i < MAX_PENDING_REQS ; i++)
  12.888 -		for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
  12.889 -			BLKTAP_INVALIDATE_HANDLE(&pending_handle(i, j));
  12.890 -
  12.891 -	err = misc_register(&blktap_miscdev);
  12.892 -	if (err != 0) {
  12.893 -		printk(KERN_ALERT "Couldn't register /dev/misc/blktap (%d)\n",
  12.894 -		       err);
  12.895 -		return err;
  12.896 -	}
  12.897 -
  12.898 -	init_waitqueue_head(&blktap_wait);
  12.899 -
  12.900 -	return 0;
  12.901 -}
  12.902 -
  12.903 -__initcall(blkif_init);
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Fri Jun 09 14:13:18 2006 +0100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,100 +0,0 @@
    13.4 -
    13.5 -#ifndef __BLKIF__BACKEND__COMMON_H__
    13.6 -#define __BLKIF__BACKEND__COMMON_H__
    13.7 -
    13.8 -#include <linux/config.h>
    13.9 -#include <linux/version.h>
   13.10 -#include <linux/module.h>
   13.11 -#include <linux/interrupt.h>
   13.12 -#include <linux/slab.h>
   13.13 -#include <linux/blkdev.h>
   13.14 -#include <linux/vmalloc.h>
   13.15 -#include <asm/io.h>
   13.16 -#include <asm/setup.h>
   13.17 -#include <asm/pgalloc.h>
   13.18 -#include <xen/evtchn.h>
   13.19 -#include <asm/hypervisor.h>
   13.20 -#include <xen/interface/io/blkif.h>
   13.21 -#include <xen/interface/io/ring.h>
   13.22 -#include <xen/gnttab.h>
   13.23 -#include <xen/driver_util.h>
   13.24 -
   13.25 -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   13.26 -                                    __FILE__ , __LINE__ , ## _a )
   13.27 -
   13.28 -#define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
   13.29 -
   13.30 -struct vbd {
   13.31 -	blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
   13.32 -	unsigned char  readonly;    /* Non-zero -> read-only */
   13.33 -	unsigned char  type;        /* VDISK_xxx */
   13.34 -	u32            pdevice;     /* phys device that this vbd maps to */
   13.35 -	struct block_device *bdev;
   13.36 -}; 
   13.37 -
   13.38 -typedef struct blkif_st {
   13.39 -	/* Unique identifier for this interface. */
   13.40 -	domid_t           domid;
   13.41 -	unsigned int      handle;
   13.42 -	/* Physical parameters of the comms window. */
   13.43 -	unsigned int      evtchn;
   13.44 -	unsigned int      irq;
   13.45 -	/* Comms information. */
   13.46 -	blkif_back_ring_t blk_ring;
   13.47 -	struct vm_struct *blk_ring_area;
   13.48 -	/* VBDs attached to this interface. */
   13.49 -	struct vbd        vbd;
   13.50 -	/* Private fields. */
   13.51 -	enum { DISCONNECTED, CONNECTED } status;
   13.52 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
   13.53 -	/* Is this a blktap frontend */
   13.54 -	unsigned int     is_blktap;
   13.55 -#endif
   13.56 -	struct list_head blkdev_list;
   13.57 -	spinlock_t       blk_ring_lock;
   13.58 -	atomic_t         refcnt;
   13.59 -
   13.60 -	struct work_struct free_work;
   13.61 -
   13.62 -	grant_handle_t   shmem_handle;
   13.63 -	grant_ref_t      shmem_ref;
   13.64 -} blkif_t;
   13.65 -
   13.66 -blkif_t *alloc_blkif(domid_t domid);
   13.67 -void free_blkif_callback(blkif_t *blkif);
   13.68 -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
   13.69 -
   13.70 -#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
   13.71 -#define blkif_put(_b)                             \
   13.72 -    do {                                          \
   13.73 -        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   13.74 -            free_blkif_callback(_b);		  \
   13.75 -    } while (0)
   13.76 -
   13.77 -/* Create a vbd. */
   13.78 -int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, u32 pdevice,
   13.79 -	       int readonly);
   13.80 -void vbd_free(struct vbd *vbd);
   13.81 -
   13.82 -unsigned long vbd_size(struct vbd *vbd);
   13.83 -unsigned int vbd_info(struct vbd *vbd);
   13.84 -unsigned long vbd_secsize(struct vbd *vbd);
   13.85 -
   13.86 -struct phys_req {
   13.87 -	unsigned short       dev;
   13.88 -	unsigned short       nr_sects;
   13.89 -	struct block_device *bdev;
   13.90 -	blkif_sector_t       sector_number;
   13.91 -};
   13.92 -
   13.93 -int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
   13.94 -
   13.95 -void blkif_interface_init(void);
   13.96 -
   13.97 -void blkif_deschedule(blkif_t *blkif);
   13.98 -
   13.99 -void blkif_xenbus_init(void);
  13.100 -
  13.101 -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
  13.102 -
  13.103 -#endif /* __BLKIF__BACKEND__COMMON_H__ */
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Fri Jun 09 14:13:18 2006 +0100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,134 +0,0 @@
    14.4 -/******************************************************************************
    14.5 - * arch/xen/drivers/blkif/backend/interface.c
    14.6 - * 
    14.7 - * Block-device interface management.
    14.8 - * 
    14.9 - * Copyright (c) 2004, Keir Fraser
   14.10 - */
   14.11 -
   14.12 -#include "common.h"
   14.13 -#include <xen/evtchn.h>
   14.14 -
   14.15 -static kmem_cache_t *blkif_cachep;
   14.16 -
   14.17 -blkif_t *alloc_blkif(domid_t domid)
   14.18 -{
   14.19 -	blkif_t *blkif;
   14.20 -
   14.21 -	blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
   14.22 -	if (!blkif)
   14.23 -		return ERR_PTR(-ENOMEM);
   14.24 -
   14.25 -	memset(blkif, 0, sizeof(*blkif));
   14.26 -	blkif->domid = domid;
   14.27 -	blkif->status = DISCONNECTED;
   14.28 -	spin_lock_init(&blkif->blk_ring_lock);
   14.29 -	atomic_set(&blkif->refcnt, 1);
   14.30 -
   14.31 -	return blkif;
   14.32 -}
   14.33 -
   14.34 -static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
   14.35 -{
   14.36 -	struct gnttab_map_grant_ref op;
   14.37 -	int ret;
   14.38 -
   14.39 -	gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   14.40 -			  GNTMAP_host_map, shared_page, blkif->domid);
   14.41 -
   14.42 -	lock_vm_area(blkif->blk_ring_area);
   14.43 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   14.44 -	unlock_vm_area(blkif->blk_ring_area);
   14.45 -	BUG_ON(ret);
   14.46 -
   14.47 -	if (op.status) {
   14.48 -		DPRINTK(" Grant table operation failure !\n");
   14.49 -		return op.status;
   14.50 -	}
   14.51 -
   14.52 -	blkif->shmem_ref    = shared_page;
   14.53 -	blkif->shmem_handle = op.handle;
   14.54 -
   14.55 -	return 0;
   14.56 -}
   14.57 -
   14.58 -static void unmap_frontend_page(blkif_t *blkif)
   14.59 -{
   14.60 -	struct gnttab_unmap_grant_ref op;
   14.61 -	int ret;
   14.62 -
   14.63 -	gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   14.64 -			    GNTMAP_host_map, blkif->shmem_handle);
   14.65 -
   14.66 -	lock_vm_area(blkif->blk_ring_area);
   14.67 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   14.68 -	unlock_vm_area(blkif->blk_ring_area);
   14.69 -	BUG_ON(ret);
   14.70 -}
   14.71 -
   14.72 -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
   14.73 -{
   14.74 -	blkif_sring_t *sring;
   14.75 -	int err;
   14.76 -	struct evtchn_bind_interdomain bind_interdomain;
   14.77 -
   14.78 -	if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
   14.79 -		return -ENOMEM;
   14.80 -
   14.81 -	err = map_frontend_page(blkif, shared_page);
   14.82 -	if (err) {
   14.83 -		free_vm_area(blkif->blk_ring_area);
   14.84 -		return err;
   14.85 -	}
   14.86 -
   14.87 -	bind_interdomain.remote_dom  = blkif->domid;
   14.88 -	bind_interdomain.remote_port = evtchn;
   14.89 -
   14.90 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   14.91 -					  &bind_interdomain);
   14.92 -	if (err) {
   14.93 -		unmap_frontend_page(blkif);
   14.94 -		free_vm_area(blkif->blk_ring_area);
   14.95 -		return err;
   14.96 -	}
   14.97 -
   14.98 -	blkif->evtchn = bind_interdomain.local_port;
   14.99 -
  14.100 -	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
  14.101 -	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
  14.102 -
  14.103 -	blkif->irq = bind_evtchn_to_irqhandler(
  14.104 -		blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
  14.105 -
  14.106 -	blkif->status = CONNECTED;
  14.107 -
  14.108 -	return 0;
  14.109 -}
  14.110 -
  14.111 -static void free_blkif(void *arg)
  14.112 -{
  14.113 -	blkif_t *blkif = (blkif_t *)arg;
  14.114 -
  14.115 -	if (blkif->irq)
  14.116 -		unbind_from_irqhandler(blkif->irq, blkif);
  14.117 -
  14.118 -	if (blkif->blk_ring.sring) {
  14.119 -		unmap_frontend_page(blkif);
  14.120 -		free_vm_area(blkif->blk_ring_area);
  14.121 -		blkif->blk_ring.sring = NULL;
  14.122 -	}
  14.123 -
  14.124 -	kmem_cache_free(blkif_cachep, blkif);
  14.125 -}
  14.126 -
  14.127 -void free_blkif_callback(blkif_t *blkif)
  14.128 -{
  14.129 -	INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
  14.130 -	schedule_work(&blkif->free_work);
  14.131 -}
  14.132 -
  14.133 -void __init blkif_interface_init(void)
  14.134 -{
  14.135 -	blkif_cachep = kmem_cache_create(
  14.136 -		"blkif_cache", sizeof(blkif_t), 0, 0, NULL, NULL);
  14.137 -}
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Fri Jun 09 14:13:18 2006 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,223 +0,0 @@
    15.4 -/*  Xenbus code for blkif tap
    15.5 -
    15.6 -    A Warfield.
    15.7 -
    15.8 -    Hastily modified from the oroginal backend code:
    15.9 -
   15.10 -    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
   15.11 -
   15.12 -    This program is free software; you can redistribute it and/or modify
   15.13 -    it under the terms of the GNU General Public License as published by
   15.14 -    the Free Software Foundation; either version 2 of the License, or
   15.15 -    (at your option) any later version.
   15.16 -
   15.17 -    This program is distributed in the hope that it will be useful,
   15.18 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.19 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.20 -    GNU General Public License for more details.
   15.21 -
   15.22 -    You should have received a copy of the GNU General Public License
   15.23 -    along with this program; if not, write to the Free Software
   15.24 -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.25 -*/
   15.26 -
   15.27 -#include <stdarg.h>
   15.28 -#include <linux/module.h>
   15.29 -#include <xen/xenbus.h>
   15.30 -#include "common.h"
   15.31 -
   15.32 -struct backend_info
   15.33 -{
   15.34 -	struct xenbus_device *dev;
   15.35 -
   15.36 -	/* our communications channel */
   15.37 -	blkif_t *blkif;
   15.38 -
   15.39 -	long int frontend_id;
   15.40 -
   15.41 -	/* watch back end for changes */
   15.42 -	struct xenbus_watch backend_watch;
   15.43 -
   15.44 -	/* watch front end for changes */
   15.45 -	struct xenbus_watch watch;
   15.46 -	char *frontpath;
   15.47 -};
   15.48 -
   15.49 -static int blkback_remove(struct xenbus_device *dev)
   15.50 -{
   15.51 -	struct backend_info *be = dev->data;
   15.52 -
   15.53 -	if (be->watch.node)
   15.54 -		unregister_xenbus_watch(&be->watch);
   15.55 -	unregister_xenbus_watch(&be->backend_watch);
   15.56 -	if (be->blkif)
   15.57 -		blkif_put(be->blkif);
   15.58 -	kfree(be->frontpath);
   15.59 -	kfree(be);
   15.60 -	return 0;
   15.61 -}
   15.62 -
   15.63 -/* Front end tells us frame. */
   15.64 -static void frontend_changed(struct xenbus_watch *watch,
   15.65 -			     const char **vec, unsigned int len)
   15.66 -{
   15.67 -	unsigned long ring_ref;
   15.68 -	unsigned int evtchn;
   15.69 -	int err;
   15.70 -	struct backend_info *be
   15.71 -		= container_of(watch, struct backend_info, watch);
   15.72 -
   15.73 -	/* If other end is gone, delete ourself. */
   15.74 -	if (vec && !xenbus_exists(be->frontpath, "")) {
   15.75 -		xenbus_rm(be->dev->nodename, "");
   15.76 -		device_unregister(&be->dev->dev);
   15.77 -		return;
   15.78 -	}
   15.79 -	if (be->blkif == NULL || be->blkif->status == CONNECTED)
   15.80 -		return;
   15.81 -
   15.82 -	err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
   15.83 -			    "event-channel", "%u", &evtchn, NULL);
   15.84 -	if (err) {
   15.85 -		xenbus_dev_error(be->dev, err,
   15.86 -				 "reading %s/ring-ref and event-channel",
   15.87 -				 be->frontpath);
   15.88 -		return;
   15.89 -	}
   15.90 -
   15.91 -	/* Map the shared frame, irq etc. */
   15.92 -	err = blkif_map(be->blkif, ring_ref, evtchn);
   15.93 -	if (err) {
   15.94 -		xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
   15.95 -				 ring_ref, evtchn);
   15.96 -		goto abort;
   15.97 -	}
   15.98 -
   15.99 -	xenbus_dev_ok(be->dev);
  15.100 -
  15.101 -	return;
  15.102 -
  15.103 -abort:
  15.104 -	xenbus_transaction_end(1);
  15.105 -}
  15.106 -
  15.107 -/* 
  15.108 -   Setup supplies physical device.  
  15.109 -   We provide event channel and device details to front end.
  15.110 -   Frontend supplies shared frame and event channel.
  15.111 - */
  15.112 -static void backend_changed(struct xenbus_watch *watch,
  15.113 -			    const char **vec, unsigned int len)
  15.114 -{
  15.115 -	int err;
  15.116 -	char *p;
  15.117 -	long int handle;
  15.118 -	struct backend_info *be
  15.119 -		= container_of(watch, struct backend_info, backend_watch);
  15.120 -	struct xenbus_device *dev = be->dev;
  15.121 -
  15.122 -	if (be->blkif == NULL) {
  15.123 -		/* Front end dir is a number, which is used as the handle. */
  15.124 -		p = strrchr(be->frontpath, '/') + 1;
  15.125 -		handle = simple_strtoul(p, NULL, 0);
  15.126 -
  15.127 -		be->blkif = alloc_blkif(be->frontend_id);
  15.128 -		if (IS_ERR(be->blkif)) {
  15.129 -			err = PTR_ERR(be->blkif);
  15.130 -			be->blkif = NULL;
  15.131 -			xenbus_dev_error(dev, err, "creating block interface");
  15.132 -			return;
  15.133 -		}
  15.134 -
  15.135 -		/* Pass in NULL node to skip exist test. */
  15.136 -		frontend_changed(&be->watch, NULL, 0);
  15.137 -	}
  15.138 -}
  15.139 -
  15.140 -static int blkback_probe(struct xenbus_device *dev,
  15.141 -			 const struct xenbus_device_id *id)
  15.142 -{
  15.143 -	struct backend_info *be;
  15.144 -	char *frontend;
  15.145 -	int err;
  15.146 -
  15.147 -	be = kzalloc(sizeof(*be), GFP_KERNEL);
  15.148 -	if (!be) {
  15.149 -		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
  15.150 -		return -ENOMEM;
  15.151 -	}
  15.152 -
  15.153 -	frontend = NULL;
  15.154 -	err = xenbus_gather(dev->nodename,
  15.155 -			    "frontend-id", "%li", &be->frontend_id,
  15.156 -			    "frontend", NULL, &frontend,
  15.157 -			    NULL);
  15.158 -	if (XENBUS_EXIST_ERR(err))
  15.159 -		goto free_be;
  15.160 -	if (err < 0) {
  15.161 -		xenbus_dev_error(dev, err,
  15.162 -				 "reading %s/frontend or frontend-id",
  15.163 -				 dev->nodename);
  15.164 -		goto free_be;
  15.165 -	}
  15.166 -	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
  15.167 -		/* If we can't get a frontend path and a frontend-id,
  15.168 -		 * then our bus-id is no longer valid and we need to
  15.169 -		 * destroy the backend device.
  15.170 -		 */
  15.171 -		err = -ENOENT;
  15.172 -		goto free_be;
  15.173 -	}
  15.174 -
  15.175 -	be->dev = dev;
  15.176 -	be->backend_watch.node = dev->nodename;
  15.177 -	be->backend_watch.callback = backend_changed;
  15.178 -	/* Registration implicitly fires backend_changed once */
  15.179 -	err = register_xenbus_watch(&be->backend_watch);
  15.180 -	if (err) {
  15.181 -		be->backend_watch.node = NULL;
  15.182 -		xenbus_dev_error(dev, err, "adding backend watch on %s",
  15.183 -				 dev->nodename);
  15.184 -		goto free_be;
  15.185 -	}
  15.186 -
  15.187 -	be->frontpath = frontend;
  15.188 -	be->watch.node = be->frontpath;
  15.189 -	be->watch.callback = frontend_changed;
  15.190 -	err = register_xenbus_watch(&be->watch);
  15.191 -	if (err) {
  15.192 -		be->watch.node = NULL;
  15.193 -		xenbus_dev_error(dev, err,
  15.194 -				 "adding frontend watch on %s",
  15.195 -				 be->frontpath);
  15.196 -		goto free_be;
  15.197 -	}
  15.198 -
  15.199 -	dev->data = be;
  15.200 -	return 0;
  15.201 -
  15.202 - free_be:
  15.203 -	if (be->backend_watch.node)
  15.204 -		unregister_xenbus_watch(&be->backend_watch);
  15.205 -	kfree(frontend);
  15.206 -	kfree(be);
  15.207 -	return err;
  15.208 -}
  15.209 -
  15.210 -static struct xenbus_device_id blkback_ids[] = {
  15.211 -	{ "vbd" },
  15.212 -	{ "" }
  15.213 -};
  15.214 -
  15.215 -static struct xenbus_driver blkback = {
  15.216 -	.name = "vbd",
  15.217 -	.owner = THIS_MODULE,
  15.218 -	.ids = blkback_ids,
  15.219 -	.probe = blkback_probe,
  15.220 -	.remove = blkback_remove,
  15.221 -};
  15.222 -
  15.223 -void blkif_xenbus_init(void)
  15.224 -{
  15.225 -	xenbus_register_backend(&blkback);
  15.226 -}