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
    17.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 10:50:15 2005 +0000
    17.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 13:08:50 2005 +0000
    17.3 @@ -120,8 +120,6 @@ static int restore_vcpu_context(int vcpu
    17.4      return 0;
    17.5  }
    17.6  
    17.7 -extern unsigned uber_debug;
    17.8 -
    17.9  static int __do_suspend(void *ignore)
   17.10  {
   17.11      int i, j;
   17.12 @@ -130,13 +128,6 @@ static int __do_suspend(void *ignore)
   17.13  
   17.14      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
   17.15  	/* XXX SMH: yes it would :-( */	
   17.16 -#ifdef CONFIG_XEN_BLKDEV_FRONTEND
   17.17 -    extern void blkdev_suspend(void);
   17.18 -    extern void blkdev_resume(void);
   17.19 -#else
   17.20 -#define blkdev_suspend() do{}while(0)
   17.21 -#define blkdev_resume()  do{}while(0)
   17.22 -#endif
   17.23  
   17.24  #ifdef CONFIG_XEN_NETDEV_FRONTEND
   17.25      extern void netif_suspend(void);
   17.26 @@ -234,8 +225,6 @@ static int __do_suspend(void *ignore)
   17.27  
   17.28      netif_suspend();
   17.29  
   17.30 -    blkdev_suspend();
   17.31 -
   17.32      time_suspend();
   17.33  
   17.34  #ifdef CONFIG_SMP
   17.35 @@ -293,8 +282,6 @@ static int __do_suspend(void *ignore)
   17.36  
   17.37      time_resume();
   17.38  
   17.39 -    blkdev_resume();
   17.40 -
   17.41      netif_resume();
   17.42  
   17.43      usbif_resume();
   17.44 @@ -315,8 +302,6 @@ static int __do_suspend(void *ignore)
   17.45  	}
   17.46      }
   17.47  
   17.48 -    uber_debug = 0;
   17.49 -
   17.50   out:
   17.51      if ( suspend_record != NULL )
   17.52          free_page((unsigned long)suspend_record);
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 10:50:15 2005 +0000
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 13:08:50 2005 +0000
    23.3 @@ -1,2 +1,2 @@
    23.4  
    23.5 -obj-y	:= blkback.o control.o interface.o vbd.o
    23.6 +obj-y	:= blkback.o xenbus.o interface.o vbd.o
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 10:50:15 2005 +0000
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 13:08:50 2005 +0000
    24.3 @@ -104,7 +104,6 @@ static inline domid_t ID_TO_DOM(unsigned
    24.4  #endif
    24.5  
    24.6  static int do_block_io_op(blkif_t *blkif, int max_to_do);
    24.7 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
    24.8  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
    24.9  static void make_response(blkif_t *blkif, unsigned long id, 
   24.10                            unsigned short op, int st);
   24.11 @@ -349,10 +348,6 @@ static int do_block_io_op(blkif_t *blkif
   24.12              dispatch_rw_block_io(blkif, req);
   24.13              break;
   24.14  
   24.15 -        case BLKIF_OP_PROBE:
   24.16 -            dispatch_probe(blkif, req);
   24.17 -            break;
   24.18 -
   24.19          default:
   24.20              DPRINTK("error: unknown block io operation [%d]\n",
   24.21                      req->operation);
   24.22 @@ -365,66 +360,6 @@ static int do_block_io_op(blkif_t *blkif
   24.23      return more_to_do;
   24.24  }
   24.25  
   24.26 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
   24.27 -{
   24.28 -    int rsp = BLKIF_RSP_ERROR;
   24.29 -    int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
   24.30 -
   24.31 -    /* We expect one buffer only. */
   24.32 -    if ( unlikely(req->nr_segments != 1) )
   24.33 -        goto out;
   24.34 -
   24.35 -    /* Make sure the buffer is page-sized. */
   24.36 -    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
   24.37 -         (blkif_last_sect(req->frame_and_sects[0]) != ((PAGE_SIZE/512)-1)) )
   24.38 -        goto out;
   24.39 -
   24.40 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   24.41 -    {
   24.42 -        struct gnttab_map_grant_ref map;
   24.43 -
   24.44 -        map.host_addr = MMAP_VADDR(pending_idx, 0);
   24.45 -        map.flags = GNTMAP_host_map;
   24.46 -        map.ref = blkif_gref_from_fas(req->frame_and_sects[0]);
   24.47 -        map.dom = blkif->domid;
   24.48 -
   24.49 -        if ( unlikely(HYPERVISOR_grant_table_op(
   24.50 -                        GNTTABOP_map_grant_ref, &map, 1)))
   24.51 -            BUG();
   24.52 -
   24.53 -        if ( map.handle < 0 )
   24.54 -            goto out;
   24.55 -
   24.56 -        pending_handle(pending_idx, 0) = map.handle;
   24.57 -    }
   24.58 -#else /* else CONFIG_XEN_BLKDEV_GRANT */
   24.59 -
   24.60 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
   24.61 -    /* Grab the real frontend out of the probe message. */
   24.62 -    if (req->frame_and_sects[1] == BLKTAP_COOKIE) 
   24.63 -        blkif->is_blktap = 1;
   24.64 -#endif
   24.65 -
   24.66 -
   24.67 -    if ( HYPERVISOR_update_va_mapping_otherdomain(
   24.68 -        MMAP_VADDR(pending_idx, 0),
   24.69 -        pfn_pte_ma(req->frame_and_sects[0] >> PAGE_SHIFT, PAGE_KERNEL),
   24.70 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
   24.71 -        0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) )
   24.72 -#else
   24.73 -        0, blkif->domid) )
   24.74 -#endif
   24.75 -        goto out;
   24.76 -#endif /* endif CONFIG_XEN_BLKDEV_GRANT */
   24.77 -   
   24.78 -    rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), 
   24.79 -                    PAGE_SIZE / sizeof(vdisk_t));
   24.80 -
   24.81 - out:
   24.82 -    fast_flush_area(pending_idx, 1);
   24.83 -    make_response(blkif, req->id, req->operation, rsp);
   24.84 -}
   24.85 -
   24.86  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
   24.87  {
   24.88      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
   24.89 @@ -460,7 +395,7 @@ static void dispatch_rw_block_io(blkif_t
   24.90          goto bad_descriptor;
   24.91      }
   24.92  
   24.93 -    preq.dev           = req->device;
   24.94 +    preq.dev           = req->handle;
   24.95      preq.sector_number = req->sector_number;
   24.96      preq.nr_sects      = 0;
   24.97  
   24.98 @@ -730,8 +665,8 @@ static int __init blkif_init(void)
   24.99          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
  24.100  #endif
  24.101  
  24.102 -    blkif_ctrlif_init();
  24.103 -    
  24.104 +    blkif_xenbus_init();
  24.105 +
  24.106  #ifdef CONFIG_XEN_BLKDEV_GRANT
  24.107      memset( pending_grant_handles,  BLKBACK_INVALID_HANDLE, MMAP_PAGES );
  24.108      printk(KERN_ALERT "Blkif backend is using grant tables.\n");
    25.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 10:50:15 2005 +0000
    25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 13:08:50 2005 +0000
    25.3 @@ -13,7 +13,6 @@
    25.4  #include <asm/io.h>
    25.5  #include <asm/setup.h>
    25.6  #include <asm/pgalloc.h>
    25.7 -#include <asm-xen/ctrl_if.h>
    25.8  #include <asm-xen/evtchn.h>
    25.9  #include <asm-xen/hypervisor.h>
   25.10  #include <asm-xen/xen-public/io/blkif.h>
   25.11 @@ -47,6 +46,7 @@ typedef struct blkif_st {
   25.12      /* Physical parameters of the comms window. */
   25.13      unsigned long     shmem_frame;
   25.14      unsigned int      evtchn;
   25.15 +    unsigned int      remote_evtchn;
   25.16      /* Comms information. */
   25.17      blkif_back_ring_t blk_ring;
   25.18      /* VBDs attached to this interface. */
   25.19 @@ -81,17 +81,29 @@ void blkif_destroy(blkif_be_destroy_t *d
   25.20  void blkif_connect(blkif_be_connect_t *connect);
   25.21  int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
   25.22  void blkif_disconnect_complete(blkif_t *blkif);
   25.23 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
   25.24 +blkif_t *blkif_find(domid_t domid);
   25.25 +void free_blkif(blkif_t *blkif);
   25.26 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
   25.27 +
   25.28  #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
   25.29  #define blkif_put(_b)                             \
   25.30      do {                                          \
   25.31          if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   25.32 -            blkif_disconnect_complete(_b);        \
   25.33 +            free_blkif(_b);			  \
   25.34      } while (0)
   25.35  
   25.36 -void vbd_create(blkif_be_vbd_create_t *create); 
   25.37 +struct vbd;
   25.38 +void vbd_free(blkif_t *blkif, struct vbd *vbd);
   25.39 +
   25.40 +/* Creates inactive vbd. */
   25.41 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly);
   25.42 +int vbd_is_active(struct vbd *vbd);
   25.43 +void vbd_activate(blkif_t *blkif, struct vbd *vbd);
   25.44 +
   25.45 +unsigned long vbd_size(struct vbd *vbd);
   25.46 +unsigned int vbd_info(struct vbd *vbd);
   25.47 +unsigned long vbd_secsize(struct vbd *vbd);
   25.48  void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
   25.49 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
   25.50  void destroy_all_vbds(blkif_t *blkif);
   25.51  
   25.52  struct phys_req {
   25.53 @@ -104,10 +116,11 @@ struct phys_req {
   25.54  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
   25.55  
   25.56  void blkif_interface_init(void);
   25.57 -void blkif_ctrlif_init(void);
   25.58  
   25.59  void blkif_deschedule(blkif_t *blkif);
   25.60  
   25.61 +void blkif_xenbus_init(void);
   25.62 +
   25.63  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
   25.64  
   25.65  #endif /* __BLKIF__BACKEND__COMMON_H__ */
    26.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/control.c	Fri Aug 19 10:50:15 2005 +0000
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,61 +0,0 @@
    26.4 -/******************************************************************************
    26.5 - * arch/xen/drivers/blkif/backend/control.c
    26.6 - * 
    26.7 - * Routines for interfacing with the control plane.
    26.8 - * 
    26.9 - * Copyright (c) 2004, Keir Fraser
   26.10 - */
   26.11 -
   26.12 -#include "common.h"
   26.13 -
   26.14 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
   26.15 -{
   26.16 -    DPRINTK("Received blkif backend message, subtype=%d\n", msg->subtype);
   26.17 -    
   26.18 -    switch ( msg->subtype )
   26.19 -    {
   26.20 -    case CMSG_BLKIF_BE_CREATE:
   26.21 -        blkif_create((blkif_be_create_t *)&msg->msg[0]);
   26.22 -        break;        
   26.23 -    case CMSG_BLKIF_BE_DESTROY:
   26.24 -        blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
   26.25 -        break;        
   26.26 -    case CMSG_BLKIF_BE_CONNECT:
   26.27 -        blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
   26.28 -        break;        
   26.29 -    case CMSG_BLKIF_BE_DISCONNECT:
   26.30 -        if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
   26.31 -            return; /* Sending the response is deferred until later. */
   26.32 -        break;        
   26.33 -    case CMSG_BLKIF_BE_VBD_CREATE:
   26.34 -        vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
   26.35 -        break;
   26.36 -    case CMSG_BLKIF_BE_VBD_DESTROY:
   26.37 -        vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
   26.38 -        break;
   26.39 -    default:
   26.40 -        DPRINTK("Parse error while reading message subtype %d, len %d\n",
   26.41 -                msg->subtype, msg->length);
   26.42 -        msg->length = 0;
   26.43 -        break;
   26.44 -    }
   26.45 -
   26.46 -    ctrl_if_send_response(msg);
   26.47 -}
   26.48 -
   26.49 -void blkif_ctrlif_init(void)
   26.50 -{
   26.51 -    ctrl_msg_t cmsg;
   26.52 -    blkif_be_driver_status_t st;
   26.53 -
   26.54 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
   26.55 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
   26.56 -
   26.57 -    /* Send a driver-UP notification to the domain controller. */
   26.58 -    cmsg.type      = CMSG_BLKIF_BE;
   26.59 -    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS;
   26.60 -    cmsg.length    = sizeof(blkif_be_driver_status_t);
   26.61 -    st.status      = BLKIF_DRIVER_STATUS_UP;
   26.62 -    memcpy(cmsg.msg, &st, sizeof(st));
   26.63 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   26.64 -}
    27.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 10:50:15 2005 +0000
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 13:08:50 2005 +0000
    27.3 @@ -7,24 +7,135 @@
    27.4   */
    27.5  
    27.6  #include "common.h"
    27.7 +#include <asm-xen/ctrl_if.h>
    27.8 +#include <asm-xen/evtchn.h>
    27.9  
   27.10  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   27.11  #define VMALLOC_VMADDR(x) ((unsigned long)(x))
   27.12  #endif
   27.13  
   27.14  #define BLKIF_HASHSZ 1024
   27.15 -#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
   27.16 +#define BLKIF_HASH(_d) (((int)(_d))&(BLKIF_HASHSZ-1))
   27.17  
   27.18  static kmem_cache_t *blkif_cachep;
   27.19  static blkif_t      *blkif_hash[BLKIF_HASHSZ];
   27.20  
   27.21 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
   27.22 +blkif_t *blkif_find(domid_t domid)
   27.23 +{
   27.24 +    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid)];
   27.25 +
   27.26 +    while (blkif) {
   27.27 +	if (blkif->domid == domid) {
   27.28 +	    blkif_get(blkif);
   27.29 +	    return blkif;
   27.30 +	}
   27.31 +        blkif = blkif->hash_next;
   27.32 +    }
   27.33 +
   27.34 +    blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
   27.35 +    if (!blkif)
   27.36 +	    return ERR_PTR(-ENOMEM);
   27.37 +
   27.38 +    memset(blkif, 0, sizeof(*blkif));
   27.39 +    blkif->domid = domid;
   27.40 +    blkif->status = DISCONNECTED;
   27.41 +    spin_lock_init(&blkif->vbd_lock);
   27.42 +    spin_lock_init(&blkif->blk_ring_lock);
   27.43 +    atomic_set(&blkif->refcnt, 1);
   27.44 +
   27.45 +    blkif->hash_next = blkif_hash[BLKIF_HASH(domid)];
   27.46 +    blkif_hash[BLKIF_HASH(domid)] = blkif;
   27.47 +    return blkif;
   27.48 +}
   27.49 +
   27.50 +#ifndef CONFIG_XEN_BLKDEV_GRANT
   27.51 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
   27.52 +			     unsigned long shared_page)
   27.53 +{
   27.54 +    return direct_remap_area_pages(&init_mm, localaddr,
   27.55 +				   shared_page<<PAGE_SHIFT, PAGE_SIZE,
   27.56 +				   __pgprot(_KERNPG_TABLE), blkif->domid);
   27.57 +}
   27.58 +
   27.59 +static void unmap_frontend_page(blkif_t *blkif)
   27.60 +{
   27.61 +}
   27.62 +#else
   27.63 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
   27.64 +			     unsigned long shared_page)
   27.65  {
   27.66 -    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
   27.67 -    while ( (blkif != NULL) && 
   27.68 -            ((blkif->domid != domid) || (blkif->handle != handle)) )
   27.69 -        blkif = blkif->hash_next;
   27.70 -    return blkif;
   27.71 +    struct gnttab_map_grant_ref op;
   27.72 +    op.host_addr = localaddr;
   27.73 +    op.flags = GNTMAP_host_map;
   27.74 +    op.ref = shared_page;
   27.75 +    op.dom = blkif->domid;
   27.76 +       
   27.77 +    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   27.78 +
   27.79 +    if (op.handle < 0) {
   27.80 +	DPRINTK(" Grant table operation failure !\n");
   27.81 +	return op.handle;
   27.82 +    }
   27.83 +
   27.84 +    blkif->shmem_ref = shared_page;
   27.85 +    blkif->shmem_handle = op.handle;
   27.86 +    blkif->shmem_vaddr = localaddr;
   27.87 +    return 0;
   27.88 +}
   27.89 +
   27.90 +static void unmap_frontend_page(blkif_t *blkif)
   27.91 +{
   27.92 +    struct gnttab_unmap_grant_ref op;
   27.93 +
   27.94 +    op.host_addr = blkif->shmem_vaddr;
   27.95 +    op.handle = blkif->shmem_handle;
   27.96 +    op.dev_bus_addr = 0;
   27.97 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   27.98 +}
   27.99 +#endif /* CONFIG_XEN_BLKDEV_GRANT */
  27.100 +
  27.101 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
  27.102 +{
  27.103 +    struct vm_struct *vma;
  27.104 +    blkif_sring_t *sring;
  27.105 +    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
  27.106 +    int err;
  27.107 +
  27.108 +    BUG_ON(blkif->remote_evtchn);
  27.109 +
  27.110 +    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
  27.111 +	return -ENOMEM;
  27.112 +
  27.113 +    err = map_frontend_page(blkif, VMALLOC_VMADDR(vma->addr), shared_page);
  27.114 +    if (err) {
  27.115 +        vfree(vma->addr);
  27.116 +	return err;
  27.117 +    }
  27.118 +
  27.119 +    op.u.bind_interdomain.dom1 = DOMID_SELF;
  27.120 +    op.u.bind_interdomain.dom2 = blkif->domid;
  27.121 +    op.u.bind_interdomain.port1 = 0;
  27.122 +    op.u.bind_interdomain.port2 = evtchn;
  27.123 +    err = HYPERVISOR_event_channel_op(&op);
  27.124 +    if (err) {
  27.125 +	unmap_frontend_page(blkif);
  27.126 +	vfree(vma->addr);
  27.127 +	return err;
  27.128 +    }
  27.129 +
  27.130 +    blkif->evtchn = op.u.bind_interdomain.port1;
  27.131 +    blkif->remote_evtchn = evtchn;
  27.132 +
  27.133 +    sring = (blkif_sring_t *)vma->addr;
  27.134 +    SHARED_RING_INIT(sring);
  27.135 +    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
  27.136 +
  27.137 +    bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
  27.138 +			      blkif);
  27.139 +    blkif->status        = CONNECTED;
  27.140 +    blkif->shmem_frame   = shared_page;
  27.141 +
  27.142 +    return 0;
  27.143  }
  27.144  
  27.145  static void __blkif_disconnect_complete(void *arg)
  27.146 @@ -32,21 +143,13 @@ static void __blkif_disconnect_complete(
  27.147      blkif_t              *blkif = (blkif_t *)arg;
  27.148      ctrl_msg_t            cmsg;
  27.149      blkif_be_disconnect_t disc;
  27.150 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  27.151 -    struct gnttab_unmap_grant_ref op;
  27.152 -#endif
  27.153  
  27.154      /*
  27.155       * These can't be done in blkif_disconnect() because at that point there
  27.156       * may be outstanding requests at the disc whose asynchronous responses
  27.157       * must still be notified to the remote driver.
  27.158       */
  27.159 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  27.160 -    op.host_addr      = blkif->shmem_vaddr;
  27.161 -    op.handle         = blkif->shmem_handle;
  27.162 -    op.dev_bus_addr   = 0;
  27.163 -    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
  27.164 -#endif
  27.165 +    unmap_frontend_page(blkif);
  27.166      vfree(blkif->blk_ring.sring);
  27.167  
  27.168      /* Construct the deferred response message. */
  27.169 @@ -81,200 +184,33 @@ void blkif_disconnect_complete(blkif_t *
  27.170      schedule_work(&blkif->work);
  27.171  }
  27.172  
  27.173 -void blkif_create(blkif_be_create_t *create)
  27.174 +void free_blkif(blkif_t *blkif)
  27.175  {
  27.176 -    domid_t       domid  = create->domid;
  27.177 -    unsigned int  handle = create->blkif_handle;
  27.178 -    blkif_t     **pblkif, *blkif;
  27.179 -
  27.180 -    if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL )
  27.181 -    {
  27.182 -        DPRINTK("Could not create blkif: out of memory\n");
  27.183 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
  27.184 -        return;
  27.185 -    }
  27.186 +    blkif_t     **pblkif;
  27.187 +    evtchn_op_t op = { .cmd = EVTCHNOP_close };
  27.188  
  27.189 -    memset(blkif, 0, sizeof(*blkif));
  27.190 -    blkif->domid  = domid;
  27.191 -    blkif->handle = handle;
  27.192 -    blkif->status = DISCONNECTED;
  27.193 -    spin_lock_init(&blkif->vbd_lock);
  27.194 -    spin_lock_init(&blkif->blk_ring_lock);
  27.195 -    atomic_set(&blkif->refcnt, 0);
  27.196 +    op.u.close.port = blkif->evtchn;
  27.197 +    op.u.close.dom = DOMID_SELF;
  27.198 +    HYPERVISOR_event_channel_op(&op);
  27.199 +    op.u.close.port = blkif->remote_evtchn;
  27.200 +    op.u.close.dom = blkif->domid;
  27.201 +    HYPERVISOR_event_channel_op(&op);
  27.202  
  27.203 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
  27.204 -    while ( *pblkif != NULL )
  27.205 +    if (blkif->evtchn)
  27.206 +        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
  27.207 +
  27.208 +    if (blkif->blk_ring.sring)
  27.209 +	    vfree(blkif->blk_ring.sring);
  27.210 +
  27.211 +    pblkif = &blkif_hash[BLKIF_HASH(blkif->domid)];
  27.212 +    while ( *pblkif != blkif )
  27.213      {
  27.214 -        if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
  27.215 -        {
  27.216 -            DPRINTK("Could not create blkif: already exists\n");
  27.217 -            create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
  27.218 -            kmem_cache_free(blkif_cachep, blkif);
  27.219 -            return;
  27.220 -        }
  27.221 +	BUG_ON(!*pblkif);
  27.222          pblkif = &(*pblkif)->hash_next;
  27.223      }
  27.224 -
  27.225 -    blkif->hash_next = *pblkif;
  27.226 -    *pblkif = blkif;
  27.227 -
  27.228 -    DPRINTK("Successfully created blkif\n");
  27.229 -    create->status = BLKIF_BE_STATUS_OKAY;
  27.230 -}
  27.231 -
  27.232 -void blkif_destroy(blkif_be_destroy_t *destroy)
  27.233 -{
  27.234 -    domid_t       domid  = destroy->domid;
  27.235 -    unsigned int  handle = destroy->blkif_handle;
  27.236 -    blkif_t     **pblkif, *blkif;
  27.237 -
  27.238 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
  27.239 -    while ( (blkif = *pblkif) != NULL )
  27.240 -    {
  27.241 -        if ( (blkif->domid == domid) && (blkif->handle == handle) )
  27.242 -        {
  27.243 -            if ( blkif->status != DISCONNECTED )
  27.244 -                goto still_connected;
  27.245 -            goto destroy;
  27.246 -        }
  27.247 -        pblkif = &blkif->hash_next;
  27.248 -    }
  27.249 -
  27.250 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
  27.251 -    return;
  27.252 -
  27.253 - still_connected:
  27.254 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
  27.255 -    return;
  27.256 -
  27.257 - destroy:
  27.258      *pblkif = blkif->hash_next;
  27.259      destroy_all_vbds(blkif);
  27.260      kmem_cache_free(blkif_cachep, blkif);
  27.261 -    destroy->status = BLKIF_BE_STATUS_OKAY;
  27.262 -}
  27.263 -
  27.264 -void blkif_connect(blkif_be_connect_t *connect)
  27.265 -{
  27.266 -    domid_t        domid  = connect->domid;
  27.267 -    unsigned int   handle = connect->blkif_handle;
  27.268 -    unsigned int   evtchn = connect->evtchn;
  27.269 -    unsigned long  shmem_frame = connect->shmem_frame;
  27.270 -    struct vm_struct *vma;
  27.271 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  27.272 -    int ref = connect->shmem_ref;
  27.273 -#else
  27.274 -    pgprot_t       prot;
  27.275 -    int            error;
  27.276 -#endif
  27.277 -    blkif_t       *blkif;
  27.278 -    blkif_sring_t *sring;
  27.279 -
  27.280 -    blkif = blkif_find_by_handle(domid, handle);
  27.281 -    if ( unlikely(blkif == NULL) )
  27.282 -    {
  27.283 -        DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", 
  27.284 -                connect->domid, connect->blkif_handle); 
  27.285 -        connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
  27.286 -        return;
  27.287 -    }
  27.288 -
  27.289 -    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
  27.290 -    {
  27.291 -        connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
  27.292 -        return;
  27.293 -    }
  27.294 -
  27.295 -#ifndef CONFIG_XEN_BLKDEV_GRANT
  27.296 -    prot = __pgprot(_KERNPG_TABLE);
  27.297 -    error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr),
  27.298 -                                    shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
  27.299 -                                    prot, domid);
  27.300 -    if ( error != 0 )
  27.301 -    {
  27.302 -        if ( error == -ENOMEM )
  27.303 -            connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
  27.304 -        else if ( error == -EFAULT )
  27.305 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
  27.306 -        else
  27.307 -            connect->status = BLKIF_BE_STATUS_ERROR;
  27.308 -        vfree(vma->addr);
  27.309 -        return;
  27.310 -    }
  27.311 -#else
  27.312 -    { /* Map: Use the Grant table reference */
  27.313 -        struct gnttab_map_grant_ref op;
  27.314 -        op.host_addr      = VMALLOC_VMADDR(vma->addr);
  27.315 -        op.flags          = GNTMAP_host_map;
  27.316 -        op.ref            = ref;
  27.317 -        op.dom            = domid;
  27.318 -       
  27.319 -        BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
  27.320 -       
  27.321 -        handle = op.handle;
  27.322 -       
  27.323 -        if (op.handle < 0) {
  27.324 -            DPRINTK(" Grant table operation failure !\n");
  27.325 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
  27.326 -            vfree(vma->addr);
  27.327 -            return;
  27.328 -        }
  27.329 -
  27.330 -        blkif->shmem_ref = ref;
  27.331 -        blkif->shmem_handle = handle;
  27.332 -        blkif->shmem_vaddr = VMALLOC_VMADDR(vma->addr);
  27.333 -    }
  27.334 -#endif
  27.335 -
  27.336 -    if ( blkif->status != DISCONNECTED )
  27.337 -    {
  27.338 -        connect->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
  27.339 -        vfree(vma->addr);
  27.340 -        return;
  27.341 -    }
  27.342 -    sring = (blkif_sring_t *)vma->addr;
  27.343 -    SHARED_RING_INIT(sring);
  27.344 -    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
  27.345 -    
  27.346 -    blkif->evtchn        = evtchn;
  27.347 -    blkif->shmem_frame   = shmem_frame;
  27.348 -    blkif->status        = CONNECTED;
  27.349 -    blkif_get(blkif);
  27.350 -
  27.351 -    bind_evtchn_to_irqhandler(
  27.352 -        blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
  27.353 -
  27.354 -    connect->status = BLKIF_BE_STATUS_OKAY;
  27.355 -}
  27.356 -
  27.357 -int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id)
  27.358 -{
  27.359 -    domid_t       domid  = disconnect->domid;
  27.360 -    unsigned int  handle = disconnect->blkif_handle;
  27.361 -    blkif_t      *blkif;
  27.362 -
  27.363 -    blkif = blkif_find_by_handle(domid, handle);
  27.364 -    if ( unlikely(blkif == NULL) )
  27.365 -    {
  27.366 -        DPRINTK("blkif_disconnect attempted for non-existent blkif"
  27.367 -                " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); 
  27.368 -        disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
  27.369 -        return 1; /* Caller will send response error message. */
  27.370 -    }
  27.371 -
  27.372 -    if ( blkif->status == CONNECTED )
  27.373 -    {
  27.374 -        blkif->status = DISCONNECTING;
  27.375 -        blkif->disconnect_rspid = rsp_id;
  27.376 -        wmb(); /* Let other CPUs see the status change. */
  27.377 -        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
  27.378 -        blkif_deschedule(blkif);
  27.379 -        blkif_put(blkif);
  27.380 -        return 0; /* Caller should not send response message. */
  27.381 -    }
  27.382 -
  27.383 -    disconnect->status = BLKIF_BE_STATUS_OKAY;
  27.384 -    return 1;
  27.385  }
  27.386  
  27.387  void __init blkif_interface_init(void)
    28.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 10:50:15 2005 +0000
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 13:08:50 2005 +0000
    28.3 @@ -11,13 +11,16 @@
    28.4   */
    28.5  
    28.6  #include "common.h"
    28.7 +#include <asm-xen/xenbus.h>
    28.8  
    28.9  struct vbd { 
   28.10 -    blkif_vdev_t   vdevice;     /* what the domain refers to this vbd as */
   28.11 +    blkif_vdev_t   handle;     /* what the domain refers to this vbd as */
   28.12      unsigned char  readonly;    /* Non-zero -> read-only */
   28.13      unsigned char  type;        /* VDISK_xxx */
   28.14      blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
   28.15      struct block_device *bdev;
   28.16 +
   28.17 +    int active;
   28.18      rb_node_t      rb;          /* for linking into R-B tree lookup struct */
   28.19  }; 
   28.20  
   28.21 @@ -33,57 +36,45 @@ static inline dev_t vbd_map_devnum(blkif
   28.22  #define bdev_hardsect_size(_b) 512
   28.23  #endif
   28.24  
   28.25 -void vbd_create(blkif_be_vbd_create_t *create) 
   28.26 +unsigned long vbd_size(struct vbd *vbd)
   28.27 +{
   28.28 +	return vbd_sz(vbd);
   28.29 +}
   28.30 +
   28.31 +unsigned int vbd_info(struct vbd *vbd)
   28.32 +{
   28.33 +	return vbd->type | (vbd->readonly?VDISK_READONLY:0);
   28.34 +}
   28.35 +
   28.36 +unsigned long vbd_secsize(struct vbd *vbd)
   28.37 +{
   28.38 +	return bdev_hardsect_size(vbd->bdev);
   28.39 +}
   28.40 +
   28.41 +int vbd_is_active(struct vbd *vbd)
   28.42 +{
   28.43 +	return vbd->active;
   28.44 +}
   28.45 +
   28.46 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
   28.47 +		       blkif_pdev_t pdevice, int readonly)
   28.48  {
   28.49      struct vbd  *vbd; 
   28.50 -    rb_node_t  **rb_p, *rb_parent = NULL;
   28.51 -    blkif_t     *blkif;
   28.52 -    blkif_vdev_t vdevice = create->vdevice;
   28.53 -
   28.54 -    blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
   28.55 -    if ( unlikely(blkif == NULL) )
   28.56 -    {
   28.57 -        DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
   28.58 -                create->domid, create->blkif_handle); 
   28.59 -        create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   28.60 -        return;
   28.61 -    }
   28.62 -
   28.63 -    rb_p = &blkif->vbd_rb.rb_node;
   28.64 -    while ( *rb_p != NULL )
   28.65 -    {
   28.66 -        rb_parent = *rb_p;
   28.67 -        vbd = rb_entry(rb_parent, struct vbd, rb);
   28.68 -        if ( vdevice < vbd->vdevice )
   28.69 -        {
   28.70 -            rb_p = &rb_parent->rb_left;
   28.71 -        }
   28.72 -        else if ( vdevice > vbd->vdevice )
   28.73 -        {
   28.74 -            rb_p = &rb_parent->rb_right;
   28.75 -        }
   28.76 -        else
   28.77 -        {
   28.78 -            DPRINTK("vbd_create attempted for already existing vbd\n");
   28.79 -            create->status = BLKIF_BE_STATUS_VBD_EXISTS;
   28.80 -            return;
   28.81 -        }
   28.82 -    }
   28.83  
   28.84      if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
   28.85      {
   28.86          DPRINTK("vbd_create: out of memory\n");
   28.87 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   28.88 -        return;
   28.89 +	return ERR_PTR(-ENOMEM);
   28.90      }
   28.91  
   28.92 -    vbd->vdevice  = vdevice; 
   28.93 -    vbd->readonly = create->readonly;
   28.94 +    vbd->handle   = handle; 
   28.95 +    vbd->readonly = readonly;
   28.96      vbd->type     = 0;
   28.97 +    vbd->active   = 0;
   28.98  
   28.99 -    /* Mask to 16-bit for compatibility with old tools */
  28.100 -    vbd->pdevice  = create->pdevice & 0xffff;
  28.101 +    vbd->pdevice  = pdevice;
  28.102  
  28.103 +    /* FIXME: Who frees vbd on failure? --RR */
  28.104  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  28.105      vbd->bdev = open_by_devnum(
  28.106          vbd_map_devnum(vbd->pdevice),
  28.107 @@ -91,16 +82,14 @@ void vbd_create(blkif_be_vbd_create_t *c
  28.108      if ( IS_ERR(vbd->bdev) )
  28.109      {
  28.110          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
  28.111 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
  28.112 -        return;
  28.113 +        return ERR_PTR(-ENOENT);
  28.114      }
  28.115  
  28.116      if ( (vbd->bdev->bd_disk == NULL) )
  28.117      {
  28.118          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
  28.119 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
  28.120          bdev_put(vbd->bdev);
  28.121 -        return;
  28.122 +        return ERR_PTR(-ENOENT);
  28.123      }
  28.124  
  28.125      if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
  28.126 @@ -112,62 +101,64 @@ void vbd_create(blkif_be_vbd_create_t *c
  28.127      if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
  28.128      {
  28.129          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
  28.130 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
  28.131 -        return;
  28.132 +        return ERR_PTR(-ENOENT);
  28.133      }
  28.134  #endif
  28.135  
  28.136 +    DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
  28.137 +            handle, blkif->domid);
  28.138 +    return vbd;
  28.139 +}
  28.140 +
  28.141 +void vbd_activate(blkif_t *blkif, struct vbd *vbd)
  28.142 +{
  28.143 +    rb_node_t  **rb_p, *rb_parent = NULL;
  28.144 +    struct vbd *i;
  28.145 +    BUG_ON(vbd_is_active(vbd));
  28.146 +
  28.147 +    /* Find where to put it. */
  28.148 +    rb_p = &blkif->vbd_rb.rb_node;
  28.149 +    while ( *rb_p != NULL )
  28.150 +    {
  28.151 +        rb_parent = *rb_p;
  28.152 +        i = rb_entry(rb_parent, struct vbd, rb);
  28.153 +        if ( vbd->handle < i->handle )
  28.154 +        {
  28.155 +            rb_p = &rb_parent->rb_left;
  28.156 +        }
  28.157 +        else if ( vbd->handle > i->handle )
  28.158 +        {
  28.159 +            rb_p = &rb_parent->rb_right;
  28.160 +        }
  28.161 +        else
  28.162 +        {
  28.163 +	    /* We never create two of same vbd, so not possible. */
  28.164 +	    BUG();
  28.165 +        }
  28.166 +    }
  28.167 +
  28.168 +    /* Now we're active. */
  28.169 +    vbd->active = 1;
  28.170 +    blkif_get(blkif);
  28.171 +
  28.172      spin_lock(&blkif->vbd_lock);
  28.173      rb_link_node(&vbd->rb, rb_parent, rb_p);
  28.174      rb_insert_color(&vbd->rb, &blkif->vbd_rb);
  28.175      spin_unlock(&blkif->vbd_lock);
  28.176 -
  28.177 -    DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
  28.178 -            vdevice, create->domid);
  28.179 -    create->status = BLKIF_BE_STATUS_OKAY;
  28.180  }
  28.181  
  28.182 -
  28.183 -void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
  28.184 +void vbd_free(blkif_t *blkif, struct vbd *vbd)
  28.185  {
  28.186 -    blkif_t           *blkif;
  28.187 -    struct vbd        *vbd;
  28.188 -    rb_node_t         *rb;
  28.189 -    blkif_vdev_t       vdevice = destroy->vdevice;
  28.190 -
  28.191 -    blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
  28.192 -    if ( unlikely(blkif == NULL) )
  28.193 -    {
  28.194 -        DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
  28.195 -                destroy->domid, destroy->blkif_handle); 
  28.196 -        destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
  28.197 -        return;
  28.198 +    if (vbd_is_active(vbd)) {
  28.199 +	spin_lock(&blkif->vbd_lock);
  28.200 +	rb_erase(&vbd->rb, &blkif->vbd_rb);
  28.201 +	spin_unlock(&blkif->vbd_lock);
  28.202 +	blkif_put(blkif);
  28.203      }
  28.204 -
  28.205 -    rb = blkif->vbd_rb.rb_node;
  28.206 -    while ( rb != NULL )
  28.207 -    {
  28.208 -        vbd = rb_entry(rb, struct vbd, rb);
  28.209 -        if ( vdevice < vbd->vdevice )
  28.210 -            rb = rb->rb_left;
  28.211 -        else if ( vdevice > vbd->vdevice )
  28.212 -            rb = rb->rb_right;
  28.213 -        else
  28.214 -            goto found;
  28.215 -    }
  28.216 -
  28.217 -    destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
  28.218 -    return;
  28.219 -
  28.220 - found:
  28.221 -    spin_lock(&blkif->vbd_lock);
  28.222 -    rb_erase(rb, &blkif->vbd_rb);
  28.223 -    spin_unlock(&blkif->vbd_lock);
  28.224      bdev_put(vbd->bdev);
  28.225      kfree(vbd);
  28.226  }
  28.227  
  28.228 -
  28.229  void destroy_all_vbds(blkif_t *blkif)
  28.230  {
  28.231      struct vbd *vbd;
  28.232 @@ -183,74 +174,12 @@ void destroy_all_vbds(blkif_t *blkif)
  28.233          bdev_put(vbd->bdev);
  28.234          kfree(vbd);
  28.235          spin_lock(&blkif->vbd_lock);
  28.236 +        blkif_put(blkif);
  28.237      }
  28.238  
  28.239      spin_unlock(&blkif->vbd_lock);
  28.240  }
  28.241  
  28.242 -
  28.243 -static void vbd_probe_single(
  28.244 -    blkif_t *blkif, vdisk_t *vbd_info, struct vbd *vbd)
  28.245 -{
  28.246 -    vbd_info->device      = vbd->vdevice; 
  28.247 -    vbd_info->info        = vbd->type | (vbd->readonly ? VDISK_READONLY : 0);
  28.248 -    vbd_info->capacity    = vbd_sz(vbd);
  28.249 -    vbd_info->sector_size = bdev_hardsect_size(vbd->bdev);
  28.250 -}
  28.251 -
  28.252 -
  28.253 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
  28.254 -{
  28.255 -    int        rc = 0, nr_vbds = 0;
  28.256 -    rb_node_t *rb;
  28.257 -
  28.258 -    spin_lock(&blkif->vbd_lock);
  28.259 -
  28.260 -    if ( (rb = blkif->vbd_rb.rb_node) == NULL )
  28.261 -        goto out;
  28.262 -
  28.263 - new_subtree:
  28.264 -    /* STEP 1. Find least node (it'll be left-most). */
  28.265 -    while ( rb->rb_left != NULL )
  28.266 -        rb = rb->rb_left;
  28.267 -
  28.268 -    for ( ; ; )
  28.269 -    {
  28.270 -        /* STEP 2. Dealt with left subtree. Now process current node. */
  28.271 -        vbd_probe_single(blkif, &vbd_info[nr_vbds],
  28.272 -                         rb_entry(rb, struct vbd, rb));
  28.273 -        if ( ++nr_vbds == max_vbds )
  28.274 -            goto out;
  28.275 -
  28.276 -        /* STEP 3. Process right subtree, if any. */
  28.277 -        if ( rb->rb_right != NULL )
  28.278 -        {
  28.279 -            rb = rb->rb_right;
  28.280 -            goto new_subtree;
  28.281 -        }
  28.282 -
  28.283 -        /* STEP 4. Done both subtrees. Head back through ancesstors. */
  28.284 -        for ( ; ; ) 
  28.285 -        {
  28.286 -            /* We're done when we get back to the root node. */
  28.287 -            if ( rb->rb_parent == NULL )
  28.288 -                goto out;
  28.289 -            /* If we are left of parent, then parent is next to process. */
  28.290 -            if ( rb->rb_parent->rb_left == rb )
  28.291 -                break;
  28.292 -            /* If we are right of parent, then we climb to grandparent. */
  28.293 -            rb = rb->rb_parent;
  28.294 -        }
  28.295 -
  28.296 -        rb = rb->rb_parent;
  28.297 -    }
  28.298 -
  28.299 - out:
  28.300 -    spin_unlock(&blkif->vbd_lock);
  28.301 -    return (rc == 0) ? nr_vbds : rc;  
  28.302 -}
  28.303 -
  28.304 -
  28.305  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
  28.306  {
  28.307      struct vbd *vbd;
  28.308 @@ -264,9 +193,9 @@ int vbd_translate(struct phys_req *req, 
  28.309      while ( rb != NULL )
  28.310      {
  28.311          vbd = rb_entry(rb, struct vbd, rb);
  28.312 -        if ( req->dev < vbd->vdevice )
  28.313 +        if ( req->dev < vbd->handle )
  28.314              rb = rb->rb_left;
  28.315 -        else if ( req->dev > vbd->vdevice )
  28.316 +        else if ( req->dev > vbd->handle )
  28.317              rb = rb->rb_right;
  28.318          else
  28.319              goto found;
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Aug 19 13:08:50 2005 +0000
    29.3 @@ -0,0 +1,308 @@
    29.4 +/*  Xenbus code for blkif backend
    29.5 +    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
    29.6 +
    29.7 +    This program is free software; you can redistribute it and/or modify
    29.8 +    it under the terms of the GNU General Public License as published by
    29.9 +    the Free Software Foundation; either version 2 of the License, or
   29.10 +    (at your option) any later version.
   29.11 +
   29.12 +    This program is distributed in the hope that it will be useful,
   29.13 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.14 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.15 +    GNU General Public License for more details.
   29.16 +
   29.17 +    You should have received a copy of the GNU General Public License
   29.18 +    along with this program; if not, write to the Free Software
   29.19 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   29.20 +*/
   29.21 +#include <stdarg.h>
   29.22 +#include <linux/module.h>
   29.23 +#include <asm-xen/xenbus.h>
   29.24 +#include "common.h"
   29.25 +
   29.26 +struct backend_info
   29.27 +{
   29.28 +	struct xenbus_device *dev;
   29.29 +
   29.30 +	/* our communications channel */
   29.31 +	blkif_t *blkif;
   29.32 +	struct vbd *vbd;
   29.33 +
   29.34 +	long int frontend_id;
   29.35 +	long int pdev;
   29.36 +	long int readonly;
   29.37 +
   29.38 +	/* watch back end for changes */
   29.39 +	struct xenbus_watch backend_watch;
   29.40 +
   29.41 +	/* watch front end for changes */
   29.42 +	struct xenbus_watch watch;
   29.43 +	char *frontpath;
   29.44 +};
   29.45 +
   29.46 +static int blkback_remove(struct xenbus_device *dev)
   29.47 +{
   29.48 +	struct backend_info *be = dev->data;
   29.49 +
   29.50 +	if (be->watch.node)
   29.51 +		unregister_xenbus_watch(&be->watch);
   29.52 +	unregister_xenbus_watch(&be->backend_watch);
   29.53 +	if (be->vbd)
   29.54 +		vbd_free(be->blkif, be->vbd);
   29.55 +	if (be->blkif)
   29.56 +		blkif_put(be->blkif);
   29.57 +	if (be->frontpath)
   29.58 +		kfree(be->frontpath);
   29.59 +	kfree(be);
   29.60 +	return 0;
   29.61 +}
   29.62 +
   29.63 +/* Front end tells us frame. */
   29.64 +static void frontend_changed(struct xenbus_watch *watch, const char *node)
   29.65 +{
   29.66 +	unsigned long sharedmfn;
   29.67 +	unsigned int evtchn;
   29.68 +	int err;
   29.69 +	struct backend_info *be
   29.70 +		= container_of(watch, struct backend_info, watch);
   29.71 +
   29.72 +	/* If other end is gone, delete ourself. */
   29.73 +	if (!xenbus_exists(be->frontpath, "")) {
   29.74 +		xenbus_rm(be->dev->nodename, "");
   29.75 +		device_unregister(&be->dev->dev);
   29.76 +		return;
   29.77 +	}
   29.78 +	if (vbd_is_active(be->vbd))
   29.79 +		return;
   29.80 +
   29.81 +#ifndef CONFIG_XEN_BLKDEV_GRANT
   29.82 +	err = xenbus_gather(be->frontpath, "shared-frame", "%lu", &sharedmfn,
   29.83 +			    "event-channel", "%u", &evtchn, NULL);
   29.84 +	if (err) {
   29.85 +		xenbus_dev_error(be->dev, err, 
   29.86 +				 "reading %s/shared-frame and event-channel",
   29.87 +				 be->frontpath);
   29.88 +		return;
   29.89 +	}
   29.90 +#else
   29.91 +	err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
   29.92 +			    "event-channel", "%u", &evtchn, NULL);
   29.93 +	if (err) {
   29.94 +		xenbus_dev_error(be->dev, err, 
   29.95 +				 "reading %s/grant-id and event-channel",
   29.96 +				 be->frontpath);
   29.97 +		return;
   29.98 +	}
   29.99 +#endif
  29.100 +
  29.101 +	/* Domains must use same shared frame for all vbds. */
  29.102 +	if (be->blkif->status == CONNECTED &&
  29.103 +	    (evtchn != be->blkif->remote_evtchn ||
  29.104 +	     sharedmfn != be->blkif->shmem_frame)) {
  29.105 +		xenbus_dev_error(be->dev, err,
  29.106 +				 "Shared frame/evtchn %li/%u not same as"
  29.107 +				 " old %li/%u",
  29.108 +				 sharedmfn, evtchn,
  29.109 +				 be->blkif->shmem_frame,
  29.110 +				 be->blkif->remote_evtchn);
  29.111 +		return;
  29.112 +	}
  29.113 +
  29.114 +	/* Supply the information about the device the frontend needs */
  29.115 +	err = xenbus_transaction_start(be->dev->nodename);
  29.116 +	if (err) {
  29.117 +		xenbus_dev_error(be->dev, err, "starting transaction");
  29.118 +		return;
  29.119 +	}
  29.120 +
  29.121 +	err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
  29.122 +			    vbd_size(be->vbd));
  29.123 +	if (err) {
  29.124 +		xenbus_dev_error(be->dev, err, "writing %s/sectors",
  29.125 +				 be->dev->nodename);
  29.126 +		goto abort;
  29.127 +	}
  29.128 +
  29.129 +	/* FIXME: use a typename instead */
  29.130 +	err = xenbus_printf(be->dev->nodename, "info", "%u",
  29.131 +			    vbd_info(be->vbd));
  29.132 +	if (err) {
  29.133 +		xenbus_dev_error(be->dev, err, "writing %s/info",
  29.134 +				 be->dev->nodename);
  29.135 +		goto abort;
  29.136 +	}
  29.137 +	err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
  29.138 +			    vbd_secsize(be->vbd));
  29.139 +	if (err) {
  29.140 +		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
  29.141 +				 be->dev->nodename);
  29.142 +		goto abort;
  29.143 +	}
  29.144 +
  29.145 +	/* First vbd?  We need to map the shared frame, irq etc. */
  29.146 +	if (be->blkif->status != CONNECTED) {
  29.147 +		err = blkif_map(be->blkif, sharedmfn, evtchn);
  29.148 +		if (err) {
  29.149 +			xenbus_dev_error(be->dev, err,
  29.150 +					 "mapping shared-frame %lu port %u",
  29.151 +					 sharedmfn, evtchn);
  29.152 +			goto abort;
  29.153 +		}
  29.154 +	}
  29.155 +
  29.156 +	/* We're ready, activate. */
  29.157 +	vbd_activate(be->blkif, be->vbd);
  29.158 +
  29.159 +	xenbus_transaction_end(0);
  29.160 +	xenbus_dev_ok(be->dev);
  29.161 +
  29.162 +	return;
  29.163 +
  29.164 +abort:
  29.165 +	xenbus_transaction_end(1);
  29.166 +}
  29.167 +
  29.168 +/* 
  29.169 +   Setup supplies physical device.  
  29.170 +   We provide event channel and device details to front end.
  29.171 +   Frontend supplies shared frame and event channel.
  29.172 + */
  29.173 +static void backend_changed(struct xenbus_watch *watch, const char *node)
  29.174 +{
  29.175 +	int err;
  29.176 +	char *p;
  29.177 +	char *frontend;
  29.178 +	long int handle, pdev;
  29.179 +	struct backend_info *be
  29.180 +		= container_of(watch, struct backend_info, backend_watch);
  29.181 +	struct xenbus_device *dev = be->dev;
  29.182 +
  29.183 +	frontend = NULL;
  29.184 +	err = xenbus_gather(dev->nodename,
  29.185 +			    "frontend-id", "%li", &be->frontend_id,
  29.186 +			    "frontend", NULL, &frontend,
  29.187 +			    NULL);
  29.188 +	if (err == -ENOENT || err == -ERANGE ||
  29.189 +	    strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
  29.190 +		if (frontend)
  29.191 +			kfree(frontend);
  29.192 +		/* If we can't get a frontend path and a frontend-id,
  29.193 +		 * then our bus-id is no longer valid and we need to
  29.194 +		 * destroy the backend device.
  29.195 +		 */
  29.196 +		goto device_fail;
  29.197 +	}
  29.198 +
  29.199 +	if (!be->frontpath || strcmp(frontend, be->frontpath)) {
  29.200 +		if (be->watch.node)
  29.201 +			unregister_xenbus_watch(&be->watch);
  29.202 +		if (be->frontpath)
  29.203 +			kfree(be->frontpath);
  29.204 +		be->frontpath = frontend;
  29.205 +		be->watch.node = be->frontpath;
  29.206 +		be->watch.callback = frontend_changed;
  29.207 +		err = register_xenbus_watch(&be->watch);
  29.208 +		if (err) {
  29.209 +			be->watch.node = NULL;
  29.210 +			goto device_fail;
  29.211 +		}
  29.212 +	} else
  29.213 +		kfree(frontend);
  29.214 +
  29.215 +	err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
  29.216 +	if (err == -ENOENT || err == -ERANGE)
  29.217 +		goto out;
  29.218 +	if (err < 0) {
  29.219 +		xenbus_dev_error(dev, err, "Reading physical-device");
  29.220 +		goto device_fail;
  29.221 +	}
  29.222 +	if (be->pdev && be->pdev != pdev) {
  29.223 +		printk(KERN_WARNING
  29.224 +		       "changing physical-device not supported\n");
  29.225 +		goto device_fail;
  29.226 +	}
  29.227 +	be->pdev = pdev;
  29.228 +
  29.229 +	/* If there's a read-only node, we're read only. */
  29.230 +	p = xenbus_read(dev->nodename, "read-only", NULL);
  29.231 +	if (!IS_ERR(p)) {
  29.232 +		be->readonly = 1;
  29.233 +		kfree(p);
  29.234 +	}
  29.235 +
  29.236 +	if (be->blkif == NULL) {
  29.237 +		/* Front end dir is a number, which is used as the handle. */
  29.238 +		p = strrchr(be->frontpath, '/') + 1;
  29.239 +		handle = simple_strtoul(p, NULL, 0);
  29.240 +
  29.241 +		be->blkif = blkif_find(be->frontend_id);
  29.242 +		if (IS_ERR(be->blkif)) {
  29.243 +			err = PTR_ERR(be->blkif);
  29.244 +			be->blkif = NULL;
  29.245 +			goto device_fail;
  29.246 +		}
  29.247 +
  29.248 +		be->vbd = vbd_create(be->blkif, handle, be->pdev,
  29.249 +				     be->readonly);
  29.250 +		if (IS_ERR(be->vbd)) {
  29.251 +			err = PTR_ERR(be->vbd);
  29.252 +			be->vbd = NULL;
  29.253 +			goto device_fail;
  29.254 +		}
  29.255 +
  29.256 +		frontend_changed(&be->watch, be->frontpath);
  29.257 +	}
  29.258 +
  29.259 +	return;
  29.260 +
  29.261 + device_fail:
  29.262 +	device_unregister(&be->dev->dev);
  29.263 + out:
  29.264 +	return;
  29.265 +}
  29.266 +
  29.267 +static int blkback_probe(struct xenbus_device *dev,
  29.268 +			 const struct xenbus_device_id *id)
  29.269 +{
  29.270 +	struct backend_info *be;
  29.271 +	int err;
  29.272 +
  29.273 +	be = kmalloc(sizeof(*be), GFP_KERNEL);
  29.274 +	if (!be)
  29.275 +		return -ENOMEM;
  29.276 +
  29.277 +	memset(be, 0, sizeof(*be));
  29.278 +
  29.279 +	be->dev = dev;
  29.280 +	be->backend_watch.node = dev->nodename;
  29.281 +	be->backend_watch.callback = backend_changed;
  29.282 +	err = register_xenbus_watch(&be->backend_watch);
  29.283 +	if (err)
  29.284 +		goto free_be;
  29.285 +
  29.286 +	dev->data = be;
  29.287 +
  29.288 +	backend_changed(&be->backend_watch, dev->nodename);
  29.289 +	return err;
  29.290 + free_be:
  29.291 +	kfree(be);
  29.292 +	return err;
  29.293 +}
  29.294 +
  29.295 +static struct xenbus_device_id blkback_ids[] = {
  29.296 +	{ "vbd" },
  29.297 +	{ "" }
  29.298 +};
  29.299 +
  29.300 +static struct xenbus_driver blkback = {
  29.301 +	.name = "vbd",
  29.302 +	.owner = THIS_MODULE,
  29.303 +	.ids = blkback_ids,
  29.304 +	.probe = blkback_probe,
  29.305 +	.remove = blkback_remove,
  29.306 +};
  29.307 +
  29.308 +void blkif_xenbus_init(void)
  29.309 +{
  29.310 +	xenbus_register_backend(&blkback);
  29.311 +}
    30.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 10:50:15 2005 +0000
    30.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 13:08:50 2005 +0000
    30.3 @@ -53,8 +53,8 @@
    30.4  #include <linux/sched.h>
    30.5  #include <linux/interrupt.h>
    30.6  #include <scsi/scsi.h>
    30.7 -#include <asm-xen/ctrl_if.h>
    30.8  #include <asm-xen/evtchn.h>
    30.9 +#include <asm-xen/xenbus.h>
   30.10  #ifdef CONFIG_XEN_BLKDEV_GRANT
   30.11  #include <asm-xen/xen-public/grant_table.h>
   30.12  #include <asm-xen/gnttab.h>
   30.13 @@ -65,22 +65,14 @@ typedef unsigned char byte; /* from linu
   30.14  /* Control whether runtime update of vbds is enabled. */
   30.15  #define ENABLE_VBD_UPDATE 1
   30.16  
   30.17 -#if ENABLE_VBD_UPDATE
   30.18 -static void vbd_update(void);
   30.19 -#else
   30.20 -static void vbd_update(void){};
   30.21 -#endif
   30.22 -
   30.23  #define BLKIF_STATE_CLOSED       0
   30.24  #define BLKIF_STATE_DISCONNECTED 1
   30.25  #define BLKIF_STATE_CONNECTED    2
   30.26  
   30.27 -static int blkif_handle = 0;
   30.28  static unsigned int blkif_state = BLKIF_STATE_CLOSED;
   30.29  static unsigned int blkif_evtchn = 0;
   30.30 -
   30.31 -static int blkif_control_rsp_valid;
   30.32 -static blkif_response_t blkif_control_rsp;
   30.33 +static unsigned int blkif_vbds = 0;
   30.34 +static unsigned int blkif_vbds_connected = 0;
   30.35  
   30.36  static blkif_front_ring_t blk_ring;
   30.37  
   30.38 @@ -92,6 +84,7 @@ static grant_ref_t gref_head, gref_termi
   30.39  #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
   30.40      (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
   30.41  #define GRANTREF_INVALID (1<<15)
   30.42 +static int shmem_ref;
   30.43  #endif
   30.44  
   30.45  static struct blk_shadow {
   30.46 @@ -105,7 +98,7 @@ static int recovery = 0; /* Recovery in 
   30.47  
   30.48  static void kick_pending_request_queues(void);
   30.49  
   30.50 -int __init xlblk_init(void);
   30.51 +static int __init xlblk_init(void);
   30.52  
   30.53  static void blkif_completion(struct blk_shadow *s);
   30.54  
   30.55 @@ -179,19 +172,6 @@ static inline void flush_requests(void)
   30.56  
   30.57  module_init(xlblk_init);
   30.58  
   30.59 -#if ENABLE_VBD_UPDATE
   30.60 -static void update_vbds_task(void *unused)
   30.61 -{ 
   30.62 -    xlvbd_update_vbds();
   30.63 -}
   30.64 -
   30.65 -static void vbd_update(void)
   30.66 -{
   30.67 -    static DECLARE_WORK(update_tq, update_vbds_task, NULL);
   30.68 -    schedule_work(&update_tq);
   30.69 -}
   30.70 -#endif /* ENABLE_VBD_UPDATE */
   30.71 -
   30.72  static struct xlbd_disk_info *head_waiting = NULL;
   30.73  static void kick_pending_request_queues(void)
   30.74  {
   30.75 @@ -221,16 +201,7 @@ int blkif_open(struct inode *inode, stru
   30.76  
   30.77  int blkif_release(struct inode *inode, struct file *filep)
   30.78  {
   30.79 -    struct gendisk *gd = inode->i_bdev->bd_disk;
   30.80 -    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
   30.81 -
   30.82 -    /*
   30.83 -     * When usage drops to zero it may allow more VBD updates to occur.
   30.84 -     * Update of usage count is protected by a per-device semaphore.
   30.85 -     */
   30.86 -    if ( --di->mi->usage == 0 )
   30.87 -        vbd_update();
   30.88 -
   30.89 +    /* FIXME: This is where we can actually free up majors, etc. --RR */
   30.90      return 0;
   30.91  }
   30.92  
   30.93 @@ -301,7 +272,7 @@ static int blkif_queue_request(struct re
   30.94      ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
   30.95          BLKIF_OP_READ;
   30.96      ring_req->sector_number = (blkif_sector_t)req->sector;
   30.97 -    ring_req->device = di->xd_device;
   30.98 +    ring_req->handle = di->handle;
   30.99  
  30.100      ring_req->nr_segments = 0;
  30.101      rq_for_each_bio(bio, req)
  30.102 @@ -446,10 +417,6 @@ static irqreturn_t blkif_int(int irq, vo
  30.103              end_that_request_last(req);
  30.104  
  30.105              break;
  30.106 -        case BLKIF_OP_PROBE:
  30.107 -            memcpy(&blkif_control_rsp, bret, sizeof(*bret));
  30.108 -            blkif_control_rsp_valid = 1;
  30.109 -            break;
  30.110          default:
  30.111              BUG();
  30.112          }
  30.113 @@ -483,28 +450,6 @@ static int nr_pending;
  30.114  #define blkif_io_lock io_request_lock
  30.115  
  30.116  /*============================================================================*/
  30.117 -#if ENABLE_VBD_UPDATE
  30.118 -
  30.119 -/*
  30.120 - * blkif_update_int/update-vbds_task - handle VBD update events.
  30.121 - *  Schedule a task for keventd to run, which will update the VBDs and perform 
  30.122 - *  the corresponding updates to our view of VBD state.
  30.123 - */
  30.124 -static void update_vbds_task(void *unused)
  30.125 -{ 
  30.126 -    xlvbd_update_vbds();
  30.127 -}
  30.128 -
  30.129 -static void vbd_update(void)
  30.130 -{
  30.131 -    static struct tq_struct update_tq;
  30.132 -    update_tq.routine = update_vbds_task;
  30.133 -    schedule_task(&update_tq);
  30.134 -}
  30.135 -
  30.136 -#endif /* ENABLE_VBD_UPDATE */
  30.137 -/*============================================================================*/
  30.138 -
  30.139  static void kick_pending_request_queues(void)
  30.140  {
  30.141      /* We kick pending request queues if the ring is reasonably empty. */
  30.142 @@ -757,7 +702,8 @@ static int blkif_queue_request(unsigned 
  30.143                                 char *          buffer,
  30.144                                 unsigned long   sector_number,
  30.145                                 unsigned short  nr_sectors,
  30.146 -                               kdev_t          device)
  30.147 +                               kdev_t          device,
  30.148 +			       blkif_vdev_t    handle)
  30.149  {
  30.150      unsigned long       buffer_ma = virt_to_bus(buffer);
  30.151      unsigned long       xid;
  30.152 @@ -871,7 +817,7 @@ static int blkif_queue_request(unsigned 
  30.153      req->id            = xid;
  30.154      req->operation     = operation;
  30.155      req->sector_number = (blkif_sector_t)sector_number;
  30.156 -    req->device        = device; 
  30.157 +    req->handle        = handle; 
  30.158      req->nr_segments   = 1;
  30.159  #ifdef CONFIG_XEN_BLKDEV_GRANT
  30.160      /* install a grant reference. */
  30.161 @@ -1047,108 +993,10 @@ static void blkif_int(int irq, void *dev
  30.162  
  30.163  /*****************************  COMMON CODE  *******************************/
  30.164  
  30.165 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.166 -void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
  30.167 -                              unsigned long address)
  30.168 -{
  30.169 -    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
  30.170 -    ASSERT( ref != -ENOSPC );
  30.171 -
  30.172 -    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
  30.173 -
  30.174 -    req->frame_and_sects[0] = blkif_fas_from_gref(ref, 0, (PAGE_SIZE/512)-1);
  30.175 -
  30.176 -    blkif_control_send(req, rsp);
  30.177 -}
  30.178 -#endif
  30.179 -
  30.180 -void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
  30.181 -{
  30.182 -    unsigned long flags, id;
  30.183 -    blkif_request_t *req_d;
  30.184 -
  30.185 - retry:
  30.186 -    while ( RING_FULL(&blk_ring) )
  30.187 -    {
  30.188 -        set_current_state(TASK_INTERRUPTIBLE);
  30.189 -        schedule_timeout(1);
  30.190 -    }
  30.191 -
  30.192 -    spin_lock_irqsave(&blkif_io_lock, flags);
  30.193 -    if ( RING_FULL(&blk_ring) )
  30.194 -    {
  30.195 -        spin_unlock_irqrestore(&blkif_io_lock, flags);
  30.196 -        goto retry;
  30.197 -    }
  30.198 -
  30.199 -    DISABLE_SCATTERGATHER();
  30.200 -    req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
  30.201 -    *req_d = *req;    
  30.202 -
  30.203 -    id = GET_ID_FROM_FREELIST();
  30.204 -    req_d->id = id;
  30.205 -    blk_shadow[id].request = (unsigned long)req;
  30.206 -
  30.207 -    pickle_request(&blk_shadow[id], req);
  30.208 -
  30.209 -    blk_ring.req_prod_pvt++;
  30.210 -    flush_requests();
  30.211 -
  30.212 -    spin_unlock_irqrestore(&blkif_io_lock, flags);
  30.213 -
  30.214 -    while ( !blkif_control_rsp_valid )
  30.215 -    {
  30.216 -        set_current_state(TASK_INTERRUPTIBLE);
  30.217 -        schedule_timeout(1);
  30.218 -    }
  30.219 -
  30.220 -    memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
  30.221 -    blkif_control_rsp_valid = 0;
  30.222 -}
  30.223 -
  30.224 -
  30.225 -/* Send a driver status notification to the domain controller. */
  30.226 -static void send_driver_status(int ok)
  30.227 -{
  30.228 -    ctrl_msg_t cmsg = {
  30.229 -        .type    = CMSG_BLKIF_FE,
  30.230 -        .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
  30.231 -        .length  = sizeof(blkif_fe_driver_status_t),
  30.232 -    };
  30.233 -    blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
  30.234 -    
  30.235 -    msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
  30.236 -
  30.237 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
  30.238 -}
  30.239 -
  30.240 -/* Tell the controller to bring up the interface. */
  30.241 -static void blkif_send_interface_connect(void)
  30.242 -{
  30.243 -    ctrl_msg_t cmsg = {
  30.244 -        .type    = CMSG_BLKIF_FE,
  30.245 -        .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
  30.246 -        .length  = sizeof(blkif_fe_interface_connect_t),
  30.247 -    };
  30.248 -    blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
  30.249 -    
  30.250 -    msg->handle      = 0;
  30.251 -    msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
  30.252 -    
  30.253 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.254 -    msg->shmem_ref   = gnttab_claim_grant_reference( &gref_head, gref_terminal );
  30.255 -    ASSERT( msg->shmem_ref != -ENOSPC );
  30.256 -    gnttab_grant_foreign_access_ref ( msg->shmem_ref , rdomid, msg->shmem_frame, 0 );
  30.257 -#endif
  30.258 -
  30.259 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
  30.260 -}
  30.261 -
  30.262  static void blkif_free(void)
  30.263  {
  30.264      /* Prevent new requests being issued until we fix things up. */
  30.265      spin_lock_irq(&blkif_io_lock);
  30.266 -    recovery = 1;
  30.267      blkif_state = BLKIF_STATE_DISCONNECTED;
  30.268      spin_unlock_irq(&blkif_io_lock);
  30.269  
  30.270 @@ -1162,31 +1010,6 @@ static void blkif_free(void)
  30.271      blkif_evtchn = 0;
  30.272  }
  30.273  
  30.274 -static void blkif_close(void)
  30.275 -{
  30.276 -}
  30.277 -
  30.278 -/* Move from CLOSED to DISCONNECTED state. */
  30.279 -static void blkif_disconnect(void)
  30.280 -{
  30.281 -    blkif_sring_t *sring;
  30.282 -    
  30.283 -    if ( blk_ring.sring != NULL )
  30.284 -        free_page((unsigned long)blk_ring.sring);
  30.285 -    
  30.286 -    sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
  30.287 -    SHARED_RING_INIT(sring);
  30.288 -    FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
  30.289 -    blkif_state  = BLKIF_STATE_DISCONNECTED;
  30.290 -    blkif_send_interface_connect();
  30.291 -}
  30.292 -
  30.293 -static void blkif_reset(void)
  30.294 -{
  30.295 -    blkif_free();
  30.296 -    blkif_disconnect();
  30.297 -}
  30.298 -
  30.299  static void blkif_recover(void)
  30.300  {
  30.301      int i;
  30.302 @@ -1257,11 +1080,14 @@ static void blkif_recover(void)
  30.303      blkif_state = BLKIF_STATE_CONNECTED;
  30.304  }
  30.305  
  30.306 -static void blkif_connect(blkif_fe_interface_status_t *status)
  30.307 +static void blkif_connect(u16 evtchn, domid_t domid)
  30.308  {
  30.309      int err = 0;
  30.310  
  30.311 -    blkif_evtchn = status->evtchn;
  30.312 +    blkif_evtchn = evtchn;
  30.313 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.314 +    rdomid       = domid;
  30.315 +#endif
  30.316  
  30.317      err = bind_evtchn_to_irqhandler(
  30.318          blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
  30.319 @@ -1270,142 +1096,318 @@ static void blkif_connect(blkif_fe_inter
  30.320          WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  30.321          return;
  30.322      }
  30.323 -
  30.324 -    if ( recovery ) 
  30.325 -    {
  30.326 -        blkif_recover();
  30.327 -    } 
  30.328 -    else 
  30.329 -    {
  30.330 -        /* Transition to connected in case we need to do 
  30.331 -         *  a partition probe on a whole disk. */
  30.332 -        blkif_state = BLKIF_STATE_CONNECTED;
  30.333 -        
  30.334 -        /* Probe for discs attached to the interface. */
  30.335 -        xlvbd_init();
  30.336 -    }
  30.337 -    
  30.338 -    /* Kick pending requests. */
  30.339 -    spin_lock_irq(&blkif_io_lock);
  30.340 -    kick_pending_request_queues();
  30.341 -    spin_unlock_irq(&blkif_io_lock);
  30.342 -}
  30.343 -
  30.344 -static void unexpected(blkif_fe_interface_status_t *status)
  30.345 -{
  30.346 -    DPRINTK(" Unexpected blkif status %u in state %u\n", 
  30.347 -            status->status, blkif_state);
  30.348 -}
  30.349 -
  30.350 -static void blkif_status(blkif_fe_interface_status_t *status)
  30.351 -{
  30.352 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.353 -    rdomid       = status->domid; /* need to set rdomid early */
  30.354 -#endif
  30.355 -
  30.356 -    if ( status->handle != blkif_handle )
  30.357 -    {
  30.358 -        WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
  30.359 -        unexpected(status);
  30.360 -        return;
  30.361 -    }
  30.362 -
  30.363 -    switch ( status->status ) 
  30.364 -    {
  30.365 -    case BLKIF_INTERFACE_STATUS_CLOSED:
  30.366 -        switch ( blkif_state )
  30.367 -        {
  30.368 -        case BLKIF_STATE_CLOSED:
  30.369 -            unexpected(status);
  30.370 -            break;
  30.371 -        case BLKIF_STATE_DISCONNECTED:
  30.372 -        case BLKIF_STATE_CONNECTED:
  30.373 -            unexpected(status);
  30.374 -            blkif_close();
  30.375 -            break;
  30.376 -        }
  30.377 -        break;
  30.378 -
  30.379 -    case BLKIF_INTERFACE_STATUS_DISCONNECTED:
  30.380 -        switch ( blkif_state )
  30.381 -        {
  30.382 -        case BLKIF_STATE_CLOSED:
  30.383 -            blkif_disconnect();
  30.384 -            break;
  30.385 -        case BLKIF_STATE_DISCONNECTED:
  30.386 -        case BLKIF_STATE_CONNECTED:
  30.387 -            /* unexpected(status); */ /* occurs during suspend/resume */
  30.388 -            blkif_reset();
  30.389 -            break;
  30.390 -        }
  30.391 -        break;
  30.392 -
  30.393 -    case BLKIF_INTERFACE_STATUS_CONNECTED:
  30.394 -        switch ( blkif_state )
  30.395 -        {
  30.396 -        case BLKIF_STATE_CLOSED:
  30.397 -            unexpected(status);
  30.398 -            blkif_disconnect();
  30.399 -            blkif_connect(status);
  30.400 -            break;
  30.401 -        case BLKIF_STATE_DISCONNECTED:
  30.402 -            blkif_connect(status);
  30.403 -            break;
  30.404 -        case BLKIF_STATE_CONNECTED:
  30.405 -            unexpected(status);
  30.406 -            blkif_connect(status);
  30.407 -            break;
  30.408 -        }
  30.409 -        break;
  30.410 -
  30.411 -    case BLKIF_INTERFACE_STATUS_CHANGED:
  30.412 -        switch ( blkif_state )
  30.413 -        {
  30.414 -        case BLKIF_STATE_CLOSED:
  30.415 -        case BLKIF_STATE_DISCONNECTED:
  30.416 -            unexpected(status);
  30.417 -            break;
  30.418 -        case BLKIF_STATE_CONNECTED:
  30.419 -            vbd_update();
  30.420 -            break;
  30.421 -        }
  30.422 -        break;
  30.423 -
  30.424 -    default:
  30.425 -        WPRINTK(" Invalid blkif status: %d\n", status->status);
  30.426 -        break;
  30.427 -    }
  30.428  }
  30.429  
  30.430  
  30.431 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
  30.432 +static struct xenbus_device_id blkfront_ids[] = {
  30.433 +	{ "vbd" },
  30.434 +	{ "" }
  30.435 +};
  30.436 +
  30.437 +struct blkfront_info
  30.438 +{
  30.439 +	/* We watch the backend */
  30.440 +	struct xenbus_watch watch;
  30.441 +	int vdevice;
  30.442 +	u16 handle;
  30.443 +	int connected;
  30.444 +	struct xenbus_device *dev;
  30.445 +	char *backend;
  30.446 +};
  30.447 +
  30.448 +static void watch_for_status(struct xenbus_watch *watch, const char *node)
  30.449  {
  30.450 -    switch ( msg->subtype )
  30.451 -    {
  30.452 -    case CMSG_BLKIF_FE_INTERFACE_STATUS:
  30.453 -        blkif_status((blkif_fe_interface_status_t *)
  30.454 -                     &msg->msg[0]);
  30.455 -        break;
  30.456 -    default:
  30.457 -        msg->length = 0;
  30.458 -        break;
  30.459 -    }
  30.460 +	struct blkfront_info *info;
  30.461 +	unsigned int binfo;
  30.462 +	unsigned long sectors, sector_size;
  30.463 +	int err;
  30.464 +
  30.465 +	info = container_of(watch, struct blkfront_info, watch);
  30.466 +	node += strlen(watch->node);
  30.467 +
  30.468 +	/* FIXME: clean up when error on the other end. */
  30.469 +	if (info->connected)
  30.470 +		return;
  30.471 +
  30.472 +	err = xenbus_gather(watch->node, 
  30.473 +			    "sectors", "%lu", &sectors,
  30.474 +			    "info", "%u", &binfo,
  30.475 +			    "sector-size", "%lu", &sector_size,
  30.476 +			    NULL);
  30.477 +
  30.478 +	if (err)
  30.479 +		xenbus_dev_error(info->dev, err, "reading backend fields");
  30.480 +	else {
  30.481 +		xlvbd_add(sectors, info->vdevice, info->handle, binfo,
  30.482 +			  sector_size);
  30.483 +		info->connected = 1;
  30.484 +
  30.485 +		/* First to connect?  blkif is now connected. */
  30.486 +		if (blkif_vbds_connected++ == 0)
  30.487 +			blkif_state = BLKIF_STATE_CONNECTED;
  30.488 +
  30.489 +		xenbus_dev_ok(info->dev);
  30.490  
  30.491 -    ctrl_if_send_response(msg);
  30.492 +		/* Kick pending requests. */
  30.493 +		spin_lock_irq(&blkif_io_lock);
  30.494 +		kick_pending_request_queues();
  30.495 +		spin_unlock_irq(&blkif_io_lock);
  30.496 +	}
  30.497 +}
  30.498 +
  30.499 +static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id)
  30.500 +{
  30.501 +	blkif_sring_t *sring;
  30.502 +	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
  30.503 +	int err;
  30.504 +
  30.505 +	sring = (void *)__get_free_page(GFP_KERNEL);
  30.506 +	if (!sring) {
  30.507 +		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
  30.508 +		return -ENOMEM;
  30.509 +	}
  30.510 +	SHARED_RING_INIT(sring);
  30.511 +	FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
  30.512 +
  30.513 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.514 +	shmem_ref = gnttab_claim_grant_reference(&gref_head,
  30.515 +						 gref_terminal);
  30.516 +	ASSERT(shmem_ref != -ENOSPC);
  30.517 +	gnttab_grant_foreign_access_ref(shmem_ref,
  30.518 +					backend_id,
  30.519 +					virt_to_machine(blk_ring.sring)
  30.520 +					>> PAGE_SHIFT, 0);
  30.521 +#endif
  30.522 +
  30.523 +	op.u.alloc_unbound.dom = backend_id;
  30.524 +	err = HYPERVISOR_event_channel_op(&op);
  30.525 +	if (err) {
  30.526 +		free_page((unsigned long)blk_ring.sring);
  30.527 +		blk_ring.sring = 0;
  30.528 +		xenbus_dev_error(dev, err, "allocating event channel");
  30.529 +		return err;
  30.530 +	}
  30.531 +	blkif_connect(op.u.alloc_unbound.port, backend_id);
  30.532 +	return 0;
  30.533  }
  30.534  
  30.535 -int wait_for_blkif(void)
  30.536 +/* Common code used when first setting up, and when resuming. */
  30.537 +static int talk_to_backend(struct xenbus_device *dev,
  30.538 +			   struct blkfront_info *info)
  30.539 +{
  30.540 +	char *backend;
  30.541 +	const char *message;
  30.542 +	int err, backend_id;
  30.543 +
  30.544 +	backend = xenbus_read(dev->nodename, "backend", NULL);
  30.545 +	if (IS_ERR(backend)) {
  30.546 +		err = PTR_ERR(backend);
  30.547 +		if (err == -ENOENT)
  30.548 +			goto out;
  30.549 +		xenbus_dev_error(dev, err, "reading %s/backend",
  30.550 +				 dev->nodename);
  30.551 +		goto out;
  30.552 +	}
  30.553 +	if (strlen(backend) == 0) {
  30.554 +		err = -ENOENT;
  30.555 +		goto free_backend;
  30.556 +	}
  30.557 +
  30.558 +	/* FIXME: This driver can't handle backends on different
  30.559 +	 * domains.  Check and fail gracefully. */
  30.560 +	err = xenbus_scanf(dev->nodename, "backend-id", "%i", &backend_id);
  30.561 +	if (err == -ENOENT)
  30.562 +		goto free_backend;
  30.563 + 	if (err < 0) {
  30.564 +		xenbus_dev_error(dev, err, "reading %s/backend-id",
  30.565 +				 dev->nodename);
  30.566 + 		goto free_backend;
  30.567 + 	}
  30.568 +
  30.569 +	/* First device?  We create shared ring, alloc event channel. */
  30.570 +	if (blkif_vbds == 0) {
  30.571 +		err = setup_blkring(dev, backend_id);
  30.572 +		if (err)
  30.573 +			goto free_backend;
  30.574 +	}
  30.575 +
  30.576 +	err = xenbus_transaction_start(dev->nodename);
  30.577 +	if (err) {
  30.578 +		xenbus_dev_error(dev, err, "starting transaction");
  30.579 +		goto destroy_blkring;
  30.580 +	}
  30.581 +
  30.582 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.583 +	err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref);
  30.584 +	if (err) {
  30.585 +		message = "writing grant-id";
  30.586 +		goto abort_transaction;
  30.587 +	}
  30.588 +#else
  30.589 +	err = xenbus_printf(dev->nodename, "shared-frame", "%lu",
  30.590 +			    virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
  30.591 +	if (err) {
  30.592 +		message = "writing shared-frame";
  30.593 +		goto abort_transaction;
  30.594 +	}
  30.595 +#endif
  30.596 +	err = xenbus_printf(dev->nodename,
  30.597 +			    "event-channel", "%u", blkif_evtchn);
  30.598 +	if (err) {
  30.599 +		message = "writing event-channel";
  30.600 +		goto abort_transaction;
  30.601 +	}
  30.602 +
  30.603 +	info->watch.node = info->backend = backend;
  30.604 +	info->watch.callback = watch_for_status;
  30.605 +
  30.606 +	err = register_xenbus_watch(&info->watch);
  30.607 +	if (err) {
  30.608 +		message = "registering watch on backend";
  30.609 +		goto abort_transaction;
  30.610 +	}
  30.611 +
  30.612 +	err = xenbus_transaction_end(0);
  30.613 +	if (err) {
  30.614 +		xenbus_dev_error(dev, err, "completing transaction");
  30.615 +		goto destroy_blkring;
  30.616 +	}
  30.617 +	return 0;
  30.618 +
  30.619 +abort_transaction:
  30.620 +	xenbus_transaction_end(1);
  30.621 +	/* Have to do this *outside* transaction.  */
  30.622 +	xenbus_dev_error(dev, err, "%s", message);
  30.623 +destroy_blkring:
  30.624 +	if (blkif_vbds == 0)
  30.625 +		blkif_free();
  30.626 +free_backend:
  30.627 +	kfree(backend);
  30.628 +out:
  30.629 +	printk("%s:%u = %i\n", __FILE__, __LINE__, err);
  30.630 +	return err;
  30.631 +}
  30.632 +
  30.633 +/* Setup supplies the backend dir, virtual device.
  30.634 +
  30.635 +   We place an event channel and shared frame entries.
  30.636 +   We watch backend to wait if it's ok. */
  30.637 +static int blkfront_probe(struct xenbus_device *dev,
  30.638 +			  const struct xenbus_device_id *id)
  30.639 +{
  30.640 +	int err;
  30.641 +	struct blkfront_info *info;
  30.642 +	int vdevice;
  30.643 +
  30.644 +	/* FIXME: Use dynamic device id if this is not set. */
  30.645 +	err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
  30.646 +	if (err == -ENOENT)
  30.647 +		return err;
  30.648 +	if (err < 0) {
  30.649 +		xenbus_dev_error(dev, err, "reading virtual-device");
  30.650 +		return err;
  30.651 +	}
  30.652 +
  30.653 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
  30.654 +	if (!info) {
  30.655 +		xenbus_dev_error(dev, err, "allocating info structure");
  30.656 +		return err;
  30.657 +	}
  30.658 +	info->dev = dev;
  30.659 +	info->vdevice = vdevice;
  30.660 +	info->connected = 0;
  30.661 +	/* Front end dir is a number, which is used as the id. */
  30.662 +	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
  30.663 +	dev->data = info;
  30.664 +
  30.665 +	err = talk_to_backend(dev, info);
  30.666 +	if (err) {
  30.667 +		kfree(info);
  30.668 +		return err;
  30.669 +	}
  30.670 +
  30.671 +	/* Call once in case entries already there. */
  30.672 +	watch_for_status(&info->watch, info->watch.node);
  30.673 +	blkif_vbds++;
  30.674 +	return 0;
  30.675 +}
  30.676 +
  30.677 +static int blkfront_remove(struct xenbus_device *dev)
  30.678 +{
  30.679 +	struct blkfront_info *info = dev->data;
  30.680 +
  30.681 +	if (info->backend)
  30.682 +		unregister_xenbus_watch(&info->watch);
  30.683 +
  30.684 +	if (info->connected) {
  30.685 +		xlvbd_del(info->handle);
  30.686 +		blkif_vbds_connected--;
  30.687 +	}
  30.688 +	kfree(info->backend);
  30.689 +	kfree(info);
  30.690 +
  30.691 +	if (--blkif_vbds == 0)
  30.692 +		blkif_free();
  30.693 +
  30.694 +	return 0;
  30.695 +}
  30.696 +
  30.697 +static int blkfront_suspend(struct xenbus_device *dev)
  30.698 +{
  30.699 +	struct blkfront_info *info = dev->data;
  30.700 +
  30.701 +	unregister_xenbus_watch(&info->watch);
  30.702 +	kfree(info->backend);
  30.703 +	info->backend = NULL;
  30.704 +
  30.705 +	if (--blkif_vbds == 0) {
  30.706 +		recovery = 1;
  30.707 +		blkif_free();
  30.708 +	}
  30.709 +
  30.710 +	return 0;
  30.711 +}
  30.712 +
  30.713 +static int blkfront_resume(struct xenbus_device *dev)
  30.714 +{
  30.715 +	struct blkfront_info *info = dev->data;
  30.716 +	int err;
  30.717 +
  30.718 +	/* FIXME: Check geometry hasn't changed here... */
  30.719 +	err = talk_to_backend(dev, info);
  30.720 +	if (!err) {
  30.721 +		if (blkif_vbds++ == 0)
  30.722 +			blkif_recover();
  30.723 +	}
  30.724 +	return err;
  30.725 +}
  30.726 +
  30.727 +static struct xenbus_driver blkfront = {
  30.728 +	.name = "vbd",
  30.729 +	.owner = THIS_MODULE,
  30.730 +	.ids = blkfront_ids,
  30.731 +	.probe = blkfront_probe,
  30.732 +	.remove = blkfront_remove,
  30.733 +	.resume = blkfront_resume,
  30.734 +	.suspend = blkfront_suspend,
  30.735 +};
  30.736 +
  30.737 +static void __init init_blk_xenbus(void)
  30.738 +{
  30.739 +	xenbus_register_device(&blkfront);
  30.740 +}
  30.741 +
  30.742 +static int wait_for_blkif(void)
  30.743  {
  30.744      int err = 0;
  30.745      int i;
  30.746 -    send_driver_status(1);
  30.747  
  30.748      /*
  30.749       * We should read 'nr_interfaces' from response message and wait
  30.750       * for notifications before proceeding. For now we assume that we
  30.751       * will be notified of exactly one interface.
  30.752       */
  30.753 -    for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
  30.754 +    for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ )
  30.755      {
  30.756          set_current_state(TASK_INTERRUPTIBLE);
  30.757          schedule_timeout(1);
  30.758 @@ -1419,7 +1421,7 @@ int wait_for_blkif(void)
  30.759      return err;
  30.760  }
  30.761  
  30.762 -int __init xlblk_init(void)
  30.763 +static int __init xlblk_init(void)
  30.764  {
  30.765      int i;
  30.766  
  30.767 @@ -1443,29 +1445,13 @@ int __init xlblk_init(void)
  30.768          blk_shadow[i].req.id = i+1;
  30.769      blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  30.770  
  30.771 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
  30.772 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
  30.773 +    init_blk_xenbus();
  30.774  
  30.775      wait_for_blkif();
  30.776  
  30.777      return 0;
  30.778  }
  30.779  
  30.780 -void blkdev_suspend(void)
  30.781 -{
  30.782 -}
  30.783 -
  30.784 -void blkdev_resume(void)
  30.785 -{
  30.786 -#ifdef CONFIG_XEN_BLKDEV_GRANT
  30.787 -    int i, j;
  30.788 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
  30.789 -        for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
  30.790 -            blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
  30.791 -#endif
  30.792 -    send_driver_status(1);
  30.793 -}
  30.794 -
  30.795  static void blkif_completion(struct blk_shadow *s)
  30.796  {
  30.797      int i;
    31.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 10:50:15 2005 +0000
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 13:08:50 2005 +0000
    31.3 @@ -100,6 +100,7 @@ struct xlbd_major_info {
    31.4  
    31.5  struct xlbd_disk_info {
    31.6      int xd_device;
    31.7 +    blkif_vdev_t handle;
    31.8      struct xlbd_major_info *mi;
    31.9  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   31.10      struct xlbd_disk_info  *next_waiting;
   31.11 @@ -119,17 +120,10 @@ extern int blkif_ioctl(struct inode *ino
   31.12                         unsigned command, unsigned long argument);
   31.13  extern int blkif_check(dev_t dev);
   31.14  extern int blkif_revalidate(dev_t dev);
   31.15 -extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
   31.16 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   31.17 -extern void blkif_control_probe_send(
   31.18 -    blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
   31.19 -#endif
   31.20  extern void do_blkif_request (request_queue_t *rq); 
   31.21  
   31.22 -extern void xlvbd_update_vbds(void);
   31.23 -
   31.24  /* Virtual block-device subsystem. */
   31.25 -extern int  xlvbd_init(void);
   31.26 -extern void xlvbd_cleanup(void); 
   31.27 -
   31.28 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
   31.29 +	      u16 info, u16 sector_size);
   31.30 +void xlvbd_del(blkif_vdev_t handle);
   31.31  #endif /* __XEN_DRIVERS_BLOCK_H__ */
    32.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 10:50:15 2005 +0000
    32.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 13:08:50 2005 +0000
    32.3 @@ -46,8 +46,9 @@
    32.4  struct lvdisk
    32.5  {
    32.6      blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
    32.7 -    blkif_vdev_t   device;   /*  8: Device number (opaque 16 bit value). */
    32.8 -    u16            info; 
    32.9 +    blkif_vdev_t   handle;   /*  8: Device number (opaque 16 bit value). */
   32.10 +    u16            info;
   32.11 +    dev_t          dev;
   32.12      struct list_head list;
   32.13  };
   32.14  
   32.15 @@ -85,7 +86,7 @@ static struct xlbd_major_info *major_inf
   32.16  
   32.17  /* Information about our VBDs. */
   32.18  #define MAX_VBDS 64
   32.19 -struct list_head vbds_list;
   32.20 +static LIST_HEAD(vbds_list);
   32.21  
   32.22  #define MAJOR_XEN(dev) ((dev)>>8)
   32.23  #define MINOR_XEN(dev) ((dev) & 0xff)
   32.24 @@ -118,49 +119,6 @@ static void xlvbd_device_free(struct lvd
   32.25      kfree(disk);
   32.26  }
   32.27  
   32.28 -static vdisk_t *xlvbd_probe(int *ret)
   32.29 -{
   32.30 -    blkif_response_t rsp;
   32.31 -    blkif_request_t req;
   32.32 -    vdisk_t *disk_info = NULL;
   32.33 -    unsigned long buf;
   32.34 -    int nr;
   32.35 -
   32.36 -    buf = __get_free_page(GFP_KERNEL);
   32.37 -    if ((void *)buf == NULL)
   32.38 -        goto out;
   32.39 -
   32.40 -    memset(&req, 0, sizeof(req));
   32.41 -    req.operation = BLKIF_OP_PROBE;
   32.42 -    req.nr_segments = 1;
   32.43 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   32.44 -    blkif_control_probe_send(&req, &rsp,
   32.45 -                             (unsigned long)(virt_to_machine(buf)));
   32.46 -#else
   32.47 -    req.frame_and_sects[0] = blkif_fas(virt_to_machine(buf), 0, (PAGE_SIZE/512)-1);
   32.48 -
   32.49 -    blkif_control_send(&req, &rsp);
   32.50 -#endif
   32.51 -    if ( rsp.status <= 0 ) {
   32.52 -        WPRINTK("Could not probe disks (%d)\n", rsp.status);
   32.53 -        goto out;
   32.54 -    }
   32.55 -    nr = rsp.status;
   32.56 -    if ( nr > MAX_VBDS )
   32.57 -        nr = MAX_VBDS;
   32.58 -
   32.59 -    disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
   32.60 -    if (disk_info != NULL)
   32.61 -        memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
   32.62 -
   32.63 -    if (ret != NULL)
   32.64 -        *ret = nr;
   32.65 -
   32.66 -out:
   32.67 -    free_page(buf);
   32.68 -    return disk_info;
   32.69 -}
   32.70 -
   32.71  static struct xlbd_major_info *xlbd_alloc_major_info(
   32.72      int major, int minor, int index)
   32.73  {
   32.74 @@ -189,6 +147,7 @@ static struct xlbd_major_info *xlbd_allo
   32.75          break;
   32.76      }
   32.77      
   32.78 +    printk("Registering block device major %i\n", ptr->major);
   32.79      if (register_blkdev(ptr->major, ptr->type->devname)) {
   32.80          WPRINTK("can't get major %d with name %s\n",
   32.81                  ptr->major, ptr->type->devname);
   32.82 @@ -231,7 +190,7 @@ static struct xlbd_major_info *xlbd_get_
   32.83              xlbd_alloc_major_info(major, minor, index));
   32.84  }
   32.85  
   32.86 -static int xlvbd_init_blk_queue(struct gendisk *gd, vdisk_t *disk)
   32.87 +static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
   32.88  {
   32.89      request_queue_t *rq;
   32.90  
   32.91 @@ -242,7 +201,7 @@ static int xlvbd_init_blk_queue(struct g
   32.92      elevator_init(rq, "noop");
   32.93  
   32.94      /* Hard sector size and max sectors impersonate the equiv. hardware. */
   32.95 -    blk_queue_hardsect_size(rq, disk->sector_size);
   32.96 +    blk_queue_hardsect_size(rq, sector_size);
   32.97      blk_queue_max_sectors(rq, 512);
   32.98  
   32.99      /* Each segment in a request is up to an aligned page in size. */
  32.100 @@ -261,8 +220,9 @@ static int xlvbd_init_blk_queue(struct g
  32.101      return 0;
  32.102  }
  32.103  
  32.104 -struct gendisk *xlvbd_alloc_gendisk(
  32.105 -    struct xlbd_major_info *mi, int minor, vdisk_t *disk)
  32.106 +static struct gendisk *xlvbd_alloc_gendisk(
  32.107 +    struct xlbd_major_info *mi, int minor, blkif_sector_t capacity,
  32.108 +    int device, blkif_vdev_t handle, u16 info, u16 sector_size)
  32.109  {
  32.110      struct gendisk *gd;
  32.111      struct xlbd_disk_info *di;
  32.112 @@ -273,7 +233,8 @@ struct gendisk *xlvbd_alloc_gendisk(
  32.113          return NULL;
  32.114      memset(di, 0, sizeof(*di));
  32.115      di->mi = mi;
  32.116 -    di->xd_device = disk->device;
  32.117 +    di->xd_device = device;
  32.118 +    di->handle = handle;
  32.119  
  32.120      if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
  32.121          nr_minors = 1 << mi->type->partn_shift;
  32.122 @@ -296,22 +257,22 @@ struct gendisk *xlvbd_alloc_gendisk(
  32.123      gd->first_minor = minor;
  32.124      gd->fops = &xlvbd_block_fops;
  32.125      gd->private_data = di;
  32.126 -    set_capacity(gd, disk->capacity);
  32.127 +    set_capacity(gd, capacity);
  32.128  
  32.129 -    if (xlvbd_init_blk_queue(gd, disk)) {
  32.130 +    if (xlvbd_init_blk_queue(gd, sector_size)) {
  32.131          del_gendisk(gd);
  32.132          goto out;
  32.133      }
  32.134  
  32.135      di->rq = gd->queue;
  32.136  
  32.137 -    if (disk->info & VDISK_READONLY)
  32.138 +    if (info & VDISK_READONLY)
  32.139          set_disk_ro(gd, 1);
  32.140  
  32.141 -    if (disk->info & VDISK_REMOVABLE)
  32.142 +    if (info & VDISK_REMOVABLE)
  32.143          gd->flags |= GENHD_FL_REMOVABLE;
  32.144  
  32.145 -    if (disk->info & VDISK_CDROM)
  32.146 +    if (info & VDISK_CDROM)
  32.147          gd->flags |= GENHD_FL_CD;
  32.148  
  32.149      add_disk(gd);
  32.150 @@ -323,38 +284,36 @@ out:
  32.151      return NULL;
  32.152  }
  32.153  
  32.154 -static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
  32.155 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
  32.156 +	      u16 info, u16 sector_size)
  32.157  {
  32.158      struct lvdisk *new;
  32.159 -    int minor;
  32.160 -    dev_t device;
  32.161      struct block_device *bd;
  32.162      struct gendisk *gd;
  32.163      struct xlbd_major_info *mi;
  32.164  
  32.165 -    mi = xlbd_get_major_info(disk->device);
  32.166 +    mi = xlbd_get_major_info(device);
  32.167      if (mi == NULL)
  32.168          return -EPERM;
  32.169  
  32.170      new = xlvbd_device_alloc();
  32.171      if (new == NULL)
  32.172 -        return -1;
  32.173 -    new->capacity = disk->capacity;
  32.174 -    new->device = disk->device;
  32.175 -    new->info = disk->info;
  32.176 -    
  32.177 -    minor = MINOR_XEN(disk->device);
  32.178 -    device = MKDEV(mi->major, minor);
  32.179 -    
  32.180 -    bd = bdget(device);
  32.181 +        return -ENOMEM;
  32.182 +    new->capacity = capacity;
  32.183 +    new->info = info;
  32.184 +    new->handle = handle;
  32.185 +    new->dev = MKDEV(MAJOR_XEN(device), MINOR_XEN(device));
  32.186 +
  32.187 +    bd = bdget(new->dev);
  32.188      if (bd == NULL)
  32.189          goto out;
  32.190      
  32.191 -    gd = xlvbd_alloc_gendisk(mi, minor, disk);
  32.192 +    gd = xlvbd_alloc_gendisk(mi, MINOR_XEN(device), capacity, device, handle,
  32.193 +			     info, sector_size);
  32.194      if (gd == NULL)
  32.195          goto out_bd;
  32.196  
  32.197 -    list_add(&new->list, list);
  32.198 +    list_add(&new->list, &vbds_list);
  32.199  out_bd:
  32.200      bdput(bd);
  32.201  out:
  32.202 @@ -363,27 +322,26 @@ out:
  32.203  
  32.204  static int xlvbd_device_del(struct lvdisk *disk)
  32.205  {
  32.206 -    dev_t device;
  32.207      struct block_device *bd;
  32.208      struct gendisk *gd;
  32.209      struct xlbd_disk_info *di;
  32.210      int ret = 0, unused;
  32.211      request_queue_t *rq;
  32.212  
  32.213 -    device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
  32.214 -
  32.215 -    bd = bdget(device);
  32.216 +    bd = bdget(disk->dev);
  32.217      if (bd == NULL)
  32.218          return -1;
  32.219  
  32.220 -    gd = get_gendisk(device, &unused);
  32.221 +    gd = get_gendisk(disk->dev, &unused);
  32.222      di = gd->private_data;
  32.223  
  32.224 +#if 0 /* This is wrong: hda and hdb share same major, for example. */
  32.225      if (di->mi->usage != 0) {
  32.226 -        WPRINTK("disk removal failed: used [dev=%x]\n", device);
  32.227 +        WPRINTK("disk removal failed: used [dev=%x]\n", disk->dev);
  32.228          ret = -1;
  32.229          goto out;
  32.230      }
  32.231 +#endif
  32.232  
  32.233      rq = gd->queue;
  32.234      del_gendisk(gd);
  32.235 @@ -391,110 +349,19 @@ static int xlvbd_device_del(struct lvdis
  32.236      blk_cleanup_queue(rq);
  32.237  
  32.238      xlvbd_device_free(disk);
  32.239 -out:
  32.240      bdput(bd);
  32.241      return ret;
  32.242  }
  32.243  
  32.244 -static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
  32.245 +void xlvbd_del(blkif_vdev_t handle)
  32.246  {
  32.247 -    dev_t device;
  32.248 -    struct block_device *bd;
  32.249 -    struct gendisk *gd;
  32.250 -    int unused;
  32.251 -
  32.252 -    if ((ldisk->capacity == disk->capacity) && (ldisk->info == disk->info))
  32.253 -        return 0;    
  32.254 -
  32.255 -    device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
  32.256 -
  32.257 -    bd = bdget(device);
  32.258 -    if (bd == NULL)
  32.259 -        return -1;
  32.260 -
  32.261 -    gd = get_gendisk(device, &unused);
  32.262 -    set_capacity(gd, disk->capacity);    
  32.263 -    ldisk->capacity = disk->capacity;
  32.264 -
  32.265 -    bdput(bd);
  32.266 -
  32.267 -    return 0;
  32.268 -}
  32.269 -
  32.270 -void xlvbd_refresh(void)
  32.271 -{
  32.272 -    vdisk_t *newdisks;
  32.273 -    struct list_head *tmp, *tmp2;
  32.274 -    struct lvdisk *disk;
  32.275 -    int i, nr;
  32.276 +	struct lvdisk *i;
  32.277  
  32.278 -    newdisks = xlvbd_probe(&nr);
  32.279 -    if (newdisks == NULL) {
  32.280 -        WPRINTK("failed to probe\n");
  32.281 -        return;
  32.282 -    }
  32.283 -    
  32.284 -    i = 0;
  32.285 -    list_for_each_safe(tmp, tmp2, &vbds_list) {
  32.286 -        disk = list_entry(tmp, struct lvdisk, list);
  32.287 -        
  32.288 -        for (i = 0; i < nr; i++) {
  32.289 -            if ( !newdisks[i].device )
  32.290 -                continue;
  32.291 -            if ( disk->device == newdisks[i].device ) {
  32.292 -                xlvbd_device_update(disk, &newdisks[i]);
  32.293 -                newdisks[i].device = 0;
  32.294 -                break;
  32.295 -            }
  32.296 -        }
  32.297 -        if (i == nr) {
  32.298 -            xlvbd_device_del(disk);
  32.299 -            newdisks[i].device = 0;
  32.300 -        }
  32.301 -    }
  32.302 -    for (i = 0; i < nr; i++)
  32.303 -        if ( newdisks[i].device )
  32.304 -            xlvbd_device_add(&vbds_list, &newdisks[i]);
  32.305 -    kfree(newdisks);
  32.306 +	list_for_each_entry(i, &vbds_list, list) {
  32.307 +		if (i->handle == handle) {
  32.308 +			xlvbd_device_del(i);
  32.309 +			return;
  32.310 +		}
  32.311 +	}
  32.312 +	BUG();
  32.313  }
  32.314 -
  32.315 -/*
  32.316 - * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
  32.317 - * state. The VBDs need to be updated in this way when the domain is
  32.318 - * initialised and also each time we receive an XLBLK_UPDATE event.
  32.319 - */
  32.320 -void xlvbd_update_vbds(void)
  32.321 -{
  32.322 -    xlvbd_refresh();
  32.323 -}
  32.324 -
  32.325 -/*
  32.326 - * Set up all the linux device goop for the virtual block devices
  32.327 - * (vbd's) that we know about. Note that although from the backend
  32.328 - * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
  32.329 - * number, the domain creation tools conventionally allocate these
  32.330 - * numbers to correspond to those used by 'real' linux -- this is just
  32.331 - * for convenience as it means e.g. that the same /etc/fstab can be
  32.332 - * used when booting with or without Xen.
  32.333 - */
  32.334 -int xlvbd_init(void)
  32.335 -{
  32.336 -    int i, nr;
  32.337 -    vdisk_t *disks;
  32.338 -
  32.339 -    INIT_LIST_HEAD(&vbds_list);
  32.340 -
  32.341 -    memset(major_info, 0, sizeof(major_info));
  32.342 -    
  32.343 -    disks = xlvbd_probe(&nr);
  32.344 -    if (disks == NULL) {
  32.345 -        WPRINTK("failed to probe\n");
  32.346 -        return -1;
  32.347 -    }
  32.348 -
  32.349 -    for (i = 0; i < nr; i++)
  32.350 -        xlvbd_device_add(&vbds_list, &disks[i]);
  32.351 -
  32.352 -    kfree(disks);
  32.353 -    return 0;
  32.354 -}
    33.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Aug 19 10:50:15 2005 +0000
    33.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Aug 19 13:08:50 2005 +0000
    33.3 @@ -168,6 +168,8 @@ static int xenbus_dev_probe(struct devic
    33.4  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
    33.5  	const struct xenbus_device_id *id;
    33.6  
    33.7 +	BUG_ON(!dev->driver);
    33.8 +
    33.9  	if (!drv->probe)
   33.10  		return -ENODEV;
   33.11  
   33.12 @@ -531,10 +533,13 @@ static struct xenbus_watch be_watch = {
   33.13  static int suspend_dev(struct device *dev, void *data)
   33.14  {
   33.15  	int err = 0;
   33.16 -	struct xenbus_driver *drv = to_xenbus_driver(dev->driver);
   33.17 -	struct xenbus_device *xdev
   33.18 -		= container_of(dev, struct xenbus_device, dev);
   33.19 +	struct xenbus_driver *drv;
   33.20 +	struct xenbus_device *xdev;
   33.21  
   33.22 +	if (dev->driver == NULL)
   33.23 +		return 0;
   33.24 +	drv = to_xenbus_driver(dev->driver);
   33.25 +	xdev = container_of(dev, struct xenbus_device, dev);
   33.26  	if (drv->suspend)
   33.27  		err = drv->suspend(xdev);
   33.28  	if (err)
   33.29 @@ -545,10 +550,13 @@ static int suspend_dev(struct device *de
   33.30  static int resume_dev(struct device *dev, void *data)
   33.31  {
   33.32  	int err = 0;
   33.33 -	struct xenbus_driver *drv = to_xenbus_driver(dev->driver);
   33.34 -	struct xenbus_device *xdev
   33.35 -		= container_of(dev, struct xenbus_device, dev);
   33.36 +	struct xenbus_driver *drv;
   33.37 +	struct xenbus_device *xdev;
   33.38  
   33.39 +	if (dev->driver == NULL)
   33.40 +		return 0;
   33.41 +	drv = to_xenbus_driver(dev->driver);
   33.42 +	xdev = container_of(dev, struct xenbus_device, dev);
   33.43  	if (drv->resume)
   33.44  		err = drv->resume(xdev);
   33.45  	if (err)
    40.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 19 10:50:15 2005 +0000
    40.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 19 13:08:50 2005 +0000
    40.3 @@ -36,8 +36,10 @@ from xen.xend.server import controller
    40.4  from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
    40.5  from xen.xend.server import messages
    40.6  from xen.xend.server.channel import EventChannel, channelFactory
    40.7 +from xen.util.blkif import blkdev_name_to_number, expand_dev_name
    40.8  
    40.9  from xen.xend import sxp
   40.10 +from xen.xend import Blkctl
   40.11  from xen.xend.PrettyPrint import prettyprintstring
   40.12  from xen.xend.XendBootloader import bootloader
   40.13  from xen.xend.XendLogging import log
   40.14 @@ -380,6 +382,39 @@ class XendDomainInfo:
   40.15          return ctrl
   40.16  
   40.17      def createDevice(self, type, devconfig, change=False):
   40.18 +        if type == 'vbd':
   40.19 +
   40.20 +            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
   40.21 +
   40.22 +            devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev'))
   40.23 +
   40.24 +            # create backend db
   40.25 +            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
   40.26 +                                         (type, self.uuid, devnum))
   40.27 +
   40.28 +            # create frontend db
   40.29 +            db = self.db.addChild("/device/%s/%d" % (type, devnum))
   40.30 +            
   40.31 +            db['virtual-device'] = "%i" % devnum
   40.32 +            #db['backend'] = sxp.child_value(devconfig, 'backend', '0')
   40.33 +            db['backend'] = backdb.getPath()
   40.34 +            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
   40.35 +                                                          'backend', '0'))
   40.36 +
   40.37 +            backdb['frontend'] = db.getPath()
   40.38 +            (type, params) = string.split(sxp.child_value(devconfig, 'uname'), ':', 1)
   40.39 +            node = Blkctl.block('bind', type, params)
   40.40 +            backdb['frontend-id'] = "%i" % self.id
   40.41 +            backdb['physical-device'] = "%li" % blkdev_name_to_number(node)
   40.42 +            backdb.saveDB(save=True)
   40.43 +
   40.44 +            # Ok, super gross, this really doesn't belong in the frontend db...
   40.45 +            db['type'] = type
   40.46 +            db['node'] = node
   40.47 +            db['params'] = params
   40.48 +            db.saveDB(save=True)
   40.49 +            
   40.50 +            return
   40.51          ctrl = self.findDeviceController(type)
   40.52          return ctrl.createDevice(devconfig, recreate=self.recreate,
   40.53                                   change=change)
   40.54 @@ -671,6 +706,16 @@ class XendDomainInfo:
   40.55          for ctrl in self.getDeviceControllers():
   40.56              if ctrl.isDestroyed(): continue
   40.57              ctrl.destroyController(reboot=reboot)
   40.58 +        ddb = self.db.addChild("/device")
   40.59 +        for type in ddb.keys():
   40.60 +            if type == 'vbd':
   40.61 +                typedb = ddb.addChild(type)
   40.62 +                for dev in typedb.keys():
   40.63 +                    devdb = typedb.addChild(str(dev))
   40.64 +                    Blkctl.block('unbind', devdb['type'].getData(),
   40.65 +                                 devdb['node'].getData())
   40.66 +                    typedb[dev].delete()
   40.67 +                typedb.saveDB(save=True)
   40.68  
   40.69      def show(self):
   40.70          """Print virtual machine info.
   40.71 @@ -926,6 +971,7 @@ class XendDomainInfo:
   40.72          at creation time, for example when it uses NFS root.
   40.73  
   40.74          """
   40.75 +        return
   40.76          blkif = self.getDeviceController("vbd", error=False)
   40.77          if not blkif:
   40.78              blkif = self.createDeviceController("vbd")
    58.1 --- a/xen/include/public/io/blkif.h	Fri Aug 19 10:50:15 2005 +0000
    58.2 +++ b/xen/include/public/io/blkif.h	Fri Aug 19 13:08:50 2005 +0000
    58.3 @@ -18,7 +18,6 @@
    58.4  
    58.5  #define BLKIF_OP_READ      0
    58.6  #define BLKIF_OP_WRITE     1
    58.7 -#define BLKIF_OP_PROBE     2
    58.8  
    58.9  /* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
   58.10  #define BLKIF_RING_SIZE        64
   58.11 @@ -33,7 +32,7 @@
   58.12  typedef struct blkif_request {
   58.13      u8             operation;    /* BLKIF_OP_???                         */
   58.14      u8             nr_segments;  /* number of segments                   */
   58.15 -    blkif_vdev_t   device;       /* only for read/write requests         */
   58.16 +    blkif_vdev_t   handle;       /* only for read/write requests         */
   58.17      unsigned long  id;           /* private guest value, echoed in resp  */
   58.18      blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
   58.19      /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect                        */
   58.20 @@ -71,31 +70,8 @@ typedef struct blkif_response {
   58.21  
   58.22  DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t);
   58.23  
   58.24 -/*
   58.25 - * BLKIF_OP_PROBE:
   58.26 - * The request format for a probe request is constrained as follows:
   58.27 - *  @operation   == BLKIF_OP_PROBE
   58.28 - *  @nr_segments == size of probe buffer in pages
   58.29 - *  @device      == unused (zero)
   58.30 - *  @id          == any value (echoed in response message)
   58.31 - *  @sector_num  == unused (zero)
   58.32 - *  @frame_and_sects == list of page-sized buffers.
   58.33 - *                       (i.e., @first_sect == 0, @last_sect == 7).
   58.34 - * 
   58.35 - * The response is a list of vdisk_t elements copied into the out-of-band
   58.36 - * probe buffer. On success the response status field contains the number
   58.37 - * of vdisk_t elements.
   58.38 - */
   58.39 -
   58.40  #define VDISK_CDROM        0x1
   58.41  #define VDISK_REMOVABLE    0x2
   58.42  #define VDISK_READONLY     0x4
   58.43  
   58.44 -typedef struct vdisk {
   58.45 -    blkif_sector_t capacity;     /* Size in terms of 512-byte sectors.   */
   58.46 -    blkif_vdev_t   device;       /* Device number (opaque 16 bit value). */
   58.47 -    u16            info;         /* Device type and flags (VDISK_*).     */
   58.48 -    u16            sector_size;  /* Minimum alignment for requests.      */
   58.49 -} vdisk_t; /* 16 bytes */
   58.50 -
   58.51  #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */