aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/include/asm/dasd.h40
-rw-r--r--drivers/s390/block/dasd_eckd.c69
-rw-r--r--drivers/s390/block/dasd_eckd.h1
3 files changed, 92 insertions, 18 deletions
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h
index 218bce81ec70..b604a9186f8e 100644
--- a/arch/s390/include/asm/dasd.h
+++ b/arch/s390/include/asm/dasd.h
@@ -217,6 +217,25 @@ typedef struct dasd_symmio_parms {
217 int rssd_result_len; 217 int rssd_result_len;
218} __attribute__ ((packed)) dasd_symmio_parms_t; 218} __attribute__ ((packed)) dasd_symmio_parms_t;
219 219
220/*
221 * Data returned by Sense Path Group ID (SNID)
222 */
223struct dasd_snid_data {
224 struct {
225 __u8 group:2;
226 __u8 reserve:2;
227 __u8 mode:1;
228 __u8 res:3;
229 } __attribute__ ((packed)) path_state;
230 __u8 pgid[11];
231} __attribute__ ((packed));
232
233struct dasd_snid_ioctl_data {
234 struct dasd_snid_data data;
235 __u8 path_mask;
236} __attribute__ ((packed));
237
238
220/******************************************************************************** 239/********************************************************************************
221 * SECTION: Definition of IOCTLs 240 * SECTION: Definition of IOCTLs
222 * 241 *
@@ -261,25 +280,10 @@ typedef struct dasd_symmio_parms {
261/* Set Attributes (cache operations) */ 280/* Set Attributes (cache operations) */
262#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) 281#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t)
263 282
283/* Get Sense Path Group ID (SNID) data */
284#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
285
264#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t) 286#define BIODASDSYMMIO _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
265 287
266#endif /* DASD_H */ 288#endif /* DASD_H */
267 289
268/*
269 * Overrides for Emacs so that we follow Linus's tabbing style.
270 * Emacs will notice this stuff at the end of the file and automatically
271 * adjust the settings for this buffer only. This must remain at the end
272 * of the file.
273 * ---------------------------------------------------------------------------
274 * Local variables:
275 * c-indent-level: 4
276 * c-brace-imaginary-offset: 0
277 * c-brace-offset: -4
278 * c-argdecl-indent: 4
279 * c-label-offset: -4
280 * c-continued-statement-offset: 4
281 * c-continued-brace-offset: 0
282 * indent-tabs-mode: nil
283 * tab-width: 8
284 * End:
285 */
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