ia64/xen-unstable

changeset 6274:7570087c2552

Switch block device setup/teardown over to xenbus/xenstore.
Remove device probing support over the device channel.
g/c all the control message code.
Simplify and cleanup internal function calling code (explicit arguments
instead of passing structs around).
Also includes:
Changed "readonly" to "read-only". "backend" is still not hyphenated, but
that seems to be fairly common usage.
Block backends use xenbus_dev_error, making debugging nicer.
The block front end is told explicitly what domid to use to talk to the
backend. There's speculation that fake domid-like tokens may be given
for cluster purposes in future, so deriving from the backend dir name is
not guaranteed to work. Backends still derive front-end ids, using a
xenbus helper (xenbus_uuid_to_domid).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Fri Aug 19 10:46:21 2005 +0000 (2005-08-19)
parents e355ae38c83b
children f22bbccf64ff
files linux-2.6-xen-sparse/arch/xen/kernel/reboot.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/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c xen/include/public/io/blkif.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 02:41:16 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Aug 19 10:46:21 2005 +0000
     1.3 @@ -65,13 +65,6 @@ static void __do_suspend(void)
     1.4  
     1.5      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
     1.6  	/* XXX SMH: yes it would :-( */	
     1.7 -#ifdef CONFIG_XEN_BLKDEV_FRONTEND
     1.8 -    extern void blkdev_suspend(void);
     1.9 -    extern void blkdev_resume(void);
    1.10 -#else
    1.11 -#define blkdev_suspend() do{}while(0)
    1.12 -#define blkdev_resume()  do{}while(0)
    1.13 -#endif
    1.14  
    1.15  #ifdef CONFIG_XEN_NETDEV_FRONTEND
    1.16      extern void netif_suspend(void);
    1.17 @@ -119,8 +112,6 @@ static void __do_suspend(void)
    1.18  
    1.19      netif_suspend();
    1.20  
    1.21 -    blkdev_suspend();
    1.22 -
    1.23      time_suspend();
    1.24  
    1.25  #ifdef CONFIG_SMP
    1.26 @@ -176,8 +167,6 @@ static void __do_suspend(void)
    1.27  
    1.28      time_resume();
    1.29  
    1.30 -    blkdev_resume();
    1.31 -
    1.32      netif_resume();
    1.33  
    1.34      usbif_resume();
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 02:41:16 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/Makefile	Fri Aug 19 10:46:21 2005 +0000
     2.3 @@ -1,2 +1,2 @@
     2.4  
     2.5 -obj-y	:= blkback.o control.o interface.o vbd.o
     2.6 +obj-y	:= blkback.o xenbus.o interface.o vbd.o
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 02:41:16 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Aug 19 10:46:21 2005 +0000
     3.3 @@ -104,7 +104,6 @@ static inline domid_t ID_TO_DOM(unsigned
     3.4  #endif
     3.5  
     3.6  static int do_block_io_op(blkif_t *blkif, int max_to_do);
     3.7 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
     3.8  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
     3.9  static void make_response(blkif_t *blkif, unsigned long id, 
    3.10                            unsigned short op, int st);
    3.11 @@ -349,10 +348,6 @@ static int do_block_io_op(blkif_t *blkif
    3.12              dispatch_rw_block_io(blkif, req);
    3.13              break;
    3.14  
    3.15 -        case BLKIF_OP_PROBE:
    3.16 -            dispatch_probe(blkif, req);
    3.17 -            break;
    3.18 -
    3.19          default:
    3.20              DPRINTK("error: unknown block io operation [%d]\n",
    3.21                      req->operation);
    3.22 @@ -365,66 +360,6 @@ static int do_block_io_op(blkif_t *blkif
    3.23      return more_to_do;
    3.24  }
    3.25  
    3.26 -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
    3.27 -{
    3.28 -    int rsp = BLKIF_RSP_ERROR;
    3.29 -    int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
    3.30 -
    3.31 -    /* We expect one buffer only. */
    3.32 -    if ( unlikely(req->nr_segments != 1) )
    3.33 -        goto out;
    3.34 -
    3.35 -    /* Make sure the buffer is page-sized. */
    3.36 -    if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) ||
    3.37 -         (blkif_last_sect(req->frame_and_sects[0]) != ((PAGE_SIZE/512)-1)) )
    3.38 -        goto out;
    3.39 -
    3.40 -#ifdef CONFIG_XEN_BLKDEV_GRANT
    3.41 -    {
    3.42 -        struct gnttab_map_grant_ref map;
    3.43 -
    3.44 -        map.host_addr = MMAP_VADDR(pending_idx, 0);
    3.45 -        map.flags = GNTMAP_host_map;
    3.46 -        map.ref = blkif_gref_from_fas(req->frame_and_sects[0]);
    3.47 -        map.dom = blkif->domid;
    3.48 -
    3.49 -        if ( unlikely(HYPERVISOR_grant_table_op(
    3.50 -                        GNTTABOP_map_grant_ref, &map, 1)))
    3.51 -            BUG();
    3.52 -
    3.53 -        if ( map.handle < 0 )
    3.54 -            goto out;
    3.55 -
    3.56 -        pending_handle(pending_idx, 0) = map.handle;
    3.57 -    }
    3.58 -#else /* else CONFIG_XEN_BLKDEV_GRANT */
    3.59 -
    3.60 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    3.61 -    /* Grab the real frontend out of the probe message. */
    3.62 -    if (req->frame_and_sects[1] == BLKTAP_COOKIE) 
    3.63 -        blkif->is_blktap = 1;
    3.64 -#endif
    3.65 -
    3.66 -
    3.67 -    if ( HYPERVISOR_update_va_mapping_otherdomain(
    3.68 -        MMAP_VADDR(pending_idx, 0),
    3.69 -        pfn_pte_ma(req->frame_and_sects[0] >> PAGE_SHIFT, PAGE_KERNEL),
    3.70 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    3.71 -        0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) )
    3.72 -#else
    3.73 -        0, blkif->domid) )
    3.74 -#endif
    3.75 -        goto out;
    3.76 -#endif /* endif CONFIG_XEN_BLKDEV_GRANT */
    3.77 -   
    3.78 -    rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), 
    3.79 -                    PAGE_SIZE / sizeof(vdisk_t));
    3.80 -
    3.81 - out:
    3.82 -    fast_flush_area(pending_idx, 1);
    3.83 -    make_response(blkif, req->id, req->operation, rsp);
    3.84 -}
    3.85 -
    3.86  static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
    3.87  {
    3.88      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
    3.89 @@ -460,7 +395,7 @@ static void dispatch_rw_block_io(blkif_t
    3.90          goto bad_descriptor;
    3.91      }
    3.92  
    3.93 -    preq.dev           = req->device;
    3.94 +    preq.dev           = req->handle;
    3.95      preq.sector_number = req->sector_number;
    3.96      preq.nr_sects      = 0;
    3.97  
    3.98 @@ -730,8 +665,8 @@ static int __init blkif_init(void)
    3.99          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
   3.100  #endif
   3.101  
   3.102 -    blkif_ctrlif_init();
   3.103 -    
   3.104 +    blkif_xenbus_init();
   3.105 +
   3.106  #ifdef CONFIG_XEN_BLKDEV_GRANT
   3.107      memset( pending_grant_handles,  BLKBACK_INVALID_HANDLE, MMAP_PAGES );
   3.108      printk(KERN_ALERT "Blkif backend is using grant tables.\n");
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 02:41:16 2005 +0000
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Fri Aug 19 10:46:21 2005 +0000
     4.3 @@ -13,7 +13,6 @@
     4.4  #include <asm/io.h>
     4.5  #include <asm/setup.h>
     4.6  #include <asm/pgalloc.h>
     4.7 -#include <asm-xen/ctrl_if.h>
     4.8  #include <asm-xen/evtchn.h>
     4.9  #include <asm-xen/hypervisor.h>
    4.10  #include <asm-xen/xen-public/io/blkif.h>
    4.11 @@ -47,6 +46,7 @@ typedef struct blkif_st {
    4.12      /* Physical parameters of the comms window. */
    4.13      unsigned long     shmem_frame;
    4.14      unsigned int      evtchn;
    4.15 +    unsigned int      remote_evtchn;
    4.16      /* Comms information. */
    4.17      blkif_back_ring_t blk_ring;
    4.18      /* VBDs attached to this interface. */
    4.19 @@ -81,17 +81,29 @@ void blkif_destroy(blkif_be_destroy_t *d
    4.20  void blkif_connect(blkif_be_connect_t *connect);
    4.21  int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
    4.22  void blkif_disconnect_complete(blkif_t *blkif);
    4.23 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
    4.24 +blkif_t *blkif_find(domid_t domid);
    4.25 +void free_blkif(blkif_t *blkif);
    4.26 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
    4.27 +
    4.28  #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
    4.29  #define blkif_put(_b)                             \
    4.30      do {                                          \
    4.31          if ( atomic_dec_and_test(&(_b)->refcnt) ) \
    4.32 -            blkif_disconnect_complete(_b);        \
    4.33 +            free_blkif(_b);			  \
    4.34      } while (0)
    4.35  
    4.36 -void vbd_create(blkif_be_vbd_create_t *create); 
    4.37 +struct vbd;
    4.38 +void vbd_free(blkif_t *blkif, struct vbd *vbd);
    4.39 +
    4.40 +/* Creates inactive vbd. */
    4.41 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice, int readonly);
    4.42 +int vbd_is_active(struct vbd *vbd);
    4.43 +void vbd_activate(blkif_t *blkif, struct vbd *vbd);
    4.44 +
    4.45 +unsigned long vbd_size(struct vbd *vbd);
    4.46 +unsigned int vbd_info(struct vbd *vbd);
    4.47 +unsigned long vbd_secsize(struct vbd *vbd);
    4.48  void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
    4.49 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
    4.50  void destroy_all_vbds(blkif_t *blkif);
    4.51  
    4.52  struct phys_req {
    4.53 @@ -104,10 +116,11 @@ struct phys_req {
    4.54  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
    4.55  
    4.56  void blkif_interface_init(void);
    4.57 -void blkif_ctrlif_init(void);
    4.58  
    4.59  void blkif_deschedule(blkif_t *blkif);
    4.60  
    4.61 +void blkif_xenbus_init(void);
    4.62 +
    4.63  irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
    4.64  
    4.65  #endif /* __BLKIF__BACKEND__COMMON_H__ */
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/control.c	Fri Aug 19 02:41:16 2005 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,61 +0,0 @@
     5.4 -/******************************************************************************
     5.5 - * arch/xen/drivers/blkif/backend/control.c
     5.6 - * 
     5.7 - * Routines for interfacing with the control plane.
     5.8 - * 
     5.9 - * Copyright (c) 2004, Keir Fraser
    5.10 - */
    5.11 -
    5.12 -#include "common.h"
    5.13 -
    5.14 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
    5.15 -{
    5.16 -    DPRINTK("Received blkif backend message, subtype=%d\n", msg->subtype);
    5.17 -    
    5.18 -    switch ( msg->subtype )
    5.19 -    {
    5.20 -    case CMSG_BLKIF_BE_CREATE:
    5.21 -        blkif_create((blkif_be_create_t *)&msg->msg[0]);
    5.22 -        break;        
    5.23 -    case CMSG_BLKIF_BE_DESTROY:
    5.24 -        blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
    5.25 -        break;        
    5.26 -    case CMSG_BLKIF_BE_CONNECT:
    5.27 -        blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
    5.28 -        break;        
    5.29 -    case CMSG_BLKIF_BE_DISCONNECT:
    5.30 -        if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
    5.31 -            return; /* Sending the response is deferred until later. */
    5.32 -        break;        
    5.33 -    case CMSG_BLKIF_BE_VBD_CREATE:
    5.34 -        vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
    5.35 -        break;
    5.36 -    case CMSG_BLKIF_BE_VBD_DESTROY:
    5.37 -        vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
    5.38 -        break;
    5.39 -    default:
    5.40 -        DPRINTK("Parse error while reading message subtype %d, len %d\n",
    5.41 -                msg->subtype, msg->length);
    5.42 -        msg->length = 0;
    5.43 -        break;
    5.44 -    }
    5.45 -
    5.46 -    ctrl_if_send_response(msg);
    5.47 -}
    5.48 -
    5.49 -void blkif_ctrlif_init(void)
    5.50 -{
    5.51 -    ctrl_msg_t cmsg;
    5.52 -    blkif_be_driver_status_t st;
    5.53 -
    5.54 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
    5.55 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
    5.56 -
    5.57 -    /* Send a driver-UP notification to the domain controller. */
    5.58 -    cmsg.type      = CMSG_BLKIF_BE;
    5.59 -    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS;
    5.60 -    cmsg.length    = sizeof(blkif_be_driver_status_t);
    5.61 -    st.status      = BLKIF_DRIVER_STATUS_UP;
    5.62 -    memcpy(cmsg.msg, &st, sizeof(st));
    5.63 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
    5.64 -}
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 02:41:16 2005 +0000
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Fri Aug 19 10:46:21 2005 +0000
     6.3 @@ -7,24 +7,135 @@
     6.4   */
     6.5  
     6.6  #include "common.h"
     6.7 +#include <asm-xen/ctrl_if.h>
     6.8 +#include <asm-xen/evtchn.h>
     6.9  
    6.10  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    6.11  #define VMALLOC_VMADDR(x) ((unsigned long)(x))
    6.12  #endif
    6.13  
    6.14  #define BLKIF_HASHSZ 1024
    6.15 -#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
    6.16 +#define BLKIF_HASH(_d) (((int)(_d))&(BLKIF_HASHSZ-1))
    6.17  
    6.18  static kmem_cache_t *blkif_cachep;
    6.19  static blkif_t      *blkif_hash[BLKIF_HASHSZ];
    6.20  
    6.21 -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
    6.22 +blkif_t *blkif_find(domid_t domid)
    6.23 +{
    6.24 +    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid)];
    6.25 +
    6.26 +    while (blkif) {
    6.27 +	if (blkif->domid == domid) {
    6.28 +	    blkif_get(blkif);
    6.29 +	    return blkif;
    6.30 +	}
    6.31 +        blkif = blkif->hash_next;
    6.32 +    }
    6.33 +
    6.34 +    blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
    6.35 +    if (!blkif)
    6.36 +	    return ERR_PTR(-ENOMEM);
    6.37 +
    6.38 +    memset(blkif, 0, sizeof(*blkif));
    6.39 +    blkif->domid = domid;
    6.40 +    blkif->status = DISCONNECTED;
    6.41 +    spin_lock_init(&blkif->vbd_lock);
    6.42 +    spin_lock_init(&blkif->blk_ring_lock);
    6.43 +    atomic_set(&blkif->refcnt, 1);
    6.44 +
    6.45 +    blkif->hash_next = blkif_hash[BLKIF_HASH(domid)];
    6.46 +    blkif_hash[BLKIF_HASH(domid)] = blkif;
    6.47 +    return blkif;
    6.48 +}
    6.49 +
    6.50 +#ifndef CONFIG_XEN_BLKDEV_GRANT
    6.51 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
    6.52 +			     unsigned long shared_page)
    6.53 +{
    6.54 +    return direct_remap_area_pages(&init_mm, localaddr,
    6.55 +				   shared_page<<PAGE_SHIFT, PAGE_SIZE,
    6.56 +				   __pgprot(_KERNPG_TABLE), blkif->domid);
    6.57 +}
    6.58 +
    6.59 +static void unmap_frontend_page(blkif_t *blkif)
    6.60 +{
    6.61 +}
    6.62 +#else
    6.63 +static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
    6.64 +			     unsigned long shared_page)
    6.65  {
    6.66 -    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
    6.67 -    while ( (blkif != NULL) && 
    6.68 -            ((blkif->domid != domid) || (blkif->handle != handle)) )
    6.69 -        blkif = blkif->hash_next;
    6.70 -    return blkif;
    6.71 +    struct gnttab_map_grant_ref op;
    6.72 +    op.host_addr = localaddr;
    6.73 +    op.flags = GNTMAP_host_map;
    6.74 +    op.ref = shared_page;
    6.75 +    op.dom = blkif->domid;
    6.76 +       
    6.77 +    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
    6.78 +
    6.79 +    if (op.handle < 0) {
    6.80 +	DPRINTK(" Grant table operation failure !\n");
    6.81 +	return op.handle;
    6.82 +    }
    6.83 +
    6.84 +    blkif->shmem_ref = shared_page;
    6.85 +    blkif->shmem_handle = op.handle;
    6.86 +    blkif->shmem_vaddr = localaddr;
    6.87 +    return 0;
    6.88 +}
    6.89 +
    6.90 +static void unmap_frontend_page(blkif_t *blkif)
    6.91 +{
    6.92 +    struct gnttab_unmap_grant_ref op;
    6.93 +
    6.94 +    op.host_addr = blkif->shmem_vaddr;
    6.95 +    op.handle = blkif->shmem_handle;
    6.96 +    op.dev_bus_addr = 0;
    6.97 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
    6.98 +}
    6.99 +#endif /* CONFIG_XEN_BLKDEV_GRANT */
   6.100 +
   6.101 +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
   6.102 +{
   6.103 +    struct vm_struct *vma;
   6.104 +    blkif_sring_t *sring;
   6.105 +    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
   6.106 +    int err;
   6.107 +
   6.108 +    BUG_ON(blkif->remote_evtchn);
   6.109 +
   6.110 +    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   6.111 +	return -ENOMEM;
   6.112 +
   6.113 +    err = map_frontend_page(blkif, VMALLOC_VMADDR(vma->addr), shared_page);
   6.114 +    if (err) {
   6.115 +        vfree(vma->addr);
   6.116 +	return err;
   6.117 +    }
   6.118 +
   6.119 +    op.u.bind_interdomain.dom1 = DOMID_SELF;
   6.120 +    op.u.bind_interdomain.dom2 = blkif->domid;
   6.121 +    op.u.bind_interdomain.port1 = 0;
   6.122 +    op.u.bind_interdomain.port2 = evtchn;
   6.123 +    err = HYPERVISOR_event_channel_op(&op);
   6.124 +    if (err) {
   6.125 +	unmap_frontend_page(blkif);
   6.126 +	vfree(vma->addr);
   6.127 +	return err;
   6.128 +    }
   6.129 +
   6.130 +    blkif->evtchn = op.u.bind_interdomain.port1;
   6.131 +    blkif->remote_evtchn = evtchn;
   6.132 +
   6.133 +    sring = (blkif_sring_t *)vma->addr;
   6.134 +    SHARED_RING_INIT(sring);
   6.135 +    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
   6.136 +
   6.137 +    bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
   6.138 +			      blkif);
   6.139 +    blkif->status        = CONNECTED;
   6.140 +    blkif->shmem_frame   = shared_page;
   6.141 +
   6.142 +    return 0;
   6.143  }
   6.144  
   6.145  static void __blkif_disconnect_complete(void *arg)
   6.146 @@ -32,21 +143,13 @@ static void __blkif_disconnect_complete(
   6.147      blkif_t              *blkif = (blkif_t *)arg;
   6.148      ctrl_msg_t            cmsg;
   6.149      blkif_be_disconnect_t disc;
   6.150 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.151 -    struct gnttab_unmap_grant_ref op;
   6.152 -#endif
   6.153  
   6.154      /*
   6.155       * These can't be done in blkif_disconnect() because at that point there
   6.156       * may be outstanding requests at the disc whose asynchronous responses
   6.157       * must still be notified to the remote driver.
   6.158       */
   6.159 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.160 -    op.host_addr      = blkif->shmem_vaddr;
   6.161 -    op.handle         = blkif->shmem_handle;
   6.162 -    op.dev_bus_addr   = 0;
   6.163 -    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   6.164 -#endif
   6.165 +    unmap_frontend_page(blkif);
   6.166      vfree(blkif->blk_ring.sring);
   6.167  
   6.168      /* Construct the deferred response message. */
   6.169 @@ -81,200 +184,33 @@ void blkif_disconnect_complete(blkif_t *
   6.170      schedule_work(&blkif->work);
   6.171  }
   6.172  
   6.173 -void blkif_create(blkif_be_create_t *create)
   6.174 +void free_blkif(blkif_t *blkif)
   6.175  {
   6.176 -    domid_t       domid  = create->domid;
   6.177 -    unsigned int  handle = create->blkif_handle;
   6.178 -    blkif_t     **pblkif, *blkif;
   6.179 -
   6.180 -    if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL )
   6.181 -    {
   6.182 -        DPRINTK("Could not create blkif: out of memory\n");
   6.183 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.184 -        return;
   6.185 -    }
   6.186 +    blkif_t     **pblkif;
   6.187 +    evtchn_op_t op = { .cmd = EVTCHNOP_close };
   6.188  
   6.189 -    memset(blkif, 0, sizeof(*blkif));
   6.190 -    blkif->domid  = domid;
   6.191 -    blkif->handle = handle;
   6.192 -    blkif->status = DISCONNECTED;
   6.193 -    spin_lock_init(&blkif->vbd_lock);
   6.194 -    spin_lock_init(&blkif->blk_ring_lock);
   6.195 -    atomic_set(&blkif->refcnt, 0);
   6.196 +    op.u.close.port = blkif->evtchn;
   6.197 +    op.u.close.dom = DOMID_SELF;
   6.198 +    HYPERVISOR_event_channel_op(&op);
   6.199 +    op.u.close.port = blkif->remote_evtchn;
   6.200 +    op.u.close.dom = blkif->domid;
   6.201 +    HYPERVISOR_event_channel_op(&op);
   6.202  
   6.203 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
   6.204 -    while ( *pblkif != NULL )
   6.205 +    if (blkif->evtchn)
   6.206 +        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
   6.207 +
   6.208 +    if (blkif->blk_ring.sring)
   6.209 +	    vfree(blkif->blk_ring.sring);
   6.210 +
   6.211 +    pblkif = &blkif_hash[BLKIF_HASH(blkif->domid)];
   6.212 +    while ( *pblkif != blkif )
   6.213      {
   6.214 -        if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
   6.215 -        {
   6.216 -            DPRINTK("Could not create blkif: already exists\n");
   6.217 -            create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
   6.218 -            kmem_cache_free(blkif_cachep, blkif);
   6.219 -            return;
   6.220 -        }
   6.221 +	BUG_ON(!*pblkif);
   6.222          pblkif = &(*pblkif)->hash_next;
   6.223      }
   6.224 -
   6.225 -    blkif->hash_next = *pblkif;
   6.226 -    *pblkif = blkif;
   6.227 -
   6.228 -    DPRINTK("Successfully created blkif\n");
   6.229 -    create->status = BLKIF_BE_STATUS_OKAY;
   6.230 -}
   6.231 -
   6.232 -void blkif_destroy(blkif_be_destroy_t *destroy)
   6.233 -{
   6.234 -    domid_t       domid  = destroy->domid;
   6.235 -    unsigned int  handle = destroy->blkif_handle;
   6.236 -    blkif_t     **pblkif, *blkif;
   6.237 -
   6.238 -    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
   6.239 -    while ( (blkif = *pblkif) != NULL )
   6.240 -    {
   6.241 -        if ( (blkif->domid == domid) && (blkif->handle == handle) )
   6.242 -        {
   6.243 -            if ( blkif->status != DISCONNECTED )
   6.244 -                goto still_connected;
   6.245 -            goto destroy;
   6.246 -        }
   6.247 -        pblkif = &blkif->hash_next;
   6.248 -    }
   6.249 -
   6.250 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.251 -    return;
   6.252 -
   6.253 - still_connected:
   6.254 -    destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
   6.255 -    return;
   6.256 -
   6.257 - destroy:
   6.258      *pblkif = blkif->hash_next;
   6.259      destroy_all_vbds(blkif);
   6.260      kmem_cache_free(blkif_cachep, blkif);
   6.261 -    destroy->status = BLKIF_BE_STATUS_OKAY;
   6.262 -}
   6.263 -
   6.264 -void blkif_connect(blkif_be_connect_t *connect)
   6.265 -{
   6.266 -    domid_t        domid  = connect->domid;
   6.267 -    unsigned int   handle = connect->blkif_handle;
   6.268 -    unsigned int   evtchn = connect->evtchn;
   6.269 -    unsigned long  shmem_frame = connect->shmem_frame;
   6.270 -    struct vm_struct *vma;
   6.271 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   6.272 -    int ref = connect->shmem_ref;
   6.273 -#else
   6.274 -    pgprot_t       prot;
   6.275 -    int            error;
   6.276 -#endif
   6.277 -    blkif_t       *blkif;
   6.278 -    blkif_sring_t *sring;
   6.279 -
   6.280 -    blkif = blkif_find_by_handle(domid, handle);
   6.281 -    if ( unlikely(blkif == NULL) )
   6.282 -    {
   6.283 -        DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", 
   6.284 -                connect->domid, connect->blkif_handle); 
   6.285 -        connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.286 -        return;
   6.287 -    }
   6.288 -
   6.289 -    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   6.290 -    {
   6.291 -        connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.292 -        return;
   6.293 -    }
   6.294 -
   6.295 -#ifndef CONFIG_XEN_BLKDEV_GRANT
   6.296 -    prot = __pgprot(_KERNPG_TABLE);
   6.297 -    error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr),
   6.298 -                                    shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
   6.299 -                                    prot, domid);
   6.300 -    if ( error != 0 )
   6.301 -    {
   6.302 -        if ( error == -ENOMEM )
   6.303 -            connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
   6.304 -        else if ( error == -EFAULT )
   6.305 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   6.306 -        else
   6.307 -            connect->status = BLKIF_BE_STATUS_ERROR;
   6.308 -        vfree(vma->addr);
   6.309 -        return;
   6.310 -    }
   6.311 -#else
   6.312 -    { /* Map: Use the Grant table reference */
   6.313 -        struct gnttab_map_grant_ref op;
   6.314 -        op.host_addr      = VMALLOC_VMADDR(vma->addr);
   6.315 -        op.flags          = GNTMAP_host_map;
   6.316 -        op.ref            = ref;
   6.317 -        op.dom            = domid;
   6.318 -       
   6.319 -        BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   6.320 -       
   6.321 -        handle = op.handle;
   6.322 -       
   6.323 -        if (op.handle < 0) {
   6.324 -            DPRINTK(" Grant table operation failure !\n");
   6.325 -            connect->status = BLKIF_BE_STATUS_MAPPING_ERROR;
   6.326 -            vfree(vma->addr);
   6.327 -            return;
   6.328 -        }
   6.329 -
   6.330 -        blkif->shmem_ref = ref;
   6.331 -        blkif->shmem_handle = handle;
   6.332 -        blkif->shmem_vaddr = VMALLOC_VMADDR(vma->addr);
   6.333 -    }
   6.334 -#endif
   6.335 -
   6.336 -    if ( blkif->status != DISCONNECTED )
   6.337 -    {
   6.338 -        connect->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
   6.339 -        vfree(vma->addr);
   6.340 -        return;
   6.341 -    }
   6.342 -    sring = (blkif_sring_t *)vma->addr;
   6.343 -    SHARED_RING_INIT(sring);
   6.344 -    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
   6.345 -    
   6.346 -    blkif->evtchn        = evtchn;
   6.347 -    blkif->shmem_frame   = shmem_frame;
   6.348 -    blkif->status        = CONNECTED;
   6.349 -    blkif_get(blkif);
   6.350 -
   6.351 -    bind_evtchn_to_irqhandler(
   6.352 -        blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
   6.353 -
   6.354 -    connect->status = BLKIF_BE_STATUS_OKAY;
   6.355 -}
   6.356 -
   6.357 -int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id)
   6.358 -{
   6.359 -    domid_t       domid  = disconnect->domid;
   6.360 -    unsigned int  handle = disconnect->blkif_handle;
   6.361 -    blkif_t      *blkif;
   6.362 -
   6.363 -    blkif = blkif_find_by_handle(domid, handle);
   6.364 -    if ( unlikely(blkif == NULL) )
   6.365 -    {
   6.366 -        DPRINTK("blkif_disconnect attempted for non-existent blkif"
   6.367 -                " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); 
   6.368 -        disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   6.369 -        return 1; /* Caller will send response error message. */
   6.370 -    }
   6.371 -
   6.372 -    if ( blkif->status == CONNECTED )
   6.373 -    {
   6.374 -        blkif->status = DISCONNECTING;
   6.375 -        blkif->disconnect_rspid = rsp_id;
   6.376 -        wmb(); /* Let other CPUs see the status change. */
   6.377 -        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
   6.378 -        blkif_deschedule(blkif);
   6.379 -        blkif_put(blkif);
   6.380 -        return 0; /* Caller should not send response message. */
   6.381 -    }
   6.382 -
   6.383 -    disconnect->status = BLKIF_BE_STATUS_OKAY;
   6.384 -    return 1;
   6.385  }
   6.386  
   6.387  void __init blkif_interface_init(void)
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 02:41:16 2005 +0000
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Fri Aug 19 10:46:21 2005 +0000
     7.3 @@ -11,13 +11,16 @@
     7.4   */
     7.5  
     7.6  #include "common.h"
     7.7 +#include <asm-xen/xenbus.h>
     7.8  
     7.9  struct vbd { 
    7.10 -    blkif_vdev_t   vdevice;     /* what the domain refers to this vbd as */
    7.11 +    blkif_vdev_t   handle;     /* what the domain refers to this vbd as */
    7.12      unsigned char  readonly;    /* Non-zero -> read-only */
    7.13      unsigned char  type;        /* VDISK_xxx */
    7.14      blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
    7.15      struct block_device *bdev;
    7.16 +
    7.17 +    int active;
    7.18      rb_node_t      rb;          /* for linking into R-B tree lookup struct */
    7.19  }; 
    7.20  
    7.21 @@ -33,57 +36,45 @@ static inline dev_t vbd_map_devnum(blkif
    7.22  #define bdev_hardsect_size(_b) 512
    7.23  #endif
    7.24  
    7.25 -void vbd_create(blkif_be_vbd_create_t *create) 
    7.26 +unsigned long vbd_size(struct vbd *vbd)
    7.27 +{
    7.28 +	return vbd_sz(vbd);
    7.29 +}
    7.30 +
    7.31 +unsigned int vbd_info(struct vbd *vbd)
    7.32 +{
    7.33 +	return vbd->type | (vbd->readonly?VDISK_READONLY:0);
    7.34 +}
    7.35 +
    7.36 +unsigned long vbd_secsize(struct vbd *vbd)
    7.37 +{
    7.38 +	return bdev_hardsect_size(vbd->bdev);
    7.39 +}
    7.40 +
    7.41 +int vbd_is_active(struct vbd *vbd)
    7.42 +{
    7.43 +	return vbd->active;
    7.44 +}
    7.45 +
    7.46 +struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
    7.47 +		       blkif_pdev_t pdevice, int readonly)
    7.48  {
    7.49      struct vbd  *vbd; 
    7.50 -    rb_node_t  **rb_p, *rb_parent = NULL;
    7.51 -    blkif_t     *blkif;
    7.52 -    blkif_vdev_t vdevice = create->vdevice;
    7.53 -
    7.54 -    blkif = blkif_find_by_handle(create->domid, create->blkif_handle);
    7.55 -    if ( unlikely(blkif == NULL) )
    7.56 -    {
    7.57 -        DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", 
    7.58 -                create->domid, create->blkif_handle); 
    7.59 -        create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
    7.60 -        return;
    7.61 -    }
    7.62 -
    7.63 -    rb_p = &blkif->vbd_rb.rb_node;
    7.64 -    while ( *rb_p != NULL )
    7.65 -    {
    7.66 -        rb_parent = *rb_p;
    7.67 -        vbd = rb_entry(rb_parent, struct vbd, rb);
    7.68 -        if ( vdevice < vbd->vdevice )
    7.69 -        {
    7.70 -            rb_p = &rb_parent->rb_left;
    7.71 -        }
    7.72 -        else if ( vdevice > vbd->vdevice )
    7.73 -        {
    7.74 -            rb_p = &rb_parent->rb_right;
    7.75 -        }
    7.76 -        else
    7.77 -        {
    7.78 -            DPRINTK("vbd_create attempted for already existing vbd\n");
    7.79 -            create->status = BLKIF_BE_STATUS_VBD_EXISTS;
    7.80 -            return;
    7.81 -        }
    7.82 -    }
    7.83  
    7.84      if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
    7.85      {
    7.86          DPRINTK("vbd_create: out of memory\n");
    7.87 -        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    7.88 -        return;
    7.89 +	return ERR_PTR(-ENOMEM);
    7.90      }
    7.91  
    7.92 -    vbd->vdevice  = vdevice; 
    7.93 -    vbd->readonly = create->readonly;
    7.94 +    vbd->handle   = handle; 
    7.95 +    vbd->readonly = readonly;
    7.96      vbd->type     = 0;
    7.97 +    vbd->active   = 0;
    7.98  
    7.99 -    /* Mask to 16-bit for compatibility with old tools */
   7.100 -    vbd->pdevice  = create->pdevice & 0xffff;
   7.101 +    vbd->pdevice  = pdevice;
   7.102  
   7.103 +    /* FIXME: Who frees vbd on failure? --RR */
   7.104  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   7.105      vbd->bdev = open_by_devnum(
   7.106          vbd_map_devnum(vbd->pdevice),
   7.107 @@ -91,16 +82,14 @@ void vbd_create(blkif_be_vbd_create_t *c
   7.108      if ( IS_ERR(vbd->bdev) )
   7.109      {
   7.110          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.111 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.112 -        return;
   7.113 +        return ERR_PTR(-ENOENT);
   7.114      }
   7.115  
   7.116      if ( (vbd->bdev->bd_disk == NULL) )
   7.117      {
   7.118          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.119 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.120          bdev_put(vbd->bdev);
   7.121 -        return;
   7.122 +        return ERR_PTR(-ENOENT);
   7.123      }
   7.124  
   7.125      if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
   7.126 @@ -112,62 +101,64 @@ void vbd_create(blkif_be_vbd_create_t *c
   7.127      if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
   7.128      {
   7.129          DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
   7.130 -        create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
   7.131 -        return;
   7.132 +        return ERR_PTR(-ENOENT);
   7.133      }
   7.134  #endif
   7.135  
   7.136 +    DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
   7.137 +            handle, blkif->domid);
   7.138 +    return vbd;
   7.139 +}
   7.140 +
   7.141 +void vbd_activate(blkif_t *blkif, struct vbd *vbd)
   7.142 +{
   7.143 +    rb_node_t  **rb_p, *rb_parent = NULL;
   7.144 +    struct vbd *i;
   7.145 +    BUG_ON(vbd_is_active(vbd));
   7.146 +
   7.147 +    /* Find where to put it. */
   7.148 +    rb_p = &blkif->vbd_rb.rb_node;
   7.149 +    while ( *rb_p != NULL )
   7.150 +    {
   7.151 +        rb_parent = *rb_p;
   7.152 +        i = rb_entry(rb_parent, struct vbd, rb);
   7.153 +        if ( vbd->handle < i->handle )
   7.154 +        {
   7.155 +            rb_p = &rb_parent->rb_left;
   7.156 +        }
   7.157 +        else if ( vbd->handle > i->handle )
   7.158 +        {
   7.159 +            rb_p = &rb_parent->rb_right;
   7.160 +        }
   7.161 +        else
   7.162 +        {
   7.163 +	    /* We never create two of same vbd, so not possible. */
   7.164 +	    BUG();
   7.165 +        }
   7.166 +    }
   7.167 +
   7.168 +    /* Now we're active. */
   7.169 +    vbd->active = 1;
   7.170 +    blkif_get(blkif);
   7.171 +
   7.172      spin_lock(&blkif->vbd_lock);
   7.173      rb_link_node(&vbd->rb, rb_parent, rb_p);
   7.174      rb_insert_color(&vbd->rb, &blkif->vbd_rb);
   7.175      spin_unlock(&blkif->vbd_lock);
   7.176 -
   7.177 -    DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
   7.178 -            vdevice, create->domid);
   7.179 -    create->status = BLKIF_BE_STATUS_OKAY;
   7.180  }
   7.181  
   7.182 -
   7.183 -void vbd_destroy(blkif_be_vbd_destroy_t *destroy) 
   7.184 +void vbd_free(blkif_t *blkif, struct vbd *vbd)
   7.185  {
   7.186 -    blkif_t           *blkif;
   7.187 -    struct vbd        *vbd;
   7.188 -    rb_node_t         *rb;
   7.189 -    blkif_vdev_t       vdevice = destroy->vdevice;
   7.190 -
   7.191 -    blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
   7.192 -    if ( unlikely(blkif == NULL) )
   7.193 -    {
   7.194 -        DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", 
   7.195 -                destroy->domid, destroy->blkif_handle); 
   7.196 -        destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   7.197 -        return;
   7.198 +    if (vbd_is_active(vbd)) {
   7.199 +	spin_lock(&blkif->vbd_lock);
   7.200 +	rb_erase(&vbd->rb, &blkif->vbd_rb);
   7.201 +	spin_unlock(&blkif->vbd_lock);
   7.202 +	blkif_put(blkif);
   7.203      }
   7.204 -
   7.205 -    rb = blkif->vbd_rb.rb_node;
   7.206 -    while ( rb != NULL )
   7.207 -    {
   7.208 -        vbd = rb_entry(rb, struct vbd, rb);
   7.209 -        if ( vdevice < vbd->vdevice )
   7.210 -            rb = rb->rb_left;
   7.211 -        else if ( vdevice > vbd->vdevice )
   7.212 -            rb = rb->rb_right;
   7.213 -        else
   7.214 -            goto found;
   7.215 -    }
   7.216 -
   7.217 -    destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   7.218 -    return;
   7.219 -
   7.220 - found:
   7.221 -    spin_lock(&blkif->vbd_lock);
   7.222 -    rb_erase(rb, &blkif->vbd_rb);
   7.223 -    spin_unlock(&blkif->vbd_lock);
   7.224      bdev_put(vbd->bdev);
   7.225      kfree(vbd);
   7.226  }
   7.227  
   7.228 -
   7.229  void destroy_all_vbds(blkif_t *blkif)
   7.230  {
   7.231      struct vbd *vbd;
   7.232 @@ -183,74 +174,12 @@ void destroy_all_vbds(blkif_t *blkif)
   7.233          bdev_put(vbd->bdev);
   7.234          kfree(vbd);
   7.235          spin_lock(&blkif->vbd_lock);
   7.236 +        blkif_put(blkif);
   7.237      }
   7.238  
   7.239      spin_unlock(&blkif->vbd_lock);
   7.240  }
   7.241  
   7.242 -
   7.243 -static void vbd_probe_single(
   7.244 -    blkif_t *blkif, vdisk_t *vbd_info, struct vbd *vbd)
   7.245 -{
   7.246 -    vbd_info->device      = vbd->vdevice; 
   7.247 -    vbd_info->info        = vbd->type | (vbd->readonly ? VDISK_READONLY : 0);
   7.248 -    vbd_info->capacity    = vbd_sz(vbd);
   7.249 -    vbd_info->sector_size = bdev_hardsect_size(vbd->bdev);
   7.250 -}
   7.251 -
   7.252 -
   7.253 -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds)
   7.254 -{
   7.255 -    int        rc = 0, nr_vbds = 0;
   7.256 -    rb_node_t *rb;
   7.257 -
   7.258 -    spin_lock(&blkif->vbd_lock);
   7.259 -
   7.260 -    if ( (rb = blkif->vbd_rb.rb_node) == NULL )
   7.261 -        goto out;
   7.262 -
   7.263 - new_subtree:
   7.264 -    /* STEP 1. Find least node (it'll be left-most). */
   7.265 -    while ( rb->rb_left != NULL )
   7.266 -        rb = rb->rb_left;
   7.267 -
   7.268 -    for ( ; ; )
   7.269 -    {
   7.270 -        /* STEP 2. Dealt with left subtree. Now process current node. */
   7.271 -        vbd_probe_single(blkif, &vbd_info[nr_vbds],
   7.272 -                         rb_entry(rb, struct vbd, rb));
   7.273 -        if ( ++nr_vbds == max_vbds )
   7.274 -            goto out;
   7.275 -
   7.276 -        /* STEP 3. Process right subtree, if any. */
   7.277 -        if ( rb->rb_right != NULL )
   7.278 -        {
   7.279 -            rb = rb->rb_right;
   7.280 -            goto new_subtree;
   7.281 -        }
   7.282 -
   7.283 -        /* STEP 4. Done both subtrees. Head back through ancesstors. */
   7.284 -        for ( ; ; ) 
   7.285 -        {
   7.286 -            /* We're done when we get back to the root node. */
   7.287 -            if ( rb->rb_parent == NULL )
   7.288 -                goto out;
   7.289 -            /* If we are left of parent, then parent is next to process. */
   7.290 -            if ( rb->rb_parent->rb_left == rb )
   7.291 -                break;
   7.292 -            /* If we are right of parent, then we climb to grandparent. */
   7.293 -            rb = rb->rb_parent;
   7.294 -        }
   7.295 -
   7.296 -        rb = rb->rb_parent;
   7.297 -    }
   7.298 -
   7.299 - out:
   7.300 -    spin_unlock(&blkif->vbd_lock);
   7.301 -    return (rc == 0) ? nr_vbds : rc;  
   7.302 -}
   7.303 -
   7.304 -
   7.305  int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
   7.306  {
   7.307      struct vbd *vbd;
   7.308 @@ -264,9 +193,9 @@ int vbd_translate(struct phys_req *req, 
   7.309      while ( rb != NULL )
   7.310      {
   7.311          vbd = rb_entry(rb, struct vbd, rb);
   7.312 -        if ( req->dev < vbd->vdevice )
   7.313 +        if ( req->dev < vbd->handle )
   7.314              rb = rb->rb_left;
   7.315 -        else if ( req->dev > vbd->vdevice )
   7.316 +        else if ( req->dev > vbd->handle )
   7.317              rb = rb->rb_right;
   7.318          else
   7.319              goto found;
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 02:41:16 2005 +0000
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Aug 19 10:46:21 2005 +0000
     8.3 @@ -53,8 +53,8 @@
     8.4  #include <linux/sched.h>
     8.5  #include <linux/interrupt.h>
     8.6  #include <scsi/scsi.h>
     8.7 -#include <asm-xen/ctrl_if.h>
     8.8  #include <asm-xen/evtchn.h>
     8.9 +#include <asm-xen/xenbus.h>
    8.10  #ifdef CONFIG_XEN_BLKDEV_GRANT
    8.11  #include <asm-xen/xen-public/grant_table.h>
    8.12  #include <asm-xen/gnttab.h>
    8.13 @@ -65,22 +65,14 @@ typedef unsigned char byte; /* from linu
    8.14  /* Control whether runtime update of vbds is enabled. */
    8.15  #define ENABLE_VBD_UPDATE 1
    8.16  
    8.17 -#if ENABLE_VBD_UPDATE
    8.18 -static void vbd_update(void);
    8.19 -#else
    8.20 -static void vbd_update(void){};
    8.21 -#endif
    8.22 -
    8.23  #define BLKIF_STATE_CLOSED       0
    8.24  #define BLKIF_STATE_DISCONNECTED 1
    8.25  #define BLKIF_STATE_CONNECTED    2
    8.26  
    8.27 -static int blkif_handle = 0;
    8.28  static unsigned int blkif_state = BLKIF_STATE_CLOSED;
    8.29  static unsigned int blkif_evtchn = 0;
    8.30 -
    8.31 -static int blkif_control_rsp_valid;
    8.32 -static blkif_response_t blkif_control_rsp;
    8.33 +static unsigned int blkif_vbds = 0;
    8.34 +static unsigned int blkif_vbds_connected = 0;
    8.35  
    8.36  static blkif_front_ring_t blk_ring;
    8.37  
    8.38 @@ -105,7 +97,7 @@ static int recovery = 0; /* Recovery in 
    8.39  
    8.40  static void kick_pending_request_queues(void);
    8.41  
    8.42 -int __init xlblk_init(void);
    8.43 +static int __init xlblk_init(void);
    8.44  
    8.45  static void blkif_completion(struct blk_shadow *s);
    8.46  
    8.47 @@ -179,19 +171,6 @@ static inline void flush_requests(void)
    8.48  
    8.49  module_init(xlblk_init);
    8.50  
    8.51 -#if ENABLE_VBD_UPDATE
    8.52 -static void update_vbds_task(void *unused)
    8.53 -{ 
    8.54 -    xlvbd_update_vbds();
    8.55 -}
    8.56 -
    8.57 -static void vbd_update(void)
    8.58 -{
    8.59 -    static DECLARE_WORK(update_tq, update_vbds_task, NULL);
    8.60 -    schedule_work(&update_tq);
    8.61 -}
    8.62 -#endif /* ENABLE_VBD_UPDATE */
    8.63 -
    8.64  static struct xlbd_disk_info *head_waiting = NULL;
    8.65  static void kick_pending_request_queues(void)
    8.66  {
    8.67 @@ -221,16 +200,7 @@ int blkif_open(struct inode *inode, stru
    8.68  
    8.69  int blkif_release(struct inode *inode, struct file *filep)
    8.70  {
    8.71 -    struct gendisk *gd = inode->i_bdev->bd_disk;
    8.72 -    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
    8.73 -
    8.74 -    /*
    8.75 -     * When usage drops to zero it may allow more VBD updates to occur.
    8.76 -     * Update of usage count is protected by a per-device semaphore.
    8.77 -     */
    8.78 -    if ( --di->mi->usage == 0 )
    8.79 -        vbd_update();
    8.80 -
    8.81 +    /* FIXME: This is where we can actually free up majors, etc. --RR */
    8.82      return 0;
    8.83  }
    8.84  
    8.85 @@ -301,7 +271,7 @@ static int blkif_queue_request(struct re
    8.86      ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
    8.87          BLKIF_OP_READ;
    8.88      ring_req->sector_number = (blkif_sector_t)req->sector;
    8.89 -    ring_req->device = di->xd_device;
    8.90 +    ring_req->handle = di->handle;
    8.91  
    8.92      ring_req->nr_segments = 0;
    8.93      rq_for_each_bio(bio, req)
    8.94 @@ -446,10 +416,6 @@ static irqreturn_t blkif_int(int irq, vo
    8.95              end_that_request_last(req);
    8.96  
    8.97              break;
    8.98 -        case BLKIF_OP_PROBE:
    8.99 -            memcpy(&blkif_control_rsp, bret, sizeof(*bret));
   8.100 -            blkif_control_rsp_valid = 1;
   8.101 -            break;
   8.102          default:
   8.103              BUG();
   8.104          }
   8.105 @@ -483,28 +449,6 @@ static int nr_pending;
   8.106  #define blkif_io_lock io_request_lock
   8.107  
   8.108  /*============================================================================*/
   8.109 -#if ENABLE_VBD_UPDATE
   8.110 -
   8.111 -/*
   8.112 - * blkif_update_int/update-vbds_task - handle VBD update events.
   8.113 - *  Schedule a task for keventd to run, which will update the VBDs and perform 
   8.114 - *  the corresponding updates to our view of VBD state.
   8.115 - */
   8.116 -static void update_vbds_task(void *unused)
   8.117 -{ 
   8.118 -    xlvbd_update_vbds();
   8.119 -}
   8.120 -
   8.121 -static void vbd_update(void)
   8.122 -{
   8.123 -    static struct tq_struct update_tq;
   8.124 -    update_tq.routine = update_vbds_task;
   8.125 -    schedule_task(&update_tq);
   8.126 -}
   8.127 -
   8.128 -#endif /* ENABLE_VBD_UPDATE */
   8.129 -/*============================================================================*/
   8.130 -
   8.131  static void kick_pending_request_queues(void)
   8.132  {
   8.133      /* We kick pending request queues if the ring is reasonably empty. */
   8.134 @@ -757,7 +701,8 @@ static int blkif_queue_request(unsigned 
   8.135                                 char *          buffer,
   8.136                                 unsigned long   sector_number,
   8.137                                 unsigned short  nr_sectors,
   8.138 -                               kdev_t          device)
   8.139 +                               kdev_t          device,
   8.140 +			       blkif_vdev_t    handle)
   8.141  {
   8.142      unsigned long       buffer_ma = virt_to_bus(buffer);
   8.143      unsigned long       xid;
   8.144 @@ -871,7 +816,7 @@ static int blkif_queue_request(unsigned 
   8.145      req->id            = xid;
   8.146      req->operation     = operation;
   8.147      req->sector_number = (blkif_sector_t)sector_number;
   8.148 -    req->device        = device; 
   8.149 +    req->handle        = handle; 
   8.150      req->nr_segments   = 1;
   8.151  #ifdef CONFIG_XEN_BLKDEV_GRANT
   8.152      /* install a grant reference. */
   8.153 @@ -1047,108 +992,10 @@ static void blkif_int(int irq, void *dev
   8.154  
   8.155  /*****************************  COMMON CODE  *******************************/
   8.156  
   8.157 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.158 -void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
   8.159 -                              unsigned long address)
   8.160 -{
   8.161 -    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
   8.162 -    ASSERT( ref != -ENOSPC );
   8.163 -
   8.164 -    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
   8.165 -
   8.166 -    req->frame_and_sects[0] = blkif_fas_from_gref(ref, 0, (PAGE_SIZE/512)-1);
   8.167 -
   8.168 -    blkif_control_send(req, rsp);
   8.169 -}
   8.170 -#endif
   8.171 -
   8.172 -void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
   8.173 -{
   8.174 -    unsigned long flags, id;
   8.175 -    blkif_request_t *req_d;
   8.176 -
   8.177 - retry:
   8.178 -    while ( RING_FULL(&blk_ring) )
   8.179 -    {
   8.180 -        set_current_state(TASK_INTERRUPTIBLE);
   8.181 -        schedule_timeout(1);
   8.182 -    }
   8.183 -
   8.184 -    spin_lock_irqsave(&blkif_io_lock, flags);
   8.185 -    if ( RING_FULL(&blk_ring) )
   8.186 -    {
   8.187 -        spin_unlock_irqrestore(&blkif_io_lock, flags);
   8.188 -        goto retry;
   8.189 -    }
   8.190 -
   8.191 -    DISABLE_SCATTERGATHER();
   8.192 -    req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
   8.193 -    *req_d = *req;    
   8.194 -
   8.195 -    id = GET_ID_FROM_FREELIST();
   8.196 -    req_d->id = id;
   8.197 -    blk_shadow[id].request = (unsigned long)req;
   8.198 -
   8.199 -    pickle_request(&blk_shadow[id], req);
   8.200 -
   8.201 -    blk_ring.req_prod_pvt++;
   8.202 -    flush_requests();
   8.203 -
   8.204 -    spin_unlock_irqrestore(&blkif_io_lock, flags);
   8.205 -
   8.206 -    while ( !blkif_control_rsp_valid )
   8.207 -    {
   8.208 -        set_current_state(TASK_INTERRUPTIBLE);
   8.209 -        schedule_timeout(1);
   8.210 -    }
   8.211 -
   8.212 -    memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
   8.213 -    blkif_control_rsp_valid = 0;
   8.214 -}
   8.215 -
   8.216 -
   8.217 -/* Send a driver status notification to the domain controller. */
   8.218 -static void send_driver_status(int ok)
   8.219 -{
   8.220 -    ctrl_msg_t cmsg = {
   8.221 -        .type    = CMSG_BLKIF_FE,
   8.222 -        .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
   8.223 -        .length  = sizeof(blkif_fe_driver_status_t),
   8.224 -    };
   8.225 -    blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
   8.226 -    
   8.227 -    msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
   8.228 -
   8.229 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   8.230 -}
   8.231 -
   8.232 -/* Tell the controller to bring up the interface. */
   8.233 -static void blkif_send_interface_connect(void)
   8.234 -{
   8.235 -    ctrl_msg_t cmsg = {
   8.236 -        .type    = CMSG_BLKIF_FE,
   8.237 -        .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
   8.238 -        .length  = sizeof(blkif_fe_interface_connect_t),
   8.239 -    };
   8.240 -    blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   8.241 -    
   8.242 -    msg->handle      = 0;
   8.243 -    msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   8.244 -    
   8.245 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.246 -    msg->shmem_ref   = gnttab_claim_grant_reference( &gref_head, gref_terminal );
   8.247 -    ASSERT( msg->shmem_ref != -ENOSPC );
   8.248 -    gnttab_grant_foreign_access_ref ( msg->shmem_ref , rdomid, msg->shmem_frame, 0 );
   8.249 -#endif
   8.250 -
   8.251 -    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   8.252 -}
   8.253 -
   8.254  static void blkif_free(void)
   8.255  {
   8.256      /* Prevent new requests being issued until we fix things up. */
   8.257      spin_lock_irq(&blkif_io_lock);
   8.258 -    recovery = 1;
   8.259      blkif_state = BLKIF_STATE_DISCONNECTED;
   8.260      spin_unlock_irq(&blkif_io_lock);
   8.261  
   8.262 @@ -1162,31 +1009,6 @@ static void blkif_free(void)
   8.263      blkif_evtchn = 0;
   8.264  }
   8.265  
   8.266 -static void blkif_close(void)
   8.267 -{
   8.268 -}
   8.269 -
   8.270 -/* Move from CLOSED to DISCONNECTED state. */
   8.271 -static void blkif_disconnect(void)
   8.272 -{
   8.273 -    blkif_sring_t *sring;
   8.274 -    
   8.275 -    if ( blk_ring.sring != NULL )
   8.276 -        free_page((unsigned long)blk_ring.sring);
   8.277 -    
   8.278 -    sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
   8.279 -    SHARED_RING_INIT(sring);
   8.280 -    FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
   8.281 -    blkif_state  = BLKIF_STATE_DISCONNECTED;
   8.282 -    blkif_send_interface_connect();
   8.283 -}
   8.284 -
   8.285 -static void blkif_reset(void)
   8.286 -{
   8.287 -    blkif_free();
   8.288 -    blkif_disconnect();
   8.289 -}
   8.290 -
   8.291  static void blkif_recover(void)
   8.292  {
   8.293      int i;
   8.294 @@ -1257,11 +1079,14 @@ static void blkif_recover(void)
   8.295      blkif_state = BLKIF_STATE_CONNECTED;
   8.296  }
   8.297  
   8.298 -static void blkif_connect(blkif_fe_interface_status_t *status)
   8.299 +static void blkif_connect(u16 evtchn, domid_t domid)
   8.300  {
   8.301      int err = 0;
   8.302  
   8.303 -    blkif_evtchn = status->evtchn;
   8.304 +    blkif_evtchn = evtchn;
   8.305 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.306 +    rdomid       = domid;
   8.307 +#endif
   8.308  
   8.309      err = bind_evtchn_to_irqhandler(
   8.310          blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
   8.311 @@ -1270,142 +1095,310 @@ static void blkif_connect(blkif_fe_inter
   8.312          WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
   8.313          return;
   8.314      }
   8.315 -
   8.316 -    if ( recovery ) 
   8.317 -    {
   8.318 -        blkif_recover();
   8.319 -    } 
   8.320 -    else 
   8.321 -    {
   8.322 -        /* Transition to connected in case we need to do 
   8.323 -         *  a partition probe on a whole disk. */
   8.324 -        blkif_state = BLKIF_STATE_CONNECTED;
   8.325 -        
   8.326 -        /* Probe for discs attached to the interface. */
   8.327 -        xlvbd_init();
   8.328 -    }
   8.329 -    
   8.330 -    /* Kick pending requests. */
   8.331 -    spin_lock_irq(&blkif_io_lock);
   8.332 -    kick_pending_request_queues();
   8.333 -    spin_unlock_irq(&blkif_io_lock);
   8.334 -}
   8.335 -
   8.336 -static void unexpected(blkif_fe_interface_status_t *status)
   8.337 -{
   8.338 -    DPRINTK(" Unexpected blkif status %u in state %u\n", 
   8.339 -            status->status, blkif_state);
   8.340 -}
   8.341 -
   8.342 -static void blkif_status(blkif_fe_interface_status_t *status)
   8.343 -{
   8.344 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.345 -    rdomid       = status->domid; /* need to set rdomid early */
   8.346 -#endif
   8.347 -
   8.348 -    if ( status->handle != blkif_handle )
   8.349 -    {
   8.350 -        WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
   8.351 -        unexpected(status);
   8.352 -        return;
   8.353 -    }
   8.354 -
   8.355 -    switch ( status->status ) 
   8.356 -    {
   8.357 -    case BLKIF_INTERFACE_STATUS_CLOSED:
   8.358 -        switch ( blkif_state )
   8.359 -        {
   8.360 -        case BLKIF_STATE_CLOSED:
   8.361 -            unexpected(status);
   8.362 -            break;
   8.363 -        case BLKIF_STATE_DISCONNECTED:
   8.364 -        case BLKIF_STATE_CONNECTED:
   8.365 -            unexpected(status);
   8.366 -            blkif_close();
   8.367 -            break;
   8.368 -        }
   8.369 -        break;
   8.370 -
   8.371 -    case BLKIF_INTERFACE_STATUS_DISCONNECTED:
   8.372 -        switch ( blkif_state )
   8.373 -        {
   8.374 -        case BLKIF_STATE_CLOSED:
   8.375 -            blkif_disconnect();
   8.376 -            break;
   8.377 -        case BLKIF_STATE_DISCONNECTED:
   8.378 -        case BLKIF_STATE_CONNECTED:
   8.379 -            /* unexpected(status); */ /* occurs during suspend/resume */
   8.380 -            blkif_reset();
   8.381 -            break;
   8.382 -        }
   8.383 -        break;
   8.384 -
   8.385 -    case BLKIF_INTERFACE_STATUS_CONNECTED:
   8.386 -        switch ( blkif_state )
   8.387 -        {
   8.388 -        case BLKIF_STATE_CLOSED:
   8.389 -            unexpected(status);
   8.390 -            blkif_disconnect();
   8.391 -            blkif_connect(status);
   8.392 -            break;
   8.393 -        case BLKIF_STATE_DISCONNECTED:
   8.394 -            blkif_connect(status);
   8.395 -            break;
   8.396 -        case BLKIF_STATE_CONNECTED:
   8.397 -            unexpected(status);
   8.398 -            blkif_connect(status);
   8.399 -            break;
   8.400 -        }
   8.401 -        break;
   8.402 -
   8.403 -    case BLKIF_INTERFACE_STATUS_CHANGED:
   8.404 -        switch ( blkif_state )
   8.405 -        {
   8.406 -        case BLKIF_STATE_CLOSED:
   8.407 -        case BLKIF_STATE_DISCONNECTED:
   8.408 -            unexpected(status);
   8.409 -            break;
   8.410 -        case BLKIF_STATE_CONNECTED:
   8.411 -            vbd_update();
   8.412 -            break;
   8.413 -        }
   8.414 -        break;
   8.415 -
   8.416 -    default:
   8.417 -        WPRINTK(" Invalid blkif status: %d\n", status->status);
   8.418 -        break;
   8.419 -    }
   8.420  }
   8.421  
   8.422  
   8.423 -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
   8.424 +static struct xenbus_device_id blkfront_ids[] = {
   8.425 +	{ "vbd" },
   8.426 +	{ "" }
   8.427 +};
   8.428 +
   8.429 +struct blkfront_info
   8.430 +{
   8.431 +	/* We watch the backend */
   8.432 +	struct xenbus_watch watch;
   8.433 +	int vdevice;
   8.434 +	u16 handle;
   8.435 +	int connected;
   8.436 +	struct xenbus_device *dev;
   8.437 +	char *backend;
   8.438 +};
   8.439 +
   8.440 +static void watch_for_status(struct xenbus_watch *watch, const char *node)
   8.441  {
   8.442 -    switch ( msg->subtype )
   8.443 -    {
   8.444 -    case CMSG_BLKIF_FE_INTERFACE_STATUS:
   8.445 -        blkif_status((blkif_fe_interface_status_t *)
   8.446 -                     &msg->msg[0]);
   8.447 -        break;
   8.448 -    default:
   8.449 -        msg->length = 0;
   8.450 -        break;
   8.451 -    }
   8.452 +	struct blkfront_info *info;
   8.453 +	unsigned int binfo;
   8.454 +	unsigned long sectors, sector_size;
   8.455 +	int err;
   8.456 +
   8.457 +	info = container_of(watch, struct blkfront_info, watch);
   8.458 +	node += strlen(watch->node);
   8.459 +
   8.460 +	/* FIXME: clean up when error on the other end. */
   8.461 +	if (info->connected)
   8.462 +		return;
   8.463 +
   8.464 +	err = xenbus_gather(watch->node, 
   8.465 +			    "sectors", "%lu", &sectors,
   8.466 +			    "info", "%u", &binfo,
   8.467 +			    "sector-size", "%lu", &sector_size,
   8.468 +			    NULL);
   8.469 +
   8.470 +	if (err)
   8.471 +		xenbus_dev_error(info->dev, err, "reading backend fields");
   8.472 +	else {
   8.473 +		xlvbd_add(sectors, info->vdevice, info->handle, binfo,
   8.474 +			  sector_size);
   8.475 +		info->connected = 1;
   8.476 +
   8.477 +		/* First to connect?  blkif is now connected. */
   8.478 +		if (blkif_vbds_connected++ == 0)
   8.479 +			blkif_state = BLKIF_STATE_CONNECTED;
   8.480 +
   8.481 +		xenbus_dev_ok(info->dev);
   8.482  
   8.483 -    ctrl_if_send_response(msg);
   8.484 +		/* Kick pending requests. */
   8.485 +		spin_lock_irq(&blkif_io_lock);
   8.486 +		kick_pending_request_queues();
   8.487 +		spin_unlock_irq(&blkif_io_lock);
   8.488 +	}
   8.489 +}
   8.490 +
   8.491 +static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id)
   8.492 +{
   8.493 +	blkif_sring_t *sring;
   8.494 +	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
   8.495 +	int err;
   8.496 +
   8.497 +	sring = (void *)__get_free_page(GFP_KERNEL);
   8.498 +	if (!sring) {
   8.499 +		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
   8.500 +		return -ENOMEM;
   8.501 +	}
   8.502 +	SHARED_RING_INIT(sring);
   8.503 +	FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
   8.504 +
   8.505 +	op.u.alloc_unbound.dom = backend_id;
   8.506 +	err = HYPERVISOR_event_channel_op(&op);
   8.507 +	if (err) {
   8.508 +		free_page((unsigned long)blk_ring.sring);
   8.509 +		blk_ring.sring = 0;
   8.510 +		xenbus_dev_error(dev, err, "allocating event channel");
   8.511 +		return err;
   8.512 +	}
   8.513 +	blkif_connect(op.u.alloc_unbound.port, backend_id);
   8.514 +	return 0;
   8.515  }
   8.516  
   8.517 -int wait_for_blkif(void)
   8.518 +/* Common code used when first setting up, and when resuming. */
   8.519 +static int talk_to_backend(struct xenbus_device *dev,
   8.520 +			   struct blkfront_info *info)
   8.521 +{
   8.522 +	char *backend;
   8.523 +	const char *message;
   8.524 +	int err, backend_id;
   8.525 +
   8.526 +	backend = xenbus_read(dev->nodename, "backend", NULL);
   8.527 +	if (IS_ERR(backend)) {
   8.528 +		err = PTR_ERR(backend);
   8.529 +		xenbus_dev_error(dev, err, "reading %s/backend",
   8.530 +				 dev->nodename);
   8.531 +		goto out;
   8.532 +	}
   8.533 +
   8.534 +	/* FIXME: This driver can't handle backends on different
   8.535 +	 * domains.  Check and fail gracefully. */
   8.536 +	err = xenbus_scanf(dev->nodename, "backend-id", "%i", &backend_id);
   8.537 + 	if (err < 0) {
   8.538 +		xenbus_dev_error(dev, err, "reading %s/backend-id",
   8.539 +				 dev->nodename);
   8.540 + 		goto free_backend;
   8.541 + 	}
   8.542 +
   8.543 +	/* First device?  We create shared ring, alloc event channel. */
   8.544 +	if (blkif_vbds == 0) {
   8.545 +		err = setup_blkring(dev, backend_id);
   8.546 +		if (err)
   8.547 +			goto free_backend;
   8.548 +	}
   8.549 +
   8.550 +	err = xenbus_transaction_start(dev->nodename);
   8.551 +	if (err) {
   8.552 +		xenbus_dev_error(dev, err, "starting transaction");
   8.553 +		goto destroy_blkring;
   8.554 +	}
   8.555 +
   8.556 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.557 +	{
   8.558 +		int shmem_ref;
   8.559 +		shmem_ref = gnttab_claim_grant_reference(&gref_head,
   8.560 +							 gref_terminal);
   8.561 +		ASSERT(shmem_ref != -ENOSPC);
   8.562 +		gnttab_grant_foreign_access_ref(shmem_ref,
   8.563 +						backend_id,
   8.564 +						virt_to_machine(blk_ring.sring)
   8.565 +						>> PAGE_SHIFT, 0);
   8.566 +		err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref);
   8.567 +		if (err) {
   8.568 +			message = "writing grant-id";
   8.569 +			goto abort_transaction;
   8.570 +		}
   8.571 +	}
   8.572 +#else
   8.573 +	err = xenbus_printf(dev->nodename, "shared-frame", "%lu",
   8.574 +			    virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   8.575 +	if (err) {
   8.576 +		message = "writing shared-frame";
   8.577 +		goto abort_transaction;
   8.578 +	}
   8.579 +#endif
   8.580 +	err = xenbus_printf(dev->nodename,
   8.581 +			    "event-channel", "%u", blkif_evtchn);
   8.582 +	if (err) {
   8.583 +		message = "writing event-channel";
   8.584 +		goto abort_transaction;
   8.585 +	}
   8.586 +
   8.587 +	info->watch.node = info->backend = backend;
   8.588 +	info->watch.callback = watch_for_status;
   8.589 +
   8.590 +	err = register_xenbus_watch(&info->watch);
   8.591 +	if (err) {
   8.592 +		message = "registering watch on backend";
   8.593 +		goto abort_transaction;
   8.594 +	}
   8.595 +
   8.596 +	err = xenbus_transaction_end(0);
   8.597 +	if (err) {
   8.598 +		xenbus_dev_error(dev, err, "completing transaction");
   8.599 +		goto destroy_blkring;
   8.600 +	}
   8.601 +	return 0;
   8.602 +
   8.603 +abort_transaction:
   8.604 +	xenbus_transaction_end(1);
   8.605 +	/* Have to do this *outside* transaction.  */
   8.606 +	xenbus_dev_error(dev, err, "%s", message);
   8.607 +destroy_blkring:
   8.608 +	if (blkif_vbds == 0)
   8.609 +		blkif_free();
   8.610 +free_backend:
   8.611 +	kfree(backend);
   8.612 +out:
   8.613 +	printk("%s:%u = %i\n", __FILE__, __LINE__, err);
   8.614 +	return err;
   8.615 +}
   8.616 +
   8.617 +/* Setup supplies the backend dir, virtual device.
   8.618 +
   8.619 +   We place an event channel and shared frame entries.
   8.620 +   We watch backend to wait if it's ok. */
   8.621 +static int blkfront_probe(struct xenbus_device *dev,
   8.622 +			  const struct xenbus_device_id *id)
   8.623 +{
   8.624 +	int err;
   8.625 +	struct blkfront_info *info;
   8.626 +	int vdevice;
   8.627 +
   8.628 +	/* FIXME: Use dynamic device id if this is not set. */
   8.629 +	err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice);
   8.630 +	if (err < 0) {
   8.631 +		xenbus_dev_error(dev, err, "reading virtual-device");
   8.632 +		return err;
   8.633 +	}
   8.634 +
   8.635 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
   8.636 +	if (!info) {
   8.637 +		xenbus_dev_error(dev, err, "allocating info structure");
   8.638 +		return err;
   8.639 +	}
   8.640 +	info->dev = dev;
   8.641 +	info->vdevice = vdevice;
   8.642 +	info->connected = 0;
   8.643 +	/* Front end dir is a number, which is used as the id. */
   8.644 +	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
   8.645 +	dev->data = info;
   8.646 +
   8.647 +	err = talk_to_backend(dev, info);
   8.648 +	if (err) {
   8.649 +		kfree(info);
   8.650 +		return err;
   8.651 +	}
   8.652 +
   8.653 +	/* Call once in case entries already there. */
   8.654 +	watch_for_status(&info->watch, info->watch.node);
   8.655 +	blkif_vbds++;
   8.656 +	return 0;
   8.657 +}
   8.658 +
   8.659 +static int blkfront_remove(struct xenbus_device *dev)
   8.660 +{
   8.661 +	struct blkfront_info *info = dev->data;
   8.662 +
   8.663 +	printk("blkfront_remove %s\n", dev->dev.bus_id);
   8.664 +	if (info->backend)
   8.665 +		unregister_xenbus_watch(&info->watch);
   8.666 +
   8.667 +	if (info->connected) {
   8.668 +		xlvbd_del(info->handle);
   8.669 +		blkif_vbds_connected--;
   8.670 +	}
   8.671 +	kfree(info->backend);
   8.672 +	kfree(info);
   8.673 +
   8.674 +	if (--blkif_vbds == 0)
   8.675 +		blkif_free();
   8.676 +
   8.677 +	printk("blkfront_remove done\n");
   8.678 +	return 0;
   8.679 +}
   8.680 +
   8.681 +static int blkfront_suspend(struct xenbus_device *dev)
   8.682 +{
   8.683 +	struct blkfront_info *info = dev->data;
   8.684 +
   8.685 +	unregister_xenbus_watch(&info->watch);
   8.686 +	kfree(info->backend);
   8.687 +	info->backend = NULL;
   8.688 +
   8.689 +	if (--blkif_vbds == 0) {
   8.690 +		recovery = 1;
   8.691 +		blkif_free();
   8.692 +	}
   8.693 +
   8.694 +	return 0;
   8.695 +}
   8.696 +
   8.697 +static int blkfront_resume(struct xenbus_device *dev)
   8.698 +{
   8.699 +	struct blkfront_info *info = dev->data;
   8.700 +	int err;
   8.701 +
   8.702 +	/* FIXME: Check geometry hasn't changed here... */
   8.703 +	err = talk_to_backend(dev, info);
   8.704 +	if (!err) {
   8.705 +		if (blkif_vbds++ == 0)
   8.706 +			blkif_recover();
   8.707 +	}
   8.708 +	return err;
   8.709 +}
   8.710 +
   8.711 +static struct xenbus_driver blkfront = {
   8.712 +	.name = __stringify(KBUILD_MODNAME),
   8.713 +	.owner = THIS_MODULE,
   8.714 +	.ids = blkfront_ids,
   8.715 +	.probe = blkfront_probe,
   8.716 +	.remove = blkfront_remove,
   8.717 +	.resume = blkfront_resume,
   8.718 +	.suspend = blkfront_suspend,
   8.719 +};
   8.720 +
   8.721 +static void __init init_blk_xenbus(void)
   8.722 +{
   8.723 +	xenbus_register_device(&blkfront);
   8.724 +}
   8.725 +
   8.726 +static int wait_for_blkif(void)
   8.727  {
   8.728      int err = 0;
   8.729      int i;
   8.730 -    send_driver_status(1);
   8.731  
   8.732      /*
   8.733       * We should read 'nr_interfaces' from response message and wait
   8.734       * for notifications before proceeding. For now we assume that we
   8.735       * will be notified of exactly one interface.
   8.736       */
   8.737 -    for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
   8.738 +    for ( i=0; blkif_state != BLKIF_STATE_CONNECTED && (i < 10*HZ); i++ )
   8.739      {
   8.740          set_current_state(TASK_INTERRUPTIBLE);
   8.741          schedule_timeout(1);
   8.742 @@ -1419,7 +1412,7 @@ int wait_for_blkif(void)
   8.743      return err;
   8.744  }
   8.745  
   8.746 -int __init xlblk_init(void)
   8.747 +static int __init xlblk_init(void)
   8.748  {
   8.749      int i;
   8.750  
   8.751 @@ -1443,29 +1436,13 @@ int __init xlblk_init(void)
   8.752          blk_shadow[i].req.id = i+1;
   8.753      blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
   8.754  
   8.755 -    (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
   8.756 -                                    CALLBACK_IN_BLOCKING_CONTEXT);
   8.757 +    init_blk_xenbus();
   8.758  
   8.759      wait_for_blkif();
   8.760  
   8.761      return 0;
   8.762  }
   8.763  
   8.764 -void blkdev_suspend(void)
   8.765 -{
   8.766 -}
   8.767 -
   8.768 -void blkdev_resume(void)
   8.769 -{
   8.770 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   8.771 -    int i, j;
   8.772 -    for ( i = 0; i < BLK_RING_SIZE; i++ )
   8.773 -        for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
   8.774 -            blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
   8.775 -#endif
   8.776 -    send_driver_status(1);
   8.777 -}
   8.778 -
   8.779  static void blkif_completion(struct blk_shadow *s)
   8.780  {
   8.781      int i;
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 02:41:16 2005 +0000
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Aug 19 10:46:21 2005 +0000
     9.3 @@ -100,6 +100,7 @@ struct xlbd_major_info {
     9.4  
     9.5  struct xlbd_disk_info {
     9.6      int xd_device;
     9.7 +    blkif_vdev_t handle;
     9.8      struct xlbd_major_info *mi;
     9.9  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    9.10      struct xlbd_disk_info  *next_waiting;
    9.11 @@ -119,17 +120,10 @@ extern int blkif_ioctl(struct inode *ino
    9.12                         unsigned command, unsigned long argument);
    9.13  extern int blkif_check(dev_t dev);
    9.14  extern int blkif_revalidate(dev_t dev);
    9.15 -extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
    9.16 -#ifdef CONFIG_XEN_BLKDEV_GRANT
    9.17 -extern void blkif_control_probe_send(
    9.18 -    blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
    9.19 -#endif
    9.20  extern void do_blkif_request (request_queue_t *rq); 
    9.21  
    9.22 -extern void xlvbd_update_vbds(void);
    9.23 -
    9.24  /* Virtual block-device subsystem. */
    9.25 -extern int  xlvbd_init(void);
    9.26 -extern void xlvbd_cleanup(void); 
    9.27 -
    9.28 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
    9.29 +	      u16 info, u16 sector_size);
    9.30 +void xlvbd_del(blkif_vdev_t handle);
    9.31  #endif /* __XEN_DRIVERS_BLOCK_H__ */
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 02:41:16 2005 +0000
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Aug 19 10:46:21 2005 +0000
    10.3 @@ -46,8 +46,9 @@
    10.4  struct lvdisk
    10.5  {
    10.6      blkif_sector_t capacity; /*  0: Size in terms of 512-byte sectors.   */
    10.7 -    blkif_vdev_t   device;   /*  8: Device number (opaque 16 bit value). */
    10.8 -    u16            info; 
    10.9 +    blkif_vdev_t   handle;   /*  8: Device number (opaque 16 bit value). */
   10.10 +    u16            info;
   10.11 +    dev_t          dev;
   10.12      struct list_head list;
   10.13  };
   10.14  
   10.15 @@ -85,7 +86,7 @@ static struct xlbd_major_info *major_inf
   10.16  
   10.17  /* Information about our VBDs. */
   10.18  #define MAX_VBDS 64
   10.19 -struct list_head vbds_list;
   10.20 +static LIST_HEAD(vbds_list);
   10.21  
   10.22  #define MAJOR_XEN(dev) ((dev)>>8)
   10.23  #define MINOR_XEN(dev) ((dev) & 0xff)
   10.24 @@ -118,49 +119,6 @@ static void xlvbd_device_free(struct lvd
   10.25      kfree(disk);
   10.26  }
   10.27  
   10.28 -static vdisk_t *xlvbd_probe(int *ret)
   10.29 -{
   10.30 -    blkif_response_t rsp;
   10.31 -    blkif_request_t req;
   10.32 -    vdisk_t *disk_info = NULL;
   10.33 -    unsigned long buf;
   10.34 -    int nr;
   10.35 -
   10.36 -    buf = __get_free_page(GFP_KERNEL);
   10.37 -    if ((void *)buf == NULL)
   10.38 -        goto out;
   10.39 -
   10.40 -    memset(&req, 0, sizeof(req));
   10.41 -    req.operation = BLKIF_OP_PROBE;
   10.42 -    req.nr_segments = 1;
   10.43 -#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.44 -    blkif_control_probe_send(&req, &rsp,
   10.45 -                             (unsigned long)(virt_to_machine(buf)));
   10.46 -#else
   10.47 -    req.frame_and_sects[0] = blkif_fas(virt_to_machine(buf), 0, (PAGE_SIZE/512)-1);
   10.48 -
   10.49 -    blkif_control_send(&req, &rsp);
   10.50 -#endif
   10.51 -    if ( rsp.status <= 0 ) {
   10.52 -        WPRINTK("Could not probe disks (%d)\n", rsp.status);
   10.53 -        goto out;
   10.54 -    }
   10.55 -    nr = rsp.status;
   10.56 -    if ( nr > MAX_VBDS )
   10.57 -        nr = MAX_VBDS;
   10.58 -
   10.59 -    disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
   10.60 -    if (disk_info != NULL)
   10.61 -        memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
   10.62 -
   10.63 -    if (ret != NULL)
   10.64 -        *ret = nr;
   10.65 -
   10.66 -out:
   10.67 -    free_page(buf);
   10.68 -    return disk_info;
   10.69 -}
   10.70 -
   10.71  static struct xlbd_major_info *xlbd_alloc_major_info(
   10.72      int major, int minor, int index)
   10.73  {
   10.74 @@ -189,6 +147,7 @@ static struct xlbd_major_info *xlbd_allo
   10.75          break;
   10.76      }
   10.77      
   10.78 +    printk("Registering block device major %i\n", ptr->major);
   10.79      if (register_blkdev(ptr->major, ptr->type->devname)) {
   10.80          WPRINTK("can't get major %d with name %s\n",
   10.81                  ptr->major, ptr->type->devname);
   10.82 @@ -231,7 +190,7 @@ static struct xlbd_major_info *xlbd_get_
   10.83              xlbd_alloc_major_info(major, minor, index));
   10.84  }
   10.85  
   10.86 -static int xlvbd_init_blk_queue(struct gendisk *gd, vdisk_t *disk)
   10.87 +static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
   10.88  {
   10.89      request_queue_t *rq;
   10.90  
   10.91 @@ -242,7 +201,7 @@ static int xlvbd_init_blk_queue(struct g
   10.92      elevator_init(rq, "noop");
   10.93  
   10.94      /* Hard sector size and max sectors impersonate the equiv. hardware. */
   10.95 -    blk_queue_hardsect_size(rq, disk->sector_size);
   10.96 +    blk_queue_hardsect_size(rq, sector_size);
   10.97      blk_queue_max_sectors(rq, 512);
   10.98  
   10.99      /* Each segment in a request is up to an aligned page in size. */
  10.100 @@ -261,8 +220,9 @@ static int xlvbd_init_blk_queue(struct g
  10.101      return 0;
  10.102  }
  10.103  
  10.104 -struct gendisk *xlvbd_alloc_gendisk(
  10.105 -    struct xlbd_major_info *mi, int minor, vdisk_t *disk)
  10.106 +static struct gendisk *xlvbd_alloc_gendisk(
  10.107 +    struct xlbd_major_info *mi, int minor, blkif_sector_t capacity,
  10.108 +    int device, blkif_vdev_t handle, u16 info, u16 sector_size)
  10.109  {
  10.110      struct gendisk *gd;
  10.111      struct xlbd_disk_info *di;
  10.112 @@ -273,7 +233,8 @@ struct gendisk *xlvbd_alloc_gendisk(
  10.113          return NULL;
  10.114      memset(di, 0, sizeof(*di));
  10.115      di->mi = mi;
  10.116 -    di->xd_device = disk->device;
  10.117 +    di->xd_device = device;
  10.118 +    di->handle = handle;
  10.119  
  10.120      if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
  10.121          nr_minors = 1 << mi->type->partn_shift;
  10.122 @@ -296,22 +257,22 @@ struct gendisk *xlvbd_alloc_gendisk(
  10.123      gd->first_minor = minor;
  10.124      gd->fops = &xlvbd_block_fops;
  10.125      gd->private_data = di;
  10.126 -    set_capacity(gd, disk->capacity);
  10.127 +    set_capacity(gd, capacity);
  10.128  
  10.129 -    if (xlvbd_init_blk_queue(gd, disk)) {
  10.130 +    if (xlvbd_init_blk_queue(gd, sector_size)) {
  10.131          del_gendisk(gd);
  10.132          goto out;
  10.133      }
  10.134  
  10.135      di->rq = gd->queue;
  10.136  
  10.137 -    if (disk->info & VDISK_READONLY)
  10.138 +    if (info & VDISK_READONLY)
  10.139          set_disk_ro(gd, 1);
  10.140  
  10.141 -    if (disk->info & VDISK_REMOVABLE)
  10.142 +    if (info & VDISK_REMOVABLE)
  10.143          gd->flags |= GENHD_FL_REMOVABLE;
  10.144  
  10.145 -    if (disk->info & VDISK_CDROM)
  10.146 +    if (info & VDISK_CDROM)
  10.147          gd->flags |= GENHD_FL_CD;
  10.148  
  10.149      add_disk(gd);
  10.150 @@ -323,38 +284,36 @@ out:
  10.151      return NULL;
  10.152  }
  10.153  
  10.154 -static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
  10.155 +int xlvbd_add(blkif_sector_t capacity, int device, blkif_vdev_t handle,
  10.156 +	      u16 info, u16 sector_size)
  10.157  {
  10.158      struct lvdisk *new;
  10.159 -    int minor;
  10.160 -    dev_t device;
  10.161      struct block_device *bd;
  10.162      struct gendisk *gd;
  10.163      struct xlbd_major_info *mi;
  10.164  
  10.165 -    mi = xlbd_get_major_info(disk->device);
  10.166 +    mi = xlbd_get_major_info(device);
  10.167      if (mi == NULL)
  10.168          return -EPERM;
  10.169  
  10.170      new = xlvbd_device_alloc();
  10.171      if (new == NULL)
  10.172 -        return -1;
  10.173 -    new->capacity = disk->capacity;
  10.174 -    new->device = disk->device;
  10.175 -    new->info = disk->info;
  10.176 -    
  10.177 -    minor = MINOR_XEN(disk->device);
  10.178 -    device = MKDEV(mi->major, minor);
  10.179 -    
  10.180 -    bd = bdget(device);
  10.181 +        return -ENOMEM;
  10.182 +    new->capacity = capacity;
  10.183 +    new->info = info;
  10.184 +    new->handle = handle;
  10.185 +    new->dev = MKDEV(MAJOR_XEN(device), MINOR_XEN(device));
  10.186 +
  10.187 +    bd = bdget(new->dev);
  10.188      if (bd == NULL)
  10.189          goto out;
  10.190      
  10.191 -    gd = xlvbd_alloc_gendisk(mi, minor, disk);
  10.192 +    gd = xlvbd_alloc_gendisk(mi, MINOR_XEN(device), capacity, device, handle,
  10.193 +			     info, sector_size);
  10.194      if (gd == NULL)
  10.195          goto out_bd;
  10.196  
  10.197 -    list_add(&new->list, list);
  10.198 +    list_add(&new->list, &vbds_list);
  10.199  out_bd:
  10.200      bdput(bd);
  10.201  out:
  10.202 @@ -363,27 +322,26 @@ out:
  10.203  
  10.204  static int xlvbd_device_del(struct lvdisk *disk)
  10.205  {
  10.206 -    dev_t device;
  10.207      struct block_device *bd;
  10.208      struct gendisk *gd;
  10.209      struct xlbd_disk_info *di;
  10.210      int ret = 0, unused;
  10.211      request_queue_t *rq;
  10.212  
  10.213 -    device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
  10.214 -
  10.215 -    bd = bdget(device);
  10.216 +    bd = bdget(disk->dev);
  10.217      if (bd == NULL)
  10.218          return -1;
  10.219  
  10.220 -    gd = get_gendisk(device, &unused);
  10.221 +    gd = get_gendisk(disk->dev, &unused);
  10.222      di = gd->private_data;
  10.223  
  10.224 +#if 0 /* This is wrong: hda and hdb share same major, for example. */
  10.225      if (di->mi->usage != 0) {
  10.226 -        WPRINTK("disk removal failed: used [dev=%x]\n", device);
  10.227 +        WPRINTK("disk removal failed: used [dev=%x]\n", disk->dev);
  10.228          ret = -1;
  10.229          goto out;
  10.230      }
  10.231 +#endif
  10.232  
  10.233      rq = gd->queue;
  10.234      del_gendisk(gd);
  10.235 @@ -391,110 +349,19 @@ static int xlvbd_device_del(struct lvdis
  10.236      blk_cleanup_queue(rq);
  10.237  
  10.238      xlvbd_device_free(disk);
  10.239 -out:
  10.240      bdput(bd);
  10.241      return ret;
  10.242  }
  10.243  
  10.244 -static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
  10.245 +void xlvbd_del(blkif_vdev_t handle)
  10.246  {
  10.247 -    dev_t device;
  10.248 -    struct block_device *bd;
  10.249 -    struct gendisk *gd;
  10.250 -    int unused;
  10.251 -
  10.252 -    if ((ldisk->capacity == disk->capacity) && (ldisk->info == disk->info))
  10.253 -        return 0;    
  10.254 -
  10.255 -    device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
  10.256 -
  10.257 -    bd = bdget(device);
  10.258 -    if (bd == NULL)
  10.259 -        return -1;
  10.260 -
  10.261 -    gd = get_gendisk(device, &unused);
  10.262 -    set_capacity(gd, disk->capacity);    
  10.263 -    ldisk->capacity = disk->capacity;
  10.264 -
  10.265 -    bdput(bd);
  10.266 -
  10.267 -    return 0;
  10.268 -}
  10.269 -
  10.270 -void xlvbd_refresh(void)
  10.271 -{
  10.272 -    vdisk_t *newdisks;
  10.273 -    struct list_head *tmp, *tmp2;
  10.274 -    struct lvdisk *disk;
  10.275 -    int i, nr;
  10.276 +	struct lvdisk *i;
  10.277  
  10.278 -    newdisks = xlvbd_probe(&nr);
  10.279 -    if (newdisks == NULL) {
  10.280 -        WPRINTK("failed to probe\n");
  10.281 -        return;
  10.282 -    }
  10.283 -    
  10.284 -    i = 0;
  10.285 -    list_for_each_safe(tmp, tmp2, &vbds_list) {
  10.286 -        disk = list_entry(tmp, struct lvdisk, list);
  10.287 -        
  10.288 -        for (i = 0; i < nr; i++) {
  10.289 -            if ( !newdisks[i].device )
  10.290 -                continue;
  10.291 -            if ( disk->device == newdisks[i].device ) {
  10.292 -                xlvbd_device_update(disk, &newdisks[i]);
  10.293 -                newdisks[i].device = 0;
  10.294 -                break;
  10.295 -            }
  10.296 -        }
  10.297 -        if (i == nr) {
  10.298 -            xlvbd_device_del(disk);
  10.299 -            newdisks[i].device = 0;
  10.300 -        }
  10.301 -    }
  10.302 -    for (i = 0; i < nr; i++)
  10.303 -        if ( newdisks[i].device )
  10.304 -            xlvbd_device_add(&vbds_list, &newdisks[i]);
  10.305 -    kfree(newdisks);
  10.306 +	list_for_each_entry(i, &vbds_list, list) {
  10.307 +		if (i->handle == handle) {
  10.308 +			xlvbd_device_del(i);
  10.309 +			return;
  10.310 +		}
  10.311 +	}
  10.312 +	BUG();
  10.313  }
  10.314 -
  10.315 -/*
  10.316 - * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
  10.317 - * state. The VBDs need to be updated in this way when the domain is
  10.318 - * initialised and also each time we receive an XLBLK_UPDATE event.
  10.319 - */
  10.320 -void xlvbd_update_vbds(void)
  10.321 -{
  10.322 -    xlvbd_refresh();
  10.323 -}
  10.324 -
  10.325 -/*
  10.326 - * Set up all the linux device goop for the virtual block devices
  10.327 - * (vbd's) that we know about. Note that although from the backend
  10.328 - * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
  10.329 - * number, the domain creation tools conventionally allocate these
  10.330 - * numbers to correspond to those used by 'real' linux -- this is just
  10.331 - * for convenience as it means e.g. that the same /etc/fstab can be
  10.332 - * used when booting with or without Xen.
  10.333 - */
  10.334 -int xlvbd_init(void)
  10.335 -{
  10.336 -    int i, nr;
  10.337 -    vdisk_t *disks;
  10.338 -
  10.339 -    INIT_LIST_HEAD(&vbds_list);
  10.340 -
  10.341 -    memset(major_info, 0, sizeof(major_info));
  10.342 -    
  10.343 -    disks = xlvbd_probe(&nr);
  10.344 -    if (disks == NULL) {
  10.345 -        WPRINTK("failed to probe\n");
  10.346 -        return -1;
  10.347 -    }
  10.348 -
  10.349 -    for (i = 0; i < nr; i++)
  10.350 -        xlvbd_device_add(&vbds_list, &disks[i]);
  10.351 -
  10.352 -    kfree(disks);
  10.353 -    return 0;
  10.354 -}
    11.1 --- a/xen/include/public/io/blkif.h	Fri Aug 19 02:41:16 2005 +0000
    11.2 +++ b/xen/include/public/io/blkif.h	Fri Aug 19 10:46:21 2005 +0000
    11.3 @@ -18,7 +18,6 @@
    11.4  
    11.5  #define BLKIF_OP_READ      0
    11.6  #define BLKIF_OP_WRITE     1
    11.7 -#define BLKIF_OP_PROBE     2
    11.8  
    11.9  /* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
   11.10  #define BLKIF_RING_SIZE        64
   11.11 @@ -33,7 +32,7 @@
   11.12  typedef struct blkif_request {
   11.13      u8             operation;    /* BLKIF_OP_???                         */
   11.14      u8             nr_segments;  /* number of segments                   */
   11.15 -    blkif_vdev_t   device;       /* only for read/write requests         */
   11.16 +    blkif_vdev_t   handle;       /* only for read/write requests         */
   11.17      unsigned long  id;           /* private guest value, echoed in resp  */
   11.18      blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
   11.19      /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect                        */
   11.20 @@ -71,31 +70,8 @@ typedef struct blkif_response {
   11.21  
   11.22  DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t);
   11.23  
   11.24 -/*
   11.25 - * BLKIF_OP_PROBE:
   11.26 - * The request format for a probe request is constrained as follows:
   11.27 - *  @operation   == BLKIF_OP_PROBE
   11.28 - *  @nr_segments == size of probe buffer in pages
   11.29 - *  @device      == unused (zero)
   11.30 - *  @id          == any value (echoed in response message)
   11.31 - *  @sector_num  == unused (zero)
   11.32 - *  @frame_and_sects == list of page-sized buffers.
   11.33 - *                       (i.e., @first_sect == 0, @last_sect == 7).
   11.34 - * 
   11.35 - * The response is a list of vdisk_t elements copied into the out-of-band
   11.36 - * probe buffer. On success the response status field contains the number
   11.37 - * of vdisk_t elements.
   11.38 - */
   11.39 -
   11.40  #define VDISK_CDROM        0x1
   11.41  #define VDISK_REMOVABLE    0x2
   11.42  #define VDISK_READONLY     0x4
   11.43  
   11.44 -typedef struct vdisk {
   11.45 -    blkif_sector_t capacity;     /* Size in terms of 512-byte sectors.   */
   11.46 -    blkif_vdev_t   device;       /* Device number (opaque 16 bit value). */
   11.47 -    u16            info;         /* Device type and flags (VDISK_*).     */
   11.48 -    u16            sector_size;  /* Minimum alignment for requests.      */
   11.49 -} vdisk_t; /* 16 bytes */
   11.50 -
   11.51  #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */