Ejemplo n.º 1
0
/*
 * _sds_fr_mem moves data into SDS from user memory.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_sds_fr_mem(
bitptr  sdsaddr,	/* SDS bit address where data will be received */
bitptr  ubuf,		/* user buffer containing data */
int     nbits		/* number of bits to move */
)
{
	long sds_bit_offset;
	char *ucaddr;
	long *uwaddr;
	int  ret;
	
	if (nbits & (BITPBLOCK - 1)) {
		errno = FDC_ERR_GRAN;	/* must be block multiple */
		return -1;
	}

	ucaddr	 = BPTR2CP(ubuf);
	uwaddr	 = BPTR2WP(ubuf);
	if (ucaddr != (char*)uwaddr) {
		errno = FDC_ERR_SDSWB;	/* must be word-aligned */
		return -1;
	}

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK - 1)) {
		errno = FDC_ERR_GRAN;	/* must be block multiple */
		return -1;
	}

	ret = sswrite(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits));
	if (ret == -1)
		errno = FDC_ERR_SDSIO;
	return ret;
}
Ejemplo n.º 2
0
/*
 * _any_mem_fr_sds moves data into user memory from a secondary data segment (SDS).
 *
 * unlike _mem_fr_sds, _any_mem_fr_sds handles moving a number of bits that
 * may not be a multiple of 512.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_any_mem_fr_sds(
bitptr  ubuf,		/* user buffer to receive data */
bitptr  sdsaddr,	/* SDS bit address of data */
int     nbits		/* number of bits to move */
)
{

	int sds_bit_offset;	
	int sds_bit_offset_blk;	
	int rbits;
	char localbuf[BYTPBLOCK];
	bitptr locptr;
	long *uwaddr;
	char *ucaddr;

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK -1)) {
		/* The sds address is not on a block boundary. */
		/* Read data from sds to a local buffer. Copy the */
		/* appropriate part of the local buffer to user's memory. */
		sds_bit_offset_blk = (sds_bit_offset & ~(BITPBLOCK - 1));
		if(ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		rbits = MIN(nbits, BITPBLOCK - (sds_bit_offset -
			sds_bit_offset_blk));
		locptr = CPTR2BP(localbuf);
		SET_BPTR(locptr, INC_BPTR(locptr, sds_bit_offset - sds_bit_offset_blk));
		MOV_BITS(ubuf, locptr, rbits);
		SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
		nbits -= rbits;
		SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
		if (nbits == 0)
			return(0);
		
		/* Verify that our sds address is now on a block boundary */
		assert (((SUBT_BPTR(sdsaddr, WPTR2BP(0))) & (BITPBLOCK -1)) == 0);
	}
	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	uwaddr	 = BPTR2WP(ubuf);
	ucaddr	 = BPTR2CP(ubuf);
	if ((nbits & (BITPBLOCK-1)) || (ucaddr != (char *)uwaddr)){
		int  left;

		/* Either we are not reading in a multiple of blocks or */
		/* the user's address is not word-aligned. */
		/* Round nbits down to a block boundary and */
		/* move those to user's memory. */

		locptr = CPTR2BP(localbuf);	
		rbits = nbits & ~(BITPBLOCK-1);
		if (rbits) {
			if (ucaddr != (char*)uwaddr) {
				/* ubuf is not word aligned. */
				/* Read the data from sds into a local */
				/* buffer and copy to the user's memory */
				left = rbits;
				sds_bit_offset_blk = BITS2BLOCKS(sds_bit_offset);
				while (left > 0) {
				   if (ssread((int *)localbuf,
				       sds_bit_offset_blk, 1) == -1) {
					errno = FDC_ERR_SDSIO;
					return(-1);
				   }
				   MOV_BITS(ubuf, locptr, BITPBLOCK);	
				   SET_BPTR(ubuf, INC_BPTR(ubuf, BITPBLOCK));
				   SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, BITPBLOCK));
				   sds_bit_offset_blk++;
				   left-= BITPBLOCK;
				}
			}
			else {
				if (ssread(uwaddr, BITS2BLOCKS(sds_bit_offset),
				   BITS2BLOCKS(rbits)) == -1) {
					errno = FDC_ERR_SDSIO;
					return(-1);
				}
				SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
				SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
			}
			sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
		}
		/* get last block into local memory and */
		/* transfer to 	user's memory */
		if (ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		assert((nbits - rbits) < BITPBLOCK);
		MOV_BITS(ubuf, locptr, nbits - rbits);	
	}
	else {
		if(ssread(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits)) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	return(0);
}
Ejemplo n.º 3
0
/*
 * _any_sds_fr_mem moves data into a secondary data segment (SDS) from
 *	user memory
 *
 * unlike _sds_fr_mem, _any_sds_fr_mem handles moving a number of bits that
 * may not be a multiple of 512.
 *
 * Returns 0 on normal return, or else -1 with error code in errno.
 */
_any_sds_fr_mem(
bitptr  sdsaddr,	/* SDS bit address of data */
bitptr  ubuf,		/* user buffer to receive data */
int     nbits		/* number of bits to move */
)
{

	int sds_bit_offset;	
	int sds_bit_offset_blk;	
	int rbits;
	char localbuf[BYTPBLOCK];
	bitptr locptr;
	long *uwaddr;
	char *ucaddr;

	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	if (sds_bit_offset & (BITPBLOCK -1)) {
		/* The sds address is not on a block boundary. */
		/* Read data from sds to a local buffer. Copy the */
		/* user's memory to the appropriate part of the local */
		/* buffer, and write it back out to sds. */
		sds_bit_offset_blk = (sds_bit_offset & ~(BITPBLOCK - 1));
		if (ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		rbits = MIN(nbits, BITPBLOCK - (sds_bit_offset -
			sds_bit_offset_blk));
		locptr = CPTR2BP(localbuf);
		SET_BPTR(locptr, INC_BPTR(locptr, sds_bit_offset - sds_bit_offset_blk));
		MOV_BITS(locptr, ubuf, rbits);
		SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
		nbits -= rbits;
		if(sswrite((int *)localbuf, BITS2BLOCKS(sds_bit_offset_blk), 1) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
		SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
		if (nbits == 0)
			return(0);
		
		assert(((SUBT_BPTR(sdsaddr, WPTR2BP(0))) & (BITPBLOCK -1)) == 0);
	}
	sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
	uwaddr	 = BPTR2WP(ubuf);
	ucaddr	 = BPTR2CP(ubuf);
	if ((nbits & (BITPBLOCK-1)) || (ucaddr != (char *)uwaddr)){
		int left;

		locptr = CPTR2BP(localbuf);	

		/* round down nbits to a block boundary */
		rbits = nbits & ~(BITPBLOCK-1);
		if (rbits) {
			if (ucaddr != (char*)uwaddr) {
				/* ubuf is not word aligned. */
				left = rbits;
				sds_bit_offset_blk = BITS2BLOCKS(sds_bit_offset);
				while (left > 0) {
				   if( ssread((int *)localbuf,
				      sds_bit_offset_blk, 1) == -1) {
				      errno = FDC_ERR_SDSIO;
				      return(-1);
				   }
				   MOV_BITS(locptr, ubuf, BITPBLOCK);	
				   SET_BPTR(ubuf, INC_BPTR(ubuf, BITPBLOCK));

				   if( sswrite((int *)localbuf,
				      sds_bit_offset_blk, 1) == -1) {
				      errno = FDC_ERR_SDSIO;
				      return(-1);
				   }
				   SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, BITPBLOCK));
				   sds_bit_offset_blk++;
				   left-= BITPBLOCK;
				
				}
			}
			else {
				if (_sds_fr_mem(sdsaddr, ubuf, rbits) == -1) {
					return(-1);
				}
				SET_BPTR(ubuf, INC_BPTR(ubuf, rbits));
				SET_BPTR(sdsaddr, INC_BPTR(sdsaddr, rbits));
			}
                        sds_bit_offset = SUBT_BPTR(sdsaddr, WPTR2BP(0));
		}
		/* Get last block into local memory. Merge in user's memory */
		/* and write it back out to sds. */
	        if( ssread((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
		      errno = FDC_ERR_SDSIO;
		      return(-1);
		}
		MOV_BITS(locptr, ubuf, nbits - rbits);	
	        if( sswrite((int *)localbuf, BITS2BLOCKS(sds_bit_offset), 1) == -1) {
		        errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	else {
		if(sswrite(uwaddr, BITS2BLOCKS(sds_bit_offset), BITS2BLOCKS(nbits)) == -1) {
			errno = FDC_ERR_SDSIO;
			return(-1);
		}
	}
	return(0);
}
Ejemplo n.º 4
0
int
_sqb_pos(struct fdinfo *fio, int cmd, long *arg, int len, struct ffsw *stat)
{
int ret = 0;
struct sqb_f *sqb_info;
struct sqbio *sqbptr;
struct sqbio *sqborig;
struct sqbio *s;
struct fdinfo *llfio;
int found = 0;
int nbits;
int sync = -1;

	llfio = fio->fioptr;
	sqb_info = (struct sqb_f *)fio->lyr_info;

	if (fio->rwflag == WRITIN) {
		/* flush buffers and wait for outstanding I/O to finish. */
		if (_sqb_flush(fio, stat) < 0) {
			return(ERR);
		}
	}

	switch(cmd) {
/* For now, this is not supported on SGI systems. */
/* We need to work out what "arg" should be. */
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
		case FP_RSEEK:
			if ((fio->rwflag == READIN) || 
			   (fio->rwflag == POSITIN)) {
			   if (*arg < 0) {
				/* Seeking backwards */
				/* Are we seeking within the current */
				/* buffer? */
				sqbptr = sqb_info->sqbio_cur;
				if (sqbptr->status == IOACTIVE) {
				   while (sqbptr->iostat.sw_flag == 0 ||
					sqbptr->iostat.sw_stat == 0) {
					ret = XRCALL(llfio,fcntlrtn) llfio,
					FC_RECALL, &(sqbptr->iostat), stat);
					if (ret < 0) {
						return(ERR);
					}
				   }
				   if (FFSTAT(sqbptr->iostat) == FFERR) {
					ERETURN(stat, sqbptr->iostat.sw_error,0);
				   }
				   sqbptr->_cnt = sqbptr->iostat.sw_count<<3;
				   sqbptr->status = IODATA;
				}
				if (sqbptr->status == IODATA) {
					nbits = -(*arg); /* convert to positive */
					nbits = nbits<<3;
					if (nbits <=
					 SUBT_BPTR(sqb_info->_ptr,sqbptr->_base)){
						SET_BPTR(sqb_info->_ptr,
						 INC_BPTR(sqb_info->_ptr,-nbits));
						sqbptr->_cnt += nbits;
						break;
					  }
				}
			   }
			   else {
				/* seeking forward */
				/* Any chance that the position would be in */
				/* our buffers? */
				nbits = *arg << 3;
				if (nbits > sqb_info->nbuf * sqb_info->bufsiz){
					/* won't be in any of the buffers */
					goto a1;
				}
				sqbptr = sqb_info->sqbio_cur;
				sqborig = sqbptr;
				do {
				   if (sqbptr->status == IOACTIVE) {
				      while (sqbptr->iostat.sw_flag == 0 ||
					sqbptr->iostat.sw_stat == 0) {
				   	   ret = XRCALL(llfio,fcntlrtn) llfio,
					   FC_RECALL, &(sqbptr->iostat), stat);
					   if (ret < 0) {
						return(ERR);
					   }
				      }
				      if (FFSTAT(sqbptr->iostat) == FFERR) {
					ERETURN(stat, sqbptr->iostat.sw_error,0);
				      }
				      sqbptr->_cnt = sqbptr->iostat.sw_count<<3;
				      sqbptr->status = IODATA;
				   }
				   if (sqbptr->status == IODATA) {
					if (nbits <= sqbptr->_cnt) {
						/* Desired position is in this buffer */
						sqbptr->_cnt -= nbits;
						/* Clear out buffers that preceeded this */
						s = sqborig;
						for (; s != sqbptr; s= s->nxt) {
							s->status = EMPTY;
							CLRFFSTAT(s->iostat);
						}
						sqb_info->sqbio_cur = sqbptr;
						if (sqbptr != sqborig)
							sqb_info->_ptr = sqbptr->_base;
						SET_BPTR(sqb_info->_ptr,
						 INC_BPTR(sqb_info->_ptr,nbits));
						found = 1;
						break;
					}
					else {
						nbits -= sqbptr->_cnt;
					}
				   }
				   else
					goto a1;	/* all out of data */
				   sqbptr = sqbptr->nxt;
				} while (sqbptr != sqborig);
			   }
			   }