_bmx_gabs(BMXFIL *f, void *blockid) { if ( f->bmx_tpos ) { if ( _tape_tpwait( f->bmx_fd, &(f->bmx_tpos) ) != 0) return(-1); } /* * If previous i/o request was a write request make sure the list * is flushed before getting the position. */ if ( f->bmx_flag & BMXIO_RW ) { if (f->bmx_flag & BMXIO_EOV == 0) { /* Not doing EOV */ if (f->bmx_lstptr->state == 0 && f->bmx_lstptr->bytes != 0) { /* error if we just wrote part of a record */ errno = FDC_ERR_NOTREC; return(-1); } else { if (__bmxflush(f) < 0) return(-1); } /* A sync is REQUIRED on Model D IOS systems. */ /* Do it for all systems. */ if (_tape_sync(f->bmx_fd) < 0) return(-1); } else { /* Flushing out the data in the library buffers, or doing * the sync could cause us to hit EOV. Call _bmx_gtpos because * it knows what to do about EOV. */ if (_bmx_gtpos(f, NULL, 0, 1) != 0) return(-1); } } else { /* wait for i/o to be quiet */ if (_bmx_eovq(f) < 0) return(-1); } return(ioctl(f->bmx_fd, TPC_GABS, blockid)); }
_er90b_gettp(struct fdinfo *fio, long *pa, long palen, long synch) { ER90BYT *f; struct tsdata tsdata; int vsn[MAXVSN]; f = (ER90BYT *)fio->lyr_info; if ( f->tpos ) { if( _tape_tpwait( f->fd, &(f->tpos) ) != 0) return(-1); } if (synch == 1 && fio->rwflag == WRITIN) { if(_tape_sync(f->fd) != 0) return(-1); } if( _tape_tptsi (&(f->tsireq), &tsdata, vsn) != 0) return(-1); _tape_gtpos(&tsdata, vsn, 0, pa, palen); return(0); }
int _er90b_pos(struct fdinfo *fio, int cmd, long *arg, int len, struct ffsw *stat) { int ret; ER90BYT *f; struct dmn_comm pos; struct ctl_abspos ctl; struct ffp_settp_s *spos; f = (ER90BYT *)fio->lyr_info; /* The caller is responsible for waiting for outstanding I/O */ if (f->tpos) { if ((ret = _tape_tpwait(f->fd, &(f->tpos))) != 0) return(-1); } switch(cmd) { #ifdef _CRAYMPP case FP_SETTP: spos = (struct ffp_settp_s *)arg; if (_er90b_stpos(fio, spos->ffp_nbs_p, spos->ffp_nb, spos->ffp_nvs_p, spos->ffp_nv, spos->ffp_vi)) ERETURN(stat,errno,0); fio->rwflag = POSITIN; break; #endif #ifndef _CRAYMPP case FP_GETPOS: if (len < 4) { ERETURN(stat, FEBIOSNT, 0); } if (fio->rwflag == WRITIN) { if (_tape_sync(f->fd) != 0) { ERETURN(stat, errno, 0); } } else if (fio->rwflag == READIN) { /* The TPC_GABS ioctl does account for */ /* data in the controller buffer, but does */ /* not account for data in the system buffer */ /* So, we do a position request to take care */ /* of that. */ if (_er90b_relpos(f->fd,0) < 0) ERETURN(stat, errno, 0); fio->rwflag = POSITIN; } if (ioctl(f->fd, TPC_GABS, &ctl) < 0) ERETURN(stat, errno, 0); *arg = ctl.datablock; *(arg+1) = ctl.absaddr; *(arg+2) = ctl.partition; *(arg+3) = ctl.filesec; break; case FP_SETPOS: if (len < 4) { ERETURN(stat, FEBIOSNT, 0); } ctl.datablock = *arg; ctl.absaddr = *(arg+1); ctl.partition = *(arg+2); ctl.filesec = *(arg+3); pos.POS_REQ = TR_PABS; pos.POS_ABSADDR = (int)&ctl; if (ioctl(f->fd, TPC_DMN_REQ, &pos) < 0) ERETURN(stat, errno, 0); if (ioctl(f->fd, TPC_DMN_REP, &pos) < 0) ERETURN(stat, errno, 0); if (pos.POS_REP != 0) { ERETURN(stat, pos.POS_REP, 0); } fio->rwflag = POSITIN; break; case FP_RSEEK: if (_er90b_relpos(f->fd,*(arg)) < 0) ERETURN(stat, errno, 0); fio->rwflag = POSITIN; break; case FP_GABS: /* This relies on struct ffp_pos matching ctl_abspos */ if (fio->rwflag == WRITIN) { if (_tape_sync(f->fd) != 0) { ERETURN(stat, errno, 0); } } if (ioctl(f->fd, TPC_GABS, arg) < 0) ERETURN(stat, errno, 0); break; case FP_SABS: pos.POS_REQ = TR_PABS; pos.POS_ABSADDR = (int)arg; if (ioctl(f->fd, TPC_DMN_REQ, &pos) < 0) ERETURN(stat, errno, 0); if (ioctl(f->fd, TPC_DMN_REP, &pos) < 0) ERETURN(stat, errno, 0); if (pos.POS_REP != 0) { ERETURN(stat, pos.POS_REP, 0); } fio->rwflag = POSITIN; break; #endif default: ERETURN(stat, FDC_ERR_NOSUP, 0); } return(0); }