aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/Kconfig8
-rw-r--r--drivers/s390/block/Kconfig14
-rw-r--r--drivers/s390/block/Makefile4
-rw-r--r--drivers/s390/block/dasd.c52
-rw-r--r--drivers/s390/block/dasd_3990_erp.c3
-rw-r--r--drivers/s390/block/dasd_cmb.c128
-rw-r--r--drivers/s390/block/dasd_devmap.c50
-rw-r--r--drivers/s390/block/dasd_eckd.c142
-rw-r--r--drivers/s390/block/dasd_eckd.h1
-rw-r--r--drivers/s390/block/dasd_eer.c682
-rw-r--r--drivers/s390/block/dasd_int.h60
-rw-r--r--drivers/s390/block/dasd_ioctl.c322
-rw-r--r--drivers/s390/block/dcssblk.c11
-rw-r--r--drivers/s390/char/Makefile1
-rw-r--r--drivers/s390/char/fs3270.c3
-rw-r--r--drivers/s390/char/keyboard.c12
-rw-r--r--drivers/s390/char/monreader.c6
-rw-r--r--drivers/s390/char/raw3270.c42
-rw-r--r--drivers/s390/char/tape.h1
-rw-r--r--drivers/s390/char/tape_34xx.c8
-rw-r--r--drivers/s390/char/tape_3590.c1301
-rw-r--r--drivers/s390/char/tape_3590.h124
-rw-r--r--drivers/s390/char/tape_class.c3
-rw-r--r--drivers/s390/char/tape_core.c57
-rw-r--r--drivers/s390/char/tape_std.c15
-rw-r--r--drivers/s390/char/tape_std.h12
-rw-r--r--drivers/s390/char/tty3270.c9
-rw-r--r--drivers/s390/char/vmlogrdr.c3
-rw-r--r--drivers/s390/cio/ccwgroup.c3
-rw-r--r--drivers/s390/cio/chsc.c457
-rw-r--r--drivers/s390/cio/chsc.h22
-rw-r--r--drivers/s390/cio/css.c44
-rw-r--r--drivers/s390/cio/css.h6
-rw-r--r--drivers/s390/cio/device.c6
-rw-r--r--drivers/s390/cio/device_fsm.c12
-rw-r--r--drivers/s390/cio/device_ops.c9
-rw-r--r--drivers/s390/cio/qdio.c20
-rw-r--r--drivers/s390/crypto/z90hardware.c10
-rw-r--r--drivers/s390/crypto/z90main.c15
-rw-r--r--drivers/s390/net/claw.c5
-rw-r--r--drivers/s390/net/fsm.c10
-rw-r--r--drivers/s390/net/iucv.c11
-rw-r--r--drivers/s390/net/lcs.c11
-rw-r--r--drivers/s390/net/netiucv.c7
-rw-r--r--drivers/s390/net/qeth_eddp.c13
-rw-r--r--drivers/s390/net/qeth_main.c77
-rw-r--r--drivers/s390/net/qeth_proc.c56
-rw-r--r--drivers/s390/net/qeth_sys.c5
-rw-r--r--drivers/s390/s390_rdev.c3
-rw-r--r--drivers/s390/scsi/zfcp_aux.c60
50 files changed, 3122 insertions, 814 deletions
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
index 721787cc5a1..4d36208ff8d 100644
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -183,7 +183,13 @@ config S390_TAPE_34XX
tape subsystems and 100% compatibles.
It is safe to say "Y" here.
-
+config S390_TAPE_3590
+ tristate "Support for 3590 tape hardware"
+ depends on S390_TAPE
+ help
+ Select this option if you want to access IBM 3590 magnetic
+ tape subsystems and 100% compatibles.
+ It is safe to say "Y" here.
config VMLOGRDR
tristate "Support for the z/VM recording system services (VM only)"
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index 6f50cc9323d..929d6fff615 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -49,20 +49,18 @@ config DASD_FBA
config DASD_DIAG
tristate "Support for DIAG access to Disks"
- depends on DASD && ( 64BIT = 'n' || EXPERIMENTAL)
+ depends on DASD
help
Select this option if you want to use Diagnose250 command to access
Disks under VM. If you are not running under VM or unsure what it is,
say "N".
-config DASD_CMB
- tristate "Compatibility interface for DASD channel measurement blocks"
+config DASD_EER
+ bool "Extended error reporting (EER)"
depends on DASD
help
- This driver provides an additional interface to the channel measurement
- facility, which is normally accessed though sysfs, with a set of
- ioctl functions specific to the dasd driver.
- This is only needed if you want to use applications written for
- linux-2.4 dasd channel measurement facility interface.
+ This driver provides a character device interface to the
+ DASD extended error reporting. This is only needed if you want to
+ use applications written for the EER facility.
endif
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile
index 58c6780134f..be9f22d52fd 100644
--- a/drivers/s390/block/Makefile
+++ b/drivers/s390/block/Makefile
@@ -7,11 +7,13 @@ dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
dasd_diag_mod-objs := dasd_diag.o
dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \
dasd_genhd.o dasd_erp.o
+ifdef CONFIG_DASD_EER
+dasd_mod-objs += dasd_eer.o
+endif
obj-$(CONFIG_DASD) += dasd_mod.o
obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o
obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o
obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o
-obj-$(CONFIG_DASD_CMB) += dasd_cmb.o
obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o
obj-$(CONFIG_DCSSBLK) += dcssblk.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 33157c84d1d..0a9f12c4e91 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -43,7 +43,6 @@ MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
MODULE_DESCRIPTION("Linux on S/390 DASD device driver,"
" Copyright 2000 IBM Corporation");
MODULE_SUPPORTED_DEVICE("dasd");
-MODULE_PARM(dasd, "1-" __MODULE_STRING(256) "s");
MODULE_LICENSE("GPL");
/*
@@ -71,10 +70,9 @@ dasd_alloc_device(void)
{
struct dasd_device *device;
- device = kmalloc(sizeof (struct dasd_device), GFP_ATOMIC);
+ device = kzalloc(sizeof (struct dasd_device), GFP_ATOMIC);
if (device == NULL)
return ERR_PTR(-ENOMEM);
- memset(device, 0, sizeof (struct dasd_device));
/* open_count = 0 means device online but not in use */
atomic_set(&device->open_count, -1);
@@ -151,6 +149,8 @@ dasd_state_new_to_known(struct dasd_device *device)
static inline void
dasd_state_known_to_new(struct dasd_device * device)
{
+ /* Disable extended error reporting for this device. */
+ dasd_eer_disable(device);
/* Forget the discipline information. */
if (device->discipline)
module_put(device->discipline->owner);
@@ -541,33 +541,29 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
struct dasd_ccw_req *cqr;
/* Sanity checks */
- if ( magic == NULL || datasize > PAGE_SIZE ||
- (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
- BUG();
+ BUG_ON( magic == NULL || datasize > PAGE_SIZE ||
+ (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
- cqr = kmalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC);
+ cqr = kzalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC);
if (cqr == NULL)
return ERR_PTR(-ENOMEM);
- memset(cqr, 0, sizeof(struct dasd_ccw_req));
cqr->cpaddr = NULL;
if (cplength > 0) {
- cqr->cpaddr = kmalloc(cplength*sizeof(struct ccw1),
+ cqr->cpaddr = kcalloc(cplength, sizeof(struct ccw1),
GFP_ATOMIC | GFP_DMA);
if (cqr->cpaddr == NULL) {
kfree(cqr);
return ERR_PTR(-ENOMEM);
}
- memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1));
}
cqr->data = NULL;
if (datasize > 0) {
- cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA);
+ cqr->data = kzalloc(datasize, GFP_ATOMIC | GFP_DMA);
if (cqr->data == NULL) {
kfree(cqr->cpaddr);
kfree(cqr);
return ERR_PTR(-ENOMEM);
}
- memset(cqr->data, 0, datasize);
}
strncpy((char *) &cqr->magic, magic, 4);
ASCEBC((char *) &cqr->magic, 4);
@@ -586,9 +582,8 @@ dasd_smalloc_request(char *magic, int cplength, int datasize,
int size;
/* Sanity checks */
- if ( magic == NULL || datasize > PAGE_SIZE ||
- (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
- BUG();
+ BUG_ON( magic == NULL || datasize > PAGE_SIZE ||
+ (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
if (cplength > 0)
@@ -892,6 +887,9 @@ dasd_handle_state_change_pending(struct dasd_device *device)
struct dasd_ccw_req *cqr;
struct list_head *l, *n;
+ /* First of all start sense subsystem status request. */
+ dasd_eer_snss(device);
+
device->stopped &= ~DASD_STOPPED_PENDING;
/* restart all 'running' IO on queue */
@@ -1111,6 +1109,19 @@ restart:
}
goto restart;
}
+
+ /* First of all call extended error reporting. */
+ if (dasd_eer_enabled(device) &&
+ cqr->status == DASD_CQR_FAILED) {
+ dasd_eer_write(device, cqr, DASD_EER_FATALERROR);
+
+ /* restart request */
+ cqr->status = DASD_CQR_QUEUED;
+ cqr->retries = 255;
+ device->stopped |= DASD_STOPPED_QUIESCE;
+ goto restart;
+ }
+
/* Process finished ERP request. */
if (cqr->refers) {
__dasd_process_erp(device, cqr);
@@ -1248,7 +1259,8 @@ __dasd_start_head(struct dasd_device * device)
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
/* check FAILFAST */
if (device->stopped & ~DASD_STOPPED_PENDING &&
- test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) {
+ test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+ (!dasd_eer_enabled(device))) {
cqr->status = DASD_CQR_FAILED;
dasd_schedule_bh(device);
}
@@ -1807,7 +1819,7 @@ dasd_exit(void)
#ifdef CONFIG_PROC_FS
dasd_proc_exit();
#endif
- dasd_ioctl_exit();
+ dasd_eer_exit();
if (dasd_page_cache != NULL) {
kmem_cache_destroy(dasd_page_cache);
dasd_page_cache = NULL;
@@ -2004,6 +2016,9 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
switch (event) {
case CIO_GONE:
case CIO_NO_PATH:
+ /* First of all call extended error reporting. */
+ dasd_eer_write(device, NULL, DASD_EER_NOPATH);
+
if (device->state < DASD_STATE_BASIC)
break;
/* Device is active. We want to keep it. */
@@ -2061,6 +2076,7 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
put_driver(drv);
}
+
static int __init
dasd_init(void)
{
@@ -2093,7 +2109,7 @@ dasd_init(void)
rc = dasd_parse();
if (rc)
goto failed;
- rc = dasd_ioctl_init();
+ rc = dasd_eer_init();
if (rc)
goto failed;
#ifdef CONFIG_PROC_FS
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 4ee0f934e32..2ed51562319 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1108,6 +1108,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x0B:
DEV_MESSAGE(KERN_WARNING, device, "%s",
"FORMAT F - Volume is suspended duplex");
+ /* call extended error reporting (EER) */
+ dasd_eer_write(device, erp->refers,
+ DASD_EER_PPRCSUSPEND);
break;
case 0x0C:
DEV_MESSAGE(KERN_WARNING, device, "%s",
diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c
deleted file mode 100644
index e88f73ee72c..00000000000
--- a/drivers/s390/block/dasd_cmb.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Linux on zSeries Channel Measurement Facility support
- * (dasd device driver interface)
- *
- * Copyright 2000,2003 IBM Corporation
- *
- * Author: Arnd Bergmann <arndb@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/ccwdev.h>
-#include <asm/cmb.h>
-
-#include "dasd_int.h"
-
-static int
-dasd_ioctl_cmf_enable(struct block_device *bdev, int no, long args)
-{
- struct dasd_device *device;
-
- device = bdev->bd_disk->private_data;
- if (!device)
- return -EINVAL;
-
- return enable_cmf(device->cdev);
-}
-
-static int
-dasd_ioctl_cmf_disable(struct block_device *bdev, int no, long args)
-{
- struct dasd_device *device;
-
- device = bdev->bd_disk->private_data;
- if (!device)
- return -EINVAL;
-
- return disable_cmf(device->cdev);
-}
-
-static int
-dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
-{
- struct dasd_device *device;
- struct cmbdata __user *udata;
- struct cmbdata data;
- size_t size;
- int ret;
-
- device = bdev->bd_disk->private_data;
- if (!device)
- return -EINVAL;
- udata = (void __user *) args;
- size = _IOC_SIZE(no);
-
- if (!access_ok(VERIFY_WRITE, udata, size))
- return -EFAULT;
- ret = cmf_readall(device->cdev, &data);
- if (ret)
- return ret;
- if (copy_to_user(udata, &data, min(size, sizeof(*udata))))
- return -EFAULT;
- return 0;
-}
-
-/* module initialization below here. dasd already provides a mechanism
- * to dynamically register ioctl functions, so we simply use this. */
-static inline int
-ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler)
-{
- return dasd_ioctl_no_register(THIS_MODULE, no, handler);
-}
-
-static inline void
-ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler)
-{
- dasd_ioctl_no_unregister(THIS_MODULE, no, handler);
-}
-
-static void
-dasd_cmf_exit(void)
-{
- ioctl_unreg(BIODASDCMFENABLE, dasd_ioctl_cmf_enable);
- ioctl_unreg(BIODASDCMFDISABLE, dasd_ioctl_cmf_disable);
- ioctl_unreg(BIODASDREADALLCMB, dasd_ioctl_readall_cmb);
-}
-
-static int __init
-dasd_cmf_init(void)
-{
- int ret;
- ret = ioctl_reg (BIODASDCMFENABLE, dasd_ioctl_cmf_enable);
- if (ret)
- goto err;
- ret = ioctl_reg (BIODASDCMFDISABLE, dasd_ioctl_cmf_disable);
- if (ret)
- goto err;
- ret = ioctl_reg (BIODASDREADALLCMB, dasd_ioctl_readall_cmb);
- if (ret)
- goto err;
-
- return 0;
-err:
- dasd_cmf_exit();
-
- return ret;
-}
-
-module_init(dasd_cmf_init);
-module_exit(dasd_cmf_exit);
-
-MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("channel measurement facility interface for dasd\n"
- "Copyright 2003 IBM Corporation\n");
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 1629b27c48a..c1c6f138115 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -16,6 +16,7 @@
#include <linux/config.h>
#include <linux/ctype.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
@@ -69,6 +70,8 @@ int dasd_autodetect = 0; /* is true, when autodetection is active */
* strings when running as a module.
*/
static char *dasd[256];
+module_param_array(dasd, charp, NULL, 0);
+
/*
* Single spinlock to protect devmap structures and lists.
*/
@@ -434,8 +437,7 @@ dasd_forget_ranges(void)
spin_lock(&dasd_devmap_lock);
for (i = 0; i < 256; i++) {
list_for_each_entry_safe(devmap, n, &dasd_hashlists[i], list) {
- if (devmap->device != NULL)
- BUG();
+ BUG_ON(devmap->device != NULL);
list_del(&devmap->list);
kfree(devmap);
}
@@ -544,8 +546,7 @@ dasd_delete_device(struct dasd_device *device)
/* First remove device pointer from devmap. */
devmap = dasd_find_busid(device->cdev->dev.bus_id);
- if (IS_ERR(devmap))
- BUG();
+ BUG_ON(IS_ERR(devmap));
spin_lock(&dasd_devmap_lock);
if (devmap->device != device) {
spin_unlock(&dasd_devmap_lock);
@@ -715,10 +716,51 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *bu
static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
+/*
+ * extended error-reporting
+ */
+static ssize_t
+dasd_eer_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct dasd_devmap *devmap;
+ int eer_flag;
+
+ devmap = dasd_find_busid(dev->bus_id);
+ if (!IS_ERR(devmap) && devmap->device)
+ eer_flag = dasd_eer_enabled(devmap->device);
+ else
+ eer_flag = 0;
+ return snprintf(buf, PAGE_SIZE, eer_flag ? "1\n" : "0\n");
+}
+
+static ssize_t
+dasd_eer_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct dasd_devmap *devmap;
+ int rc;
+
+ devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
+ if (IS_ERR(devmap))
+ return PTR_ERR(devmap);
+ if (!devmap->device)
+ return count;
+ if (buf[0] == '1') {
+ rc = dasd_eer_enable(devmap->device);
+ if (rc)
+ return rc;
+ } else
+ dasd_eer_disable(devmap->device);
+ return count;
+}
+
+static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
+
static struct attribute * dasd_attrs[] = {
&dev_attr_readonly.attr,
&dev_attr_discipline.attr,
&dev_attr_use_diag.attr,
+ &dev_attr_eer_enabled.attr,
NULL,
};
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 822e2a26557..ee09ef33d08 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1227,19 +1227,14 @@ dasd_eckd_fill_info(struct dasd_device * device,
* (see dasd_eckd_reserve) device.
*/
static int
-dasd_eckd_release(struct block_device *bdev, int no, long args)
+dasd_eckd_release(struct dasd_device *device)
{
- struct dasd_device *device;
struct dasd_ccw_req *cqr;
int rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
@@ -1272,19 +1267,14 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
* the interrupt is outstanding for a certain time.
*/
static int
-dasd_eckd_reserve(struct block_device *bdev, int no, long args)
+dasd_eckd_reserve(struct dasd_device *device)
{
- struct dasd_device *device;
struct dasd_ccw_req *cqr;
int rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
@@ -1316,19 +1306,14 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
* (unconditional reserve)
*/
static int
-dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
+dasd_eckd_steal_lock(struct dasd_device *device)
{
- struct dasd_device *device;
struct dasd_ccw_req *cqr;
int rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
@@ -1358,19 +1343,14 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
* Read performance statistics
*/
static int
-dasd_eckd_performance(struct block_device *bdev, int no, long args)
+dasd_eckd_performance(struct dasd_device *device, void __user *argp)
{
- struct dasd_device *device;
struct dasd_psf_prssd_data *prssdp;
struct dasd_rssd_perf_stats_t *stats;
struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
int rc;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1 /* PSF */ + 1 /* RSSD */ ,
(sizeof (struct dasd_psf_prssd_data) +
@@ -1414,8 +1394,9 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
/* Prepare for Read Subsystem Data */
prssdp = (struct dasd_psf_prssd_data *) cqr->data;
stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
- rc = copy_to_user((long __user *) args, (long *) stats,
- sizeof(struct dasd_rssd_perf_stats_t));
+ if (copy_to_user(argp, stats,
+ sizeof(struct dasd_rssd_perf_stats_t)))
+ rc = -EFAULT;
}
dasd_sfree_request(cqr, cqr->device);
return rc;
@@ -1426,27 +1407,22 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
* Returnes the cache attributes used in Define Extend (DE).
*/
static int
-dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
+dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)
{
- struct dasd_device *device;
- struct dasd_eckd_private *private;
- struct attrib_data_t attrib;
+ struct dasd_eckd_private *private =
+ (struct dasd_eckd_private *)device->private;
+ struct attrib_data_t attrib = private->attrib;
int rc;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!args)
+ if (!argp)
return -EINVAL;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
- private = (struct dasd_eckd_private *) device->private;
- attrib = private->attrib;
-
- rc = copy_to_user((long __user *) args, (long *) &attrib,
- sizeof (struct attrib_data_t));
+ rc = 0;
+ if (copy_to_user(argp, (long *) &attrib,
+ sizeof (struct attrib_data_t)))
+ rc = -EFAULT;
return rc;
}
@@ -1456,26 +1432,19 @@ dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
* Stores the attributes for cache operation to be used in Define Extend (DE).
*/
static int
-dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
+dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
{
- struct dasd_device *device;
- struct dasd_eckd_private *private;
+ struct dasd_eckd_private *private =
+ (struct dasd_eckd_private *)device->private;
struct attrib_data_t attrib;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (!args)
+ if (!argp)
return -EINVAL;
- device = bdev->bd_disk->private_data;
- if (device == NULL)
- return -ENODEV;
-
- if (copy_from_user(&attrib, (void __user *) args,
- sizeof (struct attrib_data_t))) {
+ if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))
return -EFAULT;
- }
- private = (struct dasd_eckd_private *) device->private;
private->attrib = attrib;
DEV_MESSAGE(KERN_INFO, device,
@@ -1484,6 +1453,27 @@ dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
return 0;
}
+static int
+dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
+{
+ switch (cmd) {
+ case BIODASDGATTR:
+ return dasd_eckd_get_attrib(device, argp);
+ case BIODASDSATTR:
+ return dasd_eckd_set_attrib(device, argp);
+ case BIODASDPSRD:
+ return dasd_eckd_performance(device, argp);
+ case BIODASDRLSE:
+ return dasd_eckd_release(device);
+ case BIODASDRSRV:
+ return dasd_eckd_reserve(device);
+ case BIODASDSLCK:
+ return dasd_eckd_steal_lock(device);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
/*
* Print sense data and related channel program.
* Parts are printed because printk buffer is only 1024 bytes.
@@ -1642,6 +1632,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.free_cp = dasd_eckd_free_cp,
.dump_sense = dasd_eckd_dump_sense,
.fill_info = dasd_eckd_fill_info,
+ .ioctl = dasd_eckd_ioctl,
};
static int __init
@@ -1649,59 +1640,18 @@ dasd_eckd_init(void)
{
int ret;
- dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR,
- dasd_eckd_get_attrib);
- dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
- dasd_eckd_set_attrib);
- dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
- dasd_eckd_performance);
- dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE,
- dasd_eckd_release);
- dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV,
- dasd_eckd_reserve);
- dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK,
- dasd_eckd_steal_lock);
-
ASCEBC(dasd_eckd_discipline.ebcname, 4);
ret = ccw_driver_register(&dasd_eckd_driver);
- if (ret) {
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
- dasd_eckd_get_attrib);
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
- dasd_eckd_set_attrib);
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
- dasd_eckd_performance);
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
- dasd_eckd_release);
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
- dasd_eckd_reserve);
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
- dasd_eckd_steal_lock);
- return ret;
- }
-
- dasd_generic_auto_online(&dasd_eckd_driver);
- return 0;
+ if (!ret)
+ dasd_generic_auto_online(&dasd_eckd_driver);
+ return ret;
}
static void __exit
dasd_eckd_cleanup(void)
{
ccw_driver_unregister(&dasd_eckd_driver);
-
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
- d