blob: 1024629ea737be74b61612dd7b5588da8c5e9ce6 (
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
109
110
111
112
113
114
115
|
/******************************************************************************
* blkif.h
*
* Unified block-device I/O interface for Xen guest OSes.
*
* Copyright (c) 2003-2004, Keir Fraser
*/
#ifndef __SHARED_BLKIF_H__
#define __SHARED_BLKIF_H__
#define blkif_vdev_t u16
#define blkif_sector_t u64
#define BLKIF_OP_READ 0
#define BLKIF_OP_WRITE 1
#define BLKIF_OP_PROBE 2
/* NB. Ring size must be small enough for sizeof(blkif_ring_t) <= PAGE_SIZE. */
#define BLKIF_RING_SIZE 64
/*
* Maximum scatter/gather segments per request.
* This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
* NB. This could be 12 if the ring indexes weren't stored in the same page.
*/
#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
typedef struct {
u8 operation; /* 0: BLKIF_OP_??? */
u8 nr_segments; /* 1: number of segments */
blkif_vdev_t device; /* 2: only for read/write requests */
unsigned long id; /* 4: private guest value, echoed in resp */
blkif_sector_t sector_number; /* start sector idx on disk (r/w only) */
/* @f_a_s[2:0]=last_sect ; @f_a_s[5:3]=first_sect ; @f_a_s[:12]=frame. */
/* @first_sect: first sector in frame to transfer (inclusive). */
/* @last_sect: last sector in frame to transfer (inclusive). */
/* @frame: machine page frame number. */
unsigned long frame_and_sects[BLKIF_MAX_SEGMENTS_PER_REQUEST];
} PACKED blkif_request_t;
#define blkif_first_sect(_fas) (((_fas)>>3)&7)
#define blkif_last_sect(_fas) ((_fas)&7)
typedef struct {
unsigned long id; /* copied from request */
u8 operation; /* copied from request */
s16 status; /* BLKIF_RSP_??? */
} PACKED blkif_response_t;
#define BLKIF_RSP_ERROR -1 /* non-specific 'error' */
#define BLKIF_RSP_OKAY 0 /* non-specific 'okay' */
/*
* We use a special capitalised type name because it is _essential_ that all
* arithmetic on indexes is done on an integer type of the correct size.
*/
typedef u32 BLKIF_RING_IDX;
/*
* Ring indexes are 'free running'. That is, they are not stored modulo the
* size of the ring buffer. The following macro converts a free-running counter
* into a value that can directly index a ring-buffer array.
*/
#define MASK_BLKIF_IDX(_i) ((_i)&(BLKIF_RING_SIZE-1))
typedef struct {
BLKIF_RING_IDX req_prod; /* 0: Request producer. Updated by front-end. */
BLKIF_RING_IDX resp_prod; /* 4: Response producer. Updated by back-end. */
union { /* 8 */
blkif_request_t req;
blkif_response_t resp;
} PACKED ring[BLKIF_RING_SIZE];
} PACKED blkif_ring_t;
/*
* BLKIF_OP_PROBE:
* The request format for a probe request is constrained as follows:
* @operation == BLKIF_OP_PROBE
* @nr_segments == size of probe buffer in pages
* @device == unused (zero)
* @id == any value (echoed in response message)
* @sector_num == unused (zero)
* @frame_and_sects == list of page-sized buffers.
* (i.e., @first_sect == 0, @last_sect == 7).
*
* The response is a list of vdisk_t elements copied into the out-of-band
* probe buffer. On success the response status field contains the number
* of vdisk_t elements.
*/
/* XXX SMH: Type values below are chosen to match ide_xxx in Linux ide.h. */
#define VDISK_TYPE_FLOPPY 0x00
#define VDISK_TYPE_TAPE 0x01
#define VDISK_TYPE_CDROM 0x05
#define VDISK_TYPE_OPTICAL 0x07
#define VDISK_TYPE_DISK 0x20
#define VDISK_TYPE_MASK 0x3F
#define VDISK_TYPE(_x) ((_x) & VDISK_TYPE_MASK)
/* The top two bits of the type field encode various flags. */
#define VDISK_FLAG_RO 0x40
#define VDISK_FLAG_VIRT 0x80
#define VDISK_READONLY(_x) ((_x) & VDISK_FLAG_RO)
#define VDISK_VIRTUAL(_x) ((_x) & VDISK_FLAG_VIRT)
typedef struct {
blkif_sector_t capacity; /* 0: Size in terms of 512-byte sectors. */
blkif_vdev_t device; /* 8: Device number (opaque 16 bit value). */
u16 info; /* 10: Device type and flags (VDISK_*). */
} PACKED vdisk_t; /* 12 bytes */
#endif /* __SHARED_BLKIF_H__ */
|