Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -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:
 */
+69 −0
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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