xref: /csrg-svn/sys/vax/stand/mt.c (revision 10776)
1*10776Ssam /*	mt.c	4.5	83/02/08	*/
25151Ssam 
35151Ssam /*
45151Ssam  * TM78/TU78 tape driver
5*10776Ssam  * Made to work reliably by by Jeffrey R. Schwab (Purdue)
65151Ssam  */
79806Ssam #include "../machine/pte.h"
85151Ssam 
95151Ssam #include "../h/param.h"
105151Ssam #include "../h/inode.h"
117446Sroot #include "../h/fs.h"
129186Ssam 
139186Ssam #include "../vaxmba/mtreg.h"
149186Ssam #include "../vaxmba/mbareg.h"
159186Ssam 
165151Ssam #include "saio.h"
175151Ssam #include "savax.h"
185151Ssam 
195151Ssam short	mttypes[] =
205151Ssam 	{ MBDT_TU78, 0 };
215151Ssam 
225151Ssam #define	MASKREG(reg)	((reg)&0xffff)
235151Ssam 
245151Ssam mtopen(io)
255151Ssam 	register struct iob *io;
265151Ssam {
275151Ssam 	register int skip;
28*10776Ssam 	register struct mtdevice *mtaddr =
29*10776Ssam 		(struct mtdevice *)mbadrv(io->i_unit);
305151Ssam 	int i;
315151Ssam 
325151Ssam 	for (i = 0; mttypes[i]; i++)
335151Ssam 		if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
345151Ssam 			goto found;
355151Ssam 	_stop("not a tape\n");
365151Ssam found:
375151Ssam 	mbainit(UNITTOMBA(io->i_unit));
385151Ssam 	mtaddr->mtid = MTID_CLR;
395151Ssam 	DELAY(250);
405151Ssam 	while ((mtaddr->mtid & MTID_RDY) == 0)
415151Ssam 		;
42*10776Ssam 
43*10776Ssam 	/* clear any attention bits present on open */
44*10776Ssam 	i = mtaddr->mtner;
45*10776Ssam 	mtaddr->mtas = mtaddr->mtas;
46*10776Ssam 
475151Ssam 	mtstrategy(io, MT_REW);
485151Ssam 	skip = io->i_boff;
495151Ssam 	while (skip--) {
505151Ssam 		io->i_cc = -1;
515151Ssam 		mtstrategy(io, MT_SFORWF);
525151Ssam 	}
535151Ssam }
545151Ssam 
555151Ssam mtclose(io)
565151Ssam 	register struct iob *io;
575151Ssam {
585151Ssam 
595151Ssam 	mtstrategy(io, MT_REW);
605151Ssam }
615151Ssam 
625151Ssam mtstrategy(io, func)
635151Ssam 	register struct iob *io;
645151Ssam 	int func;
655151Ssam {
665151Ssam 	register int errcnt, s, ic;
675151Ssam 	register struct mtdevice *mtaddr =
685151Ssam 	    (struct mtdevice *)mbadrv(io->i_unit);
69*10776Ssam 	struct mba_regs *mba = mbamba(io->i_unit);
705151Ssam 
715151Ssam 	errcnt = 0;
725151Ssam retry:
73*10776Ssam 	/* code to trap for attention up prior to start of command */
74*10776Ssam 	if ((mtaddr->mtas & 0xffff) != 0) {
75*10776Ssam 		printf("mt unexpected attention er=%x - continuing\n",
76*10776Ssam 			MASKREG(mtaddr->mtner));
77*10776Ssam 		mtaddr->mtas = mtaddr->mtas;
78*10776Ssam 	}
79*10776Ssam 
805151Ssam 	if (func == READ || func == WRITE) {
815151Ssam 		mtaddr->mtca = 1<<2;	/* 1 record */
825151Ssam 		mtaddr->mtbc = io->i_cc;
835151Ssam 		mbastart(io, func);
84*10776Ssam 		/* wait for mba to go idle and read result status */
85*10776Ssam 		while((mba->mba_sr & MBSR_DTBUSY) != 0)
86*10776Ssam 			;
87*10776Ssam 		ic = mtaddr->mter & MTER_INTCODE;
885151Ssam 	} else {
895151Ssam 		mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
905151Ssam 	rwait:
915151Ssam 		do
925151Ssam 			s = mtaddr->mtas&0xffff;
935151Ssam 		while (s == 0);
94*10776Ssam 		ic = mtaddr->mtner & MTER_INTCODE;
955151Ssam 		mtaddr->mtas = mtaddr->mtas;	/* clear attention */
965151Ssam 	}
975151Ssam 	switch (ic) {
985151Ssam 	case MTER_TM:
995151Ssam 	case MTER_EOT:
1005151Ssam 	case MTER_LEOT:
1015151Ssam 		return (0);
1025151Ssam 
1035151Ssam 	case MTER_DONE:
104*10776Ssam 		/* make sure a record was read */
105*10776Ssam 		if ((mtaddr->mtca & (1 << 2)) != 0) {
106*10776Ssam 			printf("mt record count not decremented - retrying\n");
107*10776Ssam 			goto retry;
108*10776Ssam 		}
1095151Ssam 		break;
1105151Ssam 
1115151Ssam 	case MTER_RWDING:
1125151Ssam 		goto rwait;
1135151Ssam 	default:
114*10776Ssam 		printf("mt hard error: er=%x\n",
1155151Ssam 		    MASKREG(mtaddr->mter));
1165151Ssam 		mtaddr->mtid = MTID_CLR;
1175151Ssam 		DELAY(250);
1185151Ssam 		while ((mtaddr->mtid & MTID_RDY) == 0)
1195151Ssam 			;
1205151Ssam 		return (-1);
1215151Ssam 
1225151Ssam 	case MTER_RETRY:
123*10776Ssam 		printf("mt error: er=%x\n", MASKREG(mtaddr->mter));
1245151Ssam 		if (errcnt == 10) {
1255151Ssam 			printf("mt: unrecovered error\n");
1265151Ssam 			return (-1);
1275151Ssam 		}
1285151Ssam 		errcnt++;
1295151Ssam 		goto retry;
1305151Ssam 	}
1315151Ssam 	if (errcnt)
1325151Ssam 		printf("mt: recovered by retry\n");
1335151Ssam 	return (io->i_cc);	/* NO PARTIAL RECORD READS!!! */
1345151Ssam }
135