1: /*
2: * 1.2 (2.11BSD) 1998/1/28
3: *
4: * This routine was moved from the main TMSCP driver due to size problems.
5: * The driver could become over 8kb in size and would not fit within an
6: * overlay!
7: *
8: * Thought was given to simply deleting this routine altogether - who
9: * does crash dumps to tape (and the tmscp.c driver is the only one with
10: * a crash dump routine) but in the end the decision was made to retain
11: * the capability but move it to a separate file.
12: */
13:
14: #include "tms.h"
15: #if NTMSCP > 0
16:
17: #include "param.h"
18: #include "buf.h"
19: #include "machine/seg.h"
20: #include "tmscpreg.h"
21: #include "pdp/tmscp.h"
22: #include "errno.h"
23: #include "map.h"
24: #include "uba.h"
25: #include "pdp/seg.h"
26:
27: #ifdef TMSCP_DUMP
28: #define DBSIZE 16
29:
30: extern memaddr tmscp[];
31: extern char *tmscpfatalerr;
32: extern struct tmscp_softc tmscp_softc[];
33:
34: tmsdump(dev)
35: dev_t dev;
36: {
37: register struct tmscpdevice *tmscpaddr;
38: register struct tmscp_softc *sc;
39: register struct mscp *mp;
40: daddr_t bn, dumpsize;
41: long paddr, maddr;
42: int unit = TMSUNIT(dev), count, ctlr = TMSCTLR(dev);
43: struct ubmap *ubp;
44: segm seg5;
45:
46: if (ctlr >= NTMSCP)
47: return (ENXIO);
48: sc = &tmscp_softc[ctlr];
49: tmscpaddr = sc->sc_addr;
50: if (tmscpaddr == NULL)
51: return(ENXIO);
52:
53: paddr = _iomap(tmscp[sc->sc_unit]);
54: if (ubmap) {
55: ubp = UBMAP;
56: ubp->ub_lo = loint(paddr);
57: ubp->ub_hi = hiint(paddr);
58: }
59: paddr += RINGBASE;
60: saveseg5(seg5);
61: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
62: mp = sc->sc_com->tmscp_rsp;
63: sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0;
64: bzero(mp, 2 * sizeof (*mp));
65:
66: tmscpaddr->tmscpip = 0;
67: while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
68: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
69: tmscpaddr->tmscpsa = TMSCP_ERR;
70: while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
71: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
72: tmscpaddr->tmscpsa = loint(paddr);
73: while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
74: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
75: tmscpaddr->tmscpsa = hiint(paddr);
76: while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
77: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
78: tmscpaddr->tmscpsa = TMSCP_GO;
79:
80: tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, mp, 0, 2, 0);
81:
82: if (tmscpcmd(M_OP_STCON, unit, sc) == 0) {
83: return(EFAULT);
84: }
85: sc->sc_com->tmscp_cmd[0].mscp_unit = unit;
86: if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) {
87: return(EFAULT);
88: }
89:
90: dumpsize = 8 * 1024L; /* XXX */
91: ubp = &UBMAP[1];
92: for (paddr = 0; dumpsize > 0; dumpsize -= count) {
93: count = MIN(dumpsize, DBSIZE);
94: bn = paddr >> PGSHIFT;
95: maddr = paddr;
96: if (ubmap) {
97: ubp->ub_lo = loint(paddr);
98: ubp->ub_hi = hiint(paddr);
99: maddr = (u_int)(1 << 13);
100: }
101: /* write it to the tape */
102: mp = &sc->sc_com->tmscp_rsp[1];
103: mp->mscp_lbn_l = loint(bn);
104: mp->mscp_lbn_h = hiint(bn);
105: mp->mscp_bytecnt = count * NBPG;
106: mp->mscp_buffer_l = loint(maddr);
107: mp->mscp_buffer_h = hiint(maddr);
108: if (tmscpcmd(M_OP_WRITE, unit, sc) == 0)
109: return(EIO);
110: paddr += (DBSIZE << PGSHIFT);
111: }
112: restorseg5(seg5);
113: return (0);
114: }
115:
116: /*
117: * Perform a standalone tmscp command. This routine is only used by tmscpdump.
118: */
119:
120: tmscpcmd(op, unit, sc)
121: int op;
122: int unit;
123: register struct tmscp_softc *sc;
124: {
125: int i;
126: register struct mscp *cmp, *rmp;
127: Trl *rlp;
128:
129: cmp = &sc->sc_com->tmscp_rsp[1];
130: rmp = &sc->sc_com->tmscp_rsp[0];
131: rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0];
132:
133: cmp->mscp_opcode = op;
134: cmp->mscp_unit = unit;
135: cmp->mscp_header.mscp_msglen = sizeof (struct mscp);
136: rmp->mscp_header.mscp_msglen = sizeof (struct mscp);
137: rlp[0].hsh |= TMSCP_OWN|TMSCP_INT;
138: rlp[1].hsh |= TMSCP_OWN|TMSCP_INT;
139: if (sc->sc_addr->tmscpsa&TMSCP_ERR)
140: printf(tmscpfatalerr, sc->sc_unit, unit, sc->sc_addr->tmscpsa);
141: i = sc->sc_addr->tmscpip;
142:
143: while ((rlp[1].hsh & TMSCP_INT) == 0)
144: ;
145: while ((rlp[0].hsh & TMSCP_INT) == 0)
146: ;
147:
148: sc->sc_com->tmscp_ca.ca_rspint = 0;
149: sc->sc_com->tmscp_ca.ca_cmdint = 0;
150: if (rmp->mscp_opcode != (op|M_OP_END) ||
151: (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC)
152: {
153: printf("err: com %d opc 0x%x stat 0x%x\ndump ", op,
154: rmp->mscp_opcode, rmp->mscp_status);
155: return(0);
156: }
157: return(1);
158: }
159: #endif /* TMSCP_DUMP */
160: #endif /* NTMSCP */
Defined functions
Defined macros