vm: remove leftover diag print
[minix.git] / drivers / dp8390 / dp8390.c
blobad15fe05419a066a429481fc7e1bdfaa924c136b
1 /*
2 * dp8390.c
4 * This file contains a ethernet device driver for NS dp8390 based ethernet
5 * cards.
7 * The valid messages and their parameters are:
9 * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
10 * |------------+----------+---------+----------+---------+---------+---------|
11 * | HARDINT | | | | | | |
12 * |------------|----------|---------|----------|---------|---------|---------|
13 * | DL_WRITE | port nr | proc nr | count | mode | address | |
14 * |------------|----------|---------|----------|---------|---------|---------|
15 * | DL_WRITEV | port nr | proc nr | count | mode | address | |
16 * |------------|----------|---------|----------|---------|---------|---------|
17 * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
18 * |------------|----------|---------|----------|---------|---------|---------|
19 * | DL_READ | port nr | proc nr | count | | address | |
20 * |------------|----------|---------|----------|---------|---------|---------|
21 * | DL_READV | port nr | proc nr | count | | address | |
22 * |------------|----------|---------|----------|---------|---------|---------|
23 * | DL_READV_S | port nr | proc nr | count | | | grant |
24 * |------------|----------|---------|----------|---------|---------|---------|
25 * | DL_CONF | port nr | proc nr | | mode | address | |
26 * |------------|----------|---------|----------|---------|---------|---------|
27 * | DL_GETSTAT | port nr | proc nr | | | address | |
28 * |------------|----------|---------|----------|---------|---------|---------|
29 * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
30 * |------------|----------|---------|----------|---------|---------|---------|
31 * | DL_STOP | port_nr | | | | | |
32 * |------------|----------|---------|----------|---------|---------|---------|
34 * The messages sent are:
36 * m-type DL_PORT DL_PROC DL_COUNT DL_STAT DL_CLCK
37 * |-------------+----------+---------+----------+---------+---------|
38 * |DL_TASK_REPLY| port nr | proc nr | rd-count | err|stat| clock |
39 * |-------------+----------+---------+----------+---------+---------|
41 * m_type m3_i1 m3_i2 m3_ca1
42 * |-------------+---------+-----------+---------------|
43 * |DL_CONF_REPLY| port nr | last port | ethernet addr |
44 * |-------------+---------+-----------+---------------|
46 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
48 * Modified Mar 10 1994 by Philip Homburg
49 * Become a generic dp8390 driver.
51 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
52 * Added support for 3c503 boards.
55 #include <minix/drivers.h>
56 #include <minix/netdriver.h>
58 #include <stdlib.h>
59 #include <minix/com.h>
60 #include <minix/endpoint.h>
61 #include <minix/ds.h>
62 #include <net/hton.h>
63 #include <net/gen/ether.h>
64 #include <net/gen/eth_io.h>
65 #include <machine/vm.h>
66 #include "assert.h"
68 #include "local.h"
69 #include "dp8390.h"
71 #define DE_PORT_NR 3
73 static dpeth_t de_table[DE_PORT_NR];
74 static u16_t eth_ign_proto;
75 static const char *progname;
77 u32_t system_hz;
79 /* Configuration */
80 typedef struct dp_conf
82 port_t dpc_port;
83 int dpc_irq;
84 phys_bytes dpc_mem;
85 char *dpc_envvar;
86 } dp_conf_t;
88 PRIVATE dp_conf_t dp_conf[]= /* Card addresses */
90 /* I/O port, IRQ, Buffer address, Env. var. */
91 { 0x280, 3, 0xD0000, "DPETH0" },
92 { 0x300, 5, 0xC8000, "DPETH1" },
93 { 0x380, 10, 0xD8000, "DPETH2" },
96 /* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
97 * the error: "array size is negative".
99 extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
101 /* Card inits configured out? */
102 #if !ENABLE_WDETH
103 #define wdeth_probe(dep) (0)
104 #endif
105 #if !ENABLE_NE2000
106 #define ne_probe(dep) (0)
107 #endif
108 #if !ENABLE_3C503
109 #define el2_probe(dep) (0)
110 #endif
112 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
113 * on writes to the CR register. Additional CR_STAs do not appear to hurt
114 * genuine dp8390s
116 #define CR_EXTRA CR_STA
118 #if ENABLE_PCI
119 _PROTOTYPE( static void pci_conf, (void) );
120 #endif
121 _PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
122 int vectored) );
123 _PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
124 _PROTOTYPE( static void do_vread, (message *mp, int vectored) );
125 _PROTOTYPE( static void do_vread_s, (message *mp) );
126 _PROTOTYPE( static void do_init, (message *mp) );
127 _PROTOTYPE( static void do_int, (dpeth_t *dep) );
128 _PROTOTYPE( static void do_getstat, (message *mp) );
129 _PROTOTYPE( static void do_getstat_s, (message *mp) );
130 _PROTOTYPE( static void do_getname, (message *mp) );
131 _PROTOTYPE( static void do_stop, (message *mp) );
132 _PROTOTYPE( static void dp_init, (dpeth_t *dep) );
133 _PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
134 _PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
135 _PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
136 _PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
137 _PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
138 _PROTOTYPE( static void dp_send, (dpeth_t *dep) );
139 _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
140 size_t offset, size_t size, void *dst) );
141 _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
142 size_t offset, size_t size, void *dst) );
143 _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
144 size_t offset, size_t size, void *dst) );
145 _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
146 vir_bytes length) );
147 _PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
148 vir_bytes length) );
149 _PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
150 vir_bytes offset, int nic_addr, vir_bytes count) );
151 _PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
152 vir_bytes offset, int nic_addr, vir_bytes count) );
153 _PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
154 iovec_dat_t *iovp, vir_bytes offset,
155 int nic_addr, vir_bytes count) );
156 _PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
157 iovec_dat_s_t *iovp, vir_bytes offset,
158 int nic_addr, vir_bytes count) );
159 _PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
160 iovec_dat_t *iovp, vir_bytes offset,
161 int nic_addr, vir_bytes count) );
162 _PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
163 iovec_dat_s_t *iovp, vir_bytes offset,
164 int nic_addr, vir_bytes count) );
165 _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
166 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
167 _PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
168 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
169 _PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
170 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
171 _PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
172 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
173 _PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
174 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
175 _PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
176 iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
177 _PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
178 _PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
179 _PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
180 _PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
181 _PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) );
182 _PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
183 _PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
184 _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
185 _PROTOTYPE( static void mess_reply, (message *req, message *reply) );
186 _PROTOTYPE( static void get_userdata, (int user_proc,
187 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
188 _PROTOTYPE( static void get_userdata_s, (int user_proc,
189 cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
190 void *loc_addr) );
191 _PROTOTYPE( static void put_userdata, (int user_proc,
192 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
193 _PROTOTYPE( static void put_userdata_s, (int user_proc,
194 cp_grant_id_t grant, size_t count, void *loc_addr) );
195 _PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
196 _PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
197 _PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
198 vir_bytes buf, size_t size) );
199 _PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
200 vir_bytes buf, size_t size) );
201 _PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
202 vir_bytes buf, size_t size) );
203 _PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
204 vir_bytes buf, size_t size) );
206 /* SEF functions and variables. */
207 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
208 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
209 FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
210 EXTERN int env_argc;
211 EXTERN char **env_argv;
213 PRIVATE int handle_hw_intr(void)
215 int i, r, irq;
216 dpeth_t *dep;
218 for (i= 0, dep= &de_table[0]; i<DE_PORT_NR; i++, dep++)
220 if (dep->de_mode != DEM_ENABLED)
221 continue;
222 assert(dep->de_flags & DEF_ENABLED);
223 irq= dep->de_irq;
224 assert(irq >= 0 && irq < NR_IRQ_VECTORS);
225 if (dep->de_int_pending || 1)
227 dep->de_int_pending= 0;
228 dp_check_ints(dep);
229 do_int(dep);
230 r= sys_irqenable(&dep->de_hook);
231 if (r != OK) {
232 panic("unable enable interrupts: %d", r);
237 return r;
240 /*===========================================================================*
241 * dpeth_task *
242 *===========================================================================*/
243 int main(int argc, char *argv[])
245 message m;
246 int ipc_status;
247 int r;
249 /* SEF local startup. */
250 env_setargs(argc, argv);
251 sef_local_startup();
253 while (TRUE)
255 if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
256 panic("dp8390: netdriver_receive failed: %d", r);
258 if (is_ipc_notify(ipc_status)) {
259 switch (_ENDPOINT_P(m.m_source)) {
260 case HARDWARE:
261 r = handle_hw_intr();
262 break;
263 case CLOCK:
264 printf("dp8390: notify from CLOCK\n");
265 break;
266 default:
267 panic("dp8390: illegal notify from: %d",
268 m.m_source);
271 /* done, get a new message */
272 continue;
275 switch (m.m_type)
277 case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
278 case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
279 case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
280 case DL_READ: do_vread(&m, FALSE); break;
281 case DL_READV: do_vread(&m, TRUE); break;
282 case DL_READV_S: do_vread_s(&m); break;
283 case DL_CONF: do_init(&m); break;
284 case DL_GETSTAT: do_getstat(&m); break;
285 case DL_GETSTAT_S: do_getstat_s(&m); break;
286 case DL_GETNAME: do_getname(&m); break;
287 case DL_STOP: do_stop(&m); break;
288 default:
289 panic("dp8390: illegal message: %d", m.m_type);
294 /*===========================================================================*
295 * sef_local_startup *
296 *===========================================================================*/
297 PRIVATE void sef_local_startup()
299 /* Register init callbacks. */
300 sef_setcb_init_fresh(sef_cb_init_fresh);
301 sef_setcb_init_lu(sef_cb_init_fresh);
302 sef_setcb_init_restart(sef_cb_init_fresh);
304 /* Register live update callbacks. */
305 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
306 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
308 /* Register signal callbacks. */
309 sef_setcb_signal_handler(sef_cb_signal_handler);
311 /* Let SEF perform startup. */
312 sef_startup();
315 /*===========================================================================*
316 * sef_cb_init_fresh *
317 *===========================================================================*/
318 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
320 /* Initialize the dp8390 driver. */
321 int i;
322 dpeth_t *dep;
323 long v;
325 system_hz = sys_hz();
327 if (env_argc < 1) {
328 panic("A head which at this time has no name");
330 (progname=strrchr(env_argv[0],'/')) ? progname++
331 : (progname=env_argv[0]);
333 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
335 strcpy(dep->de_name, "dp8390#0");
336 dep->de_name[7] += i;
339 v= 0;
340 (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
341 eth_ign_proto= htons((u16_t) v);
343 /* Announce we are up! */
344 netdriver_announce();
346 return(OK);
349 /*===========================================================================*
350 * sef_cb_signal_handler *
351 *===========================================================================*/
352 PRIVATE void sef_cb_signal_handler(int signo)
354 message mess;
355 int i;
357 /* Only check for termination signal, ignore anything else. */
358 if (signo != SIGTERM) return;
360 for (i= 0; i<DE_PORT_NR; i++)
362 if (de_table[i].de_mode != DEM_ENABLED)
363 continue;
364 mess.m_type= DL_STOP;
365 mess.DL_PORT= i;
366 do_stop(&mess);
370 #if 0
371 /*===========================================================================*
372 * dp8390_dump *
373 *===========================================================================*/
374 void dp8390_dump()
376 dpeth_t *dep;
377 int i, isr;
379 printf("\n");
380 for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
382 #if XXX
383 if (dep->de_mode == DEM_DISABLED)
384 printf("dp8390 port %d is disabled\n", i);
385 else if (dep->de_mode == DEM_SINK)
386 printf("dp8390 port %d is in sink mode\n", i);
387 #endif
389 if (dep->de_mode != DEM_ENABLED)
390 continue;
392 printf("dp8390 statistics of port %d:\n", i);
394 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
395 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
396 printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
398 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
399 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
400 printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
402 printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
403 printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
404 printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
406 printf("collision :%8ld\t", dep->de_stat.ets_collision);
407 printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
408 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
410 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
411 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
412 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
414 printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
416 isr= inb_reg0(dep, DP_ISR);
417 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
418 inb_reg0(dep, DP_ISR), dep->de_flags);
421 #endif
423 #if ENABLE_PCI
424 /*===========================================================================*
425 * pci_conf *
426 *===========================================================================*/
427 static void pci_conf()
429 int i, h;
430 char *envvar;
431 struct dpeth *dep;
432 static char envfmt[] = "*:d.d.d";
433 long v;
434 static int first_time= 1;
436 if (!first_time)
437 return;
438 first_time= 0;
440 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
442 envvar= dp_conf[i].dpc_envvar;
443 if (!(dep->de_pci= env_prefix(envvar, "pci")))
444 continue; /* no PCI config */
445 v= 0;
446 (void) env_parse(envvar, envfmt, 1, &v, 0, 255);
447 dep->de_pcibus= v;
448 v= 0;
449 (void) env_parse(envvar, envfmt, 2, &v, 0, 255);
450 dep->de_pcidev= v;
451 v= 0;
452 (void) env_parse(envvar, envfmt, 3, &v, 0, 255);
453 dep->de_pcifunc= v;
456 for (h= 1; h >= 0; h--) {
457 for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
459 if (!dep->de_pci)
461 printf("pci: no pci for port %d\n", i);
462 continue;
464 if (((dep->de_pcibus | dep->de_pcidev |
465 dep->de_pcifunc) != 0) != h)
467 continue;
469 if (!rtl_probe(dep))
470 dep->de_pci= -1;
474 #endif /* ENABLE_PCI */
476 /*===========================================================================*
477 * do_vwrite *
478 *===========================================================================*/
479 static void do_vwrite(mp, from_int, vectored)
480 message *mp;
481 int from_int;
482 int vectored;
484 int port, count, size;
485 int sendq_head;
486 dpeth_t *dep;
488 port = mp->DL_PORT;
489 count = mp->DL_COUNT;
490 if (port < 0 || port >= DE_PORT_NR)
491 panic("dp8390: illegal port: %d", port);
492 dep= &de_table[port];
493 dep->de_client= mp->DL_PROC;
495 if (dep->de_mode == DEM_SINK)
497 assert(!from_int);
498 dep->de_flags |= DEF_PACK_SEND;
499 reply(dep, OK, FALSE);
500 return;
502 assert(dep->de_mode == DEM_ENABLED);
503 assert(dep->de_flags & DEF_ENABLED);
504 if (dep->de_flags & DEF_SEND_AVAIL)
505 panic("dp8390: send already in progress");
507 sendq_head= dep->de_sendq_head;
508 if (dep->de_sendq[sendq_head].sq_filled)
510 if (from_int)
511 panic("dp8390: should not be sending");
512 dep->de_sendmsg= *mp;
513 dep->de_flags |= DEF_SEND_AVAIL;
514 reply(dep, OK, FALSE);
515 return;
517 assert(!(dep->de_flags & DEF_PACK_SEND));
519 if (vectored)
521 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
522 (count > IOVEC_NR ? IOVEC_NR : count) *
523 sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
524 dep->de_write_iovec.iod_iovec_s = count;
525 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
526 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
528 dep->de_tmp_iovec = dep->de_write_iovec;
529 size = calc_iovec_size(&dep->de_tmp_iovec);
531 else
533 dep->de_write_iovec.iod_iovec[0].iov_addr =
534 (vir_bytes) mp->DL_ADDR;
535 dep->de_write_iovec.iod_iovec[0].iov_size =
536 mp->DL_COUNT;
537 dep->de_write_iovec.iod_iovec_s = 1;
538 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
539 dep->de_write_iovec.iod_iovec_addr = 0;
540 size= mp->DL_COUNT;
542 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
544 panic("dp8390: invalid packet size: %d", size);
546 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
547 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
548 size);
549 dep->de_sendq[sendq_head].sq_filled= TRUE;
550 if (dep->de_sendq_tail == sendq_head)
552 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
553 outb_reg0(dep, DP_TBCR1, size >> 8);
554 outb_reg0(dep, DP_TBCR0, size & 0xff);
555 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
557 else
558 dep->de_sendq[sendq_head].sq_size= size;
560 if (++sendq_head == dep->de_sendq_nr)
561 sendq_head= 0;
562 assert(sendq_head < SENDQ_NR);
563 dep->de_sendq_head= sendq_head;
565 dep->de_flags |= DEF_PACK_SEND;
567 /* If the interrupt handler called, don't send a reply. The reply
568 * will be sent after all interrupts are handled.
570 if (from_int)
571 return;
572 reply(dep, OK, FALSE);
574 assert(dep->de_mode == DEM_ENABLED);
575 assert(dep->de_flags & DEF_ENABLED);
578 /*===========================================================================*
579 * do_vwrite_s *
580 *===========================================================================*/
581 static void do_vwrite_s(mp, from_int)
582 message *mp;
583 int from_int;
585 int port, count, size;
586 int sendq_head;
587 dpeth_t *dep;
589 port = mp->DL_PORT;
590 count = mp->DL_COUNT;
591 if (port < 0 || port >= DE_PORT_NR)
592 panic("dp8390: illegal port: %d", port);
593 dep= &de_table[port];
594 dep->de_client= mp->DL_PROC;
596 if (dep->de_mode == DEM_SINK)
598 assert(!from_int);
599 dep->de_flags |= DEF_PACK_SEND;
600 reply(dep, OK, FALSE);
601 return;
603 assert(dep->de_mode == DEM_ENABLED);
604 assert(dep->de_flags & DEF_ENABLED);
605 if (dep->de_flags & DEF_SEND_AVAIL)
606 panic("dp8390: send already in progress");
608 sendq_head= dep->de_sendq_head;
609 if (dep->de_sendq[sendq_head].sq_filled)
611 if (from_int)
612 panic("dp8390: should not be sending");
613 dep->de_sendmsg= *mp;
614 dep->de_flags |= DEF_SEND_AVAIL;
615 reply(dep, OK, FALSE);
616 return;
618 assert(!(dep->de_flags & DEF_PACK_SEND));
620 get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
621 (count > IOVEC_NR ? IOVEC_NR : count) *
622 sizeof(dep->de_write_iovec_s.iod_iovec[0]),
623 dep->de_write_iovec_s.iod_iovec);
624 dep->de_write_iovec_s.iod_iovec_s = count;
625 dep->de_write_iovec_s.iod_proc_nr = mp->DL_PROC;
626 dep->de_write_iovec_s.iod_grant = mp->DL_GRANT;
627 dep->de_write_iovec_s.iod_iovec_offset = 0;
629 dep->de_tmp_iovec_s = dep->de_write_iovec_s;
630 size = calc_iovec_size_s(&dep->de_tmp_iovec_s);
632 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
634 panic("dp8390: invalid packet size: %d", size);
636 (dep->de_user2nicf_s)(dep, &dep->de_write_iovec_s, 0,
637 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
638 size);
639 dep->de_sendq[sendq_head].sq_filled= TRUE;
640 if (dep->de_sendq_tail == sendq_head)
642 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
643 outb_reg0(dep, DP_TBCR1, size >> 8);
644 outb_reg0(dep, DP_TBCR0, size & 0xff);
645 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
647 else
648 dep->de_sendq[sendq_head].sq_size= size;
650 if (++sendq_head == dep->de_sendq_nr)
651 sendq_head= 0;
652 assert(sendq_head < SENDQ_NR);
653 dep->de_sendq_head= sendq_head;
655 dep->de_flags |= DEF_PACK_SEND;
657 /* If the interrupt handler called, don't send a reply. The reply
658 * will be sent after all interrupts are handled.
660 if (from_int)
661 return;
662 reply(dep, OK, FALSE);
664 assert(dep->de_mode == DEM_ENABLED);
665 assert(dep->de_flags & DEF_ENABLED);
668 /*===========================================================================*
669 * do_vread *
670 *===========================================================================*/
671 static void do_vread(mp, vectored)
672 message *mp;
673 int vectored;
675 int port, count;
676 int size;
677 dpeth_t *dep;
679 port = mp->DL_PORT;
680 count = mp->DL_COUNT;
681 if (port < 0 || port >= DE_PORT_NR)
682 panic("dp8390: illegal port: %d", port);
683 dep= &de_table[port];
684 dep->de_client= mp->DL_PROC;
685 if (dep->de_mode == DEM_SINK)
687 reply(dep, OK, FALSE);
688 return;
690 assert(dep->de_mode == DEM_ENABLED);
691 assert(dep->de_flags & DEF_ENABLED);
693 if(dep->de_flags & DEF_READING)
694 panic("dp8390: read already in progress");
696 dep->de_safecopy_read= 0;
698 if (vectored)
700 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
701 (count > IOVEC_NR ? IOVEC_NR : count) *
702 sizeof(iovec_t), dep->de_read_iovec.iod_iovec);
703 dep->de_read_iovec.iod_iovec_s = count;
704 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
705 dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
707 dep->de_tmp_iovec = dep->de_read_iovec;
708 size= calc_iovec_size(&dep->de_tmp_iovec);
710 else
712 dep->de_read_iovec.iod_iovec[0].iov_addr =
713 (vir_bytes) mp->DL_ADDR;
714 dep->de_read_iovec.iod_iovec[0].iov_size =
715 mp->DL_COUNT;
716 dep->de_read_iovec.iod_iovec_s = 1;
717 dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
718 dep->de_read_iovec.iod_iovec_addr = 0;
719 size= count;
721 if (size < ETH_MAX_PACK_SIZE_TAGGED)
722 panic("dp8390: wrong packet size: %d", size);
723 dep->de_flags |= DEF_READING;
725 dp_recv(dep);
727 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
728 (DEF_READING|DEF_STOPPED))
730 /* The chip is stopped, and all arrived packets are
731 * delivered.
733 dp_reset(dep);
735 reply(dep, OK, FALSE);
738 /*===========================================================================*
739 * do_vread_s *
740 *===========================================================================*/
741 static void do_vread_s(mp)
742 message *mp;
744 int port, count;
745 int size;
746 dpeth_t *dep;
748 port = mp->DL_PORT;
749 count = mp->DL_COUNT;
750 if (port < 0 || port >= DE_PORT_NR)
751 panic("dp8390: illegal port: %d", port);
752 dep= &de_table[port];
753 dep->de_client= mp->DL_PROC;
754 if (dep->de_mode == DEM_SINK)
756 reply(dep, OK, FALSE);
757 return;
759 assert(dep->de_mode == DEM_ENABLED);
760 assert(dep->de_flags & DEF_ENABLED);
762 dep->de_safecopy_read= 1;
764 if(dep->de_flags & DEF_READING)
765 panic("dp8390: read already in progress");
767 get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
768 (count > IOVEC_NR ? IOVEC_NR : count) *
769 sizeof(dep->de_read_iovec_s.iod_iovec[0]),
770 dep->de_read_iovec_s.iod_iovec);
771 dep->de_read_iovec_s.iod_iovec_s = count;
772 dep->de_read_iovec_s.iod_proc_nr = mp->DL_PROC;
773 dep->de_read_iovec_s.iod_grant = mp->DL_GRANT;
774 dep->de_read_iovec_s.iod_iovec_offset = 0;
776 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
777 size= calc_iovec_size_s(&dep->de_tmp_iovec_s);
779 if (size < ETH_MAX_PACK_SIZE_TAGGED)
780 panic("dp8390: wrong packet size: %d", size);
781 dep->de_flags |= DEF_READING;
783 dp_recv(dep);
785 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
786 (DEF_READING|DEF_STOPPED))
788 /* The chip is stopped, and all arrived packets are
789 * delivered.
791 dp_reset(dep);
793 reply(dep, OK, FALSE);
796 /*===========================================================================*
797 * do_init *
798 *===========================================================================*/
799 static void do_init(message *mp)
801 int port;
802 dpeth_t *dep;
803 message reply_mess;
805 #if ENABLE_PCI
806 pci_conf(); /* Configure PCI devices. */
807 #endif
809 port = mp->DL_PORT;
810 if (port < 0 || port >= DE_PORT_NR)
812 reply_mess.m_type= DL_CONF_REPLY;
813 reply_mess.m3_i1= ENXIO;
814 mess_reply(mp, &reply_mess);
815 return;
817 dep= &de_table[port];
818 if (dep->de_mode == DEM_DISABLED)
820 /* This is the default, try to (re)locate the device. */
821 conf_hw(dep);
822 if (dep->de_mode == DEM_DISABLED)
824 /* Probe failed, or the device is configured off. */
825 reply_mess.m_type= DL_CONF_REPLY;
826 reply_mess.m3_i1= ENXIO;
827 mess_reply(mp, &reply_mess);
828 return;
830 if (dep->de_mode == DEM_ENABLED)
831 dp_init(dep);
834 if (dep->de_mode == DEM_SINK)
836 strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
837 dep->de_address.ea_addr[5] = port;
838 dp_confaddr(dep);
839 reply_mess.m_type = DL_CONF_REPLY;
840 reply_mess.m3_i1 = mp->DL_PORT;
841 reply_mess.m3_i2 = DE_PORT_NR;
842 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
843 mess_reply(mp, &reply_mess);
844 return;
846 assert(dep->de_mode == DEM_ENABLED);
847 assert(dep->de_flags & DEF_ENABLED);
849 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
851 if (mp->DL_MODE & DL_PROMISC_REQ)
852 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
853 if (mp->DL_MODE & DL_MULTI_REQ)
854 dep->de_flags |= DEF_MULTI;
855 if (mp->DL_MODE & DL_BROAD_REQ)
856 dep->de_flags |= DEF_BROAD;
858 dep->de_client = mp->m_source;
859 dp_reinit(dep);
861 reply_mess.m_type = DL_CONF_REPLY;
862 reply_mess.m3_i1 = mp->DL_PORT;
863 reply_mess.m3_i2 = DE_PORT_NR;
864 *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
866 mess_reply(mp, &reply_mess);
869 /*===========================================================================*
870 * do_int *
871 *===========================================================================*/
872 static void do_int(dep)
873 dpeth_t *dep;
875 if (dep->de_flags & (DEF_PACK_SEND | DEF_PACK_RECV))
876 reply(dep, OK, TRUE);
879 /*===========================================================================*
880 * do_getstat *
881 *===========================================================================*/
882 static void do_getstat(message *mp)
884 int port, r;
885 dpeth_t *dep;
887 port = mp->DL_PORT;
888 if (port < 0 || port >= DE_PORT_NR)
889 panic("dp8390: illegal port: %d", port);
890 dep= &de_table[port];
891 dep->de_client= mp->DL_PROC;
892 if (dep->de_mode == DEM_SINK)
894 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
895 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
897 mp->m_type= DL_STAT_REPLY;
898 mp->DL_PORT= port;
899 mp->DL_STAT= OK;
900 r= send(mp->m_source, mp);
901 if (r != OK)
902 panic("do_getstat: send failed: %d", r);
903 return;
905 assert(dep->de_mode == DEM_ENABLED);
906 assert(dep->de_flags & DEF_ENABLED);
908 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
909 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
910 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
912 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
913 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
915 mp->m_type= DL_STAT_REPLY;
916 mp->DL_PORT= port;
917 mp->DL_STAT= OK;
918 r= send(mp->m_source, mp);
919 if (r != OK)
920 panic("do_getstat: send failed: %d", r);
923 /*===========================================================================*
924 * do_getstat_s *
925 *===========================================================================*/
926 static void do_getstat_s(mp)
927 message *mp;
929 int port, r;
930 dpeth_t *dep;
932 port = mp->DL_PORT;
933 if (port < 0 || port >= DE_PORT_NR)
934 panic("dp8390: illegal port: %d", port);
935 dep= &de_table[port];
936 dep->de_client= mp->DL_PROC;
937 if (dep->de_mode == DEM_SINK)
939 put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
940 (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
942 mp->m_type= DL_STAT_REPLY;
943 mp->DL_PORT= port;
944 mp->DL_STAT= OK;
945 r= send(mp->m_source, mp);
946 if (r != OK)
947 panic("do_getstat: send failed: %d", r);
948 return;
950 assert(dep->de_mode == DEM_ENABLED);
951 assert(dep->de_flags & DEF_ENABLED);
953 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
954 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
955 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
957 put_userdata_s(mp->DL_PROC, mp->DL_GRANT,
958 sizeof(dep->de_stat), &dep->de_stat);
960 mp->m_type= DL_STAT_REPLY;
961 mp->DL_PORT= port;
962 mp->DL_STAT= OK;
963 r= send(mp->m_source, mp);
964 if (r != OK)
965 panic("do_getstat: send failed: %d", r);
968 /*===========================================================================*
969 * do_getname *
970 *===========================================================================*/
971 static void do_getname(mp)
972 message *mp;
974 int r;
976 strncpy(mp->DL_NAME, progname, sizeof(mp->DL_NAME));
977 mp->DL_NAME[sizeof(mp->DL_NAME)-1]= '\0';
978 mp->m_type= DL_NAME_REPLY;
979 r= send(mp->m_source, mp);
980 if (r != OK)
981 panic("do_getname: send failed: %d", r);
984 /*===========================================================================*
985 * do_stop *
986 *===========================================================================*/
987 static void do_stop(mp)
988 message *mp;
990 int port;
991 dpeth_t *dep;
993 port = mp->DL_PORT;
995 if (port < 0 || port >= DE_PORT_NR)
996 panic("dp8390: illegal port: %d", port);
997 dep= &de_table[port];
998 if (dep->de_mode == DEM_SINK)
999 return;
1000 assert(dep->de_mode == DEM_ENABLED);
1002 if (!(dep->de_flags & DEF_ENABLED))
1003 return;
1005 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
1006 (dep->de_stopf)(dep);
1008 dep->de_flags= DEF_EMPTY;
1011 /*===========================================================================*
1012 * dp_init *
1013 *===========================================================================*/
1014 static void dp_init(dep)
1015 dpeth_t *dep;
1017 int dp_rcr_reg;
1018 int i, r;
1020 /* General initialization */
1021 dep->de_flags = DEF_EMPTY;
1022 (*dep->de_initf)(dep);
1024 dp_confaddr(dep);
1026 if (debug)
1028 printf("%s: Ethernet address ", dep->de_name);
1029 for (i= 0; i < 6; i++)
1030 printf("%x%c", dep->de_address.ea_addr[i],
1031 i < 5 ? ':' : '\n');
1034 /* Map buffer */
1035 map_hw_buffer(dep);
1037 /* Initialization of the dp8390 following the mandatory procedure
1038 * in reference manual ("DP8390D/NS32490D NIC Network Interface
1039 * Controller", National Semiconductor, July 1995, Page 29).
1041 /* Step 1: */
1042 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
1043 /* Step 2: */
1044 if (dep->de_16bit)
1045 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
1046 else
1047 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
1048 /* Step 3: */
1049 outb_reg0(dep, DP_RBCR0, 0);
1050 outb_reg0(dep, DP_RBCR1, 0);
1051 /* Step 4: */
1052 dp_rcr_reg = 0;
1053 if (dep->de_flags & DEF_PROMISC)
1054 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
1055 if (dep->de_flags & DEF_BROAD)
1056 dp_rcr_reg |= RCR_AB;
1057 if (dep->de_flags & DEF_MULTI)
1058 dp_rcr_reg |= RCR_AM;
1059 outb_reg0(dep, DP_RCR, dp_rcr_reg);
1060 /* Step 5: */
1061 outb_reg0(dep, DP_TCR, TCR_INTERNAL);
1062 /* Step 6: */
1063 outb_reg0(dep, DP_BNRY, dep->de_startpage);
1064 outb_reg0(dep, DP_PSTART, dep->de_startpage);
1065 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
1066 /* Step 7: */
1067 outb_reg0(dep, DP_ISR, 0xFF);
1068 /* Step 8: */
1069 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
1070 IMR_OVWE | IMR_CNTE);
1071 /* Step 9: */
1072 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
1074 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
1075 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
1076 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
1077 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
1078 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
1079 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
1081 outb_reg1(dep, DP_MAR0, 0xff);
1082 outb_reg1(dep, DP_MAR1, 0xff);
1083 outb_reg1(dep, DP_MAR2, 0xff);
1084 outb_reg1(dep, DP_MAR3, 0xff);
1085 outb_reg1(dep, DP_MAR4, 0xff);
1086 outb_reg1(dep, DP_MAR5, 0xff);
1087 outb_reg1(dep, DP_MAR6, 0xff);
1088 outb_reg1(dep, DP_MAR7, 0xff);
1090 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
1091 /* Step 10: */
1092 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
1093 /* Step 11: */
1094 outb_reg0(dep, DP_TCR, TCR_NORMAL);
1096 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
1097 inb_reg0(dep, DP_CNTR1);
1098 inb_reg0(dep, DP_CNTR2);
1100 /* Finish the initialization. */
1101 dep->de_flags |= DEF_ENABLED;
1102 for (i= 0; i<dep->de_sendq_nr; i++)
1103 dep->de_sendq[i].sq_filled= 0;
1104 dep->de_sendq_head= 0;
1105 dep->de_sendq_tail= 0;
1106 if (!dep->de_prog_IO)
1108 dep->de_user2nicf= dp_user2nic;
1109 dep->de_user2nicf_s= dp_user2nic_s;
1110 dep->de_nic2userf= dp_nic2user;
1111 dep->de_nic2userf_s= dp_nic2user_s;
1112 dep->de_getblockf= dp_getblock;
1114 else if (dep->de_16bit)
1116 dep->de_user2nicf= dp_pio16_user2nic;
1117 dep->de_user2nicf_s= dp_pio16_user2nic_s;
1118 dep->de_nic2userf= dp_pio16_nic2user;
1119 dep->de_nic2userf_s= dp_pio16_nic2user_s;
1120 dep->de_getblockf= dp_pio16_getblock;
1122 else
1124 dep->de_user2nicf= dp_pio8_user2nic;
1125 dep->de_user2nicf_s= dp_pio8_user2nic_s;
1126 dep->de_nic2userf= dp_pio8_nic2user;
1127 dep->de_nic2userf_s= dp_pio8_nic2user_s;
1128 dep->de_getblockf= dp_pio8_getblock;
1131 /* Set the interrupt handler and policy. Do not automatically
1132 * reenable interrupts. Return the IRQ line number on interrupts.
1134 dep->de_hook = dep->de_irq;
1135 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
1136 if (r != OK)
1137 panic("sys_irqsetpolicy failed: %d", r);
1139 r= sys_irqenable(&dep->de_hook);
1140 if (r != OK)
1142 panic("unable enable interrupts: %d", r);
1146 /*===========================================================================*
1147 * dp_confaddr *
1148 *===========================================================================*/
1149 static void dp_confaddr(dep)
1150 dpeth_t *dep;
1152 int i;
1153 char eakey[16];
1154 static char eafmt[]= "x:x:x:x:x:x";
1155 long v;
1157 /* User defined ethernet address? */
1158 strcpy(eakey, dp_conf[dep-de_table].dpc_envvar);
1159 strcat(eakey, "_EA");
1161 for (i= 0; i < 6; i++)
1163 v= dep->de_address.ea_addr[i];
1164 if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
1166 break;
1168 dep->de_address.ea_addr[i]= v;
1171 if (i != 0 && i != 6) env_panic(eakey); /* It's all or nothing */
1174 /*===========================================================================*
1175 * dp_reinit *
1176 *===========================================================================*/
1177 static void dp_reinit(dep)
1178 dpeth_t *dep;
1180 int dp_rcr_reg;
1182 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
1184 dp_rcr_reg = 0;
1185 if (dep->de_flags & DEF_PROMISC)
1186 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
1187 if (dep->de_flags & DEF_BROAD)
1188 dp_rcr_reg |= RCR_AB;
1189 if (dep->de_flags & DEF_MULTI)
1190 dp_rcr_reg |= RCR_AM;
1191 outb_reg0(dep, DP_RCR, dp_rcr_reg);
1194 /*===========================================================================*
1195 * dp_reset *
1196 *===========================================================================*/
1197 static void dp_reset(dep)
1198 dpeth_t *dep;
1200 int i;
1202 /* Stop chip */
1203 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
1204 outb_reg0(dep, DP_RBCR0, 0);
1205 outb_reg0(dep, DP_RBCR1, 0);
1206 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
1207 ; /* Do nothing */
1208 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
1209 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
1210 outb_reg0(dep, DP_TCR, TCR_NORMAL);
1212 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
1213 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
1214 ; /* Do nothing */
1215 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
1217 /* Reset the transmit ring. If we were transmitting a packet, we
1218 * pretend that the packet is processed. Higher layers will
1219 * retransmit if the packet wasn't actually sent.
1221 dep->de_sendq_head= dep->de_sendq_tail= 0;
1222 for (i= 0; i<dep->de_sendq_nr; i++)
1223 dep->de_sendq[i].sq_filled= 0;
1224 dp_send(dep);
1225 dep->de_flags &= ~DEF_STOPPED;
1228 /*===========================================================================*
1229 * dp_check_ints *
1230 *===========================================================================*/
1231 static void dp_check_ints(dep)
1232 dpeth_t *dep;
1234 int isr, tsr;
1235 int size, sendq_tail;
1237 if (!(dep->de_flags & DEF_ENABLED))
1238 panic("dp8390: got premature interrupt");
1240 for(;;)
1242 isr = inb_reg0(dep, DP_ISR);
1243 if (!isr)
1244 break;
1245 outb_reg0(dep, DP_ISR, isr);
1246 if (isr & (ISR_PTX|ISR_TXE))
1248 if (isr & ISR_TXE)
1250 #if DEBUG
1251 { printf("%s: got send Error\n", dep->de_name); }
1252 #endif
1253 dep->de_stat.ets_sendErr++;
1255 else
1257 tsr = inb_reg0(dep, DP_TSR);
1259 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
1260 #if 0 /* Reserved in later manuals, should be ignored */
1261 if (!(tsr & TSR_DFR))
1263 /* In most (all?) implementations of
1264 * the dp8390, this bit is set
1265 * when the packet is not deferred
1267 dep->de_stat.ets_transDef++;
1269 #endif
1270 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
1271 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
1272 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
1273 if (tsr & TSR_FU
1274 && ++dep->de_stat.ets_fifoUnder <= 10)
1276 printf("%s: fifo underrun\n",
1277 dep->de_name);
1279 if (tsr & TSR_CDH
1280 && ++dep->de_stat.ets_CDheartbeat <= 10)
1282 printf("%s: CD heart beat failure\n",
1283 dep->de_name);
1285 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
1287 sendq_tail= dep->de_sendq_tail;
1289 if (!(dep->de_sendq[sendq_tail].sq_filled))
1291 /* Software bug? */
1292 assert(!debug);
1294 /* Or hardware bug? */
1295 printf(
1296 "%s: transmit interrupt, but not sending\n",
1297 dep->de_name);
1298 continue;
1300 dep->de_sendq[sendq_tail].sq_filled= 0;
1301 if (++sendq_tail == dep->de_sendq_nr)
1302 sendq_tail= 0;
1303 dep->de_sendq_tail= sendq_tail;
1304 if (dep->de_sendq[sendq_tail].sq_filled)
1306 size= dep->de_sendq[sendq_tail].sq_size;
1307 outb_reg0(dep, DP_TPSR,
1308 dep->de_sendq[sendq_tail].sq_sendpage);
1309 outb_reg0(dep, DP_TBCR1, size >> 8);
1310 outb_reg0(dep, DP_TBCR0, size & 0xff);
1311 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
1313 if (dep->de_flags & DEF_SEND_AVAIL)
1314 dp_send(dep);
1317 if (isr & ISR_PRX)
1319 /* Only call dp_recv if there is a read request */
1320 if (dep->de_flags & DEF_READING)
1321 dp_recv(dep);
1324 if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
1325 if (isr & ISR_CNT)
1327 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
1328 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
1329 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
1331 if (isr & ISR_OVW)
1333 dep->de_stat.ets_OVW++;
1334 #if 0
1335 { printW(); printf(
1336 "%s: got overwrite warning\n", dep->de_name); }
1337 #endif
1338 if (dep->de_flags & DEF_READING)
1340 printf(
1341 "dp_check_ints: strange: overwrite warning and pending read request\n");
1342 dp_recv(dep);
1345 if (isr & ISR_RDC)
1347 /* Nothing to do */
1349 if (isr & ISR_RST)
1351 /* this means we got an interrupt but the ethernet
1352 * chip is shutdown. We set the flag DEF_STOPPED,
1353 * and continue processing arrived packets. When the
1354 * receive buffer is empty, we reset the dp8390.
1356 #if 0
1357 { printW(); printf(
1358 "%s: NIC stopped\n", dep->de_name); }
1359 #endif
1360 dep->de_flags |= DEF_STOPPED;
1361 break;
1364 if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
1365 (DEF_READING|DEF_STOPPED))
1367 /* The chip is stopped, and all arrived packets are
1368 * delivered.
1370 dp_reset(dep);
1374 /*===========================================================================*
1375 * dp_recv *
1376 *===========================================================================*/
1377 static void dp_recv(dep)
1378 dpeth_t *dep;
1380 dp_rcvhdr_t header;
1381 unsigned pageno, curr, next;
1382 vir_bytes length;
1383 int packet_processed, r;
1384 u16_t eth_type;
1386 packet_processed = FALSE;
1387 pageno = inb_reg0(dep, DP_BNRY) + 1;
1388 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
1392 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
1393 curr = inb_reg1(dep, DP_CURR);
1394 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
1396 if (curr == pageno) break;
1398 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
1399 &header);
1400 (dep->de_getblockf)(dep, pageno, sizeof(header) +
1401 2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
1403 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
1404 sizeof(dp_rcvhdr_t);
1405 next = header.dr_next;
1406 if (length < ETH_MIN_PACK_SIZE ||
1407 length > ETH_MAX_PACK_SIZE_TAGGED)
1409 printf("%s: packet with strange length arrived: %d\n",
1410 dep->de_name, (int) length);
1411 next= curr;
1413 else if (next < dep->de_startpage || next >= dep->de_stoppage)
1415 printf("%s: strange next page\n", dep->de_name);
1416 next= curr;
1418 else if (eth_type == eth_ign_proto)
1420 /* Hack: ignore packets of a given protocol, useful
1421 * if you share a net with 80 computers sending
1422 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
1424 static int first= 1;
1425 if (first)
1427 first= 0;
1428 printf("%s: dropping proto 0x%04x packets\n",
1429 dep->de_name,
1430 ntohs(eth_ign_proto));
1432 dep->de_stat.ets_packetR++;
1434 else if (header.dr_status & RSR_FO)
1436 /* This is very serious, so we issue a warning and
1437 * reset the buffers */
1438 printf("%s: fifo overrun, resetting receive buffer\n",
1439 dep->de_name);
1440 dep->de_stat.ets_fifoOver++;
1441 next = curr;
1443 else if ((header.dr_status & RSR_PRX) &&
1444 (dep->de_flags & DEF_ENABLED))
1446 if (dep->de_safecopy_read)
1447 r = dp_pkt2user_s(dep, pageno, length);
1448 else
1449 r = dp_pkt2user(dep, pageno, length);
1450 if (r != OK)
1451 return;
1453 packet_processed = TRUE;
1454 dep->de_stat.ets_packetR++;
1456 if (next == dep->de_startpage)
1457 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
1458 else
1459 outb_reg0(dep, DP_BNRY, next - 1);
1461 pageno = next;
1463 while (!packet_processed);
1466 /*===========================================================================*
1467 * dp_send *
1468 *===========================================================================*/
1469 static void dp_send(dep)
1470 dpeth_t *dep;
1472 if (!(dep->de_flags & DEF_SEND_AVAIL))
1473 return;
1475 dep->de_flags &= ~DEF_SEND_AVAIL;
1476 switch(dep->de_sendmsg.m_type)
1478 case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
1479 case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
1480 case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break;
1481 default:
1482 panic("dp8390: wrong type: %d", dep->de_sendmsg.m_type);
1483 break;
1487 /*===========================================================================*
1488 * dp_getblock *
1489 *===========================================================================*/
1490 static void dp_getblock(dep, page, offset, size, dst)
1491 dpeth_t *dep;
1492 int page;
1493 size_t offset;
1494 size_t size;
1495 void *dst;
1497 offset = page * DP_PAGESIZE + offset;
1499 memcpy(dst, dep->de_locmem + offset, size);
1502 /*===========================================================================*
1503 * dp_pio8_getblock *
1504 *===========================================================================*/
1505 static void dp_pio8_getblock(dep, page, offset, size, dst)
1506 dpeth_t *dep;
1507 int page;
1508 size_t offset;
1509 size_t size;
1510 void *dst;
1512 offset = page * DP_PAGESIZE + offset;
1513 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1514 outb_reg0(dep, DP_RBCR1, size >> 8);
1515 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1516 outb_reg0(dep, DP_RSAR1, offset >> 8);
1517 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1519 insb(dep->de_data_port, dst, size);
1522 /*===========================================================================*
1523 * dp_pio16_getblock *
1524 *===========================================================================*/
1525 static void dp_pio16_getblock(dep, page, offset, size, dst)
1526 dpeth_t *dep;
1527 int page;
1528 size_t offset;
1529 size_t size;
1530 void *dst;
1532 offset = page * DP_PAGESIZE + offset;
1533 outb_reg0(dep, DP_RBCR0, size & 0xFF);
1534 outb_reg0(dep, DP_RBCR1, size >> 8);
1535 outb_reg0(dep, DP_RSAR0, offset & 0xFF);
1536 outb_reg0(dep, DP_RSAR1, offset >> 8);
1537 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1539 assert (!(size & 1));
1540 insw(dep->de_data_port, dst, size);
1543 /*===========================================================================*
1544 * dp_pkt2user *
1545 *===========================================================================*/
1546 static int dp_pkt2user(dpeth_t *dep, int page, vir_bytes length)
1548 int last, count;
1550 if (!(dep->de_flags & DEF_READING))
1551 return EGENERIC;
1553 last = page + (length - 1) / DP_PAGESIZE;
1554 if (last >= dep->de_stoppage)
1556 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1557 sizeof(dp_rcvhdr_t);
1559 /* Save read_iovec since we need it twice. */
1560 dep->de_tmp_iovec = dep->de_read_iovec;
1561 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1562 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
1563 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
1564 &dep->de_read_iovec, count, length - count);
1566 else
1568 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1569 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
1572 dep->de_read_s = length;
1573 dep->de_flags |= DEF_PACK_RECV;
1574 dep->de_flags &= ~DEF_READING;
1576 return OK;
1579 /*===========================================================================*
1580 * dp_pkt2user_s *
1581 *===========================================================================*/
1582 static int dp_pkt2user_s(dpeth_t *dep, int page, vir_bytes length)
1584 int last, count;
1586 if (!(dep->de_flags & DEF_READING))
1587 return EGENERIC;
1589 last = page + (length - 1) / DP_PAGESIZE;
1590 if (last >= dep->de_stoppage)
1592 count = (dep->de_stoppage - page) * DP_PAGESIZE -
1593 sizeof(dp_rcvhdr_t);
1595 /* Save read_iovec since we need it twice. */
1596 dep->de_tmp_iovec_s = dep->de_read_iovec_s;
1597 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1598 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec_s, 0, count);
1599 (dep->de_nic2userf_s)(dep, dep->de_startpage * DP_PAGESIZE,
1600 &dep->de_read_iovec_s, count, length - count);
1602 else
1604 (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
1605 sizeof(dp_rcvhdr_t), &dep->de_read_iovec_s, 0, length);
1608 dep->de_read_s = length;
1609 dep->de_flags |= DEF_PACK_RECV;
1610 dep->de_flags &= ~DEF_READING;
1612 return OK;
1615 /*===========================================================================*
1616 * dp_user2nic *
1617 *===========================================================================*/
1618 static void dp_user2nic(dep, iovp, offset, nic_addr, count)
1619 dpeth_t *dep;
1620 iovec_dat_t *iovp;
1621 vir_bytes offset;
1622 int nic_addr;
1623 vir_bytes count;
1625 vir_bytes vir_hw;
1626 int i, r;
1627 vir_bytes bytes;
1629 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1631 i= 0;
1632 while (count > 0)
1634 if (i >= IOVEC_NR)
1636 dp_next_iovec(iovp);
1637 i= 0;
1638 continue;
1640 assert(i < iovp->iod_iovec_s);
1641 if (offset >= iovp->iod_iovec[i].iov_size)
1643 offset -= iovp->iod_iovec[i].iov_size;
1644 i++;
1645 continue;
1647 bytes = iovp->iod_iovec[i].iov_size - offset;
1648 if (bytes > count)
1649 bytes = count;
1651 r= sys_vircopy(iovp->iod_proc_nr, D,
1652 iovp->iod_iovec[i].iov_addr + offset,
1653 SELF, D, vir_hw, bytes);
1654 if (r != OK)
1655 panic("dp_user2nic: sys_vircopy failed: %d", r);
1657 count -= bytes;
1658 vir_hw += bytes;
1659 offset += bytes;
1661 assert(count == 0);
1664 /*===========================================================================*
1665 * dp_user2nic_s *
1666 *===========================================================================*/
1667 static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
1668 dpeth_t *dep;
1669 iovec_dat_s_t *iovp;
1670 vir_bytes offset;
1671 int nic_addr;
1672 vir_bytes count;
1674 vir_bytes vir_hw;
1675 int bytes, i, r;
1677 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1679 i= 0;
1680 while (count > 0)
1682 if (i >= IOVEC_NR)
1684 dp_next_iovec_s(iovp);
1685 i= 0;
1686 continue;
1688 assert(i < iovp->iod_iovec_s);
1689 if (offset >= iovp->iod_iovec[i].iov_size)
1691 offset -= iovp->iod_iovec[i].iov_size;
1692 i++;
1693 continue;
1695 bytes = iovp->iod_iovec[i].iov_size - offset;
1696 if (bytes > count)
1697 bytes = count;
1699 r= sys_safecopyfrom(iovp->iod_proc_nr,
1700 iovp->iod_iovec[i].iov_grant, offset,
1701 vir_hw, bytes, D);
1702 if (r != OK) {
1703 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r);
1706 count -= bytes;
1707 vir_hw += bytes;
1708 offset += bytes;
1710 assert(count == 0);
1713 /*===========================================================================*
1714 * dp_pio8_user2nic *
1715 *===========================================================================*/
1716 static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
1717 dpeth_t *dep;
1718 iovec_dat_t *iovp;
1719 vir_bytes offset;
1720 int nic_addr;
1721 vir_bytes count;
1723 int bytes, i;
1725 outb_reg0(dep, DP_ISR, ISR_RDC);
1727 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1728 outb_reg0(dep, DP_RBCR1, count >> 8);
1729 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1730 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1731 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1733 i= 0;
1734 while (count > 0)
1736 if (i >= IOVEC_NR)
1738 dp_next_iovec(iovp);
1739 i= 0;
1740 continue;
1742 assert(i < iovp->iod_iovec_s);
1743 if (offset >= iovp->iod_iovec[i].iov_size)
1745 offset -= iovp->iod_iovec[i].iov_size;
1746 i++;
1747 continue;
1749 bytes = iovp->iod_iovec[i].iov_size - offset;
1750 if (bytes > count)
1751 bytes = count;
1753 do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
1754 iovp->iod_iovec[i].iov_addr + offset, bytes);
1755 count -= bytes;
1756 offset += bytes;
1758 assert(count == 0);
1760 for (i= 0; i<100; i++)
1762 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1763 break;
1765 if (i == 100)
1767 panic("dp8390: remote dma failed to complete");
1771 /*===========================================================================*
1772 * dp_pio8_user2nic_s *
1773 *===========================================================================*/
1774 static void dp_pio8_user2nic_s(dep, iovp, offset, nic_addr, count)
1775 dpeth_t *dep;
1776 iovec_dat_s_t *iovp;
1777 vir_bytes offset;
1778 int nic_addr;
1779 vir_bytes count;
1781 int bytes, i, r;
1783 outb_reg0(dep, DP_ISR, ISR_RDC);
1785 outb_reg0(dep, DP_RBCR0, count & 0xFF);
1786 outb_reg0(dep, DP_RBCR1, count >> 8);
1787 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1788 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1789 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1791 i= 0;
1792 while (count > 0)
1794 if (i >= IOVEC_NR)
1796 dp_next_iovec_s(iovp);
1797 i= 0;
1798 continue;
1800 assert(i < iovp->iod_iovec_s);
1801 if (offset >= iovp->iod_iovec[i].iov_size)
1803 offset -= iovp->iod_iovec[i].iov_size;
1804 i++;
1805 continue;
1807 bytes = iovp->iod_iovec[i].iov_size - offset;
1808 if (bytes > count)
1809 bytes = count;
1811 r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
1812 iovp->iod_iovec[i].iov_grant, offset, bytes);
1813 if (r != OK) {
1814 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1817 count -= bytes;
1818 offset += bytes;
1820 assert(count == 0);
1822 for (i= 0; i<100; i++)
1824 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1825 break;
1827 if (i == 100)
1829 panic("dp8390: remote dma failed to complete");
1833 /*===========================================================================*
1834 * dp_pio16_user2nic *
1835 *===========================================================================*/
1836 static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
1837 dpeth_t *dep;
1838 iovec_dat_t *iovp;
1839 vir_bytes offset;
1840 int nic_addr;
1841 vir_bytes count;
1843 vir_bytes vir_user;
1844 vir_bytes ecount;
1845 int i, r, bytes, user_proc;
1846 u8_t two_bytes[2];
1847 int odd_byte;
1849 ecount= (count+1) & ~1;
1850 odd_byte= 0;
1852 outb_reg0(dep, DP_ISR, ISR_RDC);
1853 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1854 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1855 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1856 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1857 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1859 i= 0;
1860 while (count > 0)
1862 if (i >= IOVEC_NR)
1864 dp_next_iovec(iovp);
1865 i= 0;
1866 continue;
1868 assert(i < iovp->iod_iovec_s);
1869 if (offset >= iovp->iod_iovec[i].iov_size)
1871 offset -= iovp->iod_iovec[i].iov_size;
1872 i++;
1873 continue;
1875 bytes = iovp->iod_iovec[i].iov_size - offset;
1876 if (bytes > count)
1877 bytes = count;
1879 user_proc= iovp->iod_proc_nr;
1880 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1881 if (odd_byte)
1883 r= sys_vircopy(user_proc, D, vir_user,
1884 SELF, D, (vir_bytes)&two_bytes[1], 1);
1885 if (r != OK) {
1886 panic("dp_pio16_user2nic: sys_vircopy failed: %d",
1889 outw(dep->de_data_port, *(u16_t *)two_bytes);
1890 count--;
1891 offset++;
1892 bytes--;
1893 vir_user++;
1894 odd_byte= 0;
1895 if (!bytes)
1896 continue;
1898 ecount= bytes & ~1;
1899 if (ecount != 0)
1901 do_vir_outsw(dep->de_data_port, user_proc, vir_user,
1902 ecount);
1903 count -= ecount;
1904 offset += ecount;
1905 bytes -= ecount;
1906 vir_user += ecount;
1908 if (bytes)
1910 assert(bytes == 1);
1911 r= sys_vircopy(user_proc, D, vir_user,
1912 SELF, D, (vir_bytes)&two_bytes[0], 1);
1913 if (r != OK) {
1914 panic("dp_pio16_user2nic: sys_vircopy failed: %d",
1917 count--;
1918 offset++;
1919 bytes--;
1920 vir_user++;
1921 odd_byte= 1;
1924 assert(count == 0);
1926 if (odd_byte)
1927 outw(dep->de_data_port, *(u16_t *)two_bytes);
1929 for (i= 0; i<100; i++)
1931 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1932 break;
1934 if (i == 100)
1936 panic("dp8390: remote dma failed to complete");
1940 /*===========================================================================*
1941 * dp_pio16_user2nic_s *
1942 *===========================================================================*/
1943 static void dp_pio16_user2nic_s(dep, iovp, offset, nic_addr, count)
1944 dpeth_t *dep;
1945 iovec_dat_s_t *iovp;
1946 vir_bytes offset;
1947 int nic_addr;
1948 vir_bytes count;
1950 vir_bytes ecount;
1951 cp_grant_id_t gid;
1952 int i, r, bytes, user_proc;
1953 u8_t two_bytes[2];
1954 int odd_byte;
1956 ecount= (count+1) & ~1;
1957 odd_byte= 0;
1959 outb_reg0(dep, DP_ISR, ISR_RDC);
1960 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1961 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1962 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1963 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1964 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1966 i= 0;
1967 while (count > 0)
1969 if (i >= IOVEC_NR)
1971 dp_next_iovec_s(iovp);
1972 i= 0;
1973 continue;
1975 assert(i < iovp->iod_iovec_s);
1976 if (offset >= iovp->iod_iovec[i].iov_size)
1978 offset -= iovp->iod_iovec[i].iov_size;
1979 i++;
1980 continue;
1982 bytes = iovp->iod_iovec[i].iov_size - offset;
1983 if (bytes > count)
1984 bytes = count;
1986 user_proc= iovp->iod_proc_nr;
1987 gid= iovp->iod_iovec[i].iov_grant;
1988 if (odd_byte)
1990 r= sys_safecopyfrom(user_proc, gid, offset,
1991 (vir_bytes)&two_bytes[1], 1, D);
1992 if (r != OK) {
1993 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
1995 outw(dep->de_data_port, *(u16_t *)two_bytes);
1996 count--;
1997 offset++;
1998 bytes--;
1999 odd_byte= 0;
2000 if (!bytes)
2001 continue;
2003 ecount= bytes & ~1;
2004 if (ecount != 0)
2006 r= sys_safe_outsw(dep->de_data_port, user_proc,
2007 gid, offset, ecount);
2008 if (r != OK) {
2009 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r);
2011 count -= ecount;
2012 offset += ecount;
2013 bytes -= ecount;
2015 if (bytes)
2017 assert(bytes == 1);
2018 r= sys_safecopyfrom(user_proc, gid, offset,
2019 (vir_bytes)&two_bytes[0], 1, D);
2020 if (r != OK) {
2021 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r);
2023 count--;
2024 offset++;
2025 bytes--;
2026 odd_byte= 1;
2029 assert(count == 0);
2031 if (odd_byte)
2032 outw(dep->de_data_port, *(u16_t *)two_bytes);
2034 for (i= 0; i<100; i++)
2036 if (inb_reg0(dep, DP_ISR) & ISR_RDC)
2037 break;
2039 if (i == 100)
2041 panic("dp8390: remote dma failed to complete");
2045 /*===========================================================================*
2046 * dp_nic2user *
2047 *===========================================================================*/
2048 static void dp_nic2user(dep, nic_addr, iovp, offset, count)
2049 dpeth_t *dep;
2050 int nic_addr;
2051 iovec_dat_t *iovp;
2052 vir_bytes offset;
2053 vir_bytes count;
2055 int bytes, i, r;
2057 vir_bytes vir_hw = (vir_bytes) (dep->de_locmem + nic_addr);
2059 i= 0;
2060 while (count > 0)
2062 if (i >= IOVEC_NR)
2064 dp_next_iovec(iovp);
2065 i= 0;
2066 continue;
2068 assert(i < iovp->iod_iovec_s);
2069 if (offset >= iovp->iod_iovec[i].iov_size)
2071 offset -= iovp->iod_iovec[i].iov_size;
2072 i++;
2073 continue;
2075 bytes = iovp->iod_iovec[i].iov_size - offset;
2076 if (bytes > count)
2077 bytes = count;
2079 r= sys_vircopy(SELF, D, vir_hw,
2080 iovp->iod_proc_nr, D,
2081 iovp->iod_iovec[i].iov_addr + offset, bytes);
2082 if (r != OK)
2083 panic("dp_nic2user: sys_vircopy failed: %d", r);
2085 count -= bytes;
2086 vir_hw += bytes;
2087 offset += bytes;
2089 assert(count == 0);
2092 /*===========================================================================*
2093 * dp_nic2user_s *
2094 *===========================================================================*/
2095 static void dp_nic2user_s(dep, nic_addr, iovp, offset, count)
2096 dpeth_t *dep;
2097 int nic_addr;
2098 iovec_dat_s_t *iovp;
2099 vir_bytes offset;
2100 vir_bytes count;
2102 vir_bytes vir_hw;
2103 int bytes, i, r;
2105 vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
2107 i= 0;
2108 while (count > 0)
2110 if (i >= IOVEC_NR)
2112 dp_next_iovec_s(iovp);
2113 i= 0;
2114 continue;
2116 assert(i < iovp->iod_iovec_s);
2117 if (offset >= iovp->iod_iovec[i].iov_size)
2119 offset -= iovp->iod_iovec[i].iov_size;
2120 i++;
2121 continue;
2123 bytes = iovp->iod_iovec[i].iov_size - offset;
2124 if (bytes > count)
2125 bytes = count;
2127 r= sys_safecopyto(iovp->iod_proc_nr,
2128 iovp->iod_iovec[i].iov_grant, offset,
2129 vir_hw, bytes, D);
2130 if (r != OK)
2131 panic("dp_nic2user_s: sys_safecopyto failed: %d", r);
2133 count -= bytes;
2134 vir_hw += bytes;
2135 offset += bytes;
2137 assert(count == 0);
2140 /*===========================================================================*
2141 * dp_pio8_nic2user *
2142 *===========================================================================*/
2143 static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
2144 dpeth_t *dep;
2145 int nic_addr;
2146 iovec_dat_t *iovp;
2147 vir_bytes offset;
2148 vir_bytes count;
2150 int bytes, i;
2152 outb_reg0(dep, DP_RBCR0, count & 0xFF);
2153 outb_reg0(dep, DP_RBCR1, count >> 8);
2154 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
2155 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
2156 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
2158 i= 0;
2159 while (count > 0)
2161 if (i >= IOVEC_NR)
2163 dp_next_iovec(iovp);
2164 i= 0;
2165 continue;
2167 assert(i < iovp->iod_iovec_s);
2168 if (offset >= iovp->iod_iovec[i].iov_size)
2170 offset -= iovp->iod_iovec[i].iov_size;
2171 i++;
2172 continue;
2174 bytes = iovp->iod_iovec[i].iov_size - offset;
2175 if (bytes > count)
2176 bytes = count;
2178 do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
2179 iovp->iod_iovec[i].iov_addr + offset, bytes);
2180 count -= bytes;
2181 offset += bytes;
2183 assert(count == 0);
2186 /*===========================================================================*
2187 * dp_pio8_nic2user_s *
2188 *===========================================================================*/
2189 static void dp_pio8_nic2user_s(dep, nic_addr, iovp, offset, count)
2190 dpeth_t *dep;
2191 int nic_addr;
2192 iovec_dat_s_t *iovp;
2193 vir_bytes offset;
2194 vir_bytes count;
2196 int bytes, i, r;
2198 outb_reg0(dep, DP_RBCR0, count & 0xFF);
2199 outb_reg0(dep, DP_RBCR1, count >> 8);
2200 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
2201 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
2202 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
2204 i= 0;
2205 while (count > 0)
2207 if (i >= IOVEC_NR)
2209 dp_next_iovec_s(iovp);
2210 i= 0;
2211 continue;
2213 assert(i < iovp->iod_iovec_s);
2214 if (offset >= iovp->iod_iovec[i].iov_size)
2216 offset -= iovp->iod_iovec[i].iov_size;
2217 i++;
2218 continue;
2220 bytes = iovp->iod_iovec[i].iov_size - offset;
2221 if (bytes > count)
2222 bytes = count;
2224 r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
2225 iovp->iod_iovec[i].iov_grant, offset, bytes);
2226 if (r != OK) {
2227 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r);
2229 count -= bytes;
2230 offset += bytes;
2232 assert(count == 0);
2235 /*===========================================================================*
2236 * dp_pio16_nic2user *
2237 *===========================================================================*/
2238 static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
2239 dpeth_t *dep;
2240 int nic_addr;
2241 iovec_dat_t *iovp;
2242 vir_bytes offset;
2243 vir_bytes count;
2245 vir_bytes vir_user;
2246 vir_bytes ecount;
2247 int i, r, bytes, user_proc;
2248 u8_t two_bytes[2];
2249 int odd_byte;
2251 ecount= (count+1) & ~1;
2252 odd_byte= 0;
2254 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
2255 outb_reg0(dep, DP_RBCR1, ecount >> 8);
2256 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
2257 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
2258 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
2260 i= 0;
2261 while (count > 0)
2263 if (i >= IOVEC_NR)
2265 dp_next_iovec(iovp);
2266 i= 0;
2267 continue;
2269 assert(i < iovp->iod_iovec_s);
2270 if (offset >= iovp->iod_iovec[i].iov_size)
2272 offset -= iovp->iod_iovec[i].iov_size;
2273 i++;
2274 continue;
2276 bytes = iovp->iod_iovec[i].iov_size - offset;
2277 if (bytes > count)
2278 bytes = count;
2280 user_proc= iovp->iod_proc_nr;
2281 vir_user= iovp->iod_iovec[i].iov_addr + offset;
2282 if (odd_byte)
2284 r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
2285 user_proc, D, vir_user, 1);
2286 if (r != OK) {
2287 panic("dp_pio16_nic2user: sys_vircopy failed: %d",
2290 count--;
2291 offset++;
2292 bytes--;
2293 vir_user++;
2294 odd_byte= 0;
2295 if (!bytes)
2296 continue;
2298 ecount= bytes & ~1;
2299 if (ecount != 0)
2301 do_vir_insw(dep->de_data_port, user_proc, vir_user,
2302 ecount);
2303 count -= ecount;
2304 offset += ecount;
2305 bytes -= ecount;
2306 vir_user += ecount;
2308 if (bytes)
2310 assert(bytes == 1);
2311 *(u16_t *)two_bytes= inw(dep->de_data_port);
2312 r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
2313 user_proc, D, vir_user, 1);
2314 if (r != OK) {
2315 panic("dp_pio16_nic2user: sys_vircopy failed: %d", r);
2317 count--;
2318 offset++;
2319 bytes--;
2320 vir_user++;
2321 odd_byte= 1;
2324 assert(count == 0);
2327 /*===========================================================================*
2328 * dp_pio16_nic2user_s *
2329 *===========================================================================*/
2330 static void dp_pio16_nic2user_s(dep, nic_addr, iovp, offset, count)
2331 dpeth_t *dep;
2332 int nic_addr;
2333 iovec_dat_s_t *iovp;
2334 vir_bytes offset;
2335 vir_bytes count;
2337 vir_bytes ecount;
2338 cp_grant_id_t gid;
2339 int i, r, bytes, user_proc;
2340 u8_t two_bytes[2];
2341 int odd_byte;
2343 ecount= (count+1) & ~1;
2344 odd_byte= 0;
2346 outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
2347 outb_reg0(dep, DP_RBCR1, ecount >> 8);
2348 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
2349 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
2350 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
2352 i= 0;
2353 while (count > 0)
2355 if (i >= IOVEC_NR)
2357 dp_next_iovec_s(iovp);
2358 i= 0;
2359 continue;
2361 assert(i < iovp->iod_iovec_s);
2362 if (offset >= iovp->iod_iovec[i].iov_size)
2364 offset -= iovp->iod_iovec[i].iov_size;
2365 i++;
2366 continue;
2368 bytes = iovp->iod_iovec[i].iov_size - offset;
2369 if (bytes > count)
2370 bytes = count;
2372 user_proc= iovp->iod_proc_nr;
2373 gid= iovp->iod_iovec[i].iov_grant;
2374 if (odd_byte)
2376 r= sys_safecopyto(user_proc, gid, offset,
2377 (vir_bytes)&two_bytes[1], 1, D);
2378 if (r != OK) {
2379 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r);
2381 count--;
2382 offset++;
2383 bytes--;
2384 odd_byte= 0;
2385 if (!bytes)
2386 continue;
2388 ecount= bytes & ~1;
2389 if (ecount != 0)
2391 r= sys_safe_insw(dep->de_data_port, user_proc, gid,
2392 offset, ecount);
2393 if (r != OK) {
2394 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
2397 count -= ecount;
2398 offset += ecount;
2399 bytes -= ecount;
2401 if (bytes)
2403 assert(bytes == 1);
2404 *(u16_t *)two_bytes= inw(dep->de_data_port);
2405 r= sys_safecopyto(user_proc, gid, offset,
2406 (vir_bytes)&two_bytes[0], 1, D);
2407 if (r != OK)
2409 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
2412 count--;
2413 offset++;
2414 bytes--;
2415 odd_byte= 1;
2418 assert(count == 0);
2421 /*===========================================================================*
2422 * dp_next_iovec *
2423 *===========================================================================*/
2424 static void dp_next_iovec(iovp)
2425 iovec_dat_t *iovp;
2427 assert(iovp->iod_iovec_s > IOVEC_NR);
2429 iovp->iod_iovec_s -= IOVEC_NR;
2431 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
2433 get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
2434 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
2435 sizeof(iovec_t), iovp->iod_iovec);
2438 /*===========================================================================*
2439 * dp_next_iovec_s *
2440 *===========================================================================*/
2441 static void dp_next_iovec_s(iovp)
2442 iovec_dat_s_t *iovp;
2444 assert(iovp->iod_iovec_s > IOVEC_NR);
2446 iovp->iod_iovec_s -= IOVEC_NR;
2448 iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
2450 get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant,
2451 iovp->iod_iovec_offset,
2452 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
2453 sizeof(iovp->iod_iovec[0]), iovp->iod_iovec);
2456 /*===========================================================================*
2457 * conf_hw *
2458 *===========================================================================*/
2459 static void conf_hw(dep)
2460 dpeth_t *dep;
2462 static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
2464 int ifnr;
2465 dp_conf_t *dcp;
2467 dep->de_mode= DEM_DISABLED; /* Superfluous */
2468 ifnr= dep-de_table;
2470 dcp= &dp_conf[ifnr];
2471 update_conf(dep, dcp);
2472 if (dep->de_mode != DEM_ENABLED)
2473 return;
2474 if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
2476 printf("%s: No ethernet card found at 0x%x\n",
2477 dep->de_name, dep->de_base_port);
2478 dep->de_mode= DEM_DISABLED;
2479 return;
2482 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
2484 dep->de_flags = DEF_EMPTY;
2485 dep->de_stat = empty_stat;
2488 /*===========================================================================*
2489 * update_conf *
2490 *===========================================================================*/
2491 static void update_conf(dep, dcp)
2492 dpeth_t *dep;
2493 dp_conf_t *dcp;
2495 long v;
2496 static char dpc_fmt[] = "x:d:x:x";
2498 #if ENABLE_PCI
2499 if (dep->de_pci)
2501 if (dep->de_pci == 1)
2503 /* PCI device is present */
2504 dep->de_mode= DEM_ENABLED;
2506 return; /* Already configured */
2508 #endif
2510 /* Get the default settings and modify them from the environment. */
2511 dep->de_mode= DEM_SINK;
2512 v= dcp->dpc_port;
2513 switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &v, 0x0000L, 0xFFFFL)) {
2514 case EP_OFF:
2515 dep->de_mode= DEM_DISABLED;
2516 break;
2517 case EP_ON:
2518 case EP_SET:
2519 dep->de_mode= DEM_ENABLED; /* Might become disabled if
2520 * all probes fail */
2521 break;
2523 dep->de_base_port= v;
2525 v= dcp->dpc_irq | DEI_DEFAULT;
2526 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 1, &v, 0L,
2527 (long) NR_IRQ_VECTORS - 1);
2528 dep->de_irq= v;
2530 v= dcp->dpc_mem;
2531 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 2, &v, 0L, 0xFFFFFL);
2532 dep->de_linmem= v;
2534 v= 0;
2535 (void) env_parse(dcp->dpc_envvar, dpc_fmt, 3, &v, 0x2000L, 0x8000L);
2536 dep->de_ramsize= v;
2539 /*===========================================================================*
2540 * map_hw_buffer *
2541 *===========================================================================*/
2542 static void map_hw_buffer(dep)
2543 dpeth_t *dep;
2545 int r;
2546 size_t o, size;
2547 char *buf, *abuf;
2549 if (dep->de_prog_IO)
2551 #if 0
2552 printf(
2553 "map_hw_buffer: programmed I/O, no need to map buffer\n");
2554 #endif
2555 dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
2556 return;
2559 size = dep->de_ramsize + I386_PAGE_SIZE; /* Add I386_PAGE_SIZE for
2560 * alignment
2562 buf= malloc(size);
2563 if (buf == NULL)
2564 panic("map_hw_buffer: cannot malloc size: %d", size);
2565 o= I386_PAGE_SIZE - ((vir_bytes)buf % I386_PAGE_SIZE);
2566 abuf= buf + o;
2567 printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
2569 #if 0
2570 r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
2571 dep->de_ramsize, (phys_bytes)dep->de_linmem);
2572 #else
2573 r = ENOSYS;
2574 #endif
2575 if (r != OK)
2576 panic("map_hw_buffer: sys_vm_map failed: %d", r);
2577 dep->de_locmem = abuf;
2580 /*===========================================================================*
2581 * calc_iovec_size *
2582 *===========================================================================*/
2583 static int calc_iovec_size(iovp)
2584 iovec_dat_t *iovp;
2586 /* Calculate the size of a request. Note that the iovec_dat
2587 * structure will be unusable after calc_iovec_size.
2589 int size;
2590 int i;
2592 size= 0;
2593 i= 0;
2594 while (i < iovp->iod_iovec_s)
2596 if (i >= IOVEC_NR)
2598 dp_next_iovec(iovp);
2599 i= 0;
2600 continue;
2602 size += iovp->iod_iovec[i].iov_size;
2603 i++;
2605 return size;
2608 /*===========================================================================*
2609 * calc_iovec_size_s *
2610 *===========================================================================*/
2611 static int calc_iovec_size_s(iovp)
2612 iovec_dat_s_t *iovp;
2614 /* Calculate the size of a request. Note that the iovec_dat
2615 * structure will be unusable after calc_iovec_size_s.
2617 int size;
2618 int i;
2620 size= 0;
2621 i= 0;
2622 while (i < iovp->iod_iovec_s)
2624 if (i >= IOVEC_NR)
2626 dp_next_iovec_s(iovp);
2627 i= 0;
2628 continue;
2630 size += iovp->iod_iovec[i].iov_size;
2631 i++;
2633 return size;
2636 /*===========================================================================*
2637 * reply *
2638 *===========================================================================*/
2639 static void reply(dep, err, may_block)
2640 dpeth_t *dep;
2641 int err;
2642 int may_block;
2644 message reply;
2645 int status;
2646 int r;
2648 status = 0;
2649 if (dep->de_flags & DEF_PACK_SEND)
2650 status |= DL_PACK_SEND;
2651 if (dep->de_flags & DEF_PACK_RECV)
2652 status |= DL_PACK_RECV;
2654 reply.m_type = DL_TASK_REPLY;
2655 reply.DL_PORT = dep - de_table;
2656 reply.DL_PROC = dep->de_client;
2657 reply.DL_STAT = status | ((u32_t) err << 16);
2658 reply.DL_COUNT = dep->de_read_s;
2659 reply.DL_CLCK = 0; /* Don't know */
2660 r= send(dep->de_client, &reply);
2662 if (r == ELOCKED && may_block)
2664 #if 0
2665 printf("send locked\n");
2666 #endif
2667 return;
2670 if (r < 0)
2671 panic("dp8390: send failed: %d", r);
2673 dep->de_read_s = 0;
2674 dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
2677 /*===========================================================================*
2678 * mess_reply *
2679 *===========================================================================*/
2680 static void mess_reply(req, reply_mess)
2681 message *req;
2682 message *reply_mess;
2684 if (send(req->m_source, reply_mess) != OK)
2685 panic("dp8390: unable to mess_reply");
2688 /*===========================================================================*
2689 * get_userdata *
2690 *===========================================================================*/
2691 static void get_userdata(user_proc, user_addr, count, loc_addr)
2692 int user_proc;
2693 vir_bytes user_addr;
2694 vir_bytes count;
2695 void *loc_addr;
2697 int r;
2699 r= sys_vircopy(user_proc, D, user_addr,
2700 SELF, D, (vir_bytes)loc_addr, count);
2701 if (r != OK)
2702 panic("get_userdata: sys_vircopy failed: %d", r);
2705 /*===========================================================================*
2706 * get_userdata_s *
2707 *===========================================================================*/
2708 static void get_userdata_s(user_proc, grant, offset, count, loc_addr)
2709 int user_proc;
2710 cp_grant_id_t grant;
2711 vir_bytes offset;
2712 vir_bytes count;
2713 void *loc_addr;
2715 int r;
2717 r= sys_safecopyfrom(user_proc, grant, offset,
2718 (vir_bytes)loc_addr, count, D);
2719 if (r != OK)
2720 panic("get_userdata: sys_safecopyfrom failed: %d", r);
2723 /*===========================================================================*
2724 * put_userdata *
2725 *===========================================================================*/
2726 static void put_userdata(user_proc, user_addr, count, loc_addr)
2727 int user_proc;
2728 vir_bytes user_addr;
2729 vir_bytes count;
2730 void *loc_addr;
2732 int r;
2734 r= sys_vircopy(SELF, D, (vir_bytes)loc_addr,
2735 user_proc, D, user_addr, count);
2736 if (r != OK)
2737 panic("put_userdata: sys_vircopy failed: %d", r);
2740 /*===========================================================================*
2741 * put_userdata_s *
2742 *===========================================================================*/
2743 static void put_userdata_s(user_proc, grant, count, loc_addr)
2744 int user_proc;
2745 cp_grant_id_t grant;
2746 size_t count;
2747 void *loc_addr;
2749 int r;
2751 r= sys_safecopyto(user_proc, grant, 0, (vir_bytes)loc_addr,
2752 count, D);
2753 if (r != OK)
2754 panic("put_userdata: sys_safecopyto failed: %d", r);
2757 u8_t inb(port_t port)
2759 int r;
2760 u32_t value;
2762 r= sys_inb(port, &value);
2763 if (r != OK)
2765 printf("inb failed for port 0x%x\n", port);
2766 panic("sys_inb failed: %d", r);
2768 return value;
2771 u16_t inw(port_t port)
2773 int r;
2774 unsigned long value;
2776 r= sys_inw(port, &value);
2777 if (r != OK)
2778 panic("sys_inw failed: %d", r);
2779 return (u16_t) value;
2782 void outb(port_t port, u8_t value)
2784 int r;
2786 r= sys_outb(port, value);
2787 if (r != OK)
2788 panic("sys_outb failed: %d", r);
2791 void outw(port_t port, u16_t value)
2793 int r;
2795 r= sys_outw(port, value);
2796 if (r != OK)
2797 panic("sys_outw failed: %d", r);
2800 static void insb(port_t port, void *buf, size_t size)
2802 do_vir_insb(port, SELF, (vir_bytes)buf, size);
2805 static void insw(port_t port, void *buf, size_t size)
2807 do_vir_insw(port, SELF, (vir_bytes)buf, size);
2810 static void do_vir_insb(port_t port, int proc, vir_bytes buf, size_t size)
2812 int r;
2814 r= sys_insb(port, proc, (void *) buf, size);
2815 if (r != OK)
2816 panic("sys_sdevio failed: %d", r);
2819 static void do_vir_insw(port_t port, int proc, vir_bytes buf, size_t size)
2821 int r;
2823 r= sys_insw(port, proc, (void *) buf, size);
2824 if (r != OK)
2825 panic("sys_sdevio failed: %d", r);
2828 static void do_vir_outsb(port_t port, int proc, vir_bytes buf, size_t size)
2830 int r;
2832 r= sys_outsb(port, proc, (void *) buf, size);
2833 if (r != OK)
2834 panic("sys_sdevio failed: %d", r);
2837 static void do_vir_outsw(port_t port, int proc, vir_bytes buf, size_t size)
2839 int r;
2841 r= sys_outsw(port, proc, (void *) buf, size);
2842 if (r != OK)
2843 panic("sys_sdevio failed: %d", r);
2847 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $