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