ia64/xen-unstable

changeset 6287:66348ff38ec1

Merge.

Signed-off-by: Steven Smith, sos22@cam.ac.uk
author sos22@douglas.cl.cam.ac.uk
date Fri Aug 19 13:08:50 2005 +0000 (2005-08-19)
parents 509316987d65 188c782fa9bb
children 56e5cf83e3af
files linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/xen/i386/mm/init.c linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/blkback/Makefile linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/interface.c linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h linux-2.6-xen-sparse/include/asm-xen/hypervisor.h linux-2.6-xen-sparse/include/asm-xen/xenbus.h tools/examples/network-bridge tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/event.py tools/python/xen/xend/server/relocate.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py xen/arch/x86/domain.c xen/arch/x86/mm.c xen/arch/x86/setup.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/traps.c xen/common/domain.c xen/common/event_channel.c xen/common/schedule.c xen/drivers/char/console.c xen/include/asm-x86/e820.h xen/include/asm-x86/uaccess.h xen/include/public/io/blkif.h xen/include/public/xen.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 10:50:15 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 13:08:50 2005 +0000
     1.3 @@ -120,8 +120,6 @@ static int restore_vcpu_context(int vcpu
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -extern unsigned uber_debug;
     1.8 -
     1.9  static int __do_suspend(void *ignore)
    1.10  {
    1.11      int i, j;
    1.12 @@ -130,13 +128,6 @@ static int __do_suspend(void *ignore)
    1.13  
    1.14      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
    1.15  	/* XXX SMH: yes it would :-( */	
    1.16 -#ifdef CONFIG_XEN_BLKDEV_FRONTEND
    1.17 -    extern void blkdev_suspend(void);
    1.18 -    extern void blkdev_resume(void);
    1.19 -#else
    1.20 -#define blkdev_suspend() do{}while(0)
    1.21 -#define blkdev_resume()  do{}while(0)
    1.22 -#endif
    1.23  
    1.24  #ifdef CONFIG_XEN_NETDEV_FRONTEND
    1.25      extern void netif_suspend(void);
    1.26 @@ -234,8 +225,6 @@ static int __do_suspend(void *ignore)
    1.27  
    1.28      netif_suspend();
    1.29  
    1.30 -    blkdev_suspend();
    1.31 -
    1.32      time_suspend();
    1.33  
    1.34  #ifdef CONFIG_SMP
    1.35 @@ -293,8 +282,6 @@ static int __do_suspend(void *ignore)
    1.36  
    1.37      time_resume();
    1.38  
    1.39 -    blkdev_resume();
    1.40 -
    1.41      netif_resume();
    1.42  
    1.43      usbif_resume();
    1.44 @@ -315,8 +302,6 @@ static int __do_suspend(void *ignore)
    1.45  	}
    1.46      }
    1.47  
    1.48 -    uber_debug = 0;
    1.49 -
    1.50   out:
    1.51      if ( suspend_record != NULL )
    1.52          free_page((unsigned long)suspend_record);
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 10:50:15 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 13:08:50 2005 +0000
     2.3 @@ -1,2 +1,2 @@
     2.4  
     2.5 -obj-y	:= blkback.o control.o interface.o vbd.o
     2.6 +obj-y	:= blkback.o xenbus.o interface.o vbd.o
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 10:50:15 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 13:08:50 2005 +0000
     3.3 @@ -104,7 +104,6 @@ static inline domid_t ID_TO_DOM(unsigned
     3.4  #endif
     3.5  
     3.6  static int do_block_io_op(blkif_t *blkif, int max_to_do);
     3.7 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
     3.8  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
     3.9  static void make_response(blkif_t *blkif, unsigned long id, 
    3.10                            unsigned short op, int st);
    3.11 @@ -349,10 +348,6 @@ static int do_block_io_op(blkif_t *blkif
    3.12              dispatch_rw_block_io(blkif, req);
    3.13              break;
    3.14  
    3.15 -        case BLKIF_OP_PROBE:
    3.16 -            dispatch_probe(blkif, req);
    3.17 -            break;
    3.18 -
    3.19          default:
    3.20              DPRINTK("error: unknown block io operation [%d]\n",
    3.21                      req->operation);
    3.22 @@ -365,66 +360,6 @@ static int do_block_io_op(blkif_t *blkif
    3.23      return more_to_do;
    3.24  }
    3.25  
    3.26 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
    3.27 -{
    3.28 -    int rsp = BLKIF_RSP_ERROR;
    3.29 -    int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
    3.30 -
    3.31 -    /* We expect one buffer only. */
    3.32 -    if ( unlikely(req->nr_segments != 1) )
    3.33 -        goto out;
    3.34 -
    3.35 -    /* Make sure the buffer is page-sized. */
    3.36 -    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
    3.37 -         (blkif_last_sect(req->frame_and_sects[0]) != ((PAGE_SIZE/512)-1)) )
    3.38 -        goto out;
    3.39 -
    3.40 -#ifdef CONFIG_XEN_BLKDEV_GRANT
    3.41 -    {
    3.42 -        struct gnttab_map_grant_ref map;
    3.43 -
    3.44 -        map.host_addr = MMAP_VADDR(pending_idx, 0);
    3.45 -        map.flags = GNTMAP_host_map;
    3.46 -        map.ref = blkif_gref_from_fas(req->frame_and_sects[0]);
    3.47 -        map.dom = blkif->domid;
    3.48 -
    3.49 -        if ( unlikely(HYPERVISOR_grant_table_op(
    3.50 -                        GNTTABOP_map_grant_ref, &map, 1)))
    3.51 -            BUG();
    3.52 -
    3.53 -        if ( map.handle < 0 )
    3.54 -            goto out;
    3.55 -
    3.56 -        pending_handle(pending_idx, 0) = map.handle;
    3.57 -    }
    3.58 -#else /* else CONFIG_XEN_BLKDEV_GRANT */
    3.59 -
    3.60 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    3.61 -    /* Grab the real frontend out of the probe message. */
    3.62 -    if (req->frame_and_sects[1] == BLKTAP_COOKIE) 
    3.63 -        blkif->is_blktap = 1;
    3.64 -#endif
    3.65 -
    3.66 -
    3.67 -    if ( HYPERVISOR_update_va_mapping_otherdomain(
    3.68 -        MMAP_VADDR(pending_idx, 0),
    3.69 -        pfn_pte_ma(req->frame_and_sects[0] >> PAGE_SHIFT, PAGE_KERNEL),
    3.70 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    3.71 -        0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) )
    3.72 -#else
    3.73 -        0, blkif->domid) )
    3.74 -#endif
    3.75 -        goto out;
    3.76 -#endif /* endif CONFIG_XEN_BLKDEV_GRANT */
    3.77 -   
    3.78 -    rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), 
    3.79 -                    PAGE_SIZE / sizeof(vdisk_t));
    3.80 -
    3.81 - out:
    3.82 -    fast_flush_area(pending_idx, 1);
    3.83 -    make_response(blkif, req->id, req->operation, rsp);
    3.84 -}
    3.85 -
    3.86  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
    3.87  {
    3.88      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
    3.89 @@ -460,7 +395,7 @@ static void dispatch_rw_block_io(blkif_t
    3.90          goto bad_descriptor;
    3.91      }
    3.92  
    3.93 -    preq.dev           = req->device;
    3.94 +    preq.dev           = req->handle;
    3.95      preq.sector_number = req->sector_number;
    3.96      preq.nr_sects      = 0;
    3.97  
    3.98 @@ -730,8 +665,8 @@ static int __init blkif_init(void)
    3.99          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
   3.100  #endif
   3.101  
   3.102 -    blkif_ctrlif_init();
   3.103 -    
   3.104 +    blkif_xenbus_init();
   3.105 +
   3.106  #ifdef CONFIG_XEN_BLKDEV_GRANT
   3.107      memset( pending_grant_handles,  BLKBACK_INVALID_HANDLE, MMAP_PAGES );
   3.108      printk(KERN_ALERT "Blkif backend is using grant tables.\n");
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 10:50:15 2005 +0000
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 13:08:50 2005 +0000
     4.3 @@ -13,7 +13,6 @@
     4.4  #include <asm/io.h>
     4.5  #include <asm/setup.h>
     4.6  #include <asm/pgalloc.h>
     4.7 -#include <asm-xen/ctrl_if.h>
     4.8  #include <asm-xen/evtchn.h>
     4.9  #include <asm-xen/hypervisor.h>
    4.10  #include <asm-xen/xen-public/io/blkif.h>
    4.11 @@ -47,6 +46,7 @@ typedef struct blkif_st {
    4.12      /* Physical parameters of the comms window. */
    4.13      unsigned long     shmem_frame;
    4.14      unsigned int      evtchn;
    4.15 +    unsigned int      remote_evtchn;
    4.16      /* Comms information. */
    4.17      blkif_back_ring_t blk_ring;
    4.18      /* VBDs attached to this interface. */
    4.19 @@ -81,17 +81,29 @@ void blkif_destroy(blkif_be_destroy_t *d
    4.20  void blkif_connect(blkif_be_connect_t *connect);
    4.21  int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
    4.22  void blkif_disconnect_complete(blkif_t *blkif);
    4.23 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
    4.24 +blkif_t *blkif_find(domid_t domid);
    4.25 +void free_blkif(blkif_t *blkif);
    4.26 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
    4.27 +
    4.28  #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
    4.29  #define blkif_put(_b)                             \
    4.30      do {                                          \
    4.31          if ( atomic_dec_and_test(&(_b)->refcnt) ) \
    4.32 -            blkif_disconnect_complete(_b);        \
    4.33 +            free_blkif(_b);			  \
    4.34      } while (0)
    4.35  
    4.36 -void vbd_create(blkif_be_vbd_create_t *create); 
    4.37 +struct vbd;
    4.38 +void vbd_free(blkif_t *blkif, struct vbd *vbd);
    4.39 +
    4.40 +/* Creates inactive vbd. */
    4.41 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly);
    4.42 +int vbd_is_active(struct vbd *vbd);
    4.43 +void vbd_activate(blkif_t *blkif, struct vbd *vbd);
    4.44 +
    4.45 +unsigned long vbd_size(struct vbd *vbd);
    4.46 +unsigned int vbd_info(struct vbd *vbd);
    4.47 +unsigned long vbd_secsize(struct vbd *vbd);
    4.48  void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
    4.49 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
    4.50  void destroy_all_vbds(blkif_t *blkif);
    4.51  
    4.52  struct phys_req {
    4.53 @@ -104,10 +116,11 @@ struct phys_req {
    4.54  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
    4.55  
    4.56  void blkif_interface_init(void);
    4.57 -void blkif_ctrlif_init(void);
    4.58  
    4.59  void blkif_deschedule(blkif_t *blkif);
    4.60  
    4.61 +void blkif_xenbus_init(void);
    4.62 +
    4.63  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
    4.64  
    4.65  #endif /* __BLKIF__BACKEND__COMMON_H__ */
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/control.c	Fri Aug 19 10:50:15 2005 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,61 +0,0 @@
     5.4 -/******************************************************************************
     5.5 - * arch/xen/drivers/blkif/backend/control.c
     5.6 - * 
     5.7 - * Routines for interfacing with the control plane.
     5.8 - * 
     5.9 - * Copyright (c) 2004, Keir Fraser
    5.10 - */
    5.11 -
    5.12 -#include "common.h"
    5.13 -
    5.14 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
    5.15 -{
    5.16 -    DPRINTK("Received blkif backend message, subtype=%d\n", msg->subtype);
    5.17 -    
    5.18 -    switch ( msg->subtype )
    5.19 -    {
    5.20 -    case CMSG_BLKIF_BE_CREATE:
    5.21 -        blkif_create((blkif_be_create_t *)&msg->msg[0]);
    5.22 -        break;        
    5.23 -    case CMSG_BLKIF_BE_DESTROY:
    5.24 -        blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
    5.25 -        break;        
    5.26 -    case CMSG_BLKIF_BE_CONNECT:
    5.27 -        blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
    5.28 -        break;        
    5.29 -    case CMSG_BLKIF_BE_DISCONNECT:
    5.30 -        if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
    5.31 -            return; /* Sending the response is deferred until later. */
    5.32 -        break;        
    5.33 -    case CMSG_BLKIF_BE_VBD_CREATE:
    5.34 -        vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
    5.35 -        break;
    5.36 -    case CMSG_BLKIF_BE_VBD_DESTROY:
    5.37 -        vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
    5.38 -        break;
    5.39 -    default:
    5.40 -        DPRINTK("Parse error while reading message subtype %d, len %d\n",
    5.41 -                msg->subtype, msg->length);
    5.42 -        msg->length = 0;
    5.43 -        break;
    5.44 -    }
    5.45 -
    5.46 -    ctrl_if_send_response(msg);
    5.47 -}
    5.48 -
    5.49 -void blkif_ctrlif_init(void)
    5.50 -{
    5.51 -    ctrl_msg_t cmsg;
    5.52 -    blkif_be_driver_status_t st;
    5.53 -
    5.54 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
    5.55 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
    5.56 -
    5.57 -    /* Send a driver-UP notification to the domain controller. */
    5.58 -    cmsg.type      = CMSG_BLKIF_BE;
    5.59 -    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS;
    5.60 -    cmsg.length    = sizeof(blkif_be_driver_status_t);
    5.61 -    st.status      = BLKIF_DRIVER_STATUS_UP;
    5.62 -    memcpy(cmsg.msg, &st, sizeof(st));
    5.63 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    5.64 -}
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 10:50:15 2005 +0000
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 13:08:50 2005 +0000
     6.3 @@ -7,46 +7,149 @@
     6.4   */
     6.5  
     6.6  #include "common.h"
     6.7 +#include <asm-xen/ctrl_if.h>
     6.8 +#include <asm-xen/evtchn.h>
     6.9  
    6.10  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    6.11  #define VMALLOC_VMADDR(x) ((unsigned long)(x))
    6.12  #endif
    6.13  
    6.14  #define BLKIF_HASHSZ 1024
    6.15 -#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
    6.16 +#define BLKIF_HASH(_d) (((int)(_d))&(BLKIF_HASHSZ-1))
    6.17  
    6.18  static kmem_cache_t *blkif_cachep;
    6.19  static blkif_t      *blkif_hash[BLKIF_HASHSZ];
    6.20  
    6.21 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
    6.22 +blkif_t *blkif_find(domid_t domid)
    6.23  {
    6.24 -    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
    6.25 -    while ( (blkif != NULL) && 
    6.26 -            ((blkif->domid != domid) || (blkif->handle != handle)) )
    6.27 +    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid)];
    6.28 +
    6.29 +    while (blkif) {
    6.30 +	if (blkif->domid == domid) {
    6.31 +	    blkif_get(blkif);
    6.32 +	    return blkif;
    6.33 +	}
    6.34          blkif = blkif->hash_next;
    6.35 +    }
    6.36 +
    6.37 +    blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
    6.38 +    if (!blkif)
    6.39 +	    return ERR_PTR(-ENOMEM);
    6.40 +
    6.41 +    memset(blkif, 0, sizeof(*blkif));
    6.42 +    blkif->domid = domid;
    6.43 +    blkif->status = DISCONNECTED;
    6.44 +    spin_lock_init(&blkif->vbd_lock);
    6.45 +    spin_lock_init(&blkif->blk_ring_lock);
    6.46 +    atomic_set(&blkif->refcnt, 1);
    6.47 +
    6.48 +    blkif->hash_next = blkif_hash[BLKIF_HASH(domid)];
    6.49 +    blkif_hash[BLKIF_HASH(domid)] = blkif;
    6.50      return blkif;
    6.51  }
    6.52  
    6.53 +#ifndef CONFIG_XEN_BLKDEV_GRANT
    6.54 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
    6.55 +			     unsigned long shared_page)
    6.56 +{
    6.57 +    return direct_remap_area_pages(&init_mm, localaddr,
    6.58 +				   shared_page<<PAGE_SHIFT, PAGE_SIZE,
    6.59 +				   __pgprot(_KERNPG_TABLE), blkif->domid);
    6.60 +}
    6.61 +
    6.62 +static void unmap_frontend_page(blkif_t *blkif)
    6.63 +{
    6.64 +}
    6.65 +#else
    6.66 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
    6.67 +			     unsigned long shared_page)
    6.68 +{
    6.69 +    struct gnttab_map_grant_ref op;
    6.70 +    op.host_addr = localaddr;
    6.71 +    op.flags = GNTMAP_host_map;
    6.72 +    op.ref = shared_page;
    6.73 +    op.dom = blkif->domid;
    6.74 +       
    6.75 +    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
    6.76 +
    6.77 +    if (op.handle < 0) {
    6.78 +	DPRINTK(" Grant table operation failure !\n");
    6.79 +	return op.handle;
    6.80 +    }
    6.81 +
    6.82 +    blkif->shmem_ref = shared_page;
    6.83 +    blkif->shmem_handle = op.handle;
    6.84 +    blkif->shmem_vaddr = localaddr;
    6.85 +    return 0;
    6.86 +}
    6.87 +
    6.88 +static void unmap_frontend_page(blkif_t *blkif)
    6.89 +{
    6.90 +    struct gnttab_unmap_grant_ref op;
    6.91 +
    6.92 +    op.host_addr = blkif->shmem_vaddr;
    6.93 +    op.handle = blkif->shmem_handle;
    6.94 +    op.dev_bus_addr = 0;
    6.95 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
    6.96 +}
    6.97 +#endif /* CONFIG_XEN_BLKDEV_GRANT */
    6.98 +
    6.99 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
   6.100 +{
   6.101 +    struct vm_struct *vma;
   6.102 +    blkif_sring_t *sring;
   6.103 +    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
   6.104 +    int err;
   6.105 +
   6.106 +    BUG_ON(blkif->remote_evtchn);
   6.107 +
   6.108 +    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   6.109 +	return -ENOMEM;
   6.110 +
   6.111 +    err = map_frontend_page(blkif, VMALLOC_VMADDR(vma->addr), shared_page);
   6.112 +    if (err) {
   6.113 +        vfree(vma->addr);
   6.114 +	return err;
   6.115 +    }
   6.116 +
   6.117 +    op.u.bind_interdomain.dom1 = DOMID_SELF;
   6.118 +    op.u.bind_interdomain.dom2 = blkif->domid;
   6.119 +    op.u.bind_interdomain.port1 = 0;
   6.120 +    op.u.bind_interdomain.port2 = evtchn;
   6.121 +    err = HYPERVISOR_event_channel_op(&op);
   6.122 +    if (err) {
   6.123 +	unmap_frontend_page(blkif);
   6.124 +	vfree(vma->addr);
   6.125 +	return err;
   6.126 +    }
   6.127 +
   6.128 +    blkif->evtchn = op.u.bind_interdomain.port1;
   6.129 +    blkif->remote_evtchn = evtchn;
   6.130 +
   6.131 +    sring = (blkif_sring_t *)vma->addr;
   6.132 +    SHARED_RING_INIT(sring);
   6.133 +    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
   6.134 +
   6.135 +    bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
   6.136 +			      blkif);
   6.137 +    blkif->status        = CONNECTED;
   6.138 +    blkif->shmem_frame   = shared_page;
   6.139 +
   6.140 +    return 0;
   6.141 +}
   6.142 +
   6.143  static void __blkif_disconnect_complete(void *arg)
   6.144  {
   6.145      blkif_t              *blkif = (blkif_t *)arg;
   6.146      ctrl_msg_t            cmsg;
   6.147      blkif_be_disconnect_t disc;
   6.148 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.149 -    struct gnttab_unmap_grant_ref op;
   6.150 -#endif
   6.151  
   6.152      /*
   6.153       * These can't be done in blkif_disconnect() because at that point there
   6.154       * may be outstanding requests at the disc whose asynchronous responses
   6.155       * must still be notified to the remote driver.
   6.156       */
   6.157 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.158 -    op.host_addr      = blkif->shmem_vaddr;
   6.159 -    op.handle         = blkif->shmem_handle;
   6.160 -    op.dev_bus_addr   = 0;
   6.161 -    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   6.162 -#endif
   6.163 +    unmap_frontend_page(blkif);
   6.164      vfree(blkif->blk_ring.sring);
   6.165  
   6.166      /* Construct the deferred response message. */
   6.167 @@ -81,200 +184,33 @@ void blkif_disconnect_complete(blkif_t *
   6.168      schedule_work(&blkif->work);
   6.169  }
   6.170  
   6.171 -void blkif_create(blkif_be_create_t *create)
   6.172 +void free_blkif(blkif_t *blkif)
   6.173  {
   6.174 -    domid_t       domid  = create->domid;
   6.175 -    unsigned int  handle = create->blkif_handle;
   6.176 -    blkif_t     **pblkif, *blkif;
   6.177 -
   6.178 -    if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL )
   6.179 -    {
   6.180 -        DPRINTK("Could not create blkif: out of memory\n");
   6.181 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.182 -        return;
   6.183 -    }
   6.184 +    blkif_t     **pblkif;
   6.185 +    evtchn_op_t op = { .cmd = EVTCHNOP_close };
   6.186  
   6.187 -    memset(blkif, 0, sizeof(*blkif));
   6.188 -    blkif->domid  = domid;
   6.189 -    blkif->handle = handle;
   6.190 -    blkif->status = DISCONNECTED;
   6.191 -    spin_lock_init(&blkif->vbd_lock);
   6.192 -    spin_lock_init(&blkif->blk_ring_lock);
   6.193 -    atomic_set(&blkif->refcnt, 0);
   6.194 +    op.u.close.port = blkif->evtchn;
   6.195 +    op.u.close.dom = DOMID_SELF;
   6.196 +    HYPERVISOR_event_channel_op(&op);
   6.197 +    op.u.close.port = blkif->remote_evtchn;
   6.198 +    op.u.close.dom = blkif->domid;
   6.199 +    HYPERVISOR_event_channel_op(&op);
   6.200  
   6.201 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
   6.202 -    while ( *pblkif != NULL )
   6.203 +    if (blkif->evtchn)
   6.204 +        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
   6.205 +
   6.206 +    if (blkif->blk_ring.sring)
   6.207 +	    vfree(blkif->blk_ring.sring);
   6.208 +
   6.209 +    pblkif = &blkif_hash[BLKIF_HASH(blkif->domid)];
   6.210 +    while ( *pblkif != blkif )
   6.211      {
   6.212 -        if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
   6.213 -        {
   6.214 -            DPRINTK("Could not create blkif: already exists\n");
   6.215 -            create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
   6.216 -            kmem_cache_free(blkif_cachep, blkif);
   6.217 -            return;
   6.218 -        }
   6.219 +	BUG_ON(!*pblkif);
   6.220          pblkif = &(*pblkif)->hash_next;
   6.221      }
   6.222 -
   6.223 -    blkif->hash_next = *pblkif;
   6.224 -    *pblkif = blkif;
   6.225 -
   6.226 -    DPRINTK("Successfully created blkif\n");
   6.227 -    create->status = BLKIF_BE_STATUS_OKAY;
   6.228 -}
   6.229 -
   6.230 -void blkif_destroy(blkif_be_destroy_t *destroy)
   6.231 -{
   6.232 -    domid_t       domid  = destroy->domid;
   6.233 -    unsigned int  handle = destroy->blkif_handle;
   6.234 -    blkif_t     **pblkif, *blkif;
   6.235 -
   6.236 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
   6.237 -    while ( (blkif = *pblkif) != NULL )
   6.238 -    {
   6.239 -        if ( (blkif->domid == domid) && (blkif->handle == handle) )
   6.240 -        {
   6.241 -            if ( blkif->status != DISCONNECTED )
   6.242 -                goto still_connected;
   6.243 -            goto destroy;
   6.244 -        }
   6.245 -        pblkif = &blkif->hash_next;
   6.246 -    }
   6.247 -
   6.248 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.249 -    return;
   6.250 -
   6.251 - still_connected:
   6.252 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
   6.253 -    return;
   6.254 -
   6.255 - destroy:
   6.256      *pblkif = blkif->hash_next;
   6.257      destroy_all_vbds(blkif);
   6.258      kmem_cache_free(blkif_cachep, blkif);
   6.259 -    destroy->status = BLKIF_BE_STATUS_OKAY;
   6.260 -}
   6.261 -
   6.262 -void blkif_connect(blkif_be_connect_t *connect)
   6.263 -{
   6.264 -    domid_t        domid  = connect->domid;
   6.265 -    unsigned int   handle = connect->blkif_handle;
   6.266 -    unsigned int   evtchn = connect->evtchn;
   6.267 -    unsigned long  shmem_frame = connect->shmem_frame;
   6.268 -    struct vm_struct *vma;
   6.269 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.270 -    int ref = connect->shmem_ref;
   6.271 -#else
   6.272 -    pgprot_t       prot;
   6.273 -    int            error;
   6.274 -#endif
   6.275 -    blkif_t       *blkif;
   6.276 -    blkif_sring_t *sring;
   6.277 -
   6.278 -    blkif = blkif_find_by_handle(domid, handle);
   6.279 -    if ( unlikely(blkif == NULL) )
   6.280 -    {
   6.281 -        DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", 
   6.282 -                connect->domid, connect->blkif_handle); 
   6.283 -        connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.284 -        return;
   6.285 -    }
   6.286 -
   6.287 -    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   6.288 -    {
   6.289 -        connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.290 -        return;
   6.291 -    }
   6.292 -
   6.293 -#ifndef CONFIG_XEN_BLKDEV_GRANT
   6.294 -    prot = __pgprot(_KERNPG_TABLE);
   6.295 -    error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr),
   6.296 -                                    shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
   6.297 -                                    prot, domid);
   6.298 -    if ( error != 0 )
   6.299 -    {
   6.300 -        if ( error == -ENOMEM )
   6.301 -            connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.302 -        else if ( error == -EFAULT )
   6.303 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   6.304 -        else
   6.305 -            connect->status = BLKIF_BE_STATUS_ERROR;
   6.306 -        vfree(vma->addr);
   6.307 -        return;
   6.308 -    }
   6.309 -#else
   6.310 -    { /* Map: Use the Grant table reference */
   6.311 -        struct gnttab_map_grant_ref op;
   6.312 -        op.host_addr      = VMALLOC_VMADDR(vma->addr);
   6.313 -        op.flags          = GNTMAP_host_map;
   6.314 -        op.ref            = ref;
   6.315 -        op.dom            = domid;
   6.316 -       
   6.317 -        BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   6.318 -       
   6.319 -        handle = op.handle;
   6.320 -       
   6.321 -        if (op.handle < 0) {
   6.322 -            DPRINTK(" Grant table operation failure !\n");
   6.323 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   6.324 -            vfree(vma->addr);
   6.325 -            return;
   6.326 -        }
   6.327 -
   6.328 -        blkif->shmem_ref = ref;
   6.329 -        blkif->shmem_handle = handle;
   6.330 -        blkif->shmem_vaddr = VMALLOC_VMADDR(vma->addr);
   6.331 -    }
   6.332 -#endif
   6.333 -
   6.334 -    if ( blkif->status != DISCONNECTED )
   6.335 -    {
   6.336 -        connect->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
   6.337 -        vfree(vma->addr);
   6.338 -        return;
   6.339 -    }
   6.340 -    sring = (blkif_sring_t *)vma->addr;
   6.341 -    SHARED_RING_INIT(sring);
   6.342 -    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
   6.343 -    
   6.344 -    blkif->evtchn        = evtchn;
   6.345 -    blkif->shmem_frame   = shmem_frame;
   6.346 -    blkif->status        = CONNECTED;
   6.347 -    blkif_get(blkif);
   6.348 -
   6.349 -    bind_evtchn_to_irqhandler(
   6.350 -        blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
   6.351 -
   6.352 -    connect->status = BLKIF_BE_STATUS_OKAY;
   6.353 -}
   6.354 -
   6.355 -int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id)
   6.356 -{
   6.357 -    domid_t       domid  = disconnect->domid;
   6.358 -    unsigned int  handle = disconnect->blkif_handle;
   6.359 -    blkif_t      *blkif;
   6.360 -
   6.361 -    blkif = blkif_find_by_handle(domid, handle);
   6.362 -    if ( unlikely(blkif == NULL) )
   6.363 -    {
   6.364 -        DPRINTK("blkif_disconnect attempted for non-existent blkif"
   6.365 -                " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); 
   6.366 -        disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.367 -        return 1; /* Caller will send response error message. */
   6.368 -    }
   6.369 -
   6.370 -    if ( blkif->status == CONNECTED )
   6.371 -    {
   6.372 -        blkif->status = DISCONNECTING;
   6.373 -        blkif->disconnect_rspid = rsp_id;
   6.374 -        wmb(); /* Let other CPUs see the status change. */
   6.375 -        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
   6.376 -        blkif_deschedule(blkif);
   6.377 -        blkif_put(blkif);
   6.378 -        return 0; /* Caller should not send response message. */
   6.379 -    }
   6.380 -
   6.381 -    disconnect->status = BLKIF_BE_STATUS_OKAY;
   6.382 -    return 1;
   6.383  }
   6.384  
   6.385  void __init blkif_interface_init(void)
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 10:50:15 2005 +0000
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 13:08:50 2005 +0000
     7.3 @@ -11,13 +11,16 @@
     7.4   */
     7.5  
     7.6  #include "common.h"
     7.7 +#include <asm-xen/xenbus.h>
     7.8  
     7.9  struct vbd { 
    7.10 -    blkif_vdev_t   vdevice;     /* what the domain refers to this vbd as */
    7.11 +    blkif_vdev_t   handle;     /* what the domain refers to this vbd as */
    7.12      unsigned char  readonly;    /* Non-zero -> read-only */
    7.13      unsigned char  type;        /* VDISK_xxx */
    7.14      blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
    7.15      struct block_device *bdev;
    7.16 +
    7.17 +    int active;
    7.18      rb_node_t      rb;          /* for linking into R-B tree lookup struct */
    7.19  }; 
    7.20  
    7.21 @@ -33,57 +36,45 @@ static inline dev_t vbd_map_devnum(blkif
    7.22  #define bdev_hardsect_size(_b) 512
    7.23  #endif
    7.24  
    7.25 -void vbd_create(blkif_be_vbd_create_t *create) 
    7.26 +unsigned long vbd_size(struct vbd *vbd)
    7.27 +{
    7.28 +	return vbd_sz(vbd);
    7.29 +}
    7.30 +
    7.31 +unsigned int vbd_info(struct vbd *vbd)
    7.32 +{
    7.33 +	return vbd->type | (vbd->readonly?VDISK_READONLY:0);
    7.34 +}
    7.35 +
    7.36 +unsigned long vbd_secsize(struct vbd *vbd)
    7.37 +{
    7.38 +	return bdev_hardsect_size(vbd->bdev);
    7.39 +}
    7.40 +
    7.41 +int vbd_is_active(struct vbd *vbd)
    7.42 +{
    7.43 +	return vbd->active;
    7.44 +}
    7.45 +
    7.46 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
    7.47 +		       blkif_pdev_t pdevice, int readonly)
    7.48  {
    7.49      struct vbd  *vbd; 
    7.50 -    rb_node_t  **rb_p, *rb_parent = NULL;
    7.51 -    blkif_t     *blkif;
    7.52 -    blkif_vdev_t vdevice = create->vdevice;
    7.53 -
    7.54 -    blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
    7.55 -    if ( unlikely(blkif == NULL) )
    7.56 -    {
    7.57 -        DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
    7.58 -                create->domid, create->blkif_handle); 
    7.59 -        create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    7.60 -        return;
    7.61 -    }
    7.62 -
    7.63 -    rb_p = &blkif->vbd_rb.rb_node;
    7.64 -    while ( *rb_p != NULL )
    7.65 -    {
    7.66 -        rb_parent = *rb_p;
    7.67 -        vbd = rb_entry(rb_parent, struct vbd, rb);
    7.68 -        if ( vdevice < vbd->vdevice )
    7.69 -        {
    7.70 -            rb_p = &rb_parent->rb_left;
    7.71 -        }
    7.72 -        else if ( vdevice > vbd->vdevice )
    7.73 -        {
    7.74 -            rb_p = &rb_parent->rb_right;
    7.75 -        }
    7.76 -        else
    7.77 -        {
    7.78 -            DPRINTK("vbd_create attempted for already existing vbd\n");
    7.79 -            create->status = BLKIF_BE_STATUS_VBD_EXISTS;
    7.80 -            return;
    7.81 -        }
    7.82 -    }
    7.83  
    7.84      if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
    7.85      {
    7.86          DPRINTK("vbd_create: out of memory\n");
    7.87 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    7.88 -        return;
    7.89 +	return ERR_PTR(-ENOMEM);
    7.90      }
    7.91  
    7.92 -    vbd->vdevice  = vdevice; 
    7.93 -    vbd->readonly = create->readonly;
    7.94 +    vbd->handle   = handle; 
    7.95 +    vbd->readonly = readonly;
    7.96      vbd->type     = 0;
    7.97 +    vbd->active   = 0;
    7.98  
    7.99 -    /* Mask to 16-bit for compatibility with old tools */
   7.100 -    vbd->pdevice  = create->pdevice & 0xffff;
   7.101 +    vbd->pdevice  = pdevice;
   7.102  
   7.103 +    /* FIXME: Who frees vbd on failure? --RR */
   7.104  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   7.105      vbd->bdev = open_by_devnum(
   7.106          vbd_map_devnum(vbd->pdevice),
   7.107 @@ -91,16 +82,14 @@ void vbd_create(blkif_be_vbd_create_t *c
   7.108      if ( IS_ERR(vbd->bdev) )
   7.109      {
   7.110          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.111 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.112 -        return;
   7.113 +        return ERR_PTR(-ENOENT);
   7.114      }
   7.115  
   7.116      if ( (vbd->bdev->bd_disk == NULL) )
   7.117      {
   7.118          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.119 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.120          bdev_put(vbd->bdev);
   7.121 -        return;
   7.122 +        return ERR_PTR(-ENOENT);
   7.123      }
   7.124  
   7.125      if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
   7.126 @@ -112,62 +101,64 @@ void vbd_create(blkif_be_vbd_create_t *c
   7.127      if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
   7.128      {
   7.129          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.130 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.131 -        return;
   7.132 +        return ERR_PTR(-ENOENT);
   7.133      }
   7.134  #endif
   7.135  
   7.136 +    DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
   7.137 +            handle, blkif->domid);
   7.138 +    return vbd;
   7.139 +}
   7.140 +
   7.141 +void vbd_activate(blkif_t *blkif, struct vbd *vbd)
   7.142 +{
   7.143 +    rb_node_t  **rb_p, *rb_parent = NULL;
   7.144 +    struct vbd *i;
   7.145 +    BUG_ON(vbd_is_active(vbd));
   7.146 +
   7.147 +    /* Find where to put it. */
   7.148 +    rb_p = &blkif->vbd_rb.rb_node;
   7.149 +    while ( *rb_p != NULL )
   7.150 +    {
   7.151 +        rb_parent = *rb_p;
   7.152 +        i = rb_entry(rb_parent, struct vbd, rb);
   7.153 +        if ( vbd->handle < i->handle )
   7.154 +        {
   7.155 +            rb_p = &rb_parent->rb_left;
   7.156 +        }
   7.157 +        else if ( vbd->handle > i->handle )
   7.158 +        {
   7.159 +            rb_p = &rb_parent->rb_right;
   7.160 +        }
   7.161 +        else
   7.162 +        {
   7.163 +	    /* We never create two of same vbd, so not possible. */
   7.164 +	    BUG();
   7.165 +        }
   7.166 +    }
   7.167 +
   7.168 +    /* Now we're active. */
   7.169 +    vbd->active = 1;
   7.170 +    blkif_get(blkif);
   7.171 +
   7.172      spin_lock(&blkif->vbd_lock);
   7.173      rb_link_node(&vbd->rb, rb_parent, rb_p);
   7.174      rb_insert_color(&vbd->rb, &blkif->vbd_rb);
   7.175      spin_unlock(&blkif->vbd_lock);
   7.176 -
   7.177 -    DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
   7.178 -            vdevice, create->domid);
   7.179 -    create->status = BLKIF_BE_STATUS_OKAY;
   7.180  }
   7.181  
   7.182 -
   7.183 -void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
   7.184 +void vbd_free(blkif_t *blkif, struct vbd *vbd)
   7.185  {
   7.186 -    blkif_t           *blkif;
   7.187 -    struct vbd        *vbd;
   7.188 -    rb_node_t         *rb;
   7.189 -    blkif_vdev_t       vdevice = destroy->vdevice;
   7.190 -
   7.191 -    blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
   7.192 -    if ( unlikely(blkif == NULL) )
   7.193 -    {
   7.194 -        DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
   7.195 -                destroy->domid, destroy->blkif_handle); 
   7.196 -        destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   7.197 -        return;
   7.198 +    if (vbd_is_active(vbd)) {
   7.199 +	spin_lock(&blkif->vbd_lock);
   7.200 +	rb_erase(&vbd->rb, &blkif->vbd_rb);
   7.201 +	spin_unlock(&blkif->vbd_lock);
   7.202 +	blkif_put(blkif);
   7.203      }
   7.204 -
   7.205 -    rb = blkif->vbd_rb.rb_node;
   7.206 -    while ( rb != NULL )
   7.207 -    {
   7.208 -        vbd = rb_entry(rb, struct vbd, rb);
   7.209 -        if ( vdevice < vbd->vdevice )
   7.210 -            rb = rb->rb_left;
   7.211 -        else if ( vdevice > vbd->vdevice )
   7.212 -            rb = rb->rb_right;
   7.213 -        else
   7.214 -            goto found;
   7.215 -    }
   7.216 -
   7.217 -    destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   7.218 -    return;
   7.219 -
   7.220 - found:
   7.221 -    spin_lock(&blkif->vbd_lock);
   7.222 -    rb_erase(rb, &blkif->vbd_rb);
   7.223 -    spin_unlock(&blkif->vbd_lock);
   7.224      bdev_put(vbd->bdev);
   7.225      kfree(vbd);
   7.226  }
   7.227  
   7.228 -
   7.229  void destroy_all_vbds(blkif_t *blkif)
   7.230  {
   7.231      struct vbd *vbd;
   7.232 @@ -183,74 +174,12 @@ void destroy_all_vbds(blkif_t *blkif)
   7.233          bdev_put(vbd->bdev);
   7.234          kfree(vbd);
   7.235          spin_lock(&blkif->vbd_lock);
   7.236 +        blkif_put(blkif);
   7.237      }
   7.238  
   7.239      spin_unlock(&blkif->vbd_lock);
   7.240  }
   7.241  
   7.242 -
   7.243 -static void vbd_probe_single(
   7.244 -    blkif_t *blkif, vdisk_t *vbd_info, struct vbd *vbd)
   7.245 -{
   7.246 -    vbd_info->device      = vbd->vdevice; 
   7.247 -    vbd_info->info        = vbd->type | (vbd->readonly ? VDISK_READONLY : 0);
   7.248 -    vbd_info->capacity    = vbd_sz(vbd);
   7.249 -    vbd_info->sector_size = bdev_hardsect_size(vbd->bdev);
   7.250 -}
   7.251 -
   7.252 -
   7.253 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
   7.254 -{
   7.255 -    int        rc = 0, nr_vbds = 0;
   7.256 -    rb_node_t *rb;
   7.257 -
   7.258 -    spin_lock(&blkif->vbd_lock);
   7.259 -
   7.260 -    if ( (rb = blkif->vbd_rb.rb_node) == NULL )
   7.261 -        goto out;
   7.262 -
   7.263 - new_subtree:
   7.264 -    /* STEP 1. Find least node (it'll be left-most). */
   7.265 -    while ( rb->rb_left != NULL )
   7.266 -        rb = rb->rb_left;
   7.267 -
   7.268 -    for ( ; ; )
   7.269 -    {
   7.270 -        /* STEP 2. Dealt with left subtree. Now process current node. */
   7.271 -        vbd_probe_single(blkif, &vbd_info[nr_vbds],
   7.272 -                         rb_entry(rb, struct vbd, rb));
   7.273 -        if ( ++nr_vbds == max_vbds )
   7.274 -            goto out;
   7.275 -
   7.276 -        /* STEP 3. Process right subtree, if any. */
   7.277 -        if ( rb->rb_right != NULL )
   7.278 -        {
   7.279 -            rb = rb->rb_right;
   7.280 -            goto new_subtree;
   7.281 -        }
   7.282 -
   7.283 -        /* STEP 4. Done both subtrees. Head back through ancesstors. */
   7.284 -        for ( ; ; ) 
   7.285 -        {
   7.286 -            /* We're done when we get back to the root node. */
   7.287 -            if ( rb->rb_parent == NULL )
   7.288 -                goto out;
   7.289 -            /* If we are left of parent, then parent is next to process. */
   7.290 -            if ( rb->rb_parent->rb_left == rb )
   7.291 -                break;
   7.292 -            /* If we are right of parent, then we climb to grandparent. */
   7.293 -            rb = rb->rb_parent;
   7.294 -        }
   7.295 -
   7.296 -        rb = rb->rb_parent;
   7.297 -    }
   7.298 -
   7.299 - out:
   7.300 -    spin_unlock(&blkif->vbd_lock);
   7.301 -    return (rc == 0) ? nr_vbds : rc;  
   7.302 -}
   7.303 -
   7.304 -
   7.305  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
   7.306  {
   7.307      struct vbd *vbd;
   7.308 @@ -264,9 +193,9 @@ int vbd_translate(struct phys_req *req, 
   7.309      while ( rb != NULL )
   7.310      {
   7.311          vbd = rb_entry(rb, struct vbd, rb);
   7.312 -        if ( req->dev < vbd->vdevice )
   7.313 +        if ( req->dev < vbd->handle )
   7.314              rb = rb->rb_left;
   7.315 -        else if ( req->dev > vbd->vdevice )
   7.316 +        else if ( req->dev > vbd->handle )
   7.317              rb = rb->rb_right;
   7.318          else
   7.319              goto found;
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Aug 19 13:08:50 2005 +0000
     8.3 @@ -0,0 +1,308 @@
     8.4 +/*  Xenbus code for blkif backend
     8.5 +    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
     8.6 +
     8.7 +    This program is free software; you can redistribute it and/or modify
     8.8 +    it under the terms of the GNU General Public License as published by
     8.9 +    the Free Software Foundation; either version 2 of the License, or
    8.10 +    (at your option) any later version.
    8.11 +
    8.12 +    This program is distributed in the hope that it will be useful,
    8.13 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.14 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.15 +    GNU General Public License for more details.
    8.16 +
    8.17 +    You should have received a copy of the GNU General Public License
    8.18 +    along with this program; if not, write to the Free Software
    8.19 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.20 +*/
    8.21 +#include <stdarg.h>
    8.22 +#include <linux/module.h>
    8.23 +#include <asm-xen/xenbus.h>
    8.24 +#include "common.h"
    8.25 +
    8.26 +struct backend_info
    8.27 +{
    8.28 +	struct xenbus_device *dev;
    8.29 +
    8.30 +	/* our communications channel */
    8.31 +	blkif_t *blkif;
    8.32 +	struct vbd *vbd;
    8.33 +
    8.34 +	long int frontend_id;
    8.35 +	long int pdev;
    8.36 +	long int readonly;
    8.37 +
    8.38 +	/* watch back end for changes */
    8.39 +	struct xenbus_watch backend_watch;
    8.40 +
    8.41 +	/* watch front end for changes */
    8.42 +	struct xenbus_watch watch;
    8.43 +	char *frontpath;
    8.44 +};
    8.45 +
    8.46 +static int blkback_remove(struct xenbus_device *dev)
    8.47 +{
    8.48 +	struct backend_info *be = dev->data;
    8.49 +
    8.50 +	if (be->watch.node)
    8.51 +		unregister_xenbus_watch(&be->watch);
    8.52 +	unregister_xenbus_watch(&be->backend_watch);
    8.53 +	if (be->vbd)
    8.54 +		vbd_free(be->blkif, be->vbd);
    8.55 +	if (be->blkif)
    8.56 +		blkif_put(be->blkif);
    8.57 +	if (be->frontpath)
    8.58 +		kfree(be->frontpath);
    8.59 +	kfree(be);
    8.60 +	return 0;
    8.61 +}
    8.62 +
    8.63 +/* Front end tells us frame. */
    8.64 +static void frontend_changed(struct xenbus_watch *watch, const char *node)
    8.65 +{
    8.66 +	unsigned long sharedmfn;
    8.67 +	unsigned int evtchn;
    8.68 +	int err;
    8.69 +	struct backend_info *be
    8.70 +		= container_of(watch, struct backend_info, watch);
    8.71 +
    8.72 +	/* If other end is gone, delete ourself. */
    8.73 +	if (!xenbus_exists(be->frontpath, "")) {
    8.74 +		xenbus_rm(be->dev->nodename, "");
    8.75 +		device_unregister(&be->dev->dev);
    8.76 +		return;
    8.77 +	}
    8.78 +	if (vbd_is_active(be->vbd))
    8.79 +		return;
    8.80 +
    8.81 +#ifndef CONFIG_XEN_BLKDEV_GRANT
    8.82 +	err = xenbus_gather(be->frontpath, "shared-frame", "%lu", &sharedmfn,
    8.83 +			    "event-channel", "%u", &evtchn, NULL);
    8.84 +	if (err) {
    8.85 +		xenbus_dev_error(be->dev, err, 
    8.86 +				 "reading %s/shared-frame and event-channel",
    8.87 +				 be->frontpath);
    8.88 +		return;
    8.89 +	}
    8.90 +#else
    8.91 +	err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
    8.92 +			    "event-channel", "%u", &evtchn, NULL);
    8.93 +	if (err) {
    8.94 +		xenbus_dev_error(be->dev, err, 
    8.95 +				 "reading %s/grant-id and event-channel",
    8.96 +				 be->frontpath);
    8.97 +		return;
    8.98 +	}
    8.99 +#endif
   8.100 +
   8.101 +	/* Domains must use same shared frame for all vbds. */
   8.102 +	if (be->blkif->status == CONNECTED &&
   8.103 +	    (evtchn != be->blkif->remote_evtchn ||
   8.104 +	     sharedmfn != be->blkif->shmem_frame)) {
   8.105 +		xenbus_dev_error(be->dev, err,
   8.106 +				 "Shared frame/evtchn %li/%u not same as"
   8.107 +				 " old %li/%u",
   8.108 +				 sharedmfn, evtchn,
   8.109 +				 be->blkif->shmem_frame,
   8.110 +				 be->blkif->remote_evtchn);
   8.111 +		return;
   8.112 +	}
   8.113 +
   8.114 +	/* Supply the information about the device the frontend needs */
   8.115 +	err = xenbus_transaction_start(be->dev->nodename);
   8.116 +	if (err) {
   8.117 +		xenbus_dev_error(be->dev, err, "starting transaction");
   8.118 +		return;
   8.119 +	}
   8.120 +
   8.121 +	err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
   8.122 +			    vbd_size(be->vbd));
   8.123 +	if (err) {
   8.124 +		xenbus_dev_error(be->dev, err, "writing %s/sectors",
   8.125 +				 be->dev->nodename);
   8.126 +		goto abort;
   8.127 +	}
   8.128 +
   8.129 +	/* FIXME: use a typename instead */
   8.130 +	err = xenbus_printf(be->dev->nodename, "info", "%u",
   8.131 +			    vbd_info(be->vbd));
   8.132 +	if (err) {
   8.133 +		xenbus_dev_error(be->dev, err, "writing %s/info",
   8.134 +				 be->dev->nodename);
   8.135 +		goto abort;
   8.136 +	}
   8.137 +	err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
   8.138 +			    vbd_secsize(be->vbd));
   8.139 +	if (err) {
   8.140 +		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
   8.141 +				 be->dev->nodename);
   8.142 +		goto abort;
   8.143 +	}
   8.144 +
   8.145 +	/* First vbd?  We need to map the shared frame, irq etc. */
   8.146 +	if (be->blkif->status != CONNECTED) {
   8.147 +		err = blkif_map(be->blkif, sharedmfn, evtchn);
   8.148 +		if (err) {
   8.149 +			xenbus_dev_error(be->dev, err,
   8.150 +					 "mapping shared-frame %lu port %u",
   8.151 +					 sharedmfn, evtchn);
   8.152 +			goto abort;
   8.153 +		}
   8.154 +	}
   8.155 +
   8.156 +	/* We're ready, activate. */
   8.157 +	vbd_activate(be->blkif, be->vbd);
   8.158 +
   8.159 +	xenbus_transaction_end(0);
   8.160 +	xenbus_dev_ok(be->dev);
   8.161 +
   8.162 +	return;
   8.163 +
   8.164 +abort:
   8.165 +	xenbus_transaction_end(1);
   8.166 +}
   8.167 +
   8.168 +/* 
   8.169 +   Setup supplies physical device.  
   8.170 +   We provide event channel and device details to front end.
   8.171 +   Frontend supplies shared frame and event channel.
   8.172 + */
   8.173 +static void backend_changed(struct xenbus_watch *watch, const char *node)
   8.174 +{
   8.175 +	int err;
   8.176 +	char *p;
   8.177 +	char *frontend;
   8.178 +	long int handle, pdev;
   8.179 +	struct backend_info *be
   8.180 +		= container_of(watch, struct backend_info, backend_watch);
   8.181 +	struct xenbus_device *dev = be->dev;
   8.182 +
   8.183 +	frontend = NULL;
   8.184 +	err = xenbus_gather(dev->nodename,
   8.185 +			    "frontend-id", "%li", &be->frontend_id,
   8.186 +			    "frontend", NULL, &frontend,
   8.187 +			    NULL);
   8.188 +	if (err == -ENOENT || err == -ERANGE ||
   8.189 +	    strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
   8.190 +		if (frontend)
   8.191 +			kfree(frontend);
   8.192 +		/* If we can't get a frontend path and a frontend-id,
   8.193 +		 * then our bus-id is no longer valid and we need to
   8.194 +		 * destroy the backend device.
   8.195 +		 */
   8.196 +		goto device_fail;
   8.197 +	}
   8.198 +
   8.199 +	if (!be->frontpath || strcmp(frontend, be->frontpath)) {
   8.200 +		if (be->watch.node)
   8.201 +			unregister_xenbus_watch(&be->watch);
   8.202 +		if (be->frontpath)
   8.203 +			kfree(be->frontpath);
   8.204 +		be->frontpath = frontend;
   8.205 +		be->watch.node = be->frontpath;
   8.206 +		be->watch.callback = frontend_changed;
   8.207 +		err = register_xenbus_watch(&be->watch);
   8.208 +		if (err) {
   8.209 +			be->watch.node = NULL;
   8.210 +			goto device_fail;
   8.211 +		}
   8.212 +	} else
   8.213 +		kfree(frontend);
   8.214 +
   8.215 +	err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
   8.216 +	if (err == -ENOENT || err == -ERANGE)
   8.217 +		goto out;
   8.218 +	if (err < 0) {
   8.219 +		xenbus_dev_error(dev, err, "Reading physical-device");
   8.220 +		goto device_fail;
   8.221 +	}
   8.222 +	if (be->pdev && be->pdev != pdev) {
   8.223 +		printk(KERN_WARNING
   8.224 +		       "changing physical-device not supported\n");
   8.225 +		goto device_fail;
   8.226 +	}
   8.227 +	be->pdev = pdev;
   8.228 +
   8.229 +	/* If there's a read-only node, we're read only. */
   8.230 +	p = xenbus_read(dev->nodename, "read-only", NULL);
   8.231 +	if (!IS_ERR(p)) {
   8.232 +		be->readonly = 1;
   8.233 +		kfree(p);
   8.234 +	}
   8.235 +
   8.236 +	if (be->blkif == NULL) {
   8.237 +		/* Front end dir is a number, which is used as the handle. */
   8.238 +		p = strrchr(be->frontpath, '/') + 1;
   8.239 +		handle = simple_strtoul(p, NULL, 0);
   8.240 +
   8.241 +		be->blkif = blkif_find(be->frontend_id);
   8.242 +		if (IS_ERR(be->blkif)) {
   8.243 +			err = PTR_ERR(be->blkif);
   8.244 +			be->blkif = NULL;
   8.245 +			goto device_fail;
   8.246 +		}
   8.247 +
   8.248 +		be->vbd = vbd_create(be->blkif, handle, be->pdev,
   8.249 +				     be->readonly);
   8.250 +		if (IS_ERR(be->vbd)) {
   8.251 +			err = PTR_ERR(be->vbd);
   8.252 +			be->vbd = NULL;
   8.253 +			goto device_fail;
   8.254 +		}
   8.255 +
   8.256 +		frontend_changed(&be->watch, be->frontpath);
   8.257 +	}
   8.258 +
   8.259 +	return;
   8.260 +
   8.261 + device_fail:
   8.262 +	device_unregister(&be->dev->dev);
   8.263 + out:
   8.264 +	return;
   8.265 +}
   8.266 +
   8.267 +static int blkback_probe(struct xenbus_device *dev,
   8.268 +			 const struct xenbus_device_id *id)
   8.269 +{
   8.270 +	struct backend_info *be;
   8.271 +	int err;
   8.272 +
   8.273 +	be = kmalloc(sizeof(*be), GFP_KERNEL);
   8.274 +	if (!be)
   8.275 +		return -ENOMEM;
   8.276 +
   8.277 +	memset(be, 0, sizeof(*be));
   8.278 +
   8.279 +	be->dev = dev;
   8.280 +	be->backend_watch.node = dev->nodename;
   8.281 +	be->backend_watch.callback = backend_changed;
   8.282 +	err = register_xenbus_watch(&be->backend_watch);
   8.283 +	if (err)
   8.284 +		goto free_be;
   8.285 +
   8.286 +	dev->data = be;
   8.287 +
   8.288 +	backend_changed(&be->backend_watch, dev->nodename);
   8.289 +	return err;
   8.290 + free_be:
   8.291 +	kfree(be);
   8.292 +	return err;
   8.293 +}
   8.294 +
   8.295 +static struct xenbus_device_id blkback_ids[] = {
   8.296 +	{ "vbd" },
   8.297 +	{ "" }
   8.298 +};
   8.299 +
   8.300 +static struct xenbus_driver blkback = {
   8.301 +	.name = "vbd",
   8.302 +	.owner = THIS_MODULE,
   8.303 +	.ids = blkback_ids,
   8.304 +	.probe = blkback_probe,
   8.305 +	.remove = blkback_remove,
   8.306 +};
   8.307 +
   8.308 +void blkif_xenbus_init(void)
   8.309 +{
   8.310 +	xenbus_register_backend(&blkback);
   8.311 +}
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 10:50:15 2005 +0000
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 13:08:50 2005 +0000
     9.3 @@ -53,8 +53,8 @@
     9.4  #include <linux/sched.h>
     9.5  #include <linux/interrupt.h>
     9.6  #include <scsi/scsi.h>
     9.7 -#include <asm-xen/ctrl_if.h>
     9.8  #include <asm-xen/evtchn.h>
     9.9 +#include <asm-xen/xenbus.h>
    9.10  #ifdef CONFIG_XEN_BLKDEV_GRANT
    9.11  #include <asm-xen/xen-public/grant_table.h>
    9.12  #include <asm-xen/gnttab.h>
    9.13 @@ -65,22 +65,14 @@ typedef unsigned char byte; /* from linu
    9.14  /* Control whether runtime update of vbds is enabled. */
    9.15  #define ENABLE_VBD_UPDATE 1
    9.16  
    9.17 -#if ENABLE_VBD_UPDATE
    9.18 -static void vbd_update(void);
    9.19 -#else
    9.20 -static void vbd_update(void){};
    9.21 -#endif
    9.22 -
    9.23  #define BLKIF_STATE_CLOSED       0
    9.24  #define BLKIF_STATE_DISCONNECTED 1
    9.25  #define BLKIF_STATE_CONNECTED    2
    9.26  
    9.27 -static int blkif_handle = 0;
    9.28  static unsigned int blkif_state = BLKIF_STATE_CLOSED;
    9.29  static unsigned int blkif_evtchn = 0;
    9.30 -
    9.31 -static int blkif_control_rsp_valid;
    9.32 -static blkif_response_t blkif_control_rsp;
    9.33 +static unsigned int blkif_vbds = 0;
    9.34 +static unsigned int blkif_vbds_connected = 0;
    9.35  
    9.36  static blkif_front_ring_t blk_ring;
    9.37  
    9.38 @@ -92,6 +84,7 @@ static grant_ref_t gref_head, gref_termi
    9.39  #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
    9.40      (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
    9.41  #define GRANTREF_INVALID (1<<15)
    9.42 +static int shmem_ref;
    9.43  #endif
    9.44  
    9.45  static struct blk_shadow {
    9.46 @@ -105,7 +98,7 @@ static int recovery = 0; /* Recovery in 
    9.47  
    9.48  static void kick_pending_request_queues(void);
    9.49  
    9.50 -int __init xlblk_init(void);
    9.51 +static int __init xlblk_init(void);
    9.52  
    9.53  static void blkif_completion(struct blk_shadow *s);
    9.54  
    9.55 @@ -179,19 +172,6 @@ static inline void flush_requests(void)
    9.56  
    9.57  module_init(xlblk_init);
    9.58  
    9.59 -#if ENABLE_VBD_UPDATE
    9.60 -static void update_vbds_task(void *unused)
    9.61 -{ 
    9.62 -    xlvbd_update_vbds();
    9.63 -}
    9.64 -
    9.65 -static void vbd_update(void)
    9.66 -{
    9.67 -    static DECLARE_WORK(update_tq, update_vbds_task, NULL);
    9.68 -    schedule_work(&update_tq);
    9.69 -}
    9.70 -#endif /* ENABLE_VBD_UPDATE */
    9.71 -
    9.72  static struct xlbd_disk_info *head_waiting = NULL;
    9.73  static void kick_pending_request_queues(void)
    9.74  {
    9.75 @@ -221,16 +201,7 @@ int blkif_open(struct inode *inode, stru
    9.76  
    9.77  int blkif_release(struct inode *inode, struct file *filep)
    9.78  {
    9.79 -    struct gendisk *gd = inode->i_bdev->bd_disk;
    9.80 -    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
    9.81 -
    9.82 -    /*
    9.83 -     * When usage drops to zero it may allow more VBD updates to occur.
    9.84 -     * Update of usage count is protected by a per-device semaphore.
    9.85 -     */
    9.86 -    if ( --di->mi->usage == 0 )
    9.87 -        vbd_update();
    9.88 -
    9.89 +    /* FIXME: This is where we can actually free up majors, etc. --RR */
    9.90      return 0;
    9.91  }
    9.92  
    9.93 @@ -301,7 +272,7 @@ static int blkif_queue_request(struct re
    9.94      ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
    9.95          BLKIF_OP_READ;
    9.96      ring_req->sector_number = (blkif_sector_t)req->sector;
    9.97 -    ring_req->device = di->xd_device;
    9.98 +    ring_req->handle = di->handle;
    9.99  
   9.100      ring_req->nr_segments = 0;
   9.101      rq_for_each_bio(bio, req)
   9.102 @@ -446,10 +417,6 @@ static irqreturn_t blkif_int(int irq, vo
   9.103              end_that_request_last(req);
   9.104  
   9.105              break;
   9.106 -        case BLKIF_OP_PROBE:
   9.107 -            memcpy(&blkif_control_rsp, bret, sizeof(*bret));
   9.108 -            blkif_control_rsp_valid = 1;
   9.109 -            break;
   9.110          default:
   9.111              BUG();
   9.112          }
   9.113 @@ -483,28 +450,6 @@ static int nr_pending;
   9.114  #define blkif_io_lock io_request_lock
   9.115  
   9.116  /*============================================================================*/
   9.117 -#if ENABLE_VBD_UPDATE
   9.118 -
   9.119 -/*
   9.120 - * blkif_update_int/update-vbds_task - handle VBD update events.
   9.121 - *  Schedule a task for keventd to run, which will update the VBDs and perform 
   9.122 - *  the corresponding updates to our view of VBD state.
   9.123 - */
   9.124 -static void update_vbds_task(void *unused)
   9.125 -{ 
   9.126 -    xlvbd_update_vbds();
   9.127 -}
   9.128 -
   9.129 -static void vbd_update(void)
   9.130 -{
   9.131 -    static struct tq_struct update_tq;
   9.132 -    update_tq.routine = update_vbds_task;
   9.133 -    schedule_task(&update_tq);
   9.134 -}
   9.135 -
   9.136 -#endif /* ENABLE_VBD_UPDATE */
   9.137 -/*============================================================================*/
   9.138 -
   9.139  static void kick_pending_request_queues(void)
   9.140  {
   9.141      /* We kick pending request queues if the ring is reasonably empty. */
   9.142 @@ -757,7 +702,8 @@ static int blkif_queue_request(unsigned 
   9.143                                 char *          buffer,
   9.144                                 unsigned long   sector_number,
   9.145                                 unsigned short  nr_sectors,
   9.146 -                               kdev_t          device)
   9.147 +                               kdev_t          device,
   9.148 +			       blkif_vdev_t    handle)
   9.149  {
   9.150      unsigned long       buffer_ma = virt_to_bus(buffer);
   9.151      unsigned long       xid;
   9.152 @@ -871,7 +817,7 @@ static int blkif_queue_request(unsigned 
   9.153      req->id            = xid;
   9.154      req->operation     = operation;
   9.155      req->sector_number = (blkif_sector_t)sector_number;
   9.156 -    req->device        = device; 
   9.157 +    req->handle        = handle; 
   9.158      req->nr_segments   = 1;
   9.159  #ifdef CONFIG_XEN_BLKDEV_GRANT
   9.160      /* install a grant reference. */
   9.161 @@ -1047,108 +993,10 @@ static void blkif_int(int irq, void *dev
   9.162  
   9.163  /*****************************  COMMON CODE  *******************************/
   9.164  
   9.165 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.166 -void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
   9.167 -                              unsigned long address)
   9.168 -{
   9.169 -    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
   9.170 -    ASSERT( ref != -ENOSPC );
   9.171 -
   9.172 -    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
   9.173 -
   9.174 -    req->frame_and_sects[0] = blkif_fas_from_gref(ref, 0, (PAGE_SIZE/512)-1);
   9.175 -
   9.176 -    blkif_control_send(req, rsp);
   9.177 -}
   9.178 -#endif
   9.179 -
   9.180 -void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
   9.181 -{
   9.182 -    unsigned long flags, id;
   9.183 -    blkif_request_t *req_d;
   9.184 -
   9.185 - retry:
   9.186 -    while ( RING_FULL(&blk_ring) )
   9.187 -    {
   9.188 -        set_current_state(TASK_INTERRUPTIBLE);
   9.189 -        schedule_timeout(1);
   9.190 -    }
   9.191 -
   9.192 -    spin_lock_irqsave(&blkif_io_lock, flags);
   9.193 -    if ( RING_FULL(&blk_ring) )
   9.194 -    {
   9.195 -        spin_unlock_irqrestore(&blkif_io_lock, flags);
   9.196 -        goto retry;
   9.197 -    }
   9.198 -
   9.199 -    DISABLE_SCATTERGATHER();
   9.200 -    req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
   9.201 -    *req_d = *req;    
   9.202 -
   9.203 -    id = GET_ID_FROM_FREELIST();
   9.204 -    req_d->id = id;
   9.205 -    blk_shadow[id].request = (unsigned long)req;
   9.206 -
   9.207 -    pickle_request(&blk_shadow[id], req);
   9.208 -
   9.209 -    blk_ring.req_prod_pvt++;
   9.210 -    flush_requests();
   9.211 -
   9.212 -    spin_unlock_irqrestore(&blkif_io_lock, flags);
   9.213 -
   9.214 -    while ( !blkif_control_rsp_valid )
   9.215 -    {
   9.216 -        set_current_state(TASK_INTERRUPTIBLE);
   9.217 -        schedule_timeout(1);
   9.218 -    }
   9.219 -
   9.220 -    memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
   9.221 -    blkif_control_rsp_valid = 0;
   9.222 -}
   9.223 -
   9.224 -
   9.225 -/* Send a driver status notification to the domain controller. */
   9.226 -static void send_driver_status(int ok)
   9.227 -{
   9.228 -    ctrl_msg_t cmsg = {
   9.229 -        .type    = CMSG_BLKIF_FE,
   9.230 -        .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
   9.231 -        .length  = sizeof(blkif_fe_driver_status_t),
   9.232 -    };
   9.233 -    blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
   9.234 -    
   9.235 -    msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
   9.236 -
   9.237 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   9.238 -}
   9.239 -
   9.240 -/* Tell the controller to bring up the interface. */
   9.241 -static void blkif_send_interface_connect(void)
   9.242 -{
   9.243 -    ctrl_msg_t cmsg = {
   9.244 -        .type    = CMSG_BLKIF_FE,
   9.245 -        .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
   9.246 -        .length  = sizeof(blkif_fe_interface_connect_t),
   9.247 -    };
   9.248 -    blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   9.249 -    
   9.250 -    msg->handle      = 0;
   9.251 -    msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   9.252 -    
   9.253 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.254 -    msg->shmem_ref   = gnttab_claim_grant_reference( &gref_head, gref_terminal );
   9.255 -    ASSERT( msg->shmem_ref != -ENOSPC );
   9.256 -    gnttab_grant_foreign_access_ref ( msg->shmem_ref , rdomid, msg->shmem_frame, 0 );
   9.257 -#endif
   9.258 -
   9.259 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   9.260 -}
   9.261 -
   9.262  static void blkif_free(void)
   9.263  {
   9.264      /* Prevent new requests being issued until we fix things up. */
   9.265      spin_lock_irq(&blkif_io_lock);
   9.266 -    recovery = 1;
   9.267      blkif_state = BLKIF_STATE_DISCONNECTED;
   9.268      spin_unlock_irq(&blkif_io_lock);
   9.269  
   9.270 @@ -1162,31 +1010,6 @@ static void blkif_free(void)
   9.271      blkif_evtchn = 0;
   9.272  }
   9.273  
   9.274 -static void blkif_close(void)
   9.275 -{
   9.276 -}
   9.277 -
   9.278 -/* Move from CLOSED to DISCONNECTED state. */
   9.279 -static void blkif_disconnect(void)
   9.280 -{
   9.281 -    blkif_sring_t *sring;
   9.282 -    
   9.283 -    if ( blk_ring.sring != NULL )
   9.284 -        free_page((unsigned long)blk_ring.sring);
   9.285 -    
   9.286 -    sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
   9.287 -    SHARED_RING_INIT(sring);
   9.288 -    FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
   9.289 -    blkif_state  = BLKIF_STATE_DISCONNECTED;
   9.290 -    blkif_send_interface_connect();
   9.291 -}
   9.292 -
   9.293 -static void blkif_reset(void)
   9.294 -{
   9.295 -    blkif_free();
   9.296 -    blkif_disconnect();
   9.297 -}
   9.298 -
   9.299  static void blkif_recover(void)
   9.300  {
   9.301      int i;
   9.302 @@ -1257,11 +1080,14 @@ static void blkif_recover(void)
   9.303      blkif_state = BLKIF_STATE_CONNECTED;
   9.304  }
   9.305  
   9.306 -static void blkif_connect(blkif_fe_interface_status_t *status)
   9.307 +static void blkif_connect(u16 evtchn, domid_t domid)
   9.308  {
   9.309      int err = 0;
   9.310  
   9.311 -    blkif_evtchn = status->evtchn;
   9.312 +    blkif_evtchn = evtchn;
   9.313 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.314 +    rdomid       = domid;
   9.315 +#endif
   9.316  
   9.317      err = bind_evtchn_to_irqhandler(
   9.318          blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
   9.319 @@ -1270,142 +1096,318 @@ static void blkif_connect(blkif_fe_inter
   9.320          WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
   9.321          return;
   9.322      }
   9.323 -
   9.324 -    if ( recovery ) 
   9.325 -    {
   9.326 -        blkif_recover();
   9.327 -    } 
   9.328 -    else 
   9.329 -    {
   9.330 -        /* Transition to connected in case we need to do 
   9.331 -         *  a partition probe on a whole disk. */
   9.332 -        blkif_state = BLKIF_STATE_CONNECTED;
   9.333 -        
   9.334 -        /* Probe for discs attached to the interface. */
   9.335 -        xlvbd_init();
   9.336 -    }
   9.337 -    
   9.338 -    /* Kick pending requests. */
   9.339 -    spin_lock_irq(&blkif_io_lock);
   9.340 -    kick_pending_request_queues();
   9.341 -    spin_unlock_irq(&blkif_io_lock);
   9.342 -}
   9.343 -
   9.344 -static void unexpected(blkif_fe_interface_status_t *status)
   9.345 -{
   9.346 -    DPRINTK(" Unexpected blkif status %u in state %u\n", 
   9.347 -            status->status, blkif_state);
   9.348 -}
   9.349 -
   9.350 -static void blkif_status(blkif_fe_interface_status_t *status)
   9.351 -{
   9.352 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.353 -    rdomid       = status->domid; /* need to set rdomid early */
   9.354 -#endif
   9.355 -
   9.356 -    if ( status->handle != blkif_handle )
   9.357 -    {
   9.358 -        WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
   9.359 -        unexpected(status);
   9.360 -        return;
   9.361 -    }
   9.362 -
   9.363 -    switch ( status->status ) 
   9.364 -    {
   9.365 -    case BLKIF_INTERFACE_STATUS_CLOSED:
   9.366 -        switch ( blkif_state )
   9.367 -        {
   9.368 -        case BLKIF_STATE_CLOSED:
   9.369 -            unexpected(status);
   9.370 -            break;
   9.371 -        case BLKIF_STATE_DISCONNECTED:
   9.372 -        case BLKIF_STATE_CONNECTED:
   9.373 -            unexpected(status);
   9.374 -            blkif_close();
   9.375 -            break;
   9.376 -        }
   9.377 -        break;
   9.378 -
   9.379 -    case BLKIF_INTERFACE_STATUS_DISCONNECTED:
   9.380 -        switch ( blkif_state )
   9.381 -        {
   9.382 -        case BLKIF_STATE_CLOSED:
   9.383 -            blkif_disconnect();
   9.384 -            break;
   9.385 -        case BLKIF_STATE_DISCONNECTED:
   9.386 -        case BLKIF_STATE_CONNECTED:
   9.387 -            /* unexpected(status); */ /* occurs during suspend/resume */
   9.388 -            blkif_reset();
   9.389 -            break;
   9.390 -        }
   9.391 -        break;
   9.392 -
   9.393 -    case BLKIF_INTERFACE_STATUS_CONNECTED:
   9.394 -        switch ( blkif_state )
   9.395 -        {
   9.396 -        case BLKIF_STATE_CLOSED:
   9.397 -            unexpected(status);
   9.398 -            blkif_disconnect();
   9.399 -            blkif_connect(status);
   9.400 -            break;
   9.401 -        case BLKIF_STATE_DISCONNECTED:
   9.402 -            blkif_connect(status);
   9.403 -            break;
   9.404 -        case BLKIF_STATE_CONNECTED:
   9.405 -            unexpected(status);
   9.406 -            blkif_connect(status);
   9.407 -            break;
   9.408 -        }
   9.409 -        break;
   9.410 -
   9.411 -    case BLKIF_INTERFACE_STATUS_CHANGED:
   9.412 -        switch ( blkif_state )
   9.413 -        {
   9.414 -        case BLKIF_STATE_CLOSED:
   9.415 -        case BLKIF_STATE_DISCONNECTED:
   9.416 -            unexpected(status);
   9.417 -            break;
   9.418 -        case BLKIF_STATE_CONNECTED:
   9.419 -            vbd_update();
   9.420 -            break;
   9.421 -        }
   9.422 -        break;
   9.423 -
   9.424 -    default:
   9.425 -        WPRINTK(" Invalid blkif status: %d\n", status->status);
   9.426 -        break;
   9.427 -    }
   9.428  }
   9.429  
   9.430  
   9.431 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
   9.432 +static struct xenbus_device_id blkfront_ids[] = {
   9.433 +	{ "vbd" },
   9.434 +	{ "" }
   9.435 +};
   9.436 +
   9.437 +struct blkfront_info
   9.438  {
   9.439 -    switch ( msg->subtype )
   9.440 -    {
   9.441 -    case CMSG_BLKIF_FE_INTERFACE_STATUS:
   9.442 -        blkif_status((blkif_fe_interface_status_t *)
   9.443 -                     &msg->msg[0]);
   9.444 -        break;
   9.445 -    default:
   9.446 -        msg->length = 0;
   9.447 -        break;
   9.448 -    }
   9.449 +	/* We watch the backend */
   9.450 +	struct xenbus_watch watch;
   9.451 +	int vdevice;
   9.452 +	u16 handle;
   9.453 +	int connected;
   9.454 +	struct xenbus_device *dev;
   9.455 +	char *backend;
   9.456 +};
   9.457  
   9.458 -    ctrl_if_send_response(msg);
   9.459 +static void watch_for_status(struct xenbus_watch *watch, const char *node)
   9.460 +{
   9.461 +	struct blkfront_info *info;
   9.462 +	unsigned int binfo;
   9.463 +	unsigned long sectors, sector_size;
   9.464 +	int err;
   9.465 +
   9.466 +	info = container_of(watch, struct blkfront_info, watch);
   9.467 +	node += strlen(watch->node);
   9.468 +
   9.469 +	/* FIXME: clean up when error on the other end. */
   9.470 +	if (info->connected)
   9.471 +		return;
   9.472 +
   9.473 +	err = xenbus_gather(watch->node, 
   9.474 +			    "sectors", "%lu", &sectors,
   9.475 +			    "info", "%u", &binfo,
   9.476 +			    "sector-size", "%lu", &sector_size,
   9.477 +			    NULL);
   9.478 +
   9.479 +	if (err)
   9.480 +		xenbus_dev_error(info->dev, err, "reading backend fields");
   9.481 +	else {
   9.482 +		xlvbd_add(sectors, info->vdevice, info->handle, binfo,
   9.483 +			  sector_size);
   9.484 +		info->connected = 1;
   9.485 +
   9.486 +		/* First to connect?  blkif is now connected. */
   9.487 +		if (blkif_vbds_connected++ == 0)
   9.488 +			blkif_state = BLKIF_STATE_CONNECTED;
   9.489 +
   9.490 +		xenbus_dev_ok(info->dev);
   9.491 +
   9.492 +		/* Kick pending requests. */
   9.493 +		spin_lock_irq(&blkif_io_lock);
   9.494 +		kick_pending_request_queues();
   9.495 +		spin_unlock_irq(&blkif_io_lock);
   9.496 +	}
   9.497  }
   9.498  
   9.499 -int wait_for_blkif(void)
   9.500 +static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id)
   9.501 +{
   9.502 +	blkif_sring_t *sring;
   9.503 +	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
   9.504 +	int err;
   9.505 +
   9.506 +	sring = (void *)__get_free_page(GFP_KERNEL);
   9.507 +	if (!sring) {
   9.508 +		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
   9.509 +		return -ENOMEM;
   9.510 +	}
   9.511 +	SHARED_RING_INIT(sring);
   9.512 +	FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
   9.513 +
   9.514 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.515 +	shmem_ref = gnttab_claim_grant_reference(&gref_head,
   9.516 +						 gref_terminal);
   9.517 +	ASSERT(shmem_ref != -ENOSPC);
   9.518 +	gnttab_grant_foreign_access_ref(shmem_ref,
   9.519 +					backend_id,
   9.520 +					virt_to_machine(blk_ring.sring)
   9.521 +					>> PAGE_SHIFT, 0);
   9.522 +#endif
   9.523 +
   9.524 +	op.u.alloc_unbound.dom = backend_id;
   9.525 +	err = HYPERVISOR_event_channel_op(&op);
   9.526 +	if (err) {
   9.527 +		free_page((unsigned long)blk_ring.sring);
   9.528 +		blk_ring.sring = 0;
   9.529 +		xenbus_dev_error(dev, err, "allocating event channel");
   9.530 +		return err;
   9.531 +	}
   9.532 +	blkif_connect(op.u.alloc_unbound.port, backend_id);
   9.533 +	return 0;
   9.534 +}
   9.535 +
   9.536 +/* Common code used when first setting up, and when resuming. */
   9.537 +static int talk_to_backend(struct xenbus_device *dev,
   9.538 +			   struct blkfront_info *info)
   9.539 +{
   9.540 +	char *backend;
   9.541 +	const char *message;
   9.542 +	int err, backend_id;
   9.543 +
   9.544 +	backend = xenbus_read(dev->nodename, "backend", NULL);
   9.545 +	if (IS_ERR(backend)) {
   9.546 +		err = PTR_ERR(backend);
   9.547 +		if (err == -ENOENT)
   9.548 +			goto out;
   9.549 +		xenbus_dev_error(dev, err, "reading %s/backend",
   9.550 +				 dev->nodename);
   9.551 +		goto out;
   9.552 +	}
   9.553 +	if (strlen(backend) == 0) {
   9.554 +		err = -ENOENT;
   9.555 +		goto free_backend;
   9.556 +	}
   9.557 +
   9.558 +	/* FIXME: This driver can't handle backends on different
   9.559 +	 * domains.  Check and fail gracefully. */
   9.560 +	err = xenbus_scanf(dev->nodename, "backend-id", "%i", &backend_id);
   9.561 +	if (err == -ENOENT)
   9.562 +		goto free_backend;
   9.563 + 	if (err < 0) {
   9.564 +		xenbus_dev_error(dev, err, "reading %s/backend-id",
   9.565 +				 dev->nodename);
   9.566 + 		goto free_backend;
   9.567 + 	}
   9.568 +
   9.569 +	/* First device?  We create shared ring, alloc event channel. */
   9.570 +	if (blkif_vbds == 0) {
   9.571 +		err = setup_blkring(dev, backend_id);
   9.572 +		if (err)
   9.573 +			goto free_backend;
   9.574 +	}
   9.575 +
   9.576 +	err = xenbus_transaction_start(dev->nodename);
   9.577 +	if (err) {
   9.578 +		xenbus_dev_error(dev, err, "starting transaction");
   9.579 +		goto destroy_blkring;
   9.580 +	}
   9.581 +
   9.582 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.583 +	err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref);
   9.584 +	if (err) {
   9.585 +		message = "writing grant-id";
   9.586 +		goto abort_transaction;
   9.587 +	}
   9.588 +#else
   9.589 +	err = xenbus_printf(dev->nodename, "shared-frame", "%lu",
   9.590 +			    virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   9.591 +	if (err) {
   9.592 +		message = "writing shared-frame";
   9.593 +		goto abort_transaction;
   9.594 +	}
   9.595 +#endif
   9.596 +	err = xenbus_printf(dev->nodename,
   9.597 +			    "event-channel", "%u", blkif_evtchn);
   9.598 +	if (err) {
   9.599 +		message = "writing event-channel";
   9.600 +		goto abort_transaction;
   9.601 +	}
   9.602 +
   9.603 +	info->watch.node = info->backend = backend;
   9.604 +	info->watch.callback = watch_for_status;
   9.605 +
   9.606 +	err = register_xenbus_watch(&info->watch);
   9.607 +	if (err) {
   9.608 +		message = "registering watch on backend";
   9.609 +		goto abort_transaction;
   9.610 +	}
   9.611 +
   9.612 +	err = xenbus_transaction_end(0);
   9.613 +	if (err) {
   9.614 +		xenbus_dev_error(dev, err, "completing transaction");
   9.615 +		goto destroy_blkring;
   9.616 +	}
   9.617 +	return 0;
   9.618 +
   9.619 +abort_transaction:
   9.620 +	xenbus_transaction_end(1);
   9.621 +	/* Have to do this *outside* transaction.  */
   9.622 +	xenbus_dev_error(dev, err, "%s", message);
   9.623 +destroy_blkring:
   9.624 +	if (blkif_vbds == 0)
   9.625 +		blkif_free();
   9.626 +free_backend:
   9.627 +	kfree(backend);
   9.628 +out:
   9.629 +	printk("%s:%u = %i\n", __FILE__, __LINE__, err);
   9.630 +	return err;
   9.631 +}
   9.632 +
   9.633 +/* Setup supplies the backend dir, virtual device.
   9.634 +
   9.635 +   We place an event channel and shared frame entries.
   9.636 +   We watch backend to wait if it's ok. */
   9.637 +static int blkfront_probe(struct xenbus_device *dev,
   9.638 +			  const struct xenbus_device_id *id)
   9.639 +{
   9.640 +	int err;
   9.641 +	struct blkfront_info *info;
   9.642 +	int vdevice;
   9.643 +
   9.644 +	/* FIXME: Use dynamic device id if this is not set. */
   9.645 +	err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
   9.646 +	if (err == -ENOENT)
   9.647 +		return err;
   9.648 +	if (err < 0) {
   9.649 +		xenbus_dev_error(dev, err, "reading virtual-device");
   9.650 +		return err;
   9.651 +	}
   9.652 +
   9.653 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
   9.654 +	if (!info) {
   9.655 +		xenbus_dev_error(dev, err, "allocating info structure");
   9.656 +		return err;
   9.657 +	}
   9.658 +	info->dev = dev;
   9.659 +	info->vdevice = vdevice;
   9.660 +	info->connected = 0;
   9.661 +	/* Front end dir is a number, which is used as the id. */
   9.662 +	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
   9.663 +	dev->data = info;
   9.664 +
   9.665 +	err = talk_to_backend(dev, info);
   9.666 +	if (err) {
   9.667 +		kfree(info);
   9.668 +		return err;
   9.669 +	}
   9.670 +
   9.671 +	/* Call once in case entries already there. */
   9.672 +	watch_for_status(&info->watch, info->watch.node);
   9.673 +	blkif_vbds++;
   9.674 +	return 0;
   9.675 +}
   9.676 +
   9.677 +static int blkfront_remove(struct xenbus_device *dev)
   9.678 +{
   9.679 +	struct blkfront_info *info = dev->data;
   9.680 +
   9.681 +	if (info->backend)
   9.682 +		unregister_xenbus_watch(&info->watch);
   9.683 +
   9.684 +	if (info->connected) {
   9.685 +		xlvbd_del(info->handle);
   9.686 +		blkif_vbds_connected--;
   9.687 +	}
   9.688 +	kfree(info->backend);
   9.689 +	kfree(info);
   9.690 +
   9.691 +	if (--blkif_vbds == 0)
   9.692 +		blkif_free();
   9.693 +
   9.694 +	return 0;
   9.695 +}
   9.696 +
   9.697 +static int blkfront_suspend(struct xenbus_device *dev)
   9.698 +{
   9.699 +	struct blkfront_info *info = dev->data;
   9.700 +
   9.701 +	unregister_xenbus_watch(&info->watch);
   9.702 +	kfree(info->backend);
   9.703 +	info->backend = NULL;
   9.704 +
   9.705 +	if (--blkif_vbds == 0) {
   9.706 +		recovery = 1;
   9.707 +		blkif_free();
   9.708 +	}
   9.709 +
   9.710 +	return 0;
   9.711 +}
   9.712 +
   9.713 +static int blkfront_resume(struct xenbus_device *dev)
   9.714 +{
   9.715 +	struct blkfront_info *info = dev->data;
   9.716 +	int err;
   9.717 +
   9.718 +	/* FIXME: Check geometry hasn't changed here... */
   9.719 +	err = talk_to_backend(dev, info);
   9.720 +	if (!err) {
   9.721 +		if (blkif_vbds++ == 0)
   9.722 +			blkif_recover();
   9.723 +	}
   9.724 +	return err;
   9.725 +}
   9.726 +
   9.727 +static struct xenbus_driver blkfront = {
   9.728 +	.name = "vbd",
   9.729 +	.owner = THIS_MODULE,
   9.730 +	.ids = blkfront_ids,
   9.731 +	.probe = blkfront_probe,
   9.732 +	.remove = blkfront_remove,
   9.733 +	.resume = blkfront_resume,
   9.734 +	.suspend = blkfront_suspend,
   9.735 +};
   9.736 +
   9.737 +static void __init init_blk_xenbus(void)
   9.738 +{
   9.739 +	xenbus_register_device(&blkfront);
   9.740 +}
   9.741 +
   9.742 +static int wait_for_blkif(void)
   9.743  {
   9.744      int err = 0;
   9.745      int i;
   9.746 -    send_driver_status(1);
   9.747  
   9.748      /*
   9.749       * We should read 'nr_interfaces' from response message and wait
   9.750       * for notifications before proceeding. For now we assume that we
   9.751       * will be notified of exactly one interface.
   9.752       */
   9.753 -    for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
   9.754 +    for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ )
   9.755      {
   9.756          set_current_state(TASK_INTERRUPTIBLE);
   9.757          schedule_timeout(1);
   9.758 @@ -1419,7 +1421,7 @@ int wait_for_blkif(void)
   9.759      return err;
   9.760  }
   9.761  
   9.762 -int __init xlblk_init(void)
   9.763 +static int __init xlblk_init(void)
   9.764  {
   9.765      int i;
   9.766  
   9.767 @@ -1443,29 +1445,13 @@ int __init xlblk_init(void)
   9.768          blk_shadow[i].req.id = i+1;
   9.769      blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
   9.770  
   9.771 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
   9.772 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
   9.773 +    init_blk_xenbus();
   9.774  
   9.775      wait_for_blkif();
   9.776  
   9.777      return 0;
   9.778  }
   9.779  
   9.780 -void blkdev_suspend(void)
   9.781 -{
   9.782 -}
   9.783 -
   9.784 -void blkdev_resume(void)
   9.785 -{
   9.786 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   9.787 -    int i, j;
   9.788 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
   9.789 -        for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
   9.790 -            blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
   9.791 -#endif
   9.792 -    send_driver_status(1);
   9.793 -}
   9.794 -
   9.795  static void blkif_completion(struct blk_shadow *s)
   9.796  {
   9.797      int i;
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 10:50:15 2005 +0000
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 13:08:50 2005 +0000
    10.3 @@ -100,6 +100,7 @@ struct xlbd_major_info {
    10.4  
    10.5  struct xlbd_disk_info {
    10.6      int xd_device;
    10.7 +    blkif_vdev_t handle;
    10.8      struct xlbd_major_info *mi;
    10.9  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   10.10      struct xlbd_disk_info  *next_waiting;
   10.11 @@ -119,17 +120,10 @@ extern int blkif_ioctl(struct inode *ino
   10.12                         unsigned command, unsigned long argument);
   10.13  extern int blkif_check(dev_t dev);
   10.14  extern int blkif_revalidate(dev_t dev);
   10.15 -extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
   10.16 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.17 -extern void blkif_control_probe_send(
   10.18 -    blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
   10.19 -#endif
   10.20  extern void do_blkif_request (request_queue_t *rq); 
   10.21  
   10.22 -extern void xlvbd_update_vbds(void);
   10.23 -
   10.24  /* Virtual block-device subsystem. */
   10.25 -extern int  xlvbd_init(void);
   10.26 -extern void xlvbd_cleanup(void); 
   10.27 -
   10.28 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
   10.29 +	      u16 info, u16 sector_size);
   10.30 +void xlvbd_del(blkif_vdev_t handle);
   10.31  #endif /* __XEN_DRIVERS_BLOCK_H__ */
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 10:50:15 2005 +0000
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 13:08:50 2005 +0000
    11.3 @@ -46,8 +46,9 @@
    11.4  struct lvdisk
    11.5  {
    11.6      blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
    11.7 -    blkif_vdev_t   device;   /*  8: Device number (opaque 16 bit value). */
    11.8 -    u16            info; 
    11.9 +    blkif_vdev_t   handle;   /*  8: Device number (opaque 16 bit value). */
   11.10 +    u16            info;
   11.11 +    dev_t          dev;
   11.12      struct list_head list;
   11.13  };
   11.14  
   11.15 @@ -85,7 +86,7 @@ static struct xlbd_major_info *major_inf
   11.16  
   11.17  /* Information about our VBDs. */
   11.18  #define MAX_VBDS 64
   11.19 -struct list_head vbds_list;
   11.20 +static LIST_HEAD(vbds_list);
   11.21  
   11.22  #define MAJOR_XEN(dev) ((dev)>>8)
   11.23  #define MINOR_XEN(dev) ((dev) & 0xff)
   11.24 @@ -118,49 +119,6 @@ static void xlvbd_device_free(struct lvd
   11.25      kfree(disk);
   11.26  }
   11.27  
   11.28 -static vdisk_t *xlvbd_probe(int *ret)
   11.29 -{
   11.30 -    blkif_response_t rsp;
   11.31 -    blkif_request_t req;
   11.32 -    vdisk_t *disk_info = NULL;
   11.33 -    unsigned long buf;
   11.34 -    int nr;
   11.35 -
   11.36 -    buf = __get_free_page(GFP_KERNEL);
   11.37 -    if ((void *)buf == NULL)
   11.38 -        goto out;
   11.39 -
   11.40 -    memset(&req, 0, sizeof(req));
   11.41 -    req.operation = BLKIF_OP_PROBE;
   11.42 -    req.nr_segments = 1;
   11.43 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   11.44 -    blkif_control_probe_send(&req, &rsp,
   11.45 -                             (unsigned long)(virt_to_machine(buf)));
   11.46 -#else
   11.47 -    req.frame_and_sects[0] = blkif_fas(virt_to_machine(buf), 0, (PAGE_SIZE/512)-1);
   11.48 -
   11.49 -    blkif_control_send(&req, &rsp);
   11.50 -#endif
   11.51 -    if ( rsp.status <= 0 ) {
   11.52 -        WPRINTK("Could not probe disks (%d)\n", rsp.status);
   11.53 -        goto out;
   11.54 -    }
   11.55 -    nr = rsp.status;
   11.56 -    if ( nr > MAX_VBDS )
   11.57 -        nr = MAX_VBDS;
   11.58 -
   11.59 -    disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
   11.60 -    if (disk_info != NULL)
   11.61 -        memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
   11.62 -
   11.63 -    if (ret != NULL)
   11.64 -        *ret = nr;
   11.65 -
   11.66 -out:
   11.67 -    free_page(buf);
   11.68 -    return disk_info;
   11.69 -}
   11.70 -
   11.71  static struct xlbd_major_info *xlbd_alloc_major_info(
   11.72      int major, int minor, int index)
   11.73  {
   11.74 @@ -189,6 +147,7 @@ static struct xlbd_major_info *xlbd_allo
   11.75          break;
   11.76      }
   11.77      
   11.78 +    printk("Registering block device major %i\n", ptr->major);
   11.79      if (register_blkdev(ptr->major, ptr->type->devname)) {
   11.80          WPRINTK("can't get major %d with name %s\n",
   11.81                  ptr->major, ptr->type->devname);
   11.82 @@ -231,7 +190,7 @@ static struct xlbd_major_info *xlbd_get_
   11.83              xlbd_alloc_major_info(major, minor, index));
   11.84  }
   11.85  
   11.86 -static int xlvbd_init_blk_queue(struct gendisk *gd, vdisk_t *disk)
   11.87 +static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
   11.88  {
   11.89      request_queue_t *rq;
   11.90  
   11.91 @@ -242,7 +201,7 @@ static int xlvbd_init_blk_queue(struct g
   11.92      elevator_init(rq, "noop");
   11.93  
   11.94      /* Hard sector size and max sectors impersonate the equiv. hardware. */
   11.95 -    blk_queue_hardsect_size(rq, disk->sector_size);
   11.96 +    blk_queue_hardsect_size(rq, sector_size);
   11.97      blk_queue_max_sectors(rq, 512);
   11.98  
   11.99      /* Each segment in a request is up to an aligned page in size. */
  11.100 @@ -261,8 +220,9 @@ static int xlvbd_init_blk_queue(struct g
  11.101      return 0;
  11.102  }
  11.103  
  11.104 -struct gendisk *xlvbd_alloc_gendisk(
  11.105 -    struct xlbd_major_info *mi, int minor, vdisk_t *disk)
  11.106 +static struct gendisk *xlvbd_alloc_gendisk(
  11.107 +    struct xlbd_major_info *mi, int minor, blkif_sector_t capacity,
  11.108 +    int device, blkif_vdev_t handle, u16 info, u16 sector_size)
  11.109  {
  11.110      struct gendisk *gd;
  11.111      struct xlbd_disk_info *di;
  11.112 @@ -273,7 +233,8 @@ struct gendisk *xlvbd_alloc_gendisk(
  11.113          return NULL;
  11.114      memset(di, 0, sizeof(*di));
  11.115      di->mi = mi;
  11.116 -    di->xd_device = disk->device;
  11.117 +    di->xd_device = device;
  11.118 +    di->handle = handle;
  11.119  
  11.120      if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
  11.121          nr_minors = 1 << mi->type->partn_shift;
  11.122 @@ -296,22 +257,22 @@ struct gendisk *xlvbd_alloc_gendisk(
  11.123      gd->first_minor = minor;
  11.124      gd->fops = &xlvbd_block_fops;
  11.125      gd->private_data = di;
  11.126 -    set_capacity(gd, disk->capacity);
  11.127 +    set_capacity(gd, capacity);
  11.128  
  11.129 -    if (xlvbd_init_blk_queue(gd, disk)) {
  11.130 +    if (xlvbd_init_blk_queue(gd, sector_size)) {
  11.131          del_gendisk(gd);
  11.132          goto out;
  11.133      }
  11.134  
  11.135      di->rq = gd->queue;
  11.136  
  11.137 -    if (disk->info & VDISK_READONLY)
  11.138 +    if (info & VDISK_READONLY)
  11.139          set_disk_ro(gd, 1);
  11.140  
  11.141 -    if (disk->info & VDISK_REMOVABLE)
  11.142 +    if (info & VDISK_REMOVABLE)
  11.143          gd->flags |= GENHD_FL_REMOVABLE;
  11.144  
  11.145 -    if (disk->info & VDISK_CDROM)
  11.146 +    if (info & VDISK_CDROM)
  11.147          gd->flags |= GENHD_FL_CD;
  11.148  
  11.149      add_disk(gd);
  11.150 @@ -323,38 +284,36 @@ out:
  11.151      return NULL;
  11.152  }
  11.153  
  11.154 -static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
  11.155 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
  11.156 +	      u16 info, u16 sector_size)
  11.157  {
  11.158      struct lvdisk *new;
  11.159 -    int minor;
  11.160 -    dev_t device;
  11.161      struct block_device *bd;
  11.162      struct gendisk *gd;
  11.163      struct xlbd_major_info *mi;
  11.164  
  11.165 -    mi = xlbd_get_major_info(disk->device);
  11.166 +    mi = xlbd_get_major_info(device);
  11.167      if (mi == NULL)
  11.168          return -EPERM;
  11.169  
  11.170      new = xlvbd_device_alloc();
  11.171      if (new == NULL)
  11.172 -        return -1;
  11.173 -    new->capacity = disk->capacity;
  11.174 -    new->device = disk->device;
  11.175 -    new->info = disk->info;
  11.176 -    
  11.177 -    minor = MINOR_XEN(disk->device);
  11.178 -    device = MKDEV(mi->major, minor);
  11.179 -    
  11.180 -    bd = bdget(device);
  11.181 +        return -ENOMEM;
  11.182 +    new->capacity = capacity;
  11.183 +    new->info = info;
  11.184 +    new->handle = handle;
  11.185 +    new->dev = MKDEV(MAJOR_XEN(device), MINOR_XEN(device));
  11.186 +
  11.187 +    bd = bdget(new->dev);
  11.188      if (bd == NULL)
  11.189          goto out;
  11.190      
  11.191 -    gd = xlvbd_alloc_gendisk(mi, minor, disk);
  11.192 +    gd = xlvbd_alloc_gendisk(mi, MINOR_XEN(device), capacity, device, handle,
  11.193 +			     info, sector_size);
  11.194      if (gd == NULL)
  11.195          goto out_bd;
  11.196  
  11.197 -    list_add(&new->list, list);
  11.198 +    list_add(&new->list, &vbds_list);
  11.199  out_bd:
  11.200      bdput(bd);
  11.201  out:
  11.202 @@ -363,27 +322,26 @@ out:
  11.203  
  11.204  static int xlvbd_device_del(struct lvdisk *disk)
  11.205  {
  11.206 -    dev_t device;
  11.207      struct block_device *bd;
  11.208      struct gendisk *gd;
  11.209      struct xlbd_disk_info *di;
  11.210      int ret = 0, unused;
  11.211      request_queue_t *rq;
  11.212  
  11.213 -    device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
  11.214 -
  11.215 -    bd = bdget(device);
  11.216 +    bd = bdget(disk->dev);
  11.217      if (bd == NULL)
  11.218          return -1;
  11.219  
  11.220 -    gd = get_gendisk(device, &unused);
  11.221 +    gd = get_gendisk(disk->dev, &unused);
  11.222      di = gd->private_data;
  11.223  
  11.224 +#if 0 /* This is wrong: hda and hdb share same major, for example. */
  11.225      if (di->mi->usage != 0) {
  11.226 -        WPRINTK("disk removal failed: used [dev=%x]\n", device);
  11.227 +        WPRINTK("disk removal failed: used [dev=%x]\n", disk->dev);
  11.228          ret = -1;
  11.229          goto out;
  11.230      }
  11.231 +#endif
  11.232  
  11.233      rq = gd->queue;
  11.234      del_gendisk(gd);
  11.235 @@ -391,110 +349,19 @@ static int xlvbd_device_del(struct lvdis
  11.236      blk_cleanup_queue(rq);
  11.237  
  11.238      xlvbd_device_free(disk);
  11.239 -out:
  11.240      bdput(bd);
  11.241      return ret;
  11.242  }
  11.243  
  11.244 -static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
  11.245 +void xlvbd_del(blkif_vdev_t handle)
  11.246  {
  11.247 -    dev_t device;
  11.248 -    struct block_device *bd;
  11.249 -    struct gendisk *gd;
  11.250 -    int unused;
  11.251 -
  11.252 -    if ((ldisk->capacity == disk->capacity) && (ldisk->info == disk->info))
  11.253 -        return 0;    
  11.254 -
  11.255 -    device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
  11.256 -
  11.257 -    bd = bdget(device);
  11.258 -    if (bd == NULL)
  11.259 -        return -1;
  11.260 -
  11.261 -    gd = get_gendisk(device, &unused);
  11.262 -    set_capacity(gd, disk->capacity);    
  11.263 -    ldisk->capacity = disk->capacity;
  11.264 -
  11.265 -    bdput(bd);
  11.266 -
  11.267 -    return 0;
  11.268 -}
  11.269 -
  11.270 -void xlvbd_refresh(void)
  11.271 -{
  11.272 -    vdisk_t *newdisks;
  11.273 -    struct list_head *tmp, *tmp2;
  11.274 -    struct lvdisk *disk;
  11.275 -    int i, nr;
  11.276 +	struct lvdisk *i;
  11.277  
  11.278 -    newdisks = xlvbd_probe(&nr);
  11.279 -    if (newdisks == NULL) {
  11.280 -        WPRINTK("failed to probe\n");
  11.281 -        return;
  11.282 -    }
  11.283 -    
  11.284 -    i = 0;
  11.285 -    list_for_each_safe(tmp, tmp2, &vbds_list) {
  11.286 -        disk = list_entry(tmp, struct lvdisk, list);
  11.287 -        
  11.288 -        for (i = 0; i < nr; i++) {
  11.289 -            if ( !newdisks[i].device )
  11.290 -                continue;
  11.291 -            if ( disk->device == newdisks[i].device ) {
  11.292 -                xlvbd_device_update(disk, &newdisks[i]);
  11.293 -                newdisks[i].device = 0;
  11.294 -                break;
  11.295 -            }
  11.296 -        }
  11.297 -        if (i == nr) {
  11.298 -            xlvbd_device_del(disk);
  11.299 -            newdisks[i].device = 0;
  11.300 -        }
  11.301 -    }
  11.302 -    for (i = 0; i < nr; i++)
  11.303 -        if ( newdisks[i].device )
  11.304 -            xlvbd_device_add(&vbds_list, &newdisks[i]);
  11.305 -    kfree(newdisks);
  11.306 +	list_for_each_entry(i, &vbds_list, list) {
  11.307 +		if (i->handle == handle) {
  11.308 +			xlvbd_device_del(i);
  11.309 +			return;
  11.310 +		}
  11.311 +	}
  11.312 +	BUG();
  11.313  }
  11.314 -
  11.315 -/*
  11.316 - * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
  11.317 - * state. The VBDs need to be updated in this way when the domain is
  11.318 - * initialised and also each time we receive an XLBLK_UPDATE event.
  11.319 - */
  11.320 -void xlvbd_update_vbds(void)
  11.321 -{
  11.322 -    xlvbd_refresh();
  11.323 -}
  11.324 -
  11.325 -/*
  11.326 - * Set up all the linux device goop for the virtual block devices
  11.327 - * (vbd's) that we know about. Note that although from the backend
  11.328 - * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
  11.329 - * number, the domain creation tools conventionally allocate these
  11.330 - * numbers to correspond to those used by 'real' linux -- this is just
  11.331 - * for convenience as it means e.g. that the same /etc/fstab can be
  11.332 - * used when booting with or without Xen.
  11.333 - */
  11.334 -int xlvbd_init(void)
  11.335 -{
  11.336 -    int i, nr;
  11.337 -    vdisk_t *disks;
  11.338 -
  11.339 -    INIT_LIST_HEAD(&vbds_list);
  11.340 -
  11.341 -    memset(major_info, 0, sizeof(major_info));
  11.342 -    
  11.343 -    disks = xlvbd_probe(&nr);
  11.344 -    if (disks == NULL) {
  11.345 -        WPRINTK("failed to probe\n");
  11.346 -        return -1;
  11.347 -    }
  11.348 -
  11.349 -    for (i = 0; i < nr; i++)
  11.350 -        xlvbd_device_add(&vbds_list, &disks[i]);
  11.351 -
  11.352 -    kfree(disks);
  11.353 -    return 0;
  11.354 -}
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Aug 19 10:50:15 2005 +0000
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Aug 19 13:08:50 2005 +0000
    12.3 @@ -168,6 +168,8 @@ static int xenbus_dev_probe(struct devic
    12.4  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
    12.5  	const struct xenbus_device_id *id;
    12.6  
    12.7 +	BUG_ON(!dev->driver);
    12.8 +
    12.9  	if (!drv->probe)
   12.10  		return -ENODEV;
   12.11  
   12.12 @@ -531,10 +533,13 @@ static struct xenbus_watch be_watch = {
   12.13  static int suspend_dev(struct device *dev, void *data)
   12.14  {
   12.15  	int err = 0;
   12.16 -	struct xenbus_driver *drv = to_xenbus_driver(dev->driver);
   12.17 -	struct xenbus_device *xdev
   12.18 -		= container_of(dev, struct xenbus_device, dev);
   12.19 +	struct xenbus_driver *drv;
   12.20 +	struct xenbus_device *xdev;
   12.21  
   12.22 +	if (dev->driver == NULL)
   12.23 +		return 0;
   12.24 +	drv = to_xenbus_driver(dev->driver);
   12.25 +	xdev = container_of(dev, struct xenbus_device, dev);
   12.26  	if (drv->suspend)
   12.27  		err = drv->suspend(xdev);
   12.28  	if (err)
   12.29 @@ -545,10 +550,13 @@ static int suspend_dev(struct device *de
   12.30  static int resume_dev(struct device *dev, void *data)
   12.31  {
   12.32  	int err = 0;
   12.33 -	struct xenbus_driver *drv = to_xenbus_driver(dev->driver);
   12.34 -	struct xenbus_device *xdev
   12.35 -		= container_of(dev, struct xenbus_device, dev);
   12.36 +	struct xenbus_driver *drv;
   12.37 +	struct xenbus_device *xdev;
   12.38  
   12.39 +	if (dev->driver == NULL)
   12.40 +		return 0;
   12.41 +	drv = to_xenbus_driver(dev->driver);
   12.42 +	xdev = container_of(dev, struct xenbus_device, dev);
   12.43  	if (drv->resume)
   12.44  		err = drv->resume(xdev);
   12.45  	if (err)
    13.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 19 10:50:15 2005 +0000
    13.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 19 13:08:50 2005 +0000
    13.3 @@ -36,8 +36,10 @@ from xen.xend.server import controller
    13.4  from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
    13.5  from xen.xend.server import messages
    13.6  from xen.xend.server.channel import EventChannel, channelFactory
    13.7 +from xen.util.blkif import blkdev_name_to_number, expand_dev_name
    13.8  
    13.9  from xen.xend import sxp
   13.10 +from xen.xend import Blkctl
   13.11  from xen.xend.PrettyPrint import prettyprintstring
   13.12  from xen.xend.XendBootloader import bootloader
   13.13  from xen.xend.XendLogging import log
   13.14 @@ -380,6 +382,39 @@ class XendDomainInfo:
   13.15          return ctrl
   13.16  
   13.17      def createDevice(self, type, devconfig, change=False):
   13.18 +        if type == 'vbd':
   13.19 +
   13.20 +            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
   13.21 +
   13.22 +            devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev'))
   13.23 +
   13.24 +            # create backend db
   13.25 +            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
   13.26 +                                         (type, self.uuid, devnum))
   13.27 +
   13.28 +            # create frontend db
   13.29 +            db = self.db.addChild("/device/%s/%d" % (type, devnum))
   13.30 +            
   13.31 +            db['virtual-device'] = "%i" % devnum
   13.32 +            #db['backend'] = sxp.child_value(devconfig, 'backend', '0')
   13.33 +            db['backend'] = backdb.getPath()
   13.34 +            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
   13.35 +                                                          'backend', '0'))
   13.36 +
   13.37 +            backdb['frontend'] = db.getPath()
   13.38 +            (type, params) = string.split(sxp.child_value(devconfig, 'uname'), ':', 1)
   13.39 +            node = Blkctl.block('bind', type, params)
   13.40 +            backdb['frontend-id'] = "%i" % self.id
   13.41 +            backdb['physical-device'] = "%li" % blkdev_name_to_number(node)
   13.42 +            backdb.saveDB(save=True)
   13.43 +
   13.44 +            # Ok, super gross, this really doesn't belong in the frontend db...
   13.45 +            db['type'] = type
   13.46 +            db['node'] = node
   13.47 +            db['params'] = params
   13.48 +            db.saveDB(save=True)
   13.49 +            
   13.50 +            return
   13.51          ctrl = self.findDeviceController(type)
   13.52          return ctrl.createDevice(devconfig, recreate=self.recreate,
   13.53                                   change=change)
   13.54 @@ -671,6 +706,16 @@ class XendDomainInfo:
   13.55          for ctrl in self.getDeviceControllers():
   13.56              if ctrl.isDestroyed(): continue
   13.57              ctrl.destroyController(reboot=reboot)
   13.58 +        ddb = self.db.addChild("/device")
   13.59 +        for type in ddb.keys():
   13.60 +            if type == 'vbd':
   13.61 +                typedb = ddb.addChild(type)
   13.62 +                for dev in typedb.keys():
   13.63 +                    devdb = typedb.addChild(str(dev))
   13.64 +                    Blkctl.block('unbind', devdb['type'].getData(),
   13.65 +                                 devdb['node'].getData())
   13.66 +                    typedb[dev].delete()
   13.67 +                typedb.saveDB(save=True)
   13.68  
   13.69      def show(self):
   13.70          """Print virtual machine info.
   13.71 @@ -926,6 +971,7 @@ class XendDomainInfo:
   13.72          at creation time, for example when it uses NFS root.
   13.73  
   13.74          """
   13.75 +        return
   13.76          blkif = self.getDeviceController("vbd", error=False)
   13.77          if not blkif:
   13.78              blkif = self.createDeviceController("vbd")
    14.1 --- a/xen/include/public/io/blkif.h	Fri Aug 19 10:50:15 2005 +0000
    14.2 +++ b/xen/include/public/io/blkif.h	Fri Aug 19 13:08:50 2005 +0000
    14.3 @@ -18,7 +18,6 @@
    14.4  
    14.5  #define BLKIF_OP_READ      0
    14.6  #define BLKIF_OP_WRITE     1
    14.7 -#define BLKIF_OP_PROBE     2
    14.8  
    14.9  /* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
   14.10  #define BLKIF_RING_SIZE        64
   14.11 @@ -33,7 +32,7 @@
   14.12  typedef struct blkif_request {
   14.13      u8             operation;    /* BLKIF_OP_???                         */
   14.14      u8             nr_segments;  /* number of segments                   */
   14.15 -    blkif_vdev_t   device;       /* only for read/write requests         */
   14.16 +    blkif_vdev_t   handle;       /* only for read/write requests         */
   14.17      unsigned long  id;           /* private guest value, echoed in resp  */
   14.18      blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
   14.19      /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect                        */
   14.20 @@ -71,31 +70,8 @@ typedef struct blkif_response {
   14.21  
   14.22  DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t);
   14.23  
   14.24 -/*
   14.25 - * BLKIF_OP_PROBE:
   14.26 - * The request format for a probe request is constrained as follows:
   14.27 - *  @operation   == BLKIF_OP_PROBE
   14.28 - *  @nr_segments == size of probe buffer in pages
   14.29 - *  @device      == unused (zero)
   14.30 - *  @id          == any value (echoed in response message)
   14.31 - *  @sector_num  == unused (zero)
   14.32 - *  @frame_and_sects == list of page-sized buffers.
   14.33 - *                       (i.e., @first_sect == 0, @last_sect == 7).
   14.34 - * 
   14.35 - * The response is a list of vdisk_t elements copied into the out-of-band
   14.36 - * probe buffer. On success the response status field contains the number
   14.37 - * of vdisk_t elements.
   14.38 - */
   14.39 -
   14.40  #define VDISK_CDROM        0x1
   14.41  #define VDISK_REMOVABLE    0x2
   14.42  #define VDISK_READONLY     0x4
   14.43  
   14.44 -typedef struct vdisk {
   14.45 -    blkif_sector_t capacity;     /* Size in terms of 512-byte sectors.   */
   14.46 -    blkif_vdev_t   device;       /* Device number (opaque 16 bit value). */
   14.47 -    u16            info;         /* Device type and flags (VDISK_*).     */
   14.48 -    u16            sector_size;  /* Minimum alignment for requests.      */
   14.49 -} vdisk_t; /* 16 bytes */
   14.50 -
   14.51  #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */