etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libnetdriver / portio.c
blobcac33099c85688e1fec109e78e2492db7fb592ff
1 /*
2 * Port-based I/O routines. These are in a separate module because most
3 * drivers will not use them, and system services are statically linked.
4 */
5 #include <minix/drivers.h>
6 #include <minix/netdriver.h>
7 #include <assert.h>
9 #include "netdriver.h"
12 * Port-based I/O byte sequence copy routine.
14 static void
15 netdriver_portb(struct netdriver_data * data, size_t off, long port,
16 size_t size, int portin)
18 size_t chunk;
19 unsigned int i;
20 int r, req;
22 off = netdriver_prepare_copy(data, off, size, &i);
24 req = portin ? DIO_SAFE_INPUT_BYTE : DIO_SAFE_OUTPUT_BYTE;
26 while (size > 0) {
27 chunk = data->iovec[i].iov_size - off;
28 if (chunk > size)
29 chunk = size;
30 assert(chunk > 0);
32 if ((r = sys_sdevio(req, port, data->endpt,
33 (void *)data->iovec[i].iov_grant, chunk, off)) != OK)
34 panic("netdriver: port I/O failed: %d", r);
36 i++;
37 off = 0;
38 size -= chunk;
43 * Transfer bytes from hardware to a destination buffer using port-based I/O.
45 void
46 netdriver_portinb(struct netdriver_data * data, size_t off, long port,
47 size_t size)
50 return netdriver_portb(data, off, port, size, TRUE /*portin*/);
54 * Transfer bytes from a source buffer to hardware using port-based I/O.
56 void
57 netdriver_portoutb(struct netdriver_data * data, size_t off, long port,
58 size_t size)
61 return netdriver_portb(data, off, port, size, FALSE /*portin*/);
65 * Transfer words from hardware to a destination buffer using port-based I/O.
67 void
68 netdriver_portinw(struct netdriver_data * data, size_t off, long port,
69 size_t size)
71 uint16_t buf;
72 uint32_t value;
73 size_t chunk;
74 unsigned int i;
75 int r, odd_byte;
77 off = netdriver_prepare_copy(data, off, size, &i);
79 odd_byte = 0;
80 while (size > 0) {
81 chunk = data->iovec[i].iov_size - off;
82 if (chunk > size)
83 chunk = size;
84 assert(chunk > 0);
86 if (odd_byte) {
87 if ((r = sys_safecopyto(data->endpt,
88 data->iovec[i].iov_grant, off,
89 (vir_bytes)&((char *)&buf)[1], 1)) != OK)
90 panic("netdriver: unable to copy data: %d", r);
92 off++;
93 size--;
94 chunk--;
97 odd_byte = chunk & 1;
98 chunk -= odd_byte;
100 if (chunk > 0) {
101 if ((r = sys_safe_insw(port, data->endpt,
102 data->iovec[i].iov_grant, off, chunk)) != OK)
103 panic("netdriver: port input failed: %d", r);
105 off += chunk;
106 size -= chunk;
109 if (odd_byte) {
110 if ((r = sys_inw(port, &value)) != OK)
111 panic("netdriver: port input failed: %d", r);
112 buf = (uint16_t)value;
114 if ((r = sys_safecopyto(data->endpt,
115 data->iovec[i].iov_grant, off,
116 (vir_bytes)&((char *)&buf)[0], 1)) != OK)
117 panic("netdriver: unable to copy data: %d", r);
119 size--;
122 i++;
123 off = 0;
128 * Transfer words from a source buffer to hardware using port-based I/O.
130 void
131 netdriver_portoutw(struct netdriver_data * data, size_t off, long port,
132 size_t size)
134 uint16_t buf;
135 size_t chunk;
136 unsigned int i;
137 int r, odd_byte;
139 off = netdriver_prepare_copy(data, off, size, &i);
141 odd_byte = 0;
142 while (size > 0) {
143 chunk = data->iovec[i].iov_size - off;
144 if (chunk > size)
145 chunk = size;
146 assert(chunk > 0);
148 if (odd_byte) {
149 if ((r = sys_safecopyfrom(data->endpt,
150 data->iovec[i].iov_grant, off,
151 (vir_bytes)&((char *)&buf)[1], 1)) != OK)
152 panic("netdriver: unable to copy data: %d", r);
154 if ((r = sys_outw(port, buf)) != OK)
155 panic("netdriver: port output failed: %d", r);
157 off++;
158 size--;
159 chunk--;
162 odd_byte = chunk & 1;
163 chunk -= odd_byte;
165 if (chunk > 0) {
166 if ((r = sys_safe_outsw(port, data->endpt,
167 data->iovec[i].iov_grant, off, chunk)) != OK)
168 panic("netdriver: port output failed: %d", r);
170 off += chunk;
171 size -= chunk;
174 if (odd_byte) {
175 if ((r = sys_safecopyfrom(data->endpt,
176 data->iovec[i].iov_grant, off,
177 (vir_bytes)&((char *)&buf)[0], 1)) != OK)
178 panic("netdriver: unable to copy data: %d", r);
180 size--;
183 i++;
184 off = 0;
187 if (odd_byte) {
188 ((char *)&buf)[1] = 0;
190 if ((r = sys_outw(port, buf)) != OK)
191 panic("netdriver: port output failed: %d", r);