aboutsummaryrefslogtreecommitdiffstats
path: root/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h
blob: d9f1d22908626f62215bd5a40d36d637cf0bde07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/******************************************************************************
 * arch/xen/drivers/blkif/backend/common.h
 */

#ifndef __BLKIF__BACKEND__COMMON_H__
#define __BLKIF__BACKEND__COMMON_H__

#include <linux/config.h>
#include <linux/module.h>
#include <linux/rbtree.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <asm/ctrl_if.h>
#include <asm/io.h>
#include "../blkif.h"

#ifndef NDEBUG
#define ASSERT(_p) \
    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    __LINE__, __FILE__); *(int*)0=0; }
#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
                           __FILE__ , __LINE__ , ## _a )
#else
#define ASSERT(_p) ((void)0)
#define DPRINTK(_f, _a...) ((void)0)
#endif

typedef struct blkif_st {
    /* Unique identifier for this interface. */
    domid_t          domid;
    unsigned int     handle;
    /* Physical parameters of the comms window. */
    unsigned long    shmem_frame;
    unsigned int     evtchn;
    int              irq;
    /* Comms information. */
    blkif_ring_t    *blk_ring_base; /* ioremap()'ed ptr to shmem_frame. */
    BLK_RING_IDX     blk_req_cons;  /* Request consumer. */
    BLK_RING_IDX     blk_resp_prod; /* Private version of response producer. */
    /* VBDs attached to this interface. */
    rb_root_t        vbd_rb;        /* Mapping from 16-bit vdevices to VBDs. */
    spinlock_t       vbd_lock;      /* Protects VBD mapping. */
    /* Private fields. */
    enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
    /*
     * DISCONNECT response is deferred until pending requests are ack'ed.
     * We therefore need to store the id from the original request.
     */
    u8               disconnect_rspid;
    struct blkif_st *hash_next;
    struct list_head blkdev_list;
    spinlock_t       blk_ring_lock;
    atomic_t         refcnt;
} blkif_t;

void blkif_create(blkif_be_create_t *create);
void blkif_destroy(blkif_be_destroy_t *destroy);
void blkif_connect(blkif_be_connect_t *connect);
int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
void __blkif_disconnect_complete(blkif_t *blkif);
blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
#define blkif_put(_b)                             \
    do {                                          \
        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
            __blkif_disconnect_complete(_b);      \
    } while (0)

/* An entry in a list of xen_extents. */
typedef struct _blkif_extent_le { 
    blkif_extent_t extent;               /* an individual extent */
    struct _blkif_extent_le *next;       /* and a pointer to the next */ 
} blkif_extent_le_t; 

typedef struct _vbd { 
    blkif_vdev_t       vdevice;   /* what the domain refers to this vbd as */
    unsigned char      readonly;  /* Non-zero -> read-only */
    unsigned char      type;      /* XD_TYPE_xxx */
    blkif_extent_le_t *extents;   /* list of xen_extents making up this vbd */
    rb_node_t          rb;        /* for linking into R-B tree lookup struct */
} vbd_t; 

void vbd_create(blkif_be_vbd_create_t *create); 
void vbd_grow(blkif_be_vbd_grow_t *grow); 
void vbd_shrink(blkif_be_vbd_shrink_t *shrink);
void vbd_destroy(blkif_be_vbd_destroy_t *delete); 
int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
void destroy_all_vbds(blkif_t *blkif);

/* Describes a [partial] disk extent (part of a block io request) */
typedef struct {
    unsigned short dev;
    unsigned short nr_sects;
    unsigned long  buffer;
    xen_sector_t   sector_number;
} phys_seg_t;

int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation); 

void blkif_interface_init(void);
void blkif_ctrlif_init(void);

void blkif_deschedule(blkif_t *blkif);

void blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);

#endif /* __BLKIF__BACKEND__COMMON_H__ */