Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *		    Horst Hummel <Horst.Hummel@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *		    Carsten Otte <Cotte@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Bugreports.to..: <Linux390@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright IBM Corp. 1999, 2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * i/o controls for the dasd driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define KMSG_COMPONENT "dasd"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/blkpg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/ccwdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/schid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/cmb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/dasd_mod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* This is ugly... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PRINTK_HEADER "dasd_ioctl:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "dasd_int.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) dasd_ioctl_api_version(void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int ver = DASD_API_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	return put_user(ver, (int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * Enable device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * used by dasdfmt after BIODASDDISABLE to retrigger blocksize detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) dasd_ioctl_enable(struct block_device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	dasd_enable_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	/* Formatting the dasd device can change the capacity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	bd_set_nr_sectors(bdev, get_capacity(base->block->gdp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * Disable device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * Used by dasdfmt. Disable I/O operations but allow ioctls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) dasd_ioctl_disable(struct block_device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 * Man this is sick. We don't do a real disable but only downgrade
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * BIODASDDISABLE to disable accesses to the device via the block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * device layer but it still wants to do i/o on the device by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * using the BIODASDFMT ioctl. Therefore the correct state for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * device is DASD_STATE_BASIC that allows to do basic i/o.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	dasd_set_target_state(base, DASD_STATE_BASIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 * Set i_size to zero, since read, write, etc. check against this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 * value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	bd_set_nr_sectors(bdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * Quiesce device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int dasd_ioctl_quiesce(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (!capable (CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	pr_info("%s: The DASD has been put in the quiesce "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		"state\n", dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * Resume device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int dasd_ioctl_resume(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	if (!capable (CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	pr_info("%s: I/O operations have been resumed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		"on the DASD\n", dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	dasd_device_remove_stop_bits(base, DASD_STOPPED_QUIESCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	dasd_schedule_block_bh(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * Abort all failfast I/O on a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int dasd_ioctl_abortio(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct dasd_ccw_req *cqr, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (test_and_set_bit(DASD_FLAG_ABORTALL, &base->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag set");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	spin_lock_irqsave(&block->request_queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	spin_lock(&block->queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		    cqr->callback_data &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		    cqr->callback_data != DASD_SLEEPON_START_TAG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		    cqr->callback_data != DASD_SLEEPON_END_TAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			spin_unlock(&block->queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			blk_abort_request(cqr->callback_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			spin_lock(&block->queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	spin_unlock(&block->queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	spin_unlock_irqrestore(&block->request_queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	dasd_schedule_block_bh(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * Allow I/O on a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int dasd_ioctl_allowio(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (test_and_clear_bit(DASD_FLAG_ABORTALL, &base->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag unset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * performs formatting of _device_ according to _fdata_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * Note: The discipline's format_function is assumed to deliver formatting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * commands to format multiple units of the device. In terms of the ECKD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  * devices this means CCWs are generated to format multiple tracks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dasd_format(struct dasd_block *block, struct format_data_t *fdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (base->discipline->format_device == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (base->state != DASD_STATE_BASIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		pr_warn("%s: The DASD cannot be formatted while it is enabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	DBF_DEV_EVENT(DBF_NOTICE, base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		      "formatting units %u to %u (%u B blocks) flags %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		      fdata->start_unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		      fdata->stop_unit, fdata->blksize, fdata->intensity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* Since dasdfmt keeps the device open after it was disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	 * there still exists an inode for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	 * We must update i_blkbits, otherwise we might get errors when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	 * enabling the device later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (fdata->start_unit == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		struct block_device *bdev = bdget_disk(block->gdp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		bdput(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	rc = base->discipline->format_device(base, fdata, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (rc == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		rc = base->discipline->format_device(base, fdata, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int dasd_check_format(struct dasd_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			     struct format_check_t *cdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (!base->discipline->check_device_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	rc = base->discipline->check_device_format(base, cdata, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (rc == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		rc = base->discipline->check_device_format(base, cdata, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * Format device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dasd_ioctl_format(struct block_device *bdev, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	struct format_data_t fdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (!argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (base->features & DASD_FEATURE_READONLY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	    test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (bdev_is_partition(bdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		pr_warn("%s: The specified DASD is a partition and cannot be formatted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	rc = dasd_format(base->block, &fdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * Check device format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int dasd_ioctl_check_format(struct block_device *bdev, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct format_check_t cdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (!argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (bdev_is_partition(bdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		pr_warn("%s: The specified DASD is a partition and cannot be checked\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (copy_from_user(&cdata, argp, sizeof(cdata))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	rc = dasd_check_format(base->block, &cdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (copy_to_user(argp, &cdata, sizeof(cdata)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int dasd_release_space(struct dasd_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			      struct format_data_t *rdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if (!device->discipline->is_ese && !device->discipline->is_ese(device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (!device->discipline->release_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	return device->discipline->release_space(device, rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  * Release allocated space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int dasd_ioctl_release_space(struct block_device *bdev, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct format_data_t rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (!argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (base->features & DASD_FEATURE_READONLY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	    test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		rc = -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (bdev_is_partition(bdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		pr_warn("%s: The specified DASD is a partition and tracks cannot be released\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			dev_name(&base->cdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	if (copy_from_user(&rdata, argp, sizeof(rdata))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	rc = dasd_release_space(base, &rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #ifdef CONFIG_DASD_PROFILE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  * Reset device profile information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int dasd_ioctl_reset_profile(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	dasd_profile_reset(&block->profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * Return device profile information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct dasd_profile_info_t *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	data = kmalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	spin_lock_bh(&block->profile.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	if (block->profile.data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		data->dasd_io_reqs = block->profile.data->dasd_io_reqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		data->dasd_io_sects = block->profile.data->dasd_io_sects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		memcpy(data->dasd_io_secs, block->profile.data->dasd_io_secs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		       sizeof(data->dasd_io_secs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		memcpy(data->dasd_io_times, block->profile.data->dasd_io_times,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		       sizeof(data->dasd_io_times));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		memcpy(data->dasd_io_timps, block->profile.data->dasd_io_timps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		       sizeof(data->dasd_io_timps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		memcpy(data->dasd_io_time1, block->profile.data->dasd_io_time1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		       sizeof(data->dasd_io_time1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		memcpy(data->dasd_io_time2, block->profile.data->dasd_io_time2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		       sizeof(data->dasd_io_time2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		memcpy(data->dasd_io_time2ps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		       block->profile.data->dasd_io_time2ps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		       sizeof(data->dasd_io_time2ps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		memcpy(data->dasd_io_time3, block->profile.data->dasd_io_time3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		       sizeof(data->dasd_io_time3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		memcpy(data->dasd_io_nr_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		       block->profile.data->dasd_io_nr_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		       sizeof(data->dasd_io_nr_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		spin_unlock_bh(&block->profile.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		spin_unlock_bh(&block->profile.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (copy_to_user(argp, data, sizeof(*data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int dasd_ioctl_reset_profile(struct dasd_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  * Return dasd information. Used for BIODASDINFO and BIODASDINFO2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int __dasd_ioctl_information(struct dasd_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		struct dasd_information2_t *dasd_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	struct subchannel_id sch_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	struct ccw_dev_id dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	struct ccw_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	struct list_head *l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	base = block->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (!base->discipline || !base->discipline->fill_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	rc = base->discipline->fill_info(base, dasd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	cdev = base->cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	ccw_device_get_id(cdev, &dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	ccw_device_get_schid(cdev, &sch_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	dasd_info->devno = dev_id.devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	dasd_info->schid = sch_id.sch_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	dasd_info->cu_type = cdev->id.cu_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	dasd_info->cu_model = cdev->id.cu_model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	dasd_info->dev_type = cdev->id.dev_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	dasd_info->dev_model = cdev->id.dev_model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	dasd_info->status = base->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	 * The open_count is increased for every opener, that includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	 * the blkdev_get in dasd_scan_partitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	 * This must be hidden from user-space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	dasd_info->open_count = atomic_read(&block->open_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (!block->bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		dasd_info->open_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	 * check if device is really formatted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	 * LDL / CDL was returned by 'fill_info'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if ((base->state < DASD_STATE_READY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	    (dasd_check_blocksize(block->bp_block)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		dasd_info->format = DASD_FORMAT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	dasd_info->features |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		((base->features & DASD_FEATURE_READONLY) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	memcpy(dasd_info->type, base->discipline->name, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	spin_lock_irqsave(&block->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	list_for_each(l, &base->ccw_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		dasd_info->chanq_len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	spin_unlock_irqrestore(&block->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int dasd_ioctl_information(struct dasd_block *block, void __user *argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		size_t copy_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	struct dasd_information2_t *dasd_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	dasd_info = kzalloc(sizeof(*dasd_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	if (!dasd_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	error = __dasd_ioctl_information(block, dasd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	if (!error && copy_to_user(argp, dasd_info, copy_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	kfree(dasd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * Set read only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	int intval, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (bdev_is_partition(bdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		// ro setting is not allowed for partitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (get_user(intval, (int __user *)argp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		return -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	set_disk_ro(bdev->bd_disk, intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	rc = dasd_set_feature(base->cdev, DASD_FEATURE_READONLY, intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 				  struct cmbdata __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	size_t size = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct cmbdata data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	ret = cmf_readall(block->base->cdev, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int dasd_ioctl(struct block_device *bdev, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	       unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	struct dasd_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	void __user *argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	if (is_compat_task())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		argp = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		PRINT_DEBUG("empty data ptr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	base = dasd_device_from_gendisk(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	block = base->block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	case BIODASDDISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		rc = dasd_ioctl_disable(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	case BIODASDENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		rc = dasd_ioctl_enable(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	case BIODASDQUIESCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		rc = dasd_ioctl_quiesce(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	case BIODASDRESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		rc = dasd_ioctl_resume(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	case BIODASDABORTIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		rc = dasd_ioctl_abortio(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	case BIODASDALLOWIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		rc = dasd_ioctl_allowio(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	case BIODASDFMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		rc = dasd_ioctl_format(bdev, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	case BIODASDCHECKFMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		rc = dasd_ioctl_check_format(bdev, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	case BIODASDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		rc = dasd_ioctl_information(block, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 				sizeof(struct dasd_information_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	case BIODASDINFO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		rc = dasd_ioctl_information(block, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 				sizeof(struct dasd_information2_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	case BIODASDPRRD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		rc = dasd_ioctl_read_profile(block, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	case BIODASDPRRST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		rc = dasd_ioctl_reset_profile(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	case BLKROSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		rc = dasd_ioctl_set_ro(bdev, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	case DASDAPIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		rc = dasd_ioctl_api_version(argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	case BIODASDCMFENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		rc = enable_cmf(base->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	case BIODASDCMFDISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		rc = disable_cmf(base->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	case BIODASDREADALLCMB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		rc = dasd_ioctl_readall_cmb(block, cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	case BIODASDRAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		rc = dasd_ioctl_release_space(bdev, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		/* if the discipline has an ioctl method try it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		rc = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		if (base->discipline->ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			rc = base->discipline->ioctl(block, cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)  * dasd_biodasdinfo() - fill out the dasd information structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)  * @disk [in]: pointer to gendisk structure that references a DASD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  * @info [out]: pointer to the dasd_information2_t structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  * Provide access to DASD specific information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  * The gendisk structure is checked if it belongs to the DASD driver by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)  * comparing the gendisk->fops pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)  * If it does not belong to the DASD driver -EINVAL is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)  * Otherwise the provided dasd_information2_t structure is filled out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)  *   %0 on success and a negative error value on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int dasd_biodasdinfo(struct gendisk *disk, struct dasd_information2_t *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	struct dasd_device *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (disk->fops != &dasd_device_operations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	base = dasd_device_from_gendisk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	error = __dasd_ioctl_information(base->block, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	dasd_put_device(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* export that symbol_get in partition detection is possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) EXPORT_SYMBOL_GPL(dasd_biodasdinfo);