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