Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
common.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License version 2
4  * as published by the Free Software Foundation; or, when distributed
5  * separately from the Linux kernel or incorporated into other
6  * software packages, subject to the following license:
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this source file (the "Software"), to deal in the Software without
10  * restriction, including without limitation the rights to use, copy, modify,
11  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
12  * and to permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26 
27 #ifndef __XEN_BLKIF__BACKEND__COMMON_H__
28 #define __XEN_BLKIF__BACKEND__COMMON_H__
29 
30 #include <linux/module.h>
31 #include <linux/interrupt.h>
32 #include <linux/slab.h>
33 #include <linux/blkdev.h>
34 #include <linux/vmalloc.h>
35 #include <linux/wait.h>
36 #include <linux/io.h>
37 #include <asm/setup.h>
38 #include <asm/pgalloc.h>
39 #include <asm/hypervisor.h>
40 #include <xen/grant_table.h>
41 #include <xen/xenbus.h>
42 #include <xen/interface/io/ring.h>
43 #include <xen/interface/io/blkif.h>
45 
46 #define DRV_PFX "xen-blkback:"
47 #define DPRINTK(fmt, args...) \
48  pr_debug(DRV_PFX "(%s:%d) " fmt ".\n", \
49  __func__, __LINE__, ##args)
50 
51 
52 /* Not a real protocol. Used to generate ring structs which contain
53  * the elements common to all protocols only. This way we get a
54  * compiler-checkable way to use common struct elements, so we can
55  * avoid using switch(protocol) in a number of places. */
57  char dummy;
58 };
60  char dummy;
61 };
62 
64  uint8_t nr_segments; /* number of segments */
65  blkif_vdev_t handle; /* only for read/write requests */
66  uint64_t id; /* private guest value, echoed in resp */
67  blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
69 } __attribute__((__packed__));
70 
72  uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */
73  blkif_vdev_t _pad1; /* was "handle" for read/write requests */
74  uint64_t id; /* private guest value, echoed in resp */
75  blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
77 } __attribute__((__packed__));
78 
80  uint8_t operation; /* BLKIF_OP_??? */
81  union {
84  } u;
85 } __attribute__((__packed__));
86 
87 /* i386 protocol version */
88 #pragma pack(push, 4)
90  uint64_t id; /* copied from request */
91  uint8_t operation; /* copied from request */
92  int16_t status; /* BLKIF_RSP_??? */
93 };
94 #pragma pack(pop)
95 /* x86_64 protocol version */
96 
98  uint8_t nr_segments; /* number of segments */
99  blkif_vdev_t handle; /* only for read/write requests */
100  uint32_t _pad1; /* offsetof(blkif_reqest..,u.rw.id)==8 */
102  blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
104 } __attribute__((__packed__));
105 
107  uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */
108  blkif_vdev_t _pad1; /* was "handle" for read/write requests */
109  uint32_t _pad2; /* offsetof(blkif_..,u.discard.id)==8 */
111  blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
113 } __attribute__((__packed__));
114 
116  uint8_t operation; /* BLKIF_OP_??? */
117  union {
120  } u;
121 } __attribute__((__packed__));
122 
124  uint64_t __attribute__((__aligned__(8))) id;
125  uint8_t operation; /* copied from request */
126  int16_t status; /* BLKIF_RSP_??? */
127 };
128 
129 DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
130  struct blkif_common_response);
131 DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
132  struct blkif_x86_32_response);
133 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
134  struct blkif_x86_64_response);
135 
137  struct blkif_back_ring native;
138  struct blkif_common_back_ring common;
139  struct blkif_x86_32_back_ring x86_32;
140  struct blkif_x86_64_back_ring x86_64;
141 };
142 
147 };
148 
149 struct xen_vbd {
150  /* What the domain refers to this vbd as. */
152  /* Non-zero -> read-only */
153  unsigned char readonly;
154  /* VDISK_xxx */
155  unsigned char type;
156  /* phys device that this vbd maps to. */
159  /* Cached size parameter. */
161  unsigned int flush_support:1;
162  unsigned int discard_secure:1;
163 };
164 
165 struct backend_info;
166 
167 struct xen_blkif {
168  /* Unique identifier for this interface. */
170  unsigned int handle;
171  /* Physical parameters of the comms window. */
172  unsigned int irq;
173  /* Comms information. */
176  void *blk_ring;
177  /* The VBD attached to this interface. */
178  struct xen_vbd vbd;
179  /* Back pointer to the backend_info. */
180  struct backend_info *be;
181  /* Private fields. */
184 
186  /* for barrier (drain) requests */
189  /* One thread per one blkif. */
191  unsigned int waiting_reqs;
192 
193  /* statistics */
194  unsigned long st_print;
198  int st_f_req;
202 
204 };
205 
206 
207 #define vbd_sz(_v) ((_v)->bdev->bd_part ? \
208  (_v)->bdev->bd_part->nr_sects : \
209  get_capacity((_v)->bdev->bd_disk))
210 
211 #define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
212 #define xen_blkif_put(_b) \
213  do { \
214  if (atomic_dec_and_test(&(_b)->refcnt)) \
215  wake_up(&(_b)->waiting_to_free);\
216  } while (0)
217 
218 struct phys_req {
219  unsigned short dev;
223 };
224 int xen_blkif_interface_init(void);
225 
226 int xen_blkif_xenbus_init(void);
227 
228 irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
229 int xen_blkif_schedule(void *arg);
230 
232  struct backend_info *be, int state);
233 
235  struct backend_info *be, int state);
236 struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
237 
238 static inline void blkif_get_x86_32_req(struct blkif_request *dst,
239  struct blkif_x86_32_request *src)
240 {
242  dst->operation = src->operation;
243  switch (src->operation) {
244  case BLKIF_OP_READ:
245  case BLKIF_OP_WRITE:
248  dst->u.rw.nr_segments = src->u.rw.nr_segments;
249  dst->u.rw.handle = src->u.rw.handle;
250  dst->u.rw.id = src->u.rw.id;
251  dst->u.rw.sector_number = src->u.rw.sector_number;
252  barrier();
253  if (n > dst->u.rw.nr_segments)
254  n = dst->u.rw.nr_segments;
255  for (i = 0; i < n; i++)
256  dst->u.rw.seg[i] = src->u.rw.seg[i];
257  break;
258  case BLKIF_OP_DISCARD:
259  dst->u.discard.flag = src->u.discard.flag;
260  dst->u.discard.id = src->u.discard.id;
261  dst->u.discard.sector_number = src->u.discard.sector_number;
262  dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
263  break;
264  default:
265  break;
266  }
267 }
268 
269 static inline void blkif_get_x86_64_req(struct blkif_request *dst,
270  struct blkif_x86_64_request *src)
271 {
273  dst->operation = src->operation;
274  switch (src->operation) {
275  case BLKIF_OP_READ:
276  case BLKIF_OP_WRITE:
279  dst->u.rw.nr_segments = src->u.rw.nr_segments;
280  dst->u.rw.handle = src->u.rw.handle;
281  dst->u.rw.id = src->u.rw.id;
282  dst->u.rw.sector_number = src->u.rw.sector_number;
283  barrier();
284  if (n > dst->u.rw.nr_segments)
285  n = dst->u.rw.nr_segments;
286  for (i = 0; i < n; i++)
287  dst->u.rw.seg[i] = src->u.rw.seg[i];
288  break;
289  case BLKIF_OP_DISCARD:
290  dst->u.discard.flag = src->u.discard.flag;
291  dst->u.discard.id = src->u.discard.id;
292  dst->u.discard.sector_number = src->u.discard.sector_number;
293  dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
294  break;
295  default:
296  break;
297  }
298 }
299 
300 #endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */