Annotation of Net2/arch/tahoe/vba/vba.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1987, 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     @(#)vba.c       7.6 (Berkeley) 12/16/90
        !            34:  */
        !            35: 
        !            36: /*
        !            37:  * Tahoe VERSAbus adapator support routines.
        !            38:  */
        !            39: 
        !            40: #include "sys/param.h"
        !            41: #include "sys/buf.h"
        !            42: #include "sys/cmap.h"
        !            43: #include "sys/conf.h"
        !            44: #include "dk.h"
        !            45: #include "sys/map.h"
        !            46: #include "sys/systm.h"
        !            47: #include "sys/user.h"
        !            48: #include "sys/vmparam.h"
        !            49: #include "sys/vmmac.h"
        !            50: #include "sys/proc.h"
        !            51: #include "sys/syslog.h"
        !            52: #include "sys/malloc.h"
        !            53: 
        !            54: #include "../include/mtpr.h"
        !            55: #include "../include/pte.h"
        !            56: 
        !            57: #include "../vba/vbavar.h"
        !            58: 
        !            59: /*
        !            60:  * Allocate private page map and intermediate buffer
        !            61:  * for a VERSAbus device, large enough for maximum transfer size.
        !            62:  * Intermediate buffer 
        !            63:  * Make intermediate buffer uncacheable.
        !            64:  */
        !            65: vbainit(vb, xsize, flags)
        !            66:        register struct vb_buf *vb;
        !            67:        int xsize, flags;
        !            68: {
        !            69:        register struct pte *pte;
        !            70:        register n;
        !            71: 
        !            72:        vb->vb_flags = flags;
        !            73:        if (vbmapalloc((int)btoc(xsize) + 1, &vb->vb_map, &vb->vb_utl) == 0) {
        !            74:                printf("vbmap exhausted\n");
        !            75:                return (0);
        !            76:        }
        !            77:        n = roundup(xsize, NBPG);
        !            78:        vb->vb_bufsize = n;
        !            79:        if (vb->vb_rawbuf == 0)
        !            80:                vb->vb_rawbuf = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
        !            81:        if (vb->vb_rawbuf == 0) {
        !            82:                printf("no memory for device buffer\n");
        !            83:                return (0);
        !            84:        }
        !            85:        if ((int)vb->vb_rawbuf & PGOFSET)
        !            86:                panic("vbinit pgoff");
        !            87:        vb->vb_physbuf = (u_long)kvtophys(vb->vb_rawbuf);
        !            88:        if (flags & VB_20BIT)
        !            89:                vb->vb_maxphys = btoc(VB_MAXADDR20);
        !            90:        else if (flags & VB_24BIT)
        !            91:                vb->vb_maxphys = btoc(VB_MAXADDR24);
        !            92:        else
        !            93:                vb->vb_maxphys = btoc(VB_MAXADDR32);
        !            94:        if (btoc(vb->vb_physbuf + n) > vb->vb_maxphys)
        !            95:                panic("vbinit physbuf");
        !            96:        
        !            97:        /*
        !            98:         * Make raw buffer pages uncacheable.
        !            99:         */
        !           100:        pte = kvtopte(vb->vb_rawbuf);
        !           101:        for (n = btoc(n); n--; pte++)
        !           102:                pte->pg_nc = 1;
        !           103:        mtpr(TBIA, 0);
        !           104:        return (1);
        !           105: }
        !           106: 
        !           107: /*
        !           108:  * Due to unknown hardware or software errors, some sites have problems
        !           109:  * with strange crashes or corruption of text images when DMA is attempted
        !           110:  * to kernel addresses spanning a page boundary, or to user addresses
        !           111:  * (even if the buffer is physically contiguous).  To avoid this behavior,
        !           112:  * the following toggles inhibit such transfers when set.
        !           113:  *     vba_copyk: copy transfers to kernel address that span a page boundary
        !           114:  *     vba_copyu: copy transfers to user addresses
        !           115:  */
        !           116: #ifndef VBA_TRICKY
        !           117: int vba_copyk = 1;
        !           118: int vba_copyu = 1;
        !           119: #else
        !           120: int vba_copyk = 0;
        !           121: int vba_copyu = 0;
        !           122: #endif
        !           123: 
        !           124: /*
        !           125:  * Check a transfer to see whether it can be done directly
        !           126:  * to the destination buffer, or whether it must be copied.
        !           127:  * On Tahoe, the lack of a bus I/O map forces data to be copied
        !           128:  * to a physically-contiguous buffer whenever one of the following is true:
        !           129:  *     1) The data length is not a multiple of sector size.
        !           130:  *        (The swapping code does this, unfortunately.)
        !           131:  *     2) The buffer is not physically contiguous and the controller
        !           132:  *        does not support scatter-gather operations.
        !           133:  *     3) The physical address for I/O is higher than addressible
        !           134:  *        by the device.
        !           135:  * This routine is called by the start routine.
        !           136:  * If copying is necessary, the intermediate buffer is mapped;
        !           137:  * if the operation is a write, the data is copied into the buffer.
        !           138:  * It returns the physical address of the first byte for DMA, to
        !           139:  * be presented to the controller.
        !           140:  */
        !           141: u_long
        !           142: vbasetup(bp, vb, sectsize)
        !           143:        register struct buf *bp;
        !           144:        register struct vb_buf *vb;
        !           145:        int sectsize;
        !           146: {
        !           147:        register struct pte *spte, *dpte;
        !           148:        register int p, i;
        !           149:        int npf, o, v;
        !           150: 
        !           151:        o = (int)bp->b_un.b_addr & PGOFSET;
        !           152:        npf = btoc(bp->b_bcount + o);
        !           153:        vb->vb_iskernel = (((int)bp->b_un.b_addr & KERNBASE) == KERNBASE);
        !           154:        if (vb->vb_iskernel) {
        !           155:                spte = kvtopte(bp->b_un.b_addr);
        !           156: if (vba_copyk && (o != 0 || npf > 1)) goto copy;
        !           157:        } else {
        !           158:                spte = vtopte((bp->b_flags&B_DIRTY) ? &proc[2] : bp->b_proc,
        !           159:                    btop(bp->b_un.b_addr));
        !           160: if (vba_copyu) goto copy;
        !           161:        }
        !           162:        if (bp->b_bcount % sectsize != 0 || (o & (sizeof(long) - 1)) != 0)
        !           163:                goto copy;
        !           164:        else if ((vb->vb_flags & VB_SCATTER) == 0 ||
        !           165:            vb->vb_maxphys != btoc(VB_MAXADDR32)) {
        !           166:                dpte = spte;
        !           167:                p = (dpte++)->pg_pfnum;
        !           168:                for (i = npf; --i > 0; dpte++) {
        !           169:                        if ((v = dpte->pg_pfnum) != p + CLSIZE &&
        !           170:                            (vb->vb_flags & VB_SCATTER) == 0)
        !           171:                                goto copy;
        !           172:                        if (p >= vb->vb_maxphys)
        !           173:                                goto copy;
        !           174:                        p = v;
        !           175:                }
        !           176:                if (p >= vb->vb_maxphys)
        !           177:                        goto copy;
        !           178:        }
        !           179:        vb->vb_copy = 0;
        !           180:        if (vb->vb_iskernel)
        !           181:                vbastat.k_raw++;
        !           182:        else
        !           183:                vbastat.u_raw++;
        !           184:        return ((spte->pg_pfnum << PGSHIFT) + o);
        !           185: 
        !           186: copy:
        !           187:        vb->vb_copy = 1;
        !           188:        if (bp->b_bcount > vb->vb_bufsize)
        !           189:                panic("vba xfer too large");
        !           190:        if (vb->vb_iskernel) {
        !           191:                if ((bp->b_flags & B_READ) == 0)
        !           192:                        bcopy(bp->b_un.b_addr, vb->vb_rawbuf,
        !           193:                            (unsigned)bp->b_bcount);
        !           194:                vbastat.k_copy++;
        !           195:        } else  {
        !           196:                dpte = vb->vb_map;
        !           197:                for (i = npf, p = (int)vb->vb_utl; i--; p += NBPG) {
        !           198:                        *(int *)dpte++ = (spte++)->pg_pfnum |
        !           199:                            PG_V | PG_KW | PG_N;
        !           200:                        mtpr(TBIS, p);
        !           201:                }
        !           202:                if ((bp->b_flags & B_READ) == 0)
        !           203:                        bcopy(vb->vb_utl + o, vb->vb_rawbuf,
        !           204:                            (unsigned)bp->b_bcount);
        !           205:                vbastat.u_copy++;
        !           206:        }
        !           207:        return (vb->vb_physbuf);
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Called by the driver's interrupt routine, after DMA is completed.
        !           212:  * If the operation was a read, copy data to final buffer if necessary
        !           213:  * or invalidate data cache for cacheable direct buffers.
        !           214:  * Similar to the vbastart routine, but in the reverse direction.
        !           215:  */
        !           216: vbadone(bp, vb)
        !           217:        register struct buf *bp;
        !           218:        register struct vb_buf *vb;
        !           219: {
        !           220:        register npf;
        !           221:        register caddr_t v;
        !           222:        int o;
        !           223: 
        !           224:        if (bp->b_flags & B_READ) {
        !           225:                o = (int)bp->b_un.b_addr & PGOFSET;
        !           226:                if (vb->vb_copy) {
        !           227:                        if (vb->vb_iskernel)
        !           228:                                bcopy(vb->vb_rawbuf, bp->b_un.b_addr,
        !           229:                                    (unsigned)(bp->b_bcount - bp->b_resid));
        !           230:                        else {
        !           231:                                bcopy(vb->vb_rawbuf, vb->vb_utl + o,
        !           232:                                    (unsigned)(bp->b_bcount - bp->b_resid));
        !           233:                                dkeyinval(bp->b_proc);
        !           234:                        }
        !           235:                } else {
        !           236:                        if (vb->vb_iskernel) {
        !           237:                                npf = btoc(bp->b_bcount + o);
        !           238:                                for (v = bp->b_un.b_addr; npf--; v += NBPG)
        !           239:                                        mtpr(P1DC, (int)v);
        !           240:                        } else
        !           241:                                dkeyinval(bp->b_proc);
        !           242:                }
        !           243:        }
        !           244: }
        !           245: 
        !           246: /*
        !           247:  * Set up a scatter-gather operation for SMD/E controller.
        !           248:  * This code belongs half-way between {hd,vd}.c and this file.
        !           249:  */
        !           250: 
        !           251: #include "dk.h"
        !           252: #if NVD > 0
        !           253: #include "vdreg.h"
        !           254: 
        !           255: vd_sgsetup(bp, vb, sg)
        !           256:        register struct buf *bp;
        !           257:        struct vb_buf *vb;
        !           258:        struct trsg *sg;
        !           259: {
        !           260:        register struct pte *spte;
        !           261:        register struct addr_chain *adr;
        !           262:        register int i;
        !           263:        int o;
        !           264: 
        !           265:        vb->vb_iskernel = (((int)bp->b_un.b_addr & KERNBASE) == KERNBASE);
        !           266:        vb->vb_copy = 0;
        !           267:        if (vb->vb_iskernel) {
        !           268:                spte = kvtopte(bp->b_un.b_addr);
        !           269:                vbastat.k_sg++;
        !           270:        } else {
        !           271:                spte = vtopte((bp->b_flags&B_DIRTY) ? &proc[2] : bp->b_proc,
        !           272:                    btop(bp->b_un.b_addr));
        !           273:                vbastat.u_sg++;
        !           274:        }
        !           275: 
        !           276:        o = (int)bp->b_un.b_addr & PGOFSET;
        !           277:        i = min(NBPG - o, bp->b_bcount);
        !           278:        sg->start_addr.wcount = i >> 1;
        !           279:        sg->start_addr.memadr = ((spte++)->pg_pfnum << PGSHIFT) + o;
        !           280:        i = bp->b_bcount - i;
        !           281:        if (i > VDMAXPAGES * NBPG)
        !           282:                panic("vba xfer too large");
        !           283:        i = i >> 1;
        !           284:        for (adr = sg->addr_chain; i > 0; adr++, i -= NBPG / 2) {
        !           285:                adr->nxt_addr = (spte++)->pg_pfnum << PGSHIFT;
        !           286:                adr->nxt_len = imin(i, NBPG / 2);
        !           287:        }
        !           288:        adr->nxt_addr = 0;
        !           289:        adr++->nxt_len = 0;
        !           290:        return ((adr - sg->addr_chain) * sizeof(*adr) / sizeof(long));
        !           291: }
        !           292: #endif
        !           293: 
        !           294: #include "hd.h"
        !           295: #if NHD > 0
        !           296: #include "hdreg.h"
        !           297: 
        !           298: hd_sgsetup(bp, vb, sg)
        !           299:        register struct buf *bp;
        !           300:        struct vb_buf *vb;
        !           301:        struct chain *sg;
        !           302: {
        !           303:        register struct pte *spte;
        !           304:        register struct addr_chain *adr;
        !           305:        register int i, cnt;
        !           306:        int o;
        !           307: 
        !           308:        if (bp->b_bcount > HDC_MAXBC ||
        !           309:            bp->b_bcount % sizeof(long) - 1 ||
        !           310:            (u_int)bp->b_un.b_addr % sizeof(long) - 1)
        !           311:                return(0);
        !           312: 
        !           313:        vb->vb_iskernel = (((int)bp->b_un.b_addr & KERNBASE) == KERNBASE);
        !           314:        vb->vb_copy = 0;
        !           315:        if (vb->vb_iskernel) {
        !           316:                spte = kvtopte(bp->b_un.b_addr);
        !           317:                vbastat.k_sg++;
        !           318:        } else {
        !           319:                spte = vtopte((bp->b_flags&B_DIRTY) ? &proc[2] : bp->b_proc,
        !           320:                    btop(bp->b_un.b_addr));
        !           321:                vbastat.u_sg++;
        !           322:        }
        !           323: 
        !           324:        o = (int)bp->b_un.b_addr & PGOFSET;
        !           325:        i = min(NBPG - o, bp->b_bcount);
        !           326:        sg->wcount = i >> 2;
        !           327:        sg->memadr = ((spte++)->pg_pfnum << PGSHIFT) + o;
        !           328:        cnt = 0;
        !           329:        for (i = (bp->b_bcount - i) >> 2; i > 0; i -= NBPG / sizeof(long)) {
        !           330:                if (++cnt == HDC_MAXCHAIN)
        !           331:                        return(0);
        !           332:                sg->wcount |= LWC_DATA_CHAIN;
        !           333:                ++sg;
        !           334:                sg->wcount = imin(i, NBPG / sizeof(long));
        !           335:                sg->memadr = (spte++)->pg_pfnum << PGSHIFT;
        !           336:        }
        !           337:        return(1);
        !           338: }
        !           339: #endif

unix.superglobalmegacorp.com

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