Annotation of Net2/arch/tahoe/vba/vba.c, revision 1.1.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.