Annotation of researchv9/sys/boot/stand/xy.c, revision 1.1.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.