Annotation of researchv9/sys/boot/stand/xy.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * @(#)xy.c 1.1 86/02/03 Copyright (c) 1986 by Sun Microsystems, Inc.
        !             3:  */
        !             4: 
        !             5: /* Standalone driver for Xylogics 440/450 */
        !             6: 
        !             7: #include "saio.h"
        !             8: #include "param.h"
        !             9: #include "../h/dkbad.h"
        !            10: #include "../sun/dklabel.h"
        !            11: #include "../sun/dkio.h"
        !            12: #include "../ufs/fsdir.h"
        !            13: #include "../sundev/xycreg.h"
        !            14: #include "../sundev/xyreg.h"
        !            15: 
        !            16: extern char    msg_nolabel[];
        !            17: 
        !            18: struct xyparam {
        !            19:        unsigned short  xy_boff;        /* Cyl # starting partition */
        !            20:        unsigned short  xy_nsect;       /* Sect/track */
        !            21:        unsigned short  xy_ncyl;        /* Cyl/disk */
        !            22:        unsigned short  xy_nhead;       /* Heads/cyl */
        !            23:        unsigned short  xy_bhead;       /* Base head # for removable disk */
        !            24:        unsigned short  xy_drive;       /* Xylogics drive type ID */
        !            25:        int     xy_nblk;
        !            26:        int     xy_badaddr;             /* Disk block # of bad-block table */
        !            27:        struct dkbad xy_bad;
        !            28:        unsigned char   xy_unit;
        !            29: };
        !            30: 
        !            31: #define CYL(p)  (p*xyp->xy_nsect*xyp->xy_nhead)     /* cyl to block conv */
        !            32: 
        !            33: #define NSTD   2
        !            34: unsigned long xystd[NSTD] = { 0xee40, 0xee48 };
        !            35: 
        !            36: /*
        !            37:  * Structure of our DMA area
        !            38:  */
        !            39: struct xydma {
        !            40:        struct xyiopb   xyiopb;
        !            41:        char            xyblock[MAXBSIZE];      /* R/W data */
        !            42: };
        !            43: 
        !            44: /*
        !            45:  * What resources we need to run
        !            46:  */
        !            47: struct devinfo xyinfo = {
        !            48:        sizeof (struct xydevice), 
        !            49:        sizeof (struct xydma),
        !            50:        sizeof (struct xyparam),
        !            51:        NSTD,
        !            52:        xystd,
        !            53:        MAP_MBIO,
        !            54: #ifdef BOOTBLOCK
        !            55:        DEV_BSIZE,
        !            56: #else
        !            57:        DEV_BSIZE,      /* MAXBSIZE, */
        !            58: #endif
        !            59: };
        !            60: 
        !            61: /*
        !            62:  * What facilities we export to the world
        !            63:  */
        !            64: int    xyopen(), xystrategy();
        !            65: extern int     xxboot(), xxprobe();
        !            66: extern int     nullsys();
        !            67: 
        !            68: struct boottab xydriver = {
        !            69:        "xy",   xxprobe, xxboot, xyopen, nullsys, xystrategy,
        !            70:        "xy: Xylogics 440/450 disk", &xyinfo,
        !            71: }; 
        !            72: 
        !            73: 
        !            74: /*
        !            75:  * Open a xylogics disk.
        !            76:  */
        !            77: xyopen(sip)
        !            78:        register struct saioreq *sip;
        !            79: {
        !            80:        register struct xyparam *xyp;
        !            81:        register struct xydevice *xyaddr;
        !            82:        register struct xyiopb *xy;
        !            83:        struct dk_label *label;
        !            84:        register int i, t;
        !            85:        u_short ppart;
        !            86: #ifndef BOOTBLOCK
        !            87:        int xyspin();
        !            88: #endif !BOOTBLOCK
        !            89: 
        !            90:        xyp = (struct xyparam *)sip->si_devdata;
        !            91:        xyaddr = (struct xydevice *)sip->si_devaddr;
        !            92:        xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
        !            93: 
        !            94:        xyp->xy_unit = sip->si_unit & 0x03;
        !            95:        ppart = (sip->si_unit >> 2) & 1;
        !            96: 
        !            97:        /* reset controller */
        !            98:        i = xyaddr->xy_resupd;
        !            99: #ifdef lint
        !           100:        i = i;          /* Avoid complaint about "set but not used" */
        !           101: #endif
        !           102:        DELAY(100);     /* Allow for controller recovery time */
        !           103: 
        !           104:        xyp->xy_boff  = 0;              /* Don't offset block numbers */
        !           105:        xyp->xy_nsect = 2;
        !           106:        xyp->xy_nhead = 2;
        !           107:        xyp->xy_ncyl = 2;
        !           108:        xyp->xy_bad.bt_mbz = -1;
        !           109: 
        !           110: #ifndef BOOTBLOCK
        !           111:        /*
        !           112:         * Wait for disk to spin up, if necessary.
        !           113:         */
        !           114:        if (!isspinning(xyspin, (char *)sip, 0))
        !           115:                return (-1);
        !           116: #endif !BOOTBLOCK
        !           117: 
        !           118:        for (xyp->xy_drive = 0; xyp->xy_drive < NXYDRIVE; xyp->xy_drive++) {
        !           119:                label = (struct dk_label *)
        !           120:                        ((struct xydma *)sip->si_dmaaddr)->xyblock;
        !           121:                label->dkl_magic = 0;
        !           122:                if (xycmd(XY_READ, sip, 0, (char *)label, 1))
        !           123:                        continue;
        !           124:                if (chklabel(label))
        !           125:                        continue;
        !           126:                if (ppart != label->dkl_ppart)
        !           127:                        continue;
        !           128:                goto foundlabel;
        !           129:        }
        !           130:        printf(msg_nolabel);
        !           131:        return (-1);
        !           132: 
        !           133: foundlabel:
        !           134:        xyp->xy_nhead = label->dkl_nhead;
        !           135:        xyp->xy_nsect = label->dkl_nsect;
        !           136:        xyp->xy_ncyl  = label->dkl_ncyl + label->dkl_acyl;
        !           137:        xyp->xy_boff  = label->dkl_map[sip->si_boff].dkl_cylno;
        !           138:        xyp->xy_nblk  = label->dkl_map[sip->si_boff].dkl_nblk;
        !           139: 
        !           140:        bzero((char *)xy, sizeof (struct xyiopb));
        !           141:        xy->xy_reloc = 1;
        !           142:        xy->xy_cmd = XY_INIT;
        !           143:        xy->xy_drive = xyp->xy_drive;
        !           144:        xy->xy_unit = xyp->xy_unit & 3;
        !           145:        xy->xy_head = xyp->xy_nhead - 1;
        !           146:        xy->xy_cylinder = xyp->xy_ncyl - 1;
        !           147:        xy->xy_sector = xyp->xy_nsect - 1;
        !           148:        xy->xy_bhead = label->dkl_bhead;
        !           149: 
        !           150:        t = XYREL(xyaddr, MB_DMA_ADDR(xy));
        !           151:        xyaddr->xy_iopbrel[0] = t >> 8;
        !           152:        xyaddr->xy_iopbrel[1] = t;
        !           153:        xyaddr->xy_iopboff[0] = MB_DMA_ADDR(xy) >> 8;
        !           154:        xyaddr->xy_iopboff[1] = MB_DMA_ADDR(xy);
        !           155:        xyaddr->xy_csr = XY_GO;
        !           156: 
        !           157:        do {
        !           158:                DELAY(30);
        !           159:        } while (xyaddr->xy_csr & XY_BUSY);
        !           160:        if (xy->xy_iserr)
        !           161:                printf("xy: init error %x\n", xy->xy_errno);
        !           162:        /*
        !           163:         * Fetch bad block info.
        !           164:         */
        !           165:        xyp->xy_badaddr = ((int)xyp->xy_ncyl * xyp->xy_nhead - 1)
        !           166:                          * xyp->xy_nsect;
        !           167:        if (xycmd(XY_READ, sip, xyp->xy_badaddr, (char *)&xyp->xy_bad, 1))
        !           168:                printf("xy: no bad block info\n");
        !           169:        return (0);
        !           170: }
        !           171: 
        !           172: xystrategy(sip, rw)
        !           173:        struct saioreq *sip;
        !           174:        int rw;
        !           175: {
        !           176:        register int cmd = (rw == WRITE) ? XY_WRITE : XY_READ;
        !           177:        register int boff;
        !           178:        register struct xyparam *xyp = (struct xyparam *)sip->si_devdata;
        !           179:        register short nsect;
        !           180: #ifndef BOOTBLOCK
        !           181:        char *ma;
        !           182:        int i, bn;
        !           183: #endif BOOTBLOCK
        !           184: 
        !           185:        boff = CYL(xyp->xy_boff);
        !           186: #ifdef BOOTBLOCK
        !           187:        /* assert si_cc == DEV_BSIZE */
        !           188:        if (xycmd(cmd, sip, sip->si_bn + boff, sip->si_ma, 1))
        !           189:                return (-1);
        !           190:        return (sip->si_cc);
        !           191: #else BOOTBLOCK
        !           192:        nsect = sip->si_cc / DEV_BSIZE;
        !           193:        if (sip->si_bn + nsect > xyp->xy_nblk)
        !           194:                nsect = xyp->xy_nblk - sip->si_bn;
        !           195:        if (nsect == 0)
        !           196:                return (0);
        !           197:        if (xycmd(cmd, sip, sip->si_bn+boff, sip->si_ma, nsect) == 0)
        !           198:                return (nsect*DEV_BSIZE);
        !           199:        /*
        !           200:         * Large transfer failed, now do one at a time
        !           201:         */
        !           202:        bn = sip->si_bn + boff;
        !           203:        ma = sip->si_ma;
        !           204:        for (i = 0; i < nsect; i++) {
        !           205:                if (xycmd(cmd, sip, bn, ma, 1))
        !           206:                        return (-1);
        !           207:                bn++;
        !           208:                ma += DEV_BSIZE;
        !           209:        }
        !           210:        return (nsect*DEV_BSIZE);
        !           211: #endif BOOTBLOCK
        !           212: }
        !           213: 
        !           214: #ifndef BOOTBLOCK
        !           215: /*
        !           216:  * This routine is called from isspinning() as the test condition.
        !           217:  */
        !           218: int
        !           219: xyspin(sip, dummy)
        !           220:        struct saioreq *sip;
        !           221:        int dummy;
        !           222: {
        !           223:        register struct xyiopb *xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
        !           224:  
        !           225:        (void) xycmd(XY_STATUS, sip, 0, (char *)0, 0);
        !           226:        return ((xy->xy_status & XY_READY) ? 0 : 1);
        !           227: }
        !           228: #endif !BOOTBLOCK
        !           229: 
        !           230: xycmd(cmd, sip, bno, buf, nsect)
        !           231:        int cmd;
        !           232:        struct saioreq *sip;
        !           233:        register int bno;
        !           234:        char *buf;
        !           235:        int nsect;
        !           236: {
        !           237:        register int i, t;
        !           238:        register struct xyparam *xyp = (struct xyparam *)sip->si_devdata;
        !           239:        register struct xyiopb *xy = &((struct xydma *)sip->si_dmaaddr)->xyiopb;
        !           240:        register struct xydevice *xyaddr = (struct xydevice *)sip->si_devaddr;
        !           241:        register char *bp = ((struct xydma *)sip->si_dmaaddr)->xyblock;
        !           242:        unsigned short cylno, sect, head;
        !           243:        int error, errcnt = 0;
        !           244: 
        !           245:        cylno = bno / CYL(1);
        !           246:        sect = bno % xyp->xy_nsect;
        !           247:        head = (bno / xyp->xy_nsect) % xyp->xy_nhead;
        !           248: 
        !           249:        if (cmd == XY_WRITE && buf != bp)       /* Many just use common buf */
        !           250:                bcopy(buf, bp, nsect*DEV_BSIZE);
        !           251: 
        !           252: retry:
        !           253:        bzero((char *)xy, sizeof (struct xyiopb));
        !           254:        xy->xy_reloc = 1;
        !           255:        xy->xy_autoup = 1;
        !           256:        xy->xy_cmd = cmd;
        !           257:        xy->xy_drive = xyp->xy_drive;
        !           258:        xy->xy_unit = xyp->xy_unit & 3;
        !           259:        xy->xy_eccmode = 2;     /* means 0 on 440 */
        !           260:        xy->xy_throttle = XY_THROTTLE;
        !           261:        xy->xy_sector = sect;
        !           262:        xy->xy_head = head;
        !           263:        xy->xy_cylinder = cylno;
        !           264:        xy->xy_nsect = nsect;
        !           265:        xy->xy_bufoff = XYOFF(MB_DMA_ADDR(bp));
        !           266:        xy->xy_bufrel = XYREL(xyaddr, MB_DMA_ADDR(bp));
        !           267: 
        !           268:        t = XYREL(xyaddr, MB_DMA_ADDR(xy));
        !           269:        xyaddr->xy_iopbrel[0] = t >> 8;
        !           270:        xyaddr->xy_iopbrel[1] = t;
        !           271:        xyaddr->xy_iopboff[0] = MB_DMA_ADDR(xy) >> 8;
        !           272:        xyaddr->xy_iopboff[1] = MB_DMA_ADDR(xy);
        !           273:        xyaddr->xy_csr = XY_GO;
        !           274: 
        !           275:        do {
        !           276:                DELAY(30);
        !           277:        } while (xyaddr->xy_csr & XY_BUSY);
        !           278: 
        !           279:        if (xyaddr->xy_csr & XY_ERROR) {
        !           280:                xyaddr->xy_csr = XY_ERROR;
        !           281:                DELAY(100);
        !           282:                if (bno != 0)
        !           283:                        printf("xy: hard error bno %d\n", bno);
        !           284:                if (cmd != XY_RESET)
        !           285:                        (void) xycmd(XY_RESET, sip, 0, (char *)0, 0);
        !           286:                return (-1);
        !           287:        }
        !           288:        if (xy->xy_iserr && xy->xy_errno != 0x1F) {     /* FIXME constant */
        !           289:                if (nsect != 1)         /* only try hard on single sectors */
        !           290:                        return (-1);
        !           291:                error = xy->xy_errno;
        !           292:                if ((i = xyfwd(xyp, cylno, head, sect)) != 0)
        !           293:                        return xycmd(cmd, sip, i, buf, 1);
        !           294:                /* Attempt to reset the error condition */
        !           295:                if (cmd != XY_RESET)
        !           296:                        (void) xycmd(XY_RESET, sip, 0, (char *)0, 0);
        !           297:                if (++errcnt < 5)
        !           298:                        goto retry;
        !           299:                if (bno != 0 || error != 5)     /* drive type probe */
        !           300:                        printf("xy: error %x bno %d\n", error, bno);
        !           301:                return (-1);                    /* Error */
        !           302:        }
        !           303: 
        !           304:        if (cmd == XY_READ && buf != bp)        /* Many just use common buf */
        !           305:                bcopy(bp, buf, nsect*DEV_BSIZE);
        !           306: 
        !           307:        return (0);
        !           308: }
        !           309: 
        !           310: xyfwd(xyp, cn, tn, sn)
        !           311:        register struct xyparam *xyp;
        !           312:        int cn, tn, sn;
        !           313: {
        !           314:        register struct dkbad *bt = &xyp->xy_bad;
        !           315:        register int i;
        !           316: 
        !           317:        if (bt->bt_mbz != 0)    /* not initialized */
        !           318:                return (0);
        !           319:        for (i=0; i<126; i++)           /* FIXME constant */
        !           320:                if (bt->bt_bad[i].bt_cyl == cn &&
        !           321:                    bt->bt_bad[i].bt_trksec == (tn<<8)+sn) {
        !           322:                        return (xyp->xy_badaddr - i - 1);
        !           323:                }
        !           324:        return (0);
        !           325: }

unix.superglobalmegacorp.com

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