source: trunk/minix/kernel/system/do_sdevio.c@ 15

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

Minix 3.1.2a

File size: 2.1 KB
Line 
1/* The kernel call implemented in this file:
2 * m_type: SYS_SDEVIO
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_p1: DIO_VEC_ADDR (virtual address of buffer)
9 * m2_l2: DIO_VEC_SIZE (number of elements)
10 * m2_i2: DIO_VEC_PROC (process where buffer is)
11 */
12
13#include "../system.h"
14#include <minix/devio.h>
15#include <minix/endpoint.h>
16
17#if USE_SDEVIO
18
19/*===========================================================================*
20 * do_sdevio *
21 *===========================================================================*/
22PUBLIC int do_sdevio(m_ptr)
23register message *m_ptr; /* pointer to request message */
24{
25 int proc_nr, proc_nr_e = m_ptr->DIO_VEC_ENDPT;
26 int count = m_ptr->DIO_VEC_SIZE;
27 long port = m_ptr->DIO_PORT;
28 phys_bytes phys_buf;
29
30 /* Check if process endpoint is OK.
31 * A driver may directly provide a pointer to a buffer at the user-process
32 * that initiated the device I/O. Kernel processes, of course, are denied.
33 */
34 if (proc_nr_e == SELF)
35 proc_nr = who_p;
36 else
37 if(!isokendpt(proc_nr_e, &proc_nr))
38 return(EINVAL);
39 if (iskerneln(proc_nr)) return(EPERM);
40
41 /* Get and check physical address. */
42 if ((phys_buf = numap_local(proc_nr, (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
43 return(EFAULT);
44
45 /* Perform device I/O for bytes and words. Longs are not supported. */
46 if (m_ptr->DIO_REQUEST == DIO_INPUT) {
47 switch (m_ptr->DIO_TYPE) {
48 case DIO_BYTE: phys_insb(port, phys_buf, count); break;
49 case DIO_WORD: phys_insw(port, phys_buf, count); break;
50 default: return(EINVAL);
51 }
52 } else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) {
53 switch (m_ptr->DIO_TYPE) {
54 case DIO_BYTE: phys_outsb(port, phys_buf, count); break;
55 case DIO_WORD: phys_outsw(port, phys_buf, count); break;
56 default: return(EINVAL);
57 }
58 }
59 else {
60 return(EINVAL);
61 }
62 return(OK);
63}
64
65#endif /* USE_SDEVIO */
66
Note: See TracBrowser for help on using the repository browser.