Annotation of 43BSDTahoe/sys/vaxstand/rl.c, revision 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.