Annotation of XNU/osfmk/i386/iopb.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_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.