source: trunk/minix/kernel/system/do_devio.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 2.3 KB
Line 
1/* The kernel call implemented in this file:
2 * m_type: SYS_DEVIO
3 *
4 * The parameters for this kernel call are:
5 * m2_i3: DIO_REQUEST (request input or output)
6 * m2_i1: DIO_TYPE (flag indicating byte, word, or long)
7 * m2_l1: DIO_PORT (port to read/ write)
8 * m2_l2: DIO_VALUE (value to write/ return value read)
9 */
10
11#include "../system.h"
12#include <minix/devio.h>
13#include <minix/endpoint.h>
14
15#if USE_DEVIO
16
17/*===========================================================================*
18 * do_devio *
19 *===========================================================================*/
20PUBLIC int do_devio(m_ptr)
21register message *m_ptr; /* pointer to request message */
22{
23 struct proc *rp;
24 struct priv *privp;
25 port_t port;
26 struct io_range *iorp;
27 int i, size, nr_io_range;
28
29 rp= proc_addr(who_p);
30 privp= priv(rp);
31 if (!privp)
32 {
33 kprintf("no priv structure!\n");
34 goto doit;
35 }
36 if (privp->s_flags & CHECK_IO_PORT)
37 {
38 switch (m_ptr->DIO_TYPE)
39 {
40 case DIO_BYTE: size= 1; break;
41 case DIO_WORD: size= 2; break;
42 case DIO_LONG: size= 4; break;
43 default: size= 4; break; /* Be conservative */
44 }
45 port= m_ptr->DIO_PORT;
46 nr_io_range= privp->s_nr_io_range;
47 for (i= 0, iorp= privp->s_io_tab; i<nr_io_range; i++, iorp++)
48 {
49 if (port >= iorp->ior_base && port+size-1 <= iorp->ior_limit)
50 break;
51 }
52 if (i >= nr_io_range)
53 {
54 kprintf(
55 "do_devio: I/O port check failed for proc %d, port 0x%x\n",
56 m_ptr->m_source, port);
57 return EPERM;
58 }
59 }
60
61doit:
62
63/* Process a single I/O request for byte, word, and long values. */
64 if (m_ptr->DIO_REQUEST == DIO_INPUT) {
65 switch (m_ptr->DIO_TYPE) {
66 case DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break;
67 case DIO_WORD: m_ptr->DIO_VALUE = inw(m_ptr->DIO_PORT); break;
68 case DIO_LONG: m_ptr->DIO_VALUE = inl(m_ptr->DIO_PORT); break;
69 default: return(EINVAL);
70 }
71 } else {
72 switch (m_ptr->DIO_TYPE) {
73 case DIO_BYTE: outb(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
74 case DIO_WORD: outw(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
75 case DIO_LONG: outl(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
76 default: return(EINVAL);
77 }
78 }
79 return(OK);
80}
81
82#endif /* USE_DEVIO */
Note: See TracBrowser for help on using the repository browser.