21,7 → 21,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* Changes: |
* 2009 Lukas Medjrech ported to HelenOS |
* 2009 Lukas Mejdrech ported to HelenOS |
*/ |
|
/** @addtogroup dp8390 |
29,12 → 29,17 |
*/ |
|
#include <assert.h> |
|
#include <errno.h> |
|
#include "../../include/byteorder.h" |
|
#include "../../structures/packet/packet.h" |
#include "../../structures/packet/packet_client.h" |
|
#include "../netif.h" |
|
#include "dp8390_drv.h" |
#include "dp8390_module.h" |
#include "dp8390_port.h" |
|
/* |
52,6 → 57,10 |
#include "local.h" |
#include "dp8390.h" |
|
int queue_packet( dpeth_t * dep, packet_t packet ); |
static void outsb( port_t port, void * buf, size_t size ); |
static void outsw( port_t port, void * buf, size_t size ); |
|
//static u16_t eth_ign_proto; |
//static char *progname; |
|
118,27 → 127,27 |
//_PROTOTYPE( static void dp8390_stop, (void) ); |
_PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page, |
size_t offset, size_t size, void *dst) ); |
//_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page, |
// size_t offset, size_t size, void *dst) ); |
//_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page, |
// size_t offset, size_t size, void *dst) ); |
_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page, |
size_t offset, size_t size, void *dst) ); |
_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page, |
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, (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, (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, (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) ); |
146,15 → 155,15 |
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, (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, (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, (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) ); |
163,8 → 172,8 |
//_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, (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) ); |
172,8 → 181,8 |
// 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 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, |
// vir_bytes buf, size_t size) ); |
//_PROTOTYPE( static void do_vir_insw, (port_t port, int proc, |
258,7 → 267,136 |
} |
} |
|
int queue_packet( dpeth_t * dep, packet_t packet ){ |
packet_t tmp; |
|
if( dep->packet_count > 1 ){ |
if( ! pq_add( pq_previous( dep->packet_queue ), packet, 0, 0 )){ |
return EINVAL; |
} |
}else{ |
tmp = pq_add( dep->packet_queue, packet, 0, 0 ); |
if( ! tmp ) return EINVAL; |
dep->packet_queue = tmp; |
} |
++ dep->packet_count; |
return EBUSY; |
} |
|
/*===========================================================================* |
* based on do_vwrite * |
*===========================================================================*/ |
int do_pwrite( dpeth_t * dep, packet_t packet, int from_int ) |
{ |
// int port, count, size; |
int 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; |
return EOK; |
} |
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); |
return queue_packet( dep, packet ); |
} |
|
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; |
return queue_packet( dep, packet ); |
} |
assert(!(dep->de_flags & DEF_PACK_SEND)); |
|
/* if (vectored) |
{ |
get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR, |
(count > IOVEC_NR ? IOVEC_NR : count) * |
sizeof(iovec_t), dep->de_write_iovec.iod_iovec); |
dep->de_write_iovec.iod_iovec_s = count; |
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; |
dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR; |
|
dep->de_tmp_iovec = dep->de_write_iovec; |
size = calc_iovec_size(&dep->de_tmp_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 = |
mp->DL_COUNT; |
dep->de_write_iovec.iod_iovec_s = 1; |
dep->de_write_iovec.iod_proc_nr = mp->DL_PROC; |
dep->de_write_iovec.iod_iovec_addr = 0; |
size= mp->DL_COUNT; |
} |
*/ |
size = packet_get_data_length( packet ); |
dep->de_write_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_get_data( packet ); |
dep->de_write_iovec.iod_iovec[0].iov_size = size; |
dep->de_write_iovec.iod_iovec_s = 1; |
dep->de_write_iovec.iod_iovec_addr = NULL; |
|
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) |
{ |
panic("", "dp8390: invalid packet size", size); |
return EINVAL; |
} |
(dep->de_user2nicf)(dep, &dep->de_write_iovec, 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 EOK; |
reply(dep, OK, FALSE); |
|
assert(dep->de_mode == DEM_ENABLED); |
assert(dep->de_flags & DEF_ENABLED); |
return EOK; |
} |
|
/*===========================================================================* |
* dp_init * |
*===========================================================================*/ |
void dp_init(dep) |
353,30 → 491,30 |
dep->de_sendq[i].sq_filled= 0; |
dep->de_sendq_head= 0; |
dep->de_sendq_tail= 0; |
// if (!dep->de_prog_IO) |
// { |
// dep->de_user2nicf= dp_user2nic; |
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; |
} |
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= 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_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= dp_pio8_nic2user; |
// dep->de_nic2userf_s= dp_pio8_nic2user_s; |
// dep->de_getblockf= dp_pio8_getblock; |
// } |
dep->de_getblockf= dp_pio8_getblock; |
} |
|
/* Set the interrupt handler and policy. Do not automatically |
* reenable interrupts. Return the IRQ line number on interrupts. |
692,11 → 830,20 |
static void dp_send(dep) |
dpeth_t *dep; |
{ |
/* if (!(dep->de_flags & DEF_SEND_AVAIL)) |
packet_t packet; |
|
if (!(dep->de_flags & DEF_SEND_AVAIL)) |
return; |
|
dep->de_flags &= ~DEF_SEND_AVAIL; |
switch(dep->de_sendmsg.m_type) |
while( dep->packet_queue ){ |
packet = dep->packet_queue; |
dep->packet_queue = pq_detach( packet ); |
do_pwrite( dep, packet, TRUE ); |
netif_pq_release( packet_get_id( packet )); |
-- dep->packet_count; |
} |
/* switch(dep->de_sendmsg.m_type) |
{ |
case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break; |
case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break; |
726,6 → 873,47 |
} |
|
/*===========================================================================* |
* dp_pio8_getblock * |
*===========================================================================*/ |
static void dp_pio8_getblock(dep, page, offset, size, dst) |
dpeth_t *dep; |
int page; |
size_t offset; |
size_t size; |
void *dst; |
{ |
offset = page * DP_PAGESIZE + offset; |
outb_reg0(dep, DP_RBCR0, size & 0xFF); |
outb_reg0(dep, DP_RBCR1, size >> 8); |
outb_reg0(dep, DP_RSAR0, offset & 0xFF); |
outb_reg0(dep, DP_RSAR1, offset >> 8); |
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); |
|
insb(dep->de_data_port, dst, size); |
} |
|
/*===========================================================================* |
* dp_pio16_getblock * |
*===========================================================================*/ |
static void dp_pio16_getblock(dep, page, offset, size, dst) |
dpeth_t *dep; |
int page; |
size_t offset; |
size_t size; |
void *dst; |
{ |
offset = page * DP_PAGESIZE + offset; |
outb_reg0(dep, DP_RBCR0, size & 0xFF); |
outb_reg0(dep, DP_RBCR1, size >> 8); |
outb_reg0(dep, DP_RSAR0, offset & 0xFF); |
outb_reg0(dep, DP_RSAR1, offset >> 8); |
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); |
|
assert (!(size & 1)); |
insw(dep->de_data_port, dst, size); |
} |
|
/*===========================================================================* |
* dp_pkt2user * |
*===========================================================================*/ |
static int dp_pkt2user(dep, page, length) |
733,10 → 921,18 |
int page, length; |
{ |
int last, count; |
packet_t packet; |
|
if (!(dep->de_flags & DEF_READING)) |
return EGENERIC; |
|
packet = netif_packet_get_1( length ); |
if( ! packet ) return ENOMEM; |
dep->de_read_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_suffix( packet, length ); |
dep->de_read_iovec.iod_iovec[0].iov_size = length; |
dep->de_read_iovec.iod_iovec_s = 1; |
dep->de_read_iovec.iod_iovec_addr = NULL; |
|
last = page + (length - 1) / DP_PAGESIZE; |
if (last >= dep->de_stoppage) |
{ |
760,10 → 956,231 |
dep->de_flags |= DEF_PACK_RECV; |
dep->de_flags &= ~DEF_READING; |
|
if( netif_send_packet( dep, packet ) != EOK ){ |
netif_pq_release( packet_get_id( packet )); |
} |
return OK; |
} |
|
/*===========================================================================* |
* dp_user2nic * |
*===========================================================================*/ |
static void dp_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_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(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_vircopy(iovp->iod_proc_nr, D, |
iovp->iod_iovec[i].iov_addr + offset, |
SELF, D, vir_hw, bytes); |
if (r != OK) |
panic("DP8390", "dp_user2nic: sys_vircopy failed", r); |
|
count -= bytes; |
vir_hw += bytes; |
offset += bytes; |
} |
assert(count == 0); |
} |
|
/*===========================================================================* |
* dp_pio8_user2nic * |
*===========================================================================*/ |
static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count) |
dpeth_t *dep; |
iovec_dat_t *iovp; |
vir_bytes offset; |
int nic_addr; |
vir_bytes count; |
{ |
// phys_bytes phys_user; |
int bytes, i; |
|
outb_reg0(dep, DP_ISR, ISR_RDC); |
|
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); |
|
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; |
|
do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr, |
iovp->iod_iovec[i].iov_addr + offset, bytes); |
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", |
r); |
} |
outw(dep->de_data_port, *(u16_t *)two_bytes); |
count--; |
offset++; |
bytes--; |
vir_user++; |
odd_byte= 0; |
if (!bytes) |
continue; |
} |
ecount= bytes & ~1; |
if (ecount != 0) |
{ |
do_vir_outsw(dep->de_data_port, user_proc, vir_user, |
ecount); |
count -= ecount; |
offset += ecount; |
bytes -= ecount; |
vir_user += ecount; |
} |
if (bytes) |
{ |
assert(bytes == 1); |
r= sys_vircopy(user_proc, D, vir_user, |
SELF, D, (vir_bytes)&two_bytes[0], 1); |
if (r != OK) |
{ |
panic("DP8390", |
"dp_pio16_user2nic: sys_vircopy failed", |
r); |
} |
count--; |
offset++; |
bytes--; |
vir_user++; |
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 * |
*===========================================================================*/ |
static void dp_nic2user(dep, nic_addr, iovp, offset, count) |
773,7 → 1190,7 |
vir_bytes offset; |
vir_bytes count; |
{ |
/* vir_bytes vir_hw, vir_user; |
vir_bytes vir_hw;//, vir_user; |
int bytes, i, r; |
|
vir_hw = (vir_bytes)dep->de_locmem + nic_addr; |
809,11 → 1226,170 |
offset += bytes; |
} |
assert(count == 0); |
*/ |
printf("n2u"); |
} |
|
/*===========================================================================* |
* dp_pio8_nic2user * |
*===========================================================================*/ |
static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count) |
dpeth_t *dep; |
int nic_addr; |
iovec_dat_t *iovp; |
vir_bytes offset; |
vir_bytes count; |
{ |
// phys_bytes phys_user; |
int bytes, i; |
|
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(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; |
|
do_vir_insb(dep->de_data_port, iovp->iod_proc_nr, |
iovp->iod_iovec[i].iov_addr + offset, bytes); |
count -= bytes; |
offset += bytes; |
} |
assert(count == 0); |
} |
|
/*===========================================================================* |
* dp_pio16_nic2user * |
*===========================================================================*/ |
static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count) |
dpeth_t *dep; |
int nic_addr; |
iovec_dat_t *iovp; |
vir_bytes offset; |
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_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(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(SELF, D, (vir_bytes)&two_bytes[1], |
user_proc, D, vir_user, 1); |
if (r != OK) |
{ |
panic("DP8390", |
"dp_pio16_nic2user: sys_vircopy failed", |
r); |
} |
count--; |
offset++; |
bytes--; |
vir_user++; |
odd_byte= 0; |
if (!bytes) |
continue; |
} |
ecount= bytes & ~1; |
if (ecount != 0) |
{ |
do_vir_insw(dep->de_data_port, user_proc, vir_user, |
ecount); |
count -= ecount; |
offset += ecount; |
bytes -= ecount; |
vir_user += ecount; |
} |
if (bytes) |
{ |
assert(bytes == 1); |
*(u16_t *)two_bytes= inw(dep->de_data_port); |
r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0], |
user_proc, D, vir_user, 1); |
if (r != OK) |
{ |
panic("DP8390", |
"dp_pio16_nic2user: sys_vircopy failed", |
r); |
} |
count--; |
offset++; |
bytes--; |
vir_user++; |
odd_byte= 1; |
} |
} |
assert(count == 0); |
} |
|
/*===========================================================================* |
* dp_next_iovec * |
*===========================================================================*/ |
static void dp_next_iovec(iovp) |
iovec_dat_t *iovp; |
{ |
assert(iovp->iod_iovec_s > IOVEC_NR); |
|
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_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) * |
sizeof(iovec_t), iovp->iod_iovec); |
} |
|
/*===========================================================================* |
* conf_hw * |
*===========================================================================*/ |
static void conf_hw(dep) |
859,14 → 1435,16 |
|
if (dep->de_prog_IO) |
{ |
//#if 0 |
#if 0 |
if(debug){ |
printf( |
"map_hw_buffer: programmed I/O, no need to map buffer\n"); |
} |
//#endif |
#endif |
dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */ |
return; |
}else{ |
printf( "map_hw_buffer: no buffer!" ); |
} |
|
// size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for |
927,6 → 1505,59 |
*/ dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV); |
} |
|
/*===========================================================================* |
* get_userdata * |
*===========================================================================*/ |
static void get_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(user_proc, D, user_addr, |
SELF, D, (vir_bytes)loc_addr, count); |
if (r != OK) |
panic("DP8390", "get_userdata: sys_vircopy failed", r); |
} |
|
static void insb(port_t port, void *buf, size_t size) |
{ |
int i; |
|
for( i = 0; i < size; ++ i ){ |
*(( uint8_t * )( buf + i )) = inb( port ); |
} |
} |
|
static void insw(port_t port, void *buf, size_t size) |
{ |
int i; |
|
for( i = 0; i < size; i += 2 ){ |
*(( uint16_t * )( buf + i )) = inw( port ); |
} |
} |
|
static void outsb(port_t port, void *buf, size_t size) |
{ |
int i; |
|
for( i = 0; i < size; ++ i ){ |
outb( port, *(( uint8_t * )( buf + i ))); |
} |
} |
|
static void outsw(port_t port, void *buf, size_t size) |
{ |
int i; |
|
for( i = 0; i < size; i += 2 ){ |
outw( port, *(( uint16_t * )( buf + i ))); |
} |
} |
|
/* |
* $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $ |
*/ |