diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/Kconfig | 69 | ||||
-rw-r--r-- | drivers/s390/char/con3215.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/fs3270.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 18 | ||||
-rw-r--r-- | drivers/s390/char/sclp_config.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 18 | ||||
-rw-r--r-- | drivers/s390/char/tape_block.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/tape_char.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/tape_class.h | 1 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 70 | ||||
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 37 | ||||
-rw-r--r-- | drivers/s390/char/vmur.c | 3 |
13 files changed, 157 insertions, 68 deletions
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index 40834f18754c..dcee3c5c8954 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig @@ -2,76 +2,85 @@ comment "S/390 character device drivers" depends on S390 config TN3270 - tristate "Support for locally attached 3270 terminals" + def_tristate y + prompt "Support for locally attached 3270 terminals" depends on CCW help Include support for IBM 3270 terminals. config TN3270_TTY - tristate "Support for tty input/output on 3270 terminals" + def_tristate y + prompt "Support for tty input/output on 3270 terminals" depends on TN3270 help Include support for using an IBM 3270 terminal as a Linux tty. config TN3270_FS - tristate "Support for fullscreen applications on 3270 terminals" + def_tristate m + prompt "Support for fullscreen applications on 3270 terminals" depends on TN3270 help Include support for fullscreen applications on an IBM 3270 terminal. config TN3270_CONSOLE - bool "Support for console on 3270 terminal" + def_bool y + prompt "Support for console on 3270 terminal" depends on TN3270=y && TN3270_TTY=y help Include support for using an IBM 3270 terminal as a Linux system console. Available only if 3270 support is compiled in statically. config TN3215 - bool "Support for 3215 line mode terminal" + def_bool y + prompt "Support for 3215 line mode terminal" depends on CCW help Include support for IBM 3215 line-mode terminals. config TN3215_CONSOLE - bool "Support for console on 3215 line mode terminal" + def_bool y + prompt "Support for console on 3215 line mode terminal" depends on TN3215 help Include support for using an IBM 3215 line-mode terminal as a Linux system console. config CCW_CONSOLE - bool - depends on TN3215_CONSOLE || TN3270_CONSOLE - default y + def_bool y if TN3215_CONSOLE || TN3270_CONSOLE config SCLP_TTY - bool "Support for SCLP line mode terminal" + def_bool y + prompt "Support for SCLP line mode terminal" depends on S390 help Include support for IBM SCLP line-mode terminals. config SCLP_CONSOLE - bool "Support for console on SCLP line mode terminal" + def_bool y + prompt "Support for console on SCLP line mode terminal" depends on SCLP_TTY help Include support for using an IBM HWC line-mode terminal as the Linux system console. config SCLP_VT220_TTY - bool "Support for SCLP VT220-compatible terminal" + def_bool y + prompt "Support for SCLP VT220-compatible terminal" depends on S390 help Include support for an IBM SCLP VT220-compatible terminal. config SCLP_VT220_CONSOLE - bool "Support for console on SCLP VT220-compatible terminal" + def_bool y + prompt "Support for console on SCLP VT220-compatible terminal" depends on SCLP_VT220_TTY help Include support for using an IBM SCLP VT220-compatible terminal as a Linux system console. config SCLP_CPI - tristate "Control-Program Identification" + def_tristate m + prompt "Control-Program Identification" depends on S390 help This option enables the hardware console interface for system @@ -83,7 +92,8 @@ config SCLP_CPI need this feature and intend to run your kernel in LPAR. config SCLP_ASYNC - tristate "Support for Call Home via Asynchronous SCLP Records" + def_tristate m + prompt "Support for Call Home via Asynchronous SCLP Records" depends on S390 help This option enables the call home function, which is able to inform @@ -93,7 +103,8 @@ config SCLP_ASYNC need this feature and intend to run your kernel in LPAR. config S390_TAPE - tristate "S/390 tape device support" + def_tristate m + prompt "S/390 tape device support" depends on CCW help Select this option if you want to access channel-attached tape @@ -109,7 +120,8 @@ comment "S/390 tape interface support" depends on S390_TAPE config S390_TAPE_BLOCK - bool "Support for tape block devices" + def_bool y + prompt "Support for tape block devices" depends on S390_TAPE && BLOCK help Select this option if you want to access your channel-attached tape @@ -123,7 +135,8 @@ comment "S/390 tape hardware support" depends on S390_TAPE config S390_TAPE_34XX - tristate "Support for 3480/3490 tape hardware" + def_tristate m + prompt "Support for 3480/3490 tape hardware" depends on S390_TAPE help Select this option if you want to access IBM 3480/3490 magnetic @@ -131,7 +144,8 @@ config S390_TAPE_34XX It is safe to say "Y" here. config S390_TAPE_3590 - tristate "Support for 3590 tape hardware" + def_tristate m + prompt "Support for 3590 tape hardware" depends on S390_TAPE help Select this option if you want to access IBM 3590 magnetic @@ -139,7 +153,8 @@ config S390_TAPE_3590 It is safe to say "Y" here. config VMLOGRDR - tristate "Support for the z/VM recording system services (VM only)" + def_tristate m + prompt "Support for the z/VM recording system services (VM only)" depends on IUCV help Select this option if you want to be able to receive records collected @@ -148,29 +163,31 @@ config VMLOGRDR This driver depends on the IUCV support driver. config VMCP - bool "Support for the z/VM CP interface" + def_bool y + prompt "Support for the z/VM CP interface" depends on S390 help Select this option if you want to be able to interact with the control program on z/VM config MONREADER - tristate "API for reading z/VM monitor service records" + def_tristate m + prompt "API for reading z/VM monitor service records" depends on IUCV help Character device driver for reading z/VM monitor service records config MONWRITER - tristate "API for writing z/VM monitor service records" + def_tristate m + prompt "API for writing z/VM monitor service records" depends on S390 - default "m" help Character device driver for writing z/VM monitor service records config S390_VMUR - tristate "z/VM unit record device driver" + def_tristate m + prompt "z/VM unit record device driver" depends on S390 - default "m" help Character device driver for z/VM reader, puncher and printer. diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 59ec073724bf..3fb4335d491d 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -9,6 +9,7 @@ * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu> */ +#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kdev_t.h> @@ -361,6 +362,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm, int cstat, dstat; int count; + kstat_cpu(smp_processor_id()).irqs[IOINT_C15]++; raw = dev_get_drvdata(&cdev->dev); req = (struct raw3215_req *) intparm; cstat = irb->scsw.cmd.cstat; diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index eb28fb01a38a..f6489eb7e976 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -14,7 +14,6 @@ #include <linux/list.h> #include <linux/slab.h> #include <linux/types.h> -#include <linux/smp_lock.h> #include <asm/compat.h> #include <asm/ccwdev.h> diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 2a4c566456e7..96ba2fd1c8ad 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -7,6 +7,7 @@ * Copyright IBM Corp. 2003, 2009 */ +#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/err.h> #include <linux/init.h> @@ -329,6 +330,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) struct raw3270_request *rq; int rc; + kstat_cpu(smp_processor_id()).irqs[IOINT_C70]++; rp = dev_get_drvdata(&cdev->dev); if (!rp) return; diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 35cc4686b99b..b76c61f82485 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -7,6 +7,7 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> */ +#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/err.h> #include <linux/spinlock.h> @@ -18,16 +19,14 @@ #include <linux/suspend.h> #include <linux/completion.h> #include <linux/platform_device.h> -#include <asm/types.h> #include <asm/s390_ext.h> +#include <asm/types.h> +#include <asm/irq.h> #include "sclp.h" #define SCLP_HEADER "sclp: " -/* Structure for register_early_external_interrupt. */ -static ext_int_info_t ext_int_info_hwc; - /* Lock to protect internal data consistency. */ static DEFINE_SPINLOCK(sclp_lock); @@ -402,6 +401,7 @@ static void sclp_interrupt_handler(unsigned int ext_int_code, u32 finished_sccb; u32 evbuf_pending; + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; spin_lock(&sclp_lock); finished_sccb = param32 & 0xfffffff8; evbuf_pending = param32 & 0x3; @@ -824,6 +824,7 @@ static void sclp_check_handler(unsigned int ext_int_code, { u32 finished_sccb; + kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++; finished_sccb = param32 & 0xfffffff8; /* Is this the interrupt we are waiting for? */ if (finished_sccb == 0) @@ -866,8 +867,7 @@ sclp_check_interface(void) spin_lock_irqsave(&sclp_lock, flags); /* Prepare init mask command */ - rc = register_early_external_interrupt(0x2401, sclp_check_handler, - &ext_int_info_hwc); + rc = register_external_interrupt(0x2401, sclp_check_handler); if (rc) { spin_unlock_irqrestore(&sclp_lock, flags); return rc; @@ -900,8 +900,7 @@ sclp_check_interface(void) } else rc = -EBUSY; } - unregister_early_external_interrupt(0x2401, sclp_check_handler, - &ext_int_info_hwc); + unregister_external_interrupt(0x2401, sclp_check_handler); spin_unlock_irqrestore(&sclp_lock, flags); return rc; } @@ -1064,8 +1063,7 @@ sclp_init(void) if (rc) goto fail_init_state_uninitialized; /* Register interrupt handler */ - rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler, - &ext_int_info_hwc); + rc = register_external_interrupt(0x2401, sclp_interrupt_handler); if (rc) goto fail_unregister_reboot_notifier; sclp_init_state = sclp_init_state_initialized; diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index b497afe061cc..16e232a99fb7 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -33,6 +33,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work) int cpu; struct sys_device *sysdev; + s390_adjust_jiffies(); pr_warning("cpu capability changed.\n"); get_online_cpus(); for_each_online_cpu(cpu) { diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index deff2c3361e4..fbe361fcd2c0 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -24,6 +24,8 @@ #include "tape_std.h" #include "tape_3590.h" +static struct workqueue_struct *tape_3590_wq; + /* * Pointer to debug area. */ @@ -613,7 +615,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) p->device = tape_get_device(device); p->op = op; - schedule_work(&p->work); + queue_work(tape_3590_wq, &p->work); return 0; } @@ -1629,7 +1631,7 @@ fail_kmalloc: static void tape_3590_cleanup_device(struct tape_device *device) { - flush_scheduled_work(); + flush_workqueue(tape_3590_wq); tape_std_unassign(device); kfree(device->discdata); @@ -1733,11 +1735,17 @@ tape_3590_init(void) #endif DBF_EVENT(3, "3590 init\n"); + + tape_3590_wq = alloc_workqueue("tape_3590", 0, 0); + if (!tape_3590_wq) + return -ENOMEM; + /* Register driver for 3590 tapes. */ rc = ccw_driver_register(&tape_3590_driver); - if (rc) + if (rc) { + destroy_workqueue(tape_3590_wq); DBF_EVENT(3, "3590 init failed\n"); - else + } else DBF_EVENT(3, "3590 registered\n"); return rc; } @@ -1746,7 +1754,7 @@ static void tape_3590_exit(void) { ccw_driver_unregister(&tape_3590_driver); - + destroy_workqueue(tape_3590_wq); debug_unregister(TAPE_DBF_AREA); } diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index f0fa9ca5cb2c..55d2d0f4eabc 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -264,7 +264,7 @@ cleanup_queue: void tapeblock_cleanup_device(struct tape_device *device) { - flush_scheduled_work(); + flush_work_sync(&device->blk_data.requeue_task); tape_put_device(device); if (!device->blk_data.disk) { diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 883e2db02bd3..e090a307fdee 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -17,7 +17,6 @@ #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/mtio.h> -#include <linux/smp_lock.h> #include <linux/compat.h> #include <asm/uaccess.h> diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h index 707b7f48c232..9e32780c317f 100644 --- a/drivers/s390/char/tape_class.h +++ b/drivers/s390/char/tape_class.h @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> -#include <linux/kobject.h> #include <linux/kobj_map.h> #include <linux/cdev.h> diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 6c408670e08d..7978a0adeaf3 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -14,6 +14,7 @@ #define KMSG_COMPONENT "tape" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/init.h> // for kernel parameters #include <linux/kmod.h> // for requesting modules @@ -209,29 +210,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) wake_up(&device->state_change_wq); } +struct tape_med_state_work_data { + struct tape_device *device; + enum tape_medium_state state; + struct work_struct work; +}; + +static void +tape_med_state_work_handler(struct work_struct *work) +{ + static char env_state_loaded[] = "MEDIUM_STATE=LOADED"; + static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED"; + struct tape_med_state_work_data *p = + container_of(work, struct tape_med_state_work_data, work); + struct tape_device *device = p->device; + char *envp[] = { NULL, NULL }; + + switch (p->state) { + case MS_UNLOADED: + pr_info("%s: The tape cartridge has been successfully " + "unloaded\n", dev_name(&device->cdev->dev)); + envp[0] = env_state_unloaded; + kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); + break; + case MS_LOADED: + pr_info("%s: A tape cartridge has been mounted\n", + dev_name(&device->cdev->dev)); + envp[0] = env_state_loaded; + kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); + break; + default: + break; + } + tape_put_device(device); + kfree(p); +} + +static void +tape_med_state_work(struct tape_device *device, enum tape_medium_state state) +{ + struct tape_med_state_work_data *p; + + p = kzalloc(sizeof(*p), GFP_ATOMIC); + if (p) { + INIT_WORK(&p->work, tape_med_state_work_handler); + p->device = tape_get_device(device); + p->state = state; + schedule_work(&p->work); + } +} + void tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate) { - if (device->medium_state == newstate) + enum tape_medium_state oldstate; + + oldstate = device->medium_state; + if (oldstate == newstate) return; + device->medium_state = newstate; switch(newstate){ case MS_UNLOADED: device->tape_generic_status |= GMT_DR_OPEN(~0); - if (device->medium_state == MS_LOADED) - pr_info("%s: The tape cartridge has been successfully " - "unloaded\n", dev_name(&device->cdev->dev)); + if (oldstate == MS_LOADED) + tape_med_state_work(device, MS_UNLOADED); break; case MS_LOADED: device->tape_generic_status &= ~GMT_DR_OPEN(~0); - if (device->medium_state == MS_UNLOADED) - pr_info("%s: A tape cartridge has been mounted\n", - dev_name(&device->cdev->dev)); + if (oldstate == MS_UNLOADED) + tape_med_state_work(device, MS_LOADED); break; default: - // print nothing break; } - device->medium_state = newstate; wake_up(&device->state_change_wq); } @@ -1064,6 +1115,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) struct tape_request *request; int rc; + kstat_cpu(smp_processor_id()).irqs[IOINT_TAP]++; device = dev_get_drvdata(&cdev->dev); if (device == NULL) { return; diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 9f661426e4a1..c837d7419a6a 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -30,7 +30,6 @@ #include <linux/kmod.h> #include <linux/cdev.h> #include <linux/device.h> -#include <linux/smp_lock.h> #include <linux/string.h> MODULE_AUTHOR @@ -249,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, char cp_command[80]; char cp_response[160]; char *onoff, *qid_string; + int rc; - memset(cp_command, 0x00, sizeof(cp_command)); - memset(cp_response, 0x00, sizeof(cp_response)); - - onoff = ((action == 1) ? "ON" : "OFF"); + onoff = ((action == 1) ? "ON" : "OFF"); qid_string = ((recording_class_AB == 1) ? " QID * " : ""); - /* + /* * The recording commands needs to be called with option QID * for guests that have previlege classes A or B. * Purging has to be done as separate step, because recording * can't be switched on as long as records are on the queue. * Doing both at the same time doesn't work. */ - - if (purge) { + if (purge && (action == 1)) { + memset(cp_command, 0x00, sizeof(cp_command)); + memset(cp_response, 0x00, sizeof(cp_response)); snprintf(cp_command, sizeof(cp_command), "RECORDING %s PURGE %s", logptr->recording_name, qid_string); - cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); } @@ -279,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, logptr->recording_name, onoff, qid_string); - cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); /* The recording command will usually answer with 'Command complete' * on success, but when the specific service was never connected * before then there might be an additional informational message * 'HCPCRC8072I Recording entry not found' before the - * 'Command complete'. So I use strstr rather then the strncmp. + * 'Command complete'. So I use strstr rather then the strncmp. */ if (strstr(cp_response,"Command complete")) - return 0; + rc = 0; else - return -EIO; + rc = -EIO; + /* + * If we turn recording off, we have to purge any remaining records + * afterwards, as a large number of queued records may impact z/VM + * performance. + */ + if (purge && (action == 0)) { + memset(cp_command, 0x00, sizeof(cp_command)); + memset(cp_response, 0x00, sizeof(cp_response)); + snprintf(cp_command, sizeof(cp_command), + "RECORDING %s PURGE %s", + logptr->recording_name, + qid_string); + cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); + } + return rc; } diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 1de672f21037..caef1757341d 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -11,9 +11,9 @@ #define KMSG_COMPONENT "vmur" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/kernel_stat.h> #include <linux/cdev.h> #include <linux/slab.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/cio.h> @@ -303,6 +303,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, { struct urdev *urd; + kstat_cpu(smp_processor_id()).irqs[IOINT_VMR]++; TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, irb->scsw.cmd.count); |