1 /* The kernel call implemented in this file:
4 * The parameters for this kernel call are:
5 * m2_i3: DIO_REQUEST (request input or output)
6 * m2_l1: DIO_PORT (port to read/ write)
7 * m2_l2: DIO_VALUE (value to write/ return value read)
10 #include "../system.h"
11 #include <minix/devio.h>
12 #include <minix/endpoint.h>
13 #include <minix/portio.h>
17 /*===========================================================================*
19 *===========================================================================*/
20 PUBLIC
int do_devio(m_ptr
)
21 register message
*m_ptr
; /* pointer to request message */
26 struct io_range
*iorp
;
27 int i
, size
, nr_io_range
;
30 io_type
= m_ptr
->DIO_REQUEST
& _DIO_TYPEMASK
;
31 io_dir
= m_ptr
->DIO_REQUEST
& _DIO_DIRMASK
;
35 case _DIO_BYTE
: size
= 1; break;
36 case _DIO_WORD
: size
= 2; break;
37 case _DIO_LONG
: size
= 4; break;
38 default: size
= 4; break; /* Be conservative */
45 kprintf("no priv structure!\n");
48 if (privp
->s_flags
& CHECK_IO_PORT
)
52 case _DIO_BYTE
: size
= 1; break;
53 case _DIO_WORD
: size
= 2; break;
54 case _DIO_LONG
: size
= 4; break;
55 default: size
= 4; break; /* Be conservative */
57 port
= m_ptr
->DIO_PORT
;
58 nr_io_range
= privp
->s_nr_io_range
;
59 for (i
= 0, iorp
= privp
->s_io_tab
; i
<nr_io_range
; i
++, iorp
++)
61 if (port
>= iorp
->ior_base
&& port
+size
-1 <= iorp
->ior_limit
)
66 static int curr
= 0, limit
= 100, extra
= 20;
68 if (curr
< limit
+extra
)
70 kprintf("do_devio: port 0x%x (size %d) not allowed\n",
71 m_ptr
->DIO_PORT
, size
);
72 } else if (curr
== limit
+extra
)
74 kprintf("do_devio: no debug output for a while\n");
76 else if (curr
== 2*limit
-1)
84 if (m_ptr
->DIO_PORT
& (size
-1))
86 static int curr
= 0, limit
= 100, extra
= 20;
88 if (curr
< limit
+extra
)
90 kprintf("do_devio: unaligned port 0x%x (size %d)\n",
91 m_ptr
->DIO_PORT
, size
);
92 } else if (curr
== limit
+extra
)
94 kprintf("do_devio: no debug output for a while\n");
96 else if (curr
== 2*limit
-1)
102 /* Process a single I/O request for byte, word, and long values. */
103 if (io_dir
== _DIO_INPUT
) {
105 /* maybe "it" should not be called ports */
106 case _DIO_BYTE
: m_ptr
->DIO_VALUE
= inb(m_ptr
->DIO_PORT
); break;
107 case _DIO_WORD
: m_ptr
->DIO_VALUE
= inw(m_ptr
->DIO_PORT
); break;
108 case _DIO_LONG
: m_ptr
->DIO_VALUE
= inl(m_ptr
->DIO_PORT
); break;
109 default: return(EINVAL
);
113 case _DIO_BYTE
: outb(m_ptr
->DIO_PORT
, m_ptr
->DIO_VALUE
); break;
114 case _DIO_WORD
: outw(m_ptr
->DIO_PORT
, m_ptr
->DIO_VALUE
); break;
115 case _DIO_LONG
: outl(m_ptr
->DIO_PORT
, m_ptr
->DIO_VALUE
); break;
116 default: return(EINVAL
);
122 #endif /* USE_DEVIO */