mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 08:31:37 +00:00
[S390] Add ioctl support for EMC Symmetrix Subsystem Control I/O
EMC Symmetrix Subsystem Control I/O through CKD dasd requires a specific parameter list sent to the array via a Perform Subsystem Function CCW. The Symmetrix response is retrieved from the array via a Read Subsystem Data CCW. Signed-off-by: Nigel Hislop <hislop_nigel@emc.com> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
3ce66093f5
commit
ab1d848fd6
@ -3,6 +3,8 @@
|
||||
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
|
||||
* Bugreports.to..: <Linux390@de.ibm.com>
|
||||
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
|
||||
* EMC Symmetrix ioctl Copyright EMC Corporation, 2008
|
||||
* Author.........: Nigel Hislop <hislop_nigel@emc.com>
|
||||
*
|
||||
* This file is the interface of the DASD device driver, which is exported to user space
|
||||
* any future changes wrt the API will result in a change of the APIVERSION reported
|
||||
@ -202,6 +204,16 @@ typedef struct attrib_data_t {
|
||||
#define DASD_SEQ_PRESTAGE 0x4
|
||||
#define DASD_REC_ACCESS 0x5
|
||||
|
||||
/*
|
||||
* Perform EMC Symmetrix I/O
|
||||
*/
|
||||
typedef struct dasd_symmio_parms {
|
||||
unsigned char reserved[8]; /* compat with older releases */
|
||||
unsigned long long psf_data; /* char * cast to u64 */
|
||||
unsigned long long rssd_result; /* char * cast to u64 */
|
||||
int psf_data_len;
|
||||
int rssd_result_len;
|
||||
} __attribute__ ((packed)) dasd_symmio_parms_t;
|
||||
|
||||
/********************************************************************************
|
||||
* SECTION: Definition of IOCTLs
|
||||
@ -247,6 +259,7 @@ typedef struct attrib_data_t {
|
||||
/* Set Attributes (cache operations) */
|
||||
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
|
||||
|
||||
#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
|
||||
|
||||
#endif /* DASD_H */
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
* Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
* Bugreports.to..: <Linux390@de.ibm.com>
|
||||
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
|
||||
* EMC Symmetrix ioctl Copyright EMC Corporation, 2008
|
||||
* Author.........: Nigel Hislop <hislop_nigel@emc.com>
|
||||
*
|
||||
*/
|
||||
|
||||
@ -2083,6 +2085,103 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue syscall I/O to EMC Symmetrix array.
|
||||
* CCWs are PSF and RSSD
|
||||
*/
|
||||
static int dasd_symm_io(struct dasd_device *device, void __user *argp)
|
||||
{
|
||||
struct dasd_symmio_parms usrparm;
|
||||
char *psf_data, *rssd_result;
|
||||
struct dasd_ccw_req *cqr;
|
||||
struct ccw1 *ccw;
|
||||
int rc;
|
||||
|
||||
/* Copy parms from caller */
|
||||
rc = -EFAULT;
|
||||
if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
|
||||
goto out;
|
||||
#ifndef CONFIG_64BIT
|
||||
/* Make sure pointers are sane even on 31 bit. */
|
||||
if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
/* alloc I/O data area */
|
||||
psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);
|
||||
rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);
|
||||
if (!psf_data || !rssd_result) {
|
||||
rc = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* get syscall header from user space */
|
||||
rc = -EFAULT;
|
||||
if (copy_from_user(psf_data,
|
||||
(void __user *)(unsigned long) usrparm.psf_data,
|
||||
usrparm.psf_data_len))
|
||||
goto out_free;
|
||||
|
||||
/* sanity check on syscall header */
|
||||
if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
|
||||
rc = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* setup CCWs for PSF + RSSD */
|
||||
cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
|
||||
if (IS_ERR(cqr)) {
|
||||
DEV_MESSAGE(KERN_WARNING, device, "%s",
|
||||
"Could not allocate initialization request");
|
||||
rc = PTR_ERR(cqr);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
cqr->startdev = device;
|
||||
cqr->memdev = device;
|
||||
cqr->retries = 3;
|
||||
cqr->expires = 10 * HZ;
|
||||
cqr->buildclk = get_clock();
|
||||
cqr->status = DASD_CQR_FILLED;
|
||||
|
||||
/* Build the ccws */
|
||||
ccw = cqr->cpaddr;
|
||||
|
||||
/* PSF ccw */
|
||||
ccw->cmd_code = DASD_ECKD_CCW_PSF;
|
||||
ccw->count = usrparm.psf_data_len;
|
||||
ccw->flags |= CCW_FLAG_CC;
|
||||
ccw->cda = (__u32)(addr_t) psf_data;
|
||||
|
||||
ccw++;
|
||||
|
||||
/* RSSD ccw */
|
||||
ccw->cmd_code = DASD_ECKD_CCW_RSSD;
|
||||
ccw->count = usrparm.rssd_result_len;
|
||||
ccw->flags = CCW_FLAG_SLI ;
|
||||
ccw->cda = (__u32)(addr_t) rssd_result;
|
||||
|
||||
rc = dasd_sleep_on(cqr);
|
||||
if (rc)
|
||||
goto out_sfree;
|
||||
|
||||
rc = -EFAULT;
|
||||
if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,
|
||||
rssd_result, usrparm.rssd_result_len))
|
||||
goto out_sfree;
|
||||
rc = 0;
|
||||
|
||||
out_sfree:
|
||||
dasd_sfree_request(cqr, cqr->memdev);
|
||||
out_free:
|
||||
kfree(rssd_result);
|
||||
kfree(psf_data);
|
||||
out:
|
||||
DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
|
||||
{
|
||||
@ -2101,6 +2200,8 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
|
||||
return dasd_eckd_reserve(device);
|
||||
case BIODASDSLCK:
|
||||
return dasd_eckd_steal_lock(device);
|
||||
case BIODASDSYMMIO:
|
||||
return dasd_symm_io(device, argp);
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user