Mercurial > hvf > hvf-old
view cp/drivers/console.c @ 618:535aec703236
cp: define a FIXME macro that leaves a sclp message
There are far too many fixmes in the code. Sadly, the compiler simply
discards them. This usually isn't an issue until one accidentally hits a
"weird" bug which just turns out to be an unhandled (but documented) case in
another part of the code. Using a macro instead of a comment will let the
compiler string-ify the text, and then at runtime use SCLP to print it out.
This will immediatelly point at problem areas. So, keep an eye on SCLP from
now on :)
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 13 Dec 2011 22:20:50 -0500 |
parents | 6b1f2cc66681 |
children |
line wrap: on
line source
/* * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. */ #include <console.h> #include <slab.h> #include <sched.h> #include <directory.h> #include <vsprintf.h> #include <spool.h> #include <buddy.h> /* * List of all consoles on the system */ static LIST_HEAD(consoles); static spinlock_t consoles_lock = SPIN_LOCK_UNLOCKED; static void do_issue_read(struct console *con, struct io_op *ioop, struct ccw *ccws) { int ret; atomic_dec(&con->dev->attention); /* clear the buffer to allow strlen on the result */ memset(con->bigbuf, 0, CONSOLE_LINE_LEN+1); ccws[0].addr = ADDR31(con->bigbuf); ccws[0].count = CONSOLE_LINE_LEN; ccws[0].cmd = 0x0a; ccws[0].flags = CCW_FLAG_SLI; memset(&ioop->orb, 0, sizeof(struct orb)); ioop->orb.lpm = 0xff; ioop->orb.addr = ADDR31(ccws); ioop->orb.f = 1; ioop->handler = NULL; ioop->dtor = NULL; submit_io(con->dev, ioop, CAN_SLEEP); ret = spool_append_rec(con->rlines, con->bigbuf, strnlen((char*)con->bigbuf, CONSOLE_LINE_LEN)); BUG_ON(ret); } /** * console_flusher - iterates over a console's buffers and initiates the IO */ static int console_flusher(void *data) { struct console *con = data; u8 *buf; u16 len; u16 left; /* needed for the IO */ struct io_op ioop; struct ccw ccws[PAGE_SIZE/CONSOLE_LINE_LEN]; int i; for(;;) { FIXME("this should be a sub-unless-zero"); if (atomic_read(&con->dev->attention)) do_issue_read(con, &ioop, ccws); buf = con->bigbuf; left = PAGE_SIZE; for(i=0; left >= CONSOLE_LINE_LEN; i++) { len = CONSOLE_LINE_LEN; if (spool_grab_rec(con->wlines, buf, &len)) break; ccws[i].addr = ADDR31(buf); ccws[i].count = len; ccws[i].cmd = 0x01; /* write */ ccws[i].flags = CCW_FLAG_CC | CCW_FLAG_SLI; left -= len; buf += len; } if (!i) { schedule(); continue; } ccws[i-1].flags &= ~CCW_FLAG_CC; /* * Now, set up the ORB and CCW */ memset(&ioop.orb, 0, sizeof(struct orb)); ioop.orb.lpm = 0xff; ioop.orb.addr = ADDR31(ccws); ioop.orb.f = 1; /* format 1 CCW */ /* * Set up the operation handler pointers, and start the IO */ ioop.handler = NULL; ioop.dtor = NULL; submit_io(con->dev, &ioop, CAN_SLEEP); } return 0; } static void print_splash(struct console *con) { struct logo_rec *rec; struct logo *logo; list_for_each_entry(logo, &sysconf.logos, list) { if (con->dev->type != logo->devtype) continue; FIXME("check the connection type"); list_for_each_entry(rec, &logo->lines, list) con_printf(con, "%*.*s\n", CONFIG_LRECL, CONFIG_LRECL, (char*) rec->data); break; } con_printf(con, "HVF VERSION " VERSION "\n\n"); } struct console* start_oper_console(void) { struct device *dev; /* * We only start the operator console */ dev = find_device_by_ccuu(sysconf.oper_con); BUG_ON(IS_ERR(dev)); return console_enable(dev); } void* console_enable(struct device *dev) { char name[TASK_NAME_LEN+1]; struct console *con; con = find_console(dev); if (!IS_ERR(con)) return con; if (register_console(dev)) return ERR_PTR(-ENOMEM); /* try again, this time, we should always find it! */ con = find_console(dev); if (IS_ERR(con)) return con; atomic_inc(&con->dev->in_use); snprintf(name, TASK_NAME_LEN, "%05X-conflsh", con->dev->sch); create_task(name, console_flusher, con); print_splash(con); return con; } int con_read_pending(struct console *con) { return spool_nrecs(con->rlines); } int con_read(struct console *con, u8 *buf, int size) { u16 len = size; if (spool_grab_rec(con->rlines, buf, &len)) return -1; return len; } int con_write(struct console *con, u8 *buf, int len) { if (spool_append_rec(con->wlines, buf, len)) return 0; return len; } void for_each_console(void (*f)(struct console *con)) { struct console *con; if (!f) return; spin_lock(&consoles_lock); list_for_each_entry(con, &consoles, consoles) f(con); spin_unlock(&consoles_lock); } struct console* find_console(struct device *dev) { struct console *con; if (!dev) return ERR_PTR(-ENOENT); spin_lock(&consoles_lock); list_for_each_entry(con, &consoles, consoles) { if (con->dev == dev) goto found; } con = ERR_PTR(-ENOENT); found: spin_unlock(&consoles_lock); return con; }