^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);