Annotation of XNU/osfmk/i386/iopb.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_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: 
                     51: /*
                     52:  */
                     53: 
                     54: /*
                     55:  * Code to manipulate IO permission bitmaps.
                     56:  */
                     57:  
                     58: 
                     59: 
                     60: #include <mach/boolean.h>
                     61: #include <mach/kern_return.h>
                     62: 
                     63: #include <ipc/ipc_port.h>
                     64: 
                     65: #include <kern/kalloc.h>
                     66: #include <kern/lock.h>
                     67: #include <kern/queue.h>
                     68: #include <kern/thread.h>
                     69: #include <kern/misc_protos.h>
                     70: 
                     71: 
                     72: #include <i386/io_port.h>
                     73: #include <i386/iopb.h>
                     74: #include <i386/seg.h>
                     75: #include <i386/iopb_entries.h>
                     76: 
                     77: void
                     78: iopb_init(void)
                     79: {
                     80: }
                     81: 
                     82: 
                     83: void
                     84: iopb_destroy(iopb_tss_t      io_tss)
                     85: {
                     86: }
                     87: 
                     88: #if 0                          /* Code removed until better solution comes on board */
                     89: /*
                     90:  * A set of ports for an IO device.
                     91:  */
                     92: struct io_port {
                     93:        device_t        device;         /* Mach device */
                     94:        queue_chain_t   dev_list;       /* link in device list */
                     95:        queue_chain_t   io_use_list;    /* List of threads that use it */
                     96:        io_reg_t        *io_port_list;  /* list of IO ports that use it */
                     97:                                        /* list ends with IO_REG_NULL */
                     98: };
                     99: typedef struct io_port *io_port_t;
                    100: 
                    101: /*
                    102:  * Lookup table for device -> io_port mapping
                    103:  * (a linked list - I don't expect too many)
                    104:  */
                    105: queue_head_t   device_to_io_port_list;
                    106: 
                    107: /*
                    108:  * Cross-reference:
                    109:  *     all threads that have IO ports mapped
                    110:  *     all IO ports that have threads mapped
                    111:  */
                    112: struct io_use {
                    113:        queue_chain_t   psq;    /* Links from port set */
                    114:        queue_chain_t   tsq;    /* links from tss */
                    115:        io_port_t       ps;     /* Port set */
                    116:        iopb_tss_t      ts;     /* Task segment */
                    117: };
                    118: typedef        struct io_use   *io_use_t;
                    119: 
                    120: /*
                    121:  * Big lock for the whole mess.
                    122:  */
                    123: decl_simple_lock_data(,iopb_lock)
                    124: 
                    125: /* Forward */
                    126: 
                    127: extern void            io_bitmap_init(
                    128:                                isa_iopb                bp);
                    129: extern void            io_bitmap_set(
                    130:                                isa_iopb                bp,
                    131:                                io_reg_t                *bit_list);
                    132: extern void            io_bitmap_clear(
                    133:                                isa_iopb                bp,
                    134:                                io_reg_t                *bit_list);
                    135: extern io_port_t       device_to_io_port_lookup(
                    136:                                device_t                device);
                    137: extern void            io_tss_init(
                    138:                                iopb_tss_t              io_tss);
                    139: 
                    140: 
                    141: /*
                    142:  * Initialize the package.
                    143:  */
                    144: void
                    145: iopb_init(void)
                    146: {
                    147:        queue_init(&device_to_io_port_list);
                    148:        simple_lock_init(&iopb_lock, ETAP_IO_IOPB);
                    149: }
                    150: 
                    151: /*
                    152:  * Initialize bitmap (set all bits to OFF == 1)
                    153:  */
                    154: void
                    155: io_bitmap_init(
                    156:        isa_iopb        bp)
                    157: {
                    158:        register unsigned char *b;
                    159:        register int    s;
                    160: 
                    161:        s = sizeof(isa_iopb);
                    162:        b = bp;
                    163: 
                    164:        do {
                    165:            *b++ = ~0;
                    166:        } while (--s >= 0);
                    167: }
                    168: 
                    169: /*
                    170:  * Set selected bits in bitmap to ON == 0
                    171:  */
                    172: void
                    173: io_bitmap_set(
                    174:        isa_iopb        bp,
                    175:        io_reg_t        *bit_list)
                    176: {
                    177:        io_reg_t        io_bit;
                    178: 
                    179:        while ((io_bit = *bit_list++) != IO_REG_NULL) {
                    180:            bp[io_bit>>3] &= ~(1 << (io_bit & 0x7));
                    181:        }
                    182: }
                    183: 
                    184: /*
                    185:  * Set selected bits in bitmap to OFF == 1
                    186:  */
                    187: void
                    188: io_bitmap_clear(
                    189:        isa_iopb        bp,
                    190:        io_reg_t        *bit_list)
                    191: {
                    192:        io_reg_t        io_bit;
                    193: 
                    194:        while ((io_bit = *bit_list++) != IO_REG_NULL) {
                    195:            bp[io_bit>>3] |= (1 << (io_bit & 0x7));
                    196:        }
                    197: }
                    198: 
                    199: /*
                    200:  * Lookup an io-port set by device
                    201:  */
                    202: io_port_t
                    203: device_to_io_port_lookup(
                    204:        device_t        device)
                    205: {
                    206:        register io_port_t io_port;
                    207: 
                    208:        queue_iterate(&device_to_io_port_list, io_port, io_port_t, dev_list) {
                    209:            if (io_port->device == device) {
                    210:                return io_port;
                    211:            }
                    212:        }
                    213:        return 0;
                    214: }
                    215: 
                    216: /*
                    217:  * [exported]
                    218:  * Create an io_port set
                    219:  */
                    220: void
                    221: io_port_create(
                    222:        device_t        device,
                    223:        io_reg_t        *io_port_list)
                    224: {
                    225:        register io_port_t io_port, old_io_port;
                    226: 
                    227:        io_port = (io_port_t) kalloc(sizeof(struct io_port));
                    228: 
                    229:        simple_lock(&iopb_lock);
                    230:        if (device_to_io_port_lookup(device) != 0) {
                    231:            simple_unlock(&iopb_lock);
                    232:            kfree((vm_offset_t) io_port, sizeof(struct io_port));
                    233:            return;
                    234:        }
                    235: 
                    236:        io_port->device = device;
                    237:        queue_init(&io_port->io_use_list);
                    238:        io_port->io_port_list = io_port_list;
                    239: 
                    240:        /*
                    241:         * Enter in lookup list.
                    242:         */
                    243:        queue_enter(&device_to_io_port_list, io_port, io_port_t, dev_list);
                    244: 
                    245:        simple_unlock(&iopb_lock);
                    246: }
                    247: 
                    248: /*
                    249:  * [exported]
                    250:  * Destroy an io port set, removing any IO mappings.
                    251:  */
                    252: void
                    253: io_port_destroy(
                    254:        device_t        device)
                    255: {
                    256:        io_port_t       io_port;
                    257:        io_use_t        iu;
                    258: 
                    259:        simple_lock(&iopb_lock);
                    260:        io_port = device_to_io_port_lookup(device);
                    261:        if (io_port == 0) {
                    262:            simple_unlock(&iopb_lock);
                    263:            return;
                    264:        }
                    265: 
                    266:        queue_iterate(&io_port->io_use_list, iu, io_use_t, psq) {
                    267:            iopb_tss_t  io_tss;
                    268:            io_tss = iu->ts;
                    269:            io_bitmap_clear(io_tss->bitmap, io_port->io_port_list);
                    270:            queue_remove(&io_tss->io_port_list, iu, io_use_t, tsq);
                    271:        }
                    272:        queue_remove(&device_to_io_port_list, io_port, io_port_t, dev_list);
                    273:        simple_unlock(&iopb_lock);
                    274: 
                    275:        while (!queue_empty(&io_port->io_use_list)) {
                    276:            iu = (io_use_t) queue_first(&io_port->io_use_list);
                    277:            queue_remove(&io_port->io_use_list, iu, io_use_t, psq);
                    278:            kfree((vm_offset_t)iu, sizeof(struct io_use));
                    279:        }
                    280: 
                    281:        kfree((vm_offset_t)io_port, sizeof(struct io_port));
                    282: }
                    283: 
                    284: /*
                    285:  * Initialize an IO TSS.
                    286:  */
                    287: void
                    288: io_tss_init(
                    289:        iopb_tss_t      io_tss)
                    290: {
                    291:        vm_offset_t     addr = (vm_offset_t) io_tss;
                    292:        vm_size_t       size = (char *)&io_tss->barrier - (char *)io_tss;
                    293: 
                    294:        bzero((char *)&io_tss->tss, sizeof(struct i386_tss));
                    295:        io_tss->tss.io_bit_map_offset
                    296:                        = (char *)&io_tss->bitmap - (char *)io_tss;
                    297:        io_tss->tss.ss0 = KERNEL_DS;
                    298:        io_bitmap_init(io_tss->bitmap);
                    299:        io_tss->barrier = ~0;
                    300:        queue_init(&io_tss->io_port_list);
                    301:        addr += LINEAR_KERNEL_ADDRESS;
                    302:        io_tss->iopb_desc[0] = ((size-1) & 0xffff)
                    303:                | ((addr & 0xffff) << 16);
                    304:        io_tss->iopb_desc[1] = ((addr & 0x00ff0000) >> 16)
                    305:                | ((ACC_TSS|ACC_PL_K|ACC_P) << 8)
                    306:                | ((size-1) & 0x000f0000)
                    307:                | (addr & 0xff000000);
                    308: }
                    309: 
                    310: /*
                    311:  * [exported]
                    312:  * Create an IOPB_TSS
                    313:  */
                    314: iopb_tss_t
                    315: iopb_create(void)
                    316: {
                    317:        register iopb_tss_t ts;
                    318: 
                    319:        ts = (iopb_tss_t) kalloc(sizeof (struct iopb_tss));
                    320:        io_tss_init(ts);
                    321:        return (ts);
                    322: }
                    323: 
                    324: /*
                    325:  * [exported]
                    326:  * Destroy an IOPB_TSS
                    327:  */
                    328: void
                    329: iopb_destroy(
                    330:        iopb_tss_t      io_tss)
                    331: {
                    332:        io_use_t        iu;
                    333:        io_port_t       io_port;
                    334: 
                    335:        simple_lock(&iopb_lock);
                    336: 
                    337:        queue_iterate(&io_tss->io_port_list, iu, io_use_t, tsq) {
                    338:            io_port = iu->ps;
                    339:            /* skip bitmap clear - entire bitmap will vanish */
                    340:            queue_remove(&io_port->io_use_list, iu, io_use_t, psq);
                    341:        }
                    342: 
                    343:        simple_unlock(&iopb_lock);
                    344: 
                    345:        while (!queue_empty(&io_tss->io_port_list)) {
                    346:            iu = (io_use_t) queue_first(&io_tss->io_port_list);
                    347:            queue_remove(&io_tss->io_port_list, iu, io_use_t, tsq);
                    348:            kfree((vm_offset_t)iu, sizeof(struct io_use));
                    349:        }
                    350: 
                    351:        kfree((vm_offset_t)io_tss, sizeof(struct iopb_tss));
                    352: }
                    353: 
                    354: /*
                    355:  * Add an IO mapping to a thread.
                    356:  */
                    357: kern_return_t
                    358: i386_io_port_add(
                    359:        thread_t        thread,
                    360:        device_t        device)
                    361: {
                    362:        pcb_t           pcb;
                    363:        iopb_tss_t      io_tss, new_io_tss;
                    364:        io_port_t       io_port;
                    365:        io_use_t        iu, old_iu;
                    366: 
                    367:        if (thread == THREAD_NULL
                    368:         || device == DEVICE_NULL)
                    369:            return KERN_INVALID_ARGUMENT;
                    370: 
                    371:        pcb = thread->top_act->mact.pcb;
                    372: 
                    373:        new_io_tss = 0;
                    374:        iu = (io_use_t) kalloc(sizeof(struct io_use));
                    375: 
                    376:     Retry:
                    377:        simple_lock(&iopb_lock);
                    378: 
                    379:        /* find the io_port_t for the device */
                    380:        io_port = device_to_io_port_lookup(device);
                    381:        if (io_port == 0) {
                    382:            /*
                    383:             * Device does not have IO ports available.
                    384:             */
                    385:            simple_unlock(&iopb_lock);
                    386:            if (new_io_tss)
                    387:                kfree((vm_offset_t)new_io_tss, sizeof(struct iopb_tss));
                    388:            kfree((vm_offset_t) iu, sizeof(struct io_use));
                    389:            return KERN_INVALID_ARGUMENT;
                    390:        }
                    391: 
                    392:        /* Have the IO port. */
                    393: 
                    394:        /* Make sure the thread has a TSS. */
                    395: 
                    396:        simple_lock(&pcb->lock);
                    397:        io_tss = pcb->ims.io_tss;
                    398:        if (io_tss == 0) {
                    399:            if (new_io_tss == 0) {
                    400:                /*
                    401:                 * Allocate an IO-tss.
                    402:                 */
                    403:                simple_unlock(&pcb->lock);
                    404:                simple_unlock(&iopb_lock);
                    405: 
                    406:                new_io_tss = (iopb_tss_t) kalloc(sizeof(struct iopb_tss));
                    407:                io_tss_init(new_io_tss);
                    408: 
                    409:                goto Retry;
                    410:            }
                    411:            io_tss = new_io_tss;
                    412:            pcb->ims.io_tss = io_tss;
                    413:            new_io_tss = 0;
                    414:        }
                    415: 
                    416:        /*
                    417:         * Have io_port and io_tss.
                    418:         * See whether device is already mapped.
                    419:         */
                    420:        queue_iterate(&io_tss->io_port_list, old_iu, io_use_t, tsq) {
                    421:            if (old_iu->ps == io_port) {
                    422:                /*
                    423:                 * Already mapped.
                    424:                 */
                    425:                simple_unlock(&pcb->lock);
                    426:                simple_unlock(&iopb_lock);
                    427: 
                    428:                kfree((vm_offset_t)iu, sizeof(struct io_use));
                    429:                if (new_io_tss)
                    430:                    kfree((vm_offset_t)new_io_tss, sizeof(struct iopb_tss));
                    431:                return KERN_SUCCESS;
                    432:            }
                    433:        }
                    434: 
                    435:        /*
                    436:         * Add mapping.
                    437:         */
                    438:        iu->ps = io_port;
                    439:        iu->ts = io_tss;
                    440:        queue_enter(&io_port->io_use_list, iu, io_use_t, psq);
                    441:        queue_enter(&io_tss->io_port_list, iu, io_use_t, tsq);
                    442:        io_bitmap_set(io_tss->bitmap, io_port->io_port_list);
                    443: 
                    444:        simple_unlock(&pcb->lock);
                    445:        simple_unlock(&iopb_lock);
                    446: 
                    447:        if (new_io_tss)
                    448:            kfree((vm_offset_t)new_io_tss, sizeof(struct iopb_tss));
                    449:        return KERN_SUCCESS;
                    450: 
                    451: }
                    452: 
                    453: /*
                    454:  * Remove an IO mapping from a thread.
                    455:  */
                    456: kern_return_t
                    457: i386_io_port_remove(
                    458:        thread_t        thread,
                    459:        device_t        device)
                    460: {
                    461:        pcb_t           pcb;
                    462:        iopb_tss_t      io_tss;
                    463:        io_port_t       io_port;
                    464:        io_use_t        iu;
                    465: 
                    466:        if (thread == THREAD_NULL
                    467:         || device == DEVICE_NULL)
                    468:            return KERN_INVALID_ARGUMENT;
                    469: 
                    470:        pcb = thread->top_act->mact.pcb;
                    471: 
                    472:        simple_lock(&iopb_lock);
                    473: 
                    474:        /* find the io_port_t for the device */
                    475: 
                    476:        io_port = device_to_io_port_lookup(device);
                    477:        if (io_port == 0) {
                    478:            /*
                    479:             * Device does not have IO ports available.
                    480:             */
                    481:            simple_unlock(&iopb_lock);
                    482:            return KERN_INVALID_ARGUMENT;
                    483:        }
                    484: 
                    485:        simple_lock(&pcb->lock);
                    486:        io_tss = pcb->ims.io_tss;
                    487:        if (io_tss == 0) {
                    488:            simple_unlock(&pcb->lock);
                    489:            simple_unlock(&iopb_lock);
                    490:            return KERN_INVALID_ARGUMENT;       /* not mapped */
                    491:        }
                    492: 
                    493:        /*
                    494:         * Find the mapping.
                    495:         */
                    496:        queue_iterate(&io_tss->io_port_list, iu, io_use_t, tsq) {
                    497:            if (iu->ps == io_port) {
                    498:                /*
                    499:                 * Found mapping.  Remove it.
                    500:                 */
                    501:                io_bitmap_clear(io_tss->bitmap, io_port->io_port_list);
                    502: 
                    503:                queue_remove(&io_port->io_use_list, iu, io_use_t, psq);
                    504:                queue_remove(&io_tss->io_port_list, iu, io_use_t, tsq);
                    505: 
                    506:                simple_unlock(&pcb->lock);
                    507:                simple_unlock(&iopb_lock);
                    508: 
                    509:                kfree((vm_offset_t)iu, sizeof(struct io_use));
                    510: 
                    511:                return KERN_SUCCESS;
                    512:            }
                    513:        }
                    514: 
                    515:        /*
                    516:         * No mapping.
                    517:         */
                    518:        return KERN_INVALID_ARGUMENT;
                    519: }
                    520: 
                    521: /*
                    522:  * Return the IO ports mapped into a thread.
                    523:  */
                    524: 
                    525: kern_return_t
                    526: i386_io_port_list(thread, list, list_count)
                    527:        thread_t        thread;
                    528:        device_t        **list;
                    529:        unsigned int    *list_count;
                    530: {
                    531:        register pcb_t  pcb;
                    532:        register iopb_tss_t io_tss;
                    533:        unsigned int    count, alloc_count;
                    534:        device_t        *devices;
                    535:        vm_size_t       size_needed, size;
                    536:        vm_offset_t     addr;
                    537:        int             i;
                    538:        boolean_t rt = FALSE; /* ### This boolean is FALSE, because there
                    539:                               * currently exists no mechanism to determine
                    540:                               * whether or not the reply port is an RT port
                    541:                               */
                    542: 
                    543:        if (thread == THREAD_NULL)
                    544:            return KERN_INVALID_ARGUMENT;
                    545: 
                    546:        pcb = thread->top_act->mact.pcb;
                    547: 
                    548:        alloc_count = 16;               /* a guess */
                    549: 
                    550:        do {
                    551:            size_needed = alloc_count * sizeof(ipc_port_t);
                    552:            if (size_needed <= size)
                    553:                break;
                    554: 
                    555:            if (size != 0)
                    556:                KFREE(addr, size, rt);
                    557: 
                    558:            assert(size_needed > 0);
                    559:            size = size_needed;
                    560: 
                    561:            addr = KALLOC(size, rt);
                    562:            if (addr == 0)
                    563:                return KERN_RESOURCE_SHORTAGE;
                    564: 
                    565:            devices = (device_t *)addr;
                    566:            count = 0;
                    567: 
                    568:            simple_lock(&iopb_lock);
                    569:            simple_lock(&pcb->lock);
                    570:            io_tss = pcb->ims.io_tss;
                    571:            if (io_tss != 0) {
                    572:                register io_use_t iu;
                    573: 
                    574:                queue_iterate(&io_tss->io_port_list, iu, io_use_t, tsq) {
                    575:                    if (++count < alloc_count) {
                    576:                        *devices = iu->ps->device;
                    577:                        device_reference(*devices);
                    578:                        devices++;
                    579:                    }
                    580:                }
                    581:            }
                    582:            simple_unlock(&pcb->lock);
                    583:            simple_unlock(&iopb_lock);
                    584:        } while (count > alloc_count);
                    585: 
                    586:        if (count == 0) {
                    587:            /*
                    588:             * No IO ports
                    589:             */
                    590:            *list = 0;
                    591:            *list_count = 0;
                    592: 
                    593:            if (size != 0)
                    594:                KFREE(addr, size, rt);
                    595:        }
                    596:        else {
                    597:            /*
                    598:             * If we allocated too much, must copy.
                    599:             */
                    600:            size_needed = count * sizeof(ipc_port_t);
                    601:            if (size_needed < size) {
                    602:                vm_offset_t     new_addr;
                    603: 
                    604:                new_addr = KALLOC(size_needed, rt);
                    605:                if (new_addr == 0) {
                    606:                    for (i = 0; i < count; i++)
                    607:                        device_deallocate(devices[i]);
                    608:                    KFREE(addr, size, rt);
                    609:                    return KERN_RESOURCE_SHORTAGE;
                    610:                }
                    611: 
                    612:                bcopy((char *)addr, (char *)new_addr, size_needed);
                    613:                KFREE(addr, size, rt);
                    614:                devices = (device_t *)new_addr;
                    615:            }
                    616: 
                    617:            for (i = 0; i < count; i++)
                    618:                ((ipc_port_t *)devices)[i] =
                    619:                        convert_device_to_port(devices[i]);
                    620:        }
                    621:        *list = devices;
                    622:        *list_count = count;
                    623: 
                    624:        return KERN_SUCCESS;
                    625: }
                    626: 
                    627: /*
                    628:  * Check whether an IO device is mapped to a particular thread.
                    629:  * Used to support the 'iopl' device automatic mapping.
                    630:  */
                    631: boolean_t
                    632: iopb_check_mapping(
                    633:        thread_t        thread,
                    634:        device_t        device)
                    635: {
                    636:        pcb_t           pcb;
                    637:        io_port_t       io_port;
                    638:        io_use_t        iu;
                    639: 
                    640:        pcb = thread->top_act->mact.pcb;
                    641: 
                    642:        simple_lock(&iopb_lock);
                    643: 
                    644:        /* Find the io port for the device */
                    645: 
                    646:        io_port = device_to_io_port_lookup(device);
                    647:        if (io_port == 0) {
                    648:            simple_unlock(&iopb_lock);
                    649:            return FALSE;
                    650:        }
                    651: 
                    652:        /* Look up the mapping in the device`s mapping list. */
                    653: 
                    654:        queue_iterate(&io_port->io_use_list, iu, io_use_t, psq) {
                    655:            if (iu->ts == pcb->ims.io_tss) {
                    656:                /*
                    657:                 * Device is mapped.
                    658:                 */
                    659:                simple_unlock(&iopb_lock);
                    660:                return TRUE;
                    661:            }
                    662:        }
                    663:        simple_unlock(&iopb_lock);
                    664:        return FALSE;
                    665: }
                    666: #endif

unix.superglobalmegacorp.com

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