Annotation of 43BSDTahoe/sys/vaxstand/rl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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