Annotation of kernel/machdep/i386/dma.c, revision 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: 
        !            25: /*
        !            26:  * Copyright (c) 1992 NeXT Computer, Inc.
        !            27:  *
        !            28:  * dma.c -- DMA Routines.
        !            29:  *
        !            30:  * HISTORY
        !            31:  *
        !            32:  * 08 Jan 1993  David Somayajulu at NeXT
        !            33:  *     added functions is_dma_done, get_dma_addr, get_dma_count
        !            34:  * 
        !            35:  * 13 July 1992 ? at NeXT
        !            36:  *     Created.
        !            37:  */
        !            38: 
        !            39: #import <mach/mach_types.h>
        !            40: 
        !            41: #import <machdep/i386/dma.h>
        !            42: #import <machdep/i386/dma_internal.h>
        !            43: #import <machdep/i386/dma_inline.h>
        !            44: #import <machdep/i386/dma_exported.h>
        !            45: 
        !            46: struct _dma_chan_port _dma_chan_port[DMA_NCHAN] = {
        !            47:     {
        !            48:        DMA_CHAN0_ADDR_PORT,
        !            49:        DMA_CHAN0_PAGE_PORT, DMA_CHAN0_HIPAGE_PORT,
        !            50:        DMA_CHAN0_COUNT_PORT, DMA_CHAN0_HICOUNT_PORT },
        !            51:     {
        !            52:        DMA_CHAN1_ADDR_PORT,
        !            53:        DMA_CHAN1_PAGE_PORT, DMA_CHAN1_HIPAGE_PORT,
        !            54:        DMA_CHAN1_COUNT_PORT, DMA_CHAN1_HICOUNT_PORT },
        !            55:     {
        !            56:        DMA_CHAN2_ADDR_PORT,
        !            57:        DMA_CHAN2_PAGE_PORT, DMA_CHAN2_HIPAGE_PORT,
        !            58:        DMA_CHAN2_COUNT_PORT, DMA_CHAN2_HICOUNT_PORT },
        !            59:     {
        !            60:        DMA_CHAN3_ADDR_PORT,
        !            61:        DMA_CHAN3_PAGE_PORT, DMA_CHAN3_HIPAGE_PORT,
        !            62:        DMA_CHAN3_COUNT_PORT, DMA_CHAN3_HICOUNT_PORT },
        !            63:     {
        !            64:        /* CASCADE channel */
        !            65:     },
        !            66:     {
        !            67:        DMA2_CHAN1_ADDR_PORT,
        !            68:        DMA2_CHAN1_PAGE_PORT, DMA2_CHAN1_HIPAGE_PORT,
        !            69:        DMA2_CHAN1_COUNT_PORT, DMA2_CHAN1_HICOUNT_PORT },
        !            70:     {
        !            71:        DMA2_CHAN2_ADDR_PORT,
        !            72:        DMA2_CHAN2_PAGE_PORT, DMA2_CHAN2_HIPAGE_PORT,
        !            73:        DMA2_CHAN2_COUNT_PORT, DMA2_CHAN2_HICOUNT_PORT },
        !            74:     {
        !            75:        DMA2_CHAN3_ADDR_PORT,
        !            76:        DMA2_CHAN3_PAGE_PORT, DMA2_CHAN3_HIPAGE_PORT,
        !            77:        DMA2_CHAN3_COUNT_PORT, DMA2_CHAN3_HICOUNT_PORT },
        !            78: };
        !            79: 
        !            80: struct _dma_chip_port _dma_chip_port[] = {
        !            81:     {
        !            82:        DMA_CMD_STATUS_PORT, DMA_REQ_PORT, DMA_MASK_PORT, DMA_MODE_PORT,
        !            83:        DMA_CLEAR_FF_PORT, DMA_MASTER_RESET_PORT, DMA_EXTEND_MODE_PORT },
        !            84:     {
        !            85:        DMA2_CMD_STATUS_PORT, DMA2_REQ_PORT, DMA2_MASK_PORT, DMA2_MODE_PORT,
        !            86:        DMA2_CLEAR_FF_PORT, DMA2_MASTER_RESET_PORT, DMA2_EXTEND_MODE_PORT }
        !            87: };
        !            88: 
        !            89: unsigned char          dma_assigned_bits;
        !            90: struct dma_write_regs  dma_write_regs[DMA_NCHAN];
        !            91: dma_cmd_reg_t          dma_cmd_regs[DMA_NCHIPS];
        !            92: 
        !            93: unsigned prev_tcstatus0, /* previous transfer count status of 
        !            94:                        DMA Chip Port 0,for channels 0-3*/
        !            95:         prev_tcstatus1; /* previous transfer count status of 
        !            96:                        DMA Chip Port 1,for channels 5-7*/      
        !            97:                         /* The TC bits in the status register get cleared
        !            98:                        when it is read. Hence we need to keep track of it
        !            99:                                seperately */
        !           100:                
        !           101: static void dma_init_extend_mode(int chan);
        !           102:                                        
        !           103: #define PRIORITY_ROTATING      1
        !           104: 
        !           105: void
        !           106: dma_initialize(
        !           107:     void
        !           108: )
        !           109: {
        !           110:        dma_cmd_reg_t   cmd = { 0 };
        !           111:        int             chan;
        !           112: 
        !           113:        dma_master_reset();
        !           114:        prev_tcstatus0 = 0;
        !           115:        prev_tcstatus1 = 0;
        !           116:     
        !           117: #if    PRIORITY_ROTATING
        !           118:        cmd.priority = DMA_PRIO_ROTATING;
        !           119: #else  PRIORITY_ROTATING
        !           120:        cmd.priority = DMA_PRIO_FIXED;
        !           121: #endif PRIORITY_ROTATING
        !           122:        dma_set_cmd(0, cmd);
        !           123:        dma_set_cmd(1, cmd);
        !           124:        dma_cmd_regs[0] = cmd;
        !           125:        dma_cmd_regs[1] = cmd;
        !           126:     
        !           127:        for (chan = 0; chan < DMA_NCHAN; chan++) {
        !           128:                (void) dma_assign_chan(chan);
        !           129:        
        !           130:                if (chan != DMA_CASCADE_CHAN) {
        !           131:                        dma_deassign_chan(chan);        // does an unmask
        !           132:                        dma_init_extend_mode(chan);
        !           133:                }
        !           134:                else {
        !           135:                        dma_chan_xfer_mode(chan, DMA_MODE_CASCADE);
        !           136:                        dma_unmask_chan(chan);          // unmask and leave 
        !           137:                                                        //    assigned
        !           138:                }
        !           139:        }
        !           140:        dma_buf_initialize();
        !           141: }
        !           142: 
        !           143: /*
        !           144:  * Initialize extended mode register to defaults. 
        !           145:  */
        !           146: static void
        !           147: dma_init_extend_mode(
        !           148:     int                chan
        !           149: )
        !           150: {
        !           151:        dma_write_regs[chan].extend_mode.dma_timing = 
        !           152:                DMA_TIMING_COMPAT;
        !           153:        dma_write_regs[chan].extend_mode.eop_io = 
        !           154:                DMA_EOP_OUT;
        !           155:        dma_write_regs[chan].extend_mode.stop_enable = 
        !           156:                DMA_STOP_DISABLE;
        !           157:        if (!eisa_present()) {
        !           158:            /* on ISA, use this to indicate transfer mode,
        !           159:             * but don't actually try to set the mode in hardware
        !           160:             */
        !           161:            if (chan < 4)
        !           162:                dma_write_regs[chan].extend_mode.xfer_width = 
        !           163:                        DMA_XFR_8_BIT;
        !           164:            else
        !           165:                dma_write_regs[chan].extend_mode.xfer_width = 
        !           166:                        DMA_XFR_16_BIT_WORD;
        !           167:        } else {
        !           168:            dma_write_regs[chan].extend_mode.xfer_width = 
        !           169:                    DMA_XFR_8_BIT;
        !           170:            dma_set_chan_extend_mode(chan, dma_write_regs[chan].extend_mode);
        !           171:        }
        !           172: }
        !           173: boolean_t
        !           174: dma_assign_chan(
        !           175:     int                chan
        !           176: )
        !           177: {
        !           178:     if (DMA_CHAN_IS_ASSIGNED(chan))
        !           179:        return (FALSE);
        !           180: 
        !           181:     dma_assigned_bits |= (1 << chan);
        !           182: 
        !           183:     return (TRUE);
        !           184: }
        !           185: 
        !           186: void
        !           187: dma_deassign_chan(
        !           188:     int                chan
        !           189: )
        !           190: {
        !           191:     dma_mask_chan(chan);
        !           192: 
        !           193:     dma_assigned_bits &= ~(1 << chan);
        !           194: }
        !           195: 
        !           196: void
        !           197: dma_mask_chan(
        !           198:     int                chan
        !           199: )
        !           200: {
        !           201:     dma_mask_reg_t     mask = { 0 };
        !           202: 
        !           203:     if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           204:        return;
        !           205: 
        !           206:     mask.mask = DMA_MASK_SET;
        !           207:     mask.chan_sel = chan;
        !           208:   
        !           209:     dma_set_chan_mask(chan, mask);
        !           210: }
        !           211: 
        !           212: void
        !           213: dma_unmask_chan(
        !           214:     int                chan
        !           215: )
        !           216: {
        !           217:     dma_mask_reg_t     mask = { 0 };
        !           218: 
        !           219:     if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           220:        return;
        !           221: 
        !           222:     mask.mask = DMA_MASK_CLEAR;
        !           223:     mask.chan_sel = chan;
        !           224: 
        !           225:     dma_set_chan_mask(chan, mask);
        !           226: }
        !           227: 
        !           228: void
        !           229: dma_chan_xfer_mode(
        !           230:     int                chan,
        !           231:     int                xfer_mode
        !           232: )
        !           233: {
        !           234:     dma_mode_reg_t     mode;
        !           235: 
        !           236:     if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           237:        return;
        !           238: 
        !           239:     dma_write_regs[chan].mode.xfer_mode = xfer_mode;
        !           240: 
        !           241:     mode = dma_write_regs[chan].mode;
        !           242:     mode.chan_sel = chan;
        !           243: 
        !           244:     dma_set_chan_mode(chan, mode);
        !           245: }
        !           246: 
        !           247: void   
        !           248: dma_chan_autoinit(
        !           249:        int             chan,
        !           250:        boolean_t       autoinit)
        !           251: {
        !           252:        dma_mode_reg_t  mode;
        !           253: 
        !           254:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           255:            return;
        !           256:     
        !           257:        dma_write_regs[chan].mode.autoinit = autoinit;
        !           258:        mode = dma_write_regs[chan].mode;
        !           259:        mode.chan_sel = chan;
        !           260:        dma_set_chan_mode(chan, mode);
        !           261: }
        !           262: 
        !           263: void   
        !           264: dma_chan_adrs_dir(
        !           265:        int             chan,
        !           266:        boolean_t       adrs_dir)
        !           267: {
        !           268:        dma_mode_reg_t  mode;
        !           269: 
        !           270:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           271:            return;
        !           272:     
        !           273:        dma_write_regs[chan].mode.adrs_dir = adrs_dir ? 1 : 0;
        !           274:        mode = dma_write_regs[chan].mode;
        !           275:        mode.chan_sel = chan;
        !           276:        dma_set_chan_mode(chan, mode);
        !           277: }      
        !           278: 
        !           279: void
        !           280: dma_chan_xfer_dir(
        !           281:     int                chan,
        !           282:     int                xfer_dir
        !           283: )
        !           284: {
        !           285:     dma_mode_reg_t     mode;
        !           286:     
        !           287:     if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           288:        return;
        !           289:        
        !           290:     dma_write_regs[chan].mode.xfer_dir = xfer_dir;
        !           291:     
        !           292:     mode = dma_write_regs[chan].mode;
        !           293:     mode.chan_sel = chan;
        !           294:     
        !           295:     dma_set_chan_mode(chan, mode);
        !           296: }
        !           297: 
        !           298: boolean_t
        !           299: dma_xfer_chan(
        !           300:     int                        chan,
        !           301:     dma_xfer_t         *xfer
        !           302: )
        !           303: {
        !           304:        vm_offset_t             phys;
        !           305:        extern boolean_t        isEISA;
        !           306: 
        !           307: //     REMOVE THIS
        !           308:        caddr_t dma_addr;
        !           309:        unsigned dma_count;
        !           310: 
        !           311:     
        !           312:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           313:                return (FALSE);
        !           314:            
        !           315:        if (!eisa_present())
        !           316:                xfer->lower16 = xfer->bound64 = TRUE;
        !           317:            
        !           318:        if (!dma_xfer(xfer, &phys))
        !           319:                return (FALSE);
        !           320:        
        !           321:        xfer->chan = chan; xfer->use_chan = TRUE;
        !           322:     
        !           323:        (void) dma_mask_chan(chan);
        !           324:        
        !           325:        if (xfer->read)
        !           326:            dma_chan_xfer_dir(chan, DMA_XFER_WRITE);/* dma write to memory */
        !           327:        else
        !           328:            dma_chan_xfer_dir(chan, DMA_XFER_READ);/* dma read from  memory */
        !           329:            
        !           330:        dma_set_chan_addr(chan, phys);
        !           331: 
        !           332: #if    DMA_DEBUG
        !           333:        dma_addr =      get_dma_addr(2);
        !           334:        dma_count =     get_dma_count(2);
        !           335: #endif    
        !           336:        dma_set_chan_count(chan, xfer->len);
        !           337: 
        !           338: #if    DMA_DEBUG
        !           339:        dma_count =     get_dma_count(2);
        !           340: #endif    
        !           341:        /*
        !           342:         * Clear the shadow "channel done" bit.
        !           343:         */
        !           344:        if(chan <= 3) {
        !           345:                prev_tcstatus0 &= ~(1 << chan);
        !           346:        }
        !           347:        else {
        !           348:                prev_tcstatus1 &= ~(1 << (chan - 4));
        !           349:        }
        !           350:        (void) dma_unmask_chan(chan);
        !           351: 
        !           352: #if DMA_DEBUG
        !           353:        dma_count =     get_dma_count(2);
        !           354: #endif    
        !           355:    
        !           356:     return (TRUE);
        !           357: }
        !           358: 
        !           359: boolean_t
        !           360: dma_xfer(
        !           361:     dma_xfer_t         *xfer,
        !           362:     vm_offset_t                *rphys
        !           363: )
        !           364: {
        !           365:     dma_buf_t          *buf = &xfer->buf;
        !           366: 
        !           367:     /* Allocate DMA-able memory if we need to,
        !           368:      * and if a buffer has not already been allocated for this xfer.
        !           369:      */
        !           370:     if (xfer->lower16 && ((xfer->phys )>= (16*1024*1024))
        !           371:                                            && !xfer->buffered) {
        !           372:        vm_offset_t     phys;
        !           373: 
        !           374:        if (!dma_buf_alloc(buf, xfer->len))
        !           375:            return (FALSE);
        !           376:            
        !           377:        xfer->buffered = TRUE;
        !           378: 
        !           379:        phys = (vm_offset_t)buf->_ptr;
        !           380:            
        !           381:        if (!xfer->read)
        !           382:            bcopy(
        !           383:                pmap_phys_to_kern(xfer->phys),
        !           384:                pmap_phys_to_kern(phys),
        !           385:                xfer->len);
        !           386:            
        !           387:        *rphys = phys;
        !           388:     }
        !           389:     else
        !           390:        *rphys = xfer->phys;
        !           391:        
        !           392:     xfer->active = TRUE;
        !           393:        
        !           394:     return (TRUE);
        !           395: }
        !           396: 
        !           397: void
        !           398: dma_xfer_done(
        !           399:     dma_xfer_t         *xfer
        !           400: )
        !           401: {
        !           402:     if (xfer->active) {
        !           403:        if (xfer->buffered) {
        !           404:            dma_buf_t           *buf = &xfer->buf;
        !           405:            vm_offset_t         phys;
        !           406: 
        !           407:            phys = (vm_offset_t)buf->_ptr;
        !           408:     
        !           409:            if (xfer->read)
        !           410:                bcopy(
        !           411:                    pmap_phys_to_kern(phys),
        !           412:                    pmap_phys_to_kern(xfer->phys),
        !           413:                    xfer->len);
        !           414: 
        !           415:            dma_buf_free(buf);
        !           416:        }
        !           417:        
        !           418:        xfer->active = xfer->buffered = FALSE;
        !           419:     }
        !           420: }
        !           421: 
        !           422: void
        !           423: dma_xfer_abort(
        !           424:     dma_xfer_t         *xfer
        !           425: )
        !           426: {
        !           427:     if (xfer->active) {
        !           428:        if (xfer->buffered)
        !           429:            dma_buf_free(&xfer->buf);
        !           430:        
        !           431:        xfer->active = xfer->buffered = FALSE;
        !           432:     }
        !           433: }
        !           434: 
        !           435: /*
        !           436:  * Extended Mode register manipulation 
        !           437:  */
        !           438: void   
        !           439: dma_xfer_width(
        !           440:        int     chan,
        !           441:        int     xfer_width
        !           442: )
        !           443: {
        !           444:        dma_extend_mode_reg_t   extend_mode;
        !           445: 
        !           446:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           447:            return;
        !           448:     
        !           449:        dma_write_regs[chan].extend_mode.xfer_width = xfer_width;
        !           450:        extend_mode = dma_write_regs[chan].extend_mode;
        !           451:        extend_mode.chan_sel = chan;
        !           452:        dma_set_chan_extend_mode(chan, extend_mode);
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Get the current transfer width for a channel.
        !           457:  */
        !           458: int
        !           459: get_dma_xfer_width(
        !           460:        int     chan
        !           461: )
        !           462: {
        !           463:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           464:            return -1;
        !           465:        return dma_write_regs[chan].extend_mode.xfer_width;
        !           466: }
        !           467: 
        !           468: 
        !           469: void
        !           470: dma_timing(
        !           471:        int     chan,
        !           472:        int     dma_timing
        !           473: )
        !           474: {
        !           475:        dma_extend_mode_reg_t   extend_mode;
        !           476: 
        !           477:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           478:            return;
        !           479:     
        !           480:        dma_write_regs[chan].extend_mode.dma_timing = dma_timing;
        !           481:        extend_mode = dma_write_regs[chan].extend_mode;
        !           482:        extend_mode.chan_sel = chan;
        !           483:        dma_set_chan_extend_mode(chan, extend_mode);
        !           484: }
        !           485: 
        !           486: void
        !           487: dma_eop_in(
        !           488:        int     chan,
        !           489:        int     eop_io
        !           490: )
        !           491: {
        !           492:        dma_extend_mode_reg_t   extend_mode;
        !           493: 
        !           494:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           495:            return;
        !           496:     
        !           497:        dma_write_regs[chan].extend_mode.eop_io = eop_io;
        !           498:        extend_mode = dma_write_regs[chan].extend_mode;
        !           499:        extend_mode.chan_sel = chan;
        !           500:        dma_set_chan_extend_mode(chan, extend_mode);
        !           501: }
        !           502: 
        !           503: void
        !           504: dma_stop_enable(
        !           505:        int     chan,
        !           506:        int     stop_enable
        !           507: )
        !           508: {
        !           509:        dma_extend_mode_reg_t   extend_mode;
        !           510: 
        !           511:        if (!DMA_CHAN_IS_ASSIGNED(chan))
        !           512:            return;
        !           513:     
        !           514:        dma_write_regs[chan].extend_mode.stop_enable = stop_enable;
        !           515:        extend_mode = dma_write_regs[chan].extend_mode;
        !           516:        extend_mode.chan_sel = chan;
        !           517:        dma_set_chan_extend_mode(chan, extend_mode);
        !           518: }
        !           519: 
        !           520: /* returns the status register contents for the corresponding channel */
        !           521: boolean_t is_dma_done(int chan)
        !           522: {
        !           523:        unsigned char status;
        !           524:        
        !           525:        DMA_DELAY;
        !           526:        status = (unsigned char)(inb(DMA_CHIP_PORT(chan, cmd_status)));
        !           527: 
        !           528:        /*
        !           529:         * Save the volatile bits we just read and OR in shadow
        !           530:         * bits for current test.
        !           531:         */
        !           532:        if (chan <= 3) {
        !           533:                prev_tcstatus0 |= (status & 0xf);
        !           534:                return (prev_tcstatus0 & (1 << chan)) ? TRUE : FALSE;
        !           535:                
        !           536:        }else {
        !           537:                chan = chan - 4;
        !           538:                prev_tcstatus1 |= (status & 0xf);
        !           539:                return (prev_tcstatus1 & (1 << chan)) ? TRUE : FALSE;
        !           540:        }
        !           541: }
        !           542: 
        !           543: vm_offset_t get_dma_addr(int chan)
        !           544: {
        !           545:        union {
        !           546:                vm_offset_t addr;
        !           547:                struct {
        !           548:                        vm_offset_t     addr_byte0 :8,
        !           549:                                        addr_byte1 :8,
        !           550:                                        page       :8,
        !           551:                                        hipage     :8;
        !           552:                } data;
        !           553:                struct {
        !           554:                        vm_offset_t     addr       :16,
        !           555:                                        page       :8,
        !           556:                                        hipage     :8;
        !           557:                } isa_data;
        !           558:        } tconv;
        !           559:        tconv.addr = 0;
        !           560:        dma_chip_disable(chan);
        !           561:        
        !           562:        DMA_DELAY;
        !           563:        outb(DMA_CHIP_PORT(chan, clear_ff), 0xff);
        !           564:        DMA_DELAY;
        !           565:        tconv.data.addr_byte0 = inb(DMA_CHAN_PORT(chan, addr));
        !           566:        dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           567:                        DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte0));
        !           568:        DMA_DELAY;
        !           569:        tconv.data.addr_byte1 = inb(DMA_CHAN_PORT(chan, addr));
        !           570:        dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           571:                        DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte1));
        !           572:        DMA_DELAY;
        !           573:        tconv.data.page = inb(DMA_CHAN_PORT(chan, page));
        !           574:        dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           575:                        DMA_CHAN_PORT(chan, page), tconv.data.page));
        !           576:        if(eisa_present()){
        !           577:                DMA_DELAY;
        !           578:                tconv.data.hipage = inb(DMA_CHAN_PORT(chan, hipage));
        !           579:                dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           580:                        DMA_CHAN_PORT(chan, hipage), tconv.data.hipage));
        !           581:        }
        !           582:        dma_chip_enable(chan);
        !           583:        if (dma_write_regs[chan].extend_mode.xfer_width ==
        !           584:                DMA_XFR_16_BIT_WORD) {
        !           585:            tconv.isa_data.addr <<= 1;
        !           586:        }
        !           587:        return(tconv.addr);
        !           588: }
        !           589: 
        !           590: vm_size_t get_dma_count(int chan)
        !           591: {
        !           592:        union {
        !           593:                vm_size_t count;
        !           594:                struct {
        !           595:                        vm_size_t       count_byte0 :8,
        !           596:                                        count_byte1 :8,
        !           597:                                        hicount     :8,
        !           598:                                                    :8;
        !           599:                } data;
        !           600:        } tconv;
        !           601:        
        !           602:        dma_chip_disable(chan);
        !           603:        tconv.count = 0x00;
        !           604:        DMA_DELAY;
        !           605:        outb(DMA_CHIP_PORT(chan, clear_ff), 0xff);
        !           606:        
        !           607:        DMA_DELAY;
        !           608:        tconv.data.count_byte0 = inb(DMA_CHAN_PORT(chan, count));
        !           609:        dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           610:                        DMA_CHAN_PORT(chan, count), tconv.data.count_byte0));
        !           611: 
        !           612:        DMA_DELAY;
        !           613:        tconv.data.count_byte1 = inb(DMA_CHAN_PORT(chan, count));
        !           614:        dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           615:                        DMA_CHAN_PORT(chan,  count), tconv.data.count_byte1));
        !           616:        if (eisa_present()){
        !           617:                tconv.data.hicount = inb(DMA_CHAN_PORT(chan, hicount));
        !           618:                dprintf(("reading from port =0x%x value = 0x%x\n", 
        !           619:                        DMA_CHAN_PORT(chan, hicount), tconv.data.hicount));
        !           620:                dma_chip_enable(chan);
        !           621:        
        !           622:                if (tconv.count == 0xFFFFFF) {
        !           623:                        tconv.count = 0;
        !           624:                }
        !           625:                else {
        !           626:                        ++tconv.count;
        !           627:                }
        !           628:        } else {
        !           629:                dma_chip_enable(chan);
        !           630:                if (tconv.count == 0xFFFF) {
        !           631:                        tconv.count = 0;
        !           632:                }
        !           633:                else {
        !           634:                        ++tconv.count;
        !           635:                }
        !           636:        }
        !           637:        if (dma_write_regs[chan].extend_mode.xfer_width ==
        !           638:                DMA_XFR_16_BIT_WORD) {
        !           639:            tconv.count <<= 1;
        !           640:        }
        !           641: 
        !           642: }

unix.superglobalmegacorp.com

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