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 spinlock_t sclp_con_lock; 30 /* List of free pages that can be used for console output buffering */ 31 static struct list_head sclp_con_pages; 32 /* List of full struct sclp_buffer structures ready for output */ 33 static struct 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 static unsigned short sclp_con_columns; 45 static unsigned short sclp_con_width_htab; 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(unsigned long data) 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 sclp_con_width_htab); 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 init_timer(&sclp_con_timer); 215 sclp_con_timer.function = sclp_console_timeout; 216 sclp_con_timer.data = 0UL; 217 sclp_con_timer.expires = jiffies + HZ/10; 218 add_timer(&sclp_con_timer); 219 } 220 out: 221 spin_unlock_irqrestore(&sclp_con_lock, flags); 222 } 223 224 static struct tty_driver * 225 sclp_console_device(struct console *c, int *index) 226 { 227 *index = c->index; 228 return sclp_tty_driver; 229 } 230 231 /* 232 * Make sure that all buffers will be flushed to the SCLP. 233 */ 234 static void 235 sclp_console_flush(void) 236 { 237 sclp_conbuf_emit(); 238 sclp_console_sync_queue(); 239 } 240 241 /* 242 * Resume console: If there are cached messages, emit them. 243 */ 244 static void sclp_console_resume(void) 245 { 246 unsigned long flags; 247 248 spin_lock_irqsave(&sclp_con_lock, flags); 249 sclp_con_suspended = 0; 250 spin_unlock_irqrestore(&sclp_con_lock, flags); 251 sclp_conbuf_emit(); 252 } 253 254 /* 255 * Suspend console: Set suspend flag and flush console 256 */ 257 static void sclp_console_suspend(void) 258 { 259 unsigned long flags; 260 261 spin_lock_irqsave(&sclp_con_lock, flags); 262 sclp_con_suspended = 1; 263 spin_unlock_irqrestore(&sclp_con_lock, flags); 264 sclp_console_flush(); 265 } 266 267 static int sclp_console_notify(struct notifier_block *self, 268 unsigned long event, void *data) 269 { 270 sclp_console_flush(); 271 return NOTIFY_OK; 272 } 273 274 static struct notifier_block on_panic_nb = { 275 .notifier_call = sclp_console_notify, 276 .priority = SCLP_PANIC_PRIO_CLIENT, 277 }; 278 279 static struct notifier_block on_reboot_nb = { 280 .notifier_call = sclp_console_notify, 281 .priority = 1, 282 }; 283 284 /* 285 * used to register the SCLP console to the kernel and to 286 * give printk necessary information 287 */ 288 static struct console sclp_console = 289 { 290 .name = sclp_console_name, 291 .write = sclp_console_write, 292 .device = sclp_console_device, 293 .flags = CON_PRINTBUFFER, 294 .index = 0 /* ttyS0 */ 295 }; 296 297 /* 298 * This function is called for SCLP suspend and resume events. 299 */ 300 void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) 301 { 302 switch (sclp_pm_event) { 303 case SCLP_PM_EVENT_FREEZE: 304 sclp_console_suspend(); 305 break; 306 case SCLP_PM_EVENT_RESTORE: 307 case SCLP_PM_EVENT_THAW: 308 sclp_console_resume(); 309 break; 310 } 311 } 312 313 /* 314 * called by console_init() in drivers/char/tty_io.c at boot-time. 315 */ 316 static int __init 317 sclp_console_init(void) 318 { 319 void *page; 320 int i; 321 int rc; 322 323 /* SCLP consoles are handled together */ 324 if (!(CONSOLE_IS_SCLP || CONSOLE_IS_VT220)) 325 return 0; 326 rc = sclp_rw_init(); 327 if (rc) 328 return rc; 329 /* Allocate pages for output buffering */ 330 INIT_LIST_HEAD(&sclp_con_pages); 331 for (i = 0; i < sclp_console_pages; i++) { 332 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 333 list_add_tail(page, &sclp_con_pages); 334 } 335 INIT_LIST_HEAD(&sclp_con_outqueue); 336 spin_lock_init(&sclp_con_lock); 337 sclp_conbuf = NULL; 338 init_timer(&sclp_con_timer); 339 340 /* Set output format */ 341 if (MACHINE_IS_VM) 342 /* 343 * save 4 characters for the CPU number 344 * written at start of each line by VM/CP 345 */ 346 sclp_con_columns = 76; 347 else 348 sclp_con_columns = 80; 349 sclp_con_width_htab = 8; 350 351 /* enable printk-access to this driver */ 352 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); 353 register_reboot_notifier(&on_reboot_nb); 354 register_console(&sclp_console); 355 return 0; 356 } 357 358 console_initcall(sclp_console_init); 359