Annotation of XNU/osfmk/ppc/console_feed.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_FREE_COPYRIGHT@
        !            24:  * 
        !            25:  */
        !            26: 
        !            27: /* Intercept mach console output and supply it to a user application */
        !            28: 
        !            29: #include <mach_kdb.h>
        !            30: 
        !            31: #include <types.h>
        !            32: #include <device/buf.h>
        !            33: #include <device/conf.h>
        !            34: #include <device/errno.h>
        !            35: #include <device/misc_protos.h>
        !            36: #include <device/ds_routines.h>
        !            37: #include <device/cirbuf.h>
        !            38: #include <ppc/console_feed_entries.h>
        !            39: #include <ppc/POWERMAC/serial_io.h>
        !            40: 
        !            41: #if    MACH_KDB
        !            42: #include <ppc/db_machdep.h>
        !            43: #endif /* MACH_KDB */
        !            44: 
        !            45: static struct cirbuf cons_feed_cb;
        !            46: static int cons_feed_count = 0;
        !            47: io_req_t   cons_feed_queued = 0;
        !            48: 
        !            49: /* console feed lock should be taken at splhigh */
        !            50: decl_simple_lock_data(,cons_feed_lock)
        !            51: 
        !            52: boolean_t cons_feed_read_done(io_req_t ior);
        !            53: 
        !            54: io_return_t
        !            55: console_feed_open(
        !            56:        dev_t           dev,
        !            57:        dev_mode_t      flag,
        !            58:        io_req_t        ior)
        !            59: {
        !            60:        spl_t   s;
        !            61: 
        !            62:         simple_lock_init(&cons_feed_lock, ETAP_IO_TTY);
        !            63: #if    MACH_KDB
        !            64:        if (console_is_serial()) {
        !            65:                return D_DEVICE_DOWN;
        !            66:        }
        !            67: #endif /* MACH_KDB */
        !            68:        cb_alloc(&cons_feed_cb, CONSOLE_FEED_BUFSIZE);
        !            69:        s = splhigh();
        !            70:        simple_lock(&cons_feed_lock);
        !            71:        cons_feed_count++;
        !            72:        simple_unlock(&cons_feed_lock);
        !            73:        splx(s);
        !            74:        return D_SUCCESS;
        !            75: }
        !            76: 
        !            77: void
        !            78: console_feed_close(
        !            79:        dev_t           dev)
        !            80: {
        !            81:        spl_t   s;
        !            82: 
        !            83:        s = splhigh();
        !            84:        simple_lock(&cons_feed_lock);
        !            85:        cons_feed_count--;
        !            86:        simple_unlock(&cons_feed_lock);
        !            87:        splx(s);
        !            88: 
        !            89:        console_feed_cancel_and_flush();
        !            90:        cb_free(&cons_feed_cb);
        !            91: 
        !            92:        return;
        !            93: }
        !            94: 
        !            95: /* A routine that can be called from a panic or other problem
        !            96:  * situation. It switches off the console feed and dumps any
        !            97:  * remaining buffered information to the original console
        !            98:  * (usually the screen). It doesn't free up the buffer, since
        !            99:  * it tries to be as minimal as possible 
        !           100:  */
        !           101: 
        !           102: void console_feed_cancel_and_flush(void)
        !           103: {
        !           104:        int     c;
        !           105:        spl_t   s;
        !           106:        
        !           107: #if    NCONSFEED > 0
        !           108: #if    MACH_KDB
        !           109:        if (console_is_serial()) {
        !           110:                return;
        !           111:        }
        !           112: #endif /* MACH_KDB */
        !           113: 
        !           114:        s = splhigh();
        !           115:        simple_lock(&cons_feed_lock);
        !           116:        if (cons_feed_count == 0) {
        !           117:                simple_unlock(&cons_feed_lock);
        !           118:                splx(s);
        !           119:                return;
        !           120:        }
        !           121:        cons_feed_count = 0;
        !           122:        simple_unlock(&cons_feed_lock);
        !           123:        splx(s);
        !           124: 
        !           125:        do {
        !           126:                c = getc(&cons_feed_cb);
        !           127:                if (c == -1)
        !           128:                        break;
        !           129:                cnputc(c);
        !           130:        } while (1);
        !           131: #endif /* NCONSFEED > 0 */
        !           132: }
        !           133: 
        !           134: io_return_t
        !           135: console_feed_read(
        !           136:        dev_t           dev,
        !           137:        io_req_t        ior)
        !           138: {
        !           139:        spl_t           s;
        !           140:        kern_return_t   rc;
        !           141:        int             count;
        !           142: 
        !           143:        rc = device_read_alloc(ior, (vm_size_t) ior->io_count);
        !           144:        if (rc != KERN_SUCCESS)
        !           145:                return rc;
        !           146: 
        !           147:        s = splhigh();
        !           148:        simple_lock(&cons_feed_lock);
        !           149: 
        !           150:        ior->io_residual = ior->io_count;
        !           151: 
        !           152:        count = q_to_b(&cons_feed_cb, (char *) ior->io_data, ior->io_count);
        !           153:        if (count == 0) {
        !           154:                if (ior->io_mode & D_NOWAIT) {
        !           155:                        rc = D_WOULD_BLOCK;
        !           156:                }
        !           157:                if (cons_feed_queued == NULL) {
        !           158:                        ior->io_done = cons_feed_read_done;
        !           159:                        cons_feed_queued = ior;
        !           160:                        rc = D_IO_QUEUED;
        !           161:                } else {
        !           162:                        /* Can't queue multiple read requests yet */
        !           163:                        rc = D_INVALID_OPERATION;
        !           164:                }
        !           165:                simple_unlock(&cons_feed_lock);
        !           166:                splx(s);
        !           167:                return rc;
        !           168:        }
        !           169: 
        !           170:        simple_unlock(&cons_feed_lock);
        !           171:        splx(s);
        !           172: 
        !           173:        ior->io_residual -= count;
        !           174: 
        !           175:        iodone(ior);
        !           176: 
        !           177:        if (ior->io_op & IO_SYNC) {
        !           178:                iowait(ior);
        !           179:        }
        !           180: 
        !           181:        return D_SUCCESS;
        !           182: }
        !           183: 
        !           184: /* Called when data is ready and there's a queued-up read waiting */
        !           185: boolean_t cons_feed_read_done(io_req_t ior)
        !           186: {
        !           187:        spl_t   s;
        !           188:        int     count;
        !           189: 
        !           190:        s = splhigh();
        !           191:        simple_lock(&cons_feed_lock);
        !           192: 
        !           193:        count = q_to_b(&cons_feed_cb, (char *) ior->io_data, ior->io_count);
        !           194:        if (count == 0) {
        !           195:                if (cons_feed_queued == NULL) {
        !           196:                        ior->io_done = cons_feed_read_done;
        !           197:                        cons_feed_queued = ior;
        !           198:                }
        !           199:                simple_unlock(&cons_feed_lock);
        !           200:                splx(s);
        !           201:                return FALSE;
        !           202:        }
        !           203: 
        !           204:        simple_unlock(&cons_feed_lock);
        !           205:        splx(s);
        !           206: 
        !           207:        ior->io_residual -= count;
        !           208:        ds_read_done(ior);
        !           209: 
        !           210:        return TRUE;
        !           211: }
        !           212: 
        !           213: /* This routine is called from putc() - it should return TRUE if
        !           214:  * the character should be passed on to a physical console, FALSE
        !           215:  * if the feed has intercepted the character. It may be called from
        !           216:  * under interrupt (even splhigh)
        !           217:  */
        !           218: 
        !           219: boolean_t console_feed_putc(char c)
        !           220: {
        !           221:        spl_t           s;
        !           222:        io_req_t        ior;
        !           223:        boolean_t       retval;
        !           224: 
        !           225: #if    MACH_KDB
        !           226:        if (db_active) {
        !           227:                return TRUE;
        !           228:        }
        !           229: #endif /* MACH_KDB */
        !           230: 
        !           231:        retval=TRUE;    /* TRUE : character should be displayed now */
        !           232:        if (!cons_feed_count) {
        !           233:                return TRUE;
        !           234:        }
        !           235:        s = splhigh();
        !           236:        simple_lock(&cons_feed_lock);
        !           237:        if (!cons_feed_count) {
        !           238:                simple_unlock(&cons_feed_lock);
        !           239:                splx(s);
        !           240:                return TRUE;
        !           241:        }
        !           242:        /* queue up the data if we can */
        !           243:        if (!putc(c, &cons_feed_cb)) {
        !           244:                /* able to stock the character */
        !           245:                retval = FALSE;
        !           246:        }
        !           247:        if (cons_feed_queued != NULL) {
        !           248:                /* Queued up request - service it */
        !           249:                ior = cons_feed_queued;
        !           250:                cons_feed_queued = NULL;
        !           251:                simple_unlock(&cons_feed_lock);
        !           252:                splx(s);
        !           253:                iodone(ior);
        !           254:                retval=FALSE;
        !           255:        } else {
        !           256:                simple_unlock(&cons_feed_lock);
        !           257:                splx(s);
        !           258:        }
        !           259:        return retval;
        !           260: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.