4 * This file contains a ethernet device driver for NS dp8390 based ethernet
7 * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
9 * Modified Mar 10 1994 by Philip Homburg
10 * Become a generic dp8390 driver.
12 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
13 * Added support for 3c503 boards.
16 #include <minix/drivers.h>
17 #include <minix/netdriver.h>
20 #include <minix/com.h>
21 #include <minix/endpoint.h>
24 #include <net/gen/ether.h>
25 #include <net/gen/eth_io.h>
26 #include <machine/vm.h>
33 static dpeth_t de_state
;
34 static int de_instance
;
39 typedef struct dp_conf
47 static dp_conf_t dp_conf
[DP_CONF_NR
]= /* Card addresses */
49 /* I/O port, IRQ, Buffer address. */
50 { 0x280, 3, 0xD0000, },
51 { 0x300, 5, 0xC8000, },
52 { 0x380, 10, 0xD8000, },
53 { 0x000, 0, 0x00000, },
56 /* Card inits configured out? */
58 #define wdeth_probe(dep) (0)
61 #define ne_probe(dep) (0)
64 #define el2_probe(dep) (0)
67 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
68 * on writes to the CR register. Additional CR_STAs do not appear to hurt
71 #define CR_EXTRA CR_STA
74 static void pci_conf(void);
76 static void do_vwrite_s(message
*mp
, int from_int
);
77 static void do_vread_s(message
*mp
);
78 static void do_init(message
*mp
);
79 static void do_int(dpeth_t
*dep
);
80 static void do_getstat_s(message
*mp
);
81 static void dp_stop(dpeth_t
*dep
);
82 static void dp_init(dpeth_t
*dep
);
83 static void dp_confaddr(dpeth_t
*dep
);
84 static void dp_reinit(dpeth_t
*dep
);
85 static void dp_reset(dpeth_t
*dep
);
86 static void dp_check_ints(dpeth_t
*dep
);
87 static void dp_recv(dpeth_t
*dep
);
88 static void dp_send(dpeth_t
*dep
);
89 static void dp_getblock(dpeth_t
*dep
, int page
, size_t offset
, size_t
91 static void dp_pio8_getblock(dpeth_t
*dep
, int page
, size_t offset
,
92 size_t size
, void *dst
);
93 static void dp_pio16_getblock(dpeth_t
*dep
, int page
, size_t offset
,
94 size_t size
, void *dst
);
95 static int dp_pkt2user_s(dpeth_t
*dep
, int page
, vir_bytes length
);
96 static void dp_user2nic_s(dpeth_t
*dep
, iovec_dat_s_t
*iovp
, vir_bytes
97 offset
, int nic_addr
, vir_bytes count
);
98 static void dp_pio8_user2nic_s(dpeth_t
*dep
, iovec_dat_s_t
*iovp
,
99 vir_bytes offset
, int nic_addr
, vir_bytes count
);
100 static void dp_pio16_user2nic_s(dpeth_t
*dep
, iovec_dat_s_t
*iovp
,
101 vir_bytes offset
, int nic_addr
, vir_bytes count
);
102 static void dp_nic2user_s(dpeth_t
*dep
, int nic_addr
, iovec_dat_s_t
103 *iovp
, vir_bytes offset
, vir_bytes count
);
104 static void dp_pio8_nic2user_s(dpeth_t
*dep
, int nic_addr
, iovec_dat_s_t
105 *iovp
, vir_bytes offset
, vir_bytes count
);
106 static void dp_pio16_nic2user_s(dpeth_t
*dep
, int nic_addr
,
107 iovec_dat_s_t
*iovp
, vir_bytes offset
, vir_bytes count
);
108 static void dp_next_iovec_s(iovec_dat_s_t
*iovp
);
109 static void conf_hw(dpeth_t
*dep
);
110 static void update_conf(dpeth_t
*dep
, dp_conf_t
*dcp
);
111 static void map_hw_buffer(dpeth_t
*dep
);
112 static int calc_iovec_size_s(iovec_dat_s_t
*iovp
);
113 static void reply(dpeth_t
*dep
);
114 static void mess_reply(message
*req
, message
*reply
);
115 static void get_userdata_s(int user_proc
, cp_grant_id_t grant
, vir_bytes
116 offset
, vir_bytes count
, void *loc_addr
);
117 static void put_userdata_s(int user_proc
, cp_grant_id_t grant
, size_t
118 count
, void *loc_addr
);
119 static void insb(port_t port
, void *buf
, size_t size
);
120 static void insw(port_t port
, void *buf
, size_t size
);
121 static void do_vir_insb(port_t port
, int proc
, vir_bytes buf
, size_t
123 static void do_vir_insw(port_t port
, int proc
, vir_bytes buf
, size_t
126 /* SEF functions and variables. */
127 static void sef_local_startup(void);
128 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
129 static void sef_cb_signal_handler(int signo
);
131 static void handle_hw_intr(void)
138 if (dep
->de_mode
!= DEM_ENABLED
)
140 assert(dep
->de_flags
& DEF_ENABLED
);
142 assert(irq
>= 0 && irq
< NR_IRQ_VECTORS
);
143 if (dep
->de_int_pending
|| 1)
145 dep
->de_int_pending
= 0;
148 r
= sys_irqenable(&dep
->de_hook
);
150 panic("unable enable interrupts: %d", r
);
155 /*===========================================================================*
157 *===========================================================================*/
158 int main(int argc
, char *argv
[])
164 /* SEF local startup. */
165 env_setargs(argc
, argv
);
170 if ((r
= netdriver_receive(ANY
, &m
, &ipc_status
)) != OK
)
171 panic("dp8390: netdriver_receive failed: %d", r
);
173 if (is_ipc_notify(ipc_status
)) {
174 switch (_ENDPOINT_P(m
.m_source
)) {
179 printf("dp8390: notify from CLOCK\n");
182 panic("dp8390: illegal notify from: %d",
186 /* done, get a new message */
192 case DL_WRITEV_S
: do_vwrite_s(&m
, FALSE
); break;
193 case DL_READV_S
: do_vread_s(&m
); break;
194 case DL_CONF
: do_init(&m
); break;
195 case DL_GETSTAT_S
: do_getstat_s(&m
); break;
197 panic("dp8390: illegal message: %d", m
.m_type
);
202 /*===========================================================================*
203 * sef_local_startup *
204 *===========================================================================*/
205 static void sef_local_startup()
207 /* Register init callbacks. */
208 sef_setcb_init_fresh(sef_cb_init_fresh
);
209 sef_setcb_init_lu(sef_cb_init_fresh
);
210 sef_setcb_init_restart(sef_cb_init_fresh
);
212 /* Register live update callbacks. */
213 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
214 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree
);
216 /* Register signal callbacks. */
217 sef_setcb_signal_handler(sef_cb_signal_handler
);
219 /* Let SEF perform startup. */
223 /*===========================================================================*
224 * sef_cb_init_fresh *
225 *===========================================================================*/
226 static int sef_cb_init_fresh(int type
, sef_init_info_t
*UNUSED(info
))
228 /* Initialize the dp8390 driver. */
232 system_hz
= sys_hz();
235 panic("A head which at this time has no name");
239 (void) env_parse("instance", "d", 0, &v
, 0, 255);
240 de_instance
= (int) v
;
244 strlcpy(dep
->de_name
, "dp8390#0", sizeof(dep
->de_name
));
245 dep
->de_name
[7] += de_instance
;
247 /* Announce we are up! */
248 netdriver_announce();
253 /*===========================================================================*
254 * sef_cb_signal_handler *
255 *===========================================================================*/
256 static void sef_cb_signal_handler(int signo
)
258 /* Only check for termination signal, ignore anything else. */
259 if (signo
!= SIGTERM
) return;
261 if (de_state
.de_mode
== DEM_ENABLED
)
266 /*===========================================================================*
268 *===========================================================================*/
278 if (dep
->de_mode
== DEM_DISABLED
)
279 printf("dp8390 instance %d is disabled\n", de_instance
);
280 else if (dep
->de_mode
== DEM_SINK
)
281 printf("dp8390 instance %d is in sink mode\n", de_instance
);
284 if (dep
->de_mode
!= DEM_ENABLED
)
287 printf("dp8390 statistics of instance %d:\n", de_instance
);
289 printf("recvErr :%8ld\t", dep
->de_stat
.ets_recvErr
);
290 printf("sendErr :%8ld\t", dep
->de_stat
.ets_sendErr
);
291 printf("OVW :%8ld\n", dep
->de_stat
.ets_OVW
);
293 printf("CRCerr :%8ld\t", dep
->de_stat
.ets_CRCerr
);
294 printf("frameAll :%8ld\t", dep
->de_stat
.ets_frameAll
);
295 printf("missedP :%8ld\n", dep
->de_stat
.ets_missedP
);
297 printf("packetR :%8ld\t", dep
->de_stat
.ets_packetR
);
298 printf("packetT :%8ld\t", dep
->de_stat
.ets_packetT
);
299 printf("transDef :%8ld\n", dep
->de_stat
.ets_transDef
);
301 printf("collision :%8ld\t", dep
->de_stat
.ets_collision
);
302 printf("transAb :%8ld\t", dep
->de_stat
.ets_transAb
);
303 printf("carrSense :%8ld\n", dep
->de_stat
.ets_carrSense
);
305 printf("fifoUnder :%8ld\t", dep
->de_stat
.ets_fifoUnder
);
306 printf("fifoOver :%8ld\t", dep
->de_stat
.ets_fifoOver
);
307 printf("CDheartbeat:%8ld\n", dep
->de_stat
.ets_CDheartbeat
);
309 printf("OWC :%8ld\t", dep
->de_stat
.ets_OWC
);
311 isr
= inb_reg0(dep
, DP_ISR
);
312 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr
,
313 inb_reg0(dep
, DP_ISR
), dep
->de_flags
);
318 /*===========================================================================*
320 *===========================================================================*/
321 static void pci_conf()
326 static int first_time
= 1;
334 strlcpy(envvar
, "DPETH0", sizeof(envvar
));
335 envvar
[5] += de_instance
;
336 if (!(dep
->de_pci
= env_prefix(envvar
, "pci")))
337 return; /* no PCI config */
339 /* Count the number of dp instances before this one that are configured
340 * for PCI, so that we can skip that many when enumerating PCI devices.
343 for (i
= 0; i
< de_instance
; i
++) {
345 if (env_prefix(envvar
, "pci"))
349 if (!rtl_probe(dep
, pci_instance
))
352 #endif /* ENABLE_PCI */
354 /*===========================================================================*
356 *===========================================================================*/
357 static void do_vwrite_s(mp
, from_int
)
367 count
= mp
->DL_COUNT
;
368 dep
->de_client
= mp
->m_source
;
370 if (dep
->de_mode
== DEM_SINK
)
373 dep
->de_flags
|= DEF_PACK_SEND
;
377 assert(dep
->de_mode
== DEM_ENABLED
);
378 assert(dep
->de_flags
& DEF_ENABLED
);
379 if (dep
->de_flags
& DEF_SEND_AVAIL
)
380 panic("dp8390: send already in progress");
382 sendq_head
= dep
->de_sendq_head
;
383 if (dep
->de_sendq
[sendq_head
].sq_filled
)
386 panic("dp8390: should not be sending");
387 dep
->de_sendmsg
= *mp
;
388 dep
->de_flags
|= DEF_SEND_AVAIL
;
392 assert(!(dep
->de_flags
& DEF_PACK_SEND
));
394 get_userdata_s(mp
->m_source
, mp
->DL_GRANT
, 0,
395 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
396 sizeof(dep
->de_write_iovec_s
.iod_iovec
[0]),
397 dep
->de_write_iovec_s
.iod_iovec
);
398 dep
->de_write_iovec_s
.iod_iovec_s
= count
;
399 dep
->de_write_iovec_s
.iod_proc_nr
= mp
->m_source
;
400 dep
->de_write_iovec_s
.iod_grant
= mp
->DL_GRANT
;
401 dep
->de_write_iovec_s
.iod_iovec_offset
= 0;
403 dep
->de_tmp_iovec_s
= dep
->de_write_iovec_s
;
404 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
406 if (size
< ETH_MIN_PACK_SIZE
|| size
> ETH_MAX_PACK_SIZE_TAGGED
)
408 panic("dp8390: invalid packet size: %d", size
);
410 (dep
->de_user2nicf_s
)(dep
, &dep
->de_write_iovec_s
, 0,
411 dep
->de_sendq
[sendq_head
].sq_sendpage
* DP_PAGESIZE
,
413 dep
->de_sendq
[sendq_head
].sq_filled
= TRUE
;
414 if (dep
->de_sendq_tail
== sendq_head
)
416 outb_reg0(dep
, DP_TPSR
, dep
->de_sendq
[sendq_head
].sq_sendpage
);
417 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
418 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
419 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);/* there it goes.. */
422 dep
->de_sendq
[sendq_head
].sq_size
= size
;
424 if (++sendq_head
== dep
->de_sendq_nr
)
426 assert(sendq_head
< SENDQ_NR
);
427 dep
->de_sendq_head
= sendq_head
;
429 dep
->de_flags
|= DEF_PACK_SEND
;
431 /* If the interrupt handler called, don't send a reply. The reply
432 * will be sent after all interrupts are handled.
438 assert(dep
->de_mode
== DEM_ENABLED
);
439 assert(dep
->de_flags
& DEF_ENABLED
);
442 /*===========================================================================*
444 *===========================================================================*/
445 static void do_vread_s(mp
)
454 count
= mp
->DL_COUNT
;
455 dep
->de_client
= mp
->m_source
;
456 if (dep
->de_mode
== DEM_SINK
)
461 assert(dep
->de_mode
== DEM_ENABLED
);
462 assert(dep
->de_flags
& DEF_ENABLED
);
464 if(dep
->de_flags
& DEF_READING
)
465 panic("dp8390: read already in progress");
467 get_userdata_s(mp
->m_source
, mp
->DL_GRANT
, 0,
468 (count
> IOVEC_NR
? IOVEC_NR
: count
) *
469 sizeof(dep
->de_read_iovec_s
.iod_iovec
[0]),
470 dep
->de_read_iovec_s
.iod_iovec
);
471 dep
->de_read_iovec_s
.iod_iovec_s
= count
;
472 dep
->de_read_iovec_s
.iod_proc_nr
= mp
->m_source
;
473 dep
->de_read_iovec_s
.iod_grant
= mp
->DL_GRANT
;
474 dep
->de_read_iovec_s
.iod_iovec_offset
= 0;
476 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
477 size
= calc_iovec_size_s(&dep
->de_tmp_iovec_s
);
479 if (size
< ETH_MAX_PACK_SIZE_TAGGED
)
480 panic("dp8390: wrong packet size: %d", size
);
481 dep
->de_flags
|= DEF_READING
;
485 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
486 (DEF_READING
|DEF_STOPPED
))
488 /* The chip is stopped, and all arrived packets are
496 /*===========================================================================*
498 *===========================================================================*/
499 static void do_init(message
*mp
)
505 pci_conf(); /* Configure PCI devices. */
510 if (dep
->de_mode
== DEM_DISABLED
)
512 /* This is the default, try to (re)locate the device. */
514 if (dep
->de_mode
== DEM_DISABLED
)
516 /* Probe failed, or the device is configured off. */
517 reply_mess
.m_type
= DL_CONF_REPLY
;
518 reply_mess
.DL_STAT
= ENXIO
;
519 mess_reply(mp
, &reply_mess
);
522 if (dep
->de_mode
== DEM_ENABLED
)
526 if (dep
->de_mode
== DEM_SINK
)
528 strncpy((char *) dep
->de_address
.ea_addr
, "ZDP", 6);
529 dep
->de_address
.ea_addr
[5] = de_instance
;
531 reply_mess
.m_type
= DL_CONF_REPLY
;
532 reply_mess
.DL_STAT
= OK
;
533 *(ether_addr_t
*) reply_mess
.DL_HWADDR
= dep
->de_address
;
534 mess_reply(mp
, &reply_mess
);
537 assert(dep
->de_mode
== DEM_ENABLED
);
538 assert(dep
->de_flags
& DEF_ENABLED
);
540 dep
->de_flags
&= ~(DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
);
542 if (mp
->DL_MODE
& DL_PROMISC_REQ
)
543 dep
->de_flags
|= DEF_PROMISC
| DEF_MULTI
| DEF_BROAD
;
544 if (mp
->DL_MODE
& DL_MULTI_REQ
)
545 dep
->de_flags
|= DEF_MULTI
;
546 if (mp
->DL_MODE
& DL_BROAD_REQ
)
547 dep
->de_flags
|= DEF_BROAD
;
551 reply_mess
.m_type
= DL_CONF_REPLY
;
552 reply_mess
.DL_STAT
= OK
;
553 *(ether_addr_t
*) reply_mess
.DL_HWADDR
= dep
->de_address
;
555 mess_reply(mp
, &reply_mess
);
558 /*===========================================================================*
560 *===========================================================================*/
561 static void do_int(dep
)
564 if (dep
->de_flags
& (DEF_PACK_SEND
| DEF_PACK_RECV
))
568 /*===========================================================================*
570 *===========================================================================*/
571 static void do_getstat_s(mp
)
579 if (dep
->de_mode
== DEM_SINK
)
581 put_userdata_s(mp
->m_source
, (vir_bytes
) mp
->DL_GRANT
,
582 (vir_bytes
) sizeof(dep
->de_stat
), &dep
->de_stat
);
584 mp
->m_type
= DL_STAT_REPLY
;
585 r
= send(mp
->m_source
, mp
);
587 panic("do_getstat: send failed: %d", r
);
590 assert(dep
->de_mode
== DEM_ENABLED
);
591 assert(dep
->de_flags
& DEF_ENABLED
);
593 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
594 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
595 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
597 put_userdata_s(mp
->m_source
, mp
->DL_GRANT
,
598 sizeof(dep
->de_stat
), &dep
->de_stat
);
600 mp
->m_type
= DL_STAT_REPLY
;
601 r
= send(mp
->m_source
, mp
);
603 panic("do_getstat: send failed: %d", r
);
606 /*===========================================================================*
608 *===========================================================================*/
609 static void dp_stop(dep
)
613 if (dep
->de_mode
== DEM_SINK
)
615 assert(dep
->de_mode
== DEM_ENABLED
);
617 if (!(dep
->de_flags
& DEF_ENABLED
))
620 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
621 (dep
->de_stopf
)(dep
);
623 dep
->de_flags
= DEF_EMPTY
;
626 /*===========================================================================*
628 *===========================================================================*/
629 static void dp_init(dep
)
635 /* General initialization */
636 dep
->de_flags
= DEF_EMPTY
;
637 (*dep
->de_initf
)(dep
);
643 printf("%s: Ethernet address ", dep
->de_name
);
644 for (i
= 0; i
< 6; i
++)
645 printf("%x%c", dep
->de_address
.ea_addr
[i
],
652 /* Initialization of the dp8390 following the mandatory procedure
653 * in reference manual ("DP8390D/NS32490D NIC Network Interface
654 * Controller", National Semiconductor, July 1995, Page 29).
657 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_STP
| CR_DM_ABORT
);
660 outb_reg0(dep
, DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
662 outb_reg0(dep
, DP_DCR
, DCR_BYTEWIDE
| DCR_8BYTES
| DCR_BMS
);
664 outb_reg0(dep
, DP_RBCR0
, 0);
665 outb_reg0(dep
, DP_RBCR1
, 0);
668 if (dep
->de_flags
& DEF_PROMISC
)
669 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
670 if (dep
->de_flags
& DEF_BROAD
)
671 dp_rcr_reg
|= RCR_AB
;
672 if (dep
->de_flags
& DEF_MULTI
)
673 dp_rcr_reg
|= RCR_AM
;
674 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
676 outb_reg0(dep
, DP_TCR
, TCR_INTERNAL
);
678 outb_reg0(dep
, DP_BNRY
, dep
->de_startpage
);
679 outb_reg0(dep
, DP_PSTART
, dep
->de_startpage
);
680 outb_reg0(dep
, DP_PSTOP
, dep
->de_stoppage
);
682 outb_reg0(dep
, DP_ISR
, 0xFF);
684 outb_reg0(dep
, DP_IMR
, IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
|
685 IMR_OVWE
| IMR_CNTE
);
687 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_DM_ABORT
| CR_STP
);
689 outb_reg1(dep
, DP_PAR0
, dep
->de_address
.ea_addr
[0]);
690 outb_reg1(dep
, DP_PAR1
, dep
->de_address
.ea_addr
[1]);
691 outb_reg1(dep
, DP_PAR2
, dep
->de_address
.ea_addr
[2]);
692 outb_reg1(dep
, DP_PAR3
, dep
->de_address
.ea_addr
[3]);
693 outb_reg1(dep
, DP_PAR4
, dep
->de_address
.ea_addr
[4]);
694 outb_reg1(dep
, DP_PAR5
, dep
->de_address
.ea_addr
[5]);
696 outb_reg1(dep
, DP_MAR0
, 0xff);
697 outb_reg1(dep
, DP_MAR1
, 0xff);
698 outb_reg1(dep
, DP_MAR2
, 0xff);
699 outb_reg1(dep
, DP_MAR3
, 0xff);
700 outb_reg1(dep
, DP_MAR4
, 0xff);
701 outb_reg1(dep
, DP_MAR5
, 0xff);
702 outb_reg1(dep
, DP_MAR6
, 0xff);
703 outb_reg1(dep
, DP_MAR7
, 0xff);
705 outb_reg1(dep
, DP_CURR
, dep
->de_startpage
+ 1);
707 outb_reg0(dep
, DP_CR
, CR_DM_ABORT
| CR_STA
);
709 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
711 inb_reg0(dep
, DP_CNTR0
); /* reset counters by reading */
712 inb_reg0(dep
, DP_CNTR1
);
713 inb_reg0(dep
, DP_CNTR2
);
715 /* Finish the initialization. */
716 dep
->de_flags
|= DEF_ENABLED
;
717 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
718 dep
->de_sendq
[i
].sq_filled
= 0;
719 dep
->de_sendq_head
= 0;
720 dep
->de_sendq_tail
= 0;
721 if (!dep
->de_prog_IO
)
723 dep
->de_user2nicf_s
= dp_user2nic_s
;
724 dep
->de_nic2userf_s
= dp_nic2user_s
;
725 dep
->de_getblockf
= dp_getblock
;
727 else if (dep
->de_16bit
)
729 dep
->de_user2nicf_s
= dp_pio16_user2nic_s
;
730 dep
->de_nic2userf_s
= dp_pio16_nic2user_s
;
731 dep
->de_getblockf
= dp_pio16_getblock
;
735 dep
->de_user2nicf_s
= dp_pio8_user2nic_s
;
736 dep
->de_nic2userf_s
= dp_pio8_nic2user_s
;
737 dep
->de_getblockf
= dp_pio8_getblock
;
740 /* Set the interrupt handler and policy. Do not automatically
741 * reenable interrupts. Return the IRQ line number on interrupts.
743 dep
->de_hook
= dep
->de_irq
;
744 r
= sys_irqsetpolicy(dep
->de_irq
, 0, &dep
->de_hook
);
746 panic("sys_irqsetpolicy failed: %d", r
);
748 r
= sys_irqenable(&dep
->de_hook
);
751 panic("unable enable interrupts: %d", r
);
755 /*===========================================================================*
757 *===========================================================================*/
758 static void dp_confaddr(dep
)
763 static char eafmt
[]= "x:x:x:x:x:x";
766 /* User defined ethernet address? */
767 strlcpy(eakey
, "DPETH0_EA", sizeof(eakey
));
768 eakey
[5] += de_instance
;
770 for (i
= 0; i
< 6; i
++)
772 v
= dep
->de_address
.ea_addr
[i
];
773 if (env_parse(eakey
, eafmt
, i
, &v
, 0x00L
, 0xFFL
) != EP_SET
)
777 dep
->de_address
.ea_addr
[i
]= v
;
780 if (i
!= 0 && i
!= 6) env_panic(eakey
); /* It's all or nothing */
783 /*===========================================================================*
785 *===========================================================================*/
786 static void dp_reinit(dep
)
791 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
794 if (dep
->de_flags
& DEF_PROMISC
)
795 dp_rcr_reg
|= RCR_AB
| RCR_PRO
| RCR_AM
;
796 if (dep
->de_flags
& DEF_BROAD
)
797 dp_rcr_reg
|= RCR_AB
;
798 if (dep
->de_flags
& DEF_MULTI
)
799 dp_rcr_reg
|= RCR_AM
;
800 outb_reg0(dep
, DP_RCR
, dp_rcr_reg
);
803 /*===========================================================================*
805 *===========================================================================*/
806 static void dp_reset(dep
)
812 outb_reg0(dep
, DP_CR
, CR_STP
| CR_DM_ABORT
);
813 outb_reg0(dep
, DP_RBCR0
, 0);
814 outb_reg0(dep
, DP_RBCR1
, 0);
815 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RST
) == 0); i
++)
817 outb_reg0(dep
, DP_TCR
, TCR_1EXTERNAL
|TCR_OFST
);
818 outb_reg0(dep
, DP_CR
, CR_STA
|CR_DM_ABORT
);
819 outb_reg0(dep
, DP_TCR
, TCR_NORMAL
);
821 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
822 for (i
= 0; i
< 0x1000 && ((inb_reg0(dep
, DP_ISR
) & ISR_RDC
) == 0); i
++)
824 outb_reg0(dep
, DP_ISR
, inb_reg0(dep
, DP_ISR
) & ~ISR_RDC
);
826 /* Reset the transmit ring. If we were transmitting a packet, we
827 * pretend that the packet is processed. Higher layers will
828 * retransmit if the packet wasn't actually sent.
830 dep
->de_sendq_head
= dep
->de_sendq_tail
= 0;
831 for (i
= 0; i
<dep
->de_sendq_nr
; i
++)
832 dep
->de_sendq
[i
].sq_filled
= 0;
834 dep
->de_flags
&= ~DEF_STOPPED
;
837 /*===========================================================================*
839 *===========================================================================*/
840 static void dp_check_ints(dep
)
844 int size
, sendq_tail
;
846 if (!(dep
->de_flags
& DEF_ENABLED
))
847 panic("dp8390: got premature interrupt");
851 isr
= inb_reg0(dep
, DP_ISR
);
854 outb_reg0(dep
, DP_ISR
, isr
);
855 if (isr
& (ISR_PTX
|ISR_TXE
))
860 { printf("%s: got send Error\n", dep
->de_name
); }
862 dep
->de_stat
.ets_sendErr
++;
866 tsr
= inb_reg0(dep
, DP_TSR
);
868 if (tsr
& TSR_PTX
) dep
->de_stat
.ets_packetT
++;
869 #if 0 /* Reserved in later manuals, should be ignored */
870 if (!(tsr
& TSR_DFR
))
872 /* In most (all?) implementations of
873 * the dp8390, this bit is set
874 * when the packet is not deferred
876 dep
->de_stat
.ets_transDef
++;
879 if (tsr
& TSR_COL
) dep
->de_stat
.ets_collision
++;
880 if (tsr
& TSR_ABT
) dep
->de_stat
.ets_transAb
++;
881 if (tsr
& TSR_CRS
) dep
->de_stat
.ets_carrSense
++;
883 && ++dep
->de_stat
.ets_fifoUnder
<= 10)
885 printf("%s: fifo underrun\n",
889 && ++dep
->de_stat
.ets_CDheartbeat
<= 10)
891 printf("%s: CD heart beat failure\n",
894 if (tsr
& TSR_OWC
) dep
->de_stat
.ets_OWC
++;
896 sendq_tail
= dep
->de_sendq_tail
;
898 if (!(dep
->de_sendq
[sendq_tail
].sq_filled
))
903 /* Or hardware bug? */
905 "%s: transmit interrupt, but not sending\n",
909 dep
->de_sendq
[sendq_tail
].sq_filled
= 0;
910 if (++sendq_tail
== dep
->de_sendq_nr
)
912 dep
->de_sendq_tail
= sendq_tail
;
913 if (dep
->de_sendq
[sendq_tail
].sq_filled
)
915 size
= dep
->de_sendq
[sendq_tail
].sq_size
;
916 outb_reg0(dep
, DP_TPSR
,
917 dep
->de_sendq
[sendq_tail
].sq_sendpage
);
918 outb_reg0(dep
, DP_TBCR1
, size
>> 8);
919 outb_reg0(dep
, DP_TBCR0
, size
& 0xff);
920 outb_reg0(dep
, DP_CR
, CR_TXP
| CR_EXTRA
);
922 if (dep
->de_flags
& DEF_SEND_AVAIL
)
928 /* Only call dp_recv if there is a read request */
929 if (dep
->de_flags
& DEF_READING
)
933 if (isr
& ISR_RXE
) dep
->de_stat
.ets_recvErr
++;
936 dep
->de_stat
.ets_CRCerr
+= inb_reg0(dep
, DP_CNTR0
);
937 dep
->de_stat
.ets_frameAll
+= inb_reg0(dep
, DP_CNTR1
);
938 dep
->de_stat
.ets_missedP
+= inb_reg0(dep
, DP_CNTR2
);
942 dep
->de_stat
.ets_OVW
++;
945 "%s: got overwrite warning\n", dep
->de_name
); }
947 if (dep
->de_flags
& DEF_READING
)
950 "dp_check_ints: strange: overwrite warning and pending read request\n");
960 /* this means we got an interrupt but the ethernet
961 * chip is shutdown. We set the flag DEF_STOPPED,
962 * and continue processing arrived packets. When the
963 * receive buffer is empty, we reset the dp8390.
967 "%s: NIC stopped\n", dep
->de_name
); }
969 dep
->de_flags
|= DEF_STOPPED
;
973 if ((dep
->de_flags
& (DEF_READING
|DEF_STOPPED
)) ==
974 (DEF_READING
|DEF_STOPPED
))
976 /* The chip is stopped, and all arrived packets are
983 /*===========================================================================*
985 *===========================================================================*/
986 static void dp_recv(dep
)
990 unsigned pageno
, curr
, next
;
992 int packet_processed
, r
;
995 packet_processed
= FALSE
;
996 pageno
= inb_reg0(dep
, DP_BNRY
) + 1;
997 if (pageno
== dep
->de_stoppage
) pageno
= dep
->de_startpage
;
1001 outb_reg0(dep
, DP_CR
, CR_PS_P1
| CR_EXTRA
);
1002 curr
= inb_reg1(dep
, DP_CURR
);
1003 outb_reg0(dep
, DP_CR
, CR_PS_P0
| CR_EXTRA
);
1005 if (curr
== pageno
) break;
1007 (dep
->de_getblockf
)(dep
, pageno
, (size_t)0, sizeof(header
),
1009 (dep
->de_getblockf
)(dep
, pageno
, sizeof(header
) +
1010 2*sizeof(ether_addr_t
), sizeof(eth_type
), ð_type
);
1012 length
= (header
.dr_rbcl
| (header
.dr_rbch
<< 8)) -
1013 sizeof(dp_rcvhdr_t
);
1014 next
= header
.dr_next
;
1015 if (length
< ETH_MIN_PACK_SIZE
||
1016 length
> ETH_MAX_PACK_SIZE_TAGGED
)
1018 printf("%s: packet with strange length arrived: %d\n",
1019 dep
->de_name
, (int) length
);
1022 else if (next
< dep
->de_startpage
|| next
>= dep
->de_stoppage
)
1024 printf("%s: strange next page\n", dep
->de_name
);
1027 else if (header
.dr_status
& RSR_FO
)
1029 /* This is very serious, so we issue a warning and
1030 * reset the buffers */
1031 printf("%s: fifo overrun, resetting receive buffer\n",
1033 dep
->de_stat
.ets_fifoOver
++;
1036 else if ((header
.dr_status
& RSR_PRX
) &&
1037 (dep
->de_flags
& DEF_ENABLED
))
1039 r
= dp_pkt2user_s(dep
, pageno
, length
);
1043 packet_processed
= TRUE
;
1044 dep
->de_stat
.ets_packetR
++;
1046 if (next
== dep
->de_startpage
)
1047 outb_reg0(dep
, DP_BNRY
, dep
->de_stoppage
- 1);
1049 outb_reg0(dep
, DP_BNRY
, next
- 1);
1053 while (!packet_processed
);
1056 /*===========================================================================*
1058 *===========================================================================*/
1059 static void dp_send(dep
)
1062 if (!(dep
->de_flags
& DEF_SEND_AVAIL
))
1065 dep
->de_flags
&= ~DEF_SEND_AVAIL
;
1066 do_vwrite_s(&dep
->de_sendmsg
, TRUE
);
1069 /*===========================================================================*
1071 *===========================================================================*/
1072 static void dp_getblock(dep
, page
, offset
, size
, dst
)
1079 offset
= page
* DP_PAGESIZE
+ offset
;
1081 memcpy(dst
, dep
->de_locmem
+ offset
, size
);
1084 /*===========================================================================*
1085 * dp_pio8_getblock *
1086 *===========================================================================*/
1087 static void dp_pio8_getblock(dep
, page
, offset
, size
, dst
)
1094 offset
= page
* DP_PAGESIZE
+ offset
;
1095 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1096 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1097 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1098 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1099 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1101 insb(dep
->de_data_port
, dst
, size
);
1104 /*===========================================================================*
1105 * dp_pio16_getblock *
1106 *===========================================================================*/
1107 static void dp_pio16_getblock(dep
, page
, offset
, size
, dst
)
1114 offset
= page
* DP_PAGESIZE
+ offset
;
1115 outb_reg0(dep
, DP_RBCR0
, size
& 0xFF);
1116 outb_reg0(dep
, DP_RBCR1
, size
>> 8);
1117 outb_reg0(dep
, DP_RSAR0
, offset
& 0xFF);
1118 outb_reg0(dep
, DP_RSAR1
, offset
>> 8);
1119 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1121 assert (!(size
& 1));
1122 insw(dep
->de_data_port
, dst
, size
);
1125 /*===========================================================================*
1127 *===========================================================================*/
1128 static int dp_pkt2user_s(dpeth_t
*dep
, int page
, vir_bytes length
)
1132 if (!(dep
->de_flags
& DEF_READING
))
1135 last
= page
+ (length
- 1) / DP_PAGESIZE
;
1136 if (last
>= dep
->de_stoppage
)
1138 count
= (dep
->de_stoppage
- page
) * DP_PAGESIZE
-
1139 sizeof(dp_rcvhdr_t
);
1141 /* Save read_iovec since we need it twice. */
1142 dep
->de_tmp_iovec_s
= dep
->de_read_iovec_s
;
1143 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1144 sizeof(dp_rcvhdr_t
), &dep
->de_tmp_iovec_s
, 0, count
);
1145 (dep
->de_nic2userf_s
)(dep
, dep
->de_startpage
* DP_PAGESIZE
,
1146 &dep
->de_read_iovec_s
, count
, length
- count
);
1150 (dep
->de_nic2userf_s
)(dep
, page
* DP_PAGESIZE
+
1151 sizeof(dp_rcvhdr_t
), &dep
->de_read_iovec_s
, 0, length
);
1154 dep
->de_read_s
= length
;
1155 dep
->de_flags
|= DEF_PACK_RECV
;
1156 dep
->de_flags
&= ~DEF_READING
;
1161 /*===========================================================================*
1163 *===========================================================================*/
1164 static void dp_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1166 iovec_dat_s_t
*iovp
;
1174 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1181 dp_next_iovec_s(iovp
);
1185 assert(i
< iovp
->iod_iovec_s
);
1186 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1188 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1192 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1196 r
= sys_safecopyfrom(iovp
->iod_proc_nr
,
1197 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1200 panic("dp_user2nic_s: sys_safecopyfrom failed: %d", r
);
1210 /*===========================================================================*
1211 * dp_pio8_user2nic_s *
1212 *===========================================================================*/
1213 static void dp_pio8_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1215 iovec_dat_s_t
*iovp
;
1222 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1224 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1225 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1226 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1227 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1228 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1235 dp_next_iovec_s(iovp
);
1239 assert(i
< iovp
->iod_iovec_s
);
1240 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1242 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1246 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1250 r
= sys_safe_outsb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1251 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1253 panic("dp_pio8_user2nic_s: sys_safe_outsb failed: %d",
1261 for (i
= 0; i
<100; i
++)
1263 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1268 panic("dp8390: remote dma failed to complete");
1272 /*===========================================================================*
1273 * dp_pio16_user2nic_s *
1274 *===========================================================================*/
1275 static void dp_pio16_user2nic_s(dep
, iovp
, offset
, nic_addr
, count
)
1277 iovec_dat_s_t
*iovp
;
1284 int i
, r
, bytes
, user_proc
;
1288 ecount
= (count
+1) & ~1;
1291 outb_reg0(dep
, DP_ISR
, ISR_RDC
);
1292 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1293 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1294 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1295 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1296 outb_reg0(dep
, DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
1303 dp_next_iovec_s(iovp
);
1307 assert(i
< iovp
->iod_iovec_s
);
1308 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1310 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1314 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1318 user_proc
= iovp
->iod_proc_nr
;
1319 gid
= iovp
->iod_iovec
[i
].iov_grant
;
1322 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
1323 (vir_bytes
)&two_bytes
[1], 1);
1325 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
1327 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1338 r
= sys_safe_outsw(dep
->de_data_port
, user_proc
,
1339 gid
, offset
, ecount
);
1341 panic("dp_pio16_user2nic: sys_safe_outsw failed: %d", r
);
1350 r
= sys_safecopyfrom(user_proc
, gid
, offset
,
1351 (vir_bytes
)&two_bytes
[0], 1);
1353 panic("dp_pio16_user2nic: sys_safecopyfrom failed: %d", r
);
1364 outw(dep
->de_data_port
, *(u16_t
*)two_bytes
);
1366 for (i
= 0; i
<100; i
++)
1368 if (inb_reg0(dep
, DP_ISR
) & ISR_RDC
)
1373 panic("dp8390: remote dma failed to complete");
1377 /*===========================================================================*
1379 *===========================================================================*/
1380 static void dp_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1383 iovec_dat_s_t
*iovp
;
1390 vir_hw
= (vir_bytes
)dep
->de_locmem
+ nic_addr
;
1397 dp_next_iovec_s(iovp
);
1401 assert(i
< iovp
->iod_iovec_s
);
1402 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1404 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1408 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1412 r
= sys_safecopyto(iovp
->iod_proc_nr
,
1413 iovp
->iod_iovec
[i
].iov_grant
, offset
,
1416 panic("dp_nic2user_s: sys_safecopyto failed: %d", r
);
1425 /*===========================================================================*
1426 * dp_pio8_nic2user_s *
1427 *===========================================================================*/
1428 static void dp_pio8_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1431 iovec_dat_s_t
*iovp
;
1437 outb_reg0(dep
, DP_RBCR0
, count
& 0xFF);
1438 outb_reg0(dep
, DP_RBCR1
, count
>> 8);
1439 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1440 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1441 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1448 dp_next_iovec_s(iovp
);
1452 assert(i
< iovp
->iod_iovec_s
);
1453 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1455 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1459 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1463 r
= sys_safe_insb(dep
->de_data_port
, iovp
->iod_proc_nr
,
1464 iovp
->iod_iovec
[i
].iov_grant
, offset
, bytes
);
1466 panic("dp_pio8_nic2user_s: sys_safe_insb failed: %d", r
);
1474 /*===========================================================================*
1475 * dp_pio16_nic2user_s *
1476 *===========================================================================*/
1477 static void dp_pio16_nic2user_s(dep
, nic_addr
, iovp
, offset
, count
)
1480 iovec_dat_s_t
*iovp
;
1486 int i
, r
, bytes
, user_proc
;
1490 ecount
= (count
+1) & ~1;
1493 outb_reg0(dep
, DP_RBCR0
, ecount
& 0xFF);
1494 outb_reg0(dep
, DP_RBCR1
, ecount
>> 8);
1495 outb_reg0(dep
, DP_RSAR0
, nic_addr
& 0xFF);
1496 outb_reg0(dep
, DP_RSAR1
, nic_addr
>> 8);
1497 outb_reg0(dep
, DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
1504 dp_next_iovec_s(iovp
);
1508 assert(i
< iovp
->iod_iovec_s
);
1509 if (offset
>= iovp
->iod_iovec
[i
].iov_size
)
1511 offset
-= iovp
->iod_iovec
[i
].iov_size
;
1515 bytes
= iovp
->iod_iovec
[i
].iov_size
- offset
;
1519 user_proc
= iovp
->iod_proc_nr
;
1520 gid
= iovp
->iod_iovec
[i
].iov_grant
;
1523 r
= sys_safecopyto(user_proc
, gid
, offset
,
1524 (vir_bytes
)&two_bytes
[1], 1);
1526 panic("dp_pio16_nic2user: sys_safecopyto failed: %d", r
);
1538 r
= sys_safe_insw(dep
->de_data_port
, user_proc
, gid
,
1541 panic("dp_pio16_nic2user: sys_safe_insw failed: %d",
1551 *(u16_t
*)two_bytes
= inw(dep
->de_data_port
);
1552 r
= sys_safecopyto(user_proc
, gid
, offset
,
1553 (vir_bytes
)&two_bytes
[0], 1);
1556 panic("dp_pio16_nic2user: sys_safecopyto failed: %d",
1568 /*===========================================================================*
1570 *===========================================================================*/
1571 static void dp_next_iovec_s(iovp
)
1572 iovec_dat_s_t
*iovp
;
1574 assert(iovp
->iod_iovec_s
> IOVEC_NR
);
1576 iovp
->iod_iovec_s
-= IOVEC_NR
;
1578 iovp
->iod_iovec_offset
+= IOVEC_NR
* sizeof(iovec_t
);
1580 get_userdata_s(iovp
->iod_proc_nr
, iovp
->iod_grant
,
1581 iovp
->iod_iovec_offset
,
1582 (iovp
->iod_iovec_s
> IOVEC_NR
? IOVEC_NR
: iovp
->iod_iovec_s
) *
1583 sizeof(iovp
->iod_iovec
[0]), iovp
->iod_iovec
);
1586 /*===========================================================================*
1588 *===========================================================================*/
1589 static void conf_hw(dep
)
1592 static eth_stat_t empty_stat
= {0, 0, 0, 0, 0, 0 /* ,... */ };
1597 dep
->de_mode
= DEM_DISABLED
; /* Superfluous */
1599 /* Pick a default configuration for this instance. */
1600 confnr
= MIN(de_instance
, DP_CONF_NR
-1);
1602 dcp
= &dp_conf
[confnr
];
1603 update_conf(dep
, dcp
);
1604 if (dep
->de_mode
!= DEM_ENABLED
)
1606 if (!wdeth_probe(dep
) && !ne_probe(dep
) && !el2_probe(dep
))
1608 printf("%s: No ethernet card found at 0x%x\n",
1609 dep
->de_name
, dep
->de_base_port
);
1610 dep
->de_mode
= DEM_DISABLED
;
1614 /* XXX */ if (dep
->de_linmem
== 0) dep
->de_linmem
= 0xFFFF0000;
1616 dep
->de_flags
= DEF_EMPTY
;
1617 dep
->de_stat
= empty_stat
;
1620 /*===========================================================================*
1622 *===========================================================================*/
1623 static void update_conf(dep
, dcp
)
1628 static char dpc_fmt
[] = "x:d:x:x";
1634 if (dep
->de_pci
== 1)
1636 /* PCI device is present */
1637 dep
->de_mode
= DEM_ENABLED
;
1639 return; /* Already configured */
1643 strlcpy(eckey
, "DPETH0", sizeof(eckey
));
1644 eckey
[5] += de_instance
;
1646 /* Get the default settings and modify them from the environment. */
1647 dep
->de_mode
= DEM_SINK
;
1649 switch (env_parse(eckey
, dpc_fmt
, 0, &v
, 0x0000L
, 0xFFFFL
)) {
1651 dep
->de_mode
= DEM_DISABLED
;
1655 dep
->de_mode
= DEM_ENABLED
; /* Might become disabled if
1656 * all probes fail */
1659 dep
->de_base_port
= v
;
1661 v
= dcp
->dpc_irq
| DEI_DEFAULT
;
1662 (void) env_parse(eckey
, dpc_fmt
, 1, &v
, 0L, (long) NR_IRQ_VECTORS
- 1);
1666 (void) env_parse(eckey
, dpc_fmt
, 2, &v
, 0L, 0xFFFFFL
);
1670 (void) env_parse(eckey
, dpc_fmt
, 3, &v
, 0x2000L
, 0x8000L
);
1674 /*===========================================================================*
1676 *===========================================================================*/
1677 static void map_hw_buffer(dep
)
1681 if (dep
->de_prog_IO
)
1685 "map_hw_buffer: programmed I/O, no need to map buffer\n");
1687 dep
->de_locmem
= (char *)-dep
->de_ramsize
; /* trap errors */
1692 vm_map_phys(SELF
, (void *) dep
->de_linmem
, dep
->de_ramsize
);
1693 if (dep
->de_locmem
== MAP_FAILED
)
1694 panic("map_hw_buffer: vm_map_phys failed");
1697 /*===========================================================================*
1698 * calc_iovec_size_s *
1699 *===========================================================================*/
1700 static int calc_iovec_size_s(iovp
)
1701 iovec_dat_s_t
*iovp
;
1703 /* Calculate the size of a request. Note that the iovec_dat
1704 * structure will be unusable after calc_iovec_size_s.
1711 while (i
< iovp
->iod_iovec_s
)
1715 dp_next_iovec_s(iovp
);
1719 size
+= iovp
->iod_iovec
[i
].iov_size
;
1725 /*===========================================================================*
1727 *===========================================================================*/
1728 static void reply(dep
)
1736 if (dep
->de_flags
& DEF_PACK_SEND
)
1737 flags
|= DL_PACK_SEND
;
1738 if (dep
->de_flags
& DEF_PACK_RECV
)
1739 flags
|= DL_PACK_RECV
;
1741 reply
.m_type
= DL_TASK_REPLY
;
1742 reply
.DL_FLAGS
= flags
;
1743 reply
.DL_COUNT
= dep
->de_read_s
;
1744 r
= send(dep
->de_client
, &reply
);
1747 panic("dp8390: send failed: %d", r
);
1750 dep
->de_flags
&= ~(DEF_PACK_SEND
| DEF_PACK_RECV
);
1753 /*===========================================================================*
1755 *===========================================================================*/
1756 static void mess_reply(req
, reply_mess
)
1758 message
*reply_mess
;
1760 if (send(req
->m_source
, reply_mess
) != OK
)
1761 panic("dp8390: unable to mess_reply");
1764 /*===========================================================================*
1766 *===========================================================================*/
1767 static void get_userdata_s(user_proc
, grant
, offset
, count
, loc_addr
)
1769 cp_grant_id_t grant
;
1776 r
= sys_safecopyfrom(user_proc
, grant
, offset
,
1777 (vir_bytes
)loc_addr
, count
);
1779 panic("get_userdata: sys_safecopyfrom failed: %d", r
);
1782 /*===========================================================================*
1784 *===========================================================================*/
1785 static void put_userdata_s(user_proc
, grant
, count
, loc_addr
)
1787 cp_grant_id_t grant
;
1793 r
= sys_safecopyto(user_proc
, grant
, 0, (vir_bytes
)loc_addr
,
1796 panic("put_userdata: sys_safecopyto failed: %d", r
);
1799 u8_t
inb(port_t port
)
1804 r
= sys_inb(port
, &value
);
1807 printf("inb failed for port 0x%x\n", port
);
1808 panic("sys_inb failed: %d", r
);
1813 u16_t
inw(port_t port
)
1818 r
= sys_inw(port
, &value
);
1820 panic("sys_inw failed: %d", r
);
1821 return (u16_t
) value
;
1824 void outb(port_t port
, u8_t value
)
1828 r
= sys_outb(port
, value
);
1830 panic("sys_outb failed: %d", r
);
1833 void outw(port_t port
, u16_t value
)
1837 r
= sys_outw(port
, value
);
1839 panic("sys_outw failed: %d", r
);
1842 static void insb(port_t port
, void *buf
, size_t size
)
1844 do_vir_insb(port
, SELF
, (vir_bytes
)buf
, size
);
1847 static void insw(port_t port
, void *buf
, size_t size
)
1849 do_vir_insw(port
, SELF
, (vir_bytes
)buf
, size
);
1852 static void do_vir_insb(port_t port
, int proc
, vir_bytes buf
, size_t size
)
1856 r
= sys_insb(port
, proc
, (void *) buf
, size
);
1858 panic("sys_sdevio failed: %d", r
);
1861 static void do_vir_insw(port_t port
, int proc
, vir_bytes buf
, size_t size
)
1865 r
= sys_insw(port
, proc
, (void *) buf
, size
);
1867 panic("sys_sdevio failed: %d", r
);
1871 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $