/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
*/

#ident "$Header: iovec.c 1.6 89/08/07 $"

/*
 * iovec.c
 *	Support for I/O vector construction.  Used in conjunction 
 *	with bus/adapter specific I/O vector mapping functions.
 */

/* $Log:	iovec.c,v $
 */
#include "sys/types.h"
#include "sys/param.h"
#include "sys/signal.h"
#include "sys/user.h"
#include "sys/buf.h"
#include "sys/timer.h"
#include "sys/proc.h"
#include "sys/mc_vmparam.h"
#include "sys/pte.h"
#include "sys/vmmeter.h"
#include "sys/plocal.h"
#include "sys/vmmac.h"
#include "sys/mftpr.h"
#include "sys/cmn_err.h"
#include "sys/iovec.h"

/*
 * bp_iovec_info()
 *	Determine the type of I/O described in the 
 *	buf-structure, and return information to the 
 *	caller for filling out an I/O vector for it.
 *	Returned values are:
 *		Address of pte for 1st memory cluster 
 * 			in the tranfer range.
 *		Offset in 1st memory cluster at which
 *			the transfer begins.
 *		Number of bytes to transfer.
 *
 *	B_RAWIO, B_PTEIO, B_PTBIO cases must flush 
 *	TLB to avoid stale mappings thru Usrptmap[], 
 *	since this is callable from interrupt 
 *	procedures (SGS only).
 *	Panics if bad pte found (can't happen).
 */
void
bp_iovec_info(bp, pte, offset, length) 
	struct buf *bp;
	struct pte **pte;
	off_t *offset;
	int *length;
{

	extern struct pte *vtopte();

	switch(bp->b_iotype) {
	case B_RAWIO:			/* Raw I/O */
		/*
		 * Look into alignment of physical memory, 
		 * xfer can start on any 16-byte boundary.
		 */
		FLUSH_TLB();
		*pte = vtopte(bp->b_proc, clbase(btop(bp->b_un.b_addr)));
		*offset = (int)bp->b_un.b_addr & CLOFSET;
		break;
	case B_FILIO:			/* Filesystem/buffer-cache I/O */
		/*
		 * Always cluster aligned (physically and 
		 * virtually.  Note: also used when kernel 
		 * memory acquired via wmemall(), i.e., 
		 * channel configuration buffer in zdget_chancfg().
		 */
		*pte = &Sysmap[btop(bp->b_un.b_addr)];
		*offset = 0;
		break;
	case B_PTEIO:			/* Swap/page IO */
		/*
		 * Pte-based - already know pte of 1st page, 
		 * which is cluster aligned, and b_count is 
		 * a multiple of CLBYTES.
		 */
		FLUSH_TLB();
		*pte = bp->b_un.b_pte;
		*offset = 0;
		break;
	case B_PTBIO:			/* Page-Table IO */
		/*
		 * Like B_PTEIO, but can start/end with 
		 * non-cluster aligned memory, but is always 
		 * HW page aligned. Count is multiple of NBPG.
		 * Separated from B_PTEIO for efficiency.
		 */
		FLUSH_TLB();
		*pte = bp->b_un.b_pte;
		*offset = PTECLOFF(**pte);
		*pte -= btop(*offset);
		break;
	default:
		cmn_err(CE_PANIC, "bp_iovec_info: bad b_iotype");
		/*
		 *+ bp_iovec_info() was invoked to locate page
		 *+ table information from a system buf structure.
		 *+ The type of i/o described by the system buf structure is
		 *+ not recognizable and is unsupported.
		 */
		/*NOTREACHED*/
	}

	*length = bp->b_bcount;
}

#ifdef notyet
/*
 * va_iovec_info()
 *	Given a kernel space virtual address, determine
 *	and return information to the caller for filling 
 *	out an I/O vector.  Returned values are:
 *		pte address for memory cluster base
 * 			in which va resides. 
 *		Memory cluster offset in the address
 *			at which the transfer begins.
 */
void
va_iovec_info(va, pte, offset) 
	caddr_t va;
	struct pte **pte;
	off_t *offset;
{
	*pte = Sysmap + clbase(btop(va));
	*offset = (off_t)va & CLOFSET;
}

#endif /* notyet */
