00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "../system.h"
00012 #include <minix/devio.h>
00013 #include <minix/endpoint.h>
00014
00015 #if USE_VDEVIO
00016
00017
00018 PRIVATE char vdevio_buf[VDEVIO_BUF_SIZE];
00019 PRIVATE pvb_pair_t *pvb = (pvb_pair_t *) vdevio_buf;
00020 PRIVATE pvw_pair_t *pvw = (pvw_pair_t *) vdevio_buf;
00021 PRIVATE pvl_pair_t *pvl = (pvl_pair_t *) vdevio_buf;
00022
00023
00024
00025
00026 PUBLIC int do_vdevio(m_ptr)
00027 register message *m_ptr;
00028 {
00029
00030
00031
00032
00033
00034
00035 int vec_size;
00036 int io_in;
00037 size_t bytes;
00038 vir_bytes caller_vir;
00039 phys_bytes caller_phys;
00040 int i;
00041
00042
00043 if (m_ptr->DIO_REQUEST == DIO_INPUT) io_in = TRUE;
00044 else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) io_in = FALSE;
00045 else return(EINVAL);
00046 if ((vec_size = m_ptr->DIO_VEC_SIZE) <= 0) return(EINVAL);
00047 switch (m_ptr->DIO_TYPE) {
00048 case DIO_BYTE: bytes = vec_size * sizeof(pvb_pair_t); break;
00049 case DIO_WORD: bytes = vec_size * sizeof(pvw_pair_t); break;
00050 case DIO_LONG: bytes = vec_size * sizeof(pvl_pair_t); break;
00051 default: return(EINVAL);
00052 }
00053 if (bytes > sizeof(vdevio_buf)) return(E2BIG);
00054
00055
00056 caller_vir = (vir_bytes) m_ptr->DIO_VEC_ADDR;
00057 caller_phys = umap_local(proc_addr(who_p), D, caller_vir, bytes);
00058 if (0 == caller_phys) return(EFAULT);
00059 phys_copy(caller_phys, vir2phys(vdevio_buf), (phys_bytes) bytes);
00060
00061
00062
00063
00064
00065 lock(13, "do_vdevio");
00066 switch (m_ptr->DIO_TYPE) {
00067 case DIO_BYTE:
00068 if (io_in) for (i=0; i<vec_size; i++) pvb[i].value = inb(pvb[i].port);
00069 else for (i=0; i<vec_size; i++) outb(pvb[i].port, pvb[i].value);
00070 break;
00071 case DIO_WORD:
00072 if (io_in) for (i=0; i<vec_size; i++) pvw[i].value = inw(pvw[i].port);
00073 else for (i=0; i<vec_size; i++) outw(pvw[i].port, pvw[i].value);
00074 break;
00075 default:
00076 if (io_in) for (i=0; i<vec_size; i++) pvl[i].value = inl(pvl[i].port);
00077 else for (i=0; i<vec_size; i++) outl(pvb[i].port, pvl[i].value);
00078 }
00079 unlock(13);
00080
00081
00082 if (io_in) phys_copy(vir2phys(vdevio_buf), caller_phys, (phys_bytes) bytes);
00083 return(OK);
00084 }
00085
00086 #endif
00087