Subject: Part 7a of 22 /boot,/mdec,[T]MSCP updates Index: /sys/, /usr/src/etc/ 2.11BSD Description: Repeat-By: Fix: See part 0 (the README) for the Description, the Reason and the instructions on how update your system. This is part 7a of 22 Because part 7 was so large it was split into two (still large) pieces. The two parts (7a and 7b) should be joined together with no intervening text. /sys/pdpstand/* was basically rewritten. All of the drivers were modified to support at least 2 controllers. The device array in 'conf.c' was placed in major device number order (see bdevsw[] in /sys/pdp/conf.c) The files tmscpboot.s and tmscptape.data should be removed, they are no longer needed now that 'mtboot.s' can handle all 4 controller types. The switch register is no longer examined for cpu or drive type (xp) information. The return protocol for the standalone utilities was changed to prevent slightly oversized programs from wiping out the 'rtt' information stored at 0140000. A higher address at the top (rather than the bottom) of the stack is now used. *** /usr/src/sys/pdpstand.old/M.s Fri Aug 19 12:03:46 1988 --- /usr/src/sys/pdpstand/M.s Tue Apr 23 10:21:47 1991 *************** *** 1,9 **** / / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 / / Startup code for two-stage bootstrap with support for autoboot. ! / Supports 11/40, 11/45, 11/70, 11/23, 11/23+I/O map (11/24), 11/73 ! / and similar machines. systrap = 104400 / trap 0 --- 1,9 ---- / / SCCS id @(#)M.s 1.7 (Berkeley) 7/11/83 + / @(#)M.s 2.0 (2.11BSD) 4/12/91 (sms@wlv.imsd.contel.com) / / Startup code for two-stage bootstrap with support for autoboot. ! / Supports 11/45, 11/70, 11/53, 11/73, 11/83, 11/84, 11/93, 11/94 systrap = 104400 / trap 0 *************** *** 14,21 **** ENDCORE= 160000 / end of core, mem. management off SZFLAGS= 6 / size of boot flags BOOTOPTS= 2 / location of options, bytes below ENDCORE ! BOOTDEV= 4 ! CHECKWORD= 6 .globl _end .globl _main,_ubmapset --- 14,21 ---- ENDCORE= 160000 / end of core, mem. management off SZFLAGS= 6 / size of boot flags BOOTOPTS= 2 / location of options, bytes below ENDCORE ! BOOTDEV= 4 / makedev(major,unit) ! CHECKWORD= 6 / ~BOOTOPTS .globl _end .globl _main,_ubmapset *************** *** 54,59 **** --- 54,60 ---- mov r4,_bootopts mov r3,_bootdev mov r2,_checkword + mov r1,_bootcsr / 'boot' will apply ADJcsr[] correction /clobber any boot flags left in memory clr ENDCORE-BOOTOPTS clr ENDCORE-BOOTDEV *************** *** 60,101 **** clr ENDCORE-CHECKWORD / / determine what kind of cpu we are running on ! / first, check switches. if they are 40, 24, 44, 45, 70, or 73 ! / set appropriately ! / clrb _sep_id clrb _ubmap - clrb _haveCSW - mov $2f,nofault / check if we even have switches! - tst *$SWREG - clr nofault / apparently we do - incb _haveCSW - mov $40.,r0 - cmp *$SWREG,$40 - beq gotcha - cmp *$SWREG,$24 - bne 1f - mov $24.,r0 - incb _ubmap - jbr gotcha - 1: - cmp *$SWREG,$45 - bne 1f - mov $45.,r0 - incb _sep_id - jbr gotcha - 1: - cmp *$SWREG,$70 - bne 2f - mov $70.,r0 - incb _sep_id - incb _ubmap - jbr gotcha - / - / if we can't find out from switches, - / explore and see what we find - / - 2: mov $40.,r0 / assume 11/40 mov $2f,nofault mov *$KDSA6,r1 / then we have sep i/d 45, 70, 73 --- 61,77 ---- clr ENDCORE-CHECKWORD / / determine what kind of cpu we are running on ! / The check for the switch register removed because: 1) the only use ! / of it was in xp.c for the drive type and an alternate method of ! / modifying xptype is provided, 2) the only machine with a front panel ! / which can run the system is the 11/70 and i got tired of having the ! / system think it was on a 11/40 because switches were left up after the ! / boot, 3) the standalone code was becoming large enough that 'restor' ! / was having size problems due to the addition of multi-controller support, ! / 4) the probing proceedure adequately determines the hardware capabilities. ! clrb _sep_id clrb _ubmap mov $40.,r0 / assume 11/40 mov $2f,nofault mov *$KDSA6,r1 / then we have sep i/d 45, 70, 73 *************** *** 120,126 **** incb _ubmap mov $24.,r0 / unibus map, no sep. I/D = 24 1: clr nofault - gotcha: mov r0,_cputype / --- 96,101 ---- *************** *** 150,159 **** / physical addressing is completely reworked, 3*64Kb is probably the / highest we'll ever see boot relocated. This means that the maximum size / of any program boot can load is 192Kb. That size includes text, data ! / and bss. This is a problem for the current (9/87) networking kernels ! / which have the networking code and data space incorporated as part of ! / the main line kernel. Which only adds more impetus to get the networking ! / put into supervisor space ... N = 3 / 3*64Kb = 192Kb --- 125,131 ---- / physical addressing is completely reworked, 3*64Kb is probably the / highest we'll ever see boot relocated. This means that the maximum size / of any program boot can load is 192Kb. That size includes text, data ! / and bss. N = 3 / 3*64Kb = 192Kb *************** *** 224,240 **** mtpi (r1)+ sob r0,1b - / continue execution in user space copy; return protocol uses - / absolute address 140000. - mov $140004,sp - tstb _sep_id - bne 1f - clr *$KISA6 - br 2f - 1: - clr *$KDSA6 - 2: mov $140340,-(sp) mov $user,-(sp) rtt --- 196,204 ---- mtpi (r1)+ sob r0,1b + / continue execution in user space copy. No sense in loading sp with + / anything special since the call to _main below overwrites low core. mov $140340,-(sp) mov $user,-(sp) rtt *************** *** 257,265 **** --- 221,233 ---- jsr pc,_main mov _cputype,r0 + mov _bootcsr,r1 / csr of boot controller (from ROMs) + mov _bootdev,r3 / makedev(major,unit) (from ROMs & bootblock) mov _bootopts,r4 mov r4,r2 com r2 / checkword + mov $160000,-(sp) / set ksp to very top so that the trap + mtpi sp / puts the return address and psw at 157774,6 systrap br user *************** *** 343,360 **** trap: mov *$PS,-(sp) - mov r0,-(sp) - mov r1,-(sp) tst nofault bne 3f jsr pc,_trap mov (sp)+,r1 mov (sp)+,r0 tst (sp)+ rtt ! 3: mov (sp)+,r1 ! mov (sp)+,r0 ! tst (sp)+ mov nofault,(sp) rtt --- 311,326 ---- trap: mov *$PS,-(sp) tst nofault bne 3f + mov r0,-(sp) + mov r1,-(sp) jsr pc,_trap mov (sp)+,r1 mov (sp)+,r0 tst (sp)+ rtt ! 3: tst (sp)+ mov nofault,(sp) rtt *************** *** 364,383 **** SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 - KISA1 = 172342 KISA6 = 172354 - KISA7 = 172356 KISD0 = 172300 KISD7 = 172316 KDSA0 = 172360 KDSA6 = 172374 - KDSA7 = 172376 KDSD0 = 172320 - KDSD5 = 172332 - SISA0 = 172240 - SISA1 = 172242 - SISD0 = 172200 - SISD1 = 172202 UISA0 = 177640 UISD0 = 177600 UDSA0 = 177660 --- 330,341 ---- *************** *** 384,403 **** UDSD0 = 177620 MSCR = 177746 / 11/44/60/70 memory system cache control register IO = 177600 - SWREG = 177570 UBMAP = 170200 .data .globl _cputype ! .globl _ksep, _sep_id, _ubmap, _haveCSW ! .globl _bootopts, _bootdev, _checkword nofault: .=.+2 / where to go on predicted trap _cputype: .=.+2 / cpu type (currently 40,45 or 70) _sep_id: .=.+1 / 1 if we have separate I and D - _ubmap: .=.+1 / 1 if we have a unibus map - _haveCSW: .=.+1 / 1 if we have a console switch register _ksep: .=.+1 / 1 if kernel mode has sep I/D enabled _bootopts: .=.+2 / flags if an autoboot ! _bootdev: .=.+2 / device to get unix from, if not RB_ASKNAME _checkword: .=.+2 / saved r2, complement of bootopts if an autoboot --- 342,360 ---- UDSD0 = 177620 MSCR = 177746 / 11/44/60/70 memory system cache control register IO = 177600 UBMAP = 170200 .data .globl _cputype ! .globl _ksep, _sep_id, _ubmap ! .globl _bootopts, _bootdev, _checkword, _bootcsr nofault: .=.+2 / where to go on predicted trap _cputype: .=.+2 / cpu type (currently 40,45 or 70) _sep_id: .=.+1 / 1 if we have separate I and D _ksep: .=.+1 / 1 if kernel mode has sep I/D enabled + _ubmap: .=.+2 / 1 if we have a unibus map _bootopts: .=.+2 / flags if an autoboot ! _bootdev: .=.+2 / device booted from ! _bootcsr: .=.+2 / csr of device booted from _checkword: .=.+2 / saved r2, complement of bootopts if an autoboot *** /usr/src/sys/pdpstand.old/Makefile Thu Dec 20 08:55:11 1990 --- /usr/src/sys/pdpstand/Makefile Sun Apr 28 00:12:26 1991 *************** *** 41,47 **** ht.o tm.o ts.o tmscp.o \ xp.o rk.o rl.o br.o hk.o si.o ra.o ! ALL= mtboot boot mkfs restor icheck maketape tmscpboot .c.o: cc ${CFLAGS} -c $*.c --- 41,47 ---- ht.o tm.o ts.o tmscp.o \ xp.o rk.o rl.o br.o hk.o si.o ra.o ! ALL= mtboot boot mkfs restor icheck maketape .c.o: cc ${CFLAGS} -c $*.c *************** *** 56,62 **** distribution: tape1 switch_tapes tape2 tmscptape: ${ALL} ${DUMP} ! ./maketape /dev/nr${TAPE} tmscptape.data dd if=${DUMP} of=/dev/nr${TAPE} bs=20b cd ${ROOT}/usr; tar cfb /dev/nr${TAPE} 20 \ adm bin dict doc games guest hosts include ingres lib \ --- 56,62 ---- distribution: tape1 switch_tapes tape2 tmscptape: ${ALL} ${DUMP} ! ./maketape /dev/nr${TAPE} maketape.data dd if=${DUMP} of=/dev/nr${TAPE} bs=20b cd ${ROOT}/usr; tar cfb /dev/nr${TAPE} 20 \ adm bin dict doc games guest hosts include ingres lib \ *************** *** 115,125 **** mtboot: mtboot.o strip $@.o dd if=$@.o of=mtboot bs=16 skip=1 - rm -f $@.o - - tmscpboot: tmscpboot.o - strip $@.o - dd if=$@.o of=tmscpboot bs=16 skip=1 rm -f $@.o boot: M.o conf.o boot.o ubmapset.o libsa.a --- 115,120 ---- *** /usr/src/sys/pdpstand.old/Makefile.vax Sun Nov 4 12:19:58 1990 --- /usr/src/sys/pdpstand/Makefile.vax Sun Apr 28 00:13:32 1991 *************** *** 22,35 **** DUMP= /xusr/root.dump TMP1= /xusr/1st.tar TMP2= /xusr/2nd.tar - TMP3= /tmp/maketape.data ROOT= /xusr/root distribution: tape1 switch_tapes tape2 ! tape1: ${TMP3} ${TMP2} ${TMP1} ! ./maketape /dev/r${TAPE} ${TMP3} switch_tapes: FRC @echo "Switch tapes. Hit CR when second tape is mounted." --- 22,34 ---- DUMP= /xusr/root.dump TMP1= /xusr/1st.tar TMP2= /xusr/2nd.tar ROOT= /xusr/root distribution: tape1 switch_tapes tape2 ! tape1: ${TMP2} ${TMP1} ! ./maketape /dev/r${TAPE} maketape.data switch_tapes: FRC @echo "Switch tapes. Hit CR when second tape is mounted." *************** *** 50,62 **** ${TMP2}: cd ${ROOT}/usr/src; tar cf ${TMP2} sys include - - ${TMP3}: - cp tmscptape.data ${TMP3} - # cp maketape.data ${TMP3} - echo "* 1" >> ${TMP3} - echo ${DUMP} 20 >> ${TMP3} - echo "* 1" >> ${TMP3} - echo ${TMP1} 20 >> ${TMP3} - echo "* 1" >> ${TMP3} - echo ${TMP2} 20 >> ${TMP3} --- 49,51 ---- *** /usr/src/sys/pdpstand.old/boot.c Fri Aug 19 11:53:12 1988 --- /usr/src/sys/pdpstand/boot.c Tue Apr 23 13:08:44 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)boot.c 1.1 (2.10BSD Berkeley) 12/1/86 */ #include "../h/param.h" #include "../machine/seg.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)boot.c 2.0 (2.11BSD) 4/20/91 */ #include "../h/param.h" #include "../machine/seg.h" *************** *** 19,25 **** # define RB_DEFNAME "xp(0,0)unix" #endif ! #undef btoc #define KB * 1024L #define KISD0 ((u_short *) 0172300) --- 19,25 ---- # define RB_DEFNAME "xp(0,0)unix" #endif ! #undef btoc /* to save space */ #define KB * 1024L #define KISD0 ((u_short *) 0172300) *************** *** 34,48 **** #define SEG_TEXT 02 #define SEG_OVLY 04 ! extern int bootopts; /* boot options from previous incarnation */ ! extern int bootdev; /* UNIX dev we were booted from (not used) */ ! extern int checkword; /* one's complements of bootopts */ ! extern int cputype; /* 24, 40, 44, 45, 70, or 73 */ ! extern bool_t ksep; /* is kernel mode currently separated */ ! extern bool_t sep_id; /* does the cpu support separate I/D? */ char module[] = "Boot"; /* this program's name (used by trap) */ ! char line[100] = RB_DEFNAME; bool_t overlaid = 0; u_short pdrproto[16 + NOVL] = {0}; struct exec exec; --- 34,51 ---- #define SEG_TEXT 02 #define SEG_OVLY 04 ! extern caddr_t *bootcsr; /* csr of boot controller */ ! extern int bootopts; /* boot options from previous incarnation */ ! extern int bootdev; /* makedev(major,unit) booted from */ ! extern int checkword; /* one's complements of bootopts */ ! extern int cputype; /* 24, 40, 44, 45, 70, or 73 */ ! extern bool_t ksep; /* is kernel mode currently separated */ ! extern bool_t sep_id; /* does the cpu support separate I/D? */ ! extern int ndevsw; /* number of devices in devsw[] */ ! extern char ADJcsr[]; /* adjustments for ROM csr addresses */ char module[] = "Boot"; /* this program's name (used by trap) */ ! char line[64] = RB_DEFNAME; bool_t overlaid = 0; u_short pdrproto[16 + NOVL] = {0}; struct exec exec; *************** *** 58,75 **** struct loadmap *lt_map; }; - /* - * The 0401 references below are to a weird ULTRIX magic which signifies a - * stand alone 0407. This entry is present so we can boot the ULTRIX boot if - * necessary (we can't load an ULTRIX kernel and most of the ULTRIX stand alone - * utilities for instance). - */ - #define A_MAGICU 0401 - - struct loadmap load401[] = { - SEG_DATA, 56 KB, - 0, 0 KB - }; struct loadmap load407[] = { SEG_DATA, 56 KB, 0, 0 KB --- 61,66 ---- *************** *** 126,132 **** }; struct loadtable loadtable[] = { - A_MAGICU, load401, /* ULTRIX boot */ A_MAGIC1, load407, A_MAGIC2, load410, A_MAGIC3, load411, --- 117,122 ---- *************** *** 136,146 **** main() { ! int i, j; int retry = 0; struct loadtable *setup(); ! printf("\nboot: %d%s\n", cputype, module); /* * The machine language will have gotten the bootopts * if we're an autoboot and will pass them along. --- 126,160 ---- main() { ! register int i, j, maj; int retry = 0; + caddr_t *adjcsr; struct loadtable *setup(); + struct iob *file; + char *rb = RB_DEFNAME; ! maj = major(bootdev); ! if (maj >= ndevsw) { ! printf("bootdev: 0%o", bootdev); ! _stop("bad major"); ! } ! adjcsr = (caddr_t *)((short)bootcsr - ADJcsr[maj]); ! for (i = 0; devsw[maj].dv_csr != (caddr_t) -1; i++) { ! if (adjcsr == devsw[maj].dv_csr[i]) ! break; ! if (devsw[maj].dv_csr[i] == 0) { ! devsw[maj].dv_csr[i] = adjcsr; ! break; ! } ! } ! if (devsw[maj].dv_csr[i] == (caddr_t *) -1) { ! printf("bootdev: 0%o", bootdev); ! _stop("no free csr slots"); ! } ! bootdev &= ~(3 << 6); ! bootdev |= (i << 6); /* controller # to bits 6&7 */ ! printf("\n%d%s from %s(%d,0,0%o)\n", cputype, module, ! devsw[major(bootdev)].dv_name, minor(bootdev), bootcsr); /* * The machine language will have gotten the bootopts * if we're an autoboot and will pass them along. *************** *** 156,167 **** } else printf(": %s\n", line); if (line[0] == '\0') { ! printf(": %s\n", RB_DEFNAME); ! i = open(RB_DEFNAME, 0); ! } else ! i = open(line, 0); j = -1; if (i >= 0) { j = checkunix(i, setup(i)); (void) close(i); } --- 170,182 ---- } else printf(": %s\n", line); if (line[0] == '\0') { ! printf(": %s\n", rb); ! strcpy(line, rb); ! } ! i = open(line, 0); j = -1; if (i >= 0) { + file = &iob[i - 3]; /* -3 for pseudo stdin/o/e */ j = checkunix(i, setup(i)); (void) close(i); } *************** *** 168,173 **** --- 183,193 ---- if (++retry > 2) bootopts = RB_SINGLE | RB_ASKNAME; } while (j < 0); + i = file->i_ino.i_dev; + bootdev = makedev(i, file->i_unit); + bootcsr = devsw[i].dv_csr[(file->i_unit >> 6) & 3]; + bootcsr = (caddr_t *)((short)bootcsr + ADJcsr[i]); + printf("%s: bootdev=0%o bootcsr=0%o\n", module, bootdev, bootcsr); } struct loadtable * *************** *** 342,348 **** * If this is a 0407 style object, the text * and data are loaded together. */ ! if (exec.a_magic != A_MAGIC1 && exec.a_magic != A_MAGICU) { segoff += (off_t) exec.a_text; if (overlaid) for (i = 0; i < NOVL; i++) --- 362,368 ---- * If this is a 0407 style object, the text * and data are loaded together. */ ! if (exec.a_magic != A_MAGIC1) { segoff += (off_t) exec.a_text; if (overlaid) for (i = 0; i < NOVL; i++) *************** *** 539,545 **** unsigned btoc(nclicks) ! unsigned nclicks; { return((unsigned)(((((long) nclicks) + ((long) 63)) >> 6))); } --- 559,565 ---- unsigned btoc(nclicks) ! register unsigned nclicks; { return((unsigned)(((((long) nclicks) + ((long) 63)) >> 6))); } *** /usr/src/sys/pdpstand.old/br.c Fri Aug 26 14:25:30 1988 --- /usr/src/sys/pdpstand/br.c Sun Apr 21 00:05:45 1991 *************** *** 3,17 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)br.c 1.1 (2.10BSD Berkeley) 12/1/86 */ /* ! * br03-like disk driver ! * modified to handle EATON 1537 and 1711 controllers with ! * T300, T200, T80 and T50 drives. NOTE: the boot block is ! * hard coded to 32 sec/trk and 19 trk/cyl because he can't ! * be made big enough to autosize like this program can. */ #include "../h/param.h" --- 3,15 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)br.c 2.0 (2.11BSD) 4/20/91 */ /* ! * rp03-like disk driver ! * modified to handle BR 1537 and 1711 controllers with ! * T300, T200, T80 and T50 drives. */ #include "../h/param.h" *************** *** 19,49 **** #include "../pdpuba/brreg.h" #include "saio.h" ! #define BRADDR ((struct brdevice *) 0176710) ! #define SEC22 02400 /* T200 or T50 */ #define CYL5 01400 /* T80 or T50 */ ! int brsctrk[8], brtrkcyl[8]; brstrategy(io, func) register struct iob *io; { int com, cn, tn, sn, unit, sectrk, trkcyl, ctr; /* if we haven't gotten the characteristics yet, do so now. */ ! trkcyl = brtrkcyl[unit = io->i_unit]; ! if (!(sectrk = brsctrk[unit])) { ! /* give a home seek command, then wait for complete */ ! BRADDR->brcs.w = (unit << 8) | BR_HSEEK | BR_GO; ctr = 0; ! while ((BRADDR->brcs.w & BR_RDY) == 0 && --ctr) continue; ! if (BRADDR->brcs.w & BR_HE) { ! printf("br%d not ready\n", unit); return(-1); } ! com = BRADDR->brae; if (com & SEC22) sectrk = 22; else --- 17,59 ---- #include "../pdpuba/brreg.h" #include "saio.h" ! #define NBR 2 #define SEC22 02400 /* T200 or T50 */ #define CYL5 01400 /* T80 or T50 */ ! struct brdevice *BRcsr[NBR + 1] = ! { ! (struct brdevice *)0176710, ! (struct brdevice *)0, ! (struct brdevice *)-1 ! }; + int brsctrk[NBR][8], brtrkcyl[NBR][8]; + brstrategy(io, func) register struct iob *io; { + register struct brdevice *braddr; + register int ctlr; int com, cn, tn, sn, unit, sectrk, trkcyl, ctr; + unit = UNITn(io->i_unit); + ctlr = CTLRn(io->i_unit); + braddr = BRcsr[ctlr]; + /* if we haven't gotten the characteristics yet, do so now. */ ! trkcyl = brtrkcyl[ctlr][unit]; ! if (!(sectrk = brsctrk[ctlr][unit])) { ! /* give a home seek command, then wait for complete */ ! braddr->brcs.w = (unit << 8) | BR_HSEEK | BR_GO; ctr = 0; ! while ((braddr->brcs.w & BR_RDY) == 0 && --ctr) continue; ! if (braddr->brcs.w & BR_HE) { ! printf("br%d,%d not ready\n", ctlr,unit); return(-1); } ! com = braddr->brae; if (com & SEC22) sectrk = 22; else *************** *** 52,82 **** trkcyl = 5; else trkcyl = 19; ! brsctrk[unit] = sectrk; ! brtrkcyl[unit] = trkcyl; } cn = io->i_bn/(sectrk * trkcyl); sn = io->i_bn%(sectrk * trkcyl); tn = sn/sectrk; sn = sn%sectrk; ! BRADDR->brcs.w = (unit<<8); ! BRADDR->brda = (tn<<8) | sn; ! BRADDR->brca = cn; ! BRADDR->brba = io->i_ma; ! BRADDR->brwc = -(io->i_cc>>1); ! BRADDR->brae = segflag; com = (segflag<<4)|BR_GO; if (func == READ) com |= BR_RCOM; else com |= BR_WCOM; ! BRADDR->brcs.w |= com; ! while ((BRADDR->brcs.w& BR_RDY)==0) continue; ! if (BRADDR->brcs.w < 0) { /* error bit */ ! printf("disk error: cyl=%d track=%d sect=%d er=%o ds=%o\n", ! cn, tn, sn, BRADDR->brer, BRADDR->brds); return(-1); } return(io->i_cc); } --- 62,98 ---- trkcyl = 5; else trkcyl = 19; ! brsctrk[ctlr][unit] = sectrk; ! brtrkcyl[ctlr][unit] = trkcyl; } cn = io->i_bn/(sectrk * trkcyl); sn = io->i_bn%(sectrk * trkcyl); tn = sn/sectrk; sn = sn%sectrk; ! braddr->brcs.w = (unit<<8); ! braddr->brda = (tn<<8) | sn; ! braddr->brca = cn; ! braddr->brba = io->i_ma; ! braddr->brwc = -(io->i_cc>>1); ! braddr->brae = segflag; com = (segflag<<4)|BR_GO; if (func == READ) com |= BR_RCOM; else com |= BR_WCOM; ! braddr->brcs.w |= com; ! while ((braddr->brcs.w& BR_RDY)==0) continue; ! if (braddr->brcs.w < 0) { /* error bit */ ! printf("br%d,%d err: cy=%d tr=%d sc=%d er=%o ds=%o\n", ! ctlr, unit, cn, tn, sn, braddr->brer, braddr->brds); return(-1); } return(io->i_cc); + } + + bropen(io) + struct iob *io; + { + return(genopen(NBR, io)); } *** /usr/src/sys/pdpstand.old/conf.c Mon Aug 20 13:53:26 1990 --- /usr/src/sys/pdpstand/conf.c Tue Apr 23 10:39:58 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)c.c 1.1 (2.10BSD Berkeley) 12/1/86 */ #include "../h/param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)conf.c 2.0 (2.11BSD) 4/20/91 */ #include "../h/param.h" *************** *** 26,32 **** devopen(io) register struct iob *io; { ! (*devsw[io->i_ino.i_dev].dv_open)(io); } devclose(io) --- 26,32 ---- devopen(io) register struct iob *io; { ! return((*devsw[io->i_ino.i_dev].dv_open)(io)); } devclose(io) *************** *** 37,67 **** nullsys() { } ! int xpstrategy(); ! int brstrategy(); ! int rkstrategy(); ! int hkstrategy(); ! int rlstrategy(); ! int sistrategy(); ! int rastrategy(), raopen(), raclose(); ! int tmstrategy(), tmrew(), tmopen(); ! int htstrategy(), htopen(), htclose(); ! int tsstrategy(), tsopen(), tsclose(); ! int tmscpstrategy(), tmscpopen(), tmscpclose(); struct devsw devsw[] = { ! "xp", xpstrategy, nullsys, nullsys, ! "br", brstrategy, nullsys, nullsys, ! "rk", rkstrategy, nullsys, nullsys, ! "hk", hkstrategy, nullsys, nullsys, ! "rl", rlstrategy, nullsys, nullsys, ! "si", sistrategy, nullsys, nullsys, ! "ra", rastrategy, raopen, raclose, ! "tm", tmstrategy, tmopen, tmrew, ! "ht", htstrategy, htopen, htclose, ! "ts", tsstrategy, tsopen, tsclose, ! "tms", tmscpstrategy, tmscpopen, tmscpclose, 0, 0, 0, 0, }; --- 37,97 ---- nullsys() { + return(-1); } ! extern int xpstrategy(), xpopen(); ! extern int brstrategy(), bropen(); ! extern int rkstrategy(), rkopen(); ! extern int hkstrategy(), hkopen(); ! extern int rlstrategy(), rlopen(); ! extern int sistrategy(), siopen(); ! extern int rastrategy(), raopen(), raclose(); ! extern int tmstrategy(), tmopen(), tmclose(); ! extern int htstrategy(), htopen(), htclose(); ! extern int tsstrategy(), tsopen(), tsclose(); ! extern int tmscpstrategy(), tmscpopen(), tmscpclose(); + extern caddr_t *XPcsr[], *BRcsr[], *RKcsr[], *HKcsr[], *RLcsr[]; + extern caddr_t *SIcsr[], *RAcsr[], *TMcsr[], *HTcsr[], *TScsr[], *TMScsr[]; + + /* + * NOTE! This table must be in major device number order. See /sys/pdp/conf.c + * for the major device numbers. + */ + struct devsw devsw[] = { ! "ht", htstrategy, htopen, htclose, HTcsr, /* 0 */ ! "tm", tmstrategy, tmopen, tmclose, TMcsr, /* 1 */ ! "ts", tsstrategy, tsopen, tsclose, TScsr, /* 2 */ ! "ram", nullsys, nullsys, nullsys, 0, /* 3 */ ! "hk", hkstrategy, hkopen, nullsys, HKcsr, /* 4 */ ! "ra", rastrategy, raopen, raclose, RAcsr, /* 5 */ ! "rk", rkstrategy, rkopen, nullsys, RKcsr, /* 6 */ ! "rl", rlstrategy, rlopen, nullsys, RLcsr, /* 7 */ ! "rx", nullsys, nullsys, nullsys, 0, /* 8 */ ! "si", sistrategy, siopen, nullsys, SIcsr, /* 9 */ ! "xp", xpstrategy, xpopen, nullsys, XPcsr, /* 10 */ ! "br", brstrategy, bropen, nullsys, BRcsr, /* 11 */ ! "tms", tmscpstrategy, tmscpopen, tmscpclose, TMScsr,/* 12 */ 0, 0, 0, 0, }; + + int ndevsw = (sizeof (devsw) / sizeof (devsw[0])) - 1; + + char ADJcsr[] = + { + 0, /* HT = 0 */ + 2, /* TM = 1 */ + 2, /* TS = 2 */ + 0, /* RAM = 3 */ + 0, /* HK = 4 */ + 0, /* RA = 5 */ + 4, /* RK = 6 */ + 0, /* RL = 7 */ + 0, /* RX = 8 */ + 0, /* XP/SI = 9 */ + 0, /* XP = 10 */ + 4, /* BR =11 */ + 0, /* TMS = 12 */ + }; *** /usr/src/sys/pdpstand.old/hk.c Fri Aug 19 11:52:23 1988 --- /usr/src/sys/pdpstand/hk.c Sun Apr 21 00:06:35 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)hk.c 1.1 (2.10BSD Berkeley) 12/1/86 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)hk.c 2.0 (2.11BSD) 4/20/91 */ /* *************** *** 15,63 **** #include "../pdpuba/hkreg.h" #include "saio.h" ! ! #define HKADDR ((struct hkdevice *)0177440) ! ! #define NHK 8 #define NSECT 22 #define NTRAC 3 ! int hk_drvtyp[NHK]; ! char hk_mntflg[NHK]; hkstrategy(io, func) register struct iob *io; { register unit, com; ! register i; daddr_t bn; ! int sn, cn, tn; ! unit = io->i_unit; ! if (hk_mntflg[unit] != '1') { ! hk_drvtyp[unit] = 0; ! HKADDR->hkcs2 = unit; ! HKADDR->hkcs1 = HK_SELECT|HK_GO; ! while ((HKADDR->hkcs1 & HK_CRDY) == 0) continue; ! if (HKADDR->hkcs1 & HK_CERR && HKADDR->hker & HKER_DTYE) { ! hk_drvtyp[unit] = 02000; } ! hk_mntflg[unit] = '1'; } bn = io->i_bn; ! HKADDR->hkcs2 = HKCS2_SCLR; ! while ((HKADDR->hkcs1 & HK_CRDY) == 0) continue; ! HKADDR->hkcs2 = unit; ! HKADDR->hkcs1 = hk_drvtyp[unit]|HK_SELECT|HK_GO; ! while ((HKADDR->hkcs1 & HK_CRDY) == 0) continue; ! if ((HKADDR->hkds & HKDS_VV) == 0) { ! HKADDR->hkcs1 = hk_drvtyp[unit]|HK_PACK|HK_GO; ! while ((HKADDR->hkcs1 & HK_CRDY) == 0) continue; } cn = bn/(NSECT*NTRAC); --- 15,68 ---- #include "../pdpuba/hkreg.h" #include "saio.h" ! #define NHK 2 #define NSECT 22 #define NTRAC 3 ! struct hkdevice *HKcsr[NHK + 1] = ! { ! (struct hkdevice *)0177440, ! (struct hkdevice *)0, ! (struct hkdevice *)-1 ! }; + int hk_drvtyp[NHK][8]; + char hk_mntflg[NHK][8]; hkstrategy(io, func) register struct iob *io; { register unit, com; ! register struct hkdevice *hkaddr; daddr_t bn; ! int sn, cn, tn, ctlr; ! unit = UNITn(io->i_unit); ! ctlr = CTLRn(io->i_unit); ! hkaddr = HKcsr[ctlr]; ! if (hk_mntflg[ctlr][unit] != '1') { ! hk_drvtyp[ctlr][unit] = 0; ! hkaddr->hkcs2 = unit; ! hkaddr->hkcs1 = HK_SELECT|HK_GO; ! while ((hkaddr->hkcs1 & HK_CRDY) == 0) continue; ! if (hkaddr->hkcs1 & HK_CERR && hkaddr->hker & HKER_DTYE) { ! hk_drvtyp[ctlr][unit] = 02000; } ! hk_mntflg[ctlr][unit] = '1'; } bn = io->i_bn; ! hkaddr->hkcs2 = HKCS2_SCLR; ! while ((hkaddr->hkcs1 & HK_CRDY) == 0) continue; ! hkaddr->hkcs2 = unit; ! hkaddr->hkcs1 = hk_drvtyp[ctlr][unit]|HK_SELECT|HK_GO; ! while ((hkaddr->hkcs1 & HK_CRDY) == 0) continue; ! if ((hkaddr->hkds & HKDS_VV) == 0) { ! hkaddr->hkcs1 = hk_drvtyp[ctlr][unit]|HK_PACK|HK_GO; ! while ((hkaddr->hkcs1 & HK_CRDY) == 0) continue; } cn = bn/(NSECT*NTRAC); *************** *** 65,88 **** tn = sn/NSECT; sn = sn%NSECT; ! HKADDR->hkcyl = cn; ! HKADDR->hkda = (tn<<8) | sn; ! HKADDR->hkba = io->i_ma; ! HKADDR->hkwc = -(io->i_cc>>1); ! com = hk_drvtyp[unit]|(segflag << 8) | HK_GO; if (func == READ) com |= HK_READ; else if (func == WRITE) com |= HK_WRITE; ! HKADDR->hkcs1 = com; ! while ((HKADDR->hkcs1 & HK_CRDY) == 0) continue; ! if (HKADDR->hkcs1 & HK_CERR) { ! printf("disk error: cyl=%d track=%d sect=%d cs2=%d err=%o\n", ! cn, tn, sn, HKADDR->hkcs2, HKADDR->hker); return(-1); } return(io->i_cc); } --- 70,99 ---- tn = sn/NSECT; sn = sn%NSECT; ! hkaddr->hkcyl = cn; ! hkaddr->hkda = (tn<<8) | sn; ! hkaddr->hkba = io->i_ma; ! hkaddr->hkwc = -(io->i_cc>>1); ! com = hk_drvtyp[ctlr][unit]|(segflag << 8) | HK_GO; if (func == READ) com |= HK_READ; else if (func == WRITE) com |= HK_WRITE; ! hkaddr->hkcs1 = com; ! while ((hkaddr->hkcs1 & HK_CRDY) == 0) continue; ! if (hkaddr->hkcs1 & HK_CERR) { ! printf("hk%d,%d err: cy=%d tr=%d sc=%d cs2=%d er=%o\n", ! ctlr, unit, cn, tn, sn, hkaddr->hkcs2, hkaddr->hker); return(-1); } return(io->i_cc); + } + + hkopen(io) + struct iob *io; + { + return(genopen(NHK, io)); } *** /usr/src/sys/pdpstand.old/ht.c Fri Aug 19 11:53:51 1988 --- /usr/src/sys/pdpstand/ht.c Sun Apr 21 00:07:30 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ht.c 1.1 (2.10BSD Berkeley) 12/1/86 */ /* --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ht.c 2.0 (2.11BSD) 4/20/91 */ /* *************** *** 15,27 **** #include "../pdpuba/htreg.h" #include "saio.h" ! ! #define HTADDR ((struct htdevice *)0172440) ! ! #define TUUNIT(dev) (minor(dev) & 03) #define H_NOREWIND 004 /* not used in stand alone driver */ #define H_1600BPI 010 extern int tapemark; /* flag to indicate tapemark encountered (see sys.c as to how it's used) */ --- 15,30 ---- #include "../pdpuba/htreg.h" #include "saio.h" ! #define NHT 2 #define H_NOREWIND 004 /* not used in stand alone driver */ #define H_1600BPI 010 + struct htdevice *HTcsr[NHT + 1] = + { + (struct htdevice *)0172440, + (struct htdevice *)0, + (struct htdevice *)-1 + }; extern int tapemark; /* flag to indicate tapemark encountered (see sys.c as to how it's used) */ *************** *** 29,36 **** --- 32,42 ---- register struct iob *io; { register skip; + register int ctlr = CTLRn(io->i_unit); int i; + if (genopen(NHT, io) < 0) + return(-1); htstrategy(io, HT_REW); skip = io->i_boff; while (skip--) { *************** *** 42,47 **** --- 48,54 ---- continue; htstrategy(io, HT_SENSE); } + return(0); } htclose(io) *************** *** 53,71 **** htstrategy(io, func) register struct iob *io; { ! register unit, com, errcnt; ! unit = io->i_unit; errcnt = 0; retry: ! htquiet(); ! HTADDR->httc = ! ((unit&H_1600BPI) ? HTTC_1600BPI : HTTC_800BPI) ! | HTTC_PDP11 | TUUNIT(unit); ! HTADDR->htba = io->i_ma; ! HTADDR->htfc = -io->i_cc; ! HTADDR->htwc = -(io->i_cc >> 1); com = ((segflag) << 8) | HT_GO; if (func == READ) com |= HT_RCOM; --- 60,85 ---- htstrategy(io, func) register struct iob *io; { ! register unit, com; ! int errcnt, ctlr; ! register struct htdevice *htaddr; ! unit = UNITn(io->i_unit); ! ctlr = CTLRn(io->i_unit); ! htaddr = HTcsr[ctlr]; errcnt = 0; retry: ! while ((htaddr->htcs1 & HT_RDY) == 0) ! continue; ! while (htaddr->htfs & HTFS_PIP) ! continue; ! htaddr->httc = ! ((io->i_unit&H_1600BPI) ? HTTC_1600BPI : HTTC_800BPI) ! | HTTC_PDP11 | unit; ! htaddr->htba = io->i_ma; ! htaddr->htfc = -io->i_cc; ! htaddr->htwc = -(io->i_cc >> 1); com = ((segflag) << 8) | HT_GO; if (func == READ) com |= HT_RCOM; *************** *** 72,95 **** else if (func == WRITE) com |= HT_WCOM; else if (func == HT_SREV) { ! HTADDR->htfc = -1; ! HTADDR->htcs1 = com | HT_SREV; return(0); } else com |= func; ! HTADDR->htcs1 = com; ! while ((HTADDR->htcs1 & HT_RDY) == 0) continue; ! if (HTADDR->htfs & HTFS_TM) { tapemark = 1; ! htinit(); return(0); } ! if (HTADDR->htcs1 & HT_TRE) { if (errcnt == 0) ! printf("\nHT unit %d tape error: cs2=%o, er=%o", ! unit, HTADDR->htcs2, HTADDR->hter); ! htinit(); if (errcnt++ == 10) { printf("\n(FATAL ERROR)\n"); return(-1); --- 86,109 ---- else if (func == WRITE) com |= HT_WCOM; else if (func == HT_SREV) { ! htaddr->htfc = -1; ! htaddr->htcs1 = com | HT_SREV; return(0); } else com |= func; ! htaddr->htcs1 = com; ! while ((htaddr->htcs1 & HT_RDY) == 0) continue; ! if (htaddr->htfs & HTFS_TM) { tapemark = 1; ! htinit(htaddr); return(0); } ! if (htaddr->htcs1 & HT_TRE) { if (errcnt == 0) ! printf("\nHT%d,%d err: cs2=%o, er=%o", ! ctlr, unit, htaddr->htcs2, htaddr->hter); ! htinit(htaddr); if (errcnt++ == 10) { printf("\n(FATAL ERROR)\n"); return(-1); *************** *** 97,124 **** htstrategy(io, HT_SREV); goto retry; } ! if (errcnt) ! printf("\n(RECOVERED by retry)\n"); ! return(io->i_cc+HTADDR->htfc); } ! htinit() { register int omt, ocs2; ! omt = HTADDR->httc & 03777; ! ocs2 = HTADDR->htcs2 & 07; ! HTADDR->htcs2 = HTCS2_CLR; ! HTADDR->htcs2 = ocs2; ! HTADDR->httc = omt; ! HTADDR->htcs1 = HT_DCLR|HT_GO; ! } ! ! htquiet() ! { ! while ((HTADDR->htcs1 & HT_RDY) == 0) ! continue; ! while (HTADDR->htfs & HTFS_PIP) ! continue; } --- 111,129 ---- htstrategy(io, HT_SREV); goto retry; } ! return(io->i_cc+htaddr->htfc); } ! htinit(htaddr) ! register struct htdevice *htaddr; { register int omt, ocs2; ! omt = htaddr->httc & 03777; ! ocs2 = htaddr->htcs2 & 07; ! htaddr->htcs2 = HTCS2_CLR; ! htaddr->htcs2 = ocs2; ! htaddr->httc = omt; ! htaddr->htcs1 = HT_DCLR|HT_GO; } *** /usr/src/sys/pdpstand.old/maketape.c Wed Dec 19 10:18:27 1990 --- /usr/src/sys/pdpstand/maketape.c Sun Apr 28 22:56:06 1991 *************** *** 4,10 **** * specifies the terms and conditions for redistribution. * * @(#)maketape.c 1.1 (2.10BSD Berkeley) 12/1/86 ! * (2.11BSD Contel) 10/1/90 * TU81s didn't like open/close/write at 1600bpi, use * ioctl to write tape marks instead. */ --- 4,10 ---- * specifies the terms and conditions for redistribution. * * @(#)maketape.c 1.1 (2.10BSD Berkeley) 12/1/86 ! * (2.11BSD Contel) 4/20/91 * TU81s didn't like open/close/write at 1600bpi, use * ioctl to write tape marks instead. */ *************** *** 30,36 **** int argc; char *argv[]; { ! int i, j = 0, k = 0; FILE *mf; if (argc != 3) { --- 30,36 ---- int argc; char *argv[]; { ! register int i, j = 0, k = 0; FILE *mf; if (argc != 3) { *************** *** 91,96 **** --- 91,97 ---- } } if (cnt>0) { + j++; bzero(buf + cnt, recsz - cnt); if (write(mt, buf, recsz) < 0) { perror(argv[1]); *** /usr/src/sys/pdpstand.old/mtboot.s Fri Sep 2 21:02:25 1988 --- /usr/src/sys/pdpstand/mtboot.s Fri May 3 23:55:21 1991 *************** *** 1,39 **** /* * Primary tape boot program to load and execute secondary boot. * ! * Two copies of the primary boot are stored in the first and second blocks ! * of the first tape file (some boot proms execute the second block when * booting a tape). The secondary boot is also stored in the first tape ! * file, starting at block #3. * - * Note that this boot has been hacked to death in order to squeeze three - * primary tape boots in for the HT, TM, and TS. It turns out that this - * wasn't as hard as one might think since the original primary tape boots - * were overly ambitious in their generality. Needless to say, that - * generality is no longer present ... - * - * Note that while we are prepared to compile multiple different primary - * bootstraps to support different tape densities (BPI), we don't bother - * ifdef'ing out the various drivers which don't support the defined - * BPI. They all fit in 512 bytes now, so who cares? - * * Also note that the struct exec header must be removed from this bootstrap. ! * This needs to be done so taking the addresses of the various tape rewind ! * and read functions will work. */ NEWLOC = [48.*1024.] / we relocate ourselves to this address ! #ifndef BPI ! # define BPI 1600 ! #endif - busvec = 04 / bus error trap vector - hipri = 0340 / PS slp 7 - a_text = 02 / a_text (struct exec) field offset a_data = 04 / a_data (struct exec) field offset ! trew = r5 / pointer at trew routine tread = r4 / pointer at tread routine blkcnt = r3 / number of blocks to read memaddr = r2 / memory location to read into --- 1,35 ---- /* * Primary tape boot program to load and execute secondary boot. * ! * This is a universal tape boot which can handle HT, TM, TS and TMSCP ! * tapes. This boot is FULL. Some of the more extended error ! * checking had to be left out to get all the drivers to fit. ! * ! * Two copies of the primary boot are stored in the first and second records ! * of the first tape file (some boot proms execute the second one when * booting a tape). The secondary boot is also stored in the first tape ! * file, starting at record #3. * * Also note that the struct exec header must be removed from this bootstrap. ! * This needs to be done so taking the address of the tape read and rewind ! * functions will work. ! * ! * Due to size constraints and the rather destructive way in which ! * all the registers are used, this boot does not support the ! * "jsr pc,0; br restart" convention. */ NEWLOC = [48.*1024.] / we relocate ourselves to this address + OURSIZE = 512. / assume we are up to this size ! HT_MAJOR = 0 / major device number from bdevsw[] ! TM_MAJOR = 1 ! TS_MAJOR = 2 ! TMS_MAJOR = 12. a_text = 02 / a_text (struct exec) field offset a_data = 04 / a_data (struct exec) field offset ! csr = r5 / saved csr of boot device tread = r4 / pointer at tread routine blkcnt = r3 / number of blocks to read memaddr = r2 / memory location to read into *************** *** 45,86 **** br 1f / " " " " 1: mov $NEWLOC,sp / give ourselves a stack to work with ! cmp pc,sp / are we running above the stack? ! bhis 3f / [yes, no need to relocate ourselves] ! mov sp,r1 / no, we gotta move ourselves up ! clr r0 / [assume we're at location 0 now] ! mov $256.,r2 / primary boot is at most 256 words 2: ! mov (r0)+,(r1)+ / move primary boot to just above ! sob r2,2b / the stack ! jmp (sp) / reexecute ourselves at our new loc 3: ! mov $hipri,*$busvec+2 / take bus errors at high priority ! httest: ! mov $1f,*$busvec+0 / HT htcs1 register present? ! tst *$htcs1 / yes, if we got here: set trew and ! mov $htrew,trew / tread routines and continue ! mov $htread,tread ! br readit ! 1: ! tmtest: ! mov $1f,*$busvec+0 / TM tmmr register present? (the TM ! tst *$tmmr / TS controllers use the same CSR ! mov $tmread,tread / address, but tmmr is above the ! mov $tmrew,trew / last CSR address of the TS ...) ! br readit ! 1: ! tstest: ! mov $tsread,tread / else it has to be a TS ... ! mov $tsrew,trew readit: ! jsr pc,*trew / rewind the tape ! mov $2,blkcnt / skip past the two copies of our ! clr memaddr / self on the tape (throw them ! jsr pc,*tread / at location zero) ! mov $1,blkcnt / and read the first block ! clr memaddr / to location 0 ... ! jsr pc,*tread mov *$a_text,blkcnt / compute remaining amount to read: add *$a_data,blkcnt / (a_text + a_data --- 41,88 ---- br 1f / " " " " 1: mov $NEWLOC,sp / give ourselves a stack to work with ! clr r4 ! mov sp,r5 ! mov $OURSIZE\/2,r3 / primary boot size in words 2: ! clr OURSIZE(r5) / clear work area (major & TS/MSCP area) ! mov (r4)+,(r5)+ / move primary boot to just above ! sob r3,2b / the stack ! jmp *$3f / bypass the relocation code 3: ! mov r0,unit / save unit number ! mov r1,csr / save the csr ! cmp r1,$172440 / HT is always at this address ! beq common / r3 is table index ! inc r3 / index for TMSCP ! cmp r1,$172522 / is this a TS? ! blo common / no - br, likely TMSCP ! cmp r1,$172522+[7*4] / is CSR in the TS range? ! bhi common / no, is a TMSCP - br ! inc r3 / adjust index to TS ! mov (r1),r4 / save contents of csr in case of a TM ! clr (r1) / poke the controller ! / clr r2 / now we delay ! /1: ! / sob r2,1b / time for TS to run diagnostics ! 2: ! tstb (r1) / is controller ready? ! bpl 2b / no - br ! bit $2000,(r1) / TS "address required" bit ! bne common / if a TS - br ! mov r4,(r1) / is a TM, restore unit/density select ! inc r3 / make TM index ! common: ! movb table1(r3),major+1 / save major device number to high byte ! asl r3 / make a word index ! mov table2(r3),tread / fetch read routine address ! jsr pc,*table3(r3) / call rewind routine (must preserve r4) readit: ! clr memaddr / load starting at 0 ! jsr pc,*tread / skip the two copies of this ! jsr pc,*tread / program on the tape ! clr memaddr / reset memory address ! jsr pc,*tread / read first block of boot mov *$a_text,blkcnt / compute remaining amount to read: add *$a_data,blkcnt / (a_text + a_data *************** *** 88,247 **** ash $-9.,blkcnt / - 512) [already read one block] bic $177600,blkcnt / / 512 [[unsigned]] beq done / already done if == 0 [not likely] ! jsr pc,*tread done: - clr r0 / strip the a.out header from the - mov $16.,r1 / secondary boot by shifting it 1: / down by sizeof(struct exec) ! mov (r1)+,(r0)+ ! cmp r1,sp blo 1b ! clr pc / jump to location 0 ... /* ! * HT tape driver */ ! htcs1 = 0172440 ! htba = 0172444 ! htfc = 0172446 ! htcs2 = 0172450 ! htds = 0172452 ! httc = 0172472 - PIP = 020000 RESET = 040 - MOL = 010000 - ERR = 040000 - REV = 033 READ = 071 REW = 07 - #if BPI == 800 - HTBPI = 01700 / 800BPI | PDP-11 mode - #endif - #if BPI == 1600 - HTBPI = 02300 / 1600BPI | PDP-11 mode - #endif - #if BPI == 6250 - HTBPI = 0 / just so things assemble right - #endif - - /* - * Read blkcnt tape records into location memaddr. - * Side effects: - * blkcnt gets zeroed - * memaddr += 512 * blkcnt - * tape is advanced blkcnt records - */ - htread: - jsr pc,hrrec / read tape records until blkcnt - sob blkcnt,htread / goes to 0 ... - rts pc - - /* - * Read one tape record. - * Side effects: - * memaddr += 512 - * tape is advanced 1 record - */ hrrec: ! mov $htds,r0 ! tstb (r0) ! bpl hrrec ! bit $PIP,(r0) ! bne hrrec ! bit $MOL,(r0) ! beq hrrec ! mov $htfc,r0 ! mov $-512.,(r0) ! mov memaddr,-(r0) ! mov $-256.,-(r0) ! mov $READ,-(r0) ! 1: ! tstb (r0) ! bpl 1b ! bit $ERR,(r0) ! bpl 2f ! mov $RESET,*$htcs2 ! mov $-1,*$htfc ! mov $REV,(r0) ! br hrrec ! 2: ! add $512.,memaddr ! rts pc /* ! * Rewind tape. ! * Side effects: ! * just what the first line says ... */ htrew: ! mov $RESET,*$htcs2 ! mov $HTBPI,*$httc ! mov $REW,*$htcs1 ! rts pc - /* ! * TM tape driver */ ! tmer = 172520 ! tmcs = 172522 ! tmbc = 172524 ! tmba = 172526 ! tmdb = 172530 ! tmrd = 172532 ! tmmr = 172534 - #if BPI == 800 - TMBPI = 060000 - #endif - #if BPI == 1600 - TMBPI = 000000 / Third party TMs only - #endif - #if BPI == 6250 - TMBPI = 020000 / Third party TMs only - #endif - - /* - * Read blkcnt tape records into location memaddr. - * Side effects: - * blkcnt gets zeroed - * memaddr += 512 * blkcnt - * tape is advanced blkcnt records - */ - tmread: - jsr pc,tmrrec / read tape records until blkcnt - sob blkcnt,tmread / goes to 0 ... - rts pc - - /* - * Read one tape record. - * Side effects: - * memaddr += 512 - * tape is advanced 1 record - */ tmrrec: ! mov $tmer,r0 ! bit $2,(r0)+ / rewind status ! bne tmrrec ! tstb (r0)+ / cu ready ! bpl tmrrec ! inc r0 ! mov $-512.,(r0)+ / byte count ! mov memaddr,(r0) / bus address ! mov $tmcs,r0 ! mov $TMBPI|3,(r0) / read ! 1: ! tstb (r0) ! bpl 1b ! tst (r0)+ ! bpl 2f ! mov $-1,(r0) ! mov $TMBPI|13,-(r0) / backspace ! br tmrrec ! 2: add $512.,memaddr rts pc --- 90,187 ---- ash $-9.,blkcnt / - 512) [already read one block] bic $177600,blkcnt / / 512 [[unsigned]] beq done / already done if == 0 [not likely] ! 2: jsr pc,*tread + sob blkcnt,2b done: 1: / down by sizeof(struct exec) ! mov 20(blkcnt),(blkcnt)+ / r3 cleared by loop above ! cmp blkcnt,sp blo 1b ! mov csr,r1 / put things where 'boot' ! mov unit,r3 / expects them ! bis major,r3 / the major device to high byte ! clr pc / go to location 0 ... no return /* ! * HT tape driver */ ! htcs1 = 0 / offset from base csr ! htwc = 2 ! htba = 4 ! htfc = 6 ! htcs2 = 10 ! htds = 12 ! hter = 14 ! httc = 32 RESET = 040 READ = 071 REW = 07 hrrec: ! mov memaddr,htba(csr) ! mov $-256.,htwc(csr) ! mov $READ,(csr) / htcs1 ! htcmd: ! tstb (csr) / controller ready? ! bpl htcmd ! tst htds(csr) / drive ready? ! bpl htcmd ! tstb htcs2+1(csr) / any controller errors? ! bne ctlerr ! bit $!1000,hter(csr) / any drive errors except HTER_FCE? ! beq bumpaddr / no, go bump address ! ctlerr: ! halt /* ! * Rewind tape. This routine is only done once and must preceed any reads. */ htrew: ! tstb (csr) / controller ready? ! bpl htrew / no - go try again ! mov htcs2(csr),r1 / boot unit(formatter) number ! bic $!7,r1 / only the low bits ! mov httc(csr),r0 / save format,slave,density ! bic $!3767,r0 / only the bits we're interested in ! mov $RESET,htcs2(csr) / reset controller ! movb r1,htcs2(csr) / reselect boot unit(formatter) ! mov r0,httc(csr) / reselect density/format/slave(drive) ! mov $REW,(csr) ! br htcmd / join common code /* ! * TM tape driver */ ! tmer = -2 / offset from base csr ! tmcs = 0 ! tmbc = 2 ! tmba = 4 ! tmdb = 6 ! tmrd = 10 ! tmmr = 12 tmrrec: ! mov $-512.,tmbc(csr) / bytecount ! mov memaddr,tmba(csr) / bus address ! mov $3,r1 / 'read' ! tmcmd: ! mov (csr),r0 ! bic $!63400,r0 / save the density and unit ! bis r1,r0 / merge in the function code ! mov r0,(csr) / tmcs - give command ! /1: ! / bit $100,tmer(csr) / unit still selected? (TMER_SELR) ! / beq ctlerr / nope, go halt ! / bit $1,tmer(csr) / unit ready? (TMER_TUR) ! / beq 1b / no, keep waiting ! tmtscom: ! bit $100200,(csr) / error or ready? ! beq tmtscom / neither, keep looking ! bmi ctlerr / error - go halt ! ! bumpaddr: add $512.,memaddr rts pc *************** *** 251,337 **** * just what the first line says ... */ tmrew: ! mov $TMBPI|17,*$tmcs ! rts pc - /* ! * TS tape driver ! * */ ! tsdb = 172520 ! tssr = 172522 - TSINIT = 140013 TSCHAR = 140004 TSREW = 102010 TSREAD = 100001 - TSRETRY = 100401 - tsdbuf = NEWLOC + 512. / put ts data buffer just after us - - /* - * Read blkcnt tape records into location memaddr. - * Side effects: - * blkcnt gets zeroed - * memaddr += 512 * blkcnt - * tape is advanced blkcnt records - */ - tsread: - jsr pc,tsrrec / read tape records until blkcnt - sob blkcnt,tsread / goes to 0 ... - rts pc - - /* - * Read one tape record. - * Side effects: - * memaddr += 512 - * tape is advanced 1 record - */ tsrrec: - tstb tssr - bpl tsrrec mov $tsdbuf+6,r0 mov $512.,(r0) clr -(r0) mov memaddr,-(r0) mov $TSREAD,-(r0) ! mov r0,tsdb ! 1: ! tstb tssr ! bpl 1b ! cmp $1,tssr ! blos 2f ! mov $TSRETRY,(r0) ! mov r0,tsdb ! br 1b ! 2: ! add $512.,memaddr ! rts pc /* ! * Rewind tape. * Side effects: * just what the first line says ... */ tsrew: ! tstb tssr / initialize ... ! bpl tsrew ! mov $tsdbuf,r0 ! mov $TSCHAR,(r0)+ ! mov $tsdbuf+10,(r0)+ ! clr (r0)+ ! mov $10,(r0)+ ! mov r0,(r0)+ ! clr (r0)+ ! mov $16,(r0)+ ! mov $tsdbuf,tsdb ! 1: ! tstb tssr ! bpl 1b /* ! * rewind ! */ ! mov $TSREW,tsdbuf ! mov $tsdbuf,tsdb rts pc --- 191,352 ---- * just what the first line says ... */ tmrew: ! mov $17,r1 / 'rewind' ! br tmcmd / join common code /* ! * TS tape driver */ ! tsdb = -2 / offset from ROM supplied address ! tssr = 0 TSCHAR = 140004 TSREW = 102010 TSREAD = 100001 tsrrec: mov $tsdbuf+6,r0 mov $512.,(r0) clr -(r0) mov memaddr,-(r0) mov $TSREAD,-(r0) ! mov r0,tsdb(csr) ! br tmtscom /* ! * Rewind and initialize tape - only done once. * Side effects: * just what the first line says ... */ tsrew: ! mov $tsdbuf,tsdb(csr) ! br tmtscom / go join common code ! ! .if [.-start]&2 ! .blkb 2 / tsdbuf must be on a mod 4 boundary ! .endif ! tsdbuf: ! TSCHAR / command ! tsdbuf+10 / buffer address (lo) ! 0 / buffer address (hi - always 0) ! 10 / length of command buffer ! ! / from here on is used only at initialization/rewind time. The Set ! / Charactistics command only looks at the word following the buffer length, ! / part of the TMSCP code is used as the remainder of the characteristics packet. ! ! tsdbuf+10 / buffer address (lo) ! 0 / buffer address (hi - always 0) ! 16 / minimum length packet ! 0 / characteristics to set (lo byte) ! /* ! * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. ! * All Rights Reserved. ! * Reference "/usr/src/COPYRIGHT" for applicable restrictions. ! * ! * ULTRIX-11 Block Zero Bootstrap for TMSCP Magtape ! * ! * SCCSID: @(#)tkboot.s 3.0 4/21/86 ! * ! * Chung_wu Lee 2/8/85 ! * ! * sms 4/27/91 - merged into universal tape boot ! * sms 4/12/91 - saved some more space. the major device number and unit ! * number are now passed to the secondary boot along with the csr of ! * the booting controller. ! * ! * Steven M. Schultz (sms@wlv.imsd.contel.com) Aug 20 1990. Port to 2.11BSD ! */ ! ! s1 = 4000 ! go = 1 ! ! / TK initialization (and rewind) - only done once ! tkrew: ! clr (csr)+ / start tk init sequence ! / move pointer to tksa register ! mov $s1,r0 / set tk state test bit to step 1 ! mov $cmdtbl,r1 / address of init seq table ! 2: ! tst (csr) / error ? ! bmi . / yes, hang - can't restart !!! ! bit r0,(csr) / current step done ? ! beq 2b / no ! mov (r1)+,(csr) / yes, load next step info from table ! asl r0 / change state test bit to next step ! bpl 2b / if all steps not done, go back ! / r0 now = 100000, TK_OWN bit ! mov $400,cmdhdr+2 / tape VCID = 1 ! mov $36.,cmdhdr / command packet length ! / don't set response packet length, ! / little shakey but it works. ! / unit is already loaded at tkcmd+4 ! mov $11,tkcmd+8. / on-line command opcode ! mov $20000,tkcmd+10. / set clear serious exception ! mov $ring,r2 / initialize cmd/rsp ring ! mov $tkrsp,(r2)+ / address of response packet ! mov r0,(r2)+ / set TK owner ! mov $tkcmd,(r2)+ / address of command packet ! mov r0,(r2)+ / set TK owner ! mov -(csr),r0 / start TK polling ! 3: ! jsr pc,tkready ! mov $tkcmd+8.,r0 ! mov $45,(r0)+ / reposition opcode ! mov $20002,(r0)+ / set rewind & clear serious exception ! clr (r0)+ / clear record/object count ! clr (r0)+ / zzz2 ! clr (r0)+ / clear tape mark count ! tkpoll: ! mov $100000,ring+2 / set TK owner of response ! mov $100000,ring+6 / set TK owner of command ! mov (csr),r0 / start TK polling ! tkready: ! tst ring+2 / wait for response ! bmi tkready ! tstb tkrsp+10. / does returned status = SUCCESS ? ! bne . / no, hang rts pc + tkread: + mov $tkcmd+8.,r0 + mov $41,(r0)+ / read opcode + mov $20000,(r0)+ / set clear serious exception + mov $512.,(r0)+ / byte count + clr (r0)+ / zzz2 + mov memaddr,(r0)+ / buffer address + jsr pc,bumpaddr / bump address + br tkpoll / wait for response + + cmdtbl: + 100000 / TK_ERR, init step 1 + ring / address of ringbase + 0 / hi ringbase address + go / TK go bit + + table1: + .byte HT_MAJOR + .byte TMS_MAJOR + .byte TS_MAJOR + .byte TM_MAJOR + table2: + hrrec + tkread + tsrrec + tmrrec + table3: + htrew + tkrew + tsrew + tmrew + end: + + major = NEWLOC+OURSIZE + cmdint = major+2 / TMSCP stuff + rspint = cmdint+2. + ring = rspint+2. + rsphdr = ring+8. + tkrsp = rsphdr+4. + cmdhdr = tkrsp+48. + tkcmd = cmdhdr+4. + unit = tkcmd+4 *** /usr/src/sys/pdpstand.old/prf.c Fri Aug 19 11:57:00 1988 --- /usr/src/sys/pdpstand/prf.c Sun Apr 21 00:13:07 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)prf.c 1.1 (2.10BSD Berkeley) 12/1/86 */ #include "../machine/cons.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)prf.c 1.2 (2.11BSD) 4/20/91 */ #include "../machine/cons.h" *************** *** 54,62 **** */ printn(n, b) long n; ! int b; { ! register long a; if (n < 0) { /* shouldn't happen */ putchar('-'); --- 54,62 ---- */ printn(n, b) long n; ! register int b; { ! long a; if (n < 0) { /* shouldn't happen */ putchar('-'); *** /usr/src/sys/pdpstand.old/ra.c Fri Sep 29 11:48:26 1989 --- /usr/src/sys/pdpstand/ra.c Sun Apr 21 00:13:54 1991 *************** *** 3,14 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ra.c 1.1 (2.10BSD Berkeley) 12/1/86 */ /* * RAxx disk device driver ! * RQDX1 (rx50, rd50, rd51, rd52, rd53) */ #include "../h/param.h" #include "../h/inode.h" --- 3,14 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)ra.c 2.0 (2.11BSD) 4/20/91 */ /* * RAxx disk device driver ! * RQDX?/UDA50 (rx33, rx50, rd5?, ra??) */ #include "../h/param.h" #include "../h/inode.h" *************** *** 16,21 **** --- 16,30 ---- #include "../pdpuba/rareg.h" #include "saio.h" + #define NRA 2 + + struct radevice *RAcsr[NRA + 1] = + { + (struct radevice *)0172150, + (struct radevice *)0, + (struct radevice *)-1 + }; + /* * RA Communications Area */ *************** *** 36,103 **** #define RA_OWN 0x8000 /* RQ owns this descriptor */ #define RA_INT 0x4000 /* allow interrupt on ring transition */ - static struct radevice *RDADDR = ((struct radevice *)0172150); - static struct ra { struct rdca ra_ca; struct mscp ra_rsp; struct mscp ra_cmd; ! } rd; ! struct mscp *racmd(); ! static int rdinit; ! static long rdonline[8]; - /* - * XXX - Not consistent with other stand alone drivers. - * static int rd_boff[] = { 0, 9700, 27000, 30100, 0, 7460, 9700, 0 }; - */ - raopen(io) register struct iob *io; { ! register struct mscp *mp; ! int i; ! if (rdinit == 0) { ! RDADDR->raip = 0; ! while ((RDADDR->rasa & RA_STEP1) == 0) continue; ! RDADDR->rasa = RA_ERR; ! while ((RDADDR->rasa & RA_STEP2) == 0) continue; ! RDADDR->rasa = (short)&rd.ra_ca.ca_ringbase; ! while ((RDADDR->rasa & RA_STEP3) == 0) continue; ! RDADDR->rasa = (short)(segflag & 3); ! while ((RDADDR->rasa & RA_STEP4) == 0) continue; ! RDADDR->rasa = RA_GO; ! rd.ra_ca.ca_rspl = (short)&rd.ra_rsp.m_cmdref; ! rd.ra_ca.ca_rsph = (short)(segflag & 3); ! rd.ra_ca.ca_cmdl = (short)&rd.ra_cmd.m_cmdref; ! rd.ra_ca.ca_cmdh = (short)(segflag & 3); ! rd.ra_cmd.m_cntflgs = 0; ! if ((int)racmd(M_O_STCON, 0) < 0) { ! printf("RD: controller init error, STCON\n"); return(-1); } ! rdinit = 1; } ! if (rdonline[io->i_unit & 7] == 0) if (ramount(io) == -1) return(-1); - - /* - * XXX - Not consistent with other stand alone drivers. - * if ((io->i_boff < 0) || (io->i_boff > 7) || - * (rd_boff[io->i_boff] == -1)) { - * printf("RD: bad partition for unit=%d", io->i_unit & 7); - * } - * io->i_boff = rd_boff[io->i_boff]; - */ - return(0); } --- 45,102 ---- #define RA_OWN 0x8000 /* RQ owns this descriptor */ #define RA_INT 0x4000 /* allow interrupt on ring transition */ static struct ra { struct rdca ra_ca; struct mscp ra_rsp; struct mscp ra_cmd; ! } rd[NRA]; ! static u_char rainit[NRA]; ! static long raonline[NRA][8]; raopen(io) register struct iob *io; { ! register struct radevice *raaddr; ! register struct ra *racom; ! int i, ctlr, unit; ! ctlr = CTLRn(io->i_unit); ! unit = UNITn(io->i_unit); ! if (genopen(NRA, io) < 0) ! return(-1); ! raaddr = RAcsr[ctlr]; ! racom = &rd[ctlr]; ! ! if (rainit[ctlr] == 0) { ! raaddr->raip = 0; ! while ((raaddr->rasa & RA_STEP1) == 0) continue; ! raaddr->rasa = RA_ERR; ! while ((raaddr->rasa & RA_STEP2) == 0) continue; ! raaddr->rasa = (short)&racom->ra_ca.ca_ringbase; ! while ((raaddr->rasa & RA_STEP3) == 0) continue; ! raaddr->rasa = (short)(segflag & 3); ! while ((raaddr->rasa & RA_STEP4) == 0) continue; ! raaddr->rasa = RA_GO; ! racom->ra_ca.ca_rspl = (short)&racom->ra_rsp.m_cmdref; ! racom->ra_ca.ca_rsph = (short)(segflag & 3); ! racom->ra_ca.ca_cmdl = (short)&racom->ra_cmd.m_cmdref; ! racom->ra_ca.ca_cmdh = (short)(segflag & 3); ! racom->ra_cmd.m_cntflgs = 0; ! if (racmd(M_O_STCON, 0) < 0) { ! printf("RA%d ctlr STCON err\n", ctlr); return(-1); } ! rainit[ctlr] = 1; } ! if (raonline[ctlr][unit] == 0) if (ramount(io) == -1) return(-1); return(0); } *************** *** 104,110 **** raclose(io) register struct iob *io; { ! rdonline[io->i_unit & 7] = 0; return(0); } --- 103,109 ---- raclose(io) register struct iob *io; { ! raonline[CTLRn(io->i_unit)][UNITn(io->i_unit)] = 0; return(0); } *************** *** 111,152 **** ramount(io) register struct iob *io; { ! if ((int)racmd(M_O_ONLIN, io->i_unit) < 0) { ! printf("RD: bring online error, unit=%d\n", io->i_unit & 7); return(-1); } ! rdonline[io->i_unit & 7] = rd.ra_rsp.m_uslow + ! ((long)(rd.ra_rsp.m_ushigh) << 16); return(0); } - struct mscp * racmd(op, unit) int op, unit; { register struct mscp *mp; ! register int i; ! rd.ra_cmd.m_opcode = op; ! rd.ra_cmd.m_unit = unit & 7; ! rd.ra_rsp.m_header.ra_msglen = sizeof(struct mscp); ! rd.ra_cmd.m_header.ra_msglen = sizeof(struct mscp); ! rd.ra_ca.ca_rsph = RA_OWN | RA_INT | (segflag & 3); ! rd.ra_ca.ca_cmdh = RA_OWN | RA_INT | (segflag & 3); ! i = RDADDR->raip; while (1) { ! if (rd.ra_ca.ca_cmdint) ! rd.ra_ca.ca_cmdint = 0; ! if (rd.ra_ca.ca_rspint) break; } ! rd.ra_ca.ca_rspint = 0; ! mp = &rd.ra_rsp; ! if (((mp->m_opcode & 0xff) != (op | M_O_END)) || ((mp->m_status & M_S_MASK) != M_S_SUCC)) { ! printf("RD: command error, unit=%d, opcode=%x, status=%x\n", ! unit & 7, mp->m_opcode & 0xff, mp->m_status); ! return((struct mscp *)-1); } return(0); } --- 110,155 ---- ramount(io) register struct iob *io; { ! register int ctlr = CTLRn(io->i_unit); ! register int unit = UNITn(io->i_unit); ! ! if (racmd(M_O_ONLIN, io->i_unit) < 0) { ! printf("RA%d,%d: online err\n", ctlr, unit); return(-1); } ! raonline[ctlr][unit] = rd[ctlr].ra_rsp.m_uslow + ! ((long)(rd[ctlr].ra_rsp.m_ushigh) << 16); return(0); } racmd(op, unit) int op, unit; { register struct mscp *mp; ! register int ctlr = CTLRn(unit); ! register struct ra *racom = &rd[ctlr]; ! int i; ! racom->ra_cmd.m_opcode = op; ! racom->ra_cmd.m_unit = UNITn(unit); ! racom->ra_rsp.m_header.ra_msglen = sizeof(struct mscp); ! racom->ra_cmd.m_header.ra_msglen = sizeof(struct mscp); ! racom->ra_ca.ca_rsph = RA_OWN | RA_INT | (segflag & 3); ! racom->ra_ca.ca_cmdh = RA_OWN | RA_INT | (segflag & 3); ! i = RAcsr[ctlr]->raip; while (1) { ! if (racom->ra_ca.ca_cmdint) ! racom->ra_ca.ca_cmdint = 0; ! if (racom->ra_ca.ca_rspint) break; } ! racom->ra_ca.ca_rspint = 0; ! mp = &racom->ra_rsp; ! if ((mp->m_opcode != (op | M_O_END)) || ((mp->m_status & M_S_MASK) != M_S_SUCC)) { ! printf("RA%d,%d: cmd err op=%x, sts=%x\n", ! ctlr, unit, mp->m_opcode, mp->m_status); ! return(-1); } return(0); } *************** *** 155,172 **** register struct iob *io; { register struct mscp *mp; ! if (io->i_bn >= rdonline[io->i_unit & 7]) return(0); ! mp = &rd.ra_cmd; mp->m_lbn_l = loint(io->i_bn); mp->m_lbn_h = hiint(io->i_bn); mp->m_bytecnt = io->i_cc; mp->m_buf_l = (ushort)io->i_ma; mp->m_buf_h = segflag & 3; ! if ((int)racmd(func == READ ? M_O_READ : M_O_WRITE, io->i_unit) < 0) return(-1); - return(io->i_cc); } --- 158,177 ---- register struct iob *io; { register struct mscp *mp; + struct ra *racom; + register int ctlr = CTLRn(io->i_unit); ! if (io->i_bn >= raonline[ctlr][UNITn(io->i_unit)]) return(0); ! racom = &rd[ctlr]; ! mp = &racom->ra_cmd; mp->m_lbn_l = loint(io->i_bn); mp->m_lbn_h = hiint(io->i_bn); mp->m_bytecnt = io->i_cc; mp->m_buf_l = (ushort)io->i_ma; mp->m_buf_h = segflag & 3; ! if (racmd(func == READ ? M_O_READ : M_O_WRITE, io->i_unit) < 0) return(-1); return(io->i_cc); }