Subject: MSCP/TMSCP programmable vectors vs. autoconfig (#83) Index: sys/autoconfig/*,sys/pdpuba/{ra.c,rareg.h,tmscp.c} 2.11BSD Description: The MSCP and TMSCP vector assignment logic is a kludge which can cause those drivers to usurp vectors allocated to other devices. Repeat-By: Have more than 1 MSCP (or TMSCP) controller in a system. Note that the vector the driver will is independent of what 'autoconfig' reads from /etc/dtab. If you are lucky the system will ignore the controller's interrupts safely and merely report a device error, if you are not so lucky the system will crash. Since the vectors are programmable the drivers should not presume to know better than the contents of /etc/dtab. By simply assigning vectors from the base (in the case of ra.c the formula was 0154 plus 4 times the controller number) it was possible for the MSCP driver to run over the RL11 vector. Fix: The fix below updates 'autoconfig' with the capability to pass a vector to the device driver. If a symbol of the form "_xxxVec" is defined (where 'xxx' is "ra" or "tms" at present for the MSCP and TMSCP drivers respectively) 'autoconfig' will call that function as part of the attach process. Also updated are the MSCP (ra.c and rareg.h) and TMSCP (tmscp.c) drivers to define the new entry point. MSCP drives are capable of being used as boot/root devices therefore it is not an error for the vector to be assigned twice (once at root attach, from the kernel init_main.c, and once when 'autoconfig' runs). For other devices it is an error for the vector to be assigned to the same controller more than once. root/boot controllers always are assigned the first (primary) vector for the device (0154 for MSCP, 0260 for TMSCP). Additional controllers receive their interrupt vector from 'autoconfig' (who reads it from /etc/dtab). A second update (#84) will follow shortly. That patch will provide instructions for updating the kernel config files (/sys/conf/GENERIC for example) to remove the extraneous TMSCP_VEC statement. Stay tuned. To apply patches (they were all created with full pathnames) use the "-p0" option of the 'patch' program: patch -p0 < the_file_below =============================cut here================================ *** /sys/autoconfig/attach.c.old Fri Feb 27 02:13:00 1987 --- /sys/autoconfig/attach.c Thu Nov 19 21:37:24 1992 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)attach.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. * ! * @(#)attach.c 2.0 (2.11BSD GTE) 11/20/92 */ /* *************** *** 10,15 **** --- 10,22 ---- * Attach the passed device: * Patch the interrupt vector * Call the device attach routine + * + * Call (if present) the vector setting routine, passing the + * vector from /etc/dtab to the driver. At present only the + * MSCP and TMSCP drivers have routines to do this. The detach() + * routine was removed because it was superfluous. The kernel no + * longer calls every driver's XXroot() entry point at start up time, + * thus there is nothing to detach any more. */ #include *************** *** 68,73 **** --- 75,88 ---- addr += IVSIZE; } prdev(dp); + if (dp->dt_setvec && dp->dt_setvec->n_value) { + ret = ucall(PSL_BR0,dp->dt_setvec->n_value,unit,dp->dt_vector); + if (ret == -1) { + printf(" vectorset failed\n"); + exit(AC_SINGLE); + } + printf(" vectorset"); + } printf(" attached\n"); } *************** *** 151,171 **** else if (want_unit <= dn->d_unit) return(ERR); return(dn->d_unit = dp->dt_unit = want_unit); - } - - /* - * Call the device-attach routine with a 0 addr to indicate that the device - * isn't present (needed for devices that might be root devices and thus must - * have addr/vector initialized). Only done if the unit number was not a - * wildcard. - */ - detach(dp) - DTAB *dp; - { - if (dp->dt_unit == -1) - return; - if (debug) - printf("detach: ucall %o(PSL_BR0, %o, %o)\n",dp->dt_attach->n_value,0,dp->dt_unit); - else - ucall(PSL_BR0,dp->dt_attach->n_value,0,dp->dt_unit); } --- 166,169 ---- *** /sys/autoconfig/do_config.c.old Fri Feb 27 02:13:09 1987 --- /sys/autoconfig/do_config.c Thu Nov 19 21:42:04 1992 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)do_config.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. * ! * @(#)do_config.c 2.0 (2.11BSD GTE) 11/20/92 */ /* *************** *** 117,123 **** prdev(dp); puts(" skipped: No CSR."); } - detach(dp); continue; } /* Ok, try a probe now */ if (expect_intr(dp)) { --- 117,122 ---- *************** *** 125,131 **** prdev(dp); puts(" interrupt vector already in use."); } - detach(dp); continue; } ret = do_probe(dp, dp->dt_addr); --- 124,129 ---- *************** *** 136,142 **** prdev(dp); puts(" does not exist."); } - detach(dp); break; case ACP_IFINTR: switch (intval()) { --- 134,139 ---- *************** *** 145,151 **** prdev(dp); puts(" interrupt vector wrong."); } - detach(dp); break; case ACI_NOINTR: if (complain) { --- 142,147 ---- *************** *** 152,158 **** prdev(dp); puts(" didn't interrupt."); } - detach(dp); break; case ACI_GOODINTR: attach(dp); --- 148,153 ---- *** /sys/autoconfig/dtab.h.old Fri Feb 27 02:13:09 1987 --- /sys/autoconfig/dtab.h Thu Nov 19 21:45:55 1992 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)dtab.h 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. * ! * @(#)dtab.h 2.0 (2.11BSD GTE) 11/20/92 */ /* *************** *** 27,32 **** --- 27,33 ---- int dt_br; /* Priority */ int (*dt_uprobe)(); /* User-level (internal) probe */ NLIST *dt_probe, /* Address of probe function */ + *dt_setvec, /* Address of vector set function */ *dt_attach; /* Address of attach function */ } DTAB; *** /sys/autoconfig/read_nlist.c.old Fri Feb 27 02:13:09 1987 --- /sys/autoconfig/read_nlist.c Thu Nov 19 21:43:41 1992 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)read_nlist.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. * ! * @(#)read_nlist.c 2.0 (2.11BSD GTE) 11/20/92 */ /* *************** *** 59,64 **** --- 59,66 ---- dp->dt_probe = add_nlist(tname); sprintf(tname, "_%sattach", dp->dt_name); dp->dt_attach = add_nlist(tname); + sprintf(tname, "_%sVec", dp->dt_name); + dp->dt_setvec = add_nlist(tname); for (sp = dp->dt_handlers;sp;sp = sp->s_next) sp->s_nl = add_nlist(sp->s_str); } *** /sys/autoconfig/uprobe.c.old Sun Dec 22 16:00:36 1991 --- /sys/autoconfig/uprobe.c Thu Nov 19 21:44:58 1992 *************** *** 3,15 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)uprobe.c 1.2 (2.11BSD Berkeley) 12/22/91 */ /* * The uprobe table contains the pointers to the user-level probe routines ! * that usually attempt to make various devices interrupt. The actual ! * probe routines are in the device driver sources. * * NOTES: * Reads and writes to kmem (done by grab, stuff) are currently done a --- 3,14 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)uprobe.c 2.0 (2.11BSD GTE) 11/20/92 */ /* * The uprobe table contains the pointers to the user-level probe routines ! * that may attempt to make various devices interrupt. * * NOTES: * Reads and writes to kmem (done by grab, stuff) are currently done a *************** *** 30,36 **** UPROBE uprobe[] = { "hk", hkprobe, /* hk -- rk611, rk06/07 */ "hp", xpprobe, /* hp -- rjp04/06, rwp04/06 */ ! "ra", raprobe, /* ra -- rqdx? (rx50,rd51/52/53), uda50 (ra60/80/81), klesi (ra25) */ "rk", rkprobe, /* rk -- rk05 */ "rl", rlprobe, /* rl -- rl01/02 */ "si", siprobe, /* si -- SI 9500 for CDC 9766 */ --- 29,35 ---- UPROBE uprobe[] = { "hk", hkprobe, /* hk -- rk611, rk06/07 */ "hp", xpprobe, /* hp -- rjp04/06, rwp04/06 */ ! "ra", raprobe, /* ra -- MSCP "rk", rkprobe, /* rk -- rk05 */ "rl", rlprobe, /* rl -- rl01/02 */ "si", siprobe, /* si -- SI 9500 for CDC 9766 */ *** /sys/pdpuba/ra.c.old Thu Nov 12 22:12:50 1992 --- /sys/pdpuba/ra.c Fri Nov 20 23:20:09 1992 *************** *** 14,19 **** --- 14,24 ---- /* * ra.c - MSCP Driver + * Date: Nov 1992 + * Add raVec() routine. This is called by autoconfig to set the vector + * (from /etc/dtab) for controllers other than the root (1st). The boot/root + * controller's vector is always set to 0154. + * * Date: Jul 1992 * Major rework of the partition tables. Some old (RA60,80,81,RD53) tables * were retained (the rd54 'c' partition is now 'g' but the sizes stay *************** *** 284,290 **** #define PRINTB(x) #endif ! int raattach(), raintr(), wakeup(); extern ubadr_t _iomap(); struct mscp *ragetcp(); --- 289,295 ---- #define PRINTB(x) #endif ! int wakeup(); extern ubadr_t _iomap(); struct mscp *ragetcp(); *************** *** 306,314 **** --- 311,342 ---- if (!csr) /* XXX */ csr = (radeviceT *) 0172150; /* XXX */ raattach(csr, 0); + raVec(0, 0154); } /* + * Called from autoconfig and raroot() to set the vector for a controller. + * It is an error to attempt to set the vector more than once except for + * the first controller which may have had the vector set from raroot(). + * In this case the error is ignored and the vector left unchanged. + */ + + raVec(ctlr, vector) + register int ctlr; + int vector; + { + register ra_softcT *sc = &ra_sc[ctlr]; + + if (ctlr >= NRAC) + return(-1); + if (sc->sc_ivec == 0) + sc->sc_ivec = vector; + else if (ctlr) + return(-1); + return(0); + } + + /* * Attach controller for autoconfig system. */ raattach(addr, unit) *************** *** 457,463 **** /* * Cold init of controller */ - sc->sc_ivec = RA_VECTOR + sc->sc_unit * 04; ++sc->sc_ctab.b_active; PRINTD(("rainit: unit=%d, vec=%o\n", sc->sc_unit, sc->sc_ivec)); --- 485,490 ---- *************** *** 754,760 **** break; default: ! printf("raintr: state %d ignored\n", sc->sc_state); return; } --- 781,787 ---- break; default: ! printf("ra: state %d ignored\n", sc->sc_state); return; } *** /sys/pdpuba/rareg.h.old Fri Jan 9 01:58:03 1987 --- /sys/pdpuba/rareg.h Thu Nov 19 22:23:39 1992 *************** *** 25,29 **** #define RA_IE 0000200 #define RA_PI 0000001 #define RA_GO 0000001 - - #define RA_VECTOR 0154 --- 25,27 ---- *** /sys/pdpuba/tmscp.c.old Sun Sep 22 08:43:13 1991 --- /sys/pdpuba/tmscp.c Thu Nov 19 21:02:38 1992 *************** *** 31,37 **** * tmscp.c - TMSCP (TK50/TU81) tape device driver * * Modification History: ! * 23-May-91 - sms@wlv.imsd.contel.com [2.11BSD] * Minor typo in the multicontroller support fixed. Major overhaul * of the density selection, apparently some TMSCP controllers * do not treat 0 in the mscp_format word as meaning the highest --- 31,42 ---- * tmscp.c - TMSCP (TK50/TU81) tape device driver * * Modification History: ! * 20-Nov-92 - sms@wlv.iipo.gtegsc.com [2.11BSD] ! * Add tmsVec() for autoconfig to use in passing the vector from /etc/dtab ! * to this driver. The previous scheme of having a fixed vector with ! * all TMSCP vectors contiguous has been removed. ! * ! * 23-May-91 - sms@wlv.iipo.gtegsc.com [2.11BSD] * Minor typo in the multicontroller support fixed. Major overhaul * of the density selection, apparently some TMSCP controllers * do not treat 0 in the mscp_format word as meaning the highest *************** *** 38,44 **** * density, instead leaving the drive in the current/last-used * density. * ! * 29-Mar-91 - sms@wlv.imsd.contel.com [2.11BSD] * Major changes to 1) support multiple drives per controller * (the maximum number of drives per controller is 4 for now in order * to maximize compatibility with existing minor device numbers - the --- 43,49 ---- * density, instead leaving the drive in the current/last-used * density. * ! * 29-Mar-91 - sms@wlv.iipo.gtegsc.com [2.11BSD] * Major changes to 1) support multiple drives per controller * (the maximum number of drives per controller is 4 for now in order * to maximize compatibility with existing minor device numbers - the *************** *** 68,74 **** * device number are used to designate the controller, thus there is * a maximum of 4 TMSCP controllers per system. * ! * 17-Jun-90,14Aug90 - sms@wlv.imsd.contel.com * Began porting to 2.10.1BSD/2.11BSD. Multiple drives per controller * NOT supported, although multiple controllers are (maybe). Programmable * vectors don't work very well with the autoconfigure scheme in use. --- 73,79 ---- * device number are used to designate the controller, thus there is * a maximum of 4 TMSCP controllers per system. * ! * 17-Jun-90,14Aug90 - sms@wlv.iipo.gtegsc.com * Began porting to 2.10.1BSD/2.11BSD. Multiple drives per controller * NOT supported, although multiple controllers are (maybe). Programmable * vectors don't work very well with the autoconfigure scheme in use. *************** *** 190,197 **** #include "../pdp/tmscp.h" #include "../machine/seg.h" - short TMSvec = TMSCP_VEC; /* patchable base of vectors */ - /* * The density array is indexed by the density bits (bits 3 and 4) of the * minor device number AND the format menu returned for the drive. Since --- 195,200 ---- *************** *** 312,317 **** --- 315,331 ---- #define b_qsize b_resid /* queue size per drive, in tmsutab */ + tmsVec(ctlr, vector) + int ctlr, vector; + { + register struct tmscp_softc *sc = &tmscp_softc[ctlr]; + + if (ctlr >= NTMSCP || sc->sc_ivec) + return(-1); + sc->sc_ivec = vector; + return(0); + } + /* * Open routine will issue the online command, later. * *************** *** 899,905 **** register struct tmscpdevice *tmscpaddr; long adr; - sc->sc_ivec = TMSvec + sc->sc_unit * 4; sc->sc_ctab.b_active++; adr = _iomap(tmscp[sc->sc_unit]) + (u_int)RINGBASE; sc->sc_ctab.b_un.b_addr = (caddr_t)loint(adr); --- 913,918 ----