Commit 196339f1 authored by Stefan Weinhuber's avatar Stefan Weinhuber Committed by Martin Schwidefsky

[S390] dasd: provide a Sense Path Group ID ioctl

The BIODASDSNID ioctl executes a 'Sense Path Group ID'
command on a DASD ECKD device. The returned path group data
allows user space programs to determine path state and
path group ID of the channel paths to the device.
Signed-off-by: default avatarStefan Weinhuber <wein@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b25c477b
......@@ -217,6 +217,25 @@ typedef struct dasd_symmio_parms {
int rssd_result_len;
} __attribute__ ((packed)) dasd_symmio_parms_t;
/*
* Data returned by Sense Path Group ID (SNID)
*/
struct dasd_snid_data {
struct {
__u8 group:2;
__u8 reserve:2;
__u8 mode:1;
__u8 res:3;
} __attribute__ ((packed)) path_state;
__u8 pgid[11];
} __attribute__ ((packed));
struct dasd_snid_ioctl_data {
struct dasd_snid_data data;
__u8 path_mask;
} __attribute__ ((packed));
/********************************************************************************
* SECTION: Definition of IOCTLs
*
......@@ -261,25 +280,10 @@ typedef struct dasd_symmio_parms {
/* Set Attributes (cache operations) */
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
/* Get Sense Path Group ID (SNID) data */
#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
#endif /* DASD_H */
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
......@@ -2801,6 +2801,73 @@ dasd_eckd_steal_lock(struct dasd_device *device)
return rc;
}
/*
* SNID - Sense Path Group ID
* This ioctl may be used in situations where I/O is stalled due to
* a reserve, so if the normal dasd_smalloc_request fails, we use the
* preallocated dasd_reserve_req.
*/
static int dasd_eckd_snid(struct dasd_device *device,
void __user *argp)
{
struct dasd_ccw_req *cqr;
int rc;
struct ccw1 *ccw;
int useglobal;
struct dasd_snid_ioctl_data usrparm;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
return -EFAULT;
useglobal = 0;
cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,
sizeof(struct dasd_snid_data), device);
if (IS_ERR(cqr)) {
mutex_lock(&dasd_reserve_mutex);
useglobal = 1;
cqr = &dasd_reserve_req->cqr;
memset(cqr, 0, sizeof(*cqr));
memset(&dasd_reserve_req->ccw, 0,
sizeof(dasd_reserve_req->ccw));
cqr->cpaddr = &dasd_reserve_req->ccw;
cqr->data = &dasd_reserve_req->data;
cqr->magic = DASD_ECKD_MAGIC;
}
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_SNID;
ccw->flags |= CCW_FLAG_SLI;
ccw->count = 12;
ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->retries = 5;
cqr->expires = 10 * HZ;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
cqr->lpm = usrparm.path_mask;
rc = dasd_sleep_on_immediatly(cqr);
/* verify that I/O processing didn't modify the path mask */
if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))
rc = -EIO;
if (!rc) {
usrparm.data = *((struct dasd_snid_data *)cqr->data);
if (copy_to_user(argp, &usrparm, sizeof(usrparm)))
rc = -EFAULT;
}
if (useglobal)
mutex_unlock(&dasd_reserve_mutex);
else
dasd_sfree_request(cqr, cqr->memdev);
return rc;
}
/*
* Read performance statistics
*/
......@@ -3036,6 +3103,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 BIODASDSNID:
return dasd_eckd_snid(device, argp);
case BIODASDSYMMIO:
return dasd_symm_io(device, argp);
default:
......
......@@ -27,6 +27,7 @@
#define DASD_ECKD_CCW_WRITE_CKD 0x1d
#define DASD_ECKD_CCW_READ_CKD 0x1e
#define DASD_ECKD_CCW_PSF 0x27
#define DASD_ECKD_CCW_SNID 0x34
#define DASD_ECKD_CCW_RSSD 0x3e
#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
#define DASD_ECKD_CCW_SNSS 0x54
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment