This commit was generated by cvs2svn to compensate for changes in r925,
[linux-2.6.git] / drivers / xen / blktap / blktap.h
1 /*
2  * blktap.h
3  * 
4  * Interfaces for the Xen block tap driver.
5  * 
6  * (c) 2004, Andrew Warfield, University of Cambridge
7  * 
8  */
9
10 #ifndef __BLKTAP_H__
11 #define __BLKTAP_H__
12
13 #include <linux/version.h>
14 #include <linux/blkdev.h>
15 #include <linux/config.h>
16 #include <linux/sched.h>
17 #include <linux/interrupt.h>
18 #include <asm-xen/ctrl_if.h>
19 #include <linux/slab.h>
20 #include <linux/blkdev.h>
21 #include <asm/io.h>
22 #include <asm/setup.h>
23 #include <asm/pgalloc.h>
24 #include <asm-xen/hypervisor.h>
25 #include <asm-xen/xen-public/io/blkif.h>
26 #include <asm-xen/xen-public/io/ring.h>
27
28 /* Used to signal to the backend that this is a tap domain. */
29 #define BLKTAP_COOKIE 0xbeadfeed
30
31 /* -------[ debug / pretty printing ]--------------------------------- */
32
33 #define PRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
34                            __FILE__ , __LINE__ , ## _a )
35 #if 0
36 #define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
37                            __FILE__ , __LINE__ , ## _a )
38 #else
39 #define DPRINTK(_f, _a...) ((void)0)
40 #endif
41
42 #if 1
43 #define ASSERT(_p) \
44     if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
45     __LINE__, __FILE__); *(int*)0=0; }
46 #else
47 #define ASSERT(_p) ((void)0)
48 #endif
49
50 #define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
51
52
53 /* -------[ state descriptors ]--------------------------------------- */
54
55 #define BLKIF_STATE_CLOSED       0
56 #define BLKIF_STATE_DISCONNECTED 1
57 #define BLKIF_STATE_CONNECTED    2
58
59 /* -------[ connection tracking ]------------------------------------- */
60
61 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
62 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
63 #endif
64
65 extern spinlock_t blkif_io_lock;
66
67 typedef struct blkif_st {
68     /* Unique identifier for this interface. */
69     domid_t             domid;
70     unsigned int        handle;
71     /* Physical parameters of the comms window. */
72     unsigned long       shmem_frame;
73     unsigned int        evtchn;
74     int                 irq;
75     /* Comms information. */
76     blkif_back_ring_t   blk_ring;
77     
78     enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
79     /*
80      * DISCONNECT response is deferred until pending requests are ack'ed.
81      * We therefore need to store the id from the original request.
82      */    
83     u8                  disconnect_rspid;
84     struct blkif_st    *hash_next;
85     struct list_head    blkdev_list;
86     spinlock_t          blk_ring_lock;
87     atomic_t            refcnt;
88     struct work_struct work;
89 } blkif_t;
90
91 blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
92 void blkif_disconnect_complete(blkif_t *blkif);
93 #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
94 #define blkif_put(_b)                             \
95     do {                                          \
96         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
97             blkif_disconnect_complete(_b);        \
98     } while (0)
99
100
101 /* -------[ active request tracking ]--------------------------------- */
102
103 typedef struct {
104     blkif_t       *blkif;
105     unsigned long  id;
106     int            nr_pages;
107     unsigned long  mach_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
108     unsigned long  virt_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
109     int            next_free;
110 } active_req_t;
111
112 typedef unsigned int ACTIVE_RING_IDX;
113
114 active_req_t *lookup_active_req(ACTIVE_RING_IDX idx);
115
116 extern inline unsigned int ID_TO_IDX(unsigned long id) 
117
118     return ( id & 0x0000ffff );
119 }
120
121 extern inline domid_t ID_TO_DOM(unsigned long id) 
122
123     return (id >> 16); 
124 }
125
126 void active_reqs_init(void);
127
128 /* -------[ interposition -> character device interface ]------------- */
129
130 /* /dev/xen/blktap resides at device number major=10, minor=200        */ 
131 #define BLKTAP_MINOR 202
132
133 /* size of the extra VMA area to map in attached pages. */
134 #define BLKTAP_VMA_PAGES BLKIF_RING_SIZE
135
136 /* blktap IOCTLs:                                                      */
137 #define BLKTAP_IOCTL_KICK_FE         1
138 #define BLKTAP_IOCTL_KICK_BE         2
139 #define BLKTAP_IOCTL_SETMODE         3
140 #define BLKTAP_IOCTL_PRINT_IDXS      100  
141
142 /* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
143 #define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
144 #define BLKTAP_MODE_INTERCEPT_FE     0x00000001
145 #define BLKTAP_MODE_INTERCEPT_BE     0x00000002
146 #define BLKTAP_MODE_COPY_FE          0x00000004
147 #define BLKTAP_MODE_COPY_BE          0x00000008
148 #define BLKTAP_MODE_COPY_FE_PAGES    0x00000010
149 #define BLKTAP_MODE_COPY_BE_PAGES    0x00000020
150
151 #define BLKTAP_MODE_INTERPOSE \
152            (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
153
154 #define BLKTAP_MODE_COPY_BOTH \
155            (BLKTAP_MODE_COPY_FE | BLKTAP_MODE_COPY_BE)
156
157 #define BLKTAP_MODE_COPY_BOTH_PAGES \
158            (BLKTAP_MODE_COPY_FE_PAGES | BLKTAP_MODE_COPY_BE_PAGES)
159
160 static inline int BLKTAP_MODE_VALID(unsigned long arg)
161 {
162     return (
163         ( arg == BLKTAP_MODE_PASSTHROUGH  ) ||
164         ( arg == BLKTAP_MODE_INTERCEPT_FE ) ||
165         ( arg == BLKTAP_MODE_INTERCEPT_BE ) ||
166         ( arg == BLKTAP_MODE_INTERPOSE    ) ||
167         ( (arg & ~BLKTAP_MODE_COPY_FE_PAGES) == BLKTAP_MODE_COPY_FE ) ||
168         ( (arg & ~BLKTAP_MODE_COPY_BE_PAGES) == BLKTAP_MODE_COPY_BE ) ||
169         ( (arg & ~BLKTAP_MODE_COPY_BOTH_PAGES) == BLKTAP_MODE_COPY_BOTH )
170         );
171 }
172
173
174
175 /* -------[ Mappings to User VMA ]------------------------------------ */
176 #define MAX_PENDING_REQS 64
177 #define BATCH_PER_DOMAIN 16
178 extern struct vm_area_struct *blktap_vma;
179
180 /* The following are from blkback.c and should probably be put in a
181  * header and included from there.
182  * The mmap area described here is where attached data pages eill be mapped.
183  */
184  
185 extern unsigned long mmap_vstart;
186 #define MMAP_PAGES_PER_REQUEST \
187     (BLKIF_MAX_SEGMENTS_PER_REQUEST + 1)
188 #define MMAP_PAGES             \
189     (MAX_PENDING_REQS * MMAP_PAGES_PER_REQUEST)
190 #define MMAP_VADDR(_req,_seg)                        \
191     (mmap_vstart +                                   \
192      ((_req) * MMAP_PAGES_PER_REQUEST * PAGE_SIZE) + \
193      ((_seg) * PAGE_SIZE))
194
195 /* immediately before the mmap area, we have a bunch of pages reserved
196  * for shared memory rings.
197  */
198
199 #define RING_PAGES 3 /* Ctrl, Front, and Back */ 
200 extern unsigned long rings_vstart;
201
202
203 /* -------[ Here be globals ]----------------------------------------- */
204 extern unsigned long blktap_mode;
205
206 /* Connection to a single backend domain. */
207 extern blkif_front_ring_t blktap_be_ring;
208 extern unsigned int blktap_be_evtchn;
209 extern unsigned int blktap_be_state;
210
211 /* User ring status. */
212 extern unsigned long blktap_ring_ok;
213
214 /* -------[ ...and function prototypes. ]----------------------------- */
215
216 /* init function for character device interface.                       */
217 int blktap_init(void);
218
219 /* init function for the blkif cache. */
220 void __init blkif_interface_init(void);
221 void __init blkdev_schedule_init(void);
222 void blkif_deschedule(blkif_t *blkif);
223
224 /* interfaces to the char driver, passing messages to and from apps.   */
225 void blktap_kick_user(void);
226
227 /* user ring access functions: */
228 int blktap_write_fe_ring(blkif_request_t *req);
229 int blktap_write_be_ring(blkif_response_t *rsp);
230 int blktap_write_ctrl_ring(ctrl_msg_t *msg);
231
232 /* fe/be ring access functions: */
233 int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp);
234 int write_req_to_be_ring(blkif_request_t *req);
235
236 /* event notification functions */
237 void kick_fe_domain(blkif_t *blkif);
238 void kick_be_domain(void);
239
240 /* Interrupt handlers. */
241 irqreturn_t blkif_ptbe_int(int irq, void *dev_id, 
242                                   struct pt_regs *ptregs);
243 irqreturn_t blkif_ptfe_int(int irq, void *dev_id, struct pt_regs *regs);
244
245 /* Control message receiver. */
246 extern void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id);
247
248 /* debug */
249 void print_vm_ring_idxs(void);
250         
251 #define __BLKINT_H__
252 #endif