00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <types.h>
00031 #include <lib.h>
00032 #include <uio.h>
00033 #include <proc.h>
00034 #include <current.h>
00035 #include <copyinout.h>
00036
00037
00038
00039
00040
00041 int
00042 uiomove(void *ptr, size_t n, struct uio *uio)
00043 {
00044 struct iovec *iov;
00045 size_t size;
00046 int result;
00047
00048 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) {
00049 panic("uiomove: Invalid uio_rw %d\n", (int) uio->uio_rw);
00050 }
00051 if (uio->uio_segflg==UIO_SYSSPACE) {
00052 KASSERT(uio->uio_space == NULL);
00053 }
00054 else {
00055 KASSERT(uio->uio_space == curproc_getas());
00056 }
00057
00058 while (n > 0 && uio->uio_resid > 0) {
00059
00060 iov = uio->uio_iov;
00061 size = iov->iov_len;
00062
00063 if (size > n) {
00064 size = n;
00065 }
00066
00067 if (size == 0) {
00068
00069 uio->uio_iov++;
00070 uio->uio_iovcnt--;
00071 if (uio->uio_iovcnt == 0) {
00072
00073
00074
00075
00076
00077
00078 panic("uiomove: ran out of buffers\n");
00079 }
00080 continue;
00081 }
00082
00083 switch (uio->uio_segflg) {
00084 case UIO_SYSSPACE:
00085 result = 0;
00086 if (uio->uio_rw == UIO_READ) {
00087 memmove(iov->iov_kbase, ptr, size);
00088 }
00089 else {
00090 memmove(ptr, iov->iov_kbase, size);
00091 }
00092 iov->iov_kbase = ((char *)iov->iov_kbase+size);
00093 break;
00094 case UIO_USERSPACE:
00095 case UIO_USERISPACE:
00096 if (uio->uio_rw == UIO_READ) {
00097 result = copyout(ptr, iov->iov_ubase,size);
00098 }
00099 else {
00100 result = copyin(iov->iov_ubase, ptr, size);
00101 }
00102 if (result) {
00103 return result;
00104 }
00105 iov->iov_ubase += size;
00106 break;
00107 default:
00108 panic("uiomove: Invalid uio_segflg %d\n",
00109 (int)uio->uio_segflg);
00110 }
00111
00112 iov->iov_len -= size;
00113 uio->uio_resid -= size;
00114 uio->uio_offset += size;
00115 ptr = ((char *)ptr + size);
00116 n -= size;
00117 }
00118
00119 return 0;
00120 }
00121
00122 int
00123 uiomovezeros(size_t n, struct uio *uio)
00124 {
00125
00126 static char zeros[16];
00127 size_t amt;
00128 int result;
00129
00130
00131 KASSERT(uio->uio_rw == UIO_READ);
00132
00133 while (n > 0) {
00134 amt = sizeof(zeros);
00135 if (amt > n) {
00136 amt = n;
00137 }
00138 result = uiomove(zeros, amt, uio);
00139 if (result) {
00140 return result;
00141 }
00142 n -= amt;
00143 }
00144
00145 return 0;
00146 }
00147
00148
00149
00150
00151
00152 void
00153 uio_kinit(struct iovec *iov, struct uio *u,
00154 void *kbuf, size_t len, off_t pos, enum uio_rw rw)
00155 {
00156 iov->iov_kbase = kbuf;
00157 iov->iov_len = len;
00158 u->uio_iov = iov;
00159 u->uio_iovcnt = 1;
00160 u->uio_offset = pos;
00161 u->uio_resid = len;
00162 u->uio_segflg = UIO_SYSSPACE;
00163 u->uio_rw = rw;
00164 u->uio_space = NULL;
00165 }