Annotation of XNU/osfmk/ppc/console_feed.c, revision 1.1.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.