Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Mar 2001 22:25:33 +0100
From:      Frederic LOYER <loyer@ensta.fr>
To:        "John R. Shannon" <john@johnrshannon.com>
Cc:        freebsd-hardware@FreeBSD.ORG
Subject:   Re: Multiple dumps to one tape
Message-ID:  <20010322222533.A931@quickstep.localnet>
In-Reply-To: <01032108471501.02015@pablo.johnrshannon.com>
References:  <01032108471501.02015@pablo.johnrshannon.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

On Thu, Mar 22, 2001 at 09:44:34AM -0700, John R. Shannon wrote:
> Is there a known problem with writing multiple archives to a Tecmar NS20 
> tapedrive Travan TR5)? I've tried two different units and get the same 
> results.
> 
> 
[...]
> /sbin/dump -0a -f /dev/nrsa0 /dev/da0s1e
>   DUMP: Date of this level 0 dump: Mon Mar 19 05:27:38 2001
>   DUMP: Date of last level 0 dump: the epoch
>   DUMP: Dumping /dev/da0s1e (/usr) to /dev/nrsa0
>   DUMP: mapping (Pass I) [regular files]
>   DUMP: mapping (Pass II) [directories]
>   DUMP: estimated 3647150 tape blocks.
>   DUMP: write error 20 blocks into volume 1
>   DUMP: Do you want to restart?: ("yes" or "no") no
>   DUMP: The ENTIRE dump is aborted.
> 
> And in /var/log/messages:
>   Mar 19 05:27:51 pablo /kernel: (sa0:adv0:0:4:0): WRITE(06). CDB: a 0 0 28 
> 0 0
>   Mar 19 05:27:51 pablo /kernel: (sa0:adv0:0:4:0): ILLEGAL REQUEST asc:50,0
>   Mar 19 05:27:51 pablo /kernel: (sa0:adv0:0:4:0): Write append error


I had the same problem with a Colorado 5Gb.  I had made the attached
patch to solved it (A little old... you could have some trouble to
apply it).

The patch does prevent FreeBSD to freeze until the end of an operation
when issuing an other one.

-- 
LOYER Frédéric <loyer@ensta.fr>

--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wst.patch"

*** wst.c.orig	Sat Feb 13 11:52:35 1999
--- wst.c	Wed Feb 24 22:17:20 1999
***************
*** 78,83 ****
--- 78,88 ----
  #define WST_DEBUG           	0x0010	/* Print debug info */
  #define WST_CTL_WARN           	0x0020	/* Have we warned about CTL wrong? */
  
+ #define WE_OK			0
+ #define WE_EOF			1
+ #define WE_EOM			2
+ #define WE_ERROR		3
+ 
  /* ATAPI tape commands not in std ATAPI command set */
  #define ATAPI_TAPE_REWIND   		0x01
  #define ATAPI_TAPE_REQUEST_SENSE   	0x03
***************
*** 184,194 ****
--- 189,208 ----
      struct atapi_params *param;     	/* Drive parameters table */
      struct wst_header header;       	/* MODE SENSE param header */
      struct wst_cappage cap;         	/* Capabilities page info */
+     int resid;				/* number of bytes not read */
+     int pending_error;			/* pending error */
  #ifdef  DEVFS
      void    *cdevs;
      void    *bdevs;
  #endif
  };
+ static int lock_eof=0;	/* needed for "locking" the
+ 			   EOF condition when physio
+ 			   execute wst_strategy twice.
+ 
+ 			   It would be best in wsttab, but this tab
+ 			   is seen by wstread.
+ 			*/
  
  static struct wst *wsttab[NUNIT];       /* Drive info by unit number */
  static int wstnlun = 0;                 /* Number of config'd drives */
***************
*** 397,402 ****
--- 411,417 ----
  static int
  wstread(dev_t dev, struct uio *uio, int ioflag)
  {
+ 	lock_eof=0;
  	return (physio(wststrategy, NULL, dev, 1, minphys, uio));
  }
  
***************
*** 420,425 ****
--- 435,458 ----
          return;
      }
  
+     switch(t->pending_error)
+       {
+       case WE_OK:
+ 	break;
+       case WE_EOM:
+ 	t->pending_error = WE_OK;
+ 	bp->b_error = ENOSPC;
+ 	bp->b_flags |= B_ERROR;
+         biodone(bp);
+ 	return;
+       case WE_EOF:
+ 	if(!lock_eof)
+ 	  t->pending_error = WE_OK;
+ 	bp->b_resid = bp->b_bcount;
+ 	biodone(bp);
+ 	return;
+       }
+ 
      /* Check for != blocksize requests */
      if (bp->b_bcount % t->blksize) {
          printf("wst%d: bad request, must be multiple of %d\n", lun, t->blksize);
***************
*** 456,461 ****
--- 489,505 ----
      wakeup((caddr_t)t);
  }
  
+ static void
+ wst_wait_dsc(struct wst *t)
+ {
+     /* Sleep waiting for a ready drive (DSC) */
+     if (t->ata->use_dsc && !(inb(t->ata->port + AR_STATUS) & ARS_DSC)) {
+         t->ata->wait_for_dsc = 1;
+         timeout((timeout_t*)wst_poll_dsc, t, DSC_POLL_INTERVAL);
+         tsleep((caddr_t) t, 0, "wstdsc", 0);
+     }
+ }
+ 
  static void 
  wst_start(struct wst *t)
  {
***************
*** 470,481 ****
      if (t->ata->wait_for_dsc)
  	printf("wst%d: ERROR! allready waiting for DSC\n", t->lun);
  
!     /* Sleep waiting for a ready drive (DSC) */
!     if (t->ata->use_dsc && !(inb(t->ata->port + AR_STATUS) & ARS_DSC)) {
!         t->ata->wait_for_dsc = 1;
!         timeout((timeout_t*)wst_poll_dsc, t, DSC_POLL_INTERVAL);
!         tsleep((caddr_t) t, 0, "wstdsc", 0);
!     }
  
      bufq_remove(&t->buf_queue, bp);
      blk_count = bp->b_bcount / t->blksize;
--- 514,520 ----
      if (t->ata->wait_for_dsc)
  	printf("wst%d: ERROR! allready waiting for DSC\n", t->lun);
  
!     wst_wait_dsc(t);
  
      bufq_remove(&t->buf_queue, bp);
      blk_count = bp->b_bcount / t->blksize;
***************
*** 502,514 ****
  {
      if (result.code) {
  	printf("wst_done: ");
!         wst_error(t, result);
!         bp->b_error = EIO;
!         bp->b_flags |= B_ERROR;
      }
!     else
! 	bp->b_resid = resid;
! 
      biodone(bp);
      /*wst_start(t);*/
  }
--- 541,575 ----
  {
      if (result.code) {
  	printf("wst_done: ");
!         switch(wst_error(t, result))
! 	  {
! 	  case WE_EOM:
! 	    bp->b_resid = t->resid;
! 
! 	    if (bp->b_bcount == bp->b_resid)
! 	      {
! 		bp->b_error = ENOSPC;
! 		bp->b_flags |= B_ERROR;
! 	      }
! 	    else
! 	      t->pending_error = WE_EOM;
! 	    break;
! 
! 	  case WE_EOF:
! 	    bp->b_resid = t->resid;
! 
! 	    if (bp->b_resid != bp->b_bcount)
! 	      {
! 		t->pending_error = WE_EOF;
! 		lock_eof=1;
! 	      }
! 	    break;
! 	  default:
! 	    bp->b_error = EIO;
! 	    bp->b_flags |= B_ERROR;
!         }
      }
!       
      biodone(bp);
      /*wst_start(t);*/
  }
***************
*** 518,536 ****
  {
      struct wst_reqsense sense;
  
      if (result.code != RES_ERR) {
      	printf("wst%d: ERROR code=%d, status=%b, error=%b\n", t->lun,
                 result.code, result.status, ARS_BITS, result.error, AER_BITS);
!         return 1;
      }
  
!     if ((result.error & AER_SKEY) && (result.status & ARS_CHECK)) {
          atapi_request_immediate(t->ata, t->unit,
              ATAPI_TAPE_REQUEST_SENSE,
              0, 0, 0, sizeof(sense),
              0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, (char*) &sense, sizeof(struct wst_reqsense));
          /*wst_dump(t->lun, "req_sense", &sense, sizeof(struct wst_reqsense));*/
      }
      switch (result.error & AER_SKEY) {
      case AER_SK_NOT_READY:
--- 579,620 ----
  {
      struct wst_reqsense sense;
  
+     t->resid = -1;
      if (result.code != RES_ERR) {
      	printf("wst%d: ERROR code=%d, status=%b, error=%b\n", t->lun,
                 result.code, result.status, ARS_BITS, result.error, AER_BITS);
!         return WE_ERROR;
      }
  
!     if (result.status & ARS_CHECK) {
          atapi_request_immediate(t->ata, t->unit,
              ATAPI_TAPE_REQUEST_SENSE,
              0, 0, 0, sizeof(sense),
              0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, (char*) &sense, sizeof(struct wst_reqsense));
          /*wst_dump(t->lun, "req_sense", &sense, sizeof(struct wst_reqsense));*/
+ 
+ 	if (t->flags & WST_DEBUG)
+ 	    printf("wst%d: valid:%d, key:%x ili:%d, oem:%d, fm:%d\n",
+ 		  t->lun, sense.valid, sense.sense_key,
+ 		   sense.ili, sense.eom, sense.filemark);
+ 
+ 	if (sense.error_code != 0x70)
+ 	  return WE_ERROR;
+ 
+ 	t->resid=(long)ntohl(sense.info) * t->blksize;	
+ 	switch (sense.sense_key) {
+ 	case 0x00:
+ 	case 0x01:
+ 	  if (sense.eom)
+ 	    return WE_EOM;
+ 	  if (sense.filemark)
+ 	    return WE_EOF;
+ 
+ 	  return WE_OK;
+ 	default:
+ 	  return WE_ERROR;
+ 	}
      }
      switch (result.error & AER_SKEY) {
      case AER_SK_NOT_READY:
***************
*** 593,599 ****
      printf("total=%u ERR=%x len=%ld ASC=%x ASCQ=%x\n", 
  	   wst_total, sense.error_code, (long)ntohl(sense.info), 
  	   sense.asc, sense.ascq);
!     return 1;
  }
  
  int 
--- 677,690 ----
      printf("total=%u ERR=%x len=%ld ASC=%x ASCQ=%x\n", 
  	   wst_total, sense.error_code, (long)ntohl(sense.info), 
  	   sense.asc, sense.ascq);
! 
!     switch (result.error & ~AER_SKEY)
!       {
!       case AER_EOM:
! 	return WE_EOM;
!       default:
! 	return WE_ERROR;
!       }
  }
  
  int 
***************
*** 699,704 ****
--- 790,796 ----
          			ATAPI_TAPE_SPACE_CMD, function,
                      	        count>>16, count>>8, count,
          			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0);
+     wst_wait_dsc(t);
      if (result.code) {
  	printf("wst_space_cmd: ");
          wst_error(t, result);
***************
*** 721,726 ****
--- 813,819 ----
      result = atapi_request_wait(t->ata, t->unit, 
          			ATAPI_TAPE_WEOF, 0, 0, 0, function,
          			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0);
+     wst_wait_dsc(t);
      if (result.code) {
  	printf("wst_write_filemark: ");
          wst_error(t, result);
***************
*** 737,742 ****
--- 830,836 ----
      result = atapi_request_wait(t->ata, t->unit, 
          			ATAPI_TAPE_LOAD_UNLOAD, 0, 0, 0, function,
          			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0);
+     wst_wait_dsc(t);
      if (result.code) {
  	printf("wst_load_unload: ");
          wst_error(t, result);
***************
*** 757,762 ****
--- 851,857 ----
  			        ATAPI_TAPE_ERASE, 3, 0, 0, 0,
          			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  				NULL, 0);
+     wst_wait_dsc(t);
      if (result.code) {
  	printf("wst_erase: ");
          wst_error(t, result);
***************
*** 774,779 ****
--- 869,875 ----
                  		    ATAPI_TAPE_REWIND, 0, 0, 0, 0,
                  		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  				    NULL, 0);
+     wst_wait_dsc(t);
      if (result.code) {
  	printf("wst_rewind: ");
          wst_error(t, result);

--n8g4imXOkfNTN/H1--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hardware" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010322222533.A931>