diff options
Diffstat (limited to 'drivers/s390/char')
34 files changed, 376 insertions, 445 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index a367f95c7c53..4a7c084e68a6 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -21,7 +21,6 @@ #include <linux/reboot.h> #include <linux/slab.h> #include <linux/memblock.h> -#include <linux/compat.h> #include <asm/machine.h> #include <asm/ccwdev.h> @@ -1662,7 +1661,7 @@ static void tty3270_escape_sequence(struct tty3270 *tp, u8 ch) else if (tp->esc_par[0] == 6) { /* Cursor report. */ char buf[40]; - sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1); + scnprintf(buf, sizeof(buf), "\033[%d;%dR", tp->cy + 1, tp->cx + 1); kbd_puts_queue(&tp->port, buf); } return; @@ -1947,21 +1946,6 @@ static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd, return kbd_ioctl(tp->kbd, cmd, arg); } -#ifdef CONFIG_COMPAT -static long tty3270_compat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct tty3270 *tp; - - tp = tty->driver_data; - if (!tp) - return -ENODEV; - if (tty_io_error(tty)) - return -EIO; - return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); -} -#endif - static const struct tty_operations tty3270_ops = { .install = tty3270_install, .cleanup = tty3270_cleanup, @@ -1976,9 +1960,6 @@ static const struct tty_operations tty3270_ops = { .hangup = tty3270_hangup, .wait_until_sent = tty3270_wait_until_sent, .ioctl = tty3270_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = tty3270_compat_ioctl, -#endif .set_termios = tty3270_set_termios }; diff --git a/drivers/s390/char/diag_ftp.c b/drivers/s390/char/diag_ftp.c index f41b39c9d267..a1e110c96f74 100644 --- a/drivers/s390/char/diag_ftp.c +++ b/drivers/s390/char/diag_ftp.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/mm.h> diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index cfe7efd5b5da..73555dbe30d0 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -12,7 +12,6 @@ #include <linux/console.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/compat.h> #include <linux/sched/signal.h> #include <linux/module.h> #include <linux/list.h> @@ -330,10 +329,7 @@ static long fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fp = filp->private_data; if (!fp) return -ENODEV; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (char __user *)arg; + argp = (char __user *)arg; rc = 0; mutex_lock(&fs3270_mutex); switch (cmd) { @@ -512,7 +508,6 @@ static const struct file_operations fs3270_fops = { .read = fs3270_read, /* read */ .write = fs3270_write, /* write */ .unlocked_ioctl = fs3270_ioctl, /* ioctl */ - .compat_ioctl = fs3270_ioctl, /* ioctl */ .open = fs3270_open, /* open */ .release = fs3270_close, /* release */ }; diff --git a/drivers/s390/char/hmcdrv_cache.c b/drivers/s390/char/hmcdrv_cache.c index 43df27ceec11..85fb689594ca 100644 --- a/drivers/s390/char/hmcdrv_cache.c +++ b/drivers/s390/char/hmcdrv_cache.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/mm.h> diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c index b26fcf6849f2..04b938c5357f 100644 --- a/drivers/s390/char/hmcdrv_dev.c +++ b/drivers/s390/char/hmcdrv_dev.c @@ -14,8 +14,7 @@ * end read() the response. */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index 4e3c7ec6749b..3312b2ac00a9 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c @@ -6,8 +6,7 @@ * Author(s): Ralf Hoppe (rhoppe@de.ibm.com) */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/slab.h> diff --git a/drivers/s390/char/hmcdrv_mod.c b/drivers/s390/char/hmcdrv_mod.c index 1447d0887225..b1cc5ba9fed8 100644 --- a/drivers/s390/char/hmcdrv_mod.c +++ b/drivers/s390/char/hmcdrv_mod.c @@ -6,8 +6,7 @@ * Author(s): Ralf Hoppe (rhoppe@de.ibm.com) */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 2d9886651d9b..3d84f84b4cbd 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -7,8 +7,7 @@ * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ -#define KMSG_COMPONENT "monreader" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "monreader: " fmt #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 0fab1f025a94..cf2e51061422 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -7,8 +7,7 @@ * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com> */ -#define KMSG_COMPONENT "monwriter" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "monwriter: " fmt #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/s390/char/sclp_ap.c b/drivers/s390/char/sclp_ap.c index 0dd1ca712795..18bb018b4e0c 100644 --- a/drivers/s390/char/sclp_ap.c +++ b/drivers/s390/char/sclp_ap.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2020 */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include <linux/export.h> #include <linux/slab.h> diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 3480198eac02..be4730936f5c 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -5,8 +5,7 @@ * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include <linux/completion.h> #include <linux/err.h> diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 356d26a09af0..9cfbe3fc3dca 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2007 */ -#define KMSG_COMPONENT "sclp_config" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_config: " fmt #include <linux/init.h> #include <linux/errno.h> diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index d8f91aab11e8..8e1636bcf8b5 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -7,8 +7,7 @@ * Michael Ernst <mernst@de.ibm.com> */ -#define KMSG_COMPONENT "sclp_cpi" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cpi: " fmt #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c index dd6051602070..e23a97359286 100644 --- a/drivers/s390/char/sclp_ctl.c +++ b/drivers/s390/char/sclp_ctl.c @@ -7,7 +7,6 @@ * Author: Michael Holzheu <holzheu@linux.vnet.ibm.com> */ -#include <linux/compat.h> #include <linux/uaccess.h> #include <linux/miscdevice.h> #include <linux/gfp.h> @@ -43,10 +42,7 @@ static int sclp_ctl_cmdw_supported(unsigned int cmdw) static void __user *u64_to_uptr(u64 value) { - if (is_compat_task()) - return compat_ptr(value); - else - return (void __user *)(unsigned long)value; + return (void __user *)(unsigned long)value; } /* @@ -95,10 +91,7 @@ static long sclp_ctl_ioctl(struct file *filp, unsigned int cmd, { void __user *argp; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (void __user *) arg; + argp = (void __user *)arg; switch (cmd) { case SCLP_CTL_SCCB: return sclp_ctl_ioctl_sccb(argp); @@ -114,7 +107,6 @@ static const struct file_operations sclp_ctl_fops = { .owner = THIS_MODULE, .open = nonseekable_open, .unlocked_ioctl = sclp_ctl_ioctl, - .compat_ioctl = sclp_ctl_ioctl, }; /* diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index bd5e5ba50c0a..6bf501ad8ff0 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2013 */ -#define KMSG_COMPONENT "sclp_early" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_early: " fmt #include <linux/export.h> #include <linux/errno.h> diff --git a/drivers/s390/char/sclp_ftp.c b/drivers/s390/char/sclp_ftp.c index d27e2cbfbccb..2a1c4b2cafc8 100644 --- a/drivers/s390/char/sclp_ftp.c +++ b/drivers/s390/char/sclp_ftp.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include <linux/kernel.h> #include <linux/mm.h> diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 27f49f5fd358..676c085b4f8a 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -5,13 +5,15 @@ * Copyright IBM Corp. 2025 */ -#define KMSG_COMPONENT "sclp_mem" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_mem: " fmt #include <linux/cpufeature.h> +#include <linux/container_of.h> #include <linux/err.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/kobject.h> +#include <linux/kstrtox.h> #include <linux/memory.h> #include <linux/memory_hotplug.h> #include <linux/mm.h> @@ -27,7 +29,6 @@ #define SCLP_CMDW_ASSIGN_STORAGE 0x000d0001 #define SCLP_CMDW_UNASSIGN_STORAGE 0x000c0001 -static DEFINE_MUTEX(sclp_mem_mutex); static LIST_HEAD(sclp_mem_list); static u8 sclp_max_storage_id; static DECLARE_BITMAP(sclp_storage_ids, 256); @@ -38,6 +39,18 @@ struct memory_increment { int standby; }; +struct sclp_mem { + struct kobject kobj; + unsigned int id; + unsigned int memmap_on_memory; + unsigned int config; +}; + +struct sclp_mem_arg { + struct sclp_mem *sclp_mems; + struct kset *kset; +}; + struct assign_storage_sccb { struct sccb_header header; u16 rn; @@ -163,92 +176,168 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size, return rc ? -EIO : 0; } -static bool contains_standby_increment(unsigned long start, unsigned long end) +static ssize_t sclp_config_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct memory_increment *incr; - unsigned long istart; + struct sclp_mem *sclp_mem = container_of(kobj, struct sclp_mem, kobj); - list_for_each_entry(incr, &sclp_mem_list, list) { - istart = rn2addr(incr->rn); - if (end - 1 < istart) - continue; - if (start > istart + sclp.rzm - 1) - continue; - if (incr->standby) - return true; - } - return false; + return sysfs_emit(buf, "%u\n", READ_ONCE(sclp_mem->config)); } -static int sclp_mem_notifier(struct notifier_block *nb, - unsigned long action, void *data) +static ssize_t sclp_config_mem_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) { - unsigned long start, size; - struct memory_notify *arg; + unsigned long addr, block_size; + struct sclp_mem *sclp_mem; + struct memory_block *mem; unsigned char id; - int rc = 0; + bool value; + int rc; - arg = data; - start = arg->start_pfn << PAGE_SHIFT; - size = arg->nr_pages << PAGE_SHIFT; - mutex_lock(&sclp_mem_mutex); + rc = kstrtobool(buf, &value); + if (rc) + return rc; + sclp_mem = container_of(kobj, struct sclp_mem, kobj); + block_size = memory_block_size_bytes(); + addr = sclp_mem->id * block_size; + /* + * Hold device_hotplug_lock when adding/removing memory blocks. + * Additionally, also protect calls to find_memory_block() and + * sclp_attach_storage(). + */ + rc = lock_device_hotplug_sysfs(); + if (rc) + goto out; for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1) sclp_attach_storage(id); - switch (action) { - case MEM_GOING_OFFLINE: - /* - * Do not allow to set memory blocks offline that contain - * standby memory. This is done to simplify the "memory online" - * case. - */ - if (contains_standby_increment(start, start + size)) - rc = -EPERM; - break; - case MEM_PREPARE_ONLINE: + if (value) { + if (sclp_mem->config) + goto out_unlock; + rc = sclp_mem_change_state(addr, block_size, 1); + if (rc) + goto out_unlock; /* - * Access the altmap_start_pfn and altmap_nr_pages fields - * within the struct memory_notify specifically when dealing - * with only MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. - * - * When altmap is in use, take the specified memory range - * online, which includes the altmap. + * Set entire memory block CMMA state to nodat. Later, when + * page tables pages are allocated via __add_memory(), those + * regions are marked __arch_set_page_dat(). */ - if (arg->altmap_nr_pages) { - start = PFN_PHYS(arg->altmap_start_pfn); - size += PFN_PHYS(arg->altmap_nr_pages); + __arch_set_page_nodat((void *)__va(addr), block_size >> PAGE_SHIFT); + rc = __add_memory(0, addr, block_size, + sclp_mem->memmap_on_memory ? + MHP_MEMMAP_ON_MEMORY : MHP_NONE); + if (rc) { + sclp_mem_change_state(addr, block_size, 0); + goto out_unlock; } - rc = sclp_mem_change_state(start, size, 1); - if (rc || !arg->altmap_nr_pages) - break; - /* - * Set CMMA state to nodat here, since the struct page memory - * at the beginning of the memory block will not go through the - * buddy allocator later. - */ - __arch_set_page_nodat((void *)__va(start), arg->altmap_nr_pages); - break; - case MEM_FINISH_OFFLINE: - /* - * When altmap is in use, take the specified memory range - * offline, which includes the altmap. - */ - if (arg->altmap_nr_pages) { - start = PFN_PHYS(arg->altmap_start_pfn); - size += PFN_PHYS(arg->altmap_nr_pages); + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); + put_device(&mem->dev); + WRITE_ONCE(sclp_mem->config, 1); + } else { + if (!sclp_mem->config) + goto out_unlock; + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); + if (mem->state != MEM_OFFLINE) { + put_device(&mem->dev); + rc = -EBUSY; + goto out_unlock; } - sclp_mem_change_state(start, size, 0); - break; - default: - break; + /* drop the ref just got via find_memory_block() */ + put_device(&mem->dev); + sclp_mem_change_state(addr, block_size, 0); + __remove_memory(addr, block_size); + WRITE_ONCE(sclp_mem->config, 0); + } +out_unlock: + unlock_device_hotplug(); +out: + return rc ? rc : count; +} + +static struct kobj_attribute sclp_config_mem_attr = + __ATTR(config, 0644, sclp_config_mem_show, sclp_config_mem_store); + +static ssize_t sclp_memmap_on_memory_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct sclp_mem *sclp_mem = container_of(kobj, struct sclp_mem, kobj); + + return sysfs_emit(buf, "%u\n", READ_ONCE(sclp_mem->memmap_on_memory)); +} + +static ssize_t sclp_memmap_on_memory_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct sclp_mem *sclp_mem; + unsigned long block_size; + struct memory_block *mem; + bool value; + int rc; + + rc = kstrtobool(buf, &value); + if (rc) + return rc; + if (value && !mhp_supports_memmap_on_memory()) + return -EOPNOTSUPP; + rc = lock_device_hotplug_sysfs(); + if (rc) + return rc; + block_size = memory_block_size_bytes(); + sclp_mem = container_of(kobj, struct sclp_mem, kobj); + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(sclp_mem->id * block_size))); + if (!mem) { + WRITE_ONCE(sclp_mem->memmap_on_memory, value); + } else { + put_device(&mem->dev); + rc = -EBUSY; } - mutex_unlock(&sclp_mem_mutex); - return rc ? NOTIFY_BAD : NOTIFY_OK; + unlock_device_hotplug(); + return rc ? rc : count; } -static struct notifier_block sclp_mem_nb = { - .notifier_call = sclp_mem_notifier, +static const struct kobj_type ktype = { + .sysfs_ops = &kobj_sysfs_ops, +}; + +static struct kobj_attribute sclp_memmap_attr = + __ATTR(memmap_on_memory, 0644, sclp_memmap_on_memory_show, sclp_memmap_on_memory_store); + +static struct attribute *sclp_mem_attrs[] = { + &sclp_config_mem_attr.attr, + &sclp_memmap_attr.attr, + NULL, }; +static struct attribute_group sclp_mem_attr_group = { + .attrs = sclp_mem_attrs, +}; + +static int sclp_create_mem(struct sclp_mem *sclp_mem, struct kset *kset, + unsigned int id, bool config, bool memmap_on_memory) +{ + int rc; + + sclp_mem->memmap_on_memory = memmap_on_memory; + sclp_mem->config = config; + sclp_mem->id = id; + kobject_init(&sclp_mem->kobj, &ktype); + rc = kobject_add(&sclp_mem->kobj, &kset->kobj, "memory%d", id); + if (rc) + return rc; + return sysfs_create_group(&sclp_mem->kobj, &sclp_mem_attr_group); +} + +static int sclp_create_configured_mem(struct memory_block *mem, void *argument) +{ + struct sclp_mem *sclp_mems; + struct sclp_mem_arg *arg; + struct kset *kset; + unsigned int id; + + id = mem->dev.id; + arg = (struct sclp_mem_arg *)argument; + sclp_mems = arg->sclp_mems; + kset = arg->kset; + return sclp_create_mem(&sclp_mems[id], kset, id, true, false); +} + static void __init align_to_block_size(unsigned long *start, unsigned long *size, unsigned long alignment) @@ -264,14 +353,17 @@ static void __init align_to_block_size(unsigned long *start, *size = size_align; } -static void __init add_memory_merged(u16 rn) +static int __init sclp_create_standby_mems_merged(struct sclp_mem *sclp_mems, + struct kset *kset, u16 rn) { unsigned long start, size, addr, block_size; static u16 first_rn, num; + unsigned int id; + int rc = 0; if (rn && first_rn && (first_rn + num == rn)) { num++; - return; + return rc; } if (!first_rn) goto skip_add; @@ -286,24 +378,57 @@ static void __init add_memory_merged(u16 rn) if (!size) goto skip_add; for (addr = start; addr < start + size; addr += block_size) { - add_memory(0, addr, block_size, - cpu_has_edat1() ? - MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); + id = addr / block_size; + rc = sclp_create_mem(&sclp_mems[id], kset, id, false, + mhp_supports_memmap_on_memory()); + if (rc) + break; } skip_add: first_rn = rn; num = 1; + return rc; } -static void __init sclp_add_standby_memory(void) +static int __init sclp_create_standby_mems(struct sclp_mem *sclp_mems, struct kset *kset) { struct memory_increment *incr; + int rc = 0; list_for_each_entry(incr, &sclp_mem_list, list) { if (incr->standby) - add_memory_merged(incr->rn); + rc = sclp_create_standby_mems_merged(sclp_mems, kset, incr->rn); + if (rc) + return rc; } - add_memory_merged(0); + return sclp_create_standby_mems_merged(sclp_mems, kset, 0); +} + +static int __init sclp_init_mem(void) +{ + const unsigned long block_size = memory_block_size_bytes(); + unsigned int max_sclp_mems; + struct sclp_mem *sclp_mems; + struct sclp_mem_arg arg; + struct kset *kset; + int rc; + + max_sclp_mems = roundup(sclp.rnmax * sclp.rzm, block_size) / block_size; + /* Allocate memory for all blocks ahead of time. */ + sclp_mems = kcalloc(max_sclp_mems, sizeof(struct sclp_mem), GFP_KERNEL); + if (!sclp_mems) + return -ENOMEM; + kset = kset_create_and_add("memory", NULL, firmware_kobj); + if (!kset) + return -ENOMEM; + /* Initial memory is in the "configured" state already. */ + arg.sclp_mems = sclp_mems; + arg.kset = kset; + rc = for_each_memory_block(&arg, sclp_create_configured_mem); + if (rc) + return rc; + /* Standby memory is "deconfigured". */ + return sclp_create_standby_mems(sclp_mems, kset); } static void __init insert_increment(u16 rn, int standby, int assigned) @@ -336,7 +461,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) list_add(&new_incr->list, prev); } -static int __init sclp_detect_standby_memory(void) +static int __init sclp_setup_memory(void) { struct read_storage_sccb *sccb; int i, id, assigned, rc; @@ -388,12 +513,9 @@ static int __init sclp_detect_standby_memory(void) goto out; for (i = 1; i <= sclp.rnmax - assigned; i++) insert_increment(0, 1, 0); - rc = register_memory_notifier(&sclp_mem_nb); - if (rc) - goto out; - sclp_add_standby_memory(); + rc = sclp_init_mem(); out: free_page((unsigned long)sccb); return rc; } -__initcall(sclp_detect_standby_memory); +__initcall(sclp_setup_memory); diff --git a/drivers/s390/char/sclp_ocf.c b/drivers/s390/char/sclp_ocf.c index ae2479b804d8..35f3a4a08b12 100644 --- a/drivers/s390/char/sclp_ocf.c +++ b/drivers/s390/char/sclp_ocf.c @@ -6,8 +6,7 @@ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> */ -#define KMSG_COMPONENT "sclp_ocf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_ocf: " fmt #include <linux/export.h> #include <linux/kernel.h> diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c index 56400886f7fc..899063e64aef 100644 --- a/drivers/s390/char/sclp_pci.c +++ b/drivers/s390/char/sclp_pci.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2016 */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include <linux/completion.h> #include <linux/export.h> diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c index 129b89fe40a3..bb1bce70ec00 100644 --- a/drivers/s390/char/sclp_sd.c +++ b/drivers/s390/char/sclp_sd.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2017 */ -#define KMSG_COMPONENT "sclp_sd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_sd: " fmt #include <linux/completion.h> #include <linux/jiffies.h> diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index e915a343fcf5..ab8f1b758a1a 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -6,8 +6,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "sclp_sdias" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_sdias: " fmt #include <linux/completion.h> #include <linux/sched.h> diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 0aba30efb483..3953b31b0c55 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -130,6 +130,7 @@ struct tape_request { int retries; /* retry counter for error recovery. */ int rescnt; /* residual count from devstat. */ struct timer_list timer; /* timer for std_assign_timeout(). */ + struct irb irb; /* device status */ /* Callback for delivering final status. */ void (*callback)(struct tape_request *, void *); @@ -151,8 +152,8 @@ struct tape_discipline { int (*setup_device)(struct tape_device *); void (*cleanup_device)(struct tape_device *); int (*irq)(struct tape_device *, struct tape_request *, struct irb *); - struct tape_request *(*read_block)(struct tape_device *, size_t); - struct tape_request *(*write_block)(struct tape_device *, size_t); + struct tape_request *(*read_block)(struct tape_device *); + struct tape_request *(*write_block)(struct tape_device *); void (*process_eov)(struct tape_device*); /* ioctl function for additional ioctls. */ int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); @@ -172,7 +173,7 @@ struct tape_discipline { /* Char Frontend Data */ struct tape_char_data { - struct idal_buffer *idal_buf; /* idal buffer for user char data */ + struct idal_buffer **ibs; /* idal buffer array for user char data */ int block_size; /* of size block_size. */ }; @@ -234,6 +235,7 @@ struct tape_device { /* Externals from tape_core.c */ extern struct tape_request *tape_alloc_request(int cplength, int datasize); extern void tape_free_request(struct tape_request *); +extern int tape_check_idalbuffer(struct tape_device *device, size_t size); extern int tape_do_io(struct tape_device *, struct tape_request *); extern int tape_do_io_async(struct tape_device *, struct tape_request *); extern int tape_do_io_interruptible(struct tape_device *, struct tape_request *); @@ -347,12 +349,21 @@ tape_ccw_repeat(struct ccw1 *ccw, __u8 cmd_code, int count) } static inline struct ccw1 * +tape_ccw_dc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) +{ + ccw->cmd_code = cmd_code; + ccw->flags = CCW_FLAG_DC; + idal_buffer_set_cda(idal, ccw); + return ccw + 1; +} + +static inline struct ccw1 * tape_ccw_cc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) { ccw->cmd_code = cmd_code; ccw->flags = CCW_FLAG_CC; idal_buffer_set_cda(idal, ccw); - return ccw++; + return ccw + 1; } static inline struct ccw1 * @@ -361,7 +372,7 @@ tape_ccw_end_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) ccw->cmd_code = cmd_code; ccw->flags = 0; idal_buffer_set_cda(idal, ccw); - return ccw++; + return ccw + 1; } /* Global vars */ diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 1e4984acb648..a13e0ac1a4e2 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -8,8 +8,7 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> */ -#define KMSG_COMPONENT "tape_34xx" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape_34xx: " fmt #include <linux/export.h> #include <linux/module.h> @@ -234,31 +233,6 @@ tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb) return TAPE_IO_SUCCESS; } -/* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static int -tape_34xx_erp_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - if (request->op == TO_RFO) { - /* - * We did read forward, but the data could not be read - * *correctly*. We transform the request to a read backward - * and try again. - */ - tape_std_read_backward(device, request); - return tape_34xx_erp_retry(request); - } - - /* - * We tried to read forward and backward, but hat no - * success -> failed. - */ - return tape_34xx_erp_failed(request, -EIO); -} - static int tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request, struct irb *irb, int no) @@ -440,9 +414,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, dev_warn (&device->cdev->dev, "A write error on the " "tape cannot be recovered\n"); return tape_34xx_erp_failed(request, -EIO); - case 0x26: - /* Data Check (read opposite) occurred. */ - return tape_34xx_erp_read_opposite(device, request); case 0x28: /* ID-Mark at tape start couldn't be written */ dev_warn (&device->cdev->dev, "Writing the ID-mark " diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 2a2931d303cb..0d80f43b175d 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -8,8 +8,7 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> */ -#define KMSG_COMPONENT "tape_3590" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape_3590: " fmt #include <linux/export.h> #include <linux/module.h> @@ -551,31 +550,6 @@ tape_3590_mtseek(struct tape_device *device, int count) } /* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static void -tape_3590_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - struct tape_3590_disc_data *data; - - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - data = device->discdata; - tape_ccw_cc_idal(request->cpaddr + 1, data->read_back_op, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg\n"); -} - -/* * Read Attention Msg * This should be done after an interrupt with attention bit (0x80) * in device state. @@ -897,60 +871,6 @@ tape_3590_erp_special_interrupt(struct tape_device *device, } /* - * RDA: Read Alternate - */ -static int -tape_3590_erp_read_alternate(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - struct tape_3590_disc_data *data; - - /* - * The issued Read Backward or Read Previous command is not - * supported by the device - * The recovery action should be to issue another command: - * Read Revious: if Read Backward is not supported - * Read Backward: if Read Previous is not supported - */ - data = device->discdata; - if (data->read_back_op == READ_PREVIOUS) { - DBF_EVENT(2, "(%08x): No support for READ_PREVIOUS command\n", - device->cdev_id); - data->read_back_op = READ_BACKWARD; - } else { - DBF_EVENT(2, "(%08x): No support for READ_BACKWARD command\n", - device->cdev_id); - data->read_back_op = READ_PREVIOUS; - } - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); -} - -/* - * Error Recovery read opposite - */ -static int -tape_3590_erp_read_opposite(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - switch (request->op) { - case TO_RFO: - /* - * We did read forward, but the data could not be read. - * We will read backward and then skip forward again. - */ - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); - case TO_RBA: - /* We tried to read forward and backward, but hat no success */ - return tape_3590_erp_failed(device, request, irb, -EIO); - break; - default: - return tape_3590_erp_failed(device, request, irb, -EIO); - } -} - -/* * Print an MIM (Media Information Message) (message code f0) */ static void @@ -1348,10 +1268,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_read_buf_log(device, request, irb); - case 0x2011: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_alternate(device, request, irb); - case 0x2230: case 0x2231: tape_3590_print_era_msg(device, irb); @@ -1405,12 +1321,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_swap(device, request, irb); } - if (sense->rac == 0x26) { - /* Read Opposite */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_opposite(device, request, - irb); - } return tape_3590_erp_basic(device, request, irb, -EIO); case 0x5020: case 0x5021: diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 89778d922d9f..c5d3c303c15c 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -10,14 +10,12 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include <linux/module.h> #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/mtio.h> -#include <linux/compat.h> #include <linux/uaccess.h> @@ -37,9 +35,6 @@ static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); static long tapechar_ioctl(struct file *, unsigned int, unsigned long); -#ifdef CONFIG_COMPAT -static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); -#endif static const struct file_operations tape_fops = { @@ -47,9 +42,6 @@ static const struct file_operations tape_fops = .read = tapechar_read, .write = tapechar_write, .unlocked_ioctl = tapechar_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = tapechar_compat_ioctl, -#endif .open = tapechar_open, .release = tapechar_release, }; @@ -64,7 +56,7 @@ tapechar_setup_device(struct tape_device * device) { char device_name[20]; - sprintf(device_name, "ntibm%i", device->first_minor / 2); + scnprintf(device_name, sizeof(device_name), "ntibm%i", device->first_minor / 2); device->nt = register_tape_dev( &device->cdev->dev, MKDEV(tapechar_major, device->first_minor), @@ -93,33 +85,6 @@ tapechar_cleanup_device(struct tape_device *device) device->nt = NULL; } -static int -tapechar_check_idalbuffer(struct tape_device *device, size_t block_size) -{ - struct idal_buffer *new; - - if (device->char_data.idal_buf != NULL && - device->char_data.idal_buf->size == block_size) - return 0; - - if (block_size > MAX_BLOCKSIZE) { - DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n", - block_size, MAX_BLOCKSIZE); - return -EINVAL; - } - - /* The current idal buffer is not correct. Allocate a new one. */ - new = idal_buffer_alloc(block_size, 0); - if (IS_ERR(new)) - return -ENOMEM; - - if (device->char_data.idal_buf != NULL) - idal_buffer_free(device->char_data.idal_buf); - - device->char_data.idal_buf = new; - - return 0; -} /* * Tape device read function @@ -127,9 +92,12 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size) static ssize_t tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) { - struct tape_device *device; struct tape_request *request; + struct ccw1 *ccw, *last_ccw; + struct tape_device *device; + struct idal_buffer **ibs; size_t block_size; + size_t read = 0; int rc; DBF_EVENT(6, "TCHAR:read\n"); @@ -156,24 +124,37 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) block_size = count; } - rc = tapechar_check_idalbuffer(device, block_size); + rc = tape_check_idalbuffer(device, block_size); if (rc) return rc; DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); /* Let the discipline build the ccw chain. */ - request = device->discipline->read_block(device, block_size); + request = device->discipline->read_block(device); if (IS_ERR(request)) return PTR_ERR(request); /* Execute it. */ rc = tape_do_io(device, request); if (rc == 0) { - rc = block_size - request->rescnt; DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); - /* Copy data from idal buffer to user space. */ - if (idal_buffer_to_user(device->char_data.idal_buf, - data, rc) != 0) - rc = -EFAULT; + /* Channel Program Address (cpa) points to last CCW + 8 */ + last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa); + ccw = request->cpaddr; + ibs = device->char_data.ibs; + while (++ccw < last_ccw) { + /* Copy data from idal buffer to user space. */ + if (idal_buffer_to_user(*ibs++, data, ccw->count) != 0) { + rc = -EFAULT; + break; + } + read += ccw->count; + data += ccw->count; + } + if (&last_ccw[-1] == &request->cpaddr[1] && + request->rescnt == last_ccw[-1].count) + rc = 0; + else + rc = read - request->rescnt; } tape_free_request(request); return rc; @@ -185,10 +166,12 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) static ssize_t tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos) { - struct tape_device *device; struct tape_request *request; + struct ccw1 *ccw, *last_ccw; + struct tape_device *device; + struct idal_buffer **ibs; + size_t written = 0; size_t block_size; - size_t written; int nblocks; int i, rc; @@ -208,35 +191,45 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t nblocks = 1; } - rc = tapechar_check_idalbuffer(device, block_size); + rc = tape_check_idalbuffer(device, block_size); if (rc) return rc; - DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); + DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); /* Let the discipline build the ccw chain. */ - request = device->discipline->write_block(device, block_size); + request = device->discipline->write_block(device); if (IS_ERR(request)) return PTR_ERR(request); - rc = 0; - written = 0; + for (i = 0; i < nblocks; i++) { - /* Copy data from user space to idal buffer. */ - if (idal_buffer_from_user(device->char_data.idal_buf, - data, block_size)) { - rc = -EFAULT; - break; + size_t wbytes = 0; /* Used to trace written data in dbf */ + + ibs = device->char_data.ibs; + while (ibs && *ibs) { + if (idal_buffer_from_user(*ibs, data, (*ibs)->size)) { + rc = -EFAULT; + goto out; + } + data += (*ibs)->size; + ibs++; } rc = tape_do_io(device, request); if (rc) - break; - DBF_EVENT(6, "TCHAR:wbytes: %lx\n", - block_size - request->rescnt); - written += block_size - request->rescnt; + goto out; + + /* Channel Program Address (cpa) points to last CCW + 8 */ + last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa); + ccw = request->cpaddr; + while (++ccw < last_ccw) + wbytes += ccw->count; + DBF_EVENT(6, "TCHAR:wbytes: %lx\n", wbytes - request->rescnt); + written += wbytes - request->rescnt; if (request->rescnt != 0) break; - data += block_size; } + +out: tape_free_request(request); if (rc == -ENOSPC) { /* @@ -324,10 +317,8 @@ tapechar_release(struct inode *inode, struct file *filp) } } - if (device->char_data.idal_buf != NULL) { - idal_buffer_free(device->char_data.idal_buf); - device->char_data.idal_buf = NULL; - } + if (device->char_data.ibs) + idal_buffer_array_free(&device->char_data.ibs); tape_release(device); filp->private_data = NULL; tape_put_device(device); @@ -442,25 +433,6 @@ tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) return rc; } -#ifdef CONFIG_COMPAT -static long -tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) -{ - struct tape_device *device = filp->private_data; - long rc; - - if (no == MTIOCPOS32) - no = MTIOCPOS; - else if (no == MTIOCGET32) - no = MTIOCGET; - - mutex_lock(&device->mutex); - rc = __tapechar_ioctl(device, no, compat_ptr(data)); - mutex_unlock(&device->mutex); - return rc; -} -#endif /* CONFIG_COMPAT */ - /* * Initialize character device frontend. */ diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index fb18adfb95b5..6fa7b7824856 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -8,8 +8,7 @@ * Based on simple class device code by Greg K-H */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include <linux/export.h> #include <linux/slab.h> diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 6ec812280221..0250076a7d9f 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -11,8 +11,7 @@ * Stefan Bader <shbader@de.ibm.com> */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include <linux/export.h> #include <linux/module.h> @@ -726,6 +725,36 @@ tape_free_request (struct tape_request * request) kfree(request); } +int +tape_check_idalbuffer(struct tape_device *device, size_t size) +{ + struct idal_buffer **new; + size_t old_size = 0; + + old_size = idal_buffer_array_datasize(device->char_data.ibs); + if (old_size == size) + return 0; + + if (size > MAX_BLOCKSIZE) { + DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n", + size, MAX_BLOCKSIZE); + return -EINVAL; + } + + /* The current idal buffer is not correct. Allocate a new one. */ + new = idal_buffer_array_alloc(size, 0); + if (IS_ERR(new)) + return -ENOMEM; + + /* Free old idal buffer array */ + if (device->char_data.ibs) + idal_buffer_array_free(&device->char_data.ibs); + + device->char_data.ibs = new; + + return 0; +} + static int __tape_start_io(struct tape_device *device, struct tape_request *request) { @@ -1099,9 +1128,10 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } /* May be an unsolicited irq */ - if(request != NULL) + if (request != NULL) { request->rescnt = irb->scsw.cmd.count; - else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) && + memcpy(&request->irb, irb, sizeof(*irb)); + } else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) && !list_empty(&device->req_queue)) { /* Not Ready to Ready after long busy ? */ struct tape_request *req; diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index 2238d9df6c47..a1e5fab12af2 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c @@ -11,8 +11,7 @@ * PROCFS Functions */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include <linux/module.h> #include <linux/vmalloc.h> diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 176ae8e2eb6b..43a5586685ff 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -11,8 +11,7 @@ * Stefan Bader <shbader@de.ibm.com> */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include <linux/export.h> #include <linux/stddef.h> @@ -212,7 +211,7 @@ tape_std_mtload(struct tape_device *device, int count) int tape_std_mtsetblk(struct tape_device *device, int count) { - struct idal_buffer *new; + int rc; DBF_LH(6, "tape_std_mtsetblk(%d)\n", count); if (count <= 0) { @@ -224,26 +223,12 @@ tape_std_mtsetblk(struct tape_device *device, int count) device->char_data.block_size = 0; return 0; } - if (device->char_data.idal_buf != NULL && - device->char_data.idal_buf->size == count) - /* We already have a idal buffer of that size. */ - return 0; - if (count > MAX_BLOCKSIZE) { - DBF_EVENT(3, "Invalid block size (%d > %d) given.\n", - count, MAX_BLOCKSIZE); - return -EINVAL; - } + rc = tape_check_idalbuffer(device, count); + if (rc) + return rc; - /* Allocate a new idal buffer. */ - new = idal_buffer_alloc(count, 0); - if (IS_ERR(new)) - return -ENOMEM; - if (device->char_data.idal_buf != NULL) - idal_buffer_free(device->char_data.idal_buf); - device->char_data.idal_buf = new; device->char_data.block_size = count; - DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size); return 0; @@ -641,63 +626,54 @@ tape_std_mtcompression(struct tape_device *device, int mt_count) * Read Block */ struct tape_request * -tape_std_read_block(struct tape_device *device, size_t count) +tape_std_read_block(struct tape_device *device) { struct tape_request *request; + struct idal_buffer **ibs; + struct ccw1 *ccw; + size_t count; - /* - * We have to alloc 4 ccws in order to be able to transform request - * into a read backward request in error case. - */ - request = tape_alloc_request(4, 0); + ibs = device->char_data.ibs; + count = idal_buffer_array_size(ibs); + request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); if (IS_ERR(request)) { DBF_EXCEPTION(6, "xrbl fail"); return request; } request->op = TO_RFO; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD, - device->char_data.idal_buf); + ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); + while (count-- > 1) + ccw = tape_ccw_dc_idal(ccw, READ_FORWARD, *ibs++); + tape_ccw_end_idal(ccw, READ_FORWARD, *ibs); + DBF_EVENT(6, "xrbl ccwg\n"); return request; } /* - * Read Block backward transformation function. - */ -void -tape_std_read_backward(struct tape_device *device, struct tape_request *request) -{ - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg");} - -/* * Write Block */ struct tape_request * -tape_std_write_block(struct tape_device *device, size_t count) +tape_std_write_block(struct tape_device *device) { struct tape_request *request; + struct idal_buffer **ibs; + struct ccw1 *ccw; + size_t count; - request = tape_alloc_request(2, 0); + count = idal_buffer_array_size(device->char_data.ibs); + request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); if (IS_ERR(request)) { DBF_EXCEPTION(6, "xwbl fail\n"); return request; } request->op = TO_WRI; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD, - device->char_data.idal_buf); + ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); + ibs = device->char_data.ibs; + while (count-- > 1) + ccw = tape_ccw_dc_idal(ccw, WRITE_CMD, *ibs++); + tape_ccw_end_idal(ccw, WRITE_CMD, *ibs); + DBF_EVENT(6, "xwbl ccwg\n"); return request; } @@ -741,6 +717,5 @@ EXPORT_SYMBOL(tape_std_mterase); EXPORT_SYMBOL(tape_std_mtunload); EXPORT_SYMBOL(tape_std_mtcompression); EXPORT_SYMBOL(tape_std_read_block); -EXPORT_SYMBOL(tape_std_read_backward); EXPORT_SYMBOL(tape_std_write_block); EXPORT_SYMBOL(tape_std_process_eov); diff --git a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h index dcc63ff587f9..2cf9f725b3b3 100644 --- a/drivers/s390/char/tape_std.h +++ b/drivers/s390/char/tape_std.h @@ -14,10 +14,9 @@ #include <asm/tape390.h> /* - * Biggest block size to handle. Currently 64K because we only build - * channel programs without data chaining. + * Biggest block size of 256K to handle. */ -#define MAX_BLOCKSIZE 65535 +#define MAX_BLOCKSIZE 262144 /* * The CCW commands for the Tape type of command. @@ -97,10 +96,10 @@ #define SENSE_TAPE_POSITIONING 0x01 /* discipline functions */ -struct tape_request *tape_std_read_block(struct tape_device *, size_t); +struct tape_request *tape_std_read_block(struct tape_device *); void tape_std_read_backward(struct tape_device *device, struct tape_request *request); -struct tape_request *tape_std_write_block(struct tape_device *, size_t); +struct tape_request *tape_std_write_block(struct tape_device *); /* Some non-mtop commands. */ int tape_std_assign(struct tape_device *); diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 69899bb86b3e..bde6c9e59166 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -14,7 +14,6 @@ #include <linux/fs.h> #include <linux/init.h> -#include <linux/compat.h> #include <linux/kernel.h> #include <linux/miscdevice.h> #include <linux/slab.h> @@ -204,10 +203,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int __user *argp; session = file->private_data; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (int __user *)arg; + argp = (int __user *)arg; if (mutex_lock_interruptible(&session->mutex)) return -ERESTARTSYS; switch (cmd) { @@ -241,7 +237,6 @@ static const struct file_operations vmcp_fops = { .read = vmcp_read, .write = vmcp_write, .unlocked_ioctl = vmcp_ioctl, - .compat_ioctl = vmcp_ioctl, }; static struct miscdevice vmcp_dev = { diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e284eea331d7..383e7e2bd69f 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -11,8 +11,7 @@ * */ -#define KMSG_COMPONENT "vmlogrdr" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "vmlogrdr: " fmt #include <linux/module.h> #include <linux/init.h> diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 0fd918769a4b..e3e0e9f36527 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -9,8 +9,7 @@ * Frank Munzert <munzert@de.ibm.com> */ -#define KMSG_COMPONENT "vmur" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "vmur: " fmt #include <linux/cdev.h> #include <linux/slab.h> diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 33cebb91b933..b26b5fca6ce8 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -9,8 +9,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "zdump" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zdump: " fmt #include <linux/init.h> #include <linux/slab.h> |
