ia64/xen-unstable

changeset 3718:456195c4774c

bitkeeper revision 1.1159.249.1 (4208d0edi9hSgBaQl0hrDcYiEH0yxg)

blktap driver fixes:
Allow the tap to terminate a block device (not need a backend).
Allow it to run in dom0.
Forward control messages to user space as well.

Signed-off-by: akw27@cl.cam.ac.uk
author akw27@labyrinth.cl.cam.ac.uk
date Tue Feb 08 14:47:09 2005 +0000 (2005-02-08)
parents 23e7cf28ddb3
children c9f8e6db6bfd
files linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c
line diff
     1.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c	Tue Feb 08 11:07:10 2005 +0000
     1.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c	Tue Feb 08 14:47:09 2005 +0000
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5  #include "blktap.h"
     1.6  
     1.7 -int __init xlblk_init(void)
     1.8 +int __init xlblktap_init(void)
     1.9  {
    1.10      ctrl_msg_t               cmsg;
    1.11      blkif_fe_driver_status_t fe_st;
    1.12 @@ -64,6 +64,7 @@ int __init xlblk_init(void)
    1.13      return 0;
    1.14  }
    1.15  
    1.16 +#if 0 /* tap doesn't handle suspend/resume */
    1.17  void blkdev_suspend(void)
    1.18  {
    1.19  }
    1.20 @@ -81,6 +82,6 @@ void blkdev_resume(void)
    1.21      memcpy(cmsg.msg, &st, sizeof(st));
    1.22      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    1.23  }
    1.24 +#endif
    1.25  
    1.26 -
    1.27 -__initcall(xlblk_init);
    1.28 +__initcall(xlblktap_init);
     2.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h	Tue Feb 08 11:07:10 2005 +0000
     2.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h	Tue Feb 08 14:47:09 2005 +0000
     2.3 @@ -48,6 +48,12 @@
     2.4  #define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
     2.5  
     2.6  
     2.7 +/* -------[ state descriptors ]--------------------------------------- */
     2.8 +
     2.9 +#define BLKIF_STATE_CLOSED       0
    2.10 +#define BLKIF_STATE_DISCONNECTED 1
    2.11 +#define BLKIF_STATE_CONNECTED    2
    2.12 +
    2.13  /* -------[ connection tracking ]------------------------------------- */
    2.14  
    2.15  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    2.16 @@ -99,7 +105,6 @@ typedef struct {
    2.17      unsigned long  mach_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    2.18      unsigned long  virt_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    2.19      int            next_free;
    2.20 -    int inuse; /* debugging */
    2.21  } active_req_t;
    2.22  
    2.23  typedef unsigned int ACTIVE_RING_IDX;
    2.24 @@ -181,7 +186,7 @@ extern unsigned long mmap_vstart;
    2.25   * for shared memory rings.
    2.26   */
    2.27  
    2.28 -#define RING_PAGES 128 
    2.29 +#define RING_PAGES 3 /* Ctrl, Front, and Back */ 
    2.30  extern unsigned long rings_vstart;
    2.31  
    2.32  
    2.33 @@ -190,11 +195,10 @@ extern unsigned long blktap_mode;
    2.34  
    2.35  /* Connection to a single backend domain. */
    2.36  extern blkif_front_ring_t blktap_be_ring;
    2.37 +extern unsigned int blktap_be_evtchn;
    2.38 +extern unsigned int blktap_be_state;
    2.39  
    2.40 -/* Event channel to backend domain. */
    2.41 -extern unsigned int blkif_ptbe_evtchn;
    2.42 -
    2.43 -/* User ring status... this will soon vanish into a ring struct. */
    2.44 +/* User ring status. */
    2.45  extern unsigned long blktap_ring_ok;
    2.46  
    2.47  /* -------[ ...and function prototypes. ]----------------------------- */
    2.48 @@ -213,8 +217,7 @@ void blktap_kick_user(void);
    2.49  /* user ring access functions: */
    2.50  int blktap_write_fe_ring(blkif_request_t *req);
    2.51  int blktap_write_be_ring(blkif_response_t *rsp);
    2.52 -int blktap_read_fe_ring(void);
    2.53 -int blktap_read_be_ring(void);
    2.54 +int blktap_write_ctrl_ring(ctrl_msg_t *msg);
    2.55  
    2.56  /* fe/be ring access functions: */
    2.57  int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp);
     3.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Tue Feb 08 11:07:10 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Tue Feb 08 14:47:09 2005 +0000
     3.3 @@ -10,10 +10,6 @@
     3.4   
     3.5  #include "blktap.h"
     3.6  
     3.7 -#define BLKIF_STATE_CLOSED       0
     3.8 -#define BLKIF_STATE_DISCONNECTED 1
     3.9 -#define BLKIF_STATE_CONNECTED    2
    3.10 -
    3.11  static char *blkif_state_name[] = {
    3.12      [BLKIF_STATE_CLOSED]       = "closed",
    3.13      [BLKIF_STATE_DISCONNECTED] = "disconnected",
    3.14 @@ -26,9 +22,10 @@ static char * blkif_status_name[] = {
    3.15      [BLKIF_INTERFACE_STATUS_CONNECTED]    = "connected",
    3.16      [BLKIF_INTERFACE_STATUS_CHANGED]      = "changed",
    3.17  };
    3.18 -static unsigned int blkif_pt_state = BLKIF_STATE_CLOSED;
    3.19 -static unsigned blkif_ptbe_irq;
    3.20 -unsigned int blkif_ptbe_evtchn;
    3.21 +
    3.22 +static unsigned blktap_be_irq;
    3.23 +unsigned int    blktap_be_state = BLKIF_STATE_CLOSED;
    3.24 +unsigned int    blktap_be_evtchn;
    3.25  
    3.26  /*-----[ Control Messages to/from Frontend VMs ]--------------------------*/
    3.27  
    3.28 @@ -306,7 +303,7 @@ static void blkif_ptbe_disconnect(void)
    3.29      sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
    3.30      SHARED_RING_INIT(BLKIF_RING, sring);
    3.31      FRONT_RING_INIT(BLKIF_RING, &blktap_be_ring, sring);
    3.32 -    blkif_pt_state  = BLKIF_STATE_DISCONNECTED;
    3.33 +    blktap_be_state  = BLKIF_STATE_DISCONNECTED;
    3.34      DPRINTK("Blkif-Passthrough-BE is now DISCONNECTED.\n");
    3.35      blkif_ptbe_send_interface_connect();
    3.36  }
    3.37 @@ -315,10 +312,10 @@ static void blkif_ptbe_connect(blkif_fe_
    3.38  {
    3.39      int err = 0;
    3.40      
    3.41 -    blkif_ptbe_evtchn = status->evtchn;
    3.42 -    blkif_ptbe_irq    = bind_evtchn_to_irq(blkif_ptbe_evtchn);
    3.43 +    blktap_be_evtchn = status->evtchn;
    3.44 +    blktap_be_irq    = bind_evtchn_to_irq(blktap_be_evtchn);
    3.45  
    3.46 -    err = request_irq(blkif_ptbe_irq, blkif_ptbe_int, 
    3.47 +    err = request_irq(blktap_be_irq, blkif_ptbe_int, 
    3.48                        SA_SAMPLE_RANDOM, "blkif", NULL);
    3.49      if ( err ) {
    3.50  	WPRINTK("blkfront request_irq failed (%d)\n", err);
    3.51 @@ -326,7 +323,7 @@ static void blkif_ptbe_connect(blkif_fe_
    3.52      } else {
    3.53  	/* transtion to connected in case we need to do a 
    3.54             a partion probe on a whole disk */
    3.55 -        blkif_pt_state = BLKIF_STATE_CONNECTED;
    3.56 +        blktap_be_state = BLKIF_STATE_CONNECTED;
    3.57      }
    3.58  }
    3.59  
    3.60 @@ -334,7 +331,7 @@ static void unexpected(blkif_fe_interfac
    3.61  {
    3.62      WPRINTK(" TAP: Unexpected blkif status %s in state %s\n", 
    3.63             blkif_status_name[status->status],
    3.64 -           blkif_state_name[blkif_pt_state]);
    3.65 +           blkif_state_name[blktap_be_state]);
    3.66  }
    3.67  
    3.68  static void blkif_ptbe_status(
    3.69 @@ -352,7 +349,7 @@ static void blkif_ptbe_status(
    3.70      switch ( status->status )
    3.71      {
    3.72      case BLKIF_INTERFACE_STATUS_CLOSED:
    3.73 -        switch ( blkif_pt_state )
    3.74 +        switch ( blktap_be_state )
    3.75          {
    3.76          case BLKIF_STATE_CLOSED:
    3.77              unexpected(status);
    3.78 @@ -366,7 +363,7 @@ static void blkif_ptbe_status(
    3.79          break;
    3.80          
    3.81      case BLKIF_INTERFACE_STATUS_DISCONNECTED:
    3.82 -        switch ( blkif_pt_state )
    3.83 +        switch ( blktap_be_state )
    3.84          {
    3.85          case BLKIF_STATE_CLOSED:
    3.86              blkif_ptbe_disconnect();
    3.87 @@ -380,7 +377,7 @@ static void blkif_ptbe_status(
    3.88          break;
    3.89          
    3.90      case BLKIF_INTERFACE_STATUS_CONNECTED:
    3.91 -        switch ( blkif_pt_state )
    3.92 +        switch ( blktap_be_state )
    3.93          {
    3.94          case BLKIF_STATE_CLOSED:
    3.95              unexpected(status);
    3.96 @@ -398,7 +395,7 @@ static void blkif_ptbe_status(
    3.97          break;
    3.98  
    3.99     case BLKIF_INTERFACE_STATUS_CHANGED:
   3.100 -        switch ( blkif_pt_state )
   3.101 +        switch ( blktap_be_state )
   3.102          {
   3.103          case BLKIF_STATE_CLOSED:
   3.104          case BLKIF_STATE_DISCONNECTED:
   3.105 @@ -440,6 +437,14 @@ void blkif_ctrlif_rx(ctrl_msg_t *msg, un
   3.106  
   3.107      case CMSG_BLKIF_BE:
   3.108          
   3.109 +        /* send a copy of the message to user if wanted */
   3.110 +        
   3.111 +        if ( (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) ||
   3.112 +             (blktap_mode & BLKTAP_MODE_COPY_FE) ) {
   3.113 +            
   3.114 +            blktap_write_ctrl_ring(msg);
   3.115 +        }
   3.116 +        
   3.117          switch ( msg->subtype )
   3.118          {
   3.119          case CMSG_BLKIF_BE_CREATE:
   3.120 @@ -500,11 +505,13 @@ void blkif_ctrlif_rx(ctrl_msg_t *msg, un
   3.121      ctrl_if_send_response(msg);
   3.122  }
   3.123  
   3.124 -/*-----[ All control messages enter here: ]-------------------------------*/
   3.125 +/*-----[ Initialization ]-------------------------------------------------*/
   3.126  
   3.127  void __init blkif_interface_init(void)
   3.128  {
   3.129      blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
   3.130                                       0, 0, NULL, NULL);
   3.131      memset(blkif_hash, 0, sizeof(blkif_hash));
   3.132 +    
   3.133 +    blktap_be_ring.sring = NULL;
   3.134  }
     4.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c	Tue Feb 08 11:07:10 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c	Tue Feb 08 14:47:09 2005 +0000
     4.3 @@ -40,8 +40,6 @@ inline active_req_t *get_active_req(void
     4.4      spin_lock_irqsave(&active_req_lock, flags);
     4.5      idx =  active_req_ring[MASK_ACTIVE_IDX(active_cons++)];
     4.6      ar = &active_reqs[idx];
     4.7 -if (ar->inuse) WPRINTK("AR INUSE! (%lu)\n", ar->id);
     4.8 -ar->inuse = 1;
     4.9      spin_unlock_irqrestore(&active_req_lock, flags);
    4.10      
    4.11      return ar;
    4.12 @@ -52,7 +50,6 @@ inline void free_active_req(active_req_t
    4.13      unsigned long flags;
    4.14          
    4.15      spin_lock_irqsave(&active_req_lock, flags);
    4.16 -ar->inuse = 0;
    4.17      active_req_ring[MASK_ACTIVE_IDX(active_prod++)] = ACTIVE_IDX(ar);
    4.18      spin_unlock_irqrestore(&active_req_lock, flags);
    4.19  }
    4.20 @@ -97,11 +94,8 @@ inline int write_resp_to_fe_ring(blkif_t
    4.21      blkif_response_t *resp_d;
    4.22      active_req_t *ar;
    4.23      
    4.24 -    /* remap id, and free the active req. blkif lookup goes here too.*/
    4.25      ar = &active_reqs[ID_TO_IDX(rsp->id)];
    4.26 -    /* WPRINTK("%3u > %3lu\n", ID_TO_IDX(rsp->id), ar->id); */
    4.27      rsp->id = ar->id;
    4.28 -    free_active_req(ar);
    4.29              
    4.30      resp_d = RING_GET_RESPONSE(BLKIF_RING, &blkif->blk_ring,
    4.31              blkif->blk_ring.rsp_prod_pvt);
    4.32 @@ -109,6 +103,9 @@ inline int write_resp_to_fe_ring(blkif_t
    4.33      wmb();
    4.34      blkif->blk_ring.rsp_prod_pvt++;
    4.35              
    4.36 +    blkif_put(ar->blkif);
    4.37 +    free_active_req(ar);
    4.38 +    
    4.39      return 0;
    4.40  }
    4.41  
    4.42 @@ -116,6 +113,11 @@ inline int write_req_to_be_ring(blkif_re
    4.43  {
    4.44      blkif_request_t *req_d;
    4.45  
    4.46 +    if ( blktap_be_state != BLKIF_STATE_CONNECTED ) {
    4.47 +        WPRINTK("Tap trying to access an unconnected backend!\n");
    4.48 +        return 0;
    4.49 +    }
    4.50 +    
    4.51      req_d = RING_GET_REQUEST(BLKIF_RING, &blktap_be_ring,
    4.52              blktap_be_ring.req_prod_pvt);
    4.53      memcpy(req_d, req, sizeof(blkif_request_t));
    4.54 @@ -135,6 +137,9 @@ inline void kick_fe_domain(blkif_t *blki
    4.55  
    4.56  inline void kick_be_domain(void)
    4.57  {
    4.58 +    if ( blktap_be_state != BLKIF_STATE_CONNECTED ) 
    4.59 +        return;
    4.60 +    
    4.61      wmb(); /* Ensure that the frontend can see the requests. */
    4.62      RING_PUSH_REQUESTS(BLKIF_RING, &blktap_be_ring);
    4.63      notify_via_evtchn(blkif_ptbe_evtchn);
    4.64 @@ -310,6 +315,7 @@ static int do_block_io_op(blkif_t *blkif
    4.65           */
    4.66          ar = get_active_req();
    4.67          ar->id = req_s->id;
    4.68 +        blkif_get(blkif);
    4.69          ar->blkif = blkif;
    4.70          req_s->id = MAKE_ID(blkif->domid, ACTIVE_IDX(ar));
    4.71          /* WPRINTK("%3u < %3lu\n", ID_TO_IDX(req_s->id), ar->id); */
    4.72 @@ -458,11 +464,13 @@ void print_vm_ring_idxs(void)
    4.73                  blkif->blk_ring.sring->req_prod,
    4.74                  blkif->blk_ring.sring->rsp_prod);
    4.75      }
    4.76 -    WPRINTK("BE Ring: \n--------\n");
    4.77 -    WPRINTK("BE: rsp_cons: %2d, req_prod_prv: %2d "
    4.78 -        "| req_prod: %2d, rsp_prod: %2d\n",
    4.79 -        blktap_be_ring.rsp_cons,
    4.80 -        blktap_be_ring.req_prod_pvt,
    4.81 -        blktap_be_ring.sring->req_prod,
    4.82 -        blktap_be_ring.sring->rsp_prod);
    4.83 +    if (blktap_be_ring.sring != NULL) {
    4.84 +        WPRINTK("BE Ring: \n--------\n");
    4.85 +        WPRINTK("BE: rsp_cons: %2d, req_prod_prv: %2d "
    4.86 +            "| req_prod: %2d, rsp_prod: %2d\n",
    4.87 +            blktap_be_ring.rsp_cons,
    4.88 +            blktap_be_ring.req_prod_pvt,
    4.89 +            blktap_be_ring.sring->req_prod,
    4.90 +            blktap_be_ring.sring->rsp_prod);
    4.91 +    }
    4.92  }        
     5.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Tue Feb 08 11:07:10 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Tue Feb 08 14:47:09 2005 +0000
     5.3 @@ -19,6 +19,7 @@
     5.4  #include <linux/gfp.h>
     5.5  #include <linux/poll.h>
     5.6  #include <asm/pgalloc.h>
     5.7 +#include <asm-xen/xen-public/io/blkif.h> /* for control ring. */
     5.8  
     5.9  #include "blktap.h"
    5.10  
    5.11 @@ -40,6 +41,11 @@ unsigned long rings_vstart;
    5.12  /* Rings up to user space. */
    5.13  static blkif_front_ring_t blktap_ufe_ring;
    5.14  static blkif_back_ring_t  blktap_ube_ring;
    5.15 +static ctrl_front_ring_t  blktap_uctrl_ring;
    5.16 +
    5.17 +/* local prototypes */
    5.18 +static int blktap_read_fe_ring(void);
    5.19 +static int blktap_read_be_ring(void);
    5.20  
    5.21  /* -------[ blktap vm ops ]------------------------------------------- */
    5.22  
    5.23 @@ -66,16 +72,28 @@ struct vm_operations_struct blktap_vm_op
    5.24  static int blktap_open(struct inode *inode, struct file *filp)
    5.25  {
    5.26      blkif_sring_t *sring;
    5.27 +    ctrl_sring_t *csring;
    5.28      
    5.29      if ( test_and_set_bit(0, &blktap_dev_inuse) )
    5.30          return -EBUSY;
    5.31  
    5.32      printk(KERN_ALERT "blktap open.\n");
    5.33 +    
    5.34 +    /* Allocate the ctrl ring. */
    5.35 +    csring = (ctrl_sring_t *)get_zeroed_page(GFP_KERNEL);
    5.36 +    if (csring == NULL)
    5.37 +        goto fail_nomem;
    5.38 +
    5.39 +    SetPageReserved(virt_to_page(csring));
    5.40 +    
    5.41 +    SHARED_RING_INIT(CTRL_RING, csring);
    5.42 +    FRONT_RING_INIT(CTRL_RING, &blktap_uctrl_ring, csring);
    5.43 +
    5.44  
    5.45      /* Allocate the fe ring. */
    5.46      sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
    5.47      if (sring == NULL)
    5.48 -        goto fail_nomem;
    5.49 +        goto fail_free_ctrl;
    5.50  
    5.51      SetPageReserved(virt_to_page(sring));
    5.52      
    5.53 @@ -95,6 +113,9 @@ static int blktap_open(struct inode *ino
    5.54      DPRINTK(KERN_ALERT "blktap open.\n");
    5.55  
    5.56      return 0;
    5.57 +    
    5.58 + fail_free_ctrl:
    5.59 +    free_page( (unsigned long) blktap_uctrl_ring.sring);
    5.60  
    5.61   fail_free_fe:
    5.62      free_page( (unsigned long) blktap_ufe_ring.sring);
    5.63 @@ -111,6 +132,9 @@ static int blktap_release(struct inode *
    5.64      printk(KERN_ALERT "blktap closed.\n");
    5.65  
    5.66      /* Free the ring page. */
    5.67 +    ClearPageReserved(virt_to_page(blktap_uctrl_ring.sring));
    5.68 +    free_page((unsigned long) blktap_uctrl_ring.sring);
    5.69 +
    5.70      ClearPageReserved(virt_to_page(blktap_ufe_ring.sring));
    5.71      free_page((unsigned long) blktap_ufe_ring.sring);
    5.72  
    5.73 @@ -120,6 +144,15 @@ static int blktap_release(struct inode *
    5.74      return 0;
    5.75  }
    5.76  
    5.77 +/* Note on mmap:
    5.78 + * remap_pfn_range sets VM_IO on vma->vm_flags.  In trying to make libaio
    5.79 + * work to do direct page access from userspace, this ended up being a
    5.80 + * problem.  The bigger issue seems to be that there is no way to map
    5.81 + * a foreign page in to user space and have the virtual address of that 
    5.82 + * page map sanely down to a mfn.
    5.83 + * Removing the VM_IO flag results in a loop in get_user_pages, as 
    5.84 + * pfn_valid() always fails on a foreign page.
    5.85 + */
    5.86  static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
    5.87  {
    5.88      int size;
    5.89 @@ -148,20 +181,28 @@ static int blktap_mmap(struct file *filp
    5.90      /* not sure if I really need to do this... */
    5.91      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    5.92  
    5.93 +    DPRINTK("Mapping ctrl_ring page %lx.\n", __pa(blktap_uctrl_ring.sring));
    5.94 +    if (remap_pfn_range(vma, vma->vm_start, 
    5.95 +                         __pa(blktap_uctrl_ring.sring) >> PAGE_SHIFT, 
    5.96 +                         PAGE_SIZE, vma->vm_page_prot)) {
    5.97 +        WPRINTK("ctrl_ring: remap_pfn_range failure!\n");
    5.98 +    }
    5.99 +
   5.100 +
   5.101      DPRINTK("Mapping be_ring page %lx.\n", __pa(blktap_ube_ring.sring));
   5.102 -    if (remap_page_range(vma, vma->vm_start, 
   5.103 -                         __pa(blktap_ube_ring.sring), 
   5.104 +    if (remap_pfn_range(vma, vma->vm_start + PAGE_SIZE, 
   5.105 +                         __pa(blktap_ube_ring.sring) >> PAGE_SHIFT, 
   5.106                           PAGE_SIZE, vma->vm_page_prot)) {
   5.107 -        WPRINTK("be_ring: remap_page_range failure!\n");
   5.108 +        WPRINTK("be_ring: remap_pfn_range failure!\n");
   5.109      }
   5.110  
   5.111      DPRINTK("Mapping fe_ring page %lx.\n", __pa(blktap_ufe_ring.sring));
   5.112 -    if (remap_page_range(vma, vma->vm_start + PAGE_SIZE, 
   5.113 -                         __pa(blktap_ufe_ring.sring), 
   5.114 +    if (remap_pfn_range(vma, vma->vm_start + ( 2 * PAGE_SIZE ), 
   5.115 +                         __pa(blktap_ufe_ring.sring) >> PAGE_SHIFT, 
   5.116                           PAGE_SIZE, vma->vm_page_prot)) {
   5.117 -        WPRINTK("fe_ring: remap_page_range failure!\n");
   5.118 +        WPRINTK("fe_ring: remap_pfn_range failure!\n");
   5.119      }
   5.120 -
   5.121 +            
   5.122      blktap_vma = vma;
   5.123      blktap_ring_ok = 1;
   5.124  
   5.125 @@ -211,9 +252,11 @@ static unsigned int blktap_poll(struct f
   5.126  {
   5.127          poll_wait(file, &blktap_wait, wait);
   5.128  
   5.129 -        if ( RING_HAS_UNPUSHED_REQUESTS(BLKIF_RING, &blktap_ufe_ring) ||
   5.130 +        if ( RING_HAS_UNPUSHED_REQUESTS(BLKIF_RING, &blktap_uctrl_ring) ||
   5.131 +             RING_HAS_UNPUSHED_REQUESTS(BLKIF_RING, &blktap_ufe_ring)   ||
   5.132               RING_HAS_UNPUSHED_RESPONSES(BLKIF_RING, &blktap_ube_ring) ) {
   5.133  
   5.134 +            RING_PUSH_REQUESTS(BLKIF_RING, &blktap_uctrl_ring);
   5.135              RING_PUSH_REQUESTS(BLKIF_RING, &blktap_ufe_ring);
   5.136              RING_PUSH_RESPONSES(BLKIF_RING, &blktap_ube_ring);
   5.137              return POLLIN | POLLRDNORM;
   5.138 @@ -260,7 +303,6 @@ int blktap_write_fe_ring(blkif_request_t
   5.139          return 0;
   5.140      }
   5.141  
   5.142 -    //target = RING_NEXT_EMPTY_REQUEST(BLKIF_RING, &blktap_ufe_ring);
   5.143      target = RING_GET_REQUEST(BLKIF_RING, &blktap_ufe_ring,
   5.144              blktap_ufe_ring.req_prod_pvt);
   5.145      memcpy(target, req, sizeof(*req));
   5.146 @@ -270,7 +312,7 @@ int blktap_write_fe_ring(blkif_request_t
   5.147  
   5.148          error = direct_remap_area_pages(blktap_vma->vm_mm, 
   5.149                                          MMAP_VADDR(ID_TO_IDX(req->id), i), 
   5.150 -                                        target->frame_and_sects[0] & PAGE_MASK,
   5.151 +                                        target->frame_and_sects[i] & PAGE_MASK,
   5.152                                          PAGE_SIZE,
   5.153                                          blktap_vma->vm_page_prot,
   5.154                                          ID_TO_DOM(req->id));
   5.155 @@ -302,7 +344,6 @@ int blktap_write_be_ring(blkif_response_
   5.156  
   5.157      /* No test for fullness in the response direction. */
   5.158  
   5.159 -    //target = RING_NEXT_EMPTY_RESPONSE(BLKIF_RING, &blktap_ube_ring);
   5.160      target = RING_GET_RESPONSE(BLKIF_RING, &blktap_ube_ring,
   5.161              blktap_ube_ring.rsp_prod_pvt);
   5.162      memcpy(target, rsp, sizeof(*rsp));
   5.163 @@ -314,7 +355,7 @@ int blktap_write_be_ring(blkif_response_
   5.164      return 0;
   5.165  }
   5.166  
   5.167 -int blktap_read_fe_ring(void)
   5.168 +static int blktap_read_fe_ring(void)
   5.169  {
   5.170      /* This is called to read responses from the UFE ring. */
   5.171  
   5.172 @@ -329,7 +370,6 @@ int blktap_read_fe_ring(void)
   5.173      if (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) {
   5.174  
   5.175          /* for each outstanding message on the UFEring  */
   5.176 -        //RING_FOREACH_RESPONSE(BLKIF_RING, &blktap_ufe_ring, prod, resp_s) {
   5.177          rp = blktap_ufe_ring.sring->rsp_prod;
   5.178          rmb();
   5.179          
   5.180 @@ -349,7 +389,7 @@ int blktap_read_fe_ring(void)
   5.181      return 0;
   5.182  }
   5.183  
   5.184 -int blktap_read_be_ring(void)
   5.185 +static int blktap_read_be_ring(void)
   5.186  {
   5.187      /* This is called to read requests from the UBE ring. */
   5.188  
   5.189 @@ -362,7 +402,6 @@ int blktap_read_be_ring(void)
   5.190      if (blktap_mode & BLKTAP_MODE_INTERCEPT_BE) {
   5.191  
   5.192          /* for each outstanding message on the UFEring  */
   5.193 -        //RING_FOREACH_REQUEST(BLKIF_RING, &blktap_ube_ring, prod, req_s) {
   5.194          rp = blktap_ube_ring.sring->req_prod;
   5.195          rmb();
   5.196          for ( i = blktap_ube_ring.req_cons; i != rp; i++ )
   5.197 @@ -379,6 +418,31 @@ int blktap_read_be_ring(void)
   5.198  
   5.199      return 0;
   5.200  }
   5.201 +
   5.202 +int blktap_write_ctrl_ring(ctrl_msg_t *msg)
   5.203 +{
   5.204 +    ctrl_msg_t *target;
   5.205 +
   5.206 +    if ( ! blktap_ring_ok ) {
   5.207 +        DPRINTK("blktap: be_ring not ready for a request!\n");
   5.208 +        return 0;
   5.209 +    }
   5.210 +
   5.211 +    /* No test for fullness in the response direction. */
   5.212 +
   5.213 +    target = RING_GET_REQUEST(CTRL_RING, &blktap_uctrl_ring,
   5.214 +            blktap_uctrl_ring.req_prod_pvt);
   5.215 +    memcpy(target, msg, sizeof(*msg));
   5.216 +
   5.217 +    blktap_uctrl_ring.req_prod_pvt++;
   5.218 +    
   5.219 +    /* currently treat the ring as unidirectional. */
   5.220 +    blktap_uctrl_ring.rsp_cons = blktap_uctrl_ring.sring->rsp_prod;
   5.221 +    
   5.222 +    return 0;
   5.223 +       
   5.224 +}
   5.225 +
   5.226  /* -------[ blktap module setup ]------------------------------------- */
   5.227  
   5.228  static struct miscdevice blktap_miscdev = {