1*433d6423SLionel Sambuc /* The kernel call implemented in this file: 2*433d6423SLionel Sambuc * m_type: SYS_DEVIO 3*433d6423SLionel Sambuc * 4*433d6423SLionel Sambuc * The parameters for this kernel call are: 5*433d6423SLionel Sambuc * m_lsys_krn_sys_devio.request (request input or output) 6*433d6423SLionel Sambuc * m_lsys_krn_sys_devio.port (port to read/ write) 7*433d6423SLionel Sambuc * m_lsys_krn_sys_devio.value (value to write/ return value read) 8*433d6423SLionel Sambuc */ 9*433d6423SLionel Sambuc 10*433d6423SLionel Sambuc #include "kernel/system.h" 11*433d6423SLionel Sambuc #include <minix/devio.h> 12*433d6423SLionel Sambuc #include <minix/endpoint.h> 13*433d6423SLionel Sambuc #include <minix/portio.h> 14*433d6423SLionel Sambuc 15*433d6423SLionel Sambuc #if USE_DEVIO 16*433d6423SLionel Sambuc 17*433d6423SLionel Sambuc /*===========================================================================* 18*433d6423SLionel Sambuc * do_devio * 19*433d6423SLionel Sambuc *===========================================================================*/ 20*433d6423SLionel Sambuc int do_devio(struct proc * caller, message * m_ptr) 21*433d6423SLionel Sambuc { 22*433d6423SLionel Sambuc struct priv *privp; 23*433d6423SLionel Sambuc port_t port; 24*433d6423SLionel Sambuc struct io_range *iorp; 25*433d6423SLionel Sambuc int i, size, nr_io_range; 26*433d6423SLionel Sambuc int io_type, io_dir; 27*433d6423SLionel Sambuc 28*433d6423SLionel Sambuc io_type = m_ptr->m_lsys_krn_sys_devio.request & _DIO_TYPEMASK; 29*433d6423SLionel Sambuc io_dir = m_ptr->m_lsys_krn_sys_devio.request & _DIO_DIRMASK; 30*433d6423SLionel Sambuc 31*433d6423SLionel Sambuc switch (io_type) 32*433d6423SLionel Sambuc { 33*433d6423SLionel Sambuc case _DIO_BYTE: size= 1; break; 34*433d6423SLionel Sambuc case _DIO_WORD: size= 2; break; 35*433d6423SLionel Sambuc case _DIO_LONG: size= 4; break; 36*433d6423SLionel Sambuc default: size= 4; break; /* Be conservative */ 37*433d6423SLionel Sambuc } 38*433d6423SLionel Sambuc 39*433d6423SLionel Sambuc privp= priv(caller); 40*433d6423SLionel Sambuc if (!privp) 41*433d6423SLionel Sambuc { 42*433d6423SLionel Sambuc printf("no priv structure!\n"); 43*433d6423SLionel Sambuc goto doit; 44*433d6423SLionel Sambuc } 45*433d6423SLionel Sambuc if (privp->s_flags & CHECK_IO_PORT) 46*433d6423SLionel Sambuc { 47*433d6423SLionel Sambuc port= m_ptr->m_lsys_krn_sys_devio.port; 48*433d6423SLionel Sambuc nr_io_range= privp->s_nr_io_range; 49*433d6423SLionel Sambuc for (i= 0, iorp= privp->s_io_tab; i<nr_io_range; i++, iorp++) 50*433d6423SLionel Sambuc { 51*433d6423SLionel Sambuc if (port >= iorp->ior_base && port+size-1 <= iorp->ior_limit) 52*433d6423SLionel Sambuc break; 53*433d6423SLionel Sambuc } 54*433d6423SLionel Sambuc if (i >= nr_io_range) 55*433d6423SLionel Sambuc { 56*433d6423SLionel Sambuc printf("do_devio: port 0x%x (size %d) not allowed\n", 57*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_devio.port, size); 58*433d6423SLionel Sambuc return EPERM; 59*433d6423SLionel Sambuc } 60*433d6423SLionel Sambuc } 61*433d6423SLionel Sambuc 62*433d6423SLionel Sambuc doit: 63*433d6423SLionel Sambuc if (m_ptr->m_lsys_krn_sys_devio.port & (size-1)) 64*433d6423SLionel Sambuc { 65*433d6423SLionel Sambuc printf("do_devio: unaligned port 0x%x (size %d)\n", 66*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_devio.port, size); 67*433d6423SLionel Sambuc return EPERM; 68*433d6423SLionel Sambuc } 69*433d6423SLionel Sambuc 70*433d6423SLionel Sambuc /* Process a single I/O request for byte, word, and long values. */ 71*433d6423SLionel Sambuc if (io_dir == _DIO_INPUT) { 72*433d6423SLionel Sambuc switch (io_type) { 73*433d6423SLionel Sambuc /* maybe "it" should not be called ports */ 74*433d6423SLionel Sambuc case _DIO_BYTE: 75*433d6423SLionel Sambuc m_ptr->m_krn_lsys_sys_devio.value = 76*433d6423SLionel Sambuc inb(m_ptr->m_lsys_krn_sys_devio.port); 77*433d6423SLionel Sambuc break; 78*433d6423SLionel Sambuc case _DIO_WORD: 79*433d6423SLionel Sambuc m_ptr->m_krn_lsys_sys_devio.value = 80*433d6423SLionel Sambuc inw(m_ptr->m_lsys_krn_sys_devio.port); 81*433d6423SLionel Sambuc break; 82*433d6423SLionel Sambuc case _DIO_LONG: 83*433d6423SLionel Sambuc m_ptr->m_krn_lsys_sys_devio.value = 84*433d6423SLionel Sambuc inl(m_ptr->m_lsys_krn_sys_devio.port); 85*433d6423SLionel Sambuc break; 86*433d6423SLionel Sambuc default: return(EINVAL); 87*433d6423SLionel Sambuc } 88*433d6423SLionel Sambuc } else { 89*433d6423SLionel Sambuc switch (io_type) { 90*433d6423SLionel Sambuc case _DIO_BYTE: 91*433d6423SLionel Sambuc outb(m_ptr->m_lsys_krn_sys_devio.port, 92*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_devio.value); 93*433d6423SLionel Sambuc break; 94*433d6423SLionel Sambuc case _DIO_WORD: 95*433d6423SLionel Sambuc outw(m_ptr->m_lsys_krn_sys_devio.port, 96*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_devio.value); 97*433d6423SLionel Sambuc break; 98*433d6423SLionel Sambuc case _DIO_LONG: 99*433d6423SLionel Sambuc outl(m_ptr->m_lsys_krn_sys_devio.port, 100*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_devio.value); 101*433d6423SLionel Sambuc break; 102*433d6423SLionel Sambuc default: return(EINVAL); 103*433d6423SLionel Sambuc } 104*433d6423SLionel Sambuc } 105*433d6423SLionel Sambuc return(OK); 106*433d6423SLionel Sambuc } 107*433d6423SLionel Sambuc 108*433d6423SLionel Sambuc #endif /* USE_DEVIO */ 109