From 308d9a693c062b83a2f4774ead71a08aa3c611ea Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Fri, 3 Jun 2005 08:59:54 +0000 Subject: [PATCH] prettified rtl driver: . no more kmalloc . no more umaps + physcopies / abscopies . the status register is directly readable from the drivers own address space now, and no physcopy is needed to read it . map+physcopy call combinations are replaced by vircopy calls --- drivers/rtl8139/Makefile | 2 +- drivers/rtl8139/rtl8139.c | 217 ++++++++++++++++++-------------------- 2 files changed, 104 insertions(+), 115 deletions(-) diff --git a/drivers/rtl8139/Makefile b/drivers/rtl8139/Makefile index 031ae538e..f09101052 100644 --- a/drivers/rtl8139/Makefile +++ b/drivers/rtl8139/Makefile @@ -24,7 +24,7 @@ LIBPCI = $d/libpci/pci.o $d/libpci/pci_table.o all build: $(DRIVER) $(DRIVER): $(OBJ) $(PCI) $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBPCI) $(LIBS) - install -S 256w $(DRIVER) + install -S 50kw $(DRIVER) $(PCI): cd $d/libpci && $(MAKE) diff --git a/drivers/rtl8139/rtl8139.c b/drivers/rtl8139/rtl8139.c index adb0b2062..94dabda94 100755 --- a/drivers/rtl8139/rtl8139.c +++ b/drivers/rtl8139/rtl8139.c @@ -52,8 +52,6 @@ #include #include #include -#define NDEBUG /* disable assertions */ -#include #include #include #include @@ -67,23 +65,18 @@ #include #include +#include #include #include #include "../../kernel/const.h" #include "../../kernel/type.h" -#if __minix_vmd -#include "config.h" -#include "timer.h" -#else #define tmra_ut timer_t #define tmra_inittimer(tp) tmr_inittimer(tp) #define Proc_number(p) proc_number(p) #define debug 0 -#define RAND_UPDATE /**/ #define printW() ((void)0) #define vm_1phys2bus(p) (p) -#endif #if ENABLE_RTL8139 #if !ENABLE_PCI @@ -93,16 +86,11 @@ #include "../libpci/pci.h" #include "rtl8139.h" - #define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE #define RX_BUFBITS RL_RCR_RBLEN_64K #define N_TX_BUF RL_N_TX -#if __minix_vmd -#define RE_PORT_NR 3 /* Minix-vmd */ -#else #define RE_PORT_NR 1 /* Minix */ -#endif /* I/O vectors are handled IOVEC_NR entries at a time. */ #define IOVEC_NR 16 @@ -110,26 +98,6 @@ /* Configuration */ #define RL_ENVVAR "RTLETH" -#if 0 -typedef struct rl_conf -{ - char *rlc_envvar; -} rl_conf_t; - -rl_conf_t rl_conf[]= /* Card addresses */ -{ - /* Env. var. */ - { "RTLETH0" }, - { "RTLETH1" }, - { "RTLETH2" }, -}; - -/* Test if rl_conf has exactly RE_PORT_NR entries. If not then you will see - * the error: "array size is negative". - */ -extern int ___dummy[RE_PORT_NR == sizeof(rl_conf)/sizeof(rl_conf[0]) ? 1 : -1]; -#endif - PRIVATE struct pcitab { u16_t vid; @@ -161,6 +129,7 @@ typedef struct re /* Rx */ phys_bytes re_rx_buf; + char *v_re_rx_buf; vir_bytes re_read_s; /* Tx */ @@ -170,6 +139,7 @@ typedef struct re { int ret_busy; phys_bytes ret_buf; + char * v_ret_buf; } re_tx[N_TX_BUF]; u32_t re_ertxth; /* Early Tx Threshold */ @@ -194,9 +164,6 @@ re_t; #define REM_DISABLED 0x0 #define REM_ENABLED 0x1 -#if 0 -#define REF_STOPPED 0x400 -#endif #define REF_PACK_SENT 0x001 #define REF_PACK_RECV 0x002 #define REF_SEND_AVAIL 0x004 @@ -297,11 +264,7 @@ _PROTOTYPE( static void rtl8139_dump, (message *m) ); _PROTOTYPE( static void dump_phy, (re_t *rep) ); #endif _PROTOTYPE( static int rl_handler, (re_t *rep) ); -#if __minix_vmd -_PROTOTYPE( static void rl_watchdog_f, (tmra_ut *tp, tmr_arg_ut arg) ); -#else _PROTOTYPE( static void rl_watchdog_f, (timer_t *tp) ); -#endif /* The message used in the main loop is made global, so that rl_watchdog_f() * can change its message type to fake a HARD_INT message. @@ -325,16 +288,14 @@ void main(void) (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); eth_ign_proto= htons((u16_t) v); -#if !__minix_vmd - /* Claim buffer memory now under Minix, before MM takes it all. */ - for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) - rl_init_buf(rep); -#endif - /* Observe some function key for debug dumps. */ if ((r=fkey_enable(SF9)) != OK) printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r); + /* Claim buffer memory now under Minix, before MM takes it all. */ + for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) + rl_init_buf(rep); + while (TRUE) { if ((r= receive(ANY, &m)) != OK) @@ -353,7 +314,6 @@ void main(void) #if 0 case DL_STOP: do_stop(&m); break; #endif -#if !__minix_vmd case SYN_ALARM: /* Under MINIX, synchronous alarms are used instead of * watchdog functions. The approach is very different: @@ -367,11 +327,7 @@ void main(void) * case falls through. */ rl_watchdog_f(NULL); -#if DEAD_CODE /* now directly done */ - if (m.m_type != HARD_INT) -#endif break; -#endif case HARD_INT: do_hard_int(); if (int_event_check) @@ -487,9 +443,6 @@ message *mp; int port; re_t *rep; -#if __minix_vmd - tmr_arg_ut t_arg; -#endif message reply_mess; if (first_time) @@ -498,14 +451,8 @@ message *mp; rl_pci_conf(); /* Configure PCI devices. */ tmra_inittimer(&rl_watchdog); -#if __minix_vmd - t_arg.ta_int= 0; - tmra_settimer(&rl_watchdog, get_uptime()+HZ, - rl_watchdog_f, t_arg); -#else /* Use a synchronous alarm instead of a watchdog timer. */ sys_syncalrm(SELF, HZ, 0); -#endif } port = mp->DL_PORT; @@ -739,8 +686,9 @@ re_t *rep; { size_t rx_bufsize, tx_bufsize, tot_bufsize; phys_bytes buf; + char *mallocbuf; static struct memory chunk; - int fd, s, i; + int fd, s, i, off; /* Allocate receive and transmit buffers */ tx_bufsize= ETH_MAX_PACK_SIZE_TAGGED; @@ -748,36 +696,41 @@ re_t *rep; tx_bufsize += 4-(tx_bufsize % 4); /* Align */ rx_bufsize= RX_BUFSIZE; tot_bufsize= N_TX_BUF*tx_bufsize + rx_bufsize; -#if __minix_vmd - buf= (phys_bytes)kalloc_dma_128K(tot_bufsize, FALSE /* not low */); -#else /* Now try to allocate a kernel memory buffer. */ chunk.size = tot_bufsize; -#if DEAD_CODE - fd = open("/dev/mem", O_RDONLY); - if (fd <0) { - printf("RTL8139: warning, couldn't open: %d\n", fd); - } else { - if (OK != (s=ioctl(fd, MIOCGETCHUNK, &chunk))) - printf("RTL8139: ioctl failed: %d\n", s); - else - printf("RTL8139: %uK buffer from mem at 0x06%x\n", - chunk.size, chunk.base); - } - close(fd); -#endif - if (OK != (i=sys_kmalloc(tot_bufsize, &buf))) - panic("RTL8139","Couldn't allocate kernel buffer",i); - printf("RTL8139: real %uK buffer at 0x%06x\n", tot_bufsize, buf); +#define BUF_ALIGNMENT (64*1024) + +#if DEAD_CODE + if (OK != (i=sys_kmalloc(tot_bufsize, &buf))) { +#else + if(!(mallocbuf = malloc(BUF_ALIGNMENT + tot_bufsize))) { #endif + panic("RTL8139","Couldn't allocate kernel buffer",i); + } + + if(OK != (i = sys_umap(SELF, D, (vir_bytes) mallocbuf, tot_bufsize, &buf))) { + panic("RTL8139","Couldn't re-map malloced buffer",i); + } + + /* click-align mallocced buffer. this is what we used to get + * from kmalloc() too. + */ + if((off = buf % BUF_ALIGNMENT)) { + mallocbuf += BUF_ALIGNMENT - off; + buf += BUF_ALIGNMENT - off; + } + for (i= 0; ire_tx[i].ret_buf= buf; + rep->re_tx[i].v_ret_buf= mallocbuf; buf += tx_bufsize; + mallocbuf += tx_bufsize; } rep->re_rx_buf= buf; + rep->v_re_rx_buf= mallocbuf; } /*===========================================================================* @@ -788,10 +741,6 @@ re_t *rep; { int s, i; -#if __minix_vmd - rl_init_buf(rep); -#endif - rep->re_flags = REF_EMPTY; rep->re_flags |= REF_ENABLED; @@ -1021,7 +970,7 @@ int vectored; unsigned amount, totlen, packlen; phys_bytes src_phys, dst_phys, iov_src; u16_t d_start, d_end; - u32_t l, rxstat; + u32_t l, rxstat = 0x12345678; re_t *rep; iovec_t *iovp; int cps; @@ -1065,9 +1014,15 @@ int vectored; else amount= d_end+RX_BUFSIZE - d_start; + 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)); + 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) { @@ -1115,22 +1070,32 @@ int vectored; 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; src_phys= rep->re_rx_buf; for (i= 0; ire_iovec[0])) + 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; +#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 (%d)\n", cps, __LINE__); +#endif for (j= 0, iovp= rep->re_iovec; jiov_addr, s, &dst_phys) != OK) panic("rtl8139","umap_local failed\n", NO_NUM); +#endif if (o >= RX_BUFSIZE) { @@ -1155,15 +1122,30 @@ int vectored; assert(ov_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 } 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 } size += s; @@ -1192,7 +1174,7 @@ int vectored; 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); - #endif +#endif } if (rep->re_clear_rx) @@ -1256,6 +1238,7 @@ int vectored; int tx_head, re_client; re_t *rep; iovec_t *iovp; + char *ret; int cps; port = mp->DL_PORT; @@ -1301,22 +1284,37 @@ int vectored; if (vectored) { + int iov_offset = 0; +#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); +#endif size= 0; +#if 0 p= rep->re_tx[tx_head].ret_buf; +#else + ret = rep->re_tx[tx_head].v_ret_buf; +#endif for (i= 0; ire_iovec[0])) + 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; +#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); +#endif for (j= 0, iovp= rep->re_iovec; jiov_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; } } if (size < ETH_MIN_PACK_SIZE) @@ -1344,12 +1351,19 @@ int vectored; 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); +#endif } rl_outl(rep->re_base_port, RL_TSD0+tx_head*4, @@ -2061,9 +2075,6 @@ re_t *rep; clock_t t0,t1; int_event_check = FALSE; /* disable check by default */ - RAND_UPDATE - - port= rep->re_base_port; /* Ack interrupt */ @@ -2327,27 +2338,13 @@ re_t *rep; /*===========================================================================* * rl_watchdog_f * *===========================================================================*/ -#if __minix_vmd -static void rl_watchdog_f(tp, arg) -tmra_ut *tp; -tmr_arg_ut arg; -#else static void rl_watchdog_f(tp) timer_t *tp; -#endif { int i; re_t *rep; -#if __minix_vmd - tmr_arg_ut t_arg; - - assert(tp == &rl_watchdog); - t_arg.ta_int= 0; - tmra_settimer(&rl_watchdog, get_uptime()+HZ, rl_watchdog_f, t_arg); -#else /* Use a synchronous alarm instead of a watchdog timer. */ sys_syncalrm(SELF, HZ, 0); -#endif for (i= 0, rep = &re_table[0]; ire_tx[2].ret_busy, rep->re_tx[3].ret_busy); rep->re_need_reset= TRUE; rep->re_got_int= TRUE; -#if __minix_vmd -#if DEAD_CODE - notify(rl_tasknr, HARD_INT); -#else - check_int_events(); -#endif -#else /* Under MINIX, we got here via a synchronous alarm call. * Change the message type to HARD_INT to fake an interrupt. * The switch in the main loop 'falls through' if it sees @@ -2394,7 +2384,6 @@ timer_t *tp; m.m_type = HARD_INT; #else check_int_events(); -#endif #endif } }