1: /* 2: * Copyright (c) 1986 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: * @(#)conf.c 2.7 (2.11BSD) 1997/11/7 7: */ 8: 9: #include "../h/param.h" 10: #include "saio.h" 11: 12: int nullsys(); 13: 14: extern int xpstrategy(), xpopen(), xpclose(), xplabel(); 15: extern int brstrategy(), bropen(); 16: extern int rkstrategy(), rkopen(); 17: extern int rxstrategy(), rxopen(); 18: extern int hkstrategy(), hkopen(), hklabel(); 19: extern int rlstrategy(), rlopen(), rllabel(); 20: extern int sistrategy(), siopen(); 21: extern int rastrategy(), raopen(), raclose(), ralabel(); 22: extern int tmstrategy(), tmopen(), tmclose(), tmseek(); 23: extern int htstrategy(), htopen(), htclose(), htseek(); 24: extern int tsstrategy(), tsopen(), tsclose(), tsseek(); 25: extern int tmscpstrategy(), tmscpopen(), tmscpclose(), tmscpseek(); 26: 27: extern caddr_t *XPcsr[], *BRcsr[], *RKcsr[], *HKcsr[], *RLcsr[], *RXcsr[]; 28: extern caddr_t *SIcsr[], *RAcsr[], *TMcsr[], *HTcsr[], *TScsr[], *TMScsr[]; 29: 30: /* 31: * NOTE! This table must be in major device number order. See /sys/pdp/conf.c 32: * for the major device numbers. 33: */ 34: 35: struct devsw devsw[] = { 36: "ht", htstrategy, htopen, htclose, HTcsr, /* 0 */ 37: nullsys, htseek, 38: "tm", tmstrategy, tmopen, tmclose, TMcsr, /* 1 */ 39: nullsys, tmseek, 40: "ts", tsstrategy, tsopen, tsclose, TScsr, /* 2 */ 41: nullsys, tsseek, 42: "ram", nullsys, nullsys, nullsys, 0, /* 3 */ 43: nullsys, nullsys, 44: "hk", hkstrategy, hkopen, nullsys, HKcsr, /* 4 */ 45: hklabel, nullsys, 46: "ra", rastrategy, raopen, raclose, RAcsr, /* 5 */ 47: ralabel, nullsys, 48: "rk", rkstrategy, rkopen, nullsys, RKcsr, /* 6 */ 49: nullsys, nullsys, 50: "rl", rlstrategy, rlopen, nullsys, RLcsr, /* 7 */ 51: rllabel, nullsys, 52: "rx", rxstrategy, rxopen, nullsys, RXcsr, /* 8 */ 53: nullsys, nullsys, 54: "si", sistrategy, siopen, nullsys, SIcsr, /* 9 */ 55: nullsys, nullsys, 56: "xp", xpstrategy, xpopen, xpclose, XPcsr, /* 10 */ 57: xplabel, nullsys, 58: "br", brstrategy, bropen, nullsys, BRcsr, /* 11 */ 59: nullsys, nullsys, 60: "tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */ 61: nullsys, tmscpseek, 62: 0, 0, 0, 0, 0, 63: nullsys, nullsys, 64: }; 65: 66: int ndevsw = (sizeof (devsw) / sizeof (devsw[0])) - 1; 67: 68: char ADJcsr[] = 69: { 70: 0, /* HT = 0 */ 71: 2, /* TM = 1 */ 72: 2, /* TS = 2 */ 73: 0, /* RAM = 3 */ 74: 0, /* HK = 4 */ 75: 0, /* RA = 5 */ 76: 4, /* RK = 6 */ 77: 0, /* RL = 7 */ 78: 0, /* RX = 8 */ 79: 0, /* XP/SI = 9 */ 80: 0, /* XP = 10 */ 81: 4, /* BR =11 */ 82: 0, /* TMS = 12 */ 83: }; 84: 85: devread(io) 86: register struct iob *io; 87: { 88: 89: return((*devsw[io->i_ino.i_dev].dv_strategy)(io, READ)); 90: } 91: 92: devwrite(io) 93: register struct iob *io; 94: { 95: return((*devsw[io->i_ino.i_dev].dv_strategy)(io, WRITE)); 96: } 97: 98: devopen(io) 99: register struct iob *io; 100: { 101: return((*devsw[io->i_ino.i_dev].dv_open)(io)); 102: } 103: 104: devclose(io) 105: register struct iob *io; 106: { 107: (*devsw[io->i_ino.i_dev].dv_close)(io); 108: } 109: 110: /* 111: * Call the 'seek' entry for a tape device. Seeking only works for 1kb 112: * records - which is how the executables are stored - not for the dump 113: * or tar files on a boot tape. 114: */ 115: devseek(io, space) 116: register struct iob *io; 117: int space; 118: { 119: return((*devsw[io->i_ino.i_dev].dv_seek)(io, space)); 120: } 121: 122: devlabel(io, fnc) 123: register struct iob *io; 124: int fnc; 125: { 126: int (*dvlab)() = devsw[io->i_ino.i_dev].dv_label; 127: int (*strat)() = devsw[io->i_ino.i_dev].dv_strategy; 128: register struct disklabel *lp; 129: register struct partition *pi; 130: 131: switch (fnc) 132: { 133: case WRITELABEL: 134: return(writelabel(io, strat)); 135: case READLABEL: 136: return(readlabel(io, strat)); 137: case DEFAULTLABEL: 138: /* 139: * Zero out the label buffer and then assign defaults common to all drivers. 140: * Many of these are rarely (if ever) changed. The 'a' partition is set up 141: * to be one sector past the label sector - the driver is expected to change 142: * this to span the volume once the size is known. 143: */ 144: lp = &io->i_label; 145: pi = &lp->d_partitions[0]; 146: bzero(lp, sizeof (struct disklabel)); 147: lp->d_npartitions = 1; 148: pi->p_offset = 0; 149: pi->p_size = LABELSECTOR + 1; 150: pi->p_fsize = DEV_BSIZE; 151: pi->p_frag = 1; 152: pi->p_fstype = FS_V71K; 153: strcpy(lp->d_packname, "DEFAULT"); 154: lp->d_secsize = 512; 155: lp->d_interleave = 1; 156: lp->d_rpm = 3600; 157: /* 158: * param.h declares BBSIZE to be DEV_BSIZE which is 1kb. This is _wrong_, 159: * the boot block size (what the bootroms read) is 512. The disklabel(8) 160: * program explicitly sets d_bbsize to 512 so we do the same thing here. 161: * 162: * What a mess - when the 1k filesystem was created there should have been 163: * a (clearer) distinction made between '(hardware) sectors' and 164: * '(filesystem) blocks'. Sigh. 165: */ 166: lp->d_bbsize = 512; 167: lp->d_sbsize = SBSIZE; 168: return((*dvlab)(io)); 169: default: 170: printf("devlabel: bad fnc %d\n"); 171: return(-1); 172: } 173: } 174: 175: /* 176: * Common routine to print out the full device name in the form: 177: * 178: * dev(ctlr,unit,part) 179: * 180: * Have to do it the hard way since there's no sprintf to call. Register 181: * oriented string copies are small though. 182: */ 183: 184: char * 185: devname(io) 186: register struct iob *io; 187: { 188: static char dname[16]; 189: register char *cp, *dp; 190: 191: cp = dname; 192: dp = devsw[io->i_ino.i_dev].dv_name; 193: while (*cp = *dp++) 194: cp++; 195: *cp++ = '('; 196: dp = itoa(io->i_ctlr); 197: while (*cp = *dp++) 198: cp++; 199: *cp++ = ','; 200: dp = itoa(io->i_unit); 201: while (*cp = *dp++) 202: cp++; 203: *cp++ = ','; 204: dp = itoa(io->i_part); 205: while (*cp = *dp++) 206: cp++; 207: *cp++ = ')'; 208: *cp++ = '\0'; 209: return(dname); 210: } 211: /* 212: * Check for end of volume. Actually this checks for end of partition. 213: * Since this is almost always called when reading unlabeled disks (treating 214: * a floppy as a short tape for example) it's effectively an EOV check. 215: */ 216: 217: deveovchk(io) 218: register struct iob *io; 219: { 220: register struct partition *pi; 221: daddr_t sz, eov; 222: 223: pi = &io->i_label.d_partitions[io->i_part]; 224: sz = io->i_cc / 512; 225: /* 226: * i_bn already has the p_offset added in, thus we have to add in the partition 227: * offset when calculating the end point. 228: */ 229: eov = pi->p_offset + pi->p_size; 230: if (io->i_bn + sz > eov) 231: { 232: sz = eov - io->i_bn; 233: if (sz == 0) 234: return(0); /* EOF */ 235: /* 236: * Probably should call this EOF too since there is no 'errno' to specify 237: * what type of error has happened. 238: */ 239: if (sz < 0) 240: return(-1); 241: io->i_cc = dbtob(sz); 242: } 243: return(1); 244: } 245: 246: nullsys() 247: { 248: return(-1); 249: }