Annotation of coherent/d/PS2_KERNEL/io.286/ps.c, revision 1.1.1.1

1.1       root        1: /* (-lgl
                      2:  *     COHERENT Driver Kit Version 1.1.0
                      3:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
                      4:  *     All rights reserved. May not be copied without permission.
                      5:  *
                      6:  * $Log:       ps.c,v $
                      7:  * Revision 1.10  91/11/11  12:29:03  hal
                      8:  * Use n_atdr.
                      9:  * 
                     10:  * Revision 1.9  91/10/30  10:47:46  hal
                     11:  * Get psparms from tboot.
                     12:  *
                     13:  * Revision 1.8  91/10/24  12:36:25  hal
                     14:  * Bump PSSECS from 4 to 6.
                     15:  * Poll HF_REG (3F6) rather than CSR_REG (1F6).
                     16:  * COH 3.2.03.
                     17:  *
                     18:  * Revision 1.7  91/09/11  14:45:38  hal
                     19:  * Trial patch for Seagate 157A problems.
                     20:  *
                     21:  * Revision 1.6  91/09/11  13:23:12  hal
                     22:  * Explicit sys in include paths.  AT_MAJOR.
                     23:  *
                     24:  * Revision 1.5  91/05/22  15:06:59  hal
                     25:  * Don't force 8's bit of control byte.
                     26:  *
                     27:  * Revision 1.4        91/03/14  14:22:32      hal
                     28:  *
                     29:  -lgl) */
                     30: /*
                     31:  * This is a driver for the
                     32:  * hard disk on the PS.
                     33:  *
                     34:  * Reads drive characteristics from ROM (thru interrupt vector 0x41 and 0x46).
                     35:  * Reads partition information from disk.
                     36:  */
                     37: #include       <sys/coherent.h>
                     38: #include       <sys/fdisk.h>
                     39: #include       <sys/hdioctl.h>
                     40: #include       <sys/buf.h>
                     41: #include       <sys/con.h>
                     42: #include       <sys/devices.h>
                     43: #include       <sys/stat.h>
                     44: #include       <sys/uproc.h>
                     45: #include       <sys/typed.h>
                     46: #include       <sys/timeout.h>                 /* TIM */
                     47: #include       <sys/sched.h>
                     48: #include       <errno.h>
                     49: 
                     50: extern saddr_t sds;            /* System Data Selector */
                     51: extern short   n_atdr;         /* Number of "ps" drives */
                     52: int    ATSREG = 0x3F6;
                     53: 
                     54: /*
                     55:  * Configurable parameters
                     56:  */
                     57: #define        HDIRQ   14                      /* Level 14 */
                     58: #define NDRIVE 2                       /* only two drives supported */
                     59: #define        SOFTLIM 6                       /*  (7) num of retrys before diag */
                     60: #define        HARDLIM 8                       /* number of retrys before fail */
                     61: #define        BADLIM  100                     /* num to stop recov if flagged bad */
                     62: 
                     63: #define        BIT(n)          (1 << (n))
                     64: 
                     65: #define        CMOSA   0x70                    /* write cmos address to this port */
                     66: #define        CMOSD   0x71                    /* read cmos data through this port */
                     67: 
                     68: /*
                     69:  * Driver configuration.
                     70:  */
                     71: void   psload();
                     72: void   psunload();
                     73: void   psopen();
                     74: void   psread();
                     75: void   pswrite();
                     76: int    psioctl();
                     77: void   pstimer();
                     78: void   psblock();
                     79: int    nulldev();
                     80: int    nonedev();
                     81: 
                     82: CON    pscon   = {
                     83:        DFBLK|DFCHR,                    /* Flags */
                     84:        AT_MAJOR,                       /* Major index */
                     85:        psopen,                         /* Open */
                     86:        nulldev,                        /* Close */
                     87:        psblock,                        /* Block */
                     88:        psread,                         /* Read */
                     89:        pswrite,                        /* Write */
                     90:        psioctl,                        /* Ioctl */
                     91:        nulldev,                        /* Powerfail */
                     92:        nulldev,                        /* Timeout */
                     93:        psload,                         /* Load */
                     94:        psunload                        /* Unload */
                     95: };
                     96: 
                     97: /*
                     98:  * Forward Referenced Functions.
                     99:  */
                    100: void   psreset();
                    101: int    psdequeue();
                    102: void   psstart();
                    103: void   psintr();
                    104: static void psstatus();
                    105: void   psdone();
                    106: void   disk_function();
                    107: void   disk_functionb();
                    108: 
                    109: /*
                    110:  * Device States.
                    111:  */
                    112: #define        SIDLE   0                       /* controller idle */
                    113: #define        SRETRY  1                       /* seeking */
                    114: #define        SREAD   2                       /* reading */
                    115: #define        SWRITE  3                       /* writing */
                    116: #define SRESET  4                      /* reseting */
                    117: 
                    118: char *smsg[] = { "SIDLE", "SRETRY", "SREAD", "SWRITE", "SRESET" };
                    119: 
                    120: /*
                    121:  * Drive Parameters - copied from ROM.
                    122:  * If patched, use the given values instead of reading from the ROM.
                    123:  * NOTE: Exactly duplicates hdparm_s struct.
                    124:  */
                    125: struct dparm_s {
                    126:        unsigned short  d_ncyl;         /* number of cylinders */
                    127:        unsigned char   d_nhead;        /* number of heads */
                    128:        unsigned short  d_rwcc;         /* reduced write current cyl */
                    129:        unsigned short  d_wpcc;         /* write pre-compensation cyl */
                    130:        unsigned char   d_eccl;         /* max ecc data length */
                    131:        unsigned char   d_ctrl;         /* control byte */
                    132:        unsigned char   d_fill2[3];
                    133:        unsigned short  d_landc;        /* landing zone cylinder */
                    134:        unsigned char   d_nspt;         /* number of sectors per track */
                    135:        unsigned char   d_fill3;
                    136: 
                    137: }      psparm[ NDRIVE ] = {
                    138:        0                               /* Initialized to allow patching */
                    139: };
                    140: 
                    141: /*
                    142:  * Partition Parameters - copied from disk.
                    143:  *
                    144:  *     There are NDRIVE * NPARTN positions for the user partitions,
                    145:  *     plus NDRIVE additional partitions to span each drive.
                    146:  *
                    147:  *     Aligning partitions on cylinder boundaries:
                    148:  *     Optimal partition size: 2 * 3 * 4 * 5 * 7 * 17 = 14280 blocks
                    149:  *     Acceptable partition size:  3 * 4 * 5 * 7 * 17 =  7140 blocks
                    150:  */
                    151: static
                    152: struct fdisk_s pparm[NDRIVE*NPARTN + NDRIVE];
                    153: 
                    154: /*
                    155:  * Per disk controller data.
                    156:  * Only one controller; no more, no less.
                    157:  */
                    158: static
                    159: struct ps      {
                    160:        BUF             *ps_actf;       /* Link to first */
                    161:        BUF             *ps_actl;       /* Link to last */
                    162:        faddr_t         ps_faddr;       /* Source/Dest virtual address */
                    163:        daddr_t         ps_bno;         /* Block # on disk */
                    164:        unsigned        ps_nsec;        /* # of sectors on current transfer */
                    165:        unsigned        ps_drv;
                    166:        unsigned        ps_head;
                    167:        unsigned        ps_cyl;
                    168:        unsigned        ps_sec;
                    169:        unsigned        ps_partn;
                    170:        unsigned char   ps_dtype[ NDRIVE ];     /* drive type, 0 if unused */
                    171:        unsigned char   ps_tries;
                    172:        unsigned char   ps_state;
                    173:        unsigned char   ps_caching;             /* caching in progress */
                    174:        unsigned        ps_bad_drv;
                    175:        unsigned        ps_bad_head;
                    176:        unsigned        ps_bad_cyl;
                    177: }      ps;
                    178: 
                    179: static BUF     dbuf;                   /* For raw I/O */
                    180: 
                    181: 
                    182: #include <sys/abios.h>
                    183: #include <sys/mmu.h>
                    184: #include <sys/types.h>
                    185: #include <stdio.h>
                    186: 
                    187: static request_block_hd rb;
                    188: 
                    189: char killbuf[1024]; /* don't forget to fix bio.c */
                    190: char l_com_data[0x80];
                    191: paddr_t com_data_p, dev1p, fcn1p, dev2p, fcn2p;
                    192: a_sys_parm sp;
                    193: a_init_table it0, it1, it2, it15;
                    194: 
                    195: char fcn0[0x10], fcn1[0x50], fcn2[0x40], fcn15[0x58];
                    196: 
                    197: extern int com_data,i0, i1, i2, i15, fcn_trn0, fcn_trn1, fcn_trn2, fcn_trn15; 
                    198: 
                    199: #define cscolon(d)             ((faddr_t)(0x600000L + (unsigned) (d)))
                    200: #define init_tab_cp(s,r)       fkcopy(cscolon(ffword(cscolon(s))), r, 24)
                    201: 
                    202: /*
                    203:  * Patchable variables.
                    204:  *     PSBSYW is a loop count for busy-waiting after issuing commands.
                    205:  *     PSSECS is number of seconds to wait for an expected interrupt.
                    206:  */
                    207: int    PSBSYW = 50;                    /* patchable */
                    208: int    PSSECS = 6;                     /* patchable */
                    209: 
                    210: /**
                    211:  *
                    212:  * void
                    213:  * psload()    - load routine.
                    214:  *
                    215:  *     Action: The controller is reset and the interrupt vector is grabbed.
                    216:  *             The drive characteristics are set up ps this time.
                    217:  */
                    218: static void
                    219: psload()
                    220: {
                    221:        unsigned int u;
                    222:        register int    s;
                    223:        struct dparm_s * dp;
                    224: 
                    225:        init_abios();
                    226: 
                    227:        n_atdr = 1;
                    228: 
                    229:        if (n_atdr == 0)
                    230:                return;
                    231: 
                    232:        ps.ps_actf = NULL; /* Start up with this Null to avoid phony calls */
                    233: 
                    234:        /*
                    235:         * Obtain (hardwire) Drive Types.
                    236:         */
                    237:        ps.ps_dtype[0] = 1;             /* This just means that it exists */
                    238:        ps.ps_dtype[1] = 0;      /* This just means that it doesn't exist */
                    239: 
                    240:        /*
                    241:         * Obtain Drive Characteristics.
                    242:         */
                    243: 
                    244:        for (u = 0, dp = &psparm[0]; u < n_atdr; ++dp, ++u) 
                    245:        {
                    246:                rb.length = 0x80;
                    247:                rb.logical_id = 5;
                    248:                rb.unit = 0;
                    249:                rb.function = 3;
                    250:                rb.reserved = 0L;
                    251:                rb.ret_code = 0xffff;
                    252:                rb.vars.f3.reserved = 0L;
                    253:                d2_func(&rb, START_P);
                    254:                if (rb.ret_code)
                    255:                        printf("\nhard disk function 3 returned = %d\n", 
                    256:                                                                rb.ret_code);
                    257:                dp->d_ncyl = rb.vars.f3.cylinders;
                    258:                dp->d_nhead = rb.vars.f3.heads;
                    259:                dp->d_nspt = rb.vars.f3.sectors_track;
                    260:                dp->d_wpcc = 0xffff;
                    261:                dp->d_landc = rb.vars.f3.cylinders;
                    262:                if (dp->d_nhead > 8)
                    263:                        dp->d_ctrl |= 8;
                    264:  
                    265: #if 0
                    266: 
                    267:        printf(" drive %d parameters\n", u);
                    268:        printf(
                    269:        "ps%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d\n",
                    270:                u,
                    271:                dp->d_ncyl,
                    272:                dp->d_nhead,
                    273:                dp->d_wpcc,
                    274:                dp->d_eccl,
                    275:                dp->d_ctrl,
                    276:                dp->d_landc,
                    277:                dp->d_nspt);
                    278:        printf("\nhard disk function 3 returned = %d\n", rb.ret_code);
                    279:        printf("\nretries = %d", rb.vars.f3.retries);
                    280:        printf("\nblock_addresses = %lu", rb.vars.f3.block_addresses);
                    281:        printf("\nmax_blocks = %d\n", rb.vars.f3.max_blocks);
                    282: 
                    283: #endif
                    284:        }
                    285: 
                    286:        /*
                    287:         * Initialize Drive Size.
                    288:         */
                    289:        for (u = 0, dp = &psparm[0]; u < n_atdr; ++dp, ++u) {
                    290: 
                    291:                if (ps.ps_dtype[u] == 0)
                    292:                        continue;
                    293: 
                    294:                pparm[NDRIVE*NPARTN + u].p_size =
                    295:                        (long) dp->d_ncyl * dp->d_nhead * dp->d_nspt;
                    296:        }
                    297: 
                    298: 
                    299:        s = sphi(); 
                    300:        setivec(HDIRQ, psintr); 
                    301:        spl( s );
                    302:        
                    303:        ps.ps_bad_drv = -1;
                    304: 
                    305:        /*
                    306:         * Initialize Drive Controller.
                    307:         */
                    308:        psreset();
                    309: }
                    310: 
                    311: paddr_t prot;
                    312: 
                    313: /* This is the protected mode part of the abios initialization */
                    314: init_abios()
                    315: {
                    316:        unsigned int i, count, *tmp1;
                    317:        paddr_t codeseg;
                    318:        paddr_t *tmp, tmpp;
                    319:        static short done = 0;
                    320: 
                    321:        if (done)               /* Make sure we don't call this twice */
                    322:                return;
                    323: 
                    324:        done++;
                    325: 
                    326:        printf("init_abios_a() = %x\n", iresult());
                    327: 
                    328:        /* First create the virtual pointer to the comm area */
                    329:        com_data_p = ptov(vtop(l_com_data, sds), 0x80L);
                    330: 
                    331:        /* Now copy the common data table into local space */
                    332:        fkcopy(cscolon((unsigned)(&com_data) & 0xfff0), l_com_data, 0x80);
                    333: 
                    334:        /* Now copy the initialization tables into local space */
                    335:        init_tab_cp(&i0,  &it0);
                    336:        init_tab_cp(&i1,  &it1);
                    337:        init_tab_cp(&i15, &it15);
                    338:        init_tab_cp(&i2,  &it2);
                    339: 
                    340:        /* Now convert each real mode device block pointer into a protected 
                    341:         * mode device block pointer .
                    342:         */
                    343: 
                    344:        tmp = tmp1 = l_com_data;      /* Make thing easier on the compiler */
                    345: 
                    346:        codeseg = ptov(0x0600L, 0xffffL); /* Set up an r/w alias to the cs */
                    347: 
                    348:                                        /* Fix the segments in the CDA */
                    349:                                        /* the offsets are still ok */
                    350:        tmp1[9] = tmp1[13] = tmp1[17] = tmp1[21] = FP_SEL(codeseg);
                    351: 
                    352:        dev1p = tmp[6];
                    353:        dev2p = tmp[10];        /* Set this up so calls are easier later */
                    354:        
                    355:        /* Now fix each function transfer table pointer in the cda so that 
                    356:          * it points to the proper spot in the ds
                    357:         */
                    358:        
                    359:                                        /* Fix the segments in the CDA */
                    360:        tmp1[11] = tmp1[15] = tmp1[19] = tmp1[23] = sds;
                    361: 
                    362:        tmp1[10] = (unsigned)fcn0;      /* Now fix the offsets */       
                    363:        tmp1[14] = (unsigned)fcn1;
                    364:        tmp1[18] = (unsigned)fcn15;
                    365:        tmp1[22] = (unsigned)fcn2;
                    366: 
                    367:        fcn1p = tmp[7];
                    368:        fcn2p = tmp[11];        /* Set this up so calls are easier later */
                    369: 
                    370:        /* Now convert the pointers in the ftts to protected mode pointers */
                    371: 
                    372:                                      /* This is the location of the Abios */
                    373:        fkcopy(cscolon(&fcn_trn0), &tmpp, 4);
                    374:        tmpp = (tmpp & 0xffff0000L) >> 12;
                    375:        prot = ptovx(tmpp); 
                    376: 
                    377:                                  /* First do the system level functions */
                    378:        cnvt_ptrs(&fcn_trn0, fcn0, it0.ftt_length);
                    379:                                        /* Now do the diskette functions */
                    380:        cnvt_ptrs(&fcn_trn1, fcn1, it1.ftt_length);
                    381:                                             /* Now do the DMA functions */
                    382:        cnvt_ptrs(&fcn_trn15, fcn15, it15.ftt_length);
                    383:                         /* Finish up with the hard disk functions table */
                    384:        cnvt_ptrs(&fcn_trn2, fcn2, it2.ftt_length);
                    385: 
                    386:        /* Finally,  Convert the data pointers */
                    387: 
                    388:        i = *(int *)l_com_data; /* i is now a pointer to the first pointer */
                    389:        count = *(int *)(l_com_data+i+6);/* count is the # of data pointers*/
                    390:        while (count--)         /* Any more data pointers? */
                    391:        {                       /* Redo the pointer using the saved size */
                    392:                tmp = l_com_data + i + 2;
                    393:                *tmp = ptov(*tmp, (long)*(unsigned *)(tmp-2));
                    394:                i -= 6;                 /* Now point to the next pointer */
                    395:        }
                    396: }
                    397: 
                    398: 
                    399: cnvt_ptrs(cs_src, fcn_dest, length)
                    400: int cs_src, length;
                    401: char *fcn_dest;
                    402: {
                    403:        paddr_t *tmp;
                    404:        int count, i;
                    405: 
                    406:        /* First copy the tables into the data space */
                    407:        fkcopy(cscolon(cs_src), fcn_dest, length);
                    408: 
                    409:        /* First do the system level functions */
                    410: 
                    411:        tmp = fcn_dest;
                    412: 
                    413:        FP_SEL(tmp[0]) = FP_SEL(prot);  /* First the start routine */
                    414:        FP_SEL(tmp[1]) = FP_SEL(prot);  /* Next the interrupt routine */
                    415:        FP_SEL(tmp[2]) = FP_SEL(prot);  /* Next the time-out ruutine */
                    416: 
                    417:        /* Then do the individual functions */
                    418: 
                    419:        count = *((int *)(fcn_dest+0x0c));      /* how many functions */
                    420:        for (i=0; i < count; i++)               /* convert each function */
                    421:                if (FP_OFF(tmp[i+4]))
                    422:                        FP_SEL(tmp[i+4]) = FP_SEL(prot); 
                    423: }
                    424: 
                    425: 
                    426: /**
                    427:  *
                    428:  * void
                    429:  * psunload()  - unload routine.
                    430:  */
                    431: static void
                    432: psunload()
                    433: {
                    434:        clrivec(HDIRQ);
                    435: }
                    436: 
                    437: /**
                    438:  *
                    439:  * void
                    440:  * psreset()   -- reset hard disk controller, define drive characteristics.
                    441:  */
                    442: static void
                    443: psreset()
                    444: {
                    445:        ps.ps_state = SRESET;
                    446:        rb.length = 0x80;
                    447:        rb.logical_id = 5;
                    448:        rb.unit = 0;
                    449:        rb.function = 5;
                    450:        rb.reserved = 0L;
                    451:        rb.ret_code = 0xffff;
                    452:        rb.vars.f5.reserved = 0;
                    453: /*     disk_function(START_P); */
                    454:        d2_func(&rb, START_P);
                    455:        while (rb.ret_code == 2)        /* Wait for time */
                    456:        {
                    457:                unsigned long i;
                    458: 
                    459:                printf("PS: reset - %x\n", rb.ret_code);
                    460:                for(i=0L; i < rb.vars.f8.wait_time; i+=4)
                    461:                        ;
                    462: 
                    463:                d2_func(&rb, INTERRUPT_P);
                    464:        }
                    465:        ps.ps_state = SIDLE;
                    466:        if (rb.ret_code != 0)
                    467:                printf("PS: reset failed - %x\n", rb.ret_code);
                    468:        return;
                    469: }
                    470: 
                    471: /**
                    472:  *
                    473:  * void
                    474:  * psopen(dev, mode)
                    475:  * dev_t dev;
                    476:  * int mode;
                    477:  *
                    478:  *     Input:  dev = disk device to be opened.
                    479:  *             mode = access mode [IPR,IPW, IPR+IPW].
                    480:  *
                    481:  *     Action: Validate the minor device.
                    482:  *             Update the paritition table if necessary.
                    483:  */
                    484: static void
                    485: psopen(dev, mode)
                    486: register dev_t dev;
                    487: {
                    488:        register int d;         /* drive */
                    489:        register int p;         /* partition */
                    490: 
                    491:        p = minor(dev) % (NDRIVE*NPARTN);
                    492: 
                    493:        if (minor(dev) & SDEV) {
                    494:                d = minor(dev) % NDRIVE;
                    495:                p += NDRIVE * NPARTN;
                    496:        }
                    497:        else
                    498:                d = minor(dev) / NPARTN;
                    499: 
                    500:        if ((d >= NDRIVE) || (ps.ps_dtype[d] == 0)) {
                    501:                u.u_error = ENXIO;
                    502:                return;
                    503:        }
                    504: 
                    505:        if (minor(dev) & SDEV)
                    506:                return;
                    507: 
                    508:        /*
                    509:         * If partition not defined read partition characteristics.
                    510:         */
                    511:        if (pparm[p].p_size == 0)
                    512:                fdisk(makedev(major(dev), SDEV + d), &pparm[ d * NPARTN ]);
                    513:        /*
                    514:         * Ensure partition lies within drive boundaries and is non-zero size.
                    515:         */
                    516:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
                    517:                u.u_error = EBADFMT;
                    518:        else if (pparm[p].p_size == 0)
                    519:                u.u_error = ENODEV;
                    520: }
                    521: 
                    522: /**
                    523:  *
                    524:  * void
                    525:  * psread(dev, iop)    - read a block from the raw disk
                    526:  * dev_t dev;
                    527:  * IO * iop;
                    528:  *
                    529:  *     Input:  dev = disk device to be written to.
                    530:  *             iop = pointer to source I/O structure.
                    531:  *
                    532:  *     Action: Invoke the common raw I/O processing code.
                    533:  */
                    534: static void
                    535: psread(dev, iop)
                    536: dev_t  dev;
                    537: IO     *iop;
                    538: {
                    539:        ioreq(&dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC);
                    540: }
                    541: 
                    542: /**
                    543:  *
                    544:  * void
                    545:  * pswrite(dev, iop)   - write a block to the raw disk
                    546:  * dev_t dev;
                    547:  * IO * iop;
                    548:  *
                    549:  *     Input:  dev = disk device to be written to.
                    550:  *             iop = pointer to source I/O structure.
                    551:  *
                    552:  *     Action: Invoke the common raw I/O processing code.
                    553:  */
                    554: static void
                    555: pswrite(dev, iop)
                    556: dev_t  dev;
                    557: IO     *iop;
                    558: {
                    559:        ioreq(&dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC);
                    560: }
                    561: 
                    562: /**
                    563:  *
                    564:  * int
                    565:  * psioctl(dev, cmd, arg)
                    566:  * dev_t dev;
                    567:  * int cmd;
                    568:  * char * vec;
                    569:  *
                    570:  *     Input:  dev = disk device to be operated on.
                    571:  *             cmd = input/output request to be performed.
                    572:  *             vec = (pointer to) optional argument.
                    573:  *
                    574:  *     Action: Validate the minor device.
                    575:  *             Update the paritition table if necessary.
                    576:  */
                    577: static int
                    578: psioctl(dev, cmd, vec)
                    579: register dev_t dev;
                    580: int cmd;
                    581: char * vec;
                    582: {
                    583:        int d;
                    584: 
                    585:        /*
                    586:         * Identify drive number.
                    587:         */
                    588:        if (minor(dev) & SDEV)
                    589:                d = minor(dev) % NDRIVE;
                    590:        else
                    591:                d = minor(dev) / NPARTN;
                    592: 
                    593:        /*
                    594:         * Identify input/output request.
                    595:         */
                    596:        switch (cmd) {
                    597: 
                    598:        case HDGETA:
                    599:                /*
                    600:                 * Get hard disk attributes.
                    601:                 */
                    602:                kucopy(&psparm[d], vec, sizeof(psparm[0]));
                    603:                return(0);
                    604: 
                    605:        case HDSETA:
                    606:                return 0;       /* For now, do not allow this */
                    607:                /* Set hard disk pstributes. */
                    608: 
                    609:                ukcopy(vec, &psparm[d], sizeof(psparm[0]));
                    610:                ps.ps_dtype[d] = 1;             /* set drive type nonzero */
                    611:                pparm[NDRIVE * NPARTN + d].p_size = (long) psparm[d].d_ncyl 
                    612:                                * psparm[d].d_nhead * psparm[d].d_nspt;
                    613:                psreset();
                    614:                return 0;
                    615: 
                    616:        default:
                    617:                u.u_error = EINVAL;
                    618:                return(-1);
                    619:        }
                    620: }
                    621: 
                    622: /**
                    623:  *
                    624:  * void
                    625:  * pstimer()           - wait for timeout
                    626:  *
                    627:  *     Action: If drvl[AT_MAJOR] is greater than zero, decrement it.
                    628:  *             If it decrements to zero, call the abios again
                    629:  */
                    630: static void
                    631: pstimer()
                    632: {
                    633:        register int s;
                    634:        
                    635:        s = sphi();
                    636:        if (--drvl[AT_MAJOR].d_time > 0) {
                    637:                spl(s);
                    638:                return;
                    639:        }
                    640:        disk_function(INTERRUPT_P); 
                    641:        spl(s);
                    642: }
                    643: 
                    644: /**
                    645:  *
                    646:  * void
                    647:  * psblock(bp) - queue a block to the disk
                    648:  *
                    649:  *     Input:  bp = pointer to block to be queued.
                    650:  *
                    651:  *     Action: Queue a block to the disk.
                    652:  *             Make sure that the transfer is within the disk partition.
                    653:  */
                    654: static void
                    655: psblock(bp)
                    656: register BUF   *bp;
                    657: {
                    658:        register struct fdisk_s *pp;
                    659:        int partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
                    660: 
                    661:        if (minor(bp->b_dev) & SDEV)
                    662:                partn += NDRIVE * NPARTN;
                    663: 
                    664:        pp = &pparm[ partn ];
                    665: 
                    666:        /*
                    667:         * Check for read at end of partition.
                    668:         */
                    669:        if ((bp->b_req == BREAD) && (bp->b_bno == pp->p_size)) {
                    670:                bdone(bp);
                    671:                return;
                    672:        }
                    673: 
                    674:        /*
                    675:         * Range check disk region.
                    676:         */
                    677:        if (((bp->b_bno + (bp->b_count/BSIZE)) > pp->p_size)
                    678:        || (bp->b_count % BSIZE) || bp->b_count == 0) {
                    679:                bp->b_flag |= BFERR;
                    680:                bdone(bp);
                    681:                return;
                    682:        }
                    683: 
                    684:        bp->b_actf = NULL;
                    685:        if (ps.ps_actf == NULL)
                    686:                ps.ps_actf = bp;
                    687:        else
                    688:                ps.ps_actl->b_actf = bp;
                    689:        ps.ps_actl = bp;
                    690:        if (ps.ps_state == SIDLE)
                    691:                if (psdequeue())
                    692:                        psstart();
                    693: }
                    694: 
                    695: /**
                    696:  *
                    697:  * int
                    698:  * psdequeue()         - obtain next disk read/write operation
                    699:  *
                    700:  *     Action: Pull some work from the disk queue.
                    701:  *
                    702:  *     Return: 0 = no work.
                    703:  *             * = work to do.
                    704:  */
                    705: static int
                    706: psdequeue()
                    707: {
                    708:        register BUF * bp = ps.ps_actf;
                    709:        register struct fdisk_s * pp;
                    710:        unsigned int nspt;
                    711: 
                    712:        ps.ps_caching = 0;
                    713:        ps.ps_tries   = 0;
                    714: 
                    715:        if (bp == NULL)
                    716:                return (0);
                    717: 
                    718:        ps.ps_partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
                    719: 
                    720:        if (minor(bp->b_dev) & SDEV) {
                    721:                ps.ps_partn += (NDRIVE*NPARTN);
                    722:                ps.ps_drv  = minor(bp->b_dev) % NDRIVE;
                    723:        }
                    724:        else
                    725:                ps.ps_drv = minor(bp->b_dev) / NPARTN;
                    726:        nspt = psparm[ps.ps_drv].d_nspt;
                    727: 
                    728:        pp = &pparm[ ps.ps_partn ];
                    729:        ps.ps_bno   = pp->p_base + bp->b_bno;
                    730:        ps.ps_nsec  = bp->b_count / BSIZE;
                    731:        ps.ps_faddr = bp->b_faddr;
                    732:        return (1);
                    733: }
                    734: 
                    735: 
                    736: /**
                    737:  *
                    738:  * void
                    739:  * psstart()   - start or restart next disk read/write operation.
                    740:  *
                    741:  *     Action: Initiate disk read/write operation.
                    742:  */
                    743: static void
                    744: psstart()
                    745: {
                    746:        register struct dparm_s *dp;
                    747: 
                    748:        dp = &psparm[ ps.ps_drv ];
                    749: #if 0
                    750:        ps.ps_cyl  = (ps.ps_bno / dp->d_nspt) / dp->d_nhead;
                    751:        ps.ps_head = (ps.ps_bno / dp->d_nspt) % dp->d_nhead;
                    752:        ps.ps_sec  = (ps.ps_bno % dp->d_nspt) + 1;
                    753: 
                    754:        /*
                    755:         * Check for repeated access to most recently identified bad track.
                    756:         */
                    757:        if ((ps.ps_drv  == ps.ps_bad_drv)
                    758:          && (ps.ps_cyl  == ps.ps_bad_cyl)
                    759:          && (ps.ps_head == ps.ps_bad_head)) {
                    760:                BUF * bp = ps.ps_actf;
                    761:                printf("ps%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>\n",
                    762:                        ps.ps_drv,
                    763:                        (bp->b_dev & SDEV) ? 'x' : ps.ps_partn % NPARTN + 'a',
                    764:                        bp->b_bno,
                    765:                        ps.ps_head,
                    766:                        ps.ps_cyl);
                    767:                bp->b_flag |= BFERR;
                    768:                psdone();
                    769:                return;
                    770:        }
                    771: #endif
                    772:        rb.length = 0x80;
                    773:        rb.logical_id = 5;
                    774:        rb.unit = 0;
                    775:        rb.reserved = 0L;
                    776:        rb.ret_code = 0xffff;
                    777: 
                    778:        /* Note that the items below are set up the same way for a
                    779:         * read or a write. */
                    780:        rb.vars.f8.reserved = 0;
                    781:        rb.vars.f8.reserved1 = 0;
                    782:        rb.vars.f8.dptr = vtop(ps.ps_faddr);
                    783:        rb.vars.f8.reserved2 = 0;
                    784:        rb.vars.f8.rb_address = ps.ps_bno;
                    785:        rb.vars.f8.reserved3 = 0;
                    786:        rb.vars.f8.blocks_read = ps.ps_nsec;
                    787:        rb.vars.f8.caching = 0;
                    788: 
                    789:        if (ps.ps_actf->b_req == BWRITE) {
                    790:                rb.function = 9;
                    791:                ps.ps_state = SWRITE;
                    792:        }
                    793:        else {
                    794:                rb.function = 8;
                    795:                ps.ps_state = SREAD;
                    796: 
                    797:        }
                    798:        disk_function(START_P);
                    799: }
                    800: 
                    801: /**
                    802:  *
                    803:  * void
                    804:  * psintr()    - Interrupt routine.
                    805:  *
                    806:  */
                    807: static void
                    808: psintr()
                    809: {
                    810:        d2_func(&rb, INTERRUPT_P);
                    811:        defer(disk_functionb, 0); 
                    812: }
                    813: 
                    814: /**
                    815:  *
                    816:  * static void
                    817:  * psstatus()
                    818:  *
                    819:  *     Print out appropiate error message
                    820:  */
                    821: static void
                    822: psstatus()
                    823: {
                    824:        register BUF * bp = ps.ps_actf;
                    825: 
                    826:        printf("ps%d%c: bno=%U head=%u cyl=%u <",
                    827:                ps.ps_drv,
                    828:                (bp->b_dev & SDEV) ? 'x' : ps.ps_partn % NPARTN + 'a',
                    829:                (bp->b_count/BSIZE) + bp->b_bno + ps.ps_caching 
                    830:                                - ps.ps_nsec, ps.ps_head, ps.ps_cyl);
                    831: 
                    832:        switch (rb.ret_code | 0x00ff) {
                    833:                case 0x00aa:
                    834:                        printf("Drive Not Ready>");
                    835:                        break;
                    836:                case 0x00cc:
                    837:                        printf("Write Fault>");
                    838:                        break;
                    839:                case 0x0002:
                    840:                        printf("No Data Addr Mark>");
                    841:                        break;
                    842:                case 0x0010:
                    843:                        printf("Bad Data Checksum>");
                    844:                        break;
                    845:                case 0x00a:
                    846:                case 0x00b:
                    847:                        printf("Block Flagged Bad>");
                    848:                        break;
                    849:                default:
                    850:                        printf("Error 0x%x>", rb.ret_code);
                    851:        }
                    852:        printf("\n");
                    853: 
                    854: }
                    855: 
                    856: /**
                    857:  *
                    858:  * void
                    859:  * psdone()
                    860:  *
                    861:  *     Action: Release current i/o buffer to the O/S.
                    862:  */
                    863: static void
                    864: psdone()
                    865: {
                    866:        register BUF * bp = ps.ps_actf;
                    867: 
                    868:        drvl[AT_MAJOR].d_time = 0;
                    869:        ps.ps_state = SIDLE;
                    870:        bdone(bp);
                    871: 
                    872:        ps.ps_actf = bp->b_actf;
                    873: 
                    874:        if (psdequeue())
                    875:                psstart();
                    876: }
                    877: 
                    878: 
                    879: void disk_function(type)
                    880: int type;
                    881: {
                    882: /*     printf("disk function\n"); */
                    883:        d2_func(&rb, type);
                    884:        printf("%s", "");
                    885:        disk_functionb();
                    886: }
                    887: 
                    888: static TIM pstim;
                    889: 
                    890: void disk_functionb()
                    891: {
                    892: /*     printf("rb.ret_code =  %x\r", rb.ret_code); */
                    893:        while (rb.ret_code == 2)        /* Wait for time */
                    894:        {
                    895:                long i;
                    896:                for(i=0L; i < rb.vars.f8.wait_time; i+=128)
                    897:                        ;
                    898: 
                    899:                d2_func(&rb, INTERRUPT_P);
                    900:        }
                    901: 
                    902:        if (rb.ret_code == 0)           /* Finished */
                    903:        {
                    904:                ps.ps_actf->b_resid = 0;
                    905:                psdone();
                    906:        }
                    907:        else if (rb.ret_code == 1)      /* Wat for int */
                    908:        {
                    909:                /*ps.ps_state = SINT; */
                    910:        }
                    911:        else
                    912:        {
                    913:                register BUF *bp = ps.ps_actf;
                    914: 
                    915:                psstatus();
                    916:                bp->b_flag |= BFERR;
                    917:                psdone();
                    918:        }
                    919: }

unix.superglobalmegacorp.com

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