*BSD News Article 54954


Return to BSD News archive

Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!yarrina.connect.com.au!munnari.OZ.AU!spool.mu.edu!howland.reston.ans.net!news.nic.surfnet.nl!tuegate.tue.nl!asterix.urc.tue.nl!rcjvdb
From: rcjvdb@urc.tue.nl (Jan van den Bosch)
Newsgroups: comp.unix.bsd.freebsd.misc
Subject: Re: QIC-02 tape drive problemette
Date: 17 Nov 95 10:32:31 GMT
Organization: Eindhoven University of Technology, The Netherlands
Lines: 193
Message-ID: <rcjvdb.816604351@asterix.urc.tue.nl>
References: <47vrm6$j9h@yama.mcc.ac.uk> <4853i3$kf3@uriah.heep.sax.de>
NNTP-Posting-Host: asterix.urc.tue.nl
X-Newsreader: NN version 6.5.0 #10 (NOV)

j@uriah.heep.sax.de (J Wunsch) writes:

>Ian Pallfreeman <ip@mcc.ac.uk> wrote:
>>Although I've already done a successful dump on this drive, I'm getting:
>>
>>* bash# mt -f /dev/rwt0d status
>>* Wangtek tape drive, residual=0
>>* Nov 10 15:35:14 albatross /kernel: pid 8178: mt: uid 0: exited on signal 11
>>* Segmentation fault (core dumped)

>Known problem.  I think the core dump problem has been fixed recently,
>but nevertheless mt(1) doesn't report any useful status about wt-style
>drives (since it doesn't know about them).

>I promise to fix this some day.  It would reduce the time i need for
>fixing if somebody would drop a wt-style tape drive on me. :-)
>-- 
>cheers, J"org

The wt QIC02 tapedriver in the NetBSD1.0 version I am using is also
buggy. 
I don't know if it is also in other *BSD versions.
The bug is in .../sys/arch/i386/isa/wt.c.
I found a partial solution (one line of code). After changing it
the bug never occurred (to me) again. I also added some lines of code to
enable the mt program to give me some more information (about density).
There are still happening strange things if you are changing tapes with
different density's, but if I am staying with the same tape densities,
allways good back-ups are possible.
If someone who is really knowing the ins and outs of device drivers
has some suggestions about the problems I still have (when
changing tapes with different densities) then I will try them out.

Description of the problem:
The wt driver sometimes comes in a deadlock state.
It mostly happens when you are doing long backups. 
The only way to get out of it is a complete system reboot...

Reason:
In the Interrupt routine wtintr() there is no provision for 
stopping the timeout() if all i/o (one block) is completed
(state 'i/o finished'). If an interrupt is generated at this moment,
it comes in an unexpected state ('continue i/o'). In this state,
wtwait(), there is of course no wakeup, so it keeps sleeping eternaly..., 

Patch:
Allways put the timer off if i/o is finished.
Add one line before the last 3 lines of the function body
of wtintr(sc):
 	untimeout(wttimer, sc);


----context diff, patch in ../sys/arch/i386/isa directory:

*** wt.c.orig	Tue Mar 29 12:30:00 1994
--- wt.c	Wed Dec 28 22:33:41 1994
***************
*** 467,472 ****
--- 467,475 ----
  		((struct mtget*)addr)->mt_resid = 0;
  		((struct mtget*)addr)->mt_fileno = 0;		/* file */
  		((struct mtget*)addr)->mt_blkno = 0;		/* block */
+ /* JVDB added 231294 */
+ 		((struct mtget*)addr)->mt_density = sc->dens; 	/* density */
+ /**/
  		return 0;
  	case MTIOCTOP:
  		break;
***************
*** 485,497 ****
  	case MTNOCACHE:	/* disable controller cache */
  		return 0;
  	case MTREW:	/* rewind */
- 	case MTOFFL:	/* rewind and put the drive offline */
  		if (sc->flags & TPREW)   /* rewind is running */
  			return 0;
  		if (error = wtwait(sc, PCATCH, "wtorew"))
  			return error;
  		wtrewind(sc);
  		return 0;
  	case MTFSF:	/* forward space file */
  		for (count = ((struct mtop*)addr)->mt_count; count > 0;
  		    --count) {
--- 488,503 ----
  	case MTNOCACHE:	/* disable controller cache */
  		return 0;
  	case MTREW:	/* rewind */
  		if (sc->flags & TPREW)   /* rewind is running */
  			return 0;
  		if (error = wtwait(sc, PCATCH, "wtorew"))
  			return error;
  		wtrewind(sc);
  		return 0;
+ 	case MTOFFL:	/* put the drive offline */
+ 			/*JVDB: actually do a reset ... */
+ 		wtreset(sc);
+ 		return 0;
  	case MTFSF:	/* forward space file */
  		for (count = ((struct mtop*)addr)->mt_count; count > 0;
  		    --count) {
***************
*** 667,672 ****
--- 673,682 ----
  			sc->flags |= TPVOL;	/* end of file */
  		else
  			sc->flags |= TPEXCEP;	/* i/o error */
+ /* JVDB added 231294 */
+ 		/* stop timer going-off */
+ 		untimeout(wttimer, sc);
+ /**/
  		wakeup((caddr_t)sc);
  		return 1;
  	}
***************
*** 680,685 ****
--- 690,699 ----
  	}
  	if (sc->dmacount > sc->dmatotal)	/* short last block */
  		sc->dmacount = sc->dmatotal;
+ /* JVDB added 231294 */
+ 	/* stop timer going-off */
+ 	untimeout(wttimer, sc);
+ /**/
  	/* Wake up user level. */
  	wakeup((caddr_t)sc);
  	DEBUG(("i/o finished, %d\n", sc->dmacount));


------------------------- context diff mt programm

*** /usr/src/bin/mt/mt.c.orig	Tue Apr  5 23:13:55 1994
--- /usr/src/bin/mt/mt.c	Sat Dec 10 00:19:32 1994
***************
*** 49,54 ****
--- 49,57 ----
  #include <sys/types.h>
  #include <sys/ioctl.h>
  #include <sys/mtio.h>
+ #ifdef i386
+ #include "/sys/arch/i386/isa/wtreg.h"
+ #endif
  #include <fcntl.h>
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 195,200 ****
--- 198,207 ----
  #ifdef tahoe
  	{ MT_ISCY,	"cipher",	CYS_BITS,	CYCW_BITS },
  #endif
+ #ifdef i386
+ 	{ MT_ISVIPER1,	"Archive",	WTDS_BITS,	WTER_BITS },
+ /*	{ 7,		"scsi", 	0,	 	0 }, */
+ #endif
  	{ 0 }
  };
  
***************
*** 214,223 ****
--- 221,251 ----
  		printf("unknown tape drive type (%d)\n", bp->mt_type);
  		return;
  	}
+ #ifdef i386
+ 	printf("%s tape drive, ", mt->t_name);
+ 	if (bp->mt_blksiz)
+ 	  printf("block size = %d, ", bp->mt_blksiz);
+ 	else
+ 	  printf("variable block size, ");
+ 	switch (bp->mt_density /*& WT_DENSEL*/) {
+ 	case WT_QIC11:	printf("QIC 11");	break;
+ 	case WT_QIC24:	printf("QIC 24");	break;
+ 	case WT_QIC120:	printf("QIC 120");	break;
+ 	case WT_QIC150:	printf("QIC 150");	break;
+ /*	case WT_QIC525:	printf("QIC 525");	break;
+ 	case WT_QIC1320:	printf("QIC 1320");	break;
+ */
+ 	case 19:	printf("DDS");		break;
+ 	default:
+ 	  printf("density code = %d\n",  bp->mt_density);
+ 	}
+ 	putchar('\n');
+ #else
  	printf("%s tape drive, residual=%d\n", mt->t_name, bp->mt_resid);
  	printreg("ds", bp->mt_dsreg, mt->t_dsbits);
  	printreg("\ner", bp->mt_erreg, mt->t_erbits);
  	putchar('\n');
+ #endif
  }
  
  /*

****** rcjvdb@urc.tue.nl (Jan van den Bosch)