|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.