示例#1
0
int
_er90b_write(struct fdinfo *fio, bitptr bufptr, int nbytes, 
	struct ffsw *retstat, int fulp, int *ubc)
{
int ret;
int nbt = 0;	/* number of bytes transferred so far */
int nbreq;	/* number of bytes requested this request */
char *buf;
ER90BYT *f;
int zero = 0;
struct ffsw dumstat;

	buf = BPTR2CP(bufptr);
	if ((BPBITOFF(bufptr) & 7) != 0 || *ubc != 0)
		ERETURN(retstat, FDC_ERR_UBC, 0);

	nbreq = nbytes;
	if (fio->rwflag == POSITIN) {
		f = (ER90BYT *)fio->lyr_info;
		if (f->tpos) {
			ret = _tape_tpwait(f->fd, &(f->tpos));
			if (ret < 0)
				ERETURN(retstat, errno, 0);
		}		
	}
	else if (fio->rwflag == READIN) {
		/* write after read requires position to zero */
		ret = _er90b_pos(fio, FP_RSEEK, &zero, 1,
			&dumstat);
		if (ret < 0) {
			*retstat = dumstat;
			return(ERR);
		}
	}
	if (nbreq > 0) {
again:
		/* It is not safe to reissue the write if it fails */
		/* with EINTR. Some data may have been transferred */
		ret= write(fio->realfd, buf, nbreq);
		if (ret < 0)
			ERETURN(retstat, errno, nbt);
		nbt += ret;
/*
 *		The assumption is made here that the system will never return
 *		zero bytes on a non-zero request without an error!
 */
		if (nbt < nbytes) {
			buf += ret;
			nbreq -= ret;
			goto again;
		}
	}
	else if (nbytes < 0)
		ERETURN(retstat, FDC_ERR_REQ, 0);

	SETSTAT(retstat, FFCNT, nbt);
	fio->rwflag = WRITIN;
	return (nbt);
}
示例#2
0
int
_er90b_writea(struct fdinfo *fio, bitptr bufptr, int nbytes, 
	struct ffsw *retstat, int fulp, int *ubc)
{
int ret = 0;
char *buf;
ER90BYT *f;
int zero = 0;
struct ffsw dumstat;

	buf = BPTR2CP(bufptr);
	if ((BPBITOFF(bufptr) & 7) != 0 || *ubc != 0)
		ERETURN(retstat, FDC_ERR_UBC, 0);

	if (fio->rwflag == POSITIN) {
		f = (ER90BYT *)fio->lyr_info;
		if (f->tpos) {
			ret = _tape_tpwait(f->fd, &(f->tpos));
			if (ret < 0)
				ERETURN(retstat, errno, 0);
		}		
	}
	else if (fio->rwflag == READIN) {
		/* write after read requires position to zero */
		ret = _er90b_pos(fio, FP_RSEEK, &zero, 1,
			&dumstat);
		if (ret < 0) {
			*retstat = dumstat;
			return(ERR);
		}
	}

	if (nbytes > 0) {
		CLRFFSTAT(*retstat);	/* flag async in progress */
		ret=   writea(fio->realfd, buf, nbytes,
			(struct iosw *)retstat, 0);
		if (ret < 0)
			ERETURN(retstat, errno, 0);
	}
	else if (nbytes < 0) {
		ERETURN(retstat, FDC_ERR_REQ, 0);
	}
	else {	/* nbytes == 0 */
		retstat->sw_flag = 1;
		FFSTAT(*retstat) = FFCNT; /* I/O is done, and other stat */
					/* fields are already set. */
	}
	fio->rwflag = WRITIN;
	return (ret);
}
示例#3
0
_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));

}
示例#4
0
_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);
}
示例#5
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);
}