|
|
1.1 root 1: /*-
2: * Copyright (c) 1991 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)tmscp.c 7.16 (Berkeley) 5/9/91
34: */
35:
36: /*
37: * sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86";
38: */
39:
40: /************************************************************************
41: * *
42: * Licensed from Digital Equipment Corporation *
43: * Copyright (c) *
44: * Digital Equipment Corporation *
45: * Maynard, Massachusetts *
46: * 1985, 1986 *
47: * All rights reserved. *
48: * *
49: * The Information in this software is subject to change *
50: * without notice and should not be construed as a commitment *
51: * by Digital Equipment Corporation. Digital makes no *
52: * representations about the suitability of this software for *
53: * any purpose. It is supplied "As Is" without expressed or *
54: * implied warranty. *
55: * *
56: * If the Regents of the University of California or its *
57: * licensees modify the software in a manner creating *
58: * diriviative copyright rights, appropriate copyright *
59: * legends may be placed on the drivative work in addition *
60: * to that set forth above. *
61: * *
62: ************************************************************************
63: *
64: * tmscp.c - TMSCP (TK50/TU81) tape device driver
65: *
66: * Modification History:
67: *
68: * 06-Jan-86 - afd
69: * Changed the probe routine to use DELAY (not TODR). This now
70: * works for MicroVAXen as well. This eliminates the busy-wait
71: * for MicroVAXen so a dead TK50 controller will not hang autoconf.
72: *
73: * 06-Dec-85 - afd
74: * Fixed a bug in density selection. The "set unit characteristics"
75: * command to select density, was clearing the "unit flags" field
76: * where the CACHE bit was for TU81-E. Now the unit's "format" and
77: * "unitflgs" are saved in tms_info struct. And are used on STUNT
78: * commands.
79: *
80: * 19-Oct-85 - afd
81: * Added support to the open routine to allow drives to be opened
82: * for low density (800 or 1600 bpi) use. When the slave routine
83: * initiates a "get-unit-char" cmd, the format menu for the unit
84: * is saved in the tms_info structure. The format menu is used in the
85: * start routine to select the proper low density.
86: *
87: * 02-Oct-85 - afd
88: * When a tmscp-type controller is initializing, it is possible for
89: * the sa reg to become 0 between states. Thus the init code in
90: * the interrupt routine had to be modified to reflect this.
91: *
92: * 21-Sep-85 - afd
93: * The TK50 declares a serious exception when a tape mark is encountered.
94: * This causes problems to dd (& other UN*X utilities). So a flag
95: * is set in the rsp() routine when a tape mark is encountered. If
96: * this flag is set, the start() routine appends the Clear Serious
97: * Exception modifier to the next command.
98: *
99: * 03-Sep-85 -- jaw
100: * messed up previous edit..
101: *
102: * 29-Aug-85 - jaw
103: * fixed bugs in 8200 and 750 buffered datapath handling.
104: *
105: * 06-Aug-85 - afd
106: * 1. When repositioning records or files, the count of items skipped
107: * does NOT HAVE to be returned by controllers (& the TU81 doesn't).
108: * So tmscprsp() had to be modified to stop reporting
109: * residual count errors on reposition commands.
110: *
111: * 2. Fixed bug in the open routine which allowed multiple opens.
112: *
113: * 18-Jul-85 - afd
114: * 1. Need to return status when mt status (or corresponding ioctl) is done.
115: * Save resid, flags, endcode & status in tmscprsp() routine (except on
116: * clear serious exception no-op). Return these fields when status
117: * ioctl is done (in tmscpcommand()). How they are returned:
118: * mt_resid = resid
119: * mt_dsreg = flags|endcode
120: * mt_erreg = status
121: *
122: * 2. Added latent support for enabling/disabling caching. This is
123: * handled along with all other ioctl commands.
124: *
125: * 3. Need to issue a no-op on unrecognized ioctl in tmscpstart(), since
126: * we have already commited to issuing a command at that point.
127: *
128: * 4. In tmscprsp() routine if encode is 0200 (invalid command issued);
129: * We need to: Unlink the buffer from the I/O wait queue,
130: * and signal iodone, so the higher level command can exit!
131: * Just as if it were a valid command.
132: *
133: * 11-jul-85 -- jaw
134: * fix bua/bda map registers.
135: *
136: * 19-Jun-85 -- jaw
137: * VAX8200 name change.
138: *
139: * 06-Jun-85 - jaw
140: * fixes for 8200.
141: *
142: * 9-Apr-85 - afd
143: * Added timeout code to the probe routine, so if the controller
144: * fails to init in 10 seconds we return failed status.
145: *
146: * 13-Mar-85 -jaw
147: * Changes for support of the VAX8200 were merged in.
148: *
149: * 27-Feb-85 -tresvik
150: * Changes for support of the VAX8600 were merged in.
151: *
152: */
153:
154: #include "tms.h"
155: #if NTMSCP > 0
156:
157: #include "sys/param.h"
158: #include "sys/systm.h"
159: #include "sys/buf.h"
160: #include "sys/conf.h"
161: #include "sys/errno.h"
162: #include "sys/file.h"
163: #include "sys/map.h"
164: #include "sys/vm.h"
165: #include "sys/ioctl.h"
166: #include "sys/syslog.h"
167: #include "sys/mtio.h"
168: #include "sys/cmap.h"
169: #include "sys/uio.h"
170: #include "sys/tprintf.h"
171:
172: #include "../include/pte.h"
173: #include "../include/cpu.h"
174: #include "../include/mtpr.h"
175: #include "ubareg.h"
176: #include "ubavar.h"
177:
178: #define TENSEC (1000)
179: #define TMS_PRI LOG_INFO
180:
181: #define NRSPL2 3 /* log2 number of response packets */
182: #define NCMDL2 3 /* log2 number of command packets */
183: #define NRSP (1<<NRSPL2)
184: #define NCMD (1<<NCMDL2)
185:
186: #include "tmscpreg.h"
187: #include "../vax/tmscp.h"
188:
189: /* Software state per controller */
190:
191: struct tmscp_softc {
192: short sc_state; /* state of controller */
193: short sc_mapped; /* Unibus map allocated for tmscp struct? */
194: int sc_ubainfo; /* Unibus mapping info */
195: struct tmscp *sc_tmscp; /* Unibus address of tmscp struct */
196: int sc_ivec; /* interrupt vector address */
197: short sc_credits; /* transfer credits */
198: short sc_lastcmd; /* pointer into command ring */
199: short sc_lastrsp; /* pointer into response ring */
200: short sc_ipl; /* interrupt priority (Q-bus) */
201: } tmscp_softc[NTMSCP];
202:
203: struct tmscp {
204: struct tmscpca tmscp_ca; /* communications area */
205: struct mscp tmscp_rsp[NRSP]; /* response packets */
206: struct mscp tmscp_cmd[NCMD]; /* command packets */
207: } tmscp[NTMSCP];
208:
209: /*
210: * Per drive-unit info
211: */
212: struct tms_info {
213: daddr_t tms_dsize; /* Max user size from online pkt */
214: unsigned tms_type; /* Drive type int field */
215: int tms_resid; /* residual from last xfer */
216: u_char tms_endcode; /* last command endcode */
217: u_char tms_flags; /* last command end flags */
218: unsigned tms_status; /* Command status from last command */
219: char tms_openf; /* lock against multiple opens */
220: char tms_lastiow; /* last op was a write */
221: char tms_serex; /* set when serious exception occurs */
222: char tms_clserex; /* set when serex being cleared by no-op */
223: short tms_fmtmenu; /* the unit's format (density) menu */
224: short tms_unitflgs; /* unit flag parameters */
225: short tms_format; /* the unit's current format (density) */
226: tpr_t tms_tpr; /* tprintf handle */
227: } tms_info[NTMS];
228: struct uba_ctlr *tmscpminfo[NTMSCP];
229: struct uba_device *tmsdinfo[NTMS];
230: /*
231: * ifdef other tmscp devices here if they allow more than 1 unit/controller
232: */
233: struct uba_device *tmscpip[NTMSCP][1];
234: struct buf ctmscpbuf[NTMSCP]; /* internal cmd buffer (for ioctls) */
235: struct buf tmsutab[NTMS]; /* Drive queue */
236: struct buf tmscpwtab[NTMSCP]; /* I/O wait queue, per controller */
237: int tmscpmicro[NTMSCP]; /* to store microcode level */
238: short utoctlr[NTMS]; /* Slave unit to controller mapping */
239: /* filled in by the slave routine */
240:
241: /* Bits in minor device */
242: #define TMSUNIT(dev) (minor(dev)&03)
243: #define T_NOREWIND 04
244: #define T_HIDENSITY 010
245:
246: /* Slave unit to controller mapping */
247: #define TMSCPCTLR(dev) (utoctlr[TMSUNIT(dev)])
248:
249: /*
250: * Internal (ioctl) command codes (these must also be declared in the
251: * tmscpioctl routine). These correspond to ioctls in mtio.h
252: */
253: #define TMS_WRITM 0 /* write tape mark */
254: #define TMS_FSF 1 /* forward space file */
255: #define TMS_BSF 2 /* backward space file */
256: #define TMS_FSR 3 /* forward space record */
257: #define TMS_BSR 4 /* backward space record */
258: #define TMS_REW 5 /* rewind tape */
259: #define TMS_OFFL 6 /* rewind tape & mark unit offline */
260: #define TMS_SENSE 7 /* noop - do a get unit status */
261: #define TMS_CACHE 8 /* enable cache */
262: #define TMS_NOCACHE 9 /* disable cache */
263: /* These go last: after all real mt cmds, just bump the numbers up */
264: #define TMS_CSE 10 /* clear serious exception */
265: #define TMS_LOWDENSITY 11 /* set unit to low density */
266: #define TMS_HIDENSITY 12 /* set unit to high density */
267:
268: /*
269: * Controller states
270: */
271: #define S_IDLE 0 /* hasn't been initialized */
272: #define S_STEP1 1 /* doing step 1 init */
273: #define S_STEP2 2 /* doing step 2 init */
274: #define S_STEP3 3 /* doing step 3 init */
275: #define S_SCHAR 4 /* doing "set controller characteristics" */
276: #define S_RUN 5 /* running */
277:
278: int tmscperror = 0; /* causes hex dump of packets */
279: int tmscp_cp_wait = 0; /* Something to wait on for command */
280: /* packets and or credits. */
281: int wakeup();
282: extern int hz; /* Should find the right include */
283:
284: #ifdef DEBUG
285: #define printd if (tmscpdebug) printf
286: int tmscpdebug = 1;
287: #define printd10 if(tmscpdebug >= 10) printf
288: #endif
289:
290: int tmscpprobe(), tmscpslave(), tmscpattach(), tmscpintr();
291: struct mscp *tmscpgetcp();
292:
293: #define DRVNAME "tms"
294: #define CTRLNAME "tmscp"
295:
296: u_short tmscpstd[] = { 0174500, 0 };
297: struct uba_driver tmscpdriver =
298: { tmscpprobe, tmscpslave, tmscpattach, 0, tmscpstd, DRVNAME, tmsdinfo, CTRLNAME
299: , tmscpminfo, 0};
300:
301: #define b_qsize b_resid /* queue size per drive, in tmsutab */
302: #define b_ubinfo b_resid /* Unibus mapping info, per buffer */
303:
304:
305: /*************************************************************************/
306:
307: #define DELAYTEN 1000
308:
309: /*
310: * Unfortunately qbgetpri can't be used because the TK50 doesn't flip the
311: * TMSCP_STEP2 flag in the tmscpsa register until after the pending interrupt
312: * has been acknowledged by the cpu. If you are at spl6(), the TMSCP_STEP2
313: * flag never gets set and you return (0).
314: */
315: tmscpprobe(reg, ctlr)
316: caddr_t reg; /* address of the IP register */
317: int ctlr; /* index of controller in the tmscp_softc array */
318: {
319: register int br, cvec; /* MUST be 1st (r11 & r10): IPL and intr vec */
320: register struct tmscp_softc *sc = &tmscp_softc[ctlr];
321: /* ptr to software controller structure */
322: struct tmscpdevice *tmscpaddr; /* ptr to tmscpdevice struct (IP & SA) */
323: int count; /* for probe delay time out */
324:
325: # ifdef lint
326: br = 0; cvec = br; br = cvec; reg = reg;
327: tmscpreset(0); tmscpintr(0);
328: # endif
329:
330: tmscpaddr = (struct tmscpdevice *) reg;
331: /*
332: * Set host-settable interrupt vector.
333: * Assign 0 to the ip register to start the tmscp-device initialization.
334: * The device is not really initialized at this point, this is just to
335: * find out if the device exists.
336: */
337: sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
338: tmscpaddr->tmscpip = 0;
339:
340: count=0;
341: while(count < DELAYTEN)
342: { /* wait for at most 10 secs */
343: if((tmscpaddr->tmscpsa & TMSCP_STEP1) != 0)
344: break;
345: DELAY(10000);
346: count=count+1;
347: }
348: if (count == DELAYTEN)
349: return(0);
350:
351: tmscpaddr->tmscpsa = TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4);
352:
353: count=0;
354: while(count < DELAYTEN)
355: {
356: if((tmscpaddr->tmscpsa & TMSCP_STEP2) != 0)
357: break;
358: DELAY(10000);
359: count = count+1;
360: }
361: if (count == DELAYTEN)
362: return(0);
363:
364: #ifdef QBA
365: sc->sc_ipl = br = 0x15;
366: #endif
367: return(sizeof (struct tmscpdevice));
368: }
369:
370: /*
371: * Try to find a slave (a drive) on the controller.
372: * If the controller is not in the run state, call init to initialize it.
373: */
374: tmscpslave (ui, reg)
375: struct uba_device *ui; /* ptr to the uba device structure */
376: caddr_t reg; /* addr of the device controller */
377: {
378: register struct uba_ctlr *um = tmscpminfo[ui->ui_ctlr];
379: register struct tmscp_softc *sc = &tmscp_softc[ui->ui_ctlr];
380: register struct tms_info *tms = &tms_info[ui->ui_unit];
381: struct tmscpdevice *tmscpaddr; /* ptr to IP & SA */
382: struct mscp *mp;
383: int i; /* Something to write into to start */
384: /* the tmscp polling */
385:
386: # ifdef lint
387: reg = reg;
388: # endif
389: tmscpaddr = (struct tmscpdevice *)um->um_addr;
390: /*
391: * If its not in the run state, start the initialization process
392: * (tmscpintr will complete it); if the initialization doesn't start;
393: * then return.
394: */
395: if(sc->sc_state != S_RUN)
396: {
397: # ifdef DEBUG
398: printd("tmscpslave: ctlr not running: calling init \n");
399: # endif
400: if(!tmscpinit(ui->ui_ctlr))
401: return(0);
402: }
403: /*
404: * Wait for the controller to come into the run state or go idle.
405: * If it goes idle return.
406: */
407: # ifdef DEBUG
408: i=1;
409: # endif
410: while(sc->sc_state != S_RUN && sc->sc_state != S_IDLE)
411: # ifdef DEBUG
412: if (tmscpaddr->tmscpsa & TMSCP_ERR && i)
413: {
414: printd("tmscp-device: fatal error (%o)\n", tmscpaddr->tmscpsa&0xffff);
415: i=0;
416: }
417: # endif
418: ; /* wait */
419: if(sc->sc_state == S_IDLE)
420: { /* The tmscp device failed to initialize */
421: printf("tmscp controller failed to init\n");
422: return(0);
423: }
424: /* The controller is up so see if the drive is there */
425: if(0 == (mp = tmscpgetcp(um)))
426: {
427: printf("tmscp can't get command packet\n");
428: return(0);
429: }
430: /* Need to determine the drive type for generic driver */
431: mp->mscp_opcode = M_OP_GTUNT; /* This should give us the device type */
432: mp->mscp_unit = ui->ui_slave;
433: mp->mscp_cmdref = (long) ui->ui_slave;
434: tms->tms_status = 0; /* set to zero */
435: tmscpip[ui->ui_ctlr][ui->ui_slave] = ui;
436: *((long *) mp->mscp_dscptr ) |= TMSCP_OWN | TMSCP_INT;/* maybe we should poll*/
437: i = tmscpaddr->tmscpip;
438: #ifdef lint
439: i = i;
440: #endif
441: while(!tms->tms_status)
442: ; /* Wait for some status */
443: # ifdef DEBUG
444: printd("tmscpslave: status = %o\n",tms->tms_status & M_ST_MASK);
445: # endif
446: tmscpip[ui->ui_ctlr][ui->ui_slave] = 0;
447: if(!tms->tms_type) /* packet from a GTUNT */
448: return(0); /* Failed No such drive */
449: else
450: return(1); /* Got it and it is there */
451: }
452:
453:
454: /*
455: * Set ui flags to zero to show device is not online & set tmscpip.
456: * Unit to Controller mapping is set up here.
457: * Open routine will issue the online command, later.
458: */
459: tmscpattach (ui)
460: register struct uba_device *ui; /* ptr to unibus dev struct */
461: {
462:
463: ui->ui_flags = 0;
464: tmscpip[ui->ui_ctlr][ui->ui_slave] = ui;
465: # ifdef DEBUG
466: /*
467: * Check to see if the drive is available.
468: * If not then just print debug.
469: */
470: if(tms_info[ui->ui_unit].tms_status != M_ST_AVLBL)
471: printd("tmscpattach: unavailable \n");
472: # endif
473: utoctlr[ui->ui_unit] = ui->ui_ctlr;
474: }
475:
476:
477: /*
478: * TMSCP interrupt routine.
479: */
480: tmscpintr (d)
481: int d; /* index to the controller */
482: {
483: register struct uba_ctlr *um = tmscpminfo[d];
484: register struct tmscpdevice *tmscpaddr = (struct tmscpdevice *)um->um_addr;
485: struct buf *bp;
486: register int i;
487: register struct tmscp_softc *sc = &tmscp_softc[d];
488: register struct tmscp *tm = &tmscp[d];
489: struct tmscp *ttm;
490: struct mscp *mp;
491:
492: # ifdef DEBUG
493: printd10("tmscpintr: state %d, tmscpsa %o\n", sc->sc_state, tmscpaddr->tmscpsa);
494: # endif
495:
496: #ifdef QBA
497: splx(sc->sc_ipl);
498: #endif
499: /*
500: * How the interrupt is handled depends on the state of the controller.
501: */
502: switch (sc->sc_state) {
503:
504: case S_IDLE:
505: printf("tmscp%d: random interrupt ignored\n", d);
506: return;
507:
508: /* Controller was in step 1 last, see if its gone to step 2 */
509: case S_STEP1:
510: # define STEP1MASK 0174377
511: # define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
512: for (i = 0; i < 150; i++)
513: {
514: if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
515: { /* still in step 1 (wait 1/100 sec) */
516: DELAY(10000);
517: # ifdef DEBUG
518: printd("still in step 1, delaying\n");
519: # endif DEBUG
520: }
521: else
522: break;
523: }
524: if (i > 149)
525: {
526: sc->sc_state = S_IDLE;
527: printf("failed to initialize, in step1: sa 0x%x", tmscpaddr->tmscpsa);
528: wakeup((caddr_t)um);
529: return;
530: }
531: tmscpaddr->tmscpsa = ((int)&sc->sc_tmscp->tmscp_ca.ca_ringbase)
532: | ((cpu == VAX_780 || cpu == VAX_8600) ? TMSCP_PI : 0);
533: sc->sc_state = S_STEP2;
534: return;
535:
536: /* Controller was in step 2 last, see if its gone to step 3 */
537: case S_STEP2:
538: # define STEP2MASK 0174377
539: # define STEP2GOOD (TMSCP_STEP3|TMSCP_IE|(sc->sc_ivec/4))
540: for (i = 0; i < 150; i++)
541: {
542: if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
543: { /* still in step 2 (wait 1/100 sec) */
544: DELAY(10000);
545: # ifdef DEBUG
546: printd("still in step 2, delaying\n");
547: # endif DEBUG
548: }
549: else
550: break;
551: }
552: if (i > 149)
553: {
554: sc->sc_state = S_IDLE;
555: printf("failed to initialize, in step2: sa 0x%x", tmscpaddr->tmscpsa);
556: wakeup((caddr_t)um);
557: return;
558: }
559: tmscpaddr->tmscpsa = ((int)&sc->sc_tmscp->tmscp_ca.ca_ringbase)>>16;
560: sc->sc_state = S_STEP3;
561: return;
562:
563: /* Controller was in step 3 last, see if its gone to step 4 */
564: case S_STEP3:
565: # define STEP3MASK 0174000
566: # define STEP3GOOD TMSCP_STEP4
567: for (i = 0; i < 150; i++)
568: {
569: if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
570: { /* still in step 3 (wait 1/100 sec) */
571: DELAY(10000);
572: # ifdef DEBUG
573: printd("still in step 3, delaying\n");
574: # endif DEBUG
575: }
576: else
577: break;
578: }
579: if (i > 149)
580: {
581: sc->sc_state = S_IDLE;
582: printf("failed to initialize, in step3: sa 0x%x", tmscpaddr->tmscpsa);
583: wakeup((caddr_t)um);
584: return;
585: }
586: /*
587: * Get microcode version and model number of controller;
588: * Signal initialization complete (_GO) (to the controller);
589: * ask for Last Fail response if tmscperror is set;
590: * Set state to "set controller characteristics".
591: */
592: tmscpmicro[d] = tmscpaddr->tmscpsa;
593: tmscpaddr->tmscpsa = TMSCP_GO | (tmscperror? TMSCP_LF : 0);
594: sc->sc_state = S_SCHAR;
595: # ifdef DEBUG
596: printd("tmscpintr: completed state %d \n", sc->sc_state);
597: printd("tmscp%d Version %d model %d\n",d,tmscpmicro[d]&0xF,
598: (tmscpmicro[d]>>4) & 0xF);
599: # endif
600:
601: /*
602: * Initialize the data structures (response and command queues).
603: */
604: ttm = sc->sc_tmscp;
605: for (i = 0; i < NRSP; i++)
606: {
607: tm->tmscp_ca.ca_rspdsc[i] = TMSCP_OWN | TMSCP_INT |
608: (long)&ttm->tmscp_rsp[i].mscp_cmdref;
609: tm->tmscp_rsp[i].mscp_dscptr = &tm->tmscp_ca.ca_rspdsc[i];
610: tm->tmscp_rsp[i].mscp_header.tmscp_msglen = mscp_msglen;
611: }
612: for (i = 0; i < NCMD; i++)
613: {
614: tm->tmscp_ca.ca_cmddsc[i] = TMSCP_INT |
615: (long)&ttm->tmscp_cmd[i].mscp_cmdref;
616: tm->tmscp_cmd[i].mscp_dscptr = &tm->tmscp_ca.ca_cmddsc[i];
617: tm->tmscp_cmd[i].mscp_header.tmscp_msglen = mscp_msglen;
618: tm->tmscp_cmd[i].mscp_header.tmscp_vcid = 1;
619: }
620: bp = &tmscpwtab[d];
621: bp->av_forw = bp->av_back = bp;
622: sc->sc_lastcmd = 1;
623: sc->sc_lastrsp = 0;
624: mp = &tmscp[um->um_ctlr].tmscp_cmd[0];
625: mp->mscp_unit = mp->mscp_modifier = 0;
626: mp->mscp_flags = 0;
627: mp->mscp_version = 0;
628: mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
629: /*
630: * A host time out value of 0 means that the controller will not
631: * time out. This is ok for the TK50.
632: */
633: mp->mscp_hsttmo = 0;
634: mp->mscp_time.val[0] = 0;
635: mp->mscp_time.val[1] = 0;
636: mp->mscp_cntdep = 0;
637: mp->mscp_opcode = M_OP_STCON;
638: *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
639: i = tmscpaddr->tmscpip; /* initiate polling */
640: return;
641:
642: case S_SCHAR:
643: case S_RUN:
644: break;
645:
646: default:
647: printf("tmscp%d: interrupt in unknown state %d ignored\n",d,sc->sc_state);
648: return;
649: } /* end switch */
650:
651: /*
652: * The controller state is S_SCHAR or S_RUN
653: */
654:
655: /*
656: * If the error bit is set in the SA register then print an error
657: * message and reinitialize the controller.
658: */
659: if (tmscpaddr->tmscpsa&TMSCP_ERR)
660: {
661: printf("tmscp%d: fatal error (%o)\n", d, tmscpaddr->tmscpsa&0xffff);
662: tmscpaddr->tmscpip = 0;
663: wakeup((caddr_t)um);
664: }
665: /*
666: * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus)
667: */
668: if (tm->tmscp_ca.ca_bdp)
669: {
670: UBAPURGE(um->um_hd->uh_uba, tm->tmscp_ca.ca_bdp);
671: tm->tmscp_ca.ca_bdp = 0;
672: tmscpaddr->tmscpsa = 0; /* signal purge complete */
673: }
674:
675: /*
676: * Check for response ring transition.
677: */
678: if (tm->tmscp_ca.ca_rspint)
679: {
680: tm->tmscp_ca.ca_rspint = 0;
681: for (i = sc->sc_lastrsp;; i++)
682: {
683: i %= NRSP;
684: if (tm->tmscp_ca.ca_rspdsc[i]&TMSCP_OWN)
685: break;
686: tmscprsp(um, tm, sc, i);
687: tm->tmscp_ca.ca_rspdsc[i] |= TMSCP_OWN;
688: }
689: sc->sc_lastrsp = i;
690: }
691:
692: /*
693: * Check for command ring transition.
694: */
695: if (tm->tmscp_ca.ca_cmdint)
696: {
697: # ifdef DEBUG
698: printd("tmscpintr: command ring transition\n");
699: # endif
700: tm->tmscp_ca.ca_cmdint = 0;
701: }
702: if(tmscp_cp_wait)
703: wakeup((caddr_t)&tmscp_cp_wait);
704: (void) tmscpstart(um);
705: }
706:
707:
708: /*
709: * Open a tmscp device and set the unit online. If the controller is not
710: * in the run state, call init to initialize the tmscp controller first.
711: */
712:
713: /* ARGSUSED */
714: tmscpopen(dev, flag)
715: dev_t dev;
716: int flag;
717: {
718: register int unit;
719: register struct uba_device *ui;
720: register struct tmscp_softc *sc;
721: register struct tms_info *tms;
722: register struct mscp *mp;
723: register struct uba_ctlr *um;
724: struct tmscpdevice *tmscpaddr;
725: int s,i;
726:
727: unit = TMSUNIT(dev);
728: # ifdef DEBUG
729: printd("tmscpopen unit %d\n",unit);
730: if(tmscpdebug)DELAY(10000);
731: # endif
732: if (unit >= NTMS || (ui = tmsdinfo[unit]) == 0 || ui->ui_alive == 0)
733: return (ENXIO);
734: tms = &tms_info[ui->ui_unit];
735: if (tms->tms_openf)
736: return (EBUSY);
737: sc = &tmscp_softc[ui->ui_ctlr];
738: tms->tms_openf = 1;
739: tms->tms_tpr = tprintf_open();
740: s = spl5();
741: if (sc->sc_state != S_RUN)
742: {
743: if (sc->sc_state == S_IDLE)
744: if(!tmscpinit(ui->ui_ctlr))
745: {
746: printf("tmscp controller failed to init\n");
747: (void) splx(s);
748: tms->tms_openf = 0;
749: return(ENXIO);
750: }
751: /*
752: * Wait for initialization to complete
753: */
754: timeout(wakeup,(caddr_t)ui->ui_mi,11*hz); /* to be sure*/
755: sleep((caddr_t)ui->ui_mi, 0);
756: if (sc->sc_state != S_RUN)
757: {
758: (void) splx(s);
759: tms->tms_openf = 0;
760: return (EIO);
761: }
762: }
763: /*
764: * Check to see if the device is really there.
765: * this code was taken from Fred Canters 11 driver
766: */
767: um = ui->ui_mi;
768: tmscpaddr = (struct tmscpdevice *) um->um_addr;
769: (void) splx(s);
770: if(ui->ui_flags == 0)
771: {
772: s = spl5();
773: while(0 ==(mp = tmscpgetcp(um)))
774: {
775: tmscp_cp_wait++;
776: sleep((caddr_t)&tmscp_cp_wait,PSWP+1);
777: tmscp_cp_wait--;
778: }
779: (void) splx(s);
780: mp->mscp_opcode = M_OP_ONLIN;
781: mp->mscp_unit = ui->ui_slave;
782: mp->mscp_cmdref = (long) & tms->tms_type;
783: /* need to sleep on something */
784: # ifdef DEBUG
785: printd("tmscpopen: bring unit %d online\n",ui->ui_unit);
786: # endif
787: *((long *) mp->mscp_dscptr ) |= TMSCP_OWN | TMSCP_INT;
788: i = tmscpaddr->tmscpip;
789: #ifdef lint
790: i = i;
791: #endif
792: /*
793: * To make sure we wake up, timeout in 240 seconds.
794: * Wakeup in tmscprsp routine.
795: * 240 seconds (4 minutes) is necessary since a rewind
796: * can take a few minutes.
797: */
798: timeout(wakeup,(caddr_t) mp->mscp_cmdref,240 * hz);
799: sleep((caddr_t) mp->mscp_cmdref,PSWP+1);
800: }
801: if(ui->ui_flags == 0) {
802: tms->tms_openf = 0;
803: return(ENXIO); /* Didn't go online */
804: }
805: tms->tms_lastiow = 0;
806: /*
807: * If the high density device is not specified, set unit to low
808: * density. This is done as an "internal" ioctl command so
809: * that the command setup and response handling
810: * is done thru "regular" command routines.
811: */
812: if ((minor(dev) & T_HIDENSITY) == 0)
813: tmscpcommand(dev, TMS_LOWDENSITY, 1);
814: else
815: tmscpcommand(dev, TMS_HIDENSITY, 1);
816: return (0);
817: }
818:
819:
820: /*
821: * Close tape device.
822: *
823: * If tape was open for writing or last operation was
824: * a write, then write two EOF's and backspace over the last one.
825: * Unless this is a non-rewinding special file, rewind the tape.
826: *
827: * NOTE:
828: * We want to be sure that any serious exception is cleared on the
829: * close. A Clear Serious Exception (CSE) modifier is always done on
830: * the rewind command. For the non-rewind case we check to see if the
831: * "serex" field is set in the softc struct; if it is then issue a noop
832: * command with the CSE modifier.
833: * Make the tape available to others, by clearing openf flag.
834: */
835: tmscpclose(dev, flag)
836: register dev_t dev;
837: register flag;
838: {
839: register struct tms_info *tms;
840: register struct uba_device *ui;
841:
842: ui = tmsdinfo[TMSUNIT(dev)];
843: # ifdef DEBUG
844: printd("tmscpclose: ctlr = %d\n",TMSCPCTLR(dev));
845: printd("tmscpclose: unit = %d\n",TMSUNIT(dev));
846: if(tmscpdebug)DELAY(10000);
847: # endif
848: tms = &tms_info[ui->ui_unit];
849: if (flag == FWRITE || (flag&FWRITE) && tms->tms_lastiow)
850: {
851: /* device, command, count */
852: tmscpcommand (dev, TMS_WRITM, 1);
853: tmscpcommand (dev, TMS_WRITM, 1);
854: tmscpcommand (dev, TMS_BSR, 1);
855: }
856: if ((minor(dev)&T_NOREWIND) == 0)
857: /*
858: * Don't hang waiting for rewind complete.
859: */
860: tmscpcommand(dev, TMS_REW, 0);
861: else
862: if (tms->tms_serex)
863: {
864: # ifdef DEBUG
865: printd("tmscpclose: clearing serex\n");
866: if(tmscpdebug)DELAY(10000);
867: # endif
868: tmscpcommand(dev, TMS_CSE, 1);
869: }
870: tprintf_close(tms->tms_tpr);
871: tms->tms_openf = 0;
872: return (0);
873: }
874:
875:
876: /*
877: * Execute a command on the tape drive a specified number of times.
878: * This routine sets up a buffer and calls the strategy routine which
879: * links the buffer onto the drive's buffer queue.
880: * The start routine will take care of creating a tmscp command packet
881: * with the command. The start routine is called by the strategy or the
882: * interrupt routine.
883: */
884:
885: tmscpcommand (dev, com, count)
886: register dev_t dev;
887: int com, count;
888: {
889: register struct uba_device *ui;
890: register struct buf *bp;
891: register int s;
892: int unit = TMSUNIT(dev);
893:
894: ui = tmsdinfo[unit];
895: bp = &ctmscpbuf[ui->ui_ctlr];
896:
897: s = spl5();
898: while (bp->b_flags&B_BUSY)
899: {
900: /*
901: * This special check is because B_BUSY never
902: * gets cleared in the non-waiting rewind case.
903: */
904: if (bp->b_bcount == 0 && (bp->b_flags&B_DONE))
905: break;
906: bp->b_flags |= B_WANTED;
907: sleep((caddr_t)bp, PRIBIO);
908: }
909: bp->b_flags = B_BUSY|B_READ;
910: splx(s);
911: /*
912: * Load the buffer. The b_count field gets used to hold the command
913: * count. the b_resid field gets used to hold the command mneumonic.
914: * These 2 fields are "known" to be "safe" to use for this purpose.
915: * (Most other drivers also use these fields in this way.)
916: */
917: bp->b_dev = dev;
918: bp->b_bcount = count;
919: bp->b_resid = com;
920: bp->b_blkno = 0;
921: tmscpstrategy(bp);
922: /*
923: * In case of rewind from close, don't wait.
924: * This is the only case where count can be 0.
925: */
926: if (count == 0)
927: return;
928: iowait(bp);
929: if (bp->b_flags&B_WANTED)
930: wakeup((caddr_t)bp);
931: bp->b_flags &= B_ERROR;
932: }
933:
934: /*
935: * Find an unused command packet
936: */
937: struct mscp *
938: tmscpgetcp(um)
939: struct uba_ctlr *um;
940: {
941: register struct mscp *mp;
942: register struct tmscpca *cp;
943: register struct tmscp_softc *sc;
944: register int i;
945: int s;
946:
947: s = spl5();
948: cp = &tmscp[um->um_ctlr].tmscp_ca;
949: sc = &tmscp_softc[um->um_ctlr];
950: /*
951: * If no credits, can't issue any commands
952: * until some outstanding commands complete.
953: */
954: i = sc->sc_lastcmd;
955: # ifdef DEBUG
956: printd10("tmscpgetcp: %d credits remain\n", sc->sc_credits);
957: # endif
958: if(((cp->ca_cmddsc[i]&(TMSCP_OWN|TMSCP_INT))==TMSCP_INT) &&
959: (sc->sc_credits >= 2))
960: {
961: sc->sc_credits--; /* This commits to issuing a command */
962: cp->ca_cmddsc[i] &= ~TMSCP_INT;
963: mp = &tmscp[um->um_ctlr].tmscp_cmd[i];
964: mp->mscp_unit = mp->mscp_modifier = 0;
965: mp->mscp_opcode = mp->mscp_flags = 0;
966: mp->mscp_bytecnt = mp->mscp_buffer = 0;
967: sc->sc_lastcmd = (i + 1) % NCMD;
968: (void) splx(s);
969: return(mp);
970: }
971: (void) splx(s);
972: return(NULL);
973: }
974:
975:
976: /*
977: * Initialize a TMSCP device. Set up UBA mapping registers,
978: * initialize data structures, and start hardware
979: * initialization sequence.
980: */
981: tmscpinit (d)
982: int d; /* index to the controller */
983: {
984: register struct tmscp_softc *sc;
985: register struct tmscp *t; /* communications area; cmd & resp packets */
986: struct tmscpdevice *tmscpaddr;
987: struct uba_ctlr *um;
988:
989: sc = &tmscp_softc[d];
990: um = tmscpminfo[d];
991: um->um_tab.b_active++;
992: t = &tmscp[d];
993: tmscpaddr = (struct tmscpdevice *)um->um_addr;
994: if (sc->sc_mapped == 0)
995: {
996: /*
997: * Map the communications area and command
998: * and response packets into Unibus address
999: * space.
1000: */
1001: sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)t, sizeof (struct tmscp), 0);
1002: sc->sc_tmscp = (struct tmscp *)(UBAI_ADDR(sc->sc_ubainfo));
1003: sc->sc_mapped = 1;
1004: }
1005:
1006: /*
1007: * Start the hardware initialization sequence.
1008: */
1009: tmscpaddr->tmscpip = 0; /* start initialization */
1010:
1011: while((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
1012: {
1013: # ifdef DEBUG
1014: printd("tmscpinit: tmscpsa = 0%o\n",tmscpaddr->tmscpsa);
1015: DELAY(100000);
1016: # endif
1017: if(tmscpaddr->tmscpsa & TMSCP_ERR)
1018: return(0); /* CHECK */
1019: }
1020: tmscpaddr->tmscpsa=TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4);
1021: /*
1022: * Initialization continues in the interrupt routine.
1023: */
1024: sc->sc_state = S_STEP1;
1025: sc->sc_credits = 0;
1026: return(1);
1027: }
1028:
1029:
1030: /*
1031: * Start I/O operation
1032: * This code is convoluted. The majority of it was copied from the uda driver.
1033: */
1034:
1035: tmscpstart(um)
1036: register struct uba_ctlr *um;
1037: {
1038: register struct buf *bp, *dp;
1039: register struct mscp *mp;
1040: register struct tmscp_softc *sc;
1041: register struct tms_info *tms;
1042: register struct uba_device *ui;
1043: struct tmscpdevice *tmscpaddr;
1044: struct tmscp *tm = &tmscp[um->um_ctlr];
1045: int i,tempi;
1046: char ioctl; /* flag: set true if its an IOCTL command */
1047:
1048: sc = &tmscp_softc[um->um_ctlr];
1049:
1050: for(;;)
1051: {
1052: if ((dp = um->um_tab.b_actf) == NULL)
1053: {
1054: /*
1055: * Release unneeded UBA resources and return
1056: * (drive was inactive)
1057: */
1058: um->um_tab.b_active = 0;
1059: break;
1060: }
1061: if ((bp = dp->b_actf) == NULL)
1062: {
1063: /*
1064: * No more requests for this drive, remove
1065: * from controller queue and look at next drive.
1066: * We know we're at the head of the controller queue.
1067: */
1068: dp->b_active = 0;
1069: um->um_tab.b_actf = dp->b_forw;
1070: continue; /* Need to check for loop */
1071: }
1072: um->um_tab.b_active++;
1073: tmscpaddr = (struct tmscpdevice *)um->um_addr;
1074: ui = tmsdinfo[(TMSUNIT(bp->b_dev))];
1075: tms = &tms_info[ui->ui_unit];
1076: if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN)
1077: {
1078: tprintf(tms->tms_tpr,
1079: "tms%d: hard error bn%d\n",
1080: minor(bp->b_dev)&03, bp->b_blkno);
1081: log(TMS_PRI, "tmscp%d: sa 0%o, state %d\n",um->um_ctlr,
1082: tmscpaddr->tmscpsa&0xffff, sc->sc_state);
1083: (void)tmscpinit(um->um_ctlr);
1084: /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */
1085: break;
1086: }
1087: /*
1088: * Default is that last command was NOT a write command;
1089: * if a write command is done it will be detected in tmscprsp.
1090: */
1091: tms->tms_lastiow = 0;
1092: if (ui->ui_flags == 0)
1093: { /* not online */
1094: if ((mp = tmscpgetcp(um)) == NULL)
1095: break;
1096: mp->mscp_opcode = M_OP_ONLIN;
1097: mp->mscp_unit = ui->ui_slave;
1098: dp->b_active = 2;
1099: um->um_tab.b_actf = dp->b_forw; /* remove from controller q */
1100: *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
1101: if (tmscpaddr->tmscpsa&TMSCP_ERR)
1102: printf("tmscp%d fatal error (0%o)\n",um->um_ctlr,
1103: tmscpaddr->tmscpsa&0xffff);
1104: i = tmscpaddr->tmscpip;
1105: continue;
1106: }
1107: switch (cpu) {
1108:
1109: case VAX_8600:
1110: case VAX_780:
1111: i = UBA_NEEDBDP|UBA_CANTWAIT;
1112: break;
1113: case VAX_750:
1114: i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
1115: break;
1116: case VAX_730:
1117: case VAX_630:
1118: i = UBA_CANTWAIT;
1119: break;
1120: } /* end switch (cpu) */
1121: /*
1122: * If command is an ioctl command then set the ioctl flag for later use.
1123: * If not (i.e. it is a read or write) then attempt
1124: * to set up a buffer pointer.
1125: */
1126: ioctl = 0;
1127: if (bp == &ctmscpbuf[um->um_ctlr])
1128: ioctl = 1;
1129: else
1130: if ((i = ubasetup(um->um_ubanum, bp, i)) == 0)
1131: {
1132: if(dp->b_qsize != 0)
1133: break; /* When a command completes and */
1134: /* frees a bdp tmscpstart will be called */
1135: if ((mp = tmscpgetcp(um)) == NULL)
1136: break;
1137: # ifdef DEBUG
1138: printd("tmscpstart: GTUNT %d ubasetup = %d\n",ui->ui_unit, i);
1139: if(tmscpdebug)DELAY(10000);
1140: # endif
1141: mp->mscp_opcode = M_OP_GTUNT;
1142: mp->mscp_unit = ui->ui_slave;
1143: *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
1144: if (tmscpaddr->tmscpsa&TMSCP_ERR)
1145: printf("tmscp%d: fatal error (0%o)\n",um->um_ctlr,
1146: tmscpaddr->tmscpsa&0xffff);
1147: i = tmscpaddr->tmscpip; /* initiate polling */
1148: break;
1149: }
1150: # if defined(VAX750)
1151: if (cpu == VAX_750)
1152: tempi = i & 0xfffffff; /* mask off bdp */
1153: else
1154: # endif
1155: tempi = i;
1156: if ((mp = tmscpgetcp(um)) == NULL)
1157: {
1158: if (!ioctl) /* only need to release if NOT ioctl */
1159: ubarelse(um->um_ubanum,&tempi);
1160: break;
1161: }
1162: mp->mscp_cmdref = (long)bp; /* pointer to get back */
1163: mp->mscp_unit = ui->ui_slave;
1164: /*
1165: * If its an ioctl-type command then set up the appropriate
1166: * tmscp command; by doing a switch on the "b_resid" field where
1167: * the command mneumonic is stored.
1168: */
1169: if (ioctl)
1170: {
1171: # ifdef DEBUG
1172: printd("tmscpstart: doing ioctl cmd %d\n", bp->b_resid);
1173: # endif
1174: /*
1175: * The reccnt and tmkcnt fields are set to zero by the getcp
1176: * routine (as bytecnt and buffer fields). Thus reccnt and
1177: * tmkcnt are only modified here if they need to be set to
1178: * a non-zero value.
1179: */
1180: switch ((int)bp->b_resid) {
1181:
1182: case TMS_WRITM:
1183: mp->mscp_opcode = M_OP_WRITM;
1184: break;
1185: case TMS_FSF:
1186: mp->mscp_opcode = M_OP_REPOS;
1187: mp->mscp_tmkcnt = bp->b_bcount;
1188: break;
1189: case TMS_BSF:
1190: mp->mscp_opcode = M_OP_REPOS;
1191: mp->mscp_modifier = M_MD_REVRS;
1192: mp->mscp_tmkcnt = bp->b_bcount;
1193: break;
1194: case TMS_FSR:
1195: mp->mscp_opcode = M_OP_REPOS;
1196: mp->mscp_modifier = M_MD_OBJCT;
1197: mp->mscp_reccnt = bp->b_bcount;
1198: break;
1199: case TMS_BSR:
1200: mp->mscp_opcode = M_OP_REPOS;
1201: mp->mscp_modifier = M_MD_REVRS | M_MD_OBJCT;
1202: mp->mscp_reccnt = bp->b_bcount;
1203: break;
1204: /*
1205: * Clear serious exception is done for Rewind & Available cmds
1206: */
1207: case TMS_REW:
1208: mp->mscp_opcode = M_OP_REPOS;
1209: mp->mscp_modifier = M_MD_REWND | M_MD_CLSEX;
1210: if (bp->b_bcount == 0)
1211: mp->mscp_modifier |= M_MD_IMMED;
1212: tms->tms_serex = 0;
1213: break;
1214: case TMS_OFFL:
1215: mp->mscp_opcode = M_OP_AVAIL;
1216: mp->mscp_modifier = M_MD_UNLOD | M_MD_CLSEX;
1217: tms->tms_serex = 0;
1218: break;
1219: case TMS_SENSE:
1220: mp->mscp_opcode = M_OP_GTUNT;
1221: break;
1222: case TMS_CACHE:
1223: mp->mscp_opcode = M_OP_STUNT;
1224: tms->tms_unitflgs |= M_UF_WBKNV;
1225: mp->mscp_unitflgs = tms->tms_unitflgs;
1226: mp->mscp_format = tms->tms_format;
1227: /* default device dependant parameters */
1228: mp->mscp_mediaid = 0;
1229: break;
1230: case TMS_NOCACHE:
1231: mp->mscp_opcode = M_OP_STUNT;
1232: tms->tms_unitflgs &= ~(M_UF_WBKNV);
1233: mp->mscp_unitflgs = tms->tms_unitflgs;
1234: mp->mscp_format = tms->tms_format;
1235: /* default device dependant parameters */
1236: mp->mscp_mediaid = 0;
1237: break;
1238: case TMS_CSE:
1239: /*
1240: * This is a no-op command. It performs a
1241: * clear serious exception only. (Done on a
1242: * non-rewinding close after a serious exception.)
1243: */
1244: mp->mscp_opcode = M_OP_REPOS;
1245: mp->mscp_modifier = M_MD_CLSEX;
1246: tms->tms_serex = 0;
1247: tms->tms_clserex = 1;
1248: break;
1249: case TMS_LOWDENSITY:
1250: /*
1251: * Set the unit to low density
1252: */
1253: mp->mscp_opcode = M_OP_STUNT;
1254: mp->mscp_unitflgs = tms->tms_unitflgs;
1255: mp->mscp_mediaid = 0; /* default device dependant parameters */
1256: if ((tms->tms_fmtmenu & M_TF_800) != 0)
1257: mp->mscp_format = M_TF_800;
1258: else
1259: mp->mscp_format = M_TF_PE & tms->tms_fmtmenu;
1260: tms->tms_format = mp->mscp_format;
1261: break;
1262: case TMS_HIDENSITY:
1263: /*
1264: * Set the unit to high density (format == 0)
1265: */
1266: mp->mscp_opcode = M_OP_STUNT;
1267: mp->mscp_unitflgs = tms->tms_unitflgs;
1268: mp->mscp_mediaid = 0; /* default device dependant parameters */
1269: mp->mscp_format = 0;
1270: tms->tms_format = 0;
1271: break;
1272: default:
1273: printf("Bad ioctl on tms unit %d\n", ui->ui_unit);
1274: /* Need a no-op. Reposition no amount */
1275: mp->mscp_opcode = M_OP_REPOS;
1276: break;
1277: } /* end switch (bp->b_resid) */
1278: }
1279: else /* Its a read/write command (not an ioctl) */
1280: {
1281: mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
1282: mp->mscp_bytecnt = bp->b_bcount;
1283: mp->mscp_buffer = UBAI_ADDR(i) | (UBAI_BDP(i) << 24);
1284:
1285: bp->b_ubinfo = tempi; /* save mapping info */
1286: }
1287: if (tms->tms_serex == 2) /* if tape mark read */
1288: {
1289: mp->mscp_modifier |= M_MD_CLSEX; /* clear serious exc */
1290: tms->tms_serex = 0;
1291: }
1292: *((long *)mp->mscp_dscptr) |= TMSCP_OWN|TMSCP_INT;
1293: # ifdef DEBUG
1294: printd("tmscpstart: opcode 0%o mod %o unit %d cnt %d\n",mp->mscp_opcode,mp->mscp_modifier,mp->mscp_unit,mp->mscp_bytecnt);
1295: if(tmscpdebug)DELAY(100000);
1296: # endif
1297: i = tmscpaddr->tmscpip; /* initiate polling */
1298: dp->b_qsize++;
1299: /*
1300: * Move drive to the end of the controller queue
1301: */
1302: if (dp->b_forw != NULL)
1303: {
1304: um->um_tab.b_actf = dp->b_forw;
1305: um->um_tab.b_actl->b_forw = dp;
1306: um->um_tab.b_actl = dp;
1307: dp->b_forw = NULL;
1308: }
1309: /*
1310: * Move buffer to I/O wait queue
1311: */
1312: dp->b_actf = bp->av_forw;
1313: dp = &tmscpwtab[um->um_ctlr];
1314: bp->av_forw = dp;
1315: bp->av_back = dp->av_back;
1316: dp->av_back->av_forw = bp;
1317: dp->av_back = bp;
1318: if (tmscpaddr->tmscpsa&TMSCP_ERR)
1319: {
1320: printf("tmscp%d: fatal error (0%o)\n", um->um_ctlr, tmscpaddr->tmscpsa&0xffff);
1321: (void)tmscpinit(um->um_ctlr);
1322: break;
1323: }
1324: } /* end for */
1325: /*
1326: * Check for response ring transitions lost in the
1327: * Race condition
1328: */
1329: for (i = sc->sc_lastrsp;; i++)
1330: {
1331: i %= NRSP;
1332: if (tm->tmscp_ca.ca_rspdsc[i]&TMSCP_OWN)
1333: break;
1334: tmscprsp(um, tm, sc, i);
1335: tm->tmscp_ca.ca_rspdsc[i] |= TMSCP_OWN;
1336: }
1337: sc->sc_lastrsp = i;
1338: }
1339:
1340:
1341: /*
1342: * Process a response packet
1343: */
1344: tmscprsp(um, tm, sc, i)
1345: register struct uba_ctlr *um;
1346: register struct tmscp *tm;
1347: register struct tmscp_softc *sc;
1348: int i;
1349: {
1350: register struct mscp *mp;
1351: register struct tms_info *tms;
1352: struct uba_device *ui;
1353: struct buf *dp, *bp;
1354: int st;
1355:
1356: mp = &tm->tmscp_rsp[i];
1357: mp->mscp_header.tmscp_msglen = mscp_msglen;
1358: sc->sc_credits += mp->mscp_header.tmscp_credits & 0xf; /* low 4 bits */
1359: if ((mp->mscp_header.tmscp_credits & 0xf0) > 0x10) /* Check */
1360: return;
1361: # ifdef DEBUG
1362: printd("tmscprsp, opcode 0%o status 0%o\n",mp->mscp_opcode,mp->mscp_status&M_ST_MASK);
1363: # endif
1364: /*
1365: * If it's an error log message (datagram),
1366: * pass it on for more extensive processing.
1367: */
1368: if ((mp->mscp_header.tmscp_credits & 0xf0) == 0x10)
1369: { /* check */
1370: tmserror(um, (struct mslg *)mp);
1371: return;
1372: }
1373: st = mp->mscp_status&M_ST_MASK;
1374: /*
1375: * The controller interrupts as drive 0.
1376: * This means that you must check for controller interrupts
1377: * before you check to see if there is a drive 0.
1378: */
1379: if((M_OP_STCON|M_OP_END) == mp->mscp_opcode)
1380: {
1381: if (st == M_ST_SUCC)
1382: {
1383: # ifdef DEBUG
1384: printd("ctlr has %d credits\n", mp->mscp_header.tmscp_credits & 0xf);
1385: printd("ctlr timeout = %d\n", mp->mscp_cnttmo);
1386: # endif
1387: sc->sc_state = S_RUN;
1388: }
1389: else
1390: sc->sc_state = S_IDLE;
1391: um->um_tab.b_active = 0;
1392: wakeup((caddr_t)um);
1393: return;
1394: }
1395: if (mp->mscp_unit >= NTMS)
1396: return;
1397: if ((ui = tmscpip[um->um_ctlr][mp->mscp_unit]) == 0)
1398: return;
1399: tms = &tms_info[ui->ui_unit];
1400: /*
1401: * Save endcode, endflags, and status for mtioctl get unit status.
1402: * NOTE: Don't do this on Clear serious exception (reposition no-op);
1403: * which is done on close since this would
1404: * overwrite the real status we want.
1405: */
1406: if (tms->tms_clserex != 1)
1407: {
1408: tms->tms_endcode = mp->mscp_opcode;
1409: tms->tms_flags = mp->mscp_flags;
1410: tms->tms_status = st;
1411: }
1412: else tms->tms_clserex = 0;
1413:
1414: switch (mp->mscp_opcode) {
1415: case M_OP_ONLIN|M_OP_END:
1416: tms->tms_type = mp->mscp_mediaid;
1417: dp = &tmsutab[ui->ui_unit];
1418: if (st == M_ST_SUCC)
1419: {
1420: /*
1421: * Link the drive onto the controller queue
1422: */
1423: dp->b_forw = NULL;
1424: if (um->um_tab.b_actf == NULL)
1425: um->um_tab.b_actf = dp;
1426: else
1427: um->um_tab.b_actl->b_forw = dp;
1428: um->um_tab.b_actl = dp;
1429: ui->ui_flags = 1; /* mark it online */
1430: tms->tms_dsize=(daddr_t)mp->mscp_maxwrt;
1431: # ifdef DEBUG
1432: printd("tmscprsp: unit %d online\n", mp->mscp_unit);
1433: # endif
1434: /*
1435: * This define decodes the Media type identifier
1436: */
1437: # define F_to_C(x,i) ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ')
1438: # ifdef DEBUG
1439: printd("tmscprsp: unit %d online %x %c%c %c%c%c%d\n"
1440: ,mp->mscp_unit, mp->mscp_mediaid ,F_to_C(mp,4)
1441: ,F_to_C(mp,3), F_to_C(mp,2)
1442: ,F_to_C(mp,1), F_to_C(mp,0), mp->mscp_mediaid & 0x7f);
1443: # endif
1444: dp->b_active = 1;
1445: } /* end if st == M_ST_SUCC */
1446: else
1447: {
1448: if (bp = dp->b_actf)
1449: tprintf(tms->tms_tpr,
1450: "tms%d: hard error bn%d: OFFLINE\n",
1451: minor(bp->b_dev)&03, bp->b_blkno);
1452: else
1453: tprintf(tms->tms_tpr,
1454: "tms%d: hard error: OFFLINE\n",
1455: ui->ui_unit);
1456: while (bp = dp->b_actf)
1457: {
1458: dp->b_actf = bp->av_forw;
1459: bp->b_flags |= B_ERROR;
1460: iodone(bp);
1461: }
1462: }
1463: if(mp->mscp_cmdref!=NULL)
1464: /* Seems to get lost sometimes in uda */
1465: wakeup((caddr_t)mp->mscp_cmdref);
1466: break;
1467: /*
1468: * The AVAILABLE ATTENTION message occurs when the
1469: * unit becomes available after loading,
1470: * marking the unit offline (ui_flags = 0) will force an
1471: * online command prior to using the unit.
1472: */
1473: case M_OP_AVATN:
1474: ui->ui_flags = 0;
1475: tms->tms_type = mp->mscp_mediaid;
1476: break;
1477: case M_OP_END:
1478: /*
1479: * An endcode without an opcode (0200) is an invalid command.
1480: * The mscp specification states that this would be a protocol
1481: * type error, such as illegal opcodes. The mscp spec. also
1482: * states that parameter error type of invalid commands should
1483: * return the normal end message for the command. This does not appear
1484: * to be the case. An invalid logical block number returned an endcode
1485: * of 0200 instead of the 0241 (read) that was expected.
1486: */
1487:
1488: printf("tmscp%d: invalid cmd, endcode = %o, status=%o\n",
1489: um->um_ctlr, mp->mscp_opcode, st);
1490: bp = (struct buf *)mp->mscp_cmdref;
1491: /*
1492: * Unlink buffer from I/O wait queue.
1493: * And signal iodone, so the higher level command can exit!
1494: *
1495: */
1496: bp->av_back->av_forw = bp->av_forw;
1497: bp->av_forw->av_back = bp->av_back;
1498: dp = &tmsutab[ui->ui_unit];
1499: dp->b_qsize--;
1500: iodone(bp);
1501: break;
1502: case M_OP_WRITE|M_OP_END:
1503: /* mark the last io op as a write */
1504: tms->tms_lastiow = 1;
1505: case M_OP_READ|M_OP_END:
1506: case M_OP_WRITM|M_OP_END:
1507: case M_OP_REPOS|M_OP_END:
1508: case M_OP_STUNT|M_OP_END:
1509: /*
1510: * The AVAILABLE message occurs when the mt ioctl "rewoffl" is
1511: * issued. For the ioctl, "rewoffl", a tmscp AVAILABLE command is
1512: * done with the UNLOAD modifier. This performs a rewind, followed
1513: * by marking the unit offline. So mark the unit offline
1514: * software wise as well (ui_flags = 0 and
1515: * tms->tms_openf = 0).
1516: */
1517: case M_OP_AVAIL|M_OP_END:
1518: # ifdef DEBUG
1519: printd("tmscprsp: position = %d\n", mp->mscp_lbn);
1520: # endif
1521: bp = (struct buf *)mp->mscp_cmdref;
1522: /*
1523: * Only need to release buffer if the command was read or write.
1524: * No ubasetup was done in "tmscpstart" if it was an ioctl cmd.
1525: */
1526: if (mp->mscp_opcode == (M_OP_READ|M_OP_END) ||
1527: mp->mscp_opcode == (M_OP_WRITE|M_OP_END))
1528: ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo);
1529: /*
1530: * Unlink buffer from I/O wait queue.
1531: */
1532: bp->av_back->av_forw = bp->av_forw;
1533: bp->av_forw->av_back = bp->av_back;
1534: # if defined(VAX750)
1535: if (cpu == VAX_750) {
1536: if ((tmscpwtab[um->um_ctlr].av_forw == &tmscpwtab[um->um_ctlr]) &&
1537: (um->um_ubinfo != 0)) {
1538: ubarelse(um->um_ubanum, &um->um_ubinfo);
1539: }
1540: else {
1541: if (mp->mscp_opcode == (M_OP_READ|M_OP_END) ||
1542: mp->mscp_opcode == (M_OP_WRITE|M_OP_END))
1543: UBAPURGE(uba_hd[um->um_ubanum].uh_uba,(um->um_ubinfo >>28) & 0x0f);
1544: }
1545: }
1546: # endif
1547: dp = &tmsutab[ui->ui_unit];
1548: dp->b_qsize--;
1549: if (st == M_ST_OFFLN || st == M_ST_AVLBL)
1550: {
1551: ui->ui_flags = 0; /* mark unit offline */
1552: tms->tms_openf = 0;
1553: tms->tms_type = mp->mscp_mediaid;
1554: /*
1555: * Link the buffer onto the front of the drive queue
1556: */
1557: if ((bp->av_forw = dp->b_actf) == 0)
1558: dp->b_actl = bp;
1559: dp->b_actf = bp;
1560: /*
1561: * Link the drive onto the controller queue
1562: */
1563: if (dp->b_active == 0)
1564: {
1565: dp->b_forw = NULL;
1566: if (um->um_tab.b_actf == NULL)
1567: um->um_tab.b_actf = dp;
1568: else
1569: um->um_tab.b_actl->b_forw = dp;
1570: um->um_tab.b_actl = dp;
1571: dp->b_active = 1;
1572: }
1573: # if defined(VAX750)
1574: if (cpu == VAX_750 && um->um_ubinfo == 0)
1575: um->um_ubinfo = uballoc(um->um_ubanum, (caddr_t)0, 0, UBA_NEEDBDP);
1576: # endif
1577: return;
1578: }
1579: if (st != M_ST_SUCC)
1580: {
1581: if (mp->mscp_flags & M_EF_SEREX)
1582: tms->tms_serex = 1;
1583: if (st != M_ST_TAPEM)
1584: {
1585: tprintf(tms->tms_tpr,
1586: "tms%d: hard error bn%d\n",
1587: minor(bp->b_dev)&03, bp->b_blkno);
1588: errinfo(st); /* produces more info */
1589: # ifdef DEBUG
1590: printd("tmscprsp: error; status sub-code = 0%o, flags = 0%o\n",
1591: (mp->mscp_status & 177740)>>5, mp->mscp_flags);
1592: # endif
1593: bp->b_flags |= B_ERROR;
1594: }
1595: else
1596: /* Hit a tape mark - Set serex flag to
1597: * a special value so we can clear the
1598: * serious exception on the next command.
1599: */
1600: tms->tms_serex = 2;
1601: }
1602: /*
1603: * The tmscp spec states that controllers do not have to
1604: * report the number of records or files skipped. So on
1605: * reposition commands we go strictly by cmd status.
1606: */
1607: if (mp->mscp_opcode != (M_OP_REPOS|M_OP_END))
1608: bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
1609: else
1610: bp->b_resid = 0;
1611: tms->tms_resid = bp->b_resid;
1612: iodone(bp);
1613: break;
1614:
1615: case M_OP_GTUNT|M_OP_END:
1616: # ifdef DEBUG
1617: printd("tmscprsp: GTUNT end packet status = 0%o\n",st);
1618: printd("tmscprsp: unit %d mediaid %x %c%c %c%c%c%d %x %x t=%d\n"
1619: ,mp->mscp_unit, mp->mscp_mediaid
1620: ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
1621: ,F_to_C(mp,1),F_to_C(mp,0)
1622: ,mp->mscp_mediaid & 0x7f
1623: ,mp->mscp_unitid.val[0]
1624: ,mp->mscp_unitid.val[1]
1625: ,mp->mscp_format);
1626: # endif
1627: tms->tms_type = mp->mscp_mediaid;
1628: tms->tms_fmtmenu = mp->mscp_fmtmenu;
1629: tms->tms_unitflgs = mp->mscp_unitflgs;
1630: break;
1631:
1632: default:
1633: printf("tmscp unknown packet\n");
1634: tmserror(um, (struct mslg *)mp);
1635: } /* end switch mp->mscp_opcode */
1636: }
1637:
1638:
1639: /*
1640: * Give a meaningful error when the mscp_status field returns an error code.
1641: */
1642:
1643: errinfo(st)
1644: int st; /* the status code */
1645: {
1646: switch(st) {
1647: case M_ST_ICMD:
1648: printf("invalid command\n");
1649: break;
1650: case M_ST_ABRTD:
1651: printf("command aborted\n");
1652: break;
1653: case M_ST_OFFLN:
1654: printf("unit offline\n");
1655: break;
1656: case M_ST_WRTPR:
1657: printf("unit write protected\n");
1658: break;
1659: case M_ST_COMP:
1660: printf("compare error\n");
1661: break;
1662: case M_ST_DATA:
1663: printf("data error\n");
1664: break;
1665: case M_ST_HSTBF:
1666: printf("host buffer access error\n");
1667: break;
1668: case M_ST_CNTLR:
1669: printf("controller error\n");
1670: break;
1671: case M_ST_DRIVE:
1672: printf("drive error\n");
1673: break;
1674: case M_ST_FMTER:
1675: printf("formatter error\n");
1676: break;
1677: case M_ST_BOT:
1678: printf("BOT encountered\n");
1679: break;
1680: case M_ST_TAPEM:
1681: printf("tape mark encountered\n");
1682: break;
1683: case M_ST_RDTRN:
1684: printf("record data truncated\n");
1685: break;
1686: case M_ST_PLOST:
1687: printf("position lost\n");
1688: break;
1689: case M_ST_SEX:
1690: printf("serious exception\n");
1691: break;
1692: case M_ST_LED:
1693: printf("LEOT detected\n");
1694: break;
1695: }
1696: }
1697:
1698:
1699: /*
1700: * Manage buffers and perform block mode read and write operations.
1701: */
1702:
1703: tmscpstrategy (bp)
1704: register struct buf *bp;
1705: {
1706: register struct uba_device *ui;
1707: register struct uba_ctlr *um;
1708: register struct buf *dp;
1709: register int unit = TMSUNIT(bp->b_dev);
1710: int s;
1711:
1712: if (unit >= NTMS)
1713: {
1714: # ifdef DEBUG
1715: printd ("tmscpstrategy: bad unit # %d\n",unit);
1716: # endif
1717: bp->b_flags |= B_ERROR;
1718: iodone(bp);
1719: return;
1720: }
1721: ui = tmsdinfo[unit];
1722: um = ui->ui_mi;
1723: if (ui == 0 || ui->ui_alive == 0)
1724: {
1725: bp->b_flags |= B_ERROR;
1726: iodone(bp);
1727: return;
1728: }
1729: s = spl5();
1730: /*
1731: * Link the buffer onto the drive queue
1732: */
1733: dp = &tmsutab[ui->ui_unit];
1734: if (dp->b_actf == 0)
1735: dp->b_actf = bp;
1736: else
1737: dp->b_actl->av_forw = bp;
1738: dp->b_actl = bp;
1739: bp->av_forw = 0;
1740: /*
1741: * Link the drive onto the controller queue
1742: */
1743: if (dp->b_active == 0)
1744: {
1745: dp->b_forw = NULL;
1746: if (um->um_tab.b_actf == NULL)
1747: um->um_tab.b_actf = dp;
1748: else
1749: um->um_tab.b_actl->b_forw = dp;
1750: um->um_tab.b_actl = dp;
1751: dp->b_active = 1;
1752: }
1753: /*
1754: * If the controller is not active, start it.
1755: */
1756: if (um->um_tab.b_active == 0)
1757: {
1758: # if defined(VAX750)
1759: if (cpu == VAX_750
1760: && tmscpwtab[um->um_ctlr].av_forw == &tmscpwtab[um->um_ctlr])
1761: {
1762: if (um->um_ubinfo != 0)
1763: log(TMS_PRI, "tmscpstrategy: ubinfo 0x%x\n",
1764: um->um_ubinfo);
1765: else
1766: um->um_ubinfo = uballoc(um->um_ubanum, (caddr_t)0, 0, UBA_NEEDBDP);
1767: }
1768: # endif
1769: # ifdef DEBUG
1770: printd10("tmscpstrategy: Controller not active, starting it\n");
1771: # endif
1772: (void) tmscpstart(um);
1773: }
1774: splx(s);
1775: return;
1776: }
1777:
1778: #define DBSIZE 32
1779:
1780: #define ca_Rspdsc ca_rspdsc[0]
1781: #define ca_Cmddsc ca_rspdsc[1]
1782: #define tmscp_Rsp tmscp_rsp[0]
1783: #define tmscp_Cmd tmscp_cmd[0]
1784:
1785: struct tmscp tmscpd[NTMSCP];
1786:
1787: tmscpdump(dev)
1788: dev_t dev;
1789: {
1790: struct tmscpdevice *tmscpaddr;
1791: struct tmscp *tmscp_ubaddr;
1792: char *start;
1793: int num, blk, unit;
1794: register struct uba_regs *uba;
1795: register struct uba_device *ui;
1796: register struct tmscp *tmscpp;
1797: register struct pte *io;
1798: register int i;
1799:
1800: unit = minor(dev) & 03;
1801: if (unit >= NTMS)
1802: return (ENXIO);
1803: # define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
1804: ui = phys(struct uba_device *, tmsdinfo[unit]);
1805: if (ui->ui_alive == 0)
1806: return (ENXIO);
1807: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
1808: ubainit(uba);
1809: tmscpaddr = (struct tmscpdevice *)ui->ui_physaddr;
1810: DELAY(2000000);
1811: tmscpp = phys(struct tmscp *, &tmscpd[ui->ui_ctlr]);
1812:
1813: num = btoc(sizeof(struct tmscp)) + 1;
1814: io = &uba->uba_map[NUBMREG-num];
1815: for(i = 0; i<num; i++)
1816: *(int *)io++ = UBAMR_MRV|(btop(tmscpp)+i);
1817: tmscp_ubaddr = (struct tmscp *)(((int)tmscpp & PGOFSET)|((NUBMREG-num)<<9));
1818:
1819: tmscpaddr->tmscpip = 0;
1820: while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
1821: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
1822: tmscpaddr->tmscpsa = TMSCP_ERR;
1823: while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
1824: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
1825: tmscpaddr->tmscpsa = (short)&tmscp_ubaddr->tmscp_ca.ca_ringbase;
1826: while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
1827: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
1828: tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16);
1829: while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
1830: if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
1831: tmscpaddr->tmscpsa = TMSCP_GO;
1832: tmscpp->tmscp_ca.ca_Rspdsc = (long)&tmscp_ubaddr->tmscp_Rsp.mscp_cmdref;
1833: tmscpp->tmscp_ca.ca_Cmddsc = (long)&tmscp_ubaddr->tmscp_Cmd.mscp_cmdref;
1834: tmscpp->tmscp_Cmd.mscp_header.tmscp_vcid = 1; /* for tape */
1835: tmscpp->tmscp_Cmd.mscp_cntflgs = 0;
1836: tmscpp->tmscp_Cmd.mscp_version = 0;
1837: if (tmscpcmd(M_OP_STCON, tmscpp, tmscpaddr) == 0) {
1838: return(EFAULT);
1839: }
1840: tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;
1841: if (tmscpcmd(M_OP_ONLIN, tmscpp, tmscpaddr) == 0) {
1842: return(EFAULT);
1843: }
1844:
1845: num = maxfree;
1846: start = 0;
1847: while (num > 0)
1848: {
1849: blk = num > DBSIZE ? DBSIZE : num;
1850: io = uba->uba_map;
1851: for (i = 0; i < blk; i++)
1852: *(int *)io++ = (btop(start)+i) | UBAMR_MRV;
1853: *(int *)io = 0;
1854: tmscpp->tmscp_Cmd.mscp_lbn = btop(start);
1855: tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;
1856: tmscpp->tmscp_Cmd.mscp_bytecnt = blk*NBPG;
1857: # ifdef MVAX
1858: if( cpu == MVAX_I )
1859: tmscpp->tmscp_Cmd.mscp_buffer = (long) start;
1860: else
1861: # endif MVAX
1862: tmscpp->tmscp_Cmd.mscp_buffer = 0;
1863: if (tmscpcmd(M_OP_WRITE, tmscpp, tmscpaddr) == 0)
1864: return(EIO);
1865: start += blk*NBPG;
1866: num -= blk;
1867: }
1868: return (0);
1869: }
1870:
1871:
1872: /*
1873: * Perform a standalone tmscp command. This routine is only used by tmscpdump.
1874: */
1875:
1876: tmscpcmd(op, tmscpp, tmscpaddr)
1877: int op;
1878: register struct tmscp *tmscpp;
1879: struct tmscpdevice *tmscpaddr;
1880: {
1881: int i;
1882:
1883:
1884: tmscpp->tmscp_Cmd.mscp_opcode = op;
1885: tmscpp->tmscp_Rsp.mscp_header.tmscp_msglen = mscp_msglen;
1886: tmscpp->tmscp_Cmd.mscp_header.tmscp_msglen = mscp_msglen;
1887: tmscpp->tmscp_ca.ca_Rspdsc |= TMSCP_OWN|TMSCP_INT;
1888: tmscpp->tmscp_ca.ca_Cmddsc |= TMSCP_OWN|TMSCP_INT;
1889: if (tmscpaddr->tmscpsa&TMSCP_ERR)
1890: printf("tmscp fatal error (0%o)\n", tmscpaddr->tmscpsa&0xffff);
1891: i = tmscpaddr->tmscpip;
1892: #ifdef lint
1893: i = i;
1894: #endif
1895: for (;;)
1896: {
1897: if (tmscpp->tmscp_ca.ca_cmdint)
1898: tmscpp->tmscp_ca.ca_cmdint = 0;
1899: if (tmscpp->tmscp_ca.ca_rspint)
1900: break;
1901: }
1902: tmscpp->tmscp_ca.ca_rspint = 0;
1903: if (tmscpp->tmscp_Rsp.mscp_opcode != (op|M_OP_END) ||
1904: (tmscpp->tmscp_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC)
1905: {
1906: printf("error: com %d opc 0x%x stat 0x%x\ndump ", op,
1907: tmscpp->tmscp_Rsp.mscp_opcode, tmscpp->tmscp_Rsp.mscp_status);
1908: return(0);
1909: }
1910: return(1);
1911: }
1912:
1913: /*
1914: * Catch ioctl commands, and call the "command" routine to do them.
1915: */
1916:
1917: /* ARGSUSED */
1918: tmscpioctl(dev, cmd, data, flag)
1919: dev_t dev;
1920: int cmd;
1921: caddr_t data;
1922: int flag;
1923: {
1924: register struct buf *bp = &ctmscpbuf[TMSCPCTLR(dev)];
1925: register callcount; /* number of times to call cmd routine */
1926: register struct uba_device *ui;
1927: register struct tms_info *tms;
1928: int fcount; /* number of files (or records) to space */
1929: int error = 0;
1930: register struct mtop *mtop; /* mag tape cmd op to perform */
1931: register struct mtget *mtget; /* mag tape struct to get info in */
1932:
1933: /* we depend of the values and order of the TMS ioctl codes here */
1934: static tmsops[] =
1935: {TMS_WRITM,TMS_FSF,TMS_BSF,TMS_FSR,TMS_BSR,TMS_REW,TMS_OFFL,TMS_SENSE,
1936: TMS_CACHE,TMS_NOCACHE};
1937:
1938: switch (cmd) {
1939: case MTIOCTOP: /* tape operation */
1940: mtop = (struct mtop *)data;
1941: switch (mtop->mt_op) {
1942:
1943: case MTWEOF:
1944: callcount = mtop->mt_count;
1945: fcount = 1;
1946: break;
1947: case MTFSF: case MTBSF:
1948: case MTFSR: case MTBSR:
1949: callcount = 1;
1950: fcount = mtop->mt_count;
1951: break;
1952: case MTREW: case MTOFFL: case MTNOP:
1953: case MTCACHE: case MTNOCACHE:
1954: callcount = 1;
1955: fcount = 1; /* wait for this rewind */
1956: break;
1957: default:
1958: return (ENXIO);
1959: } /* end switch mtop->mt_op */
1960:
1961: if (callcount <= 0 || fcount <= 0)
1962: return (EINVAL);
1963: while (--callcount >= 0)
1964: {
1965: tmscpcommand(dev, tmsops[mtop->mt_op], fcount);
1966: if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
1967: bp->b_resid)
1968: return (EIO);
1969: if (bp->b_flags & B_ERROR) /* like hitting BOT */
1970: break;
1971: }
1972: if (bp->b_flags&B_ERROR)
1973: if ((error = bp->b_error)==0)
1974: return (EIO);
1975: return (error);
1976:
1977: case MTIOCGET:
1978: /*
1979: * Return status info associated with the particular UNIT.
1980: */
1981: ui = tmsdinfo[TMSUNIT(dev)];
1982: tms = &tms_info[ui->ui_unit];
1983: mtget = (struct mtget *)data;
1984: mtget->mt_type = MT_ISTMSCP;
1985: mtget->mt_dsreg = tms->tms_flags << 8;
1986: mtget->mt_dsreg |= tms->tms_endcode;
1987: mtget->mt_erreg = tms->tms_status;
1988: mtget->mt_resid = tms->tms_resid;
1989: break;
1990:
1991: default:
1992: return (ENXIO);
1993: }
1994: return (0);
1995: }
1996:
1997:
1998: /*
1999: * Reset (for raw mode use only).
2000: */
2001:
2002: tmscpreset (uban)
2003: int uban;
2004: {
2005: register struct uba_ctlr *um;
2006: register struct uba_device *ui;
2007: register struct buf *bp, *dp;
2008: register int unit;
2009: struct buf *nbp;
2010: int d;
2011:
2012: for (d = 0; d < NTMSCP; d++)
2013: {
2014: if ((um = tmscpminfo[d]) == 0 || um->um_ubanum != uban ||
2015: um->um_alive == 0)
2016: continue;
2017: printf(" tmscp%d", d);
2018: um->um_tab.b_active = 0;
2019: um->um_tab.b_actf = um->um_tab.b_actl = 0;
2020: tmscp_softc[d].sc_state = S_IDLE;
2021: tmscp_softc[d].sc_mapped = 0;
2022: for (unit = 0; unit < NTMS; unit++)
2023: {
2024: if ((ui = tmsdinfo[unit]) == 0)
2025: continue;
2026: if (ui->ui_alive == 0 || ui->ui_mi != um)
2027: continue;
2028: tmsutab[unit].b_active = 0;
2029: tmsutab[unit].b_qsize = 0;
2030: }
2031: for (bp = tmscpwtab[d].av_forw; bp != &tmscpwtab[d]; bp = nbp)
2032: {
2033: nbp = bp->av_forw;
2034: bp->b_ubinfo = 0;
2035: /*
2036: * Link the buffer onto the drive queue
2037: */
2038: dp = &tmsutab[TMSUNIT(bp->b_dev)];
2039: if (dp->b_actf == 0)
2040: dp->b_actf = bp;
2041: else
2042: dp->b_actl->av_forw = bp;
2043: dp->b_actl = bp;
2044: bp->av_forw = 0;
2045: /*
2046: * Link the drive onto the controller queue
2047: */
2048: if (dp->b_active == 0)
2049: {
2050: dp->b_forw = NULL;
2051: if (um->um_tab.b_actf == NULL)
2052: um->um_tab.b_actf = dp;
2053: else
2054: um->um_tab.b_actl->b_forw = dp;
2055: um->um_tab.b_actl = dp;
2056: dp->b_active = 1;
2057: }
2058: }
2059: (void)tmscpinit(d);
2060: }
2061: }
2062:
2063:
2064: /*
2065: * Process an error log message
2066: *
2067: * Only minimal decoding is done, only "useful"
2068: * information is printed. Eventually should
2069: * send message to an error logger.
2070: */
2071:
2072: tmserror(um, mp)
2073: register struct uba_ctlr *um;
2074: register struct mslg *mp;
2075: {
2076: register i;
2077:
2078: # ifdef DEBUG
2079: printd("tmserror:\n");
2080: # endif
2081: if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
2082: log(TMS_PRI, "tmscp%d: %s error, ", um->um_ctlr,
2083: mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
2084:
2085: switch (mp->mslg_format) {
2086:
2087: case M_FM_CNTERR:
2088: log(TMS_PRI, "controller error, event 0%o\n", mp->mslg_event);
2089: break;
2090: case M_FM_BUSADDR:
2091: log(TMS_PRI, "host memory access error, event 0%o, addr 0%o\n",
2092: mp->mslg_event, mp->mslg_busaddr);
2093: break;
2094: case M_FM_TAPETRN:
2095: log(TMS_PRI, "tape transfer error, unit %d, grp 0x%x, event 0%o\n",
2096: mp->mslg_unit, mp->mslg_group, mp->mslg_event);
2097: break;
2098: case M_FM_STIERR:
2099: log(TMS_PRI, "STI error, unit %d, event 0%o\n",
2100: mp->mslg_unit, mp->mslg_event);
2101: #ifdef notdef
2102: /* too painful to do with log() */
2103: for(i = 0; i < 62;i++)
2104: mprintf("\t0x%x",mp->mslg_stiunsucc[i] & 0xff);
2105: mprintf("\n");
2106: #endif
2107: break;
2108: case M_FM_STIDEL:
2109: log(TMS_PRI, "STI Drive Error Log, unit %d, event 0%o\n",
2110: mp->mslg_unit, mp->mslg_event);
2111: break;
2112: case M_FM_STIFEL:
2113: log(TMS_PRI, "STI Formatter Error Log, unit %d, event 0%o\n",
2114: mp->mslg_unit, mp->mslg_event);
2115: break;
2116: default:
2117: log(TMS_PRI, "unknown error, unit %d, format 0%o, event 0%o\n",
2118: mp->mslg_unit, mp->mslg_format, mp->mslg_event);
2119: }
2120:
2121: if (tmscperror)
2122: {
2123: register long *p = (long *)mp;
2124:
2125: for (i = 0; i < mp->mslg_header.tmscp_msglen; i += sizeof(*p))
2126: printf("%x ", *p++);
2127: printf("\n");
2128: }
2129: }
2130: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.