1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * SCLP line mode console driver 4 * 5 * Copyright IBM Corp. 1999, 2009 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 */ 9 10 #include <linux/kmod.h> 11 #include <linux/console.h> 12 #include <linux/init.h> 13 #include <linux/timer.h> 14 #include <linux/jiffies.h> 15 #include <linux/termios.h> 16 #include <linux/err.h> 17 #include <linux/reboot.h> 18 #include <linux/gfp.h> 19 20 #include "sclp.h" 21 #include "sclp_rw.h" 22 #include "sclp_tty.h" 23 24 #define sclp_console_major 4 /* TTYAUX_MAJOR */ 25 #define sclp_console_minor 64 26 #define sclp_console_name "ttyS" 27 28 /* Lock to guard over changes to global variables */ 29 static DEFINE_SPINLOCK(sclp_con_lock); 30 /* List of free pages that can be used for console output buffering */ 31 static LIST_HEAD(sclp_con_pages); 32 /* List of full struct sclp_buffer structures ready for output */ 33 static LIST_HEAD(sclp_con_outqueue); 34 /* Pointer to current console buffer */ 35 static struct sclp_buffer *sclp_conbuf; 36 /* Timer for delayed output of console messages */ 37 static struct timer_list sclp_con_timer; 38 /* Flag that output queue is currently running */ 39 static int sclp_con_queue_running; 40 41 /* Output format for console messages */ 42 #define SCLP_CON_COLUMNS 320 43 #define SPACES_PER_TAB 8 44 45 static void 46 sclp_conbuf_callback(struct sclp_buffer *buffer, int rc) 47 { 48 unsigned long flags; 49 void *page; 50 51 do { 52 page = sclp_unmake_buffer(buffer); 53 spin_lock_irqsave(&sclp_con_lock, flags); 54 55 /* Remove buffer from outqueue */ 56 list_del(&buffer->list); 57 list_add_tail((struct list_head *) page, &sclp_con_pages); 58 59 /* Check if there is a pending buffer on the out queue. */ 60 buffer = NULL; 61 if (!list_empty(&sclp_con_outqueue)) 62 buffer = list_first_entry(&sclp_con_outqueue, 63 struct sclp_buffer, list); 64 if (!buffer) { 65 sclp_con_queue_running = 0; 66 spin_unlock_irqrestore(&sclp_con_lock, flags); 67 break; 68 } 69 spin_unlock_irqrestore(&sclp_con_lock, flags); 70 } while (sclp_emit_buffer(buffer, sclp_conbuf_callback)); 71 } 72 73 /* 74 * Finalize and emit first pending buffer. 75 */ 76 static void sclp_conbuf_emit(void) 77 { 78 struct sclp_buffer* buffer; 79 unsigned long flags; 80 int rc; 81 82 spin_lock_irqsave(&sclp_con_lock, flags); 83 if (sclp_conbuf) 84 list_add_tail(&sclp_conbuf->list, &sclp_con_outqueue); 85 sclp_conbuf = NULL; 86 if (sclp_con_queue_running) 87 goto out_unlock; 88 if (list_empty(&sclp_con_outqueue)) 89 goto out_unlock; 90 buffer = list_first_entry(&sclp_con_outqueue, struct sclp_buffer, 91 list); 92 sclp_con_queue_running = 1; 93 spin_unlock_irqrestore(&sclp_con_lock, flags); 94 95 rc = sclp_emit_buffer(buffer, sclp_conbuf_callback); 96 if (rc) 97 sclp_conbuf_callback(buffer, rc); 98 return; 99 out_unlock: 100 spin_unlock_irqrestore(&sclp_con_lock, flags); 101 } 102 103 /* 104 * Wait until out queue is empty 105 */ 106 static void sclp_console_sync_queue(void) 107 { 108 unsigned long flags; 109 110 spin_lock_irqsave(&sclp_con_lock, flags); 111 if (timer_pending(&sclp_con_timer)) 112 del_timer(&sclp_con_timer); 113 while (sclp_con_queue_running) { 114 spin_unlock_irqrestore(&sclp_con_lock, flags); 115 sclp_sync_wait(); 116 spin_lock_irqsave(&sclp_con_lock, flags); 117 } 118 spin_unlock_irqrestore(&sclp_con_lock, flags); 119 } 120 121 /* 122 * When this routine is called from the timer then we flush the 123 * temporary write buffer without further waiting on a final new line. 124 */ 125 static void 126 sclp_console_timeout(struct timer_list *unused) 127 { 128 sclp_conbuf_emit(); 129 } 130 131 /* 132 * Drop oldest console buffer if sclp_con_drop is set 133 */ 134 static int 135 sclp_console_drop_buffer(void) 136 { 137 struct list_head *list; 138 struct sclp_buffer *buffer; 139 void *page; 140 141 if (!sclp_console_drop) 142 return 0; 143 list = sclp_con_outqueue.next; 144 if (sclp_con_queue_running) 145 /* The first element is in I/O */ 146 list = list->next; 147 if (list == &sclp_con_outqueue) 148 return 0; 149 list_del(list); 150 buffer = list_entry(list, struct sclp_buffer, list); 151 page = sclp_unmake_buffer(buffer); 152 list_add_tail((struct list_head *) page, &sclp_con_pages); 153 return 1; 154 } 155 156 /* 157 * Writes the given message to S390 system console 158 */ 159 static void 160 sclp_console_write(struct console *console, const char *message, 161 unsigned int count) 162 { 163 unsigned long flags; 164 void *page; 165 int written; 166 167 if (count == 0) 168 return; 169 spin_lock_irqsave(&sclp_con_lock, flags); 170 /* 171 * process escape characters, write message into buffer, 172 * send buffer to SCLP 173 */ 174 do { 175 /* make sure we have a console output buffer */ 176 if (sclp_conbuf == NULL) { 177 if (list_empty(&sclp_con_pages)) 178 sclp_console_full++; 179 while (list_empty(&sclp_con_pages)) { 180 if (sclp_console_drop_buffer()) 181 break; 182 spin_unlock_irqrestore(&sclp_con_lock, flags); 183 sclp_sync_wait(); 184 spin_lock_irqsave(&sclp_con_lock, flags); 185 } 186 page = sclp_con_pages.next; 187 list_del((struct list_head *) page); 188 sclp_conbuf = sclp_make_buffer(page, SCLP_CON_COLUMNS, 189 SPACES_PER_TAB); 190 } 191 /* try to write the string to the current output buffer */ 192 written = sclp_write(sclp_conbuf, (const unsigned char *) 193 message, count); 194 if (written == count) 195 break; 196 /* 197 * Not all characters could be written to the current 198 * output buffer. Emit the buffer, create a new buffer 199 * and then output the rest of the string. 200 */ 201 spin_unlock_irqrestore(&sclp_con_lock, flags); 202 sclp_conbuf_emit(); 203 spin_lock_irqsave(&sclp_con_lock, flags); 204 message += written; 205 count -= written; 206 } while (count > 0); 207 /* Setup timer to output current console buffer after 1/10 second */ 208 if (sclp_conbuf != NULL && sclp_chars_in_buffer(sclp_conbuf) != 0 && 209 !timer_pending(&sclp_con_timer)) { 210 mod_timer(&sclp_con_timer, jiffies + HZ / 10); 211 } 212 spin_unlock_irqrestore(&sclp_con_lock, flags); 213 } 214 215 static struct tty_driver * 216 sclp_console_device(struct console *c, int *index) 217 { 218 *index = c->index; 219 return sclp_tty_driver; 220 } 221 222 /* 223 * Make sure that all buffers will be flushed to the SCLP. 224 */ 225 static void 226 sclp_console_flush(void) 227 { 228 sclp_conbuf_emit(); 229 sclp_console_sync_queue(); 230 } 231 232 static int sclp_console_notify(struct notifier_block *self, 233 unsigned long event, void *data) 234 { 235 sclp_console_flush(); 236 return NOTIFY_OK; 237 } 238 239 static struct notifier_block on_panic_nb = { 240 .notifier_call = sclp_console_notify, 241 .priority = 1, 242 }; 243 244 static struct notifier_block on_reboot_nb = { 245 .notifier_call = sclp_console_notify, 246 .priority = 1, 247 }; 248 249 /* 250 * used to register the SCLP console to the kernel and to 251 * give printk necessary information 252 */ 253 static struct console sclp_console = 254 { 255 .name = sclp_console_name, 256 .write = sclp_console_write, 257 .device = sclp_console_device, 258 .flags = CON_PRINTBUFFER, 259 .index = 0 /* ttyS0 */ 260 }; 261 262 /* 263 * called by console_init() in drivers/char/tty_io.c at boot-time. 264 */ 265 static int __init 266 sclp_console_init(void) 267 { 268 void *page; 269 int i; 270 int rc; 271 272 /* SCLP consoles are handled together */ 273 if (!(CONSOLE_IS_SCLP || CONSOLE_IS_VT220)) 274 return 0; 275 rc = sclp_rw_init(); 276 if (rc) 277 return rc; 278 /* Allocate pages for output buffering */ 279 for (i = 0; i < sclp_console_pages; i++) { 280 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 281 list_add_tail(page, &sclp_con_pages); 282 } 283 sclp_conbuf = NULL; 284 timer_setup(&sclp_con_timer, sclp_console_timeout, 0); 285 286 /* enable printk-access to this driver */ 287 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); 288 register_reboot_notifier(&on_reboot_nb); 289 register_console(&sclp_console); 290 return 0; 291 } 292 293 console_initcall(sclp_console_init); 294