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