Annotation of 42BSD/sys/stand/rl.c, revision 1.1.1.1

1.1       root        1: /*     rl.c    6.1     83/07/29        */
                      2: 
                      3: /*
                      4:  * Standalone RL02 disk driver
                      5:  */
                      6: #include "../machine/pte.h"
                      7: 
                      8: #include "../h/param.h"
                      9: #include "../h/inode.h"
                     10: #include "../h/fs.h"
                     11: 
                     12: #include "../vaxuba/rlreg.h"
                     13: #include "../vaxuba/ubareg.h"
                     14: 
                     15: #include "saio.h"
                     16: #include "savax.h"
                     17: 
                     18: u_short        rlstd[] = { 0774400 };
                     19: short  rl_off[] = { 0, 361, 0, -1, -1, -1, -1, -1 };
                     20: 
                     21: /* struct to keep state info about the controller */
                     22: struct rl_stat {
                     23:        short   rl_dn;          /* drive number */
                     24:        short   rl_cylnhd;      /* cylinder and head */
                     25:        u_short rl_bleft;       /* bytes left to transfer */
                     26:        u_short rl_bpart;       /* bytes transferred */
                     27: } rl_stat[] = { -1, 0, 0, 0};
                     28: 
                     29: rlopen(io)
                     30:        register struct iob *io;
                     31: {
                     32:        register struct rldevice *rladdr =
                     33:                (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
                     34:        register struct rl_stat *st = &rl_stat[0];
                     35:        register int ctr = 0;
                     36: 
                     37:        if (rl_off[io->i_boff] == -1 ||
                     38:            io->i_boff < 0 || io->i_boff > 7)
                     39:                _stop("rl bad unit");
                     40: 
                     41:        /*
                     42:         * DEC reports that:
                     43:         * For some unknown reason the RL02 (seems to be only drive 1)
                     44:         * does not return a valid drive status the first time that a
                     45:         * GET STATUS request is issued for the drive, in fact it can
                     46:         * take up to three or more GET STATUS requests to obtain the
                     47:         * correct status.
                     48:         * In order to overcome this, the driver has been modified to
                     49:         * issue a GET STATUS request and validate the drive status
                     50:         * returned.  If a valid status is not returned after eight
                     51:         * attempts, then an error message is printed.
                     52:         */
                     53:        do {
                     54:                rladdr->rlda.getstat = RL_RESET;
                     55:                rladdr->rlcs = (io->i_unit <<8) | RL_GETSTAT; /* Get status*/
                     56:                rlwait(rladdr);
                     57:        } while( (rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8 );
                     58: 
                     59:        if ((rladdr->rlcs & RL_DE) || (ctr >= 8))
                     60:                _stop("rl unit does not respond");
                     61: 
                     62:        if ((rladdr->rlmp.getstat & RLMP_DT) == 0 )     /* NO RL01'S */
                     63:                _stop("rl01 unit not supported");
                     64: 
                     65:        /* Determine disk posistion */
                     66:        rladdr->rlcs = (io->i_unit << 8) | RL_RHDR;
                     67:        rlwait(rladdr);
                     68: 
                     69:        /* save disk drive posistion */
                     70:        st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6;
                     71:        st->rl_dn = io->i_unit;
                     72: 
                     73:        /* byte offset for cylinder desired */
                     74:        io->i_boff = rl_off[io->i_boff] * NRLBPSC * NRLTRKS * NRLSECT;
                     75: }
                     76: 
                     77: rlstrategy(io, func)
                     78:        register struct iob *io;
                     79: {
                     80:        register struct rldevice *rladdr =
                     81:                (struct rldevice *)ubamem(io->i_unit, rlstd[0]);
                     82:        register struct rl_stat *st = &rl_stat[0];
                     83:        int com;
                     84:        daddr_t bn;
                     85:        short cn, sn, head;
                     86:        int diff, ubinfo, ubaddr, errcnt = 0;
                     87: 
                     88: retry:
                     89:        ubinfo = ubasetup(io, 1);
                     90:        bn = io->i_bn;          /* block number */
                     91:        cn = bn / 40;           /* 40 512 byte blocks per cylinder */
                     92:        sn = (bn % 20) << 1;
                     93:        head = (bn / 20) & 1;
                     94:        st->rl_bleft = io->i_cc;        /* total number of bytes to trans */
                     95:        ubaddr = ubinfo;
                     96: 
                     97: stupid_rl:
                     98:        /* find out how many cylinders to seek */
                     99:        diff = (st->rl_cylnhd >> 1) - cn;
                    100:        if ( diff == 0 && (st->rl_cylnhd & 1) == head )
                    101:                goto noseek;
                    102: 
                    103:        /* first time or we switched drives */
                    104:        st->rl_dn = io->i_unit; /* drive number */
                    105: 
                    106:        if ( diff < 0 )
                    107:                rladdr->rlda.seek = -diff<<7 | RLDA_HGH | head << 4;
                    108:        else
                    109:                rladdr->rlda.seek = diff<<7 | RLDA_LOW | head << 4;
                    110:        rladdr->rlcs = (st->rl_dn << 8) | RL_SEEK;
                    111: 
                    112:        /* reset position of drive */
                    113:        st->rl_cylnhd = (cn << 1) | head;
                    114: 
                    115: noseek:
                    116:        /* wait for controller and drive */
                    117:        while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY)
                    118:                continue;
                    119: 
                    120:        /* calculate the max number of bytes we can trans */
                    121:        st->rl_bpart = NRLSECT * NRLBPSC - (sn * NRLBPSC);
                    122:        if ( st->rl_bleft < st->rl_bpart )
                    123:                st->rl_bpart = st->rl_bleft;
                    124: 
                    125:        rladdr->rlda.rw = (st->rl_cylnhd << 6) | sn;
                    126:        rladdr->rlmp.rw = -(st->rl_bpart >> 1);
                    127:        rladdr->rlba = ubaddr;
                    128: 
                    129:        com = (st->rl_dn << 8) | ((ubaddr>>12)&RL_BAE);
                    130: 
                    131:        if (func == READ)
                    132:                com |= RL_READ;
                    133:        else
                    134:                com |= RL_WRITE;
                    135:        rladdr->rlcs = com;
                    136: 
                    137:        /* wait for controller and drive */
                    138:        while( (rladdr->rlcs & RL_DCRDY) != RL_DCRDY)
                    139:                continue;
                    140: 
                    141:        if (rladdr->rlcs & RL_ERR) {
                    142:                int status;
                    143: 
                    144:                if ( rladdr->rlcs & RL_DE ) {
                    145:                        rladdr->rlda.getstat = RL_GSTAT;
                    146:                        rladdr->rlcs = (st->rl_dn << 8) | RL_GETSTAT;
                    147:                        rlwait(rladdr);
                    148:                        status = rladdr->rlmp.getstat;
                    149:                        rladdr->rlda.getstat = RL_RESET;
                    150:                        rladdr->rlcs = (st->rl_dn <<8) | RL_GETSTAT;
                    151:                        rlwait(rladdr);
                    152:                }
                    153:                printf("rl error: (cyl,head,sec)=(%d,%d,%d) cs=%b mp=%b\n",
                    154:                    cn, head, sn, rladdr->rlcs & 0xffff, RLCS_BITS,
                    155:                    status, RLER_BITS);
                    156: 
                    157:                /* Determine disk posistion */
                    158:                rladdr->rlcs = (st->rl_dn << 8) | RL_RHDR;
                    159:                rlwait(rladdr);
                    160: 
                    161:                /* save disk drive posistion */
                    162:                st->rl_cylnhd = (rladdr->rlmp.readhdr & 0177700) >> 6;
                    163: 
                    164:                if (errcnt == 10) {
                    165:                        printf("rl: unrecovered error\n");
                    166:                        return (-1);
                    167:                }
                    168:                errcnt++;
                    169:                goto retry;
                    170:        }
                    171: 
                    172:        /* do we have to finish off the rest of the transfer? */
                    173:        if ( (st->rl_bleft -= st->rl_bpart) > 0 ) {
                    174:                /* increment head and/or cylinder */
                    175:                if ( ++head > 1 ) {
                    176:                        cn++;           /* want next cyl, head 0 sector 0 */
                    177:                        head = 0;
                    178:                }
                    179: 
                    180:                /* we always want sector to be zero */
                    181:                sn = 0;
                    182: 
                    183:                /*
                    184:                 * standalone code for ubafree does what regular
                    185:                 *   ubapurge does and we want to purge last transfer
                    186:                 */
                    187:                ubafree(io, ubinfo);
                    188: 
                    189:                ubaddr = ubinfo + io->i_cc - st->rl_bleft;
                    190: 
                    191:                goto stupid_rl;
                    192:        }
                    193: 
                    194:        ubafree(io, ubinfo);
                    195: 
                    196:        if (errcnt)
                    197:                printf("rl: recovered by retry\n");
                    198:        return (io->i_cc);
                    199: }
                    200: 
                    201: rlwait(rladdr)
                    202:        register struct rldevice *rladdr;
                    203: {
                    204: 
                    205:        while ((rladdr->rlcs & RL_CRDY) == 0)
                    206:                continue;
                    207: }
                    208: 
                    209: rlioctl(io, cmd, arg)
                    210:        struct iob *io;
                    211:        int cmd;
                    212:        caddr_t arg;
                    213: {
                    214: 
                    215:        return (ECMD);
                    216: }

unix.superglobalmegacorp.com

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