Path: blob/master/drivers/block/xen-blkback/common.h
15115 views
/*1* This program is free software; you can redistribute it and/or2* modify it under the terms of the GNU General Public License version 23* as published by the Free Software Foundation; or, when distributed4* separately from the Linux kernel or incorporated into other5* software packages, subject to the following license:6*7* Permission is hereby granted, free of charge, to any person obtaining a copy8* of this source file (the "Software"), to deal in the Software without9* restriction, including without limitation the rights to use, copy, modify,10* merge, publish, distribute, sublicense, and/or sell copies of the Software,11* and to permit persons to whom the Software is furnished to do so, subject to12* the following conditions:13*14* The above copyright notice and this permission notice shall be included in15* all copies or substantial portions of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE20* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER21* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING22* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS23* IN THE SOFTWARE.24*/2526#ifndef __XEN_BLKIF__BACKEND__COMMON_H__27#define __XEN_BLKIF__BACKEND__COMMON_H__2829#include <linux/version.h>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>44#include <xen/interface/io/protocols.h>4546#define DRV_PFX "xen-blkback:"47#define DPRINTK(fmt, args...) \48pr_debug(DRV_PFX "(%s:%d) " fmt ".\n", \49__func__, __LINE__, ##args)505152/* Not a real protocol. Used to generate ring structs which contain53* the elements common to all protocols only. This way we get a54* compiler-checkable way to use common struct elements, so we can55* avoid using switch(protocol) in a number of places. */56struct blkif_common_request {57char dummy;58};59struct blkif_common_response {60char dummy;61};6263/* i386 protocol version */64#pragma pack(push, 4)65struct blkif_x86_32_request {66uint8_t operation; /* BLKIF_OP_??? */67uint8_t nr_segments; /* number of segments */68blkif_vdev_t handle; /* only for read/write requests */69uint64_t id; /* private guest value, echoed in resp */70blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */71struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];72};73struct blkif_x86_32_response {74uint64_t id; /* copied from request */75uint8_t operation; /* copied from request */76int16_t status; /* BLKIF_RSP_??? */77};78#pragma pack(pop)7980/* x86_64 protocol version */81struct blkif_x86_64_request {82uint8_t operation; /* BLKIF_OP_??? */83uint8_t nr_segments; /* number of segments */84blkif_vdev_t handle; /* only for read/write requests */85uint64_t __attribute__((__aligned__(8))) id;86blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */87struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];88};89struct blkif_x86_64_response {90uint64_t __attribute__((__aligned__(8))) id;91uint8_t operation; /* copied from request */92int16_t status; /* BLKIF_RSP_??? */93};9495DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,96struct blkif_common_response);97DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,98struct blkif_x86_32_response);99DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,100struct blkif_x86_64_response);101102union blkif_back_rings {103struct blkif_back_ring native;104struct blkif_common_back_ring common;105struct blkif_x86_32_back_ring x86_32;106struct blkif_x86_64_back_ring x86_64;107};108109enum blkif_protocol {110BLKIF_PROTOCOL_NATIVE = 1,111BLKIF_PROTOCOL_X86_32 = 2,112BLKIF_PROTOCOL_X86_64 = 3,113};114115struct xen_vbd {116/* What the domain refers to this vbd as. */117blkif_vdev_t handle;118/* Non-zero -> read-only */119unsigned char readonly;120/* VDISK_xxx */121unsigned char type;122/* phys device that this vbd maps to. */123u32 pdevice;124struct block_device *bdev;125/* Cached size parameter. */126sector_t size;127bool flush_support;128};129130struct backend_info;131132struct xen_blkif {133/* Unique identifier for this interface. */134domid_t domid;135unsigned int handle;136/* Physical parameters of the comms window. */137unsigned int irq;138/* Comms information. */139enum blkif_protocol blk_protocol;140union blkif_back_rings blk_rings;141struct vm_struct *blk_ring_area;142/* The VBD attached to this interface. */143struct xen_vbd vbd;144/* Back pointer to the backend_info. */145struct backend_info *be;146/* Private fields. */147spinlock_t blk_ring_lock;148atomic_t refcnt;149150wait_queue_head_t wq;151/* One thread per one blkif. */152struct task_struct *xenblkd;153unsigned int waiting_reqs;154155/* statistics */156unsigned long st_print;157int st_rd_req;158int st_wr_req;159int st_oo_req;160int st_f_req;161int st_rd_sect;162int st_wr_sect;163164wait_queue_head_t waiting_to_free;165166grant_handle_t shmem_handle;167grant_ref_t shmem_ref;168};169170171#define vbd_sz(_v) ((_v)->bdev->bd_part ? \172(_v)->bdev->bd_part->nr_sects : \173get_capacity((_v)->bdev->bd_disk))174175#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))176#define xen_blkif_put(_b) \177do { \178if (atomic_dec_and_test(&(_b)->refcnt)) \179wake_up(&(_b)->waiting_to_free);\180} while (0)181182struct phys_req {183unsigned short dev;184unsigned short nr_sects;185struct block_device *bdev;186blkif_sector_t sector_number;187};188int xen_blkif_interface_init(void);189190int xen_blkif_xenbus_init(void);191192irqreturn_t xen_blkif_be_int(int irq, void *dev_id);193int xen_blkif_schedule(void *arg);194195int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,196struct backend_info *be, int state);197198struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);199200static inline void blkif_get_x86_32_req(struct blkif_request *dst,201struct blkif_x86_32_request *src)202{203int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;204dst->operation = src->operation;205dst->nr_segments = src->nr_segments;206dst->handle = src->handle;207dst->id = src->id;208dst->u.rw.sector_number = src->sector_number;209barrier();210if (n > dst->nr_segments)211n = dst->nr_segments;212for (i = 0; i < n; i++)213dst->u.rw.seg[i] = src->seg[i];214}215216static inline void blkif_get_x86_64_req(struct blkif_request *dst,217struct blkif_x86_64_request *src)218{219int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;220dst->operation = src->operation;221dst->nr_segments = src->nr_segments;222dst->handle = src->handle;223dst->id = src->id;224dst->u.rw.sector_number = src->sector_number;225barrier();226if (n > dst->nr_segments)227n = dst->nr_segments;228for (i = 0; i < n; i++)229dst->u.rw.seg[i] = src->seg[i];230}231232#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */233234235