diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/con3270.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/ctrlchar.c | 16 | ||||
-rw-r--r-- | drivers/s390/char/ctrlchar.h | 12 | ||||
-rw-r--r-- | drivers/s390/char/diag_ftp.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/monreader.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 6 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 18 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 52 | ||||
-rw-r--r-- | drivers/s390/char/tty3270.c | 4 |
9 files changed, 99 insertions, 19 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 75ffe9980..7c511add5 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -413,6 +413,10 @@ con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb) else /* Normal end. Copy residual count. */ rq->rescnt = irb->scsw.cmd.count; + } else if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { + /* Interrupt without an outstanding request -> update all */ + cp->update_flags = CON_UPDATE_ALL; + con3270_set_timer(cp, 1); } return RAW3270_IO_DONE; } diff --git a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c index 8de2deb17..f7d92584b 100644 --- a/drivers/s390/char/ctrlchar.c +++ b/drivers/s390/char/ctrlchar.c @@ -14,15 +14,21 @@ #include "ctrlchar.h" #ifdef CONFIG_MAGIC_SYSRQ -static int ctrlchar_sysrq_key; +static struct sysrq_work ctrlchar_sysrq; static void ctrlchar_handle_sysrq(struct work_struct *work) { - handle_sysrq(ctrlchar_sysrq_key); + struct sysrq_work *sysrq = container_of(work, struct sysrq_work, work); + + handle_sysrq(sysrq->key); } -static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); +void schedule_sysrq_work(struct sysrq_work *sw) +{ + INIT_WORK(&sw->work, ctrlchar_handle_sysrq); + schedule_work(&sw->work); +} #endif @@ -51,8 +57,8 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) #ifdef CONFIG_MAGIC_SYSRQ /* racy */ if (len == 3 && buf[1] == '-') { - ctrlchar_sysrq_key = buf[2]; - schedule_work(&ctrlchar_work); + ctrlchar_sysrq.key = buf[2]; + schedule_sysrq_work(&ctrlchar_sysrq); return CTRLCHAR_SYSRQ; } #endif diff --git a/drivers/s390/char/ctrlchar.h b/drivers/s390/char/ctrlchar.h index 1a53552f4..59c2d6e55 100644 --- a/drivers/s390/char/ctrlchar.h +++ b/drivers/s390/char/ctrlchar.h @@ -7,6 +7,8 @@ */ #include <linux/tty.h> +#include <linux/sysrq.h> +#include <linux/workqueue.h> extern unsigned int ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty); @@ -17,3 +19,13 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty); #define CTRLCHAR_SYSRQ (3 << 8) #define CTRLCHAR_MASK (~0xffu) + + +#ifdef CONFIG_MAGIC_SYSRQ +struct sysrq_work { + int key; + struct work_struct work; +}; + +void schedule_sysrq_work(struct sysrq_work *sw); +#endif diff --git a/drivers/s390/char/diag_ftp.c b/drivers/s390/char/diag_ftp.c index 93889632f..12db8db04 100644 --- a/drivers/s390/char/diag_ftp.c +++ b/drivers/s390/char/diag_ftp.c @@ -223,7 +223,7 @@ int diag_ftp_startup(void) if (rc) return rc; - ctl_set_bit(0, 63 - 22); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); return 0; } @@ -232,6 +232,6 @@ int diag_ftp_startup(void) */ void diag_ftp_shutdown(void) { - ctl_clear_bit(0, 63 - 22); + irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL); unregister_external_irq(EXT_IRQ_CP_SERVICE, diag_ftp_handler); } diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 0da3ae3cd..b7d60306b 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -95,7 +95,7 @@ static void dcss_mkname(char *ascii_name, char *ebcdic_name) if (ascii_name[i] == '\0') break; ebcdic_name[i] = toupper(ascii_name[i]); - }; + } for (; i < 8; i++) ebcdic_name[i] = ' '; ASCEBC(ebcdic_name, 8); diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 5e20513c0..f58bf4c6c 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -53,7 +53,7 @@ static DECLARE_COMPLETION(sclp_request_queue_flushed); /* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */ int sclp_console_pages = SCLP_CONSOLE_PAGES; /* Flag to indicate if buffer pages are dropped on buffer full condition */ -int sclp_console_drop = 0; +int sclp_console_drop = 1; /* Number of times the console dropped buffer pages */ unsigned long sclp_console_full; @@ -79,8 +79,8 @@ static int __init sclp_setup_console_drop(char *str) int drop, rc; rc = kstrtoint(str, 0, &drop); - if (!rc && drop) - sclp_console_drop = 1; + if (!rc) + sclp_console_drop = drop; return 1; } diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index e9485fbbb..806239c2c 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -25,6 +25,7 @@ #include <asm/setup.h> #include <asm/page.h> #include <asm/sclp.h> +#include <asm/numa.h> #include "sclp.h" @@ -388,11 +389,11 @@ static struct notifier_block sclp_mem_nb = { }; static void __init align_to_block_size(unsigned long long *start, - unsigned long long *size) + unsigned long long *size, + unsigned long long alignment) { - unsigned long long start_align, size_align, alignment; + unsigned long long start_align, size_align; - alignment = memory_block_size_bytes(); start_align = roundup(*start, alignment); size_align = rounddown(*start + *size, alignment) - start_align; @@ -404,8 +405,8 @@ static void __init align_to_block_size(unsigned long long *start, static void __init add_memory_merged(u16 rn) { + unsigned long long start, size, addr, block_size; static u16 first_rn, num; - unsigned long long start, size; if (rn && first_rn && (first_rn + num == rn)) { num++; @@ -423,9 +424,12 @@ static void __init add_memory_merged(u16 rn) goto skip_add; if (memory_end_set && (start + size > memory_end)) size = memory_end - start; - align_to_block_size(&start, &size); - if (size) - add_memory(0, start, size); + block_size = memory_block_size_bytes(); + align_to_block_size(&start, &size, block_size); + if (!size) + goto skip_add; + for (addr = start; addr < start + size; addr += block_size) + add_memory(numa_pfn_to_nid(PFN_DOWN(addr)), addr, block_size); skip_add: first_rn = rn; num = 1; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index ae67386c0..68d6ee7ae 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -12,6 +12,7 @@ #include <linux/wait.h> #include <linux/timer.h> #include <linux/kernel.h> +#include <linux/sysrq.h> #include <linux/tty.h> #include <linux/tty_driver.h> #include <linux/tty_flip.h> @@ -27,6 +28,7 @@ #include <asm/uaccess.h> #include "sclp.h" +#include "ctrlchar.h" #define SCLP_VT220_MAJOR TTY_MAJOR #define SCLP_VT220_MINOR 65 @@ -477,6 +479,53 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) #define SCLP_VT220_SESSION_STARTED 0x80 #define SCLP_VT220_SESSION_DATA 0x00 +#ifdef CONFIG_MAGIC_SYSRQ + +static int sysrq_pressed; +static struct sysrq_work sysrq; + +static void sclp_vt220_reset_session(void) +{ + sysrq_pressed = 0; +} + +static void sclp_vt220_handle_input(const char *buffer, unsigned int count) +{ + int i; + + for (i = 0; i < count; i++) { + /* Handle magic sys request */ + if (buffer[i] == ('O' ^ 0100)) { /* CTRL-O */ + /* + * If pressed again, reset sysrq_pressed + * and flip CTRL-O character + */ + sysrq_pressed = !sysrq_pressed; + if (sysrq_pressed) + continue; + } else if (sysrq_pressed) { + sysrq.key = buffer[i]; + schedule_sysrq_work(&sysrq); + sysrq_pressed = 0; + continue; + } + tty_insert_flip_char(&sclp_vt220_port, buffer[i], 0); + } +} + +#else + +static void sclp_vt220_reset_session(void) +{ +} + +static void sclp_vt220_handle_input(const char *buffer, unsigned int count) +{ + tty_insert_flip_string(&sclp_vt220_port, buffer, count); +} + +#endif + /* * Called by the SCLP to report incoming event buffers. */ @@ -492,12 +541,13 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) switch (*buffer) { case SCLP_VT220_SESSION_ENDED: case SCLP_VT220_SESSION_STARTED: + sclp_vt220_reset_session(); break; case SCLP_VT220_SESSION_DATA: /* Send input to line discipline */ buffer++; count--; - tty_insert_flip_string(&sclp_vt220_port, buffer, count); + sclp_vt220_handle_input(buffer, count); tty_flip_buffer_push(&sclp_vt220_port); break; } diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index e91b89dc6..e96fc7fd9 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -659,6 +659,10 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) else /* Normal end. Copy residual count. */ rq->rescnt = irb->scsw.cmd.count; + } else if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { + /* Interrupt without an outstanding request -> update all */ + tp->update_flags = TTY_UPDATE_ALL; + tty3270_set_timer(tp, 1); } return RAW3270_IO_DONE; } |