FreeBSD/sys/arm/arm/uio_machdep.c
/*
 * Implement uiomove(9) from physical memory using sf_bufs to
 * avoid the creation and destruction of ephemeral mappings.
 */
Implement uiomove(9) from physical memory using sf_bufs to
avoid the creation and destruction of ephemeral mappings.
Implement uiomove ( 9 ) from physical memory using sf_bufs to avoid the creation and destruction of ephemeral mappings .
int
uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
{
	struct thread *td = curthread;
	struct iovec *iov;
	void *cp;
	vm_offset_t page_offset;
	size_t cnt;
	int error = 0;
	int save = 0;
	struct sf_buf *sf;
	KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
	    ("uiomove_fromphys: mode"));
	KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
	    ("uiomove_fromphys proc"));
	save = td->td_pflags & TDP_DEADLKTREAT;
	td->td_pflags |= TDP_DEADLKTREAT;
	while (n > 0 && uio->uio_resid) {
		iov = uio->uio_iov;
		cnt = iov->iov_len;
		if (cnt == 0) {
			uio->uio_iov++;
			uio->uio_iovcnt--;
			continue;
		}
		if (cnt > n)
			cnt = n;
		page_offset = offset & PAGE_MASK;
		cnt = min(cnt, PAGE_SIZE - page_offset);
		sf = sf_buf_alloc(ma[offset >> PAGE_SHIFT], 0);
		cp = (char*)sf_buf_kva(sf) + page_offset;
		switch (uio->uio_segflg) {
		case UIO_USERSPACE:
			maybe_yield();
			if (uio->uio_rw == UIO_READ)
				error = copyout(cp, iov->iov_base, cnt);
			else
				error = copyin(iov->iov_base, cp, cnt);
			if (error) {
				sf_buf_free(sf);
				goto out;
			}
			break;
		case UIO_SYSSPACE:
			if (uio->uio_rw == UIO_READ)
				bcopy(cp, iov->iov_base, cnt);
			else
				bcopy(iov->iov_base, cp, cnt);
			break;
		case UIO_NOCOPY:
			break;
		}
		sf_buf_free(sf);
		iov->iov_base = (char *)iov->iov_base + cnt;
		iov->iov_len -= cnt;
		uio->uio_resid -= cnt;
		uio->uio_offset += cnt;
		offset += cnt;
		n -= cnt;
	}
out:
	if (save == 0)
		td->td_pflags &= ~TDP_DEADLKTREAT;
	return (error);
}
int uiomove_fromphys ( vm_page_t ma [ ] , vm_offset_t offset , int n , struct uio * uio ) { struct thread * td = curthread ; struct iovec * iov ; void * cp ; vm_offset_t page_offset ; size_t cnt ; int error = 0 ; int save = 0 ; struct sf_buf * sf ; KASSERT ( uio -> uio_rw == UIO_READ || uio -> uio_rw == UIO_WRITE , ( " " ) ) ; KASSERT ( uio -> uio_segflg != UIO_USERSPACE || uio -> uio_td == curthread , ( " " ) ) ; save = td -> td_pflags & TDP_DEADLKTREAT ; td -> td_pflags |= TDP_DEADLKTREAT ; while ( n > 0 && uio -> uio_resid ) { iov = uio -> uio_iov ; cnt = iov -> iov_len ; if ( cnt == 0 ) { uio -> uio_iov ++ ; uio -> uio_iovcnt -- ; continue ; } if ( cnt > n ) cnt = n ; page_offset = offset & PAGE_MASK ; cnt = min ( cnt , PAGE_SIZE - page_offset ) ; sf = sf_buf_alloc ( ma [ offset >> PAGE_SHIFT ] , 0 ) ; cp = ( char * ) sf_buf_kva ( sf ) + page_offset ; switch ( uio -> uio_segflg ) { case UIO_USERSPACE : maybe_yield ( ) ; if ( uio -> uio_rw == UIO_READ ) error = copyout ( cp , iov -> iov_base , cnt ) ; else error = copyin ( iov -> iov_base , cp , cnt ) ; if ( error ) { sf_buf_free ( sf ) ; goto out ; } break ; case UIO_SYSSPACE : if ( uio -> uio_rw == UIO_READ ) bcopy ( cp , iov -> iov_base , cnt ) ; else bcopy ( iov -> iov_base , cp , cnt ) ; break ; case UIO_NOCOPY : break ; } sf_buf_free ( sf ) ; iov -> iov_base = ( char * ) iov -> iov_base + cnt ; iov -> iov_len -= cnt ; uio -> uio_resid -= cnt ; uio -> uio_offset += cnt ; offset += cnt ; n -= cnt ; } out : if ( save == 0 ) td -> td_pflags &= ~ TDP_DEADLKTREAT ; return ( error ) ; }
Implement uiomove(9) from physical memory using sf_bufs to
 avoid the creation and destruction of ephemeral mappings.
Implement uiomove ( 9 ) from physical memory using sf_bufs to avoid the creation and destruction of ephemeral mappings .