14d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk/*
24d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * This program is free software; you can redistribute it and/or
34d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * modify it under the terms of the GNU General Public License version 2
44d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * as published by the Free Software Foundation; or, when distributed
54d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * separately from the Linux kernel or incorporated into other
64d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * software packages, subject to the following license:
74d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk *
84d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * Permission is hereby granted, free of charge, to any person obtaining a copy
94d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * of this source file (the "Software"), to deal in the Software without
104d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * restriction, including without limitation the rights to use, copy, modify,
114d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * merge, publish, distribute, sublicense, and/or sell copies of the Software,
124d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * and to permit persons to whom the Software is furnished to do so, subject to
134d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * the following conditions:
144d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk *
154d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * The above copyright notice and this permission notice shall be included in
164d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * all copies or substantial portions of the Software.
174d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk *
184d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
194d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
204d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
214d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
224d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
234d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
244d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk * IN THE SOFTWARE.
254d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk */
264d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
275a577e38724226e06337bc8361f492b6bb76b9a5Konrad Rzeszutek Wilk#ifndef __XEN_BLKIF__BACKEND__COMMON_H__
285a577e38724226e06337bc8361f492b6bb76b9a5Konrad Rzeszutek Wilk#define __XEN_BLKIF__BACKEND__COMMON_H__
294d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
304d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/module.h>
314d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/interrupt.h>
324d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/slab.h>
334d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/blkdev.h>
344d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/vmalloc.h>
354d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <linux/wait.h>
365489377ce40d52fb722dcd811617114cebad7bbaKonrad Rzeszutek Wilk#include <linux/io.h>
374d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <asm/setup.h>
384d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <asm/pgalloc.h>
394d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <asm/hypervisor.h>
408812293323a79134e06c3bf82eba1e217d23382eJeremy Fitzhardinge#include <xen/grant_table.h>
414d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk#include <xen/xenbus.h>
42452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk#include <xen/interface/io/ring.h>
43452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk#include <xen/interface/io/blkif.h>
44452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk#include <xen/interface/io/protocols.h>
454d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
4622b20f2dffd09edd66127f2022c26d0039bad88eKonrad Rzeszutek Wilk#define DRV_PFX "xen-blkback:"
471afbd730a33c6e4ca780a70351e8929dd4c40636Konrad Rzeszutek Wilk#define DPRINTK(fmt, args...)				\
481bc05b0ae6448b20d46076899e0cc12ad999e50eJoe Jin	pr_debug(DRV_PFX "(%s:%d) " fmt ".\n",		\
491afbd730a33c6e4ca780a70351e8929dd4c40636Konrad Rzeszutek Wilk		 __func__, __LINE__, ##args)
504d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
51452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
52452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk/* Not a real protocol.  Used to generate ring structs which contain
53452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk * the elements common to all protocols only.  This way we get a
54452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk * compiler-checkable way to use common struct elements, so we can
55452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk * avoid using switch(protocol) in a number of places.  */
56452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_common_request {
57452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	char dummy;
58452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
59452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_common_response {
60452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	char dummy;
61452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
62452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
63b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyangstruct blkif_x86_32_request_rw {
6497e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint8_t        nr_segments;  /* number of segments                   */
6597e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	blkif_vdev_t   handle;       /* only for read/write requests         */
6697e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       id;           /* private guest value, echoed in resp  */
67b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
68b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
6997e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
70b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang
71b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyangstruct blkif_x86_32_request_discard {
725ea42986694a96542644f9cae8b122d3a00c508fKonrad Rzeszutek Wilk	uint8_t        flag;         /* BLKIF_DISCARD_SECURE or zero         */
7397e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	blkif_vdev_t   _pad1;        /* was "handle" for read/write requests */
7497e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       id;           /* private guest value, echoed in resp  */
75b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
7697e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       nr_sectors;
7797e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
78b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang
79452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_x86_32_request {
80452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint8_t        operation;    /* BLKIF_OP_???                         */
81b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	union {
82b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		struct blkif_x86_32_request_rw rw;
83b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		struct blkif_x86_32_request_discard discard;
84b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	} u;
8597e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
8697e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk
8797e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk/* i386 protocol version */
8897e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk#pragma pack(push, 4)
89452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_x86_32_response {
90452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint64_t        id;              /* copied from request */
91452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint8_t         operation;       /* copied from request */
92452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	int16_t         status;          /* BLKIF_RSP_???       */
93452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
94452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk#pragma pack(pop)
95452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk/* x86_64 protocol version */
96b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang
97b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyangstruct blkif_x86_64_request_rw {
9897e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint8_t        nr_segments;  /* number of segments                   */
9997e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	blkif_vdev_t   handle;       /* only for read/write requests         */
10097e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint32_t       _pad1;        /* offsetof(blkif_reqest..,u.rw.id)==8  */
10197e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       id;
102b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
103b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
10497e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
105b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang
106b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyangstruct blkif_x86_64_request_discard {
1075ea42986694a96542644f9cae8b122d3a00c508fKonrad Rzeszutek Wilk	uint8_t        flag;         /* BLKIF_DISCARD_SECURE or zero         */
10897e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	blkif_vdev_t   _pad1;        /* was "handle" for read/write requests */
10997e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk        uint32_t       _pad2;        /* offsetof(blkif_..,u.discard.id)==8   */
11097e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       id;
111b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
11297e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk	uint64_t       nr_sectors;
11397e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
114b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang
115452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_x86_64_request {
116452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint8_t        operation;    /* BLKIF_OP_???                         */
117b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	union {
118b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		struct blkif_x86_64_request_rw rw;
119b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		struct blkif_x86_64_request_discard discard;
120b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	} u;
12197e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk} __attribute__((__packed__));
12297e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk
123452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkstruct blkif_x86_64_response {
124452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint64_t       __attribute__((__aligned__(8))) id;
125452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	uint8_t         operation;       /* copied from request */
126452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	int16_t         status;          /* BLKIF_RSP_???       */
127452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
128452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
129452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek WilkDEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
130452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk		  struct blkif_common_response);
131452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek WilkDEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
132452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk		  struct blkif_x86_32_response);
133452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek WilkDEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
134452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk		  struct blkif_x86_64_response);
135452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
136452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkunion blkif_back_rings {
137452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	struct blkif_back_ring        native;
138452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	struct blkif_common_back_ring common;
139452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	struct blkif_x86_32_back_ring x86_32;
140452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	struct blkif_x86_64_back_ring x86_64;
141452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
142452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
143452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilkenum blkif_protocol {
144452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	BLKIF_PROTOCOL_NATIVE = 1,
145452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	BLKIF_PROTOCOL_X86_32 = 2,
146452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk	BLKIF_PROTOCOL_X86_64 = 3,
147452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk};
148452a6b2bb6de677acdd2ccb8b39cf6e8fe06f306Konrad Rzeszutek Wilk
1493d814731ba67f9514bdf380c1b95dd852ac82a2fKonrad Rzeszutek Wilkstruct xen_vbd {
15001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	/* What the domain refers to this vbd as. */
15101f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	blkif_vdev_t		handle;
15201f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	/* Non-zero -> read-only */
15301f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned char		readonly;
15401f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	/* VDISK_xxx */
15501f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned char		type;
15601f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	/* phys device that this vbd maps to. */
15701f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	u32			pdevice;
15801f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	struct block_device	*bdev;
15901f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	/* Cached size parameter. */
16001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	sector_t		size;
16101f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	bool			flush_support;
1625ea42986694a96542644f9cae8b122d3a00c508fKonrad Rzeszutek Wilk	bool			discard_secure;
1634d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk};
1644d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
1654d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilkstruct backend_info;
1664d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
16730fd150202fb2d08a62f9c2966a4b1fcf2e861e7Konrad Rzeszutek Wilkstruct xen_blkif {
1684d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* Unique identifier for this interface. */
16901f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	domid_t			domid;
17001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned int		handle;
1714d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* Physical parameters of the comms window. */
17201f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned int		irq;
1734d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* Comms information. */
17401f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	enum blkif_protocol	blk_protocol;
17501f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	union blkif_back_rings	blk_rings;
1762d073846b891c3f49c4ea03c5db3ac92f92742f1David Vrabel	void			*blk_ring;
1774d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* The VBD attached to this interface. */
1783d814731ba67f9514bdf380c1b95dd852ac82a2fKonrad Rzeszutek Wilk	struct xen_vbd		vbd;
1794d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* Back pointer to the backend_info. */
18001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	struct backend_info	*be;
1814d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* Private fields. */
18201f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	spinlock_t		blk_ring_lock;
18301f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	atomic_t		refcnt;
1844d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
18501f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	wait_queue_head_t	wq;
18629bde093787f3bdf7b9b4270ada6be7c8076e36bKonrad Rzeszutek Wilk	/* for barrier (drain) requests */
18729bde093787f3bdf7b9b4270ada6be7c8076e36bKonrad Rzeszutek Wilk	struct completion	drain_complete;
18829bde093787f3bdf7b9b4270ada6be7c8076e36bKonrad Rzeszutek Wilk	atomic_t		drain;
189a1397fa3090c25c6c51c04b4101f2786d16b615fKonrad Rzeszutek Wilk	/* One thread per one blkif. */
19001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	struct task_struct	*xenblkd;
19101f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned int		waiting_reqs;
1924d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
1934d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	/* statistics */
19401f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned long		st_print;
19501f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_rd_req;
19601f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_wr_req;
19701f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_oo_req;
19801f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_f_req;
199b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	int			st_ds_req;
20001f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_rd_sect;
20101f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	int			st_wr_sect;
20201f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk
20301f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	wait_queue_head_t	waiting_to_free;
2045489377ce40d52fb722dcd811617114cebad7bbaKonrad Rzeszutek Wilk};
2054d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
20642c7841d171a2fe32005738dfebd724a90921496Konrad Rzeszutek Wilk
20742c7841d171a2fe32005738dfebd724a90921496Konrad Rzeszutek Wilk#define vbd_sz(_v)	((_v)->bdev->bd_part ? \
20842c7841d171a2fe32005738dfebd724a90921496Konrad Rzeszutek Wilk			 (_v)->bdev->bd_part->nr_sects : \
20942c7841d171a2fe32005738dfebd724a90921496Konrad Rzeszutek Wilk			  get_capacity((_v)->bdev->bd_disk))
2104d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
2118b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilk#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
2128b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilk#define xen_blkif_put(_b)				\
2134d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	do {						\
2144d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk		if (atomic_dec_and_test(&(_b)->refcnt))	\
2154d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk			wake_up(&(_b)->waiting_to_free);\
2164d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk	} while (0)
2174d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
2184d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilkstruct phys_req {
21901f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	unsigned short		dev;
220b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	blkif_sector_t		nr_sects;
22101f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	struct block_device	*bdev;
22201f37f2d53e14a05b7fc3601d182f31ac3b35847Konrad Rzeszutek Wilk	blkif_sector_t		sector_number;
2234d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk};
2248b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilkint xen_blkif_interface_init(void);
2254d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
2268b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilkint xen_blkif_xenbus_init(void);
2274d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
2288b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilkirqreturn_t xen_blkif_be_int(int irq, void *dev_id);
2298b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilkint xen_blkif_schedule(void *arg);
2304d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
23124f567f952aa308c3352f3340b9d296fc72bd066Konrad Rzeszutek Wilkint xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
23224f567f952aa308c3352f3340b9d296fc72bd066Konrad Rzeszutek Wilk			      struct backend_info *be, int state);
2334d05a28db56225bbab5e1321d818f318e92a4657Konrad Rzeszutek Wilk
23429bde093787f3bdf7b9b4270ada6be7c8076e36bKonrad Rzeszutek Wilkint xen_blkbk_barrier(struct xenbus_transaction xbt,
23529bde093787f3bdf7b9b4270ada6be7c8076e36bKonrad Rzeszutek Wilk		      struct backend_info *be, int state);
2368b6bf747d70e5bac1a34c8fd773230e1cfdd7546Konrad Rzeszutek Wilkstruct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
23798e036a356747cfaa225478b1e4875e190257b09Jeremy Fitzhardinge
238b0f801273f7359a7d91fc94f5c6bf216bc17aaa1Konrad Rzeszutek Wilkstatic inline void blkif_get_x86_32_req(struct blkif_request *dst,
23968c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk					struct blkif_x86_32_request *src)
24068c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk{
24168c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
24268c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk	dst->operation = src->operation;
243b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	switch (src->operation) {
244b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_READ:
245b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_WRITE:
246b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_WRITE_BARRIER:
247b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_FLUSH_DISKCACHE:
24897e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.nr_segments = src->u.rw.nr_segments;
24997e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.handle = src->u.rw.handle;
25097e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.id = src->u.rw.id;
251b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.rw.sector_number = src->u.rw.sector_number;
252b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		barrier();
25397e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		if (n > dst->u.rw.nr_segments)
25497e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk			n = dst->u.rw.nr_segments;
255b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		for (i = 0; i < n; i++)
256b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang			dst->u.rw.seg[i] = src->u.rw.seg[i];
257b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
258b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_DISCARD:
2595ea42986694a96542644f9cae8b122d3a00c508fKonrad Rzeszutek Wilk		dst->u.discard.flag = src->u.discard.flag;
2608c890e34f58fc8d3c0eafecf0bdc92c4161b1679Konrad Rzeszutek Wilk		dst->u.discard.id = src->u.discard.id;
261b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.discard.sector_number = src->u.discard.sector_number;
262b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
263b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
264b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	default:
265b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
266b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	}
26768c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk}
26868c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk
269b0f801273f7359a7d91fc94f5c6bf216bc17aaa1Konrad Rzeszutek Wilkstatic inline void blkif_get_x86_64_req(struct blkif_request *dst,
27068c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk					struct blkif_x86_64_request *src)
27168c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk{
27268c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
27368c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk	dst->operation = src->operation;
274b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	switch (src->operation) {
275b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_READ:
276b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_WRITE:
277b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_WRITE_BARRIER:
278b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_FLUSH_DISKCACHE:
27997e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.nr_segments = src->u.rw.nr_segments;
28097e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.handle = src->u.rw.handle;
28197e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		dst->u.rw.id = src->u.rw.id;
282b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.rw.sector_number = src->u.rw.sector_number;
283b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		barrier();
28497e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk		if (n > dst->u.rw.nr_segments)
28597e36834f5a106459ab1b290e663a4eb6264639eKonrad Rzeszutek Wilk			n = dst->u.rw.nr_segments;
286b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		for (i = 0; i < n; i++)
287b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang			dst->u.rw.seg[i] = src->u.rw.seg[i];
288b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
289b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	case BLKIF_OP_DISCARD:
2905ea42986694a96542644f9cae8b122d3a00c508fKonrad Rzeszutek Wilk		dst->u.discard.flag = src->u.discard.flag;
2918c890e34f58fc8d3c0eafecf0bdc92c4161b1679Konrad Rzeszutek Wilk		dst->u.discard.id = src->u.discard.id;
292b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.discard.sector_number = src->u.discard.sector_number;
293b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
294b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
295b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	default:
296b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang		break;
297b3cb0d6adc4bbc70b5e37e49a6068e973545ead7Li Dongyang	}
29868c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk}
29968c88dd7d3caf1737112238fbe91cccd8e7a69fcKonrad Rzeszutek Wilk
3005a577e38724226e06337bc8361f492b6bb76b9a5Konrad Rzeszutek Wilk#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */
301