s390/dasd: Add new ioctl to release space

Userspace tools might have the need to release space for Extent Space
Efficient (ESE) volumes when working with such a device.

Provide the necessarry interface for such a task by implementing a new
ioctl BIODASDRAS. The ioctl uses the format_data_t data structure for
data input:

typedef struct format_data_t {
        unsigned int start_unit;        /* from track */
        unsigned int stop_unit;         /* to track */
        unsigned int blksize;           /* sectorsize */
        unsigned int intensity;
} format_data_t;

If the intensity is set to 0x40, start_unit and stop_unit are ignored
and space for the entire volume is released. Otherwise, if intensity is
set to 0, the respective range is released (if possible).

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index bc59980..4226936 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -50,6 +50,10 @@
 #define DASD_ECKD_CCW_PFX_READ		 0xEA
 #define DASD_ECKD_CCW_RSCK		 0xF9
 #define DASD_ECKD_CCW_RCD		 0xFA
+#define DASD_ECKD_CCW_DSO		 0xF7
+
+/* Define Subssystem Function / Orders */
+#define DSO_ORDER_RAS			 0x81
 
 /*
  * Perform Subsystem Function / Orders
@@ -513,6 +517,42 @@ struct dasd_psf_ssc_data {
 	unsigned char reserved[59];
 } __attribute__((packed));
 
+/* Maximum number of extents for a single Release Allocated Space command */
+#define DASD_ECKD_RAS_EXTS_MAX		110U
+
+struct dasd_dso_ras_ext_range {
+	struct ch_t beg_ext;
+	struct ch_t end_ext;
+} __packed;
+
+/*
+ * Define Subsytem Operation - Release Allocated Space
+ */
+struct dasd_dso_ras_data {
+	__u8 order;
+	struct {
+		__u8 message:1;		/* Must be zero */
+		__u8 reserved1:2;
+		__u8 vol_type:1;	/* 0 - CKD/FBA, 1 - FB */
+		__u8 reserved2:4;
+	} __packed flags;
+	/* Operation Flags to specify scope */
+	struct {
+		__u8 reserved1:2;
+		/* Release Space by Extent */
+		__u8 by_extent:1;	/* 0 - entire volume, 1 - specified extents */
+		__u8 guarantee_init:1;
+		__u8 force_release:1;	/* Internal - will be ignored */
+		__u16 reserved2:11;
+	} __packed op_flags;
+	__u8 lss;
+	__u8 dev_addr;
+	__u32 reserved1;
+	__u8 reserved2[10];
+	__u16 nr_exts;			/* Defines number of ext_scope - max 110 */
+	__u16 reserved3;
+} __packed;
+
 
 /*
  * some structures and definitions for alias handling