xref: /csrg-svn/sys/vax/stand/mt.c (revision 9186)
1*9186Ssam /*	mt.c	4.3	82/11/13	*/
25151Ssam 
35151Ssam /*
45151Ssam  * TM78/TU78 tape driver
55151Ssam  */
65151Ssam 
75151Ssam #include "../h/param.h"
8*9186Ssam #include "../h/pte.h"
95151Ssam #include "../h/inode.h"
107446Sroot #include "../h/fs.h"
11*9186Ssam 
12*9186Ssam #include "../vaxmba/mtreg.h"
13*9186Ssam #include "../vaxmba/mbareg.h"
14*9186Ssam 
155151Ssam #include "saio.h"
165151Ssam #include "savax.h"
175151Ssam 
185151Ssam short	mttypes[] =
195151Ssam 	{ MBDT_TU78, 0 };
205151Ssam 
215151Ssam #define	MASKREG(reg)	((reg)&0xffff)
225151Ssam 
235151Ssam mtopen(io)
245151Ssam 	register struct iob *io;
255151Ssam {
265151Ssam 	register int skip;
275151Ssam 	register struct mtdevice *mtaddr = (struct mtdevice *)mbadrv(io->i_unit);
285151Ssam 	int i;
295151Ssam 
305151Ssam 	for (i = 0; mttypes[i]; i++)
315151Ssam 		if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
325151Ssam 			goto found;
335151Ssam 	_stop("not a tape\n");
345151Ssam found:
355151Ssam 	mbainit(UNITTOMBA(io->i_unit));
365151Ssam 	mtaddr->mtid = MTID_CLR;
375151Ssam 	DELAY(250);
385151Ssam 	while ((mtaddr->mtid & MTID_RDY) == 0)
395151Ssam 		;
405151Ssam 	mtstrategy(io, MT_REW);
415151Ssam 	skip = io->i_boff;
425151Ssam 	while (skip--) {
435151Ssam 		io->i_cc = -1;
445151Ssam 		mtstrategy(io, MT_SFORWF);
455151Ssam 	}
465151Ssam }
475151Ssam 
485151Ssam mtclose(io)
495151Ssam 	register struct iob *io;
505151Ssam {
515151Ssam 
525151Ssam 	mtstrategy(io, MT_REW);
535151Ssam }
545151Ssam 
555151Ssam mtstrategy(io, func)
565151Ssam 	register struct iob *io;
575151Ssam 	int func;
585151Ssam {
595151Ssam 	register int errcnt, s, ic;
605151Ssam 	register struct mtdevice *mtaddr =
615151Ssam 	    (struct mtdevice *)mbadrv(io->i_unit);
625151Ssam 
635151Ssam 	errcnt = 0;
645151Ssam retry:
655151Ssam 	if (func == READ || func == WRITE) {
665151Ssam 		mtaddr->mtca = 1<<2;	/* 1 record */
675151Ssam 		mtaddr->mtbc = io->i_cc;
685151Ssam 		mtaddr->mter = 0;
695151Ssam 		mbastart(io, func);
705151Ssam 		do
715151Ssam 			s = mtaddr->mter & MTER_INTCODE;
725151Ssam 		while (s == 0);
735151Ssam 		ic = s;
745151Ssam 		DELAY(2000);
755151Ssam 	} else {
765151Ssam 		mtaddr->mtas = -1;
775151Ssam 		mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
785151Ssam 	rwait:
795151Ssam 		do
805151Ssam 			s = mtaddr->mtas&0xffff;
815151Ssam 		while (s == 0);
825151Ssam 		mtaddr->mtas = mtaddr->mtas;	/* clear attention */
835151Ssam 		ic = mtaddr->mtner & MTER_INTCODE;
845151Ssam 	}
855151Ssam 	switch (ic) {
865151Ssam 	case MTER_TM:
875151Ssam 	case MTER_EOT:
885151Ssam 	case MTER_LEOT:
895151Ssam 		return (0);
905151Ssam 
915151Ssam 	case MTER_DONE:
925151Ssam 		break;
935151Ssam 
945151Ssam 	case MTER_RWDING:
955151Ssam 		goto rwait;
965151Ssam 	default:
975151Ssam 		printf("mt hard error: er=%b\n",
985151Ssam 		    MASKREG(mtaddr->mter));
995151Ssam 		mtaddr->mtid = MTID_CLR;
1005151Ssam 		DELAY(250);
1015151Ssam 		while ((mtaddr->mtid & MTID_RDY) == 0)
1025151Ssam 			;
1035151Ssam 		return (-1);
1045151Ssam 
1055151Ssam 	case MTER_RETRY:
1065151Ssam 		printf("mt error: er=%b\n",
1075151Ssam 		    MASKREG(mtaddr->mter));
1085151Ssam 		if (errcnt == 10) {
1095151Ssam 			printf("mt: unrecovered error\n");
1105151Ssam 			return (-1);
1115151Ssam 		}
1125151Ssam 		errcnt++;
1135151Ssam 		goto retry;
1145151Ssam 	}
1155151Ssam 	if (errcnt)
1165151Ssam 		printf("mt: recovered by retry\n");
1175151Ssam 	return (io->i_cc);	/* NO PARTIAL RECORD READS!!! */
1185151Ssam }
119