Annotation of coherent/d/PS2_KERNEL/io.286/hld/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: 
                     53: /*
                     54:  * Configurable parameters
                     55:  */
                     56: #define        HDIRQ   14                      /* Level 14 */
                     57: #define NDRIVE 2                       /* only two drives supported */
                     58: #define        SOFTLIM 6                       /*  (7) num of retrys before diag */
                     59: #define        HARDLIM 4                       /* number of retrys before fail */
                     60: #define        BADLIM  100                     /* num to stop recov if flagged bad */
                     61: 
                     62: #define        BIT(n)          (1 << (n))
                     63: 
                     64: #define        CMOSA   0x70                    /* write cmos address to this port */
                     65: #define        CMOSD   0x71                    /* read cmos data through this port */
                     66: 
                     67: /*
                     68:  * Driver configuration.
                     69:  */
                     70: void   psload();
                     71: void   psunload();
                     72: void   psopen();
                     73: void   psread();
                     74: void   pswrite();
                     75: int    psioctl();
                     76: void   pstimer();
                     77: void   psblock();
                     78: int    nulldev();
                     79: int    nonedev();
                     80: 
                     81: CON    pscon   = {
                     82:        DFBLK|DFCHR,                    /* Flags */
                     83:        AT_MAJOR,                       /* Major index */
                     84:        psopen,                         /* Open */
                     85:        nulldev,                        /* Close */
                     86:        psblock,                        /* Block */
                     87:        psread,                         /* Read */
                     88:        pswrite,                        /* Write */
                     89:        psioctl,                        /* Ioctl */
                     90:        nulldev,                        /* Powerfail */
                     91:        pstimer,                        /* Timeout */
                     92:        psload,                         /* Load */
                     93:        psunload                        /* Unload */
                     94: };
                     95: 
                     96: /*
                     97:  * Forward Referenced Functions.
                     98:  */
                     99: void   psreset();
                    100: int    psdequeue();
                    101: void   psstart();
                    102: void   psintr();
                    103: int    pserror();
                    104: void   psrecov();
                    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, it7, it15;
                    194: 
                    195: 
                    196: char fcn0[0x10], fcn1[0x50], fcn2[0x40], fcn7[0x50], fcn15[0x58];
                    197: 
                    198: extern int com_data,i0, i1, i2, i7, i15, end_table,
                    199:                        fcn_trn0, fcn_trn1, fcn_trn2, fcn_trn7, fcn_trn15; 
                    200: 
                    201: #define cscolon(d)             ((faddr_t)(0x600000L + (unsigned) (d)))
                    202: #define ftop(d)                        ((paddr_t)(FP_SEL(d)<<4L) + FP_OFF(d))
                    203: #define init_tab_cp(s,r)       fkcopy(cscolon(ffword(cscolon(s))), r, 24)
                    204: 
                    205: /*
                    206:  * Patchable variables.
                    207:  *     PSBSYW is a loop count for busy-waiting after issuing commands.
                    208:  *     PSSECS is number of seconds to wait for an expected interrupt.
                    209:  */
                    210: int    PSBSYW = 50;                    /* patchable */
                    211: int    PSSECS = 6;                     /* patchable */
                    212: 
                    213: /**
                    214:  *
                    215:  * void
                    216:  * psload()    - load routine.
                    217:  *
                    218:  *     Action: The controller is reset and the interrupt vector is grabbed.
                    219:  *             The drive characteristics are set up ps this time.
                    220:  */
                    221: static void
                    222: psload()
                    223: {
                    224:        unsigned int u;
                    225:        register int    s;
                    226:        struct dparm_s * dp;
                    227: 
                    228:        {int i; for (i=0;i<1000; i++);}
                    229:        {int i; for (i=0;i<1000; i++);}
                    230:        {int i; for (i=0;i<1000; i++);}
                    231:        {int i; for (i=0;i<1000; i++);}
                    232:        {int i; for (i=0;i<1000; i++);}
                    233:        {int i; for (i=0;i<1000; i++);}
                    234:        {int i; for (i=0;i<1000; i++);}
                    235:        {int i; for (i=0;i<1000; i++);}
                    236:        {int i; for (i=0;i<1000; i++);}
                    237:        {int i; for (i=0;i<1000; i++);}
                    238:        {int i; for (i=0;i<1000; i++);}
                    239:        {int i; for (i=0;i<1000; i++);}
                    240:        {int i; for (i=0;i<1000; i++);}
                    241:        {int i; for (i=0;i<1000; i++);}
                    242:        {int i; for (i=0;i<1000; i++);}
                    243:        {int i; for (i=0;i<1000; i++);}
                    244:        {int i; for (i=0;i<1000; i++);}
                    245: 
                    246:        printf("loading ps\n");
                    247:        init_abios();
                    248: 
                    249:        n_atdr = 1;
                    250: /*     printf("n_atdr = %d\n", n_atdr); */
                    251: 
                    252:        if (n_atdr == 0)
                    253:                return;
                    254: 
                    255:        ps.ps_actf = NULL; /* Start up with this Null to avoid phony calls */
                    256: 
                    257:        /*
                    258:         * Obtain (hardwire) Drive Types.
                    259:         */
                    260:        ps.ps_dtype[0] = 1;             /* This just means that it exists */
                    261:        ps.ps_dtype[1] = 0;      /* This just means that it doesn't exist */
                    262: 
                    263:        /*
                    264:         * Obtain Drive Characteristics.
                    265:         */
                    266: 
                    267:        for (u = 0, dp = &psparm[0]; u < n_atdr; ++dp, ++u) 
                    268:        {
                    269:                rb.length = 0x80;
                    270:                rb.logical_id = 6;
                    271:                rb.unit = 0;
                    272:                rb.function = 3;
                    273:                rb.reserved = 0L;
                    274:                rb.ret_code = 0xffff;
                    275:                rb.vars.f3.reserved = 0L;
                    276:                d2_func(&rb, START_P);
                    277:                if (rb.ret_code)
                    278:                        printf("\nhard disk function 3 returned = %d\n", 
                    279:                                                                rb.ret_code);
                    280:                dp->d_ncyl = rb.vars.f3.cylinders;
                    281:                dp->d_nhead = rb.vars.f3.heads;
                    282:                dp->d_nspt = rb.vars.f3.sectors_track;
                    283:                dp->d_wpcc = 0xffff;
                    284:                dp->d_landc = rb.vars.f3.cylinders;
                    285:                if (dp->d_nhead > 8)
                    286:                        dp->d_ctrl |= 8;
                    287:  
                    288: #if 0
                    289: 
                    290:        printf(" drive %d parameters\n", u);
                    291:        printf(
                    292:        "ps%d: ncyl=%d nhead=%d wpcc=%d eccl=%d ctrl=%d landc=%d nspt=%d\n",
                    293:                u,
                    294:                dp->d_ncyl,
                    295:                dp->d_nhead,
                    296:                dp->d_wpcc,
                    297:                dp->d_eccl,
                    298:                dp->d_ctrl,
                    299:                dp->d_landc,
                    300:                dp->d_nspt);
                    301:        printf("\nhard disk function 3 returned = %d\n", rb.ret_code);
                    302:        printf("\nretries = %d", rb.vars.f3.retries);
                    303:        printf("\nblock_addresses = %lu", rb.vars.f3.block_addresses);
                    304:        printf("\nmax_blocks = %d\n", rb.vars.f3.max_blocks);
                    305: 
                    306: #endif
                    307:        }
                    308: 
                    309:        /*
                    310:         * Initialize Drive Size.
                    311:         */
                    312:        for (u = 0, dp = &psparm[0]; u < n_atdr; ++dp, ++u) {
                    313: 
                    314:                if (ps.ps_dtype[u] == 0)
                    315:                        continue;
                    316: 
                    317:                pparm[NDRIVE*NPARTN + u].p_size =
                    318:                        (long) dp->d_ncyl * dp->d_nhead * dp->d_nspt;
                    319:        }
                    320: 
                    321: /*     
                    322:        s = sphi(); 
                    323:        spl( s );
                    324: */
                    325:        setivec(HDIRQ, psintr); 
                    326:        
                    327:        ps.ps_bad_drv = -1;
                    328: 
                    329:        /*
                    330:         * Initialize Drive Controller.
                    331:         */
                    332:        psreset();
                    333: }
                    334: 
                    335: paddr_t prot;
                    336: 
                    337: /* This is the protected mode part of the abios initialization */
                    338: init_abios()
                    339: {
                    340:        unsigned int i, count, *tmp1;
                    341:        paddr_t codeseg;
                    342:        paddr_t *tmp;
                    343:        static short done = 0;
                    344: 
                    345:        if (done)               /* Make sure we don't call this twice */
                    346:                return;
                    347: 
                    348:        done++;
                    349: 
                    350:        printf("init_abios_a() = %x\n", iresult());
                    351: 
                    352:        /* First create the virtual pointer to the comm area */
                    353:        com_data_p = ptov(vtop(l_com_data, sds), 0x80L);
                    354: 
                    355:        /* Now copy the common data table into local space */
                    356:        fkcopy(cscolon((unsigned)(&com_data) & 0xfff0), l_com_data, 0x80);
                    357: 
                    358:        /* Now copy the initialization tables into local space */
                    359:        init_tab_cp(&i0,  &it0);
                    360:        init_tab_cp(&i1,  &it1);
                    361:        init_tab_cp(&i7,  &it7);
                    362:        init_tab_cp(&i15, &it15);
                    363:        init_tab_cp(&i2,  &it2);
                    364: /*
                    365:        fkcopy(cscolon(ffword(cscolon(&i0))), &it0, 24);
                    366:        fkcopy(cscolon(ffword(cscolon(&i1))), &it1, 24);
                    367:        fkcopy(cscolon(ffword(cscolon(&i1))), &it7, 24);
                    368:        fkcopy(cscolon(ffword(cscolon(&i15))), &it15, 24);
                    369:        fkcopy(cscolon(ffword(cscolon(&i2))), &it2, 24);
                    370: */
                    371:        /* Now convert each real mode device block pointer into a protected 
                    372:         * mode device block pointer .
                    373:         */
                    374: 
                    375:        tmp = tmp1 = l_com_data;      /* Make thing easier on the compiler */
                    376: 
                    377:        codeseg = ptov(0x0600L,&end_table);/* Set up an r/w alias to the cs */
                    378: 
                    379:                                        /* Fix the segments in the CDA */
                    380:                                        /* the offsets are still ok */
                    381:        tmp1[9] = tmp1[13] = tmp1[17] = tmp1[21] = tmp1[25] = FP_SEL(codeseg);
                    382: 
                    383:        dev1p = tmp[6];
                    384:        dev2p = tmp[12];        /* Set this up so calls are easier later */
                    385:        
                    386:        /* Now fix each function transfer table pointer in the cda so that 
                    387:          * it points to the proper spot in the ds
                    388:         */
                    389:        
                    390:                                        /* Fix the segments in the CDA */
                    391:        tmp1[11] = tmp1[15] = tmp1[19] = tmp1[23] = tmp1[27] = sds;
                    392: 
                    393:        tmp1[10] = (unsigned)fcn0;      /* Now fix the offsets */       
                    394:        tmp1[14] = (unsigned)fcn1;
                    395:        tmp1[18] = (unsigned)fcn7;
                    396:        tmp1[22] = (unsigned)fcn15;
                    397:        tmp1[26] = (unsigned)fcn2;
                    398: 
                    399:        fcn1p = tmp[7];
                    400:        fcn2p = tmp[13];        /* Set this up so calls are easier later */
                    401: 
                    402:        /* Now convert the pointers in the ftts to protected mode pointers */
                    403:                                      /* This is the location of the Abios */
                    404:        prot = ptovx((paddr_t)(0xE0000L)); 
                    405:                                    /* Take out this hardwired number later */
                    406: 
                    407:                                  /* First do the system level functions */
                    408:        cnvt_ptrs(&fcn_trn0, fcn0, it0.ftt_length);
                    409:                                        /* Now do the diskette functions */
                    410:        cnvt_ptrs(&fcn_trn1, fcn1, it1.ftt_length);
                    411:                                           /* Now do the timer functions */
                    412:        cnvt_ptrs(&fcn_trn7, fcn7, it7.ftt_length);
                    413:                                             /* Now do the DMA functions */
                    414:        cnvt_ptrs(&fcn_trn15, fcn15, it15.ftt_length);
                    415:                         /* Finish up with the hard disk functions table */
                    416:        cnvt_ptrs(&fcn_trn2, fcn2, it2.ftt_length);
                    417: 
                    418:        /* Finally,  Convert the data pointers */
                    419: 
                    420:        i = *(int *)l_com_data; /* i is now a pointer to the first pointer */
                    421:        count = *(int *)(l_com_data+i+6);/* count is the # of data pointers*/
                    422:        while (count--)         /* Any more data pointers? */
                    423:        {                       /* Redo the pointer using the saved size */
                    424:                tmp = l_com_data + i + 2;
                    425:                *tmp = ptov(ftop(*tmp),(long)*(unsigned *)(tmp-2));
                    426:                i -= 6;                 /* Now point to the next pointer */
                    427:        }
                    428: 
                    429:        printf("abios inited\n");
                    430: }
                    431: 
                    432: 
                    433: cnvt_ptrs(cs_src, fcn_dest, length)
                    434: int cs_src, length;
                    435: char *fcn_dest;
                    436: {
                    437:        paddr_t *tmp;
                    438:        int count, i;
                    439: 
                    440:        /* First copy the tables into the data space */
                    441:        fkcopy(cscolon(cs_src), fcn_dest, length);
                    442: 
                    443:        /* First do the system level functions */
                    444: 
                    445:        tmp = fcn_dest;
                    446: 
                    447:        FP_SEL(tmp[0]) = FP_SEL(prot);  /* First the start routine */
                    448:        FP_SEL(tmp[1]) = FP_SEL(prot);  /* Next the interrupt routine */
                    449:        FP_SEL(tmp[2]) = FP_SEL(prot);  /* Next the time-out ruutine */
                    450: 
                    451:        /* Then do the individual functions */
                    452: 
                    453:        count = *((int *)(fcn_dest+0x0c));      /* how many functions */
                    454:        for (i=0; i < count; i++)               /* convert each function */
                    455:                if (FP_OFF(tmp[i+4]))
                    456:                        FP_SEL(tmp[i+4]) = FP_SEL(prot); 
                    457: }
                    458: 
                    459: 
                    460: /**
                    461:  *
                    462:  * void
                    463:  * psunload()  - unload routine.
                    464:  */
                    465: static void
                    466: psunload()
                    467: {
                    468:        clrivec(HDIRQ);
                    469: }
                    470: 
                    471: static TIM     psrstlck;
                    472: 
                    473: /**
                    474:  *
                    475:  * void
                    476:  * psreset()   -- reset hard disk controller, define drive characteristics.
                    477:  */
                    478: static void
                    479: psreset()
                    480: {
                    481:        register int s;
                    482: 
                    483:        ps.ps_state = SRESET;
                    484:        rb.length = 0x80;
                    485:        rb.logical_id = 6;
                    486:        rb.unit = 0;
                    487:        rb.function = 5;
                    488:        rb.reserved = 0L;
                    489:        rb.ret_code = 0xffff;
                    490:        rb.vars.f5.reserved = 0;
                    491: 
                    492:        d2_func(&rb, START_P);
                    493: 
                    494:        while (rb.ret_code == 2)        /* Wait for time */
                    495:        {
                    496:                unsigned long i;
                    497: 
                    498:                for(i=0L; i < rb.vars.f8.wait_time; i+=8)
                    499:                        ;
                    500:                d2_func(&rb, INTERRUPT_P); 
                    501:        }
                    502: 
                    503:        ps.ps_state = SIDLE;
                    504:        if (rb.ret_code != 0)
                    505:                printf("PS: reset failed - %x\n", rb.ret_code);
                    506:        return;
                    507: #if 0
                    508:        disk_function(START_P); 
                    509: 
                    510:        s = sphi();
                    511:        while ((rb.ret_code == 1) || (rb.ret_code == 2))
                    512:                sleep(&psrstlck, CVWAIT, IVWAIT, SVWAIT);
                    513:        spl( s );
                    514: 
                    515:        ps.ps_state = SIDLE;
                    516:        if (rb.ret_code != 0)
                    517:                printf("PS: reset failed - %u\n", rb.ret_code);
                    518:        return;
                    519: #endif
                    520: }
                    521: 
                    522: /**
                    523:  *
                    524:  * void
                    525:  * psopen(dev, mode)
                    526:  * dev_t dev;
                    527:  * int mode;
                    528:  *
                    529:  *     Input:  dev = disk device to be opened.
                    530:  *             mode = access mode [IPR,IPW, IPR+IPW].
                    531:  *
                    532:  *     Action: Validate the minor device.
                    533:  *             Update the paritition table if necessary.
                    534:  */
                    535: static void
                    536: psopen(dev, mode)
                    537: register dev_t dev;
                    538: {
                    539:        register int d;         /* drive */
                    540:        register int p;         /* partition */
                    541: 
                    542:        p = minor(dev) % (NDRIVE*NPARTN);
                    543: 
                    544:        if (minor(dev) & SDEV) {
                    545:                d = minor(dev) % NDRIVE;
                    546:                p += NDRIVE * NPARTN;
                    547:        }
                    548:        else
                    549:                d = minor(dev) / NPARTN;
                    550: 
                    551:        if ((d >= NDRIVE) || (ps.ps_dtype[d] == 0)) {
                    552:                u.u_error = ENXIO;
                    553:                return;
                    554:        }
                    555: 
                    556:        if (minor(dev) & SDEV)
                    557:                return;
                    558: 
                    559:        /*
                    560:         * If partition not defined read partition characteristics.
                    561:         */
                    562:        if (pparm[p].p_size == 0)
                    563:                fdisk(makedev(major(dev), SDEV + d), &pparm[ d * NPARTN ]);
                    564:        /*
                    565:         * Ensure partition lies within drive boundaries and is non-zero size.
                    566:         */
                    567:        if ((pparm[p].p_base+pparm[p].p_size) > pparm[d+NDRIVE*NPARTN].p_size)
                    568:                u.u_error = EBADFMT;
                    569:        else if (pparm[p].p_size == 0)
                    570:                u.u_error = ENODEV;
                    571: }
                    572: 
                    573: /**
                    574:  *
                    575:  * void
                    576:  * psread(dev, iop)    - read a block from the raw disk
                    577:  * dev_t dev;
                    578:  * IO * iop;
                    579:  *
                    580:  *     Input:  dev = disk device to be written to.
                    581:  *             iop = pointer to source I/O structure.
                    582:  *
                    583:  *     Action: Invoke the common raw I/O processing code.
                    584:  */
                    585: static void
                    586: psread(dev, iop)
                    587: dev_t  dev;
                    588: IO     *iop;
                    589: {
                    590:        ioreq(&dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC);
                    591: }
                    592: 
                    593: /**
                    594:  *
                    595:  * void
                    596:  * pswrite(dev, iop)   - write a block to the raw disk
                    597:  * dev_t dev;
                    598:  * IO * iop;
                    599:  *
                    600:  *     Input:  dev = disk device to be written to.
                    601:  *             iop = pointer to source I/O structure.
                    602:  *
                    603:  *     Action: Invoke the common raw I/O processing code.
                    604:  */
                    605: static void
                    606: pswrite(dev, iop)
                    607: dev_t  dev;
                    608: IO     *iop;
                    609: {
                    610:        ioreq(&dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC);
                    611: }
                    612: 
                    613: /**
                    614:  *
                    615:  * int
                    616:  * psioctl(dev, cmd, arg)
                    617:  * dev_t dev;
                    618:  * int cmd;
                    619:  * char * vec;
                    620:  *
                    621:  *     Input:  dev = disk device to be operated on.
                    622:  *             cmd = input/output request to be performed.
                    623:  *             vec = (pointer to) optional argument.
                    624:  *
                    625:  *     Action: Validate the minor device.
                    626:  *             Update the paritition table if necessary.
                    627:  */
                    628: static int
                    629: psioctl(dev, cmd, vec)
                    630: register dev_t dev;
                    631: int cmd;
                    632: char * vec;
                    633: {
                    634:        int d;
                    635: 
                    636:        /*
                    637:         * Identify drive number.
                    638:         */
                    639:        if (minor(dev) & SDEV)
                    640:                d = minor(dev) % NDRIVE;
                    641:        else
                    642:                d = minor(dev) / NPARTN;
                    643: 
                    644:        /*
                    645:         * Identify input/output request.
                    646:         */
                    647:        switch (cmd) {
                    648: 
                    649:        case HDGETA:
                    650:                /*
                    651:                 * Get hard disk attributes.
                    652:                 */
                    653:                kucopy(&psparm[d], vec, sizeof(psparm[0]));
                    654:                return(0);
                    655: 
                    656:        case HDSETA:
                    657:                return 0;       /* For now, do not allow this */
                    658:                /* Set hard disk pstributes. */
                    659:                ukcopy(vec, &psparm[d], sizeof(psparm[0]));
                    660:                ps.ps_dtype[d] = 1;             /* set drive type nonzero */
                    661:                pparm[NDRIVE * NPARTN + d].p_size = (long) psparm[d].d_ncyl 
                    662:                                * psparm[d].d_nhead * psparm[d].d_nspt;
                    663:                psreset();
                    664:                return 0;
                    665: 
                    666:        default:
                    667:                u.u_error = EINVAL;
                    668:                return(-1);
                    669:        }
                    670: }
                    671: 
                    672: /**
                    673:  *
                    674:  * void
                    675:  * pstimer()           - wait for timeout
                    676:  *
                    677:  *     Action: If drvl[AT_MAJOR] is greater than zero, decrement it.
                    678:  *             If it decrements to zero, call the abios again
                    679:  */
                    680: static void
                    681: pstimer()
                    682: {
                    683:        register int s;
                    684:        
                    685:        s = sphi();
                    686:        if (--drvl[AT_MAJOR].d_time > 0) {
                    687:                spl(s);
                    688:                return;
                    689:        }
                    690:        disk_function(INTERRUPT_P); 
                    691:        spl(s);
                    692: }
                    693: 
                    694: /**
                    695:  *
                    696:  * void
                    697:  * psblock(bp) - queue a block to the disk
                    698:  *
                    699:  *     Input:  bp = pointer to block to be queued.
                    700:  *
                    701:  *     Action: Queue a block to the disk.
                    702:  *             Make sure that the transfer is within the disk partition.
                    703:  */
                    704: static void
                    705: psblock(bp)
                    706: register BUF   *bp;
                    707: {
                    708:        register struct fdisk_s *pp;
                    709:        int partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
                    710: 
                    711:        if (minor(bp->b_dev) & SDEV)
                    712:                partn += NDRIVE * NPARTN;
                    713: 
                    714:        pp = &pparm[ partn ];
                    715: 
                    716:        /*
                    717:         * Check for read at end of partition.
                    718:         */
                    719:        if ((bp->b_req == BREAD) && (bp->b_bno == pp->p_size)) {
                    720:                bdone(bp);
                    721:                return;
                    722:        }
                    723: 
                    724:        /*
                    725:         * Range check disk region.
                    726:         */
                    727:        if (((bp->b_bno + (bp->b_count/BSIZE)) > pp->p_size)
                    728:        || (bp->b_count % BSIZE) || bp->b_count == 0) {
                    729:                bp->b_flag |= BFERR;
                    730:                bdone(bp);
                    731:                return;
                    732:        }
                    733: 
                    734:        bp->b_actf = NULL;
                    735:        if (ps.ps_actf == NULL)
                    736:                ps.ps_actf = bp;
                    737:        else
                    738:                ps.ps_actl->b_actf = bp;
                    739:        ps.ps_actl = bp;
                    740:        if (ps.ps_state == SIDLE)
                    741:                if (psdequeue())
                    742:                        psstart();
                    743: }
                    744: 
                    745: /**
                    746:  *
                    747:  * int
                    748:  * psdequeue()         - obtain next disk read/write operation
                    749:  *
                    750:  *     Action: Pull some work from the disk queue.
                    751:  *
                    752:  *     Return: 0 = no work.
                    753:  *             * = work to do.
                    754:  */
                    755: static int
                    756: psdequeue()
                    757: {
                    758:        register BUF * bp = ps.ps_actf;
                    759:        register struct fdisk_s * pp;
                    760:        unsigned int nspt;
                    761: 
                    762:        ps.ps_caching = 0;
                    763:        ps.ps_tries   = 0;
                    764: 
                    765:        if (bp == NULL)
                    766:                return (0);
                    767: 
                    768:        ps.ps_partn = minor(bp->b_dev) % (NDRIVE*NPARTN);
                    769: 
                    770:        if (minor(bp->b_dev) & SDEV) {
                    771:                ps.ps_partn += (NDRIVE*NPARTN);
                    772:                ps.ps_drv  = minor(bp->b_dev) % NDRIVE;
                    773:        }
                    774:        else
                    775:                ps.ps_drv = minor(bp->b_dev) / NPARTN;
                    776:        nspt = psparm[ps.ps_drv].d_nspt;
                    777: 
                    778:        pp = &pparm[ ps.ps_partn ];
                    779:        ps.ps_bno   = pp->p_base + bp->b_bno;
                    780:        ps.ps_nsec  = bp->b_count / BSIZE;
                    781:        ps.ps_faddr = bp->b_faddr;
                    782:        return (1);
                    783: }
                    784: 
                    785: 
                    786: /**
                    787:  *
                    788:  * void
                    789:  * psstart()   - start or restart next disk read/write operation.
                    790:  *
                    791:  *     Action: Initiate disk read/write operation.
                    792:  */
                    793: static void
                    794: psstart()
                    795: {
                    796:        register struct dparm_s *dp;
                    797: 
                    798:        dp = &psparm[ ps.ps_drv ];
                    799: #if 0
                    800:        ps.ps_cyl  = (ps.ps_bno / dp->d_nspt) / dp->d_nhead;
                    801:        ps.ps_head = (ps.ps_bno / dp->d_nspt) % dp->d_nhead;
                    802:        ps.ps_sec  = (ps.ps_bno % dp->d_nspt) + 1;
                    803: 
                    804:        /*
                    805:         * Check for repeated access to most recently identified bad track.
                    806:         */
                    807:        if ((ps.ps_drv  == ps.ps_bad_drv)
                    808:          && (ps.ps_cyl  == ps.ps_bad_cyl)
                    809:          && (ps.ps_head == ps.ps_bad_head)) {
                    810:                BUF * bp = ps.ps_actf;
                    811:                printf("ps%d%c: bno=%U head=%u cyl=%u <Track Flagged Bad>\n",
                    812:                        ps.ps_drv,
                    813:                        (bp->b_dev & SDEV) ? 'x' : ps.ps_partn % NPARTN + 'a',
                    814:                        bp->b_bno,
                    815:                        ps.ps_head,
                    816:                        ps.ps_cyl);
                    817:                bp->b_flag |= BFERR;
                    818:                psdone();
                    819:                return;
                    820:        }
                    821: #endif
                    822:        rb.length = 0x80;
                    823:        rb.logical_id = 6;
                    824:        rb.unit = 0;
                    825:        rb.reserved = 0L;
                    826:        rb.ret_code = 0xffff;
                    827: 
                    828:        /* Note that the items below are set up the same way for a
                    829:         * read or a write. */
                    830:        rb.vars.f8.reserved = 0;
                    831:        rb.vars.f8.reserved1 = 0;
                    832:        rb.vars.f8.dptr = vtop(ps.ps_faddr);
                    833:        rb.vars.f8.reserved2 = 0;
                    834:        rb.vars.f8.rb_address = ps.ps_bno;
                    835:        rb.vars.f8.reserved3 = 0;
                    836:        rb.vars.f8.blocks_read = ps.ps_nsec;
                    837:        rb.vars.f8.caching = 0;
                    838:        if (ps.ps_actf->b_req == BWRITE) {
                    839:                rb.function = 9;
                    840:                ps.ps_state = SWRITE;
                    841:        }
                    842:        else {
                    843:                rb.function = 8;
                    844:                ps.ps_state = SREAD;
                    845: 
                    846:        }
                    847:        disk_function(START_P);
                    848: }
                    849: 
                    850: /**
                    851:  *
                    852:  * void
                    853:  * psintr()    - Interrupt routine.
                    854:  *
                    855:  */
                    856: static void
                    857: psintr()
                    858: {
                    859:        d2_func(&rb, INTERRUPT_P);
                    860:        defer(disk_functionb, 0); 
                    861: }
                    862: 
                    863: /**
                    864:  *
                    865:  * int
                    866:  * pserror()
                    867:  *
                    868:  *     Action: Check for drive error.
                    869:  *             If found, increment error count and report it.
                    870:  *
                    871:  *     Return: 0 = No error found.
                    872:  *             1 = Error occurred.
                    873:  */
                    874: static int
                    875: pserror()
                    876: {
                    877:        register BUF * bp = ps.ps_actf;
                    878: 
                    879:        if (rb.ret_code <= 2)
                    880:                return 0;       /* For now, do nothing */
                    881:        else 
                    882:        {
                    883:                printf("ps%d%c: bno=%U head=%u cyl=%u error=%x",
                    884:                        ps.ps_drv,
                    885:                        (bp->b_dev & SDEV) ? 'x' : ps.ps_partn % NPARTN + 'a',
                    886:                        (bp->b_count/BSIZE) + bp->b_bno
                    887:                                + ps.ps_caching - ps.ps_nsec,
                    888:                        ps.ps_head, ps.ps_cyl, rb.ret_code);
                    889:                return rb.ret_code;
                    890:        }
                    891:                
                    892: #if 0
                    893:        if ((csr = inb(HF_REG)) & (ERR_ST|WFLT_ST)) {
                    894: 
                    895:                aux = inb(AUX_REG);
                    896: 
                    897:                if (aux & BAD_ERR) {
                    898:                        ps.ps_tries     = BADLIM;
                    899:                        ps.ps_bad_drv   = ps.ps_drv;
                    900:                        ps.ps_bad_head  = ps.ps_head;
                    901:                        ps.ps_bad_cyl   = ps.ps_cyl;
                    902:                }
                    903:                else if (++ps.ps_tries < SOFTLIM)
                    904:                        return 1;
                    905: 
                    906:                printf("ps%d%c: bno=%U head=%u cyl=%u",
                    907:                        ps.ps_drv,
                    908:                        (bp->b_dev & SDEV) ? 'x' : ps.ps_partn % NPARTN + 'a',
                    909:                        (bp->b_count/BSIZE) + bp->b_bno
                    910:                                + ps.ps_caching - ps.ps_nsec,
                    911:                        ps.ps_head, ps.ps_cyl);
                    912: 
                    913: #if VERBOSE > 0
                    914:                if ((csr & RDY_ST) == 0)
                    915:                        printf(" <Drive Not Ready>");
                    916:                if (csr & WFLT_ST)
                    917:                        printf(" <Write Fault>");
                    918: 
                    919:                if (aux & DAM_ERR)
                    920:                        printf(" <No Data Addr Mark>");
                    921:                if (aux & TR0_ERR)
                    922:                        printf(" <Track 0 Not Found>");
                    923:                if (aux & ID_ERR)
                    924:                        printf(" <ID Not Found>");
                    925:                if (aux & ECC_ERR)
                    926:                        printf(" <Bad Data Checksum>");
                    927:                if (aux & ABT_ERR)
                    928:                        printf(" <Command Aborted>");
                    929: #else
                    930:                if ((csr & (RDY_ST|WFLT_ST)) != RDY_ST)
                    931:                        printf(" csr=%x", csr);
                    932:                if (aux & (DAM_ERR|TR0_ERR|ID_ERR|ECC_ERR|ABT_ERR))
                    933:                        printf(" aux=%x", aux);
                    934: #endif
                    935:                if (aux & BAD_ERR)
                    936:                        printf(" <Block Flagged Bad>");
                    937: 
                    938:                if (ps.ps_tries < HARDLIM)
                    939:                        printf(" retrying...");
                    940:                printf("\n");
                    941:                return 1;
                    942:        }
                    943:        return 0;
                    944: #endif
                    945: }
                    946: 
                    947: /**
                    948:  *
                    949:  * void
                    950:  * psrecov()
                    951:  *
                    952:  *     Action: Attempt recovery.
                    953:  */
                    954: static void
                    955: psrecov()
                    956: {
                    957:        register BUF *bp = ps.ps_actf;
                    958:        if (ps.ps_tries < HARDLIM) {
                    959:                ps.ps_tries++;
                    960:                psdequeue();
                    961:                psstart();
                    962:        }
                    963: 
                    964:        /*
                    965:         * Give up on block.
                    966:         */
                    967:        else {
                    968:                bp->b_flag |= BFERR;
                    969:                psdone();
                    970:        }
                    971: }
                    972: 
                    973: /**
                    974:  *
                    975:  * void
                    976:  * psdone()
                    977:  *
                    978:  *     Action: Release current i/o buffer to the O/S.
                    979:  */
                    980: static void
                    981: psdone()
                    982: {
                    983:        register BUF * bp = ps.ps_actf;
                    984: 
                    985:        drvl[AT_MAJOR].d_time = 0;
                    986:        ps.ps_state = SIDLE;
                    987:        bdone(bp);
                    988: 
                    989:        ps.ps_actf = bp->b_actf;
                    990: 
                    991:        if (psdequeue())
                    992:                psstart();
                    993: }
                    994: 
                    995: 
                    996: void disk_function(type)
                    997: int type;
                    998: {
                    999:        d2_func(&rb, type);
                   1000:        disk_functionb();
                   1001: }
                   1002: 
                   1003: static TIM pstim;
                   1004: 
                   1005: void disk_functionb()
                   1006: {
                   1007: static int test=0;
                   1008:        while (rb.ret_code == 2)        /* Wait for time */
                   1009:        {
                   1010: test++;
                   1011: if (test > 1) printf("%");
                   1012: /*             timeout(&pstim, 1, wakeup, (int)&pstim);
                   1013:                sleep((char *)&pstim, CVTTOUT, IVTTOUT, SVTTOUT);
                   1014: */
                   1015: {
                   1016: long i;
                   1017:        for(i=0L; i < rb.vars.f8.wait_time; i+=64)
                   1018:                ;
                   1019: }
                   1020:                d2_func(&rb, INTERRUPT_P);
                   1021:        }
                   1022: test=0;
                   1023:        if (rb.ret_code == 0)           /* Finished */
                   1024:        {
                   1025:                if (ps.ps_state != SRESET) 
                   1026:                {
                   1027:                        ps.ps_actf->b_resid = 0;
                   1028:                        psdone();
                   1029:                }
                   1030:                else
                   1031:                        wakeup(&psrstlck);
                   1032:        }
                   1033:        else if (rb.ret_code == 1)      /* Wat for int */
                   1034:        {
                   1035:                /*ps.ps_state = SINT; */
                   1036:        }
                   1037:        else
                   1038:        {
                   1039:                printf("PS: error %x in %s.\n", rb.ret_code, 
                   1040:                                        smsg[ps.ps_state]);
                   1041:                psrecov();
                   1042:        }
                   1043: 
                   1044: }

unix.superglobalmegacorp.com

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