aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2010-10-29 10:50:43 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-29 10:50:50 -0400
commit196339f1733726ffd69ab81ec1c66678585f5846 (patch)
tree2974211770a2d0ead128f80fef972748673e7e3c /drivers/s390
parentb25c477b3456ce87a5938d2ea511bf13187d0f0d (diff)
[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: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd_eckd.c69
-rw-r--r--drivers/s390/block/dasd_eckd.h1
2 files changed, 70 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 50cf96389d2c..bf61274af3bb 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2802,6 +2802,73 @@ dasd_eckd_steal_lock(struct dasd_device *device)
2802} 2802}
2803 2803
2804/* 2804/*
2805 * SNID - Sense Path Group ID
2806 * This ioctl may be used in situations where I/O is stalled due to
2807 * a reserve, so if the normal dasd_smalloc_request fails, we use the
2808 * preallocated dasd_reserve_req.
2809 */
2810static int dasd_eckd_snid(struct dasd_device *device,
2811 void __user *argp)
2812{
2813 struct dasd_ccw_req *cqr;
2814 int rc;
2815 struct ccw1 *ccw;
2816 int useglobal;
2817 struct dasd_snid_ioctl_data usrparm;
2818
2819 if (!capable(CAP_SYS_ADMIN))
2820 return -EACCES;
2821
2822 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
2823 return -EFAULT;
2824
2825 useglobal = 0;
2826 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,
2827 sizeof(struct dasd_snid_data), device);
2828 if (IS_ERR(cqr)) {
2829 mutex_lock(&dasd_reserve_mutex);
2830 useglobal = 1;
2831 cqr = &dasd_reserve_req->cqr;
2832 memset(cqr, 0, sizeof(*cqr));
2833 memset(&dasd_reserve_req->ccw, 0,
2834 sizeof(dasd_reserve_req->ccw));
2835 cqr->cpaddr = &dasd_reserve_req->ccw;
2836 cqr->data = &dasd_reserve_req->data;
2837 cqr->magic = DASD_ECKD_MAGIC;
2838 }
2839 ccw = cqr->cpaddr;
2840 ccw->cmd_code = DASD_ECKD_CCW_SNID;
2841 ccw->flags |= CCW_FLAG_SLI;
2842 ccw->count = 12;
2843 ccw->cda = (__u32)(addr_t) cqr->data;
2844 cqr->startdev = device;
2845 cqr->memdev = device;
2846 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
2847 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2848 cqr->retries = 5;
2849 cqr->expires = 10 * HZ;
2850 cqr->buildclk = get_clock();
2851 cqr->status = DASD_CQR_FILLED;
2852 cqr->lpm = usrparm.path_mask;
2853
2854 rc = dasd_sleep_on_immediatly(cqr);
2855 /* verify that I/O processing didn't modify the path mask */
2856 if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))
2857 rc = -EIO;
2858 if (!rc) {
2859 usrparm.data = *((struct dasd_snid_data *)cqr->data);
2860 if (copy_to_user(argp, &usrparm, sizeof(usrparm)))
2861 rc = -EFAULT;
2862 }
2863
2864 if (useglobal)
2865 mutex_unlock(&dasd_reserve_mutex);
2866 else
2867 dasd_sfree_request(cqr, cqr->memdev);
2868 return rc;
2869}
2870
2871/*
2805 * Read performance statistics 2872 * Read performance statistics
2806 */ 2873 */
2807static int 2874static int
@@ -3036,6 +3103,8 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
3036 return dasd_eckd_reserve(device); 3103 return dasd_eckd_reserve(device);
3037 case BIODASDSLCK: 3104 case BIODASDSLCK:
3038 return dasd_eckd_steal_lock(device); 3105 return dasd_eckd_steal_lock(device);
3106 case BIODASDSNID:
3107 return dasd_eckd_snid(device, argp);
3039 case BIODASDSYMMIO: 3108 case BIODASDSYMMIO:
3040 return dasd_symm_io(device, argp); 3109 return dasd_symm_io(device, argp);
3041 default: 3110 default:
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 0eb49655a6cd..12097c24f2f5 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -27,6 +27,7 @@
27#define DASD_ECKD_CCW_WRITE_CKD 0x1d 27#define DASD_ECKD_CCW_WRITE_CKD 0x1d
28#define DASD_ECKD_CCW_READ_CKD 0x1e 28#define DASD_ECKD_CCW_READ_CKD 0x1e
29#define DASD_ECKD_CCW_PSF 0x27 29#define DASD_ECKD_CCW_PSF 0x27
30#define DASD_ECKD_CCW_SNID 0x34
30#define DASD_ECKD_CCW_RSSD 0x3e 31#define DASD_ECKD_CCW_RSSD 0x3e
31#define DASD_ECKD_CCW_LOCATE_RECORD 0x47 32#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
32#define DASD_ECKD_CCW_SNSS 0x54 33#define DASD_ECKD_CCW_SNSS 0x54