1 commit ab1d848fd6a9151b02c6cbf4bddce6e24707b094
2 From: Nigel Hislop <hislop_nigel@emc.com>
3 Date: Fri Oct 10 21:33:25 2008 +0200
4 Subject: Add ioctl support for EMC Symmetrix Subsystem Control I/O
7 EMC Symmetrix Subsystem Control I/O through CKD dasd requires a
8 specific parameter list sent to the array via a Perform Subsystem
9 Function CCW. The Symmetrix response is retrieved from the array
10 via a Read Subsystem Data CCW.
12 Signed-off-by: Nigel Hislop <hislop_nigel@emc.com>
13 Signed-off-by: Hannes Reinecke <hare@suse.de>
14 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
17 arch/s390/include/asm/dasd.h | 13 +++++
18 drivers/s390/block/dasd_eckd.c | 101 +++++++++++++++++++++++++++++++++++++++++
19 2 files changed, 114 insertions(+)
21 --- a/arch/s390/include/asm/dasd.h
22 +++ b/arch/s390/include/asm/dasd.h
24 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
25 * Bugreports.to..: <Linux390@de.ibm.com>
26 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
27 + * EMC Symmetrix ioctl Copyright EMC Corporation, 2008
28 + * Author.........: Nigel Hislop <hislop_nigel@emc.com>
30 * This file is the interface of the DASD device driver, which is exported to user space
31 * any future changes wrt the API will result in a change of the APIVERSION reported
32 @@ -202,6 +204,16 @@ typedef struct attrib_data_t {
33 #define DASD_SEQ_PRESTAGE 0x4
34 #define DASD_REC_ACCESS 0x5
37 + * Perform EMC Symmetrix I/O
39 +typedef struct dasd_symmio_parms {
40 + unsigned char reserved[8]; /* compat with older releases */
41 + unsigned long long psf_data; /* char * cast to u64 */
42 + unsigned long long rssd_result; /* char * cast to u64 */
44 + int rssd_result_len;
45 +} __attribute__ ((packed)) dasd_symmio_parms_t;
47 /********************************************************************************
48 * SECTION: Definition of IOCTLs
49 @@ -247,6 +259,7 @@ typedef struct attrib_data_t {
50 /* Set Attributes (cache operations) */
51 #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
53 +#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
57 --- a/drivers/s390/block/dasd_eckd.c
58 +++ b/drivers/s390/block/dasd_eckd.c
60 * Martin Schwidefsky <schwidefsky@de.ibm.com>
61 * Bugreports.to..: <Linux390@de.ibm.com>
62 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
63 + * EMC Symmetrix ioctl Copyright EMC Corporation, 2008
64 + * Author.........: Nigel Hislop <hislop_nigel@emc.com>
68 @@ -2083,6 +2085,103 @@ dasd_eckd_set_attrib(struct dasd_device
73 + * Issue syscall I/O to EMC Symmetrix array.
74 + * CCWs are PSF and RSSD
76 +static int dasd_symm_io(struct dasd_device *device, void __user *argp)
78 + struct dasd_symmio_parms usrparm;
79 + char *psf_data, *rssd_result;
80 + struct dasd_ccw_req *cqr;
84 + /* Copy parms from caller */
86 + if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
89 + /* Make sure pointers are sane even on 31 bit. */
90 + if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) {
95 + /* alloc I/O data area */
96 + psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
97 + rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
98 + if (!psf_data || !rssd_result) {
103 + /* get syscall header from user space */
105 + if (copy_from_user(psf_data,
106 + (void __user *)(unsigned long) usrparm.psf_data,
107 + usrparm.psf_data_len))
110 + /* sanity check on syscall header */
111 + if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
116 + /* setup CCWs for PSF + RSSD */
117 + cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
119 + DEV_MESSAGE(KERN_WARNING, device, "%s",
120 + "Could not allocate initialization request");
125 + cqr->startdev = device;
126 + cqr->memdev = device;
128 + cqr->expires = 10 * HZ;
129 + cqr->buildclk = get_clock();
130 + cqr->status = DASD_CQR_FILLED;
132 + /* Build the ccws */
136 + ccw->cmd_code = DASD_ECKD_CCW_PSF;
137 + ccw->count = usrparm.psf_data_len;
138 + ccw->flags |= CCW_FLAG_CC;
139 + ccw->cda = (__u32)(addr_t) psf_data;
144 + ccw->cmd_code = DASD_ECKD_CCW_RSSD;
145 + ccw->count = usrparm.rssd_result_len;
146 + ccw->flags = CCW_FLAG_SLI ;
147 + ccw->cda = (__u32)(addr_t) rssd_result;
149 + rc = dasd_sleep_on(cqr);
154 + if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,
155 + rssd_result, usrparm.rssd_result_len))
160 + dasd_sfree_request(cqr, cqr->memdev);
162 + kfree(rssd_result);
165 + DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
170 dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
172 @@ -2101,6 +2200,8 @@ dasd_eckd_ioctl(struct dasd_block *block
173 return dasd_eckd_reserve(device);
175 return dasd_eckd_steal_lock(device);
176 + case BIODASDSYMMIO:
177 + return dasd_symm_io(device, argp);