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>