2007-07-17 18:37:04 -07:00
/******************************************************************************
* blkif . h
*
* Unified block - device I / O interface for Xen guest OSes .
*
* Copyright ( c ) 2003 - 2004 , Keir Fraser
*/
# ifndef __XEN_PUBLIC_IO_BLKIF_H__
# define __XEN_PUBLIC_IO_BLKIF_H__
2012-10-02 18:01:25 +01:00
# include <xen/interface/io/ring.h>
# include <xen/interface/grant_table.h>
2007-07-17 18:37:04 -07:00
/*
* Front - > back notifications : When enqueuing a new request , sending a
* notification can be made conditional on req_event ( i . e . , the generic
* hold - off mechanism provided by the ring macros ) . Backends must set
* req_event appropriately ( e . g . , using RING_FINAL_CHECK_FOR_REQUESTS ( ) ) .
*
* Back - > front notifications : When enqueuing a new response , sending a
* notification can be made conditional on rsp_event ( i . e . , the generic
* hold - off mechanism provided by the ring macros ) . Frontends must set
* rsp_event appropriately ( e . g . , using RING_FINAL_CHECK_FOR_RESPONSES ( ) ) .
*/
typedef uint16_t blkif_vdev_t ;
typedef uint64_t blkif_sector_t ;
/*
* REQUEST CODES .
*/
# define BLKIF_OP_READ 0
# define BLKIF_OP_WRITE 1
/*
* Recognised only if " feature-barrier " is present in backend xenbus info .
* The " feature_barrier " node contains a boolean indicating whether barrier
* requests are likely to succeed or fail . Either way , a barrier request
* may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by
* the underlying block - device hardware . The boolean simply indicates whether
* or not it is worthwhile for the frontend to attempt barrier requests .
* If a backend does not recognise BLKIF_OP_WRITE_BARRIER , it should * not *
* create the " feature-barrier " node !
*/
# define BLKIF_OP_WRITE_BARRIER 2
2011-05-05 12:41:03 -04:00
/*
* Recognised if " feature-flush-cache " is present in backend xenbus
* info . A flush will ask the underlying storage hardware to flush its
* non - volatile caches as appropriate . The " feature-flush-cache " node
* contains a boolean indicating whether flush requests are likely to
* succeed or fail . Either way , a flush request may fail at any time
* with BLKIF_RSP_EOPNOTSUPP if it is unsupported by the underlying
* block - device hardware . The boolean simply indicates whether or not it
* is worthwhile for the frontend to attempt flushes . If a backend does
* not recognise BLKIF_OP_WRITE_FLUSH_CACHE , it should * not * create the
* " feature-flush-cache " node !
*/
# define BLKIF_OP_FLUSH_DISKCACHE 3
2011-09-01 18:39:08 +08:00
/*
* Recognised only if " feature-discard " is present in backend xenbus info .
* The " feature-discard " node contains a boolean indicating whether trim
* ( ATA ) or unmap ( SCSI ) - conviently called discard requests are likely
* to succeed or fail . Either way , a discard request
* may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by
* the underlying block - device hardware . The boolean simply indicates whether
* or not it is worthwhile for the frontend to attempt discard requests .
* If a backend does not recognise BLKIF_OP_DISCARD , it should * not *
* create the " feature-discard " node !
*
* Discard operation is a request for the underlying block device to mark
* extents to be erased . However , discard does not guarantee that the blocks
* will be erased from the device - it is just a hint to the device
* controller that these blocks are no longer in use . What the device
* controller does with that information is left to the controller .
* Discard operations are passed with sector_number as the
* sector index to begin discard operations at and nr_sectors as the number of
* sectors to be discarded . The specified sectors should be discarded if the
* underlying block device supports trim ( ATA ) or unmap ( SCSI ) operations ,
* or a BLKIF_RSP_EOPNOTSUPP should be returned .
* More information about trim / unmap operations at :
* http : //t13.org/Documents/UploadedDocuments/docs2008/
* e07154r6 - Data_Set_Management_Proposal_for_ATA - ACS2 . doc
* http : //www.seagate.com/staticfiles/support/disc/manuals/
* Interface % 20 manuals / 100293068 c . pdf
2011-10-12 16:23:30 -04:00
* The backend can optionally provide three extra XenBus attributes to
* further optimize the discard functionality :
2014-05-21 16:32:41 +02:00
* ' discard - alignment ' - Devices that support discard functionality may
2011-10-12 16:23:30 -04:00
* internally allocate space in units that are bigger than the exported
* logical block size . The discard - alignment parameter indicates how many bytes
* the beginning of the partition is offset from the internal allocation unit ' s
* natural alignment .
* ' discard - granularity ' - Devices that support discard functionality may
* internally allocate space using units that are bigger than the logical block
* size . The discard - granularity parameter indicates the size of the internal
* allocation unit in bytes if reported by the device . Otherwise the
* discard - granularity will be set to match the device ' s physical block size .
* ' discard - secure ' - All copies of the discarded sectors ( potentially created
* by garbage collection ) must also be erased . To use this feature , the flag
* BLKIF_DISCARD_SECURE must be set in the blkif_request_trim .
2011-09-01 18:39:08 +08:00
*/
# define BLKIF_OP_DISCARD 5
2013-04-18 16:06:54 +02:00
/*
* Recognized if " feature-max-indirect-segments " in present in the backend
* xenbus info . The " feature-max-indirect-segments " node contains the maximum
* number of segments allowed by the backend per request . If the node is
* present , the frontend might use blkif_request_indirect structs in order to
* issue requests with more than BLKIF_MAX_SEGMENTS_PER_REQUEST ( 11 ) . The
* maximum number of indirect segments is fixed by the backend , but the
* frontend can issue requests with any number of indirect segments as long as
* it ' s less than the number provided by the backend . The indirect_grefs field
* in blkif_request_indirect should be filled by the frontend with the
* grant references of the pages that are holding the indirect segments .
2014-02-04 11:26:15 +01:00
* These pages are filled with an array of blkif_request_segment that hold the
* information about the segments . The number of indirect pages to use is
* determined by the number of segments an indirect request contains . Every
* indirect page can contain a maximum of
* ( PAGE_SIZE / sizeof ( struct blkif_request_segment ) ) segments , so to
* calculate the number of indirect pages to use we have to do
* ceil ( indirect_segments / ( PAGE_SIZE / sizeof ( struct blkif_request_segment ) ) ) .
2013-04-18 16:06:54 +02:00
*
* If a backend does not recognize BLKIF_OP_INDIRECT , it should * not *
* create the " feature-max-indirect-segments " node !
*/
# define BLKIF_OP_INDIRECT 6
2007-07-17 18:37:04 -07:00
/*
* Maximum scatter / gather segments per request .
* This is carefully chosen so that sizeof ( struct blkif_ring ) < = 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
2013-04-18 16:06:54 +02:00
# define BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST 8
2014-02-04 11:26:15 +01:00
struct blkif_request_segment {
grant_ref_t gref ; /* reference to I/O buffer frame */
/* @first_sect: first sector in frame to transfer (inclusive). */
/* @last_sect: last sector in frame to transfer (inclusive). */
uint8_t first_sect , last_sect ;
} ;
2013-04-18 16:06:54 +02:00
2010-12-22 15:05:00 +00:00
struct blkif_request_rw {
2011-10-12 12:12:36 -04:00
uint8_t nr_segments ; /* number of segments */
blkif_vdev_t handle ; /* only for read/write requests */
2013-12-03 15:40:37 +00:00
# ifndef CONFIG_X86_32
2011-10-12 12:12:36 -04:00
uint32_t _pad1 ; /* offsetof(blkif_request,u.rw.id) == 8 */
# endif
uint64_t id ; /* private guest value, echoed in resp */
2007-07-17 18:37:04 -07:00
blkif_sector_t sector_number ; /* start sector idx on disk (r/w only) */
2014-02-04 11:26:15 +01:00
struct blkif_request_segment seg [ BLKIF_MAX_SEGMENTS_PER_REQUEST ] ;
2011-10-12 12:12:36 -04:00
} __attribute__ ( ( __packed__ ) ) ;
2007-07-17 18:37:04 -07:00
2011-09-01 18:39:08 +08:00
struct blkif_request_discard {
2011-10-12 16:23:30 -04:00
uint8_t flag ; /* BLKIF_DISCARD_SECURE or zero. */
# define BLKIF_DISCARD_SECURE (1<<0) /* ignored if discard-secure=0 */
2011-10-12 12:12:36 -04:00
blkif_vdev_t _pad1 ; /* only for read/write requests */
2013-12-03 15:40:37 +00:00
# ifndef CONFIG_X86_32
2011-10-12 12:12:36 -04:00
uint32_t _pad2 ; /* offsetof(blkif_req..,u.discard.id)==8*/
# endif
uint64_t id ; /* private guest value, echoed in resp */
2011-09-01 18:39:08 +08:00
blkif_sector_t sector_number ;
2011-10-12 12:12:36 -04:00
uint64_t nr_sectors ;
uint8_t _pad3 ;
} __attribute__ ( ( __packed__ ) ) ;
2011-09-01 18:39:08 +08:00
2013-03-07 17:32:01 +00:00
struct blkif_request_other {
uint8_t _pad1 ;
blkif_vdev_t _pad2 ; /* only for read/write requests */
2013-12-03 15:40:37 +00:00
# ifndef CONFIG_X86_32
2013-03-07 17:32:01 +00:00
uint32_t _pad3 ; /* offsetof(blkif_req..,u.other.id)==8*/
# endif
uint64_t id ; /* private guest value, echoed in resp */
} __attribute__ ( ( __packed__ ) ) ;
2013-04-18 16:06:54 +02:00
struct blkif_request_indirect {
uint8_t indirect_op ;
uint16_t nr_segments ;
2013-12-03 15:40:37 +00:00
# ifndef CONFIG_X86_32
2013-04-18 16:06:54 +02:00
uint32_t _pad1 ; /* offsetof(blkif_...,u.indirect.id) == 8 */
# endif
uint64_t id ;
blkif_sector_t sector_number ;
blkif_vdev_t handle ;
uint16_t _pad2 ;
grant_ref_t indirect_grefs [ BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST ] ;
2013-12-03 15:40:37 +00:00
# ifndef CONFIG_X86_32
2013-04-18 16:06:54 +02:00
uint32_t _pad3 ; /* make it 64 byte aligned */
# else
uint64_t _pad3 ; /* make it 64 byte aligned */
# endif
} __attribute__ ( ( __packed__ ) ) ;
2010-12-22 15:05:00 +00:00
struct blkif_request {
uint8_t operation ; /* BLKIF_OP_??? */
union {
struct blkif_request_rw rw ;
2011-09-01 18:39:08 +08:00
struct blkif_request_discard discard ;
2013-03-07 17:32:01 +00:00
struct blkif_request_other other ;
2013-04-18 16:06:54 +02:00
struct blkif_request_indirect indirect ;
2010-12-22 15:05:00 +00:00
} u ;
2011-10-12 12:12:36 -04:00
} __attribute__ ( ( __packed__ ) ) ;
2010-12-22 15:05:00 +00:00
2007-07-17 18:37:04 -07:00
struct blkif_response {
uint64_t id ; /* copied from request */
uint8_t operation ; /* copied from request */
int16_t status ; /* BLKIF_RSP_??? */
} ;
/*
* STATUS RETURN CODES .
*/
/* Operation not supported (only happens on barrier writes). */
# define BLKIF_RSP_EOPNOTSUPP -2
/* Operation failed for some unspecified reason (-EIO). */
# define BLKIF_RSP_ERROR -1
/* Operation completed successfully. */
# define BLKIF_RSP_OKAY 0
/*
* Generate blkif ring structures and types .
*/
DEFINE_RING_TYPES ( blkif , struct blkif_request , struct blkif_response ) ;
# define VDISK_CDROM 0x1
# define VDISK_REMOVABLE 0x2
# define VDISK_READONLY 0x4
2010-12-02 17:55:00 +00:00
/* Xen-defined major numbers for virtual disks, they look strangely
* familiar */
# define XEN_IDE0_MAJOR 3
# define XEN_IDE1_MAJOR 22
# define XEN_SCSI_DISK0_MAJOR 8
# define XEN_SCSI_DISK1_MAJOR 65
# define XEN_SCSI_DISK2_MAJOR 66
# define XEN_SCSI_DISK3_MAJOR 67
# define XEN_SCSI_DISK4_MAJOR 68
# define XEN_SCSI_DISK5_MAJOR 69
# define XEN_SCSI_DISK6_MAJOR 70
# define XEN_SCSI_DISK7_MAJOR 71
# define XEN_SCSI_DISK8_MAJOR 128
# define XEN_SCSI_DISK9_MAJOR 129
# define XEN_SCSI_DISK10_MAJOR 130
# define XEN_SCSI_DISK11_MAJOR 131
# define XEN_SCSI_DISK12_MAJOR 132
# define XEN_SCSI_DISK13_MAJOR 133
# define XEN_SCSI_DISK14_MAJOR 134
# define XEN_SCSI_DISK15_MAJOR 135
2007-07-17 18:37:04 -07:00
# endif /* __XEN_PUBLIC_IO_BLKIF_H__ */