source: branches/minix3-book/kernel/system/do_sdevio.c@ 25

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

Importazione sorgenti libro

File size: 2.1 KB
RevLine 
[4]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
16#if USE_SDEVIO
17
18/*===========================================================================*
19 * do_sdevio *
20 *===========================================================================*/
21PUBLIC int do_sdevio(m_ptr)
22register message *m_ptr; /* pointer to request message */
23{
24 int proc_nr = m_ptr->DIO_VEC_PROC;
25 int count = m_ptr->DIO_VEC_SIZE;
26 long port = m_ptr->DIO_PORT;
27 phys_bytes phys_buf;
28
29 /* Check if process number is OK. A process number is allowed here, because
30 * driver may directly provide a pointer to a buffer at the user-process
31 * that initiated the device I/O. Kernel processes, of course, are denied.
32 */
33 if (proc_nr == SELF) proc_nr = m_ptr->m_source;
34 if (! isokprocn(proc_nr)) return(EINVAL);
35 if (iskerneln(proc_nr)) return(EPERM);
36
37 /* Get and check physical address. */
38 if ((phys_buf = numap_local(proc_nr, (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
39 return(EFAULT);
40
41 /* Perform device I/O for bytes and words. Longs are not supported. */
42 if (m_ptr->DIO_REQUEST == DIO_INPUT) {
43 switch (m_ptr->DIO_TYPE) {
44 case DIO_BYTE: phys_insb(port, phys_buf, count); break;
45 case DIO_WORD: phys_insw(port, phys_buf, count); break;
46 default: return(EINVAL);
47 }
48 } else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) {
49 switch (m_ptr->DIO_TYPE) {
50 case DIO_BYTE: phys_outsb(port, phys_buf, count); break;
51 case DIO_WORD: phys_outsw(port, phys_buf, count); break;
52 default: return(EINVAL);
53 }
54 }
55 else {
56 return(EINVAL);
57 }
58 return(OK);
59}
60
61#endif /* USE_SDEVIO */
62
Note: See TracBrowser for help on using the repository browser.