Annotation of researchv9/sys/boot/stand/ip.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)ip.c       1.1 86/02/03    Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "saio.h"
                     10: #include "../sun/dklabel.h"
                     11: #include "../sun/dkio.h"
                     12: #include "../sundev/ipreg.h"
                     13: #include "../ufs/fsdir.h"      /* DEV_BSIZE */
                     14: 
                     15: #define MAXHEAD                4       /* Max # heads to search for a label */
                     16: 
                     17: #define        MAX(a, b)       (a > b ? a : b)
                     18: 
                     19: #define IPSTD 4
                     20: u_long ipstd[] = { 0x40, 0x44, 0x48, 0x4c, };
                     21: 
                     22: struct ipparam {
                     23:        int     ip_unit;
                     24:        int     ip_boff;
                     25:        int     ip_nsect;
                     26:        int     ip_ncyl;
                     27:        int     ip_nhead;
                     28:        int     ip_bhead;               /* Base head #, for CDC Lark support */
                     29:        struct ipdevice *ip_addr;
                     30: };
                     31: 
                     32: /*
                     33:  * Layout of our DMA space
                     34:  */
                     35: struct ipdma {
                     36:        struct iopb0    iopb0;
                     37:        union {
                     38:                char    buffer[DEV_BSIZE];
                     39:                struct dk_label label;
                     40:                struct uib      up;
                     41:        } u;
                     42: };
                     43: 
                     44: #define        ipbuffer        (((struct ipdma *)sip->si_dmaaddr)->u.buffer)
                     45: #define        iplabel         (&((struct ipdma *)sip->si_dmaaddr)->u.label)
                     46: #define        ipup            (&((struct ipdma *)sip->si_dmaaddr)->u.up)
                     47: 
                     48: 
                     49: /*
                     50:  * What resources we need
                     51:  */
                     52: struct devinfo ipinfo = {
                     53:        sizeof (struct ipdevice),
                     54:        sizeof (struct ipdma),
                     55:        sizeof (struct ipparam),
                     56:        IPSTD,
                     57:        ipstd,
                     58:        MAP_MBIO,
                     59:        DEV_BSIZE,              /* block at a time */
                     60: };
                     61: 
                     62: /*
                     63:  * What facilities we export to the world
                     64:  */
                     65: int ipprobe(), ipopen(), ipstrategy();
                     66: extern int xxboot(), xxprobe();
                     67: extern int nullsys();
                     68: 
                     69: struct boottab ipdriver = {
                     70:        "ip",   xxprobe, xxboot, ipopen, nullsys, ipstrategy,
                     71:        "ip: Interphase disk", &ipinfo,
                     72: };
                     73: 
                     74: 
                     75: #define        CYL(p)  (p * ipp->ip_nsect * ipp->ip_nhead)     /* block # at cylinder location */
                     76: 
                     77: 
                     78: /*
                     79:  * Open an Interphase disk.
                     80:  */
                     81: ipopen(sip)
                     82:        register struct saioreq *sip;
                     83: {
                     84:        register struct ipparam *ipp;
                     85:        register struct dk_label *label = iplabel;
                     86:        u_short ppart;
                     87: 
                     88:        ipp = (struct ipparam *)sip->si_devdata;
                     89:        ipp->ip_unit = sip->si_unit & 0x03;
                     90:        ppart = (sip->si_unit >> 2) & 1;
                     91:        ipp->ip_addr = (struct ipdevice *)sip->si_devaddr;
                     92: 
                     93:        ipp->ip_nsect = 2;              /* Read label */
                     94:        ipp->ip_ncyl  = 2;
                     95:        ipp->ip_nhead = MAXHEAD;
                     96:        ipp->ip_bhead = 0;              /* No base head yet, til label read */
                     97:        ipp->ip_boff  = 0;              /* Don't offset block numbers */
                     98: 
                     99:        for (ipp->ip_bhead = 0; ipp->ip_bhead < MAXHEAD; ipp->ip_bhead++) {
                    100:                register short *sp, sum;
                    101:                short count;
                    102: 
                    103:                label->dkl_magic = 0;
                    104:                if (ipcmd(IP_READ, sip, 0, label))
                    105:                        continue;
                    106:                if (label->dkl_magic != DKL_MAGIC)
                    107:                        continue;
                    108: 
                    109:                sum = 0;
                    110:                count = sizeof (struct dk_label) / sizeof (short);
                    111:                sp = (short *)label;
                    112:                while (count--) 
                    113:                        sum ^= *sp++;
                    114:                if (sum != 0) {
                    115:                        printf("Corrupt label on head %d\n", ipp->ip_bhead);
                    116:                        continue;
                    117:                }
                    118:                if (ipp->ip_bhead != label->dkl_bhead) {
                    119:                        printf("Misplaced label on head %d\n", ipp->ip_bhead);
                    120:                        continue;
                    121:                }
                    122:                if (ppart != label->dkl_ppart)
                    123:                        continue;
                    124:                goto foundlabel;
                    125:        }
                    126:        if (ppart)
                    127:                printf("For phys part %d, ", ppart);
                    128:        printf("No label found.\n");
                    129:        return (-1);
                    130: 
                    131: foundlabel:
                    132:        ipp->ip_nhead = label->dkl_nhead;
                    133:        ipp->ip_nsect = label->dkl_nsect;
                    134:        ipp->ip_ncyl  = label->dkl_ncyl;
                    135:        ipp->ip_bhead = label->dkl_bhead;
                    136:        ipp->ip_boff  = label->dkl_map[sip->si_boff].dkl_cylno;
                    137:        return (0);
                    138: }
                    139: 
                    140: ipstrategy(sip, rw)
                    141:        struct saioreq *sip;
                    142:        int rw;
                    143: {
                    144:        register int cmd = (rw == WRITE) ? IP_WRITE : IP_READ;
                    145:        register int blk = sip->si_bn;
                    146:        register char *ma = sip->si_ma;
                    147: 
                    148:        if (ipcmd(cmd, sip, blk, ma))
                    149:                return (-1);
                    150:        return (sip->si_cc);
                    151: }
                    152: 
                    153: ipcmd(cmd, sip, bno, buf)
                    154:        register int cmd;
                    155:        struct saioreq *sip;
                    156:        register int bno;
                    157:        register char *buf;
                    158: {
                    159:        register struct ipparam *ipp = (struct ipparam *)sip->si_devdata;
                    160:        register int i, u;
                    161:        register struct iopb0 *ip0;
                    162:        register struct ipdevice *ipaddr = ipp->ip_addr;
                    163:        register char *bp;
                    164:        int cylno, sect, status, error, errcnt = 0;
                    165: 
                    166:        ip0 = &((struct ipdma *)sip->si_dmaaddr)->iopb0;
                    167:        bzero((char *)ip0, IPIOPBSZ);
                    168:        bp = ipbuffer;
                    169: 
                    170:        cylno = bno / CYL(1);
                    171:        cylno += ipp->ip_boff;
                    172:        if (cylno > ipp->ip_ncyl)
                    173:                return (-1);
                    174:        sect = bno % ipp->ip_nsect;
                    175: 
                    176:        if (cmd == IP_WRITE && buf != bp)       /* Many just use common buf */
                    177:                bcopy(buf, bp, DEV_BSIZE);
                    178: 
                    179: retry:
                    180:        while (ipaddr->ip_r0 & IP_BUSY)
                    181:                DELAY(30);
                    182:        ip0->i0_cmd = cmd;
                    183:        ip0->i0_status = 0;
                    184:        ip0->i0_error = 0;
                    185:        u = 1 << (ipp->ip_unit&3);
                    186:        ip0->i0_unit_cylhi = (u<<4) | ((cylno>>8)&0xF);
                    187:        ip0->i0_cylinder = cylno;
                    188:        if (cmd == IP_RESTORE)
                    189:                ip0->i0_sector = ipp->ip_nsect;
                    190:        else
                    191:                ip0->i0_sector = sect;
                    192:        ip0->i0_secnt = 1;
                    193:        ip0->i0_buf_xmb = (MB_DMA_ADDR(bp)) >> 16;
                    194:        ip0->i0_buf_msb = (MB_DMA_ADDR(bp)) >> 08;
                    195:        ip0->i0_buf_lsb = (MB_DMA_ADDR(bp));
                    196:        ip0->i0_head = ((bno % CYL(1)) / ipp->ip_nsect) + ipp->ip_bhead;
                    197:        ip0->i0_ioaddr = (int)ipaddr;
                    198:        ip0->i0_burstlen = IP0_BURSTLEN;
                    199:        ip0->i0_nxt_xmb = 0;
                    200:        ip0->i0_nxt_msb = 0;
                    201:        ip0->i0_nxt_lsb = 0;
                    202:        ip0->i0_seg_msb = 0;
                    203:        ip0->i0_seg_lsb = 0;
                    204: 
                    205:        /* point controller at iopb and start it up */
                    206: 
                    207:        ipaddr->ip_r1 = ((MB_DMA_ADDR(ip0)) >> 16) | IP_BUS;
                    208:        ipaddr->ip_r2 = (MB_DMA_ADDR(ip0)) >> 8;
                    209:        ipaddr->ip_r3 = (MB_DMA_ADDR(ip0));
                    210:        ipaddr->ip_r0 = IP_GO;
                    211: 
                    212:        while ((ip0->i0_status == 0) || (ip0->i0_status == IP_DBUSY))
                    213:                DELAY(30);
                    214:        status = ip0->i0_status;
                    215:        error = ip0->i0_error;
                    216: 
                    217:        ipaddr->ip_r0 = IP_CLRINT;
                    218:        if (status != IP_OK) {
                    219:                printf("ip: error %x\n", error);
                    220:                /* Attempt to reset the error condition */
                    221:                if (cmd != IP_RESTORE)
                    222:                        if (ipcmd(IP_RESTORE, ipp, 0, (char *)0))
                    223:                                return (-1);
                    224:                if (++errcnt < 10)
                    225:                        goto retry;
                    226:                return (-1);                    /* Error */
                    227:        }
                    228: 
                    229:        ipaddr->ip_r0 = IP_CLRINT;
                    230: 
                    231:        if (cmd == IP_READ && buf != bp)        /* Many just use common buf */
                    232:                bcopy(bp, buf, DEV_BSIZE);
                    233: 
                    234:        return (0);
                    235: }

unix.superglobalmegacorp.com

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