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