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