Annotation of cci/sys/vba/scat_vddc.c, revision 1.1.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.