Annotation of driverkit/tests/dma.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
                     25:  *
                     26:  * dma.m - kern_dev stub for IODevice testing.
                     27:  *
                     28:  * HISTORY
                     29:  * 08-Apr-91    Doug Mitchell at NeXT
                     30:  *      Created. 
                     31:  */
                     32: 
                     33: #import <objc/objc.h>
                     34: #import <driverkit/driverServer.h>
                     35: #import <driverkit/return.h>
                     36: #import <driverkit/Device_ddm.h>
                     37: #import <architecture/nrw/io.h>
                     38: #import <driverkit/generalFuncs.h>
                     39: #import <driverkit/interruptMsg.h>
                     40: #import <machkit/NXLock.h>
                     41: #import <bsd/sys/printf.h>
                     42: #import <driverkit/IODeviceParams.h>
                     43: #import <libc.h>
                     44: 
                     45: #ifndef        KERNEL
                     46: #define vm_map_t       vm_task_t
                     47: #endif KERNEL
                     48: 
                     49: /*
                     50:  * Struct for "enqueueing" dma requests.
                     51:  */
                     52: typedef struct {
                     53:        unsigned        dma_id;
                     54:        vm_offset_t     address;
                     55:        unsigned        byte_count;
                     56:        unsigned        completed:1;
                     57:        queue_chain_t   link;
                     58: } dma_frame_t;
                     59: 
                     60: /*
                     61:  * Info for one mapped dma channel.
                     62:  */
                     63: typedef struct {
                     64:        queue_head_t    frame_list;     // queue of dma frames
                     65:        id              channel_lock;
                     66:        unsigned        mapped:1,       // true if channel is mapped
                     67:                        running:1;
                     68:        IODmaDirection  dir;
                     69: } dma_chan_t;
                     70: 
                     71: /*
                     72:  * Static variables for "registering" one (and only one) device.
                     73:  * If we want to get fancy, we can make these one-per-dev_port.
                     74:  */
                     75: BOOL           dev_port_exists = NO;   // dev_port_create() called
                     76: BOOL           dev_is_mapped = NO;             // dev_reg_mapped() called
                     77: port_t                 interrupt_port = PORT_NULL;
                     78: BOOL           streamMode;
                     79: dma_chan_t     channel[CHAN_PER_DEV];
                     80: IODevicePage   *dev_page = NULL;
                     81: BOOL           int_enabled;
                     82: BOOL           int_pending;
                     83: 
                     84: static dma_frame_t *dma_frame_alloc();
                     85: static void dma_frame_free(dma_frame_t *frame);
                     86: static void set_eor(int channel);
                     87: static void set_error_int(int channel);
                     88: 
                     89: IOReturn _IOLookupByObjectNumber(
                     90:        port_t device_master,
                     91:        IODeviceNumber dev_number,
                     92:        IOSlotId *slot_id,              // returned
                     93:        IODeviceType *dev_type,
                     94:        BOOL *in_use)
                     95: {
                     96:        xpr_dma("dev_get_type\n", 1,2,3,4,5);
                     97:        return(IO_R_SUCCESS);
                     98: }
                     99: 
                    100: IOReturn _IOLookupByObjectNumberFromPort(
                    101:        port_t dev_port,
                    102:        IOSlotId *slot_id,              // returned
                    103:        IODeviceType *dev_type)         // returned
                    104: {
                    105:        xpr_dma("dev_port_to_type\n", 1,2,3,4,5);
                    106:        return(IO_R_SUCCESS);
                    107: }
                    108: 
                    109: IOReturn _IOCreateDevicePort(
                    110:        port_t device_master, 
                    111:        task_t target_task,
                    112:        IODeviceNumber dev_num,
                    113:        port_name_t *dev_port)
                    114: {
                    115:        xpr_dma("dev_port_create\n", 1,2,3,4,5);
                    116:        dev_port_exists = YES;
                    117:        return(IO_R_SUCCESS);
                    118: }
                    119: 
                    120: IOReturn _IODestroyDevicePort(
                    121:        port_t device_master,
                    122:        port_t dev_port)
                    123: {
                    124:        xpr_dma("dev_port_destroy\n", 1,2,3,4,5);
                    125:        dev_port_exists = NO;
                    126:        return(IO_R_SUCCESS);
                    127: }
                    128: 
                    129: IOReturn _IOAttachInterrupt(
                    130:        port_t dev_port, 
                    131:        port_t intr_port)
                    132: {
                    133:        xpr_dma("dev_intr_attach\n", 1,2,3,4,5);
                    134:        if(!dev_port_exists) {
                    135:                IOLog("dev_intr_attach: no dev_port\n");
                    136:                return IO_R_PRIVILEGE;
                    137:        }
                    138:        interrupt_port = intr_port;
                    139:        int_enabled = NO;
                    140:        return(IO_R_SUCCESS);
                    141: }
                    142:        
                    143: IOReturn _IODetachInterrupt(
                    144:        port_t dev_port, 
                    145:        port_t intr_port)
                    146: {
                    147:        xpr_dma("dev_intr_detach\n", 1,2,3,4,5);
                    148:        if(!dev_port_exists) {
                    149:                IOLog("dev_intr_detach: no dev_port\n");
                    150:                return IO_R_PRIVILEGE;
                    151:        }
                    152:        if(interrupt_port == PORT_NULL) {
                    153:                IOLog("dev_intr_detach: no interrupt port\n");
                    154:                return IO_R_NOT_ATTACHED;
                    155:        }
                    156:        interrupt_port = PORT_NULL;
                    157:        return(IO_R_SUCCESS);
                    158: }
                    159: IOReturn _IOAttachChannel(
                    160:        port_t dev_port, 
                    161:        int chan_num,
                    162:        BOOL stream_mode,
                    163:        int buffer_size)
                    164: {
                    165:        dma_chan_t *chan;
                    166:        
                    167:        xpr_dma("dev_chan_attach\n", 1,2,3,4,5);
                    168:        if(!dev_port_exists) {
                    169:                IOLog("dev_chan_attach: no dev_port\n");
                    170:                return IO_R_PRIVILEGE;
                    171:        }
                    172:        if(channel[chan_num].mapped) {
                    173:                IOLog("dev_chan_attach: chan already mapped\n");
                    174:                return IO_R_BUSY;
                    175:        }
                    176:        if(chan_num > CHAN_PER_DEV) {
                    177:                IOLog("dev_chan_attach: bogus channel number (%d)\n", 
                    178:                        chan_num);
                    179:                return(IO_R_INVALID_ARG);
                    180:        }
                    181:        chan = &channel[chan_num];
                    182:        chan->mapped = 1;
                    183:        int_pending = 0;
                    184:        queue_init(&chan->frame_list);
                    185:        streamMode = stream_mode;
                    186:        chan->channel_lock = [NXSpinLock new];
                    187:        return(IO_R_SUCCESS);
                    188: }
                    189: 
                    190: IOReturn _IODetachChannel(
                    191:        port_t dev_port, 
                    192:        int chan_num)
                    193: {
                    194:        dma_chan_t *chan = &channel[chan_num];
                    195:        IOReturn rtn = IO_R_SUCCESS;
                    196:        
                    197:        xpr_dma("dev_chan_detach\n", 1,2,3,4,5);
                    198:        if(!dev_port_exists) {
                    199:                IOLog("dev_chan_detach: no dev_port\n");
                    200:                return IO_R_PRIVILEGE;
                    201:        }
                    202:        [chan->channel_lock lock];
                    203:        if(!channel[chan_num].mapped) {
                    204:                IOLog("dev_chan_detach: chan not mapped\n");
                    205:                rtn = IO_R_NOT_ATTACHED;
                    206:                goto done;
                    207:        }
                    208:        channel[chan_num].mapped = 0;
                    209: done:
                    210:        [chan->channel_lock unlock];
                    211:        return rtn;
                    212: }
                    213: 
                    214: IOReturn _IOMapDevicePage(
                    215:        IODevicePort dev_port,
                    216:        task_t target_task,
                    217:        vm_offset_t *addr,      /* in/out */
                    218:        BOOL anywhere,
                    219:        IOCache cache)
                    220: {
                    221:        xpr_dma("dev_reg_map\n", 1,2,3,4,5);
                    222:        if(!dev_port_exists) {
                    223:                IOLog("dev_reg_map: no dev_port\n");
                    224:                return IO_R_PRIVILEGE;
                    225:        }
                    226:        dev_page = IOMalloc(sizeof(IODevicePage));
                    227:        bzero(dev_page, sizeof(*dev_page));
                    228:        *addr = (vm_offset_t)dev_page;
                    229:        dev_is_mapped = YES;
                    230:        return(IO_R_SUCCESS);
                    231: }
                    232: 
                    233: IOReturn _IOUnmapDevicePage(
                    234:        port_t dev_port,
                    235:        task_t target_task,
                    236:        vm_offset_t addr)
                    237: {
                    238:        xpr_dma("dev_reg_unmap\n", 1,2,3,4,5);
                    239:        if(!dev_port_exists) {
                    240:                IOLog("dev_reg_unmap: no dev_port\n");
                    241:                return IO_R_PRIVILEGE;
                    242:        }
                    243:        if(!dev_is_mapped) {
                    244:                IOLog("dev_reg_unmap: dev not mapped\n");
                    245:                return(IO_R_NOT_ATTACHED);
                    246:        }
                    247:        if(addr != (vm_offset_t)dev_page) {
                    248:                IOLog("dev_reg_unmap: bad address\n");
                    249:                return IO_R_PRIVILEGE;
                    250:        }
                    251:        IOFree(dev_page, sizeof(IODevicePage));
                    252:        dev_is_mapped = NO;
                    253:        return(IO_R_SUCCESS);
                    254: }
                    255: 
                    256: IOReturn _IOMapSlotSpace(
                    257:        port_t dev_port,
                    258:        task_t target_task,
                    259:        vm_offset_t slot_offset,
                    260:        vm_size_t length,
                    261:        vm_offset_t *addr,              // in/out
                    262:        BOOL anywhere,
                    263:        IOCache cache)
                    264: {
                    265:        xpr_dma("dev_slot_map\n", 1,2,3,4,5);
                    266:        if(!dev_port_exists) 
                    267:                return IO_R_PRIVILEGE;
                    268:        return(IO_R_SUCCESS);
                    269: }
                    270: 
                    271: IOReturn _IOUnmapSlotSpace(port_t dev_port,
                    272:        task_t target_task,
                    273:        vm_offset_t addr,
                    274:        vm_size_t len)
                    275: {
                    276:        xpr_dma("dev_slot_unmap\n", 1,2,3,4,5);
                    277:        if(!dev_port_exists) 
                    278:                return IO_R_PRIVILEGE;
                    279:        return(IO_R_SUCCESS);
                    280: }
                    281: 
                    282: IOReturn _IOSendChannelCommand(port_t dev_port,
                    283:        int chan_num,
                    284:        IOChannelCommand command)
                    285: {
                    286:        xpr_dma("chan_command cmd = 0x%x\n", command,2,3,4,5);
                    287:        if(!dev_port_exists) {
                    288:                IOLog("chan_command: no dev_port\n");
                    289:                return IO_R_PRIVILEGE;
                    290:        }
                    291:        if(command & IO_CC_ENABLE_INTERRUPTS)
                    292:                int_enabled = 1;
                    293:        else if(command & IO_CC_ENABLE_INTERRUPTS)
                    294:                int_enabled = 0;
                    295:        else {
                    296:                IOLog("chan_command: BOGUS COMMAND (0x%x)\n", command);
                    297:                return IO_R_INVALID_ARG;
                    298:        }
                    299:        return(IO_R_SUCCESS);
                    300: }
                    301: 
                    302: IOReturn _IOEnqueueDMA(port_t dev_port,
                    303:        int  chan_num,
                    304:        vm_task_t task_id,
                    305:        vm_offset_t addr,
                    306:        vm_size_t len,
                    307:        IODmaDirection rw,
                    308:        IODescriptorCommand cmd,
                    309:        u_char index,
                    310:        IOChannelEnqueueOption opts,
                    311:        unsigned dma_id,
                    312:        BOOL *running)
                    313: {
                    314:        IOReturn rtn = IO_R_SUCCESS;
                    315:        dma_chan_t *chan;
                    316:        dma_frame_t *frame;
                    317:        
                    318:        xpr_dma("chan_dma_enqueue dma_id 0x%x len %d chan %d\n", 
                    319:                dma_id, len, chan_num, 4,5);
                    320:        if(!dev_port_exists) {
                    321:                IOLog("chan_dma_enqueue: no dev_port\n");
                    322:                return IO_R_PRIVILEGE;
                    323:        }
                    324:        if(!dev_is_mapped) {
                    325:                IOLog("chan_dma_enqueue: no dev_page\n");
                    326:                return IO_R_PRIVILEGE;
                    327:        }
                    328:        chan = &channel[chan_num];
                    329:        [chan->channel_lock lock];
                    330:        if(!chan->mapped) {
                    331:                IOLog("chan_dma_enqueue: channel not mapped\n");
                    332:                rtn = IO_R_NOT_ATTACHED;
                    333:                goto done;
                    334:        }
                    335:        
                    336:        /*
                    337:         * Take care of enabling interrupts now to simpify notification...
                    338:         */
                    339:        if(opts & IO_CEO_ENABLE_INTERRUPTS)
                    340:                int_enabled = YES;
                    341:                
                    342:        /*
                    343:         * Enqueue this on the end of this channel's pending DMAs.
                    344:         */
                    345:        frame = dma_frame_alloc();
                    346:        frame->dma_id = dma_id;
                    347:        frame->address = addr;
                    348:        frame->byte_count = len;
                    349:        frame->completed = 0;
                    350:        if(!queue_empty(&chan->frame_list)) {
                    351:        
                    352:                /*
                    353:                 * Make sure we're not changing direction.
                    354:                 */
                    355:                if(chan->dir != rw) {
                    356:                        IOLog("chan_dma_enqueue: DMA DIRECTION CHANGE\n");
                    357:                        rtn = IO_R_INVALID_ARG;
                    358:                        goto done;
                    359:                }
                    360:        }
                    361:        else {
                    362:                chan->dir = rw;
                    363:        }
                    364:        queue_enter(&chan->frame_list,
                    365:                frame,
                    366:                dma_frame_t *,
                    367:                link);
                    368:                
                    369:        /*
                    370:         * Block devices:
                    371:         * Mark this frame as done. Block devices do their own interrupt
                    372:         * simulation for testing.
                    373:         *
                    374:         * Stream devices:
                    375:         * Mark this frame as done for outbound frames only.
                    376:         * If this is a IO_DMAWrite and there exists a IO_DMARead 
                    377:         * channel on this device, mark the first non-complete frame
                    378:         * on the read channel's queue as done, copy the data we just enqueued
                    379:         * to that (DMA read) frame, and send an interrupt message to the
                    380:         * driver. (Intended for ethernet debug).
                    381:         */
                    382:        if(!streamMode) {
                    383:                frame->completed = 1;
                    384:                set_eor(chan_num);
                    385:        }
                    386:        else if(rw == IO_DMAWrite) {
                    387:                
                    388:                int read_chan_num;
                    389:                dma_chan_t *read_chan = &channel[0];
                    390:                dma_frame_t *read_frame;
                    391:                BOOL found = NO;
                    392:                IOInterruptMsg int_msg;
                    393:                kern_return_t krtn;
                    394:                
                    395:                frame->completed = 1;
                    396:                set_eor(chan_num);
                    397:                for(read_chan_num=0; 
                    398:                    read_chan_num<CHAN_PER_DEV; 
                    399:                    read_chan_num++) {
                    400:                        if(read_chan->dir == IO_DMARead) 
                    401:                                break;
                    402:                        chan++;
                    403:                }
                    404:                if(read_chan_num == CHAN_PER_DEV) {
                    405:                        xpr_dma("chan_dma_enqueue: NO READ CHANNEL\n", 
                    406:                                1,2,3,4,5);
                    407:                                
                    408:                        /*
                    409:                         * for int_pending....
                    410:                         */
                    411:                        read_chan = chan;
                    412:                        goto send_intr;
                    413:                }
                    414:                
                    415:                /*
                    416:                 * OK, look for an uncompleted DMA frame on the Read channel 
                    417:                 * queue.
                    418:                 */
                    419:                read_frame = (dma_frame_t *)
                    420:                        queue_first(&read_chan->frame_list);
                    421:                while(!queue_end(&read_chan->frame_list, 
                    422:                    (queue_t)read_frame)) {
                    423:                        if(!read_frame->completed) {
                    424:                                found = YES;
                    425:                                break;
                    426:                        }
                    427:                        read_frame = (dma_frame_t *)read_frame->link.next;
                    428:                }
                    429:                if(!found) {
                    430:                        /*
                    431:                         * DMA overrun! Let's call this a "channel error"
                    432:                         * interrupt.
                    433:                         */
                    434:                        xpr_dma("chan_dma_enqueue: DMA Overrun on Read\n ",
                    435:                                1,2,3,4,5);
                    436:                        if(queue_empty(&read_chan->frame_list)) {
                    437:                                xpr_dma("   (no frames)\n", 1,2,3,4,5);
                    438:                        }
                    439:                        else {
                    440:                                xpr_dma("   (no incompl frames)\n", 1,2,3,4,5);
                    441:                        }
                    442:                        set_error_int(read_chan_num);
                    443:                        goto send_intr;
                    444:                }
                    445:                                        
                    446:                /*
                    447:                 * Found an incomplete Read frame. Copy data over to it
                    448:                 * and make it complete.
                    449:                 */
                    450:                bcopy((void *)frame->address, (void *)read_frame->address,
                    451:                        frame->byte_count);
                    452:                read_frame->completed = 1;
                    453:                read_frame->byte_count = frame->byte_count;
                    454:                set_eor(read_chan_num);
                    455:                
                    456:                /*
                    457:                 * Finally, send an interrupt message to the device if 
                    458:                 * we haven't already done so since the last "enable
                    459:                 * interrupts".
                    460:                 */
                    461: send_intr:
                    462:                if(int_enabled && !int_pending) {
                    463:                        bzero(&int_msg, sizeof(int_msg));
                    464:                        int_msg.header.msg_size = sizeof(int_msg);
                    465:                        int_msg.header.msg_id = IO_DMA_INTERRUPT_MSG;
                    466:                        int_msg.header.msg_remote_port = interrupt_port;
                    467:                        int_msg.header.msg_local_port = PORT_NULL;
                    468:                        
                    469:                        /*
                    470:                         * Timeout is to handle port queue full. If that
                    471:                         * happens, it's a bug in this weird test simulation,
                    472:                         * not the driver. That can never happen on the 
                    473:                         * NRW.
                    474:                         */
                    475:                        krtn = msg_send(&int_msg.header, SEND_TIMEOUT, 1);
                    476:                        if(krtn) {
                    477:                                IOLog("chan_dma_enqueue: msg_send returned "
                    478:                                        "%d\n", krtn);
                    479:                        }
                    480:                        int_pending = 1;
                    481:                        int_enabled = 0;
                    482:                }
                    483:        }
                    484:        *running = NO;  // right???
                    485: done:
                    486:        [chan->channel_lock unlock];
                    487:        return rtn;
                    488: }
                    489: 
                    490: IOReturn _IOEnqueueDMAInt(
                    491:        IODevicePort dev_port,
                    492:        int chan_num,
                    493:        vm_map_t task_id,
                    494:        vm_offset_t addr,
                    495:        vm_size_t len,
                    496:        IODmaDirection rw,
                    497:        IODescriptorCommand cmd,        // descriptor command - m88k only
                    498:        u_char index,
                    499:        IOChannelEnqueueOption opts,
                    500:        unsigned dma_id,                // must be non-zero
                    501:        BOOL *running)                  // returned - m88k only
                    502: {
                    503:        return _IOEnqueueDMA(dev_port,
                    504:                chan_num,
                    505:                task_id,
                    506:                addr,
                    507:                len,
                    508:                rw,
                    509:                cmd,
                    510:                index,
                    511:                opts,
                    512:                dma_id,
                    513:                running);
                    514: }
                    515: 
                    516: IOReturn _IODequeueDMA(port_t dev_port,
                    517:        int chan_num,
                    518:        IOChannelDequeueOption opts,
                    519:        vm_size_t *bcount,              // RETURNED
                    520:        IOUserStatus *userStatus,       // RETURNED, m88k only
                    521:        IODmaStatus *dmaStatus,         // RETURNED
                    522:        BOOL *eor,                      // RETURNED
                    523:        unsigned *dma_id)               // RETURNED
                    524: {
                    525:        dma_frame_t *frame = NULL;
                    526:        dma_chan_t *chan;
                    527:        IOReturn rtn = IO_R_SUCCESS;
                    528:        BOOL found = NO;
                    529:        unsigned summary_bit = 1 << chan_num;
                    530:        
                    531:        if(!dev_port_exists) 
                    532:                return IO_R_PRIVILEGE;
                    533:        chan = &channel[chan_num];
                    534:        [chan->channel_lock lock];
                    535:        if(!chan->mapped) {
                    536:                IOLog("chan_dma_dequeue: channel not mapped\n");
                    537:                rtn = IO_R_NOT_ATTACHED;
                    538:                goto done;
                    539:        }
                    540:        
                    541:        /*
                    542:         * See if we have a frame to dequeue. We can't tell if a channel
                    543:         * is running; this'll be crude.
                    544:         */
                    545:        if(!queue_empty(&chan->frame_list)) {
                    546:                frame = (dma_frame_t *)queue_first(&chan->frame_list);
                    547:                if(frame->completed || (opts & IO_CDO_ALL)) 
                    548:                        found = YES;
                    549:        }
                    550:        if(found) {
                    551:                queue_remove(&chan->frame_list,
                    552:                        frame,
                    553:                        dma_frame_t *,
                    554:                        link);
                    555:                *dma_id = frame->dma_id;
                    556:                *bcount = frame->byte_count;
                    557:                *dma_status = IO_Complete;
                    558:                *user_status = 0;
                    559:                *eor = frame->completed ? YES : NO;
                    560:                dma_frame_free(frame);
                    561:        }
                    562:        else
                    563:                *dma_id = IO_NULL_DMA_ID;
                    564:                
                    565:        /*
                    566:         * Clear this channel's interrupt bit in the summary register.
                    567:         */
                    568:        dev_page->int_dev.intr_summ.is_u.is_int &= ~summary_bit;
                    569:        int_pending = 0;
                    570:        
                    571:        /*
                    572:         * Re-enable interrupts if appropriate.
                    573:         */
                    574:        if((opts & IO_CDO_ENABLE_INTERRUPTS) ||
                    575:           ((opts & IO_CDO_ENABLE_INTERRUPTS_IF_EMPTY) && (*dma_id == IO_NULL_DMA_ID))) {
                    576:                int_enabled = 1;  
                    577:        }
                    578:        
                    579: done:
                    580:        xpr_dma("chan_dma_dequeue dma_id 0x%x bcount %d chan %d\n", 
                    581:                *dma_id, *bcount ,chan_num, 4,5);
                    582:        [chan->channel_lock unlock];
                    583:        return rtn;
                    584: }
                    585: 
                    586: /*
                    587:  * Determine deviceType and name of specified unit.
                    588:  */
                    589: IOReturn _IOLookupByObjectNumber(
                    590:        port_t deviceMaster,
                    591:        IOObjectNumber unit,
                    592:        IOString *deviceType,                   // returned
                    593:        IOString *name)                 // returned
                    594: {
                    595:        return IODoInquire(unit, 
                    596:                deviceType, 
                    597:                name);
                    598: }
                    599: 
                    600: /*
                    601:  * Get/set parameter RPCs. 
                    602:  */
                    603:  
                    604: IOReturn _IOGetParameterInIntArray(
                    605:        port_t device_master,
                    606:        IOObjectNumber unit,
                    607:        IOParameterName parameterName,
                    608:        unsigned int maxCount,                  // 0 means "as much as
                    609:                                                //    possible"
                    610:        unsigned int *parameterArray,           // data returned here
                    611:        unsigned int *returnedCount)            // size returned here
                    612: {
                    613:        return IODoGetParameterInt(unit, 
                    614:                parameterName,
                    615:                maxCount,
                    616:                parameterArray,
                    617:                returnedCount);
                    618: }
                    619: 
                    620: IOReturn _IOGetParameterInCharArray(
                    621:        port_t device_master,
                    622:        IOObjectNumber unit,
                    623:        IOParameterName parameterName,
                    624:        unsigned int maxCount,                  // 0 means "as much as
                    625:                                                //    possible"
                    626:        unsigned char *parameterArray,          // data returned here
                    627:        unsigned int *returnedCount)            // size returned here
                    628: {
                    629:        return IODoGetParameterChar(unit, 
                    630:                parameterName,
                    631:                maxCount,
                    632:                parameterArray,
                    633:                returnedCount);
                    634: }
                    635: 
                    636: IOReturn _IOSetParameterFromIntArray(
                    637:        port_t device_master,
                    638:        IOObjectNumber unit,
                    639:        IOParameterName parameterName,
                    640:        unsigned int count,                     // size of parameterArray
                    641:        unsigned int *parameterArray)
                    642: {
                    643:        return IODoSetParameterInt(unit, 
                    644:                parameterName,
                    645:                count,
                    646:                parameterArray);
                    647: }
                    648: 
                    649: IOReturn _IOSetParameterFromCharArray(
                    650:        port_t device_master,
                    651:        IOObjectNumber unit,
                    652:        IOParameterName parameterName,
                    653:        unsigned int count,                     // size of parameterArray
                    654:        unsigned char *parameterArray)
                    655: {
                    656:        return IODoSetParameterChar(unit, 
                    657:                parameterName,
                    658:                count,
                    659:                parameterArray);
                    660: }
                    661: 
                    662: 
                    663: static dma_frame_t *dma_frame_alloc()
                    664: {
                    665:        return(IOMalloc(sizeof(dma_frame_t)));
                    666: }
                    667: 
                    668: static void dma_frame_free(dma_frame_t *frame)
                    669: {
                    670:        IOFree(frame, sizeof(dma_frame_t));
                    671: }
                    672: 
                    673: /*
                    674:  * Set channel's EOR and descriptor interrupt bits in channel interrupt cause.
                    675:  * Also set the channel interrupt bit in the device interrupt summary 
                    676:  * register.
                    677:  */
                    678: static void set_eor(int channel)
                    679: {
                    680:        chan_t *io_chan = &dev_page->chan_regs[channel];
                    681:        unsigned summary_bit = 1 << channel;
                    682:        
                    683:        io_chan->chan_intr_cause.ci_u.ci_int |= (CI_DESC | CI_EIO);
                    684:        dev_page->int_dev.intr_summ.is_u.is_int |= summary_bit;
                    685: }
                    686: 
                    687: /*
                    688:  * Set channel's error interrupt.
                    689:  */
                    690: static void set_error_int(int channel)
                    691: {
                    692:        chan_t *io_chan = &dev_page->chan_regs[channel];
                    693:        unsigned summary_bit = 1 << channel;
                    694:        
                    695:        io_chan->chan_intr_cause.ci_u.ci_int |= CI_ERROR;
                    696:        dev_page->int_dev.intr_summ.is_u.is_int |= summary_bit;
                    697: }

unix.superglobalmegacorp.com

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