#include "8390.h"
+#define sys_nic2mem(srcOffs,dstProc,dstOffs,length) \
+ sys_vircopy(SELF,dep->de_memsegm,(vir_bytes)(srcOffs),\
+ (dstProc),D,(vir_bytes)(dstOffs),length)
+#define sys_user2nic(srcProc,srcOffs,dstOffs,length) \
+ sys_vircopy((srcProc),D,(vir_bytes)(srcOffs),\
+ SELF,dep->de_memsegm,(vir_bytes)(dstOffs),length)
+
static const char RdmaErrMsg[] = "remote dma failed to complete";
/*
*/
static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
{
-
- sys_datacopy(dep->de_memsegm, dep->de_linmem + offset,
- SELF, (vir_bytes)dst, size);
+
+ sys_nic2mem(dep->de_linmem + offset, SELF, dst, size);
return;
}
/* Circular buffer wrap-around */
bytes = dep->de_stoppage * DP_PAGESIZE - offset;
- sys_datacopy(dep->de_memsegm, dep->de_linmem + offset,
- iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
+ sys_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_addr, bytes);
pktsize -= bytes;
phys_user += bytes;
bytes = iovp->iod_iovec[ix].iov_size - bytes;
if (bytes > pktsize) bytes = pktsize;
offset = dep->de_startpage * DP_PAGESIZE;
}
- sys_datacopy(dep->de_memsegm, dep->de_linmem + offset,
- iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
+ sys_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_addr, bytes);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
int bytes, ix = 0;
/* Computes shared memory address */
- offset = dep->de_linmem + pageno * DP_PAGESIZE;
+ offset = pageno * DP_PAGESIZE;
do { /* Reads chuncks of packet from user area */
if (bytes > pktsize) bytes = pktsize;
/* Reads from user area to board (shared memory) */
- sys_datacopy(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr,
- dep->de_memsegm, dep->de_linmem + offset, bytes);
+ sys_user2nic(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr,
+ dep->de_linmem + offset, bytes);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
reply.m_type = DL_TASK_REPLY;
reply.DL_PORT = dep - de_table;
reply.DL_PROC = dep->de_client;
- reply.DL_STAT = status | ((u32_t) err << 16);
+ reply.DL_STAT = status /* | ((u32_t) err << 16) */;
reply.DL_COUNT = dep->de_read_s;
getuptime(&reply.DL_CLCK);
DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT));
- if ((status = send(dep->de_client, &reply)) != OK)
- panic(dep->de_name, SendErrMsg, dep->de_client);
+ if ((status = send(dep->de_client, &reply)) == OK) {
+ dep->de_read_s = 0;
+ dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
+
+ } else if (status != ELOCKED || err == OK)
+ panic(dep->de_name, SendErrMsg, status);
- dep->de_read_s = 0;
- dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
return;
}
/*
** Name: void dp_confaddr(dpeth_t *dep)
-** Function: Chechs environment for a User defined ethernet address.
+** Function: Checks environment for a User defined ethernet address.
*/
static void dp_confaddr(dpeth_t * dep)
{
printf("%s statistics:\t\t", dep->de_name);
/* Network interface status */
- printf("Status: 0x%04x\n\n", dep->de_flags);
+ printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
(*dep->de_dumpstatsf) (dep);
/* Device specific initialization */
(*dep->de_initf) (dep);
- /* Set the interrupt handler policy. Request interrupts to be reenabled
+ /* Set the interrupt handler policy. Request interrupts not to be reenabled
* automatically. Return the IRQ line number when an interrupt occurs.
*/
dep->de_hook = dep->de_irq;
- sys_irqsetpolicy(dep->de_irq, IRQ_REENABLE, &dep->de_hook);
+ sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook);
+ dep->de_int_pending = FALSE;
sys_irqenable(&dep->de_hook);
return;
for (dep = de_table; dep < &de_table[DE_PORT_NR]; dep += 1) {
/* If device is enabled and interrupt pending */
if (dep->de_mode == DEM_ENABLED) {
- /* dep->de_int_pending = FALSE; */
+ dep->de_int_pending = TRUE;
(*dep->de_interruptf) (dep);
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
- reply(dep, OK);
- /* enable_irq(&dep->de_hook); */
+ reply(dep, !OK);
+ dep->de_int_pending = FALSE;
+ sys_irqenable(&dep->de_hook);
}
}
break;
** Interface description for ethernet device driver
**
** $Log$
+** Revision 1.4 2005/09/04 18:52:16 beng
+** Giovanni's fixes to dpeth:
+** Date: Sat, 03 Sep 2005 11:05:22 +0200
+** Subject: Minix 3.0.8
+**
** Revision 1.3 2005/08/03 11:53:34 jnherder
** Miscellaneous cleanups.
**
port_t de_data_port; /* For boards using Prog. I/O for xmit/recv */
int de_irq;
- /* int de_int_pending; */
- int de_hook; /* V306 irq_hook_t de_hook; */
+ int de_int_pending;
+ int de_hook; /* interrupt hook at kernel */
char de_name[8];
#define wdeth_probe(x) (0)
#endif
-#define lock() sys_irqdisable(&dep->de_hook);
-#define unlock() sys_irqenable(&dep->de_hook);
+#define lock() (++dep->de_int_pending,sys_irqdisable(&dep->de_hook))
+#define unlock() do{int i=(--dep->de_int_pending)?0:sys_irqenable(&dep->de_hook);}while(0)
#define milli_delay(t) tickdelay(1)
/** dp.h **/