Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/netif/dp8390/dp8390.c

    r7e752b2 re0854e3  
    11/*
    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
     2 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Martin Decky
     4 * All rights reserved.
     5 *
     6 * Redistribution and use in source and binary forms, with or without
     7 * modification, are permitted provided that the following conditions
     8 * are met:
     9 *
     10 * - Redistributions of source code must retain the above copyright
     11 *   notice, this list of conditions and the following disclaimer.
     12 * - Redistributions in binary form must reproduce the above copyright
     13 *   notice, this list of conditions and the following disclaimer in the
     14 *   documentation and/or other materials provided with the distribution.
     15 * - The name of the author may not be used to endorse or promote products
     16 *   derived from this software without specific prior written permission.
     17 *
     18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1319 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1420 * 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,
     21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1622 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1723 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     
    2026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    2127 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22  *
    23  * Changes:
    24  *  2009 ported to HelenOS, Lukas Mejdrech
     28 */
     29
     30/*
     31 * This code is based upon the NE2000 driver for MINIX,
     32 * distributed according to a BSD-style license.
     33 *
     34 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
     35 * Copyright (c) 1992, 1994 Philip Homburg
     36 * Copyright (c) 1996 G. Falzoni
     37 *
    2538 */
    2639
     
    3649#include <byteorder.h>
    3750#include <errno.h>
    38 
    3951#include <netif_local.h>
    4052#include <net/packet.h>
     53#include <nil_interface.h>
    4154#include <packet_client.h>
    42 
    4355#include "dp8390_drv.h"
    4456#include "dp8390_port.h"
    45 
    46 /*
    47  * dp8390.c
    48  *
    49  * Created:     before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
    50  *
    51  * Modified Mar 10 1994 by Philip Homburg
    52  *      Become a generic dp8390 driver.
    53  *
    54  * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
    55  *      Added support for 3c503 boards.
    56  */
    57 
    58 #include "local.h"
    5957#include "dp8390.h"
    60 
    61 /** Queues the outgoing packet.
    62  *  @param[in] dep The network interface structure.
    63  *  @param[in] packet The outgoing packet.
    64  *  @return EOK on success.
    65  *  @return EINVAL
    66  */
    67 int queue_packet(dpeth_t * dep, packet_t *packet);
    68 
    69 /** Reads a memory block byte by byte.
     58#include "ne2000.h"
     59
     60/** Read a memory block byte by byte.
     61 *
    7062 *  @param[in] port The source address.
    7163 *  @param[out] buf The destination buffer.
    7264 *  @param[in] size The memory block size in bytes.
     65 *
    7366 */
    7467static void outsb(port_t port, void * buf, size_t size);
    7568
    76 /** Reads a memory block word by word.
     69/** Read a memory block word by word.
     70 *
    7771 *  @param[in] port The source address.
    7872 *  @param[out] buf The destination buffer.
    7973 *  @param[in] size The memory block size in bytes.
     74 *
    8075 */
    8176static void outsw(port_t port, void * buf, size_t size);
    8277
    83 //static u16_t eth_ign_proto;
    84 //static char *progname;
    85 
    86 /* Configuration */
    87 /*typedef struct dp_conf
    88 {
    89         port_t dpc_port;
    90         int dpc_irq;
    91         phys_bytes dpc_mem;
    92         char *dpc_envvar;
    93 } dp_conf_t;
    94 */
    95 //dp_conf_t dp_conf[]=  /* Card addresses */
    96 //{
    97         /* I/O port, IRQ,  Buffer address,  Env. var. */
    98 /*      { 0x280,     3,    0xD0000,        "DPETH0"     },
    99         { 0x300,     5,    0xC8000,        "DPETH1"     },
    100         { 0x380,    10,    0xD8000,        "DPETH2"     },
    101 };
    102 */
    103 /* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
    104  * the error: "array size is negative".
     78/*
     79 * Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
     80 * on writes to the CR register. Additional CR_STAs do not appear to hurt
     81 * genuine dp8390s.
    10582 */
    106 //extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
    107 
    108 /* Card inits configured out? */
    109 #if !ENABLE_WDETH
    110 #define wdeth_probe(dep)        (0)
    111 #endif
    112 #if !ENABLE_NE2000
    113 #define ne_probe(dep)           (0)
    114 #endif
    115 #if !ENABLE_3C503
    116 #define el2_probe(dep)          (0)
    117 #endif
    118 
    119 /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
    120  * on writes to the CR register. Additional CR_STAs do not appear to hurt
    121  * genuine dp8390s
    122  */
    123 #define CR_EXTRA        CR_STA
    124 
    125 //#if ENABLE_PCI
    126 //_PROTOTYPE(static void pci_conf, (void)                               );
    127 //#endif
    128 //_PROTOTYPE(static void do_vwrite, (message *mp, int from_int,
    129 //                                                      int vectored)   );
    130 //_PROTOTYPE(static void do_vwrite_s, (message *mp, int from_int)       );
    131 //_PROTOTYPE(static void do_vread, (message *mp, int vectored)          );
    132 //_PROTOTYPE(static void do_vread_s, (message *mp)                      );
    133 //_PROTOTYPE(static void do_init, (message *mp)                         );
    134 //_PROTOTYPE(static void do_int, (dpeth_t *dep)                         );
    135 //_PROTOTYPE(static void do_getstat, (message *mp)                      );
    136 //_PROTOTYPE(static void do_getstat_s, (message *mp)                    );
    137 //_PROTOTYPE(static void do_getname, (message *mp)                      );
    138 //_PROTOTYPE(static void do_stop, (message *mp)                         );
    139 _PROTOTYPE(static void dp_init, (dpeth_t *dep)                          );
    140 //_PROTOTYPE(static void dp_confaddr, (dpeth_t *dep)                    );
    141 _PROTOTYPE(static void dp_reinit, (dpeth_t *dep)                        );
    142 _PROTOTYPE(static void dp_reset, (dpeth_t *dep)                 );
    143 //_PROTOTYPE(static void dp_check_ints, (dpeth_t *dep)                  );
    144 _PROTOTYPE(static void dp_recv, (dpeth_t *dep)                          );
    145 _PROTOTYPE(static void dp_send, (dpeth_t *dep)                          );
    146 //_PROTOTYPE(static void dp8390_stop, (void)                            );
    147 _PROTOTYPE(static void dp_getblock, (dpeth_t *dep, int page,
    148                                 size_t offset, size_t size, void *dst)  );
    149 _PROTOTYPE(static void dp_pio8_getblock, (dpeth_t *dep, int page,
    150                                 size_t offset, size_t size, void *dst)  );
    151 _PROTOTYPE(static void dp_pio16_getblock, (dpeth_t *dep, int page,
    152                                 size_t offset, size_t size, void *dst)  );
    153 _PROTOTYPE(static int dp_pkt2user, (dpeth_t *dep, int page,
    154                                                         int length) );
    155 //_PROTOTYPE(static int dp_pkt2user_s, (dpeth_t *dep, int page,
    156 //                                                      int length)     );
    157 _PROTOTYPE(static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
    158                 vir_bytes offset, int nic_addr, vir_bytes count) );
    159 //_PROTOTYPE(static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
    160 //              vir_bytes offset, int nic_addr, vir_bytes count)        );
    161 _PROTOTYPE(static void dp_pio8_user2nic, (dpeth_t *dep,
    162                                 iovec_dat_t *iovp, vir_bytes offset,
    163                                 int nic_addr, vir_bytes count) );
    164 //_PROTOTYPE(static void dp_pio8_user2nic_s, (dpeth_t *dep,
    165 //                              iovec_dat_s_t *iovp, vir_bytes offset,
    166 //                              int nic_addr, vir_bytes count)          );
    167 _PROTOTYPE(static void dp_pio16_user2nic, (dpeth_t *dep,
    168                                 iovec_dat_t *iovp, vir_bytes offset,
    169                                 int nic_addr, vir_bytes count) );
    170 //_PROTOTYPE(static void dp_pio16_user2nic_s, (dpeth_t *dep,
    171 //                              iovec_dat_s_t *iovp, vir_bytes offset,
    172 //                              int nic_addr, vir_bytes count)          );
    173 _PROTOTYPE(static void dp_nic2user, (dpeth_t *dep, int nic_addr,
    174                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
    175 //_PROTOTYPE(static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
    176 //              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
    177 _PROTOTYPE(static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
    178                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
    179 //_PROTOTYPE(static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
    180 //              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
    181 _PROTOTYPE(static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
    182                 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
    183 //_PROTOTYPE(static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
    184 //              iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
    185 _PROTOTYPE(static void dp_next_iovec, (iovec_dat_t *iovp)               );
    186 //_PROTOTYPE(static void dp_next_iovec_s, (iovec_dat_s_t *iovp)         );
    187 _PROTOTYPE(static void conf_hw, (dpeth_t *dep)                          );
    188 //_PROTOTYPE(static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)    );
    189 _PROTOTYPE(static void map_hw_buffer, (dpeth_t *dep)                    );
    190 //_PROTOTYPE(static int calc_iovec_size, (iovec_dat_t *iovp)            );
    191 //_PROTOTYPE(static int calc_iovec_size_s, (iovec_dat_s_t *iovp)                );
    192 _PROTOTYPE(static void reply, (dpeth_t *dep, int err, int may_block)    );
    193 //_PROTOTYPE(static void mess_reply, (message *req, message *reply)     );
    194 _PROTOTYPE(static void get_userdata, (int user_proc,
    195                 vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
    196 //_PROTOTYPE(static void get_userdata_s, (int user_proc,
    197 //              cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
    198 //              void *loc_addr) );
    199 //_PROTOTYPE(static void put_userdata, (int user_proc,
    200 //              vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
    201 //_PROTOTYPE(static void put_userdata_s, (int user_proc,
    202 //              cp_grant_id_t grant, size_t count, void *loc_addr)      );
    203 _PROTOTYPE(static void insb, (port_t port, void *buf, size_t size)                              );
    204 _PROTOTYPE(static void insw, (port_t port, void *buf, size_t size)                              );
    205 //_PROTOTYPE(static void do_vir_insb, (port_t port, int proc,
    206 //                                      vir_bytes buf, size_t size)     );
    207 //_PROTOTYPE(static void do_vir_insw, (port_t port, int proc,
    208 //                                      vir_bytes buf, size_t size)     );
    209 //_PROTOTYPE(static void do_vir_outsb, (port_t port, int proc,
    210 //                                      vir_bytes buf, size_t size)     );
    211 //_PROTOTYPE(static void do_vir_outsw, (port_t port, int proc,
    212 //                                      vir_bytes buf, size_t size)     );
    213 
    214 int do_probe(dpeth_t * dep){
     83#define CR_EXTRA  CR_STA
     84
     85static void dp_init(dpeth_t *dep);
     86static void dp_reinit(dpeth_t *dep);
     87static void dp_reset(dpeth_t *dep);
     88static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep);
     89static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst);
     90static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst);
     91static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length);
     92static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size);
     93static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size);
     94static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size);
     95static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size);
     96static void conf_hw(dpeth_t *dep);
     97static void insb(port_t port, void *buf, size_t size);
     98static void insw(port_t port, void *buf, size_t size);
     99
     100int do_probe(dpeth_t *dep)
     101{
    215102        /* This is the default, try to (re)locate the device. */
    216103        conf_hw(dep);
    217104        if (dep->de_mode == DEM_DISABLED)
    218         {
    219105                /* Probe failed, or the device is configured off. */
    220                 return EXDEV;//ENXIO;
    221         }
     106                return EXDEV;
     107       
    222108        if (dep->de_mode == DEM_ENABLED)
    223109                dp_init(dep);
     110       
    224111        return EOK;
    225112}
    226113
    227 /*===========================================================================*
    228  *                              dp8390_dump                                  *
    229  *===========================================================================*/
    230 void dp8390_dump(dpeth_t * dep)
    231 {
    232 //      dpeth_t *dep;
    233         int /*i,*/ isr;
    234 
    235 //      printf("\n");
    236 //      for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
    237 //      {
    238 #if XXX
    239                 if (dep->de_mode == DEM_DISABLED)
    240                         printf("dp8390 port %d is disabled\n", i);
    241                 else if (dep->de_mode == DEM_SINK)
    242                         printf("dp8390 port %d is in sink mode\n", i);
    243 #endif
    244 
    245                 if (dep->de_mode != DEM_ENABLED)
    246 //                      continue;
    247                         return;
    248 
    249 //              printf("dp8390 statistics of port %d:\n", i);
    250 
    251                 printf("recvErr    :%8ld\t", dep->de_stat.ets_recvErr);
    252                 printf("sendErr    :%8ld\t", dep->de_stat.ets_sendErr);
    253                 printf("OVW        :%8ld\n", dep->de_stat.ets_OVW);
    254 
    255                 printf("CRCerr     :%8ld\t", dep->de_stat.ets_CRCerr);
    256                 printf("frameAll   :%8ld\t", dep->de_stat.ets_frameAll);
    257                 printf("missedP    :%8ld\n", dep->de_stat.ets_missedP);
    258 
    259                 printf("packetR    :%8ld\t", dep->de_stat.ets_packetR);
    260                 printf("packetT    :%8ld\t", dep->de_stat.ets_packetT);
    261                 printf("transDef   :%8ld\n", dep->de_stat.ets_transDef);
    262 
    263                 printf("collision  :%8ld\t", dep->de_stat.ets_collision);
    264                 printf("transAb    :%8ld\t", dep->de_stat.ets_transAb);
    265                 printf("carrSense  :%8ld\n", dep->de_stat.ets_carrSense);
    266 
    267                 printf("fifoUnder  :%8ld\t", dep->de_stat.ets_fifoUnder);
    268                 printf("fifoOver   :%8ld\t", dep->de_stat.ets_fifoOver);
    269                 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
    270 
    271                 printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);
    272 
    273                 isr= inb_reg0(dep, DP_ISR);
    274                 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
    275                                         inb_reg0(dep, DP_ISR), dep->de_flags);
    276 //      }
    277 }
    278 
    279 /*===========================================================================*
    280  *                              do_init                                      *
    281  *===========================================================================*/
    282 int do_init(dpeth_t * dep, int mode){
     114int do_init(dpeth_t *dep, int mode)
     115{
    283116        if (dep->de_mode == DEM_DISABLED)
    284         {
    285                 // might call do_probe()
     117                /* FIXME: Perhaps call do_probe()? */
    286118                return EXDEV;
    287         }
    288 
    289         if (dep->de_mode == DEM_SINK)
    290         {
    291 //              strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
    292 //              dep->de_address.ea_addr[5] = port;
    293 //              dp_confaddr(dep);
    294 //              reply_mess.m_type = DL_CONF_REPLY;
    295 //              reply_mess.m3_i1 = mp->DL_PORT;
    296 //              reply_mess.m3_i2 = DE_PORT_NR;
    297 //              *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
    298 //              mess_reply(mp, &reply_mess);
    299 //              return;
    300                 return EOK;
    301         }
     119       
    302120        assert(dep->de_mode == DEM_ENABLED);
    303         assert(dep->de_flags &DEF_ENABLED);
    304 
     121        assert(dep->de_flags & DEF_ENABLED);
     122       
    305123        dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
    306 
     124       
    307125        if (mode &DL_PROMISC_REQ)
    308126                dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
     127       
    309128        if (mode &DL_MULTI_REQ)
    310129                dep->de_flags |= DEF_MULTI;
     130       
    311131        if (mode &DL_BROAD_REQ)
    312132                dep->de_flags |= DEF_BROAD;
    313 
    314 //      dep->de_client = mp->m_source;
     133       
    315134        dp_reinit(dep);
    316 
    317 //      reply_mess.m_type = DL_CONF_REPLY;
    318 //      reply_mess.m3_i1 = mp->DL_PORT;
    319 //      reply_mess.m3_i2 = DE_PORT_NR;
    320 //      *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
    321 
    322 //      mess_reply(mp, &reply_mess);
    323135        return EOK;
    324136}
    325137
    326 /*===========================================================================*
    327  *                              do_stop                                      *
    328  *===========================================================================*/
    329 void do_stop(dpeth_t * dep){
    330         if((dep->de_mode != DEM_SINK) && (dep->de_mode == DEM_ENABLED) && (dep->de_flags &DEF_ENABLED)){
     138void do_stop(dpeth_t *dep)
     139{
     140        if ((dep->de_mode == DEM_ENABLED)
     141            && (dep->de_flags & DEF_ENABLED)) {
    331142                outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    332143                (dep->de_stopf)(dep);
    333 
    334144                dep->de_flags = DEF_EMPTY;
    335145        }
    336146}
    337147
    338 int queue_packet(dpeth_t * dep, packet_t *packet){
    339         packet_t *tmp;
    340 
    341         if(dep->packet_count >= MAX_PACKETS){
    342                 netif_pq_release(packet_get_id(packet));
    343                 return ELIMIT;
    344         }
    345 
    346         tmp = dep->packet_queue;
    347         while(pq_next(tmp)){
    348                 tmp = pq_next(tmp);
    349         }
    350         if(pq_add(&tmp, packet, 0, 0) != EOK){
    351                 return EINVAL;
    352         }
    353         if(! dep->packet_count){
    354                 dep->packet_queue = packet;
    355         }
    356         ++ dep->packet_count;
    357         return EBUSY;
    358 }
    359 
    360 /*===========================================================================*
    361  *                      based on        do_vwrite                                    *
    362  *===========================================================================*/
    363 int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int)
    364 {
    365 //      int port, count, size;
     148int do_pwrite(dpeth_t *dep, packet_t *packet, int from_int)
     149{
    366150        int size;
    367151        int sendq_head;
    368 /*      dpeth_t *dep;
    369 
    370         port = mp->DL_PORT;
    371         count = mp->DL_COUNT;
    372         if (port < 0 || port >= DE_PORT_NR)
    373                 panic("", "dp8390: illegal port", port);
    374         dep= &de_table[port];
    375         dep->de_client= mp->DL_PROC;
    376 */
    377         if (dep->de_mode == DEM_SINK)
    378         {
    379                 assert(!from_int);
    380 //              dep->de_flags |= DEF_PACK_SEND;
    381                 reply(dep, OK, FALSE);
    382 //              return;
    383                 return EOK;
    384         }
     152       
    385153        assert(dep->de_mode == DEM_ENABLED);
    386         assert(dep->de_flags &DEF_ENABLED);
    387         if(dep->packet_queue && (! from_int)){
    388 //      if (dep->de_flags &DEF_SEND_AVAIL){
    389 //              panic("", "dp8390: send already in progress", NO_NUM);
    390                 return queue_packet(dep, packet);
    391         }
    392 
    393         sendq_head= dep->de_sendq_head;
    394 //      if (dep->de_sendq[sendq_head].sq_filled)
    395 //      {
    396 //              if (from_int)
    397 //                      panic("", "dp8390: should not be sending\n", NO_NUM);
    398 //              dep->de_sendmsg= *mp;
    399 //              dep->de_flags |= DEF_SEND_AVAIL;
    400 //              reply(dep, OK, FALSE);
    401 //              return;
    402 //              return queue_packet(dep, packet);
    403 //      }
    404 //      assert(!(dep->de_flags &DEF_PACK_SEND));
    405 
    406 /*      if (vectored)
    407         {
    408                 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
    409                         (count > IOVEC_NR ? IOVEC_NR : count) *
    410                         sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
    411                 dep->de_write_iovec.iod_iovec_s = count;
    412                 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
    413                 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
    414 
    415                 dep->de_tmp_iovec = dep->de_write_iovec;
    416                 size = calc_iovec_size(&dep->de_tmp_iovec);
    417         }
    418         else
    419         {
    420                 dep->de_write_iovec.iod_iovec[0].iov_addr =
    421                         (vir_bytes) mp->DL_ADDR;
    422                 dep->de_write_iovec.iod_iovec[0].iov_size =
    423                         mp->DL_COUNT;
    424                 dep->de_write_iovec.iod_iovec_s = 1;
    425                 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
    426                 dep->de_write_iovec.iod_iovec_addr = 0;
    427                 size= mp->DL_COUNT;
    428         }
    429 */
     154        assert(dep->de_flags & DEF_ENABLED);
     155       
     156        if (dep->de_flags & DEF_SEND_AVAIL) {
     157                fprintf(stderr, "dp8390: send already in progress\n");
     158                return EBUSY;
     159        }
     160       
     161        sendq_head = dep->de_sendq_head;
     162        if (dep->de_sendq[sendq_head].sq_filled) {
     163                if (from_int)
     164                        fprintf(stderr, "dp8390: should not be sending\n");
     165                dep->de_flags |= DEF_SEND_AVAIL;
     166                dep->de_flags &= ~DEF_PACK_SEND;
     167               
     168                return EBUSY;
     169        }
     170       
     171        assert(!(dep->de_flags & DEF_PACK_SEND));
     172       
     173        void *buf = packet_get_data(packet);
    430174        size = packet_get_data_length(packet);
    431         dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_get_data(packet);
    432         dep->de_write_iovec.iod_iovec[0].iov_size = size;
    433         dep->de_write_iovec.iod_iovec_s = 1;
    434         dep->de_write_iovec.iod_iovec_addr = (uintptr_t) NULL;
    435 
    436         if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
    437         {
    438                 panic("", "dp8390: invalid packet size", size);
     175       
     176        if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) {
     177                fprintf(stderr, "dp8390: invalid packet size\n");
    439178                return EINVAL;
    440179        }
    441         (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
    442                 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
    443                 size);
    444         dep->de_sendq[sendq_head].sq_filled= TRUE;
    445         if (dep->de_sendq_tail == sendq_head)
    446         {
     180       
     181        (dep->de_user2nicf)(dep, buf, 0,
     182            dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, size);
     183        dep->de_sendq[sendq_head].sq_filled = true;
     184       
     185        if (dep->de_sendq_tail == sendq_head) {
    447186                outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
    448187                outb_reg0(dep, DP_TBCR1, size >> 8);
    449                 outb_reg0(dep, DP_TBCR0, size &0xff);
    450                 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
    451         }
    452         else
    453                 dep->de_sendq[sendq_head].sq_size= size;
     188                outb_reg0(dep, DP_TBCR0, size & 0xff);
     189                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);  /* there it goes .. */
     190        } else
     191                dep->de_sendq[sendq_head].sq_size = size;
    454192       
    455193        if (++sendq_head == dep->de_sendq_nr)
    456                 sendq_head= 0;
     194                sendq_head = 0;
     195       
    457196        assert(sendq_head < SENDQ_NR);
    458         dep->de_sendq_head= sendq_head;
    459 
    460 //      dep->de_flags |= DEF_PACK_SEND;
    461 
    462         /* If the interrupt handler called, don't send a reply. The reply
    463          * will be sent after all interrupts are handled.
    464          */
     197        dep->de_sendq_head = sendq_head;
     198       
     199        dep->de_flags |= DEF_PACK_SEND;
     200       
    465201        if (from_int)
    466202                return EOK;
    467         reply(dep, OK, FALSE);
    468 
    469         assert(dep->de_mode == DEM_ENABLED);
    470         assert(dep->de_flags &DEF_ENABLED);
     203       
     204        dep->de_flags &= ~DEF_PACK_SEND;
     205       
    471206        return EOK;
    472207}
    473208
    474 /*===========================================================================*
    475  *                              dp_init                                      *
    476  *===========================================================================*/
    477 void dp_init(dep)
    478 dpeth_t *dep;
     209void dp_init(dpeth_t *dep)
    479210{
    480211        int dp_rcr_reg;
    481         int i;//, r;
    482 
     212        int i;
     213       
    483214        /* General initialization */
    484215        dep->de_flags = DEF_EMPTY;
    485216        (*dep->de_initf)(dep);
    486 
    487 //      dp_confaddr(dep);
    488 
    489         if (debug)
    490         {
    491                 printf("%s: Ethernet address ", dep->de_name);
    492                 for (i= 0; i < 6; i++)
    493                         printf("%x%c", dep->de_address.ea_addr[i],
    494                                                         i < 5 ? ':' : '\n');
    495         }
    496 
    497         /* Map buffer */
    498         map_hw_buffer(dep);
    499 
    500         /* Initialization of the dp8390 following the mandatory procedure
     217       
     218        printf("%s: Ethernet address ", dep->de_name);
     219        for (i = 0; i < 6; i++)
     220                printf("%x%c", dep->de_address.ea_addr[i], i < 5 ? ':' : '\n');
     221       
     222        /*
     223         * Initialization of the dp8390 following the mandatory procedure
    501224         * in reference manual ("DP8390D/NS32490D NIC Network Interface
    502225         * Controller", National Semiconductor, July 1995, Page 29).
    503226         */
     227       
    504228        /* Step 1: */
    505229        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
     230       
    506231        /* Step 2: */
    507232        if (dep->de_16bit)
     
    509234        else
    510235                outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
     236       
    511237        /* Step 3: */
    512238        outb_reg0(dep, DP_RBCR0, 0);
    513239        outb_reg0(dep, DP_RBCR1, 0);
     240       
    514241        /* Step 4: */
    515242        dp_rcr_reg = 0;
    516         if (dep->de_flags &DEF_PROMISC)
     243       
     244        if (dep->de_flags & DEF_PROMISC)
    517245                dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
    518         if (dep->de_flags &DEF_BROAD)
     246       
     247        if (dep->de_flags & DEF_BROAD)
    519248                dp_rcr_reg |= RCR_AB;
    520         if (dep->de_flags &DEF_MULTI)
     249       
     250        if (dep->de_flags & DEF_MULTI)
    521251                dp_rcr_reg |= RCR_AM;
     252       
    522253        outb_reg0(dep, DP_RCR, dp_rcr_reg);
     254       
    523255        /* Step 5: */
    524256        outb_reg0(dep, DP_TCR, TCR_INTERNAL);
     257       
    525258        /* Step 6: */
    526259        outb_reg0(dep, DP_BNRY, dep->de_startpage);
    527260        outb_reg0(dep, DP_PSTART, dep->de_startpage);
    528261        outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
     262       
    529263        /* Step 7: */
    530264        outb_reg0(dep, DP_ISR, 0xFF);
     265       
    531266        /* Step 8: */
    532267        outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
    533                 IMR_OVWE | IMR_CNTE);
     268            IMR_OVWE | IMR_CNTE);
     269       
    534270        /* Step 9: */
    535271        outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
    536 
     272       
    537273        outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
    538274        outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
     
    541277        outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
    542278        outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
    543 
     279       
    544280        outb_reg1(dep, DP_MAR0, 0xff);
    545281        outb_reg1(dep, DP_MAR1, 0xff);
     
    550286        outb_reg1(dep, DP_MAR6, 0xff);
    551287        outb_reg1(dep, DP_MAR7, 0xff);
    552 
     288       
    553289        outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
     290       
    554291        /* Step 10: */
    555292        outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
     293       
    556294        /* Step 11: */
    557295        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    558 
    559         inb_reg0(dep, DP_CNTR0);                /* reset counters by reading */
     296       
     297        inb_reg0(dep, DP_CNTR0);  /* Reset counters by reading */
    560298        inb_reg0(dep, DP_CNTR1);
    561299        inb_reg0(dep, DP_CNTR2);
    562 
     300       
    563301        /* Finish the initialization. */
    564302        dep->de_flags |= DEF_ENABLED;
    565         for (i= 0; i<dep->de_sendq_nr; i++)
     303        for (i = 0; i < dep->de_sendq_nr; i++)
    566304                dep->de_sendq[i].sq_filled= 0;
    567         dep->de_sendq_head= 0;
    568         dep->de_sendq_tail= 0;
    569         if (!dep->de_prog_IO)
    570         {
    571                 dep->de_user2nicf= dp_user2nic;
    572 //              dep->de_user2nicf_s= dp_user2nic_s;
    573                 dep->de_nic2userf= dp_nic2user;
    574 //              dep->de_nic2userf_s= dp_nic2user_s;
    575                 dep->de_getblockf= dp_getblock;
    576         }
    577         else if (dep->de_16bit)
    578         {
     305       
     306        dep->de_sendq_head = 0;
     307        dep->de_sendq_tail = 0;
     308       
     309        if (dep->de_16bit) {
    579310                dep->de_user2nicf= dp_pio16_user2nic;
    580 //              dep->de_user2nicf_s= dp_pio16_user2nic_s;
    581311                dep->de_nic2userf= dp_pio16_nic2user;
    582 //              dep->de_nic2userf_s= dp_pio16_nic2user_s;
    583312                dep->de_getblockf= dp_pio16_getblock;
    584         }
    585         else
    586         {
     313        } else {
    587314                dep->de_user2nicf= dp_pio8_user2nic;
    588 //              dep->de_user2nicf_s= dp_pio8_user2nic_s;
    589315                dep->de_nic2userf= dp_pio8_nic2user;
    590 //              dep->de_nic2userf_s= dp_pio8_nic2user_s;
    591316                dep->de_getblockf= dp_pio8_getblock;
    592317        }
    593 
    594         /* Set the interrupt handler and policy. Do not automatically
    595          * reenable interrupts. Return the IRQ line number on interrupts.
    596          */
    597 /*      dep->de_hook = dep->de_irq;
    598         r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
    599         if (r != OK)
    600                 panic("DP8390", "sys_irqsetpolicy failed", r);
    601 
    602         r= sys_irqenable(&dep->de_hook);
    603         if (r != OK)
    604         {
    605                 panic("DP8390", "unable enable interrupts", r);
    606         }
    607 */
    608 }
    609 
    610 /*===========================================================================*
    611  *                              dp_reinit                                    *
    612  *===========================================================================*/
    613 static void dp_reinit(dep)
    614 dpeth_t *dep;
     318}
     319
     320static void dp_reinit(dpeth_t *dep)
    615321{
    616322        int dp_rcr_reg;
    617 
     323       
    618324        outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    619 
     325       
    620326        dp_rcr_reg = 0;
    621         if (dep->de_flags &DEF_PROMISC)
     327       
     328        if (dep->de_flags & DEF_PROMISC)
    622329                dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
    623         if (dep->de_flags &DEF_BROAD)
     330       
     331        if (dep->de_flags & DEF_BROAD)
    624332                dp_rcr_reg |= RCR_AB;
    625         if (dep->de_flags &DEF_MULTI)
     333       
     334        if (dep->de_flags & DEF_MULTI)
    626335                dp_rcr_reg |= RCR_AM;
     336       
    627337        outb_reg0(dep, DP_RCR, dp_rcr_reg);
    628338}
    629339
    630 /*===========================================================================*
    631  *                              dp_reset                                     *
    632  *===========================================================================*/
    633 static void dp_reset(dep)
    634 dpeth_t *dep;
     340static void dp_reset(dpeth_t *dep)
    635341{
    636342        int i;
    637 
     343       
    638344        /* Stop chip */
    639345        outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
    640346        outb_reg0(dep, DP_RBCR0, 0);
    641347        outb_reg0(dep, DP_RBCR1, 0);
    642         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
     348       
     349        for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
    643350                ; /* Do nothing */
    644         outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
    645         outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
     351       
     352        outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
     353        outb_reg0(dep, DP_CR, CR_STA | CR_DM_ABORT);
    646354        outb_reg0(dep, DP_TCR, TCR_NORMAL);
    647 
    648         /* Acknowledge the ISR_RDC (remote dma) interrupt. */
    649         for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
     355       
     356        /* Acknowledge the ISR_RDC (remote DMA) interrupt. */
     357        for (i = 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
    650358                ; /* Do nothing */
    651         outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) &~ISR_RDC);
    652 
    653         /* Reset the transmit ring. If we were transmitting a packet, we
     359       
     360        outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
     361       
     362        /*
     363         * Reset the transmit ring. If we were transmitting a packet, we
    654364         * pretend that the packet is processed. Higher layers will
    655365         * retransmit if the packet wasn't actually sent.
    656366         */
    657         dep->de_sendq_head= dep->de_sendq_tail= 0;
    658         for (i= 0; i<dep->de_sendq_nr; i++)
    659                 dep->de_sendq[i].sq_filled= 0;
    660         dp_send(dep);
     367        dep->de_sendq_head = 0;
     368        dep->de_sendq_tail = 0;
     369       
     370        for (i = 0; i < dep->de_sendq_nr; i++)
     371                dep->de_sendq[i].sq_filled = 0;
     372       
     373        dep->de_flags &= ~DEF_SEND_AVAIL;
    661374        dep->de_flags &= ~DEF_STOPPED;
    662375}
    663376
    664 /*===========================================================================*
    665  *                              dp_check_ints                                *
    666  *===========================================================================*/
    667 void dp_check_ints(dep, isr)
    668 dpeth_t *dep;
    669 int isr;
    670 {
    671         int /*isr,*/ tsr;
     377void dp_check_ints(int nil_phone, device_id_t device_id, dpeth_t *dep, int isr)
     378{
     379        int tsr;
    672380        int size, sendq_tail;
    673 
    674         if (!(dep->de_flags &DEF_ENABLED))
    675                 panic("", "dp8390: got premature interrupt", NO_NUM);
    676 
    677         for(;;)
    678         {
    679 //              isr = inb_reg0(dep, DP_ISR);
    680                 if (!isr)
    681                         break;
     381       
     382        if (!(dep->de_flags & DEF_ENABLED))
     383                fprintf(stderr, "dp8390: got premature interrupt\n");
     384       
     385        for (; isr; isr = inb_reg0(dep, DP_ISR)) {
    682386                outb_reg0(dep, DP_ISR, isr);
    683                 if (isr &(ISR_PTX|ISR_TXE))
    684                 {
    685                         if (isr &ISR_TXE)
    686                         {
    687 #if DEBUG
    688  {printf("%s: got send Error\n", dep->de_name);}
    689 #endif
     387               
     388                if (isr & (ISR_PTX | ISR_TXE)) {
     389                        if (isr & ISR_TXE)
    690390                                dep->de_stat.ets_sendErr++;
     391                        else {
     392                                tsr = inb_reg0(dep, DP_TSR);
     393                               
     394                                if (tsr & TSR_PTX)
     395                                        dep->de_stat.ets_packetT++;
     396                               
     397                                if (tsr & TSR_COL)
     398                                        dep->de_stat.ets_collision++;
     399                               
     400                                if (tsr & TSR_ABT)
     401                                        dep->de_stat.ets_transAb++;
     402                               
     403                                if (tsr & TSR_CRS)
     404                                        dep->de_stat.ets_carrSense++;
     405                               
     406                                if ((tsr & TSR_FU) && (++dep->de_stat.ets_fifoUnder <= 10))
     407                                        printf("%s: fifo underrun\n", dep->de_name);
     408                               
     409                                if ((tsr & TSR_CDH) && (++dep->de_stat.ets_CDheartbeat <= 10))
     410                                        printf("%s: CD heart beat failure\n", dep->de_name);
     411                               
     412                                if (tsr & TSR_OWC)
     413                                        dep->de_stat.ets_OWC++;
    691414                        }
    692                         else
    693                         {
    694                                 tsr = inb_reg0(dep, DP_TSR);
    695 
    696                                 if (tsr &TSR_PTX) dep->de_stat.ets_packetT++;
    697 #if 0   /* Reserved in later manuals, should be ignored */
    698                                 if (!(tsr &TSR_DFR))
    699                                 {
    700                                         /* In most (all?) implementations of
    701                                          * the dp8390, this bit is set
    702                                          * when the packet is not deferred
    703                                          */
    704                                         dep->de_stat.ets_transDef++;
    705                                 }
    706 #endif
    707                                 if (tsr &TSR_COL) dep->de_stat.ets_collision++;
    708                                 if (tsr &TSR_ABT) dep->de_stat.ets_transAb++;
    709                                 if (tsr &TSR_CRS) dep->de_stat.ets_carrSense++;
    710                                 if (tsr &TSR_FU
    711                                         && ++dep->de_stat.ets_fifoUnder <= 10)
    712                                 {
    713                                         printf("%s: fifo underrun\n",
    714                                                 dep->de_name);
    715                                 }
    716                                 if (tsr &TSR_CDH
    717                                         && ++dep->de_stat.ets_CDheartbeat <= 10)
    718                                 {
    719                                         printf("%s: CD heart beat failure\n",
    720                                                 dep->de_name);
    721                                 }
    722                                 if (tsr &TSR_OWC) dep->de_stat.ets_OWC++;
    723                         }
    724                         sendq_tail= dep->de_sendq_tail;
    725 
    726                         if (!(dep->de_sendq[sendq_tail].sq_filled))
    727                         {
    728                                 /* Software bug? */
    729                                 assert(!debug);
    730 
     415                       
     416                        sendq_tail = dep->de_sendq_tail;
     417                       
     418                        if (!(dep->de_sendq[sendq_tail].sq_filled)) {
    731419                                /* Or hardware bug? */
    732                                 printf(
    733                                 "%s: transmit interrupt, but not sending\n",
    734                                         dep->de_name);
     420                                printf("%s: transmit interrupt, but not sending\n", dep->de_name);
    735421                                continue;
    736422                        }
    737                         dep->de_sendq[sendq_tail].sq_filled= 0;
     423                       
     424                        dep->de_sendq[sendq_tail].sq_filled = 0;
     425                       
    738426                        if (++sendq_tail == dep->de_sendq_nr)
    739                                 sendq_tail= 0;
    740                         dep->de_sendq_tail= sendq_tail;
    741                         if (dep->de_sendq[sendq_tail].sq_filled)
    742                         {
    743                                 size= dep->de_sendq[sendq_tail].sq_size;
     427                                sendq_tail = 0;
     428                       
     429                        dep->de_sendq_tail = sendq_tail;
     430                       
     431                        if (dep->de_sendq[sendq_tail].sq_filled) {
     432                                size = dep->de_sendq[sendq_tail].sq_size;
    744433                                outb_reg0(dep, DP_TPSR,
    745                                         dep->de_sendq[sendq_tail].sq_sendpage);
     434                                    dep->de_sendq[sendq_tail].sq_sendpage);
    746435                                outb_reg0(dep, DP_TBCR1, size >> 8);
    747                                 outb_reg0(dep, DP_TBCR0, size &0xff);
     436                                outb_reg0(dep, DP_TBCR0, size & 0xff);
    748437                                outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
    749438                        }
    750 //                      if (dep->de_flags &DEF_SEND_AVAIL)
    751                                 dp_send(dep);
     439                       
     440                        dep->de_flags &= ~DEF_SEND_AVAIL;
    752441                }
    753 
    754                 if (isr &ISR_PRX)
    755                 {
    756                         /* Only call dp_recv if there is a read request */
    757 //                      if (dep->de_flags) &DEF_READING)
    758                                 dp_recv(dep);
    759                 }
    760                
    761                 if (isr &ISR_RXE) dep->de_stat.ets_recvErr++;
    762                 if (isr &ISR_CNT)
    763                 {
     442               
     443                if (isr & ISR_PRX)
     444                        dp_recv(nil_phone, device_id, dep);
     445               
     446                if (isr & ISR_RXE)
     447                        dep->de_stat.ets_recvErr++;
     448               
     449                if (isr & ISR_CNT) {
    764450                        dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
    765451                        dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
    766452                        dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
    767453                }
    768                 if (isr &ISR_OVW)
    769                 {
     454               
     455                if (isr & ISR_OVW)
    770456                        dep->de_stat.ets_OVW++;
    771 #if 0
    772                         {printW(); printf(
    773                                 "%s: got overwrite warning\n", dep->de_name);}
    774 #endif
    775 /*                      if (dep->de_flags &DEF_READING)
    776                         {
    777                                 printf(
    778 "dp_check_ints: strange: overwrite warning and pending read request\n");
    779                                 dp_recv(dep);
    780                         }
    781 */              }
    782                 if (isr &ISR_RDC)
    783                 {
     457               
     458                if (isr & ISR_RDC) {
    784459                        /* Nothing to do */
    785460                }
    786                 if (isr &ISR_RST)
    787                 {
    788                         /* this means we got an interrupt but the ethernet
     461               
     462                if (isr & ISR_RST) {
     463                        /*
     464                         * This means we got an interrupt but the ethernet
    789465                         * chip is shutdown. We set the flag DEF_STOPPED,
    790466                         * and continue processing arrived packets. When the
    791467                         * receive buffer is empty, we reset the dp8390.
    792468                         */
    793 #if 0
    794                          {printW(); printf(
    795                                 "%s: NIC stopped\n", dep->de_name);}
    796 #endif
    797469                        dep->de_flags |= DEF_STOPPED;
    798470                        break;
    799471                }
    800                 isr = inb_reg0(dep, DP_ISR);
    801         }
    802 //      if ((dep->de_flags &(DEF_READING|DEF_STOPPED)) ==
    803 //                                              (DEF_READING|DEF_STOPPED))
    804         if ((dep->de_flags &DEF_STOPPED) == DEF_STOPPED)
    805         {
    806                 /* The chip is stopped, and all arrived packets are
    807                  * delivered.
     472        }
     473       
     474        if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED) {
     475                /*
     476                 * The chip is stopped, and all arrived packets
     477                 * are delivered.
    808478                 */
    809479                dp_reset(dep);
    810480        }
    811 }
    812 
    813 /*===========================================================================*
    814  *                              dp_recv                                      *
    815  *===========================================================================*/
    816 static void dp_recv(dep)
    817 dpeth_t *dep;
     481       
     482        dep->de_flags &= ~DEF_PACK_SEND;
     483}
     484
     485static void dp_recv(int nil_phone, device_id_t device_id, dpeth_t *dep)
    818486{
    819487        dp_rcvhdr_t header;
    820         //unsigned pageno, curr, next;
    821488        int pageno, curr, next;
    822         vir_bytes length;
     489        size_t length;
    823490        int packet_processed, r;
    824         u16_t eth_type;
    825 
    826         packet_processed = FALSE;
     491        uint16_t eth_type;
     492       
     493        packet_processed = false;
    827494        pageno = inb_reg0(dep, DP_BNRY) + 1;
    828         if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
    829 
    830         do
    831         {
     495        if (pageno == dep->de_stoppage)
     496                pageno = dep->de_startpage;
     497       
     498        do {
    832499                outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
    833500                curr = inb_reg1(dep, DP_CURR);
    834501                outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
    835 
    836                 if (curr == pageno) break;
    837 
    838                 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
    839                         &header);
    840                 (dep->de_getblockf)(dep, pageno, sizeof(header) +
    841                         2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
    842 
    843                 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
    844                         sizeof(dp_rcvhdr_t);
     502               
     503                if (curr == pageno)
     504                        break;
     505               
     506                (dep->de_getblockf)(dep, pageno, (size_t) 0, sizeof(header), &header);
     507                (dep->de_getblockf)(dep, pageno, sizeof(header) + 2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
     508               
     509                length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);
    845510                next = header.dr_next;
    846                 if (length < ETH_MIN_PACK_SIZE ||
    847                         length > ETH_MAX_PACK_SIZE_TAGGED)
    848                 {
    849                         printf("%s: packet with strange length arrived: %d\n",
    850                                 dep->de_name, (int) length);
     511                if ((length < ETH_MIN_PACK_SIZE) || (length > ETH_MAX_PACK_SIZE_TAGGED)) {
     512                        printf("%s: packet with strange length arrived: %d\n", dep->de_name, (int) length);
    851513                        next= curr;
    852                 }
    853                 else if (next < dep->de_startpage || next >= dep->de_stoppage)
    854                 {
     514                } else if ((next < dep->de_startpage) || (next >= dep->de_stoppage)) {
    855515                        printf("%s: strange next page\n", dep->de_name);
    856516                        next= curr;
    857                 }
    858 /*              else if (eth_type == eth_ign_proto)
    859                 {
    860 */                      /* Hack: ignore packets of a given protocol, useful
    861                          * if you share a net with 80 computers sending
    862                          * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
     517                } else if (header.dr_status & RSR_FO) {
     518                        /*
     519                         * This is very serious, so we issue a warning and
     520                         * reset the buffers
    863521                         */
    864 /*                      static int first= 1;
    865                         if (first)
    866                         {
    867                                 first= 0;
    868                                 printf("%s: dropping proto 0x%04x packets\n",
    869                                         dep->de_name,
    870                                         ntohs(eth_ign_proto));
    871                         }
     522                        printf("%s: fifo overrun, resetting receive buffer\n", dep->de_name);
     523                        dep->de_stat.ets_fifoOver++;
     524                        next = curr;
     525                } else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) {
     526                        r = dp_pkt2user(nil_phone, device_id, dep, pageno, length);
     527                        if (r != EOK)
     528                                return;
     529                       
     530                        packet_processed = true;
    872531                        dep->de_stat.ets_packetR++;
    873532                }
    874 */              else if (header.dr_status &RSR_FO)
    875                 {
    876                         /* This is very serious, so we issue a warning and
    877                          * reset the buffers */
    878                         printf("%s: fifo overrun, resetting receive buffer\n",
    879                                 dep->de_name);
    880                         dep->de_stat.ets_fifoOver++;
    881                         next = curr;
    882                 }
    883                 else if ((header.dr_status &RSR_PRX) &&
    884                                            (dep->de_flags &DEF_ENABLED))
    885                 {
    886 //                      if (dep->de_safecopy_read)
    887 //                              r = dp_pkt2user_s(dep, pageno, length);
    888 //                      else
    889                                 r = dp_pkt2user(dep, pageno, length);
    890                         if (r != OK)
    891                                 return;
    892 
    893                         packet_processed = TRUE;
    894                         dep->de_stat.ets_packetR++;
    895                 }
     533               
    896534                if (next == dep->de_startpage)
    897535                        outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
    898536                else
    899537                        outb_reg0(dep, DP_BNRY, next - 1);
    900 
     538               
    901539                pageno = next;
    902         }
    903         while (!packet_processed);
    904 }
    905 
    906 /*===========================================================================*
    907  *                              dp_send                                      *
    908  *===========================================================================*/
    909 static void dp_send(dep)
    910 dpeth_t *dep;
    911 {
    912         packet_t *packet;
    913 
    914 //      if (!(dep->de_flags &DEF_SEND_AVAIL))
    915 //              return;
    916 
    917         if(dep->packet_queue){
    918                 packet = dep->packet_queue;
    919                 dep->packet_queue = pq_detach(packet);
    920                 do_pwrite(dep, packet, TRUE);
    921                 netif_pq_release(packet_get_id(packet));
    922                 -- dep->packet_count;
    923         }
    924 //      if(! dep->packet_queue){
    925 //              dep->de_flags &= ~DEF_SEND_AVAIL;
    926 //      }
    927 /*      switch(dep->de_sendmsg.m_type)
    928         {
    929         case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);       break;
    930         case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);        break;
    931         case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE);  break;
    932         default:
    933                 panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
    934                 break;
    935         }
    936 */
    937 }
    938 
    939 /*===========================================================================*
    940  *                              dp_getblock                                  *
    941  *===========================================================================*/
    942 static void dp_getblock(dep, page, offset, size, dst)
    943 dpeth_t *dep;
    944 int page;
    945 size_t offset;
    946 size_t size;
    947 void *dst;
    948 {
    949 //      int r;
    950 
    951         offset = page * DP_PAGESIZE + offset;
    952 
    953         memcpy(dst, dep->de_locmem + offset, size);
    954 }
    955 
    956 /*===========================================================================*
    957  *                              dp_pio8_getblock                             *
    958  *===========================================================================*/
    959 static void dp_pio8_getblock(dep, page, offset, size, dst)
    960 dpeth_t *dep;
    961 int page;
    962 size_t offset;
    963 size_t size;
    964 void *dst;
     540        } while (!packet_processed);
     541}
     542
     543static void dp_pio8_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst)
    965544{
    966545        offset = page * DP_PAGESIZE + offset;
     
    970549        outb_reg0(dep, DP_RSAR1, offset >> 8);
    971550        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    972 
     551       
    973552        insb(dep->de_data_port, dst, size);
    974553}
    975554
    976 /*===========================================================================*
    977  *                              dp_pio16_getblock                            *
    978  *===========================================================================*/
    979 static void dp_pio16_getblock(dep, page, offset, size, dst)
    980 dpeth_t *dep;
    981 int page;
    982 size_t offset;
    983 size_t size;
    984 void *dst;
     555static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst)
    985556{
    986557        offset = page * DP_PAGESIZE + offset;
     
    990561        outb_reg0(dep, DP_RSAR1, offset >> 8);
    991562        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    992 
    993         assert (!(size &1));
     563       
     564        assert(!(size & 1));
     565       
    994566        insw(dep->de_data_port, dst, size);
    995567}
    996568
    997 /*===========================================================================*
    998  *                              dp_pkt2user                                  *
    999  *===========================================================================*/
    1000 static int dp_pkt2user(dep, page, length)
    1001 dpeth_t *dep;
    1002 int page, length;
     569static int dp_pkt2user(int nil_phone, device_id_t device_id, dpeth_t *dep, int page, int length)
    1003570{
    1004571        int last, count;
    1005572        packet_t *packet;
    1006 
    1007 //      if (!(dep->de_flags &DEF_READING))
    1008 //              return EGENERIC;
    1009 
     573       
    1010574        packet = netif_packet_get_1(length);
    1011         if(! packet){
     575        if (!packet)
    1012576                return ENOMEM;
    1013         }
    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 = (uintptr_t) NULL;
    1018 
     577       
     578        void *buf = packet_suffix(packet, length);
     579       
    1019580        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;
     581        if (last >= dep->de_stoppage) {
     582                count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t);
     583               
    1027584                (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         {
     585                    sizeof(dp_rcvhdr_t), buf, 0, count);
     586                (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
     587                    buf, count, length - count);
     588        } else {
    1034589                (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 
     590                    sizeof(dp_rcvhdr_t), buf, 0, length);
     591        }
     592       
     593        nil_received_msg(nil_phone, device_id, packet, SERVICE_NONE);
     594       
     595        return EOK;
     596}
     597
     598static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
     599{
    1119600        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);
     601       
     602        outb_reg0(dep, DP_RBCR0, size & 0xFF);
     603        outb_reg0(dep, DP_RBCR1, size >> 8);
     604        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    1124605        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    1125606        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)
     607       
     608        outsb(dep->de_data_port, buf + offset, size);
     609       
     610        unsigned int i;
     611        for (i = 0; i < 100; i++) {
     612                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
    1157613                        break;
    1158614        }
     615       
    1159616        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 
     617                fprintf(stderr, "dp8390: remote DMA failed to complete\n");
     618}
     619
     620static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
     621{
     622        void *vir_user;
     623        size_t ecount;
     624        uint16_t two_bytes;
     625       
     626        ecount = size & ~1;
     627       
    1186628        outb_reg0(dep, DP_ISR, ISR_RDC);
    1187         outb_reg0(dep, DP_RBCR0, ecount &0xFF);
     629        outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
    1188630        outb_reg0(dep, DP_RBCR1, ecount >> 8);
    1189         outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
     631        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    1190632        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    1191633        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);
     634       
     635        vir_user = buf + offset;
     636        if (ecount != 0) {
     637                outsw(dep->de_data_port, vir_user, ecount);
     638                size -= ecount;
     639                offset += ecount;
     640                vir_user += ecount;
     641        }
     642       
     643        if (size) {
     644                assert(size == 1);
     645               
     646                memcpy(&(((uint8_t *) &two_bytes)[0]), vir_user, 1);
    1269647                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)
     648        }
     649       
     650        unsigned int i;
     651        for (i = 0; i < 100; i++) {
     652                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
    1274653                        break;
    1275654        }
     655       
    1276656        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);
     657                fprintf(stderr, "dp8390: remote dma failed to complete\n");
     658}
     659
     660static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size)
     661{
     662        outb_reg0(dep, DP_RBCR0, size & 0xFF);
     663        outb_reg0(dep, DP_RBCR1, size >> 8);
     664        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    1348665        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    1349666        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);
     667       
     668        insb(dep->de_data_port, buf + offset, size);
     669}
     670
     671static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size)
     672{
     673        void *vir_user;
     674        size_t ecount;
     675        uint16_t two_bytes;
     676       
     677        ecount = size & ~1;
     678       
     679        outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
    1401680        outb_reg0(dep, DP_RBCR1, ecount >> 8);
    1402         outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
     681        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    1403682        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    1404683        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         {
     684       
     685        vir_user = buf + offset;
     686        if (ecount != 0) {
     687                insw(dep->de_data_port, vir_user, ecount);
     688                size -= ecount;
     689                offset += ecount;
     690                vir_user += ecount;
     691        }
     692       
     693        if (size) {
     694                assert(size == 1);
     695               
     696                two_bytes = inw(dep->de_data_port);
     697                memcpy(vir_user, &(((uint8_t *) &two_bytes)[0]), 1);
     698        }
     699}
     700
     701static void conf_hw(dpeth_t *dep)
     702{
     703        if (!ne_probe(dep)) {
    1518704                printf("%s: No ethernet card found at %#lx\n",
    1519705                    dep->de_name, dep->de_base_port);
     
    1521707                return;
    1522708        }
    1523 
    1524 /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
    1525 
     709       
    1526710        dep->de_mode = DEM_ENABLED;
    1527 
    1528711        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);
    1629712}
    1630713
     
    1632715{
    1633716        size_t i;
    1634 
    1635         for(i = 0; i < size; ++ i){
     717       
     718        for (i = 0; i < size; i++)
    1636719                *((uint8_t *) buf + i) = inb(port);
    1637         }
    1638720}
    1639721
     
    1641723{
    1642724        size_t i;
    1643 
    1644         for(i = 0; i * 2 < size; ++ i){
     725       
     726        for (i = 0; i * 2 < size; i++)
    1645727                *((uint16_t *) buf + i) = inw(port);
    1646         }
    1647728}
    1648729
     
    1650731{
    1651732        size_t i;
    1652 
    1653         for(i = 0; i < size; ++ i){
     733       
     734        for (i = 0; i < size; i++)
    1654735                outb(port, *((uint8_t *) buf + i));
    1655         }
    1656736}
    1657737
     
    1659739{
    1660740        size_t i;
    1661 
    1662         for(i = 0; i * 2 < size; ++ i){
     741       
     742        for (i = 0; i * 2 < size; i++)
    1663743                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  */
     744}
    1670745
    1671746/** @}
Note: See TracChangeset for help on using the changeset viewer.