Subject: Part 11 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 11 of 22 The TMSCP (TK50/TU81) driver was modified to use an externally mapped communication packet arena. Also a number of changes were made to reduce the size of the driver. Other fixes dealing with onlining the unit were made. Space savings were achieved partially by altering the error messages. *** /usr/src/sys/pdpuba/tmscp.c.old Wed Dec 19 10:11:09 1990 --- /usr/src/sys/pdpuba/tmscp.c Fri May 10 20:42:24 1991 *************** *** 1,4 **** ! /* @(#)tmscp.c 7.1 (Berkeley) 6/5/86 */ #if !defined(lint) && defined(DOSCCS) static char *sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86"; --- 1,4 ---- ! /* @(#)tmscp.c 1.1 (2.11BSD) 5/10/91 */ #if !defined(lint) && defined(DOSCCS) static char *sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86"; *************** *** 32,40 **** * * Modification History: * * 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. Programmable * vectors don't work very well with the autoconfigure scheme in use. * the define TMSCP_VEC will have to be adjusted in tms.h (see * conf/config and the sample config files). For patching purposes --- 32,70 ---- * * Modification History: * + * 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 + * norewind and density bit stay in the same place) and 2) more + * importantly reduce the bloat of this driver. The command + * packet area is now allocated from an external heap setup at boot + * time (the MSCP, ra.c driver also does this). Allocating from an + * external arena save approximately 2kb of kernel D space PER CONTROLLER + * and costs little in speed because the amount of remapping involved is + * quite small. + * + * The 'errinfo' routine was removed in the interest of space savings, + * the error code was already being printed out in hex and it's not + * worth eating up another 250 or so bytes of kernel D space to pretty + * print messages for which tmscp.h provides the cross reference (I space + * is also saved by not printing the messages). Besides, the ra.c (MSCP) + * driver doesn't do it and it is worth a degree of non 4.3BSD verisimility + * to save a significant amount of space. + * + * The tms_type field should have been a 'long' (mediatype). Since the + * drives are not probed at autoconfigure time a GTUNT (TMS_SENSE) command + * is done at open() time to fetch the format/density menu and unit flags. + * iodone() proccessing was missing for the GTUNT function in tmscprsp() + * causing hangs in both open and ioctl functions. + * + * Multiple controller support made to work, the top 2 bits of the minor + * 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. * the define TMSCP_VEC will have to be adjusted in tms.h (see * conf/config and the sample config files). For patching purposes *************** *** 162,167 **** --- 192,198 ---- struct tmscpdevice *sc_addr; /* controller CSR address */ short sc_state; /* state of controller */ short sc_ivec; /* interrupt vector address */ + short sc_unit; /* CONTROLLER number - NOT drive unit # */ short sc_credits; /* transfer credits */ short sc_lastcmd; /* pointer into command ring */ short sc_lastrsp; /* pointer into response ring */ *************** *** 169,174 **** --- 200,206 ---- struct buf sc_ctab; /* controller queue */ struct buf sc_wtab; /* I/O wait queue for controller */ struct tmscp *sc_com; /* communications area pointer */ + struct tms_info *sc_drives[4]; /* pointers to per drive info */ } tmscp_softc[NTMSCP]; #define RINGBASE (4 * sizeof (short)) *************** *** 177,190 **** struct tmscpca tmscp_ca; /* communications area */ struct mscp tmscp_rsp[NRSP]; /* response packets */ struct mscp tmscp_cmd[NCMD]; /* command packets */ ! } tmscp[NTMSCP]; /* * Per drive-unit info */ struct tms_info { daddr_t tms_dsize; /* Max user size from online pkt */ ! unsigned tms_type; /* Drive type int field */ int tms_resid; /* residual from last xfer */ u_char tms_endcode; /* last command endcode */ u_char tms_flags; /* last command end flags */ --- 209,224 ---- struct tmscpca tmscp_ca; /* communications area */ struct mscp tmscp_rsp[NRSP]; /* response packets */ struct mscp tmscp_cmd[NCMD]; /* command packets */ ! }; /* 1896 bytes per controller! */ + memaddr tmscp[NTMSCP]; /* click addresses of ctrl comm area */ + /* * Per drive-unit info */ struct tms_info { daddr_t tms_dsize; /* Max user size from online pkt */ ! long tms_type; /* Drive type field */ int tms_resid; /* residual from last xfer */ u_char tms_endcode; /* last command endcode */ u_char tms_flags; /* last command end flags */ *************** *** 199,218 **** struct tty *tms_ttyp; /* record user's tty for errors */ struct buf tms_dtab; /* I/O tape drive queues */ struct buf tms_rtab; /* raw I/O tape block header */ ! short tms_online; /* online flag */ } tms_info[NTMS]; - struct buf tmscomphys; /* Communication area phys map */ - long tmsphys(); - - #ifndef KDSA0 - #define KDSA0 ((u_short *)0172360) - #endif /* Bits in minor device */ #define TMSUNIT(dev) (minor(dev)&03) #define T_NOREWIND 04 #define T_HIDENSITY 010 /* * Internal (ioctl) command codes (these must also be declared in the * tmscpioctl routine). These correspond to ioctls in mtio.h --- 233,250 ---- struct tty *tms_ttyp; /* record user's tty for errors */ struct buf tms_dtab; /* I/O tape drive queues */ struct buf tms_rtab; /* raw I/O tape block header */ ! short tms_online; /* 0=available, 1=online, -1=offline */ } tms_info[NTMS]; /* Bits in minor device */ #define TMSUNIT(dev) (minor(dev)&03) + #define TMSCTLR(dev) ((minor(dev) >> 6) & 3) #define T_NOREWIND 04 #define T_HIDENSITY 010 + /* Size to map in when mapping a controller's command packet area */ + #define MAPBUFDESC (((btoc(sizeof (struct tmscp)) - 1) << 8) | RW) + /* * Internal (ioctl) command codes (these must also be declared in the * tmscpioctl routine). These correspond to ioctls in mtio.h *************** *** 247,252 **** --- 279,285 ---- /* packets and or credits. */ int wakeup(); extern int hz; /* Should find the right include */ + extern long _iomap(); #ifdef TMSCP_DEBUG #define printd if (tmscpdebug) printf *************** *** 259,282 **** #define b_qsize b_resid /* queue size per drive, in tmsutab */ /* - * Set ui flags to zero to show device is not online & set tmscpip. - * Unit to Controller mapping is set up here. * Open routine will issue the online command, later. */ tmsattach(addr, unit) struct tmscpdevice *addr; register int unit; { ! register struct tmscp_softc *sc = &tmscp_softc[TMSUNIT(unit)]; if (sc->sc_addr == NULL && addr != NULL) { sc->sc_addr = addr; ! sc->sc_com = &tmscp[TMSUNIT(unit)]; return (1); } return(0); } /* * TMSCP interrupt routine. */ --- 292,338 ---- #define b_qsize b_resid /* queue size per drive, in tmsutab */ /* * Open routine will issue the online command, later. + * + * This routine attaches controllers, not drives - sc_unit and 'unit' are + * the controller number not a drive unit number. sc_com is initialized + * to SEG5 because all communication areas are mapped to the same virtual + * address now. */ tmsattach(addr, unit) struct tmscpdevice *addr; register int unit; { ! register struct tmscp_softc *sc = &tmscp_softc[unit]; + if (unit >= NTMSCP) + return(0); if (sc->sc_addr == NULL && addr != NULL) { + tmscp[unit] = (memaddr)_ioget(sizeof (struct tmscp)); + if (tmscp[unit] == NULL) + return(0); sc->sc_addr = addr; ! sc->sc_unit = unit; ! sc->sc_com = (struct tmscp *)SEG5; return (1); } return(0); } + struct tms_info * + getdd() + { + register int i; + register struct tms_info *p; + + for (i = NTMS, p = tms_info; i--; p++) { + if (p->tms_online == 0) + return(p); + } + log(TMS_PRI, "tms: no drive descriptors\n"); + return(NULL); + } + /* * TMSCP interrupt routine. */ *************** *** 283,295 **** tmsintr(dev) dev_t dev; { - int unit = TMSUNIT(dev); register struct tmscpdevice *tmscpaddr; struct buf *bp; register int i; ! register struct tmscp_softc *sc = &tmscp_softc[unit]; ! register struct tmscp *tm = &tmscp[unit]; struct mscp *mp; tmscpaddr = sc->sc_addr; #ifdef TMSCP_DEBUG --- 339,351 ---- tmsintr(dev) dev_t dev; { register struct tmscpdevice *tmscpaddr; struct buf *bp; register int i; ! register struct tmscp_softc *sc = &tmscp_softc[dev]; ! register struct tmscp *tm = sc->sc_com; struct mscp *mp; + segm seg5; tmscpaddr = sc->sc_addr; #ifdef TMSCP_DEBUG *************** *** 302,308 **** switch (sc->sc_state) { case S_IDLE: ! printf("tms%d: random interrupt ignored\n", unit); return; /* Controller was in step 1 last, see if its gone to step 2 */ --- 358,364 ---- switch (sc->sc_state) { case S_IDLE: ! printf("tms%d: random interrupt ignored\n", dev); return; /* Controller was in step 1 last, see if its gone to step 2 */ *************** *** 402,407 **** --- 458,465 ---- /* * Initialize the data structures (response and command queues). */ + saveseg5(seg5); + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, sc->sc_com->tmscp_rsp, 0, NRSP, TMSCP_OWN|TMSCP_INT); tmsginit(sc, sc->sc_com->tmscp_ca.ca_cmddsc, sc->sc_com->tmscp_cmd, *************** *** 425,430 **** --- 483,489 ---- mp->mscp_opcode = M_OP_STCON; ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT; i = tmscpaddr->tmscpip; /* initiate polling */ + restorseg5(seg5); return; case S_SCHAR: *************** *** 432,438 **** break; default: ! printf("tms%d: interrupt in unknown state %d ignored\n",unit,sc->sc_state); return; } /* end switch */ --- 491,497 ---- break; default: ! printf("tms%d: interrupt in unknown state %d ignored\n",dev,sc->sc_state); return; } /* end switch */ *************** *** 446,452 **** */ if (tmscpaddr->tmscpsa&TMSCP_ERR) { ! printf("tms%d: fatal error (%o)\n", unit, tmscpaddr->tmscpsa); tmscpaddr->tmscpip = 0; sc->sc_state = S_IDLE; sc->sc_ctab.b_active = 0; --- 505,511 ---- */ if (tmscpaddr->tmscpsa&TMSCP_ERR) { ! printf("tms%d: fatal error %o\n", dev, tmscpaddr->tmscpsa); tmscpaddr->tmscpip = 0; sc->sc_state = S_IDLE; sc->sc_ctab.b_active = 0; *************** *** 455,460 **** --- 514,521 ---- /* * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus) */ + saveseg5(seg5); + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); if (tm->tmscp_ca.ca_bdp) { tm->tmscp_ca.ca_bdp = 0; *************** *** 472,478 **** i %= NRSP; if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) break; ! tmscprsp(unit, tm, sc, i); tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; } sc->sc_lastrsp = i; --- 533,539 ---- i %= NRSP; if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) break; ! tmscprsp(sc, i); tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; } sc->sc_lastrsp = i; *************** *** 488,494 **** #endif tm->tmscp_ca.ca_cmdint = 0; } ! if(tmscp_cp_wait) wakeup((caddr_t)&tmscp_cp_wait); (void) tmsstart(sc); } --- 549,556 ---- #endif tm->tmscp_ca.ca_cmdint = 0; } ! restorseg5(seg5); ! if (tmscp_cp_wait) wakeup((caddr_t)&tmscp_cp_wait); (void) tmsstart(sc); } *************** *** 504,510 **** dev_t dev; int flag; { ! register int unit; register struct tmscp_softc *sc; register struct tms_info *tms; register struct mscp *mp; --- 566,573 ---- dev_t dev; int flag; { ! register int unit = TMSUNIT(dev); ! int ctlr = TMSCTLR(dev); register struct tmscp_softc *sc; register struct tms_info *tms; register struct mscp *mp; *************** *** 511,529 **** struct tmscpdevice *tmscpaddr; int s,i; - unit = TMSUNIT(dev); #ifdef TMSCP_DEBUG ! printd("tmscpopen unit %d\n",unit); ! if(tmscpdebug)delay(10000L); #endif ! if (unit >= NTMS) return (ENXIO); - tms = &tms_info[unit]; - if (tms->tms_openf) - return (EBUSY); sc = &tmscp_softc[unit]; if (sc->sc_addr == NULL) return (ENXIO); tms->tms_openf = 1; tms->tms_ttyp = u.u_ttyp; s = spl5(); --- 574,597 ---- struct tmscpdevice *tmscpaddr; int s,i; #ifdef TMSCP_DEBUG ! printd("tmscpopen %d,%d\n", ctlr, unit); ! if (tmscpdebug) delay(10000L); #endif ! if (ctlr >= NTMSCP) return (ENXIO); sc = &tmscp_softc[unit]; if (sc->sc_addr == NULL) return (ENXIO); + if ((tms = sc->sc_drives[unit]) == NULL) { + tms = getdd(); + if (!tms) + return(ENXIO); + tms->tms_online = -1; + sc->sc_drives[unit] = tms; + } + if (tms->tms_openf) + return(EBUSY); tms->tms_openf = 1; tms->tms_ttyp = u.u_ttyp; s = spl5(); *************** *** 532,538 **** if (sc->sc_state == S_IDLE) if(!tkini(sc)) { ! printf("tms ctrl failed to init\n"); (void) splx(s); return(ENXIO); } --- 600,606 ---- if (sc->sc_state == S_IDLE) if(!tkini(sc)) { ! printf("tms%d failed to init\n", ctlr); (void) splx(s); return(ENXIO); } *************** *** 543,550 **** sleep((caddr_t)&sc->sc_ctab, PSWP+1); if (sc->sc_state != S_RUN) { (void) splx(s); - tms->tms_openf = 0; return (EIO); } } --- 611,619 ---- sleep((caddr_t)&sc->sc_ctab, PSWP+1); if (sc->sc_state != S_RUN) { + sc->sc_drives[unit] = NULL; + tms->tms_online = tms->tms_openf = 0; (void) splx(s); return (EIO); } } *************** *** 554,563 **** */ tmscpaddr = (struct tmscpdevice *) sc->sc_addr; (void) splx(s); ! if(tms->tms_online == 0) { s = spl5(); ! while((mp = tmscpgetcp(sc)) == 0) { tmscp_cp_wait++; sleep((caddr_t)&tmscp_cp_wait,PSWP+1); --- 623,632 ---- */ tmscpaddr = (struct tmscpdevice *) sc->sc_addr; (void) splx(s); ! if(tms->tms_online == -1) { s = spl5(); ! while ((mp = tmscpgetcp(sc)) == 0) { tmscp_cp_wait++; sleep((caddr_t)&tmscp_cp_wait,PSWP+1); *************** *** 564,577 **** tmscp_cp_wait--; } (void) splx(s); mp->mscp_opcode = M_OP_ONLIN; ! mp->mscp_unit = 0; /* unit? */ mp->mscp_cmdref = (u_short)&tms->tms_type; /* need to sleep on something */ #ifdef TMSCP_DEBUG ! printd("tmscpopen: bring unit %d online\n",unit); #endif ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN | TMSCP_INT; i = tmscpaddr->tmscpip; /* * To make sure we wake up, timeout in 240 seconds. --- 633,648 ---- tmscp_cp_wait--; } (void) splx(s); + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); mp->mscp_opcode = M_OP_ONLIN; ! mp->mscp_unit = unit; /* unit? */ mp->mscp_cmdref = (u_short)&tms->tms_type; /* need to sleep on something */ #ifdef TMSCP_DEBUG ! printd("tmscpopen: bring unit %d,%d online\n",ctlr, unit); #endif ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN | TMSCP_INT; + normalseg5(); i = tmscpaddr->tmscpip; /* * To make sure we wake up, timeout in 240 seconds. *************** *** 579,591 **** * 240 seconds (4 minutes) is necessary since a rewind * can take a few minutes. */ ! timeout(wakeup,(caddr_t) mp->mscp_cmdref,240 * hz); ! sleep((caddr_t) mp->mscp_cmdref,PSWP+1); } ! if(tms->tms_online == 0) { ! tms->tms_openf = 0; return(ENXIO); /* Didn't go online */ ! } tms->tms_lastiow = 0; /* * If the high density device is not specified, set unit to low --- 650,675 ---- * 240 seconds (4 minutes) is necessary since a rewind * can take a few minutes. */ ! timeout(wakeup,(caddr_t) &tms->tms_type,240 * hz); ! sleep((caddr_t) &tms->tms_type,PSWP+1); } ! if (tms->tms_online == -1) ! { ! oops: tms->tms_online = tms->tms_openf = 0; ! sc->sc_drives[unit] = NULL; return(ENXIO); /* Didn't go online */ ! } ! /* ! * Get the unit characteristics (GTUNT). Done here because we ! * do not check for slave units at autoconfigure time. This really ! * only need be done once, but it's easier to do it on each open. ! * tmscpcommand() is used since the iodone() handling for GTUNT has ! * been fixed. ! */ ! tms->tms_type = 0; ! tmscpcommand(dev, TMS_SENSE, 1); ! if (tms->tms_type == 0) ! goto oops; tms->tms_lastiow = 0; /* * If the high density device is not specified, set unit to low *************** *** 619,632 **** register dev_t dev; register flag; { register struct tms_info *tms; int unit = TMSUNIT(dev); #ifdef TMSCP_DEBUG ! printd("tmscpclose: unit = %d\n", unit); if(tmscpdebug)delay(10000L); #endif ! tms = &tms_info[unit]; if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow) { /* device, command, count */ --- 703,718 ---- register dev_t dev; register flag; { + struct tmscp_softc *sc; register struct tms_info *tms; int unit = TMSUNIT(dev); #ifdef TMSCP_DEBUG ! printd("tmscpclose: %d,%d\n", TMSCTLR(dev), unit); if(tmscpdebug)delay(10000L); #endif ! sc = &tmscp_softc[TMSCTLR(dev)]; ! tms = sc->sc_drives[unit]; if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow) { /* device, command, count */ *************** *** 668,674 **** register int s; int unit = TMSUNIT(dev); ! bp = &tmscp_softc[unit].sc_cmdbuf; s = spl5(); while (bp->b_flags&B_BUSY) --- 754,760 ---- register int s; int unit = TMSUNIT(dev); ! bp = &tmscp_softc[TMSCTLR(dev)].sc_cmdbuf; s = spl5(); while (bp->b_flags&B_BUSY) *************** *** 723,731 **** /* * Figure out virtual address of message * skip comm area and mscp messages header and previous messages */ ! vaddr = (u_int)tmscomphys.b_un.b_addr | ((long)tmscomphys.b_xmem << 16); ! vaddr += (u_int)sc->sc_com - (u_int)tmscp; /* unit offset */ vaddr += sizeof(struct tmscpca) /* skip comm area */ +sizeof(struct mscp_header); /* m_cmdref disp */ vaddr += offset * sizeof(struct mscp); /* skip previous */ --- 809,819 ---- /* * Figure out virtual address of message * skip comm area and mscp messages header and previous messages + * + * N.B. Assumes SEG5 has been remapped to the comm area for this + * controller. */ ! vaddr = _iomap(tmscp[sc->sc_unit]); vaddr += sizeof(struct tmscpca) /* skip comm area */ +sizeof(struct mscp_header); /* m_cmdref disp */ vaddr += offset * sizeof(struct mscp); /* skip previous */ *************** *** 746,757 **** tmscpgetcp(sc) register struct tmscp_softc *sc; { ! register struct mscp *mp; struct tmscpca *cp; register int i; int s; s = spl5(); cp = &sc->sc_com->tmscp_ca; /* * If no credits, can't issue any commands --- 834,848 ---- tmscpgetcp(sc) register struct tmscp_softc *sc; { ! register struct mscp *mp = NULL; struct tmscpca *cp; register int i; int s; + segm seg5; s = spl5(); + saveseg5(seg5); + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); cp = &sc->sc_com->tmscp_ca; /* * If no credits, can't issue any commands *************** *** 773,786 **** mp->mscp_buffer_h = mp->mscp_buffer_l = 0; mp->mscp_zzz2 = 0; sc->sc_lastcmd = (i + 1) % NCMD; - (void) splx(s); - return(mp); } (void) splx(s); ! return(NULL); } - /* * Initialize a TMSCP device. Set up UBA mapping registers, * initialize data structures, and start hardware --- 864,875 ---- mp->mscp_buffer_h = mp->mscp_buffer_l = 0; mp->mscp_zzz2 = 0; sc->sc_lastcmd = (i + 1) % NCMD; } + restorseg5(seg5); (void) splx(s); ! return(mp); } /* * Initialize a TMSCP device. Set up UBA mapping registers, * initialize data structures, and start hardware *************** *** 790,822 **** register struct tmscp_softc *sc; { register struct tmscpdevice *tmscpaddr; ! register int unit = sc - tmscp_softc; ! long comaddr, rap; ! sc->sc_ivec = TMSvec + unit * 4; sc->sc_ctab.b_active++; tmscpaddr = sc->sc_addr; - if (tmscomphys.b_flags == 0) - { - /* - * Map or calculate the addresses (Qbus) of communications area - * and response packets - */ - rap = tmsphys((u_int)tmscp); - tmscomphys.b_un.b_addr = (caddr_t)loint(rap); - tmscomphys.b_xmem = hiint(rap); - tmscomphys.b_bcount = sizeof (tmscp); - tmscomphys.b_flags = B_PHYS; - #ifdef UNIBUS_MAP - mapalloc(&tmscomphys); - #endif - comaddr = ((u_int)tmscomphys.b_un.b_addr | - ((long)tmscomphys.b_xmem << 16)) + - sizeof (struct tmscp) * unit + - (u_int)RINGBASE; - sc->sc_ctab.b_un.b_addr = (caddr_t)loint(comaddr); - sc->sc_ctab.b_xmem = hiint(comaddr); - } /* * Start the hardware initialization sequence. --- 879,892 ---- register struct tmscp_softc *sc; { 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); + sc->sc_ctab.b_xmem = hiint(adr); tmscpaddr = sc->sc_addr; /* * Start the hardware initialization sequence. *************** *** 841,847 **** return(1); } - /* * Start I/O operation * This code is convoluted. The majority of it was copied from the uda driver. --- 911,916 ---- *************** *** 850,864 **** tmsstart(sc) register struct tmscp_softc *sc; { - register struct buf *bp, *dp; register struct mscp *mp; register struct tms_info *tms; struct tmscpdevice *tmscpaddr; ! struct tmscp *tm; ! int i, unit = sc - tmscp_softc; ! char ioctl; /* flag: set true if its an IOCTL command */ ! tm = &tmscp[unit]; for(;;) { if ((dp = sc->sc_ctab.b_actf) == NULL) --- 919,932 ---- tmsstart(sc) register struct tmscp_softc *sc; { register struct mscp *mp; + register struct buf *bp, *dp; register struct tms_info *tms; struct tmscpdevice *tmscpaddr; ! int i; ! segm seg5; ! saveseg5(seg5); /* save just once at top */ for(;;) { if ((dp = sc->sc_ctab.b_actf) == NULL) *************** *** 883,896 **** } sc->sc_ctab.b_active++; tmscpaddr = (struct tmscpdevice *)sc->sc_addr; ! tms = &tms_info[TMSUNIT(bp->b_dev)]; if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN) { tprintf(tms->tms_ttyp, ! "tms%d: hard error bn%ld\n", ! minor(bp->b_dev)&03, bp->b_blkno); ! log(TMS_PRI, "tms%d: sa 0%o, state %d\n", unit, ! tmscpaddr->tmscpsa&0xffff, sc->sc_state); (void)tkini(sc); /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */ break; --- 951,964 ---- } sc->sc_ctab.b_active++; tmscpaddr = (struct tmscpdevice *)sc->sc_addr; ! tms = sc->sc_drives[TMSUNIT(bp->b_dev)]; if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN) { tprintf(tms->tms_ttyp, ! "tms%d,%d: hard error bn%ld\n", sc->sc_unit, ! TMSUNIT(bp->b_dev), bp->b_blkno); ! log(TMS_PRI, "tms%d,%d: sa 0%o, state %d\n", sc->sc_unit, ! TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa, sc->sc_state); (void)tkini(sc); /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */ break; *************** *** 900,938 **** * if a write command is done it will be detected in tmscprsp. */ tms->tms_lastiow = 0; ! if (tms->tms_online == 0) { /* not online */ if ((mp = tmscpgetcp(sc)) == NULL) break; mp->mscp_opcode = M_OP_ONLIN; ! mp->mscp_unit = 0; /* ui->ui_slave; */ dp->b_active = 2; sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */ ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT; if (tmscpaddr->tmscpsa&TMSCP_ERR) ! printf("tms%d fatal error (0%o)\n", unit, ! tmscpaddr->tmscpsa); i = tmscpaddr->tmscpip; continue; } - /* - * If command is an ioctl command then set the ioctl flag for later use. - * If not (i.e. it is a read or write) then attempt - * to set up a buffer pointer. - */ - ioctl = 0; - if (bp == &sc->sc_cmdbuf) - ioctl = 1; if ((mp = tmscpgetcp(sc)) == NULL) break; mp->mscp_cmdref = (u_short)bp; /* pointer to get back */ ! mp->mscp_unit = 0; /* ui->ui_slave; */ /* * If its an ioctl-type command then set up the appropriate * tmscp command; by doing a switch on the "b_resid" field where * the command mneumonic is stored. */ ! if (ioctl) { #ifdef TMSCP_DEBUG printd("tmsstart: doing ioctl cmd %d\n", bp->b_resid); --- 968,1001 ---- * if a write command is done it will be detected in tmscprsp. */ tms->tms_lastiow = 0; ! if (tms->tms_online == -1) { /* not online */ if ((mp = tmscpgetcp(sc)) == NULL) break; + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); mp->mscp_opcode = M_OP_ONLIN; ! mp->mscp_unit = TMSUNIT(bp->b_dev); dp->b_active = 2; sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */ ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT; if (tmscpaddr->tmscpsa&TMSCP_ERR) ! printf("tms%d,%d fatal error 0%o\n", sc->sc_unit, ! TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa); ! restorseg5(seg5); i = tmscpaddr->tmscpip; continue; } if ((mp = tmscpgetcp(sc)) == NULL) break; + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); mp->mscp_cmdref = (u_short)bp; /* pointer to get back */ ! mp->mscp_unit = TMSUNIT(bp->b_dev); /* * If its an ioctl-type command then set up the appropriate * tmscp command; by doing a switch on the "b_resid" field where * the command mneumonic is stored. */ ! if (bp == &sc->sc_cmdbuf) { #ifdef TMSCP_DEBUG printd("tmsstart: doing ioctl cmd %d\n", bp->b_resid); *************** *** 1036,1042 **** tms->tms_format = 0; break; default: ! printf("Bad ioctl on tms%d\n", unit); /* Need a no-op. Reposition no amount */ mp->mscp_opcode = M_OP_REPOS; break; --- 1099,1106 ---- tms->tms_format = 0; break; default: ! printf("Bad ioctl on tms%d,%d\n", sc->sc_unit, ! TMSUNIT(bp->b_dev)); /* Need a no-op. Reposition no amount */ mp->mscp_opcode = M_OP_REPOS; break; *************** *** 1082,1088 **** dp->av_back = bp; if (tmscpaddr->tmscpsa&TMSCP_ERR) { ! printf("tms%d: fatal error (0%o)\n",unit, tmscpaddr->tmscpsa); (void)tkini(sc); break; } --- 1146,1153 ---- dp->av_back = bp; if (tmscpaddr->tmscpsa&TMSCP_ERR) { ! printf("tms%d,%d: fatal error 0%o\n",sc->sc_unit, ! TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa); (void)tkini(sc); break; } *************** *** 1089,1114 **** } /* end for */ /* * Check for response ring transitions lost in the ! * Race condition */ for (i = sc->sc_lastrsp;; i++) { i %= NRSP; ! if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) break; ! tmscprsp(unit, tm, sc, i); ! tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; } sc->sc_lastrsp = i; } /* ! * Process a response packet */ ! tmscprsp(unit, tm, sc, i) ! int unit; ! register struct tmscp *tm; register struct tmscp_softc *sc; int i; { --- 1154,1179 ---- } /* end for */ /* * Check for response ring transitions lost in the ! * Race condition. Map SEG5 in case we escaped early from the for(). */ + mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); for (i = sc->sc_lastrsp;; i++) { i %= NRSP; ! if (sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) break; ! tmscprsp(sc, i); ! sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; } sc->sc_lastrsp = i; + restorseg5(seg5); } /* ! * Process a response packet. N.B. Assumes SEG5 maps comm area for controller */ ! tmscprsp(sc, i) register struct tmscp_softc *sc; int i; { *************** *** 1117,1123 **** struct buf *dp, *bp; int st; ! mp = &tm->tmscp_rsp[i]; mp->mscp_header.tmscp_msglen = mscp_msglen; sc->sc_credits += mp->mscp_header.tmscp_credits & 0xf; /* low 4 bits */ if ((mp->mscp_header.tmscp_credits & 0xf0) > 0x10) /* Check */ --- 1182,1188 ---- struct buf *dp, *bp; int st; ! mp = &sc->sc_com->tmscp_rsp[i]; mp->mscp_header.tmscp_msglen = mscp_msglen; sc->sc_credits += mp->mscp_header.tmscp_credits & 0xf; /* low 4 bits */ if ((mp->mscp_header.tmscp_credits & 0xf0) > 0x10) /* Check */ *************** *** 1124,1129 **** --- 1189,1195 ---- return; #ifdef TMSCP_DEBUG printd("tmscprsp, opcode 0%o status 0%o\n",mp->mscp_opcode,mp->mscp_status&M_ST_MASK); + printd(" SEG5: 0%o sc: 0%o mp: 0%o i: %d\n",*KDSA5, sc, mp, i); #endif /* * If it's an error log message (datagram), *************** *** 1131,1137 **** */ if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10) { /* check */ ! tmserror(unit, (struct mslg *)mp); return; } st = mp->mscp_status&M_ST_MASK; --- 1197,1203 ---- */ if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10) { /* check */ ! tmserror(sc->sc_unit, (struct mslg *)mp); return; } st = mp->mscp_status&M_ST_MASK; *************** *** 1156,1164 **** wakeup((caddr_t)&sc->sc_ctab); return; } ! if (mp->mscp_unit >= NTMS) return; ! tms = &tms_info[unit]; /* * Save endcode, endflags, and status for mtioctl get unit status. * NOTE: Don't do this on Clear serious exception (reposition no-op); --- 1222,1232 ---- wakeup((caddr_t)&sc->sc_ctab); return; } ! if (mp->mscp_unit >= 4) return; ! tms = sc->sc_drives[mp->mscp_unit]; ! if (!tms) /* unopened unit coming online - ignore it */ ! return; /* * Save endcode, endflags, and status for mtioctl get unit status. * NOTE: Don't do this on Clear serious exception (reposition no-op); *************** *** 1190,1207 **** sc->sc_ctab.b_actl = dp; tms->tms_online = 1; /* mark it online */ tms->tms_dsize=(daddr_t)mp->mscp_maxwrt; - #ifdef TMSCP_DEBUG - printd("tmscprsp: unit %d online\n", mp->mscp_unit); - #endif /* * This define decodes the Media type identifier */ - # define F_to_C(x,i) ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ') #ifdef TMSCP_DEBUG ! printd("tmscprsp: unit %d online %x %c%c %c%c%c%d\n" ! ,mp->mscp_unit, mp->mscp_mediaid ,F_to_C(mp,4) ! ,F_to_C(mp,3), F_to_C(mp,2) ! ,F_to_C(mp,1), F_to_C(mp,0), mp->mscp_mediaid & 0x7f); #endif dp->b_active = 1; } /* end if st == M_ST_SUCC */ --- 1258,1270 ---- sc->sc_ctab.b_actl = dp; tms->tms_online = 1; /* mark it online */ tms->tms_dsize=(daddr_t)mp->mscp_maxwrt; /* * This define decodes the Media type identifier */ #ifdef TMSCP_DEBUG ! printd("tmscprsp: %d,%d online mediaid 0x%lx format 0x%x\n", ! sc->sc_unit, mp->mscp_unit, mp->mscp_mediaid, ! mp->mscp_format); #endif dp->b_active = 1; } /* end if st == M_ST_SUCC */ *************** *** 1209,1219 **** { if (bp = dp->b_actf) tprintf(tms->tms_ttyp, ! "tms%d: hard error bn%ld: OFFLINE\n", ! minor(bp->b_dev)&03, bp->b_blkno); else tprintf(tms->tms_ttyp, ! "tms%d: hard error: OFFLINE\n", unit); while (bp = dp->b_actf) { dp->b_actf = bp->av_forw; --- 1272,1283 ---- { if (bp = dp->b_actf) tprintf(tms->tms_ttyp, ! "tms%d,%d: hard error bn%ld: OFFLINE\n", ! sc->sc_unit, mp->mscp_unit, bp->b_blkno); else tprintf(tms->tms_ttyp, ! "tms%d,%d: hard error: OFFLINE\n", ! sc->sc_unit, mp->mscp_unit); while (bp = dp->b_actf) { dp->b_actf = bp->av_forw; *************** *** 1228,1238 **** /* * The AVAILABLE ATTENTION message occurs when the * unit becomes available after loading, ! * marking the unit offline (ui_flags = 0) will force an * online command prior to using the unit. */ case M_OP_AVATN: ! tms->tms_online = 0; tms->tms_type = mp->mscp_mediaid; break; case M_OP_END: --- 1292,1302 ---- /* * The AVAILABLE ATTENTION message occurs when the * unit becomes available after loading, ! * marking the unit offline (tms_online = -1) will force an * online command prior to using the unit. */ case M_OP_AVATN: ! tms->tms_online = -1; tms->tms_type = mp->mscp_mediaid; break; case M_OP_END: *************** *** 1246,1253 **** * of 0200 instead of the 0241 (read) that was expected. */ ! printf("tms%d: invalid cmd, endcode = %o, status=%o\n", ! unit, mp->mscp_opcode, st); bp = (struct buf *)mp->mscp_cmdref; /* * Unlink buffer from I/O wait queue. --- 1310,1318 ---- * of 0200 instead of the 0241 (read) that was expected. */ ! printf("tms%d,%d: invalid cmd, endcode = %o, status=%o\n", ! sc->sc_unit, mp->mscp_unit, mp->mscp_opcode, st); ! common: /* GTUNT finishes up thru here too */ bp = (struct buf *)mp->mscp_cmdref; /* * Unlink buffer from I/O wait queue. *************** *** 1272,1279 **** * issued. For the ioctl, "rewoffl", a tmscp AVAILABLE command is * done with the UNLOAD modifier. This performs a rewind, followed * by marking the unit offline. So mark the unit offline ! * software wise as well (ui_flags = 0 and ! * tms->tms_openf = 0). */ case M_OP_AVAIL|M_OP_END: #ifdef TMSCP_DEBUG --- 1337,1343 ---- * issued. For the ioctl, "rewoffl", a tmscp AVAILABLE command is * done with the UNLOAD modifier. This performs a rewind, followed * by marking the unit offline. So mark the unit offline ! * software wise as well (tms->tms_online = -1 and tms_open = 0). */ case M_OP_AVAIL|M_OP_END: #ifdef TMSCP_DEBUG *************** *** 1289,1295 **** dp->b_qsize--; if (st == M_ST_OFFLN || st == M_ST_AVLBL) { ! tms->tms_online = 0; /* mark unit offline */ tms->tms_openf = 0; tms->tms_type = mp->mscp_mediaid; /* --- 1353,1359 ---- dp->b_qsize--; if (st == M_ST_OFFLN || st == M_ST_AVLBL) { ! tms->tms_online = -1; /* mark unit offline */ tms->tms_openf = 0; tms->tms_type = mp->mscp_mediaid; /* *************** *** 1320,1329 **** if (st != M_ST_TAPEM) { tprintf(tms->tms_ttyp, ! "tms%d: hard error bn%ld\n",minor(bp->b_dev)&03, bp->b_blkno); ! tprintf(tms->tms_ttyp, "status:0%o flags:0%o\n", ! (mp->mscp_status & 177740)>>5, mp->mscp_flags); ! errinfo(st); /* produces more info */ bp->b_flags |= B_ERROR; } else --- 1384,1392 ---- if (st != M_ST_TAPEM) { tprintf(tms->tms_ttyp, ! "tms%d,%d: hard error bn%ld status:0%o flags:0%o\n", ! sc->sc_unit, mp->mscp_unit, bp->b_blkno, ! mp->mscp_status >> 5, mp->mscp_flags); bp->b_flags |= B_ERROR; } else *************** *** 1349,1450 **** case M_OP_GTUNT|M_OP_END: #ifdef TMSCP_DEBUG printd("tmscprsp: GTUNT end packet status = 0%o\n",st); ! printd("tmscprsp: unit %d mediaid %x %c%c %c%c%c%d %x %x t=%d\n" ! ,mp->mscp_unit, mp->mscp_mediaid ! ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2) ! ,F_to_C(mp,1),F_to_C(mp,0) ! ,mp->mscp_mediaid & 0x7f ,mp->mscp_unitid.val[0] ,mp->mscp_unitid.val[1] ,mp->mscp_format); ! #endif tms->tms_type = mp->mscp_mediaid; tms->tms_fmtmenu = mp->mscp_fmtmenu; tms->tms_unitflgs = mp->mscp_unitflgs; ! break; default: ! printf("tms unknown packet\n"); ! tmserror(unit, (struct mslg *)mp); } /* end switch mp->mscp_opcode */ } - - /* - * Give a meaningful error when the mscp_status field returns an error code. - */ - - errinfo(st) - int st; /* the status code */ - { - switch(st) { - case M_ST_ICMD: - printf("invalid command\n"); - break; - case M_ST_ABRTD: - printf("command aborted\n"); - break; - case M_ST_OFFLN: - printf("unit offline\n"); - break; - case M_ST_WRTPR: - printf("unit write protected\n"); - break; - case M_ST_COMP: - printf("compare error\n"); - break; - case M_ST_DATA: - printf("data error\n"); - break; - case M_ST_HSTBF: - printf("host buffer access error\n"); - break; - case M_ST_CNTLR: - printf("controller error\n"); - break; - case M_ST_DRIVE: - printf("drive error\n"); - break; - case M_ST_FMTER: - printf("formatter error\n"); - break; - case M_ST_BOT: - printf("BOT encountered\n"); - break; - case M_ST_TAPEM: - printf("tape mark encountered\n"); - break; - case M_ST_RDTRN: - printf("record data truncated\n"); - break; - case M_ST_PLOST: - printf("position lost\n"); - break; - case M_ST_SEX: - printf("serious exception\n"); - break; - case M_ST_LED: - printf("LEOT detected\n"); - break; - } - } - /* - * Return the physical address corresponding to a virtual data space address. - * On a separate I&D CPU this is a noop, but it's only called when the first - * controller is initialized and on a dump. - */ - long - tmsphys(vaddr) - register unsigned vaddr; - { - register unsigned click; - - click = (sep_id ? KDSA0 : KISA0)[(vaddr >> 13) & 07]; - return(((long)click << 6) + (vaddr & 017777)); - } - - /* * Manage buffers and perform block mode read and write operations. */ --- 1412,1435 ---- case M_OP_GTUNT|M_OP_END: #ifdef TMSCP_DEBUG printd("tmscprsp: GTUNT end packet status = 0%o\n",st); ! printd("tmscprsp: %d,%d mediaid 0x%lx %x %x format=%d\n", ! sc->sc_unit,mp->mscp_unit, mp->mscp_mediaid ,mp->mscp_unitid.val[0] ,mp->mscp_unitid.val[1] ,mp->mscp_format); ! #endif tms->tms_type = mp->mscp_mediaid; tms->tms_fmtmenu = mp->mscp_fmtmenu; tms->tms_unitflgs = mp->mscp_unitflgs; ! goto common; /* need to dequeue buffer and do iodone() */ default: ! printf("tms %d,%d unknown packet\n", sc->sc_unit,mp->mscp_unit); ! tmserror(sc->sc_unit, (struct mslg *)mp); } /* end switch mp->mscp_opcode */ } /* * Manage buffers and perform block mode read and write operations. */ *************** *** 1454,1479 **** register struct buf *dp; register struct tmscp_softc *sc; struct tms_info *tms; ! int unit = TMSUNIT(bp->b_dev); int s; ! if (unit >= NTMS) { - #ifdef TMSCP_DEBUG - printd ("tmscpstrategy: bad unit # %d\n",unit); - #endif bp->b_flags |= B_ERROR; iodone(bp); return; } - sc = &tmscp_softc[unit]; - tms = &tms_info[unit]; - if (tms->tms_online == 0) - { - bp->b_flags |= B_ERROR; - iodone(bp); - return; - } #ifdef UNIBUS_MAP mapalloc(bp); #endif --- 1439,1455 ---- register struct buf *dp; register struct tmscp_softc *sc; struct tms_info *tms; ! int ctlr = TMSCTLR(bp->b_dev); int s; ! sc = &tmscp_softc[ctlr]; ! tms = sc->sc_drives[TMSUNIT(bp->b_dev)]; ! if (!tms || tms->tms_online != 1) { bp->b_flags |= B_ERROR; iodone(bp); return; } #ifdef UNIBUS_MAP mapalloc(bp); #endif *************** *** 1526,1555 **** register struct mscp *mp; daddr_t bn, dumpsize; long paddr, maddr; ! int unit, count; struct ubmap *ubp; ! unit = TMSUNIT(dev); ! if (unit >= NTMS) return (ENXIO); ! sc = &tmscp_softc[unit]; tmscpaddr = sc->sc_addr; if (tmscpaddr == NULL) return(ENXIO); #ifdef UNIBUS_MAP if (ubmap) { ubp = UBMAP; ! ubp->ub_lo = loint(tmscomphys.b_un.b_addr); ! ubp->ub_hi = hiint(tmscomphys.b_xmem); ! tmscomphys.b_un.b_addr = NULL; ! tmscomphys.b_xmem = 0; } #endif ! paddr = (u_int)tmscomphys.b_un.b_addr + ! ((long)tmscomphys.b_xmem << 16) + ! (u_int)RINGBASE; ! sc->sc_com = tmscp; mp = sc->sc_com->tmscp_rsp; sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0; bzero(mp, 2 * sizeof (*mp)); --- 1502,1529 ---- register struct mscp *mp; daddr_t bn, dumpsize; long paddr, maddr; ! int unit = TMSUNIT(dev), count, ctlr = TMSCTLR(dev); struct ubmap *ubp; + segm seg5; ! if (ctlr >= NTMSCP) return (ENXIO); ! sc = &tmscp_softc[ctlr]; tmscpaddr = sc->sc_addr; if (tmscpaddr == NULL) return(ENXIO); + paddr = _iomap(tmscp[sc->sc_unit]); #ifdef UNIBUS_MAP if (ubmap) { ubp = UBMAP; ! ubp->ub_lo = loint(paddr); ! ubp->ub_hi = hiint(paddr); } #endif ! paddr += RINGBASE; ! saveseg5(seg5); ! mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); mp = sc->sc_com->tmscp_rsp; sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0; bzero(mp, 2 * sizeof (*mp)); *************** *** 1573,1579 **** if (tmscpcmd(M_OP_STCON, unit, sc) == 0) { return(EFAULT); } ! sc->sc_com->tmscp_cmd[0].mscp_unit = 0; /* ui->ui_slave */ if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) { return(EFAULT); } --- 1547,1553 ---- if (tmscpcmd(M_OP_STCON, unit, sc) == 0) { return(EFAULT); } ! sc->sc_com->tmscp_cmd[0].mscp_unit = unit; if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) { return(EFAULT); } *************** *** 1604,1609 **** --- 1578,1584 ---- return(EIO); paddr += (DBSIZE << PGSHIFT); } + restorseg5(seg5); return (0); } *************** *** 1625,1637 **** rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0]; cmp->mscp_opcode = op; ! cmp->mscp_unit = 0; /* unit? */ cmp->mscp_header.tmscp_msglen = mscp_msglen; rmp->mscp_header.tmscp_msglen = mscp_msglen; rlp[0].hsh |= TMSCP_OWN|TMSCP_INT; rlp[1].hsh |= TMSCP_OWN|TMSCP_INT; if (sc->sc_addr->tmscpsa&TMSCP_ERR) ! printf("tms fatal error (0%o)\n", sc->sc_addr->tmscpsa); i = sc->sc_addr->tmscpip; while ((rlp[1].hsh & TMSCP_INT) == 0) --- 1600,1613 ---- rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0]; cmp->mscp_opcode = op; ! cmp->mscp_unit = unit; cmp->mscp_header.tmscp_msglen = mscp_msglen; rmp->mscp_header.tmscp_msglen = mscp_msglen; rlp[0].hsh |= TMSCP_OWN|TMSCP_INT; rlp[1].hsh |= TMSCP_OWN|TMSCP_INT; if (sc->sc_addr->tmscpsa&TMSCP_ERR) ! printf("tms%d,%d fatal error 0%o\n", sc->sc_unit, unit, ! sc->sc_addr->tmscpsa); i = sc->sc_addr->tmscpip; while ((rlp[1].hsh & TMSCP_INT) == 0) *************** *** 1644,1650 **** if (rmp->mscp_opcode != (op|M_OP_END) || (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC) { ! printf("error: com %d opc 0x%x stat 0x%x\ndump ", op, rmp->mscp_opcode, rmp->mscp_status); return(0); } --- 1620,1626 ---- if (rmp->mscp_opcode != (op|M_OP_END) || (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC) { ! printf("err: com %d opc 0x%x stat 0x%x\ndump ", op, rmp->mscp_opcode, rmp->mscp_status); return(0); } *************** *** 1652,1689 **** } #endif TMSCP_DUMP ! /* ! * Perform raw read ! */ tmscpread(dev, uio) ! dev_t dev; struct uio *uio; { ! register int unit = TMSUNIT(dev); ! ! if (unit >= NTMS) ! return (ENXIO); ! return (physio(tmscpstrategy, &tms_info[unit].tms_rtab, dev, B_READ, BYTE, uio)); } - - /* - * Perform raw write - */ - tmscpwrite(dev, uio) ! dev_t dev; struct uio *uio; { ! register int unit = TMSUNIT(dev); ! ! if (unit >= NTMS) ! return (ENXIO); ! return (physio(tmscpstrategy, &tms_info[unit].tms_rtab, dev, B_WRITE, BYTE, uio)); } - /* * Catch ioctl commands, and call the "command" routine to do them. */ --- 1628,1656 ---- } #endif TMSCP_DUMP ! struct buf * ! tmsrtab(dev) ! register dev_t dev; ! { ! register struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)]; + return(&sc->sc_drives[TMSUNIT(dev)]->tms_rtab); + } + tmscpread(dev, uio) ! register dev_t dev; struct uio *uio; { ! return(physio(tmscpstrategy, tmsrtab(dev), dev, B_READ, BYTE, uio)); } tmscpwrite(dev, uio) ! register dev_t dev; struct uio *uio; { ! return(physio(tmscpstrategy, tmsrtab(dev), dev, B_WRITE, BYTE, uio)); } /* * Catch ioctl commands, and call the "command" routine to do them. */ *************** *** 1695,1701 **** caddr_t data; int flag; { ! register struct buf *bp = &tmscp_softc[TMSUNIT(dev)].sc_cmdbuf; register callcount; /* number of times to call cmd routine */ register struct tms_info *tms; int fcount; /* number of files (or records) to space */ --- 1662,1669 ---- caddr_t data; int flag; { ! struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)]; ! register struct buf *bp = &sc->sc_cmdbuf; register callcount; /* number of times to call cmd routine */ register struct tms_info *tms; int fcount; /* number of files (or records) to space */ *************** *** 1747,1753 **** /* * Return status info associated with the particular UNIT. */ ! tms = &tms_info[TMSUNIT(dev)]; mtget = (struct mtget *)data; mtget->mt_type = MT_ISTMSCP; mtget->mt_dsreg = tms->tms_flags << 8; --- 1715,1723 ---- /* * Return status info associated with the particular UNIT. */ ! tms = sc->sc_drives[TMSUNIT(dev)]; ! if (!tms) ! return(ENXIO); mtget = (struct mtget *)data; mtget->mt_type = MT_ISTMSCP; mtget->mt_dsreg = tms->tms_flags << 8; *************** *** 1770,1777 **** * send message to an error logger. */ ! tmserror(unit, mp) ! register int unit; register struct mslg *mp; { register i; --- 1740,1747 ---- * send message to an error logger. */ ! tmserror(ctlr, mp) ! register int ctlr; register struct mslg *mp; { register i; *************** *** 1780,1803 **** printd("tmserror:\n"); #endif if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT))) ! log(TMS_PRI, "tms%d: %s error, ", unit, mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard"); switch (mp->mslg_format) { case M_FM_CNTERR: ! log(TMS_PRI, "controller error, event 0%o\n", mp->mslg_event); break; case M_FM_BUSADDR: ! log(TMS_PRI, "host memory access error, event 0%o, addr 0%o\n", mp->mslg_event, mp->mslg_busaddr); break; case M_FM_TAPETRN: ! log(TMS_PRI, "tape transfer error, unit %d, grp 0x%x, event 0%o\n", mp->mslg_unit, mp->mslg_group, mp->mslg_event); break; case M_FM_STIERR: ! log(TMS_PRI, "STI error, unit %d, event 0%o\n", mp->mslg_unit, mp->mslg_event); #ifdef notdef /* too painful to do with log() */ --- 1750,1773 ---- printd("tmserror:\n"); #endif if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT))) ! log(TMS_PRI, "tms%d,%d: %s err, ", ctlr, mp->mslg_unit, mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard"); switch (mp->mslg_format) { case M_FM_CNTERR: ! log(TMS_PRI, "ctlr err, event 0%o\n", mp->mslg_event); break; case M_FM_BUSADDR: ! log(TMS_PRI, "host memory access err, event 0%o, addr 0%o\n", mp->mslg_event, mp->mslg_busaddr); break; case M_FM_TAPETRN: ! log(TMS_PRI, "tape transfer err, unit %d, grp 0x%x, event 0%o\n", mp->mslg_unit, mp->mslg_group, mp->mslg_event); break; case M_FM_STIERR: ! log(TMS_PRI, "STI err, unit %d, event 0%o\n", mp->mslg_unit, mp->mslg_event); #ifdef notdef /* too painful to do with log() */ *************** *** 1815,1822 **** mp->mslg_unit, mp->mslg_event); break; default: ! log(TMS_PRI, "unknown error, unit %d, format 0%o, event 0%o\n", ! mp->mslg_unit, mp->mslg_format, mp->mslg_event); } if (tmscperror) --- 1785,1792 ---- mp->mslg_unit, mp->mslg_event); break; default: ! log(TMS_PRI, "unknown err, %d,%d, format 0%o, event 0%o\n", ! ctlr,mp->mslg_unit, mp->mslg_format, mp->mslg_event); } if (tmscperror) *************** *** 1828,1849 **** printf("\n"); } } ! ! #ifdef notSMS ! tprintf(pri,fmt,a) ! int pri; ! char *fmt; ! unsigned a; ! { ! prf(fmt, &a, 5); /* 5 = TOLOG|TOCONSOLE */ ! } ! ! log(pri,fmt,a) ! int pri; ! char *fmt; ! unsigned a; ! { ! prf(fmt, &a, 5); ! } ! #endif notSMS ! #endif --- 1798,1801 ---- printf("\n"); } } ! #endif NTMSCP