2
* Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
* * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
6
* * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
7
* * Any deviations from these conditions require written permission from the copyright holder in advance
12
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
13
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
* 2009 ported to HelenOS, Lukas Mejdrech
27
/** @addtogroup dp8390
32
* DP8390 network interface core implementation.
38
#include "../../include/byteorder.h"
40
#include "../../structures/packet/packet.h"
41
#include "../../structures/packet/packet_client.h"
45
#include "dp8390_drv.h"
46
#include "dp8390_port.h"
51
* Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
53
* Modified Mar 10 1994 by Philip Homburg
54
* Become a generic dp8390 driver.
56
* Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
57
* Added support for 3c503 boards.
63
/** Queues the outgoing packet.
64
* @param[in] dep The network interface structure.
65
* @param[in] packet The outgoing packet.
66
* @returns EOK on success.
69
int queue_packet( dpeth_t * dep, packet_t packet );
71
/** Reads a memory block byte by byte.
72
* @param[in] port The source address.
73
* @param[out] buf The destination buffer.
74
* @param[in] size The memory block size in bytes.
76
static void outsb( port_t port, void * buf, size_t size );
78
/** Reads a memory block word by word.
79
* @param[in] port The source address.
80
* @param[out] buf The destination buffer.
81
* @param[in] size The memory block size in bytes.
83
static void outsw( port_t port, void * buf, size_t size );
85
//static u16_t eth_ign_proto;
86
//static char *progname;
89
/*typedef struct dp_conf
97
//dp_conf_t dp_conf[]= /* Card addresses */
99
/* I/O port, IRQ, Buffer address, Env. var. */
100
/* { 0x280, 3, 0xD0000, "DPETH0" },
101
{ 0x300, 5, 0xC8000, "DPETH1" },
102
{ 0x380, 10, 0xD8000, "DPETH2" },
105
/* Test if dp_conf has exactly DE_PORT_NR entries. If not then you will see
106
* the error: "array size is negative".
108
//extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
110
/* Card inits configured out? */
112
#define wdeth_probe(dep) (0)
115
#define ne_probe(dep) (0)
118
#define el2_probe(dep) (0)
121
/* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
122
* on writes to the CR register. Additional CR_STAs do not appear to hurt
125
#define CR_EXTRA CR_STA
128
//_PROTOTYPE( static void pci_conf, (void) );
130
//_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
132
//_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
133
//_PROTOTYPE( static void do_vread, (message *mp, int vectored) );
134
//_PROTOTYPE( static void do_vread_s, (message *mp) );
135
//_PROTOTYPE( static void do_init, (message *mp) );
136
//_PROTOTYPE( static void do_int, (dpeth_t *dep) );
137
//_PROTOTYPE( static void do_getstat, (message *mp) );
138
//_PROTOTYPE( static void do_getstat_s, (message *mp) );
139
//_PROTOTYPE( static void do_getname, (message *mp) );
140
//_PROTOTYPE( static void do_stop, (message *mp) );
141
_PROTOTYPE( static void dp_init, (dpeth_t *dep) );
142
//_PROTOTYPE( static void dp_confaddr, (dpeth_t *dep) );
143
_PROTOTYPE( static void dp_reinit, (dpeth_t *dep) );
144
_PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
145
//_PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
146
_PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
147
_PROTOTYPE( static void dp_send, (dpeth_t *dep) );
148
//_PROTOTYPE( static void dp8390_stop, (void) );
149
_PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
150
size_t offset, size_t size, void *dst) );
151
_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
152
size_t offset, size_t size, void *dst) );
153
_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
154
size_t offset, size_t size, void *dst) );
155
_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
157
//_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
159
_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
160
vir_bytes offset, int nic_addr, vir_bytes count) );
161
//_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
162
// vir_bytes offset, int nic_addr, vir_bytes count) );
163
_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
164
iovec_dat_t *iovp, vir_bytes offset,
165
int nic_addr, vir_bytes count) );
166
//_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
167
// iovec_dat_s_t *iovp, vir_bytes offset,
168
// int nic_addr, vir_bytes count) );
169
_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
170
iovec_dat_t *iovp, vir_bytes offset,
171
int nic_addr, vir_bytes count) );
172
//_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
173
// iovec_dat_s_t *iovp, vir_bytes offset,
174
// int nic_addr, vir_bytes count) );
175
_PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
176
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
177
//_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
178
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
179
_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
180
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
181
//_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
182
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
183
_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
184
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
185
//_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
186
// iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
187
_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
188
//_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
189
_PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
190
//_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
191
_PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) );
192
//_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
193
//_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
194
_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
195
//_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
196
_PROTOTYPE( static void get_userdata, (int user_proc,
197
vir_bytes user_addr, vir_bytes count, void *loc_addr) );
198
//_PROTOTYPE( static void get_userdata_s, (int user_proc,
199
// cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
200
// void *loc_addr) );
201
//_PROTOTYPE( static void put_userdata, (int user_proc,
202
// vir_bytes user_addr, vir_bytes count, void *loc_addr) );
203
//_PROTOTYPE( static void put_userdata_s, (int user_proc,
204
// cp_grant_id_t grant, size_t count, void *loc_addr) );
205
_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
206
_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
207
//_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
208
// vir_bytes buf, size_t size) );
209
//_PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
210
// vir_bytes buf, size_t size) );
211
//_PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
212
// vir_bytes buf, size_t size) );
213
//_PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
214
// vir_bytes buf, size_t size) );
216
int do_probe( dpeth_t * dep ){
217
/* This is the default, try to (re)locate the device. */
219
if (dep->de_mode == DEM_DISABLED)
221
/* Probe failed, or the device is configured off. */
222
return EXDEV;//ENXIO;
224
if (dep->de_mode == DEM_ENABLED)
229
/*===========================================================================*
231
*===========================================================================*/
232
void dp8390_dump( dpeth_t * dep )
238
// for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
241
if (dep->de_mode == DEM_DISABLED)
242
printf("dp8390 port %d is disabled\n", i);
243
else if (dep->de_mode == DEM_SINK)
244
printf("dp8390 port %d is in sink mode\n", i);
247
if (dep->de_mode != DEM_ENABLED)
251
// printf("dp8390 statistics of port %d:\n", i);
253
printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
254
printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
255
printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
257
printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
258
printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
259
printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
261
printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
262
printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
263
printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
265
printf("collision :%8ld\t", dep->de_stat.ets_collision);
266
printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
267
printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
269
printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
270
printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
271
printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
273
printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
275
isr= inb_reg0(dep, DP_ISR);
276
printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
277
inb_reg0(dep, DP_ISR), dep->de_flags);
281
/*===========================================================================*
283
*===========================================================================*/
284
int do_init( dpeth_t * dep, int mode ){
285
if (dep->de_mode == DEM_DISABLED)
287
// might call do_probe()
291
if (dep->de_mode == DEM_SINK)
293
// strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
294
// dep->de_address.ea_addr[5] = port;
296
// reply_mess.m_type = DL_CONF_REPLY;
297
// reply_mess.m3_i1 = mp->DL_PORT;
298
// reply_mess.m3_i2 = DE_PORT_NR;
299
// *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
300
// mess_reply(mp, &reply_mess);
304
assert(dep->de_mode == DEM_ENABLED);
305
assert(dep->de_flags & DEF_ENABLED);
307
dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
309
if (mode & DL_PROMISC_REQ)
310
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
311
if (mode & DL_MULTI_REQ)
312
dep->de_flags |= DEF_MULTI;
313
if (mode & DL_BROAD_REQ)
314
dep->de_flags |= DEF_BROAD;
316
// dep->de_client = mp->m_source;
319
// reply_mess.m_type = DL_CONF_REPLY;
320
// reply_mess.m3_i1 = mp->DL_PORT;
321
// reply_mess.m3_i2 = DE_PORT_NR;
322
// *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
324
// mess_reply(mp, &reply_mess);
328
/*===========================================================================*
330
*===========================================================================*/
331
void do_stop( dpeth_t * dep ){
332
if(( dep->de_mode != DEM_SINK ) && ( dep->de_mode == DEM_ENABLED ) && ( dep->de_flags & DEF_ENABLED )){
333
outb_reg0( dep, DP_CR, CR_STP | CR_DM_ABORT );
334
( dep->de_stopf )( dep );
336
dep->de_flags = DEF_EMPTY;
340
int queue_packet( dpeth_t * dep, packet_t packet ){
343
if( dep->packet_count >= MAX_PACKETS ){
344
netif_pq_release( packet_get_id( packet ));
348
tmp = dep->packet_queue;
349
while( pq_next( tmp )){
350
tmp = pq_next( tmp );
352
if( pq_add( & tmp, packet, 0, 0 ) != EOK ){
355
if( ! dep->packet_count ){
356
dep->packet_queue = packet;
358
++ dep->packet_count;
362
/*===========================================================================*
363
* based on do_vwrite *
364
*===========================================================================*/
365
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int )
367
// int port, count, size;
373
count = mp->DL_COUNT;
374
if (port < 0 || port >= DE_PORT_NR)
375
panic("", "dp8390: illegal port", port);
376
dep= &de_table[port];
377
dep->de_client= mp->DL_PROC;
379
if (dep->de_mode == DEM_SINK)
382
// dep->de_flags |= DEF_PACK_SEND;
383
reply(dep, OK, FALSE);
387
assert(dep->de_mode == DEM_ENABLED);
388
assert(dep->de_flags & DEF_ENABLED);
389
if( dep->packet_queue && ( ! from_int )){
390
// if (dep->de_flags & DEF_SEND_AVAIL){
391
// panic("", "dp8390: send already in progress", NO_NUM);
392
return queue_packet( dep, packet );
395
sendq_head= dep->de_sendq_head;
396
// if (dep->de_sendq[sendq_head].sq_filled)
399
// panic("", "dp8390: should not be sending\n", NO_NUM);
400
// dep->de_sendmsg= *mp;
401
// dep->de_flags |= DEF_SEND_AVAIL;
402
// reply(dep, OK, FALSE);
404
// return queue_packet( dep, packet );
406
// assert(!(dep->de_flags & DEF_PACK_SEND));
410
get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
411
(count > IOVEC_NR ? IOVEC_NR : count) *
412
sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
413
dep->de_write_iovec.iod_iovec_s = count;
414
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
415
dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
417
dep->de_tmp_iovec = dep->de_write_iovec;
418
size = calc_iovec_size(&dep->de_tmp_iovec);
422
dep->de_write_iovec.iod_iovec[0].iov_addr =
423
(vir_bytes) mp->DL_ADDR;
424
dep->de_write_iovec.iod_iovec[0].iov_size =
426
dep->de_write_iovec.iod_iovec_s = 1;
427
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
428
dep->de_write_iovec.iod_iovec_addr = 0;
432
size = packet_get_data_length( packet );
433
dep->de_write_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_get_data( packet );
434
dep->de_write_iovec.iod_iovec[0].iov_size = size;
435
dep->de_write_iovec.iod_iovec_s = 1;
436
dep->de_write_iovec.iod_iovec_addr = NULL;
438
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
440
panic("", "dp8390: invalid packet size", size);
443
(dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
444
dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
446
dep->de_sendq[sendq_head].sq_filled= TRUE;
447
if (dep->de_sendq_tail == sendq_head)
449
outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
450
outb_reg0(dep, DP_TBCR1, size >> 8);
451
outb_reg0(dep, DP_TBCR0, size & 0xff);
452
outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
455
dep->de_sendq[sendq_head].sq_size= size;
457
if (++sendq_head == dep->de_sendq_nr)
459
assert(sendq_head < SENDQ_NR);
460
dep->de_sendq_head= sendq_head;
462
// dep->de_flags |= DEF_PACK_SEND;
464
/* If the interrupt handler called, don't send a reply. The reply
465
* will be sent after all interrupts are handled.
469
reply(dep, OK, FALSE);
471
assert(dep->de_mode == DEM_ENABLED);
472
assert(dep->de_flags & DEF_ENABLED);
476
/*===========================================================================*
478
*===========================================================================*/
485
/* General initialization */
486
dep->de_flags = DEF_EMPTY;
487
(*dep->de_initf)(dep);
493
printf("%s: Ethernet address ", dep->de_name);
494
for (i= 0; i < 6; i++)
495
printf("%x%c", dep->de_address.ea_addr[i],
502
/* Initialization of the dp8390 following the mandatory procedure
503
* in reference manual ("DP8390D/NS32490D NIC Network Interface
504
* Controller", National Semiconductor, July 1995, Page 29).
507
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
510
outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
512
outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
514
outb_reg0(dep, DP_RBCR0, 0);
515
outb_reg0(dep, DP_RBCR1, 0);
518
if (dep->de_flags & DEF_PROMISC)
519
dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
520
if (dep->de_flags & DEF_BROAD)
521
dp_rcr_reg |= RCR_AB;
522
if (dep->de_flags & DEF_MULTI)
523
dp_rcr_reg |= RCR_AM;
524
outb_reg0(dep, DP_RCR, dp_rcr_reg);
526
outb_reg0(dep, DP_TCR, TCR_INTERNAL);
528
outb_reg0(dep, DP_BNRY, dep->de_startpage);
529
outb_reg0(dep, DP_PSTART, dep->de_startpage);
530
outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
532
outb_reg0(dep, DP_ISR, 0xFF);
534
outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
535
IMR_OVWE | IMR_CNTE);
537
outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
539
outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
540
outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
541
outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
542
outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
543
outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
544
outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
546
outb_reg1(dep, DP_MAR0, 0xff);
547
outb_reg1(dep, DP_MAR1, 0xff);
548
outb_reg1(dep, DP_MAR2, 0xff);
549
outb_reg1(dep, DP_MAR3, 0xff);
550
outb_reg1(dep, DP_MAR4, 0xff);
551
outb_reg1(dep, DP_MAR5, 0xff);
552
outb_reg1(dep, DP_MAR6, 0xff);
553
outb_reg1(dep, DP_MAR7, 0xff);
555
outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
557
outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
559
outb_reg0(dep, DP_TCR, TCR_NORMAL);
561
inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
562
inb_reg0(dep, DP_CNTR1);
563
inb_reg0(dep, DP_CNTR2);
565
/* Finish the initialization. */
566
dep->de_flags |= DEF_ENABLED;
567
for (i= 0; i<dep->de_sendq_nr; i++)
568
dep->de_sendq[i].sq_filled= 0;
569
dep->de_sendq_head= 0;
570
dep->de_sendq_tail= 0;
571
if (!dep->de_prog_IO)
573
dep->de_user2nicf= dp_user2nic;
574
// dep->de_user2nicf_s= dp_user2nic_s;
575
dep->de_nic2userf= dp_nic2user;
576
// dep->de_nic2userf_s= dp_nic2user_s;
577
dep->de_getblockf= dp_getblock;
579
else if (dep->de_16bit)
581
dep->de_user2nicf= dp_pio16_user2nic;
582
// dep->de_user2nicf_s= dp_pio16_user2nic_s;
583
dep->de_nic2userf= dp_pio16_nic2user;
584
// dep->de_nic2userf_s= dp_pio16_nic2user_s;
585
dep->de_getblockf= dp_pio16_getblock;
589
dep->de_user2nicf= dp_pio8_user2nic;
590
// dep->de_user2nicf_s= dp_pio8_user2nic_s;
591
dep->de_nic2userf= dp_pio8_nic2user;
592
// dep->de_nic2userf_s= dp_pio8_nic2user_s;
593
dep->de_getblockf= dp_pio8_getblock;
596
/* Set the interrupt handler and policy. Do not automatically
597
* reenable interrupts. Return the IRQ line number on interrupts.
599
/* dep->de_hook = dep->de_irq;
600
r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
602
panic("DP8390", "sys_irqsetpolicy failed", r);
604
r= sys_irqenable(&dep->de_hook);
607
panic("DP8390", "unable enable interrupts", r);
612
/*===========================================================================*
614
*===========================================================================*/
615
static void dp_reinit(dep)
620
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
623
if (dep->de_flags & DEF_PROMISC)
624
dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
625
if (dep->de_flags & DEF_BROAD)
626
dp_rcr_reg |= RCR_AB;
627
if (dep->de_flags & DEF_MULTI)
628
dp_rcr_reg |= RCR_AM;
629
outb_reg0(dep, DP_RCR, dp_rcr_reg);
632
/*===========================================================================*
634
*===========================================================================*/
635
static void dp_reset(dep)
641
outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
642
outb_reg0(dep, DP_RBCR0, 0);
643
outb_reg0(dep, DP_RBCR1, 0);
644
for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
646
outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
647
outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
648
outb_reg0(dep, DP_TCR, TCR_NORMAL);
650
/* Acknowledge the ISR_RDC (remote dma) interrupt. */
651
for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
653
outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
655
/* Reset the transmit ring. If we were transmitting a packet, we
656
* pretend that the packet is processed. Higher layers will
657
* retransmit if the packet wasn't actually sent.
659
dep->de_sendq_head= dep->de_sendq_tail= 0;
660
for (i= 0; i<dep->de_sendq_nr; i++)
661
dep->de_sendq[i].sq_filled= 0;
663
dep->de_flags &= ~DEF_STOPPED;
666
/*===========================================================================*
668
*===========================================================================*/
669
void dp_check_ints(dep, isr)
674
int size, sendq_tail;
676
if (!(dep->de_flags & DEF_ENABLED))
677
panic("", "dp8390: got premature interrupt", NO_NUM);
681
// isr = inb_reg0(dep, DP_ISR);
684
outb_reg0(dep, DP_ISR, isr);
685
if (isr & (ISR_PTX|ISR_TXE))
690
{ printf("%s: got send Error\n", dep->de_name); }
692
dep->de_stat.ets_sendErr++;
696
tsr = inb_reg0(dep, DP_TSR);
698
if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
699
#if 0 /* Reserved in later manuals, should be ignored */
700
if (!(tsr & TSR_DFR))
702
/* In most (all?) implementations of
703
* the dp8390, this bit is set
704
* when the packet is not deferred
706
dep->de_stat.ets_transDef++;
709
if (tsr & TSR_COL) dep->de_stat.ets_collision++;
710
if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
711
if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
713
&& ++dep->de_stat.ets_fifoUnder <= 10)
715
printf("%s: fifo underrun\n",
719
&& ++dep->de_stat.ets_CDheartbeat <= 10)
721
printf("%s: CD heart beat failure\n",
724
if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
726
sendq_tail= dep->de_sendq_tail;
728
if (!(dep->de_sendq[sendq_tail].sq_filled))
733
/* Or hardware bug? */
735
"%s: transmit interrupt, but not sending\n",
739
dep->de_sendq[sendq_tail].sq_filled= 0;
740
if (++sendq_tail == dep->de_sendq_nr)
742
dep->de_sendq_tail= sendq_tail;
743
if (dep->de_sendq[sendq_tail].sq_filled)
745
size= dep->de_sendq[sendq_tail].sq_size;
746
outb_reg0(dep, DP_TPSR,
747
dep->de_sendq[sendq_tail].sq_sendpage);
748
outb_reg0(dep, DP_TBCR1, size >> 8);
749
outb_reg0(dep, DP_TBCR0, size & 0xff);
750
outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
752
// if (dep->de_flags & DEF_SEND_AVAIL)
758
/* Only call dp_recv if there is a read request */
759
// if (dep->de_flags) & DEF_READING)
763
if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
766
dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
767
dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
768
dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
772
dep->de_stat.ets_OVW++;
775
"%s: got overwrite warning\n", dep->de_name); }
777
/* if (dep->de_flags & DEF_READING)
780
"dp_check_ints: strange: overwrite warning and pending read request\n");
790
/* this means we got an interrupt but the ethernet
791
* chip is shutdown. We set the flag DEF_STOPPED,
792
* and continue processing arrived packets. When the
793
* receive buffer is empty, we reset the dp8390.
797
"%s: NIC stopped\n", dep->de_name); }
799
dep->de_flags |= DEF_STOPPED;
802
isr = inb_reg0(dep, DP_ISR);
804
// if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
805
// (DEF_READING|DEF_STOPPED))
806
if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED )
808
/* The chip is stopped, and all arrived packets are
815
/*===========================================================================*
817
*===========================================================================*/
818
static void dp_recv(dep)
822
//unsigned pageno, curr, next;
823
int pageno, curr, next;
825
int packet_processed, r;
828
packet_processed = FALSE;
829
pageno = inb_reg0(dep, DP_BNRY) + 1;
830
if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
834
outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
835
curr = inb_reg1(dep, DP_CURR);
836
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
838
if (curr == pageno) break;
840
(dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
842
(dep->de_getblockf)(dep, pageno, sizeof(header) +
843
2*sizeof(ether_addr_t), sizeof(eth_type), ð_type);
845
length = (header.dr_rbcl | (header.dr_rbch << 8)) -
847
next = header.dr_next;
848
if (length < ETH_MIN_PACK_SIZE ||
849
length > ETH_MAX_PACK_SIZE_TAGGED)
851
printf("%s: packet with strange length arrived: %d\n",
852
dep->de_name, (int) length);
855
else if (next < dep->de_startpage || next >= dep->de_stoppage)
857
printf("%s: strange next page\n", dep->de_name);
860
/* else if (eth_type == eth_ign_proto)
862
*/ /* Hack: ignore packets of a given protocol, useful
863
* if you share a net with 80 computers sending
864
* Amoeba FLIP broadcasts. (Protocol 0x8146.)
866
/* static int first= 1;
870
printf("%s: dropping proto 0x%04x packets\n",
872
ntohs(eth_ign_proto));
874
dep->de_stat.ets_packetR++;
876
*/ else if (header.dr_status & RSR_FO)
878
/* This is very serious, so we issue a warning and
879
* reset the buffers */
880
printf("%s: fifo overrun, resetting receive buffer\n",
882
dep->de_stat.ets_fifoOver++;
885
else if ((header.dr_status & RSR_PRX) &&
886
(dep->de_flags & DEF_ENABLED))
888
// if (dep->de_safecopy_read)
889
// r = dp_pkt2user_s(dep, pageno, length);
891
r = dp_pkt2user(dep, pageno, length);
895
packet_processed = TRUE;
896
dep->de_stat.ets_packetR++;
898
if (next == dep->de_startpage)
899
outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
901
outb_reg0(dep, DP_BNRY, next - 1);
905
while (!packet_processed);
908
/*===========================================================================*
910
*===========================================================================*/
911
static void dp_send(dep)
916
// if (!(dep->de_flags & DEF_SEND_AVAIL))
919
if( dep->packet_queue ){
920
packet = dep->packet_queue;
921
dep->packet_queue = pq_detach( packet );
922
do_pwrite( dep, packet, TRUE );
923
netif_pq_release( packet_get_id( packet ));
924
-- dep->packet_count;
926
// if( ! dep->packet_queue ){
927
// dep->de_flags &= ~DEF_SEND_AVAIL;
929
/* switch(dep->de_sendmsg.m_type)
931
case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
932
case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
933
case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break;
935
panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
941
/*===========================================================================*
943
*===========================================================================*/
944
static void dp_getblock(dep, page, offset, size, dst)
953
offset = page * DP_PAGESIZE + offset;
955
memcpy(dst, dep->de_locmem + offset, size);
958
/*===========================================================================*
960
*===========================================================================*/
961
static void dp_pio8_getblock(dep, page, offset, size, dst)
968
offset = page * DP_PAGESIZE + offset;
969
outb_reg0(dep, DP_RBCR0, size & 0xFF);
970
outb_reg0(dep, DP_RBCR1, size >> 8);
971
outb_reg0(dep, DP_RSAR0, offset & 0xFF);
972
outb_reg0(dep, DP_RSAR1, offset >> 8);
973
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
975
insb(dep->de_data_port, dst, size);
978
/*===========================================================================*
979
* dp_pio16_getblock *
980
*===========================================================================*/
981
static void dp_pio16_getblock(dep, page, offset, size, dst)
988
offset = page * DP_PAGESIZE + offset;
989
outb_reg0(dep, DP_RBCR0, size & 0xFF);
990
outb_reg0(dep, DP_RBCR1, size >> 8);
991
outb_reg0(dep, DP_RSAR0, offset & 0xFF);
992
outb_reg0(dep, DP_RSAR1, offset >> 8);
993
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
995
assert (!(size & 1));
996
insw(dep->de_data_port, dst, size);
999
/*===========================================================================*
1001
*===========================================================================*/
1002
static int dp_pkt2user(dep, page, length)
1009
// if (!(dep->de_flags & DEF_READING))
1012
packet = netif_packet_get_1( length );
1013
if( ! packet ) return ENOMEM;
1014
dep->de_read_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_suffix( packet, length );
1015
dep->de_read_iovec.iod_iovec[0].iov_size = length;
1016
dep->de_read_iovec.iod_iovec_s = 1;
1017
dep->de_read_iovec.iod_iovec_addr = NULL;
1019
last = page + (length - 1) / DP_PAGESIZE;
1020
if (last >= dep->de_stoppage)
1022
count = (dep->de_stoppage - page) * DP_PAGESIZE -
1023
sizeof(dp_rcvhdr_t);
1025
/* Save read_iovec since we need it twice. */
1026
dep->de_tmp_iovec = dep->de_read_iovec;
1027
(dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1028
sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
1029
(dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
1030
&dep->de_read_iovec, count, length - count);
1034
(dep->de_nic2userf)(dep, page * DP_PAGESIZE +
1035
sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
1038
dep->de_read_s = length;
1039
dep->de_flags |= DEF_PACK_RECV;
1040
// dep->de_flags &= ~DEF_READING;
1042
if( dep->received_count >= MAX_PACKETS ){
1043
netif_pq_release( packet_get_id( packet ));
1046
if( pq_add( & dep->received_queue, packet, 0, 0 ) == EOK ){
1047
++ dep->received_count;
1049
netif_pq_release( packet_get_id( packet ));
1055
/*===========================================================================*
1057
*===========================================================================*/
1058
static void dp_user2nic(dep, iovp, offset, nic_addr, count)
1065
vir_bytes vir_hw;//, vir_user;
1070
vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1077
dp_next_iovec(iovp);
1081
assert(i < iovp->iod_iovec_s);
1082
if (offset >= iovp->iod_iovec[i].iov_size)
1084
offset -= iovp->iod_iovec[i].iov_size;
1088
bytes = iovp->iod_iovec[i].iov_size - offset;
1092
r= sys_vircopy(iovp->iod_proc_nr, D,
1093
iovp->iod_iovec[i].iov_addr + offset,
1094
SELF, D, vir_hw, bytes);
1096
panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
1105
/*===========================================================================*
1106
* dp_pio8_user2nic *
1107
*===========================================================================*/
1108
static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
1115
// phys_bytes phys_user;
1119
outb_reg0(dep, DP_ISR, ISR_RDC);
1121
outb_reg0(dep, DP_RBCR0, count & 0xFF);
1122
outb_reg0(dep, DP_RBCR1, count >> 8);
1123
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1124
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1125
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1132
dp_next_iovec(iovp);
1136
assert(i < iovp->iod_iovec_s);
1137
if (offset >= iovp->iod_iovec[i].iov_size)
1139
offset -= iovp->iod_iovec[i].iov_size;
1143
bytes = iovp->iod_iovec[i].iov_size - offset;
1147
do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
1148
iovp->iod_iovec[i].iov_addr + offset, bytes);
1154
for (i= 0; i<100; i++)
1156
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1161
panic("", "dp8390: remote dma failed to complete", NO_NUM);
1165
/*===========================================================================*
1166
* dp_pio16_user2nic *
1167
*===========================================================================*/
1168
static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
1177
int i, r, user_proc;
1179
//u8_t two_bytes[2];
1183
ecount= (count+1) & ~1;
1186
outb_reg0(dep, DP_ISR, ISR_RDC);
1187
outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1188
outb_reg0(dep, DP_RBCR1, ecount >> 8);
1189
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1190
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1191
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
1198
dp_next_iovec(iovp);
1202
assert(i < iovp->iod_iovec_s);
1203
if (offset >= iovp->iod_iovec[i].iov_size)
1205
offset -= iovp->iod_iovec[i].iov_size;
1209
bytes = iovp->iod_iovec[i].iov_size - offset;
1213
user_proc= iovp->iod_proc_nr;
1214
vir_user= iovp->iod_iovec[i].iov_addr + offset;
1217
r= sys_vircopy(user_proc, D, vir_user,
1218
// SELF, D, (vir_bytes)&two_bytes[1], 1);
1219
SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1);
1223
"dp_pio16_user2nic: sys_vircopy failed",
1226
//outw(dep->de_data_port, *(u16_t *)two_bytes);
1227
outw(dep->de_data_port, two_bytes);
1239
do_vir_outsw(dep->de_data_port, user_proc, vir_user,
1249
r= sys_vircopy(user_proc, D, vir_user,
1250
// SELF, D, (vir_bytes)&two_bytes[0], 1);
1251
SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1);
1255
"dp_pio16_user2nic: sys_vircopy failed",
1268
//outw(dep->de_data_port, *(u16_t *)two_bytes);
1269
outw(dep->de_data_port, two_bytes);
1271
for (i= 0; i<100; i++)
1273
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
1278
panic("", "dp8390: remote dma failed to complete", NO_NUM);
1282
/*===========================================================================*
1284
*===========================================================================*/
1285
static void dp_nic2user(dep, nic_addr, iovp, offset, count)
1292
vir_bytes vir_hw;//, vir_user;
1296
vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
1303
dp_next_iovec(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
r= sys_vircopy(SELF, D, vir_hw,
1319
iovp->iod_proc_nr, D,
1320
iovp->iod_iovec[i].iov_addr + offset, bytes);
1322
panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
1331
/*===========================================================================*
1332
* dp_pio8_nic2user *
1333
*===========================================================================*/
1334
static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
1341
// phys_bytes phys_user;
1345
outb_reg0(dep, DP_RBCR0, count & 0xFF);
1346
outb_reg0(dep, DP_RBCR1, count >> 8);
1347
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1348
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1349
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1356
dp_next_iovec(iovp);
1360
assert(i < iovp->iod_iovec_s);
1361
if (offset >= iovp->iod_iovec[i].iov_size)
1363
offset -= iovp->iod_iovec[i].iov_size;
1367
bytes = iovp->iod_iovec[i].iov_size - offset;
1371
do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
1372
iovp->iod_iovec[i].iov_addr + offset, bytes);
1379
/*===========================================================================*
1380
* dp_pio16_nic2user *
1381
*===========================================================================*/
1382
static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
1391
int i, r, user_proc;
1393
//u8_t two_bytes[2];
1397
ecount= (count+1) & ~1;
1400
outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
1401
outb_reg0(dep, DP_RBCR1, ecount >> 8);
1402
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
1403
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1404
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1411
dp_next_iovec(iovp);
1415
assert(i < iovp->iod_iovec_s);
1416
if (offset >= iovp->iod_iovec[i].iov_size)
1418
offset -= iovp->iod_iovec[i].iov_size;
1422
bytes = iovp->iod_iovec[i].iov_size - offset;
1426
user_proc= iovp->iod_proc_nr;
1427
vir_user= iovp->iod_iovec[i].iov_addr + offset;
1430
//r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
1431
r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]),
1432
user_proc, D, vir_user, 1);
1436
"dp_pio16_nic2user: sys_vircopy failed",
1450
do_vir_insw(dep->de_data_port, user_proc, vir_user,
1460
//*(u16_t *)two_bytes= inw(dep->de_data_port);
1461
two_bytes= inw(dep->de_data_port);
1462
//r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
1463
r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]),
1464
user_proc, D, vir_user, 1);
1468
"dp_pio16_nic2user: sys_vircopy failed",
1481
/*===========================================================================*
1483
*===========================================================================*/
1484
static void dp_next_iovec(iovp)
1487
assert(iovp->iod_iovec_s > IOVEC_NR);
1489
iovp->iod_iovec_s -= IOVEC_NR;
1491
iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
1493
get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
1494
(iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1495
sizeof(iovec_t), iovp->iod_iovec);
1498
/*===========================================================================*
1500
*===========================================================================*/
1501
static void conf_hw(dep)
1504
// static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */ };
1509
// dep->de_mode= DEM_DISABLED; /* Superfluous */
1510
// ifnr= dep-de_table;
1512
// dcp= &dp_conf[ifnr];
1513
// update_conf(dep, dcp);
1514
// if (dep->de_mode != DEM_ENABLED)
1516
if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
1518
printf("%s: No ethernet card found at 0x%x\n",
1519
dep->de_name, dep->de_base_port);
1520
dep->de_mode= DEM_DISABLED;
1524
/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1526
dep->de_mode = DEM_ENABLED;
1528
dep->de_flags = DEF_EMPTY;
1529
// dep->de_stat = empty_stat;
1532
/*===========================================================================*
1534
*===========================================================================*/
1535
static void map_hw_buffer(dep)
1540
// char *buf, *abuf;
1542
if (dep->de_prog_IO)
1547
"map_hw_buffer: programmed I/O, no need to map buffer\n");
1550
dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
1553
printf( "map_hw_buffer: no buffer!\n" );
1556
// size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
1559
// buf= malloc(size);
1561
// panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
1562
// o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
1564
// printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
1566
// r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
1567
// dep->de_ramsize, (phys_bytes)dep->de_linmem);
1569
// panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
1570
// dep->de_locmem = abuf;
1573
/*===========================================================================*
1575
*===========================================================================*/
1576
static void reply(dep, err, may_block)
1586
if (dep->de_flags & DEF_PACK_SEND)
1587
status |= DL_PACK_SEND;
1588
if (dep->de_flags & DEF_PACK_RECV)
1589
status |= DL_PACK_RECV;
1591
reply.m_type = DL_TASK_REPLY;
1592
reply.DL_PORT = dep - de_table;
1593
reply.DL_PROC = dep->de_client;
1594
reply.DL_STAT = status | ((u32_t) err << 16);
1595
reply.DL_COUNT = dep->de_read_s;
1596
reply.DL_CLCK = 0; *//* Don't know */
1597
/* r= send(dep->de_client, &reply);
1599
if (r == ELOCKED && may_block)
1602
printf("send locked\n");
1608
panic("", "dp8390: send failed:", r);
1610
*/ dep->de_read_s = 0;
1611
// dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1614
/*===========================================================================*
1616
*===========================================================================*/
1617
static void get_userdata(user_proc, user_addr, count, loc_addr)
1619
vir_bytes user_addr;
1625
r= sys_vircopy(user_proc, D, user_addr,
1626
SELF, D, (vir_bytes)loc_addr, count);
1628
panic("DP8390", "get_userdata: sys_vircopy failed", r);
1631
static void insb(port_t port, void *buf, size_t size)
1635
for( i = 0; i < size; ++ i ){
1636
*(( uint8_t * ) buf + i ) = inb( port );
1640
static void insw(port_t port, void *buf, size_t size)
1644
for( i = 0; i * 2 < size; ++ i ){
1645
*(( uint16_t * ) buf + i ) = inw( port );
1649
static void outsb(port_t port, void *buf, size_t size)
1653
for( i = 0; i < size; ++ i ){
1654
outb( port, *(( uint8_t * ) buf + i ));
1658
static void outsw(port_t port, void *buf, size_t size)
1662
for( i = 0; i * 2 < size; ++ i ){
1663
outw( port, *(( uint16_t * ) buf + i ));
1668
* $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $