Annotation of cci/sys/vba/scat_vddc.c, revision 1.1

1.1     ! root        1: #include "fsd.h"
        !             2: #if NVD > 0
        !             3: /*
        !             4: **     VDDC Driver - Versabus to SMD direct interface version.
        !             5: **             Written for TAHOE vmunix, CCI-WDC 9/1/83.               
        !             6: **             Modified June 1984 to use scatter/gather.
        !             7: */
        !             8: 
        !             9: #include "../h/param.h"
        !            10: #include "../h/buf.h"
        !            11: #include "../h/cmap.h"
        !            12: #include "../h/conf.h"
        !            13: #include "../h/dir.h"
        !            14: #include "../h/dk.h"
        !            15: #include "../h/map.h"
        !            16: #include "../machine/mtpr.h"
        !            17: #include "../machine/pte.h"
        !            18: #include "../h/systm.h"
        !            19: #include "../vba/vbavar.h"
        !            20: #include "../h/user.h"
        !            21: #include "../h/vmmac.h"
        !            22: #include "../h/proc.h"
        !            23: #include "../h/uio.h"
        !            24: #include "../vba/vddc.h"
        !            25: 
        !            26: int    vddebug = 1;    /* if = 1, error messages are printed on the console */
        !            27: int    vdintflg = 0;   /* if = 1, interrupts are handled by the driver, 
        !            28:                         * otherwise they are just ignored. (during setup) */
        !            29: 
        !            30: static struct size FSD[] = {
        !            31:     9600,       0,     /* minor 0/ 8/16/24 = fsd0a - fsd3a - cyl   0 -  59*/
        !            32:    12000,    9600,     /* minor 1/ 9/17/25 = fsd0b - fsd3b - cyl  60 - 134*/
        !            33:   108480,   21600,     /* minor 2/10/18/26 = fsd0c - fsd3c - cyl 135 - 812*/
        !            34:     1600,  130080,     /* minor 3/11/19/27 = fsd0d - fsd3d - cyl 813 - 822*/
        !            35:   130080,       0,     /* minor 4/12/20/28 = fsd0e - fsd3e - cyl   0 - 812*/
        !            36:   131680,       0,     /* minor 5/13/21/29 = fsd0f - fsd3f - cyl   0 - 822*/
        !            37:        0,      0,      /* Non existent minor device */
        !            38:        0,      0,      /* Non existent minor device */
        !            39:        0,      0,      /* Non existent minor device */
        !            40:        0,      0,      /* Non existent minor device */
        !            41:        0,      0,      /* Non existent minor device */
        !            42:        0,      0,      /* Non existent minor device */
        !            43:        0,      0,      /* Non existent minor device */
        !            44:        0,      0,      /* Non existent minor device */
        !            45:        0,      0,      /* Non existent minor device */
        !            46:        0,      0,      /* Non existent minor device */
        !            47: };
        !            48: 
        !            49: static struct size     SMD[]= {
        !            50:     20064,     0,      /* minor 32/40/48/56 = smd0a - smd3a cyl 0- 65 */
        !            51:     13680,  20064,     /* minor 33/41/49/57 = smd0b - smd3b cyl 66- 110 */
        !            52:    214928,  33744,     /* minor 34/42/50/58 = smd0c - smd3c cyl 111-817 */
        !            53:      1520, 248672,     /* minor 35/43/51/59 = smd0d - smd3d cyl 818-822 */
        !            54:    248672,     0,      /* minor 36/44/52/60 = smd0e - smd3e cyl 0-817 */
        !            55:    250192,     0,      /* minor 37/45/53/61 = smd0f - smd3f cyl 0-822 */
        !            56:        0,      0,      /* minor 38/46/54/62 = smd0g - smd3g */
        !            57:        0,      0,      /* minor 39/47/55/63 = smd0h - smd3h */
        !            58:        0,      0,      /* Non existent minor device */
        !            59:        0,      0,      /* Non existent minor device */
        !            60:        0,      0,      /* Non existent minor device */
        !            61:        0,      0,      /* Non existent minor device */
        !            62:        0,      0,      /* Non existent minor device */
        !            63:        0,      0,      /* Non existent minor device */
        !            64:        0,      0,      /* Non existent minor device */
        !            65:        0,      0,      /* Non existent minor device */
        !            66: };
        !            67: 
        !            68: static struct size XFSD[] = {
        !            69:     20352,     0,      /* minor 64/72/80/88 = xfsd0a - xfsd3a cyl 0- 52 */
        !            70:     20352,  20352,     /* minor 65/73/81/89 = xfsd0b - xfsd3b cyl 53- 105 */
        !            71:    230400,  40704,     /* minor 66/74/82/90 = xfsd0c - xfsd3c cyl 106-705 */
        !            72:      1920, 271104,     /* minor 67/75/83/91 = xfsd0d - xfsd3d cyl 706-710 */
        !            73:    271104,     0,      /* minor 68/76/84/92 = xfsd0e - xfsd3e cyl 0-705 */
        !            74:    273024,     0,      /* minor 69/77/85/93 = xfsd0f - xfsd3f cyl 0-710 */
        !            75:        0,      0,      /* minor 70/78/86/94 = xfsd0g - xfsd3g */
        !            76:        0,      0,      /* minor 71/79/87/95 = xfsd0h - xfsd3h */
        !            77:        0,      0,      /* Non existent minor device */
        !            78:        0,      0,      /* Non existent minor device */
        !            79:        0,      0,      /* Non existent minor device */
        !            80:        0,      0,      /* Non existent minor device */
        !            81:        0,      0,      /* Non existent minor device */
        !            82:        0,      0,      /* Non existent minor device */
        !            83:        0,      0,      /* Non existent minor device */
        !            84:        0,      0,      /* Non existent minor device */
        !            85: };
        !            86: 
        !            87: /*
        !            88: /*
        !            89: /* Layout of major/minor number assignments for the VDDC devices.
        !            90: /*
        !            91: /*       1
        !            92: /*       5              8 7      4 3 2   0
        !            93: /*      +----------------+------+---+-----+
        !            94: /*      | Major device # | TYPE | D | FLS |
        !            95: /*      +----------------+------+---+-----+
        !            96: /*                          |     |    |_____ File system # ( 0-7 )
        !            97: /*                          |     |__________ Drive # (0-3)
        !            98: /*                          |________________ Drive type ( 0-FSD, 1-SMD )
        !            99: /*                                             ( 2-XFSD       ) (obsolete)
        !           100: /*
        !           101: /********************************************************/
        !           102: 
        !           103: #define VDUNIT(x)      ((minor(x) & 0x18) >> 3)
        !           104: #define DRVTYPE(x)     ((minor(x) & 0xe0) >> 5) (obsolete)
        !           105: #define FLSYS(x)       (minor(x) & 0x07)
        !           106: #define PHYS(x)                ( vtoph( &proc[2], (int) (x) ) )
        !           107: 
        !           108: 
        !           109: /* Drive types should be in order of drive capacity for auto-configuration */
        !           110: /* e.g: smallest capacity = drive type 0, highest capacity = type NXPDRV-1 */
        !           111: 
        !           112: struct vdst {
        !           113:        short nsect;
        !           114:        short ntrak;
        !           115:        short nspc;
        !           116:        short ncyl;
        !           117:        struct size *sizes;
        !           118:        short dtype;            /* type as in byte 5 (drive) of iopb */
        !           119:        char    *name;          /* drive name for autoconf */
        !           120: } vdst[] = {
        !           121: 
        !           122: 16,    10,     16*10,  823,    FSD,    0,      "160 Mb FSD " ,
        !           123: 16,    19,     16*19,  823,    SMD,    1,      "300 Mb SMD " ,
        !           124: 16,    24,     16*24,  711,   XFSD,    2,      "340 Mb FSD "
        !           125: };
        !           126: 
        !           127: 
        !           128: struct vba_ctlr *vdminfo[NVDDC];
        !           129: struct  vba_device *vddinfo[NUNIT];
        !           130: 
        !           131: /*
        !           132: **     Internal Functions
        !           133: */
        !           134: int    vdopen();
        !           135: int    vdclose();
        !           136: int    vdprobe();              /* See if VDDC is really there */
        !           137: int    vd_setup();             /* Called from vdprobe */
        !           138: int    vdslave();              /* See if drive is really there */
        !           139: int    vdattach();
        !           140: int    vddgo();
        !           141: int    vdstrategy();           /* VDDC strategy routine */
        !           142: int    vdstart();              /* Top level interface to device queue */
        !           143: int    vdintr();               /* Top Level ISR */
        !           144: int    vdread();               /* raw i/o read routine */
        !           145: int    vdwrite();              /* raw i/o write routine */
        !           146: int    vddump();               /* dump routine */
        !           147: int    vdsize();               /* sizes for swapconfig */
        !           148: 
        !           149: long   vdstd[] = {
        !           150:                0x0f2000 };
        !           151: 
        !           152: struct vba_driver vddriver = 
        !           153: {
        !           154:        vdprobe, vdslave, vdattach, vddgo, vdstd, 
        !           155:        "smd/fsd", vddinfo, "VSMD controller ", vdminfo
        !           156: };
        !           157: 
        !           158: struct buf     vdutab[NUNIT];
        !           159: struct         buf     rvdbuf[NUNIT];
        !           160: char   vdbuf[SECTSIZ*2];
        !           161: extern char    vdutl[];
        !           162: 
        !           163: /*
        !           164: **     Disk Address
        !           165: */
        !           166: struct dskadr  {
        !           167:        char    track;          /* all 8 bits */
        !           168:        char    sector;         /* low order 5 bits */
        !           169:        short   cylinder;       /* low order 12 bits */
        !           170: };
        !           171: 
        !           172: /*
        !           173: **     DCB Trailer Formats
        !           174: **********************************/
        !           175: 
        !           176: /*
        !           177: **     Read / Write Trailer
        !           178: */
        !           179: struct trrw    {
        !           180:        char    *memadr;                        /* memory address */
        !           181:        long    wcount;                         /* 16 bit word count */
        !           182:        struct  dskadr  disk;                   /* disk address */
        !           183:        long    scat[MAXBPTE*2+1];              /* gather/scatter trailer */
        !           184: };
        !           185: 
        !           186: /*
        !           187: **     Format Trailer
        !           188: */
        !           189: struct trfmt   {
        !           190:        char    *addr;                  /* data buffer to be filled on sector*/
        !           191:        long    nsectors;               /* # of sectors to be formatted */
        !           192:        struct  dskadr  disk;
        !           193:        struct  dskadr  hdr;
        !           194: };
        !           195: 
        !           196: /*
        !           197: **     Reset / Configure Trailer
        !           198: */
        !           199: struct treset  {
        !           200:        long    ncyl;           /* # cylinders */
        !           201:        long    nsurfaces;      /* # surfaces */
        !           202: };                             /* # of sectors is defined by VDDC */
        !           203:                                /* to be 32/track of 512 data bytes each */
        !           204: 
        !           205: /*
        !           206: **     Seek Trailer
        !           207: */
        !           208: struct trseek  {
        !           209:        struct  dskadr  disk;
        !           210: };
        !           211: 
        !           212: /*
        !           213: **     DCB Format
        !           214: */
        !           215: struct fmt_dcb {
        !           216:        struct  fmt_dcb *nxtdcb;        /* next dcb in chain or End of Chain */
        !           217:        short   intflg;                 /* interrupt settings and flags */
        !           218:        short   opcode;                 /* DCB Command code etc... */
        !           219:        long    operrsta;               /* Error & Status info */
        !           220:        short   fill;                   /* not used */
        !           221:        char    devselect;              /* Drive selection */
        !           222:        char    trailcnt;               /* Trailer Word Count */
        !           223:        long    err_memadr;             /* Error memory address */
        !           224:        short   fill2;
        !           225:        short   err_wcount;             /* Error word count */
        !           226:        short   err_track;              /* Error track/sector */
        !           227:        short   err_cyl;                /* Error cylinder adr */
        !           228:        union   {
        !           229:                struct  trrw    rwtrail;        /* read/write trailer */
        !           230:                struct  trfmt   fmtrail;        /* format trailer */
        !           231:                struct  treset  resetrail;      /* reset/configure trailer */
        !           232:                struct  trseek  seektrail;      /* seek trailer */
        !           233:        } trail;
        !           234: };
        !           235: 
        !           236: /*
        !           237: **     MDCB Format
        !           238: */
        !           239: struct fmt_mdcb        {
        !           240:        struct  fmt_dcb *firstdcb;      /* first dcb in chain */
        !           241:        struct  fmt_dcb *procdcb;       /* dcb being processed */
        !           242:        struct  fmt_dcb *intdcb;        /* dcb causing interrupt */
        !           243:        long    vddcstat;               /* VDDC status */
        !           244: }mdcbx;
        !           245: 
        !           246: /*
        !           247: **     MDCB
        !           248: */
        !           249: struct fmt_mdcb        *mdcb = &mdcbx;
        !           250: 
        !           251: /*
        !           252: **     DCB
        !           253: */
        !           254: 
        !           255: struct fmt_dcb         dcbx[NVDDC];
        !           256: 
        !           257: int vdtimeout; 
        !           258: #define        POLLTILLDONE(x) { vdtimeout = 1000*(x); \
        !           259:                         uncache((char *)&dcb->operrsta); \
        !           260:                         while (! (dcb->operrsta & DCBCMP)) { \
        !           261:                                DELAY(1000); \
        !           262:                                vdtimeout--; \
        !           263:                                uncache((char *)&dcb->operrsta); \
        !           264:                                if (vdtimeout <=0) { \
        !           265:                                        printf("VDDC controller timeout\n"); \
        !           266:                                        return(0); \
        !           267:                                } \
        !           268:                         } \
        !           269:                        }
        !           270: 
        !           271: /*
        !           272: **     See if the controller is really there. 
        !           273: **     if TRUE - initialize the controller.
        !           274: */
        !           275: vdprobe(cntrl_vaddr)
        !           276: caddr_t cntrl_vaddr;
        !           277: {
        !           278:        if ( badaddr(cntrl_vaddr,2) ) return(0); /* no controller */
        !           279:        else 
        !           280:                if (vd_setup(cntrl_vaddr))      /* initialize the controller */
        !           281:                        return(1);
        !           282:                else return(0);         /* initialization error */      
        !           283: }
        !           284: 
        !           285: vd_setup(cntrl_vaddr)
        !           286: caddr_t cntrl_vaddr;
        !           287: {
        !           288:        register struct fmt_dcb *dcb = &dcbx[0];
        !           289:        int j;
        !           290: 
        !           291:        VDDC_RESET(cntrl_vaddr);                /* Reset the controller */
        !           292:                /* Burn some time ...... needed after accessing reset port */
        !           293:        for (j=0; j<20; j++)
        !           294:                DELAY(1000);
        !           295: 
        !           296:        /* setup & issue INIT to initialize VDDC */
        !           297: 
        !           298:        dcb->opcode = INIT;
        !           299:        dcb->nxtdcb = (struct fmt_dcb *)0;
        !           300:        dcb->intflg = NOINT;
        !           301:        mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           302:        dcb->operrsta  = 0;
        !           303:        VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           304:        POLLTILLDONE(1)         /* poll till done */
        !           305:        if (dcb->operrsta & HRDERR) {
        !           306:                if (vddebug)
        !           307:                        printf("VDDC INIT error. Status = %x\n",dcb->operrsta);
        !           308:                return(0);
        !           309:        }
        !           310:        /* setup & issue DIAGNOSE */
        !           311: 
        !           312:        dcb->opcode = DIAG;
        !           313:        dcb->nxtdcb = (struct fmt_dcb *)0;
        !           314:        dcb->intflg = NOINT;
        !           315:        mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           316:        dcb->operrsta  = 0;
        !           317:        VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           318:        POLLTILLDONE(1)         /* poll till done */
        !           319:        if (dcb->operrsta & HRDERR) {
        !           320:                if (vddebug)
        !           321:                        printf("VDDC DIAGNOSE error. Status = %x\n",dcb->operrsta);
        !           322:                return(0);
        !           323:        }
        !           324:        /* Start drives command */
        !           325: /*
        !           326: /*     dcb->opcode = VDSTART;
        !           327: /*     dcb->nxtdcb = (struct fmt_dcb *)0;
        !           328: /*     dcb->intflg = NOINT;
        !           329: /*     mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           330: /*     dcb->operrsta  = 0;
        !           331: /*     VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           332: /*     POLLTILLDONE(20)                /* poll till done */
        !           333: /*     if (dcb->operrsta & HRDERR) {
        !           334: /*             if (vddebug)
        !           335: /*                printf("VDDC START DRIVES error. Status = %x\n",dcb->operrsta);
        !           336: /*             return(0);
        !           337: /*     }
        !           338: /**/
        !           339:        return(1);
        !           340:    }
        !           341: 
        !           342: /*
        !           343:  * See if a drive is really there
        !           344:  * Try to Reset/Configure the drive, then test its status.
        !           345: */
        !           346: vdslave(ui,cntrl_vaddr)
        !           347: register struct vba_device *ui;
        !           348: register caddr_t cntrl_vaddr;
        !           349: {
        !           350:        register struct fmt_dcb *dcb = &dcbx[0];
        !           351:        register struct vdst *st;
        !           352:        int dsktype;
        !           353: 
        !           354:        /*
        !           355:        **  check drive status - see if drive exists. 
        !           356:        */
        !           357:        dcb->opcode = VDSTATUS;
        !           358:        dcb->intflg = NOINT;
        !           359:        dcb->operrsta  = 0;
        !           360:        dcb->devselect = (char)ui->ui_slave;
        !           361:        dcb->trailcnt = (char)0;
        !           362:        mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           363:        mdcb->vddcstat = 0;
        !           364:        VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb))  /* do it */
        !           365:        POLLTILLDONE(5)
        !           366: /*
        !           367:        if (dcb->operrsta & HRDERR) {
        !           368:                if (vddebug) 
        !           369:                  printf("VDDC STATUS error. Status = %x, drive %d\n",dcb->operrsta,ui->ui_slave);
        !           370:                return(0);
        !           371:        }
        !           372: */
        !           373:        uncache((char *)&mdcb->vddcstat);
        !           374:        if (mdcb->vddcstat & DRVNRDY) return(0); /* not ready-> non existent */
        !           375: 
        !           376:        /*
        !           377:         * drive is alive, now get its type!
        !           378:         * Seek on all drive types starting from the largest one.
        !           379:         * a sucessful seek to the last sector/cylinder/track verifies 
        !           380:         * the drive type connected to this port. 
        !           381:         */
        !           382:        for (dsktype = NVDDRV-1; dsktype >= 0; dsktype--) {     
        !           383:                st = &vdst[dsktype];
        !           384:                dcb->opcode = RSTCFG;           /* configure drive command */
        !           385:                dcb->intflg = NOINT;
        !           386:                dcb->operrsta  = 0;
        !           387:                dcb->trail.resetrail.ncyl = st->ncyl;
        !           388:                dcb->trail.resetrail.nsurfaces = st->ntrak;
        !           389:                dcb->devselect = (char)ui->ui_slave;
        !           390:                dcb->trailcnt = (char)2;
        !           391:                mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           392:                VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           393:                POLLTILLDONE(3)
        !           394:                if (dcb->operrsta & HRDERR) {
        !           395:                        if (vddebug) 
        !           396:                          printf("VDDC RESET/CONFIGURE error. Status = %x\n",dcb->operrsta);
        !           397:                        return(0);
        !           398:                }
        !           399:                mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           400:                dcb->intflg = NOINT;
        !           401:                dcb->opcode =  RD;
        !           402:                dcb->operrsta = 0;
        !           403:                dcb->devselect = (char)ui->ui_slave;
        !           404:                dcb->trailcnt = (char)3;
        !           405:                dcb->trail.rwtrail.memadr = (char *)PHYS(vdbuf);
        !           406:                dcb->trail.rwtrail.wcount = SECTSIZ;
        !           407:                dcb->trail.rwtrail.disk.cylinder = st->ncyl -2;
        !           408:                dcb->trail.rwtrail.disk.track = st->ntrak -1;
        !           409:                dcb->trail.rwtrail.disk.sector = 0;
        !           410:                VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           411:                POLLTILLDONE(3)
        !           412:                if ( (dcb->operrsta & HRDERR) == 0) 
        !           413:                /* found the drive type! */
        !           414:                        break;
        !           415:        }
        !           416:        if (dsktype < 0) {
        !           417:                /* If reached here, a drive which is not defined in the 
        !           418:                 * 'vdst' tables is connected. Cannot set it's type.
        !           419:                 */
        !           420:                printf("VDDC error, unrecognized drive type, drive %d\n",ui->ui_slave);
        !           421:                return(0);
        !           422:        }
        !           423:        ui->ui_type = dsktype;
        !           424:        vddriver.ud_dname = st->name;
        !           425:        return(1);
        !           426: }
        !           427: 
        !           428: vdattach(ui)
        !           429: struct vba_device *ui;
        !           430: {
        !           431: }
        !           432: 
        !           433: vddgo(um)
        !           434: struct vba_ctlr *um;
        !           435: {
        !           436: }
        !           437: 
        !           438: #define b_cylin b_resid
        !           439: 
        !           440: vdstrategy(bp)
        !           441: register struct buf *bp;
        !           442: {
        !           443:        register struct vba_device *ui;
        !           444:        register struct vba_ctlr *um;
        !           445:        register int unit;
        !           446:        register struct buf *dp;
        !           447:        register struct size *sizep;
        !           448:        int index, blocks, s;
        !           449: 
        !           450:        vdintflg = 1;           /* enable interrupts handling by the driver */
        !           451:        blocks = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
        !           452:        if (bp->b_bcount > NBPG*MAXBPTE) {
        !           453:                printf ("VDDC I/O length error: %d\n", bp->b_bcount);
        !           454:                goto bad1;
        !           455:        }
        !           456:        unit = VDUNIT(bp->b_dev);
        !           457:        ui = vddinfo[unit];
        !           458:        if (ui == 0 || ui->ui_alive == 0) goto bad1;
        !           459:        index = FLSYS(bp->b_dev); /* get file system index */
        !           460:        sizep = vdst[ui->ui_type].sizes;
        !           461:        if (bp->b_blkno < 0 ||
        !           462:         (dkblock(bp)+blocks > sizep[index].nblocks))   /* disk overflow */
        !           463:                goto bad1;
        !           464:        s = spl8();
        !           465:        dp = &vdutab[ui->ui_unit];
        !           466:        bp->b_resid = bp->b_blkno ;     /* block # plays same role as
        !           467:                                           cylinder # for disksort, as long
        !           468:                                           as increasing blocks correspond to
        !           469:                                           increasing cylinders on disk */
        !           470: 
        !           471:        disksort(dp, bp);
        !           472:        if (dp->b_active == 0) {        /* unit is on controller queue */
        !           473:                /* put the device on the controller queue */
        !           474:                dp->b_forw = NULL;              /* end of queue indicator */
        !           475:                um = ui->ui_mi;         /* get controller structure !! */
        !           476:                if (um->um_tab.b_actf == NULL)  /* controller queue is empty */
        !           477:                        um->um_tab.b_actf = dp; 
        !           478:                else
        !           479:                        um->um_tab.b_actl->b_forw = dp; /* add into queue */
        !           480:                um->um_tab.b_actl = dp;         /* update queue tail */
        !           481:                dp->b_active ++;
        !           482:        }
        !           483:        bp = &ui->ui_mi->um_tab;        /* controller structure addr */
        !           484:        if (bp->b_actf &&               /* cntrl queue not empty */
        !           485:                bp->b_active == 0)      /* controller not active */
        !           486:                (void) vdstart(ui->ui_mi);/* go start I/O */
        !           487:        splx(s);
        !           488:        return;
        !           489: 
        !           490: bad1:
        !           491:        bp->b_flags |= B_ERROR;
        !           492:        iodone(bp);
        !           493:        return;
        !           494: }
        !           495: 
        !           496: 
        !           497: /*
        !           498:  * Start up a transfer on a drive.
        !           499:  */
        !           500: vdstart(um)
        !           501: register struct vba_ctlr *um;
        !           502: {
        !           503:        register struct buf *bp, *dp;
        !           504:        register struct fmt_dcb *dcb = &dcbx[um->um_ctlr];
        !           505:        struct size *sizep;     /* Pointer to one of the tables */
        !           506:        register struct vdst *st;
        !           507:        register int index ;            /* Index in the relevant table */
        !           508:        register int phadr;             /* Buffer's physical address */
        !           509:        register caddr_t cntrl_vaddr = um->um_addr;
        !           510:        register struct proc *this_proc;
        !           511:        register long phaddr, vaddr, length, i;
        !           512:        register long *longp;
        !           513:        int     sblock, unit;
        !           514: 
        !           515: loop:
        !           516:        /*
        !           517:         * Pull a request off the controller queue
        !           518:         */
        !           519:        if ((dp = um->um_tab.b_actf) == NULL)
        !           520:                return ;
        !           521:        if ((bp = dp->b_actf) == NULL) {
        !           522:                dp->b_active = 0;       /* device removed from ctlr queue */
        !           523:                um->um_tab.b_actf = dp->b_forw;
        !           524:                goto loop;
        !           525:        }
        !           526:        /*
        !           527:         * Mark controller busy, and
        !           528:         * prepare a command packet for the controller.
        !           529:         */
        !           530:        um->um_tab.b_active++;
        !           531:        unit = VDUNIT(bp->b_dev);
        !           532:        st = &vdst[vddinfo[unit]->ui_type];
        !           533:        index = FLSYS(bp->b_dev);
        !           534:        sizep = st->sizes;
        !           535:        mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           536:        dcb->intflg = INTDUN;           /* interrupt on completion */
        !           537: 
        !           538:        dcb->operrsta = 0;
        !           539:        dcb->devselect = VDUNIT(bp->b_dev);
        !           540:        sblock = sizep[index].block0 + bp->b_blkno;
        !           541:        dcb->trail.rwtrail.disk.cylinder = (short)(sblock / st->nspc);
        !           542:        dcb->trail.rwtrail.disk.track=(char)((sblock % st->nspc) / st->nsect);
        !           543:        dcb->trail.rwtrail.disk.sector = (char)(sblock*2 % (st->nsect*2));
        !           544:        if (bp->b_flags & B_DIRTY || bp->b_proc==0) this_proc = &proc[2];
        !           545:        else this_proc = bp->b_proc;
        !           546:        phaddr = vtoph(this_proc, bp->b_un.b_addr);     /* start addresses */
        !           547:        vaddr = (int)bp->b_un.b_addr;
        !           548:        length = (bp->b_bcount+1) & ~1;                 /* total # of bytes */
        !           549: printf("\nvaddr=%x length=%x\n", vaddr, length);
        !           550:        dcb->trail.rwtrail.memadr = (char *)phaddr;     /* default trailer */
        !           551: printf("%x ", dcb->trail.rwtrail.memadr);
        !           552:        i = imin ( NBPG-(phaddr&PGOFSET),length);    /* bytes in this page */
        !           553:        dcb->trail.rwtrail.wcount = i/2;
        !           554: if (i != 0x400) printf("/%x ", i/2);
        !           555:        dcb->trailcnt = 3;
        !           556: /*
        !           557:  * If all required bytes fit into one page frame, that's it.
        !           558:  * Otherwise we have to generate a scatter/gather trailer.
        !           559:  */
        !           560:        length -= i;
        !           561:        vaddr += i;
        !           562:        longp = dcb->trail.rwtrail.scat;                /* 1'st pair address */
        !           563:        while (length > 0) {
        !           564:                i = imin ( NBPG-(phaddr&PGOFSET),length);
        !           565:                *longp++ = i/2;
        !           566:                *longp++ = vtoph (this_proc, vaddr);
        !           567:                vaddr += i;
        !           568:                length -= i;
        !           569:                dcb->trailcnt += 2;
        !           570:        }
        !           571:        *longp++ = 0;                                   /* End of list */
        !           572:        *longp = 0;                                     /* End of list */
        !           573:        /***********
        !           574:        dcb->trailcnt +=2 ;
        !           575:        ***********/
        !           576:        if (bp->b_flags & B_READ) {             /* Read or read&scatter */
        !           577:                if (dcb->trailcnt == 3) dcb->opcode = RD;
        !           578:                else dcb->opcode = RAS;
        !           579:        } else {                                /* Write or gather&write */
        !           580:                if (dcb->trailcnt == 3) dcb->opcode = WD;
        !           581:                else dcb->opcode = GAW;
        !           582:        }
        !           583: while (longp >= (long *)dcb)
        !           584: printf("%x\n", *longp--);
        !           585: 
        !           586: #ifdef VDDCPERF
        !           587:        scope_out(1);
        !           588: #endif
        !           589: 
        !           590:        VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb))  /* do it */
        !           591: }
        !           592: 
        !           593: 
        !           594: /*
        !           595:  * Handle a disk interrupt.
        !           596:  */
        !           597: vdintr(vdnum)
        !           598: register vdnum;
        !           599: {
        !           600:        register struct buf *bp, *dp;
        !           601:        register struct vba_ctlr *um = vdminfo[vdnum];  
        !           602:        register struct fmt_dcb *dcb = &dcbx[vdnum];
        !           603:        register int cnt;
        !           604: 
        !           605: #ifdef VDDCPERF
        !           606:        scope_out(2);
        !           607: #endif
        !           608: printf("vddc 1\n");
        !           609:        if (intenable == 0 || vdintflg == 0)    /* ignore all interrupts */
        !           610:                return;
        !           611:        if (um->um_tab.b_active == NULL) return;/* unexpected interrupt */
        !           612:        uncache((char *)&mdcb->intdcb);
        !           613:        uncache((char *)&dcb->operrsta);
        !           614:        if ( mdcb->intdcb != (struct fmt_dcb *)PHYS(dcb)) {     /* dcb causing interrupt */
        !           615:                printf("VDDC error - dcb causing interrupt (%x) is different from expected dcb (%x) Interrupt ignored\n", mdcb->intdcb,dcb);
        !           616:                return;
        !           617:        }
        !           618:        if (! (dcb->operrsta & DCBCMP)) { /* unexpected interrupt */
        !           619:                printf("VDDC Unexpected interrupt, DCB completed not set. Status = %x\n",dcb->operrsta);
        !           620:                return;
        !           621:        }
        !           622:        dp = um->um_tab.b_actf;         /* device queue head in ctlr queue */
        !           623:        bp = dp->b_actf;                /* first buffer in device queue */
        !           624:        if (dcb->operrsta & HRDERR) {
        !           625:                  printf("VDDC hard error - dcb status = %x\n",dcb->operrsta);
        !           626:                bp->b_flags |= B_ERROR;
        !           627:        }
        !           628:        else if (dcb->operrsta & SFTERR)
        !           629:            printf("Soft error on VDDC,status = %x, dev=%x, block # %d\n",
        !           630:                                dcb->operrsta, bp->b_dev, bp->b_blkno);
        !           631: 
        !           632: /*
        !           633:  *     If this was a read, we have to purge the data cache for the
        !           634:  *     rigth virtual pages. It could be nice to just change the
        !           635:  *     relevant process's data key but this key is in PCB, in _u,
        !           636:  *     which can be on the disk right now. And besides, what about
        !           637:  *     reads into the system space? There's no key to change there.
        !           638:  */
        !           639:        if (bp->b_flags & B_READ) {
        !           640: printf("vddc 2\n");
        !           641:                if (dcb->opcode == RAS) {       /* Multiple pages read */
        !           642: printf("vddc 3\n");
        !           643:                        for (cnt=bp->b_bcount; cnt>=0; cnt -= NBPG)
        !           644:                                mtpr ((caddr_t)bp->b_un.b_addr+cnt-1, P1DC);
        !           645:                        if ( ((int)bp->b_un.b_addr & PGOFSET) != 0 )
        !           646:                                mtpr ((caddr_t)bp->b_un.b_addr, P1DC);
        !           647:                } else {                        /* Only one page read */
        !           648:                        mtpr ((caddr_t)bp->b_un.b_addr, P1DC);
        !           649: printf("vddc 4\n");
        !           650:                }
        !           651:        }
        !           652: 
        !           653:        um->um_tab.b_active = 0;
        !           654:        um->um_tab.b_errcnt = 0;
        !           655:        if (dp->b_forw != NULL) {               /* more than 1 unit on queue */
        !           656:                um->um_tab.b_actf = dp->b_forw; /* next device on ctlr queue */
        !           657:                dp->b_forw = um->um_tab.b_actl->b_forw; /* be last in queue */
        !           658:                um->um_tab.b_actl->b_forw = dp; /* last points now to dp */
        !           659:                um->um_tab.b_actl = dp;         /* pointer in ctlr structure */
        !           660:        }
        !           661:        dp->b_errcnt = 0;
        !           662:        dp->b_actf = bp->av_forw;               /* remove first from queue */
        !           663:        bp->b_resid = 0;        /* All data read here */
        !           664: 
        !           665: #ifdef VDDCPERF
        !           666:        scope_out(3);
        !           667: #endif
        !           668: 
        !           669: printf("vddc 5\n");
        !           670:        iodone(bp);
        !           671: printf("vddc 6\n");
        !           672:        vdstart(um);            /* start requests for next device on queue */
        !           673: printf("vddc 7\n");
        !           674: }
        !           675: 
        !           676: 
        !           677: vdread(dev, uio)
        !           678: dev_t dev;
        !           679: struct uio *uio;
        !           680: {
        !           681:        register int unit = VDUNIT(dev);
        !           682:        register int error;
        !           683: 
        !           684:        if (unit >= NUNIT) return ( ENXIO );
        !           685:        else return 
        !           686:                (physio(vdstrategy, &rvdbuf[unit], dev, B_READ, minphys, uio));
        !           687: }
        !           688: 
        !           689: vdwrite(dev, uio)
        !           690: dev_t dev;
        !           691: struct uio *uio;
        !           692: {
        !           693:        register int unit = VDUNIT(dev);
        !           694:        register int error;
        !           695: 
        !           696:        if (unit >= NUNIT) return (ENXIO);
        !           697:        else return 
        !           698:                (physio(vdstrategy, &rvdbuf[unit], dev, B_WRITE,minphys, uio));
        !           699: }
        !           700: 
        !           701: #define        DUMPSIZE        32      /* Up to 32k at a time - controller limit */
        !           702: 
        !           703: vddump(dev)
        !           704: dev_t  dev;
        !           705: /*
        !           706:  * Dump the main memory to the given device.
        !           707:  */
        !           708: {
        !           709:        register struct vba_ctlr *um;
        !           710:        register struct fmt_dcb *dcb = &dcbx[0];
        !           711:        register struct vdst *st;
        !           712:        register int unit;
        !           713:        register caddr_t cntrl_vaddr ;
        !           714:        register struct size *sizep;    /* Pointer to one of the tables */
        !           715:        int index,sblock,blkcount,thiscount;
        !           716:        int     memaddr;
        !           717: 
        !           718:        unit = VDUNIT(dev);
        !           719:        um = (vddinfo[unit])->ui_mi;
        !           720:        st = &vdst[(vddinfo[unit])->ui_type];
        !           721:        dcb = &dcbx[um->um_ctlr];
        !           722:        cntrl_vaddr = um->um_addr;
        !           723:        memaddr = 0x0;
        !           724:        index = FLSYS(dev);
        !           725:        sizep = st->sizes;
        !           726:        blkcount = maxfree - 2;         /* In 1k byte pages */
        !           727:        if (dumplo + blkcount > sizep[index].nblocks) return(EINVAL);
        !           728:        sblock = sizep[index].block0 + dumplo;
        !           729:        while (blkcount > 0) {
        !           730:                thiscount = MIN (blkcount, DUMPSIZE);
        !           731:                mdcb->firstdcb = (struct fmt_dcb *)PHYS(dcb);
        !           732:                dcb->intflg = NOINT;
        !           733:                dcb->opcode = WD;
        !           734:                dcb->operrsta = 0;
        !           735:                dcb->devselect = unit;
        !           736:                dcb->trailcnt = (char)3;
        !           737:                dcb->trail.rwtrail.memadr = (char *)memaddr;
        !           738:                dcb->trail.rwtrail.wcount = thiscount*512;
        !           739:                dcb->trail.rwtrail.disk.cylinder= (short)(sblock/st->nspc);
        !           740:                dcb->trail.rwtrail.disk.track = (char)((sblock % st->nspc) 
        !           741:                        / st->nsect);
        !           742:                dcb->trail.rwtrail.disk.sector = (char)(sblock*2 % (st->nsect*2));
        !           743:                VDDC_ATTENTION(cntrl_vaddr,PHYS(mdcb) ) /* do it */
        !           744:                POLLTILLDONE(5);
        !           745:                if (dcb->operrsta & HRDERR) {
        !           746:                                if (vddebug)
        !           747:                                printf("VDDC DUMP error. Status = %x\n",
        !           748:                                        dcb->operrsta);
        !           749:                        return(EIO);
        !           750:                };
        !           751:                blkcount -= thiscount;
        !           752:                memaddr += thiscount*NBPG;
        !           753:                sblock += thiscount;
        !           754:        }
        !           755:        return(0);
        !           756: }
        !           757: 
        !           758: vdopen(dev, flag)
        !           759: register dev_t dev;
        !           760: int flag;
        !           761: {
        !           762:        register struct vba_device *ui;
        !           763:        register unit = VDUNIT(dev);
        !           764: 
        !           765:        ui = vddinfo[unit];
        !           766:        if (ui == 0 || ui->ui_alive == 0 || ui->ui_type >= NVDDRV)
        !           767:                return ENXIO;
        !           768:        return 0;
        !           769: }
        !           770: 
        !           771: vdsize(dev)
        !           772: register dev_t dev;
        !           773: {
        !           774:        register struct vba_device *ui;
        !           775:        register unit = VDUNIT(dev);
        !           776: 
        !           777:        ui = vddinfo[unit];
        !           778:        if (ui == 0 || ui->ui_alive == 0 || ui->ui_type >= NVDDRV)
        !           779:                return -1;
        !           780:        return vdst[ui->ui_type].sizes[FLSYS(dev)].nblocks;
        !           781: }
        !           782: #endif

unix.superglobalmegacorp.com

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