Subject: Disklabels arrive for 2.11BSD (#262 part 13 of 18) Index: sys,bin,usr.lib,(many more)/ 2.11BSD Description: The moving the partitions tables out of the disk drivers and to a disklabel residing on the media has been on the wish list for many many years. Disklabels have finally arrived for 2.11BSD! Repeat-By: Observation. Also a reading of the setup and installation documentation for previous 2BSD releases (2.9, 2.10, 2.11) all have a paragraph similar to this present: "It is possible to change the partitions by changing the code for the table in the disk driver. Since it's desirable to do this, these tables really should be read off each pack...." Fix: This is part 13 of 18. Gather all parts before doing anything except reading the instructions which are in #250 (part 1). Updated by this part are: /usr/src/sys/pdpstand/M.s /usr/src/sys/pdpstand/Makefile /usr/src/sys/pdpstand/label.c /usr/src/sys/pdpstand/boot.c /usr/src/sys/pdpstand/br.c /usr/src/sys/pdpstand/conf.c /usr/src/sys/pdpstand/hk.c /usr/src/sys/pdpstand/ht.c /usr/src/sys/pdpstand/maketape.data /usr/src/sys/pdpstand/mtboot.s /usr/src/sys/pdpstand/prf.c /usr/src/sys/pdpstand/ra.c /usr/src/sys/pdpstand/rk.c /usr/src/sys/pdpstand/rl.c /usr/src/sys/pdpstand/saio.h /usr/src/sys/pdpstand/si.c /usr/src/sys/pdpstand/srt0.s /usr/src/sys/pdpstand/sys.c /usr/src/sys/pdpstand/tm.c /usr/src/sys/pdpstand/tmscp.c /usr/src/sys/pdpstand/ts.c /usr/src/sys/pdpstand/xp.c /usr/src/sys/pdpstand/displaylab.c /usr/src/sys/pdpstand/disklabel.c label.c, disklabel.c, and displaylab.c are NEW and are added by upacking the shar file included below. Essentially the standalone system was rewritten. The changes are large and widespread. Almost everything about the standalone i/o system is different. The major changes are: disklabel support (for MSCP and RL drives). routines to read and write disklabels. Best of all - a standalone disklabel program that attempts to be "sysadmin friendly". This program is now the 1st program on the tape (right after boot). The capability to load split I/D executables from tape. This was required for 'restor' because the disklabel support added too much code+data to fit 'restor' in 48kb. Tape drivers can now do "seek" operations! This was a major pain but required for loading split I/D executables. Such executables are loaded in two steps - first the data, and then the code. Normal executables are loaded in one sequential read. NOTE: seeking on tape only works for 1kb record sizes. That is the record size used for executables on the tape. Although not strictly required (yet) the 'icheck' program is built split I/D. As more drivers are converted to support labels the space required would have driven icheck over the 48kb limit soon or later. The split I/D support meant that the I/O address calculation had to change - simply using 'segflag' as the top two bits of an 18 bit UNIBUS address no longer was the correct thing to do in all cases. As a result of the change above it is no longer necessary to load /boot on a 64kb boundary! Boot must still be loaded below 256kb (for reasons to do with UNIBUS mapping) but if necessary Boot could be loaded above 192kb. The layout of a bootable tape has changed slightly. There is an additional standalone program - disklabel, present. The layout of the tape is now: file program ---- ------- 0 bootblock + boot 1 disklabel 2 mkfs 3 restor 4 icheck 5 dump of root filesystem 6 tar file 7 tar file 8 tar file The message from Boot and how to specify which image to boot have changed. UNLESS you are booting from a second (or third) controller you will not notice much of a difference. Basically the format of the string entered at the ':' prompt is of the form: : ra(c,u,p)file where 'c' is the controller number (0-3), 'u' is the unit number (0-7) and 'p' is the partition number (0-7). The old method of embedding the controller number in the unit number is gone. Previously to boot from the second MSCP controller you used the string "ra(64,0)unix". The new string would be "ra(1,0,0)unix". At this time only the MSCP and RL drivers implement labels. The 'xp' (SMD) driver is the next in line to be converted at which time a much smaller update kit will be posted. ONLY the TMSCP and TS tape drivers have been tested as far as 'seek'ing - they're the only ones I have. The other drivers should work, the changes were straight forward but... If you do have a problem with the HT (TU16) or TM (TU10) drivers let me know and we'll try to work something out. Cut where indicated and save to a file (/tmp/262). Then: cd /tmp sh 262 sh pdpstand.shar patch -p0 < pdpstand.patch rm pdpstand.shar pdpstand.patch ------------------------------cut here--------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # pdpstand.shar # pdpstand.patch # This archive created: Mon Jul 10 23:29:03 1995 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'pdpstand.shar' then echo shar: "will not over-write existing file 'pdpstand.shar'" else sed 's/^Y//' << \SHAR_EOF > 'pdpstand.shar' Y#! /bin/sh Y# This is a shell archive, meaning: Y# 1. Remove everything above the #! /bin/sh line. Y# 2. Save the resulting text in a file. Y# 3. Execute the file with /bin/sh (not csh) to create: Y# /usr/src/sys/pdpstand/label.c Y# /usr/src/sys/pdpstand/displaylab.c Y# /usr/src/sys/pdpstand/disklabel.c Y# This archive created: Mon Jul 10 23:27:56 1995 Yexport PATH; PATH=/bin:/usr/bin:$PATH Yif test -f '/usr/src/sys/pdpstand/label.c' Ythen Y echo shar: "will not over-write existing file '/usr/src/sys/pdpstand/label.c'" Yelse Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/pdpstand/label.c' YX/*- YX * Public domain, May 1995 YX * YX * @(#)label.c 1.0 (2.11BSD GTE) 1995/06/08 YX */ YX YX#include "../h/param.h" YX#include "saio.h" YX YX/* YX * Called from the general device label routine in conf.c. A label with YX * a fake geometry suitable for reading the label sector is created and YX * the driver's strategy routine is called. If the label is corrupted YX * or absent an error is possibly printed. YX * YX * NOTES: We reuse the iob structure's buffer (i_buf). YX * All disks must have at least LABELSECTOR+1 sectors in a track. YX * (this is not expected to be a problem since LABELSECTOR is 1). YX*/ YX YXreadlabel(io, strat, name) YX struct iob *io; YX int (*strat)(); YX char *name; YX { YX struct disklabel *lp = &io->i_label; YX YX io->i_bn = LABELSECTOR; YX io->i_ma = io->i_buf; YX io->i_cc = 512; /* XXX */ YX lp->d_nsectors = LABELSECTOR + 1; /* # sectors per track */ YX lp->d_ntracks = 1; /* # tracks per cylinder */ YX lp->d_secpercyl = LABELSECTOR + 1; /* # sectors per cylinder */ YX if ((*strat)(io, READ) != 512) YX { YX printf("%s%d,%d: error reading labelsector\n", name, YX io->i_ctlr, io->i_unit); YX return(-1); YX } YX bcopy(io->i_buf, lp, sizeof (struct disklabel)); YX if (Nolabelerr) YX return(0); YX if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || YX dkcksum(lp) != 0) YX { YX printf("%s%d,%d disklabel missing or corrupt\n", name, YX io->i_ctlr, io->i_unit); YX return(-1); YX } YX return(0); YX } YX YXwritelabel(io, strat, name) YX register struct iob *io; YX int (*strat)(); YX char *name; YX { YX register struct disklabel *lp = &io->i_label; YX YX if ((io->i_flgs & F_WRITE) == 0) YX return(-1); YX io->i_bn = LABELSECTOR; YX io->i_ma = (char *)&io->i_label; YX io->i_cc = 512; /* XXX */ YX/* YX * The geometry had better be set up and correct at this point - we can not YX * fake the geometry because that would overwrite the contents of the label YX * itself. YX*/ YX lp->d_secsize = 512; /* XXX */ YX lp->d_magic = DISKMAGIC; YX lp->d_magic2 = DISKMAGIC; YX lp->d_checksum = 0; YX lp->d_checksum = dkcksum(lp); YX YX if ((*strat)(io, WRITE) != 512) YX { YX printf("%s: error writing labelsector\n", name); YX return(-1); YX } YX return(0); YX } YX/* YX * Compute checksum for disk label. YX */ YXdkcksum(lp) YX register struct disklabel *lp; YX { YX register u_short *start, *end; YX register u_short sum = 0; YX YX start = (u_short *)lp; YX end = (u_short *)&lp->d_partitions[lp->d_npartitions]; YX while (start < end) YX sum ^= *start++; YX return (sum); YX } YX YX/* YX * Check for partitions which overlap each other. While it is legal YX * to have partitions which overlap (as long as they are not used at the YX * same time) it is often a mistake or oversite. YX*/ YX YXoverlapchk(lp) YX register struct disklabel *lp; YX { YX register struct partition *pp; YX int i, part, openmask; YX daddr_t start, end; YX YX#define RAWPART 2 YX/* YX * 'c' is normally (but not always) the partition which spans the whole YX * drive, thus it is not normally an error for it to overlap all other YX * partitions. YX*/ YX openmask = ~0 & ~(1 << RAWPART); YX for (part = 0; part < lp->d_npartitions; part++) YX { YX pp = &lp->d_partitions[part]; YX if (part == RAWPART || pp->p_size == 0) YX continue; YX start = pp->p_offset; YX end = start + pp->p_size; YX YX for (pp = lp->d_partitions, i = 0; YX i < lp->d_npartitions; YX pp++, i++) YX { YX/* YX * We make sure to not report zero length partitions or that a YX * partition overlaps itself. We've already checked lower partitions YX * so avoid giving something like "a overlaps b" and then "b overlaps a". YX*/ YX if (i <= part || pp->p_size == 0) YX continue; YX if (pp->p_offset + pp->p_size <= start || YX pp->p_offset >= end) YX continue; YX if ((openmask & (1 << i)) == 0) YX continue; YX printf("warning: partition '%c' overlaps '%c'\n", YX 'a' + part, 'a' + i); YX } YX } YX } YSHAR_EOF Yfi Yif test -f '/usr/src/sys/pdpstand/displaylab.c' Ythen Y echo shar: "will not over-write existing file '/usr/src/sys/pdpstand/displaylab.c'" Yelse Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/pdpstand/displaylab.c' YX/* YX * 1995/06/08 - Borrowed from disklabel.c YX * YX * Many of the unused or invariant fields are omitted from the display. This YX * has the benefit of having everything fit on one screen - important since YX * the standalone console driver does not do xon/xoff. YX * YX * The partition display is jagged because the minimal printf() function YX * does not do field padding or justification. YX*/ YX YX#define DKTYPENAMES YX#include YX#include "saio.h" YX YXdisplaylabel(lp) YX register struct disklabel *lp; YX { YX register int i; YX register struct partition *pp; YX char junk[32]; YX YX putchar('\n'); YX if (lp->d_type < DKMAXTYPES) YX printf("type: %s\n", dktypenames[lp->d_type]); YX else YX printf("type: %d\n", lp->d_type); YX strncpy(junk, lp->d_typename, sizeof (lp->d_typename)); YX junk[sizeof(lp->d_typename)] = '\0'; YX printf("disk: %s\n", junk); YX YX strncpy(junk, lp->d_packname, sizeof (lp->d_packname)); YX junk[sizeof(lp->d_packname)] = '\0'; YX printf("label: %s\n", junk); YX YX printf("flags:"); YX if (lp->d_flags & D_REMOVABLE) YX printf(" removeable"); YX if (lp->d_flags & D_ECC) YX printf(" ecc"); YX if (lp->d_flags & D_BADSECT) YX printf(" badsect"); YX printf("\n"); YX printf("bytes/sector: %d\n", lp->d_secsize); YX printf("sectors/track: %d\n", lp->d_nsectors); YX printf("tracks/cylinder: %d\n", lp->d_ntracks); YX printf("sectors/cylinder: %d\n", lp->d_secpercyl); YX printf("cylinders: %d\n", lp->d_ncylinders); YX printf("rpm: %d\n", lp->d_rpm); YX printf("drivedata: "); YX for (i = 0; i < NDDATA; i++) YX printf("%D ", lp->d_drivedata[i]); YX printf("\n\n%d partitions:\n", lp->d_npartitions); YX printf("# size offset fstype [fsize bsize]\n"); YX pp = lp->d_partitions; YX for (i = 0; i < lp->d_npartitions; i++, pp++) YX { YX if (pp->p_size == 0) YX continue; YX printf(" %c: %D %D ", 'a' + i, YX pp->p_size, pp->p_offset); YX if ((unsigned) pp->p_fstype < FSMAXTYPES) YX printf("%s", fstypenames[pp->p_fstype]); YX else YX printf("%d", pp->p_fstype); YX switch (pp->p_fstype) YX { YX case FS_V71K: YX case FS_UNUSED: YX printf(" %d %d ", pp->p_fsize, YX pp->p_fsize * pp->p_frag); YX break; YX default: YX printf(" "); YX break; YX } YX printf("\t# (Cyl. %D", pp->p_offset / lp->d_secpercyl); YX if (pp->p_offset % lp->d_secpercyl) YX putchar('*'); YX else YX putchar(' '); YX printf("- %D", YX (pp->p_offset + YX pp->p_size + lp->d_secpercyl - 1) / YX lp->d_secpercyl - 1); YX if (pp->p_size % lp->d_secpercyl) YX putchar('*'); YX printf(")\n"); YX } YX putchar('\n'); YX } YSHAR_EOF Yfi Yif test -f '/usr/src/sys/pdpstand/disklabel.c' Ythen Y echo shar: "will not over-write existing file '/usr/src/sys/pdpstand/disklabel.c'" Yelse Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/pdpstand/disklabel.c' YX/* YX * Public domain, June 1995 YX * YX * @(#)disklabel.c 1.2 (2.11BSD GTE) 1995/07/10 YX*/ YX YX#define DKTYPENAMES YX#include "../h/param.h" YX#include "saio.h" YX YX int Nolabelerr = 1; /* Inhibit spurious label error msgs */ YX char module[] = "disklabel"; /* This program's name */ YX char line[80], device[80]; YX YXextern long atol(); YXextern struct iob iob[]; YXextern struct devsw devsw[]; YX YXmain() YX { YX register int f; YX register struct disklabel *lp; YX struct iob *io; YX YX printf("%s\n", module); YX YX while (1) YX { YX printf("Disk? "); YX gets(line); YX if (!line[0]) YX continue; YX strcpy(device, line); YX f = open(device, F_WRITE); YX if (f < 0) YX { YX printf("Error opening '%s' for writing\n", device); YX continue; YX } YX io = &iob[f - 3]; YX if (io->i_flgs & F_TAPE) YX { YX printf("Can not label tapes.\n"); YX continue; YX } YX break; YX } YX/* YX * The open() will have retrieved the label sector. This explicit read YX * is for debugging and testing because the driver's open routine may be YX * under development and the automatic retrieval of the label is commented YX * out. YX*/ YX if (devlabel(io, READLABEL) < 0) YX { YX printf("Can not read label sector from '%s'\n", device); YX return; /* back to Boot */ YX } YX lp = &io->i_label; YX if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || YX dkcksum(lp)) YX { YX printf("'%s' is unlabeled or the label is corrupt.\n", device); YX printf("Proceed? [y/n] "); YX if (gyon() == 'n') YX return; /* back to Boot */ YX/* YX * We next call the driver's entry which attempts to identify the drive YX * and set up a default (1 partition) label with the best guess as to YX * geometry, etc. If this call fails then the driver does not support YX * labels ('nullsys' is being used in the device table). YX*/ YX if (devlabel(io, DEFAULTLABEL) < 0) YX { YX printf("The '%s' driver does not support labels.\n", YX devsw[io->i_ino.i_dev].dv_name); YX return; /* back to Boot */ YX } YX } YX doit(io); YX return; YX } YX YXdoit(io) YX register struct iob *io; YX { YX int c, dirty = 0; YX struct disklabel *lp = &io->i_label; YX YX while (1) YX { YX printf("d(isplay) D(efault) m(odify) w(rite) q(uit)? "); YX c = egetchar("dDmwq"); YX switch (c) YX { YX case 'm': YX modifylabel(lp); YX overlapchk(lp); YX (void)checklabel(lp); YX/* YX * We make the assumption that the label was modified - the dirty YX * flag is set so we can ask if the changes should be discarded on a 'q'. YX*/ YX dirty = 1; YX break; YX case 'w': YX overlapchk(lp); YX (void)checklabel(lp); YX devlabel(io, WRITELABEL); YX/* YX * Changed label was committed to disk so we can clear the dirty flag now YX * and not ask the user if the changes should be kept when a 'q'uit is done. YX*/ YX dirty = 0; YX break; YX case 'd': YX displaylabel(lp); YX break; YX case 'D': YX devlabel(io, DEFAULTLABEL); YX dirty = 1; YX break; YX case 'q': YX if (!dirty) YX return; YX printf("Label changed. Discard changes [y/n]? "); YX if (gyon() == 'n') YX break; YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXmodifylabel(lp) YX register struct disklabel *lp; YX { YX register int c; YX YX while (1) YX { YX printf("modify\n"); YX printf("d(isplay) g(eometry) m(isc) p(artitions) q(uit)? "); YX c = egetchar("dgmpq"); YX switch (c) YX { YX case 'd': YX displaylabel(lp); YX break; YX case 'g': YX dogeometry(lp); YX break; YX case 'm': YX domisc(lp); YX break; YX case 'p': YX dopartitions(lp); YX break; YX case 'q': YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXdogeometry(lp) YX struct disklabel *lp; YX { YX register int c; YX YX while (1) YX { YX printf("modify geometry\n"); YX printf("d(isplay) s(ector/trk) t(rk/cyl) c(yl) S(ector/cyl) q(uit)? "); YX c = egetchar("dstcSq"); YX switch (c) YX { YX case 'd': YX displaylabel(lp); YX break; YX case 's': YX fillin_int(&lp->d_nsectors, YX "sectors/track [%d]: ", 512); YX break; YX case 't': YX fillin_int(&lp->d_ntracks, YX "tracks/cylinder [%d]: ", 127); YX break; YX case 'c': YX fillin_int(&lp->d_ncylinders, YX "cylinders [%d]: ", 4096); YX break; YX case 'S': YX lp->d_secpercyl= lp->d_nsectors * lp->d_ntracks; YX fillin_int(&lp->d_secpercyl, YX "sectors/cylinder [%d]: ", 65535); YX break; YX case 'q': YX if (lp->d_secpercyl == 0) YX lp->d_secpercyl = lp->d_nsectors * YX lp->d_ntracks; YX lp->d_secperunit = (long)lp->d_ncylinders * YX lp->d_secpercyl; YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXdomisc(lp) YX register struct disklabel *lp; YX { YX register int c; YX char junk[32]; YX YX while (1) YX { YX printf("modify misc\n"); YX printf("d(isplay) t(ype) n(ame) l(abel) f(lags) r(pm) D(rivedata) q(uit)? "); YX c = egetchar("dtnlfrDq"); YX switch (c) YX { YX case 'd': YX displaylabel(lp); YX break; YX case 't': YX if (lp->d_type >= DKMAXTYPES) YX lp->d_type = 0; YX printf("type [%s]: ", dktypenames[lp->d_type]); YX gets(line); YX if (line[0]) YX lp->d_type = findtype(dktypenames, YX line, YX lp->d_type); YX break; YX case 'n': YX strncpy(junk, lp->d_typename, YX sizeof (lp->d_typename)); YX junk[sizeof (lp->d_typename)] = '\0'; YX printf("disk [%s]: ", junk); YX gets(line); YX if (line[0]) YX strncpy(lp->d_typename, line, YX sizeof (lp->d_typename)); YX break; YX case 'l': YX strncpy(junk, lp->d_packname, YX sizeof (lp->d_packname)); YX junk[sizeof (lp->d_packname)] = '\0'; YX printf("label [%s]: ", junk); YX gets(line); YX if (line[0]) YX strncpy(lp->d_packname, line, YX sizeof (lp->d_packname)); YX break; YX case 'f': YX doflags(lp); YX break; YX case 'r': YX fillin_int(&lp->d_rpm, "rpm [%d]: ", 32767); YX break; YX case 'D': YX dodrivedata(lp); YX break; YX case 'q': YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXdodrivedata(lp) YX struct disklabel *lp; YX { YX register u_long *ulp; YX register int i; YX YX for (i = 0, ulp = lp->d_drivedata; i < NDDATA; i++, ulp++) YX { YX printf("modify misc drivedata\n"); YX printf("drivedata #%d [%D]: ", i, *ulp); YX gets(line); YX if (line[0]) YX *ulp = atol(line); YX } YX return; YX } YX YXdoflags(lp) YX register struct disklabel *lp; YX { YX register int c; YX YX while (1) YX { YX printf("modify misc flags\n"); YX printf("d(isplay) c(lear) e(cc) b(adsect) r(emovable) q(uit)? "); YX c = egetchar("dcerbq"); YX switch (c) YX { YX case 'c': YX lp->d_flags = 0; YX break; YX case 'd': YX displaylabel(lp); YX break; YX case 'r': YX lp->d_flags |= D_REMOVABLE; YX break; YX case 'e': YX lp->d_flags |= D_ECC; YX break; YX case 'b': YX lp->d_flags |= D_BADSECT; YX break; YX case 'q': YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXdopartitions(lp) YX struct disklabel *lp; YX { YX register int c; YX int i; YX YX while (1) YX { YX printf("modify partitions\n"); YX printf("d(isplay) n(umber) s(elect) q(uit)? "); YX c = egetchar("dsnq"); YX switch (c) YX { YX case 'd': YX displaylabel(lp); YX break; YX case 'n': YX printf("Number of partitions (%d max) [%d]? ", YX MAXPARTITIONS, lp->d_npartitions); YX gets(line); YX if (line[0] == '\0') YX i = lp->d_npartitions; YX else YX i = atoi(line); YX if (i > 0 && i <= MAXPARTITIONS) YX lp->d_npartitions = i; YX break; YX case 's': YX printf("a b c d e f g h q(uit)? "); YX i = getpartnum(); YX if (i < 0) YX break; YX if (i > lp->d_npartitions) YX lp->d_npartitions = i + 1; YX dopartmods(lp, i); YX break; YX case 'q': YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXdopartmods(lp, part) YX struct disklabel *lp; YX int part; YX { YX char pname = 'a' + part; YX int i, c; YX register struct partition *pp = &lp->d_partitions[part]; YX u_int cyl; YX daddr_t off, sec, size; YX YX printf("sizes and offsets may be given as sectors, cylinders\n"); YX printf("or cylinders plus sectors: 6200, 32c, 19c10s respectively\n"); YX YX while (1) YX { YX printf("modify partition '%c'\n", pname); YX printf("d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? "); YX c = egetchar("dztosfFq"); YX switch (c) YX { YX case 'z': YX pp->p_size = 0; YX pp->p_offset = 0; YX pp->p_fstype = FS_UNUSED; YX break; YX case 'd': YX displaylabel(lp); YX break; YX case 't': YX if (pp->p_fstype >= FSMAXTYPES) YX pp->p_fstype = FS_UNUSED; YX printf("'%c' fstype [%s]: ", pname, YX fstypenames[pp->p_fstype]); YX gets(line); YX if (line[0]) YX pp->p_fstype = findtype(fstypenames, YX line, YX pp->p_fstype); YX break; YX case 'o': YX printf("'%c' offset [%D]: ",pname,pp->p_offset); YX gets(line); YX if (line[0] == '\0') YX break; YX i = parse_sec_cyl(lp, line, &sec, &cyl); YX if (i < 0) YX break; YX if (cyl) YX off = lp->d_secpercyl * cyl; YX else YX off = 0; YX off += sec; YX pp->p_offset = off; YX break; YX case 's': YX printf("'%c' size [%D]: ", pname, pp->p_size); YX gets(line); YX if (line[0] == '\0') YX break; YX i = parse_sec_cyl(lp, line, &sec, &cyl); YX if (i < 0) YX break; YX if (cyl) YX size = lp->d_secpercyl * cyl; YX else YX size = 0; YX size += sec; YX pp->p_size = size; YX break; YX case 'f': YX printf("'%c' frags/fs-block [1]: ", pname); YX gets(line); YX if (line[0] == '\0') YX break; YX i = atoi(line); YX if (i <= 0 || i > 255) YX { YX printf("frags/block <= 0 || > 255\n"); YX pp->p_frag = 1; YX } YX else YX pp->p_frag = i; YX break; YX case 'F': /* Not really used at the present */ YX printf("'%c' frag size [1024]: ", pname); YX gets(line); YX if (line[0] == '\0') YX break; YX i = atoi(line); YX if (i <= 0 || (i % NBPG)) YX { YX printf("fragsize <= 0 || ! % NBPG\n"); YX pp->p_fsize = 0; YX } YX else YX pp->p_fsize = i; YX break; YX case 'q': YX if (pp->p_fsize == 0) YX pp->p_fsize = 1024; YX if (pp->p_frag == 0) YX pp->p_frag = 1; YX return; YX default: YX break; YX } YX } YX/* NOTREACHED */ YX } YX YXgetpartnum() YX { YX register int c; YX YX c = egetchar("abcdefghq"); YX if (c == 'q') YX return(-1); YX return(c - 'a'); YX } YX YXfindtype(list, name, deflt) YX char **list; YX char *name; YX int deflt; YX { YX register char **cpp; YX int i; YX YX for (i = 0, cpp = list; *cpp; cpp++, i++) YX { YX if (strcmp(*cpp, name) == 0) YX return(i); YX } YX printf("%s not found in list. The possible choices are:\n\n", name); YX for (cpp = list; *cpp; cpp++) YX printf(" %s\n", *cpp); YX putchar('\n'); YX return(deflt); YX } YX YX/* YX * Sizes and offsets can be specified in four ways: YX * YX * Number of sectors: 32678 YX * Number of cylinders: 110c YX * Number of cylinders and sectors: 29c14s YX * Number of sectors and cylinders: 22s134c YX * YX * The trailing 's' or 'c' can be left off in the last two cases. YX * YX * The geometry section of the label must have been filled in previously. YX * A warning is issued if the cylinder or cylinder+sector forms are used YX * and the necessary geometry information is not present. YX*/ YX YXparse_sec_cyl(lp, line, sec, cyl) YX struct disklabel *lp; YX char line[]; YX daddr_t *sec; YX u_int *cyl; YX { YX register char *cp; YX int error = 0; YX long tmp, tmpcyl = 0, tmpsec = 0; YX YX for (tmp = 0, cp = line; *cp; cp++) YX { YX if (*cp >= '0' && *cp <= '9') YX { YX tmp *= 10; YX tmp += (*cp - '0'); YX } YX else if (*cp == 'c') YX { YX if (tmpcyl) YX { YX printf("duplicate 'c'ylinder specified\n"); YX error = 1; YX break; YX } YX tmpcyl = tmp; YX tmp = 0; YX } YX else if (*cp == 's') YX { YX if (tmpsec) YX { YX printf("duplicate 's'ector specified\n"); YX error = 1; YX break; YX } YX tmpsec = tmp; YX tmp = 0; YX } YX else YX { YX printf("illegal character '%c'\n", *cp); YX error = 1; YX break; YX } YX } YX if (error) YX return(-1); YX YX/* YX * At this point if either a 's' or 'c' was encountered in the string then YX * one or both of 'tmpsec' and 'tmpcyl' will be non-zero. If the trailing YX * character was omitted we need to figure out which variable gets the YX * contents left in 'tmp' when the terminating null character was seen. This YX * is because "15c8" and "18s3" are both valid and indicate "15 cylinders + YX * 8 sectors" and "18 sectors + 3 cylinders" respectively. YX * YX * If neither 'tmpsec' or 'tmpcyl' are nonzero then we have a simple sector YX * number in 'tmp'. YX*/ YX if (tmpsec || tmpcyl) YX { YX if (tmpsec) YX tmpcyl = tmp; YX else YX tmpsec = tmp; YX } YX else YX { YX tmpsec = tmp; YX tmpcyl = 0; YX } YX/* YX * It is an error condition to specify a number of cylinders and not YX * have previously defined the geometry - it is impossible to calculate YX * the number of sectors in the partition without geometry. YX*/ YX if (tmpcyl && lp->d_secpercyl == 0) YX { YX printf("# cylinders specified but no geometry info present!\n"); YX return(-1); YX } YX YX/* YX * Sanity check to make sure erroneous number of cylinders is not believed YX * due to truncation (number of cylinders is really a 'u_int') YX*/ YX YX if (tmpcyl > 65535L) YX { YX printf("Number of cylinders specified (%D) is ridiculous!\n", YX tmpcyl); YX return(-1); YX } YX *cyl = (u_int)tmpcyl; YX *sec = tmpsec; YX return(0); YX } YX YXfillin_int(where, fmt, limit) YX u_int *where; YX char *fmt; YX u_int limit; YX { YX u_int i; YX YX printf(fmt, *where); YX gets(line); YX if (line[0]) YX { YX i = (u_int)atoi(line); YX if (i > limit) YX { YX printf("%d is out of bounds (> %d)\n", i, limit); YX return; YX } YX *where = i; YX } YX } YX YXfillin_long(where, fmt, limit) YX u_long *where; YX char *fmt; YX u_long limit; YX { YX u_long l; YX YX printf(fmt, *where); YX gets(line); YX if (line[0]) YX { YX l = (u_int)atol(line); YX if (l > limit) YX { YX printf("%D is out of bounds (> %D)\n", l, limit); YX return; YX } YX *where = l; YX } YX } YX YXgyon() YX { YX register int c; YX YX c = egetchar("yYnN"); YX if (c >= 'A' && c <= 'Z') YX c += ('a' - 'A'); YX return(c); YX } YX YXegetchar(str) YX char *str; YX { YX register int c; YX YX while (1) YX { YX c = getchar(); YX if (index(str, c)) YX break; YX putchar('\007'); YX } YX putchar(c); YX putchar('\n'); YX return(c); YX } YX YX/* YX * Check disklabel for errors and fill in YX * derived fields according to supplied values. YX * YX * Adapted from the disklabel utility. YX */ YXchecklabel(lp) YX register struct disklabel *lp; YX { YX register struct partition *pp; YX int i, errors = 0; YX char part; YX YX if (lp->d_nsectors == 0) YX { YX printf("sectors/track %d\n", lp->d_nsectors); YX return(1); YX } YX if (lp->d_ntracks == 0) YX { YX printf("tracks/cylinder %d\n", lp->d_ntracks); YX return(1); YX } YX if (lp->d_ncylinders == 0) YX { YX printf("cylinders/unit %d\n", lp->d_ncylinders); YX errors++; YX } YX if (lp->d_rpm == 0) YX Warning("revolutions/minute %d", lp->d_rpm); YX if (lp->d_secpercyl == 0) YX lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; YX if (lp->d_secperunit == 0) YX lp->d_secperunit = (long) lp->d_secpercyl * lp->d_ncylinders; YX YX for (i = 0; i < lp->d_npartitions; i++) YX { YX part = 'a' + i; YX pp = &lp->d_partitions[i]; YX if (pp->p_size == 0 && pp->p_offset != 0) YX Warning("partition %c: size 0, but offset %d", YX part, pp->p_offset); YX#ifdef notdef YX if (pp->p_size % lp->d_secpercyl) YX Warning("partition %c: size %% cylinder-size != 0", YX part); YX if (pp->p_offset % lp->d_secpercyl) YX Warning("partition %c: offset %% cylinder-size != 0", YX part); YX#endif YX if (pp->p_offset > lp->d_secperunit) YX { YX printf("partition %c: offset past end of unit %D %D\n", YX part, pp->p_offset, lp->d_secperunit); YX errors++; YX } YX if (pp->p_offset + pp->p_size > lp->d_secperunit) YX { YX printf("partition %c: extends past end of unit %D %D %D\n", YX part, pp->p_offset, pp->p_size, lp->d_secperunit); YX errors++; YX } YX } YX for (; i < MAXPARTITIONS; i++) YX { YX part = 'a' + i; YX pp = &lp->d_partitions[i]; YX if (pp->p_size || pp->p_offset) YX Warning("unused partition %c: size %D offset %D", YX 'a' + i, pp->p_size, pp->p_offset); YX } YX return(errors); YX } YX YX/*VARARGS1*/ YXWarning(fmt, a1, a2, a3, a4, a5) YX char *fmt; YX { YX YX printf("Warning, "); YX printf(fmt, a1, a2, a3, a4, a5); YX printf("\n"); YX } YSHAR_EOF Yfi Yexit 0 Y# End of shell archive SHAR_EOF fi if test -f 'pdpstand.patch' then echo shar: "will not over-write existing file 'pdpstand.patch'" else sed 's/^Y//' << \SHAR_EOF > 'pdpstand.patch' Y*** /usr/src/sys/pdpstand/M.s.old Sat Jul 4 00:03:21 1992 Y--- /usr/src/sys/pdpstand/M.s Mon Jun 5 20:26:53 1995 Y*************** Y*** 1,6 **** Y / Y / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 Y! / @(#)M.s 3.0 (2.11BSD) 7/03/92 (sms@wlv.iipo.gtegsc.com) Y / Y / Startup code for two-stage bootstrap with support for autoboot. Y / Supports 11/45, 11/70, 11/53, 11/73, 11/83, 11/84, 11/93, 11/94 Y--- 1,6 ---- Y / Y / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 Y! / @(#)M.s 3.1 (2.11BSD) 1995/06/01 (sms@wlv.iipo.gtegsc.com) Y / Y / Startup code for two-stage bootstrap with support for autoboot. Y / Supports 11/45, 11/70, 11/53, 11/73, 11/83, 11/84, 11/93, 11/94 Y*************** Y*** 37,45 **** Y / 192K and therefore overwrites boot here. Just change the .=400^. Y / below to something like .=10240^. This will move the critical Y / sections of boot up far enough so that the load can finish. Y! / We can't actually load boot higher than 192K since it has to be Y! / loaded on a 64K boundry and it can't use memory above 256-8K (so Y! / it can run on any system). Y / Y .=400^. Y Y--- 37,44 ---- Y / 192K and therefore overwrites boot here. Just change the .=400^. Y / below to something like .=10240^. This will move the critical Y / sections of boot up far enough so that the load can finish. Y! / We can't actually load boot too much higher because it can't use memory Y! / above 256-8K (to avoid UNIBUS mapping problems). Y / Y .=400^. Y Y*************** Y*** 79,99 **** Y Y Y / Set user I space registers to physical N*64kb and I/O page. This is Y! / where boot will copy itself to. Boot is very simple minded about its Y! / I/O addressing. To compute physical memory addresses for I/O devices, Y! / it simply hands off an address within itself as the low word and Y! / ``segflag'' as the high order word. This has the immediate consequence Y! / that boot *MUST* be located on a 64Kb boundry. Y / Y! / Also, several constraints force us to keep boot in the bootom 248Kb of Y! / memory (UNIBUS mapping being a primary contender.) If boot is ever Y! / fixed so that it can be located on a non-64Kb boundry this constraint Y! / will still be present. Y / Y! / All told, unless boot's method of managing its I/O addressing and Y! / physical addressing is completely reworked, 3*64Kb is probably the Y! / highest we'll ever see boot relocated. This means that the maximum size Y! / of any program boot can load is 192Kb. That size includes text, data Y / and bss. Y Y N = 3 / 3*64Kb = 192Kb Y--- 78,96 ---- Y Y Y / Set user I space registers to physical N*64kb and I/O page. This is Y! / where boot will copy itself to. Boot is less simple minded about its Y! / I/O addressing than it used to be. Physical memory addresses are now Y! / calculated (because support was needed for running split I/D utilities) Y! / rather than assuming that boot is loaded on a 64kb boundary. Y / Y! / The constraint forcing us to keep boot in the bottom 248Kb of Y! / memory is UNIBUS mapping. There would be little difficulty in relocating Y! / Boot much higher on a Qbus system. Y / Y! / Unless boot's method of managing its I/O addressing and physical addressing Y! / is reworked some more, 3*64Kb +/- a couple Kb is probably the highest Y! / we'll ever relocate boot. This means that the maximum size Y! / of any program boot can load is ~192Kb. That size includes text, data Y / and bss. Y Y N = 3 / 3*64Kb = 192Kb Y*************** Y*** 178,186 **** Y mov $_end+512.,sp Y mov sp,r5 Y Y- .globl _segflag Y- mov $N,_segflag Y- Y jsr pc,_main Y mov _cputype,r0 Y mov _bootcsr,r1 / csr of boot controller (from ROMs) Y--- 175,180 ---- Y*************** Y*** 294,302 **** Y .globl _clrseg Y _clrseg: Y mov 4(sp),r0 Y- beq 2f Y asr r0 Y bic $!77777,r0 Y mov 2(sp),r1 Y 1: Y clr -(sp) Y--- 288,296 ---- Y .globl _clrseg Y _clrseg: Y mov 4(sp),r0 Y asr r0 Y bic $!77777,r0 Y+ beq 2f Y mov 2(sp),r1 Y 1: Y clr -(sp) Y*************** Y*** 323,331 **** Y Y .globl __rtt Y __rtt: Y! halt Y Y! .globl _trap Y Y trap: Y mov *$PS,-(sp) Y--- 317,327 ---- Y Y .globl __rtt Y __rtt: Y! br . / Can't do halt because that is an illegal Y! / instruction in 'user mode' (which Boot Y! / runs in). Y Y! .globl _trap Y Y trap: Y mov *$PS,-(sp) Y*************** Y*** 365,373 **** Y Y .data Y .globl _cputype Y! .globl _ksep, _sep_id, _ubmap Y! .globl _bootopts, _bootdev, _checkword, _bootcsr Y Y nofault: .=.+2 / where to go on predicted trap Y _cputype: .=.+2 / cpu type Y _sep_id: .=.+1 / 1 if we have separate I and D Y--- 361,372 ---- Y Y .data Y .globl _cputype Y! .globl _ksep, _sep_id, _ubmap, _ssr3copy Y! .globl _bootopts, _bootdev, _checkword, _bootcsr, _bootctlr Y Y+ _ssr3copy: .=.+2 / copy of SSR3. Always 0 in Boot because that runs Y+ / in user mode. The standalone utilities which run Y+ / in kernel mode have their copy of SSR3 in srt0.s Y nofault: .=.+2 / where to go on predicted trap Y _cputype: .=.+2 / cpu type Y _sep_id: .=.+1 / 1 if we have separate I and D Y*************** Y*** 376,380 **** Y--- 375,380 ---- Y _bootopts: .=.+2 / flags if an autoboot Y _bootdev: .=.+2 / device booted from Y _bootcsr: .=.+2 / csr of device booted from Y+ _bootctlr: .=.+2 / number of controller booted from Y _checkword: .=.+2 / saved r2, complement of bootopts if an autoboot Y j11typ: .byte 0, 73., 83., 0, 53., 93. Y*** /usr/src/sys/pdpstand/Makefile.old Sat Apr 9 00:10:52 1994 Y--- /usr/src/sys/pdpstand/Makefile Wed Jun 7 21:11:57 1995 Y*************** Y*** 1,13 **** Y- # Y # Standalone Makefile Y # Y! # Note that there are limitations on how large a program may Y! # be loaded along with all device drivers. This is especially Y! # a problem with restor. Programs should be <= 48K to be safe. Y # Y # If a GENERIC kernel distribution is being created be sure Y # to install /sys/pdpdist/dtab (or /etc/dtab.save) as ${ROOT}/etc/dtab Y # so that the GENERIC kernel can find the tape device. Y Y # DISK which disk to take a root dump of for the distribution tape Y # TAPE which tape to write the distribution on Y--- 1,25 ---- Y # Standalone Makefile Y # Y! # The limitations on program size have been removed. The addition Y! # of disklabel support pushed 'restor' over the limit. Even with Y! # additional space saving measures it was impossible to fit restor Y! # into 48kb. 'icheck' and 'restor' are now built with split I/D. Y # Y+ # This is not as bad as it sounds - the kernel has not been able to Y+ # run on a non split machine for many years. It made little sense Y+ # to restrict the standalone utilities to non-split mode when the Y+ # operating system itself required split I/D. Y+ # Y+ # It is still possible to hand craft a version of the utilities by leaving Y+ # out all but the necessary drivers. Y+ # Y # If a GENERIC kernel distribution is being created be sure Y # to install /sys/pdpdist/dtab (or /etc/dtab.save) as ${ROOT}/etc/dtab Y # so that the GENERIC kernel can find the tape device. Y+ # Y+ # 1995/06/05 - add disklabel program to Makefile. Y+ # 1995/06/01 - use split I/D for icheck and restor. Y+ # 1995/05/30 - Begin adding disklabel support. Y Y # DISK which disk to take a root dump of for the distribution tape Y # TAPE which tape to write the distribution on Y*************** Y*** 23,38 **** Y RESTOR= ${ETCSRC}/restor/restor.c Y ICHECK= ${ETCSRC}/icheck.c Y Y! DEFS= -DSTANDALONE -I${ROOT}/usr/include Y CFLAGS= -O ${DEFS} Y Y BOOT= M.o boot.o ubmapset.o Y! DRIVERS=prf.o sys.o \ Y ht.o tm.o ts.o tmscp.o \ Y xp.o rk.o rl.o br.o hk.o si.o ra.o Y Y! ALL= mtboot boot mkfs restor icheck maketape toyset Y Y .c.o: Y cc ${CFLAGS} -c $*.c Y Y--- 35,52 ---- Y RESTOR= ${ETCSRC}/restor/restor.c Y ICHECK= ${ETCSRC}/icheck.c Y Y! DEFS= -DSTANDALONE -I${ROOT}/usr/include -I${ROOT}. Y CFLAGS= -O ${DEFS} Y Y BOOT= M.o boot.o ubmapset.o Y! DRIVERS=prf.o sys.o label.o \ Y ht.o tm.o ts.o tmscp.o \ Y xp.o rk.o rl.o br.o hk.o si.o ra.o Y Y! ALL= mtboot boot disklabel mkfs restor icheck maketape toyset Y Y+ all: ${ALL} Y+ Y .c.o: Y cc ${CFLAGS} -c $*.c Y Y*************** Y*** 39,45 **** Y .s.o: Y /lib/cpp -P ${DEFS} $< | as -u -V -o $@ Y Y! all: ${ALL} Y Y distribution: tape1 switch_tapes tape2 Y Y--- 53,60 ---- Y .s.o: Y /lib/cpp -P ${DEFS} $< | as -u -V -o $@ Y Y! srt0-i.o: srt0.s Y! /lib/cpp -P -DSPLIT_ID ${DEFS} srt0.s | as -u -V -o $@ Y Y distribution: tape1 switch_tapes tape2 Y Y*************** Y*** 90,96 **** Y ar rv $@ $? Y ranlib $@ Y Y- Y mkfs.o: ${MKFS} Y cc ${CFLAGS} -c ${MKFS} Y Y--- 105,110 ---- Y*************** Y*** 109,127 **** Y ld -X -o $@ M.o conf.o boot.o ubmapset.o libsa.a -lc Y Y mkfs: srt0.o conf.o libsa.a mkfs.o Y! ld -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y! restor: srt0.o conf.o libsa.a restor.o Y! ld -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y! icheck: srt0.o conf.o libsa.a icheck.o Y! ld -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y maketape: maketape.c Y cc -o $@ maketape.c Y Y toyset: toyset.o srt0.o conf.o libsa.a Y! ld -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y tags: FRC Y rm -f tags Y--- 123,144 ---- Y ld -X -o $@ M.o conf.o boot.o ubmapset.o libsa.a -lc Y Y mkfs: srt0.o conf.o libsa.a mkfs.o Y! ld -X -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y! restor: srt0-i.o conf.o libsa.a restor.o Y! ld -X -i -o $@ srt0-i.o conf.o $@.o libsa.a -lc Y Y! icheck: srt0-i.o conf.o libsa.a icheck.o Y! ld -X -i -o $@ srt0-i.o conf.o $@.o libsa.a -lc Y Y+ disklabel: srt0.o conf.o libsa.a disklabel.o displaylab.o Y+ ld -X -o $@ srt0.o conf.o $@.o displaylab.o libsa.a -lc Y+ Y maketape: maketape.c Y cc -o $@ maketape.c Y Y toyset: toyset.o srt0.o conf.o libsa.a Y! ld -X -o $@ srt0.o conf.o $@.o libsa.a -lc Y Y tags: FRC Y rm -f tags Y*************** Y*** 141,148 **** Y--- 158,168 ---- Y boot.o: boot.c Y conf.o: conf.c Y cat.o: cat.c Y+ displaylab.o: displaylab.c Y+ disklabel.o: disklabel.c Y hk.o: hk.c Y ht.o: ht.c Y+ label.o: label.c Y mtboot.o: mtboot.s Y prf.o: prf.c Y rk.o: rk.c Y*************** Y*** 149,154 **** Y--- 169,175 ---- Y rl.o: rl.c Y br.o: br.c Y srt0.o: srt0.s Y+ srt0-i.o: srt0.s Y sys.o: sys.c Y tm.o: tm.c Y tmscp.o: tmscp.c Y*** /usr/src/sys/pdpstand/boot.c.old Sat Jan 2 00:18:13 1993 Y--- /usr/src/sys/pdpstand/boot.c Thu Jun 8 19:31:39 1995 Y*************** Y*** 3,15 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)boot.c 2.2 (2.11BSD) 1/1/93 Y */ Y #include "../h/param.h" Y #include "../machine/seg.h" Y #include "../machine/koverlay.h" Y- #include "../h/fs.h" Y- #include "../h/inode.h" Y #include "../h/reboot.h" Y #include "saio.h" Y #include Y--- 3,13 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)boot.c 2.3 (2.11BSD) 1995/06/08 Y */ Y #include "../h/param.h" Y #include "../machine/seg.h" Y #include "../machine/koverlay.h" Y #include "../h/reboot.h" Y #include "saio.h" Y #include Y*************** Y*** 30,35 **** Y--- 28,34 ---- Y #define SEG_OVLY 04 Y Y extern caddr_t *bootcsr; /* csr of boot controller */ Y+ extern int bootctlr; /* boot controller number */ Y extern int bootopts; /* boot options from previous incarnation */ Y extern int bootdev; /* makedev(major,unit) booted from */ Y extern int checkword; /* one's complements of bootopts */ Y*************** Y*** 38,43 **** Y--- 37,46 ---- Y extern bool_t sep_id; /* does the cpu support separate I/D? */ Y extern int ndevsw; /* number of devices in devsw[] */ Y extern char ADJcsr[]; /* adjustments for ROM csr addresses */ Y+ extern char *itoa(); Y+ extern char *index(); Y+ extern struct devsw devsw[]; /* device table */ Y+ extern struct iob iob[]; /* I/O descriptor table */ Y Y char module[] = "Boot"; /* this program's name (used by trap) */ Y bool_t overlaid = 0; Y*************** Y*** 121,136 **** Y main() Y { Y register int i, j, maj; Y! int retry = 0; Y caddr_t *adjcsr; Y struct loadtable *setup(); Y struct iob *file; Y! char line[64], defnam[64], *itoa(); Y Y maj = major(bootdev); Y if (maj >= ndevsw) Y _stop("bad major"); /* can't happen */ Y adjcsr = (caddr_t *)((short)bootcsr - ADJcsr[maj]); Y for (i = 0; devsw[maj].dv_csr != (caddr_t) -1; i++) { Y if (adjcsr == devsw[maj].dv_csr[i]) Y break; Y--- 124,140 ---- Y main() Y { Y register int i, j, maj; Y! int retry = 0, unit, part; Y caddr_t *adjcsr; Y struct loadtable *setup(); Y struct iob *file; Y! char *cp, *defname = "unix", line[64], defdev[64]; Y Y maj = major(bootdev); Y if (maj >= ndevsw) Y _stop("bad major"); /* can't happen */ Y adjcsr = (caddr_t *)((short)bootcsr - ADJcsr[maj]); Y+ Y for (i = 0; devsw[maj].dv_csr != (caddr_t) -1; i++) { Y if (adjcsr == devsw[maj].dv_csr[i]) Y break; Y*************** Y*** 139,155 **** Y break; Y } Y } Y if (devsw[maj].dv_csr[i] == (caddr_t *) -1) Y _stop("no free csr slots"); Y bootdev &= ~(3 << 6); Y bootdev |= (i << 6); /* controller # to bits 6&7 */ Y! printf("\n%d%s from %s(%d,0,0%o)\n", cputype, module, Y! devsw[major(bootdev)].dv_name, minor(bootdev), bootcsr); Y! strcpy(defnam, devsw[major(bootdev)].dv_name); Y! strcat(defnam, "("); Y! strcat(defnam, itoa(minor(bootdev))); Y! strcat(defnam, ",0)unix"); Y! strcpy(line, defnam); Y /* Y * The machine language will have gotten the bootopts Y * if we're an autoboot and will pass them along. Y--- 143,169 ---- Y break; Y } Y } Y+ Y if (devsw[maj].dv_csr[i] == (caddr_t *) -1) Y _stop("no free csr slots"); Y bootdev &= ~(3 << 6); Y bootdev |= (i << 6); /* controller # to bits 6&7 */ Y! bootctlr = i; Y! unit = (minor(bootdev) >> 3) & 7; Y! part = minor(bootdev) & 7; Y! Y! printf("\n%d%s from %s(%d,%d,%d) at 0%o\n", cputype, module, Y! devsw[major(bootdev)].dv_name, bootctlr, unit, part, bootcsr); Y! Y! strcpy(defdev, devsw[major(bootdev)].dv_name); Y! strcat(defdev, "("); Y! strcat(defdev, itoa(bootctlr)); Y! strcat(defdev, ","); Y! strcat(defdev, itoa(unit)); Y! strcat(defdev, ","); Y! strcat(defdev, itoa(part)); Y! strcat(defdev, ")"); Y! Y /* Y * The machine language will have gotten the bootopts Y * if we're an autoboot and will pass them along. Y*************** Y*** 162,173 **** Y if (bootopts & RB_ASKNAME) { Y printf(": "); Y gets(line); Y! } else Y printf(": %s\n", line); Y if (line[0] == '\0') { Y! strcpy(line, defnam); Y printf(": %s\n", line); Y } Y i = open(line, 0); Y j = -1; Y if (i >= 0) { Y--- 176,201 ---- Y if (bootopts & RB_ASKNAME) { Y printf(": "); Y gets(line); Y! } else { Y! strcpy(line, defdev); Y! strcat(line, defname); Y printf(": %s\n", line); Y+ } Y if (line[0] == '\0') { Y! strcpy(line, defdev); Y! strcat(line, defname); Y printf(": %s\n", line); Y } Y+ /* Y+ * If a plain filename (/unix) is entered then prepend the default Y+ * device, e.g. ra(0,1,0) to the filename. Y+ */ Y+ cp = index(line, ')'); Y+ if (!cp) Y+ { Y+ bcopy(line, line + strlen(defdev), strlen(line) + 1); Y+ bcopy(defdev, line, strlen(defdev)); Y+ } Y i = open(line, 0); Y j = -1; Y if (i >= 0) { Y*************** Y*** 179,186 **** Y bootopts = RB_SINGLE | RB_ASKNAME; Y } while (j < 0); Y i = file->i_ino.i_dev; Y! bootdev = makedev(i, file->i_unit); Y! bootcsr = devsw[i].dv_csr[(file->i_unit >> 6) & 3]; Y bootcsr = (caddr_t *)((short)bootcsr + ADJcsr[i]); Y printf("%s: bootdev=0%o bootcsr=0%o\n", module, bootdev, bootcsr); Y } Y--- 207,215 ---- Y bootopts = RB_SINGLE | RB_ASKNAME; Y } while (j < 0); Y i = file->i_ino.i_dev; Y! bootdev = makedev(i, Y! ((file->i_ctlr << 6) | (file->i_unit << 3) | file->i_part)); Y! bootcsr = devsw[i].dv_csr[file->i_ctlr]; Y bootcsr = (caddr_t *)((short)bootcsr + ADJcsr[i]); Y printf("%s: bootdev=0%o bootcsr=0%o\n", module, bootdev, bootcsr); Y } Y*************** Y*** 222,228 **** Y checkunix(io, lt) Y struct loadtable *lt; Y { Y! char *segname; Y register int ovseg, segtype; Y register unsigned seglen; Y struct loadmap *lm = lt->lt_map; Y--- 251,257 ---- Y checkunix(io, lt) Y struct loadtable *lt; Y { Y! char *segname, *toosmall = "Base too small, %dK min\n"; Y register int ovseg, segtype; Y register unsigned seglen; Y struct loadmap *lm = lt->lt_map; Y*************** Y*** 304,316 **** Y switch (exec.a_magic) { Y case A_MAGIC5: Y if (seglen <= 8 KB) { Y! printf("Base too small, 8K min\n"); Y return(-1); Y } Y break; Y case A_MAGIC6: Y if (seglen <= 48 KB) { Y! printf("Base too small, 48K min\n"); Y return(-1); Y } Y break; Y--- 333,345 ---- Y switch (exec.a_magic) { Y case A_MAGIC5: Y if (seglen <= 8 KB) { Y! printf(toosmall, 8); Y return(-1); Y } Y break; Y case A_MAGIC6: Y if (seglen <= 48 KB) { Y! printf(toosmall, 48); Y return(-1); Y } Y break; Y*************** Y*** 375,381 **** Y ovseg++; Y break; Y default: Y! printf("copyunix: bad segment type %d\n", segtype); Y seglen=0; Y break; Y } Y--- 404,410 ---- Y ovseg++; Y break; Y default: Y! printf("copyunix: bad seg type %d\n", segtype); Y seglen=0; Y break; Y } Y*************** Y*** 383,388 **** Y--- 412,422 ---- Y if (!seglen) Y continue; Y setseg(phys); Y+ /* Y+ * ARGH! Despite (or in spite of) the earlier cautions against seeking and Y+ * tape devices here is an 'lseek' that caused problems loading split I/D Y+ * images from tape! Y+ */ Y if (exec.a_magic != A_MAGIC1) Y (void) lseek(io, segoff, 0); Y for (addr = 0; addr < seglen; addr += 2) Y*************** Y*** 557,574 **** Y register unsigned nclicks; Y { Y return((unsigned)(((((long) nclicks) + ((long) 63)) >> 6))); Y- } Y- Y- char * Y- itoa(i) Y- register int i; Y- { Y- static char x[8]; Y- register char *cp = x+8; Y- Y- do { Y- *--cp = (i % 10) + '0'; Y- i /= 10; Y- } while (i); Y- return(cp); Y } Y--- 591,594 ---- Y*** /usr/src/sys/pdpstand/br.c.old Sat Jan 2 00:20:10 1993 Y--- /usr/src/sys/pdpstand/br.c Thu Jun 8 19:32:49 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)br.c 2.1 (2.11BSD) 1/2/93 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)br.c 2.2 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 13,19 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/brreg.h" Y #include "saio.h" Y Y--- 13,18 ---- Y*************** Y*** 35,44 **** Y { Y register struct brdevice *braddr; Y register int ctlr; Y! int com, cn, tn, sn, unit, sectrk, trkcyl, ctr; Y Y! unit = UNITn(io->i_unit); Y! ctlr = CTLRn(io->i_unit); Y braddr = BRcsr[ctlr]; Y Y /* if we haven't gotten the characteristics yet, do so now. */ Y--- 34,43 ---- Y { Y register struct brdevice *braddr; Y register int ctlr; Y! int com, cn, tn, sn, unit, sectrk, trkcyl, ctr, bae, lo16; Y Y! unit = io->i_unit; Y! ctlr = io->i_ctlr; Y braddr = BRcsr[ctlr]; Y Y /* if we haven't gotten the characteristics yet, do so now. */ Y*************** Y*** 69,81 **** Y sn = io->i_bn%(sectrk * trkcyl); Y tn = sn/sectrk; Y sn = sn%sectrk; Y braddr->brcs.w = (unit<<8); Y braddr->brda = (tn<<8) | sn; Y braddr->brca = cn; Y! braddr->brba = io->i_ma; Y braddr->brwc = -(io->i_cc>>1); Y! braddr->brae = segflag; Y! com = (segflag<<4)|BR_GO; Y if (func == READ) Y com |= BR_RCOM; Y else Y--- 68,82 ---- Y sn = io->i_bn%(sectrk * trkcyl); Y tn = sn/sectrk; Y sn = sn%sectrk; Y+ Y+ iomapadr(io->i_ma, &bae, &lo16); Y braddr->brcs.w = (unit<<8); Y braddr->brda = (tn<<8) | sn; Y braddr->brca = cn; Y! braddr->brba = (caddr_t)lo16; Y braddr->brwc = -(io->i_cc>>1); Y! braddr->brae = bae; Y! com = (bae<<4)|BR_GO; Y if (func == READ) Y com |= BR_RCOM; Y else Y*** /usr/src/sys/pdpstand/conf.c.old Tue Apr 23 10:39:58 1991 Y--- /usr/src/sys/pdpstand/conf.c Thu Jun 15 20:09:14 1995 Y*************** Y*** 3,56 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)conf.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "saio.h" Y Y! devread(io) Y! register struct iob *io; Y! { Y Y- return((*devsw[io->i_ino.i_dev].dv_strategy)(io, READ)); Y- } Y- Y- devwrite(io) Y- register struct iob *io; Y- { Y- return((*devsw[io->i_ino.i_dev].dv_strategy)(io, WRITE)); Y- } Y- Y- devopen(io) Y- register struct iob *io; Y- { Y- return((*devsw[io->i_ino.i_dev].dv_open)(io)); Y- } Y- Y- devclose(io) Y- register struct iob *io; Y- { Y- (*devsw[io->i_ino.i_dev].dv_close)(io); Y- } Y- Y- nullsys() Y- { Y- return(-1); Y- } Y- Y extern int xpstrategy(), xpopen(); Y extern int brstrategy(), bropen(); Y extern int rkstrategy(), rkopen(); Y extern int hkstrategy(), hkopen(); Y! extern int rlstrategy(), rlopen(); Y extern int sistrategy(), siopen(); Y! extern int rastrategy(), raopen(), raclose(); Y! extern int tmstrategy(), tmopen(), tmclose(); Y! extern int htstrategy(), htopen(), htclose(); Y! extern int tsstrategy(), tsopen(), tsclose(); Y! extern int tmscpstrategy(), tmscpopen(), tmscpclose(); Y Y extern caddr_t *XPcsr[], *BRcsr[], *RKcsr[], *HKcsr[], *RLcsr[]; Y extern caddr_t *SIcsr[], *RAcsr[], *TMcsr[], *HTcsr[], *TScsr[], *TMScsr[]; Y--- 3,27 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)conf.c 2.3 (2.11BSD) 1995/06/15 Y */ Y Y #include "../h/param.h" Y #include "saio.h" Y Y! int nullsys(); Y Y extern int xpstrategy(), xpopen(); Y extern int brstrategy(), bropen(); Y extern int rkstrategy(), rkopen(); Y extern int hkstrategy(), hkopen(); Y! extern int rlstrategy(), rlopen(), rllabel(); Y extern int sistrategy(), siopen(); Y! extern int rastrategy(), raopen(), raclose(), ralabel(); Y! extern int tmstrategy(), tmopen(), tmclose(), tmseek(); Y! extern int htstrategy(), htopen(), htclose(), htseek(); Y! extern int tsstrategy(), tsopen(), tsclose(), tsseek(); Y! extern int tmscpstrategy(), tmscpopen(), tmscpclose(), tmscpseek(); Y Y extern caddr_t *XPcsr[], *BRcsr[], *RKcsr[], *HKcsr[], *RLcsr[]; Y extern caddr_t *SIcsr[], *RAcsr[], *TMcsr[], *HTcsr[], *TScsr[], *TMScsr[]; Y*************** Y*** 62,80 **** Y Y struct devsw devsw[] = { Y "ht", htstrategy, htopen, htclose, HTcsr, /* 0 */ Y "tm", tmstrategy, tmopen, tmclose, TMcsr, /* 1 */ Y "ts", tsstrategy, tsopen, tsclose, TScsr, /* 2 */ Y "ram", nullsys, nullsys, nullsys, 0, /* 3 */ Y "hk", hkstrategy, hkopen, nullsys, HKcsr, /* 4 */ Y "ra", rastrategy, raopen, raclose, RAcsr, /* 5 */ Y "rk", rkstrategy, rkopen, nullsys, RKcsr, /* 6 */ Y "rl", rlstrategy, rlopen, nullsys, RLcsr, /* 7 */ Y "rx", nullsys, nullsys, nullsys, 0, /* 8 */ Y "si", sistrategy, siopen, nullsys, SIcsr, /* 9 */ Y "xp", xpstrategy, xpopen, nullsys, XPcsr, /* 10 */ Y "br", brstrategy, bropen, nullsys, BRcsr, /* 11 */ Y "tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */ Y! 0, 0, 0, 0, Y }; Y Y int ndevsw = (sizeof (devsw) / sizeof (devsw[0])) - 1; Y--- 33,65 ---- Y Y struct devsw devsw[] = { Y "ht", htstrategy, htopen, htclose, HTcsr, /* 0 */ Y+ nullsys, htseek, Y "tm", tmstrategy, tmopen, tmclose, TMcsr, /* 1 */ Y+ nullsys, tmseek, Y "ts", tsstrategy, tsopen, tsclose, TScsr, /* 2 */ Y+ nullsys, tsseek, Y "ram", nullsys, nullsys, nullsys, 0, /* 3 */ Y+ nullsys, nullsys, Y "hk", hkstrategy, hkopen, nullsys, HKcsr, /* 4 */ Y+ nullsys, nullsys, Y "ra", rastrategy, raopen, raclose, RAcsr, /* 5 */ Y+ ralabel, nullsys, Y "rk", rkstrategy, rkopen, nullsys, RKcsr, /* 6 */ Y+ nullsys, nullsys, Y "rl", rlstrategy, rlopen, nullsys, RLcsr, /* 7 */ Y+ rllabel, nullsys, Y "rx", nullsys, nullsys, nullsys, 0, /* 8 */ Y+ nullsys, nullsys, Y "si", sistrategy, siopen, nullsys, SIcsr, /* 9 */ Y+ nullsys, nullsys, Y "xp", xpstrategy, xpopen, nullsys, XPcsr, /* 10 */ Y+ nullsys, nullsys, Y "br", brstrategy, bropen, nullsys, BRcsr, /* 11 */ Y+ nullsys, nullsys, Y "tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */ Y! nullsys, tmscpseek, Y! 0, 0, 0, 0, 0, Y! nullsys, nullsys, Y }; Y Y int ndevsw = (sizeof (devsw) / sizeof (devsw[0])) - 1; Y*************** Y*** 95,97 **** Y--- 80,178 ---- Y 4, /* BR =11 */ Y 0, /* TMS = 12 */ Y }; Y+ Y+ devread(io) Y+ register struct iob *io; Y+ { Y+ Y+ return((*devsw[io->i_ino.i_dev].dv_strategy)(io, READ)); Y+ } Y+ Y+ devwrite(io) Y+ register struct iob *io; Y+ { Y+ return((*devsw[io->i_ino.i_dev].dv_strategy)(io, WRITE)); Y+ } Y+ Y+ devopen(io) Y+ register struct iob *io; Y+ { Y+ return((*devsw[io->i_ino.i_dev].dv_open)(io)); Y+ } Y+ Y+ devclose(io) Y+ register struct iob *io; Y+ { Y+ (*devsw[io->i_ino.i_dev].dv_close)(io); Y+ } Y+ Y+ /* Y+ * Call the 'seek' entry for a tape device. Seeking only works for 1kb Y+ * records - which is how the executables are stored - not for the dump Y+ * or tar files on a boot tape. Y+ */ Y+ devseek(io, space) Y+ register struct iob *io; Y+ int space; Y+ { Y+ return((*devsw[io->i_ino.i_dev].dv_seek)(io, space)); Y+ } Y+ Y+ devlabel(io, fnc) Y+ register struct iob *io; Y+ int fnc; Y+ { Y+ int (*dvlab)() = devsw[io->i_ino.i_dev].dv_label; Y+ int (*strat)() = devsw[io->i_ino.i_dev].dv_strategy; Y+ register struct disklabel *lp; Y+ register struct partition *pi; Y+ char *name = devsw[io->i_ino.i_dev].dv_name; Y+ Y+ switch (fnc) Y+ { Y+ case WRITELABEL: Y+ return(writelabel(io, strat, name)); Y+ case READLABEL: Y+ return(readlabel(io, strat, name)); Y+ case DEFAULTLABEL: Y+ /* Y+ * Zero out the label buffer and then assign defaults common to all drivers. Y+ * Many of these are rarely (if ever) changed. The 'a' partition is set up Y+ * to be one sector past the label sector - the driver is expected to change Y+ * this to span the volume once the size is known. Y+ */ Y+ lp = &io->i_label; Y+ pi = &lp->d_partitions[0]; Y+ bzero(lp, sizeof (struct disklabel)); Y+ lp->d_npartitions = 1; Y+ pi->p_offset = 0; Y+ pi->p_size = LABELSECTOR + 1; Y+ pi->p_fsize = DEV_BSIZE; Y+ pi->p_frag = 1; Y+ pi->p_fstype = FS_V71K; Y+ strcpy(lp->d_packname, "DEFAULT"); Y+ lp->d_secsize = 512; Y+ lp->d_interleave = 1; Y+ lp->d_rpm = 3600; Y+ /* Y+ * param.h declares BBSIZE to be DEV_BSIZE which is 1kb. This is _wrong_, Y+ * the boot block size (what the bootroms read) is 512. The disklabel(8) Y+ * program explicitly sets d_bbsize to 512 so we do the same thing here. Y+ * Y+ * What a mess - when the 1k filesystem was created there should have been Y+ * a (clearer) distinction made between '(hardware) sectors' and Y+ * '(filesystem) blocks'. Sigh. Y+ */ Y+ lp->d_bbsize = 512; Y+ lp->d_sbsize = SBSIZE; Y+ return((*dvlab)(io)); Y+ default: Y+ printf("devlabel: bad fnc %d\n"); Y+ return(-1); Y+ } Y+ } Y+ Y+ nullsys() Y+ { Y+ return(-1); Y+ } Y*** /usr/src/sys/pdpstand/hk.c.old Sun Apr 21 00:06:35 1991 Y--- /usr/src/sys/pdpstand/hk.c Thu Jun 8 19:35:27 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)hk.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)hk.c 2.1 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 11,17 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/hkreg.h" Y #include "saio.h" Y Y--- 11,16 ---- Y*************** Y*** 35,44 **** Y register unit, com; Y register struct hkdevice *hkaddr; Y daddr_t bn; Y! int sn, cn, tn, ctlr; Y Y! unit = UNITn(io->i_unit); Y! ctlr = CTLRn(io->i_unit); Y hkaddr = HKcsr[ctlr]; Y if (hk_mntflg[ctlr][unit] != '1') { Y hk_drvtyp[ctlr][unit] = 0; Y--- 34,43 ---- Y register unit, com; Y register struct hkdevice *hkaddr; Y daddr_t bn; Y! int sn, cn, tn, ctlr, bae, lo16; Y Y! unit = io->i_unit; Y! ctlr = io->i_ctlr; Y hkaddr = HKcsr[ctlr]; Y if (hk_mntflg[ctlr][unit] != '1') { Y hk_drvtyp[ctlr][unit] = 0; Y*************** Y*** 70,80 **** Y tn = sn/NSECT; Y sn = sn%NSECT; Y Y hkaddr->hkcyl = cn; Y hkaddr->hkda = (tn<<8) | sn; Y! hkaddr->hkba = io->i_ma; Y hkaddr->hkwc = -(io->i_cc>>1); Y! com = hk_drvtyp[ctlr][unit]|(segflag << 8) | HK_GO; Y if (func == READ) Y com |= HK_READ; Y else if (func == WRITE) Y--- 69,80 ---- Y tn = sn/NSECT; Y sn = sn%NSECT; Y Y+ iomapadr(io->i_ma, &bae, &lo16); Y hkaddr->hkcyl = cn; Y hkaddr->hkda = (tn<<8) | sn; Y! hkaddr->hkba = (caddr_t)lo16; Y hkaddr->hkwc = -(io->i_cc>>1); Y! com = hk_drvtyp[ctlr][unit]|(bae << 8) | HK_GO; Y if (func == READ) Y com |= HK_READ; Y else if (func == WRITE) Y*** /usr/src/sys/pdpstand/ht.c.old Sun Apr 21 00:07:30 1991 Y--- /usr/src/sys/pdpstand/ht.c Thu Jun 8 19:35:38 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ht.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ht.c 2.2 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 11,17 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/htreg.h" Y #include "saio.h" Y Y--- 11,16 ---- Y*************** Y*** 32,51 **** Y register struct iob *io; Y { Y register skip; Y! register int ctlr = CTLRn(io->i_unit); Y! int i; Y Y if (genopen(NHT, io) < 0) Y return(-1); Y htstrategy(io, HT_REW); Y! skip = io->i_boff; Y while (skip--) { Y io->i_cc = -1; Y while (htstrategy(io, HT_SFORW)) Y continue; Y! i = 0; Y! while (--i) Y! continue; Y htstrategy(io, HT_SENSE); Y } Y return(0); Y--- 31,48 ---- Y register struct iob *io; Y { Y register skip; Y! register int ctlr = io->i_ctlr; Y Y if (genopen(NHT, io) < 0) Y return(-1); Y+ io->i_flgs |= F_TAPE; Y htstrategy(io, HT_REW); Y! skip = io->i_part; Y while (skip--) { Y io->i_cc = -1; Y while (htstrategy(io, HT_SFORW)) Y continue; Y! delay(30000); Y htstrategy(io, HT_SENSE); Y } Y return(0); Y*************** Y*** 57,71 **** Y htstrategy(io, HT_REW); Y } Y Y htstrategy(io, func) Y register struct iob *io; Y { Y register unit, com; Y! int errcnt, ctlr; Y register struct htdevice *htaddr; Y Y! unit = UNITn(io->i_unit); Y! ctlr = CTLRn(io->i_unit); Y htaddr = HTcsr[ctlr]; Y errcnt = 0; Y retry: Y--- 54,100 ---- Y htstrategy(io, HT_REW); Y } Y Y+ /* Y+ * Copy the space logic from the open routine but add the check for spacing Y+ * backwards. Y+ */ Y+ Y+ htseek(io, space) Y+ struct iob *io; Y+ register int space; Y+ { Y+ register int fnc; Y+ Y+ if (space < 0) Y+ { Y+ space = -space; Y+ fnc = HT_SREV; Y+ } Y+ else Y+ fnc = HT_SFORW; Y+ while (space--) Y+ { Y+ io->i_cc = -1; Y+ htstrategy(io, fnc); Y+ delay(30000); Y+ htstrategy(io, HT_SENSE); Y+ } Y+ } Y+ Y+ /* Y+ * Returns 0 if no tape mark was seen. Returns 1 if a tape mark (or error) Y+ * has been encountered. Y+ */ Y+ Y htstrategy(io, func) Y register struct iob *io; Y { Y register unit, com; Y! int errcnt, ctlr, bae, lo16; Y register struct htdevice *htaddr; Y Y! unit = io->i_unit; Y! ctlr = io->i_ctlr; Y htaddr = HTcsr[ctlr]; Y errcnt = 0; Y retry: Y*************** Y*** 74,86 **** Y while (htaddr->htfs & HTFS_PIP) Y continue; Y Y htaddr->httc = Y ((io->i_unit&H_1600BPI) ? HTTC_1600BPI : HTTC_800BPI) Y | HTTC_PDP11 | unit; Y! htaddr->htba = io->i_ma; Y htaddr->htfc = -io->i_cc; Y htaddr->htwc = -(io->i_cc >> 1); Y! com = ((segflag) << 8) | HT_GO; Y if (func == READ) Y com |= HT_RCOM; Y else if (func == WRITE) Y--- 103,116 ---- Y while (htaddr->htfs & HTFS_PIP) Y continue; Y Y+ iomapadr(io->i_ma, &bae, &lo16); Y htaddr->httc = Y ((io->i_unit&H_1600BPI) ? HTTC_1600BPI : HTTC_800BPI) Y | HTTC_PDP11 | unit; Y! htaddr->htba = (caddr_t) lo16; Y htaddr->htfc = -io->i_cc; Y htaddr->htwc = -(io->i_cc >> 1); Y! com = (bae << 8) | HT_GO; Y if (func == READ) Y com |= HT_RCOM; Y else if (func == WRITE) Y*************** Y*** 101,107 **** Y } Y if (htaddr->htcs1 & HT_TRE) { Y if (errcnt == 0) Y! printf("\nHT%d,%d err: cs2=%o, er=%o", Y ctlr, unit, htaddr->htcs2, htaddr->hter); Y htinit(htaddr); Y if (errcnt++ == 10) { Y--- 131,137 ---- Y } Y if (htaddr->htcs1 & HT_TRE) { Y if (errcnt == 0) Y! printf("\nht%d,%d err: cs2=%o, er=%o", Y ctlr, unit, htaddr->htcs2, htaddr->hter); Y htinit(htaddr); Y if (errcnt++ == 10) { Y*** /usr/src/sys/pdpstand/maketape.data.old Sun Apr 28 17:01:04 1991 Y--- /usr/src/sys/pdpstand/maketape.data Mon Jun 12 19:27:35 1995 Y*************** Y*** 2,7 **** Y--- 2,9 ---- Y mtboot 1 Y boot 1 Y * 1 Y+ disklabel 2 Y+ * 1 Y mkfs 2 Y * 1 Y restor 2 Y*** /usr/src/sys/pdpstand/mtboot.s.old Fri May 3 23:55:21 1991 Y--- /usr/src/sys/pdpstand/mtboot.s Wed May 31 19:54:10 1995 Y*************** Y*** 1,6 **** Y--- 1,8 ---- Y /* Y * Primary tape boot program to load and execute secondary boot. Y * Y+ * 1995/05/31 - unit number changed to be in bits 3-5 of 'bootdev' Y+ * Y * This is a universal tape boot which can handle HT, TM, TS and TMSCP Y * tapes. This boot is FULL. Some of the more extended error Y * checking had to be left out to get all the drivers to fit. Y*************** Y*** 100,105 **** Y--- 102,108 ---- Y blo 1b Y mov csr,r1 / put things where 'boot' Y mov unit,r3 / expects them Y+ ash $3,r3 / unit # in bits 3-5 Y bis major,r3 / the major device to high byte Y clr pc / go to location 0 ... no return Y Y*** /usr/src/sys/pdpstand/prf.c.old Sun Apr 21 00:13:07 1991 Y--- /usr/src/sys/pdpstand/prf.c Sun Jun 4 12:02:42 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)prf.c 1.2 (2.11BSD) 4/20/91 Y */ Y Y #include "../machine/cons.h" Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)prf.c 1.3 (2.11BSD) 1995/06/04 Y */ Y Y #include "../machine/cons.h" Y*************** Y*** 95,104 **** Y KLADDR->dlxbuf = c; Y if (c == '\n') { Y putchar('\r'); Y- putchar(0177); Y- putchar(0177); Y- putchar(0177); Y- putchar(0177); Y putchar(0177); Y } Y putchar(0); Y--- 95,100 ---- Y*** /usr/src/sys/pdpstand/ra.c.old Sat Jan 2 00:29:55 1993 Y--- /usr/src/sys/pdpstand/ra.c Mon Jul 10 21:56:45 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ra.c 2.3 (2.11BSD GTE) 1/1/93 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ra.c 2.5 (2.11BSD GTE) 1995/07/10 Y */ Y Y /* Y*************** Y*** 10,16 **** Y * MSCP disk device driver (rx23, rx33, rx50, rd??, ra??, rz??) Y */ Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../machine/mscp.h" Y #include "../pdpuba/rareg.h" Y #include "saio.h" Y--- 10,15 ---- Y*************** Y*** 52,57 **** Y--- 51,66 ---- Y } rd[NRA]; Y Y static u_char rainit[NRA]; Y+ static int mx(); Y+ Y+ extern char *itoa(); Y+ Y+ /* Y+ * This contains the volume size in sectors of units which have been Y+ * brought online. This value is used at default label generation time Y+ * along with the results of a 'get unit status' command to compute the Y+ * "geometry" of the drive. Y+ */ Y static long raonline[NRA][8]; Y Y raopen(io) Y*************** Y*** 59,69 **** Y { Y register struct radevice *raaddr; Y register struct ra *racom; Y! int i, ctlr, unit; Y Y! ctlr = CTLRn(io->i_unit); Y! unit = UNITn(io->i_unit); Y! if (genopen(NRA, io) < 0) Y return(-1); Y raaddr = RAcsr[ctlr]; Y racom = &rd[ctlr]; Y--- 68,79 ---- Y { Y register struct radevice *raaddr; Y register struct ra *racom; Y! struct disklabel *lp = &io->i_label; Y! int i, ctlr, unit, bae, lo16; Y Y! ctlr = io->i_ctlr; Y! unit = io->i_unit; Y! if (genopen(NRA, io) < 0) Y return(-1); Y raaddr = RAcsr[ctlr]; Y racom = &rd[ctlr]; Y*************** Y*** 75,94 **** Y raaddr->rasa = RA_ERR | (0154/4); Y if (ra_step(raaddr, RA_STEP2, 2)) Y goto again; Y! raaddr->rasa = (short)&racom->ra_ca.ca_ringbase; Y if (ra_step(raaddr, RA_STEP3, 3)) Y goto again; Y! raaddr->rasa = segflag; Y if (ra_step(raaddr, RA_STEP4, 4)) Y goto again; Y raaddr->rasa = RA_GO; Y! racom->ra_ca.ca_rspl = (short)&racom->ra_rsp.m_cmdref; Y! racom->ra_ca.ca_rsph = segflag; Y! racom->ra_ca.ca_cmdl = (short)&racom->ra_cmd.m_cmdref; Y! racom->ra_ca.ca_cmdh = segflag; Y! racom->ra_cmd.m_cntflgs = 0; Y! if (racmd(M_O_STCON, io->i_unit) < 0) { Y! printf("RA%d STCON err\n", ctlr); Y return(-1); Y } Y rainit[ctlr] = 1; Y--- 85,100 ---- Y raaddr->rasa = RA_ERR | (0154/4); Y if (ra_step(raaddr, RA_STEP2, 2)) Y goto again; Y! iomapadr(&racom->ra_ca.ca_ringbase, &bae, &lo16); Y! raaddr->rasa = lo16; Y if (ra_step(raaddr, RA_STEP3, 3)) Y goto again; Y! raaddr->rasa = bae; Y if (ra_step(raaddr, RA_STEP4, 4)) Y goto again; Y raaddr->rasa = RA_GO; Y! if (racmd(M_O_STCON, io) < 0) { Y! printf("ra%d STCON err\n", ctlr); Y return(-1); Y } Y rainit[ctlr] = 1; Y*************** Y*** 97,102 **** Y--- 103,118 ---- Y if (raonline[ctlr][unit] == 0) Y if (ramount(io) == -1) Y return(-1); Y+ if (devlabel(io, READLABEL) == -1) Y+ return(-1); Y+ if (io->i_part >= lp->d_npartitions || Y+ lp->d_partitions[io->i_part].p_size == 0) Y+ { Y+ printf("ra%d,%d%c bad partition # or size = 0\n", Y+ ctlr, unit, 'a' + io->i_part); Y+ return(-1); Y+ } Y+ io->i_boff = lp->d_partitions[io->i_part].p_offset; Y return(0); Y } Y Y*************** Y*** 103,109 **** Y raclose(io) Y register struct iob *io; Y { Y! raonline[CTLRn(io->i_unit)][UNITn(io->i_unit)] = 0; Y return(0); Y } Y Y--- 119,125 ---- Y raclose(io) Y register struct iob *io; Y { Y! raonline[io->i_ctlr][io->i_unit] = 0; Y return(0); Y } Y Y*************** Y*** 110,120 **** Y ramount(io) Y register struct iob *io; Y { Y! register int ctlr = CTLRn(io->i_unit); Y! register int unit = UNITn(io->i_unit); Y Y! if (racmd(M_O_ONLIN, io->i_unit) < 0) { Y! printf("RA%d: online err\n", io->i_unit); Y return(-1); Y } Y raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow + Y--- 126,136 ---- Y ramount(io) Y register struct iob *io; Y { Y! register int ctlr = io->i_ctlr; Y! register int unit = io->i_unit; Y Y! if (racmd(M_O_ONLIN, io) < 0) { Y! printf("ra%d,%d: !online\n", ctlr, unit); Y return(-1); Y } Y raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow + Y*************** Y*** 122,143 **** Y return(0); Y } Y Y! racmd(op, unit) Y! int op, unit; Y { Y register struct mscp *mp; Y! register int ctlr = CTLRn(unit); Y register struct ra *racom = &rd[ctlr]; Y struct radevice *csr = RAcsr[ctlr]; Y! int i; Y Y racom->ra_cmd.m_opcode = op; Y! racom->ra_cmd.m_unit = UNITn(unit); Y racom->ra_rsp.m_header.ra_msglen = sizeof(struct mscp); Y racom->ra_cmd.m_header.ra_msglen = sizeof(struct mscp); Y! racom->ra_ca.ca_rsph = RA_OWN | segflag; Y! racom->ra_ca.ca_cmdh = RA_OWN | segflag; Y i = csr->raip; Y mp = &racom->ra_rsp; Y while (1) { Y while (racom->ra_ca.ca_cmdh & RA_OWN) { Y--- 138,170 ---- Y return(0); Y } Y Y! racmd(op, io) Y! int op; Y! struct iob *io; Y { Y register struct mscp *mp; Y! int ctlr = io->i_ctlr; Y! int unit = io->i_unit; Y register struct ra *racom = &rd[ctlr]; Y struct radevice *csr = RAcsr[ctlr]; Y! int i, bae, lo16; Y Y racom->ra_cmd.m_opcode = op; Y! racom->ra_cmd.m_unit = unit; Y! racom->ra_cmd.m_cntflgs = 0; Y racom->ra_rsp.m_header.ra_msglen = sizeof(struct mscp); Y racom->ra_cmd.m_header.ra_msglen = sizeof(struct mscp); Y! Y! iomapadr(&racom->ra_rsp.m_cmdref, &bae, &lo16); Y! racom->ra_ca.ca_rspl = lo16; Y! racom->ra_ca.ca_rsph = RA_OWN | bae; Y! Y! iomapadr(&racom->ra_cmd.m_cmdref, &bae, &lo16); Y! racom->ra_ca.ca_cmdl = lo16; Y! racom->ra_ca.ca_cmdh = RA_OWN | bae; Y! Y i = csr->raip; Y+ Y mp = &racom->ra_rsp; Y while (1) { Y while (racom->ra_ca.ca_cmdh & RA_OWN) { Y*************** Y*** 154,191 **** Y racom->ra_ca.ca_rspint = 0; Y if (mp->m_opcode == (op | M_O_END)) Y break; Y! printf("RA%d: rsp %x op %x ignored\n", Y! unit,mp->m_header.ra_credits & 0xf0, mp->m_opcode); Y racom->ra_ca.ca_rsph |= RA_OWN; Y } Y if ((mp->m_status & M_S_MASK) != M_S_SUCC) { Y! printf("RA%d: err op=%x sts=%x\n",unit, Y mp->m_opcode, mp->m_status); Y return(-1); Y } Y return(0); Y fail: Y! printf("RA%d: rasa=%o\n", ctlr, csr->rasa); Y } Y Y rastrategy(io, func) Y register struct iob *io; Y { Y register struct mscp *mp; Y struct ra *racom; Y! register int ctlr = CTLRn(io->i_unit); Y Y! if (io->i_bn >= raonline[ctlr][UNITn(io->i_unit)]) Y! return(0); Y! Y! racom = &rd[ctlr]; Y mp = &racom->ra_cmd; Y mp->m_lbn_l = loint(io->i_bn); Y mp->m_lbn_h = hiint(io->i_bn); Y mp->m_bytecnt = io->i_cc; Y! mp->m_buf_l = (ushort)io->i_ma; Y! mp->m_buf_h = segflag; Y! if (racmd(func == READ ? M_O_READ : M_O_WRITE, io->i_unit) < 0) Y return(-1); Y return(io->i_cc); Y } Y--- 181,217 ---- Y racom->ra_ca.ca_rspint = 0; Y if (mp->m_opcode == (op | M_O_END)) Y break; Y! printf("ra%d: rsp %x op %x ignored\n", Y! ctlr,mp->m_header.ra_credits & 0xf0, mp->m_opcode); Y racom->ra_ca.ca_rsph |= RA_OWN; Y } Y if ((mp->m_status & M_S_MASK) != M_S_SUCC) { Y! printf("ra%d,%d: err op=%x sts=%x\n", ctlr, unit, Y mp->m_opcode, mp->m_status); Y return(-1); Y } Y return(0); Y fail: Y! printf("ra%d: rasa=%o\n", ctlr, csr->rasa); Y } Y Y rastrategy(io, func) Y register struct iob *io; Y+ int func; Y { Y register struct mscp *mp; Y struct ra *racom; Y! int bae, lo16; Y Y! racom = &rd[io->i_ctlr]; Y mp = &racom->ra_cmd; Y+ iomapadr(io->i_ma, &bae, &lo16); Y mp->m_lbn_l = loint(io->i_bn); Y mp->m_lbn_h = hiint(io->i_bn); Y mp->m_bytecnt = io->i_cc; Y! mp->m_buf_l = lo16; Y! mp->m_buf_h = bae; Y! if (racmd(func == READ ? M_O_READ : M_O_WRITE, io) < 0) Y return(-1); Y return(io->i_cc); Y } Y*************** Y*** 200,206 **** Y { Y delay(2000); Y cnt++; Y! if (cnt < 10000) Y continue; Y printf("RA(%o) failed step %d. retrying\n",csr,step); Y return(1); Y--- 226,232 ---- Y { Y delay(2000); Y cnt++; Y! if (cnt < 5000) Y continue; Y printf("RA(%o) failed step %d. retrying\n",csr,step); Y return(1); Y*************** Y*** 208,217 **** Y return(0); Y } Y Y! delay(l) Y! int l; Y { Y Y! while (l > 0) Y! l--; Y } Y--- 234,311 ---- Y return(0); Y } Y Y! /* Y! * This routine is called by the general 'devlabel' routine out of conf.c Y! * and is used by the standalone disklabel program to initialize the Y! * default disklabel. The MSCP driver does not need geometry info but Y! * it is almost trivial (because the drive has already been brought online by Y! * 'raopen') to fetch the required information with a 'get unit status' Y! * command. Y! */ Y! Y! ralabel(io) Y! struct iob *io; Y { Y+ register struct disklabel *lp = &io->i_label; Y+ register char *cp, *dp; Y+ daddr_t nblks = raonline[io->i_ctlr][io->i_unit]; Y+ struct mscp *mp = &rd[io->i_ctlr].ra_rsp; Y+ int nameid, numid; Y Y! lp->d_type = DTYPE_MSCP; Y! lp->d_partitions[0].p_size = nblks; /* span the drive with 'a' */ Y! /* lp->d_secperunit = nblks; /* size of entire volume */ Y! Y! if (racmd(M_O_GTUNT, io) != 0) Y! { Y! printf("ra%d,%d M_OP_GTUNT failed\n", io->i_ctlr, io->i_unit); Y! return(-1); Y! } Y! /* Y! * Yes it's a lot of code but since the standalone utilities (at least 'restor') Y! * are likely going to end up split I/D anyhow why not get the information. Y! * Y! * sectors/track Y! * tracks/group * group/cyl = tracks/cyl Y! * sectors/track * tracks/cyl = sectors/cyl Y! * sectors / sectors/cyl = cyl Y! */ Y! lp->d_nsectors = mp->m_track; Y! lp->d_ntracks = mp->m_group * mp->m_cylinder; Y! lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; Y! lp->d_ncylinders = nblks / lp->d_secpercyl; Y! nameid = (((loint(mp->m_mediaid) & 0x3f) << 9) | Y! ((hiint(mp->m_mediaid) >> 7) & 0x1ff)); Y! numid = hiint(mp->m_mediaid) & 0x7f; Y! /* Y! * Next put 'RA81' or 'RD54', etc into the typename field. Y! */ Y! cp = lp->d_typename; Y! *cp++ = mx(nameid, 2); Y! *cp++ = mx(nameid, 1); Y! dp = itoa(numid); Y! while (*cp++ = *dp++) Y! ; Y! *cp = mx(nameid, 0); Y! if (*cp != ' ') Y! cp++; Y! *cp = '\0'; Y! return(0); Y! } Y! Y! /* Y! * this is a routine rather than a macro to save space - shifting, etc Y! * generates a lot of code. Y! */ Y! Y! static Y! mx(l, i) Y! int l, i; Y! { Y! register int c; Y! Y! c = (l >> (5 * i)) & 0x1f; Y! if (c == 0) Y! c = ' ' - '@'; Y! return(c + '@'); Y } Y*** /usr/src/sys/pdpstand/rk.c.old Sun Apr 21 00:14:35 1991 Y--- /usr/src/sys/pdpstand/rk.c Thu Jun 8 19:36:31 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)rk.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)rk.c 2.1 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 11,17 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/rkreg.h" Y #include "saio.h" Y Y--- 11,16 ---- Y*************** Y*** 30,46 **** Y register com; Y register struct rkdevice *rkaddr; Y daddr_t bn; Y! int dn, cn, sn; Y Y bn = io->i_bn; Y! dn = UNITn(io->i_unit); Y cn = bn/12; Y sn = bn%12; Y! rkaddr = RKcsr[CTLRn(io->i_unit)]; Y rkaddr->rkda = (dn<<13) | (cn<<4) | sn; Y! rkaddr->rkba = io->i_ma; Y rkaddr->rkwc = -(io->i_cc>>1); Y! com = (segflag<<4)|RKCS_GO; Y if (func == READ) Y com |= RKCS_RCOM; Y else Y--- 29,46 ---- Y register com; Y register struct rkdevice *rkaddr; Y daddr_t bn; Y! int dn, cn, sn, bae, lo16; Y Y bn = io->i_bn; Y! dn = io->i_unit; Y cn = bn/12; Y sn = bn%12; Y! iomapadr(io->i_ma, &bae, &lo16); Y! rkaddr = RKcsr[io->i_ctlr]; Y rkaddr->rkda = (dn<<13) | (cn<<4) | sn; Y! rkaddr->rkba = (caddr_t)lo16; Y rkaddr->rkwc = -(io->i_cc>>1); Y! com = (bae<<4)|RKCS_GO; Y if (func == READ) Y com |= RKCS_RCOM; Y else Y*************** Y*** 50,57 **** Y continue; Y if (rkaddr->rkcs<0) { /* error bit */ Y printf("RK%d,%d err cy=%d sc=%d, er=%o, ds=%o\n", Y! CTLRn(io->i_unit), UNITn(io->i_unit), cn, sn, Y! rkaddr->rker, rkaddr->rkds); Y return(-1); Y } Y return(io->i_cc); Y--- 50,56 ---- Y continue; Y if (rkaddr->rkcs<0) { /* error bit */ Y printf("RK%d,%d err cy=%d sc=%d, er=%o, ds=%o\n", Y! io->i_ctlr, io->i_unit, cn, sn, rkaddr->rker, rkaddr->rkds); Y return(-1); Y } Y return(io->i_cc); Y*** /usr/src/sys/pdpstand/rl.c.old Sat Jan 2 00:31:59 1993 Y--- /usr/src/sys/pdpstand/rl.c Thu Jun 15 20:53:15 1995 Y*************** Y*** 3,20 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)rl.c 2.1 (2.11BSD) 1/2/93 Y */ Y Y /* Y * RL disk driver Y * Y * RL driver modified for the standalone shell. Y * Armando P. Stettner Digital Equipment Corp. July, 1980 Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/rlreg.h" Y #include "saio.h" Y Y--- 3,20 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)rl.c 2.3 (2.11BSD) 1995/06/15 Y */ Y Y /* Y * RL disk driver Y * Y+ * Modified to handle disklabels - 1995/06/15 Y * RL driver modified for the standalone shell. Y * Armando P. Stettner Digital Equipment Corp. July, 1980 Y */ Y Y #include "../h/param.h" Y #include "../pdpuba/rlreg.h" Y #include "saio.h" Y Y*************** Y*** 35,41 **** Y struct Rldrives Y { Y int cn[4]; /* location of heads for each drive */ Y! int type[4]; /* parameter dependent upon drive type (RL01/02) */ Y int com; /* read or write command word */ Y int chn; /* cylinder and head number */ Y unsigned int bleft; /* bytes left to be transferred */ Y--- 35,41 ---- Y struct Rldrives Y { Y int cn[4]; /* location of heads for each drive */ Y! int type[4]; /* # blocks on drive (RL01/02) */ Y int com; /* read or write command word */ Y int chn; /* cylinder and head number */ Y unsigned int bleft; /* bytes left to be transferred */ Y*************** Y*** 53,124 **** Y register struct iob *io; Y int func; Y { Y! int nblocks; /* number of UNIX blocks for the drive in question */ Y! int drive; Y int dif; Y int head; Y! int ctr; Y! int ctlr = CTLRn(io->i_unit); Y register struct rldevice *rladdr; Y register struct Rldrives *rlp; Y Y- /* Y- * We must determine what type of drive we are talking to in order Y- * to determine how many blocks are on the device. The rl.type[] Y- * array has been initialized with -1's so that we may test first Y- * contact with a particular drive and do this determination only once. Y- * Sorry tjk for this hack. Y- * Y- * RL02 GET STATUS BAND-AID - Fred Canter 10/14/80 Y- * Y- * For some unknown reason the RL02 (seems to be Y- * only drive 1) does not return a valid drive status Y- * the first time that a GET STATUS request is issued Y- * for the drive, in fact it can take up to three or more Y- * GET STATUS requests to obtain the correct status. Y- * In order to overcome this "HACK" the driver has been Y- * modified to issue a GET STATUS request, validate the Y- * drive status returned, and then use it to determine the Y- * drive type. If a valid status is not returned after eight Y- * attempts, then an error message is printed. Y- */ Y- drive = UNITn(io->i_unit); Y rladdr = RLcsr[ctlr]; Y rlp = &rl[ctlr]; Y Y! if (rlp->type[drive] < 0) { Y! ctr = 0; Y! do { Y! /* load this register; what a dumb controller */ Y! rladdr->rlda = RLDA_RESET|RLDA_GS; Y! /* set up csr */ Y! rladdr->rlcs = (drive << 8) | RL_GETSTATUS; Y! while ((rladdr->rlcs & RL_CRDY) == 0) /* wait for it */ Y! continue; Y! } while (((rladdr->rlmp & 0177477) != 035) && (++ctr < 8)); Y! if (ctr >= 8) Y! printf("\nCan't get RL%d,%d sts\n", ctlr, drive); Y! if (rladdr->rlmp & RLMP_DTYP) Y! rlp->type[drive] = BLKRL2; /* drive is RL02 */ Y! else Y! rlp->type[drive] = BLKRL1; /* drive RL01 */ Y! /* Y! * When the device is first touched, find out where the heads are. Y! */ Y! /* find where the heads are */ Y! rladdr->rlcs = (drive << 8) | RL_RHDR; Y! while ((rladdr->rlcs&RL_CRDY) == 0) Y! continue; Y! rlp->cn[drive] = ((rladdr->rlmp) >> 6) & 01777; Y! } Y! nblocks = rlp->type[drive]; /* how many blocks on this drive */ Y! if (io->i_bn >= nblocks) Y! return -1; Y rlp->chn = io->i_bn/20; Y rlp->sn = (io->i_bn%20) << 1; Y rlp->bleft = io->i_cc; Y! rlp->addr.w[0] = segflag; Y! rlp->addr.w[1] = (int)io->i_ma; Y rlp->com = (drive << 8); Y if (func == READ) Y rlp->com |= RL_RCOM; Y--- 53,75 ---- Y register struct iob *io; Y int func; Y { Y! int drive = io->i_unit; Y int dif; Y int head; Y! int bae, lo16; Y! int ctlr = io->i_ctlr; Y register struct rldevice *rladdr; Y register struct Rldrives *rlp; Y Y rladdr = RLcsr[ctlr]; Y rlp = &rl[ctlr]; Y Y! iomapadr(io->i_ma, &bae, &lo16); Y rlp->chn = io->i_bn/20; Y rlp->sn = (io->i_bn%20) << 1; Y rlp->bleft = io->i_cc; Y! rlp->addr.w[0] = bae; Y! rlp->addr.w[1] = lo16; Y rlp->com = (drive << 8); Y if (func == READ) Y rlp->com |= RL_RCOM; Y*************** Y*** 158,164 **** Y while ((rladdr->rlcs & RL_CRDY) == 0) /* wait for controller */ Y continue; Y } Y! printf("RL%d,%d err cy=%d, hd=%d, sc=%d, rlcs=%o, rlmp=%o\n", Y ctlr, drive, rlp->chn>>01, rlp->chn&01, rlp->sn, Y rladdr->rlcs, rladdr->rlmp); Y return(-1); Y--- 109,115 ---- Y while ((rladdr->rlcs & RL_CRDY) == 0) /* wait for controller */ Y continue; Y } Y! printf("rl%d,%d err cy=%d, hd=%d, sc=%d, rlcs=%o, rlmp=%o\n", Y ctlr, drive, rlp->chn>>01, rlp->chn&01, rlp->sn, Y rladdr->rlcs, rladdr->rlmp); Y return(-1); Y*************** Y*** 165,171 **** Y } Y /* Y * Determine if there is more to read to satisfy this request. Y! * This is to compensate for the lacl of spiraling reads. Y */ Y if ((rlp->bleft -= rlp->bpart) > 0) { Y rlp->addr.l += rlp->bpart; Y--- 116,122 ---- Y } Y /* Y * Determine if there is more to read to satisfy this request. Y! * This is to compensate for the lack of spiraling reads. Y */ Y if ((rlp->bleft -= rlp->bpart) > 0) { Y rlp->addr.l += rlp->bpart; Y*************** Y*** 177,183 **** Y } Y Y rlopen(io) Y! struct iob *io; Y! { Y! return(genopen(NRL, io)); Y } Y--- 128,230 ---- Y } Y Y rlopen(io) Y! register struct iob *io; Y! { Y! register struct disklabel *lp = &io->i_label; Y! register int part = io->i_part; Y! Y! if (io->i_unit > 3) Y! return(-1); Y! if (genopen(NRL, io) < 0) Y! return(-1); Y! rlgsts(io); /* get status and head position */ Y! if (devlabel(io, READLABEL) < 0) Y! return(-1); Y! if (part >= lp->d_npartitions || Y! lp->d_partitions[part].p_size == 0) Y! { Y! printf("rl%d,%d%c bad partition # or size = 0\n", Y! io->i_ctlr, io->i_unit, 'a' + part); Y! return(-1); Y! } Y! io->i_boff = lp->d_partitions[part].p_offset; Y! return(0); Y! } Y! Y! /* Y! * We must determine what type of drive we are talking to in order Y! * to determine how many blocks are on the device. The rl.type[] Y! * array has been initialized with -1's so that we may test first Y! * contact with a particular drive and do this determination only once. Y! * Y! * RL02 GET STATUS BAND-AID - Fred Canter 10/14/80 Y! * Y! * For some unknown reason the RL02 (seems to be Y! * only drive 1) does not return a valid drive status Y! * the first time that a GET STATUS request is issued Y! * for the drive, in fact it can take up to three or more Y! * GET STATUS requests to obtain the correct status. Y! * In order to overcome this "HACK" the driver has been Y! * modified to issue a GET STATUS request, validate the Y! * drive status returned, and then use it to determine the Y! * drive type. If a valid status is not returned after eight Y! * attempts, then an error message is printed. Y! */ Y! Y! rlgsts(io) Y! struct iob *io; Y! { Y! int ctr; Y! int drive = io->i_unit; Y! int ctlr = io->i_ctlr; Y! register struct Rldrives *rlp = &rl[ctlr]; Y! register struct rldevice *rladdr = RLcsr[ctlr]; Y! Y! Y! if (rlp->type[drive] < 0) { Y! ctr = 0; Y! do { Y! /* load this register; what a dumb controller */ Y! rladdr->rlda = RLDA_RESET|RLDA_GS; Y! /* set up csr */ Y! rladdr->rlcs = (drive << 8) | RL_GETSTATUS; Y! while ((rladdr->rlcs & RL_CRDY) == 0) /* wait for it */ Y! continue; Y! } while (((rladdr->rlmp & 0177477) != 035) && (++ctr < 8)); Y! if (ctr >= 8) Y! printf("\nCan't get rl%d,%d sts\n", ctlr, drive); Y! if (rladdr->rlmp & RLMP_DTYP) Y! rlp->type[drive] = BLKRL2; /* drive is RL02 */ Y! else Y! rlp->type[drive] = BLKRL1; /* drive RL01 */ Y! /* Y! * When device is first touched, find out where the heads are. Y! */ Y! rladdr->rlcs = (drive << 8) | RL_RHDR; Y! while ((rladdr->rlcs&RL_CRDY) == 0) Y! continue; Y! rlp->cn[drive] = ((rladdr->rlmp) >> 6) & 01777; Y! } Y! return; Y } Y+ Y+ /* Y+ * This generates a default label. 'rlopen' has already been called so Y+ * we can use the 'types' field as the number of sectors on the device. Y+ */ Y+ Y+ rllabel(io) Y+ register struct iob *io; Y+ { Y+ register struct disklabel *lp = &io->i_label; Y+ daddr_t nblks = rl[io->i_ctlr].type[io->i_unit]; Y+ Y+ lp->d_type = DTYPE_DEC; Y+ lp->d_partitions[0].p_size = nblks; Y+ lp->d_nsectors = 20; /* sectors per track */ Y+ lp->d_ntracks = 2; /* tracks per cylinder */ Y+ lp->d_secpercyl = 40; /* sectors per cylinder */ Y+ lp->d_ncylinders = nblks / (lp->d_nsectors * lp->d_ntracks); Y+ lp->d_secperunit = nblks; Y+ return(0); Y+ } Y*** /usr/src/sys/pdpstand/saio.h.old Fri Apr 12 22:06:04 1991 Y--- /usr/src/sys/pdpstand/saio.h Thu Jun 8 19:31:19 1995 Y*************** Y*** 3,31 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)saio.h 1.1 (2.10BSD Berkeley) 12/1/86 Y */ Y Y /* Y! * header file for standalone package Y! */ Y Y /* Y * io block: includes an Y! * inode, cells for the use of seek, etc, Y! * and a buffer. Y */ Y struct iob { Y char i_flgs; Y struct inode i_ino; Y! int i_unit; Y daddr_t i_boff; Y- daddr_t i_cyloff; Y off_t i_offset; Y daddr_t i_bn; Y char *i_ma; Y int i_cc; Y char i_buf[DEV_BSIZE]; Y }; Y Y #define F_READ 01 Y--- 3,40 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)saio.h 2.1 (2.11BSD GTE) 1995/06/08 Y */ Y Y /* Y! * This must be done so that the standalone I/O system uses the same Y! * size for the inode structure as the utilities (restor, mkfs, etc). Y! * See the comments in mkfs.c for more information. Y! */ Y! #undef EXTERNALITIMES Y Y+ #include Y+ #include Y+ #include Y+ Y /* Y * io block: includes an Y! * inode, cells for the use of seek, etc, a buffer Y! * and a disklabel. Y */ Y struct iob { Y char i_flgs; Y+ char i_ctlr; Y struct inode i_ino; Y! short i_unit; Y! short i_part; Y daddr_t i_boff; Y off_t i_offset; Y daddr_t i_bn; Y char *i_ma; Y int i_cc; Y char i_buf[DEV_BSIZE]; Y+ struct disklabel i_label; Y }; Y Y #define F_READ 01 Y*************** Y*** 32,40 **** Y--- 41,54 ---- Y #define F_WRITE 02 Y #define F_ALLOC 04 Y #define F_FILE 010 Y+ #define F_TAPE 020 Y #define READ F_READ Y #define WRITE F_WRITE Y Y+ #define READLABEL 0x1 Y+ #define WRITELABEL 0x2 Y+ #define DEFAULTLABEL 0x3 Y+ Y /* Y * device switch Y */ Y*************** Y*** 44,71 **** Y int (*dv_open)(); Y int (*dv_close)(); Y caddr_t **dv_csr; Y }; Y Y- struct devsw devsw[]; Y- Y- #define NBUFS 4 Y- Y- char b[NBUFS][DEV_BSIZE]; Y- daddr_t blknos[NBUFS]; Y- Y- #define NFILES 4 Y- struct iob iob[NFILES]; Y- Y /* Y! * Set to which 64Kb segment the code is physically running in. Y! * Must be set by the user's main (or thereabouts). Y! */ Y! int segflag; Y! Y! /* Y! * macros to extract the controller and unit number. common to all drivers Y! * so the macros are defined here rather than in each driver. Y */ Y! Y! #define CTLRn(dev) ((minor(dev) >> 6) & 3) Y! #define UNITn(dev) (minor(dev) & 7) Y--- 58,70 ---- Y int (*dv_open)(); Y int (*dv_close)(); Y caddr_t **dv_csr; Y+ int (*dv_label)(); Y+ int (*dv_seek)(); Y }; Y Y /* Y! * Set to inhibit 'disklabel missing or corrupt' error messages. This Y! * is normally left off and only set by the standalone disklabeling utility Y! * when it expects to be reading an unlabeled disk. Y */ Y! int Nolabelerr; Y*** /usr/src/sys/pdpstand/si.c.old Sat Jan 2 00:32:46 1993 Y--- /usr/src/sys/pdpstand/si.c Thu Jun 8 19:36:51 1995 Y*************** Y*** 3,15 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)si.c 2.0 (2.11BSD) 4/20/91 Y * Y * SI 9500 CDC 9766 Stand Alone disk driver Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/sireg.h" Y #include "saio.h" Y Y--- 3,14 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)si.c 2.1 (2.11BSD) 1995/06/08 Y * Y * SI 9500 CDC 9766 Stand Alone disk driver Y */ Y Y #include "../h/param.h" Y #include "../pdpuba/sireg.h" Y #include "saio.h" Y Y*************** Y*** 32,43 **** Y sistrategy(io, func) Y register struct iob *io; Y { Y! int unit = UNITn(io->i_unit); Y! register int ctlr = CTLRn(io->i_unit); Y register struct sidevice *siaddr = SIcsr[ctlr]; Y int ii; Y daddr_t bn; Y! int sn, cn, tn; Y Y /* Y * weirdness with bit 2 (04) removed - see xp.c for comments Y--- 31,42 ---- Y sistrategy(io, func) Y register struct iob *io; Y { Y! int unit = io->i_unit; Y! register int ctlr = io->i_ctlr; Y register struct sidevice *siaddr = SIcsr[ctlr]; Y int ii; Y daddr_t bn; Y! int sn, cn, tn, bae, lo16; Y Y /* Y * weirdness with bit 2 (04) removed - see xp.c for comments Y*************** Y*** 61,71 **** Y siaddr->sicnr = SI_RESET; Y siaddr->siscr = 1; Y } Y siaddr->sipcr = cn + (unit <<10); Y siaddr->sihsr = (tn << 5) + sn; Y! siaddr->simar = io->i_ma; Y siaddr->siwcr = io->i_cc >> 1; Y! ii = (segflag << 4) | SI_GO; Y if (func == READ) Y ii |= SI_READ; Y else if (func == WRITE) Y--- 60,71 ---- Y siaddr->sicnr = SI_RESET; Y siaddr->siscr = 1; Y } Y+ iomapadr(io->i_ma, &bae, &lo16); Y siaddr->sipcr = cn + (unit <<10); Y siaddr->sihsr = (tn << 5) + sn; Y! siaddr->simar = (caddr_t)lo16; Y siaddr->siwcr = io->i_cc >> 1; Y! ii = (bae << 4) | SI_GO; Y if (func == READ) Y ii |= SI_READ; Y else if (func == WRITE) Y*************** Y*** 77,83 **** Y continue; Y Y if (siaddr->sierr & SIERR_ERR) { Y! printf("SI%d,%d err cy=%d hd=%d sc=%d cnr=%o, err=%o\n", Y ctlr, unit, cn, tn, sn, siaddr->sicnr, siaddr->sierr); Y return(-1); Y } Y--- 77,83 ---- Y continue; Y Y if (siaddr->sierr & SIERR_ERR) { Y! printf("si%d,%d err cy=%d hd=%d sc=%d cnr=%o, err=%o\n", Y ctlr, unit, cn, tn, sn, siaddr->sicnr, siaddr->sierr); Y return(-1); Y } Y*** /usr/src/sys/pdpstand/srt0.s.old Tue Apr 23 21:29:33 1991 Y--- /usr/src/sys/pdpstand/srt0.s Mon Jun 5 20:29:16 1995 Y*************** Y*** 1,49 **** Y / Startup code for standalone utilities Y! / sms- mods to pass boot device and csr on to program Y! / wfj- mod's to allow non sep i/d machines, error recovery Y! / note that the bootstrap passes the cputype through in Y! / r0. Y Y PS = 177776 Y Y- .globl _end Y .globl _main, __rtt, _devsw, _ADJcsr Y! .globl _edata Y jmp start Y Y / Y / trap vectors Y / Y! trap;340 / bus error Y! trap;341 / illegal instruction Y! trap;342 / BPT Y! trap;343 / IOT Y! trap;344 / POWER FAIL Y! trap;345 / EMT Y! tvec: Y! start;346 / TRAP Y! .=400^. Y! .text Y Y- Y start: Y mov $340,*$PS Y! mov $trap,tvec Y! / Y! / restore what kind of cpu we are running on Y! mov r0,*$_cputype / assume that the boot left this in r0 Y mov r1,_bootcsr / assume that boot left csr in r1 Y mov r3,_bootdev / and boot device major,minor in r3 Y mov $157772,sp / return address,psw at 157774&6 Y- mov $_edata,r0 Y- mov $_end,r1 Y- sub r0,r1 Y- inc r1 Y- clc Y- ror r1 Y- 1: Y- clr (r0)+ Y- sob r1,1b Y Y / controller number is in bits 6&7 of r3 (_bootdev). major device number Y / is in bits 8-15. what we need to do now is place the csr into Y--- 1,57 ---- Y+ / 1995/06/04 - devsw[] entries are 14. bytes, need a tape seek routine entry. Y+ / 1995/06/02 - Modifications for split I/D to work. The vectors need to be Y+ / in 'data' space. Y+ / 1995/06/01 - Make copy of SSR3 so we can tell if split I/D is enabled. Y+ / 1995/05/30 - devsw[] entries are 12. bytes now. Y+ / Y / Startup code for standalone utilities Y! / sms - mods to pass boot device and csr on to program Y! / Y! / Note that the bootstrap passes the cputype through in r0. Y Y PS = 177776 Y+ SSR3 = 172516 Y Y .globl _main, __rtt, _devsw, _ADJcsr Y! Y! #ifdef SPLIT_ID Y! .data Y! #else Y! .text Y! #endif Y! ZERO: Y jmp start Y Y / Y / trap vectors Y / Y! trap;340 / 004 - bus error Y! trap;341 / 010 - illegal instruction Y! trap;342 / 014 - BPT Y! trap;343 / 020 - IOT Y! trap;344 / 024 - POWER FAIL Y! trap;345 / 030 - EMT Y! start;346 / 034 - TRAP Y! .= ZERO + 400 Y! .text Y Y start: Y mov $340,*$PS Y! mov $trap,*$034 Y! Y! / Save information which Boot has passed thru to us Y! Y! mov r0,_cputype / assume that the boot left this in r0 Y mov r1,_bootcsr / assume that boot left csr in r1 Y mov r3,_bootdev / and boot device major,minor in r3 Y+ Y+ / Make a copy of SSR3. If this register does not exist it is probably better Y+ / to trap now rather than later - the absence of this register means no split Y+ / I/D space and the kernel won't run. Y+ Y+ mov *$SSR3,_ssr3copy Y+ Y mov $157772,sp / return address,psw at 157774&6 Y Y / controller number is in bits 6&7 of r3 (_bootdev). major device number Y / is in bits 8-15. what we need to do now is place the csr into Y*************** Y*** 54,62 **** Y bic $!6,r0 / make a word index Y ash $-3,r3 / major device # to bits 0-7 Y mov r3,r2 / save major for later Y! mul $10.,r3 / devsw[] members are 10. bytes each Y mov _devsw+10(r3),r3 / get csrlist for driver Y add r0,r3 / point to controller's entry Y Y / the CSR passed from the ROMs is not necessarily the first address Y / of a device! We therefore have to adjust the CSR so that the structure Y--- 62,72 ---- Y bic $!6,r0 / make a word index Y ash $-3,r3 / major device # to bits 0-7 Y mov r3,r2 / save major for later Y! mul $14.,r3 / devsw[] members are 14. bytes each Y mov _devsw+10(r3),r3 / get csrlist for driver Y add r0,r3 / point to controller's entry Y+ asr r0 / controller number in bits 0,1 Y+ mov r0,_bootctlr / set default controller number Y Y / the CSR passed from the ROMs is not necessarily the first address Y / of a device! We therefore have to adjust the CSR so that the structure Y*************** Y*** 100,109 **** Y mov nofault,(sp) Y rtt Y Y! .data Y! .globl _cputype, _bootcsr, _bootdev Y Y nofault: .=.+2 / where to go on predicted trap Y _cputype: .=.+2 / cpu type (currently 44, 70, 73) Y _bootdev: .=.+2 / makedev(major,unit) for boot device Y _bootcsr: .=.+2 / csr of boot controller Y--- 110,121 ---- Y mov nofault,(sp) Y rtt Y Y! .data Y! .globl _cputype, _bootcsr, _bootdev, _ssr3copy, _bootctlr Y Y nofault: .=.+2 / where to go on predicted trap Y _cputype: .=.+2 / cpu type (currently 44, 70, 73) Y _bootdev: .=.+2 / makedev(major,unit) for boot device Y _bootcsr: .=.+2 / csr of boot controller Y+ _bootctlr: .=.+2 / number of boot controller (bits 6 and 7 of minor) Y+ _ssr3copy: .=.+2 / copy of SSR3 Y*** /usr/src/sys/pdpstand/sys.c.old Sat Jan 2 15:01:48 1993 Y--- /usr/src/sys/pdpstand/sys.c Mon Jun 12 21:17:02 1995 Y*************** Y*** 3,17 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)sys.c 2.1 (2.11BSD) 1/2/93 Y */ Y Y #include "../h/param.h" Y- #include "../h/fs.h" Y #include "../h/dir.h" Y! #include "../h/inode.h" Y #include "saio.h" Y Y ino_t dlook(); Y struct direct *readdir(); Y Y--- 3,58 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)sys.c 2.2 (2.11BSD) 1995/06/08 Y */ Y Y #include "../h/param.h" Y #include "../h/dir.h" Y! #include "../machine/seg.h" Y! #include "../machine/iopage.h" Y! #include "../machine/psl.h" Y! #include "../machine/machparam.h" Y #include "saio.h" Y Y+ #undef KISA0 Y+ #define KISA0 ((u_short *) 0172340) Y+ #define KDSA0 ((u_short *) 0172360) Y+ Y+ extern struct devsw devsw[]; Y+ extern int ssr3copy, bootctlr; Y+ extern long atol(); Y+ Y+ /* Y+ * These buffers are only used in mapping inode blocks to disk sectors, Y+ * no good reason to make them global. Y+ * Y+ * The strange initialization is due to the fact that the 0'th case is Y+ * not legal since it would be used for quadruple indirect files. The Y+ * use of the array 'b' is: Y+ * Y+ * b[0] - not allocated, saving 1kb of space Y+ * b[1] - triple indirect block Y+ * b[2] - double indirect block Y+ * b[3] - single indirect block Y+ * Y+ * In the 1kb filesystem double indirect files can be up to ~65 megabytes Y+ * (the old 512 byte filesystem double indirect files were up to ~8mb). Y+ */ Y+ Y+ static char tplind[DEV_BSIZE], dblind[DEV_BSIZE], sngind[DEV_BSIZE]; Y+ Y+ static char *b[4] = { Y+ NULL, /* j = 0 */ Y+ tplind, /* j = 1 */ Y+ dblind, /* j = 2 */ Y+ sngind /* j = 3 */ Y+ }; Y+ Y+ static daddr_t blknos[4]; Y+ Y+ #define NFILES 4 Y+ struct iob iob[NFILES]; Y+ Y ino_t dlook(); Y struct direct *readdir(); Y Y*************** Y*** 24,31 **** Y * wfj - mods to trap to explicitly detail why we stopped Y */ Y Y- int segflag = 0; Y- Y static Y openi(n, io) Y register ino_t n; Y--- 65,70 ---- Y*************** Y*** 135,140 **** Y--- 174,189 ---- Y printf("bn ovf %D\n", bn); Y return((daddr_t)0); Y } Y+ /* Y+ * At this point: Y+ * Y+ * j NADDR-j meaning Y+ * --- ------- ------- Y+ * 0 7 illegal - tossed out in the 'if' above Y+ * 1 6 triple indirect block number Y+ * 2 5 double indirect block number Y+ * 3 4 single indirect block number Y+ */ Y Y /* Y * fetch the address from the inode Y*************** Y*** 181,196 **** Y if (s==NULL || *s=='\0') Y return(0); Y ip = &io->i_ino; Y! if ((ip->i_mode&IFMT)!=IFDIR) { Y! printf("%s: not directory,mode %o ip %o\n",s, ip->i_mode, ip); Y return(0); Y } Y Y- if (ip->i_size==0) { Y- printf("%s: 0 len directory\n",s); Y- return(0); Y- } Y- Y len = strlen(s); Y dirp.loc = 0; Y dirp.io = io; Y--- 230,241 ---- Y if (s==NULL || *s=='\0') Y return(0); Y ip = &io->i_ino; Y! if ((ip->i_mode&IFMT) != IFDIR || !ip->i_size) { Y! printf("%s: !directory,mode %o size: %D ip %o\n", s, Y! ip->i_mode, ip->i_size, ip); Y return(0); Y } Y Y len = strlen(s); Y dirp.loc = 0; Y dirp.io = io; Y*************** Y*** 234,244 **** Y--- 279,294 ---- Y } Y } Y Y+ /* Y+ * Modified to call the tape driver's seek routine. This only works when Y+ * the record size is DEV_BSIZE (1kb). Y+ */ Y lseek(fdesc, addr, ptr) Y register int fdesc; Y off_t addr; Y int ptr; Y { Y+ off_t new; Y register struct iob *io; Y Y if (ptr != 0) { Y*************** Y*** 246,255 **** Y return(-1); Y } Y fdesc -= 3; Y! if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) Y return(-1); Y io->i_offset = addr; Y! io->i_bn = fsbtodb(addr/DEV_BSIZE) + io->i_boff; Y io->i_cc = 0; Y return(0); Y } Y--- 296,320 ---- Y return(-1); Y } Y fdesc -= 3; Y! if (fdesc < 0 || fdesc >= NFILES || Y! ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) Y return(-1); Y+ new = addr / DEV_BSIZE; Y+ Y+ if (io->i_flgs & F_TAPE) Y+ { Y+ #ifdef debug Y+ printf("seek: new=%D i_bn=%D\n", new, io->i_bn); Y+ #endif Y+ /* Y+ * Subtract 1 to acccount for the block currently in the buffer - the Y+ * tape is currently positioned at the next record. Need to convert the Y+ * block number from 512 byte to 1024 byte records (undo the fsbtodb). Y+ */ Y+ devseek(io, (int)(new - dbtofsb(io->i_bn) - 1)); Y+ } Y io->i_offset = addr; Y! io->i_bn = fsbtodb(new) + io->i_boff; Y io->i_cc = 0; Y return(0); Y } Y*************** Y*** 285,301 **** Y #endif Y tapemark = 0; Y devread(io); Y if (io->i_flgs&F_FILE) { Y- off = io->i_offset % (off_t)DEV_BSIZE; Y if (io->i_offset+(DEV_BSIZE-off) >= io->i_ino.i_size) Y io->i_cc = io->i_ino.i_size - io->i_offset + off; Y- io->i_cc -= off; Y- if (io->i_cc <= 0) Y- return(-1); Y- } else { Y- off = 0; Y- if (tapemark)return(-1); Y } Y io->i_ma = &io->i_buf[off]; Y } Y io->i_cc--; Y--- 350,365 ---- Y #endif Y tapemark = 0; Y devread(io); Y+ off = io->i_offset % (off_t)DEV_BSIZE; Y if (io->i_flgs&F_FILE) { Y if (io->i_offset+(DEV_BSIZE-off) >= io->i_ino.i_size) Y io->i_cc = io->i_ino.i_size - io->i_offset + off; Y } Y+ if (tapemark) Y+ return(-1); Y+ io->i_cc -= off; Y+ if (io->i_cc <= 0) Y+ return(-1); Y io->i_ma = &io->i_buf[off]; Y } Y io->i_cc--; Y*************** Y*** 393,411 **** Y int how; Y { Y register char *cp; Y! int i; Y register struct iob *file; Y register struct devsw *dp; Y int fdesc; Y- static first = 1; Y- long atol(); Y Y- if (first) { Y- for (i = 0; i < NFILES; i++) Y- iob[i].i_flgs = 0; Y- first = 0; Y- } Y- Y for (fdesc = 0; fdesc < NFILES; fdesc++) Y if (iob[fdesc].i_flgs == 0) Y goto gotfile; Y--- 457,467 ---- Y int how; Y { Y register char *cp; Y! int i, i2, i3; Y register struct iob *file; Y register struct devsw *dp; Y int fdesc; Y Y for (fdesc = 0; fdesc < NFILES; fdesc++) Y if (iob[fdesc].i_flgs == 0) Y goto gotfile; Y*************** Y*** 420,426 **** Y file->i_flgs = 0; Y return(-1); Y } Y! *cp++ = '\0'; Y for (dp = devsw; dp->dv_name; dp++) { Y if (strcmp(str, dp->dv_name) == 0) Y goto gotdev; Y--- 476,482 ---- Y file->i_flgs = 0; Y return(-1); Y } Y! *cp = '\0'; Y for (dp = devsw; dp->dv_name; dp++) { Y if (strcmp(str, dp->dv_name) == 0) Y goto gotdev; Y*************** Y*** 429,457 **** Y file->i_flgs = 0; Y return(-1); Y gotdev: Y! *(cp-1) = '('; Y file->i_ino.i_dev = dp-devsw; Y! for (file->i_unit = 0; *cp >= '0' && *cp <= '9'; cp++) { Y! file->i_unit *= 10; Y! file->i_unit += (*cp - '0'); Y } Y if (*cp++ != ',') { Y badoff: Y! printf("Missing offset\n"); Y file->i_flgs = 0; Y return(-1); Y } Y! file->i_boff = atol(cp); Y! for (;;) { Y! if (*cp == ')') Y! break; Y! if (*cp++) Y! continue; Y goto badoff; Y! } Y! if (devopen(file) < 0) Y return(-1); Y! if (*++cp == '\0') { Y file->i_flgs |= how+1; Y goto comret; Y } Y--- 485,565 ---- Y file->i_flgs = 0; Y return(-1); Y gotdev: Y! /* Y! * The parse is a bit lengthier and complex now. The syntax is now: Y! * Y! * xx(ctlr, unit, partition)filename Y! * or Y! * xx(unit, partition)filename Y! * Y! * Y! * The controller number must be less than 4. NOTE: many drivers Y! * limit the number of controllers to 1 or 2. If the controller is not Y! * specified it defaults to 0. Y! * Y! * The unit number must be less than 8. Y! * Y! * The partition number is also used to specify the tapefile to be loaded. Y! * When loading a tapefile the filename' must not be specified. The partition Y! * number must be less than 8. Y! */ Y! Y! *cp++ = '('; Y file->i_ino.i_dev = dp-devsw; Y! for (i = 0; *cp >= '0' && *cp <= '9'; cp++) { Y! i *= 10; Y! i += (*cp - '0'); Y } Y+ Y if (*cp++ != ',') { Y badoff: Y! printf("Bad offset or ctlr, unit, part out of bounds\n"); Y file->i_flgs = 0; Y return(-1); Y } Y! Y! for (i2 = 0; *cp >= '0' && *cp <= '9'; cp++) Y! { Y! i2 *= 10; Y! i2 += (*cp - '0'); Y! } Y! /* Y! * If we encounter a ')' now it means we have the two arg form 'ra(x,y)'. If Y! * a ',' is seen then we have the three arg form 'xp(x,y,z)'. If neither a Y! * ',' or ')' it is an error. Y! */ Y! if (*cp == ')') Y! { Y! file->i_ctlr = bootctlr; Y! file->i_unit = i; Y! file->i_part = i2; Y! cp++; /* skip ) */ Y! } Y! else if (*cp == ',') Y! { Y! for (i3 = 0, cp++; *cp >= '0' && *cp <= '9'; cp++) Y! { Y! i3 *= 10; Y! i3 += (*cp - '0'); Y! } Y! file->i_ctlr = i; Y! file->i_unit = i2; Y! file->i_part = i3; Y! if (*cp++ != ')') Y! goto badoff; Y! } Y! else Y goto badoff; Y! if (file->i_ctlr > 3 || file->i_unit > 7 || file->i_part > 7) Y! goto badoff; Y! Y! if (devopen(file) < 0) Y! { Y! file->i_flgs = 0; Y return(-1); Y! } Y! file->i_boff = 0; /* tapes don't want this */ Y! if (*cp == '\0') { Y file->i_flgs |= how+1; Y goto comret; Y } Y*************** Y*** 542,548 **** Y { Y register struct devsw *dp = &devsw[io->i_ino.i_dev]; Y register char *cp; Y! register int ctlr = CTLRn(io->i_unit); Y int csr; Y char line[64]; Y Y--- 650,656 ---- Y { Y register struct devsw *dp = &devsw[io->i_ino.i_dev]; Y register char *cp; Y! register int ctlr = io->i_ctlr; Y int csr; Y char line[64]; Y Y*************** Y*** 558,561 **** Y--- 666,757 ---- Y return(-1); Y dp->dv_csr[ctlr] = (caddr_t *)csr; Y return(0); Y+ } Y+ Y+ delay(i) Y+ int i; Y+ { Y+ Y+ while (i) Y+ i--; Y+ } Y+ Y+ char * Y+ ltoa(l) Y+ u_long l; Y+ { Y+ static char x[12]; Y+ register char *cp = x + sizeof (x); Y+ Y+ do { Y+ *--cp = (l % 10) + '0'; Y+ l /= 10; Y+ } while (l); Y+ return(cp); Y+ } Y+ Y+ char * Y+ itoa(i) Y+ register int i; Y+ { Y+ static char x[8]; Y+ register char *cp = x + sizeof (x); Y+ Y+ do { Y+ *--cp = (i % 10) + '0'; Y+ i /= 10; Y+ } while (i); Y+ return(cp); Y+ } Y+ Y+ /* Y+ * Convert a 16 bit (virtual) address into a 18 bit (UNIBUS) address. Y+ * The address extension bits (bits 16, 17) are placed into 'bae' while Y+ * the lower order bits (bits 0 - 15) are placed in 'lo16'. Y+ * Y+ * This routine was primarily created to handle split I/D kernel mode Y+ * utilities. Boot itself must run non split I/D and runs in user mode. Y+ * A side effect of this routine is that Boot no longer must be loaded at Y+ * a 64Kb boundary. Y+ * Y+ * Everything (Boot and standalone utilities) must still run in the low Y+ * 248kb of memory which is mapped by the UNIBUS mapping registers. Y+ */ Y+ Y+ iomapadr(buf, bae, lo16) Y+ memaddr buf; Y+ u_short *bae, *lo16; Y+ { Y+ u_long uadr; Y+ int curmode = *PS & PSL_CURMOD, segno; Y+ u_int nb, ts; Y+ extern char module[]; Y+ Y+ if (curmode == 0) Y+ { /* Kernel mode - we're in a utility */ Y+ /* Y+ * For split I/D we need to emulate the kernel's method of looking at Y+ * the segment registers and calculating the physical address. Whew, forgot Y+ * that ;-) Y+ */ Y+ nb = ((int)buf >> 6) & 01777; Y+ segno = nb >> 7; Y+ if (ssr3copy & 4) Y+ ts = KDSA0[segno]; /* kernel I/D is on */ Y+ else Y+ ts = KISA0[segno]; /* kernel I/D is off */ Y+ ts += (nb & 0177); Y+ uadr = ((u_long)ts << 6) + (buf & 077); Y+ } Y+ else if (curmode == PSL_CURMOD) Y+ { /* User mode - we're in Boot */ Y+ uadr = UISA[0]; /* No I/D for Boot! */ Y+ uadr <<= 6; /* clicks to bytes */ Y+ uadr += buf; Y+ } Y+ else Y+ _stop("Bad PSL mode"); Y+ Y+ *bae = (uadr >> 16) & 3; /* 18 bit mode */ Y+ *lo16 = uadr & 0xffff; Y } Y*** /usr/src/sys/pdpstand/tm.c.old Sun Apr 21 00:19:06 1991 Y--- /usr/src/sys/pdpstand/tm.c Thu Jun 8 19:37:33 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)tm.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)tm.c 2.1 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 11,17 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/tmreg.h" Y #include "saio.h" Y Y--- 11,16 ---- Y*************** Y*** 46,53 **** Y Y if (genopen(NTM, io) < 0) Y return(-1); Y tmstrategy(io, TM_REW); Y! skip = io->i_boff; Y while (skip--) { Y io->i_cc = 0; Y while (tmstrategy(io, TM_SFORW)) Y--- 45,53 ---- Y Y if (genopen(NTM, io) < 0) Y return(-1); Y+ io->i_flgs |= F_TAPE; Y tmstrategy(io, TM_REW); Y! skip = io->i_part; Y while (skip--) { Y io->i_cc = 0; Y while (tmstrategy(io, TM_SFORW)) Y*************** Y*** 61,69 **** Y tmstrategy(io, func) Y register struct iob *io; Y { Y! register int com, unit = UNITn(io->i_unit); Y register struct tmdevice *tmaddr; Y! int errcnt = 0, ctlr = CTLRn(io->i_unit); Y Y tmaddr = TMcsr[ctlr]; Y retry: Y--- 61,69 ---- Y tmstrategy(io, func) Y register struct iob *io; Y { Y! register int com, unit = io->i_unit; Y register struct tmdevice *tmaddr; Y! int errcnt = 0, ctlr = io->i_ctlr, bae, lo16; Y Y tmaddr = TMcsr[ctlr]; Y retry: Y*************** Y*** 73,81 **** Y continue; Y while ((tmaddr->tmer&TMER_SDWN) != 0) Y continue; Y! com = (unit<<8)|(segflag<<4) | tmdens[TMDENS(unit)]; Y tmaddr->tmbc = -io->i_cc; Y! tmaddr->tmba = io->i_ma; Y if (func == READ) Y tmaddr->tmcs = com | TM_RCOM | TM_GO; Y else if (func == WRITE) Y--- 73,82 ---- Y continue; Y while ((tmaddr->tmer&TMER_SDWN) != 0) Y continue; Y! iomapadr(io->i_ma, &bae, &lo16); Y! com = (unit<<8)|(bae<<4) | tmdens[TMDENS(unit)]; Y tmaddr->tmbc = -io->i_cc; Y! tmaddr->tmba = (caddr_t)lo16; Y if (func == READ) Y tmaddr->tmcs = com | TM_RCOM | TM_GO; Y else if (func == WRITE) Y*************** Y*** 94,100 **** Y } Y if (tmaddr->tmer & TM_ERR) { Y if (errcnt == 0) Y! printf("\nTM%d,%d err: er=%o cs=%o", Y ctlr, unit, tmaddr->tmer, tmaddr->tmcs); Y if (errcnt++ == 10) { Y printf("\n(FATAL ERROR)\n"); Y--- 95,101 ---- Y } Y if (tmaddr->tmer & TM_ERR) { Y if (errcnt == 0) Y! printf("\ntm%d,%d err: er=%o cs=%o", Y ctlr, unit, tmaddr->tmer, tmaddr->tmcs); Y if (errcnt++ == 10) { Y printf("\n(FATAL ERROR)\n"); Y*************** Y*** 105,107 **** Y--- 106,126 ---- Y } Y return(io->i_cc+tmaddr->tmbc); Y } Y+ Y+ tmseek(io, space) Y+ register struct iob *io; Y+ int space; Y+ { Y+ int fnc; Y+ Y+ if (space < 0) Y+ { Y+ fnc = TM_SREV; Y+ space = -space; Y+ } Y+ else Y+ fnc = TM_SFORW; Y+ while (space--) Y+ tmstrategy(io, fnc); Y+ return(0); Y+ } Y*** /usr/src/sys/pdpstand/tmscp.c.old Sat Jan 2 00:33:59 1993 Y--- /usr/src/sys/pdpstand/tmscp.c Thu Jun 8 19:37:52 1995 Y*************** Y*** 1,4 **** Y! /* @(#)tmscp.c 7.1 (Berkeley) 6/5/86 */ Y Y /**************************************************************** Y * Licensed from Digital Equipment Corporation * Y--- 1,4 ---- Y! /* @(#)tmscp.c 7.1.2 (2.11BSD GTE) 1995/06/08 */ Y Y /**************************************************************** Y * Licensed from Digital Equipment Corporation * Y*************** Y*** 30,37 **** Y /* ------------------------------------------------------------------------ Y * Modification History: /sys/pdpstand/tmscp.c Y * Y * 4-20-91 sms - add multi controller and unit support (sms) Y! * 8-20-90 steven m. schultz (sms@wlv.imsd.contel.com) Y * Port from 4.3BSD to 2.11BSD Y * 3-15-85 afd Y * Don't ask for an interrupt when commands are issued and Y--- 30,38 ---- Y /* ------------------------------------------------------------------------ Y * Modification History: /sys/pdpstand/tmscp.c Y * Y+ * 5-30-95 sms - new iob structure. Y * 4-20-91 sms - add multi controller and unit support (sms) Y! * 8-20-90 steven m. schultz (sms@wlv.iipo.gtegsc.com) Y * Port from 4.3BSD to 2.11BSD Y * 3-15-85 afd Y * Don't ask for an interrupt when commands are issued and Y*************** Y*** 43,49 **** Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "saio.h" Y Y /* Y--- 44,49 ---- Y*************** Y*** 89,99 **** Y register struct iob *io; Y { Y register struct tmscpdevice *tmscpaddr; Y! int ctlr = CTLRn(io->i_unit); Y register struct tmscp *tms = &tmscp[ctlr]; Y Y if (genopen(NTMS, io) < 0) Y return(-1); Y tmscpaddr = TMScsr[ctlr]; Y Y /* Y--- 89,101 ---- Y register struct iob *io; Y { Y register struct tmscpdevice *tmscpaddr; Y! int ctlr = io->i_ctlr; Y! int unit = io->i_unit, bae, lo16; Y register struct tmscp *tms = &tmscp[ctlr]; Y Y if (genopen(NTMS, io) < 0) Y return(-1); Y+ io->i_flgs |= F_TAPE; Y tmscpaddr = TMScsr[ctlr]; Y Y /* Y*************** Y*** 113,138 **** Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0) Y ; Y! # define STEP1MASK 0174377 Y! # define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2) Y if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD) Y printf(opnmsg, ctlr, 1, tmscpaddr->tmscpsa); Y! tmscpaddr->tmscpsa = (short)&tms->tmscp_ca.ca_ringbase; Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0) Y ; Y! # define STEP2MASK 0174377 Y! # define STEP2GOOD (TMSCP_STEP3) Y if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD) Y printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa); Y! tmscpaddr->tmscpsa = segflag; Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0) Y ; Y! # define STEP3MASK 0174000 Y! # define STEP3GOOD TMSCP_STEP4 Y if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD) Y! printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa); Y tmscpaddr->tmscpsa = TMSCP_GO; Y if (tmscpcmd(ctlr, M_OP_STCON, 0) == 0) Y { Y--- 115,141 ---- Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0) Y ; Y! #define STEP1MASK 0174377 Y! #define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2) Y! iomapadr(&tms->tmscp_ca.ca_ringbase, &bae, &lo16); Y if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD) Y printf(opnmsg, ctlr, 1, tmscpaddr->tmscpsa); Y! tmscpaddr->tmscpsa = lo16; Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0) Y ; Y! #define STEP2MASK 0174377 Y! #define STEP2GOOD (TMSCP_STEP3) Y if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD) Y printf(opnmsg, ctlr, 2, tmscpaddr->tmscpsa); Y! tmscpaddr->tmscpsa = bae; Y Y while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0) Y ; Y! #define STEP3MASK 0174000 Y! #define STEP3GOOD TMSCP_STEP4 Y if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD) Y! printf(opnmsg, ctlr, 3, tmscpaddr->tmscpsa); Y tmscpaddr->tmscpsa = TMSCP_GO; Y if (tmscpcmd(ctlr, M_OP_STCON, 0) == 0) Y { Y*************** Y*** 141,170 **** Y } Y tmsoffline[ctlr] = 0; Y } Y! tms->tmscp_cmd.mscp_unit = UNITn(io->i_unit); Y /* Y * Has this unit been issued an ONLIN? Y */ Y! if (tms_offline[ctlr][tms->tmscp_cmd.mscp_unit]) Y { Y if (tmscpcmd(ctlr, M_OP_ONLIN, 0) == 0) Y { Y! printf("tms%d ONLIN", ctlr); Y return(-1); Y } Y! tms_offline[ctlr][tms->tmscp_cmd.mscp_unit] = 0; Y } Y tmscpclose(io); /* close just does a rewind */ Y! if (io->i_boff < 0) { Y! printf("tms%d bad offset", ctlr); Y! return(-1); Y! } Y! else if (io->i_boff > 0) Y /* Y * Skip forward the appropriate number of files on the tape. Y */ Y { Y! tms->tmscp_cmd.mscp_tmkcnt = io->i_boff; Y tms->tmscp_cmd.mscp_buffer_h = 0; Y tms->tmscp_cmd.mscp_bytecnt = 0; Y tmscpcmd(ctlr, M_OP_REPOS, 0); Y--- 144,169 ---- Y } Y tmsoffline[ctlr] = 0; Y } Y! tms->tmscp_cmd.mscp_unit = unit; Y /* Y * Has this unit been issued an ONLIN? Y */ Y! if (tms_offline[ctlr][unit]) Y { Y if (tmscpcmd(ctlr, M_OP_ONLIN, 0) == 0) Y { Y! printf("tms%d,%d ONLIN", ctlr, unit); Y return(-1); Y } Y! tms_offline[ctlr][unit] = 0; Y } Y tmscpclose(io); /* close just does a rewind */ Y! if (io->i_part > 0) Y /* Y * Skip forward the appropriate number of files on the tape. Y */ Y { Y! tms->tmscp_cmd.mscp_tmkcnt = io->i_part; Y tms->tmscp_cmd.mscp_buffer_h = 0; Y tms->tmscp_cmd.mscp_bytecnt = 0; Y tmscpcmd(ctlr, M_OP_REPOS, 0); Y*************** Y*** 179,192 **** Y tmscpclose(io) Y register struct iob *io; Y { Y! register int ctlr = CTLRn(io->i_unit); Y! register struct tmscp *tms = &tmscp[ctlr]; Y Y tms->tmscp_cmd.mscp_buffer_l = 0; /* tmkcnt */ Y tms->tmscp_cmd.mscp_buffer_h = 0; Y tms->tmscp_cmd.mscp_bytecnt = 0; Y! tms->tmscp_cmd.mscp_unit = UNITn(io->i_unit); Y! tmscpcmd(ctlr, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX); Y } Y Y /* Y--- 178,190 ---- Y tmscpclose(io) Y register struct iob *io; Y { Y! register struct tmscp *tms = &tmscp[io->i_ctlr]; Y Y tms->tmscp_cmd.mscp_buffer_l = 0; /* tmkcnt */ Y tms->tmscp_cmd.mscp_buffer_h = 0; Y tms->tmscp_cmd.mscp_bytecnt = 0; Y! tms->tmscp_cmd.mscp_unit = io->i_unit; Y! tmscpcmd(io->i_ctlr, M_OP_REPOS, M_MD_REWND | M_MD_CLSEX); Y } Y Y /* Y*************** Y*** 200,215 **** Y register struct tmscp *tms = &tmscp[ctlr]; Y register struct mscp *mp; /* ptr to cmd packet */ Y int i; /* read into to init polling */ Y Y /* Y * Init cmd & rsp area Y */ Y! tms->tmscp_ca.ca_cmddsc[0].lsh = (short)&tms->tmscp_cmd.mscp_cmdref; Y! tms->tmscp_ca.ca_cmddsc[0].hsh = segflag; Y tms->tmscp_cmd.mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc; Y tms->tmscp_cmd.mscp_header.tmscp_vcid = 1; /* for tape */ Y! tms->tmscp_ca.ca_rspdsc[0].lsh = (short)&tms->tmscp_rsp.mscp_cmdref; Y! tms->tmscp_ca.ca_rspdsc[0].hsh = segflag; Y tms->tmscp_rsp.mscp_dscptr = (long *)tms->tmscp_ca.ca_rspdsc; Y tms->tmscp_cmd.mscp_cntflgs = 0; Y Y--- 198,217 ---- Y register struct tmscp *tms = &tmscp[ctlr]; Y register struct mscp *mp; /* ptr to cmd packet */ Y int i; /* read into to init polling */ Y+ int bae, lo16; Y Y /* Y * Init cmd & rsp area Y */ Y! iomapadr(&tms->tmscp_cmd.mscp_cmdref, &bae, &lo16); Y! tms->tmscp_ca.ca_cmddsc[0].lsh = lo16; Y! tms->tmscp_ca.ca_cmddsc[0].hsh = bae; Y tms->tmscp_cmd.mscp_dscptr = (long *)tms->tmscp_ca.ca_cmddsc; Y tms->tmscp_cmd.mscp_header.tmscp_vcid = 1; /* for tape */ Y! Y! iomapadr(&tms->tmscp_rsp.mscp_cmdref, &bae, &lo16); Y! tms->tmscp_ca.ca_rspdsc[0].lsh = lo16; Y! tms->tmscp_ca.ca_rspdsc[0].hsh = bae; Y tms->tmscp_rsp.mscp_dscptr = (long *)tms->tmscp_ca.ca_rspdsc; Y tms->tmscp_cmd.mscp_cntflgs = 0; Y Y*************** Y*** 225,231 **** Y for (;;) Y { Y if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) { Y! printf("tmscp%d: Fatal error sa=%o\n", Y ctlr, TMScsr[ctlr]->tmscpsa); Y return(0); Y } Y--- 227,233 ---- Y for (;;) Y { Y if (TMScsr[ctlr]->tmscpsa & TMSCP_ERR) { Y! printf("tms%d: Fatal error sa=%o\n", Y ctlr, TMScsr[ctlr]->tmscpsa); Y return(0); Y } Y*************** Y*** 258,263 **** Y--- 260,267 ---- Y tapemark = 1; Y return(1); Y } Y+ printf("tms%d,%d: I/O err 0%o op=0%o mod=0%o\n", ctlr, Y+ mp->mscp_unit, mp->mscp_status, op, mod); Y return(0); Y } Y return(1); Y*************** Y*** 270,276 **** Y register struct iob *io; Y int func; Y { Y! int ctlr = CTLRn(io->i_unit); Y register struct tmscp *tms = &tmscp[ctlr]; Y register struct mscp *mp; Y Y--- 274,281 ---- Y register struct iob *io; Y int func; Y { Y! int ctlr = io->i_ctlr, unit = io->i_unit; Y! int bae, lo16; Y register struct tmscp *tms = &tmscp[ctlr]; Y register struct mscp *mp; Y Y*************** Y*** 277,290 **** Y mp = &tms->tmscp_cmd; Y mp->mscp_lbn_l = loint(io->i_bn); Y mp->mscp_lbn_h = hiint(io->i_bn); Y! mp->mscp_unit = UNITn(io->i_unit); Y mp->mscp_bytecnt = io->i_cc; Y! mp->mscp_buffer_l = (u_short)io->i_ma; Y! mp->mscp_buffer_h = segflag; Y! if (tmscpcmd(ctlr, func == READ ? M_OP_READ : M_OP_WRITE, 0)==0) { Y! printf("tms%d,%d: I/O err\n", ctlr, UNITn(io->i_unit)); Y return(-1); Y- } Y /* Y * Detect hitting tape mark so we do it gracefully and return a Y * character count of 0 to signify end of copy. Y--- 282,294 ---- Y mp = &tms->tmscp_cmd; Y mp->mscp_lbn_l = loint(io->i_bn); Y mp->mscp_lbn_h = hiint(io->i_bn); Y! mp->mscp_unit = unit; Y mp->mscp_bytecnt = io->i_cc; Y! iomapadr(io->i_ma, &bae, &lo16); Y! mp->mscp_buffer_l = lo16; Y! mp->mscp_buffer_h = bae; Y! if (tmscpcmd(ctlr, func == READ ? M_OP_READ : M_OP_WRITE, 0) ==0) Y return(-1); Y /* Y * Detect hitting tape mark so we do it gracefully and return a Y * character count of 0 to signify end of copy. Y*************** Y*** 293,295 **** Y--- 297,323 ---- Y return(0); Y return(io->i_cc); Y } Y+ Y+ tmscpseek(io, space) Y+ register struct iob *io; Y+ int space; Y+ { Y+ register struct tmscp *tms = &tmscp[io->i_ctlr]; Y+ int mod; Y+ Y+ if (space == 0) Y+ return(0); Y+ if (space < 0) Y+ { Y+ mod = M_MD_REVRS; Y+ space = -space; Y+ } Y+ else Y+ mod = 0; Y+ tms->tmscp_cmd.mscp_buffer_l = 0; Y+ tms->tmscp_cmd.mscp_buffer_h = 0; Y+ tms->tmscp_cmd.mscp_unit = io->i_unit; Y+ tms->tmscp_cmd.mscp_reccnt = space; Y+ tmscpcmd(io->i_ctlr, M_OP_REPOS, mod | M_MD_OBJCT); Y+ return(0); Y+ } Y*** /usr/src/sys/pdpstand/ts.c.old Fri Jul 15 23:52:29 1994 Y--- /usr/src/sys/pdpstand/ts.c Thu Jun 8 19:38:04 1995 Y*************** Y*** 3,17 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ts.c 2.1 (2.11BSD) 7/15/94 Y */ Y Y /* Y! * Stand-alone TS11/TU80/TS05/TK25 1600 BPI magtape driver. Y */ Y Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/tsreg.h" Y #include "saio.h" Y Y--- 3,16 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)ts.c 2.2 (2.11BSD) 1995/06/08 Y */ Y Y /* Y! * Stand-alone TS11/TU80/TS05/TK25 magtape driver. Y */ Y Y #include "../h/param.h" Y #include "../pdpuba/tsreg.h" Y #include "saio.h" Y Y*************** Y*** 39,78 **** Y tsopen(io) Y register struct iob *io; Y { Y! int skip; Y register struct tsdevice *tsaddr; Y register struct ts_char *chrb; Y struct ts_cmd *cmb; Y! int ctlr = CTLRn(io->i_unit); Y char *cp; Y Y if (genopen(NTS, io) < 0) Y return(-1); Y tsaddr = TScsr[ctlr]; Y Y! /* combuf must be alligned on a mod 4 byte boundary */ Y cp = (char *)((u_short)softspace + 3 & ~3); Y cp += (ctlr * sizeof (struct ts_cmd)); Y cmb = combuf[ctlr] = (struct ts_cmd *)cp; Y! tsptr[ctlr] = (caddr_t)((int)&combuf[ctlr]->c_cmd | (int)segflag); Y cmb->c_cmd = (TS_ACK|TS_CVC|TS_INIT); Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y while ((tsaddr->tssr & TS_SSR) == 0) Y continue; Y chrb = &chrbuf[ctlr]; Y! chrb->char_bptr = (u_short) &mesbuf; Y! chrb->char_bae = segflag; Y chrb->char_size = 016; Y chrb->char_mode = 0; Y cmb->c_cmd = (TS_ACK|TS_CVC|TS_SETCHR); Y! cmb->c_loba = (u_short) &chrbuf; Y! cmb->c_hiba = segflag; Y cmb->c_size = 010; Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y while ((tsaddr->tssr & TS_SSR) == 0) Y continue; Y tsstrategy(io, TS_REW); Y! skip = io->i_boff; Y while (skip--) { Y io->i_cc = 0; Y while (tsstrategy(io, TS_SFORWF)) Y--- 38,85 ---- Y tsopen(io) Y register struct iob *io; Y { Y! int skip, bae, lo16; Y register struct tsdevice *tsaddr; Y register struct ts_char *chrb; Y struct ts_cmd *cmb; Y! int ctlr = io->i_ctlr; Y char *cp; Y Y if (genopen(NTS, io) < 0) Y return(-1); Y+ io->i_flgs |= F_TAPE; Y tsaddr = TScsr[ctlr]; Y Y! /* combuf must be aligned on a mod 4 byte boundary */ Y cp = (char *)((u_short)softspace + 3 & ~3); Y cp += (ctlr * sizeof (struct ts_cmd)); Y cmb = combuf[ctlr] = (struct ts_cmd *)cp; Y! Y! iomapadr(cmb, &bae, &lo16); Y! tsptr[ctlr] = (caddr_t)(lo16 | bae); Y cmb->c_cmd = (TS_ACK|TS_CVC|TS_INIT); Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y while ((tsaddr->tssr & TS_SSR) == 0) Y continue; Y+ Y chrb = &chrbuf[ctlr]; Y! iomapadr(&mesbuf, &bae, &lo16); Y! chrb->char_bptr = lo16; Y! chrb->char_bae = bae; Y chrb->char_size = 016; Y chrb->char_mode = 0; Y+ Y cmb->c_cmd = (TS_ACK|TS_CVC|TS_SETCHR); Y! iomapadr(&chrbuf, &bae, &lo16); Y! cmb->c_loba = lo16; Y! cmb->c_hiba = bae; Y cmb->c_size = 010; Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y while ((tsaddr->tssr & TS_SSR) == 0) Y continue; Y+ Y tsstrategy(io, TS_REW); Y! skip = io->i_part; Y while (skip--) { Y io->i_cc = 0; Y while (tsstrategy(io, TS_SFORWF)) Y*************** Y*** 90,105 **** Y tsstrategy(io, func) Y register struct iob *io; Y { Y! register int ctlr = CTLRn(io->i_unit); Y! int errcnt, unit; Y register struct tsdevice *tsaddr = TScsr[ctlr]; Y Y- unit = UNITn(io->i_unit); Y errcnt = 0; Y! combuf[ctlr]->c_loba = (u_short) io->i_ma; Y! combuf[ctlr]->c_hiba = segflag; Y combuf[ctlr]->c_size = io->i_cc; Y! if (func == TS_SFORW || func == TS_SFORWF) Y combuf[ctlr]->c_repcnt = 1; Y if (func == READ) Y combuf[ctlr]->c_cmd = TS_ACK|TS_RCOM; Y--- 97,113 ---- Y tsstrategy(io, func) Y register struct iob *io; Y { Y! register int ctlr = io->i_ctlr; Y! int errcnt, unit = io->i_unit, bae, lo16; Y register struct tsdevice *tsaddr = TScsr[ctlr]; Y Y errcnt = 0; Y! iomapadr(io->i_ma, &bae, &lo16); Y! combuf[ctlr]->c_loba = lo16; Y! combuf[ctlr]->c_hiba = bae; Y combuf[ctlr]->c_size = io->i_cc; Y! if (func == TS_SFORW || func == TS_SFORWF || func == TS_SREV || Y! func == TS_SREVF) Y combuf[ctlr]->c_repcnt = 1; Y if (func == READ) Y combuf[ctlr]->c_cmd = TS_ACK|TS_RCOM; Y*************** Y*** 117,124 **** Y } Y if (tsaddr->tssr & TS_SC) { Y if (errcnt == 0) Y! printf("\nTS%d,%d err sr=%o xs0=%o xs1=%o xs2=%o xs3=%o", Y! ctlr, UNITn(io->i_unit), tsaddr->tssr, Y mesbuf[ctlr].s_xs0, mesbuf[ctlr].s_xs1, Y mesbuf[ctlr].s_xs2, mesbuf[ctlr].s_xs3); Y if (errcnt++ == 10) { Y--- 125,132 ---- Y } Y if (tsaddr->tssr & TS_SC) { Y if (errcnt == 0) Y! printf("\nts%d,%d err sr=%o xs0=%o xs1=%o xs2=%o xs3=%o", Y! ctlr, unit, tsaddr->tssr, Y mesbuf[ctlr].s_xs0, mesbuf[ctlr].s_xs1, Y mesbuf[ctlr].s_xs2, mesbuf[ctlr].s_xs3); Y if (errcnt++ == 10) { Y*************** Y*** 130,136 **** Y else if (func == WRITE) Y combuf[ctlr]->c_cmd = (TS_ACK|TS_RETRY|TS_WCOM); Y else { Y! printf("\n"); Y return(-1); Y } Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y--- 138,144 ---- Y else if (func == WRITE) Y combuf[ctlr]->c_cmd = (TS_ACK|TS_RETRY|TS_WCOM); Y else { Y! putchar('\n'); Y return(-1); Y } Y tsaddr->tsdb = (u_short) tsptr[ctlr]; Y*************** Y*** 138,140 **** Y--- 146,169 ---- Y } Y return (io->i_cc+mesbuf[ctlr].s_rbpcr); Y } Y+ Y+ tsseek(io, space) Y+ register struct iob *io; Y+ int space; Y+ { Y+ int fnc; Y+ Y+ if (space < 0) Y+ { Y+ fnc = TS_SREV; Y+ space = -space; Y+ } Y+ else Y+ fnc = TS_SFORW; Y+ while (space--) Y+ { Y+ io->i_cc = 0; Y+ tsstrategy(io, fnc); Y+ } Y+ return(0); Y+ } Y*** /usr/src/sys/pdpstand/xp.c.old Sat May 4 17:49:43 1991 Y--- /usr/src/sys/pdpstand/xp.c Thu Jun 8 19:38:21 1995 Y*************** Y*** 3,9 **** Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)xp.c 2.0 (2.11BSD) 4/20/91 Y */ Y Y /* Y--- 3,9 ---- Y * All rights reserved. The Berkeley software License Agreement Y * specifies the terms and conditions for redistribution. Y * Y! * @(#)xp.c 2.1 (2.11BSD) 1995/06/08 Y */ Y Y /* Y*************** Y*** 10,16 **** Y * SMD disk driver Y */ Y #include "../h/param.h" Y- #include "../h/inode.h" Y #include "../pdpuba/hpreg.h" Y #include "../machine/iopage.h" Y #include "saio.h" Y--- 10,15 ---- Y*************** Y*** 32,43 **** Y xpstrategy(io, func) Y register struct iob *io; Y { Y! int unit = UNITn(io->i_unit); Y! int ctlr = CTLRn(io->i_unit); Y int i; Y register nm_sect_per_cyl, nsect; Y daddr_t bn; Y! int sn, cn, tn; Y struct hpdevice *xpaddr = XPcsr[ctlr]; Y Y bn = io->i_bn; Y--- 31,42 ---- Y xpstrategy(io, func) Y register struct iob *io; Y { Y! int unit = io->i_unit; Y! int ctlr = io->i_ctlr; Y int i; Y register nm_sect_per_cyl, nsect; Y daddr_t bn; Y! int sn, cn, tn, bae, lo16; Y struct hpdevice *xpaddr = XPcsr[ctlr]; Y Y bn = io->i_bn; Y*************** Y*** 113,123 **** Y tn = sn/nsect; Y sn = sn%nsect; Y Y xpaddr->hpdc = cn; Y xpaddr->hpda = (tn << 8) + sn; Y! xpaddr->hpba = io->i_ma; Y xpaddr->hpwc = -(io->i_cc>>1); Y! i = (segflag << 8) | HP_GO; Y if (func == READ) Y i |= HP_RCOM; Y else if (func == WRITE) Y--- 112,123 ---- Y tn = sn/nsect; Y sn = sn%nsect; Y Y+ iomapadr(io->i_ma, &bae, &lo16); Y xpaddr->hpdc = cn; Y xpaddr->hpda = (tn << 8) + sn; Y! xpaddr->hpba = (caddr_t)lo16; Y xpaddr->hpwc = -(io->i_cc>>1); Y! i = (bae << 8) | HP_GO; Y if (func == READ) Y i |= HP_RCOM; Y else if (func == WRITE) SHAR_EOF fi exit 0 # End of shell archive