all build: $(DRIVER)
$(DRIVER): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
- install -S 4096 $(DRIVER)
+ install -S 32k $(DRIVER)
# install with other drivers
install: /usr/sbin/$(DRIVER)
*
* The valid messages and their parameters are:
*
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
- * |------------+----------+---------+----------+---------+---------|
- * | HARDINT | | | | | |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_INIT | port nr | proc nr | mode | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_STOP | port_nr | | | | |
- * |------------|----------|---------|----------|---------|---------|
+ * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
+ * |------------+----------+---------+----------+---------+---------+---------|
+ * | HARDINT | | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITE | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READ | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV_S | port nr | proc nr | count | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_CONF | port nr | proc nr | | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_GETSTAT | port nr | proc nr | | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_STOP | port_nr | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
*
* The messages sent are:
*
*
* m_type m3_i1 m3_i2 m3_ca1
* |-------------+---------+-----------+---------------|
- * |DL_INIT_REPLY| port nr | last port | ethernet addr |
+ * |DL_CONF_REPLY| port nr | last port | ethernet addr |
* |-------------+---------+-----------+---------------|
*
* Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
#include <net/hton.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
+#include <sys/vm.h>
#include "assert.h"
#include "local.h"
#endif
_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
int vectored) );
+_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int) );
_PROTOTYPE( static void do_vread, (message *mp, int vectored) );
+_PROTOTYPE( static void do_vread_s, (message *mp) );
_PROTOTYPE( static void do_init, (message *mp) );
_PROTOTYPE( static void do_int, (dpeth_t *dep) );
_PROTOTYPE( static void do_getstat, (message *mp) );
+_PROTOTYPE( static void do_getstat_s, (message *mp) );
_PROTOTYPE( static void do_getname, (message *mp) );
_PROTOTYPE( static void do_stop, (message *mp) );
_PROTOTYPE( static void dp_init, (dpeth_t *dep) );
size_t offset, size_t size, void *dst) );
_PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
int length) );
+_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
+ int length) );
_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
vir_bytes offset, int nic_addr, vir_bytes count) );
+_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
+ vir_bytes offset, int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
iovec_dat_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
+_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
+ iovec_dat_s_t *iovp, vir_bytes offset,
+ int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
iovec_dat_t *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
+_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
+ iovec_dat_s_t *iovp, vir_bytes offset,
+ int nic_addr, vir_bytes count) );
_PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
+_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
+ iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
+_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
+ iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
+_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
+ iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp) );
+_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp) );
_PROTOTYPE( static void conf_hw, (dpeth_t *dep) );
_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp) );
+_PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep) );
_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
+_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp) );
_PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static void get_userdata, (int user_proc,
vir_bytes user_addr, vir_bytes count, void *loc_addr) );
+_PROTOTYPE( static void get_userdata_s, (int user_proc,
+ cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
+ void *loc_addr) );
_PROTOTYPE( static void put_userdata, (int user_proc,
vir_bytes user_addr, vir_bytes count, void *loc_addr) );
+_PROTOTYPE( static void put_userdata_s, (int user_proc,
+ cp_grant_id_t grant, size_t count, void *loc_addr) );
_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size) );
_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size) );
_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
case DEV_PING: notify(m.m_source); continue;
case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
+ case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
case DL_READ: do_vread(&m, FALSE); break;
case DL_READV: do_vread(&m, TRUE); break;
- case DL_INIT: do_init(&m); break;
+ case DL_READV_S: do_vread_s(&m); break;
+ case DL_CONF: do_init(&m); break;
case DL_GETSTAT: do_getstat(&m); break;
+ case DL_GETSTAT_S: do_getstat_s(&m); break;
case DL_GETNAME: do_getname(&m); break;
case DL_STOP: do_stop(&m); break;
case HARD_INT:
assert(dep->de_flags & DEF_ENABLED);
}
+/*===========================================================================*
+ * do_vwrite_s *
+ *===========================================================================*/
+static void do_vwrite_s(mp, from_int)
+message *mp;
+int from_int;
+{
+ int port, count, size;
+ int sendq_head;
+ dpeth_t *dep;
+
+ port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (port < 0 || port >= DE_PORT_NR)
+ panic("", "dp8390: illegal port", port);
+ dep= &de_table[port];
+ dep->de_client= mp->DL_PROC;
+
+ if (dep->de_mode == DEM_SINK)
+ {
+ assert(!from_int);
+ dep->de_flags |= DEF_PACK_SEND;
+ reply(dep, OK, FALSE);
+ return;
+ }
+ assert(dep->de_mode == DEM_ENABLED);
+ assert(dep->de_flags & DEF_ENABLED);
+ if (dep->de_flags & DEF_SEND_AVAIL)
+ panic("", "dp8390: send already in progress", NO_NUM);
+
+ sendq_head= dep->de_sendq_head;
+ if (dep->de_sendq[sendq_head].sq_filled)
+ {
+ if (from_int)
+ panic("", "dp8390: should not be sending\n", NO_NUM);
+ dep->de_sendmsg= *mp;
+ dep->de_flags |= DEF_SEND_AVAIL;
+ reply(dep, OK, FALSE);
+ return;
+ }
+ assert(!(dep->de_flags & DEF_PACK_SEND));
+
+ get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ (count > IOVEC_NR ? IOVEC_NR : count) *
+ sizeof(dep->de_write_iovec_s.iod_iovec[0]),
+ dep->de_write_iovec_s.iod_iovec);
+ dep->de_write_iovec_s.iod_iovec_s = count;
+ dep->de_write_iovec_s.iod_proc_nr = mp->DL_PROC;
+ dep->de_write_iovec_s.iod_grant = mp->DL_GRANT;
+ dep->de_write_iovec_s.iod_iovec_offset = 0;
+
+ dep->de_tmp_iovec_s = dep->de_write_iovec_s;
+ size = calc_iovec_size_s(&dep->de_tmp_iovec_s);
+
+ if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
+ {
+ panic("", "dp8390: invalid packet size", size);
+ }
+ (dep->de_user2nicf_s)(dep, &dep->de_write_iovec_s, 0,
+ dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
+ size);
+ dep->de_sendq[sendq_head].sq_filled= TRUE;
+ if (dep->de_sendq_tail == sendq_head)
+ {
+ outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
+ outb_reg0(dep, DP_TBCR1, size >> 8);
+ outb_reg0(dep, DP_TBCR0, size & 0xff);
+ outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
+ }
+ else
+ dep->de_sendq[sendq_head].sq_size= size;
+
+ if (++sendq_head == dep->de_sendq_nr)
+ sendq_head= 0;
+ assert(sendq_head < SENDQ_NR);
+ dep->de_sendq_head= sendq_head;
+
+ dep->de_flags |= DEF_PACK_SEND;
+
+ /* If the interrupt handler called, don't send a reply. The reply
+ * will be sent after all interrupts are handled.
+ */
+ if (from_int)
+ return;
+ reply(dep, OK, FALSE);
+
+ assert(dep->de_mode == DEM_ENABLED);
+ assert(dep->de_flags & DEF_ENABLED);
+}
+
/*===========================================================================*
* do_vread *
*===========================================================================*/
if(dep->de_flags & DEF_READING)
panic("", "dp8390: read already in progress", NO_NUM);
+ dep->de_safecopy_read= 0;
+
if (vectored)
{
get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
reply(dep, OK, FALSE);
}
+/*===========================================================================*
+ * do_vread_s *
+ *===========================================================================*/
+static void do_vread_s(mp)
+message *mp;
+{
+ int port, count;
+ int size;
+ dpeth_t *dep;
+
+ port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (port < 0 || port >= DE_PORT_NR)
+ panic("", "dp8390: illegal port", port);
+ dep= &de_table[port];
+ dep->de_client= mp->DL_PROC;
+ if (dep->de_mode == DEM_SINK)
+ {
+ reply(dep, OK, FALSE);
+ return;
+ }
+ assert(dep->de_mode == DEM_ENABLED);
+ assert(dep->de_flags & DEF_ENABLED);
+
+ dep->de_safecopy_read= 1;
+
+ if(dep->de_flags & DEF_READING)
+ panic("", "dp8390: read already in progress", NO_NUM);
+
+ get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ (count > IOVEC_NR ? IOVEC_NR : count) *
+ sizeof(dep->de_read_iovec_s.iod_iovec[0]),
+ dep->de_read_iovec_s.iod_iovec);
+ dep->de_read_iovec_s.iod_iovec_s = count;
+ dep->de_read_iovec_s.iod_proc_nr = mp->DL_PROC;
+ dep->de_read_iovec_s.iod_grant = mp->DL_GRANT;
+ dep->de_read_iovec_s.iod_iovec_offset = 0;
+
+ dep->de_tmp_iovec_s = dep->de_read_iovec_s;
+ size= calc_iovec_size_s(&dep->de_tmp_iovec_s);
+
+ if (size < ETH_MAX_PACK_SIZE_TAGGED)
+ panic("", "dp8390: wrong packet size", size);
+ dep->de_flags |= DEF_READING;
+
+ dp_recv(dep);
+
+ if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
+ (DEF_READING|DEF_STOPPED))
+ {
+ /* The chip is stopped, and all arrived packets are
+ * delivered.
+ */
+ dp_reset(dep);
+ }
+ reply(dep, OK, FALSE);
+}
+
/*===========================================================================*
* do_init *
*===========================================================================*/
port = mp->DL_PORT;
if (port < 0 || port >= DE_PORT_NR)
{
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
if (dep->de_mode == DEM_DISABLED)
{
/* Probe failed, or the device is configured off. */
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
dep->de_address.ea_addr[5] = port;
dp_confaddr(dep);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = DE_PORT_NR;
*(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
dep->de_client = mp->m_source;
dp_reinit(dep);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = DE_PORT_NR;
*(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
reply(dep, OK, FALSE);
}
+/*===========================================================================*
+ * do_getstat_s *
+ *===========================================================================*/
+static void do_getstat_s(mp)
+message *mp;
+{
+ int port;
+ dpeth_t *dep;
+
+ port = mp->DL_PORT;
+ if (port < 0 || port >= DE_PORT_NR)
+ panic("", "dp8390: illegal port", port);
+ dep= &de_table[port];
+ dep->de_client= mp->DL_PROC;
+ if (dep->de_mode == DEM_SINK)
+ {
+ put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
+ (vir_bytes) sizeof(dep->de_stat), &dep->de_stat);
+ reply(dep, OK, FALSE);
+ return;
+ }
+ assert(dep->de_mode == DEM_ENABLED);
+ assert(dep->de_flags & DEF_ENABLED);
+
+ dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
+ dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
+ dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
+
+ put_userdata_s(mp->DL_PROC, mp->DL_GRANT,
+ sizeof(dep->de_stat), &dep->de_stat);
+ reply(dep, OK, FALSE);
+}
+
/*===========================================================================*
* do_getname *
*===========================================================================*/
i < 5 ? ':' : '\n');
}
+ /* Map buffer */
+ map_hw_buffer(dep);
+
/* Initialization of the dp8390 following the mandatory procedure
* in reference manual ("DP8390D/NS32490D NIC Network Interface
* Controller", National Semiconductor, July 1995, Page 29).
if (!dep->de_prog_IO)
{
dep->de_user2nicf= dp_user2nic;
+ dep->de_user2nicf_s= dp_user2nic_s;
dep->de_nic2userf= dp_nic2user;
+ dep->de_nic2userf_s= dp_nic2user_s;
dep->de_getblockf= dp_getblock;
}
else if (dep->de_16bit)
{
dep->de_user2nicf= dp_pio16_user2nic;
+ dep->de_user2nicf_s= dp_pio16_user2nic_s;
dep->de_nic2userf= dp_pio16_nic2user;
+ dep->de_nic2userf_s= dp_pio16_nic2user_s;
dep->de_getblockf= dp_pio16_getblock;
}
else
{
dep->de_user2nicf= dp_pio8_user2nic;
+ dep->de_user2nicf_s= dp_pio8_user2nic_s;
dep->de_nic2userf= dp_pio8_nic2user;
+ dep->de_nic2userf_s= dp_pio8_nic2user_s;
dep->de_getblockf= dp_pio8_getblock;
}
else if ((header.dr_status & RSR_PRX) &&
(dep->de_flags & DEF_ENABLED))
{
- r = dp_pkt2user(dep, pageno, length);
+ if (dep->de_safecopy_read)
+ r = dp_pkt2user_s(dep, pageno, length);
+ else
+ r = dp_pkt2user(dep, pageno, length);
if (r != OK)
return;
{
case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
+ case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break;
default:
- panic("", "dp8390: wrong type:", dep->de_sendmsg.m_type);
+ panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
break;
}
}
offset = page * DP_PAGESIZE + offset;
- r = sys_vircopy(SELF, BIOS_SEG, dep->de_linmem + offset,
- SELF, D, (vir_bytes)dst, size);
-
- if (r != OK)
- panic("DP8390", "dp_getblock: sys_vircopy failed", r);
+ memcpy(dst, dep->de_locmem + offset, size);
}
/*===========================================================================*
return OK;
}
+/*===========================================================================*
+ * dp_pkt2user_s *
+ *===========================================================================*/
+static int dp_pkt2user_s(dep, page, length)
+dpeth_t *dep;
+int page, length;
+{
+ int last, count;
+
+ if (!(dep->de_flags & DEF_READING))
+ return EGENERIC;
+
+ last = page + (length - 1) / DP_PAGESIZE;
+ if (last >= dep->de_stoppage)
+ {
+ count = (dep->de_stoppage - page) * DP_PAGESIZE -
+ sizeof(dp_rcvhdr_t);
+
+ /* Save read_iovec since we need it twice. */
+ dep->de_tmp_iovec_s = dep->de_read_iovec_s;
+ (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
+ sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec_s, 0, count);
+ (dep->de_nic2userf_s)(dep, dep->de_startpage * DP_PAGESIZE,
+ &dep->de_read_iovec_s, count, length - count);
+ }
+ else
+ {
+ (dep->de_nic2userf_s)(dep, page * DP_PAGESIZE +
+ sizeof(dp_rcvhdr_t), &dep->de_read_iovec_s, 0, length);
+ }
+
+ dep->de_read_s = length;
+ dep->de_flags |= DEF_PACK_RECV;
+ dep->de_flags &= ~DEF_READING;
+
+ return OK;
+}
+
/*===========================================================================*
* dp_user2nic *
*===========================================================================*/
vir_bytes vir_hw, vir_user;
int bytes, i, r;
- vir_hw = dep->de_linmem + nic_addr;
+ vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
i= 0;
while (count > 0)
r= sys_vircopy(iovp->iod_proc_nr, D,
iovp->iod_iovec[i].iov_addr + offset,
- SELF, BIOS_SEG, vir_hw, bytes);
+ SELF, D, vir_hw, bytes);
if (r != OK)
panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
assert(count == 0);
}
+/*===========================================================================*
+ * dp_user2nic_s *
+ *===========================================================================*/
+static void dp_user2nic_s(dep, iovp, offset, nic_addr, count)
+dpeth_t *dep;
+iovec_dat_s_t *iovp;
+vir_bytes offset;
+int nic_addr;
+vir_bytes count;
+{
+ vir_bytes vir_hw, vir_user;
+ int bytes, i, r;
+
+ vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ r= sys_safecopyfrom(iovp->iod_proc_nr,
+ iovp->iod_iovec[i].iov_grant, offset,
+ vir_hw, bytes, D);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_user2nic_s: sys_safecopyfrom failed", r);
+ }
+
+ count -= bytes;
+ vir_hw += bytes;
+ offset += bytes;
+ }
+ assert(count == 0);
+}
+
/*===========================================================================*
* dp_pio8_user2nic *
*===========================================================================*/
}
/*===========================================================================*
- * dp_pio16_user2nic *
+ * dp_pio8_user2nic_s *
*===========================================================================*/
-static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
+static void dp_pio8_user2nic_s(dep, iovp, offset, nic_addr, count)
dpeth_t *dep;
-iovec_dat_t *iovp;
+iovec_dat_s_t *iovp;
vir_bytes offset;
int nic_addr;
vir_bytes count;
{
- vir_bytes vir_user;
- vir_bytes ecount;
- int i, r, bytes, user_proc;
- u8_t two_bytes[2];
- int odd_byte;
-
- ecount= (count+1) & ~1;
- odd_byte= 0;
+ phys_bytes phys_user;
+ int bytes, i, r;
outb_reg0(dep, DP_ISR, ISR_RDC);
- outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
- outb_reg0(dep, DP_RBCR1, ecount >> 8);
+
+ outb_reg0(dep, DP_RBCR0, count & 0xFF);
+ outb_reg0(dep, DP_RBCR1, count >> 8);
outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
{
if (i >= IOVEC_NR)
{
- dp_next_iovec(iovp);
+ dp_next_iovec_s(iovp);
i= 0;
continue;
}
if (bytes > count)
bytes = count;
- user_proc= iovp->iod_proc_nr;
- vir_user= iovp->iod_iovec[i].iov_addr + offset;
- if (odd_byte)
+ r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[i].iov_grant, offset, bytes);
+ if (r != OK)
{
- r= sys_vircopy(user_proc, D, vir_user,
- SELF, D, (vir_bytes)&two_bytes[1], 1);
- if (r != OK)
+ panic(__FILE__,
+ "dp_pio8_user2nic_s: sys_safe_outsb failed",
+ r);
+ }
+ count -= bytes;
+ offset += bytes;
+ }
+ assert(count == 0);
+
+ for (i= 0; i<100; i++)
+ {
+ if (inb_reg0(dep, DP_ISR) & ISR_RDC)
+ break;
+ }
+ if (i == 100)
+ {
+ panic("", "dp8390: remote dma failed to complete", NO_NUM);
+ }
+}
+
+/*===========================================================================*
+ * dp_pio16_user2nic *
+ *===========================================================================*/
+static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
+dpeth_t *dep;
+iovec_dat_t *iovp;
+vir_bytes offset;
+int nic_addr;
+vir_bytes count;
+{
+ vir_bytes vir_user;
+ vir_bytes ecount;
+ int i, r, bytes, user_proc;
+ u8_t two_bytes[2];
+ int odd_byte;
+
+ ecount= (count+1) & ~1;
+ odd_byte= 0;
+
+ outb_reg0(dep, DP_ISR, ISR_RDC);
+ outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
+ outb_reg0(dep, DP_RBCR1, ecount >> 8);
+ outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
+ outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
+ outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ user_proc= iovp->iod_proc_nr;
+ vir_user= iovp->iod_iovec[i].iov_addr + offset;
+ if (odd_byte)
+ {
+ r= sys_vircopy(user_proc, D, vir_user,
+ SELF, D, (vir_bytes)&two_bytes[1], 1);
+ if (r != OK)
{
panic("DP8390",
"dp_pio16_user2nic: sys_vircopy failed",
}
}
+/*===========================================================================*
+ * dp_pio16_user2nic_s *
+ *===========================================================================*/
+static void dp_pio16_user2nic_s(dep, iovp, offset, nic_addr, count)
+dpeth_t *dep;
+iovec_dat_s_t *iovp;
+vir_bytes offset;
+int nic_addr;
+vir_bytes count;
+{
+ vir_bytes ecount;
+ cp_grant_id_t gid;
+ int i, r, bytes, user_proc;
+ u8_t two_bytes[2];
+ int odd_byte;
+
+ ecount= (count+1) & ~1;
+ odd_byte= 0;
+
+ outb_reg0(dep, DP_ISR, ISR_RDC);
+ outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
+ outb_reg0(dep, DP_RBCR1, ecount >> 8);
+ outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
+ outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
+ outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ user_proc= iovp->iod_proc_nr;
+ gid= iovp->iod_iovec[i].iov_grant;
+ if (odd_byte)
+ {
+ r= sys_safecopyfrom(user_proc, gid, offset,
+ (vir_bytes)&two_bytes[1], 1, D);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_user2nic: sys_safecopyfrom failed",
+ r);
+ }
+ outw(dep->de_data_port, *(u16_t *)two_bytes);
+ count--;
+ offset++;
+ bytes--;
+ odd_byte= 0;
+ if (!bytes)
+ continue;
+ }
+ ecount= bytes & ~1;
+ if (ecount != 0)
+ {
+ r= sys_safe_outsw(dep->de_data_port, user_proc,
+ gid, offset, ecount);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_user2nic: sys_safe_outsw failed",
+ r);
+ }
+ count -= ecount;
+ offset += ecount;
+ bytes -= ecount;
+ }
+ if (bytes)
+ {
+ assert(bytes == 1);
+ r= sys_safecopyfrom(user_proc, gid, offset,
+ (vir_bytes)&two_bytes[0], 1, D);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_user2nic: sys_safecopyfrom failed",
+ r);
+ }
+ count--;
+ offset++;
+ bytes--;
+ odd_byte= 1;
+ }
+ }
+ assert(count == 0);
+
+ if (odd_byte)
+ outw(dep->de_data_port, *(u16_t *)two_bytes);
+
+ for (i= 0; i<100; i++)
+ {
+ if (inb_reg0(dep, DP_ISR) & ISR_RDC)
+ break;
+ }
+ if (i == 100)
+ {
+ panic("", "dp8390: remote dma failed to complete", NO_NUM);
+ }
+}
+
/*===========================================================================*
* dp_nic2user *
*===========================================================================*/
vir_bytes vir_hw, vir_user;
int bytes, i, r;
- vir_hw = dep->de_linmem + nic_addr;
+ vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
i= 0;
while (count > 0)
if (bytes > count)
bytes = count;
- r= sys_vircopy(SELF, BIOS_SEG, vir_hw,
+ r= sys_vircopy(SELF, D, vir_hw,
iovp->iod_proc_nr, D,
iovp->iod_iovec[i].iov_addr + offset, bytes);
if (r != OK)
assert(count == 0);
}
+/*===========================================================================*
+ * dp_nic2user_s *
+ *===========================================================================*/
+static void dp_nic2user_s(dep, nic_addr, iovp, offset, count)
+dpeth_t *dep;
+int nic_addr;
+iovec_dat_s_t *iovp;
+vir_bytes offset;
+vir_bytes count;
+{
+ vir_bytes vir_hw, vir_user;
+ int bytes, i, r;
+
+ vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ r= sys_safecopyto(iovp->iod_proc_nr,
+ iovp->iod_iovec[i].iov_grant, offset,
+ vir_hw, bytes, D);
+ if (r != OK)
+ panic("DP8390",
+ "dp_nic2user_s: sys_safecopyto failed", r);
+
+ count -= bytes;
+ vir_hw += bytes;
+ offset += bytes;
+ }
+ assert(count == 0);
+}
+
/*===========================================================================*
* dp_pio8_nic2user *
*===========================================================================*/
assert(count == 0);
}
+/*===========================================================================*
+ * dp_pio8_nic2user_s *
+ *===========================================================================*/
+static void dp_pio8_nic2user_s(dep, nic_addr, iovp, offset, count)
+dpeth_t *dep;
+int nic_addr;
+iovec_dat_s_t *iovp;
+vir_bytes offset;
+vir_bytes count;
+{
+ phys_bytes phys_user;
+ int bytes, i, r;
+
+ outb_reg0(dep, DP_RBCR0, count & 0xFF);
+ outb_reg0(dep, DP_RBCR1, count >> 8);
+ outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
+ outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
+ outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[i].iov_grant, offset, bytes);
+ if (r != OK)
+ {
+ panic(__FILE__,
+ "dp_pio8_nic2user_s: sys_safe_insb failed", r);
+ }
+ count -= bytes;
+ offset += bytes;
+ }
+ assert(count == 0);
+}
+
/*===========================================================================*
* dp_pio16_nic2user *
*===========================================================================*/
}
/*===========================================================================*
- * dp_next_iovec *
+ * dp_pio16_nic2user_s *
+ *===========================================================================*/
+static void dp_pio16_nic2user_s(dep, nic_addr, iovp, offset, count)
+dpeth_t *dep;
+int nic_addr;
+iovec_dat_s_t *iovp;
+vir_bytes offset;
+vir_bytes count;
+{
+ vir_bytes ecount;
+ cp_grant_id_t gid;
+ int i, r, bytes, user_proc;
+ u8_t two_bytes[2];
+ int odd_byte;
+
+ ecount= (count+1) & ~1;
+ odd_byte= 0;
+
+ outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
+ outb_reg0(dep, DP_RBCR1, ecount >> 8);
+ outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
+ outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
+ outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
+
+ i= 0;
+ while (count > 0)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ assert(i < iovp->iod_iovec_s);
+ if (offset >= iovp->iod_iovec[i].iov_size)
+ {
+ offset -= iovp->iod_iovec[i].iov_size;
+ i++;
+ continue;
+ }
+ bytes = iovp->iod_iovec[i].iov_size - offset;
+ if (bytes > count)
+ bytes = count;
+
+ user_proc= iovp->iod_proc_nr;
+ gid= iovp->iod_iovec[i].iov_grant;
+ if (odd_byte)
+ {
+ r= sys_safecopyto(user_proc, gid, offset,
+ (vir_bytes)&two_bytes[1], 1, D);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_nic2user: sys_safecopyto failed",
+ r);
+ }
+ count--;
+ offset++;
+ bytes--;
+ odd_byte= 0;
+ if (!bytes)
+ continue;
+ }
+ ecount= bytes & ~1;
+ if (ecount != 0)
+ {
+ r= sys_safe_insw(dep->de_data_port, user_proc, gid,
+ offset, ecount);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_nic2user: sys_safe_insw failed",
+ r);
+ }
+ count -= ecount;
+ offset += ecount;
+ bytes -= ecount;
+ }
+ if (bytes)
+ {
+ assert(bytes == 1);
+ *(u16_t *)two_bytes= inw(dep->de_data_port);
+ r= sys_safecopyto(user_proc, gid, offset,
+ (vir_bytes)&two_bytes[0], 1, D);
+ if (r != OK)
+ {
+ panic("DP8390",
+ "dp_pio16_nic2user: sys_safecopyto failed",
+ r);
+ }
+ count--;
+ offset++;
+ bytes--;
+ odd_byte= 1;
+ }
+ }
+ assert(count == 0);
+}
+
+/*===========================================================================*
+ * dp_next_iovec *
*===========================================================================*/
static void dp_next_iovec(iovp)
iovec_dat_t *iovp;
sizeof(iovec_t), iovp->iod_iovec);
}
+/*===========================================================================*
+ * dp_next_iovec_s *
+ *===========================================================================*/
+static void dp_next_iovec_s(iovp)
+iovec_dat_s_t *iovp;
+{
+ assert(iovp->iod_iovec_s > IOVEC_NR);
+
+ iovp->iod_iovec_s -= IOVEC_NR;
+
+ iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
+
+ get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant,
+ iovp->iod_iovec_offset,
+ (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
+ sizeof(iovp->iod_iovec[0]), iovp->iod_iovec);
+}
+
/*===========================================================================*
* conf_hw *
*===========================================================================*/
dep->de_ramsize= v;
}
+/*===========================================================================*
+ * map_hw_buffer *
+ *===========================================================================*/
+static void map_hw_buffer(dep)
+dpeth_t *dep;
+{
+ int r;
+ size_t o, size;
+ char *buf, *abuf;
+
+ if (dep->de_prog_IO)
+ {
+#if 0
+ printf(
+ "map_hw_buffer: programmed I/O, no need to map buffer\n");
+#endif
+ dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
+ return;
+ }
+
+ size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
+ * alignment
+ */
+ buf= malloc(size);
+ if (buf == NULL)
+ panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
+ o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
+ abuf= buf + o;
+ printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
+
+ r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
+ dep->de_ramsize, (phys_bytes)dep->de_linmem);
+ if (r != OK)
+ panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
+ dep->de_locmem = abuf;
+}
+
/*===========================================================================*
* calc_iovec_size *
*===========================================================================*/
return size;
}
+/*===========================================================================*
+ * calc_iovec_size_s *
+ *===========================================================================*/
+static int calc_iovec_size_s(iovp)
+iovec_dat_s_t *iovp;
+{
+ /* Calculate the size of a request. Note that the iovec_dat
+ * structure will be unusable after calc_iovec_size_s.
+ */
+ int size;
+ int i;
+
+ size= 0;
+ i= 0;
+ while (i < iovp->iod_iovec_s)
+ {
+ if (i >= IOVEC_NR)
+ {
+ dp_next_iovec_s(iovp);
+ i= 0;
+ continue;
+ }
+ size += iovp->iod_iovec[i].iov_size;
+ i++;
+ }
+ return size;
+}
+
/*===========================================================================*
* reply *
*===========================================================================*/
panic("DP8390", "get_userdata: sys_vircopy failed", r);
}
+/*===========================================================================*
+ * get_userdata_s *
+ *===========================================================================*/
+static void get_userdata_s(user_proc, grant, offset, count, loc_addr)
+int user_proc;
+cp_grant_id_t grant;
+vir_bytes offset;
+vir_bytes count;
+void *loc_addr;
+{
+ int r;
+
+ r= sys_safecopyfrom(user_proc, grant, offset,
+ (vir_bytes)loc_addr, count, D);
+ if (r != OK)
+ panic("DP8390", "get_userdata: sys_safecopyfrom failed", r);
+}
+
/*===========================================================================*
* put_userdata *
*===========================================================================*/
panic("DP8390", "put_userdata: sys_vircopy failed", r);
}
+/*===========================================================================*
+ * put_userdata_s *
+ *===========================================================================*/
+static void put_userdata_s(user_proc, grant, count, loc_addr)
+int user_proc;
+cp_grant_id_t grant;
+size_t count;
+void *loc_addr;
+{
+ int r;
+
+ r= sys_safecopyto(user_proc, grant, 0, (vir_bytes)loc_addr,
+ count, D);
+ if (r != OK)
+ panic("DP8390", "put_userdata: sys_safecopyto failed", r);
+}
+
u8_t inb(port_t port)
{
int r;
struct dpeth;
struct iovec_dat;
+struct iovec_dat_s;
_PROTOTYPE( typedef void (*dp_initf_t), (struct dpeth *dep) );
_PROTOTYPE( typedef void (*dp_stopf_t), (struct dpeth *dep) );
_PROTOTYPE( typedef void (*dp_user2nicf_t), (struct dpeth *dep,
struct iovec_dat *iovp, vir_bytes offset,
int nic_addr, vir_bytes count) );
+_PROTOTYPE( typedef void (*dp_user2nicf_s_t), (struct dpeth *dep,
+ struct iovec_dat_s *iovp, vir_bytes offset,
+ int nic_addr, vir_bytes count) );
_PROTOTYPE( typedef void (*dp_nic2userf_t), (struct dpeth *dep,
int nic_addr, struct iovec_dat *iovp,
vir_bytes offset, vir_bytes count) );
+_PROTOTYPE( typedef void (*dp_nic2userf_s_t), (struct dpeth *dep,
+ int nic_addr, struct iovec_dat_s *iovp,
+ vir_bytes offset, vir_bytes count) );
#if 0
_PROTOTYPE( typedef void (*dp_getheaderf_t), (struct dpeth *dep,
int page, struct dp_rcvhdr *h, u16_t *eth_type) );
vir_bytes iod_iovec_addr;
} iovec_dat_t;
+typedef struct iovec_dat_s
+{
+ iovec_s_t iod_iovec[IOVEC_NR];
+ int iod_iovec_s;
+ int iod_proc_nr;
+ cp_grant_id_t iod_grant;
+ vir_bytes iod_iovec_offset;
+} iovec_dat_s_t;
+
#define SENDQ_NR 2 /* Maximum size of the send queue */
#define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */
*/
port_t de_base_port;
phys_bytes de_linmem;
+ char *de_locmem;
int de_irq;
int de_int_pending;
irq_hook_t de_hook;
int de_mode;
eth_stat_t de_stat;
iovec_dat_t de_read_iovec;
+ iovec_dat_s_t de_read_iovec_s;
+ int de_safecopy_read;
iovec_dat_t de_write_iovec;
+ iovec_dat_s_t de_write_iovec_s;
iovec_dat_t de_tmp_iovec;
+ iovec_dat_s_t de_tmp_iovec_s;
vir_bytes de_read_s;
int de_client;
message de_sendmsg;
dp_user2nicf_t de_user2nicf;
+ dp_user2nicf_s_t de_user2nicf_s;
dp_nic2userf_t de_nic2userf;
+ dp_nic2userf_s_t de_nic2userf_s;
dp_getblock_t de_getblockf;
} dpeth_t;
{
phys_bytes phys_user;
int bytes, ix = 0;
- iovec_dat_t *iovp = &dep->de_write_iovec;
- int padding = pktsize;
+ iovec_dat_s_t *iovp = &dep->de_write_iovec;
+ int r, padding = pktsize;
do { /* Writes chuncks of packet from user buffers */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes > pktsize) bytes = pktsize;
/* Writes from user buffer to Tx FIFO */
- outsb(dep->de_data_port, iovp->iod_proc_nr,
- (void*)(iovp->iod_iovec[ix].iov_addr), bytes);
+ r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, 0, bytes);
+ if (r != OK)
+ panic(__FILE__, "el3_write_fifo: sys_safe_insb failed", r);
+
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
+#include <assert.h>
/*
** File: 8390.c May 02, 2000
**
#include "8390.h"
+#if 0
#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)
+#endif
+#if 0
+#define sys_user2nic_s(srcProc,grant,dstOffs,length) \
+ sys_safecopyfrom((srcProc),(grant),0, \
+ (vir_bytes)(dstOffs),length,dep->de_memsegm)
+#endif
-static const char RdmaErrMsg[] = "remote dma failed to complete";
+static char RdmaErrMsg[] = "remote dma failed to complete";
/*
** Name: void ns_rw_setup(dpeth_t *dep, int mode, int size, u16_t offset);
*/
static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
{
-
+ panic(__FILE__, "mem_getblock: not converted to safecopies", NO_NUM);
+#if 0
sys_nic2mem(dep->de_linmem + offset, SELF, dst, size);
return;
+#endif
}
/*
static void mem_nic2user(dpeth_t * dep, int pageno, int pktsize)
{
phys_bytes offset, phys_user;
- iovec_dat_t *iovp = &dep->de_read_iovec;
+ iovec_dat_s_t *iovp = &dep->de_read_iovec;
int bytes, ix = 0;
+ panic(__FILE__, "mem_nic2user: not converted to safecopies", NO_NUM);
+#if 0
+
/* Computes shared memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
/* Circular buffer wrap-around */
bytes = dep->de_stoppage * DP_PAGESIZE - offset;
- sys_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,
- iovp->iod_iovec[ix].iov_addr, bytes);
+ sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, 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_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,
- iovp->iod_iovec[ix].iov_addr, bytes);
+ sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, bytes);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
+#endif
}
/*
static void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
phys_bytes offset, phys_user;
- iovec_dat_t *iovp = &dep->de_write_iovec;
+ iovec_dat_s_t *iovp = &dep->de_write_iovec;
int bytes, ix = 0;
+ panic(__FILE__, "mem_user2nic: not converted to safecopies", NO_NUM);
+#if 0
+
/* Computes shared memory address */
offset = pageno * DP_PAGESIZE;
if (bytes > pktsize) bytes = pktsize;
/* Reads from user area to board (shared memory) */
- sys_user2nic(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr,
+ sys_user2nic_s(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
dep->de_linmem + offset, bytes);
offset += bytes;
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
+#endif
}
/*
static void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)
{
phys_bytes phys_user;
- iovec_dat_t *iovp = &dep->de_read_iovec;
- unsigned offset; int bytes, ix = 0;
+ iovec_dat_s_t *iovp = &dep->de_read_iovec;
+ unsigned offset, iov_offset; int r, bytes, ix = 0;
/* Computes memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
ns_rw_setup(dep, CR_DM_RR, ((offset + pktsize) > (dep->de_stoppage * DP_PAGESIZE)) ?
(dep->de_stoppage * DP_PAGESIZE) - offset : pktsize, offset);
+ iov_offset= 0;
do { /* Reads chuncks of packet into user area */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of a chunck */
/* Circular buffer wrap-around */
bytes = dep->de_stoppage * DP_PAGESIZE - offset;
- insb(dep->de_data_port, iovp->iod_proc_nr, (void*)(iovp->iod_iovec[ix].iov_addr), bytes);
+ r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
+ if (r != OK)
+ {
+ panic(__FILE__, "pio_nic2user: sys_safe_insb failed",
+ r);
+ }
pktsize -= bytes;
- iovp->iod_iovec[ix].iov_addr += bytes;
+ iov_offset += bytes;
bytes = iovp->iod_iovec[ix].iov_size - bytes;
if (bytes > pktsize) bytes = pktsize;
offset = dep->de_startpage * DP_PAGESIZE;
ns_rw_setup(dep, CR_DM_RR, pktsize, offset);
}
- insb(dep->de_data_port, iovp->iod_proc_nr, (void*)(iovp->iod_iovec[ix].iov_addr), bytes);
+ r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
+ if (r != OK)
+ panic(__FILE__, "pio_nic2user: sys_safe_insb failed", r);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
+ iov_offset= 0;
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
static void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
phys_bytes phys_user;
- iovec_dat_t *iovp = &dep->de_write_iovec;
- int bytes, ix = 0;
+ iovec_dat_s_t *iovp = &dep->de_write_iovec;
+ int r, bytes, ix = 0;
/* Sets up board for writing */
ns_rw_setup(dep, CR_DM_RW, pktsize, pageno * DP_PAGESIZE);
bytes = iovp->iod_iovec[ix].iov_size; /* Size of chunck */
if (bytes > pktsize) bytes = pktsize;
- outsb(dep->de_data_port, iovp->iod_proc_nr,
- (void*)(iovp->iod_iovec[ix].iov_addr), bytes);
+ r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
+ iovp->iod_iovec[ix].iov_grant, 0, bytes);
+ if (r != OK)
+ panic(__FILE__, "pio_user2nic: sys_safe_outsb failed", r);
if (++ix >= IOVEC_NR) { /* Next buffer of I/O vector */
dp_next_iovec(iovp);
## Makefile for ISA ethernet drivers May 02, 2000
##
## $Log$
+## Revision 1.4 2006/07/10 12:43:38 philip
+## Safecopy support in ethernet drivers.
+##
## Revision 1.3 2005/07/19 13:21:48 jnherder
## Renamed src/lib/utils to src/lib/sysutil --- because of new src/lib/util
##
CC = exec cc
LD = $(CC)
CPPFLAGS= -I.. -I/usr/include -Ddebug=$(debug)
-CFLAGS = -ws $(CPPFLAGS)
+CFLAGS = $(CPPFLAGS)
LDFLAGS = -i -o $@
SRCS = 3c501.c 3c509.c 3c503.c ne.c wd.c 8390.c devio.c netbuff.c dp.c
*/
PUBLIC unsigned int inb(unsigned short port)
{
- unsigned int value;
+ unsigned long value;
int rc;
if ((rc = sys_inb(port, &value)) != OK) warning("inb", rc);
*/
PUBLIC unsigned int inw(unsigned short port)
{
- unsigned int value;
+ unsigned long value;
int rc;
if ((rc = sys_inw(port, &value)) != OK) warning("inw", rc);
+#include <assert.h>
/*
** File: eth.c Version 1.00, Jan. 14, 1997
**
** +------------+---------+---------+--------+-------+---------+
** | DL_READV | port nr | proc nr | count | | address | (6)
** +------------+---------+---------+--------+-------+---------+
-** | DL_INIT | port nr | proc nr | | mode | address | (7)
+** | DL_CONF | port nr | proc nr | | mode | address | (7)
** +------------+---------+---------+--------+-------+---------+
** | DL_STOP | port_nr | | | | | (8)
** +------------+---------+---------+--------+-------+---------+
**
** m_type m3_i1 m3_i2 m3_ca1
** +------------+---------+---------+---------------+
-** |DL_INIT_REPL| port nr |last port| ethernet addr | (20)
+** |DL_CONF_REPL| port nr |last port| ethernet addr | (20)
** +------------+---------+---------+---------------+
**
** $Id$
{ 0x280, 10, 0xCC000, "DPETH1", },
};
-static const char CopyErrMsg[] = "unable to read/write user data";
-static const char PortErrMsg[] = "illegal port";
-static const char RecvErrMsg[] = "receive failed";
-static const char SendErrMsg[] = "send failed";
-static const char SizeErrMsg[] = "illegal packet size";
-static const char TypeErrMsg[] = "illegal message type";
-static const char DevName[] = "eth#?";
+static char CopyErrMsg[] = "unable to read/write user data";
+static char PortErrMsg[] = "illegal port";
+static char RecvErrMsg[] = "receive failed";
+static char SendErrMsg[] = "send failed";
+static char SizeErrMsg[] = "illegal packet size";
+static char TypeErrMsg[] = "illegal message type";
+static char DevName[] = "eth#?";
static void do_getname(message *mp);
}
/*
-** Name: void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
+** Name: void get_userdata_s(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
** Function: Copies data from user area.
*/
-static void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
+static void get_userdata_s(int user_proc, cp_grant_id_t grant,
+ vir_bytes offset, int count, void *loc_addr)
{
int rc;
vir_bytes len;
len = (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_t);
- if ((rc = sys_datacopy(user_proc, user_addr, SELF, (vir_bytes)loc_addr, len)) != OK)
+ if ((rc = sys_safecopyfrom(user_proc, grant, 0, (vir_bytes)loc_addr, len, D)) != OK)
panic(DevName, CopyErrMsg, rc);
return;
}
} else /* Port number is out of range */
port = ENXIO;
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = port;
reply_mess.m3_i2 = DE_PORT_NR;
DEBUG(printf("\t reply %d\n", reply_mess.m_type));
** Name: void dp_next_iovec(iovec_dat_t *iovp)
** Function: Retrieves data from next iovec element.
*/
-PUBLIC void dp_next_iovec(iovec_dat_t * iovp)
+PUBLIC void dp_next_iovec(iovec_dat_s_t * iovp)
{
iovp->iod_iovec_s -= IOVEC_NR;
- iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
- get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
+ iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
+ get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant, iovp->iod_iovec_offset,
iovp->iod_iovec_s, iovp->iod_iovec);
return;
}
** Name: int calc_iovec_size(iovec_dat_t *iovp)
** Function: Compute the size of a request.
*/
-static int calc_iovec_size(iovec_dat_t * iovp)
+static int calc_iovec_size(iovec_dat_s_t * iovp)
{
int size, ix;
}
/*
-** Name: void do_vwrite(message *mp, int vectored)
+** Name: void do_vwrite_s(message *mp, int vectored)
** Function:
*/
-static void do_vwrite(message * mp, int vectored)
+static void do_vwrite_s(message * mp)
{
int port, size;
dpeth_t *dep;
panic(dep->de_name, "send already in progress ", NO_NUM);
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
- if (vectored) {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- mp->DL_COUNT, dep->de_write_iovec.iod_iovec);
- dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT;
- dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
- size = calc_iovec_size(&dep->de_write_iovec);
- } else {
- dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
- dep->de_write_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT;
- dep->de_write_iovec.iod_iovec_s = 1;
- dep->de_write_iovec.iod_iovec_addr = 0;
- }
+ get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ mp->DL_COUNT, dep->de_write_iovec.iod_iovec);
+ dep->de_write_iovec.iod_iovec_s = mp->DL_COUNT;
+ dep->de_write_iovec.iod_grant = (vir_bytes) mp->DL_GRANT;
+ dep->de_write_iovec.iod_iovec_offset = 0;
+ size = calc_iovec_size(&dep->de_write_iovec);
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
panic(dep->de_name, SizeErrMsg, size);
}
/*
-** Name: void do_vread(message *mp, int vectored)
+** Name: void do_vread_s(message *mp, int vectored)
** Function:
*/
-static void do_vread(message * mp, int vectored)
+static void do_vread_s(message * mp)
{
int port, size;
dpeth_t *dep;
panic(dep->de_name, "read already in progress", NO_NUM);
dep->de_read_iovec.iod_proc_nr = mp->DL_PROC;
- if (vectored) {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
- dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
- dep->de_read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
- size = calc_iovec_size(&dep->de_read_iovec);
- } else {
- dep->de_read_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
- dep->de_read_iovec.iod_iovec[0].iov_size = size = mp->DL_COUNT;
- dep->de_read_iovec.iod_iovec_s = 1;
- dep->de_read_iovec.iod_iovec_addr = 0;
- }
+ get_userdata_s(mp->DL_PROC, (vir_bytes) mp->DL_GRANT, 0,
+ mp->DL_COUNT, dep->de_read_iovec.iod_iovec);
+ dep->de_read_iovec.iod_iovec_s = mp->DL_COUNT;
+ dep->de_read_iovec.iod_grant = (vir_bytes) mp->DL_GRANT;
+ dep->de_read_iovec.iod_iovec_offset = 0;
+ size = calc_iovec_size(&dep->de_read_iovec);
if (size < ETH_MAX_PACK_SIZE) panic(dep->de_name, SizeErrMsg, size);
dep->de_flags |= DEF_READING;
}
/*
-** Name: void do_getstat(message *mp)
+** Name: void do_getstat_s(message *mp)
** Function: Reports device statistics.
*/
-static void do_getstat(message * mp)
+static void do_getstat_s(message * mp)
{
int port, rc;
dpeth_t *dep;
dep->de_client = mp->DL_PROC;
if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep);
- if ((rc = sys_datacopy(SELF, (vir_bytes)&dep->de_stat,
- mp->DL_PROC, (vir_bytes)mp->DL_ADDR,
- (vir_bytes) sizeof(dep->de_stat))) != OK)
+ if ((rc = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ (vir_bytes)&dep->de_stat,
+ (vir_bytes) sizeof(dep->de_stat), 0)) != OK)
panic(DevName, CopyErrMsg, rc);
reply(dep, OK);
return;
case DEV_PING: /* Status request from RS */
notify(m.m_source);
continue;
- case DL_WRITE: /* Write message to device */
- do_vwrite(&m, FALSE);
- break;
- case DL_WRITEV: /* Write message to device */
- do_vwrite(&m, TRUE);
- break;
- case DL_READ: /* Read message from device */
- do_vread(&m, FALSE);
+ case DL_WRITEV_S: /* Write message to device */
+ do_vwrite_s(&m);
break;
- case DL_READV: /* Read message from device */
- do_vread(&m, TRUE);
+ case DL_READV_S: /* Read message from device */
+ do_vread_s(&m);
break;
- case DL_INIT: /* Initialize device */
+ case DL_CONF: /* Initialize device */
do_init(&m);
break;
- case DL_GETSTAT: /* Get device statistics */
- do_getstat(&m);
+ case DL_GETSTAT_S: /* Get device statistics */
+ do_getstat_s(&m);
break;
case DL_GETNAME:
do_getname(&m);
** Interface description for ethernet device driver
**
** $Log$
+** Revision 1.5 2006/07/10 12:43:38 philip
+** Safecopy support in ethernet drivers.
+**
** Revision 1.4 2005/09/04 18:52:16 beng
** Giovanni's fixes to dpeth:
** Date: Sat, 03 Sep 2005 11:05:22 +0200
#define SENDQ_NR 2 /* Size of the send queue */
#define IOVEC_NR 16 /* Number of IOVEC entries at a time */
-typedef struct iovec_dat {
- iovec_t iod_iovec[IOVEC_NR];
+typedef struct iovec_dat_s {
+ iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
int iod_proc_nr;
- vir_bytes iod_iovec_addr;
-} iovec_dat_t;
+ cp_grant_id_t iod_grant;
+ vir_bytes iod_iovec_offset;
+} iovec_dat_s_t;
typedef struct dpeth {
/* The de_base_port field is the starting point of the probe. The
#define DEM_ENABLED 0x0002
/* Temporary storage for RECV/SEND requests */
- iovec_dat_t de_read_iovec;
- iovec_dat_t de_write_iovec;
+ iovec_dat_s_t de_read_iovec;
+ iovec_dat_s_t de_write_iovec;
vir_bytes de_read_s;
vir_bytes de_send_s;
int de_client;
*/
/* dp.c */
-void dp_next_iovec(iovec_dat_t * iovp);
+void dp_next_iovec(iovec_dat_s_t * iovp);
/* devio.c */
#if defined USE_IOPL
{
phys_bytes phys_user;
int bytes, ix = 0;
- iovec_dat_t *iovp = &dep->de_read_iovec;
- int pktsize = rxbuff->size;
+ iovec_dat_s_t *iovp = &dep->de_read_iovec;
+ int r, pktsize = rxbuff->size;
char *buffer = rxbuff->buffer;
do { /* Reads chuncks of packet into user buffers */
if (bytes > pktsize) bytes = pktsize;
/* Reads from Rx buffer to user area */
- sys_datacopy(SELF, (vir_bytes)buffer, iovp->iod_proc_nr,
- iovp->iod_iovec[ix].iov_addr, bytes);
+ r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
+ (vir_bytes)buffer, bytes, D);
+ if (r != OK)
+ panic(__FILE__, "mem2user: sys_safecopyto failed", r);
buffer += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
{
phys_bytes phys_user;
int bytes, ix = 0;
- iovec_dat_t *iovp = &dep->de_write_iovec;
- int pktsize = txbuff->size;
+ iovec_dat_s_t *iovp = &dep->de_write_iovec;
+ int r, pktsize = txbuff->size;
char *buffer = txbuff->buffer;
do { /* Reads chuncks of packet from user buffers */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes > pktsize) bytes = pktsize;
- sys_datacopy(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr,
- SELF, (vir_bytes)buffer, bytes);
+ r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
+ 0, (vir_bytes)buffer, bytes, D);
+ if (r != OK)
+ panic(__FILE__, "user2mem: sys_safecopyfrom failed", r);
buffer += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
all build: $(DRIVER)
$(DRIVER): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
- install -S 4096 $(DRIVER)
+ install -S 8k $(DRIVER)
# install with other drivers
install: /usr/sbin/$(DRIVER)
*
* The valid messages and their parameters are:
*
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
- * |------------+----------+---------+----------+---------+---------|
- * | HARDINT | | | | | |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_INIT | port nr | proc nr | mode | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_STOP | port_nr | | | | |
- * |------------|----------|---------|----------|---------|---------|
+ * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
+ * |------------+----------+---------+----------+---------+---------+---------|
+ * | HARDINT | | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITE | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READ | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV_S | port nr | proc nr | count | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_CONF | port nr | proc nr | | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_GETSTAT | port nr | proc nr | | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_STOP | port_nr | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
*
* The messages sent are:
*
*
* m_type m3_i1 m3_i2 m3_ca1
* |-------------+---------+-----------+---------------|
- * |DL_INIT_REPLY| port nr | last port | ethernet addr |
+ * |DL_CONF_REPLY| port nr | last port | ethernet addr |
* |-------------+---------+-----------+---------------|
*
* Created: Nov 2004 by Philip Homburg <philip@f-mnx.phicoh.com>
u8_t fxp_conf_bytes[CC_BYTES_NR];
char fxp_name[sizeof("fxp#n")];
iovec_t fxp_iovec[IOVEC_NR];
+ iovec_s_t fxp_iovec_s[IOVEC_NR];
}
fxp_t;
_PROTOTYPE( static void fxp_rec_mode, (fxp_t *fp) );
_PROTOTYPE( static void fxp_writev, (message *mp, int from_int,
int vectored) );
+_PROTOTYPE( static void fxp_writev_s, (message *mp, int from_int) );
_PROTOTYPE( static void fxp_readv, (message *mp, int from_int,
int vectored) );
+_PROTOTYPE( static void fxp_readv_s, (message *mp, int from_int) );
_PROTOTYPE( static void fxp_do_conf, (fxp_t *fp) );
_PROTOTYPE( static void fxp_cu_ptr_cmd, (fxp_t *fp, int cmd,
phys_bytes bus_addr, int check_idle) );
phys_bytes bus_addr, int check_idle) );
_PROTOTYPE( static void fxp_restart_ru, (fxp_t *fp) );
_PROTOTYPE( static void fxp_getstat, (message *mp) );
+_PROTOTYPE( static void fxp_getstat_s, (message *mp) );
_PROTOTYPE( static void fxp_getname, (message *mp) );
_PROTOTYPE( static int fxp_handler, (fxp_t *fp) );
_PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
_PROTOTYPE( static void fxp_stop, (void));
_PROTOTYPE( static void reply, (fxp_t *fp, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
-_PROTOTYPE( static void put_userdata, (int user_proc,
- vir_bytes user_addr, vir_bytes count, void *loc_addr) );
_PROTOTYPE( static u16_t eeprom_read, (fxp_t *fp, int reg) );
_PROTOTYPE( static void eeprom_addrsize, (fxp_t *fp) );
_PROTOTYPE( static u16_t mii_read, (fxp_t *fp, int reg) );
case DEV_PING: notify(m.m_source); continue;
case DL_WRITEV: fxp_writev(&m, FALSE, TRUE); break;
case DL_WRITE: fxp_writev(&m, FALSE, FALSE); break;
-#if 0
- case DL_READ: fxp_vread(&m, FALSE); break;
-#endif
+ case DL_WRITEV_S: fxp_writev_s(&m, FALSE); break;
+ case DL_READ: fxp_readv(&m, FALSE, FALSE); break;
case DL_READV: fxp_readv(&m, FALSE, TRUE); break;
- case DL_INIT: fxp_init(&m); break;
+ case DL_READV_S: fxp_readv_s(&m, FALSE); break;
+ case DL_CONF: fxp_init(&m); break;
case DL_GETSTAT: fxp_getstat(&m); break;
+ case DL_GETSTAT_S: fxp_getstat_s(&m); break;
case DL_GETNAME: fxp_getname(&m); break;
case HARD_INT:
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
port = mp->DL_PORT;
if (port < 0 || port >= FXP_PORT_NR)
{
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
if (fp->fxp_mode == FM_DISABLED)
{
/* Probe failed, or the device is configured off. */
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
fp->fxp_client = mp->m_source;
fxp_rec_mode(fp);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = FXP_PORT_NR;
*(ether_addr_t *) reply_mess.m3_ca1 = fp->fxp_address;
reply(fp, OK, FALSE);
}
+/*===========================================================================*
+ * fxp_writev_s *
+ *===========================================================================*/
+static void fxp_writev_s(mp, from_int)
+message *mp;
+int from_int;
+{
+ cp_grant_id_t iov_grant;
+ vir_bytes iov_offset;
+ int i, j, n, o, r, s, dl_port, count, size, prev_head;
+ int fxp_client, fxp_tx_nbuf, fxp_tx_head;
+ u16_t tx_command;
+ fxp_t *fp;
+ iovec_s_t *iovp;
+ struct tx *txp, *prev_txp;
+
+ dl_port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (dl_port < 0 || dl_port >= FXP_PORT_NR)
+ panic("FXP","fxp_writev: illegal port", dl_port);
+ fp= &fxp_table[dl_port];
+ fxp_client= mp->DL_PROC;
+ fp->fxp_client= fxp_client;
+
+ assert(fp->fxp_mode == FM_ENABLED);
+ assert(fp->fxp_flags & FF_ENABLED);
+
+ if (from_int)
+ {
+ assert(fp->fxp_flags & FF_SEND_AVAIL);
+ fp->fxp_flags &= ~FF_SEND_AVAIL;
+ fp->fxp_tx_alive= TRUE;
+ }
+
+ if (fp->fxp_tx_idle)
+ {
+ txp= fp->fxp_tx_buf;
+ fxp_tx_head= 0; /* lint */
+ prev_txp= NULL; /* lint */
+ }
+ else
+ {
+ fxp_tx_nbuf= fp->fxp_tx_nbuf;
+ prev_head= fp->fxp_tx_head;
+ fxp_tx_head= prev_head+1;
+ if (fxp_tx_head == fxp_tx_nbuf)
+ fxp_tx_head= 0;
+ assert(fxp_tx_head < fxp_tx_nbuf);
+
+ if (fxp_tx_head == fp->fxp_tx_tail)
+ {
+ /* Send queue is full */
+ assert(!(fp->fxp_flags & FF_SEND_AVAIL));
+ fp->fxp_flags |= FF_SEND_AVAIL;
+ goto suspend;
+ }
+
+ prev_txp= &fp->fxp_tx_buf[prev_head];
+ txp= &fp->fxp_tx_buf[fxp_tx_head];
+ }
+
+ assert(!(fp->fxp_flags & FF_SEND_AVAIL));
+ assert(!(fp->fxp_flags & FF_PACK_SENT));
+
+ iov_grant= mp->DL_GRANT;
+
+ size= 0;
+ o= 0;
+ iov_offset= 0;
+ for (i= 0; i<count; i += IOVEC_NR,
+ iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0]))
+ {
+ n= IOVEC_NR;
+ if (i+n > count)
+ n= count-i;
+ r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset,
+ (vir_bytes)fp->fxp_iovec_s,
+ n * sizeof(fp->fxp_iovec_s[0]), D);
+ if (r != OK)
+ panic("FXP","fxp_writev: sys_safecopyfrom failed", r);
+
+ for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++)
+ {
+ s= iovp->iov_size;
+ if (size + s > ETH_MAX_PACK_SIZE_TAGGED)
+ {
+ panic("FXP","fxp_writev: invalid packet size",
+ size + s);
+ }
+
+ r= sys_safecopyfrom(fxp_client, iovp->iov_grant,
+ 0, (vir_bytes)(txp->tx_buf+o), s, D);
+ if (r != OK)
+ {
+ panic("FXP",
+ "fxp_writev_s: sys_safecopyfrom failed",
+ r);
+ }
+ size += s;
+ o += s;
+ }
+ }
+ if (size < ETH_MIN_PACK_SIZE)
+ panic("FXP","fxp_writev: invalid packet size", size);
+
+ txp->tx_status= 0;
+ txp->tx_command= TXC_EL | CBL_XMIT;
+ txp->tx_tbda= TX_TBDA_NIL;
+ txp->tx_size= TXSZ_EOF | size;
+ txp->tx_tthresh= fp->fxp_tx_threshold;
+ txp->tx_ntbd= 0;
+ if (fp->fxp_tx_idle)
+ {
+ fp->fxp_tx_idle= 0;
+ fp->fxp_tx_head= fp->fxp_tx_tail= 0;
+
+ fxp_cu_ptr_cmd(fp, SC_CU_START, fp->fxp_tx_busaddr,
+ TRUE /* check idle */);
+ }
+ else
+ {
+ /* Link new request in transmit list */
+ tx_command= prev_txp->tx_command;
+ assert(tx_command == (TXC_EL | CBL_XMIT));
+ prev_txp->tx_command= CBL_XMIT;
+ fp->fxp_tx_head= fxp_tx_head;
+ }
+
+ fp->fxp_flags |= FF_PACK_SENT;
+
+ /* If the interrupt handler called, don't send a reply. The reply
+ * will be sent after all interrupts are handled.
+ */
+ if (from_int)
+ return;
+ reply(fp, OK, FALSE);
+ return;
+
+suspend:
+ if (from_int)
+ panic("FXP","fxp: should not be sending\n", NO_NUM);
+
+ fp->fxp_tx_mess= *mp;
+ reply(fp, OK, FALSE);
+}
+
/*===========================================================================*
* fxp_readv *
*===========================================================================*/
reply(fp, OK, FALSE);
}
+/*===========================================================================*
+ * fxp_readv_s *
+ *===========================================================================*/
+static void fxp_readv_s(mp, from_int)
+message *mp;
+int from_int;
+{
+ int i, j, n, o, r, s, dl_port, fxp_client, count, size,
+ fxp_rx_head, fxp_rx_nbuf;
+ cp_grant_id_t iov_grant;
+ port_t port;
+ unsigned packlen;
+ vir_bytes iov_offset;
+ u16_t rfd_status;
+ u16_t rfd_res;
+ u8_t scb_status;
+ fxp_t *fp;
+ iovec_s_t *iovp;
+ struct rfd *rfdp, *prev_rfdp;
+
+ dl_port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (dl_port < 0 || dl_port >= FXP_PORT_NR)
+ panic("FXP","fxp_readv: illegal port", dl_port);
+ fp= &fxp_table[dl_port];
+ fxp_client= mp->DL_PROC;
+ fp->fxp_client= fxp_client;
+
+ assert(fp->fxp_mode == FM_ENABLED);
+ assert(fp->fxp_flags & FF_ENABLED);
+
+ port= fp->fxp_base_port;
+
+ fxp_rx_head= fp->fxp_rx_head;
+ rfdp= &fp->fxp_rx_buf[fxp_rx_head];
+
+ rfd_status= rfdp->rfd_status;
+ if (!(rfd_status & RFDS_C))
+ {
+ /* Receive buffer is empty, suspend */
+ goto suspend;
+ }
+
+ if (!rfd_status & RFDS_OK)
+ {
+ /* Not OK? What happened? */
+ assert(0);
+ }
+ else
+ {
+ assert(!(rfd_status & (RFDS_CRCERR | RFDS_ALIGNERR |
+ RFDS_OUTOFBUF | RFDS_DMAOVR | RFDS_TOOSHORT |
+ RFDS_RXERR)));
+ }
+ rfd_res= rfdp->rfd_res;
+ assert(rfd_res & RFDR_EOF);
+ assert(rfd_res & RFDR_F);
+
+ packlen= rfd_res & RFDSZ_SIZE;
+
+ iov_grant = mp->DL_GRANT;
+
+ size= 0;
+ o= 0;
+ iov_offset= 0;
+ for (i= 0; i<count; i += IOVEC_NR,
+ iov_offset += IOVEC_NR * sizeof(fp->fxp_iovec_s[0]))
+ {
+ n= IOVEC_NR;
+ if (i+n > count)
+ n= count-i;
+ r= sys_safecopyfrom(fxp_client, iov_grant, iov_offset,
+ (vir_bytes)fp->fxp_iovec_s,
+ n * sizeof(fp->fxp_iovec_s[0]), D);
+ if (r != OK)
+ panic("FXP","fxp_readv_s: sys_safecopyfrom failed", r);
+
+ for (j= 0, iovp= fp->fxp_iovec_s; j<n; j++, iovp++)
+ {
+ s= iovp->iov_size;
+ if (size + s > packlen)
+ {
+ assert(packlen > size);
+ s= packlen-size;
+ }
+
+ r= sys_safecopyto(fxp_client, iovp->iov_grant,
+ 0, (vir_bytes)(rfdp->rfd_buf+o), s, D);
+ if (r != OK)
+ {
+ panic("FXP","fxp_readv: sys_safecopyto failed",
+ r);
+ }
+
+ size += s;
+ if (size == packlen)
+ break;
+ o += s;
+ }
+ if (size == packlen)
+ break;
+ }
+ if (size < packlen)
+ {
+ assert(0);
+ }
+
+ fp->fxp_read_s= packlen;
+ fp->fxp_flags= (fp->fxp_flags & ~FF_READING) | FF_PACK_RECV;
+
+ /* Re-init the current buffer */
+ rfdp->rfd_status= 0;
+ rfdp->rfd_command= RFDC_EL;
+ rfdp->rfd_reserved= 0;
+ rfdp->rfd_res= 0;
+ rfdp->rfd_size= sizeof(rfdp->rfd_buf);
+
+ fxp_rx_nbuf= fp->fxp_rx_nbuf;
+ if (fxp_rx_head == 0)
+ {
+ prev_rfdp= &fp->fxp_rx_buf[fxp_rx_nbuf-1];
+ }
+ else
+ prev_rfdp= &rfdp[-1];
+
+ assert(prev_rfdp->rfd_command & RFDC_EL);
+ prev_rfdp->rfd_command &= ~RFDC_EL;
+
+ fxp_rx_head++;
+ if (fxp_rx_head == fxp_rx_nbuf)
+ fxp_rx_head= 0;
+ assert(fxp_rx_head < fxp_rx_nbuf);
+ fp->fxp_rx_head= fxp_rx_head;
+
+ if (!from_int)
+ reply(fp, OK, FALSE);
+
+ return;
+
+suspend:
+ if (fp->fxp_rx_need_restart)
+ {
+ fp->fxp_rx_need_restart= 0;
+
+ /* Check the status of the RU */
+ scb_status= fxp_inb(port, SCB_STATUS);
+ if ((scb_status & SS_RUS_MASK) != SS_RU_NORES)
+ {
+ /* Race condition? */
+ printf("fxp_readv: restart race: 0x%x\n",
+ scb_status);
+ assert((scb_status & SS_RUS_MASK) == SS_RU_READY);
+ }
+ else
+ {
+ fxp_restart_ru(fp);
+ }
+ }
+ if (from_int)
+ {
+ assert(fp->fxp_flags & FF_READING);
+
+ /* No need to store any state */
+ return;
+ }
+
+ fp->fxp_rx_mess= *mp;
+ assert(!(fp->fxp_flags & FF_READING));
+ fp->fxp_flags |= FF_READING;
+
+ reply(fp, OK, FALSE);
+}
+
/*===========================================================================*
* fxp_do_conf *
*===========================================================================*/
message *mp;
{
clock_t t0,t1;
- int dl_port;
+ int r, dl_port;
port_t port;
fxp_t *fp;
u32_t *p;
stats.ets_CDheartbeat= 0;
stats.ets_OWC= fp->fxp_stat.sc_tx_latecol;
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (vir_bytes) sizeof(stats), &stats);
+ r= sys_vircopy(SELF, D, (vir_bytes)&stats,
+ mp->DL_PROC, D, (vir_bytes) mp->DL_ADDR, sizeof(stats));
+ if (r != OK)
+ panic(__FILE__,"fxp_getstat: sys_vircopy failed", r);
+ reply(fp, OK, FALSE);
+}
+
+
+/*===========================================================================*
+ * fxp_getstat_s *
+ *===========================================================================*/
+static void fxp_getstat_s(mp)
+message *mp;
+{
+ clock_t t0,t1;
+ int r, dl_port;
+ port_t port;
+ fxp_t *fp;
+ u32_t *p;
+ eth_stat_t stats;
+
+ dl_port = mp->DL_PORT;
+ if (dl_port < 0 || dl_port >= FXP_PORT_NR)
+ panic("FXP","fxp_getstat: illegal port", dl_port);
+ fp= &fxp_table[dl_port];
+ fp->fxp_client= mp->DL_PROC;
+
+ assert(fp->fxp_mode == FM_ENABLED);
+ assert(fp->fxp_flags & FF_ENABLED);
+
+ port= fp->fxp_base_port;
+
+ p= &fp->fxp_stat.sc_tx_fcp;
+ *p= 0;
+
+ /* The dump commmand doesn't take a pointer. Setting a pointer
+ * doesn't hurt though.
+ */
+ fxp_cu_ptr_cmd(fp, SC_CU_DUMP_SC, 0, FALSE /* do not check idle */);
+
+ getuptime(&t0);
+ do {
+ /* Wait for CU command to complete */
+ if (*p != 0)
+ break;
+ } while (getuptime(&t1)==OK && (t1-t0) < MICROS_TO_TICKS(1000));
+
+ if (*p == 0)
+ panic("FXP","fxp_getstat: CU command failed to complete", NO_NUM);
+ if (*p != SCM_DSC)
+ panic("FXP","fxp_getstat: bad magic", NO_NUM);
+
+ stats.ets_recvErr=
+ fp->fxp_stat.sc_rx_crc +
+ fp->fxp_stat.sc_rx_align +
+ fp->fxp_stat.sc_rx_resource +
+ fp->fxp_stat.sc_rx_overrun +
+ fp->fxp_stat.sc_rx_cd +
+ fp->fxp_stat.sc_rx_short;
+ stats.ets_sendErr=
+ fp->fxp_stat.sc_tx_maxcol +
+ fp->fxp_stat.sc_tx_latecol +
+ fp->fxp_stat.sc_tx_crs;
+ stats.ets_OVW= fp->fxp_stat.sc_rx_overrun;
+ stats.ets_CRCerr= fp->fxp_stat.sc_rx_crc;
+ stats.ets_frameAll= fp->fxp_stat.sc_rx_align;
+ stats.ets_missedP= fp->fxp_stat.sc_rx_resource;
+ stats.ets_packetR= fp->fxp_stat.sc_rx_good;
+ stats.ets_packetT= fp->fxp_stat.sc_tx_good;
+ stats.ets_transDef= fp->fxp_stat.sc_tx_defered;
+ stats.ets_collision= fp->fxp_stat.sc_tx_totcol;
+ stats.ets_transAb= fp->fxp_stat.sc_tx_maxcol;
+ stats.ets_carrSense= fp->fxp_stat.sc_tx_crs;
+ stats.ets_fifoUnder= fp->fxp_stat.sc_tx_underrun;
+ stats.ets_fifoOver= fp->fxp_stat.sc_rx_overrun;
+ stats.ets_CDheartbeat= 0;
+ stats.ets_OWC= fp->fxp_stat.sc_tx_latecol;
+
+ r= sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0, (vir_bytes)&stats,
+ sizeof(stats), D);
+ if (r != OK)
+ panic(__FILE__,"fxp_getstat_s: sys_safecopyto failed", r);
reply(fp, OK, FALSE);
}
fxp_readv(&fp->fxp_rx_mess, TRUE /* from int */,
TRUE /* vectored */);
}
+ else if (fp->fxp_rx_mess.m_type == DL_READV_S)
+ {
+ fxp_readv_s(&fp->fxp_rx_mess, TRUE /* from int */);
+
+ }
else
{
assert(fp->fxp_rx_mess.m_type == DL_READ);
TRUE /* from int */,
TRUE /* vectored */);
}
+ else if (fp->fxp_tx_mess.m_type == DL_WRITEV_S)
+ {
+ fxp_writev_s(&fp->fxp_tx_mess,
+ TRUE /* from int */);
+ }
else
{
assert(fp->fxp_tx_mess.m_type ==
panic("FXP","fxp: unable to mess_reply", NO_NUM);
}
-/*===========================================================================*
- * put_userdata *
- *===========================================================================*/
-static void put_userdata(user_proc, user_addr, count, loc_addr)
-int user_proc;
-vir_bytes user_addr;
-vir_bytes count;
-void *loc_addr;
-{
- int r;
-
- r= sys_vircopy(SELF, D, (vir_bytes)loc_addr,
- user_proc, D, user_addr, count);
- if (r != OK)
- panic("FXP","put_userdata: sys_vircopy failed", r);
-}
-
/*===========================================================================*
* eeprom_read *
*===========================================================================*/
*
* The valid messages and their parameters are:
*
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
- * |------------+----------+---------+----------+---------+---------|
- * | HARDINT | | | | | |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_INIT | port nr | proc nr | mode | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_STOP | port_nr | | | | |
- * |------------|----------|---------|----------|---------|---------|
+ * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
+ * |------------+----------+---------+----------+---------+---------+---------|
+ * | HARDINT | | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITE | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READ | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV_S | port nr | proc nr | count | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_CONF | port nr | proc nr | | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_GETSTAT | port nr | proc nr | | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_STOP | port_nr | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
*
* The messages sent are:
*
*
* m_type m3_i1 m3_i2 m3_ca1
* |------------+---------+-----------+---------------|
- * |DL_INIT_REPL| port nr | last port | ethernet addr |
+ * |DL_CONF_REPL| port nr | last port | ethernet addr |
* |------------|---------|-----------|---------------|
*
* Created: Jul 27, 2002 by Kazuya Kodama <kazuya@nii.ac.jp>
_PROTOTYPE( static void ec_reset, (ether_card_t *ec) );
_PROTOTYPE( static void ec_send, (ether_card_t *ec) );
_PROTOTYPE( static void ec_recv, (ether_card_t *ec) );
-_PROTOTYPE( static void do_vwrite,
- (message *mp, int from_int, int vectored) );
-_PROTOTYPE( static void do_vread, (message *mp, int vectored) );
-_PROTOTYPE( static void get_userdata,
- (int user_proc, vir_bytes user_addr,
+_PROTOTYPE( static void do_vwrite_s,
+ (message *mp, int from_int) );
+_PROTOTYPE( static void do_vread_s, (message *mp) );
+_PROTOTYPE( static void get_userdata_s,
+ (int user_proc, cp_grant_id_t grant, vir_bytes offset,
vir_bytes count, void *loc_addr) );
_PROTOTYPE( static void ec_user2nic,
(ether_card_t *dep, iovec_dat_t *iovp,
vir_bytes count) );
_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp) );
_PROTOTYPE( static void ec_next_iovec, (iovec_dat_t *iovp) );
-_PROTOTYPE( static void do_getstat, (message *mp) );
-_PROTOTYPE( static void put_userdata,
- (int user_proc,
- vir_bytes user_addr, vir_bytes count,
- void *loc_addr) );
+_PROTOTYPE( static void do_getstat_s, (message *mp) );
+_PROTOTYPE( static void put_userdata_s,
+ (int user_proc, cp_grant_id_t grant,
+ void *loc_addr, vir_bytes count) );
_PROTOTYPE( static void do_stop, (message *mp) );
_PROTOTYPE( static void do_getname, (message *mp) );
switch (m.m_type){
case DEV_PING: notify(m.m_source); continue;
- case DL_WRITE: do_vwrite(&m, FALSE, FALSE); break;
- case DL_WRITEV: do_vwrite(&m, FALSE, TRUE); break;
- case DL_READ: do_vread(&m, FALSE); break;
- case DL_READV: do_vread(&m, TRUE); break;
- case DL_INIT: do_init(&m); break;
- case DL_GETSTAT: do_getstat(&m); break;
+ case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
+ case DL_READV_S: do_vread_s(&m); break;
+ case DL_CONF: do_init(&m); break;
+ case DL_GETSTAT_S: do_getstat_s(&m); break;
case DL_STOP: do_stop(&m); break;
- case DL_GETNAME: do_getname(&m); break;
+ case DL_GETNAME: do_getname(&m); break;
case FKEY_PRESSED: lance_dump(); break;
/*case HARD_STOP: lance_stop(); break;*/
case SYS_SIG:
port = mp->DL_PORT;
if (port < 0 || port >= EC_PORT_NR_MAX)
{
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
if (ec->mode == EC_DISABLED)
{
/* Probe failed, or the device is configured off. */
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
ec->mac_address.ea_addr[4] =
ec->mac_address.ea_addr[5] = 0;
ec_confaddr(ec);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = EC_PORT_NR_MAX;
*(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
ec->client = mp->m_source;
ec_reinit(ec);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = EC_PORT_NR_MAX;
*(ether_addr_t *) reply_mess.m3_ca1 = ec->mac_address;
ec->flags &= ~ECF_SEND_AVAIL;
switch(ec->sendmsg.m_type)
{
- case DL_WRITE: do_vwrite(&ec->sendmsg, TRUE, FALSE); break;
- case DL_WRITEV: do_vwrite(&ec->sendmsg, TRUE, TRUE); break;
+ case DL_WRITEV_S: do_vwrite_s(&ec->sendmsg, TRUE); break;
default:
panic( "lance", "wrong type:", ec->sendmsg.m_type);
break;
}
/*===========================================================================*
- * do_vread *
+ * do_vread_s *
*===========================================================================*/
-static void do_vread(mp, vectored)
+static void do_vread_s(mp)
message *mp;
-int vectored;
{
int port, count, size;
ether_card_t *ec;
ec= &ec_table[port];
ec->client= mp->DL_PROC;
- if (vectored)
- {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (count > IOVEC_NR ? IOVEC_NR : count) *
- sizeof(iovec_t), ec->read_iovec.iod_iovec);
- ec->read_iovec.iod_iovec_s = count;
- ec->read_iovec.iod_proc_nr = mp->DL_PROC;
- ec->read_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
-
- ec->tmp_iovec = ec->read_iovec;
- size= calc_iovec_size(&ec->tmp_iovec);
- }
- else
- {
- ec->read_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
- ec->read_iovec.iod_iovec[0].iov_size = mp->DL_COUNT;
- ec->read_iovec.iod_iovec_s = 1;
- ec->read_iovec.iod_proc_nr = mp->DL_PROC;
- ec->read_iovec.iod_iovec_addr = 0;
+ get_userdata_s(mp->DL_PROC, (vir_bytes) mp->DL_GRANT, 0,
+ (count > IOVEC_NR ? IOVEC_NR : count) *
+ sizeof(iovec_s_t), ec->read_iovec.iod_iovec);
+ ec->read_iovec.iod_iovec_s = count;
+ ec->read_iovec.iod_proc_nr = mp->DL_PROC;
+ ec->read_iovec.iod_grant = (vir_bytes) mp->DL_GRANT;
+ ec->read_iovec.iod_iovec_offset = 0;
+
+ ec->tmp_iovec = ec->read_iovec;
+ size= calc_iovec_size(&ec->tmp_iovec);
- size= count;
- }
ec->flags |= ECF_READING;
ec_recv(ec);
}
/*===========================================================================*
- * do_vwrite *
+ * do_vwrite_s *
*===========================================================================*/
-static void do_vwrite(mp, from_int, vectored)
+static void do_vwrite_s(mp, from_int)
message *mp;
int from_int;
-int vectored;
{
int port, count, check;
ether_card_t *ec;
}
/* convert the message to write_iovec */
- if (vectored)
- {
- get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (count > IOVEC_NR ? IOVEC_NR : count) *
- sizeof(iovec_t), ec->write_iovec.iod_iovec);
+ get_userdata_s(mp->DL_PROC, mp->DL_GRANT, 0,
+ (count > IOVEC_NR ? IOVEC_NR : count) *
+ sizeof(iovec_s_t), ec->write_iovec.iod_iovec);
- ec->write_iovec.iod_iovec_s = count;
- ec->write_iovec.iod_proc_nr = mp->DL_PROC;
- ec->write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
+ ec->write_iovec.iod_iovec_s = count;
+ ec->write_iovec.iod_proc_nr = mp->DL_PROC;
+ ec->write_iovec.iod_grant = mp->DL_GRANT;
+ ec->write_iovec.iod_iovec_offset = 0;
- ec->tmp_iovec = ec->write_iovec;
- ec->write_s = calc_iovec_size(&ec->tmp_iovec);
- }
- else
- {
- ec->write_iovec.iod_iovec[0].iov_addr = (vir_bytes) mp->DL_ADDR;
- ec->write_iovec.iod_iovec[0].iov_size = mp->DL_COUNT;
-
- ec->write_iovec.iod_iovec_s = 1;
- ec->write_iovec.iod_proc_nr = mp->DL_PROC;
- ec->write_iovec.iod_iovec_addr = 0;
-
- ec->write_s = mp->DL_COUNT;
- }
+ ec->tmp_iovec = ec->write_iovec;
+ ec->write_s = calc_iovec_size(&ec->tmp_iovec);
/* copy write_iovec to the slot on DMA address */
ec_user2nic(ec, &ec->write_iovec, 0,
/*===========================================================================*
- * get_userdata *
+ * get_userdata_s *
*===========================================================================*/
-static void get_userdata(user_proc, user_addr, count, loc_addr)
+static void get_userdata_s(user_proc, grant, offset, count, loc_addr)
int user_proc;
-vir_bytes user_addr;
+cp_grant_id_t grant;
+vir_bytes offset;
vir_bytes count;
void *loc_addr;
{
- /*
- phys_bytes src;
-
- src = numap_local(user_proc, user_addr, count);
- if (!src)
- panic( "lance", "umap failed", NO_NUM);
-
- phys_copy(src, vir2phys(loc_addr), (phys_bytes) count);
- */
int cps;
- cps = sys_datacopy(user_proc, user_addr, SELF, (vir_bytes) loc_addr, count);
- if (cps != OK) printf("lance: warning, scopy failed: %d\n", cps);
+ cps = sys_safecopyfrom(user_proc, grant, offset,
+ (vir_bytes)loc_addr, count, D);
+ if (cps != OK)
+ panic(__FILE__,
+ "get_userdata_s: sys_safecopyfrom failed: %d\n", cps);
}
/*===========================================================================*
int nic_addr;
vir_bytes count;
{
- /*phys_bytes phys_hw, phys_user;*/
int bytes, i, r;
- /*
- phys_hw = vir2phys(nic_addr);
- */
i= 0;
while (count > 0)
{
if (bytes > count)
bytes = count;
- /*
- phys_user = numap_local(iovp->iod_proc_nr,
- iovp->iod_iovec[i].iov_addr + offset, bytes);
-
- phys_copy(phys_user, phys_hw, (phys_bytes) bytes);
- */
- if ( (r=sys_datacopy(iovp->iod_proc_nr, iovp->iod_iovec[i].iov_addr + offset,
- SELF, nic_addr, count )) != OK )
- panic( "lance", "sys_datacopy failed", r );
+ if ( (r=sys_safecopyfrom(iovp->iod_proc_nr,
+ iovp->iod_iovec[i].iov_grant, offset,
+ nic_addr, bytes, D )) != OK )
+ panic( __FILE__, "ec_user2nic: sys_safecopyfrom failed", r );
count -= bytes;
nic_addr += bytes;
vir_bytes offset;
vir_bytes count;
{
- /*phys_bytes phys_hw, phys_user;*/
int bytes, i, r;
- /*phys_hw = vir2phys(nic_addr);*/
-
i= 0;
while (count > 0)
{
bytes = iovp->iod_iovec[i].iov_size - offset;
if (bytes > count)
bytes = count;
- /*
- phys_user = numap_local(iovp->iod_proc_nr,
- iovp->iod_iovec[i].iov_addr + offset, bytes);
-
- phys_copy(phys_hw, phys_user, (phys_bytes) bytes);
- */
- if ( (r=sys_datacopy( SELF, nic_addr, iovp->iod_proc_nr, iovp->iod_iovec[i].iov_addr + offset, bytes )) != OK )
- panic( "lance", "sys_datacopy failed: ", r );
+ if ( (r=sys_safecopyto( iovp->iod_proc_nr, iovp->iod_iovec[i].iov_grant,
+ offset, nic_addr, bytes, D )) != OK )
+ panic( __FILE__, "ec_nic2user: sys_safecopyto failed: ", r );
count -= bytes;
nic_addr += bytes;
iovec_dat_t *iovp;
{
iovp->iod_iovec_s -= IOVEC_NR;
- iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
+ iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_s_t);
- get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
+ get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant,
+ iovp->iod_iovec_offset,
(iovp->iod_iovec_s > IOVEC_NR ?
- IOVEC_NR : iovp->iod_iovec_s) * sizeof(iovec_t),
+ IOVEC_NR : iovp->iod_iovec_s) * sizeof(iovec_s_t),
iovp->iod_iovec);
}
/*===========================================================================*
- * do_getstat *
+ * do_getstat_s *
*===========================================================================*/
-static void do_getstat(mp)
+static void do_getstat_s(mp)
message *mp;
{
int port;
ec= &ec_table[port];
ec->client= mp->DL_PROC;
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (vir_bytes) sizeof(ec->eth_stat), &ec->eth_stat);
+ put_userdata_s(mp->DL_PROC, mp->DL_GRANT,
+ &ec->eth_stat, sizeof(ec->eth_stat));
reply(ec, OK, FALSE);
}
/*===========================================================================*
- * put_userdata *
+ * put_userdata_s *
*===========================================================================*/
-static void put_userdata(user_proc, user_addr, count, loc_addr)
+static void put_userdata_s(user_proc, grant, loc_addr, count)
int user_proc;
-vir_bytes user_addr;
-vir_bytes count;
+cp_grant_id_t grant;
void *loc_addr;
+vir_bytes count;
{
- /*phys_bytes dst;
-
- dst = numap_local(user_proc, user_addr, count);
- if (!dst)
- panic( "lance", "umap failed", NO_NUM);
-
- phys_copy(vir2phys(loc_addr), dst, (phys_bytes) count);
- */
int cps;
- cps = sys_datacopy(SELF, (vir_bytes) loc_addr, user_proc, user_addr, count);
- if (cps != OK) printf("lance: warning, scopy failed: %d\n", cps);
+ cps = sys_safecopyto(user_proc, grant, 0,
+ (vir_bytes) loc_addr, count, D);
+ if (cps != OK)
+ panic(__FILE__,
+ "put_userdata_s: sys_safecopyto failed: %d\n", cps);
}
/*===========================================================================*
#define IOVEC_NR 16
typedef struct iovec_dat
{
- iovec_t iod_iovec[IOVEC_NR];
+ iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
int iod_proc_nr;
- vir_bytes iod_iovec_addr;
+ cp_grant_id_t iod_grant;
+ vir_bytes iod_iovec_offset;
} iovec_dat_t;
#define ETH0_SELECTOR 0x61
*
* The valid messages and their parameters are:
*
- * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR
- * |------------+----------+---------+----------+---------+---------|
- * | HARD_INT | | | | | |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITE | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_WRITEV | port nr | proc nr | count | mode | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READ | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_READV | port nr | proc nr | count | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_INIT | port nr | proc nr | mode | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_GETSTAT | port nr | proc nr | | | address |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_GETNAME | | | | | |
- * |------------|----------|---------|----------|---------|---------|
- * | DL_STOP | port_nr | | | | |
- * |------------|----------|---------|----------|---------|---------|
+ * m_type DL_PORT DL_PROC DL_COUNT DL_MODE DL_ADDR DL_GRANT
+ * |------------+----------+---------+----------+---------+---------+---------|
+ * | HARDINT | | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITE | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV | port nr | proc nr | count | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_WRITEV_S| port nr | proc nr | count | mode | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READ | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV | port nr | proc nr | count | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_READV_S | port nr | proc nr | count | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_CONF | port nr | proc nr | | mode | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_GETSTAT | port nr | proc nr | | | address | |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * |DL_GETSTAT_S| port nr | proc nr | | | | grant |
+ * |------------|----------|---------|----------|---------|---------|---------|
+ * | DL_STOP | port_nr | | | | | |
+ * |------------|----------|---------|----------|---------|---------|---------|
*
* The messages sent are:
*
*
* m_type m3_i1 m3_i2 m3_ca1
* |------------+---------+-----------+---------------|
- * |DL_INIT_REPL| port nr | last port | ethernet addr |
+ * |DL_CONF_REPL| port nr | last port | ethernet addr |
* |------------|---------|-----------|---------------|
*
* Created: Aug 2003 by Philip Homburg <philip@cs.vu.nl>
message re_tx_mess;
char re_name[sizeof("rtl8139#n")];
iovec_t re_iovec[IOVEC_NR];
+ iovec_s_t re_iovec_s[IOVEC_NR];
}
re_t;
_PROTOTYPE( static void rl_rec_mode, (re_t *rep) );
_PROTOTYPE( static void rl_readv, (message *mp, int from_int,
int vectored) );
+_PROTOTYPE( static void rl_readv_s, (message *mp, int from_int) );
_PROTOTYPE( static void rl_writev, (message *mp, int from_int,
int vectored) );
+_PROTOTYPE( static void rl_writev_s, (message *mp, int from_int) );
_PROTOTYPE( static void rl_check_ints, (re_t *rep) );
_PROTOTYPE( static void rl_report_link, (re_t *rep) );
_PROTOTYPE( static void mii_print_techab, (U16_t techab) );
_PROTOTYPE( static void rl_clear_rx, (re_t *rep) );
_PROTOTYPE( static void rl_do_reset, (re_t *rep) );
_PROTOTYPE( static void rl_getstat, (message *mp) );
+_PROTOTYPE( static void rl_getstat_s, (message *mp) );
_PROTOTYPE( static void rl_getname, (message *mp) );
_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
-_PROTOTYPE( static void put_userdata, (int user_proc,
- vir_bytes user_addr, vir_bytes count, void *loc_addr) );
_PROTOTYPE( static void rtl8139_stop, (void) );
_PROTOTYPE( static void check_int_events, (void) );
_PROTOTYPE( static int do_hard_int, (void) );
switch (m.m_type)
{
- case DEV_PING: notify(m.m_source); continue;
- case DL_WRITEV: rl_writev(&m, FALSE, TRUE); break;
+ case DEV_PING: notify(m.m_source); break;
case DL_WRITE: rl_writev(&m, FALSE, FALSE); break;
-#if 0
- case DL_READ: do_vread(&m, FALSE); break;
-#endif
+ case DL_WRITEV: rl_writev(&m, FALSE, TRUE); break;
+ case DL_WRITEV_S: rl_writev_s(&m, FALSE); break;
+ case DL_READ: rl_readv(&m, FALSE, FALSE); break;
case DL_READV: rl_readv(&m, FALSE, TRUE); break;
- case DL_INIT: rl_init(&m); break;
+ case DL_READV_S: rl_readv_s(&m, FALSE); break;
+ case DL_CONF: rl_init(&m); break;
case DL_GETSTAT: rl_getstat(&m); break;
+ case DL_GETSTAT_S: rl_getstat_s(&m); break;
case DL_GETNAME: rl_getname(&m); break;
#if 0
case DL_STOP: do_stop(&m); break;
port = mp->DL_PORT;
if (port < 0 || port >= RE_PORT_NR)
{
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
if (rep->re_mode == REM_DISABLED)
{
/* Probe failed, or the device is configured off. */
- reply_mess.m_type= DL_INIT_REPLY;
+ reply_mess.m_type= DL_CONF_REPLY;
reply_mess.m3_i1= ENXIO;
mess_reply(mp, &reply_mess);
return;
rep->re_client = mp->m_source;
rl_rec_mode(rep);
- reply_mess.m_type = DL_INIT_REPLY;
+ reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m3_i1 = mp->DL_PORT;
reply_mess.m3_i2 = RE_PORT_NR;
*(ether_addr_t *) reply_mess.m3_ca1 = rep->re_address;
rxstat = *(u32_t *) (rep->v_re_rx_buf + d_start);
-#if DEAD_CODE
- src_phys= rep->re_rx_buf + d_start;
- cps = sys_physcopy(
- NONE, PHYS_SEG, src_phys,
- SELF, D, (vir_bytes) &rxstat, sizeof(rxstat));
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#endif
-
if (rep->re_clear_rx)
{
#if 0
if (vectored)
{
int iov_offset = 0;
-#if 0
- if ((cps = sys_umap(re_client, D, (vir_bytes) mp->DL_ADDR,
- count * sizeof(rep->re_iovec[0]), &iov_src)) != OK)
- printf("sys_umap failed: %d\n", cps);
-#endif
size= 0;
o= d_start+4;
n= IOVEC_NR;
if (i+n > count)
n= count-i;
-#if 0
- cps = sys_physcopy(NONE, PHYS_SEG, iov_src, SELF, D, (vir_bytes) rep->re_iovec,
+
+ cps = sys_vircopy(re_client, D,
+ (vir_bytes) mp->DL_ADDR + iov_offset,
+ SELF, D, (vir_bytes) rep->re_iovec,
n * sizeof(rep->re_iovec[0]));
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
- cps = sys_vircopy(re_client, D, (vir_bytes) mp->DL_ADDR + iov_offset,
- SELF, D, (vir_bytes) rep->re_iovec, n * sizeof(rep->re_iovec[0]));
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);
-#endif
+ if (cps != OK)
+ printf(
+ "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
+ cps, __LINE__);
for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)
{
s= packlen-size;
}
-#if 0
- if (sys_umap(re_client, D, iovp->iov_addr, s, &dst_phys) != OK)
- panic("rtl8139","umap_local failed\n", NO_NUM);
-#endif
-
if (o >= RX_BUFSIZE)
{
o -= RX_BUFSIZE;
assert(o<RX_BUFSIZE);
s1= RX_BUFSIZE-o;
-#if 0
- cps = sys_abscopy(src_phys+o, dst_phys, s1);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
- cps = sys_abscopy(src_phys, dst_phys+s1, s-s1);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
- cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf+o,
- re_client, D, iovp->iov_addr, s1);
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);
- cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf,
- re_client, D, iovp->iov_addr+s1, s-s1);
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);
-#endif
+ cps = sys_vircopy(SELF, D,
+ (vir_bytes) rep->v_re_rx_buf+o,
+ re_client, D, iovp->iov_addr,
+ s1);
+ if (cps != OK)
+ printf(
+ "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
+ cps, __LINE__);
+ cps = sys_vircopy(SELF, D,
+ (vir_bytes) rep->v_re_rx_buf,
+ re_client, D,
+ iovp->iov_addr+s1, s-s1);
+ if (cps != OK)
+ printf(
+ "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
+ cps, __LINE__);
}
else
{
-#if 0
- cps = sys_abscopy(src_phys+o, dst_phys, s);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
- cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf+o,
- re_client, D, iovp->iov_addr, s);
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);
-#endif
+ cps = sys_vircopy(SELF, D,
+ (vir_bytes) rep->v_re_rx_buf+o,
+ re_client, D, iovp->iov_addr,
+ s);
+ if (cps != OK)
+ printf(
+ "RTL8139: warning, sys_vircopy failed: %d (%d)\n",
+ cps, __LINE__);
}
size += s;
cps = sys_abscopy(phys_user, p, size);
if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
#endif
- }
+ }
- if (rep->re_clear_rx)
- {
- /* For some reason the receiver FIFO is not stopped when
- * the buffer is full.
- */
- #if 0
- printf("rl_readv: later buffer overflow\n");
- #endif
- goto suspend; /* Buffer overflow */
- }
+ if (rep->re_clear_rx)
+ {
+ /* For some reason the receiver FIFO is not stopped when
+ * the buffer is full.
+ */
+#if 0
+ printf("rl_readv: later buffer overflow\n");
+#endif
+ goto suspend; /* Buffer overflow */
+ }
- rep->re_stat.ets_packetR++;
- rep->re_read_s= packlen;
- rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV;
+ rep->re_stat.ets_packetR++;
+ rep->re_read_s= packlen;
+ rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV;
- /* Avoid overflow in 16-bit computations */
- l= d_start;
- l += totlen+4;
- l= (l+3) & ~3; /* align */
- if (l >= RX_BUFSIZE)
- {
- l -= RX_BUFSIZE;
- assert(l < RX_BUFSIZE);
- }
- rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
+ /* Avoid overflow in 16-bit computations */
+ l= d_start;
+ l += totlen+4;
+ l= (l+3) & ~3; /* align */
+ if (l >= RX_BUFSIZE)
+ {
+ l -= RX_BUFSIZE;
+ assert(l < RX_BUFSIZE);
+ }
+ rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
- if (!from_int)
- reply(rep, OK, FALSE);
+ if (!from_int)
+ reply(rep, OK, FALSE);
+ return;
+
+suspend:
+ if (from_int)
+ {
+ assert(rep->re_flags & REF_READING);
+
+ /* No need to store any state */
return;
+ }
- suspend:
- if (from_int)
- {
- assert(rep->re_flags & REF_READING);
+ rep->re_rx_mess= *mp;
+ assert(!(rep->re_flags & REF_READING));
+ rep->re_flags |= REF_READING;
- /* No need to store any state */
- return;
- }
+ reply(rep, OK, FALSE);
+}
- rep->re_rx_mess= *mp;
- assert(!(rep->re_flags & REF_READING));
- rep->re_flags |= REF_READING;
+/*===========================================================================*
+ * rl_readv_s *
+ *===========================================================================*/
+static void rl_readv_s(mp, from_int)
+message *mp;
+int from_int;
+{
+ int i, j, n, o, s, s1, dl_port, re_client, count, size;
+ port_t port;
+ unsigned amount, totlen, packlen;
+ phys_bytes src_phys, dst_phys, iov_src;
+ u16_t d_start, d_end;
+ u32_t l, rxstat = 0x12345678;
+ re_t *rep;
+ iovec_s_t *iovp;
+ int cps;
+ int iov_offset = 0;
- reply(rep, OK, FALSE);
+ dl_port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (dl_port < 0 || dl_port >= RE_PORT_NR)
+ panic("rtl8139"," illegal port", dl_port);
+ rep= &re_table[dl_port];
+ re_client= mp->DL_PROC;
+ rep->re_client= re_client;
+
+ if (rep->re_clear_rx)
+ goto suspend; /* Buffer overflow */
+
+ assert(rep->re_mode == REM_ENABLED);
+ assert(rep->re_flags & REF_ENABLED);
+
+ port= rep->re_base_port;
+
+ /* Assume that the RL_CR_BUFE check was been done by rl_checks_ints
+ */
+ if (!from_int && (rl_inb(port, RL_CR) & RL_CR_BUFE))
+ {
+ /* Receive buffer is empty, suspend */
+ goto suspend;
}
- /*===========================================================================*
- * rl_writev *
- *===========================================================================*/
- static void rl_writev(mp, from_int, vectored)
- message *mp;
- int from_int;
- int vectored;
- {
- phys_bytes p, iov_src, phys_user;
- int i, j, n, s, port, count, size;
- int tx_head, re_client;
- re_t *rep;
- iovec_t *iovp;
- char *ret;
- int cps;
-
- port = mp->DL_PORT;
- count = mp->DL_COUNT;
- if (port < 0 || port >= RE_PORT_NR)
- panic("rtl8139","illegal port", port);
- rep= &re_table[port];
- re_client= mp->DL_PROC;
- rep->re_client= re_client;
-
- assert(rep->re_mode == REM_ENABLED);
- assert(rep->re_flags & REF_ENABLED);
-
- if (from_int)
- {
- assert(rep->re_flags & REF_SEND_AVAIL);
- rep->re_flags &= ~REF_SEND_AVAIL;
- rep->re_send_int= FALSE;
- rep->re_tx_alive= TRUE;
- }
+ d_start= rl_inw(port, RL_CAPR) + RL_CAPR_DATA_OFF;
+ d_end= rl_inw(port, RL_CBR) % RX_BUFSIZE;
- tx_head= rep->re_tx_head;
- if (rep->re_tx[tx_head].ret_busy)
+ if (d_start >= RX_BUFSIZE)
+ {
+ printf("rl_readv: strange value in RL_CAPR: 0x%x\n",
+ rl_inw(port, RL_CAPR));
+ d_start %= RX_BUFSIZE;
+ }
+
+ if (d_end > d_start)
+ amount= d_end-d_start;
+ else
+ amount= d_end+RX_BUFSIZE - d_start;
+
+ rxstat = *(u32_t *) (rep->v_re_rx_buf + d_start);
+
+ if (rep->re_clear_rx)
+ {
+#if 0
+ printf("rl_readv: late buffer overflow\n");
+#endif
+ goto suspend; /* Buffer overflow */
+ }
+
+ /* Should convert from little endian to host byte order */
+
+ if (!(rxstat & RL_RXS_ROK))
+ {
+ printf("rxstat = 0x%08lx\n", rxstat);
+ printf("d_start: 0x%x, d_end: 0x%x, rxstat: 0x%lx\n",
+ d_start, d_end, rxstat);
+ panic("rtl8139","received packet not OK", NO_NUM);
+ }
+ totlen= (rxstat >> RL_RXS_LEN_S);
+ if (totlen < 8 || totlen > 2*ETH_MAX_PACK_SIZE)
+ {
+ /* Someting went wrong */
+ printf(
+ "rl_readv: bad length (%u) in status 0x%08lx at offset 0x%x\n",
+ totlen, rxstat, d_start);
+ printf(
+ "d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%lx\n",
+ d_start, d_end, totlen, rxstat);
+ panic(NULL, NULL, NO_NUM);
+ }
+
+#if 0
+ printf("d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%x\n",
+ d_start, d_end, totlen, rxstat);
+#endif
+
+ if (totlen+4 > amount)
+ {
+ printf("rl_readv: packet not yet ready\n");
+ goto suspend;
+ }
+
+ /* Should subtract the CRC */
+ packlen= totlen - ETH_CRC_SIZE;
+
+ size= 0;
+ o= d_start+4;
+ src_phys= rep->re_rx_buf;
+ for (i= 0; i<count; i += IOVEC_NR,
+ iov_src += IOVEC_NR * sizeof(rep->re_iovec_s[0]),
+ iov_offset += IOVEC_NR * sizeof(rep->re_iovec_s[0]))
+ {
+ n= IOVEC_NR;
+ if (i+n > count)
+ n= count-i;
+
+ cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ (vir_bytes) rep->re_iovec_s,
+ n * sizeof(rep->re_iovec_s[0]), D);
+ if (cps != OK)
{
- assert(!(rep->re_flags & REF_SEND_AVAIL));
- rep->re_flags |= REF_SEND_AVAIL;
- if (rep->re_tx[tx_head].ret_busy)
- goto suspend;
-
- /* Race condition, the interrupt handler may clear re_busy
- * before we got a chance to set REF_SEND_AVAIL. Checking
- * ret_busy twice should be sufficient.
- */
- #if 0
- printf("rl_writev: race detected\n");
- #endif
- rep->re_flags &= ~REF_SEND_AVAIL;
- rep->re_send_int= FALSE;
+ panic(__FILE__, "rl_readv_s: sys_safecopyfrom failed",
+ cps);
}
- assert(!(rep->re_flags & REF_SEND_AVAIL));
- assert(!(rep->re_flags & REF_PACK_SENT));
-
- if (vectored)
+ for (j= 0, iovp= rep->re_iovec_s; j<n; j++, iovp++)
{
- int iov_offset = 0;
+ s= iovp->iov_size;
+ if (size + s > packlen)
+ {
+ assert(packlen > size);
+ s= packlen-size;
+ }
#if 0
- if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR,
- count * sizeof(rep->re_iovec[0]), &iov_src))
- panic("rtl8139","umap_local failed", NO_NUM);
+ if (sys_umap(re_client, D, iovp->iov_addr, s, &dst_phys) != OK)
+ panic("rtl8139","umap_local failed\n", NO_NUM);
#endif
- size= 0;
+ if (o >= RX_BUFSIZE)
+ {
+ o -= RX_BUFSIZE;
+ assert(o < RX_BUFSIZE);
+ }
+
+ if (o+s > RX_BUFSIZE)
+ {
+ assert(o<RX_BUFSIZE);
+ s1= RX_BUFSIZE-o;
+
+ cps = sys_safecopyto(re_client,
+ iovp->iov_grant, 0,
+ (vir_bytes) rep->v_re_rx_buf+o, s1, D);
+ if (cps != OK)
+ {
+ panic(__FILE__,
+ "rl_readv_s: sys_safecopyto failed",
+ cps);
+ }
+ cps = sys_safecopyto(re_client,
+ iovp->iov_grant, s1,
+ (vir_bytes) rep->v_re_rx_buf, s-s1, S);
+ if (cps != OK)
+ {
+ panic(__FILE__,
+ "rl_readv_s: sys_safecopyto failed",
+ cps);
+ }
+ }
+ else
+ {
+ cps = sys_safecopyto(re_client,
+ iovp->iov_grant, 0,
+ (vir_bytes) rep->v_re_rx_buf+o, s, D);
+ if (cps != OK)
+ panic(__FILE__,
+ "rl_readv_s: sys_vircopy failed",
+ cps);
+ }
+
+ size += s;
+ if (size == packlen)
+ break;
+ o += s;
+ }
+ if (size == packlen)
+ break;
+ }
+ if (size < packlen)
+ {
+ assert(0);
+ }
+
+ if (rep->re_clear_rx)
+ {
+ /* For some reason the receiver FIFO is not stopped when
+ * the buffer is full.
+ */
#if 0
- p= rep->re_tx[tx_head].ret_buf;
-#else
- ret = rep->re_tx[tx_head].v_ret_buf;
+ printf("rl_readv: later buffer overflow\n");
#endif
- for (i= 0; i<count; i += IOVEC_NR,
- iov_src += IOVEC_NR * sizeof(rep->re_iovec[0]),
- iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))
- {
- n= IOVEC_NR;
- if (i+n > count)
- n= count-i;
+ goto suspend; /* Buffer overflow */
+ }
+
+ rep->re_stat.ets_packetR++;
+ rep->re_read_s= packlen;
+ rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV;
+
+ /* Avoid overflow in 16-bit computations */
+ l= d_start;
+ l += totlen+4;
+ l= (l+3) & ~3; /* align */
+ if (l >= RX_BUFSIZE)
+ {
+ l -= RX_BUFSIZE;
+ assert(l < RX_BUFSIZE);
+ }
+ rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);
+
+ if (!from_int)
+ reply(rep, OK, FALSE);
+
+ return;
+
+suspend:
+ if (from_int)
+ {
+ assert(rep->re_flags & REF_READING);
+
+ /* No need to store any state */
+ return;
+ }
+
+ rep->re_rx_mess= *mp;
+ assert(!(rep->re_flags & REF_READING));
+ rep->re_flags |= REF_READING;
+
+ reply(rep, OK, FALSE);
+}
+
+/*===========================================================================*
+ * rl_writev *
+ *===========================================================================*/
+static void rl_writev(mp, from_int, vectored)
+message *mp;
+int from_int;
+int vectored;
+{
+ phys_bytes iov_src, phys_user;
+ int i, j, n, s, port, count, size;
+ int tx_head, re_client;
+ re_t *rep;
+ iovec_t *iovp;
+ char *ret;
+ int cps;
+
+ port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (port < 0 || port >= RE_PORT_NR)
+ panic("rtl8139","illegal port", port);
+ rep= &re_table[port];
+ re_client= mp->DL_PROC;
+ rep->re_client= re_client;
+
+ assert(rep->re_mode == REM_ENABLED);
+ assert(rep->re_flags & REF_ENABLED);
+
+ if (from_int)
+ {
+ assert(rep->re_flags & REF_SEND_AVAIL);
+ rep->re_flags &= ~REF_SEND_AVAIL;
+ rep->re_send_int= FALSE;
+ rep->re_tx_alive= TRUE;
+ }
+
+ tx_head= rep->re_tx_head;
+ if (rep->re_tx[tx_head].ret_busy)
+ {
+ assert(!(rep->re_flags & REF_SEND_AVAIL));
+ rep->re_flags |= REF_SEND_AVAIL;
+ if (rep->re_tx[tx_head].ret_busy)
+ goto suspend;
+
+ /* Race condition, the interrupt handler may clear re_busy
+ * before we got a chance to set REF_SEND_AVAIL. Checking
+ * ret_busy twice should be sufficient.
+ */
#if 0
- cps = sys_physcopy(NONE, PHYS_SEG, iov_src, SELF, D, (vir_bytes) rep->re_iovec,
- n * sizeof(rep->re_iovec[0]));
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
- cps = sys_vircopy(re_client, D, ((vir_bytes) mp->DL_ADDR) + iov_offset,
- SELF, D, (vir_bytes) rep->re_iovec,
- n * sizeof(rep->re_iovec[0]));
- if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);
+ printf("rl_writev: race detected\n");
#endif
+ rep->re_flags &= ~REF_SEND_AVAIL;
+ rep->re_send_int= FALSE;
+ }
+
+ assert(!(rep->re_flags & REF_SEND_AVAIL));
+ assert(!(rep->re_flags & REF_PACK_SENT));
+
+ if (vectored)
+ {
+ int iov_offset = 0;
+
+ size= 0;
+ ret = rep->re_tx[tx_head].v_ret_buf;
+ for (i= 0; i<count; i += IOVEC_NR,
+ iov_src += IOVEC_NR * sizeof(rep->re_iovec[0]),
+ iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))
+ {
+ n= IOVEC_NR;
+ if (i+n > count)
+ n= count-i;
+ cps = sys_vircopy(re_client, D, ((vir_bytes) mp->DL_ADDR) + iov_offset,
+ SELF, D, (vir_bytes) rep->re_iovec,
+ n * sizeof(rep->re_iovec[0]));
+if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);
for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)
{
if (OK != sys_umap(re_client, D, iovp->iov_addr, s, &phys_user))
panic("rtl8139","umap_local failed\n", NO_NUM);
-#if 0
- cps = sys_abscopy(phys_user, p, s);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
cps = sys_vircopy(re_client, D, iovp->iov_addr,
SELF, D, (vir_bytes) ret, s);
if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);
-#endif
size += s;
-#if 0
- p += s;
-#endif
ret += s;
}
}
size= mp->DL_COUNT;
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
panic("rtl8139","invalid packet size", size);
-#if 0
- if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR, size, &phys_user))
- panic("rtl8139","umap_local failed\n", NO_NUM);
-
- p= rep->re_tx[tx_head].ret_buf;
- cps = sys_abscopy(phys_user, p, size);
- if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
-#else
ret = rep->re_tx[tx_head].v_ret_buf;
cps = sys_vircopy(re_client, D, (vir_bytes)mp->DL_ADDR,
SELF, D, (vir_bytes) ret, size);
if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);
+ }
+
+ rl_outl(rep->re_base_port, RL_TSD0+tx_head*4,
+ rep->re_ertxth | size);
+ rep->re_tx[tx_head].ret_busy= TRUE;
+
+ if (++tx_head == N_TX_BUF)
+ tx_head= 0;
+ assert(tx_head < RL_N_TX);
+ rep->re_tx_head= tx_head;
+
+ rep->re_flags |= REF_PACK_SENT;
+
+ /* If the interrupt handler called, don't send a reply. The reply
+ * will be sent after all interrupts are handled.
+ */
+ if (from_int)
+ return;
+ reply(rep, OK, FALSE);
+ return;
+
+suspend:
+#if 0
+ printf("rl_writev: head %d, tail %d, busy: %d %d %d %d\n",
+ tx_head, rep->re_tx_tail,
+ rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,
+ rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);
+ printf("rl_writev: TSD: 0x%x, 0x%x, 0x%x, 0x%x\n",
+ rl_inl(rep->re_base_port, RL_TSD0+0*4),
+ rl_inl(rep->re_base_port, RL_TSD0+1*4),
+ rl_inl(rep->re_base_port, RL_TSD0+2*4),
+ rl_inl(rep->re_base_port, RL_TSD0+3*4));
+#endif
+
+ if (from_int)
+ panic("rtl8139","should not be sending\n", NO_NUM);
+
+ rep->re_tx_mess= *mp;
+ reply(rep, OK, FALSE);
+}
+
+/*===========================================================================*
+ * rl_writev_s *
+ *===========================================================================*/
+static void rl_writev_s(mp, from_int)
+message *mp;
+int from_int;
+{
+ phys_bytes iov_src;
+ int i, j, n, s, port, count, size;
+ int tx_head, re_client;
+ re_t *rep;
+ iovec_s_t *iovp;
+ char *ret;
+ int cps;
+ int iov_offset = 0;
+
+ port = mp->DL_PORT;
+ count = mp->DL_COUNT;
+ if (port < 0 || port >= RE_PORT_NR)
+ panic("rtl8139","illegal port", port);
+ rep= &re_table[port];
+ re_client= mp->DL_PROC;
+ rep->re_client= re_client;
+
+ assert(rep->re_mode == REM_ENABLED);
+ assert(rep->re_flags & REF_ENABLED);
+
+ if (from_int)
+ {
+ assert(rep->re_flags & REF_SEND_AVAIL);
+ rep->re_flags &= ~REF_SEND_AVAIL;
+ rep->re_send_int= FALSE;
+ rep->re_tx_alive= TRUE;
+ }
+
+ tx_head= rep->re_tx_head;
+ if (rep->re_tx[tx_head].ret_busy)
+ {
+ assert(!(rep->re_flags & REF_SEND_AVAIL));
+ rep->re_flags |= REF_SEND_AVAIL;
+ if (rep->re_tx[tx_head].ret_busy)
+ goto suspend;
+
+ /* Race condition, the interrupt handler may clear re_busy
+ * before we got a chance to set REF_SEND_AVAIL. Checking
+ * ret_busy twice should be sufficient.
+ */
+#if 0
+ printf("rl_writev: race detected\n");
#endif
+ rep->re_flags &= ~REF_SEND_AVAIL;
+ rep->re_send_int= FALSE;
+ }
+
+ assert(!(rep->re_flags & REF_SEND_AVAIL));
+ assert(!(rep->re_flags & REF_PACK_SENT));
+
+ size= 0;
+ ret = rep->re_tx[tx_head].v_ret_buf;
+ for (i= 0; i<count; i += IOVEC_NR,
+ iov_src += IOVEC_NR * sizeof(rep->re_iovec_s[0]),
+ iov_offset += IOVEC_NR * sizeof(rep->re_iovec_s[0]))
+ {
+ n= IOVEC_NR;
+ if (i+n > count)
+ n= count-i;
+ cps = sys_safecopyfrom(re_client, mp->DL_GRANT, iov_offset,
+ (vir_bytes) rep->re_iovec_s,
+ n * sizeof(rep->re_iovec_s[0]), D);
+ if (cps != OK)
+ {
+ panic(__FILE__, "rl_writev_s: sys_safecopyfrom failed",
+ cps);
+ }
+
+ for (j= 0, iovp= rep->re_iovec_s; j<n; j++, iovp++)
+ {
+ s= iovp->iov_size;
+ if (size + s > ETH_MAX_PACK_SIZE_TAGGED)
+ {
+ panic("rtl8139","invalid packet size",
+ NO_NUM);
+ }
+ cps = sys_safecopyfrom(re_client, iovp->iov_grant, 0,
+ (vir_bytes) ret, s, D);
+ if (cps != OK)
+ {
+ panic(__FILE__,
+ "rl_writev_s: sys_safecopyfrom failed",
+ cps);
+ }
+ size += s;
+ ret += s;
+ }
}
+ if (size < ETH_MIN_PACK_SIZE)
+ panic("rtl8139","invalid packet size", size);
rl_outl(rep->re_base_port, RL_TSD0+tx_head*4,
rep->re_ertxth | size);
rl_readv(&rep->re_rx_mess, TRUE /* from int */,
TRUE /* vectored */);
}
+ else if (rep->re_rx_mess.m_type == DL_READV_S)
+ {
+ rl_readv_s(&rep->re_rx_mess, TRUE /* from int */);
+ }
else
{
assert(rep->re_rx_mess.m_type == DL_READ);
static void rl_getstat(mp)
message *mp;
{
- int port;
+ int r, port;
eth_stat_t stats;
re_t *rep;
stats= rep->re_stat;
- put_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
- (vir_bytes) sizeof(stats), &stats);
+ r = sys_datacopy(SELF, (vir_bytes) &stats, mp->DL_PROC,
+ (vir_bytes) mp->DL_ADDR, sizeof(stats));
+ if (r != OK)
+ panic(__FILE__, "rl_getstat: sys_datacopy failed", r);
+ reply(rep, OK, FALSE);
+}
+
+/*===========================================================================*
+ * rl_getstat_s *
+ *===========================================================================*/
+static void rl_getstat_s(mp)
+message *mp;
+{
+ int r, port;
+ eth_stat_t stats;
+ re_t *rep;
+
+ port = mp->DL_PORT;
+ if (port < 0 || port >= RE_PORT_NR)
+ panic("rtl8139","illegal port", port);
+ rep= &re_table[port];
+ rep->re_client= mp->DL_PROC;
+
+ assert(rep->re_mode == REM_ENABLED);
+ assert(rep->re_flags & REF_ENABLED);
+
+ stats= rep->re_stat;
+
+ r = sys_safecopyto(mp->DL_PROC, mp->DL_GRANT, 0,
+ (vir_bytes) &stats, sizeof(stats), D);
+ if (r != OK)
+ panic(__FILE__, "rl_getstat_s: sys_safecopyto failed", r);
reply(rep, OK, FALSE);
}
panic("rtl8139","unable to mess_reply", NO_NUM);
}
-/*===========================================================================*
- * put_userdata *
- *===========================================================================*/
-static void put_userdata(user_proc, user_addr, count, loc_addr)
-int user_proc;
-vir_bytes user_addr;
-vir_bytes count;
-void *loc_addr;
-{
- int cps;
- cps = sys_datacopy(SELF, (vir_bytes) loc_addr, user_proc, user_addr, count);
- if (cps != OK) printf("RTL8139: warning, scopy failed: %d\n", cps);
-}
-
#if 0
static void dump_phy(rep)
re_t *rep;