~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to uspace/srv/net/netif/dp8390/dp8390.c

  • Committer: Pavel Rimsky
  • Date: 2010-02-20 20:54:53 UTC
  • mfrom: (292 head)
  • mto: This revision was merged to the branch mainline in revision 296.
  • Revision ID: pavel@pavel-laptop-20100220205453-70sim280j709dgp3
Synchronize with head.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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:
 
3
 *
 
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
 
8
 *
 
9
 *
 
10
 * Disclaimer
 
11
 *
 
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.
 
22
 *
 
23
 * Changes:
 
24
 *  2009 ported to HelenOS, Lukas Mejdrech
 
25
 */
 
26
 
 
27
/** @addtogroup dp8390
 
28
 *  @{
 
29
 */
 
30
 
 
31
/** @file
 
32
 *  DP8390 network interface core implementation.
 
33
 */
 
34
 
 
35
#include <assert.h>
 
36
#include <errno.h>
 
37
 
 
38
#include "../../include/byteorder.h"
 
39
 
 
40
#include "../../structures/packet/packet.h"
 
41
#include "../../structures/packet/packet_client.h"
 
42
 
 
43
#include "../netif.h"
 
44
 
 
45
#include "dp8390_drv.h"
 
46
#include "dp8390_port.h"
 
47
 
 
48
/*
 
49
 * dp8390.c
 
50
 *
 
51
 * Created:     before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
 
52
 *
 
53
 * Modified Mar 10 1994 by Philip Homburg
 
54
 *      Become a generic dp8390 driver.
 
55
 *
 
56
 * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
 
57
 *      Added support for 3c503 boards.
 
58
 */
 
59
 
 
60
#include "local.h"
 
61
#include "dp8390.h"
 
62
 
 
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.
 
67
 *  @returns EINVAL 
 
68
 */
 
69
int     queue_packet( dpeth_t * dep, packet_t packet );
 
70
 
 
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.
 
75
 */
 
76
static void outsb( port_t port, void * buf, size_t size );
 
77
 
 
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.
 
82
 */
 
83
static void outsw( port_t port, void * buf, size_t size );
 
84
 
 
85
//static u16_t eth_ign_proto;
 
86
//static char *progname;
 
87
 
 
88
/* Configuration */
 
89
/*typedef struct dp_conf
 
90
{
 
91
        port_t dpc_port;
 
92
        int dpc_irq;
 
93
        phys_bytes dpc_mem;
 
94
        char *dpc_envvar;
 
95
} dp_conf_t;
 
96
*/
 
97
//dp_conf_t dp_conf[]=  /* Card addresses */
 
98
//{
 
99
        /* I/O port, IRQ,  Buffer address,  Env. var. */
 
100
/*      {  0x280,     3,    0xD0000,        "DPETH0"    },
 
101
        {  0x300,     5,    0xC8000,        "DPETH1"    },
 
102
        {  0x380,    10,    0xD8000,        "DPETH2"    },
 
103
};
 
104
*/
 
105
/* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
 
106
 * the error: "array size is negative".
 
107
 */
 
108
//extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
 
109
 
 
110
/* Card inits configured out? */
 
111
#if !ENABLE_WDETH
 
112
#define wdeth_probe(dep)        (0)
 
113
#endif
 
114
#if !ENABLE_NE2000
 
115
#define ne_probe(dep)           (0)
 
116
#endif
 
117
#if !ENABLE_3C503
 
118
#define el2_probe(dep)          (0)
 
119
#endif
 
120
 
 
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
 
123
 * genuine dp8390s
 
124
 */
 
125
#define CR_EXTRA        CR_STA
 
126
 
 
127
//#if ENABLE_PCI
 
128
//_PROTOTYPE( static void pci_conf, (void)                              );
 
129
//#endif
 
130
//_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
 
131
//                                                      int vectored)   );
 
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,
 
156
                                                        int length)     );
 
157
//_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
 
158
//                                                      int length)     );
 
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)     );
 
215
 
 
216
int do_probe( dpeth_t * dep ){
 
217
        /* This is the default, try to (re)locate the device. */
 
218
        conf_hw(dep);
 
219
        if (dep->de_mode == DEM_DISABLED)
 
220
        {
 
221
                /* Probe failed, or the device is configured off. */
 
222
                return EXDEV;//ENXIO;
 
223
        }
 
224
        if (dep->de_mode == DEM_ENABLED)
 
225
                dp_init(dep);
 
226
        return EOK;
 
227
}
 
228
 
 
229
/*===========================================================================*
 
230
 *                              dp8390_dump                                  *
 
231
 *===========================================================================*/
 
232
void dp8390_dump( dpeth_t * dep )
 
233
{
 
234
//      dpeth_t *dep;
 
235
        int /*i,*/ isr;
 
236
 
 
237
//      printf("\n");
 
238
//      for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
 
239
//      {
 
240
#if XXX
 
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);
 
245
#endif
 
246
 
 
247
                if (dep->de_mode != DEM_ENABLED)
 
248
//                      continue;
 
249
                        return;
 
250
 
 
251
//              printf("dp8390 statistics of port %d:\n", i);
 
252
 
 
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);
 
256
 
 
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);
 
260
 
 
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);
 
264
 
 
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);
 
268
 
 
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);
 
272
 
 
273
                printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);
 
274
 
 
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);
 
278
//      }
 
279
}
 
280
 
 
281
/*===========================================================================*
 
282
 *                              do_init                                      *
 
283
 *===========================================================================*/
 
284
int do_init( dpeth_t * dep, int mode ){
 
285
        if (dep->de_mode == DEM_DISABLED)
 
286
        {
 
287
                // might call do_probe()
 
288
                return EXDEV;
 
289
        }
 
290
 
 
291
        if (dep->de_mode == DEM_SINK)
 
292
        {
 
293
//              strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
 
294
//              dep->de_address.ea_addr[5] = port;
 
295
//              dp_confaddr(dep);
 
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);
 
301
//              return;
 
302
                return EOK;
 
303
        }
 
304
        assert(dep->de_mode == DEM_ENABLED);
 
305
        assert(dep->de_flags & DEF_ENABLED);
 
306
 
 
307
        dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
 
308
 
 
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;
 
315
 
 
316
//      dep->de_client = mp->m_source;
 
317
        dp_reinit(dep);
 
318
 
 
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;
 
323
 
 
324
//      mess_reply(mp, &reply_mess);
 
325
        return EOK;
 
326
}
 
327
 
 
328
/*===========================================================================*
 
329
 *                              do_stop                                      *
 
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 );
 
335
 
 
336
                dep->de_flags = DEF_EMPTY;
 
337
        }
 
338
}
 
339
 
 
340
int queue_packet( dpeth_t * dep, packet_t packet ){
 
341
        packet_t        tmp;
 
342
 
 
343
        if( dep->packet_count >= MAX_PACKETS ){
 
344
                netif_pq_release( packet_get_id( packet ));
 
345
                return ELIMIT;
 
346
        }
 
347
 
 
348
        tmp = dep->packet_queue;
 
349
        while( pq_next( tmp )){
 
350
                tmp = pq_next( tmp );
 
351
        }
 
352
        if( pq_add( & tmp, packet, 0, 0 ) != EOK ){
 
353
                return EINVAL;
 
354
        }
 
355
        if( ! dep->packet_count ){
 
356
                dep->packet_queue = packet;
 
357
        }
 
358
        ++ dep->packet_count;
 
359
        return EBUSY;
 
360
}
 
361
 
 
362
/*===========================================================================*
 
363
 *                      based on        do_vwrite                                    *
 
364
 *===========================================================================*/
 
365
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int )
 
366
{
 
367
//      int port, count, size;
 
368
        int size;
 
369
        int sendq_head;
 
370
/*      dpeth_t *dep;
 
371
 
 
372
        port = mp->DL_PORT;
 
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;
 
378
*/
 
379
        if (dep->de_mode == DEM_SINK)
 
380
        {
 
381
                assert(!from_int);
 
382
//              dep->de_flags |= DEF_PACK_SEND;
 
383
                reply(dep, OK, FALSE);
 
384
//              return;
 
385
                return EOK;
 
386
        }
 
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 );
 
393
        }
 
394
 
 
395
        sendq_head= dep->de_sendq_head;
 
396
//      if (dep->de_sendq[sendq_head].sq_filled)
 
397
//      {
 
398
//              if (from_int)
 
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);
 
403
//              return;
 
404
//              return queue_packet( dep, packet );
 
405
//      }
 
406
//      assert(!(dep->de_flags & DEF_PACK_SEND));
 
407
 
 
408
/*      if (vectored)
 
409
        {
 
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;
 
416
 
 
417
                dep->de_tmp_iovec = dep->de_write_iovec;
 
418
                size = calc_iovec_size(&dep->de_tmp_iovec);
 
419
        }
 
420
        else
 
421
        {  
 
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 =
 
425
                        mp->DL_COUNT;
 
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;
 
429
                size= mp->DL_COUNT;
 
430
        }
 
431
*/
 
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;
 
437
 
 
438
        if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
 
439
        {
 
440
                panic("", "dp8390: invalid packet size", size);
 
441
                return EINVAL;
 
442
        }
 
443
        (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
 
444
                dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
 
445
                size);
 
446
        dep->de_sendq[sendq_head].sq_filled= TRUE;
 
447
        if (dep->de_sendq_tail == sendq_head)
 
448
        {
 
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.. */
 
453
        }
 
454
        else
 
455
                dep->de_sendq[sendq_head].sq_size= size;
 
456
        
 
457
        if (++sendq_head == dep->de_sendq_nr)
 
458
                sendq_head= 0;
 
459
        assert(sendq_head < SENDQ_NR);
 
460
        dep->de_sendq_head= sendq_head;
 
461
 
 
462
//      dep->de_flags |= DEF_PACK_SEND;
 
463
 
 
464
        /* If the interrupt handler called, don't send a reply. The reply
 
465
         * will be sent after all interrupts are handled. 
 
466
         */
 
467
        if (from_int)
 
468
                return EOK;
 
469
        reply(dep, OK, FALSE);
 
470
 
 
471
        assert(dep->de_mode == DEM_ENABLED);
 
472
        assert(dep->de_flags & DEF_ENABLED);
 
473
        return EOK;
 
474
}
 
475
 
 
476
/*===========================================================================*
 
477
 *                              dp_init                                      *
 
478
 *===========================================================================*/
 
479
void dp_init(dep)
 
480
dpeth_t *dep;
 
481
{
 
482
        int dp_rcr_reg;
 
483
        int i;//, r;
 
484
 
 
485
        /* General initialization */
 
486
        dep->de_flags = DEF_EMPTY;
 
487
        (*dep->de_initf)(dep);
 
488
 
 
489
//      dp_confaddr(dep);
 
490
 
 
491
        if (debug)
 
492
        {
 
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],
 
496
                                                        i < 5 ? ':' : '\n');
 
497
        }
 
498
 
 
499
        /* Map buffer */
 
500
        map_hw_buffer(dep);
 
501
 
 
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).
 
505
         */
 
506
        /* Step 1: */
 
507
        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
 
508
        /* Step 2: */
 
509
        if (dep->de_16bit)
 
510
                outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
 
511
        else
 
512
                outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
 
513
        /* Step 3: */
 
514
        outb_reg0(dep, DP_RBCR0, 0);
 
515
        outb_reg0(dep, DP_RBCR1, 0);
 
516
        /* Step 4: */
 
517
        dp_rcr_reg = 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);
 
525
        /* Step 5: */
 
526
        outb_reg0(dep, DP_TCR, TCR_INTERNAL);
 
527
        /* Step 6: */
 
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);
 
531
        /* Step 7: */
 
532
        outb_reg0(dep, DP_ISR, 0xFF);
 
533
        /* Step 8: */
 
534
        outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
 
535
                IMR_OVWE | IMR_CNTE);
 
536
        /* Step 9: */
 
537
        outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
 
538
 
 
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]);
 
545
 
 
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);
 
554
 
 
555
        outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
 
556
        /* Step 10: */
 
557
        outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
 
558
        /* Step 11: */
 
559
        outb_reg0(dep, DP_TCR, TCR_NORMAL);
 
560
 
 
561
        inb_reg0(dep, DP_CNTR0);                /* reset counters by reading */
 
562
        inb_reg0(dep, DP_CNTR1);
 
563
        inb_reg0(dep, DP_CNTR2);
 
564
 
 
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)
 
572
        {
 
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;
 
578
        }
 
579
        else if (dep->de_16bit)
 
580
        {
 
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;
 
586
        }
 
587
        else
 
588
        {
 
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;
 
594
        }
 
595
 
 
596
        /* Set the interrupt handler and policy. Do not automatically 
 
597
         * reenable interrupts. Return the IRQ line number on interrupts.
 
598
         */
 
599
/*      dep->de_hook = dep->de_irq;
 
600
        r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
 
601
        if (r != OK)
 
602
                panic("DP8390", "sys_irqsetpolicy failed", r);
 
603
 
 
604
        r= sys_irqenable(&dep->de_hook);
 
605
        if (r != OK)
 
606
        {
 
607
                panic("DP8390", "unable enable interrupts", r);
 
608
        }
 
609
*/
 
610
}
 
611
 
 
612
/*===========================================================================*
 
613
 *                              dp_reinit                                    *
 
614
 *===========================================================================*/
 
615
static void dp_reinit(dep)
 
616
dpeth_t *dep;
 
617
{
 
618
        int dp_rcr_reg;
 
619
 
 
620
        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
 
621
 
 
622
        dp_rcr_reg = 0;
 
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);
 
630
}
 
631
 
 
632
/*===========================================================================*
 
633
 *                              dp_reset                                     *
 
634
 *===========================================================================*/
 
635
static void dp_reset(dep)
 
636
dpeth_t *dep;
 
637
{
 
638
        int i;
 
639
 
 
640
        /* Stop chip */
 
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++)
 
645
                ; /* Do nothing */
 
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);
 
649
 
 
650
        /* Acknowledge the ISR_RDC (remote dma) interrupt. */
 
651
        for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
 
652
                ; /* Do nothing */
 
653
        outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
 
654
 
 
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.
 
658
         */
 
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;
 
662
        dp_send(dep);
 
663
        dep->de_flags &= ~DEF_STOPPED;
 
664
}
 
665
 
 
666
/*===========================================================================*
 
667
 *                              dp_check_ints                                *
 
668
 *===========================================================================*/
 
669
void dp_check_ints(dep, isr)
 
670
dpeth_t *dep;
 
671
int isr;
 
672
{
 
673
        int /*isr,*/ tsr;
 
674
        int size, sendq_tail;
 
675
 
 
676
        if (!(dep->de_flags & DEF_ENABLED))
 
677
                panic("", "dp8390: got premature interrupt", NO_NUM);
 
678
 
 
679
        for(;;)
 
680
        {
 
681
//              isr = inb_reg0(dep, DP_ISR);
 
682
                if (!isr)
 
683
                        break;
 
684
                outb_reg0(dep, DP_ISR, isr);
 
685
                if (isr & (ISR_PTX|ISR_TXE))
 
686
                {
 
687
                        if (isr & ISR_TXE)
 
688
                        {
 
689
#if DEBUG
 
690
 { printf("%s: got send Error\n", dep->de_name); }
 
691
#endif
 
692
                                dep->de_stat.ets_sendErr++;
 
693
                        }
 
694
                        else
 
695
                        {
 
696
                                tsr = inb_reg0(dep, DP_TSR);
 
697
 
 
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))
 
701
                                {
 
702
                                        /* In most (all?) implementations of
 
703
                                         * the dp8390, this bit is set
 
704
                                         * when the packet is not deferred
 
705
                                         */
 
706
                                        dep->de_stat.ets_transDef++;
 
707
                                }
 
708
#endif
 
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++;
 
712
                                if (tsr & TSR_FU
 
713
                                        && ++dep->de_stat.ets_fifoUnder <= 10)
 
714
                                {
 
715
                                        printf("%s: fifo underrun\n",
 
716
                                                dep->de_name);
 
717
                                }
 
718
                                if (tsr & TSR_CDH
 
719
                                        && ++dep->de_stat.ets_CDheartbeat <= 10)
 
720
                                {
 
721
                                        printf("%s: CD heart beat failure\n",
 
722
                                                dep->de_name);
 
723
                                }
 
724
                                if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
 
725
                        }
 
726
                        sendq_tail= dep->de_sendq_tail;
 
727
 
 
728
                        if (!(dep->de_sendq[sendq_tail].sq_filled))
 
729
                        {
 
730
                                /* Software bug? */
 
731
                                assert(!debug);
 
732
 
 
733
                                /* Or hardware bug? */
 
734
                                printf(
 
735
                                "%s: transmit interrupt, but not sending\n",
 
736
                                        dep->de_name);
 
737
                                continue;
 
738
                        }
 
739
                        dep->de_sendq[sendq_tail].sq_filled= 0;
 
740
                        if (++sendq_tail == dep->de_sendq_nr)
 
741
                                sendq_tail= 0;
 
742
                        dep->de_sendq_tail= sendq_tail;
 
743
                        if (dep->de_sendq[sendq_tail].sq_filled)
 
744
                        {
 
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);
 
751
                        }
 
752
//                      if (dep->de_flags & DEF_SEND_AVAIL)
 
753
                                dp_send(dep);
 
754
                }
 
755
 
 
756
                if (isr & ISR_PRX)
 
757
                {
 
758
                        /* Only call dp_recv if there is a read request */
 
759
//                      if (dep->de_flags) & DEF_READING)
 
760
                                dp_recv(dep);
 
761
                }
 
762
                
 
763
                if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
 
764
                if (isr & ISR_CNT)
 
765
                {
 
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);
 
769
                }
 
770
                if (isr & ISR_OVW)
 
771
                {
 
772
                        dep->de_stat.ets_OVW++;
 
773
#if 0
 
774
                        { printW(); printf(
 
775
                                "%s: got overwrite warning\n", dep->de_name); }
 
776
#endif
 
777
/*                      if (dep->de_flags & DEF_READING)
 
778
                        {
 
779
                                printf(
 
780
"dp_check_ints: strange: overwrite warning and pending read request\n");
 
781
                                dp_recv(dep);
 
782
                        }
 
783
*/              }
 
784
                if (isr & ISR_RDC)
 
785
                {
 
786
                        /* Nothing to do */
 
787
                }
 
788
                if (isr & ISR_RST)
 
789
                {
 
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.
 
794
                         */
 
795
#if 0
 
796
                         { printW(); printf(
 
797
                                "%s: NIC stopped\n", dep->de_name); }
 
798
#endif
 
799
                        dep->de_flags |= DEF_STOPPED;
 
800
                        break;
 
801
                }
 
802
                isr = inb_reg0(dep, DP_ISR);
 
803
        }
 
804
//      if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) == 
 
805
//                                              (DEF_READING|DEF_STOPPED))
 
806
        if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED )
 
807
        {
 
808
                /* The chip is stopped, and all arrived packets are 
 
809
                 * delivered.
 
810
                 */
 
811
                dp_reset(dep);
 
812
        }
 
813
}
 
814
 
 
815
/*===========================================================================*
 
816
 *                              dp_recv                                      *
 
817
 *===========================================================================*/
 
818
static void dp_recv(dep)
 
819
dpeth_t *dep;
 
820
{
 
821
        dp_rcvhdr_t header;
 
822
        //unsigned pageno, curr, next;
 
823
        int pageno, curr, next;
 
824
        vir_bytes length;
 
825
        int packet_processed, r;
 
826
        u16_t eth_type;
 
827
 
 
828
        packet_processed = FALSE;
 
829
        pageno = inb_reg0(dep, DP_BNRY) + 1;
 
830
        if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
 
831
 
 
832
        do
 
833
        {
 
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);
 
837
 
 
838
                if (curr == pageno) break;
 
839
 
 
840
                (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
 
841
                        &header);
 
842
                (dep->de_getblockf)(dep, pageno, sizeof(header) +
 
843
                        2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
 
844
 
 
845
                length = (header.dr_rbcl | (header.dr_rbch << 8)) -
 
846
                        sizeof(dp_rcvhdr_t);
 
847
                next = header.dr_next;
 
848
                if (length < ETH_MIN_PACK_SIZE ||
 
849
                        length > ETH_MAX_PACK_SIZE_TAGGED)
 
850
                {
 
851
                        printf("%s: packet with strange length arrived: %d\n",
 
852
                                dep->de_name, (int) length);
 
853
                        next= curr;
 
854
                }
 
855
                else if (next < dep->de_startpage || next >= dep->de_stoppage)
 
856
                {
 
857
                        printf("%s: strange next page\n", dep->de_name);
 
858
                        next= curr;
 
859
                }
 
860
/*              else if (eth_type == eth_ign_proto)
 
861
                {
 
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.)
 
865
                         */
 
866
/*                      static int first= 1;
 
867
                        if (first)
 
868
                        {
 
869
                                first= 0;
 
870
                                printf("%s: dropping proto 0x%04x packets\n",
 
871
                                        dep->de_name,
 
872
                                        ntohs(eth_ign_proto));
 
873
                        }
 
874
                        dep->de_stat.ets_packetR++;
 
875
                }
 
876
*/              else if (header.dr_status & RSR_FO)
 
877
                {
 
878
                        /* This is very serious, so we issue a warning and
 
879
                         * reset the buffers */
 
880
                        printf("%s: fifo overrun, resetting receive buffer\n",
 
881
                                dep->de_name);
 
882
                        dep->de_stat.ets_fifoOver++;
 
883
                        next = curr;
 
884
                }
 
885
                else if ((header.dr_status & RSR_PRX) &&
 
886
                                           (dep->de_flags & DEF_ENABLED))
 
887
                {
 
888
//                      if (dep->de_safecopy_read)
 
889
//                              r = dp_pkt2user_s(dep, pageno, length);
 
890
//                      else
 
891
                                r = dp_pkt2user(dep, pageno, length);
 
892
                        if (r != OK)
 
893
                                return;
 
894
 
 
895
                        packet_processed = TRUE;
 
896
                        dep->de_stat.ets_packetR++;
 
897
                }
 
898
                if (next == dep->de_startpage)
 
899
                        outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
 
900
                else
 
901
                        outb_reg0(dep, DP_BNRY, next - 1);
 
902
 
 
903
                pageno = next;
 
904
        }
 
905
        while (!packet_processed);
 
906
}
 
907
 
 
908
/*===========================================================================*
 
909
 *                              dp_send                                      *
 
910
 *===========================================================================*/
 
911
static void dp_send(dep)
 
912
dpeth_t *dep;
 
913
{
 
914
        packet_t packet;
 
915
 
 
916
//      if (!(dep->de_flags & DEF_SEND_AVAIL))
 
917
//              return;
 
918
 
 
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;
 
925
        }
 
926
//      if( ! dep->packet_queue ){
 
927
//              dep->de_flags &= ~DEF_SEND_AVAIL;
 
928
//      }
 
929
/*      switch(dep->de_sendmsg.m_type)
 
930
        {
 
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;
 
934
        default:
 
935
                panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
 
936
                break;
 
937
        }
 
938
*/
 
939
}
 
940
 
 
941
/*===========================================================================*
 
942
 *                              dp_getblock                                  *
 
943
 *===========================================================================*/
 
944
static void dp_getblock(dep, page, offset, size, dst)
 
945
dpeth_t *dep;
 
946
int page;
 
947
size_t offset;
 
948
size_t size;
 
949
void *dst;
 
950
{
 
951
//      int r;
 
952
 
 
953
        offset = page * DP_PAGESIZE + offset;
 
954
 
 
955
        memcpy(dst, dep->de_locmem + offset, size);
 
956
}
 
957
 
 
958
/*===========================================================================*
 
959
 *                              dp_pio8_getblock                             *
 
960
 *===========================================================================*/
 
961
static void dp_pio8_getblock(dep, page, offset, size, dst)
 
962
dpeth_t *dep;
 
963
int page;
 
964
size_t offset;
 
965
size_t size;
 
966
void *dst;
 
967
{
 
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);
 
974
 
 
975
        insb(dep->de_data_port, dst, size);
 
976
}
 
977
 
 
978
/*===========================================================================*
 
979
 *                              dp_pio16_getblock                            *
 
980
 *===========================================================================*/
 
981
static void dp_pio16_getblock(dep, page, offset, size, dst)
 
982
dpeth_t *dep;
 
983
int page;
 
984
size_t offset;
 
985
size_t size;
 
986
void *dst;
 
987
{
 
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);
 
994
 
 
995
        assert (!(size & 1));
 
996
        insw(dep->de_data_port, dst, size);
 
997
}
 
998
 
 
999
/*===========================================================================*
 
1000
 *                              dp_pkt2user                                  *
 
1001
 *===========================================================================*/
 
1002
static int dp_pkt2user(dep, page, length)
 
1003
dpeth_t *dep;
 
1004
int page, length;
 
1005
{
 
1006
        int last, count;
 
1007
        packet_t        packet;
 
1008
 
 
1009
//      if (!(dep->de_flags & DEF_READING))
 
1010
//              return EGENERIC;
 
1011
 
 
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;
 
1018
 
 
1019
        last = page + (length - 1) / DP_PAGESIZE;
 
1020
        if (last >= dep->de_stoppage)
 
1021
        {
 
1022
                count = (dep->de_stoppage - page) * DP_PAGESIZE -
 
1023
                        sizeof(dp_rcvhdr_t);
 
1024
 
 
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);
 
1031
        }
 
1032
        else
 
1033
        {
 
1034
                (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
 
1035
                        sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
 
1036
        }
 
1037
 
 
1038
        dep->de_read_s = length;
 
1039
        dep->de_flags |= DEF_PACK_RECV;
 
1040
//      dep->de_flags &= ~DEF_READING;
 
1041
 
 
1042
        if( dep->received_count >= MAX_PACKETS ){
 
1043
                netif_pq_release( packet_get_id( packet ));
 
1044
                return ELIMIT;
 
1045
        }else{
 
1046
                if( pq_add( & dep->received_queue, packet, 0, 0 ) == EOK ){
 
1047
                        ++ dep->received_count;
 
1048
                }else{
 
1049
                        netif_pq_release( packet_get_id( packet ));
 
1050
                }
 
1051
        }
 
1052
        return OK;
 
1053
}
 
1054
 
 
1055
/*===========================================================================*
 
1056
 *                              dp_user2nic                                  *
 
1057
 *===========================================================================*/
 
1058
static void dp_user2nic(dep, iovp, offset, nic_addr, count)
 
1059
dpeth_t *dep;
 
1060
iovec_dat_t *iovp;
 
1061
vir_bytes offset;
 
1062
int nic_addr;
 
1063
vir_bytes count;
 
1064
{
 
1065
        vir_bytes vir_hw;//, vir_user;
 
1066
        //int bytes, i, r;
 
1067
        int i, r;
 
1068
        vir_bytes bytes;
 
1069
 
 
1070
        vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
 
1071
 
 
1072
        i= 0;
 
1073
        while (count > 0)
 
1074
        {
 
1075
                if (i >= IOVEC_NR)
 
1076
                {
 
1077
                        dp_next_iovec(iovp);
 
1078
                        i= 0;
 
1079
                        continue;
 
1080
                }
 
1081
                assert(i < iovp->iod_iovec_s);
 
1082
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1083
                {
 
1084
                        offset -= iovp->iod_iovec[i].iov_size;
 
1085
                        i++;
 
1086
                        continue;
 
1087
                }
 
1088
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1089
                if (bytes > count)
 
1090
                        bytes = count;
 
1091
 
 
1092
                r= sys_vircopy(iovp->iod_proc_nr, D,
 
1093
                        iovp->iod_iovec[i].iov_addr + offset,
 
1094
                        SELF, D, vir_hw, bytes);
 
1095
                if (r != OK)
 
1096
                        panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
 
1097
 
 
1098
                count -= bytes;
 
1099
                vir_hw += bytes;
 
1100
                offset += bytes;
 
1101
        }
 
1102
        assert(count == 0);
 
1103
}
 
1104
 
 
1105
/*===========================================================================*
 
1106
 *                              dp_pio8_user2nic                             *
 
1107
 *===========================================================================*/
 
1108
static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
 
1109
dpeth_t *dep;
 
1110
iovec_dat_t *iovp;
 
1111
vir_bytes offset;
 
1112
int nic_addr;
 
1113
vir_bytes count;
 
1114
{
 
1115
//      phys_bytes phys_user;
 
1116
        int i;
 
1117
        vir_bytes bytes;
 
1118
 
 
1119
        outb_reg0(dep, DP_ISR, ISR_RDC);
 
1120
 
 
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);
 
1126
 
 
1127
        i= 0;
 
1128
        while (count > 0)
 
1129
        {
 
1130
                if (i >= IOVEC_NR)
 
1131
                {
 
1132
                        dp_next_iovec(iovp);
 
1133
                        i= 0;
 
1134
                        continue;
 
1135
                }
 
1136
                assert(i < iovp->iod_iovec_s);
 
1137
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1138
                {
 
1139
                        offset -= iovp->iod_iovec[i].iov_size;
 
1140
                        i++;
 
1141
                        continue;
 
1142
                }
 
1143
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1144
                if (bytes > count)
 
1145
                        bytes = count;
 
1146
 
 
1147
                do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
 
1148
                        iovp->iod_iovec[i].iov_addr + offset, bytes);
 
1149
                count -= bytes;
 
1150
                offset += bytes;
 
1151
        }
 
1152
        assert(count == 0);
 
1153
 
 
1154
        for (i= 0; i<100; i++)
 
1155
        {
 
1156
                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
 
1157
                        break;
 
1158
        }
 
1159
        if (i == 100)
 
1160
        {
 
1161
                panic("", "dp8390: remote dma failed to complete", NO_NUM);
 
1162
        }
 
1163
}
 
1164
 
 
1165
/*===========================================================================*
 
1166
 *                              dp_pio16_user2nic                            *
 
1167
 *===========================================================================*/
 
1168
static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
 
1169
dpeth_t *dep;
 
1170
iovec_dat_t *iovp;
 
1171
vir_bytes offset;
 
1172
int nic_addr;
 
1173
vir_bytes count;
 
1174
{
 
1175
        vir_bytes vir_user;
 
1176
        vir_bytes ecount;
 
1177
        int i, r, user_proc;
 
1178
        vir_bytes bytes;
 
1179
        //u8_t two_bytes[2];
 
1180
        u16_t two_bytes;
 
1181
        int odd_byte;
 
1182
 
 
1183
        ecount= (count+1) & ~1;
 
1184
        odd_byte= 0;
 
1185
 
 
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);
 
1192
 
 
1193
        i= 0;
 
1194
        while (count > 0)
 
1195
        {
 
1196
                if (i >= IOVEC_NR)
 
1197
                {
 
1198
                        dp_next_iovec(iovp);
 
1199
                        i= 0;
 
1200
                        continue;
 
1201
                }
 
1202
                assert(i < iovp->iod_iovec_s);
 
1203
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1204
                {
 
1205
                        offset -= iovp->iod_iovec[i].iov_size;
 
1206
                        i++;
 
1207
                        continue;
 
1208
                }
 
1209
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1210
                if (bytes > count)
 
1211
                        bytes = count;
 
1212
 
 
1213
                user_proc= iovp->iod_proc_nr;
 
1214
                vir_user= iovp->iod_iovec[i].iov_addr + offset;
 
1215
                if (odd_byte)
 
1216
                {
 
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);
 
1220
                        if (r != OK)
 
1221
                        {
 
1222
                                panic("DP8390",
 
1223
                                        "dp_pio16_user2nic: sys_vircopy failed",
 
1224
                                        r);
 
1225
                        }
 
1226
                        //outw(dep->de_data_port, *(u16_t *)two_bytes);
 
1227
                        outw(dep->de_data_port, two_bytes);
 
1228
                        count--;
 
1229
                        offset++;
 
1230
                        bytes--;
 
1231
                        vir_user++;
 
1232
                        odd_byte= 0;
 
1233
                        if (!bytes)
 
1234
                                continue;
 
1235
                }
 
1236
                ecount= bytes & ~1;
 
1237
                if (ecount != 0)
 
1238
                {
 
1239
                        do_vir_outsw(dep->de_data_port, user_proc, vir_user,
 
1240
                                ecount);
 
1241
                        count -= ecount;
 
1242
                        offset += ecount;
 
1243
                        bytes -= ecount;
 
1244
                        vir_user += ecount;
 
1245
                }
 
1246
                if (bytes)
 
1247
                {
 
1248
                        assert(bytes == 1);
 
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);
 
1252
                        if (r != OK)
 
1253
                        {
 
1254
                                panic("DP8390",
 
1255
                                        "dp_pio16_user2nic: sys_vircopy failed",
 
1256
                                        r);
 
1257
                        }
 
1258
                        count--;
 
1259
                        offset++;
 
1260
                        bytes--;
 
1261
                        vir_user++;
 
1262
                        odd_byte= 1;
 
1263
                }
 
1264
        }
 
1265
        assert(count == 0);
 
1266
 
 
1267
        if (odd_byte)
 
1268
                //outw(dep->de_data_port, *(u16_t *)two_bytes);
 
1269
                outw(dep->de_data_port, two_bytes);
 
1270
 
 
1271
        for (i= 0; i<100; i++)
 
1272
        {
 
1273
                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
 
1274
                        break;
 
1275
        }
 
1276
        if (i == 100)
 
1277
        {
 
1278
                panic("", "dp8390: remote dma failed to complete", NO_NUM);
 
1279
        }
 
1280
}
 
1281
 
 
1282
/*===========================================================================*
 
1283
 *                              dp_nic2user                                  *
 
1284
 *===========================================================================*/
 
1285
static void dp_nic2user(dep, nic_addr, iovp, offset, count)
 
1286
dpeth_t *dep;
 
1287
int nic_addr;
 
1288
iovec_dat_t *iovp;
 
1289
vir_bytes offset;
 
1290
vir_bytes count;
 
1291
{
 
1292
        vir_bytes vir_hw;//, vir_user;
 
1293
        vir_bytes bytes;
 
1294
        int i, r;
 
1295
 
 
1296
        vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
 
1297
 
 
1298
        i= 0;
 
1299
        while (count > 0)
 
1300
        {
 
1301
                if (i >= IOVEC_NR)
 
1302
                {
 
1303
                        dp_next_iovec(iovp);
 
1304
                        i= 0;
 
1305
                        continue;
 
1306
                }
 
1307
                assert(i < iovp->iod_iovec_s);
 
1308
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1309
                {
 
1310
                        offset -= iovp->iod_iovec[i].iov_size;
 
1311
                        i++;
 
1312
                        continue;
 
1313
                }
 
1314
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1315
                if (bytes > count)
 
1316
                        bytes = count;
 
1317
 
 
1318
                r= sys_vircopy(SELF, D, vir_hw,
 
1319
                        iovp->iod_proc_nr, D,
 
1320
                        iovp->iod_iovec[i].iov_addr + offset, bytes);
 
1321
                if (r != OK)
 
1322
                        panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
 
1323
 
 
1324
                count -= bytes;
 
1325
                vir_hw += bytes;
 
1326
                offset += bytes;
 
1327
        }
 
1328
        assert(count == 0);
 
1329
}
 
1330
 
 
1331
/*===========================================================================*
 
1332
 *                              dp_pio8_nic2user                             *
 
1333
 *===========================================================================*/
 
1334
static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
 
1335
dpeth_t *dep;
 
1336
int nic_addr;
 
1337
iovec_dat_t *iovp;
 
1338
vir_bytes offset;
 
1339
vir_bytes count;
 
1340
{
 
1341
//      phys_bytes phys_user;
 
1342
        int i;
 
1343
        vir_bytes bytes;
 
1344
 
 
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);
 
1350
 
 
1351
        i= 0;
 
1352
        while (count > 0)
 
1353
        {
 
1354
                if (i >= IOVEC_NR)
 
1355
                {
 
1356
                        dp_next_iovec(iovp);
 
1357
                        i= 0;
 
1358
                        continue;
 
1359
                }
 
1360
                assert(i < iovp->iod_iovec_s);
 
1361
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1362
                {
 
1363
                        offset -= iovp->iod_iovec[i].iov_size;
 
1364
                        i++;
 
1365
                        continue;
 
1366
                }
 
1367
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1368
                if (bytes > count)
 
1369
                        bytes = count;
 
1370
 
 
1371
                do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
 
1372
                        iovp->iod_iovec[i].iov_addr + offset, bytes);
 
1373
                count -= bytes;
 
1374
                offset += bytes;
 
1375
        }
 
1376
        assert(count == 0);
 
1377
}
 
1378
 
 
1379
/*===========================================================================*
 
1380
 *                              dp_pio16_nic2user                            *
 
1381
 *===========================================================================*/
 
1382
static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
 
1383
dpeth_t *dep;
 
1384
int nic_addr;
 
1385
iovec_dat_t *iovp;
 
1386
vir_bytes offset;
 
1387
vir_bytes count;
 
1388
{
 
1389
        vir_bytes vir_user;
 
1390
        vir_bytes ecount;
 
1391
        int i, r, user_proc;
 
1392
        vir_bytes bytes;
 
1393
        //u8_t two_bytes[2];
 
1394
        u16_t two_bytes;
 
1395
        int odd_byte;
 
1396
 
 
1397
        ecount= (count+1) & ~1;
 
1398
        odd_byte= 0;
 
1399
 
 
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);
 
1405
 
 
1406
        i= 0;
 
1407
        while (count > 0)
 
1408
        {
 
1409
                if (i >= IOVEC_NR)
 
1410
                {
 
1411
                        dp_next_iovec(iovp);
 
1412
                        i= 0;
 
1413
                        continue;
 
1414
                }
 
1415
                assert(i < iovp->iod_iovec_s);
 
1416
                if (offset >= iovp->iod_iovec[i].iov_size)
 
1417
                {
 
1418
                        offset -= iovp->iod_iovec[i].iov_size;
 
1419
                        i++;
 
1420
                        continue;
 
1421
                }
 
1422
                bytes = iovp->iod_iovec[i].iov_size - offset;
 
1423
                if (bytes > count)
 
1424
                        bytes = count;
 
1425
 
 
1426
                user_proc= iovp->iod_proc_nr;
 
1427
                vir_user= iovp->iod_iovec[i].iov_addr + offset;
 
1428
                if (odd_byte)
 
1429
                {
 
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);
 
1433
                        if (r != OK)
 
1434
                        {
 
1435
                                panic("DP8390",
 
1436
                                        "dp_pio16_nic2user: sys_vircopy failed",
 
1437
                                        r);
 
1438
                        }
 
1439
                        count--;
 
1440
                        offset++;
 
1441
                        bytes--;
 
1442
                        vir_user++;
 
1443
                        odd_byte= 0;
 
1444
                        if (!bytes)
 
1445
                                continue;
 
1446
                }
 
1447
                ecount= bytes & ~1;
 
1448
                if (ecount != 0)
 
1449
                {
 
1450
                        do_vir_insw(dep->de_data_port, user_proc, vir_user,
 
1451
                                ecount);
 
1452
                        count -= ecount;
 
1453
                        offset += ecount;
 
1454
                        bytes -= ecount;
 
1455
                        vir_user += ecount;
 
1456
                }
 
1457
                if (bytes)
 
1458
                {
 
1459
                        assert(bytes == 1);
 
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);
 
1465
                        if (r != OK)
 
1466
                        {
 
1467
                                panic("DP8390",
 
1468
                                        "dp_pio16_nic2user: sys_vircopy failed",
 
1469
                                        r);
 
1470
                        }
 
1471
                        count--;
 
1472
                        offset++;
 
1473
                        bytes--;
 
1474
                        vir_user++;
 
1475
                        odd_byte= 1;
 
1476
                }
 
1477
        }
 
1478
        assert(count == 0);
 
1479
}
 
1480
 
 
1481
/*===========================================================================*
 
1482
 *                              dp_next_iovec                                *
 
1483
 *===========================================================================*/
 
1484
static void dp_next_iovec(iovp)
 
1485
iovec_dat_t *iovp;
 
1486
{
 
1487
        assert(iovp->iod_iovec_s > IOVEC_NR);
 
1488
 
 
1489
        iovp->iod_iovec_s -= IOVEC_NR;
 
1490
 
 
1491
        iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
 
1492
 
 
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); 
 
1496
}
 
1497
 
 
1498
/*===========================================================================*
 
1499
 *                              conf_hw                                      *
 
1500
 *===========================================================================*/
 
1501
static void conf_hw(dep)
 
1502
dpeth_t *dep;
 
1503
{
 
1504
//      static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */ };
 
1505
 
 
1506
//      int ifnr;
 
1507
//      dp_conf_t *dcp;
 
1508
 
 
1509
//      dep->de_mode= DEM_DISABLED;     /* Superfluous */
 
1510
//      ifnr= dep-de_table;
 
1511
 
 
1512
//      dcp= &dp_conf[ifnr];
 
1513
//      update_conf(dep, dcp);
 
1514
//      if (dep->de_mode != DEM_ENABLED)
 
1515
//              return;
 
1516
        if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
 
1517
        {
 
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;
 
1521
                return;
 
1522
        }
 
1523
 
 
1524
/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
 
1525
 
 
1526
        dep->de_mode = DEM_ENABLED;
 
1527
 
 
1528
        dep->de_flags = DEF_EMPTY;
 
1529
//      dep->de_stat = empty_stat;
 
1530
}
 
1531
 
 
1532
/*===========================================================================*
 
1533
 *                              map_hw_buffer                                *
 
1534
 *===========================================================================*/
 
1535
static void map_hw_buffer(dep)
 
1536
dpeth_t *dep;
 
1537
{
 
1538
//      int r;
 
1539
//      size_t o, size;
 
1540
//      char *buf, *abuf;
 
1541
 
 
1542
        if (dep->de_prog_IO)
 
1543
        {
 
1544
#if 0
 
1545
                if(debug){
 
1546
                        printf(
 
1547
                        "map_hw_buffer: programmed I/O, no need to map buffer\n");
 
1548
                }
 
1549
#endif
 
1550
                dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
 
1551
                return;
 
1552
        }else{
 
1553
                printf( "map_hw_buffer: no buffer!\n" );
 
1554
        }
 
1555
 
 
1556
//      size = dep->de_ramsize + PAGE_SIZE;     /* Add PAGE_SIZE for
 
1557
//                                               * alignment
 
1558
//                                               */
 
1559
//      buf= malloc(size);
 
1560
//      if (buf == NULL)
 
1561
//              panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
 
1562
//      o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
 
1563
//      abuf= buf + o;
 
1564
//      printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
 
1565
 
 
1566
//      r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
 
1567
//                      dep->de_ramsize, (phys_bytes)dep->de_linmem);
 
1568
//      if (r != OK)
 
1569
//              panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
 
1570
//      dep->de_locmem = abuf;
 
1571
}
 
1572
 
 
1573
/*===========================================================================*
 
1574
 *                              reply                                        *
 
1575
 *===========================================================================*/
 
1576
static void reply(dep, err, may_block)
 
1577
dpeth_t *dep;
 
1578
int err;
 
1579
int may_block;
 
1580
{
 
1581
/*      message reply;
 
1582
        int status;
 
1583
        int r;
 
1584
 
 
1585
        status = 0;
 
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;
 
1590
 
 
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);
 
1598
 
 
1599
        if (r == ELOCKED && may_block)
 
1600
        {
 
1601
#if 0
 
1602
                printf("send locked\n");
 
1603
#endif
 
1604
                return;
 
1605
        }
 
1606
 
 
1607
        if (r < 0)
 
1608
                panic("", "dp8390: send failed:", r);
 
1609
        
 
1610
*/      dep->de_read_s = 0;
 
1611
//      dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
 
1612
}
 
1613
 
 
1614
/*===========================================================================*
 
1615
 *                              get_userdata                                 *
 
1616
 *===========================================================================*/
 
1617
static void get_userdata(user_proc, user_addr, count, loc_addr)
 
1618
int user_proc;
 
1619
vir_bytes user_addr;
 
1620
vir_bytes count;
 
1621
void *loc_addr;
 
1622
{
 
1623
        int r;
 
1624
 
 
1625
        r= sys_vircopy(user_proc, D, user_addr,
 
1626
                SELF, D, (vir_bytes)loc_addr, count);
 
1627
        if (r != OK)
 
1628
                panic("DP8390", "get_userdata: sys_vircopy failed", r);
 
1629
}
 
1630
 
 
1631
static void insb(port_t port, void *buf, size_t size)
 
1632
{
 
1633
        size_t i;
 
1634
 
 
1635
        for( i = 0; i < size; ++ i ){
 
1636
                *(( uint8_t * ) buf + i ) = inb( port );
 
1637
        }
 
1638
}
 
1639
 
 
1640
static void insw(port_t port, void *buf, size_t size)
 
1641
{
 
1642
        size_t i;
 
1643
 
 
1644
        for( i = 0; i * 2 < size; ++ i ){
 
1645
                *(( uint16_t * ) buf + i ) = inw( port );
 
1646
        }
 
1647
}
 
1648
 
 
1649
static void outsb(port_t port, void *buf, size_t size)
 
1650
{
 
1651
        size_t i;
 
1652
 
 
1653
        for( i = 0; i < size; ++ i ){
 
1654
                outb( port, *(( uint8_t * ) buf + i ));
 
1655
        }
 
1656
}
 
1657
 
 
1658
static void outsw(port_t port, void *buf, size_t size)
 
1659
{
 
1660
        size_t i;
 
1661
 
 
1662
        for( i = 0; i * 2 < size; ++ i ){
 
1663
                outw( port, *(( uint16_t * ) buf + i ));
 
1664
        }
 
1665
}
 
1666
 
 
1667
/*
 
1668
 * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
 
1669
 */
 
1670
 
 
1671
/** @}
 
1672
 */